/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE file at the root of the source * tree and available online at * * https://github.com/keeps/roda */ package org.roda.core.common.monitor; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertTrue; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Optional; import java.util.Random; import org.apache.commons.io.FileUtils; import org.roda.core.RodaCoreFactory; import org.roda.core.TestsHelper; import org.roda.core.data.common.RodaConstants; import org.roda.core.data.v2.index.IndexResult; import org.roda.core.data.v2.index.sublist.Sublist; import org.roda.core.data.v2.ip.TransferredResource; import org.roda.core.index.IndexService; import org.roda.core.storage.fs.FSUtils; import org.roda.core.util.IdUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @Test(groups = {RodaConstants.TEST_GROUP_ALL, RodaConstants.TEST_GROUP_TRAVIS}) public class MonitorIndexTest { private static final Logger LOGGER = LoggerFactory.getLogger(MonitorIndexTest.class); private static Path basePath; private static IndexService index; private static int fileCounter; @BeforeClass public static void setUp() throws Exception { basePath = TestsHelper.createBaseTempDir(MonitorIndexTest.class, true); boolean deploySolr = true; boolean deployLdap = false; boolean deployFolderMonitor = true; boolean deployOrchestrator = true; boolean deployPluginManager = true; boolean deployDefaultResources = false; RodaCoreFactory.instantiateTest(deploySolr, deployLdap, deployFolderMonitor, deployOrchestrator, deployPluginManager, deployDefaultResources); index = RodaCoreFactory.getIndexService(); fileCounter = 0; LOGGER.info("Running folder monitor tests under storage {}", basePath); } @AfterClass public static void tearDown() throws Exception { RodaCoreFactory.shutdown(); FSUtils.deletePath(basePath); } @Test public void testUpdate() throws Exception { String transferredResourcesFolder = RodaCoreFactory.getRodaConfiguration().getString("transferredResources.folder", RodaConstants.CORE_TRANSFERREDRESOURCE_FOLDER); Path sips = RodaCoreFactory.getDataPath().resolve(transferredResourcesFolder); TransferredResourcesScanner monitor = new TransferredResourcesScanner(sips, index); populate(sips); monitor.updateTransferredResources(Optional.empty(), true); int folderToIndex = -1; IndexResult<TransferredResource> transferredResources = index.find(TransferredResource.class, null, null, new Sublist(0, fileCounter), new ArrayList<>()); int result1 = transferredResources.getResults().size(); assertTrue(result1 > 0); for (int i = 0; i < result1; i++) { TransferredResource tr = transferredResources.getResults().get(i); if (!tr.isFile()) { folderToIndex = i; } } TransferredResource resource = transferredResources.getResults().get(folderToIndex); Path parent = Paths.get(resource.getFullPath()); Path p = Files.createFile(parent.resolve(IdUtils.createUUID() + ".txt")); Files.write(p, "NUNCAMAISACABA".getBytes()); monitor.updateTransferredResources(Optional.of(resource.getRelativePath()), true); IndexResult<TransferredResource> transferredResources2 = index.find(TransferredResource.class, null, null, new Sublist(0, fileCounter + 1), new ArrayList<>()); int result2 = transferredResources2.getResults().size(); assertTrue(result2 == result1 + 1); } @Test public void testRemoveFile() throws Exception { String transferredResourcesFolder = RodaCoreFactory.getRodaConfiguration().getString("transferredResources.folder", RodaConstants.CORE_TRANSFERREDRESOURCE_FOLDER); Path sips = RodaCoreFactory.getDataPath().resolve(transferredResourcesFolder); TransferredResourcesScanner monitor = new TransferredResourcesScanner(sips, index); populate(sips); monitor.updateTransferredResources(Optional.empty(), true); int toRemove1 = -1; int toRemove2 = -1; IndexResult<TransferredResource> transferredResources = index.find(TransferredResource.class, null, null, new Sublist(0, fileCounter), new ArrayList<>()); int resultBeforeRemoves = transferredResources.getResults().size(); for (int i = 0; i < resultBeforeRemoves; i++) { TransferredResource tr = transferredResources.getResults().get(i); if (tr.isFile() && toRemove1 == -1) { toRemove1 = i; continue; } if (tr.isFile() && toRemove1 != -1) { toRemove2 = i; } } TransferredResource resource = transferredResources.getResults().get(toRemove1); File firstFileRemoved = new File(resource.getFullPath()); firstFileRemoved.delete(); TransferredResource resource2 = transferredResources.getResults().get(toRemove2); File secondFileRemoved = new File(resource2.getFullPath()); secondFileRemoved.delete(); monitor.updateTransferredResources(Optional.empty(), true); IndexResult<TransferredResource> transferredResources2 = index.find(TransferredResource.class, null, null, new Sublist(0, fileCounter), new ArrayList<>()); int resultAfterRemoves = transferredResources2.getResults().size(); assertEquals(resultBeforeRemoves, resultAfterRemoves + 2); } @Test public void testRemoveFolder() throws Exception { String transferredResourcesFolder = RodaCoreFactory.getRodaConfiguration().getString("transferredResources.folder", RodaConstants.CORE_TRANSFERREDRESOURCE_FOLDER); Path sips = RodaCoreFactory.getDataPath().resolve(transferredResourcesFolder); TransferredResourcesScanner monitor = new TransferredResourcesScanner(sips, index); populate(sips); monitor.updateTransferredResources(Optional.empty(), true); int toRemove = -1; IndexResult<TransferredResource> transferredResources = index.find(TransferredResource.class, null, null, new Sublist(0, fileCounter), new ArrayList<>()); int resultBeforeRemoves = transferredResources.getResults().size(); for (int i = 0; i < resultBeforeRemoves; i++) { TransferredResource tr = transferredResources.getResults().get(i); if (!tr.isFile() && toRemove == -1) { toRemove = i; } } TransferredResource resource = transferredResources.getResults().get(toRemove); FileUtils.deleteDirectory(new File(resource.getFullPath())); monitor.updateTransferredResources(Optional.empty(), true); IndexResult<TransferredResource> transferredResources2 = index.find(TransferredResource.class, null, null, new Sublist(0, fileCounter), new ArrayList<>()); int resultAfterRemoves = transferredResources2.getResults().size(); assertTrue(resultBeforeRemoves > resultAfterRemoves); } @Test public void testRemoveFileOnSpecificFolder() throws Exception { String transferredResourcesFolder = RodaCoreFactory.getRodaConfiguration().getString("transferredResources.folder", RodaConstants.CORE_TRANSFERREDRESOURCE_FOLDER); Path sips = RodaCoreFactory.getDataPath().resolve(transferredResourcesFolder); TransferredResourcesScanner monitor = new TransferredResourcesScanner(sips, index); populate(sips); monitor.updateTransferredResources(Optional.empty(), true); int toRemove = -1; String folder = ""; int folderIndex = -1; IndexResult<TransferredResource> transferredResources = index.find(TransferredResource.class, null, null, new Sublist(0, fileCounter), new ArrayList<>()); int resultBeforeRemoves = transferredResources.getResults().size(); for (int i = 0; i < resultBeforeRemoves; i++) { TransferredResource tr = transferredResources.getResults().get(i); if (!tr.isFile() && folderIndex == -1) { folder = tr.getRelativePath(); folderIndex = i; break; } } for (int i = 0; i < resultBeforeRemoves; i++) { TransferredResource tr = transferredResources.getResults().get(i); if (tr.isFile() && toRemove == -1 && tr.getAncestorsPaths().contains(folder)) { toRemove = i; } } TransferredResource resource = transferredResources.getResults().get(toRemove); File fileRemoved = new File(resource.getFullPath()); fileRemoved.delete(); TransferredResource transferredResourceFolder = transferredResources.getResults().get(folderIndex); monitor.updateTransferredResources(Optional.of(transferredResourceFolder.getRelativePath()), true); IndexResult<TransferredResource> transferredResources2 = index.find(TransferredResource.class, null, null, new Sublist(0, fileCounter), new ArrayList<>()); int resultAfterRemoves = transferredResources2.getResults().size(); assertEquals(resultBeforeRemoves, resultAfterRemoves + 1); } private static void populate(Path basePath) throws IOException { Random randomno = new Random(); int numberOfItemsByLevel = nextIntInRange(2, 3, randomno); int numberOfLevels = nextIntInRange(2, 3, randomno); populate(basePath, numberOfItemsByLevel, numberOfLevels, 0, randomno); } private static void populate(Path path, int numberOfItemsByLevel, int numberOfLevels, int currentLevel, Random randomno) throws IOException { currentLevel++; for (int i = 0; i < numberOfItemsByLevel; i++) { Path p; if (i % 2 == 0) { if (currentLevel > 1) { p = Files.createFile(path.resolve(IdUtils.createUUID() + ".txt")); Files.write(p, "NUNCAMAISACABA".getBytes()); fileCounter++; } } else { p = Files.createDirectory(path.resolve(IdUtils.createUUID())); fileCounter++; if (currentLevel <= numberOfLevels) { populate(p, numberOfItemsByLevel, numberOfLevels, currentLevel, randomno); } else { if (currentLevel > 1) { for (int j = 0; j < numberOfItemsByLevel; j++) { Path temp = Files.createFile(p.resolve(IdUtils.createUUID() + ".txt")); Files.write(temp, "NUNCAMAISACABA".getBytes()); fileCounter++; } } } } } } static int nextIntInRange(int min, int max, Random rng) { if (min > max) { throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "]."); } int diff = max - min; if (diff >= 0 && diff != Integer.MAX_VALUE) { return min + rng.nextInt(diff + 1); } int i; do { i = rng.nextInt(); } while (i < min || i > max); return i; } }