@Test
  public void testUpdateSettings() throws Throwable {
    ImageEntity imageEntity = new ImageEntity();
    imageEntity.setName("image-name");
    imageEntity.setSize(1000L);
    imageEntity.setState(ImageState.READY);

    imageDao.create(imageEntity);
    String imageId = imageEntity.getId();

    Map<String, String> imageSettings = new HashMap<>();
    imageSettings.put("property-1", "value-1");
    imageSettings.put("property-2", null);

    imageBackend.updateSettings(imageEntity, imageSettings);

    List<ImageSettingsEntity> imageSettingsEntityList = imageSettingsDao.listAll();
    assertThat(imageSettingsEntityList.size(), is(2));

    ImageSettingsEntity settings1 = imageSettingsEntityList.get(0);
    assertThat(settings1.getImage().getId(), is(imageId));
    assertThat(settings1.getName(), is("property-1"));
    assertThat(settings1.getDefaultValue(), is("value-1"));

    ImageSettingsEntity settings2 = imageSettingsEntityList.get(1);
    assertThat(settings2.getImage().getId(), is(imageId));
    assertThat(settings2.getName(), is("property-2"));
    assertThat(settings2.getDefaultValue(), is(""));

    assertThat(imageDao.listAll().size(), is(1));
    assertThat(imageDao.listAll().get(0).getImageSettings().size(), is(2));
  }
 @Test(expectedExceptions = InvalidImageStateException.class)
 public void testNullImageSizeThrowsInvalidImageStateException() throws Throwable {
   AttachedDiskCreateSpec disk = new AttachedDiskCreateSpec();
   disk.setBootDisk(true);
   ImageEntity image = new ImageEntity();
   image.setSize(null);
   List<Throwable> warnings = new ArrayList<>();
   VmDcpBackend.updateBootDiskCapacity(Arrays.asList(disk), image, warnings);
 }
  @Test(expectedExceptions = ConcurrentTaskException.class)
  public void testDeletingAnUploadingImage() throws Throwable {
    TaskEntity task =
        imageBackend.prepareImageUpload(inputStream, "image-name", ImageReplicationType.ON_DEMAND);
    StepEntity step = task.getSteps().get(0);
    ImageEntity image = (ImageEntity) step.getTransientResourceEntities().get(0);

    imageBackend.prepareImageDelete(image.getId());
  }
  @Test(expectedExceptions = InvalidImageStateException.class)
  public void testPrepareImageDeleteInPendingDelete() throws Throwable {
    ImageEntity imageInDb = new ImageEntity();
    imageInDb.setName("image-0");
    imageInDb.setState(ImageState.PENDING_DELETE);
    imageInDb.setSize(1000L);

    imageDao.create(imageInDb);
    imageBackend.prepareImageDelete(imageInDb.getId());
  }
  @Test
  public void testPrepareImageDelete() throws Throwable {
    ImageEntity imageInDb = new ImageEntity();
    imageInDb.setName("image-0");
    imageInDb.setState(ImageState.READY);
    imageInDb.setSize(1000L);

    imageDao.create(imageInDb);
    TaskEntity taskDelete = imageBackend.prepareImageDelete(imageInDb.getId());
    assertThat(taskDelete.getSteps().size(), is(2));
    assertThat(taskDelete.getSteps().get(0).getOperation(), is(Operation.DELETE_IMAGE));
    assertThat(taskDelete.getSteps().get(1).getOperation(), is(Operation.DELETE_IMAGE_REPLICAS));
  }
  @Test(dataProvider = "ImageFileNames")
  public void testPrepareImageUploadImageFileNames(String imageFileName) throws ExternalException {
    TaskEntity task =
        imageBackend.prepareImageUpload(inputStream, imageFileName, ImageReplicationType.ON_DEMAND);
    assertThat(task.getSteps().size(), is(1));

    StepEntity step = task.getSteps().get(0);
    assertThat(step.getTransientResourceEntities().size(), is(1));
    assertThat(step.getOperation(), is(Operation.UPLOAD_IMAGE));
    ImageEntity image = (ImageEntity) step.getTransientResourceEntities().get(0);
    assertThat(image.getState(), is(ImageState.CREATING));
    assertThat(image.getName(), is(imageName));
  }
  @Test
  public void testPrepareImageUploadOnDemand() throws ExternalException {
    TaskEntity task =
        imageBackend.prepareImageUpload(inputStream, "image-name", ImageReplicationType.ON_DEMAND);
    assertThat(task.getSteps().size(), is(1));

    StepEntity step = task.getSteps().get(0);
    assertThat(step.getTransientResourceEntities().size(), is(1));
    assertThat(step.getOperation(), is(Operation.UPLOAD_IMAGE));
    ImageEntity image = (ImageEntity) step.getTransientResourceEntities().get(0);
    assertThat(image.getName(), is("image-name"));
    assertThat(image.getState(), is(ImageState.CREATING));
    assertThat(image.getReplicationType(), is(ImageReplicationType.ON_DEMAND));
    assertThat(
        (InputStream) step.getTransientResource(ImageUploadStepCmd.INPUT_STREAM), is(inputStream));
  }
  @Test
  public void testDeriveImage() throws Throwable {
    ImageCreateSpec imageCreateSpec = new ImageCreateSpec();
    imageCreateSpec.setName("i1");
    imageCreateSpec.setReplicationType(ImageReplicationType.EAGER);

    ImageEntity vmImage =
        entityFactory.createImage(
            "image1", ImageState.READY, ImageReplicationType.EAGER, 100L, "n1", "v1", "n2", "v2");

    flushSession();

    String imageId = imageBackend.deriveImage(imageCreateSpec, vmImage).getId();

    flushSession();

    ImageEntity image = imageBackend.findById(imageId);
    assertThat(image.getName(), is(imageCreateSpec.getName()));
    assertThat(image.getReplicationType(), is(imageCreateSpec.getReplicationType()));
    assertThat(image.getState(), is(ImageState.CREATING));
    assertThat(image.getSize(), is(100L));
    assertThat(
        image.getImageSettingsMap(),
        is((Map<String, String>) ImmutableMap.of("n1", "v1", "n2", "v2")));
  }
  @Test
  public void testGetTasksWithGivenState() throws Exception {
    ImageEntity imageInDb = new ImageEntity();
    imageInDb.setName("image-0");
    imageInDb.setState(ImageState.READY);
    imageInDb.setSize(1000L);

    imageDao.create(imageInDb);
    TaskEntity taskDelete = imageBackend.prepareImageDelete(imageInDb.getId());

    List<Task> tasks = imageBackend.getTasks(imageInDb.getId(), Optional.of("FINISHED"));

    assertThat(tasks.size(), is(0));
  }
  @Test
  public void testGetTasks() throws Exception {
    ImageEntity imageInDb = new ImageEntity();
    imageInDb.setName("image-0");
    imageInDb.setState(ImageState.READY);
    imageInDb.setSize(1000L);

    imageDao.create(imageInDb);
    TaskEntity taskDelete = imageBackend.prepareImageDelete(imageInDb.getId());

    List<Task> tasks = imageBackend.getTasks(imageInDb.getId(), Optional.<String>absent());

    assertThat(tasks.size(), is(1));
    assertThat(tasks.get(0).getState(), is("QUEUED"));
  }
    @Test(dataProvider = "vmCreateImageReplicationType")
    public void testPrepareVmCreateImage(ImageReplicationType replicationType) throws Throwable {
      ImageCreateSpec imageCreateSpec = new ImageCreateSpec();
      imageCreateSpec.setName("i1");
      imageCreateSpec.setReplicationType(replicationType);

      TaskEntity task = vmDcpBackend.prepareVmCreateImage(vmId, imageCreateSpec);

      assertThat(task, is(notNullValue()));
      assertThat(task.getState(), is(TaskEntity.State.QUEUED));
      assertThat(task.getSteps().size(), is(2));
      StepEntity step = task.getSteps().get(0);
      assertThat(
          step.getOperation(), is(com.vmware.photon.controller.api.Operation.CREATE_VM_IMAGE));
      assertThat(step.getTransientResourceEntities().size(), is(3));
      assertThat(step.getTransientResourceEntities(Vm.KIND).size(), is(1));
      assertThat(step.getTransientResourceEntities(Image.KIND).size(), is(2));

      assertThat(step.getTransientResourceEntities(Vm.KIND).get(0).getId(), is(vm.getId()));

      ImageEntity image = (ImageEntity) step.getTransientResourceEntities(ImageEntity.KIND).get(0);
      assertThat(image.getName(), is(imageCreateSpec.getName()));
      assertThat(image.getReplicationType(), is(imageCreateSpec.getReplicationType()));
      assertThat(image.getState(), is(ImageState.CREATING));
      assertThat(image.getSize(), is(createdImageState.size));
      assertThat(
          image.getImageSettingsMap(),
          is((Map<String, String>) ImmutableMap.of("n1", "v1", "n2", "v2")));

      ImageEntity vmImage =
          (ImageEntity) step.getTransientResourceEntities(ImageEntity.KIND).get(1);
      assertThat(vmImage.getId(), is(vm.getImageId()));

      step = task.getSteps().get(1);
      assertThat(
          step.getOperation(), is(com.vmware.photon.controller.api.Operation.REPLICATE_IMAGE));
    }
  @Test
  public void testTombstone() throws Throwable {
    TaskEntity task =
        imageBackend.prepareImageUpload(inputStream, "image-name", ImageReplicationType.ON_DEMAND);
    StepEntity step = task.getSteps().get(0);
    ImageEntity image = (ImageEntity) step.getTransientResourceEntities().get(0);
    assertThat(image.getState(), is(ImageState.CREATING));

    image.setState(ImageState.READY);
    flushSession();

    TenantEntity tenant = new TenantEntity();
    tenant.setName("t1");
    tenantDao.create(tenant);

    ProjectEntity project = new ProjectEntity();
    project.setTenantId(tenant.getId());
    project.setName("staging");
    projectDao.create(project);

    VmEntity vm = new VmEntity();
    vm.setName("vm-1");
    vm.setProjectId(project.getId());
    vm.setImageId(image.getId());
    vmDao.create(vm);

    flushSession();

    imageBackend.tombstone(image);
    assertThat(image.getState(), is(ImageState.PENDING_DELETE));

    vm = vmDao.findById(vm.getId()).get();
    vmDao.delete(vm);
    flushSession();

    imageBackend.tombstone(image);
    try {
      imageBackend.findById(image.getId());
      fail("Image should be deleted in database");
    } catch (ImageNotFoundException e) {
    }
  }