Java tutorial
/* * #%L * Netarchivesuite - archive - test * %% * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, * the National Library of France and the Austrian National Library. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * <http://www.gnu.org/licenses/lgpl-2.1.html>. * #L% */ package dk.netarkivet.archive.arcrepository.bitpreservation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import javax.jms.Message; import javax.jms.MessageListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.archive.io.arc.ARCReaderFactory; import org.archive.io.arc.ARCRecord; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import dk.netarkivet.archive.ArchiveSettings; import dk.netarkivet.archive.arcrepositoryadmin.AdminData; import dk.netarkivet.archive.arcrepositoryadmin.UpdateableAdminData; import dk.netarkivet.archive.bitarchive.BitarchiveAdmin; import dk.netarkivet.archive.bitarchive.distribute.BatchMessage; import dk.netarkivet.archive.bitarchive.distribute.BatchReplyMessage; import dk.netarkivet.common.CommonSettings; import dk.netarkivet.common.distribute.Channels; import dk.netarkivet.common.distribute.ChannelsTesterHelper; import dk.netarkivet.common.distribute.JMSConnection; import dk.netarkivet.common.distribute.JMSConnectionFactory; import dk.netarkivet.common.distribute.RemoteFile; import dk.netarkivet.common.distribute.RemoteFileFactory; import dk.netarkivet.common.distribute.StringRemoteFile; import dk.netarkivet.common.distribute.TestRemoteFile; import dk.netarkivet.common.distribute.arcrepository.ArcRepositoryClient; import dk.netarkivet.common.distribute.arcrepository.ArcRepositoryClientFactory; import dk.netarkivet.common.distribute.arcrepository.BatchStatus; import dk.netarkivet.common.distribute.arcrepository.BitarchiveRecord; import dk.netarkivet.common.distribute.arcrepository.Replica; import dk.netarkivet.common.distribute.arcrepository.ReplicaStoreState; import dk.netarkivet.common.exceptions.ArgumentNotValid; import dk.netarkivet.common.exceptions.IOFailure; import dk.netarkivet.common.exceptions.NotImplementedException; import dk.netarkivet.common.exceptions.PermissionDenied; import dk.netarkivet.common.utils.FileUtils; import dk.netarkivet.common.utils.KeyValuePair; import dk.netarkivet.common.utils.Settings; import dk.netarkivet.common.utils.batch.BatchLocalFiles; import dk.netarkivet.common.utils.batch.ChecksumJob; import dk.netarkivet.common.utils.batch.FileBatchJob; import dk.netarkivet.common.utils.batch.FileListJob; import dk.netarkivet.testutils.LogbackRecorder; import dk.netarkivet.testutils.ReflectUtils; import dk.netarkivet.testutils.preconfigured.MockupJMS; import dk.netarkivet.testutils.preconfigured.MoveTestFiles; import dk.netarkivet.testutils.preconfigured.ReloadSettings; import dk.netarkivet.testutils.preconfigured.UseTestRemoteFile; /** * Unit test for the class FileBasedActiveBitPreservation. */ @SuppressWarnings({ "unused", "deprecation" }) public class FileBasedActiveBitPreservationTester { private Log log = LogFactory.getLog(getClass().getName()); private UseTestRemoteFile rf = new UseTestRemoteFile(); private ReloadSettings rs = new ReloadSettings(); private MockupJMS mj = new MockupJMS(); private MoveTestFiles mtf = new MoveTestFiles(TestInfo.ORIGINALS_DIR, TestInfo.WORKING_DIR); FileBasedActiveBitPreservation abp; private static final Replica ONE = Replica.getReplicaFromId(TestInfo.REPLICA_ID_ONE); private static final Replica TWO = Replica.getReplicaFromId(TestInfo.REPLICA_ID_TWO); private static final Replica THREE = Replica.getReplicaFromId("THREE"); @Before public void setUp() throws Exception { rs.setUp(); ChannelsTesterHelper.resetChannels(); mtf.setUp(); mj.setUp(); rf.setUp(); Settings.set(CommonSettings.ARC_REPOSITORY_CLIENT, MockupArcRepositoryClient.class.getName()); Settings.set(ArchiveSettings.DIRS_ARCREPOSITORY_ADMIN, TestInfo.WORKING_DIR.getAbsolutePath()); Settings.set(ArchiveSettings.DIR_ARCREPOSITORY_BITPRESERVATION, TestInfo.WORKING_DIR.getAbsolutePath()); } @After public void tearDown() throws Exception { // Make sure admin data instance is closed. UpdateableAdminData.getInstance().close(); // Make sure the ArcRepositoryClient is closed. ArcRepositoryClientFactory.getPreservationInstance().close(); // Close the ActiveBitPreservation if it was instantiated. if (abp != null) { abp.close(); } MockupArcRepositoryClient.instance = null; rf.tearDown(); mtf.tearDown(); mj.tearDown(); rs.tearDown(); } /** * Tests the normal behaviour of findChangedFiles. * <p> * This should check: * <p> * That the two files are created with the expected output. What happens if the expected input isn't there. * * @throws IOException */ @Test @Ignore("FIXME") // FIXME: test temporarily disabled public void testFindChangedFiles() throws IOException { // We check the following four cases: // integrity1 is marked as failed, but is correct in bitarchives // integrity2 is missing from admin data, but exists in bitarchives // integrity7 is marked as completed, but is not in bitarchives // FIXME: integrity7 is discovered nowhere! // integrity11 has no state and wrong checksum // integrity12 is marked as completed but has wrong checksum // Set up admin data UpdateableAdminData ad = UpdateableAdminData.getUpdateableInstance(); ad.addEntry("integrity1.ARC", null, "708afc1b7aebc12f7e65ecf1be054d23"); ad.addEntry("integrity7.ARC", null, "44ddf7a30f7fabb838e43a8505f927c2"); ad.addEntry("integrity11.ARC", null, "4236be8e67e0c10da2902764ff4b954a"); ad.addEntry("integrity12.ARC", null, "4236be8e67e0c10da2902764ff4b954a"); Replica replicaTwo = Replica.getReplicaFromId("TWO"); ad.setState("integrity1.ARC", replicaTwo.getIdentificationChannel().getName(), ReplicaStoreState.UPLOAD_FAILED); ad.setState("integrity7.ARC", replicaTwo.getIdentificationChannel().getName(), ReplicaStoreState.UPLOAD_COMPLETED); ad.setState("integrity12.ARC", replicaTwo.getIdentificationChannel().getName(), ReplicaStoreState.UPLOAD_COMPLETED); abp = FileBasedActiveBitPreservation.getInstance(); abp = FileBasedActiveBitPreservation.getInstance(); abp.findChangedFiles(replicaTwo); // Check that wrong-files file exists and has correct content List<String> expectedContent = Arrays.asList("integrity11.ARC", "integrity12.ARC"); File wrong = WorkFiles.getFile(replicaTwo, WorkFiles.WRONG_FILES); List<String> actualContent = FileUtils.readListFromFile(wrong); Collections.sort(actualContent); assertEquals("Wrong state list should be as expected.\n" + "Expected " + expectedContent + " but was " + actualContent, expectedContent, actualContent); // Check that wrong-state file exists and has correct content List<String> expectedContent2 = Arrays.asList("integrity1.ARC"); List<String> actualContent2 = WorkFiles.getLines(replicaTwo, WorkFiles.WRONG_STATES); Collections.sort(actualContent2); assertEquals("Wrong state list should be as expected.\n" + "Expected " + expectedContent2 + " but was " + actualContent2, expectedContent2, actualContent2); abp.close(); } /** * Tests the normal behaviour of findMissingFiles. * * @throws IOException */ @Test public void testFindMissingFiles() throws IOException { File dir = new File(TestInfo.WORKING_DIR, "referenceFiles"); /* Set it up so fileListJob will return expected results. */ File listingDir = new File(new File(dir, "filelistOutput"), "unsorted.txt"); MockupArcRepositoryClient.getInstance().overrideBatch = new BatchStatus("AP1", Collections.<File>emptySet(), 5, RemoteFileFactory.getMovefileInstance(listingDir), new ArrayList<FileBatchJob.ExceptionOccurrence>(0)); Replica replicaOne = Replica.getReplicaFromId("ONE"); // Run method. FileBasedActiveBitPreservation abp = FileBasedActiveBitPreservation.getInstance(); abp.findMissingFiles(replicaOne); // Clean up MockupArcRepositoryClient.getInstance().overrideBatch = null; // Check that missing-files file exists and has correct content File missing = WorkFiles.getFile(replicaOne, WorkFiles.MISSING_FILES_BA); String[] expectedContent = { "g.arc", "h.arc" }; String[] actualContent = FileUtils.readFile(missing).split("\n"); for (int i = 0; i < actualContent.length; i++) { actualContent[i] = actualContent[i].trim(); } Arrays.sort(expectedContent); Arrays.sort(actualContent); // Compare sorted arrays assertTrue( "Missing files list should be as expected." + "\nExpected " + Arrays.toString(expectedContent) + " but was " + Arrays.toString(actualContent), Arrays.equals(expectedContent, actualContent)); abp.close(); } /** * Tests that the correct setup is done when running a checksum batch job and that the checksum batch job generates * the expected output. * <p> * Tests requirements of Assignment 3.1.2 * * @throws FileNotFoundException * @throws IOException */ @Test public void testRunChecksumJob() throws FileNotFoundException, IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method runChecksumJob = ReflectUtils.getPrivateMethod(FileBasedActiveBitPreservation.class, "runChecksumJob", Replica.class); FileBasedActiveBitPreservation acp = FileBasedActiveBitPreservation.getInstance(); // Test valid parameters: try { runChecksumJob.invoke(acp, (Replica) null); fail("Argument 'replica' must not be null"); } catch (InvocationTargetException e) { assertEquals("Should have thrown ANV", ArgumentNotValid.class, e.getCause().getClass()); // expected } Replica replica = Replica.getReplicaFromId(TestInfo.REPLICA_ID_ONE); runChecksumJob.invoke(acp, replica); File unsortedOutput = WorkFiles.getFile(replica, WorkFiles.CHECKSUMS_ON_BA); assertTrue("No output file generated for unsorted output", unsortedOutput.exists()); /* * No longer automatically sorting when not needed File sortedOutput = new File(outputSubDir, * Constants.SORTED_OUTPUT_FILE); assertTrue("No output file generated for sorted output", * sortedOutput.exists()); */ assertEquals("Unsorted output file should have been deleted from FTP " + "server", 0, TestRemoteFile.remainingFiles().size()); /* * assertEquals("The two files containing unsorted output" + " and sorted output do not have the same size", * unsortedOutput.length(), sortedOutput.length()); * * FileInputStream fis = new FileInputStream(sortedOutput); BufferedReader in = new BufferedReader(new * InputStreamReader(fis)); String line = null; String prevArcFileName = null; while ((line = in.readLine()) != * null) { String arcFileName = line.substring(0, line.indexOf(Constants.STRING_FILENAME_SEPARATOR)); if * (prevArcFileName != null) { assertTrue("Batch output is not sorted (lexicographically) " + * "according to ARC file name", arcFileName.compareTo(prevArcFileName) > 0); } prevArcFileName = arcFileName; } * in.close(); fis.close(); */ // ChecksumJobTester tests that the correct MD5 checksums are generated. acp.close(); } @Test @Ignore("FIXME") // FIXME: test temporarily disabled public void testGetFilePreservationStatus() throws NoSuchFieldException, IllegalAccessException { FileUtils.copyFile(TestInfo.CORRECT_ADMIN_DATA, TestInfo.ADMIN_DATA); // Ensure that the admin data are read from the file AdminData.getUpdateableInstance(); abp = FileBasedActiveBitPreservation.getInstance(); FilePreservationState fps = (FilePreservationState) abp.getPreservationState(TestInfo.FILE_IN_ADMIN_DATA); assertNotNull("Should get FilePreservationStatus for existing file", fps); assertEquals("Should get FPS for correct file", TestInfo.FILE_IN_ADMIN_DATA, fps.getFilename()); fps = (FilePreservationState) abp.getPreservationState(TestInfo.FILE_NOT_IN_ADMIN_DATA); assertNull("Should get null for non-existing file", fps); } /** * Test for bug #462: Should be able to run checksum jobs in either place. */ @Test public void testRunChecksumJobElsewhere() throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Method runChecksumJob = ReflectUtils.getPrivateMethod(FileBasedActiveBitPreservation.class, "runChecksumJob", Replica.class); final FileBasedActiveBitPreservation abp = FileBasedActiveBitPreservation.getInstance(); // Make a dummy archive repository client that just drops the name // into an array. final String[] replica = new String[1]; MockupArcRepositoryClient.instance = new MockupArcRepositoryClient() { @Override public BatchStatus batch(FileBatchJob job, String replicaId, String... args) { replica[0] = replicaId; File file = new File(new File(TestInfo.WORKING_DIR, "checksums"), "unsorted.txt"); file.getParentFile().mkdirs(); try { new FileWriter(file).close(); } catch (IOException e) { throw new IOFailure("Can't make empty file " + file, e); } return new BatchStatus(replicaId, new HashSet<File>(), 0, new TestRemoteFile(file, false, false, false), job.getExceptions()); } public void close() { MockupArcRepositoryClient.instance = null; } }; // Try to run "checksumjobs" on both allowable locations runChecksumJob.invoke(abp, Replica.getReplicaFromId("ONE")); assertEquals("Checksum job should have run on ONE", "ONE", replica[0]); runChecksumJob.invoke(abp, Replica.getReplicaFromId("TWO")); assertEquals("Checksum job should have run on TWO", "TWO", replica[0]); abp.close(); } /** * Test normal behaviour of runFileListJob(): * <p> * It should pick normal or reference dir. It should generate the correct files. It should restrict itself to * specified files. It should check the number of lines. It should remove the temporary file. * <p> * Note that we don't need to test if the expected files are found, as the file scanning is done in submethods, but * it comes automatically when we check for restriction. * * @throws IOException */ @Test public void testRunFileListJob() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method runFilelistJob = ReflectUtils.getPrivateMethod(FileBasedActiveBitPreservation.class, "runFileListJob", Replica.class); FileBasedActiveBitPreservation abp = FileBasedActiveBitPreservation.getInstance(); // Check normal run final String replicaId = TestInfo.REPLICA_ID_TWO; Replica replica = Replica.getReplicaFromId(replicaId); // final String otherLocationName = TestInfo.OTHER_LOCATION_NAME; // Location otherLocation = Location.get(otherLocationName); runFilelistJob.invoke(abp, replica); File normalOutputFile = WorkFiles.getFile(replica, WorkFiles.FILES_ON_BA); File referenceOutputFile = WorkFiles.getFile(replica, WorkFiles.FILES_ON_REFERENCE_BA); assertTrue("Output should exist", normalOutputFile.exists()); assertFalse("Reference output should not exist", referenceOutputFile.exists()); normalOutputFile.delete(); // Check that wrong counts are caught File unsortedFile = new File(TestInfo.WORKING_DIR, "test_file_list_output/filelistOutput/unsorted.txt"); MockupArcRepositoryClient.getInstance().overrideBatch = new BatchStatus("AP1", Collections.<File>emptyList(), 17, RemoteFileFactory.getMovefileInstance(unsortedFile), new ArrayList<>(0)); runFilelistJob.invoke(abp, replica); abp.close(); } /** * Fails in Ant * * @throws Exception */ @Test @Ignore("FIXME") // FIXME: test temporarily disabled public void failingTestGetBitarchiveChecksum() throws Exception { LogbackRecorder lr = LogbackRecorder.startRecorder(); AdminData.getUpdateableInstance().addEntry("foobar", null, "md5-1"); AdminData.getUpdateableInstance().addEntry("barfu", null, "klaf"); final Map<Replica, String> results = new HashMap<Replica, String>(); // Test standard case MockupArcRepositoryClient.instance = new MockupArcRepositoryClient() { public BatchStatus batch(FileBatchJob job, String replicaId) { if (job.getClass().equals(ChecksumJob.class)) { if (results.containsKey(Replica.getReplicaFromId(replicaId))) { return new BatchStatus("AP1", Collections.<File>emptyList(), 1, new StringRemoteFile(results.get(Replica.getReplicaFromId(replicaId))), new ArrayList<FileBatchJob.ExceptionOccurrence>(0)); } else { return new BatchStatus("AP1", Collections.<File>emptyList(), 0, null, new ArrayList<FileBatchJob.ExceptionOccurrence>(0)); } } else { return super.batch(job, replicaId); } } public String getChecksum(String replicaId, String filename) { if (results.containsKey(Replica.getReplicaFromId(replicaId))) { try { String res = results.get(Replica.getReplicaFromId(replicaId)); KeyValuePair<String, String> kvp = ChecksumJob.parseLine(res); if (kvp.getKey().equals(filename)) { return kvp.getValue(); } log.warn("Found unexpected file '" + kvp.getKey() + "' while asking replica '" + Replica.getReplicaFromId(replicaId) + "' for file '" + filename + "'"); } catch (ArgumentNotValid e) { log.warn("Unexpected error '" + e + "' while asking " + "replica '" + Replica.getReplicaFromId(replicaId) + "' for file '" + filename + "'"); } } return null; } }; results.put(ONE, "foobar##md5-1"); results.put(TWO, "foobar##md5-2"); results.put(THREE, "foobar##md5-3"); FilePreservationState fps = (FilePreservationState) FileBasedActiveBitPreservation.getInstance() .getPreservationState("foobar"); assertFalse("Should have received result non-null result for ONE", fps.getReplicaChecksum(ONE) == null); assertEquals("Should have expected size for ONE", 1, fps.getReplicaChecksum(ONE).size()); assertEquals("Should have expected value for ONE", "md5-1", fps.getReplicaChecksum(ONE).get(0)); assertFalse("Should have received result non-null result for TWO", fps.getReplicaChecksum(TWO) == null); assertEquals("Should have expected size for TWO", 1, fps.getReplicaChecksum(TWO).size()); assertEquals("Should have expected value for TWO", "md5-2", fps.getReplicaChecksum(TWO).get(0)); assertFalse("Should have received result non-null result for THREE", fps.getReplicaChecksum(THREE) == null); assertEquals("Should have expected size for THREE", 1, fps.getReplicaChecksum(THREE).size()); assertEquals("Should have expected value for THREE", "md5-3", fps.getReplicaChecksum(THREE).get(0)); // Test fewer checksums results.clear(); results.put(ONE, " "); fps = (FilePreservationState) FileBasedActiveBitPreservation.getInstance().getPreservationState("foobar"); assertFalse("Should have received result non-null result for ONE", fps.getReplicaChecksum(ONE) == null); assertEquals("Should have expected size for ONE", 0, fps.getReplicaChecksum(ONE).size()); assertEquals("Should have expected size for TWO", 0, fps.getReplicaChecksum(TWO).size()); /* * LogUtils.flushLogs(getClass().getName()); * FileAsserts.assertFileNotContains("Should have no warning about ONE", TestInfo.LOG_FILE, * "while asking 'Replica ONE'"); FileAsserts.assertFileNotContains("Should have no warning about TWO", * TestInfo.LOG_FILE, "while asking 'Replica TWO'"); */ lr.assertLogNotContains("Should have no warning about ONE", "while asking 'Replica ONE'"); lr.assertLogNotContains("Should have no warning about TWO", "while asking 'Replica TWO'"); // Test malformed checksums results.clear(); results.put(ONE, "foobar#klaf"); results.put(TWO, "foobarf##klaff"); fps = (FilePreservationState) FileBasedActiveBitPreservation.getInstance().getPreservationState("foobar"); assertEquals("Should have expected size for ONE", 0, fps.getReplicaChecksum(ONE).size()); assertEquals("Should have expected size for TWO", 0, fps.getReplicaChecksum(TWO).size()); assertEquals("Should have expected size for THREE", 0, fps.getReplicaChecksum(THREE).size()); /* * LogUtils.flushLogs(getClass().getName()); * FileAsserts.assertFileContains("Should have warning about ONE in logfile: " + * FileUtils.readFile(TestInfo.LOG_FILE), //Before: "while asking replica 'Replica One'", * "while asking replica '" + ONE + "'", TestInfo.LOG_FILE); * FileAsserts.assertFileContains("Should have warning about TWO in logfile: " + * FileUtils.readFile(TestInfo.LOG_FILE), //Before: "while asking replica 'Replica TWO'", * "while asking replica '" + TWO + "'", TestInfo.LOG_FILE); */ // Before: "while asking replica 'Replica One'", lr.assertLogContains("Should have warning about ONE in log", "while asking replica '" + ONE + "'"); // Before: "while asking replica 'Replica TWO'", lr.assertLogContains("Should have warning about TWO in log", "while asking replica '" + TWO + "'"); // TODO: More funny cases lr.stopRecorder(); } private static class DummyBatchMessageReplyServer implements MessageListener { JMSConnection conn = JMSConnectionFactory.getInstance(); private byte[] encodedKey; private BitarchiveRecord bar; public DummyBatchMessageReplyServer() { conn.setListener(Channels.getTheRepos(), this); } public void close() { conn.removeListener(Channels.getTheRepos(), this); } public void onMessage(Message msg) { try { BatchMessage bMsg = (BatchMessage) JMSConnection.unpack(msg); BatchStatus lbs = batch(bMsg.getJob(), bMsg.getReplicaId(), null); conn.reply(new BatchReplyMessage(bMsg.getTo(), bMsg.getReplyTo(), bMsg.getID(), 4, new ArrayList<File>(), lbs.getResultFile())); } catch (IOFailure e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * The following three methods are used by the ActiveBitPreservation. * * @param job a given FileBatchjob * @param file a given RemoteFile (ignored) * @return BatchStatus * @throws IOException If trouble creating temporary files and writing to this temporary files. */ public BatchStatus batch(FileBatchJob job, String locationName, RemoteFile file) throws IOException { BatchStatus lbs = null; File tmpfile = File.createTempFile("DummyBatch", ""); OutputStream os = new FileOutputStream(tmpfile); // The file name File bitarchive_dir = new File(TestInfo.WORKING_DIR, locationName); Settings.set(ArchiveSettings.BITARCHIVE_SERVER_FILEDIR, bitarchive_dir.getAbsolutePath()); BitarchiveAdmin admin = BitarchiveAdmin.getInstance(); BatchLocalFiles localBatchRunner = new BatchLocalFiles(admin.getFiles()); localBatchRunner.run(job, os); os.close(); RemoteFile resultFile = RemoteFileFactory.getInstance(tmpfile, true, false, true); if (false) { File artificialFailure = new File(bitarchive_dir, TestInfo.REFERENCE_FILES[0]); List<File> l = new ArrayList<File>(); l.add(artificialFailure); lbs = new BatchStatus(bitarchive_dir.getName(), l, job.getNoOfFilesProcessed(), null, null); } else { lbs = new BatchStatus(bitarchive_dir.getName(), job.getFilesFailed(), job.getNoOfFilesProcessed(), resultFile, null); } return lbs; } } public static class MockupArcRepositoryClient implements ArcRepositoryClient { private static MockupArcRepositoryClient instance; private BitarchiveRecord overrideGet; private File overrideGetFile; private File overrideStore; private BatchStatus overrideBatch; private File overrideRemoveAndGetFile; public static MockupArcRepositoryClient getInstance() { if (instance == null) { instance = new MockupArcRepositoryClient(); } return instance; } public void close() { instance = null; } public BitarchiveRecord get(String arcfile, long index) throws ArgumentNotValid { if (overrideGet != null) { return overrideGet; } File file = new File(TestInfo.GOOD_ARCHIVE_FILE_DIR, arcfile); try { if (!file.exists()) { return null; } else { return new BitarchiveRecord((ARCRecord) ARCReaderFactory.get(file).get(index), arcfile); } } catch (IOException e) { fail("Test failure while reading file '" + file + "'"); return null; } } public void getFile(String arcfilename, Replica replica, File toFile) { if (overrideGetFile != null) { FileUtils.copyFile(overrideGetFile, toFile); return; } File file = new File(TestInfo.GOOD_ARCHIVE_FILE_DIR, arcfilename); FileUtils.copyFile(file, toFile); } public void store(File file) throws IOFailure, ArgumentNotValid { File f = new File(TestInfo.GOOD_ARCHIVE_FILE_DIR, file.getName()); if (overrideStore != null) { FileUtils.copyFile(overrideStore, f); return; } FileUtils.copyFile(file, f); } public BatchStatus batch(FileBatchJob job, String locationName, String... args) { if (overrideBatch != null) { return overrideBatch; } try { File output = File.createTempFile("Batch", ".dat", TestInfo.WORKING_DIR); File[] in_files = TestInfo.GOOD_ARCHIVE_FILE_DIR.listFiles(); FileOutputStream os = new FileOutputStream(output); new BatchLocalFiles(in_files).run(job, os); os.close(); return new BatchStatus("BA1", Collections.<File>emptyList(), in_files.length, RemoteFileFactory.getMovefileInstance(output), new ArrayList<FileBatchJob.ExceptionOccurrence>(0)); } catch (IOException e) { fail("IO error during test"); return null; } } public void updateAdminData(String fileName, String bitarchiveId, ReplicaStoreState newval) { UpdateableAdminData adminData = AdminData.getUpdateableInstance(); if (!adminData.hasEntry(fileName)) { adminData.addEntry(fileName, null, "xx"); } adminData.setState(fileName, bitarchiveId, newval); } public void updateAdminChecksum(String filename, String checksum) { UpdateableAdminData adminData = AdminData.getUpdateableInstance(); adminData.setCheckSum(filename, checksum); } public File removeAndGetFile(String fileName, String bitarchiveName, String checksum, String credentials) { if (overrideRemoveAndGetFile != null) { return overrideRemoveAndGetFile; } File output = null; try { output = File.createTempFile(fileName, ".removed", TestInfo.WORKING_DIR); } catch (IOException e) { fail("IO error during test."); } if (!credentials.equals("XX")) { throw new PermissionDenied("Credentials are not XX"); } FileUtils.copyFile(new File(TestInfo.GOOD_ARCHIVE_FILE_DIR, fileName), output); return output; } public File getAllChecksums(String replicaId) { try { BatchStatus bs = batch(new ChecksumJob(), replicaId); File result = File.createTempFile("all", ".checksum", TestInfo.WORKING_DIR); bs.copyResults(result); return result; } catch (IOException e) { fail("Got the following error: " + e); } // This cannot happen! return null; } public File getAllFilenames(String replicaId) { try { BatchStatus bs = batch(new FileListJob(), replicaId); File result = File.createTempFile("all", ".filename", TestInfo.WORKING_DIR); bs.copyResults(result); return result; } catch (IOException e) { fail("Got the following error: " + e); } // This cannot happen! return null; } public File correct(String replicaId, String checksum, File file, String credentials) { // TODO: something! throw new NotImplementedException("TODO: ME!"); } @Override public String getChecksum(String replicaId, String filename) { throw new NotImplementedException("TODO: ME!"); } } }