ResourceReserveStepCmd extends StepCommand { @Override protected void execute() throws ApiFeException, InterruptedException, RpcException { List<BaseEntity> entityList = step.getTransientResourceEntities(); for (BaseEntity entity : entityList) { if (!entity.getKind().equals(Vm.KIND) && !entity.getKind().equals(PersistentDisk.KIND)) { continue; } infrastructureEntity = (InfrastructureEntity) entity; } Preconditions.checkArgument(infrastructureEntity != null, "There should be at least one InfrastructureEntity referenced by step %s", step.getId()); Resource resource = createResource(infrastructureEntity); taskCommand.setResource(resource); String reservation; if (infrastructureEntity.getKind().equals(Vm.KIND)) { String targetHostIp = ((VmEntity) infrastructureEntity).getHostAffinity(); reservation = loadReservation(resource, targetHostIp, infrastructureEntity.getKind()); } else { reservation = loadReservation(resource, infrastructureEntity.getKind()); } taskCommand.setReservation(reservation); } ResourceReserveStepCmd(TaskCommand taskCommand,
                                StepBackend stepBackend,
                                StepEntity step,
                                DiskBackend diskBackend,
                                VmBackend vmBackend,
                                NetworkBackend networkBackend,
                                FlavorBackend flavorBackend,
                                Boolean useVirtualNetwork);  static final String LOGICAL_SWITCH_ID; static final String VIRTUAL_NETWORK_ID; static final String VM_ID; }
@Test public void testSuccessfulVmExecutionWithDiskAffinities() throws Throwable { List<QuotaLineItem> quotaLineItems = new ArrayList<>(); quotaLineItems.add(new QuotaLineItem("vm.cost", "100.0", com.vmware.photon.controller.flavors.gen.QuotaUnit.COUNT)); Flavor expectedFlavor = new Flavor(); expectedFlavor.setName("vm-100"); expectedFlavor.setCost(quotaLineItems); PersistentDiskEntity disk1 = new PersistentDiskEntity(); PersistentDiskEntity disk2 = new PersistentDiskEntity(); disk1.setDatastore("datastore-1"); disk2.setDatastore("datastore-1"); when(diskBackend.find(PersistentDisk.KIND, "disk-1")).thenReturn(disk1); when(diskBackend.find(PersistentDisk.KIND, "disk-2")).thenReturn(disk2); List<LocalityEntity> affinities = new ArrayList<>(); LocalityEntity localityEntity1 = new LocalityEntity(); localityEntity1.setResourceId("disk-1"); localityEntity1.setKind("disk"); LocalityEntity localityEntity2 = new LocalityEntity(); localityEntity2.setResourceId("disk-2"); localityEntity2.setKind("disk"); affinities.add(localityEntity1); affinities.add(localityEntity2); vm.setAffinities(affinities); PlacementTask placementTask = generateResourcePlacementList(); placementTask.resource.getPlacement_list().addToPlacements( generateResourcePlacement(ResourcePlacementType.VM, "vm-id")); Operation placementOperation = new Operation().setBody(placementTask); when(photonControllerXenonRestClient.post(any(), any(), anyLong())).thenReturn(placementOperation); when(hostClient.reserve(any(Resource.class), eq(SUCCESSFUL_GENERATION))).thenReturn(SUCCESSFUL_RESERVE_RESPONSE); ResourceReserveStepCmd command = getVmReservationCommand(); command.execute(); verify(photonControllerXenonRestClient).post(any(), placementTaskCaptor.capture(), anyLong()); Resource resource = placementTaskCaptor.getValue().resource; assertThat(resource.getVm().getResource_constraints().size(), is(vm.getAffinities().size() + 1)); assertThat(resource.getVm().getResource_constraints().get(0).getType(), is(ResourceConstraintType.DATASTORE)); assertThat(resource.getVm().getResource_constraints().get(0).getValues().equals(ImmutableList.of("datastore-1")), is(true)); assertThat(resource.getVm().getResource_constraints().get(1).getType(), is(ResourceConstraintType.DATASTORE)); assertThat(resource.getVm().getResource_constraints().get(1).getValues().equals(ImmutableList.of("datastore-1")), is(true)); verify(photonControllerXenonRestClient).post(any(), placementTaskCaptor.capture(), anyLong()); verify(hostClient).reserve(resourceCaptor.capture(), eq(SUCCESSFUL_GENERATION)); assertThat(placementTaskCaptor.getValue().resource, is(resource)); assertThat(resourceCaptor.getValue(), is(resource)); }
@Test public void testSuccessfulVmExecutionWithAvailabilityZoneAffinities() throws Throwable { List<LocalityEntity> affinities = new ArrayList<>(); LocalityEntity localityEntity = new LocalityEntity(); localityEntity.setResourceId("availabilityZone-1"); localityEntity.setKind("availabilityZone"); affinities.add(localityEntity); vm.setAffinities(affinities); PlacementTask placementTask = generateResourcePlacementList(); placementTask.resource.getPlacement_list().addToPlacements( generateResourcePlacement(ResourcePlacementType.VM, "vm-id")); Operation placementOperation = new Operation().setBody(placementTask); when(photonControllerXenonRestClient.post(any(), any(), anyLong())).thenReturn(placementOperation); when(hostClient.reserve(any(Resource.class), eq(42))).thenReturn(SUCCESSFUL_RESERVE_RESPONSE); ResourceReserveStepCmd command = getVmReservationCommand(); command.execute(); verify(photonControllerXenonRestClient).post(any(), placementTaskCaptor.capture(), anyLong()); Resource resource = placementTaskCaptor.getValue().resource; assertThat(resource.getVm().getResource_constraints().size(), is(vm.getAffinities().size() + 1)); assertThat(resource.getVm().getResource_constraints().get(0).getType(), is(ResourceConstraintType.AVAILABILITY_ZONE)); assertThat(resource.getVm().getResource_constraints().get(0).getValues() .equals(ImmutableList.of("availabilityZone-1")), is(true)); verify(photonControllerXenonRestClient).post(any(), placementTaskCaptor.capture(), anyLong()); verify(hostClient).reserve(resourceCaptor.capture(), eq(SUCCESSFUL_GENERATION)); assertThat(placementTaskCaptor.getValue().resource, is(resource)); assertThat(resourceCaptor.getValue(), is(resource)); }
@Test public void testSuccessfulVmExecutionWithEphemeralDiskAttached() throws Exception { List<QuotaLineItem> quotaLineItems = new ArrayList<>(); quotaLineItems.add(new QuotaLineItem("ephemeral-disk.cost", "10000.0", com.vmware.photon.controller.flavors.gen.QuotaUnit.COUNT)); quotaLineItems.add(new QuotaLineItem("ephemeral-disk.capacity", "0.0", com.vmware.photon.controller.flavors.gen.QuotaUnit.GB)); quotaLineItems.add(new QuotaLineItem("storage.SHARED_VMFS", "1.0", com.vmware.photon.controller.flavors.gen.QuotaUnit.COUNT)); Flavor expectedDiskFlavor = new Flavor(); expectedDiskFlavor.setName("ephemeral-disk-10000"); expectedDiskFlavor.setCost(quotaLineItems); attachEphemeralDisk(vm); ResourceReserveStepCmd command = getVmReservationCommand(); PlacementTask placementTask = generateResourcePlacementList(); placementTask.resource.getPlacement_list().addToPlacements( generateResourcePlacement(ResourcePlacementType.VM, "vm-id")); placementTask.resource.getPlacement_list().addToPlacements( generateResourcePlacement(ResourcePlacementType.DISK, "disk-id")); Operation placementOperation = new Operation().setBody(placementTask); when(photonControllerXenonRestClient.post(any(), any(), anyLong())).thenReturn(placementOperation); when(hostClient.reserve(any(Resource.class), eq(SUCCESSFUL_GENERATION))).thenReturn(SUCCESSFUL_RESERVE_RESPONSE); command.execute(); verify(photonControllerXenonRestClient).post(any(), placementTaskCaptor.capture(), anyLong()); Resource resource = placementTaskCaptor.getValue().resource; assertThat(resource.getVm().isSetResource_constraints(), is(true)); assertThat(resource.getVm().getResource_constraints().size(), is(2)); assertThat(resource.getVm().getResource_constraints().get(0).getType(), is(ResourceConstraintType.DATASTORE_TAG)); assertThat(resource.getVm().getResource_constraints().get(0).getValues().equals(ImmutableList.of("SHARED_VMFS")), is(true)); assertThat(resource.getVm().getDisks().size(), is(vm.getAttachedDisks().size())); assertThat(resource.getVm().getDisks().get(0).getId(), is("disk1")); assertThat(resource.getVm().getDisks().get(0).getFlavor_info(), is(expectedDiskFlavor)); assertThat(resource.getVm().getDisks().get(0).isSetResource_constraints(), is(false)); assertThat(resource.getPlacement_list().getPlacements().size(), is(1 + vm.getAttachedDisks().size())); assertThat(resource.getPlacement_list().getPlacements().get(0).getType(), is(ResourcePlacementType.VM)); assertThat(resource.getPlacement_list().getPlacements().get(1).getType(), is(ResourcePlacementType.DISK)); }
@Test public void testSuccessfulVmExecutionWithEphemeralDiskAttachedAndDatastoreAffinity() throws Exception { List<LocalityEntity> affinities = new ArrayList<>(); LocalityEntity localityEntity = new LocalityEntity(); localityEntity.setResourceId("datastore-id"); localityEntity.setKind("datastore"); affinities.add(localityEntity); vm.setAffinities(affinities); List<QuotaLineItem> quotaLineItems = new ArrayList<>(); quotaLineItems.add(new QuotaLineItem("ephemeral-disk.cost", "10000.0", com.vmware.photon.controller.flavors.gen.QuotaUnit.COUNT)); quotaLineItems.add(new QuotaLineItem("ephemeral-disk.capacity", "0.0", com.vmware.photon.controller.flavors.gen.QuotaUnit.GB)); quotaLineItems.add(new QuotaLineItem("storage.SHARED_VMFS", "1.0", com.vmware.photon.controller.flavors.gen.QuotaUnit.COUNT)); Flavor expectedDiskFlavor = new Flavor(); expectedDiskFlavor.setName("ephemeral-disk-10000"); expectedDiskFlavor.setCost(quotaLineItems); attachEphemeralDisk(vm); ResourceReserveStepCmd command = getVmReservationCommand(); PlacementTask placementTask = generateResourcePlacementList(); placementTask.resource.getPlacement_list().addToPlacements( generateResourcePlacement(ResourcePlacementType.VM, "vm-id")); placementTask.resource.getPlacement_list().addToPlacements( generateResourcePlacement(ResourcePlacementType.DISK, "disk-id")); Operation placementOperation = new Operation().setBody(placementTask); when(photonControllerXenonRestClient.post(any(), any(), anyLong())).thenReturn(placementOperation); when(hostClient.reserve(any(Resource.class), eq(SUCCESSFUL_GENERATION))).thenReturn(SUCCESSFUL_RESERVE_RESPONSE); command.execute(); verify(photonControllerXenonRestClient).post(any(), placementTaskCaptor.capture(), anyLong()); Resource resource = placementTaskCaptor.getValue().resource; assertThat(resource.getVm().isSetResource_constraints(), is(true)); assertThat(resource.getVm().getDisks().size(), is(vm.getAttachedDisks().size())); assertThat(resource.getVm().getDisks().get(0).getId(), is("disk1")); assertThat(resource.getVm().getDisks().get(0).getFlavor_info(), is(expectedDiskFlavor)); assertThat(resource.getVm().getDisks().get(0).isSetResource_constraints(), is(false)); assertThat(resource.getVm().getResource_constraintsSize(), is(3)); assertThat(resource.getVm().getResource_constraints().get(0).getType(), is(ResourceConstraintType.DATASTORE_TAG)); assertThat(resource.getVm().getResource_constraints().get(0).getValues().equals(ImmutableList.of("SHARED_VMFS")), is(true)); assertThat(resource.getVm().getResource_constraints().get(1).getType(), is(ResourceConstraintType.DATASTORE)); assertThat(resource.getVm().getResource_constraints().get(1).getValues().equals(ImmutableList.of("datastore-id")), is(true)); assertThat(resource.getPlacement_list().getPlacements().size(), is(1 + vm.getAttachedDisks().size())); assertThat(resource.getPlacement_list().getPlacements().get(0).getType(), is(ResourcePlacementType.VM)); assertThat(resource.getPlacement_list().getPlacements().get(1).getType(), is(ResourcePlacementType.DISK)); }
@Test(expectedExceptions = InternalException.class, expectedExceptionsMessageRegExp = "Project entity not found in the step.") public void testFailedVmExecutionNoProject() throws Throwable { ResourceReserveStepCmd command = getVmReservationCommand(false, false); command.execute(); }
@Test(expectedExceptions = InternalException.class, expectedExceptionsMessageRegExp = "Project entity in transient resource list did not match VMs project.") public void testFailedVmExecutionProjectEntityIdDoesNotMatchVmProjectId() throws Throwable { vm.setProjectId("some-other-id"); ResourceReserveStepCmd command = getVmReservationCommand(); command.execute(); }
@Test public void testSuccessfulDiskExecution() throws Exception { List<LocalityEntity> affinities = new ArrayList<>(); LocalityEntity localityEntity1 = new LocalityEntity(); localityEntity1.setResourceId("vm-1"); localityEntity1.setKind("vm"); LocalityEntity localityEntity2 = new LocalityEntity(); localityEntity2.setResourceId("vm-2"); localityEntity2.setKind("vm"); affinities.add(localityEntity1); affinities.add(localityEntity2); disk.setAffinities(affinities); ResourceReserveStepCmd command = getDiskReservationCommand(); PlacementTask placementTask = generateResourcePlacementList(); placementTask.resource.getPlacement_list().addToPlacements( generateResourcePlacement(ResourcePlacementType.DISK, "disk-id")); Operation placementOperation = new Operation().setBody(placementTask); when(photonControllerXenonRestClient.post(any(), any(), anyLong())).thenReturn(placementOperation); when(hostClient.reserve(any(Resource.class), eq(SUCCESSFUL_GENERATION))).thenReturn(SUCCESSFUL_RESERVE_RESPONSE); when(vmBackend.findDatastoreByVmId("vm-1")).thenReturn("datastore-2"); when(vmBackend.findDatastoreByVmId("vm-2")).thenReturn("datastore-2"); command.execute(); verify(photonControllerXenonRestClient).post(any(), placementTaskCaptor.capture(), anyLong()); Resource resource = placementTaskCaptor.getValue().resource; assertThat(resource.getDisks().get(0).getId(), is("disk-1")); assertThat(resource.getDisks().get(0).getResource_constraints().get(0).getType(), is(ResourceConstraintType.DATASTORE)); assertThat( resource.getDisks().get(0).getResource_constraints().get(0).getValues() .equals(ImmutableList.of("datastore-2")), is(true)); assertThat( resource.getDisks().get(0).getResource_constraints().get(1).getValues() .equals(ImmutableList.of("datastore-2")), is(true)); assertThat(resource.getDisks().get(0).getResource_constraints().get(2).getType(), is(ResourceConstraintType .DATASTORE_TAG)); assertThat(resource.getDisks().get(0).getResource_constraints().get(2).getValues().equals(ImmutableList.of( "LOCAL_VMFS")), is(true)); assertThat(resource.getPlacement_list().getPlacements().get(0).getType(), is(ResourcePlacementType.DISK)); assertThat(resource.getPlacement_list().getPlacements().get(0).getResource_id(), is("disk-id")); verify(photonControllerXenonRestClient).post(any(), placementTaskCaptor.capture(), anyLong()); verify(hostClient).reserve(resourceCaptor.capture(), eq(SUCCESSFUL_GENERATION)); assertThat(placementTaskCaptor.getValue().resource, is(resource)); assertThat(resourceCaptor.getValue(), is(resource)); }
@Test(expectedExceptions = StaleGenerationException.class) public void testFailedReservation() throws Throwable { ResourceReserveStepCmd command = getVmReservationCommand(); Operation placementOperation = new Operation().setBody(generateResourcePlacementList()); when(photonControllerXenonRestClient.post(any(), any(), anyLong())).thenReturn(placementOperation); when(hostClient.reserve(any(Resource.class), eq(SUCCESSFUL_GENERATION))) .thenThrow(new StaleGenerationException("Error")); command.execute(); }
@Test(expectedExceptions = XenonRuntimeException.class) public void testFailedPlacement() throws Throwable { ResourceReserveStepCmd command = getVmReservationCommand(); when(photonControllerXenonRestClient.post(any(), any(), anyLong())).thenThrow(new XenonRuntimeException("Error")); command.execute(); }
@Test(dataProvider = "PlaceFailureResultCodes") public void testFailedPlaceResultCodes(PlaceResultCode resultCode, Class<RuntimeException> exceptionClass) throws Throwable { PlacementTask placementTask = generateResourcePlacementList(); placementTask.resultCode = resultCode; Operation placementOperation = new Operation().setBody(placementTask); ResourceReserveStepCmd command = getVmReservationCommand(); when(photonControllerXenonRestClient.post(any(), any(), anyLong())).thenReturn(placementOperation); try { command.execute(); } catch (Exception e) { assertTrue(e.getClass().equals(exceptionClass)); } }
@Test public void testReservationFailedOnFirstTry() throws Throwable { ResourceReserveStepCmd command = getVmReservationCommand(); Operation placementOperation = new Operation().setBody(generateResourcePlacementList()); when(photonControllerXenonRestClient.post(any(), any(), anyLong())).thenReturn(placementOperation); when(hostClient.reserve(any(Resource.class), eq(SUCCESSFUL_GENERATION))) .thenThrow(new StaleGenerationException("Error")) .thenReturn(SUCCESSFUL_RESERVE_RESPONSE); command.execute(); verify(photonControllerXenonRestClient, times(2)).post(any(), any(), anyLong()); verify(hostClient, times(2)).reserve(any(Resource.class), eq(SUCCESSFUL_GENERATION)); }