18
18
19
19
import static com .google .common .truth .Truth .assertThat ;
20
20
import 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 ;
21
25
26
+ import com .google .api .gax .longrunning .OperationFuture ;
22
27
import com .google .api .gax .rpc .NotFoundException ;
28
+ import com .google .cloud .compute .v1 .AllocationSpecificSKUReservation ;
29
+ import com .google .cloud .compute .v1 .Operation ;
23
30
import com .google .cloud .compute .v1 .Reservation ;
24
31
import com .google .cloud .compute .v1 .ReservationsClient ;
32
+ import com .google .cloud .compute .v1 .ShareSettings ;
33
+ import com .google .cloud .compute .v1 .ShareSettingsProjectConfig ;
25
34
import compute .CreateInstanceTemplate ;
26
35
import compute .CreateRegionalInstanceTemplate ;
27
36
import compute .DeleteInstanceTemplate ;
36
45
import java .util .concurrent .TimeoutException ;
37
46
import org .junit .Assert ;
38
47
import org .junit .jupiter .api .AfterAll ;
48
+ import org .junit .jupiter .api .AfterEach ;
39
49
import org .junit .jupiter .api .Assertions ;
40
50
import org .junit .jupiter .api .BeforeAll ;
51
+ import org .junit .jupiter .api .BeforeEach ;
41
52
import org .junit .jupiter .api .MethodOrderer ;
42
53
import org .junit .jupiter .api .Order ;
43
54
import org .junit .jupiter .api .Test ;
@@ -69,7 +80,16 @@ public class ReservationIT {
69
80
private static final String REGIONAL_INSTANCE_TEMPLATE_URI =
70
81
String .format ("projects/%s/regions/%s/instanceTemplates/%s" ,
71
82
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 );
72
91
private static final int NUMBER_OF_VMS = 3 ;
92
+ private ByteArrayOutputStream stdOut ;
73
93
74
94
// Check if the required environment variables are set.
75
95
public static void requireEnvVar (String envVarName ) {
@@ -93,6 +113,7 @@ public static void setUp()
93
113
Util .cleanUpExistingReservations (
94
114
"test-reservation-global-" + javaVersion , PROJECT_ID , ZONE );
95
115
Util .cleanUpExistingReservations ("test-reservation-regional-" + javaVersion , PROJECT_ID , ZONE );
116
+ Util .cleanUpExistingInstanceTemplates ("test-shared-inst-temp-" + javaVersion , PROJECT_ID );
96
117
97
118
// Initialize the client once for all tests
98
119
reservationsClient = ReservationsClient .create ();
@@ -105,6 +126,9 @@ public static void setUp()
105
126
CreateRegionalInstanceTemplate .createRegionalInstanceTemplate (
106
127
PROJECT_ID , REGION , REGIONAL_INSTANCE_TEMPLATE_NAME );
107
128
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 );
108
132
109
133
stdOut .close ();
110
134
System .setOut (out );
@@ -130,6 +154,13 @@ public static void cleanup()
130
154
.contains ("Instance template deletion operation status for "
131
155
+ REGIONAL_INSTANCE_TEMPLATE_NAME );
132
156
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
+
133
164
// Delete all reservations created for testing.
134
165
DeleteReservation .deleteReservation (PROJECT_ID , ZONE , RESERVATION_NAME_GLOBAL );
135
166
DeleteReservation .deleteReservation (PROJECT_ID , ZONE , RESERVATION_NAME_REGIONAL );
@@ -149,6 +180,18 @@ public static void cleanup()
149
180
System .setOut (out );
150
181
}
151
182
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
+
152
195
@ Test
153
196
@ Order (1 )
154
197
public void testCreateReservationWithGlobalInstanceTemplate ()
@@ -189,4 +232,53 @@ public void testUpdateVmsForReservation()
189
232
190
233
Assert .assertEquals (newNumberOfVms , reservation .getSpecificReservation ().getCount ());
191
234
}
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
+ }
192
284
}
0 commit comments