Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'tests/plugins/org.eclipse.tcf.debug.test/src/org/eclipse/tcf/debug/test/CacheTests.java')
-rw-r--r--tests/plugins/org.eclipse.tcf.debug.test/src/org/eclipse/tcf/debug/test/CacheTests.java832
1 files changed, 832 insertions, 0 deletions
diff --git a/tests/plugins/org.eclipse.tcf.debug.test/src/org/eclipse/tcf/debug/test/CacheTests.java b/tests/plugins/org.eclipse.tcf.debug.test/src/org/eclipse/tcf/debug/test/CacheTests.java
new file mode 100644
index 000000000..5021e4983
--- /dev/null
+++ b/tests/plugins/org.eclipse.tcf.debug.test/src/org/eclipse/tcf/debug/test/CacheTests.java
@@ -0,0 +1,832 @@
+/***********************************************s********************************
+ * Copyright (c) 2006 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.debug.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.eclipse.tcf.debug.test.util.Callback;
+import org.eclipse.tcf.debug.test.util.CallbackCache;
+import org.eclipse.tcf.debug.test.util.DataCallback;
+import org.eclipse.tcf.debug.test.util.Query;
+import org.eclipse.tcf.protocol.Protocol;
+
+/**
+ * Tests that exercise the DataCache object.
+ */
+public class CacheTests extends TestCase {
+
+ TestCache fTestCache;
+ DataCallback<Integer> fRetrieveRm;
+
+ class TestCache extends CallbackCache<Integer> {
+
+ @Override
+ protected void retrieve(DataCallback<Integer> rm) {
+ synchronized(CacheTests.this) {
+ fRetrieveRm = rm;
+ CacheTests.this.notifyAll();
+ }
+ }
+
+ @Override
+ protected void handleCompleted(Integer data, Throwable error, boolean canceled) {
+ // TODO Auto-generated method stub
+ super.handleCompleted(data, error, canceled);
+ }
+
+ }
+
+ class TestQuery extends Query<Integer> {
+ @Override
+ protected void execute(final DataCallback<Integer> rm) {
+ fTestCache.update(new DataCallback<Integer>(rm) {
+ @Override
+ protected void handleSuccess() {
+ rm.setData(fTestCache.getData());
+ rm.done();
+ }
+ });
+ }
+ }
+
+ /**
+ * There's no rule on how quickly the cache has to start data retrieval
+ * after it has been requested. It could do it immediately, or it could
+ * wait a dispatch cycle, etc..
+ */
+ private void waitForRetrieveRm() {
+ synchronized(this) {
+ while (fRetrieveRm == null) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+ }
+ }
+
+ public void setUp() throws ExecutionException, InterruptedException {
+ fTestCache = new TestCache();
+ }
+
+ public void tearDown() throws ExecutionException, InterruptedException {
+ fRetrieveRm = null;
+ fTestCache = null;
+ }
+
+ private void assertCacheValidWithData(Object data) {
+ Assert.assertTrue(fTestCache.isValid());
+ Assert.assertEquals(data, fTestCache.getData());
+ Assert.assertNull(fTestCache.getError());
+ }
+
+ private void assertCacheResetWithoutData() {
+ 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) {}
+ }
+
+ private void assertCacheValidWithoutData() {
+ Assert.assertTrue(fTestCache.isValid());
+ Assert.assertEquals(null, fTestCache.getData());
+ Assert.assertNotNull(fTestCache.getError());
+ Assert.assertEquals(fTestCache.getError(), ERROR_TARGET_RUNNING);
+ }
+
+ private void assertCacheWaiting() {
+ 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.assertFalse(fRetrieveRm.isCanceled());
+ }
+
+ 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());
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ public void testGetWithTwoClients() throws InterruptedException, ExecutionException {
+ // Check initial state
+ Assert.assertFalse(fTestCache.isValid());
+
+ // Request data from cache
+ Query<Integer> q1 = new TestQuery();
+ q1.invoke();
+
+ // Request data from cache again
+ Query<Integer> q2 = new TestQuery();
+ q2.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(new Runnable() {
+ public void run() {
+ fRetrieveRm.setData(1);
+ fRetrieveRm.done();
+
+ }
+ });
+
+ Assert.assertEquals(1, (int)q1.get());
+ Assert.assertEquals(1, (int)q2.get());
+
+ // Check final state
+ assertCacheValidWithData(1);
+ }
+
+ 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);
+ }
+
+ private static final Exception ERROR_TARGET_RUNNING = new Exception("Target is running");
+
+ // DISABLE TESTS
+ //
+ // We say a cache is "disabled" when its most recent attempt to update from
+ // the source failed. Also, a cache may make itself disabled as a reaction
+ // to a state change notification from its source (e.g., the target
+ // resumed). In either case, the cache is in the valid state but it has no
+ // data and the status reflects an error. Keep in mind that the 'valid'
+ // state is not a reflection of the quality of the data, but merely whether
+ // the cache object's representation of the data is stale or
+ // not. A transaction that uses a "disabled" cache object will simply fail;
+ // it will not ask the cache to update its data from the source. Only a
+ // change in the source's state would cause the cache to put itself back in
+ // the invalid state, thus opening the door to another update.
+
+ /**
+ * 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
+ }
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * 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();
+ }
+
+ public void testSetWithValue() throws InterruptedException, ExecutionException {
+ // Disable the cache
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ fTestCache.set(2, null, true);
+ }
+ });
+
+ // Validate that cache is disabled without data.
+ assertCacheValidWithData(2);
+ }
+
+
+ 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();
+ }
+
+ 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();
+ }
+
+ 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();
+ }
+
+ 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.update(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();
+ }
+
+ /**
+ * 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.update(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);
+ }
+
+ 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();
+ }
+
+ 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();
+ }
+
+ 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();
+ }
+
+ 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();
+ }
+
+} \ No newline at end of file

Back to the top