> getAttachments() {
27 | return attachments;
28 | }
29 |
30 | public String getUrl(String testCase, String filename) {
31 | if (this.attachmentsStoredAtClassLevel) {
32 | return "attachments/" + Util.rawEncode(filename);
33 | }
34 |
35 | return "attachments/" + Util.rawEncode(testCase) + "/" + Util.rawEncode(filename);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/resources/hudson/plugins/junitattachments/AttachmentPublisher/config.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/main/resources/hudson/plugins/junitattachments/AttachmentTestAction/sidepanel.jelly:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/hudson/plugins/junitattachments/TestCaseAttachmentTestAction/summary.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ${%Attachments}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ${attachment}
18 | |
19 |
20 |
21 |
22 | |
23 |
24 |
--------------------------------------------------------------------------------
/src/main/resources/hudson/plugins/junitattachments/TestClassAttachmentTestAction/summary.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ${%Attachments}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | ${entry.key} |
17 |
18 |
19 | ${file}
22 | |
23 |
24 |
25 |
26 |
27 | |
28 |
29 |
--------------------------------------------------------------------------------
/src/main/resources/index.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 | This plugin can archive certain files (attachments) together with your JUnit results.
4 | Attached files are shown in the JUnit results.
5 |
6 |
--------------------------------------------------------------------------------
/src/test/java/hudson/plugins/junitattachments/AttachmentPublisherPipelineTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2016, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | *
24 | */
25 | package hudson.plugins.junitattachments;
26 |
27 | import hudson.FilePath;
28 | import hudson.model.Result;
29 | import hudson.tasks.junit.CaseResult;
30 | import hudson.tasks.junit.ClassResult;
31 | import hudson.tasks.junit.TestResultAction;
32 | import hudson.tasks.test.TestResult;
33 | import org.apache.commons.io.IOUtils;
34 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
35 | import org.jenkinsci.plugins.workflow.job.WorkflowJob;
36 | import org.jenkinsci.plugins.workflow.job.WorkflowRun;
37 | import org.junit.jupiter.api.Test;
38 | import org.jvnet.hudson.test.Issue;
39 | import org.jvnet.hudson.test.JenkinsRule;
40 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
41 |
42 | import java.io.IOException;
43 | import java.net.URL;
44 | import java.nio.file.Paths;
45 | import java.nio.charset.StandardCharsets;
46 | import java.util.Collection;
47 | import java.util.Collections;
48 | import java.util.List;
49 | import java.util.Map;
50 |
51 | import static hudson.plugins.junitattachments.AttachmentPublisherTest.getClassResult;
52 | import static org.junit.jupiter.api.Assertions.assertEquals;
53 | import static org.junit.jupiter.api.Assertions.assertNotNull;
54 |
55 | @WithJenkins
56 | class AttachmentPublisherPipelineTest {
57 | // Package name used in tests in workspace2.zip
58 | private static final String TEST_PACKAGE = "com.example.test";
59 |
60 | @Test
61 | void testWellKnownFilenamesAreAttached(JenkinsRule jenkinsRule) throws Exception {
62 | TestResultAction action = getTestResultActionForPipeline(jenkinsRule, "workspace.zip", "pipelineTest.groovy", Result.SUCCESS);
63 |
64 | ClassResult cr = getClassResult(action, "test.foo.bar", "DefaultIntegrationTest");
65 |
66 | TestClassAttachmentTestAction ata = cr.getTestAction(TestClassAttachmentTestAction.class);
67 | assertNotNull(ata);
68 |
69 | Map> attachmentsByTestCase = ata.getAttachments();
70 | assertNotNull(attachmentsByTestCase);
71 | assertEquals(1, attachmentsByTestCase.size());
72 |
73 | List testCaseAttachments = attachmentsByTestCase.get("");
74 | assertEquals(2, testCaseAttachments.size());
75 | Collections.sort(testCaseAttachments);
76 | assertEquals("file", testCaseAttachments.get(0));
77 | assertEquals("test.foo.bar.DefaultIntegrationTest-output.txt", testCaseAttachments.get(1));
78 | }
79 |
80 | @Issue("JENKINS-36504")
81 | @Test
82 | void annotationDoesNotFailForPipeline(JenkinsRule jenkinsRule) throws Exception {
83 | TestResultAction action = getTestResultActionForPipeline(jenkinsRule, "workspace2.zip", "pipelineTest.groovy", Result.UNSTABLE);
84 |
85 | ClassResult cr = getClassResult(action, TEST_PACKAGE, "SignupTest");
86 | Collection extends TestResult> caseResults = cr.getChildren();
87 | assertEquals(3, caseResults.size());
88 |
89 | CaseResult failingCase = cr.getCaseResult("A_003_Type_the_text__jenkins__into_the_field__username_");
90 | assertNotNull(failingCase);
91 | assertEquals("Timed out after 10 seconds", failingCase.annotate(failingCase.getErrorDetails()));
92 |
93 | TestCaseAttachmentTestAction ata = failingCase.getTestAction(TestCaseAttachmentTestAction.class);
94 | assertNotNull(ata);
95 |
96 | final List attachments = ata.getAttachments();
97 | assertNotNull(attachments);
98 | assertEquals(1, attachments.size());
99 |
100 | Collections.sort(attachments);
101 | assertEquals("signup-username", attachments.get(0));
102 | }
103 |
104 | @Test
105 | void testBothWellKnownFilenamesAndPatternAreAttached(JenkinsRule jenkinsRule) throws Exception {
106 | TestResultAction action = getTestResultActionForPipeline(jenkinsRule, "workspace4.zip", "pipelineTest.groovy", Result.SUCCESS);
107 |
108 | ClassResult cr = getClassResult(action, "test.foo.bar", "DefaultIntegrationTest");
109 | {
110 | TestClassAttachmentTestAction ata = cr.getTestAction(TestClassAttachmentTestAction.class);
111 | assertNotNull(ata);
112 | final Map> attachmentsByTestCase = ata.getAttachments();
113 | assertNotNull(attachmentsByTestCase);
114 | assertEquals(2, attachmentsByTestCase.size());
115 |
116 | List testClassAttachments = attachmentsByTestCase.get("");
117 | assertEquals(3, testClassAttachments.size());
118 | Collections.sort(testClassAttachments);
119 | assertEquals(Paths.get("experimentsWithJavaElements", "attachment.txt").toString(), testClassAttachments.get(0));
120 | assertEquals("file", testClassAttachments.get(1));
121 | assertEquals("test.foo.bar.DefaultIntegrationTest-output.txt", testClassAttachments.get(2));
122 | }
123 |
124 | CaseResult caseResult = cr.getCaseResult("experimentsWithJavaElements");
125 | {
126 | TestCaseAttachmentTestAction caseAta = caseResult.getTestAction(TestCaseAttachmentTestAction.class);
127 | assertNotNull(caseAta);
128 | final List caseAttachments = caseAta.getAttachments();
129 | assertNotNull(caseAttachments);
130 | assertEquals(1, caseAttachments.size());
131 | assertEquals("attachment.txt", caseAttachments.get(0));
132 | }
133 | }
134 |
135 | // Creates a job from the given workspace zip file, builds it and retrieves the TestResultAction
136 | private static TestResultAction getTestResultActionForPipeline(JenkinsRule jenkinsRule, String workspaceZip, String pipelineFile, Result expectedStatus) throws Exception {
137 | WorkflowJob project = jenkinsRule.jenkins.createProject(WorkflowJob.class, "test-job");
138 | FilePath workspace = jenkinsRule.jenkins.getWorkspaceFor(project);
139 | FilePath wsZip = workspace.child("workspace.zip");
140 | wsZip.copyFrom(AttachmentPublisherPipelineTest.class.getResource(workspaceZip));
141 | wsZip.unzip(workspace);
142 | for (FilePath f : workspace.list()) {
143 | f.touch(System.currentTimeMillis());
144 | }
145 |
146 | project.setDefinition(new CpsFlowDefinition(fileContentsFromResources(pipelineFile), true));
147 |
148 | WorkflowRun r = jenkinsRule.assertBuildStatus(expectedStatus, project.scheduleBuild2(0).get());
149 |
150 | TestResultAction action = r.getAction(TestResultAction.class);
151 | assertNotNull(action);
152 |
153 | return action;
154 | }
155 |
156 | private static String fileContentsFromResources(String fileName) throws IOException {
157 | String fileContents = null;
158 |
159 | URL url = AttachmentPublisherPipelineTest.class.getResource(fileName);
160 | if (url != null) {
161 | fileContents = IOUtils.toString(url, StandardCharsets.UTF_8);
162 | }
163 |
164 | return fileContents;
165 | }
166 |
167 | }
168 |
--------------------------------------------------------------------------------
/src/test/java/hudson/plugins/junitattachments/AttachmentPublisherTest.java:
--------------------------------------------------------------------------------
1 | package hudson.plugins.junitattachments;
2 |
3 | import static org.junit.jupiter.api.Assertions.assertEquals;
4 | import static org.junit.jupiter.api.Assertions.assertNotNull;
5 | import static org.junit.jupiter.api.Assertions.assertNull;
6 |
7 | import org.htmlunit.html.HtmlAnchor;
8 | import org.htmlunit.html.HtmlPage;
9 | import hudson.FilePath;
10 | import hudson.Launcher;
11 | import hudson.model.AbstractBuild;
12 | import hudson.model.BuildListener;
13 | import hudson.model.Descriptor;
14 | import hudson.model.FreeStyleBuild;
15 | import hudson.model.FreeStyleProject;
16 | import hudson.model.Result;
17 | import hudson.tasks.Builder;
18 | import hudson.tasks.junit.ClassResult;
19 | import hudson.tasks.junit.CaseResult;
20 | import hudson.tasks.junit.JUnitResultArchiver;
21 | import hudson.tasks.junit.PackageResult;
22 | import hudson.tasks.junit.TestDataPublisher;
23 | import hudson.tasks.junit.TestResultAction;
24 | import hudson.tasks.test.TabulatedResult;
25 | import hudson.tasks.test.TestResult;
26 | import hudson.util.DescribableList;
27 | import java.io.IOException;
28 | import java.io.Serializable;
29 | import java.util.ArrayList;
30 | import java.util.Collections;
31 | import java.util.List;
32 |
33 | import org.junit.jupiter.api.Test;
34 | import java.util.Map;
35 |
36 | import org.jvnet.hudson.test.ExtractResourceSCM;
37 | import org.jvnet.hudson.test.JenkinsRule;
38 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
39 |
40 | @WithJenkins
41 | class AttachmentPublisherTest {
42 |
43 | // Package name used in tests in workspace2.zip
44 | private static final String TEST_PACKAGE = "com.example.test";
45 |
46 | @Test
47 | void testWellKnownFilenamesAreAttached(JenkinsRule j) throws Exception {
48 | TestResultAction action = getTestResultActionForBuild(j, "workspace.zip", Result.SUCCESS);
49 |
50 | ClassResult cr = getClassResult(action, "test.foo.bar", "DefaultIntegrationTest");
51 |
52 | TestClassAttachmentTestAction ata = cr.getTestAction(TestClassAttachmentTestAction.class);
53 | assertNotNull(ata);
54 |
55 | final Map> attachmentsByTestCase = ata.getAttachments();
56 | assertNotNull(attachmentsByTestCase);
57 | assertEquals(1, attachmentsByTestCase.size());
58 |
59 | List testCaseAttachments = attachmentsByTestCase.get("");
60 | assertEquals(2, testCaseAttachments.size());
61 | Collections.sort(testCaseAttachments);
62 | assertEquals("file", testCaseAttachments.get(0));
63 | assertEquals("test.foo.bar.DefaultIntegrationTest-output.txt", testCaseAttachments.get(1));
64 | }
65 |
66 | @Test
67 | void testNoAttachmentsShownForPackage(JenkinsRule j) throws Exception {
68 | TestResultAction action = getTestResultActionForBuild(j, "workspace2.zip", Result.UNSTABLE);
69 |
70 | // At the package level, attachments shouldn't be shown
71 | PackageResult pr = action.getResult().byPackage(TEST_PACKAGE);
72 | AttachmentTestAction ata = pr.getTestAction(AttachmentTestAction.class);
73 | assertNull(ata);
74 | }
75 |
76 | //-------------------------------------------------------------------------------------
77 |
78 | // Tests that the correct summary of attachments are shown at the class level
79 | @Test
80 | void testAttachmentsShownForClass_SignupTest(JenkinsRule j) throws Exception {
81 | // There should be 5 attachments: 3 from the test methods, and 2 from the test suite
82 | //
83 | // The two testsuite files should come first, in order of appearance,
84 | // while the remaining files should appear in order of the test method name
85 | String[] expectedFiles = { "signup-suite-1", "signup-suite-2",
86 | "signup-reset", "signup-login", "signup-username" };
87 | runBuildAndAssertAttachmentsExist(j, "SignupTest", expectedFiles);
88 | }
89 |
90 | // Tests that the correct attachments are shown for individual test methods
91 | @Test
92 | void testAttachmentsShownForTestcases_SignupTest(JenkinsRule j) throws Exception {
93 | TestResultAction action = getTestResultActionForBuild(j, "workspace2.zip", Result.UNSTABLE);
94 |
95 | TabulatedResult classResult = getClassResult(action, "SignupTest");
96 | List cases = new ArrayList<>(classResult.getChildren());
97 | assertEquals(3, cases.size());
98 |
99 | // Each test case should have the respective one attachment
100 | String[] names = { "signup-reset", "signup-login", "signup-username" };
101 | for (int i = 0; i < cases.size(); i++) {
102 | assertAttachmentsExist(cases.get(i), new String[] { names[i] });
103 | }
104 | }
105 |
106 | // Tests that the correct attachments are shown for individual test methods with additional output prefix by ant/maven
107 | @Test
108 | void testAttachmentsShownForTestcases_SignupTest_WithRunnerPrefix(JenkinsRule j) throws Exception {
109 | TestResultAction action = getTestResultActionForBuild(j, "workspace3.zip", Result.UNSTABLE);
110 |
111 | TabulatedResult classResult = getClassResult(action, "SignupTest");
112 | List cases = new ArrayList<>(classResult.getChildren());
113 | assertEquals(3, cases.size());
114 |
115 | // Each test case should have the respective one attachment
116 | String[] names = { "signup-reset", "signup-login", "signup-username" };
117 | for (int i = 0; i < cases.size(); i++) {
118 | assertAttachmentsExist(cases.get(i), new String[] { names[i] });
119 | }
120 | }
121 |
122 | //-------------------------------------------------------------------------------------
123 |
124 | @Test
125 | void testAttachmentsShownForClass_LoginTest(JenkinsRule j) throws Exception {
126 | // There should be 2 attachments from the test methods
127 | String[] expectedFiles = { "login-reset", "login-password", "login-reset" };
128 | runBuildAndAssertAttachmentsExist(j, "LoginTest", expectedFiles);
129 | }
130 |
131 | @Test
132 | void testAttachmentsShownForTestcases_LoginTest(JenkinsRule j) throws Exception {
133 | TestResultAction action = getTestResultActionForBuild(j, "workspace2.zip", Result.UNSTABLE);
134 |
135 | TabulatedResult classResult = getClassResult(action, "LoginTest");
136 | List cases = new ArrayList<>(classResult.getChildren());
137 | assertEquals(4, cases.size());
138 |
139 | // Each test case should have the respective one (or zero) attachments
140 | String[] expectedFiles = { "login-reset", null, "login-password", "login-reset" };
141 | for (int i = 0; i < cases.size(); i++) {
142 | String expectedFile = expectedFiles[i];
143 | String[] files = expectedFile == null ? null : new String[] { expectedFile };
144 | assertAttachmentsExist(cases.get(i), files);
145 | }
146 | }
147 |
148 | //-------------------------------------------------------------------------------------
149 |
150 | @Test
151 | void testAttachmentsShownForClass_MiscTest1(JenkinsRule j) throws Exception {
152 | // There should be 2 attachments from the test suite
153 | String[] expectedFiles = { "misc-suite-1", "misc-suite-2" };
154 | runBuildAndAssertAttachmentsExist(j, "MiscTest1", expectedFiles);
155 | }
156 |
157 | // Individual test case should have no attachments, i.e. not overridden by class system-out
158 | @Test
159 | void testAttachmentsShownForTestcases_MiscTest1(JenkinsRule j) throws Exception {
160 | TestResultAction action = getTestResultActionForBuild(j, "workspace2.zip", Result.UNSTABLE);
161 |
162 | TabulatedResult classResult = getClassResult(action, "MiscTest1");
163 | List cases = new ArrayList<>(classResult.getChildren());
164 | assertEquals(1, cases.size());
165 |
166 | // Attachment should not be inherited from testsuite
167 | assertAttachmentsExist(cases.get(0), null);
168 | }
169 |
170 | //-------------------------------------------------------------------------------------
171 |
172 | @Test
173 | void testAttachmentsShownForClass_MiscTest2(JenkinsRule j) throws Exception {
174 | // There should be 6 attachments from the test suite, first stdout, then stderr,
175 | // followed by two from a single test case
176 | String[] expectedFiles = { "misc-suite-3", "misc-suite-4", "misc-suite-1", "misc-suite-2",
177 | "misc-something-1", "misc-something-2" };
178 | runBuildAndAssertAttachmentsExist(j, "MiscTest2", expectedFiles);
179 | }
180 |
181 | @Test
182 | void testAttachmentsShownForTestcases_MiscTest2(JenkinsRule j) throws Exception {
183 | TestResultAction action = getTestResultActionForBuild(j, "workspace2.zip", Result.UNSTABLE);
184 |
185 | TabulatedResult classResult = getClassResult(action, "MiscTest2");
186 | List cases = new ArrayList<>(classResult.getChildren());
187 | assertEquals(2, cases.size());
188 |
189 | // Alphabetically first comes the "doNothing" test
190 | assertAttachmentsExist(cases.get(0), null);
191 | // Followed by the "doSomething" test
192 | assertAttachmentsExist(cases.get(1), new String[] { "misc-something-1", "misc-something-2" });
193 | }
194 |
195 | @Test
196 | void testAttachmentsWithStrangeFileNames(JenkinsRule j) throws Exception {
197 | FreeStyleBuild build = getBuild(j, "workspace5.zip");
198 |
199 | HtmlPage page = j.createWebClient().withJavaScriptEnabled(false)
200 | .getPage(build, "testReport/com.example.test/SignupTest/");
201 | HtmlAnchor anchor1 = page.getAnchorByText("unicödeAndかわいいStuff");
202 | assertNotNull(anchor1.click());
203 | HtmlAnchor anchor2 = page.getAnchorByText("with space");
204 | assertNotNull(anchor2.click());
205 | HtmlAnchor anchor3 = page.getAnchorByText("special%§$_-%&[;]{}()char");
206 | assertNotNull(anchor3.click());
207 | }
208 |
209 | //-------------------------------------------------------------------------------------
210 |
211 | private static void runBuildAndAssertAttachmentsExist(JenkinsRule j, String className, String[] expectedFiles) throws Exception {
212 | TestResultAction action = getTestResultActionForBuild(j, "workspace2.zip", Result.UNSTABLE);
213 |
214 | ClassResult cr = getClassResult(action, className);
215 | assertAttachmentsExist(cr, expectedFiles);
216 | }
217 |
218 | // Asserts that, for the given TestResult, the given attachments exist
219 | private static void assertAttachmentsExist(TestResult result, String[] expectedFiles) {
220 | AttachmentTestAction ata = null;
221 | if (result instanceof ClassResult) {
222 | ata = result.getTestAction(AttachmentTestAction.class);
223 | }
224 | else if (result instanceof CaseResult) {
225 | ata = result.getTestAction(AttachmentTestAction.class);
226 | }
227 |
228 | if (expectedFiles == null) {
229 | assertNull(ata);
230 | return;
231 | }
232 | assertNotNull(ata);
233 |
234 | // Assert that attachments exist for this TestResult
235 | List attachments;
236 | if (result instanceof ClassResult) {
237 | Map> attachmentsByTestCase = ((TestClassAttachmentTestAction)ata).getAttachments();
238 | attachments = new ArrayList<>();
239 | for (List list : attachmentsByTestCase.values()) {
240 | attachments.addAll(list);
241 | }
242 | }
243 | else {
244 | attachments = ((TestCaseAttachmentTestAction)ata).getAttachments();
245 | }
246 |
247 | assertNotNull(attachments);
248 | assertEquals(expectedFiles.length, attachments.size());
249 |
250 | // Assert that the expected files are there in the given order
251 | for (int i = 0; i < expectedFiles.length; i++) {
252 | assertEquals(expectedFiles[i], attachments.get(i));
253 | }
254 | }
255 |
256 | static ClassResult getClassResult(TestResultAction action, String className) {
257 | return getClassResult(action, TEST_PACKAGE, className);
258 | }
259 |
260 | static ClassResult getClassResult(TestResultAction action, String packageName, String className) {
261 | return action.getResult().byPackage(packageName).getClassResult(className);
262 | }
263 |
264 | private static FreeStyleBuild getBuild(JenkinsRule j, String workspaceZip) throws Exception {
265 | FreeStyleProject project = j.createFreeStyleProject();
266 |
267 | DescribableList> publishers =
268 | new DescribableList<>(project);
269 | publishers.add(new AttachmentPublisher());
270 |
271 | project.setScm(new ExtractResourceSCM(AttachmentPublisherTest.class.getResource(workspaceZip)));
272 | project.getBuildersList().add(new TouchBuilder());
273 | JUnitResultArchiver archiver = new JUnitResultArchiver("*.xml");
274 | archiver.setTestDataPublishers(publishers);
275 | project.getPublishersList().add(archiver);
276 |
277 | return project.scheduleBuild2(0).get();
278 | }
279 |
280 | // Creates a job from the given workspace zip file, builds it and retrieves the TestResultAction
281 | private static TestResultAction getTestResultActionForBuild(JenkinsRule j, String workspaceZip, Result expectedStatus) throws Exception {
282 | FreeStyleBuild b = getBuild(j, workspaceZip);
283 | j.assertBuildStatus(expectedStatus, b);
284 |
285 | TestResultAction action = b.getAction(TestResultAction.class);
286 | assertNotNull(action);
287 |
288 | return action;
289 | }
290 |
291 | public static final class TouchBuilder extends Builder implements Serializable {
292 | @Override
293 | public boolean perform(AbstractBuild, ?> build, Launcher launcher,
294 | BuildListener listener) throws InterruptedException,
295 | IOException {
296 | for (FilePath f : build.getWorkspace().list()) {
297 | f.touch(System.currentTimeMillis());
298 | }
299 | return true;
300 | }
301 | }
302 |
303 | }
304 |
--------------------------------------------------------------------------------
/src/test/resources/hudson/plugins/junitattachments/pipelineTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2016, CloudBees, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | *
24 | */
25 | node {
26 | junit testResults: '*.xml', testDataPublishers: [attachments()]
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/src/test/resources/hudson/plugins/junitattachments/workspace.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/junit-attachments-plugin/2d3169b5d0d1b4be3b272de42c4dd4dcf71e113f/src/test/resources/hudson/plugins/junitattachments/workspace.zip
--------------------------------------------------------------------------------
/src/test/resources/hudson/plugins/junitattachments/workspace2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/junit-attachments-plugin/2d3169b5d0d1b4be3b272de42c4dd4dcf71e113f/src/test/resources/hudson/plugins/junitattachments/workspace2.zip
--------------------------------------------------------------------------------
/src/test/resources/hudson/plugins/junitattachments/workspace3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/junit-attachments-plugin/2d3169b5d0d1b4be3b272de42c4dd4dcf71e113f/src/test/resources/hudson/plugins/junitattachments/workspace3.zip
--------------------------------------------------------------------------------
/src/test/resources/hudson/plugins/junitattachments/workspace4.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/junit-attachments-plugin/2d3169b5d0d1b4be3b272de42c4dd4dcf71e113f/src/test/resources/hudson/plugins/junitattachments/workspace4.zip
--------------------------------------------------------------------------------
/src/test/resources/hudson/plugins/junitattachments/workspace5.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/junit-attachments-plugin/2d3169b5d0d1b4be3b272de42c4dd4dcf71e113f/src/test/resources/hudson/plugins/junitattachments/workspace5.zip
--------------------------------------------------------------------------------