@Test
    public void testPrepareVmCreate() throws Throwable {
      String vmId = createdVmTaskEntity.getEntityId();
      assertThat(createdVmTaskEntity.getSteps().size(), is(2));
      assertThat(
          createdVmTaskEntity.getSteps().get(0).getOperation(),
          is(com.vmware.photon.controller.api.Operation.RESERVE_RESOURCE));
      assertThat(
          createdVmTaskEntity
              .getSteps()
              .get(0)
              .getTransientResourceEntities(ProjectEntity.KIND)
              .size(),
          is(1));
      assertThat(
          createdVmTaskEntity
              .getSteps()
              .get(0)
              .getTransientResourceEntities(ProjectEntity.KIND)
              .get(0)
              .getId(),
          is(projectId));
      assertThat(
          createdVmTaskEntity.getSteps().get(1).getOperation(),
          is(com.vmware.photon.controller.api.Operation.CREATE_VM));
      assertThat(createdVmTaskEntity.getToBeLockedEntityIds().size(), is(1));
      assertThat(createdVmTaskEntity.getToBeLockedEntityIds().get(0), is(vmId));

      VmEntity vm = vmDcpBackend.findById(vmId);
      assertThat(vm, is(notNullValue()));
      assertThat(getUsage("vm.cost"), is(1.0));
      assertThat(vm.getImageId(), is(imageId));

      assertThat(vm.getAffinities().get(0).getResourceId(), is("disk-id1"));
      assertThat(vm.getAffinities().get(0).getKind(), is("disk"));
      assertThat(vm.getAffinities().get(1).getResourceId(), is("disk-id2"));
      assertThat(vm.getAffinities().get(1).getKind(), is("disk"));

      Set<TagEntity> tags = vm.getTags();
      assertThat(tags.size(), is(2));
      TagEntity tag1 = new TagEntity();
      tag1.setValue("value1");
      TagEntity tag2 = new TagEntity();
      tag2.setValue("value2");
      assertTrue(tags.contains(tag1));
      assertTrue(tags.contains(tag2));

      assertThat(vmCreateSpec.getNetworks().equals(vm.getNetworks()), is(true));
    }
  /**
   * This method creates a VmCreateSpec object for creating an VM.
   *
   * @param vmState Supplies the state object of the VmService entity.
   * @param hostState Supplies the state object of the HostService entity.
   * @param imageState Supplies the state object of the ImageService entity.
   * @param vmFlavorState Supplies the state object of the FlavorService entity.
   * @param diskFlavorState Supplies the state object of the FlavorService entity.
   * @return Returns the VmCreateSpec object.
   */
  private VmCreateSpec composeVmCreateSpec(
      final VmService.State vmState,
      final HostService.State hostState,
      final ImageService.State imageState,
      final FlavorService.State vmFlavorState,
      final FlavorService.State diskFlavorState) {

    // Craft the VM creation spec.
    VmCreateSpec spec = new VmCreateSpec();
    spec.setName(vmState.name);
    spec.setFlavor(vmFlavorState.name);

    spec.setSourceImageId(ServiceUtils.getIDFromDocumentSelfLink(imageState.documentSelfLink));

    List<AttachedDiskCreateSpec> attachedDisks = new ArrayList<>();

    AttachedDiskCreateSpec bootDisk = new AttachedDiskCreateSpec();
    bootDisk.setName(vmState.name + "-bootdisk");
    bootDisk.setBootDisk(true);
    bootDisk.setFlavor(diskFlavorState.name);
    bootDisk.setKind(EphemeralDisk.KIND);
    attachedDisks.add(bootDisk);

    spec.setAttachedDisks(attachedDisks);

    Map<String, String> environment = new HashMap<>();
    spec.setEnvironment(environment);

    List<LocalitySpec> affinities = new ArrayList<>();

    LocalitySpec hostSpec = new LocalitySpec();
    hostSpec.setId(hostState.hostAddress);
    hostSpec.setKind("host");
    affinities.add(hostSpec);

    LocalitySpec datastoreSpec = new LocalitySpec();
    datastoreSpec.setId(
        hostState.metadata.get(HostService.State.METADATA_KEY_NAME_MANAGEMENT_DATASTORE));
    datastoreSpec.setKind("datastore");
    affinities.add(datastoreSpec);

    LocalitySpec portGroupSpec = new LocalitySpec();
    portGroupSpec.setId(
        hostState.metadata.get(HostService.State.METADATA_KEY_NAME_MANAGEMENT_PORTGROUP));
    portGroupSpec.setKind("portGroup");
    affinities.add(portGroupSpec);

    spec.setAffinities(affinities);

    return spec;
  }
    @Test
    public void testAddTagWhenOriginalTagIsNull() throws Throwable {
      // overwriting the vmCreateSpec tags to empty from non-empty
      vmCreateSpec.setTags(null);

      createdVmTaskEntity = vmDcpBackend.prepareVmCreate(projectId, vmCreateSpec);
      vmId = createdVmTaskEntity.getEntityId();
      entityLockDcpBackend.clearTaskLocks(createdVmTaskEntity);
      vm = vmDcpBackend.findById(vmId);
      int originalSize = vm.getTags().size();
      Tag tag = new Tag("namespace:predicate=value");
      vmDcpBackend.addTag(vm.getId(), tag);
      vm = vmDcpBackend.findById(vm.getId());
      assertThat(vm.getTags().size(), is(1));
      List<String> tagValues =
          vm.getTags().stream().map(t -> t.getValue()).collect(Collectors.toList());
      assertTrue(tagValues.contains(tag.getValue()));
    }
  private static void commonVmAndImageSetup(
      VmDcpBackend vmDcpBackend, NetworkDcpBackend networkDcpBackend) throws Throwable {
    AttachedDiskCreateSpec disk1 =
        new AttachedDiskCreateSpecBuilder().name("disk1").flavor("core-100").bootDisk(true).build();
    AttachedDiskCreateSpec disk2 =
        new AttachedDiskCreateSpecBuilder().name("disk2").flavor("core-200").capacityGb(10).build();

    List<LocalitySpec> affinities = new ArrayList<>();
    affinities.add(new LocalitySpec("disk-id1", "disk"));
    affinities.add(new LocalitySpec("disk-id2", "disk"));

    ImageService.State imageServiceState = new ImageService.State();
    imageServiceState.name = "image-1";
    imageServiceState.state = ImageState.READY;
    imageServiceState.size = 1024L * 1024L;
    imageServiceState.replicationType = ImageReplicationType.EAGER;
    imageServiceState.imageSettings = new ArrayList<>();
    ImageService.State.ImageSetting imageSetting = new ImageService.State.ImageSetting();
    imageSetting.name = "n1";
    imageSetting.defaultValue = "v1";
    imageServiceState.imageSettings.add(imageSetting);
    imageSetting = new ImageService.State.ImageSetting();
    imageSetting.name = "n2";
    imageSetting.defaultValue = "v2";
    imageServiceState.imageSettings.add(imageSetting);

    Operation result = dcpClient.post(ImageServiceFactory.SELF_LINK, imageServiceState);

    createdImageState = result.getBody(ImageService.State.class);

    imageId = ServiceUtils.getIDFromDocumentSelfLink(createdImageState.documentSelfLink);

    vmCreateSpec = new VmCreateSpec();
    vmCreateSpec.setName("test-vm");
    vmCreateSpec.setFlavor("core-100");
    vmCreateSpec.setSourceImageId(imageId);
    vmCreateSpec.setAttachedDisks(ImmutableList.of(disk1, disk2));
    vmCreateSpec.setAffinities(affinities);
    vmCreateSpec.setTags(ImmutableSet.of("value1", "value2"));

    List<String> networks = new ArrayList<>();

    List<String> portGroups = new ArrayList<>();
    portGroups.add("p1");
    NetworkCreateSpec networkCreateSpec = new NetworkCreateSpec();
    networkCreateSpec.setName("n1");
    networkCreateSpec.setPortGroups(portGroups);
    TaskEntity networkTask = networkDcpBackend.createNetwork(networkCreateSpec);
    networks.add(networkTask.getEntityId());

    portGroups = new ArrayList<>();
    portGroups.add("p2");
    networkCreateSpec.setName("n2");
    networkCreateSpec.setPortGroups(portGroups);
    networkTask = networkDcpBackend.createNetwork(networkCreateSpec);
    networks.add(networkTask.getEntityId());

    vmCreateSpec.setNetworks(networks);

    createdVmTaskEntity = vmDcpBackend.prepareVmCreate(projectId, vmCreateSpec);
  }