001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tctest;
006:
007: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
008:
009: import com.tc.object.config.ConfigVisitor;
010: import com.tc.object.config.TransparencyClassSpec;
011: import com.tc.object.config.spec.CyclicBarrierSpec;
012: import com.tc.object.tx.UnlockedSharedObjectException;
013: import com.tc.simulator.app.ApplicationConfig;
014: import com.tc.simulator.listener.ListenerProvider;
015: import com.tc.util.Assert;
016: import com.tctest.runner.AbstractErrorCatchingTransparentApp;
017:
018: import java.util.ArrayList;
019: import java.util.List;
020:
021: /**
022: * Test for CDV-190 - auto-synchronize feature
023: *
024: * @author hhuynh
025: */
026: public class AutoSynchTestApp extends
027: AbstractErrorCatchingTransparentApp {
028: private final CyclicBarrier barrier;
029: private AutoSynchronizedClass autoSynchronizedRoot = new AutoSynchronizedClass();
030: private NonSynchronizedClass nonSynchronizedRoot = new NonSynchronizedClass();
031:
032: public AutoSynchTestApp(String appId, ApplicationConfig cfg,
033: ListenerProvider listenerProvider) {
034: super (appId, cfg, listenerProvider);
035: barrier = new CyclicBarrier(getParticipantCount());
036: }
037:
038: public static void visitL1DSOConfig(ConfigVisitor visitor,
039: com.tc.object.config.DSOClientConfigHelper config) {
040: String testClass = AutoSynchTestApp.class.getName();
041: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
042:
043: String methodExpression = "* " + testClass + "*.*(..)";
044: config.addWriteAutolock(methodExpression);
045: spec.addRoot("barrier", "barrier");
046: spec.addRoot("autoSynchronizedRoot", "autoSynchronizedRoot");
047: spec.addRoot("nonSynchronizedRoot", "nonSynchronizedRoot");
048: new CyclicBarrierSpec().visit(visitor, config);
049:
050: String baseClass = AutoSynchronizedClass.class.getName();
051: config.addIncludePattern(baseClass);
052: methodExpression = "* " + baseClass + "*.add(..)";
053: config.addWriteAutoSynchronize(methodExpression);
054: methodExpression = "* " + baseClass + "*.getSize(..)";
055: config.addReadAutoSynchronize(methodExpression);
056:
057: baseClass = NonSynchronizedClass.class.getName();
058: config.addIncludePattern(baseClass);
059: }
060:
061: protected void runTest() throws Throwable {
062: autoSynchronizedRoot.add("one");
063: autoSynchronizedRoot.add("two");
064:
065: barrier.barrier();
066: Assert.assertEquals(4, autoSynchronizedRoot.getSize());
067:
068: barrier.barrier();
069:
070: try {
071: nonSynchronizedRoot.add("one");
072: throw new AssertionError(
073: "Expect to throw an UnlockedSharedObjectException.");
074: } catch (UnlockedSharedObjectException e) {
075: // Expected
076: }
077: }
078:
079: static class AutoSynchronizedClass {
080: protected List list = new ArrayList();
081:
082: public void add(Object o) {
083: // intentionally not using synchronize
084: list.add(o);
085: }
086:
087: public int getSize() {
088: // intentionally not using synchronize
089: return list.size();
090: }
091:
092: }
093:
094: static class NonSynchronizedClass {
095: protected List list = new ArrayList();
096:
097: public void add(Object o) {
098: // intentionally not using synchronize
099: list.add(o);
100: }
101:
102: public int getSize() {
103: // intentionally not using synchronize
104: return list.size();
105: }
106:
107: }
108:
109: }
|