001: /*
002: * TestTokenizerCleanup.java: JUnit test for the StandardTokenizer
003: *
004: * Copyright (C) 2003 Heiko Blau
005: *
006: * This file belongs to the JTopas test suite.
007: * The JTopas test suite is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as published by the
009: * Free Software Foundation; either version 2.1 of the License, or (at your option)
010: * any later version.
011: *
012: * This software is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE.
015: * See the GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License along
018: * with the JTopas test suite. If not, write to the
019: *
020: * Free Software Foundation, Inc.
021: * 59 Temple Place, Suite 330,
022: * Boston, MA 02111-1307
023: * USA
024: *
025: * or check the Internet: http://www.fsf.org
026: *
027: * The JTopas test suite uses the test framework JUnit by Kent Beck and Erich Gamma.
028: * You should have received a copy of their JUnit licence agreement along with
029: * the JTopas test suite.
030: *
031: * We do NOT provide the JUnit archive junit.jar nessecary to compile and run
032: * our tests, since we assume, that You either have it already or would like
033: * to get the current release Yourself.
034: * Please visit either:
035: * http://sourceforge.net/projects/junit
036: * or
037: * http://junit.org
038: * to obtain JUnit.
039: *
040: * Contact:
041: * email: heiko@susebox.de
042: */
043:
044: package de.susebox.jtopas;
045:
046: //-----------------------------------------------------------------------------
047: // Imports
048: //
049: import java.io.StringReader;
050: import java.text.MessageFormat;
051: import java.util.Date;
052:
053: import junit.framework.Test;
054: import junit.framework.TestCase;
055: import junit.framework.TestSuite;
056: import junit.framework.Assert;
057:
058: import de.susebox.java.lang.ExtRuntimeException;
059:
060: import de.susebox.TestUtilities;
061:
062: //-----------------------------------------------------------------------------
063: // Class TestTokenizerCleanup
064: //
065:
066: /**<p>
067: * This test suite checks memory usage, registration end other things related
068: * to cleanup operations of a {@link Tokenizer}.
069: *</p>
070: *
071: * @see Tokenizer
072: * @author Heiko Blau
073: */
074: public class TestTokenizerCleanup extends TestCase {
075:
076: //---------------------------------------------------------------------------
077: // main method
078: //
079:
080: /**
081: * call this method to invoke the tests
082: */
083: public static void main(String[] args) {
084: String[] tests = { TestTokenizerCleanup.class.getName() };
085:
086: TestUtilities.run(tests, args);
087: }
088:
089: //---------------------------------------------------------------------------
090: // suite method
091: //
092:
093: /**
094: * Implementation of the JUnit method <code>suite</code>. For each set of test
095: * properties one or more tests are instantiated.
096: *
097: * @return a test suite
098: */
099: public static Test suite() {
100: TestSuite suite = new TestSuite(TestTokenizerCleanup.class
101: .getName());
102:
103: suite.addTest(new TestTokenizerCleanup("testMemoryUsage"));
104: return suite;
105: }
106:
107: //---------------------------------------------------------------------------
108: // Constructor
109: //
110:
111: /**
112: * Default constructor. Standard input {@link java.lang.System#in} is used
113: * to construct the input stream reader.
114: */
115: public TestTokenizerCleanup(String test) {
116: super (test);
117: }
118:
119: //---------------------------------------------------------------------------
120: // Fixture setup and release
121: //
122:
123: /**
124: * Sets up the fixture, for example, open a network connection.
125: * This method is called before a test is executed.
126: */
127: protected void setUp() throws Exception {
128: // empty properties
129: _properties = new StandardTokenizerProperties();
130:
131: _properties.setParseFlags(Flags.F_KEEP_DATA
132: | Flags.F_RETURN_WHITESPACES);
133:
134: // create a large source
135: String source = "This is just a source with lots of data:\n"
136: + "when it is multiplied, see below!\n\n"
137: + "There is >>nothing<< special here, since only the\n"
138: + "memory usage is of interest.\n";
139: StringBuffer buffer = new StringBuffer(1024);
140:
141: while (buffer.length() < 1024) {
142: buffer.append(source);
143: }
144: _source = buffer.toString();
145: }
146:
147: /**
148: * Tears down the fixture, for example, close a network connection.
149: * This method is called after a test is executed.
150: */
151: protected void tearDown() throws Exception {
152: _properties = null;
153: }
154:
155: //---------------------------------------------------------------------------
156: // test cases
157: //
158:
159: /**
160: * The method creates a huge amount of tokenizers and dismisses them again.
161: * Memory usage should be fairly constant.
162: */
163: public void testMemoryUsage() throws Throwable {
164: long start = System.currentTimeMillis();
165: Runtime runtime = Runtime.getRuntime();
166: double totalMemoryStart = runtime.totalMemory();
167: double freeMemoryStart = runtime.freeMemory();
168: int currIndex = 0;
169:
170: System.out.println(MessageFormat.format(
171: "Total/free memory on start (MB): {0}/{1}",
172: new Object[] {
173: new Double(totalMemoryStart / (1024 * 1024)),
174: new Double(freeMemoryStart / (1024 * 1024)) }));
175:
176: for (int counter = 0; counter < 1000; ++counter) {
177: double totalMemory = runtime.totalMemory();
178: double freeMemory = runtime.freeMemory();
179:
180: System.out
181: .println(MessageFormat
182: .format(
183: "{2}: Total/free memory before tokenizing (MB): {0}/{1}",
184: new Object[] {
185: new Double(totalMemory
186: / (1024 * 1024)),
187: new Double(freeMemory
188: / (1024 * 1024)),
189: new Long(
190: System
191: .currentTimeMillis()) }));
192:
193: // create tokenizer and parse the source
194: Tokenizer tokenizer = new StandardTokenizer(_properties);
195:
196: try {
197: tokenizer.setSource(new ReaderSource(new StringReader(
198: _source)));
199:
200: while (tokenizer.hasMoreToken()) {
201: tokenizer.nextToken();
202: tokenizer.currentImage();
203: }
204: System.out
205: .println(MessageFormat
206: .format(
207: "{2}: Total/free memory after tokenizing (MB): {0}/{1}",
208: new Object[] {
209: new Double(totalMemory
210: / (1024 * 1024)),
211: new Double(freeMemory
212: / (1024 * 1024)),
213: new Long(
214: System
215: .currentTimeMillis()) }));
216: } finally {
217: // close the tokenizer and see what happens to memory
218: tokenizer.close();
219: totalMemory = runtime.totalMemory();
220: freeMemory = runtime.freeMemory();
221: System.out
222: .println(MessageFormat
223: .format(
224: "{2}: Total/free memory after closing (MB): {0}/{1}",
225: new Object[] {
226: new Double(totalMemory
227: / (1024 * 1024)),
228: new Double(freeMemory
229: / (1024 * 1024)),
230: new Long(
231: System
232: .currentTimeMillis()) }));
233:
234: // try to close it a few times
235: for (int ii = 0; ii < 5; ++ii) {
236: tokenizer.close();
237: }
238:
239: // dont block the system :-)
240: synchronized (this ) {
241: try {
242: wait(10);
243: } catch (InterruptedException ex) {
244: }
245: }
246: }
247: }
248:
249: long diff = System.currentTimeMillis() - start;
250: System.out.println("Finished after " + diff + " milliseconds");
251: }
252:
253: //---------------------------------------------------------------------------
254: // Members
255: //
256: protected volatile TokenizerProperties _properties = null;
257: protected volatile String _source = null;
258: }
|