Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 93607 invoked from network); 6 Sep 2006 07:16:30 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 6 Sep 2006 07:16:30 -0000 Received: (qmail 68015 invoked by uid 500); 6 Sep 2006 07:16:28 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 67663 invoked by uid 500); 6 Sep 2006 07:16:26 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 67652 invoked by uid 500); 6 Sep 2006 07:16:26 -0000 Received: (qmail 67649 invoked by uid 99); 6 Sep 2006 07:16:26 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Sep 2006 00:16:26 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Sep 2006 00:16:25 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 90D671A981C; Wed, 6 Sep 2006 00:16:05 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r440640 - /jakarta/commons/sandbox/id/trunk/src/test/org/apache/commons/id/serial/TimeBasedAlphanumericIdentifierGeneratorTest.java Date: Wed, 06 Sep 2006 07:16:05 -0000 To: commons-cvs@jakarta.apache.org From: joehni@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20060906071605.90D671A981C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: joehni Date: Wed Sep 6 00:16:04 2006 New Revision: 440640 URL: http://svn.apache.org/viewvc?view=rev&rev=440640 Log: More robust tests on time-shifting machines. Modified: jakarta/commons/sandbox/id/trunk/src/test/org/apache/commons/id/serial/TimeBasedAlphanumericIdentifierGeneratorTest.java Modified: jakarta/commons/sandbox/id/trunk/src/test/org/apache/commons/id/serial/TimeBasedAlphanumericIdentifierGeneratorTest.java URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/id/trunk/src/test/org/apache/commons/id/serial/TimeBasedAlphanumericIdentifierGeneratorTest.java?view=diff&rev=440640&r1=440639&r2=440640 ============================================================================== --- jakarta/commons/sandbox/id/trunk/src/test/org/apache/commons/id/serial/TimeBasedAlphanumericIdentifierGeneratorTest.java (original) +++ jakarta/commons/sandbox/id/trunk/src/test/org/apache/commons/id/serial/TimeBasedAlphanumericIdentifierGeneratorTest.java Wed Sep 6 00:16:04 2006 @@ -98,24 +98,23 @@ /** * Test that the generator can be tweaked to start with '0'. + * @throws InterruptedException unexpected */ - public void testMayStartWithIdentifierOfZeros() { + public void testMayStartWithIdentifierOfZeros() throws InterruptedException { final int maxSize = Long.toString(Long.MAX_VALUE, 36).length(); final char[] zeros = new char[maxSize]; Arrays.fill(zeros, '0'); - // synchronize with current time slice ... - final long waitForNextPeriod = System.currentTimeMillis(); - long next = waitForNextPeriod; - while (next <= waitForNextPeriod) { - next = System.currentTimeMillis(); - } - - // ... next id should be in same time slice if it is used as current offset - final StringIdentifierGenerator idGenerator = new TimeBasedAlphanumericIdentifierGenerator( - 0, next); - - assertEquals(new String(zeros), idGenerator.nextStringIdentifier()); + final TimeSliceSynchronizer synchronizer = new TimeSliceSynchronizer() { + void runTest() { + // ... next id should be in same time slice if it is used as current offset + final StringIdentifierGenerator idGenerator = new TimeBasedAlphanumericIdentifierGenerator(0, next); + // note, that this might still fail on time shifting machines occasionally + assertEquals(new String(zeros), idGenerator.nextStringIdentifier()); + } + + }; + synchronizer.runSynced(); } /** @@ -171,39 +170,47 @@ /** * Test ensures, that generator can recalculate the time from the id if internally no overflow * had happened. + * @throws InterruptedException unexpected */ - public void testCanRetrieveTimeFromIdWithoutInternalOverflow() { - // synchronize with current time slice ... - final long waitForNextPeriod = System.currentTimeMillis(); - final TimeBasedAlphanumericIdentifierGenerator idGenerator = new TimeBasedAlphanumericIdentifierGenerator( - 4, waitForNextPeriod - 1000); - - long next = waitForNextPeriod; - while (next <= waitForNextPeriod) { - next = System.currentTimeMillis(); - } + public void testCanRetrieveTimeFromIdWithoutInternalOverflow() throws InterruptedException { + final TimeSliceSynchronizer synchronizer = new TimeSliceSynchronizer() { + TimeBasedAlphanumericIdentifierGenerator idGenerator; + void initialize() { + idGenerator = new TimeBasedAlphanumericIdentifierGenerator( + 4, waitForNextPeriod - 1000); + } - final String id = idGenerator.nextStringIdentifier(); - assertEquals(next, idGenerator.getMillisecondsFromId(id, waitForNextPeriod - 1000)); + void runTest() { + // note, that this might still fail on time shifting machines occasionally + final String id = idGenerator.nextStringIdentifier(); + assertEquals(next, idGenerator.getMillisecondsFromId(id, waitForNextPeriod - 1000)); + } + + }; + synchronizer.runSynced(); } /** * Test ensures, that generator can recalculate the time from the id even if internally an * overflow had happened. + * @throws InterruptedException unexpected */ - public void testCanRetrieveTimeFromIdWithInternalOverflow() { - // synchronize with current time slice ... - final long waitForNextPeriod = System.currentTimeMillis(); - final TimeBasedAlphanumericIdentifierGenerator idGenerator = new TimeBasedAlphanumericIdentifierGenerator( - 4, waitForNextPeriod + 1000); - - long next = waitForNextPeriod; - while (next <= waitForNextPeriod) { - next = System.currentTimeMillis(); - } + public void testCanRetrieveTimeFromIdWithInternalOverflow() throws InterruptedException { + final TimeSliceSynchronizer synchronizer = new TimeSliceSynchronizer() { + TimeBasedAlphanumericIdentifierGenerator idGenerator; + void initialize() { + idGenerator = new TimeBasedAlphanumericIdentifierGenerator( + 4, waitForNextPeriod + 1000); + } - final String id = idGenerator.nextStringIdentifier(); - assertEquals(next, idGenerator.getMillisecondsFromId(id, waitForNextPeriod + 1000)); + void runTest() { + // note, that this might still fail on time shifting machines occasionally + final String id = idGenerator.nextStringIdentifier(); + assertEquals(next, idGenerator.getMillisecondsFromId(id, waitForNextPeriod + 1000)); + } + + }; + synchronizer.runSynced(); } /** @@ -252,5 +259,48 @@ } })); return suite; + } + + /** + * A guardian class that tries hard to synchronize the test to run in the same time slice of the CPU even on time + * shifting machines. + */ + abstract static class TimeSliceSynchronizer { + + long waitForNextPeriod; + long next; + + void runSynced() throws InterruptedException { + // idea here is to generate an id in the same time slice of the CPU as the last System.currentTimeMillis() call + int tries = 0; + for (;;) { + waitForNextPeriod = System.currentTimeMillis(); + initialize(); + + next = waitForNextPeriod; + while (next == waitForNextPeriod) { + next = System.currentTimeMillis(); + } + + // sanity check, neither condition should normally occur, but on time shifting machines we start over + if (next < waitForNextPeriod || next - waitForNextPeriod > 100) { + // we already tried 10 times to find a situation without time shifting + if (++tries > 10) { + fail("Cannot perform this test on a machine, that is steadily time shifting!"); + } + Thread.sleep(1); + continue; + } + + runTest(); + break; + } + } + + void initialize() { + // do nothing + } + + abstract void runTest(); } } --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org