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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to