File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\tasks\junit\JUnitResultArchiver.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt,
5 * Tom Huybrechts, Yahoo!, Inc., Richard Hierlmeier
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25 package hudson.tasks.junit;
26
27 import hudson.AbortException;
28 import hudson.Extension;
29 import hudson.FilePath;
30 import hudson.Launcher;
31 import hudson.matrix.MatrixAggregatable;
32 import hudson.matrix.MatrixAggregator;
33 import hudson.matrix.MatrixBuild;
34 import hudson.model.AbstractBuild;
35 import hudson.model.AbstractProject;
36 import hudson.model.Action;
37 import hudson.model.BuildListener;
38 import hudson.model.CheckPoint;
39 import hudson.model.Descriptor;
40 import hudson.model.Result;
41 import hudson.model.Saveable;
42 import hudson.tasks.BuildStepDescriptor;
43 import hudson.tasks.BuildStepMonitor;
44 import hudson.tasks.Publisher;
45 import hudson.tasks.Recorder;
46 import hudson.tasks.junit.TestResultAction.Data;
47 import hudson.tasks.test.TestResultAggregator;
48 import hudson.tasks.test.TestResultProjectAction;
49 import hudson.util.DescribableList;
50 import hudson.util.FormValidation;
51 import net.sf.json.JSONObject;
52 import org.apache.tools.ant.DirectoryScanner;
53 import org.apache.tools.ant.types.FileSet;
54 import org.kohsuke.stapler.AncestorInPath;
55 import org.kohsuke.stapler.DataBoundConstructor;
56 import org.kohsuke.stapler.QueryParameter;
57 import org.kohsuke.stapler.StaplerRequest;
58
59 import java.io.IOException;
60 import java.io.Serializable;
61 import java.util.ArrayList;
62 import java.util.Collection;
63 import java.util.Collections;
64 import java.util.List;
65
66 /**
67 * Generates HTML report from JUnit test result XML files.
68 *
69 * @author Kohsuke Kawaguchi
70 */
71 public class JUnitResultArchiver extends Recorder implements MatrixAggregatable {
72
73 /**
74 * {@link FileSet} "includes" string, like "foo/bar/*.xml"
75 */
76 private final String testResults;
77
78 /**
79 * If true, retain a suite's complete stdout/stderr even if this is huge and the suite passed.
80 * @since 1.358
81 */
82 private final boolean keepLongStdio;
83
84 /**
85 * {@link TestDataPublisher}s configured for this archiver, to process the recorded data.
86 * For compatibility reasons, can be null.
87 * @since 1.320
88 */
89 private final DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers;
90
91 /**
92 * left for backwards compatibility
93 * @deprecated since 2009-08-09.
94 */
95 @Deprecated
96 public JUnitResultArchiver(String testResults) {
97 this(testResults, false, null);
98 }
99
100 @Deprecated
101 public JUnitResultArchiver(String testResults,
102 DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers) {
103 this(testResults, false, testDataPublishers);
104 }
105
106 @DataBoundConstructor
107 public JUnitResultArchiver(
108 String testResults,
109 boolean keepLongStdio,
110 DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers) {
111 this.testResults = testResults;
112 this.keepLongStdio = keepLongStdio;
113 this.testDataPublishers = testDataPublishers;
114 }
115
116 /**
117 * In progress. Working on delegating the actual parsing to the JUnitParser.
118 */
119 protected TestResult parse(String expandedTestResults, AbstractBuild build, Launcher launcher, BuildListener listener)
120 throws IOException, InterruptedException
121 {
122 return new JUnitParser(isKeepLongStdio()).parse(expandedTestResults, build, launcher, listener);
123 }
124
125 @Override
126 public boolean perform(AbstractBuild build, Launcher launcher,
127 BuildListener listener) throws InterruptedException, IOException {
128 listener.getLogger().println(Messages.JUnitResultArchiver_Recording());
129 TestResultAction action;
130
131 final String testResults = build.getEnvironment(listener).expand(this.testResults);
132
133 try {
134 TestResult result = parse(testResults, build, launcher, listener);
135
136 try {
137 action = new TestResultAction(build, result, listener);
138 } catch (NullPointerException npe) {
139 throw new AbortException(Messages.JUnitResultArchiver_BadXML(testResults));
140 }
141 result.freeze(action);
142 if (result.getPassCount() == 0 && result.getFailCount() == 0)
143 throw new AbortException(Messages.JUnitResultArchiver_ResultIsEmpty());
144
145 // TODO: Move into JUnitParser [BUG 3123310]
146 List<Data> data = new ArrayList<Data>();
147 if (testDataPublishers != null) {
148 for (TestDataPublisher tdp : testDataPublishers) {
149 Data d = tdp.getTestData(build, launcher, listener, result);
150 if (d != null) {
151 data.add(d);
152 }
153 }
154 }
155
156 action.setData(data);
157
158 CHECKPOINT.block();
159
160 } catch (AbortException e) {
161 if (build.getResult() == Result.FAILURE)
162 // most likely a build failed before it gets to the test phase.
163 // don't report confusing error message.
164 return true;
165
166 listener.getLogger().println(e.getMessage());
167 build.setResult(Result.FAILURE);
168 return true;
169 } catch (IOException e) {
170 e.printStackTrace(listener.error("Failed to archive test reports"));
171 build.setResult(Result.FAILURE);
172 return true;
173 }
174
175 build.getActions().add(action);
176 CHECKPOINT.report();
177
178 if (action.getResult().getFailCount() > 0)
179 build.setResult(Result.UNSTABLE);
180
181 return true;
182 }
183
184 /**
185 * Not actually used, but left for backward compatibility
186 *
187 * @deprecated since 2009-08-10.
188 */
189 protected TestResult parseResult(DirectoryScanner ds, long buildTime)
190 throws IOException {
191 return new TestResult(buildTime, ds);
192 }
193
194 /**
195 * This class does explicit checkpointing.
196 */
197 public BuildStepMonitor getRequiredMonitorService() {
198 return BuildStepMonitor.NONE;
199 }
200
201 public String getTestResults() {
202 return testResults;
203 }
204
205 public DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> getTestDataPublishers() {
206 return testDataPublishers;
207 }
208
209 @Override
210 public Collection<Action> getProjectActions(AbstractProject<?, ?> project) {
211 return Collections.<Action>singleton(new TestResultProjectAction(project));
212 }
213
214 public MatrixAggregator createAggregator(MatrixBuild build,
215 Launcher launcher, BuildListener listener) {
216 return new TestResultAggregator(build, launcher, listener);
217 }
218
219 /**
220 * @return the keepLongStdio
221 */
222 public boolean isKeepLongStdio() {
223 return keepLongStdio;
224 }
225
226 /**
227 * Test result tracks the diff from the previous run, hence the checkpoint.
228 */
229 private static final CheckPoint CHECKPOINT = new CheckPoint(
230 "JUnit result archiving");
231
232 private static final long serialVersionUID = 1L;
233
234 @Extension
235 public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
236 public String getDisplayName() {
237 return Messages.JUnitResultArchiver_DisplayName();
238 }
239
240 @Override
241 public String getHelpFile() {
242 return "/help/tasks/junit/report.html";
243 }
244
245 @Override
246 public Publisher newInstance(StaplerRequest req, JSONObject formData)
247 throws hudson.model.Descriptor.FormException {
248 String testResults = formData.getString("testResults");
249 boolean keepLongStdio = formData.getBoolean("keepLongStdio");
250 DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers = new DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>>(Saveable.NOOP);
251 try {
252 testDataPublishers.rebuild(req, formData, TestDataPublisher.all());
253 } catch (IOException e) {
254 throw new FormException(e,null);
255 }
256
257 return new JUnitResultArchiver(testResults, keepLongStdio, testDataPublishers);
258 }
259
260 /**
261 * Performs on-the-fly validation on the file mask wildcard.
262 */
263 public FormValidation doCheckTestResults(
264 @AncestorInPath AbstractProject project,
265 @QueryParameter String value) throws IOException {
266 return FilePath.validateFileMask(project.getSomeWorkspace(), value);
267 }
268
269 public boolean isApplicable(Class<? extends AbstractProject> jobType) {
270 return true;
271 }
272 }
273 }
274