Пример #1
0
  public void testResetWhileValid() throws InterruptedException, ExecutionException {
    // Request data from cache
    Query<Integer> q = new TestQuery();
    q.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    q.get();

    // Disable cache
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fTestCache.reset();
          }
        });

    // Check final state
    assertCacheResetWithoutData();
  }
Пример #2
0
  public void testCancelWhilePending2() throws InterruptedException, ExecutionException {
    // Request data from cache
    Query<Integer> q = new TestQuery();
    q.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Cancel the client request
    q.cancel(true);
    try {
      q.get();
      Assert.fail("Expected a cancellation exception");
    } catch (CancellationException e) {
    } // Expected exception;

    assertCacheInvalidAndWithCanceledRM();

    // Simulate retrieval logic that is regularly checking the RM's cancel
    // status and has discovered that the request has been canceled. It
    // technically does not need to explicitly set a cancel status object in
    // the RM, thanks to RequestMonitor.getStatus() automatically returning
    // Status.CANCEL_STATUS when its in the cancel state. So here we
    // simulate the retrieval logic just aborting its operations and
    // completing the RM. Note that it hasn't provided the data to the
    // cache.
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.done();
          }
        });

    assertCacheInvalidAndWithCanceledRM();
  }
Пример #3
0
  public void testCancelWhilePending3() throws InterruptedException, ExecutionException {
    // Request data from cache
    Query<Integer> q = new TestQuery();
    q.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Cancel the client request
    q.cancel(true);
    try {
      q.get();
      Assert.fail("Expected a cancellation exception");
    } catch (CancellationException e) {
    } // Expected exception;

    assertCacheInvalidAndWithCanceledRM();

    // Simulate retrieval logic that is regularly checking the RM's cancel
    // status and has discovered that the request has been canceled. It
    // aborts its processing, sets STATUS.CANCEL_STATUS in the RM and
    // completes it.
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setError(new CancellationException());
            fRetrieveRm.done();
          }
        });

    // Validate that cache didn't accept the result after its RM was canceled
    assertCacheInvalidAndWithCanceledRM();
  }
Пример #4
0
  /**
   * Test behavior when a cache object goes into the "disabled" state while it's in the valid state.
   * The cache remains in the valid state but it loses its data and obtains an error status.
   */
  public void testDisableWhileValid() throws InterruptedException, ExecutionException {
    // Request data from cache
    Query<Integer> q = new TestQuery();
    q.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Complete the request
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    Assert.assertEquals(Integer.valueOf(1), q.get());

    // Disable the cache
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fTestCache.set(null, ERROR_TARGET_RUNNING, true);
          }
        });

    // Check final state
    assertCacheValidWithoutData();
  }
Пример #5
0
  public void testCancelWhilePending() throws InterruptedException, ExecutionException {
    // Request data from cache
    Query<Integer> q = new TestQuery();
    q.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Cancel the client request
    q.cancel(true);
    try {
      q.get();
      Assert.fail("Expected a cancellation exception");
    } catch (CancellationException e) {
    } // Expected exception;

    assertCacheInvalidAndWithCanceledRM();

    // Simulate the retrieval completing successfully despite the cancel
    // request. Perhaps the retrieval logic isn't checking the RM status.
    // Even if it is checking, it may have gotten passed its last checkpoint
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    // Validate that cache didn't accept the result after its RM was canceled
    assertCacheInvalidAndWithCanceledRM();
  }
Пример #6
0
  /**
   * Test behavior when a cache object goes into the "disabled" state while an update request is
   * ongoing. The subsequent completion of the request should have no effect on the cache
   */
  public void testDisableWhilePending() throws InterruptedException, ExecutionException {
    // Request data from cache
    Query<Integer> q = new TestQuery();
    q.invoke();

    // Disable the cache
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fTestCache.set(null, ERROR_TARGET_RUNNING, true);
          }
        });

    assertCacheValidWithoutData();

    // Complete the retrieve RM. Note that the disabling of the cache above
    // disassociates it from its retrieval RM. Thus regardless of how that
    // request completes, it does not affect the cache.
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    // Validate that cache is still disabled without data.
    assertCacheValidWithoutData();
  }
Пример #7
0
  public void testGetWithManyClients() throws InterruptedException, ExecutionException {
    // Check initial state
    Assert.assertFalse(fTestCache.isValid());

    // Request data from cache
    List<Query<Integer>> qList = new ArrayList<Query<Integer>>();
    for (int i = 0; i < 10; i++) {
      Query<Integer> q = new TestQuery();
      q.invoke();
      qList.add(q);
    }
    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Check state while waiting for data
    Assert.assertFalse(fTestCache.isValid());

    // Set the data to the callback
    Protocol.invokeLater(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    for (Query<Integer> q : qList) {
      Assert.assertEquals(1, (int) q.get());
    }

    // Check final state
    assertCacheValidWithData(1);
  }
Пример #8
0
  public void testGetWithCompletionDelay() throws InterruptedException, ExecutionException {
    // Check initial state
    Assert.assertFalse(fTestCache.isValid());

    // Request data from cache
    Query<Integer> q = new TestQuery();
    q.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Check state while waiting for data
    Assert.assertFalse(fTestCache.isValid());

    // Set the data to the callback
    Protocol.invokeLater(
        100,
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    Assert.assertEquals(1, (int) q.get());

    // Check final state
    assertCacheValidWithData(1);
  }
Пример #9
0
  public void testGet() throws InterruptedException, ExecutionException {
    // Request data from cache
    Query<Integer> q = new TestQuery();

    // Check initial state
    Assert.assertFalse(fTestCache.isValid());

    q.invoke();

    // Wait until the cache requests the data.
    waitForRetrieveRm();

    // Check state while waiting for data
    Assert.assertFalse(fTestCache.isValid());

    // Complete the cache's retrieve data request.
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();

            // Check that the data is available in the cache immediately
            // (in the same dispatch cycle).
            Assert.assertEquals(1, (int) fTestCache.getData());
            Assert.assertTrue(fTestCache.isValid());
          }
        });

    Assert.assertEquals(1, (int) q.get());

    // Re-check final state
    assertCacheValidWithData(1);
  }
Пример #10
0
  public void testCancelWhilePendingWithTwoClients()
      throws InterruptedException, ExecutionException {

    // Request data from cache. Use an additional invokeAndWait to
    // ensure both update requests are initiated before we wait
    // for retrieval to start
    Query<Integer> q1 = new TestQuery();
    q1.invoke();
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {}
        });

    // Request data from cache again
    Query<Integer> q2 = new TestQuery();
    q2.invoke();
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {}
        });

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Cancel the first client request
    q1.cancel(true);
    try {
      q1.get();
      Assert.fail("Expected a cancellation exception");
    } catch (CancellationException e) {
    } // Expected exception;
    assertCacheWaiting();

    // Cancel the second request
    q2.cancel(true);
    try {
      q2.get();
      Assert.fail("Expected a cancellation exception");
    } catch (CancellationException e) {
    } // Expected exception;

    assertCacheInvalidAndWithCanceledRM();

    // Completed the retrieve RM
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    // Validate that cache didn't accept the result after its RM was canceled
    assertCacheInvalidAndWithCanceledRM();
  }
Пример #11
0
  public void testSetAndReset() throws InterruptedException, ExecutionException {
    fTestCache =
        new TestCache() {
          @Override
          protected void handleCompleted(Integer data, Throwable error, boolean canceled) {
            if (!canceled) {
              // USE 'false' for valid argument.  Cache should be left in
              // invalid state.
              set(data, error, false);
            }
          }
        };

    // Request data from cache
    Query<Integer> q = new TestQuery();
    q.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    // Query should complete with the data from request monitor.
    try {
      q.get();
      Assert.fail("Expected InvalidCacheException");
    } catch (ExecutionException e) {
    }

    // No need to disable cache, it should already be disabled.

    // Check final state
    assertCacheResetWithoutData();
  }
Пример #12
0
  /**
   * Test behavior when a cache object is asked to update itself after it has become "disabled".
   * Since a "disabled" cache is in the valid state, a request for it to update from the source
   * should be ignored. However, the client callback is not completed until next state change in
   * cache.
   */
  public void testDisableBeforeRequest() throws InterruptedException, ExecutionException {
    // Disable the cache
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fTestCache.set(null, ERROR_TARGET_RUNNING, true);
          }
        });

    assertCacheValidWithoutData();

    // Try to request data from cache
    Query<Integer> q = new TestQuery();
    q.invoke();

    Thread.sleep(100);

    // Retrieval should never have been made.
    Assert.assertEquals(null, fRetrieveRm);

    // Disable the cache.  This should trigger the qery to complete.
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fTestCache.set(null, new Throwable("Cache invalid"), false);
          }
        });

    // The cache has no data so the query should have failed
    try {
      q.get();
      Assert.fail("expected an exeption");
    } catch (ExecutionException e) {
      // expected the exception
    }
  }
Пример #13
0
  public void testCancelWhilePendingWithManyClients()
      throws InterruptedException, ExecutionException {
    // Request data from cache
    List<Query<Integer>> qList = new ArrayList<Query<Integer>>();
    for (int i = 0; i < 10; i++) {
      Query<Integer> q = new TestQuery();
      q.invoke();
      Protocol.invokeAndWait(
          new Runnable() {
            public void run() {}
          });
      qList.add(q);
    }

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Cancel some client requests
    int[] toCancel = new int[] {0, 2, 5, 9};
    for (int i = 0; i < toCancel.length; i++) {

      // Cancel request and verify that its canceled
      Query<Integer> q = qList.get(toCancel[i]);
      q.cancel(true);
      try {
        q.get();
        Assert.fail("Expected a cancellation exception");
      } catch (CancellationException e) {
      } // Expected exception;
      qList.set(toCancel[i], null);

      assertCacheWaiting();
    }

    // Replace canceled requests with new ones
    for (int i = 0; i < toCancel.length; i++) {
      Query<Integer> q = new TestQuery();
      q.invoke();
      Protocol.invokeAndWait(
          new Runnable() {
            public void run() {}
          });
      qList.set(toCancel[i], q);
      assertCacheWaiting();
    }

    // Now cancel all requests
    for (int i = 0; i < (qList.size() - 1); i++) {
      // Validate that cache is still waiting and is not canceled
      assertCacheWaiting();
      qList.get(i).cancel(true);
    }
    qList.get(qList.size() - 1).cancel(true);
    assertCacheInvalidAndWithCanceledRM();

    // Completed the retrieve RM
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    // Validate that cache didn't accept the result after its RM was canceled
    assertCacheInvalidAndWithCanceledRM();
  }
Пример #14
0
  /**
   * This test forces a race condition where a client that requested data cancels. While shortly
   * after a second client starts a new request. The first request's cancel should not interfere
   * with the second request.
   */
  public void testCancelAfterCompletedRaceCondition()
      throws InterruptedException, ExecutionException {

    // Create a client request with a badly behaved cancel implementation.
    final Callback[] rmBad = new Callback[1];
    final boolean qBadCanceled[] = new boolean[] {false};
    Query<Integer> qBad =
        new Query<Integer>() {
          @Override
          protected void execute(final DataCallback<Integer> rm) {
            rmBad[0] =
                new Callback(rm) {
                  @Override
                  public synchronized void removeCancelListener(ICanceledListener listener) {
                    // Do not add the cancel listener so that the cancel request is not
                    // propagated to the cache.
                  }

                  @Override
                  public void cancel() {
                    if (qBadCanceled[0]) {
                      super.cancel();
                    }
                  }

                  @Override
                  public synchronized boolean isCanceled() {
                    return qBadCanceled[0];
                  }

                  @Override
                  public synchronized void done() {
                    // Avoid clearing cancel listeners list
                  };

                  @Override
                  protected void handleSuccess() {
                    rm.setData(fTestCache.getData());
                    rm.done();
                  };
                };

            fTestCache.wait(rmBad[0]);
          }
        };
    qBad.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Reset the cache
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm = null;
            fTestCache.set(null, null, true);
            fTestCache.reset();
          }
        });

    Query<Integer> qGood = new TestQuery();
    qGood.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    qBadCanceled[0] = true;
    rmBad[0].cancel();

    Assert.assertFalse(fRetrieveRm.isCanceled());

    // Completed the retrieve RM
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    qGood.get();

    assertCacheValidWithData(1);
  }
Пример #15
0
  public void testCancelWhilePendingWithoutClientNotification()
      throws InterruptedException, ExecutionException {
    final boolean canceledCalled[] = new boolean[] {false};

    fTestCache =
        new TestCache() {
          protected synchronized void canceled() {
            canceledCalled[0] = true;
          };
        };

    // Request data from cache
    Query<Integer> q =
        new Query<Integer>() {
          @Override
          protected void execute(final DataCallback<Integer> rm) {

            fTestCache.wait(
                new Callback(rm) {
                  @Override
                  public synchronized void addCancelListener(ICanceledListener listener) {
                    // Do not add the cancel listener so that the cancel request is not
                    // propagated to the cache.
                  }

                  @Override
                  protected void handleSuccess() {
                    rm.setData(fTestCache.getData());
                    rm.done();
                  }
                });
          }
        };
    q.invoke();

    // Wait until the cache starts data retrieval.
    waitForRetrieveRm();

    // Cancel the client request
    q.cancel(true);

    assertCacheInvalidAndWithCanceledRM();

    // AbstractCache.canceled() should be called after isCanceled()
    // discovers that the client has canceled its request.  The canceled() method is
    // called in a separate dispatch cycle, so we have to wait one cycle of the executor
    // after is canceled is called.
    fRetrieveRm.isCanceled();
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {}
        });
    Assert.assertTrue(canceledCalled[0]);

    try {
      q.get();
      Assert.fail("Expected a cancellation exception");
    } catch (CancellationException e) {
    } // Expected exception;

    // Completed the retrieve RM
    Protocol.invokeAndWait(
        new Runnable() {
          public void run() {
            fRetrieveRm.setData(1);
            fRetrieveRm.done();
          }
        });

    // Validate that cache didn't accept the result after its RM was canceled
    assertCacheInvalidAndWithCanceledRM();
  }