KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dom4j > ThreadingTest


1 /*
2  * Copyright 2001-2005 (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
8 package org.dom4j;
9
10 import com.clarkware.junitperf.LoadTest;
11 import com.clarkware.junitperf.TimedTest;
12
13 import junit.extensions.RepeatedTest;
14
15 import junit.framework.Test;
16 import junit.framework.TestSuite;
17
18 import junit.textui.TestRunner;
19
20 import java.text.FieldPosition JavaDoc;
21 import java.text.SimpleDateFormat JavaDoc;
22 import java.util.Date JavaDoc;
23
24 /**
25  * A test harness to test the dom4j package in a threaded environment
26  *
27  * @author <a HREF="mailto:ddlucas@lse.com">David Lucas </a>
28  * @version $Revision: 1.3 $
29  */

30 public class ThreadingTest extends AbstractTestCase {
31     private static final ThreadLocal JavaDoc FORMATTER_CACHE = new ThreadLocal JavaDoc();
32
33     private static final String JavaDoc SEPERATOR = " - ";
34
35     private static final FieldPosition JavaDoc FIELD_ZERO = new FieldPosition JavaDoc(0);
36
37     public ThreadingTest(String JavaDoc name) {
38         super(name);
39     }
40
41     private static void preformat(StringBuffer JavaDoc strBuf, String JavaDoc context) {
42         long now = System.currentTimeMillis();
43         Date JavaDoc currentTime = new Date JavaDoc(now);
44         SimpleDateFormat JavaDoc formatter = (SimpleDateFormat JavaDoc) FORMATTER_CACHE.get();
45
46         if (formatter == null) {
47             formatter = new SimpleDateFormat JavaDoc("yyyy-MM-dd HH:mm:ss.SSS zzz");
48             FORMATTER_CACHE.set(formatter);
49         }
50
51         strBuf.append("[");
52         formatter.format(currentTime, strBuf, FIELD_ZERO);
53         strBuf.append(" (").append(now).append(") ]");
54
55         strBuf.append(SEPERATOR);
56         strBuf.append(getThreadId());
57         strBuf.append(SEPERATOR);
58         strBuf.append(context);
59         strBuf.append(SEPERATOR);
60     }
61
62     private static String JavaDoc getThreadId() {
63         String JavaDoc tid = Thread.currentThread().getName();
64
65         return tid;
66     }
67
68     /**
69      * This test combines many different types of operations on DOM4J in a
70      * threaded environment. If a problem occurs with threading, the tests will
71      * fail. This was used to help isolate an internal threading issue.
72      * Unfortunately it may not always create the condition necessary to break
73      * un-thread-safe code. This is due to the nature of the machine, JVM, and
74      * application and if the conditions are right. Typically the problems of
75      * multithreading occur due to an unprotected HashMap or ArrayList in a
76      * class being used by more than one thread. Also, most developers think
77      * that their class or object instance will only be used by one thread. But
78      * if a factory or singleton caches a class or instance, it can quickly
79      * become an unsafe environment. Hence this test to assist in locating
80      * threading issues.
81      */

82     public void testCombo() {
83         int loop = 10;
84
85         try {
86             long begin = System.currentTimeMillis();
87             String JavaDoc value = null;
88             String JavaDoc expected = null;
89             String JavaDoc xml = null;
90             Document doc = null;
91             Element root = null;
92             Element item = null;
93             Element newItem = null;
94             QName qn = null;
95             Namespace ns = null;
96             long now = 0;
97
98             xml = "<ROOT xmlns:t0=\"http://www.lse.com/t0\" >"
99                     + " <ctx><type>Context</type></ctx>"
100                     + " <A><B><C><D>This is a TEST</D></C></B></A>"
101                     + " <t0:Signon><A>xyz</A><t0:Cust>customer</t0:Cust>"
102                     + "</t0:Signon></ROOT>";
103
104             for (int i = 0; i < loop; i++) {
105                 doc = DocumentHelper.parseText(xml);
106
107                 root = doc.getRootElement();
108                 ns = Namespace.get("t0", "http://www.lse.com/t0");
109                 qn = QName.get("Signon", ns);
110                 item = root.element(qn);
111                 value = item.asXML();
112                 expected = "<t0:Signon xmlns:t0=\"http://www.lse.com/t0\">"
113                         + "<A>xyz</A><t0:Cust>customer</t0:Cust></t0:Signon>";
114                 assertEquals("test t0:Signon ", expected, value);
115
116                 qn = root.getQName("Test");
117                 newItem = DocumentHelper.createElement(qn);
118                 now = System.currentTimeMillis();
119                 newItem.setText(String.valueOf(now));
120                 root.add(newItem);
121
122                 qn = root.getQName("Test2");
123                 newItem = DocumentHelper.createElement(qn);
124                 now = System.currentTimeMillis();
125                 newItem.setText(String.valueOf(now));
126                 root.add(newItem);
127
128                 item = root.element(qn);
129                 item.detach();
130                 item.setQName(qn);
131                 root.add(item);
132                 value = item.asXML();
133                 expected = "<Test2>" + now + "</Test2>";
134                 assertEquals("test Test2 ", expected, value);
135
136                 qn = root.getQName("Test3");
137                 newItem = DocumentHelper.createElement(qn);
138                 now = System.currentTimeMillis();
139                 newItem.setText(String.valueOf(now));
140                 root.add(newItem);
141
142                 item = root.element(qn);
143                 item.detach();
144                 item.setQName(qn);
145                 root.add(item);
146                 value = item.asXML();
147                 expected = "<Test3>" + now + "</Test3>";
148                 assertEquals("test Test3 ", expected, value);
149
150                 qn = item.getQName("Test4");
151                 newItem = DocumentHelper.createElement(qn);
152                 now = System.currentTimeMillis();
153                 newItem.setText(String.valueOf(now));
154                 root.add(newItem);
155
156                 item = root.element(qn);
157                 item.detach();
158                 item.setQName(qn);
159                 root.add(item);
160                 value = item.asXML();
161                 expected = "<Test4>" + now + "</Test4>";
162                 assertEquals("test Test4 ", expected, value);
163             }
164
165             double duration = System.currentTimeMillis() - begin;
166             double avg = duration / loop;
167         } catch (Exception JavaDoc e) {
168             e.printStackTrace();
169             assertTrue("Exception in test: " + e.getMessage(), false);
170         }
171     }
172
173     /**
174      * This test isolates QNameCache in a multithreaded environment.
175      */

176     public void testQNameCache() {
177         int loop = 100;
178
179         try {
180             long begin = System.currentTimeMillis();
181             String JavaDoc value = null;
182             String JavaDoc expected = null;
183             String JavaDoc xml = null;
184             Document doc = null;
185             Element root = null;
186             Element item = null;
187             Element newItem = null;
188             QName qn = null;
189             Namespace ns = null;
190             long now = 0;
191
192             xml = "<ROOT xmlns:t0=\"http://www.lse.com/t0\" >"
193                     + " <ctx><type>Context</type></ctx>"
194                     + " <A><B><C><D>This is a TEST</D></C></B></A>"
195                     + " <t0:Signon><A>xyz</A><t0:Cust>customer</t0:Cust>"
196                     + "</t0:Signon></ROOT>";
197
198             for (int i = 0; i < loop; i++) {
199                 doc = DocumentHelper.parseText(xml);
200                 root = doc.getRootElement();
201
202                 qn = DocumentHelper.createQName("test");
203                 value = fetchValue(qn);
204                 expected = "<test/>";
205                 assertEquals("test test ", expected, value);
206
207                 // creat it again
208
qn = DocumentHelper.createQName("test");
209                 value = fetchValue(qn);
210                 expected = "<test/>";
211                 assertEquals("test test again ", expected, value);
212
213                 qn = root.getQName("t0:Signon");
214                 value = fetchValue(qn);
215                 expected = "<t0:Signon xmlns:t0=\"http://www.lse.com/t0\"/>";
216                 assertEquals("test t0:Signon ", expected, value);
217             }
218
219             double duration = System.currentTimeMillis() - begin;
220             double avg = duration / loop;
221         } catch (Exception JavaDoc e) {
222             e.printStackTrace();
223             assertTrue("Exception in test: " + e.getMessage(), false);
224         }
225     }
226
227     /**
228      * This method creates a value that can be expected during a test
229      *
230      * @param qn
231      *
232      * @return
233      */

234     public String JavaDoc fetchValue(QName qn) {
235         String JavaDoc value = null;
236
237         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
238         sb.append("<");
239
240         String JavaDoc prefix = qn.getNamespacePrefix();
241
242         if ((prefix != null) && (prefix.length() > 0)) {
243             sb.append(prefix).append(":");
244         }
245
246         sb.append(qn.getName());
247
248         String JavaDoc uri = qn.getNamespaceURI();
249
250         if ((uri != null) && (uri.length() > 0)) {
251             sb.append(" xmlns");
252
253             if ((prefix != null) && (prefix.length() > 0)) {
254                 sb.append(":").append(prefix);
255             }
256
257             sb.append("=\"").append(uri).append("\"");
258         }
259
260         sb.append("/>");
261
262         value = sb.toString();
263
264         return value;
265     }
266
267     /**
268      * Assembles and returns a test suite.
269      *
270      * @return The suite
271      */

272     public static Test suite() {
273         TestSuite suite = new TestSuite();
274         suite.addTest(makeRepeatedLoadTest(5, 10, "testCombo"));
275         suite.addTest(makeRepeatedLoadTest(5, 10, "testQNameCache"));
276
277         return suite;
278     }
279
280     /**
281      * JUnit method to exercise test via threads and loops
282      *
283      * @param users
284      * Number of users to simulate (i.e. Threads).
285      * @param iterations
286      * Number of iterations per user ( repeat the test x times).
287      * @param testMethod
288      * method to execute (testXXX).
289      *
290      * @return A Junit test
291      */

292     protected static Test makeRepeatedLoadTest(int users, int iterations,
293             String JavaDoc testMethod) {
294         long maxElapsedTime = 120000 + (1000 * users * iterations);
295
296         Test testCase = new ThreadingTest(testMethod);
297
298         Test repeatedTest = new RepeatedTest(testCase, iterations);
299         Test loadTest = new LoadTest(repeatedTest, users);
300         Test timedTest = new TimedTest(loadTest, maxElapsedTime);
301
302         return timedTest;
303     }
304
305     public static void main(String JavaDoc[] args) {
306         TestRunner.run(ThreadingTest.class);
307     }
308 }
309
310 /*
311  * Redistribution and use of this software and associated documentation
312  * ("Software"), with or without modification, are permitted provided that the
313  * following conditions are met:
314  *
315  * 1. Redistributions of source code must retain copyright statements and
316  * notices. Redistributions must also contain a copy of this document.
317  *
318  * 2. Redistributions in binary form must reproduce the above copyright notice,
319  * this list of conditions and the following disclaimer in the documentation
320  * and/or other materials provided with the distribution.
321  *
322  * 3. The name "DOM4J" must not be used to endorse or promote products derived
323  * from this Software without prior written permission of MetaStuff, Ltd. For
324  * written permission, please contact dom4j-info@metastuff.com.
325  *
326  * 4. Products derived from this Software may not be called "DOM4J" nor may
327  * "DOM4J" appear in their names without prior written permission of MetaStuff,
328  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
329  *
330  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
331  *
332  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
333  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
334  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
335  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
336  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
337  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
338  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
339  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
340  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
341  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
342  * POSSIBILITY OF SUCH DAMAGE.
343  *
344  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
345  */

346
Popular Tags