Skip to content

Commit

Permalink
fix(compute): fixed compute_reservation_create_shared sample and test…
Browse files Browse the repository at this point in the history
… to use mocked client (#9840)

* Fixed sample and test to use mocked client

* Fixed code as requested in the comments
  • Loading branch information
TetyanaYahodska authored Dec 23, 2024
1 parent 230665f commit 3b9ac56
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

// [START compute_reservation_create_shared]
import com.google.cloud.compute.v1.AllocationSpecificSKUReservation;
import com.google.cloud.compute.v1.InsertReservationRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.Reservation;
import com.google.cloud.compute.v1.ReservationsClient;
import com.google.cloud.compute.v1.ShareSettings;
Expand All @@ -29,12 +31,6 @@
import java.util.concurrent.TimeoutException;

public class CreateSharedReservation {
private final ReservationsClient reservationsClient;

// Constructor to inject the ReservationsClient
public CreateSharedReservation(ReservationsClient reservationsClient) {
this.reservationsClient = reservationsClient;
}

public static void main(String[] args)
throws IOException, ExecutionException, InterruptedException, TimeoutException {
Expand All @@ -48,62 +44,66 @@ public static void main(String[] args)
// For more information visit this page:
// https://cloud.google.com/compute/docs/instances/reservations-shared#shared_reservation_constraint
String projectId = "YOUR_PROJECT_ID";
// Zone in which the reservation resides.
// Zone in which to reserve resources.
String zone = "us-central1-a";
// Name of the reservation to be created.
String reservationName = "YOUR_RESERVATION_NAME";
// The URI of the global instance template to be used for creating the reservation.
String instanceTemplateUri = String.format(
"projects/%s/global/instanceTemplates/YOUR_INSTANCE_TEMPLATE_NAME", projectId);
"projects/%s/global/instanceTemplates/%s", projectId, "YOUR_INSTANCE_TEMPLATE_NAME");
// Number of instances for which capacity needs to be reserved.
int vmCount = 3;
// In your main method, create ReservationsClient
ReservationsClient client = ReservationsClient.create();
// Create an instance of your class, passing in the client
CreateSharedReservation creator = new CreateSharedReservation(client);

creator.createSharedReservation(projectId, zone, reservationName, instanceTemplateUri, vmCount);
createSharedReservation(projectId, zone, reservationName, instanceTemplateUri, vmCount);
}

// Creates a shared reservation with the given name in the given zone.
public void createSharedReservation(
String projectId, String zone,
String reservationName, String instanceTemplateUri, int vmCount)
throws ExecutionException, InterruptedException, TimeoutException {
public static Status createSharedReservation(
String projectId, String zone,
String reservationName, String instanceTemplateUri, int vmCount)
throws ExecutionException, InterruptedException, TimeoutException, IOException {

// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try (ReservationsClient reservationsClient = ReservationsClient.create()) {
ShareSettings shareSettings = ShareSettings.newBuilder()
.setShareType(String.valueOf(ShareSettings.ShareType.SPECIFIC_PROJECTS))
// The IDs of projects that can consume this reservation. You can include up to
// 100 consumer projects. These projects must be in the same organization as
// the owner project. Don't include the owner project.
// By default, it is already allowed to consume the reservation.
.putProjectMap("CONSUMER_PROJECT_1", ShareSettingsProjectConfig.newBuilder().build())
.putProjectMap("CONSUMER_PROJECT_2", ShareSettingsProjectConfig.newBuilder().build())
.build();

ShareSettings shareSettings = ShareSettings.newBuilder()
.setShareType(String.valueOf(ShareSettings.ShareType.SPECIFIC_PROJECTS))
// The IDs of projects that can consume this reservation. You can include up to 100
// consumer projects. These projects must be in the same organization as
// the owner project. Don't include the owner project. By default, it is already allowed
// to consume the reservation.
.putProjectMap("CONSUMER_PROJECT_ID_1", ShareSettingsProjectConfig.newBuilder().build())
.putProjectMap("CONSUMER_PROJECT_ID_2", ShareSettingsProjectConfig.newBuilder().build())
.build();
Reservation reservationResource =
Reservation.newBuilder()
.setName(reservationName)
.setZone(zone)
.setSpecificReservationRequired(true)
.setShareSettings(shareSettings)
.setSpecificReservation(
AllocationSpecificSKUReservation.newBuilder()
.setCount(vmCount)
.setSourceInstanceTemplate(instanceTemplateUri)
.build())
.build();

// Create the reservation.
Reservation reservation =
Reservation.newBuilder()
.setName(reservationName)
.setZone(zone)
.setSpecificReservationRequired(true)
.setShareSettings(shareSettings)
.setSpecificReservation(
AllocationSpecificSKUReservation.newBuilder()
.setCount(vmCount)
.setSourceInstanceTemplate(instanceTemplateUri)
.build())
.build();
InsertReservationRequest request =
InsertReservationRequest.newBuilder()
.setProject(projectId)
.setZone(zone)
.setReservationResource(reservationResource)
.build();

// Wait for the create reservation operation to complete.
Operation response =
this.reservationsClient.insertAsync(projectId, zone, reservation).get(3, TimeUnit.MINUTES);
Operation response = reservationsClient.insertAsync(request)
.get(3, TimeUnit.MINUTES);

if (response.hasError()) {
System.out.println("Reservation creation failed!" + response);
return;
if (response.hasError()) {
throw new Error("Reservation creation failed!!" + response);
}
return response.getStatus();
}
System.out.println("Reservation created. Operation Status: " + response.getStatus());
}
}
// [END compute_reservation_create_shared]
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,23 @@

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.google.api.gax.longrunning.OperationFuture;
import com.google.api.gax.rpc.NotFoundException;
import com.google.cloud.compute.v1.AllocationSpecificSKUReservation;
import com.google.cloud.compute.v1.InsertReservationRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.Reservation;
import com.google.cloud.compute.v1.ReservationsClient;
import com.google.cloud.compute.v1.ShareSettings;
import com.google.cloud.compute.v1.ShareSettingsProjectConfig;
import compute.CreateInstanceTemplate;
import compute.CreateRegionalInstanceTemplate;
import compute.DeleteInstanceTemplate;
Expand All @@ -53,6 +55,7 @@
import org.junit.jupiter.api.Timeout;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.MockedStatic;

@RunWith(JUnit4.class)
@Timeout(value = 6, unit = TimeUnit.MINUTES)
Expand Down Expand Up @@ -184,50 +187,26 @@ public void testCreateReservationWithRegionInstanceTemplate()

@Test
public void testCreateSharedReservation()
throws ExecutionException, InterruptedException, TimeoutException {
// Mock the ReservationsClient
ReservationsClient mockReservationsClient = mock(ReservationsClient.class);

// This test require projects in the test environment to share reservation with,
// therefore the operation should be mocked. If you want to make a real test,
// please set the CONSUMER_PROJECT_ID_1 and CONSUMER_PROJECT_ID_2 accordingly.
// Make sure that base project has proper permissions to share reservations.
// See: https://cloud.google.com/compute/docs/instances/reservations-shared#shared_reservation_constraint
ShareSettings shareSettings = ShareSettings.newBuilder()
.setShareType(String.valueOf(ShareSettings.ShareType.SPECIFIC_PROJECTS))
.putProjectMap("CONSUMER_PROJECT_ID_1", ShareSettingsProjectConfig.newBuilder().build())
.putProjectMap("CONSUMER_PROJECT_ID_2", ShareSettingsProjectConfig.newBuilder().build())
.build();

Reservation reservation =
Reservation.newBuilder()
.setName(RESERVATION_NAME_SHARED)
.setZone(ZONE)
.setSpecificReservationRequired(true)
.setShareSettings(shareSettings)
.setSpecificReservation(
AllocationSpecificSKUReservation.newBuilder()
.setCount(NUMBER_OF_VMS)
.setSourceInstanceTemplate(INSTANCE_TEMPLATE_SHARED_RESERV_URI)
.build())
.build();

OperationFuture mockFuture = mock(OperationFuture.class);
when(mockReservationsClient.insertAsync(PROJECT_ID, ZONE, reservation))
.thenReturn(mockFuture);
Operation mockOperation = mock(Operation.class);
when(mockFuture.get(3, TimeUnit.MINUTES)).thenReturn(mockOperation);
when(mockOperation.hasError()).thenReturn(false);
when(mockOperation.getStatus()).thenReturn(Status.DONE);

// Create an instance, passing in the mock client
CreateSharedReservation creator = new CreateSharedReservation(mockReservationsClient);

creator.createSharedReservation(PROJECT_ID, ZONE,
RESERVATION_NAME_SHARED, INSTANCE_TEMPLATE_SHARED_RESERV_URI, NUMBER_OF_VMS);

verify(mockReservationsClient, times(1))
.insertAsync(PROJECT_ID, ZONE, reservation);
assertThat(stdOut.toString()).contains("Reservation created. Operation Status: DONE");
throws ExecutionException, InterruptedException, TimeoutException, IOException {
try (MockedStatic<ReservationsClient> mockReservationsClient =
mockStatic(ReservationsClient.class)) {
ReservationsClient mockClient = mock(ReservationsClient.class);
OperationFuture mockFuture = mock(OperationFuture.class);
Operation mockOperation = mock(Operation.class);

mockReservationsClient.when(ReservationsClient::create).thenReturn(mockClient);
when(mockClient.insertAsync(any(InsertReservationRequest.class)))
.thenReturn(mockFuture);
when(mockFuture.get(3, TimeUnit.MINUTES)).thenReturn(mockOperation);
when(mockOperation.getStatus()).thenReturn(Status.DONE);

Status status = CreateSharedReservation.createSharedReservation(PROJECT_ID, ZONE,
RESERVATION_NAME_SHARED, INSTANCE_TEMPLATE_SHARED_RESERV_URI, NUMBER_OF_VMS);

verify(mockClient, times(1)).insertAsync(any(InsertReservationRequest.class));
verify(mockFuture, times(1)).get(anyLong(), any(TimeUnit.class));
assertEquals(Status.DONE, status);

}
}
}

0 comments on commit 3b9ac56

Please sign in to comment.