001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are met:
008: * * Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * * Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014: * names of its contributors may be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: * This software is Open Source Initiative approved Open Source Software.
030: * Open Source Initative Approved is a trademark of the Open Source Initiative.
031: *
032: * This file is part of DrJava. Download the current version of this project
033: * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034: *
035: * END_COPYRIGHT_BLOCK*/
036:
037: package edu.rice.cs.util;
038:
039: import junit.framework.TestCase;
040: import java.io.FileReader;
041: import java.io.BufferedReader;
042: import java.io.IOException;
043: import java.io.FileWriter;
044: import java.io.File;
045: import java.text.ParseException;
046: import java.util.Date;
047: import java.util.Random;
048:
049: import edu.rice.cs.drjava.model.MultiThreadedTestCase;
050: import edu.rice.cs.plt.io.IOUtil;
051:
052: /** Test cases for {@link Log}.
053: * @version $Id: LogTest.java 4255 2007-08-28 19:17:37Z mgricken $
054: */
055: public class LogTest extends MultiThreadedTestCase {
056:
057: static final int SHORT_TIME = 10000; // few seconds in milliseconds
058:
059: static final int DATE_END = 28; // the ending index of the date field in a log entry
060:
061: /** A thread class that adds a log message after sleeping a given number of milliseconds */
062: private class LogTestThread extends Thread {
063:
064: Log _log;
065: int _millis;
066:
067: public LogTestThread(Log log, int millis) {
068: _log = log;
069: _millis = millis;
070: }
071:
072: public void run() {
073: try {
074: sleep(_millis);
075: } catch (InterruptedException e) {
076: e.printStackTrace();
077: fail("testConcurrent failed: sleep interrupted");
078: }
079: _log.log("Test message");
080: }
081:
082: }
083:
084: /** Parses a date printed by Date.toString(); returns null if there is a parse error. */
085: @SuppressWarnings("deprecation")
086: private static Date parse(String s) {
087: try {
088: return new Date(Date.parse(s.substring(0, DATE_END)));
089: } // the undeprecated version of parse DOES NOT WORK
090: catch (RuntimeException e) {
091: return null;
092: } // either IllegalArgument or StringIndexOutOfBounds
093: }
094:
095: /** Adds a couple of generic messages to a log, and then tests to make sure they are all correct, in the correct order,
096: * and their timestamps are within the past few seconds.
097: */
098: public void testLog() throws IOException {
099: File file1 = IOUtil.createAndMarkTempFile("logtest001", ".txt");
100: Log log1 = new Log(file1, true);
101: log1.log("Message 1");
102: log1.log("Message 2");
103: log1.log("Message 3");
104:
105: BufferedReader fin = new BufferedReader(new FileReader(file1));
106: Date earlier = new Date(new Date().getTime() - SHORT_TIME);
107: Date now = new Date();
108:
109: String s0 = fin.readLine();
110: // System.err.println("s0 = " + s0);
111: // System.err.println("s0 converted to millis " + parse(s0));
112: // System.err.println("Current time in millis is: " + System.currentTimeMillis());
113: Date time0 = parse(s0);
114: assertTrue("Log opened within last few seconds", time0
115: .compareTo(earlier) >= 0
116: && time0.compareTo(now) <= 0);
117: assertEquals("Log open message", "Log '" + file1.getName()
118: + "' opened", s0.substring(30, 43 + file1.getName()
119: .length()));
120:
121: String s1 = fin.readLine();
122: Date time1 = parse(s1);
123: assertTrue("Date of message 1 within last few seconds", time1
124: .compareTo(earlier) >= 0
125: && time1.compareTo(now) <= 0);
126: assertEquals("Log message 1", "Message 1", s1.substring(30));
127:
128: String s2 = fin.readLine();
129: Date time2 = parse(s2);
130: assertTrue("Date of message 2 within last few seconds", time2
131: .compareTo(earlier) >= 0
132: && time2.compareTo(now) <= 0);
133: assertEquals("Log message 2", "Message 2", s2.substring(30));
134:
135: String s3 = fin.readLine();
136: Date time3 = parse(s3);
137: assertTrue("Date of message 3 within last few seconds", time3
138: .compareTo(earlier) >= 0
139: && time3.compareTo(now) <= 0);
140: assertEquals("Log message 3", "Message 3", s3.substring(30));
141:
142: fin.close();
143: }
144:
145: /** Tests the Exception printing methods in the Log file by throwing two exceptions and using the two types of log
146: * methods (one with the Throwable itself and the other with the the StackTraceElement[])
147: */
148: public void testExceptionPrinting() throws IOException {
149: File file2 = IOUtil.createAndMarkTempFile("logtest002", ".txt");
150: Log log2 = new Log(file2, true);
151: // System.err.println("Starting testExceptionPrinting");
152:
153: // Throw a couple of exceptions and log them
154: try {
155: throw new ArrayIndexOutOfBoundsException();
156: } catch (ArrayIndexOutOfBoundsException e) {
157: //e.printStackTrace();
158: log2.log("Message 1", e);
159: }
160:
161: try {
162: throw new NullPointerException();
163: } catch (NullPointerException e) {
164: //e.printStackTrace();
165: log2.log("Message 2", e.getStackTrace());
166: }
167:
168: BufferedReader fin = new BufferedReader(new FileReader(file2));
169: Date earlier = new Date(new Date().getTime() - SHORT_TIME);
170: Date now = new Date();
171:
172: String s0 = fin.readLine();
173: Date time0 = parse(s0);
174: assertTrue("Log opened within last few seconds", time0
175: .compareTo(earlier) >= 0
176: && time0.compareTo(now) <= 0);
177: assertEquals("Log open message", "Log '" + file2.getName()
178: + "' opened", s0.substring(30, 43 + file2.getName()
179: .length()));
180:
181: String s1 = fin.readLine();
182: Date time1 = parse(s1);
183: assertTrue("Date of message 1 within last few seconds", time1
184: .compareTo(earlier) >= 0
185: && time1.compareTo(now) <= 0);
186: assertEquals("Log message 1", "Message 1", s1.substring(30));
187: assertEquals("Log exception 1",
188: "java.lang.ArrayIndexOutOfBoundsException", fin
189: .readLine());
190:
191: // Since it's difficult to test the rest of the stack trace, just skip over it
192: String s2;
193: Date time2;
194: do {
195: s2 = fin.readLine();
196: // System.err.println("traceback line = " + s2);
197: time2 = parse(s2); // returns null if there is a parse error
198: } while (time2 == null);
199:
200: // System.err.println("Skipped over traceback");
201:
202: assertTrue("Date of message 2 within last few seconds", time2
203: .compareTo(earlier) >= 0
204: && time2.compareTo(now) <= 0);
205: assertEquals("Log message 2", "Message 2", s2.substring(30));
206: assertEquals("Log exception 2 (trace line 1)",
207: "edu.rice.cs.util.LogTest.testExceptionPrinting", fin
208: .readLine().substring(0, 46));
209:
210: fin.close();
211: }
212:
213: private static final int NUM_THREADS = 50;
214: private static final int DELAY = 100;
215:
216: /** Attempts to test Log's behavior when called concurrently from several sources. Spawns NUM_THREADS LogTestThreads
217: * (see above)that wait a random number between 0 and DELAY milliseconds and then log a message. The function tests
218: * to make sure that the messages and dates are all intact (if the Log was not handling concurrent requests properly,
219: * the entries in the log may be corrupted).
220: */
221: public void testConcurrentWrites() throws IOException,
222: InterruptedException {
223: File file3 = IOUtil.createAndMarkTempFile("logtest003", ".txt");
224: Log log3 = new Log(file3, true);
225: Random r = new Random();
226: Thread[] threads = new Thread[NUM_THREADS];
227: for (int i = 0; i < NUM_THREADS; i++)
228: threads[i] = new LogTestThread(log3, r.nextInt(DELAY));
229: for (int i = 0; i < NUM_THREADS; i++)
230: threads[i].start();
231: for (int i = 0; i < NUM_THREADS; i++)
232: threads[i].join();
233:
234: BufferedReader fin = new BufferedReader(new FileReader(file3));
235: Date earlier = new Date(new Date().getTime() - SHORT_TIME);
236: Date now = new Date();
237: String s0 = fin.readLine();
238: Date time0 = parse(s0);
239: assertTrue("Log opened within last 10 seconds", time0
240: .compareTo(earlier) >= 0
241: && time0.compareTo(now) <= 0);
242: assertEquals("Log open message", "Log '" + file3.getName()
243: + "' opened", s0.substring(30, 43 + file3.getName()
244: .length()));
245:
246: for (int i = 0; i < NUM_THREADS; i++) {
247: String s1 = fin.readLine();
248: Date time1 = parse(s1);
249: assertTrue("Date of message within last 10 seconds", time1
250: .compareTo(earlier) >= 0
251: && time1.compareTo(now) <= 0);
252: assertEquals("Log message", "Test message", s1
253: .substring(30));
254: }
255:
256: fin.close();
257: }
258:
259: }
|