package votorola.a.diff.harvest.run; // Copyright 2012. Christian Weilbach. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. import static org.junit.Assert.*; import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.sql.SQLException; import java.util.Date; import java.util.Formatter; import java.util.concurrent.Semaphore; import java.util.logging.Level; import java.util.logging.Logger; import javax.script.ScriptException; import org.junit.Before; import org.junit.Test; import votorola.a.VoteServer; import votorola.a.diff.harvest.cache.HarvestCache; import votorola.a.diff.harvest.run.AbstractFetcher; import votorola.a.diff.harvest.run.HarvestRunner; import votorola.g.logging.LoggerX; /** * Unit test for DiffMessage. */ public class HarvestRunnerTest { final public static int JOB_COUNT = 3; final public static int SLOTS = 100; // stepping in ms final public static int STEPPING = HarvestRunner.STEPPING * 1000; private Semaphore sem = new Semaphore(SLOTS, true); final private static Logger LOGGER = LoggerX.i(HarvestRunnerTest.class); /** * A job that triggers SuccessfulJobs. */ private class ChainJob extends AbstractFetcher { private final int count; private final Date initDate = new Date(); public ChainJob(String baseUrl, String relUrl, int count) throws MalformedURLException, InterruptedException { super(baseUrl, relUrl); this.count = count; sem.acquire(); } @Override public void run() { sem.release(); long passed = new Date().getTime() - initDate.getTime(); System.out.println("Fetched and run " + url() + " after " + passed + " ms."); for (int i = 0; i < JOB_COUNT; i++) { Formatter formatter = new Formatter(); formatter.format("%06d", offset + count + i); final String rel = mon + formatter.toString() + ".html"; SuccessfulJob job; try { job = new SuccessfulJob(baseUrl, rel, JOB_COUNT - i); hr.scheduleFirst(job); } catch (MalformedURLException | InterruptedException e) { LOGGER.log(Level.INFO, "Problem with " + baseUrl + rel, e); } } } @Override public void fault(final String msg) { fail(msg); } } /** * A job which succeeds */ private class SuccessfulJob extends AbstractFetcher { final private int count; final private Date initDate = new Date(); public SuccessfulJob(String baseUrl, String relUrl, int count) throws MalformedURLException, InterruptedException { super(baseUrl, relUrl); sem.acquire(); this.count = count; } @Override public void run() { sem.release(); assert (getInputStream() != null); // check that we are not executed too early long passed = new Date().getTime() - initDate.getTime(); // long delay = passed - (count * HarvestRunner.STEPPING * STEPPING); // assert (delay > 0); System.out.println("Fetched and run " + url() + " after " + passed + " ms."); } @Override public void fault(final String msg){ fail(msg); } } /** * Setup VoteServer * * @throws URISyntaxException * @throws SQLException * @throws ScriptException * @throws IOException */ @Before public void setup() throws IOException, ScriptException, SQLException, URISyntaxException { final VoteServer.Run vsr = new VoteServer( System.getProperty("user.name")).new Run(false); HarvestCache.init(vsr); hr = HarvestRunner.i(); } private volatile HarvestRunner hr; /** * Use a stable public repository not related to e-democracy. Starts with * post 15. */ final private String baseUrl = "http://mail.python.org/pipermail/mailman-users/"; final private String mon = "1998-July/"; final private int offset = 15; /** * Test job scheduling last with the Votorola static pipermail archive. * * @throws InterruptedException * @throws MalformedURLException */ @Test public void testScheduleLast() throws MalformedURLException, InterruptedException { for (int i = 0; i < JOB_COUNT; i++) { Formatter formatter = new Formatter(); formatter.format("%06d", offset + i); final String rel = mon + formatter.toString() + ".html"; SuccessfulJob job = new SuccessfulJob(baseUrl, rel, i); hr.scheduleLast(job); } // two seconds grace period to complete last job Thread.sleep((JOB_COUNT + 2) * STEPPING); // no job lost assert (sem.availablePermits() == SLOTS); } /** * Test job scheduling first with the Votorola static pipermail archive. * * @throws InterruptedException * @throws MalformedURLException */ @Test public void testScheduleFirst() throws MalformedURLException, InterruptedException { for (int i = 0; i < JOB_COUNT; i++) { Formatter formatter = new Formatter(); formatter.format("%06d", offset + i); final String rel = mon + formatter.toString() + ".html"; // may be executed immediately depending on timing TODO SuccessfulJob job = new SuccessfulJob(baseUrl, rel, JOB_COUNT - i); hr.scheduleFirst(job); } // two seconds grace period to complete last job Thread.sleep((JOB_COUNT + 2) * STEPPING); // no job lost assert (sem.availablePermits() == SLOTS); } final private String altBaseUrl = "http://mail.zelea.com/list/votorola/"; final private String altMon = "2012-April/"; final private int altOffset = 1328; @Test public void testTwoArchivesParallel() throws MalformedURLException, InterruptedException { for (int i = 0; i < JOB_COUNT; i++) { Formatter formatter = new Formatter(); formatter.format("%06d", offset + i); final String rel = mon + formatter.toString() + ".html"; SuccessfulJob job = new SuccessfulJob(baseUrl, rel, i); hr.scheduleLast(job); Formatter altFormatter = new Formatter(); altFormatter.format("%06d", altOffset + i); final String altRel = altMon + altFormatter.toString() + ".html"; System.out.println("URL: "+ altBaseUrl + altRel); SuccessfulJob altJob = new SuccessfulJob(altBaseUrl, altRel, i); hr.scheduleLast(altJob); } // two seconds grace period to complete last job Thread.sleep((JOB_COUNT + 5) * STEPPING); // no job lost assert (sem.availablePermits() == SLOTS); } }