KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > module > run > StandardLoggerTest


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.apache.tools.ant.module.run;
21
22 import java.io.File JavaDoc;
23 import java.net.MalformedURLException JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Arrays JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.WeakHashMap JavaDoc;
32 import java.util.logging.Level JavaDoc;
33 import java.util.regex.Matcher JavaDoc;
34 import java.util.regex.Pattern JavaDoc;
35 import org.apache.tools.ant.module.spi.AntEvent;
36 import org.apache.tools.ant.module.spi.AntLogger;
37 import org.apache.tools.ant.module.spi.AntSession;
38 import org.apache.tools.ant.module.spi.TaskStructure;
39 import org.netbeans.junit.NbTestCase;
40 import org.openide.filesystems.FileUtil;
41 import org.openide.util.NbBundle;
42 import org.openide.util.Utilities;
43 import org.openide.util.WeakSet;
44 import org.openide.windows.OutputEvent;
45 import org.openide.windows.OutputListener;
46
47 /**
48  * Tests functionality of the standard logger using a mock execution environment.
49  * @author Jesse Glick
50  */

51 public class StandardLoggerTest extends NbTestCase {
52     
53     // XXX set up mock StatusDisplayer impl?
54

55     public StandardLoggerTest(String JavaDoc name) {
56         super(name);
57     }
58     
59     public void testBasicUsage() throws Exception JavaDoc {
60         // Just simulates something like
61
// <target name="some-target">
62
// <echo>some message</echo>
63
// <target>
64
AntLogger[] loggers = new AntLogger[] {new StandardLogger(15345L)};
65         MockAntSession session = new MockAntSession(loggers, AntEvent.LOG_INFO);
66         AntSession realSession = LoggerTrampoline.ANT_SESSION_CREATOR.makeAntSession(session);
67         session.sendBuildStarted(makeAntEvent(realSession, null, -1, null, null, null));
68         session.sendTargetStarted(makeAntEvent(realSession, null, -1, null, "some-target", null));
69         session.sendMessageLogged(makeAntEvent(realSession, "some message", AntEvent.LOG_WARN, null, null, null));
70         session.sendTargetFinished(makeAntEvent(realSession, null, -1, null, "some-target", null));
71         session.sendBuildFinished(makeAntEvent(realSession, null, -1, null, null, null));
72         List JavaDoc<Message> expectedMessages = Arrays.asList(new Message[] {
73             new Message(NbBundle.getMessage(StandardLogger.class, "MSG_target_started_printed", "some-target"), false, null),
74             new Message("some message", true, null),
75             new Message(NbBundle.getMessage(StandardLogger.class, "FMT_finished_target_printed", new Integer JavaDoc(0), new Integer JavaDoc(15)), false, null),
76         });
77         assertEquals("correct text printed", expectedMessages, session.messages);
78     }
79     
80     public void testMultilineMessagesSplit() throws Exception JavaDoc {
81         // Tests what happens when messages with embedded newlines are sent.
82
// Does not cover build-terminating errors; for that use testThrownErrors.
83
AntLogger[] loggers = new AntLogger[] {new MockStackTraceLogger(), new StandardLogger(1000L)};
84         MockAntSession session = new MockAntSession(loggers, AntEvent.LOG_INFO);
85         AntSession realSession = LoggerTrampoline.ANT_SESSION_CREATOR.makeAntSession(session);
86         session.sendBuildStarted(makeAntEvent(realSession, null, -1, null, null, null));
87         session.sendMessageLogged(makeAntEvent(realSession, "Stack trace in separate lines:", AntEvent.LOG_INFO, null, null, null));
88         session.sendMessageLogged(makeAntEvent(realSession, "\tat Foo.java:3", AntEvent.LOG_INFO, null, null, null));
89         session.sendMessageLogged(makeAntEvent(realSession, "\tat Bar.java:5", AntEvent.LOG_INFO, null, null, null));
90         session.sendMessageLogged(makeAntEvent(realSession, "Stack trace in one big line:\n" +
91                                                             "\tat Quux.java:11\n" +
92                                                             "\tat Baz.java:6\n" +
93                                                             "...and an unrelated message",
94             AntEvent.LOG_WARN, null, null, null));
95         session.sendBuildFinished(makeAntEvent(realSession, null, -1, null, null, null));
96         List JavaDoc<Message> expectedMessages = Arrays.asList(new Message[] {
97             new Message("Stack trace in separate lines:", false, null),
98             new Message("\tat Foo.java:3", false, new MockHyperlink("file:/src/Foo.java", "stack trace", 3, -1, -1, -1)),
99             new Message("\tat Bar.java:5", false, new MockHyperlink("file:/src/Bar.java", "stack trace", 5, -1, -1, -1)),
100             new Message("Stack trace in one big line:", true, null),
101             new Message("\tat Quux.java:11", true, new MockHyperlink("file:/src/Quux.java", "stack trace", 11, -1, -1, -1)),
102             new Message("\tat Baz.java:6", true, new MockHyperlink("file:/src/Baz.java", "stack trace", 6, -1, -1, -1)),
103             new Message("...and an unrelated message", true, null),
104             new Message(NbBundle.getMessage(StandardLogger.class, "FMT_finished_target_printed", new Integer JavaDoc(0), new Integer JavaDoc(1)), false, null),
105         });
106         assertEquals("correct text printed", expectedMessages, session.messages);
107     }
108
109     public void testFileHyperlinks() throws Exception JavaDoc {
110         clearWorkDir();
111         File JavaDoc top = new File JavaDoc(getWorkDir(), "top");
112         FileUtil.createData(top);
113         File JavaDoc dir1 = new File JavaDoc(getWorkDir(), "dir1");
114         File JavaDoc middle = new File JavaDoc(dir1, "middle");
115         FileUtil.createData(middle);
116         File JavaDoc dir2 = new File JavaDoc(dir1, "dir2");
117         File JavaDoc bottom = new File JavaDoc(dir2, "bottom");
118         FileUtil.createData(bottom);
119         MockAntSession session = new MockAntSession(new AntLogger[] {new StandardLogger(1000L)}, AntEvent.LOG_INFO);
120         AntSession realSession = LoggerTrampoline.ANT_SESSION_CREATOR.makeAntSession(session);
121         session.sendBuildStarted(makeAntEvent(realSession, null, -1, null, null, null));
122         session.sendTargetStarted(makeAntEvent(realSession, null, -1, null, "some-target", null));
123         /* Can't test, since the file does not actually exist:
124         session.sendMessageLogged(makeAntEvent(realSession, "c:\\temp\\foo: malformed", AntEvent.LOG_WARN, null, null, null));
125         session.sendMessageLogged(makeAntEvent(realSession, "c:\\temp\\bar:27: really malformed", AntEvent.LOG_WARN, null, null, null));
126         */

127         session.sendMessageLogged(makeAntEvent(realSession, top + ":1: some problem", AntEvent.LOG_WARN, null, null, null));
128         session.sendMessageLogged(makeAntEvent(realSession, top.toURI() + ":1:10:2:5: same problem", AntEvent.LOG_WARN, null, null, null));
129         session.sendMessageLogged(makeAntEvent(realSession, "make: Entering directory `" + dir1 + "'", AntEvent.LOG_INFO, null, null, null));
130         session.sendMessageLogged(makeAntEvent(realSession, "middle:2:3: some other problem", AntEvent.LOG_WARN, null, null, null));
131         session.sendMessageLogged(makeAntEvent(realSession, "../top: yet another problem", AntEvent.LOG_WARN, null, null, null));
132         session.sendMessageLogged(makeAntEvent(realSession, "make: Entering directory `" + dir2 + "'", AntEvent.LOG_INFO, null, null, null));
133         session.sendMessageLogged(makeAntEvent(realSession, "bottom: something new", AntEvent.LOG_WARN, null, null, null));
134         session.sendMessageLogged(makeAntEvent(realSession, "\"../middle\", line 12: warning: statement is stupid", AntEvent.LOG_WARN, null, null, null));
135         session.sendMessageLogged(makeAntEvent(realSession, "make: Leaving directory `" + dir2 + "'", AntEvent.LOG_INFO, null, null, null));
136         session.sendMessageLogged(makeAntEvent(realSession, "middle: back here", AntEvent.LOG_WARN, null, null, null));
137         session.sendMessageLogged(makeAntEvent(realSession, "make: Leaving directory `" + dir1 + "'", AntEvent.LOG_INFO, null, null, null));
138         session.sendTargetFinished(makeAntEvent(realSession, null, -1, null, "some-target", null));
139         session.sendBuildFinished(makeAntEvent(realSession, null, -1, null, null, null));
140         List JavaDoc<Message> expectedMessages = Arrays.asList(
141             new Message(NbBundle.getMessage(StandardLogger.class, "MSG_target_started_printed", "some-target"), false, null),
142             /*
143             new Message("c:\\temp\\foo: malformed", true, new MockHyperlink("c:\\temp\\foo", "malformed", -1, -1, -1, -1)),
144             new Message("c:\\temp\\bar:27: really malformed", true, new MockHyperlink("c:\\temp\\bar", "really malformed", 27, -1, -1, -1)),
145              */

146             new Message(top + ":1: some problem", true, new MockHyperlink(top.toURI().toString(), "some problem", 1, -1, -1, -1)),
147             new Message(top.toURI() + ":1:10:2:5: same problem", true, new MockHyperlink(top.toURI().toString(), "same problem", 1, 10, 2, 5)),
148             new Message("make: Entering directory `" + dir1 + "'", false, null),
149             new Message("middle:2:3: some other problem", true, new MockHyperlink(middle.toURI().toString(), "some other problem", 2, 3, -1, -1)),
150             new Message("../top: yet another problem", true, new MockHyperlink(top.toURI().toString(), "yet another problem", -1, -1, -1, -1)),
151             new Message("make: Entering directory `" + dir2 + "'", false, null),
152             new Message("bottom: something new", true, new MockHyperlink(bottom.toURI().toString(), "something new", -1, -1, -1, -1)),
153             new Message("\"../middle\", line 12: warning: statement is stupid", true, new MockHyperlink(middle.toURI().toString(), "warning: statement is stupid", 12, -1, -1, -1)),
154             new Message("make: Leaving directory `" + dir2 + "'", false, null),
155             new Message("middle: back here", true, new MockHyperlink(middle.toURI().toString(), "back here", -1, -1, -1, -1)),
156             new Message("make: Leaving directory `" + dir1 + "'", false, null),
157             new Message(NbBundle.getMessage(StandardLogger.class, "FMT_finished_target_printed", 0, 1), false, null));
158         assertEquals("correct text printed", expectedMessages.toString(), session.messages.toString());
159         
160     }
161     
162     // XXX testVerbosityLevels
163
// XXX testThrownErrors
164
// XXX testCaretShowingColumn
165

166     /**
167      * Create an event to be delivered.
168      */

169     private static AntEvent makeAntEvent(AntSession realSession, String JavaDoc message, int level, Throwable JavaDoc exc, String JavaDoc target, String JavaDoc task) {
170         return LoggerTrampoline.ANT_EVENT_CREATOR.makeAntEvent(new MockAntEvent(realSession, message, level, exc, target, task));
171     }
172
173     /**
174      * Minimal session implementation.
175      * Supports delivery of various events, though it does no filtering beyond
176      * filtering of messageLogged according to log level (has a custom verbosity).
177      * Handles custom data and consumption of exceptions.
178      * See {@link MockHyperlink} for hyperlink impl.
179      * Display name always "Mock Session"; orig target is "mock-target"; orig script is "/tmp/mock-script".
180      */

181     private static final class MockAntSession implements LoggerTrampoline.AntSessionImpl {
182         
183         private final AntLogger[] loggers;
184         private final int verbosity;
185         private final Map JavaDoc<AntLogger,Object JavaDoc> customData = new WeakHashMap JavaDoc<AntLogger,Object JavaDoc>();
186         private final Set JavaDoc<Throwable JavaDoc> consumedExceptions = new WeakSet<Throwable JavaDoc>();
187         public final List JavaDoc<Message> messages = new ArrayList JavaDoc<Message>();
188         
189         public MockAntSession(AntLogger[] loggers, int verbosity) {
190             this.loggers = loggers;
191             this.verbosity = verbosity;
192         }
193         
194         public void sendMessageLogged(AntEvent event) {
195             for (AntLogger logger : loggers) {
196                 int[] levels = logger.interestedInLogLevels(event.getSession());
197                 Arrays.sort(levels);
198                 if (Arrays.binarySearch(levels, event.getLogLevel()) >= 0) {
199                     logger.messageLogged(event);
200                 }
201             }
202         }
203         
204         public void sendBuildStarted(AntEvent event) {
205             for (AntLogger logger : loggers) {
206                 logger.buildStarted(event);
207             }
208         }
209         
210         public void sendBuildFinished(AntEvent event) {
211             for (AntLogger logger : loggers) {
212                 logger.buildFinished(event);
213             }
214         }
215         
216         public void sendBuildInitializationFailed(AntEvent event) {
217             for (AntLogger logger : loggers) {
218                 logger.buildInitializationFailed(event);
219             }
220         }
221         
222         public void sendTargetStarted(AntEvent event) {
223             for (AntLogger logger : loggers) {
224                 logger.targetStarted(event);
225             }
226         }
227         
228         public void sendTargetFinished(AntEvent event) {
229             for (AntLogger logger : loggers) {
230                 logger.targetFinished(event);
231             }
232         }
233         
234         public void sendTaskStarted(AntEvent event) {
235             for (AntLogger logger : loggers) {
236                 logger.taskStarted(event);
237             }
238         }
239         
240         public void sendTaskFinished(AntEvent event) {
241             for (AntLogger logger : loggers) {
242                 logger.taskFinished(event);
243             }
244         }
245         
246         public void deliverMessageLogged(AntEvent originalEvent, String JavaDoc message, int level) {
247             sendMessageLogged(makeAntEvent(originalEvent.getSession(), message, level, null, originalEvent.getTargetName(), originalEvent.getTaskName()));
248         }
249
250         public OutputListener createStandardHyperlink(URL JavaDoc file, String JavaDoc message, int line1, int column1, int line2, int column2) {
251             return new MockHyperlink(file.toExternalForm(), message, line1, column1, line2, column2);
252         }
253
254         public void println(String JavaDoc message, boolean err, OutputListener listener) {
255             messages.add(new Message(message, err, listener));
256         }
257
258         public void putCustomData(AntLogger logger, Object JavaDoc data) {
259             customData.put(logger, data);
260         }
261
262         public boolean isExceptionConsumed(Throwable JavaDoc t) { // copied from NbBuildLogger
263
if (consumedExceptions.contains(t)) {
264                 return true;
265             }
266             Throwable JavaDoc nested = t.getCause();
267             if (nested != null && isExceptionConsumed(nested)) {
268                 consumedExceptions.add(t);
269                 return true;
270             }
271             return false;
272         }
273
274         public void consumeException(Throwable JavaDoc t) throws IllegalStateException JavaDoc { // copied from NbBuildLogger
275
if (isExceptionConsumed(t)) {
276                 throw new IllegalStateException JavaDoc();
277             }
278             consumedExceptions.add(t);
279         }
280
281         public Object JavaDoc getCustomData(AntLogger logger) {
282             return customData.get(logger);
283         }
284
285         public int getVerbosity() {
286             return verbosity;
287         }
288
289         public String JavaDoc[] getOriginatingTargets() {
290             return new String JavaDoc[] {"mock-target"};
291         }
292
293         public File JavaDoc getOriginatingScript() {
294             return new File JavaDoc(System.getProperty("java.io.tmpdir"), "mock-script");
295         }
296
297         public String JavaDoc getDisplayName() {
298             return "Mock Session";
299         }
300         
301     }
302
303     /**
304      * Minimal event class.
305      * Supports a message, level, exception, target and task.
306      * Supports isConsumed/consume.
307      */

308     private static final class MockAntEvent implements LoggerTrampoline.AntEventImpl {
309         
310         private final AntSession session;
311         private final String JavaDoc message;
312         private final int level;
313         private final Throwable JavaDoc exc;
314         private final String JavaDoc target;
315         private final String JavaDoc task;
316         private boolean consumed = false;
317         
318         public MockAntEvent(AntSession session, String JavaDoc message, int level, Throwable JavaDoc exc, String JavaDoc target, String JavaDoc task) {
319             this.session = session;
320             this.message = message;
321             this.level = level;
322             this.exc = exc;
323             this.target = target;
324             this.task = task;
325         }
326         
327         public String JavaDoc evaluate(String JavaDoc text) {
328             return null;
329         }
330
331         public String JavaDoc getProperty(String JavaDoc name) {
332             return null;
333         }
334
335         public boolean isConsumed() {
336             return consumed;
337         }
338
339         public void consume() throws IllegalStateException JavaDoc {
340             if (consumed) {
341                 throw new IllegalStateException JavaDoc();
342             } else {
343                 consumed = true;
344             }
345         }
346
347         public Throwable JavaDoc getException() {
348             return exc;
349         }
350
351         public int getLine() {
352             return -1;
353         }
354
355         public int getLogLevel() {
356             return level;
357         }
358
359         public String JavaDoc getMessage() {
360             return message;
361         }
362
363         public Set JavaDoc<String JavaDoc> getPropertyNames() {
364             return Collections.emptySet();
365         }
366
367         public File JavaDoc getScriptLocation() {
368             return null;
369         }
370
371         public AntSession getSession() {
372             return session;
373         }
374
375         public String JavaDoc getTargetName() {
376             return target;
377         }
378
379         public String JavaDoc getTaskName() {
380             return task;
381         }
382
383         public TaskStructure getTaskStructure() {
384             return null;
385         }
386         
387     }
388     
389     /**
390      * Struct representing a message printed to an output stream.
391      */

392     private static final class Message {
393         
394         public final String JavaDoc message;
395         public final boolean err;
396         public final MockHyperlink hyperlink;
397         
398         public Message(String JavaDoc message, boolean err, OutputListener listener) {
399             this.message = message;
400             this.err = err;
401             if (listener instanceof MockHyperlink) {
402                 hyperlink = (MockHyperlink) listener;
403             } else {
404                 hyperlink = null;
405             }
406         }
407         
408         @Override JavaDoc
409         public boolean equals(Object JavaDoc o) {
410             if (o instanceof Message) {
411                 Message m = (Message) o;
412                 return m.message.equals(message) && m.err == err && Utilities.compareObjects(m.hyperlink, hyperlink);
413             } else {
414                 return false;
415             }
416         }
417         
418         @Override JavaDoc
419         public String JavaDoc toString() {
420             return "Message[" + message + "]" + (err ? "(err)" : "(out)") + (hyperlink != null ? "(" + hyperlink + ")" : "");
421         }
422         
423     }
424
425     /**
426      * Struct representing a hyperlink in a message.
427      */

428     private static final class MockHyperlink implements OutputListener {
429         
430         public final String JavaDoc url;
431         public final String JavaDoc message;
432         public final int line1;
433         public final int column1;
434         public final int line2;
435         public final int column2;
436         
437         public MockHyperlink(String JavaDoc url, String JavaDoc message, int line1, int column1, int line2, int column2) {
438             this.url = url;
439             this.message = message;
440             this.line1 = line1;
441             this.column1 = column1;
442             this.line2 = line2;
443             this.column2 = column2;
444         }
445         
446         @Override JavaDoc
447         public boolean equals(Object JavaDoc o) {
448             if (o instanceof MockHyperlink) {
449                 MockHyperlink h = (MockHyperlink) o;
450                 return h.url.equals(url) && h.message.equals(message) &&
451                     h.line1 == line1 && h.column1 == column1 && h.line2 == line2 && h.column2 == column2;
452             } else {
453                 return false;
454             }
455         }
456         
457         @Override JavaDoc
458         public String JavaDoc toString() {
459             return "MockHyperlink[" + url + ":" + line1 + ":" + column1 + ":" + line2 + ":" + column2 + ":" + message + "]";
460         }
461
462         public void outputLineSelected(OutputEvent ev) {}
463
464         public void outputLineCleared(OutputEvent ev) {}
465
466         public void outputLineAction(OutputEvent ev) {}
467         
468     }
469
470     /**
471      * Sample logger which hyperlinks stuff looking a bit like Java stack traces,
472      * to test redelivery of logging events.
473      */

474     private static final class MockStackTraceLogger extends AntLogger {
475         
476         private static final Pattern JavaDoc STACK_TRACE_LINE = Pattern.compile("\tat ([a-zA-Z]+\\.java):([0-9]+)");
477         
478         public MockStackTraceLogger() {}
479
480         @Override JavaDoc
481         public void messageLogged(AntEvent event) {
482             if (event.isConsumed()) {
483                 return;
484             }
485             Matcher JavaDoc m = STACK_TRACE_LINE.matcher(event.getMessage());
486             if (m.matches()) {
487                 event.consume();
488                 String JavaDoc filename = m.group(1);
489                 int line = Integer.parseInt(m.group(2));
490                 AntSession session = event.getSession();
491                 URL JavaDoc u;
492                 try {
493                     u = new URL JavaDoc("file:/src/" + filename);
494                 } catch (MalformedURLException JavaDoc e) {
495                     throw new AssertionError JavaDoc(e);
496                 }
497                 session.println(event.getMessage(),
498                     event.getLogLevel() <= AntEvent.LOG_WARN,
499                     session.createStandardHyperlink(u, "stack trace", line, -1, -1, -1));
500             }
501         }
502
503         @Override JavaDoc
504         public String JavaDoc[] interestedInTasks(AntSession session) {
505             return AntLogger.ALL_TASKS;
506         }
507
508         @Override JavaDoc
509         public String JavaDoc[] interestedInTargets(AntSession session) {
510             return AntLogger.ALL_TARGETS;
511         }
512
513         @Override JavaDoc
514         public boolean interestedInSession(AntSession session) {
515             return true;
516         }
517
518         @Override JavaDoc
519         public int[] interestedInLogLevels(AntSession session) {
520             return new int[] {
521                 AntEvent.LOG_INFO,
522                 AntEvent.LOG_WARN,
523                 AntEvent.LOG_ERR,
524             };
525         }
526
527         @Override JavaDoc
528         public boolean interestedInAllScripts(AntSession session) {
529             return true;
530         }
531
532         @Override JavaDoc
533         public boolean interestedInScript(File JavaDoc script, AntSession session) {
534             return true;
535         }
536         
537     }
538     
539     @Override JavaDoc
540     protected Level JavaDoc logLevel() {
541         return Level.FINE;
542     }
543
544 }
545
Popular Tags