Java tutorial
/* * #%L * Netarchivesuite - common - 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.common.distribute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.lang.reflect.Field; import java.net.SocketException; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.junit.Ignore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dk.netarkivet.common.CommonSettings; import dk.netarkivet.common.exceptions.ArgumentNotValid; import dk.netarkivet.common.exceptions.IOFailure; import dk.netarkivet.common.utils.FileUtils; import dk.netarkivet.common.utils.RememberNotifications; import dk.netarkivet.common.utils.Settings; import dk.netarkivet.common.utils.TestInfo; import dk.netarkivet.common.utils.ZipUtils; import dk.netarkivet.testutils.TestFileUtils; import dk.netarkivet.testutils.preconfigured.ReloadSettings; /** * Class testing the FTPRemoteFile class. */ @Ignore("Not in junit3 test suite") public class IntegrityTestsFTP { private static final String FILE_1_CONTENTS = "The contents of file 1"; private static final String FILE_2_CONTENTS = "File 2 contains\n" + "this and this\nit also has\nsome more\nlike this\nBurma-Shave"; private FTPClient theFTPClient; private ArrayList<RemoteFile> upLoadedFTPRemoteFiles = new ArrayList<RemoteFile>(); private ArrayList<String> upLoadedFiles = new ArrayList<String>(); /** testFile1-3 represents duplicates of TestInfo.TESTXML */ private File testFile1; private File testFile2; private File testFile3; protected static final Logger log = LoggerFactory.getLogger(IntegrityTestsFTP.class); ReloadSettings rs = new ReloadSettings(); public void setUp() { rs.setUp(); if (!TestInfo.TEMPDIR.exists()) { dk.netarkivet.common.utils.TestInfo.TEMPDIR.mkdir(); } FileUtils.removeRecursively(TestInfo.TEMPDIR); TestFileUtils.copyDirectoryNonCVS(TestInfo.DATADIR, TestInfo.TEMPDIR); /* make 3 duplicates of TestInfo.TESTXML: test1.xml, test2.xml, test3.xml */ testFile1 = new File(TestInfo.TEMPDIR, "test1.xml"); testFile2 = new File(TestInfo.TEMPDIR, "test2.xml"); testFile3 = new File(TestInfo.TEMPDIR, "test3.xml"); assertTrue("The test xml file must exist", TestInfo.TESTXML.exists()); FileUtils.copyFile(TestInfo.TESTXML, testFile1); FileUtils.copyFile(TestInfo.TESTXML, testFile2); FileUtils.copyFile(TestInfo.TESTXML, testFile3); /* Read ftp-related settings from settings.xml. */ final String ftpServerName = Settings.get(CommonSettings.FTP_SERVER_NAME); final int ftpServerPort = Integer.parseInt(Settings.get(CommonSettings.FTP_SERVER_PORT)); final String ftpUserName = Settings.get(CommonSettings.FTP_USER_NAME); final String ftpUserPassword = Settings.get(CommonSettings.FTP_USER_PASSWORD); /* Connect to test ftp-server. */ theFTPClient = new FTPClient(); try { theFTPClient.connect(ftpServerName, ftpServerPort); assertTrue( "Could not login to ' + " + ftpServerName + ":" + ftpServerPort + "' with username,password=" + ftpUserName + "," + ftpUserPassword, theFTPClient.login(ftpUserName, ftpUserPassword)); assertTrue("Must be possible to set the file type to binary after login", theFTPClient.setFileType(FTPClient.BINARY_FILE_TYPE)); } catch (SocketException e) { throw new IOFailure("Connect to " + ftpServerName + ":" + ftpServerPort + " failed", e.getCause()); } catch (IOException e) { throw new IOFailure("Connect to " + ftpServerName + ":" + ftpServerPort + " failed", e.getCause()); } /** Do not send notification by email. Print them to STDOUT. */ Settings.set(CommonSettings.NOTIFICATIONS_CLASS, RememberNotifications.class.getName()); } public void tearDown() throws IOException { /** delete all uploaded files on ftp-server and then disconnect. */ Iterator<String> fileIterator = upLoadedFiles.iterator(); while (fileIterator.hasNext()) { String currentUploadedFile = (String) fileIterator.next(); if (currentUploadedFile != null) { if (!theFTPClient.deleteFile(currentUploadedFile)) { log.warn("deleteFile operation failed on {}. Reply from ftpserver: {}", currentUploadedFile, theFTPClient.getReplyString()); } } } if (!theFTPClient.logout()) { log.warn("logout operation failed. Reply from ftp-server: {}", theFTPClient.getReplyString()); } theFTPClient.disconnect(); Iterator<RemoteFile> ftpIterator = upLoadedFTPRemoteFiles.iterator(); while (ftpIterator.hasNext()) { FTPRemoteFile currentUploadedFile = (FTPRemoteFile) ftpIterator.next(); if (currentUploadedFile != null) { currentUploadedFile.cleanup(); } } FileUtils.removeRecursively(dk.netarkivet.common.utils.TestInfo.TEMPDIR); rs.tearDown(); } /** * Initially verify that communication with the ftp-server succeeds without using the RemoteFile. (1) Verify, that * you can upload a file to a ftp-server, and retrieve the same file from this server-server. (2) Verify, that file * was not corrupted in transit author: SVC * * @throws IOException */ public void testConfigSettings() throws IOException { /** * this code has been tested with the ftp-server proftpd (www.proftpd.org), using the configuration stored in * CVS here: /projects/webarkivering/proftpd.org */ String nameOfUploadedFile; String nameOfUploadedFile2; File inputFile = TestInfo.TESTXML; File inputFile2 = TestInfo.INVALIDXML; InputStream in = new FileInputStream(inputFile); InputStream in2 = new FileInputStream(inputFile2); nameOfUploadedFile = inputFile.getName(); nameOfUploadedFile2 = inputFile2.getName(); /** try to append data to file on FTP-server */ /** Assumption: File does not exist on FTP-server */ assertFalse("File should not exist already on server", onServer(nameOfUploadedFile)); assertTrue("Appendfile operation failed", theFTPClient.appendFile(nameOfUploadedFile, in)); upLoadedFiles.add(nameOfUploadedFile); /** try to append data to file on the FTP-server */ assertTrue("AppendFile operation 2 failed!", theFTPClient.appendFile(nameOfUploadedFile, in2)); if (!upLoadedFiles.contains(nameOfUploadedFile)) { upLoadedFiles.add(nameOfUploadedFile); } /** try to store data to a file on the FTP-server */ assertTrue("Store operation failed", theFTPClient.storeFile(nameOfUploadedFile2, in)); upLoadedFiles.add(nameOfUploadedFile2); } /** * test arguments extensively * * @throws FileNotFoundException */ public void testArguments() throws FileNotFoundException { /** test 1: test that FTPRemoteFile.getInstance(null) throws an ArgumentNotValid exception */ try { FTPRemoteFile.getInstance(null, true, false, true); fail("ArgumentNotValid Expected"); } catch (ArgumentNotValid e) { // Expected } /** test 3: test that FTPRemoteFile.appendTo(null) throws an ArgumentNotValid exception */ try { RemoteFile rf = FTPRemoteFile.getInstance(testFile1, true, false, true); rf.appendTo(null); fail("ArgumentNotValid Expected"); } catch (ArgumentNotValid e) { // Expected } /** test 4: test that FTPRemoteFile.copyTo(null) throws an ArgumentNotValid exception */ try { RemoteFile rf = FTPRemoteFile.getInstance(testFile2, true, false, true); upLoadedFTPRemoteFiles.add(rf); rf.copyTo(null); fail("ArgumentNotValid Expected"); } catch (ArgumentNotValid e) { // Expected } /** * test 5: test that FTPRemoteFile.copyTo(destFile) throws an ArgumentNotValid exception if destFile is not an * acceptable destinationFile, i.e. the file 'destFile' is writable */ RemoteFile rf = FTPRemoteFile.getInstance(testFile2, true, false, true); /** this creates a File object pointing to an illegal file */ File destFile = new File(TestInfo.TEMPDIR.getAbsolutePath() + "/" + TestInfo.TEMPDIR.getName() + "/" + TestInfo.TESTXML.getName()); assertFalse(destFile.getAbsolutePath() + " should not exist!", destFile.exists()); try { rf.copyTo(destFile); /* This operation tries to copy the file to an file, which cannot be created */ fail("ArgumentNotValid Expected"); } catch (ArgumentNotValid e) { // Expected } } /** * (1) Test, if uploaded and retrieved file are equal (2) test that rf.getSize() reports the correct value; * * @throws IOException */ public void testUploadAndRetrieve() throws IOException { File testFile = TestInfo.TESTXML; RemoteFile rf = FTPRemoteFile.getInstance(testFile, true, false, true); File newFile = new File(TestInfo.TEMPDIR, "newfile.xml"); /** register that testFile should now be present on ftp-server */ upLoadedFTPRemoteFiles.add(rf); assertEquals("The size of the file written to the ftp-server " + "should not differ from the original size", rf.getSize(), testFile.length()); rf.copyTo(newFile); /** * check, if the original file and the same file retrieved from the ftp-server contains the same contents */ byte[] datasend = FileUtils.readBinaryFile(testFile); byte[] datareceived = FileUtils.readBinaryFile(newFile); boolean isok = Arrays.equals(datareceived, datasend); assertTrue(" verify the same data received as uploaded ", isok); } /** * Check that the delete method can delete a file on the ftp server * * @throws FileNotFoundException */ public void testDelete() throws FileNotFoundException { File testFile = TestInfo.TESTXML; RemoteFile rf = FTPRemoteFile.getInstance(testFile, true, false, true); File newFile = new File(TestInfo.TEMPDIR, "newfile.xml"); // Check that file is actually there rf.copyTo(newFile); // Delete the file (both locally and one the server) newFile.delete(); rf.cleanup(); // And check to see that it's gone try { rf.copyTo(newFile); fail("Should throw an exception getting deleted file"); } catch (IOFailure e) { // expected } } /** * Test that multiple uploads of the same file does not clash. Test for bug #135 * * @throws IOException */ public void testDoubleUpload() throws IOException { Settings.set(CommonSettings.REMOTE_FILE_CLASS, "dk.netarkivet.common.distribute.FTPRemoteFile"); File testFile = TestInfo.TESTXML; PrintWriter write1 = new PrintWriter(new FileWriter(testFile)); write1.print(FILE_1_CONTENTS); write1.close(); RemoteFile rf1 = RemoteFileFactory.getInstance(testFile, true, false, true); /** register that testFile should now be present on ftp-server */ upLoadedFTPRemoteFiles.add(rf1); PrintWriter write2 = new PrintWriter(new FileWriter(testFile)); write2.print(FILE_2_CONTENTS); write2.close(); RemoteFile rf2 = RemoteFileFactory.getInstance(testFile, true, false, true); upLoadedFTPRemoteFiles.add(rf2); File newFile = new File(TestInfo.TEMPDIR, "newfile.xml"); rf1.copyTo(newFile); assertEquals("Contents of first file should be preserved", FILE_1_CONTENTS, FileUtils.readFile(newFile)); rf2.copyTo(newFile); assertEquals("Contents of second file should be preserved", FILE_2_CONTENTS, FileUtils.readFile(newFile)); } public void tet501MFile() throws FileNotFoundException { File zipFile = new File(TestInfo.DATADIR, TestInfo.FIVE_HUNDRED_MEGA_FILE_ZIPPED); assertTrue("File '" + TestInfo.FIVE_HUNDRED_MEGA_FILE_ZIPPED + " does not exist!", zipFile.exists()); ZipUtils.unzip(zipFile, TestInfo.TEMPDIR); File unzippedFile = new File(TestInfo.TEMPDIR, TestInfo.FIVE_HUNDRED_MEGA_FILE_UNZIPPED); assertTrue("File '" + TestInfo.FIVE_HUNDRED_MEGA_FILE_UNZIPPED + " does not exist!", unzippedFile.exists()); RemoteFile rf = FTPRemoteFile.getInstance(unzippedFile, true, false, true); upLoadedFTPRemoteFiles.add(rf); assertEquals("Size of Uploaded data should be the same as original data", unzippedFile.length(), rf.getSize()); File destinationFile = new File(TestInfo.TEMPDIR, unzippedFile.getName() + ".new"); rf.copyTo(destinationFile); // throw new IOFailure("Unable to copy remoteFile: " + rf + // " to " + destinationFile); /** Check filesizes, and see, if they differ */ assertEquals( "Length of original unzipped file " + " and unzipped file retrieved from the ftp-server should not differ!", unzippedFile.length(), destinationFile.length()); } // public void testSerializability(){ // fail("test of serializability not yet implemented!"); // // } public boolean onServer(String nameOfUploadedFile) throws IOException { assertTrue("theFTPClient should not be null", theFTPClient != null); FTPFile[] listOfFiles = theFTPClient.listFiles(); // assertTrue("This list should not be null",listOfFiles != null); if (listOfFiles == null) { return false; } for (int i = 0; i < listOfFiles.length; i++) { if (listOfFiles[i].getName().equals(nameOfUploadedFile)) { return true; } } return false; } public void testWrongChecksumThrowsError() throws Exception { Settings.set(CommonSettings.REMOTE_FILE_CLASS, "dk.netarkivet.common.distribute.FTPRemoteFile"); RemoteFile rf = RemoteFileFactory.getInstance(testFile2, true, false, true); // upload error to ftp server File temp = File.createTempFile("foo", "bar"); FTPClient client = new FTPClient(); client.connect(Settings.get(CommonSettings.FTP_SERVER_NAME), Integer.parseInt(Settings.get(CommonSettings.FTP_SERVER_PORT))); client.login(Settings.get(CommonSettings.FTP_USER_NAME), Settings.get(CommonSettings.FTP_USER_PASSWORD)); Field field = FTPRemoteFile.class.getDeclaredField("ftpFileName"); field.setAccessible(true); String filename = (String) field.get(rf); client.storeFile(filename, new ByteArrayInputStream("foo".getBytes())); client.logout(); try { rf.copyTo(temp); fail("Should throw exception on wrong checksum"); } catch (IOFailure e) { // expected } assertFalse("Destination file should not exist", temp.exists()); } }