Example #1
0
 private void assertCacheInvalidAndWithCanceledRM() {
   Assert.assertFalse(fTestCache.isValid());
   try {
     fTestCache.getData();
     Assert.fail("Expected an IllegalStateException");
   } catch (IllegalStateException e) {
   }
   try {
     fTestCache.getError();
     Assert.fail("Expected an IllegalStateException");
   } catch (IllegalStateException e) {
   }
   Assert.assertTrue(fRetrieveRm.isCanceled());
 }
Example #2
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);
  }
Example #3
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();
  }