mobile/android/tests/background/junit3/src/common/TestWaitHelper.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 package org.mozilla.gecko.background.common;
     6 import junit.framework.AssertionFailedError;
     8 import org.mozilla.gecko.background.helpers.AndroidSyncTestCase;
     9 import org.mozilla.gecko.background.testhelpers.WaitHelper;
    10 import org.mozilla.gecko.background.testhelpers.WaitHelper.InnerError;
    11 import org.mozilla.gecko.background.testhelpers.WaitHelper.TimeoutError;
    12 import org.mozilla.gecko.sync.ThreadPool;
    14 public class TestWaitHelper extends AndroidSyncTestCase {
    15   private static final String ERROR_UNIQUE_IDENTIFIER = "error unique identifier";
    17   public static int NO_WAIT    = 1;               // Milliseconds.
    18   public static int SHORT_WAIT = 100;             // Milliseconds.
    19   public static int LONG_WAIT  = 3 * SHORT_WAIT;
    21   private Object notifyMonitor = new Object();
    22   // Guarded by notifyMonitor.
    23   private boolean performNotifyCalled      = false;
    24   private boolean performNotifyErrorCalled = false;
    25   private void setPerformNotifyCalled() {
    26     synchronized (notifyMonitor) {
    27       performNotifyCalled = true;
    28     }
    29   }
    30   private void setPerformNotifyErrorCalled() {
    31     synchronized (notifyMonitor) {
    32       performNotifyErrorCalled = true;
    33     }
    34   }
    35   private void resetNotifyCalled() {
    36     synchronized (notifyMonitor) {
    37       performNotifyCalled      = false;
    38       performNotifyErrorCalled = false;
    39     }
    40   }
    41   private void assertBothCalled() {
    42     synchronized (notifyMonitor) {
    43       assertTrue(performNotifyCalled);
    44       assertTrue(performNotifyErrorCalled);
    45     }
    46   }
    47   private void assertErrorCalled() {
    48     synchronized (notifyMonitor) {
    49       assertFalse(performNotifyCalled);
    50       assertTrue(performNotifyErrorCalled);
    51     }
    52   }
    53   private void assertCalled() {
    54     synchronized (notifyMonitor) {
    55       assertTrue(performNotifyCalled);
    56       assertFalse(performNotifyErrorCalled);
    57     }
    58   }
    60   public WaitHelper waitHelper;
    62   public TestWaitHelper() {
    63     super();
    64   }
    66   public void setUp() {
    67     WaitHelper.resetTestWaiter();
    68     waitHelper = WaitHelper.getTestWaiter();
    69     resetNotifyCalled();
    70   }
    72   public void tearDown() {
    73     assertTrue(waitHelper.isIdle());
    74   }
    76   public Runnable performNothingRunnable() {
    77     return new Runnable() {
    78       public void run() {
    79       }
    80     };
    81   }
    83   public Runnable performNotifyRunnable() {
    84     return new Runnable() {
    85       public void run() {
    86         setPerformNotifyCalled();
    87         waitHelper.performNotify();
    88       }
    89     };
    90   }
    92   public Runnable performNotifyAfterDelayRunnable(final int delayInMillis) {
    93     return new Runnable() {
    94       public void run() {
    95         try {
    96           Thread.sleep(delayInMillis);
    97         } catch (InterruptedException e) {
    98           fail("Interrupted.");
    99         }
   101         setPerformNotifyCalled();
   102         waitHelper.performNotify();
   103       }
   104     };
   105   }
   107   public Runnable performNotifyErrorRunnable() {
   108     return new Runnable() {
   109       public void run() {
   110         setPerformNotifyCalled();
   111         waitHelper.performNotify(new AssertionFailedError(ERROR_UNIQUE_IDENTIFIER));
   112       }
   113     };
   114   }
   116   public Runnable inThreadPool(final Runnable runnable) {
   117     return new Runnable() {
   118       @Override
   119       public void run() {
   120         ThreadPool.run(runnable);
   121       }
   122     };
   123   }
   125   public Runnable inThread(final Runnable runnable) {
   126     return new Runnable() {
   127       @Override
   128       public void run() {
   129         new Thread(runnable).start();
   130       }
   131     };
   132   }
   134   protected void expectAssertionFailedError(Runnable runnable) {
   135     try {
   136       waitHelper.performWait(runnable);
   137     } catch (InnerError e) {
   138       AssertionFailedError inner = (AssertionFailedError)e.innerError;
   139       setPerformNotifyErrorCalled();
   140       String message = inner.getMessage();
   141       assertTrue("Expected '" + message + "' to contain '" + ERROR_UNIQUE_IDENTIFIER + "'",
   142                  message.contains(ERROR_UNIQUE_IDENTIFIER));
   143     }
   144   }
   146   protected void expectAssertionFailedErrorAfterDelay(int wait, Runnable runnable) {
   147     try {
   148       waitHelper.performWait(wait, runnable);
   149     } catch (InnerError e) {
   150       AssertionFailedError inner = (AssertionFailedError)e.innerError;
   151       setPerformNotifyErrorCalled();
   152       String message = inner.getMessage();
   153       assertTrue("Expected '" + message + "' to contain '" + ERROR_UNIQUE_IDENTIFIER + "'",
   154                  message.contains(ERROR_UNIQUE_IDENTIFIER));
   155     }
   156   }
   158   public void testPerformWait() {
   159     waitHelper.performWait(performNotifyRunnable());
   160     assertCalled();
   161   }
   163   public void testPerformWaitInThread() {
   164     waitHelper.performWait(inThread(performNotifyRunnable()));
   165     assertCalled();
   166   }
   168   public void testPerformWaitInThreadPool() {
   169     waitHelper.performWait(inThreadPool(performNotifyRunnable()));
   170     assertCalled();
   171   }
   173   public void testPerformTimeoutWait() {
   174     waitHelper.performWait(SHORT_WAIT, performNotifyRunnable());
   175     assertCalled();
   176   }
   178   public void testPerformTimeoutWaitInThread() {
   179     waitHelper.performWait(SHORT_WAIT, inThread(performNotifyRunnable()));
   180     assertCalled();
   181   }
   183   public void testPerformTimeoutWaitInThreadPool() {
   184     waitHelper.performWait(SHORT_WAIT, inThreadPool(performNotifyRunnable()));
   185     assertCalled();
   186   }
   188   public void testPerformErrorWaitInThread() {
   189     expectAssertionFailedError(inThread(performNotifyErrorRunnable()));
   190     assertBothCalled();
   191   }
   193   public void testPerformErrorWaitInThreadPool() {
   194     expectAssertionFailedError(inThreadPool(performNotifyErrorRunnable()));
   195     assertBothCalled();
   196   }
   198   public void testPerformErrorTimeoutWaitInThread() {
   199     expectAssertionFailedErrorAfterDelay(SHORT_WAIT, inThread(performNotifyErrorRunnable()));
   200     assertBothCalled();
   201   }
   203   public void testPerformErrorTimeoutWaitInThreadPool() {
   204     expectAssertionFailedErrorAfterDelay(SHORT_WAIT, inThreadPool(performNotifyErrorRunnable()));
   205     assertBothCalled();
   206   }
   208   public void testTimeout() {
   209     try {
   210       waitHelper.performWait(SHORT_WAIT, performNothingRunnable());
   211     } catch (TimeoutError e) {
   212       setPerformNotifyErrorCalled();
   213       assertEquals(SHORT_WAIT, e.waitTimeInMillis);
   214     }
   215     assertErrorCalled();
   216   }
   218   /**
   219    * This will pass.  The sequence in the main thread is:
   220    * - A short delay.
   221    * - performNotify is called.
   222    * - performWait is called and immediately finds that performNotify was called before.
   223    */
   224   public void testDelay() {
   225     try {
   226       waitHelper.performWait(1, performNotifyAfterDelayRunnable(SHORT_WAIT));
   227     } catch (AssertionFailedError e) {
   228       setPerformNotifyErrorCalled();
   229       assertTrue(e.getMessage(), e.getMessage().contains("TIMEOUT"));
   230     }
   231     assertCalled();
   232   }
   234   public Runnable performNotifyMultipleTimesRunnable() {
   235     return new Runnable() {
   236       public void run() {
   237         waitHelper.performNotify();
   238         setPerformNotifyCalled();
   239         waitHelper.performNotify();
   240       }
   241     };
   242   }
   244   public void testPerformNotifyMultipleTimesFails() {
   245     try {
   246       waitHelper.performWait(NO_WAIT, performNotifyMultipleTimesRunnable()); // Not run on thread, so runnable executes before performWait looks for notifications.
   247     } catch (WaitHelper.MultipleNotificationsError e) {
   248       setPerformNotifyErrorCalled();
   249     }
   250     assertBothCalled();
   251     assertFalse(waitHelper.isIdle()); // First perform notify should be hanging around.
   252     waitHelper.performWait(NO_WAIT, performNothingRunnable());
   253   }
   255   public void testNestedWaitsAndNotifies() {
   256       waitHelper.performWait(new Runnable() {
   257         @Override
   258         public void run() {
   259           waitHelper.performWait(new Runnable() {
   260             public void run() {
   261               setPerformNotifyCalled();
   262               waitHelper.performNotify();
   263             }
   264           });
   265           setPerformNotifyErrorCalled();
   266           waitHelper.performNotify();
   267         }
   268       });
   269     assertBothCalled();
   270   }
   272   public void testAssertIsReported() {
   273     try {
   274       waitHelper.performWait(1, new Runnable() {
   275         @Override
   276         public void run() {
   277           assertTrue("unique identifier", false);
   278         }
   279       });
   280     } catch (AssertionFailedError e) {
   281       setPerformNotifyErrorCalled();
   282       assertTrue(e.getMessage(), e.getMessage().contains("unique identifier"));
   283     }
   284     assertErrorCalled();
   285   }
   287   /**
   288    * The inner wait will timeout, but the outer wait will succeed.  The sequence in the helper thread is:
   289    * - A short delay.
   290    * - performNotify is called.
   291    *
   292    * The sequence in the main thread is:
   293    * - performWait is called and times out because the helper thread does not call
   294    *   performNotify quickly enough.
   295    */
   296   public void testDelayInThread() throws InterruptedException {
   297     waitHelper.performWait(new Runnable() {
   298       @Override
   299       public void run() {
   300         try {
   301           waitHelper.performWait(NO_WAIT, inThread(new Runnable() {
   302             public void run() {
   303               try {
   304                 Thread.sleep(SHORT_WAIT);
   305               } catch (InterruptedException e) {
   306                 fail("Interrupted.");
   307               }
   309               setPerformNotifyCalled();
   310               waitHelper.performNotify();
   311             }
   312           }));
   313         } catch (WaitHelper.TimeoutError e) {
   314           setPerformNotifyErrorCalled();
   315           assertEquals(NO_WAIT, e.waitTimeInMillis);
   316         }
   317       }
   318     });
   319     assertBothCalled();
   320   }
   322   /**
   323    * The inner wait will timeout, but the outer wait will succeed.  The sequence in the helper thread is:
   324    * - A short delay.
   325    * - performNotify is called.
   326    *
   327    * The sequence in the main thread is:
   328    * - performWait is called and times out because the helper thread does not call
   329    *   performNotify quickly enough.
   330    */
   331   public void testDelayInThreadPool() throws InterruptedException {
   332     waitHelper.performWait(new Runnable() {
   333       @Override
   334       public void run() {
   335         try {
   336           waitHelper.performWait(NO_WAIT, inThreadPool(new Runnable() {
   337             public void run() {
   338               try {
   339                 Thread.sleep(SHORT_WAIT);
   340               } catch (InterruptedException e) {
   341                 fail("Interrupted.");
   342               }
   344               setPerformNotifyCalled();
   345               waitHelper.performNotify();
   346             }
   347           }));
   348         } catch (WaitHelper.TimeoutError e) {
   349           setPerformNotifyErrorCalled();
   350           assertEquals(NO_WAIT, e.waitTimeInMillis);
   351         }
   352       }
   353     });
   354     assertBothCalled();
   355   }
   356 }

mercurial