/** @throws Exception */
  @Test
  public void testSerialization() throws Exception {
    // a simple worker that acquires a lock on page 5
    class Locker extends Thread {
      private final PageAccessSynchronizer sync;

      public Locker(PageAccessSynchronizer sync) {
        this.sync = sync;
      }

      @Override
      public void run() {
        sync.lockPage(5);
      }
    }

    // set up a synchronizer and lock page 5 with locker1
    final Duration timeout = Duration.seconds(30);
    final PageAccessSynchronizer sync = new PageAccessSynchronizer(timeout);
    Locker locker1 = new Locker(sync);

    final long start = System.currentTimeMillis();
    locker1.run();

    // make sure we can serialize the synchronizer

    final PageAccessSynchronizer sync2 = WicketObjects.cloneObject(sync);
    assertTrue(sync != sync2);

    // make sure the clone does not retain locks by attempting to lock page locked by locker1 in
    // locker2
    Locker locker2 = new Locker(sync2);
    locker2.run();
    assertTrue(Duration.milliseconds(System.currentTimeMillis() - start).lessThan(timeout));
  }
 /**
  * Verifies that getting a value which is expired will return <code>null</code>.
  *
  * @throws Exception
  */
 @Test
 public void getExpiredValue() throws Exception {
   Time start = Time.now();
   Duration timeout = Duration.milliseconds(50);
   StoredResponsesMap map = new StoredResponsesMap(1000, timeout);
   assertEquals(0, map.size());
   map.put("1", new BufferedWebResponse(null));
   assertEquals(1, map.size());
   TimeUnit.MILLISECONDS.sleep(
       timeout.getMilliseconds() * 2); // sleep for twice longer than the timeout
   assertTrue("The timeout has passed.", Time.now().subtract(start).compareTo(timeout) == 1);
   Object value = map.get("1");
   assertNull(value);
 }
  /** @throws Exception */
  @Test
  public void testBlocking() throws Exception {
    final PageAccessSynchronizer sync = new PageAccessSynchronizer(Duration.seconds(5));
    final Duration hold = Duration.seconds(1);
    final Time t1locks[] = new Time[1];
    final Time t2locks[] = new Time[1];

    class T1 extends Thread {
      @Override
      public void run() {
        sync.lockPage(1);
        t1locks[0] = Time.now();
        hold.sleep();
        sync.unlockAllPages();
      }
    }

    class T2 extends Thread {
      @Override
      public void run() {
        sync.lockPage(1);
        t2locks[0] = Time.now();
        sync.unlockAllPages();
      }
    }

    T1 t1 = new T1();
    t1.setName("t1");
    T2 t2 = new T2();
    t2.setName("t2");
    t1.start();
    Duration.milliseconds(100).sleep();
    t2.start();

    t1.join();
    t2.join();

    assertTrue(!t2locks[0].before(t1locks[0].add(hold)));
  }
 /**
  * Constructor.
  *
  * @param status job status to check
  */
 public WorkflowTransformationJobStatusUpdatingBehaviour(JobStatus status) {
   super(Duration.milliseconds(1000));
   this.status = status;
 }