/** * Creates a new ThreadConfinedProxy with the given Strictness (ASSERT_AND_LOG or VALIDATE), initially assigned to the current thread. */ public static <T> T newProxyInstance(Class<T> interfaceClass, T delegate, Strictness strictness) { return newProxyInstance(interfaceClass, delegate, strictness, Thread.currentThread()); }
@Test public void testCurrentThreadCanCreateAndUseSubject() { @SuppressWarnings("unchecked") List<String> subject = ThreadConfinedProxy.newProxyInstance(List.class, new ArrayList<String>(), ThreadConfinedProxy.Strictness.VALIDATE); subject.add(testString); assertEquals(testString, Iterables.getOnlyElement(subject)); }
@Test public void testExplicitThreadCannotAndUseSubjectFromMainThread() throws InterruptedException { final AtomicReference<List<String>> inputReference = new AtomicReference<List<String>>(null); final AtomicBoolean outputReference = new AtomicBoolean(false); Thread childThread = new Thread(() -> { outputReference.set(true); List<String> subjectInChildThread = inputReference.get(); subjectInChildThread.add(testString); // Should fail outputReference.set(false); }); @SuppressWarnings("unchecked") List<String> subject = ThreadConfinedProxy.newProxyInstance(List.class, new ArrayList<String>(), ThreadConfinedProxy.Strictness.VALIDATE); inputReference.set(subject); childThread.start(); childThread.join(10000); assertTrue(outputReference.get()); }
@Test public void testExplicitThreadCanCreateAndUseSubject() throws InterruptedException { final AtomicReference<List<String>> inputReference = new AtomicReference<List<String>>(null); final AtomicBoolean outputReference = new AtomicBoolean(false); Thread childThread = new Thread(() -> { List<String> subjectInChildThread = inputReference.get(); subjectInChildThread.add(testString); if (Iterables.getOnlyElement(subjectInChildThread).equals(testString)) { outputReference.set(Boolean.TRUE); } }); @SuppressWarnings("unchecked") List<String> subject = ThreadConfinedProxy.newProxyInstance(List.class, new ArrayList<String>(), ThreadConfinedProxy.Strictness.VALIDATE, childThread); inputReference.set(subject); childThread.start(); childThread.join(10000); assertTrue(outputReference.get()); }
@Test public void testChildThreadCanDelegateBackToMainThread() throws InterruptedException { final AtomicReference<List<String>> inputReference = new AtomicReference<List<String>>(null); final AtomicInteger outputReference = new AtomicInteger(0); final Thread mainThread = Thread.currentThread(); Thread childThread = new Thread(() -> { outputReference.compareAndSet(0, 1); List<String> subjectInChildThread = inputReference.get(); ThreadConfinedProxy.changeThread(subjectInChildThread, mainThread, Thread.currentThread()); subjectInChildThread.add(testString); if (Iterables.getOnlyElement(subjectInChildThread).equals(testString)) { outputReference.compareAndSet(1, 2); } ThreadConfinedProxy.changeThread(subjectInChildThread, Thread.currentThread(), mainThread); }); @SuppressWarnings("unchecked") List<String> subject = ThreadConfinedProxy.newProxyInstance(List.class, new ArrayList<String>(), ThreadConfinedProxy.Strictness.VALIDATE); inputReference.set(subject); childThread.start(); childThread.join(10000); assertEquals(2, outputReference.get()); // We got delegated back, so we can use subject again assertEquals(testString, Iterables.getOnlyElement(subject)); }
subject = ThreadConfinedProxy.newProxyInstance(List.class, subject, ThreadConfinedProxy.Strictness.VALIDATE); subject = TimingProxy.newProxyInstance(List.class, subject, LoggingOperationTimer.create(log)); subject = ThreadConfinedProxy.newProxyInstance(List.class, subject, ThreadConfinedProxy.Strictness.VALIDATE); subject = new DelegatingArrayListString(subject);
List<String> subject = ThreadConfinedProxy.newProxyInstance(List.class, new ArrayList<String>(), ThreadConfinedProxy.Strictness.VALIDATE); inputReference.set(subject);
/** * Creates a new ThreadConfinedProxy with the given Strictness (ASSERT_AND_LOG or VALIDATE), initially assigned to the current thread. */ public static <T> T newProxyInstance(Class<T> interfaceClass, T delegate, Strictness strictness) { return newProxyInstance(interfaceClass, delegate, strictness, Thread.currentThread()); }
@Test public void testPropagateExceptions() throws SQLException { IThingThatThrows thing = ThreadConfinedProxy.newProxyInstance(IThingThatThrows.class, new ThingThatThrows(), ThreadConfinedProxy.Strictness.VALIDATE); assertEquals(1, thing.doStuff(IThingThatThrows.Behavior.RETURN_ONE)); try { thing.doStuff(IThingThatThrows.Behavior.THROW_RUNTIME); fail("Should throw Runtime Exception"); } catch (RuntimeException e) { // OK } try { thing.doStuff(IThingThatThrows.Behavior.THROW_SQL); fail("Should throw SQL Exception"); } catch (SQLException e) { // OK } }