KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > test > dom4j > TestThreading


1 /*
2  * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
3  *
4  * This software is open source.
5  * See the bottom of this file for the licence.
6  *
7  * $Id: TestThreading.java,v 1.2 2003/11/02 18:31:28 per_nyfelt Exp $
8  */

9
10 package test.dom4j;
11
12 import com.clarkware.junitperf.LoadTest;
13 import com.clarkware.junitperf.TimedTest;
14 import junit.extensions.RepeatedTest;
15 import junit.framework.Test;
16 import junit.framework.TestSuite;
17 import org.dom4j.Document;
18 import org.dom4j.Element;
19 import org.dom4j.Namespace;
20 import org.dom4j.QName;
21 import org.dom4j.tree.AbstractNamespace;
22 import org.dom4j.tree.DefaultQName;
23 import org.ozoneDB.xml.dom4j.O3DocumentHelper;
24
25 import java.text.FieldPosition JavaDoc;
26 import java.text.SimpleDateFormat JavaDoc;
27 import java.util.Date JavaDoc;
28
29
30 /** A test harness to test the dom4j package in a threaded environment
31   *
32   * @author <a HREF="mailto:ddlucas@lse.com">David Lucas</a>
33   * @version $Revision: 1.2 $
34   */

35 public class TestThreading extends AbstractTestCase {
36     public TestThreading(String JavaDoc name) {
37         super(name);
38     }
39
40     final static boolean debug=true;
41
42     final static java.lang.ThreadLocal JavaDoc formatterCache = new java.lang.ThreadLocal JavaDoc();
43     final static String JavaDoc seperator=" - ";
44     final static FieldPosition JavaDoc FIELD_ZERO = new FieldPosition JavaDoc(0);
45
46     private final static void preformat(StringBuffer JavaDoc strBuf, String JavaDoc context) {
47         long now = System.currentTimeMillis();
48         Date JavaDoc currentTime = new Date JavaDoc(now);
49         SimpleDateFormat JavaDoc formatter = (SimpleDateFormat JavaDoc) formatterCache.get();
50         if (formatter == null) {
51             formatter = new SimpleDateFormat JavaDoc("yyyy-MM-dd HH:mm:ss.SSS zzz");
52             formatterCache.set(formatter);
53         }
54         strBuf.append("[");
55         formatter.format(currentTime, strBuf, FIELD_ZERO);
56         strBuf.append(" (").append(now).append(") ]");
57
58         strBuf.append(seperator);
59         strBuf.append(getThreadId());
60         strBuf.append(seperator);
61         strBuf.append(context);
62         strBuf.append(seperator);
63     }
64
65     private static final String JavaDoc getThreadId() {
66       String JavaDoc tid = Thread.currentThread().getName();
67       return tid;
68     }
69
70     public static final void debug(String JavaDoc context, String JavaDoc msg ) {
71       if (debug) {
72         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
73         preformat(sb,context);
74         sb.append(msg);
75         System.out.println(sb.toString());
76       }
77     }
78
79     /**
80      * static initializer
81      */

82     static {
83     }
84
85     /**
86      * The JUnit setup method
87      */

88     protected void setUp() { }
89
90
91     /**
92      * The teardown method for JUnit
93      */

94     protected void tearDown() { }
95
96
97     /**
98      * This test combines many different types of operations on DOM4J in a
99      * threaded environment. If a problem occurs with threading, the tests will
100      * fail. This was used to help isolate an internal threading issue.
101      * Unfortunately it may not always create the condition necessary to break
102      * un-thread-safe code. This is due to the nature of the machine, JVM, and
103      * application and if the conditions are right. Typically the problems of
104      * multithreading occur due to an unprotected HashMap or ArrayList in a class
105      * being used by more than one thread. Also, most developers think that
106      * their class or object instance will only be used by one thread. But if
107      * a factory or singleton caches a class or instance, it can quickly become
108      * an unsafe environment. Hence this test to assist in locating threading
109      * issues.
110      */

111     public void testCombo() {
112       int loop = 10;
113       try {
114         debug("testCombo", "beginning test...");
115
116         long begin = System.currentTimeMillis();
117         String JavaDoc value=null;
118         String JavaDoc expected=null;
119         String JavaDoc xml=null;
120         Document doc=null;
121         Element root=null;
122         Element item=null;
123         Element newItem=null;
124         QName qn = null;
125         Namespace ns = null;
126         long now=0;
127
128         xml = "<ROOT xmlns:t0=\"http://www.lse.com/t0\" >" +
129                 " <ctx><type>Context</type></ctx>" +
130                 " <A><B><C><D>This is a TEST</D></C></B></A>" +
131                 " <t0:Signon><A>xyz</A><t0:Cust>customer</t0:Cust></t0:Signon>" +
132                 "</ROOT>";
133
134
135         for (int i = 0; i < loop; i++) {
136             doc = O3DocumentHelper.parseText(xml);
137
138             root = doc.getRootElement();
139             ns = AbstractNamespace.get("t0","http://www.lse.com/t0");
140             qn = DefaultQName.get("Signon",ns);
141             item = root.element(qn);
142             value = item.asXML();
143             expected="<t0:Signon xmlns:t0=\"http://www.lse.com/t0\"><A>xyz</A><t0:Cust>customer</t0:Cust></t0:Signon>";
144             assertEquals("test t0:Signon ",expected,value);
145
146             qn = root.getQName("Test");
147             newItem = O3DocumentHelper.createElement(qn);
148             now=System.currentTimeMillis();
149             newItem.setText(String.valueOf(now));
150             root.add(newItem);
151
152             qn = root.getQName("Test2");
153             newItem = O3DocumentHelper.createElement(qn);
154             now=System.currentTimeMillis();
155             newItem.setText(String.valueOf(now));
156             root.add(newItem);
157
158             item=root.element(qn);
159             item.detach();
160             item.setQName(qn);
161             root.add(item);
162             value = item.asXML();
163             expected="<Test2>"+now+"</Test2>";
164             assertEquals("test Test2 ",expected,value);
165
166             qn = root.getQName("Test3");
167             newItem = O3DocumentHelper.createElement(qn);
168             now=System.currentTimeMillis();
169             newItem.setText(String.valueOf(now));
170             root.add(newItem);
171
172             item=root.element(qn);
173             item.detach();
174             item.setQName(qn);
175             root.add(item);
176             value = item.asXML();
177             expected="<Test3>"+now+"</Test3>";
178             assertEquals("test Test3 ",expected,value);
179
180             qn = item.getQName("Test4");
181             newItem = O3DocumentHelper.createElement(qn);
182             now=System.currentTimeMillis();
183             newItem.setText(String.valueOf(now));
184             root.add(newItem);
185
186             item=root.element(qn);
187             item.detach();
188             item.setQName(qn);
189             root.add(item);
190             value = item.asXML();
191             expected="<Test4>"+now+"</Test4>";
192             assertEquals("test Test4 ",expected,value);
193         }
194         double duration = System.currentTimeMillis()-begin;
195         double avg = duration / loop;
196         debug("testCombo",
197               "*** duration="+duration+" , loop="+loop+" , avg="+avg);
198       }
199       catch (Exception JavaDoc e) {
200         e.printStackTrace();
201         assertTrue("Exception in test: "+e.getMessage(),false);
202       }
203     }
204
205
206     /**
207      * This test isolates QNameCache in a multithreaded environment.
208      */

209     public void testQNameCache() {
210       int loop = 100;
211       try {
212         debug("testQNameCache", "beginning test...");
213
214         long begin = System.currentTimeMillis();
215         String JavaDoc value=null;
216         String JavaDoc expected=null;
217         String JavaDoc xml=null;
218         Document doc=null;
219         Element root=null;
220         Element item=null;
221         Element newItem=null;
222         QName qn = null;
223         Namespace ns = null;
224         long now=0;
225
226         xml = "<ROOT xmlns:t0=\"http://www.lse.com/t0\" >" +
227                 " <ctx><type>Context</type></ctx>" +
228                 " <A><B><C><D>This is a TEST</D></C></B></A>" +
229                 " <t0:Signon><A>xyz</A><t0:Cust>customer</t0:Cust></t0:Signon>" +
230                 "</ROOT>";
231
232
233         for (int i = 0; i < loop; i++) {
234             doc = O3DocumentHelper.parseText(xml);
235             root = doc.getRootElement();
236
237             qn=O3DocumentHelper.createQName("test");
238             value = fetchValue(qn);
239             expected="<test/>";
240             assertEquals("test test ",expected,value);
241
242             //creat it again
243
qn=O3DocumentHelper.createQName("test");
244             value = fetchValue(qn);
245             expected="<test/>";
246             assertEquals("test test again ",expected,value);
247
248             qn=root.getQName("t0:Signon");
249             value= fetchValue(qn);
250             expected="<t0:Signon xmlns:t0=\"http://www.lse.com/t0\"/>";
251             assertEquals("test t0:Signon ",expected,value);
252
253         }
254         double duration = System.currentTimeMillis()-begin;
255         double avg = duration / loop;
256         debug("testQNameCache",
257               "*** duration="+duration+" , loop="+loop+" , avg="+avg);
258       }
259       catch (Exception JavaDoc e) {
260         e.printStackTrace();
261         assertTrue("Exception in test: "+e.getMessage(),false);
262       }
263     }
264
265
266     /**
267      * This method creates a value that can be expected during a test
268      * @param qn
269      * @return
270      */

271     public String JavaDoc fetchValue(QName qn) {
272       String JavaDoc value=null;
273
274       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
275       sb.append("<");
276       String JavaDoc prefix=qn.getNamespacePrefix();
277       if (prefix!=null && prefix.length()>0) {
278         sb.append(prefix).append(":");
279       }
280       sb.append(qn.getName());
281       String JavaDoc uri=qn.getNamespaceURI();
282       if (uri!=null && uri.length()>0) {
283         sb.append(" xmlns");
284         if (prefix!=null && prefix.length()>0){
285           sb.append(":").append(prefix);
286         }
287         sb.append("=\"").append(uri).append("\"");
288       }
289       sb.append("/>");
290
291       value=sb.toString();
292       return value;
293     }
294
295     /**
296      * Assembles and returns a test suite.
297      *
298      *@return The suite
299      */

300     public static Test suite() {
301         TestSuite suite = new TestSuite();
302         suite.addTest(makeRepeatedLoadTest(5, 10, "testCombo"));
303         suite.addTest(makeRepeatedLoadTest(5, 10, "testQNameCache"));
304         return suite;
305     }
306
307
308
309     /**
310      * JUnit method to exercise test via threads and loops
311      *
312      *@param users Number of users to simulate (i.e. Threads).
313      *@param iterations Number of iterations per user ( repeat the test x times).
314      *@param testMethod method to execute (testXXX).
315      *@return A Junit test
316      */

317     protected static Test makeRepeatedLoadTest(int users, int iterations, String JavaDoc testMethod) {
318         long maxElapsedTime = 120000 + (1000 * users * iterations);
319
320         Test testCase = new TestThreading(testMethod);
321
322         Test repeatedTest = new RepeatedTest(testCase, iterations);
323         Test loadTest = new LoadTest(repeatedTest, users);
324         Test timedTest = new TimedTest(loadTest, maxElapsedTime);
325
326         return timedTest;
327     }
328
329     /**
330      * The main program for the DOM4JThreadTest class
331      *
332      *@param args The command line arguments
333      */

334     public static void main(String JavaDoc[] args) {
335         String JavaDoc[] testCaseName = {TestThreading.class.getName()};
336         junit.textui.TestRunner.main(testCaseName);
337     }
338
339
340 }
341
342
343
344
345 /*
346  * Redistribution and use of this software and associated documentation
347  * ("Software"), with or without modification, are permitted provided
348  * that the following conditions are met:
349  *
350  * 1. Redistributions of source code must retain copyright
351  * statements and notices. Redistributions must also contain a
352  * copy of this document.
353  *
354  * 2. Redistributions in binary form must reproduce the
355  * above copyright notice, this list of conditions and the
356  * following disclaimer in the documentation and/or other
357  * materials provided with the distribution.
358  *
359  * 3. The name "DOM4J" must not be used to endorse or promote
360  * products derived from this Software without prior written
361  * permission of MetaStuff, Ltd. For written permission,
362  * please contact dom4j-info@metastuff.com.
363  *
364  * 4. Products derived from this Software may not be called "DOM4J"
365  * nor may "DOM4J" appear in their names without prior written
366  * permission of MetaStuff, Ltd. DOM4J is a registered
367  * trademark of MetaStuff, Ltd.
368  *
369  * 5. Due credit should be given to the DOM4J Project
370  * (http://dom4j.org/).
371  *
372  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
373  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
374  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
375  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
376  * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
377  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
378  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
379  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
380  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
381  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
382  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
383  * OF THE POSSIBILITY OF SUCH DAMAGE.
384  *
385  * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
386  *
387  * $Id: TestThreading.java,v 1.2 2003/11/02 18:31:28 per_nyfelt Exp $
388  */

389
Popular Tags