This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 158019
Collapse All | Expand All

(-)a/gsf.testrunner/manifest.mf (-1 / +1 lines)
Lines 3-7 Link Here
3
OpenIDE-Module: org.netbeans.modules.gsf.testrunner
3
OpenIDE-Module: org.netbeans.modules.gsf.testrunner
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/gsf/testrunner/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/gsf/testrunner/Bundle.properties
5
OpenIDE-Module-Layer: org/netbeans/modules/gsf/testrunner/layer.xml
5
OpenIDE-Module-Layer: org/netbeans/modules/gsf/testrunner/layer.xml
6
OpenIDE-Module-Specification-Version: 1.20
6
OpenIDE-Module-Specification-Version: 1.21
7
7
(-)a/gsf.testrunner/nbproject/project.xml (+1 lines)
Lines 166-171 Link Here
166
                <friend>org.netbeans.modules.android.testrunner</friend>
166
                <friend>org.netbeans.modules.android.testrunner</friend>
167
                <friend>org.netbeans.modules.cnd.cncppunit</friend>
167
                <friend>org.netbeans.modules.cnd.cncppunit</friend>
168
                <friend>org.netbeans.modules.cnd.testrunner</friend>
168
                <friend>org.netbeans.modules.cnd.testrunner</friend>
169
                <friend>org.netbeans.modules.hudson</friend>
169
                <friend>org.netbeans.modules.junit</friend>
170
                <friend>org.netbeans.modules.junit</friend>
170
                <friend>org.netbeans.modules.maven.junit</friend>
171
                <friend>org.netbeans.modules.maven.junit</friend>
171
                <friend>org.netbeans.modules.php.project</friend>
172
                <friend>org.netbeans.modules.php.project</friend>
(-)a/hudson/nbproject/project.xml (+8 lines)
Lines 51-56 Link Here
51
                    </run-dependency>
51
                    </run-dependency>
52
                </dependency>
52
                </dependency>
53
                <dependency>
53
                <dependency>
54
                    <code-name-base>org.netbeans.modules.gsf.testrunner</code-name-base>
55
                    <build-prerequisite/>
56
                    <compile-dependency/>
57
                    <run-dependency>
58
                        <specification-version>1.21</specification-version>
59
                    </run-dependency>
60
                </dependency>
61
                <dependency>
54
                    <code-name-base>org.netbeans.modules.keyring</code-name-base>
62
                    <code-name-base>org.netbeans.modules.keyring</code-name-base>
55
                    <build-prerequisite/>
63
                    <build-prerequisite/>
56
                    <compile-dependency/>
64
                    <compile-dependency/>
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/ShowFailures.java (-21 / +128 lines)
Lines 46-72 Link Here
46
import java.awt.event.ActionEvent;
46
import java.awt.event.ActionEvent;
47
import java.io.FileNotFoundException;
47
import java.io.FileNotFoundException;
48
import java.io.IOException;
48
import java.io.IOException;
49
import java.net.MalformedURLException;
50
import java.net.URL;
51
import java.util.ArrayList;
49
import java.util.ArrayList;
52
import java.util.List;
50
import java.util.List;
53
import java.util.Stack;
51
import java.util.Stack;
54
import java.util.logging.Level;
52
import java.util.logging.Level;
55
import java.util.logging.Logger;
53
import java.util.logging.Logger;
54
import java.util.regex.Matcher;
55
import java.util.regex.Pattern;
56
import javax.swing.AbstractAction;
56
import javax.swing.AbstractAction;
57
import javax.swing.Action;
57
import javax.swing.Action;
58
import org.netbeans.api.java.classpath.GlobalPathRegistry;
59
import org.netbeans.api.project.Project;
60
import org.netbeans.modules.gsf.testrunner.api.CallstackFrameNode;
61
import org.netbeans.modules.gsf.testrunner.api.DiffViewAction;
62
import org.netbeans.modules.gsf.testrunner.api.Manager;
63
import org.netbeans.modules.gsf.testrunner.api.TestMethodNode;
64
import org.netbeans.modules.gsf.testrunner.api.TestRunnerNodeFactory;
65
import org.netbeans.modules.gsf.testrunner.api.TestSession;
66
import org.netbeans.modules.gsf.testrunner.api.TestSuite;
67
import org.netbeans.modules.gsf.testrunner.api.Testcase;
68
import org.netbeans.modules.gsf.testrunner.api.TestsuiteNode;
69
import org.netbeans.modules.gsf.testrunner.api.Trouble;
58
import org.netbeans.modules.hudson.api.ConnectionBuilder;
70
import org.netbeans.modules.hudson.api.ConnectionBuilder;
59
import org.netbeans.modules.hudson.api.HudsonJob;
71
import org.netbeans.modules.hudson.api.HudsonJob;
60
import org.netbeans.modules.hudson.api.HudsonJobBuild;
72
import org.netbeans.modules.hudson.api.HudsonJobBuild;
61
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
73
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
62
import org.openide.awt.HtmlBrowser.URLDisplayer;
74
import org.netbeans.modules.hudson.spi.HudsonLogger;
75
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
76
import org.openide.filesystems.FileObject;
77
import org.openide.filesystems.FileUtil;
78
import org.openide.nodes.Node;
79
import org.openide.util.Lookup;
63
import org.openide.util.NbBundle.Messages;
80
import org.openide.util.NbBundle.Messages;
64
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
81
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
65
import org.openide.util.RequestProcessor;
82
import org.openide.util.RequestProcessor;
83
import org.openide.util.lookup.Lookups;
66
import org.openide.windows.IOProvider;
84
import org.openide.windows.IOProvider;
67
import org.openide.windows.InputOutput;
85
import org.openide.windows.InputOutput;
68
import org.openide.windows.OutputEvent;
69
import org.openide.windows.OutputListener;
70
import org.openide.windows.OutputWriter;
86
import org.openide.windows.OutputWriter;
71
import org.openide.xml.XMLUtil;
87
import org.openide.xml.XMLUtil;
72
import org.xml.sax.Attributes;
88
import org.xml.sax.Attributes;
Lines 106-113 Link Here
106
        new RequestProcessor(url + "testReport").post(this); // NOI18N
122
        new RequestProcessor(url + "testReport").post(this); // NOI18N
107
    }
123
    }
108
124
109
    @Messages({"# {0} - job #build", "ShowFailures.title={0} Test Failures",
125
    private static final Pattern ASSERTION_FAILURE = Pattern.compile("(?m)junit[.]framework[.](AssertionFailedError|(Array)?ComparisonFailure)|java[.]lang[.]AssertionError($|: )");
110
               "# {0} - class & method name of failed test", "# {1} - suite name of failed test", "ShowFailures.from_suite={0} (from {1})"})
126
127
    @Messages({
128
        "# {0} - job #build", "ShowFailures.title={0} Test Failures",
129
        "# {0} - class & method name of failed test", "# {1} - suite name of failed test", "ShowFailures.from_suite={0} (from {1})",
130
        "LBL_GotoSource=Go to Source"
131
    })
111
    public void run() {
132
    public void run() {
112
        try {
133
        try {
113
            XMLReader parser = XMLUtil.createXMLReader();
134
            XMLReader parser = XMLUtil.createXMLReader();
Lines 115-125 Link Here
115
                InputOutput io;
136
                InputOutput io;
116
                StringBuilder buf;
137
                StringBuilder buf;
117
                Hyperlinker hyperlinker = new Hyperlinker(job);
138
                Hyperlinker hyperlinker = new Hyperlinker(job);
139
                TestSession session = new TestSession(displayName, new Project() {
140
                    public @Override FileObject getProjectDirectory() {
141
                        return FileUtil.createMemoryFileSystem().getRoot();
142
                    }
143
                    public @Override Lookup getLookup() {
144
                        return Lookup.EMPTY;
145
                    }
146
                }, TestSession.SessionType.TEST, new TestRunnerNodeFactory() {
147
                    public @Override TestsuiteNode createTestSuiteNode(String suiteName, boolean filtered) {
148
                        // XXX could add OpenableInBrowser
149
                        return new TestsuiteNode(suiteName, filtered);
150
                    }
151
                    public @Override Node createTestMethodNode(final Testcase testcase, Project project) {
152
                        return new TestMethodNode(testcase, project, Lookups.singleton(new OpenableInBrowser() {
153
                            public @Override String getUrl() {
154
                                return url + "testReport/" + testcase.getClassName().replaceFirst("[.][^.]+$", "") + "/" + testcase.getClassName().replaceFirst(".+[.]", "") + "/" + testcase.getName() + "/";
155
                            }
156
                        })) {
157
                            public @Override Action[] getActions(boolean context) {
158
                                return new Action[] {
159
                                    // XXX singleton disabled since TR window has no activatedNodes (and no other parent of ResultTreeView implements Lookup.Provider)
160
                                    OpenUrlAction.get(OpenUrlAction.class).createContextAwareInstance(Lookups.singleton(this)),
161
                                    new DiffViewAction(testcase),
162
                                };
163
                            }
164
                        };
165
                    }
166
                    public @Override Node createCallstackFrameNode(String frameInfo, String displayName) {
167
                        return new CallstackFrameNode(frameInfo, displayName) {
168
                            public @Override Action getPreferredAction() {
169
                                return new AbstractAction(LBL_GotoSource()) {
170
                                    FileObject f;
171
                                    int line;
172
                                    {
173
                                        // XXX should have utility API to parse stack traces
174
                                        Matcher m = Pattern.compile("\tat (.+[.])[^.]+[.][^.]+[(]([^.]+[.]java):([0-9]+)[)]").matcher(frameInfo);
175
                                        if (m.matches()) {
176
                                            String resource = m.group(1).replace('.', '/') + m.group(2);
177
                                            f = GlobalPathRegistry.getDefault().findResource(resource);
178
                                            line = Integer.parseInt(m.group(3));
179
                                            LOG.log(Level.FINER, "matched {0} -> {1}", new Object[] {resource, f});
180
                                        } else {
181
                                            LOG.log(Level.FINER, "no match for {0}", frameInfo);
182
                                        }
183
                                        setEnabled(f != null);
184
                                    }
185
                                    public @Override void actionPerformed(ActionEvent e) {
186
                                        if (f != null) {
187
                                            HudsonLogger.Helper.openAt(f, line - 1, -1, true);
188
                                        }
189
                                    }
190
                                };
191
                            }
192
                            public @Override Action[] getActions(boolean context) {
193
                                return new Action[] {getPreferredAction()};
194
                            }
195
                        };
196
                    }
197
                });
118
                private void prepareOutput() {
198
                private void prepareOutput() {
119
                    if (io == null) {
199
                    if (io == null) {
120
                        String title = ShowFailures_title(displayName);
200
                        String title = ShowFailures_title(displayName);
121
                        io = IOProvider.getDefault().getIO(title, new Action[0]);
201
                        io = IOProvider.getDefault().getIO(title, new Action[0]);
122
                        io.select();
202
                        io.select();
203
                        Manager.getInstance().testStarted(session);
123
                    }
204
                    }
124
                }
205
                }
125
                class Suite {
206
                class Suite {
Lines 128-138 Link Here
128
                    String stderr;
209
                    String stderr;
129
                    Stack<Case> cases = new Stack<Case>();
210
                    Stack<Case> cases = new Stack<Case>();
130
                    List<Case> casesDone = new ArrayList<Case>();
211
                    List<Case> casesDone = new ArrayList<Case>();
212
                    long duration;
131
                }
213
                }
132
                class Case {
214
                class Case {
133
                    String className;
215
                    String className;
134
                    String name;
216
                    String name;
135
                    String errorStackTrace;
217
                    String errorStackTrace;
218
                    long duration;
219
                }
220
                long parseDuration(String d) {
221
                    if (d == null) {
222
                        return 0;
223
                    }
224
                    try {
225
                        return (long) (1000 * Float.parseFloat(d));
226
                    } catch (NumberFormatException x) {
227
                        return 0;
228
                    }
136
                }
229
                }
137
                Stack<Suite> suites = new Stack<Suite>();
230
                Stack<Suite> suites = new Stack<Suite>();
138
                public @Override void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
231
                public @Override void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
Lines 163-168 Link Here
163
                            s.stderr = text;
256
                            s.stderr = text;
164
                        } else if (qName.equals("name")) { // NOI18N
257
                        } else if (qName.equals("name")) { // NOI18N
165
                            s.name = text;
258
                            s.name = text;
259
                        } else if (qName.equals("duration")) { // NOI18N
260
                            s.duration = parseDuration(text);
166
                        }
261
                        }
167
                    } else { // case level
262
                    } else { // case level
168
                        Case c = s.cases.peek();
263
                        Case c = s.cases.peek();
Lines 172-177 Link Here
172
                            c.name = text;
267
                            c.name = text;
173
                        } else if (qName.equals("className")) { // NOI18N
268
                        } else if (qName.equals("className")) { // NOI18N
174
                            c.className = text;
269
                            c.className = text;
270
                        } else if (qName.equals("duration")) { // NOI18N
271
                            c.duration = parseDuration(text);
175
                        }
272
                        }
176
                    }
273
                    }
177
                    if (qName.equals("suite")) { // NOI18N
274
                    if (qName.equals("suite")) { // NOI18N
Lines 189-224 Link Here
189
                    prepareOutput();
286
                    prepareOutput();
190
                    OutputWriter out = io.getOut();
287
                    OutputWriter out = io.getOut();
191
                    OutputWriter err = io.getErr();
288
                    OutputWriter err = io.getErr();
289
                    TestSuite suite = new TestSuite(s.name);
290
                    session.addSuite(suite);
291
                    Manager.getInstance().displaySuiteRunning(session, suite.getName());
292
                    if (s.stderr != null) {
293
                        // XXX TR window does not seem to show only stdio from selected suite
294
                        Manager.getInstance().displayOutput(session, s.stderr, true);
295
                    }
296
                    if (s.stdout != null) {
297
                        Manager.getInstance().displayOutput(session, s.stdout, false);
298
                    }
192
                    for (final Case c : s.casesDone) {
299
                    for (final Case c : s.casesDone) {
193
                        if (c.errorStackTrace == null) {
300
                        if (c.errorStackTrace == null) {
194
                            continue;
301
                            continue;
195
                        }
302
                        }
196
                        String name = c.className + "." + c.name;
303
                        String name = c.className + "." + c.name;
304
                        String shortName = c.name;
197
                        if (s.name != null && !s.name.equals(c.className)) {
305
                        if (s.name != null && !s.name.equals(c.className)) {
306
                            shortName = name;
198
                            name = ShowFailures_from_suite(name, s.name);
307
                            name = ShowFailures_from_suite(name, s.name);
199
                        }
308
                        }
200
                        println();
309
                        println();
201
                        out.println(name, new OutputListener() {
310
                        out.println("[" + name + "]"); // XXX use color printing to make it stand out?
202
                            public void outputLineAction(OutputEvent ev) {
203
                                try {
204
                                    // XXX try to find name in Java method index and open it instead
205
                                    URLDisplayer.getDefault().showURL(new URL(url +
206
                                            "testReport/" + c.className.replaceFirst("[.][^.]+$", "") + "/" + // NOI18N
207
                                            c.className.replaceFirst(".+[.]", "") + "/" + c.name + "/")); // NOI18Nb
208
                                } catch (MalformedURLException x) {
209
                                    LOG.log(Level.FINE, null, x);
210
                                }
211
                            }
212
                            public void outputLineSelected(OutputEvent ev) {}
213
                            public void outputLineCleared(OutputEvent ev) {}
214
                        });
215
                        show(c.errorStackTrace, /* err is too hard to read */ out);
311
                        show(c.errorStackTrace, /* err is too hard to read */ out);
312
                        Testcase test = new Testcase(shortName, null, session);
313
                        test.setClassName(c.className);
314
                        Trouble trouble = new Trouble(!ASSERTION_FAILURE.matcher(c.errorStackTrace).lookingAt());
315
                        trouble.setStackTrace(c.errorStackTrace.split("\r?\n"));
316
                        // XXX call setComparisonFailure if matches "expected:<...> but was:<...>"
317
                        test.setTrouble(trouble);
318
                        LOG.log(Level.FINE, "got {0} as {1}", new Object[] {name, test.getStatus()});
319
                        test.setTimeMillis(c.duration);
320
                        session.addTestCase(test);
216
                    }
321
                    }
217
                    if (s.stderr != null || s.stdout != null) {
322
                    if (s.stderr != null || s.stdout != null) {
218
                        println();
323
                        println();
219
                        show(s.stderr, err);
324
                        show(s.stderr, err);
220
                        show(s.stdout, out);
325
                        show(s.stdout, out);
221
                    }
326
                    }
327
                    Manager.getInstance().displayReport(session, session.getReport(s.duration));
222
                }
328
                }
223
                boolean firstLine = true;
329
                boolean firstLine = true;
224
                void println() {
330
                void println() {
Lines 240-245 Link Here
240
                    if (io != null) {
346
                    if (io != null) {
241
                        io.getOut().close();
347
                        io.getOut().close();
242
                        io.getErr().close();
348
                        io.getErr().close();
349
                        Manager.getInstance().sessionFinished(session);
243
                    }
350
                    }
244
                }
351
                }
245
            });
352
            });

Return to bug 158019