/*
* Copyright 2013-2015 University of Dundee. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package integration.delete;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import integration.AbstractServerTest;
import omero.RType;
import omero.ServerError;
import omero.api.IRenderingSettingsPrx;
import omero.cmd.Delete2;
import omero.cmd.SkipHead;
import omero.gateway.util.Requests;
import omero.model.Dataset;
import omero.model.DatasetImageLink;
import omero.model.DatasetImageLinkI;
import omero.model.Fileset;
import omero.model.FilesetI;
import omero.model.Image;
import omero.sys.Parameters;
import omero.sys.ParametersI;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.Assert;
/**
* Tests for deleting hierarchies and the effects that that should have under
* double- and multiple-linking.
*
* @since 5.-
*/
@Test(groups = { "delete", "integration"})
public class MultiImageFilesetDeleteTest extends AbstractServerTest {
/**
* Test the delete of datasets hosting images composing a MIF.
* @throws Exception Thrown if an error occurred.
*/
@Test
public void testDeleteDatasetWithSharedImageFromMIF()
throws Exception
{
//first create a project
Image i1 = (Image) iUpdate.saveAndReturnObject(
mmFactory.simpleImage());
Image i2 = (Image) iUpdate.saveAndReturnObject(
mmFactory.simpleImage());
Fileset fileset = new FilesetI();
fileset.setTemplatePrefix(omero.rtypes.rstring("fake"));
fileset.addImage(i1);
fileset.addImage(i2);
fileset = (Fileset) iUpdate.saveAndReturnObject(fileset);
Assert.assertEquals(fileset.copyImages().size(), 2);
Dataset d1 = (Dataset) iUpdate.saveAndReturnObject(
mmFactory.simpleDatasetData().asIObject());
Dataset d2 = (Dataset) iUpdate.saveAndReturnObject(
mmFactory.simpleDatasetData().asIObject());
DatasetImageLink link = new DatasetImageLinkI();
link.setChild((Image) i1.proxy());
link.setParent((Dataset) d1.proxy());
iUpdate.saveAndReturnObject(link);
link = new DatasetImageLinkI();
link.setChild((Image) i2.proxy());
link.setParent((Dataset) d2.proxy());
iUpdate.saveAndReturnObject(link);
Delete2 dc = Requests.delete("Dataset", Arrays.asList(d1.getId().getValue(), d2.getId().getValue()));
doChange(dc);
assertDoesNotExist(d1);
assertDoesNotExist(d2);
assertDoesNotExist(fileset);
assertDoesNotExist(i1);
assertDoesNotExist(i2);
}
/* for anchored delete test cases */
private enum Target {IMAGES_OF_FILESET, RENDERING_SETTINGS_OF_FILESET, RENDERING_SETTINGS_OF_IMAGE, NONSENSE_OF_IMAGE};
/**
* Asserts that a given image has some rendering settings.
* @param imageId the ID of an image
* @param hasSettings if the image is expected to have some rendering settings
* @throws ServerError unexpected
*/
private void assertHasRenderingDef(long imageId, boolean hasSettings) throws ServerError {
final String query = "SELECT id FROM RenderingDef WHERE pixels.image.id = :id";
final Parameters params = new ParametersI().addId(imageId);
final List<List<RType>> results = iQuery.projection(query, params);
Assert.assertEquals(results.isEmpty(), !hasSettings);
}
/**
* Test an anchored delete operation expressed using {@link SkipHead}.
* @param target the kind of object to actually delete
* @param dryRun if the deletion should be a dry run
* @throws Exception unexpected
*/
@Test(dataProvider = "anchored")
public void testAnchoredDelete(Target target, boolean dryRun) throws Exception {
/* create a fileset with two images, each of which has rendering settings */
final Image image1 = (Image) iUpdate.saveAndReturnObject(mmFactory.createImage());
final Image image2 = (Image) iUpdate.saveAndReturnObject(mmFactory.createImage());
final long image1Id = image1.getId().getValue();
final long image2Id = image2.getId().getValue();
Fileset fileset = newFileset();
fileset.addImage(image1);
fileset.addImage(image2);
fileset = (Fileset) iUpdate.saveAndReturnObject(fileset);
final long filesetId = fileset.getId().getValue();
final IRenderingSettingsPrx renderingSettingsService = factory.getRenderingSettingsService();
renderingSettingsService.setOriginalSettingsInImage(image1Id);
renderingSettingsService.setOriginalSettingsInImage(image2Id);
/* delete the images of the fileset, the rendering settings of one of the images, or nonsense */
final SkipHead skipHead;
switch (target) {
case IMAGES_OF_FILESET:
skipHead = Requests.skipHead("Fileset", filesetId, dryRun, "Image", new Delete2());
break;
case RENDERING_SETTINGS_OF_FILESET:
skipHead = Requests.skipHead("Fileset", filesetId, dryRun, "RenderingDef", new Delete2());
break;
case RENDERING_SETTINGS_OF_IMAGE:
skipHead = Requests.skipHead("Image", image1Id, dryRun, "RenderingDef", new Delete2());
break;
case NONSENSE_OF_IMAGE:
skipHead = Requests.skipHead("Image", image1Id, dryRun, "I like penguins", new Delete2());
break;
default:
skipHead = null;
Assert.fail("unexpected target for delete");
}
final boolean isExpectSuccess = target != Target.NONSENSE_OF_IMAGE;
doChange(client, factory, skipHead, isExpectSuccess);
/* check the outcome */
if (target == Target.IMAGES_OF_FILESET && !dryRun) {
/* actually deleted the fileset via its images */
} else {
/* deleted no more than rendering settings, but check exactly what */
assertExists(fileset);
assertExists(image1);
assertExists(image2);
final boolean isImage1SettingsExist, isImage2SettingsExist;
if (target == Target.NONSENSE_OF_IMAGE || dryRun) {
isImage1SettingsExist = true;
isImage2SettingsExist = true;
} else {
isImage1SettingsExist = false;
isImage2SettingsExist = target == Target.RENDERING_SETTINGS_OF_IMAGE;
}
assertHasRenderingDef(image1Id, isImage1SettingsExist);
assertHasRenderingDef(image2Id, isImage2SettingsExist);
/* delete the fileset */
final Delete2 delete = Requests.delete("Fileset", filesetId);
doChange(delete);
}
/* fileset no longer exists */
assertDoesNotExist(fileset);
assertDoesNotExist(image1);
assertDoesNotExist(image2);
}
/**
* @return a variety of test cases for anchored delete
*/
@DataProvider(name = "anchored")
public Object[][] provideAnchoredDeleteCases() {
int index = 0;
final int TARGET = index++;
final int DRY_RUN = index++;
final boolean[] booleanCases = new boolean[]{false, true};
final List<Object[]> testCases = new ArrayList<Object[]>();
for (final Target target : Target.values()) {
for (final boolean dryRun : booleanCases) {
final Object[] testCase = new Object[index];
testCase[TARGET] = target;
testCase[DRY_RUN] = dryRun;
// DEBUG: if (target == Target.IMAGES_OF_FILESET && dryRun == true)
testCases.add(testCase);
}
}
return testCases.toArray(new Object[testCases.size()][]);
}
}