1818
1919import  static  com .google .common .truth .Truth .assertThat ;
2020import  static  com .google .common .truth .Truth .assertWithMessage ;
21+ import  static  org .mockito .Mockito .mock ;
22+ import  static  org .mockito .Mockito .times ;
23+ import  static  org .mockito .Mockito .verify ;
24+ import  static  org .mockito .Mockito .when ;
2125
26+ import  com .google .api .gax .longrunning .OperationFuture ;
2227import  com .google .api .gax .rpc .NotFoundException ;
28+ import  com .google .cloud .compute .v1 .AllocationSpecificSKUReservation ;
29+ import  com .google .cloud .compute .v1 .Operation ;
2330import  com .google .cloud .compute .v1 .Reservation ;
2431import  com .google .cloud .compute .v1 .ReservationsClient ;
32+ import  com .google .cloud .compute .v1 .ShareSettings ;
33+ import  com .google .cloud .compute .v1 .ShareSettingsProjectConfig ;
2534import  compute .CreateInstanceTemplate ;
2635import  compute .CreateRegionalInstanceTemplate ;
2736import  compute .DeleteInstanceTemplate ;
3645import  java .util .concurrent .TimeoutException ;
3746import  org .junit .Assert ;
3847import  org .junit .jupiter .api .AfterAll ;
48+ import  org .junit .jupiter .api .AfterEach ;
3949import  org .junit .jupiter .api .Assertions ;
4050import  org .junit .jupiter .api .BeforeAll ;
51+ import  org .junit .jupiter .api .BeforeEach ;
4152import  org .junit .jupiter .api .MethodOrderer ;
4253import  org .junit .jupiter .api .Order ;
4354import  org .junit .jupiter .api .Test ;
@@ -69,7 +80,16 @@ public class ReservationIT {
6980  private  static  final  String  REGIONAL_INSTANCE_TEMPLATE_URI  =
7081      String .format ("projects/%s/regions/%s/instanceTemplates/%s" ,
7182          PROJECT_ID , REGION , REGIONAL_INSTANCE_TEMPLATE_NAME );
83+   private  static  final  String  SPECIFIC_SHARED_INSTANCE_TEMPLATE_NAME  =
84+       "test-shared-inst-temp-"   + javaVersion   + "-" 
85+           + UUID .randomUUID ().toString ().substring (0 , 8 );
86+   private  static  final  String   INSTANCE_TEMPLATE_SHARED_RESERV_URI  =
87+       String .format ("projects/%s/global/instanceTemplates/%s" ,
88+       PROJECT_ID , SPECIFIC_SHARED_INSTANCE_TEMPLATE_NAME );
89+   private  static  final  String  RESERVATION_NAME_SHARED  = "test-reservation-shared-"  + javaVersion 
90+       + "-"  + UUID .randomUUID ().toString ().substring (0 , 8 );
7291  private  static  final  int  NUMBER_OF_VMS  = 3 ;
92+   private  ByteArrayOutputStream  stdOut ;
7393
7494  // Check if the required environment variables are set. 
7595  public  static  void  requireEnvVar (String  envVarName ) {
@@ -93,6 +113,7 @@ public static void setUp()
93113    Util .cleanUpExistingReservations (
94114        "test-reservation-global-"  + javaVersion , PROJECT_ID , ZONE );
95115    Util .cleanUpExistingReservations ("test-reservation-regional-"  + javaVersion , PROJECT_ID , ZONE );
116+     Util .cleanUpExistingInstanceTemplates ("test-shared-inst-temp-"  + javaVersion , PROJECT_ID );
96117
97118    // Initialize the client once for all tests 
98119    reservationsClient  = ReservationsClient .create ();
@@ -105,6 +126,9 @@ public static void setUp()
105126    CreateRegionalInstanceTemplate .createRegionalInstanceTemplate (
106127        PROJECT_ID , REGION , REGIONAL_INSTANCE_TEMPLATE_NAME );
107128    assertThat (stdOut .toString ()).contains ("Instance Template Operation Status: DONE" );
129+     // Create instance template for shares reservation. 
130+     CreateInstanceTemplate .createInstanceTemplate (
131+         PROJECT_ID , SPECIFIC_SHARED_INSTANCE_TEMPLATE_NAME );
108132
109133    stdOut .close ();
110134    System .setOut (out );
@@ -130,6 +154,13 @@ public static void cleanup()
130154        .contains ("Instance template deletion operation status for " 
131155            + REGIONAL_INSTANCE_TEMPLATE_NAME );
132156
157+     // Delete instance template for shared reservation 
158+     DeleteInstanceTemplate .deleteInstanceTemplate (
159+         PROJECT_ID , SPECIFIC_SHARED_INSTANCE_TEMPLATE_NAME );
160+     assertThat (stdOut .toString ())
161+         .contains ("Instance template deletion operation status for " 
162+             + SPECIFIC_SHARED_INSTANCE_TEMPLATE_NAME );
163+ 
133164    // Delete all reservations created for testing. 
134165    DeleteReservation .deleteReservation (PROJECT_ID , ZONE , RESERVATION_NAME_GLOBAL );
135166    DeleteReservation .deleteReservation (PROJECT_ID , ZONE , RESERVATION_NAME_REGIONAL );
@@ -149,6 +180,18 @@ public static void cleanup()
149180    System .setOut (out );
150181  }
151182
183+   @ BeforeEach 
184+   public  void  beforeEach () {
185+     stdOut  = new  ByteArrayOutputStream ();
186+     System .setOut (new  PrintStream (stdOut ));
187+   }
188+ 
189+   @ AfterEach 
190+   public  void  afterEach () {
191+     stdOut  = null ;
192+     System .setOut (null );
193+   }
194+ 
152195  @ Test 
153196  @ Order (1 )
154197  public  void  testCreateReservationWithGlobalInstanceTemplate ()
@@ -189,4 +232,53 @@ public void testUpdateVmsForReservation()
189232
190233    Assert .assertEquals (newNumberOfVms , reservation .getSpecificReservation ().getCount ());
191234  }
235+ 
236+   @ Test 
237+   public  void  testCreateSharedReservation ()
238+       throws  ExecutionException , InterruptedException , TimeoutException  {
239+     // Mock the ReservationsClient 
240+     ReservationsClient  mockReservationsClient  = mock (ReservationsClient .class );
241+ 
242+     // This test require projects in the test environment to share reservation with, 
243+     // therefore the operation should be mocked. If you want to make a real test, 
244+     // please set the CONSUMER_PROJECT_ID_1 and CONSUMER_PROJECT_ID_2 accordingly. 
245+     // Make sure that base project has proper permissions to share reservations. 
246+     // See: https://cloud.google.com/compute/docs/instances/reservations-shared#shared_reservation_constraint 
247+     ShareSettings  shareSettings  = ShareSettings .newBuilder ()
248+         .setShareType (String .valueOf (ShareSettings .ShareType .SPECIFIC_PROJECTS ))
249+         .putProjectMap ("CONSUMER_PROJECT_ID_1" , ShareSettingsProjectConfig .newBuilder ().build ())
250+         .putProjectMap ("CONSUMER_PROJECT_ID_2" , ShareSettingsProjectConfig .newBuilder ().build ())
251+         .build ();
252+ 
253+     Reservation  reservation  =
254+         Reservation .newBuilder ()
255+             .setName (RESERVATION_NAME_SHARED )
256+             .setZone (ZONE )
257+             .setSpecificReservationRequired (true )
258+             .setShareSettings (shareSettings )
259+             .setSpecificReservation (
260+                 AllocationSpecificSKUReservation .newBuilder ()
261+                     .setCount (NUMBER_OF_VMS )
262+                     .setSourceInstanceTemplate (INSTANCE_TEMPLATE_SHARED_RESERV_URI )
263+                     .build ())
264+             .build ();
265+ 
266+     OperationFuture  mockFuture  = mock (OperationFuture .class );
267+     when (mockReservationsClient .insertAsync (PROJECT_ID , ZONE , reservation ))
268+         .thenReturn (mockFuture );
269+     Operation  mockOperation  = mock (Operation .class );
270+     when (mockFuture .get (3 , TimeUnit .MINUTES )).thenReturn (mockOperation );
271+     when (mockOperation .hasError ()).thenReturn (false );
272+     when (mockOperation .getStatus ()).thenReturn (Operation .Status .DONE );
273+ 
274+     // Create an instance, passing in the mock client 
275+     CreateSharedReservation  creator  = new  CreateSharedReservation (mockReservationsClient );
276+ 
277+     creator .createSharedReservation (PROJECT_ID , ZONE ,
278+         RESERVATION_NAME_SHARED , INSTANCE_TEMPLATE_SHARED_RESERV_URI , NUMBER_OF_VMS );
279+ 
280+     verify (mockReservationsClient , times (1 ))
281+         .insertAsync (PROJECT_ID , ZONE , reservation );
282+     assertThat (stdOut .toString ()).contains ("Reservation created. Operation Status: DONE" );
283+   }
192284}
0 commit comments