001: /*
002: * All content copyright (c) 2003-2006 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.DSOClientConfigHelper;
011: import com.tc.object.config.spec.CyclicBarrierSpec;
012: import com.tc.object.loaders.IsolationClassLoader;
013: import com.tc.simulator.app.ApplicationConfig;
014: import com.tc.simulator.listener.ListenerProvider;
015: import com.tctest.runner.AbstractTransparentApp;
016:
017: import java.util.ArrayList;
018: import java.util.List;
019:
020: public class MissingClassApplyTestApp extends AbstractTransparentApp {
021:
022: private static final String MISSING_CLASS_NAME = MissingClassApplyTestApp.class
023: .getName()
024: + "$MissingClass";
025: private List root = new ArrayList();
026: private CyclicBarrier barrier = new CyclicBarrier(
027: getParticipantCount());
028:
029: public MissingClassApplyTestApp(String appId,
030: ApplicationConfig cfg, ListenerProvider listenerProvider) {
031: super (appId, cfg, listenerProvider);
032: System.err.println("\n### CTor.missingClass="
033: + MISSING_CLASS_NAME);
034: }
035:
036: public void run() {
037: try {
038: runTest();
039: } catch (Throwable t) {
040: notifyError(t);
041: }
042:
043: }
044:
045: private void runTest() throws Exception {
046:
047: final int nodeId = barrier.barrier();
048: final boolean masterNode = nodeId == 0;
049: System.err.println("\n### NodeId=" + nodeId + ", ThreadId="
050: + Thread.currentThread().getName());
051: if (!masterNode) {
052: final IsolationClassLoader icl = (IsolationClassLoader) getClass()
053: .getClassLoader();
054: icl.throwOnLoad(MISSING_CLASS_NAME, MISSING_CLASS_NAME
055: + " should not be found in this node [nodeId="
056: + nodeId + "]");
057: }
058: barrier.barrier();
059: // make sure that referencing MissingClass throws exception everywhere except the master node...
060: checkClassAvailability(masterNode);
061:
062: barrier.barrier();
063: // make sure that we can push some updates to root
064: if (masterNode) {
065: add(new Object());
066: }
067: barrier.barrier();
068: checkSize(1);
069: barrier.barrier();
070: // make sure that update that refer to MissingClass don't throw exceptions in those nodes that don't have access to
071: // it
072: if (masterNode) {
073: add(new MissingClass());
074: }
075: if (!masterNode) {
076: checkSize((masterNode) ? 2 : 1);
077: }
078: barrier.barrier();
079: // just for fun, check class availability again
080: checkClassAvailability(masterNode);
081: }
082:
083: private void checkClassAvailability(final boolean masterNode) {
084: if (masterNode) {
085: new MissingClass();
086: } else {
087: Throwable exception = null;
088: try {
089: new MissingClass();
090: } catch (Throwable e) {
091: exception = e;
092: }
093: if (exception == null) {
094: notifyError("Expected exception was not thrown!");
095: }
096: }
097: }
098:
099: public void add(Object o) {
100: synchronized (root) {
101: root.add(o);
102: }
103: }
104:
105: public synchronized void checkSize(final int i) {
106: int actual;
107: synchronized (root) {
108: actual = root.size();
109: }
110: if (i != actual) {
111: notifyError("Unexpected size: expected=" + i + ", actual="
112: + actual);
113: }
114: }
115:
116: public static void visitL1DSOConfig(ConfigVisitor visitor,
117: DSOClientConfigHelper config) {
118: String testClass = MissingClassApplyTestApp.class.getName();
119:
120: System.err.println("\n### testClass=" + testClass);
121: System.err.println("\n### missingClass=" + MISSING_CLASS_NAME);
122:
123: config.getOrCreateSpec(testClass) //
124: .addRoot("barrier", "barrier") //
125: .addRoot("root", "root");
126:
127: config.getOrCreateSpec(MISSING_CLASS_NAME);
128:
129: config.addWriteAutolock("* " + testClass + "*.*(..)");
130: new CyclicBarrierSpec().visit(visitor, config);
131: }
132:
133: static class MissingClass {
134: // n/a
135: }
136:
137: }
|