KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tctest > GenericTestApp


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tctest;
6
7 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
8
9 import com.tc.object.config.ConfigVisitor;
10 import com.tc.object.config.DSOClientConfigHelper;
11 import com.tc.object.config.TransparencyClassSpec;
12 import com.tc.object.config.spec.CyclicBarrierSpec;
13 import com.tc.simulator.app.ApplicationConfig;
14 import com.tc.simulator.listener.ListenerProvider;
15 import com.tctest.runner.AbstractTransparentApp;
16
17 import java.lang.reflect.InvocationTargetException JavaDoc;
18 import java.lang.reflect.Method JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.Collections JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25
26 public abstract class GenericTestApp extends AbstractTransparentApp {
27
28   private static final String JavaDoc METHOD_PREFIX = "test";
29   private static final String JavaDoc METHOD_PATTERN = "^" + METHOD_PREFIX + ".*$";
30
31   // roots
32
private final CyclicBarrier barrier;
33   private final CyclicBarrier barrier2;
34   private final Exit exit = new Exit();
35   protected final Map JavaDoc sharedMap = new HashMap JavaDoc();
36
37   private final Class JavaDoc type;
38   private final List JavaDoc tests;
39
40   public GenericTestApp(String JavaDoc appId, ApplicationConfig cfg, ListenerProvider listenerProvider, Class JavaDoc type) {
41     super(appId, cfg, listenerProvider);
42
43     final int count = getParticipantCount();
44     if (count < 2) { throw new RuntimeException JavaDoc("wrong number of nodes: " + count); }
45
46     this.barrier = new CyclicBarrier(getParticipantCount());
47     this.barrier2 = new CyclicBarrier(getParticipantCount());
48
49     this.type = type;
50     this.tests = getTestNames();
51   }
52
53   public final void run() {
54     try {
55       runTest();
56     } catch (Throwable JavaDoc t) {
57       notifyError(t);
58     }
59   }
60
61   protected abstract Object JavaDoc getTestObject(String JavaDoc testName);
62
63   protected abstract void setupTestObject(String JavaDoc testName);
64
65   private void makeTestObject(String JavaDoc test) {
66     synchronized (sharedMap) {
67       sharedMap.clear(); // don't want any cross talk
68
setupTestObject(test);
69     }
70   }
71
72   private void runTest() throws Throwable JavaDoc {
73     int num = barrier.barrier();
74     boolean mutator = (num == 0);
75
76     if (mutator) {
77       doMutate();
78     } else {
79       doValidate();
80     }
81   }
82
83   private void doValidate() throws Throwable JavaDoc {
84     Thread.currentThread().setName("VALIDATOR " + getApplicationId());
85     for (Iterator JavaDoc i = tests.iterator(); i.hasNext();) {
86       String JavaDoc name = (String JavaDoc) i.next();
87       barrier.barrier();
88
89       if (exit.shouldExit()) { return; }
90
91       try {
92         runOp(name, true);
93       } catch (Throwable JavaDoc t) {
94         exit.toggle();
95         throw t;
96       } finally {
97         barrier2.barrier();
98       }
99
100       if (exit.shouldExit()) { return; }
101     }
102   }
103
104   private void doMutate() throws Throwable JavaDoc {
105     Thread.currentThread().setName("MUTATOR " + getApplicationId());
106     for (Iterator JavaDoc i = tests.iterator(); i.hasNext();) {
107       String JavaDoc name = (String JavaDoc) i.next();
108       System.err.print("Running test: " + name + " ... ");
109       long start = System.currentTimeMillis();
110
111       try {
112         runOp(name, false);
113         runOp(name, true);
114       } catch (Throwable JavaDoc t) {
115         exit.toggle();
116         throw t;
117       } finally {
118         barrier.barrier();
119
120         if (!exit.shouldExit()) {
121           barrier2.barrier();
122         }
123       }
124
125       System.err.println(" took " + (System.currentTimeMillis() - start) + " millis");
126
127       if (exit.shouldExit()) { return; }
128     }
129   }
130
131   private void runOp(String JavaDoc op, boolean validate) throws Throwable JavaDoc {
132     Method JavaDoc m = findMethod(op);
133
134     if (!validate) {
135       makeTestObject(op);
136     }
137
138     Object JavaDoc object = getTestObject(op);
139
140     if (object instanceof Iterator JavaDoc) {
141       // do some automagic for Iterators
142
for (Iterator JavaDoc i = (Iterator JavaDoc) object; i.hasNext();) {
143         runMethod(m, i.next(), validate);
144       }
145     } else {
146       runMethod(m, object, validate);
147     }
148   }
149
150   private void runMethod(Method JavaDoc m, Object JavaDoc object, boolean validate) throws Throwable JavaDoc {
151     try {
152       m.invoke(this, new Object JavaDoc[] { object, Boolean.valueOf(validate) });
153     } catch (InvocationTargetException JavaDoc ite) {
154       throw ite.getTargetException();
155     }
156   }
157
158   private Method JavaDoc findMethod(String JavaDoc name) throws NoSuchMethodException JavaDoc {
159     Method JavaDoc method = getClass().getDeclaredMethod(METHOD_PREFIX + name, new Class JavaDoc[] { type, Boolean.TYPE });
160     method.setAccessible(true);
161     return method;
162   }
163
164   private List JavaDoc getTestNames() {
165     List JavaDoc rv = new ArrayList JavaDoc();
166     Class JavaDoc klass = getClass();
167     Method JavaDoc[] methods = klass.getDeclaredMethods();
168     for (int i = 0; i < methods.length; i++) {
169       Method JavaDoc m = methods[i];
170       if (m.getName().matches(METHOD_PATTERN)) {
171         Class JavaDoc[] args = m.getParameterTypes();
172         if ((args.length == 2) && args[0].equals(type) && args[1].equals(Boolean.TYPE)) {
173           rv.add(m.getName().replaceFirst(METHOD_PREFIX, ""));
174         } else {
175           throw new RuntimeException JavaDoc("bad method: " + m);
176         }
177       }
178     }
179
180     if (rv.size() <= 0) { throw new RuntimeException JavaDoc("Didn't find any operations"); }
181
182     // make test order predictable (although this is a bad thing to rely on)
183
Collections.sort(rv);
184
185     return rv;
186   }
187
188   public static void visitL1DSOConfig(ConfigVisitor visitor, DSOClientConfigHelper config) {
189     String JavaDoc testClass = GenericTestApp.class.getName();
190     TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
191     config.getOrCreateSpec(Exit.class.getName());
192
193     spec.addRoot("sharedMap", "sharedMap");
194     spec.addRoot("barrier", "barrier");
195     spec.addRoot("barrier2", "barrier2");
196     spec.addRoot("exit", "exit");
197
198     String JavaDoc methodExpression = "* " + testClass + "*.*(..)";
199     config.addWriteAutolock(methodExpression);
200
201     new CyclicBarrierSpec().visit(visitor, config);
202   }
203
204   private static class Exit {
205     private boolean exit = false;
206
207     synchronized boolean shouldExit() {
208       return exit;
209     }
210
211     synchronized void toggle() {
212       exit = true;
213     }
214   }
215
216 }
217
Popular Tags