package geniusweb.partiesserver; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import org.junit.Test; import geniusweb.partiesserver.repository.AvailableParty; import tudelft.utilities.files.FileInfo; import tudelft.utilities.files.FileWatcher; import tudelft.utilities.immutablelist.Tuple; import tudelft.utilities.listener.Listenable; import tudelft.utilities.repository.Repository; public class AvailablePartiesUpdaterTest { private static final String RANDOMPARTY = "src/main/webapp/partiesrepo/randomparty-2.1.1.jar"; private static final int TESTRATE = 200; // check file changes every 200ms @SuppressWarnings("unchecked") private Repository repo = new TestRepo(); private AvailablePartiesUpdater updater; private Path tmpdir; private final List logrecords = new LinkedList<>(); private Path RNDPARTY; private void init() throws IOException { tmpdir = Files.createTempDirectory("geniuswebparties"); RNDPARTY = tmpdir.resolve("randomparty.jar"); logrecords.clear(); Logger.getLogger("partiesserver").addHandler(new Handler() { @Override public void publish(LogRecord record) { if (record.getLevel().intValue() >= Level.WARNING.intValue()) { logrecords.add(record); } } @Override public void flush() { // TODO Auto-generated method stub } @Override public void close() throws SecurityException { // TODO Auto-generated method stub } }); updater = new AvailablePartiesUpdater(repo) { @Override protected Path getRootDir() { return tmpdir; } @Override protected Listenable> getFileWatcher( File directory) { return new FileWatcher(directory, TESTRATE, 1); } }; } @Test public void smokeTest() throws IOException { init(); } @Test public void initiallyEmptyTest() throws IOException, InterruptedException { init(); Thread.sleep(2 * TESTRATE); assertTrue(repo.list().isEmpty()); assertTrue(logrecords.isEmpty()); } @Test public void IgnoreBadFileTest() throws IOException, InterruptedException { init(); Path file = tmpdir.resolve("file1.txt"); Files.write(file, Arrays.asList("blah blah"), Charset.forName("UTF-8")); Thread.sleep(2 * TESTRATE); assertTrue(repo.list().isEmpty()); assertEquals(1, logrecords.size()); assertTrue(logrecords.get(0).getMessage() .contains("Can not load class from file")); assertTrue(logrecords.get(0).getThrown().getMessage() .contains("must be a file and have extension .jar")); } @Test public void IgnoreBadJarFileTest() throws IOException, InterruptedException { init(); Path file = tmpdir.resolve("file1.jar"); Files.write(file, Arrays.asList("blah blah"), Charset.forName("UTF-8")); Thread.sleep(2 * TESTRATE); assertTrue(repo.list().isEmpty()); assertEquals(1, logrecords.size()); assertTrue(logrecords.get(0).getMessage() .contains("Can not load class from file")); // someone changed the error message deep down. // assertTrue(logrecords.get(0).getThrown().getMessage().contains("error // in opening zip file")); } @Test public void ignoreEmptyJarFileTest() throws IOException, InterruptedException { init(); Files.copy(getClass().getResourceAsStream("/empty.jar"), tmpdir.resolve("empty.jar")); Thread.sleep(2 * TESTRATE); assertTrue(repo.list().isEmpty()); assertEquals(1, logrecords.size()); assertTrue(logrecords.get(0).getMessage() .contains("Can not load class from file")); assertTrue(logrecords.get(0).getThrown().getMessage().contains( "jar file does not contain manifest with main class")); } @Test public void randomPartyJarTest() throws IOException, InterruptedException { init(); Files.copy(Paths.get(RANDOMPARTY), tmpdir.resolve(RNDPARTY)); Thread.sleep(2 * TESTRATE); assertTrue(logrecords.isEmpty()); assertEquals(1, repo.list().size()); } @Test public void removeJarTest() throws IOException, InterruptedException { init(); Files.copy(Paths.get(RANDOMPARTY), RNDPARTY); Thread.sleep(2 * TESTRATE); assertEquals(1, repo.list().size()); Files.delete(RNDPARTY); Thread.sleep(2 * TESTRATE); assertEquals(0, repo.list().size()); } @Test public void removeRootTest() throws IOException, InterruptedException { init(); Files.copy(Paths.get(RANDOMPARTY), RNDPARTY); Thread.sleep(2 * TESTRATE); assertEquals(1, repo.list().size()); Files.delete(RNDPARTY); Files.delete(tmpdir); Thread.sleep(2 * TESTRATE); assertEquals(0, repo.list().size()); assertEquals(1, logrecords.size()); assertTrue(logrecords.get(0).getMessage() .contains("Can not read repository root directory")); } } /** * Basic repo to track what the updater is doing. */ class TestRepo implements Repository { private Map map = new HashMap(); @Override public Collection list() { return map.values(); } @Override public AvailableParty get(String id) { return map.get(id); } @Override public void put(AvailableParty entity) { if (map.containsKey(entity.getID())) { throw new IllegalStateException("repo already contains entity"); } map.put(entity.getID(), entity); } @Override public void remove(String id) { map.remove(id); } @Override public void replace(AvailableParty entity) { if (!map.containsKey(entity.getID())) { throw new IllegalStateException("repo does not contain entity"); } map.put(entity.getID(), entity); } }