/*******************************************************************************
* Copyright (c) 2006, 2012 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.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.eclipse.tcf.debug.test.util.Callback;
import org.eclipse.tcf.debug.test.util.Callback.ICanceledListener;
import org.eclipse.tcf.debug.test.util.DataCallback;
import org.eclipse.tcf.debug.test.util.Query;
import org.eclipse.tcf.protocol.Protocol;
import org.junit.Test;
/**
* Tests that exercise the Query object.
*/
public class QueryTests extends TestCase{
public void testSimpleGet() throws InterruptedException, ExecutionException {
Query<Integer> q = new Query<Integer>() {
@Override
protected void execute(DataCallback<Integer> rm) {
rm.setData(1);
rm.done();
}
};
// Check initial state
Assert.assertTrue(!q.isDone());
Assert.assertTrue(!q.isCancelled());
q.invoke();
Assert.assertEquals(1, (int)q.get());
// Check final state
Assert.assertTrue(q.isDone());
Assert.assertTrue(!q.isCancelled());
}
public void testGetError() throws InterruptedException, ExecutionException {
final String error_message = "Test Error";
Query<Integer> q = new Query<Integer>() {
@Override
protected void execute(DataCallback<Integer> rm) {
rm.setError(new Throwable(error_message)); //$NON-NLS-1$
rm.done();
}
};
// Check initial state
Assert.assertTrue(!q.isDone());
Assert.assertTrue(!q.isCancelled());
q.invoke();
try {
q.get();
Assert.fail("Expected exception");
} catch (ExecutionException e) {
Assert.assertEquals(e.getCause().getMessage(), error_message);
}
// Check final state
Assert.assertTrue(q.isDone());
Assert.assertTrue(!q.isCancelled());
}
public void testGetWithMultipleDispatches() throws InterruptedException, ExecutionException {
Query<Integer> q = new Query<Integer>() {
@Override
protected void execute(final DataCallback<Integer> rm) {
Protocol.invokeLater(new Runnable() {
public void run() {
rm.setData(1);
rm.done();
}
@Override
public String toString() { return super.toString() + "\n getWithMultipleDispatchesTest() second runnable"; } //$NON-NLS-1$
});
}
@Override
public String toString() { return super.toString() + "\n getWithMultipleDispatchesTest() first runnable (query)"; } //$NON-NLS-1$
};
q.invoke();
Assert.assertEquals(1, (int)q.get());
}
public void testExceptionOnGet() throws InterruptedException, ExecutionException {
Query<Integer> q = new Query<Integer>() {
@Override
protected void execute(final DataCallback<Integer> rm) {
rm.setError(new Throwable("")); //$NON-NLS-1$
rm.done();
}
};
q.invoke();
try {
q.get();
Assert.fail("Excpected ExecutionExeption");
} catch (ExecutionException e) {
} finally {
Assert.assertTrue(q.isDone());
Assert.assertTrue(!q.isCancelled());
}
}
public void testCancelBeforeWaiting() throws InterruptedException, ExecutionException {
final Query<Integer> q = new Query<Integer>() {
@Override protected void execute(final DataCallback<Integer> rm) {
Assert.fail("Query was cancelled, it should not be called."); //$NON-NLS-1$
rm.done();
}
};
// Cancel before invoking the query.
q.cancel(false);
Assert.assertTrue(q.isDone());
Assert.assertTrue(q.isCancelled());
// Start the query.
q.invoke();
// Block to retrieve data
try {
q.get();
} catch (CancellationException e) {
return; // Success
} finally {
Assert.assertTrue(q.isDone());
Assert.assertTrue(q.isCancelled());
}
Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$
}
public void testCancelWhileWaiting() throws InterruptedException, ExecutionException {
final DataCallback<?>[] rmHolder = new DataCallback<?>[1];
final Boolean[] cancelCalled = new Boolean[] { Boolean.FALSE };
final Query<Integer> q = new Query<Integer>() {
@Override protected void execute(final DataCallback<Integer> rm) {
synchronized (rmHolder) {
rmHolder[0] = rm;
rmHolder.notifyAll();
}
}
};
// Start the query.
q.invoke();
// Wait until the query is started
synchronized (rmHolder) {
while(rmHolder[0] == null) {
rmHolder.wait();
}
}
// Add a cancel listener to the query RM
rmHolder[0].addCancelListener(new ICanceledListener() {
public void requestCanceled(Callback rm) {
cancelCalled[0] = Boolean.TRUE;
}
});
// Cancel running request.
q.cancel(false);
Assert.assertTrue(cancelCalled[0]);
Assert.assertTrue(rmHolder[0].isCanceled());
Assert.assertTrue(q.isCancelled());
Assert.assertTrue(q.isDone());
// Retrieve data
try {
q.get();
} catch (CancellationException e) {
return; // Success
} finally {
Assert.assertTrue(q.isDone());
Assert.assertTrue(q.isCancelled());
}
// Complete rm and query.
@SuppressWarnings("unchecked")
DataCallback<Integer> drm = (DataCallback<Integer>)rmHolder[0];
drm.setData(new Integer(1));
rmHolder[0].done();
// Try to retrieve data again, it should still result in
// cancellation exception.
try {
q.get();
} catch (CancellationException e) {
return; // Success
} finally {
Assert.assertTrue(q.isDone());
Assert.assertTrue(q.isCancelled());
}
Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$
}
public void testGetTimeout() throws InterruptedException, ExecutionException {
final Query<Integer> q = new Query<Integer>() {
@Override
protected void execute(final DataCallback<Integer> rm) {
// Call done with a delay of 1 second, to avoid stalling the tests.
Protocol.invokeLater(
60000,
new Runnable() {
public void run() { rm.done(); }
});
}
};
q.invoke();
// Note: no point in checking isDone() and isCancelled() here, because
// the value could change on timing.
try {
q.get(1, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
return; // Success
} finally {
Assert.assertFalse("Query should not be done yet, it should have timed out first.", q.isDone()); //$NON-NLS-1$
}
Assert.assertTrue("TimeoutException should have been thrown", false); //$NON-NLS-1$
}
}