blob: bcb4055832038c0425541e2a59ab223fe215c665 [file] [log] [blame]
Alan Batemandb4d3832016-03-17 19:04:16 +00001/**
Igor Ignatyevc85d2732017-05-30 15:05:33 -07002 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
Alan Batemandb4d3832016-03-17 19:04:16 +00003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
Igor Ignatyevc85d2732017-05-30 15:05:33 -070026 * @library /lib/testlibrary /test/lib
Mandy Chung44a7c1b2016-10-12 15:41:00 -070027 * @modules jdk.compiler
28 * jdk.jlink
Igor Ignatyevc85d2732017-05-30 15:05:33 -070029 * @build CompilerUtils
Alan Batemandb4d3832016-03-17 19:04:16 +000030 * @run testng JmodNegativeTest
31 * @summary Negative tests for jmod
32 */
33
34import java.io.*;
35import java.nio.file.Files;
36import java.nio.file.Path;
37import java.nio.file.Paths;
38import java.util.Arrays;
39import java.util.List;
40import java.util.function.Consumer;
41import java.util.function.Supplier;
Mandy Chung44a7c1b2016-10-12 15:41:00 -070042import java.util.spi.ToolProvider;
Alan Batemandb4d3832016-03-17 19:04:16 +000043import java.util.zip.ZipOutputStream;
Igor Ignatyevc85d2732017-05-30 15:05:33 -070044import jdk.test.lib.util.FileUtils;
Alan Batemandb4d3832016-03-17 19:04:16 +000045import org.testng.annotations.BeforeTest;
46import org.testng.annotations.DataProvider;
47import org.testng.annotations.Test;
48
49import static java.io.File.pathSeparator;
50import static java.nio.charset.StandardCharsets.UTF_8;
51import static org.testng.Assert.assertTrue;
52
53public class JmodNegativeTest {
54
Mandy Chung44a7c1b2016-10-12 15:41:00 -070055 static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
56 .orElseThrow(() ->
57 new RuntimeException("jmod tool not found")
58 );
59
Alan Batemandb4d3832016-03-17 19:04:16 +000060 static final String TEST_SRC = System.getProperty("test.src", ".");
61 static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
62 static final Path EXPLODED_DIR = Paths.get("build");
63 static final Path MODS_DIR = Paths.get("jmods");
64
65 @BeforeTest
66 public void buildExplodedModules() throws IOException {
67 if (Files.exists(EXPLODED_DIR))
68 FileUtils.deleteFileTreeWithRetry(EXPLODED_DIR);
69
70 for (String name : new String[] { "foo"/*, "bar", "baz"*/ } ) {
71 Path dir = EXPLODED_DIR.resolve(name);
72 assertTrue(compileModule(name, dir.resolve("classes")));
73 }
74
75 if (Files.exists(MODS_DIR))
76 FileUtils.deleteFileTreeWithRetry(MODS_DIR);
77 Files.createDirectories(MODS_DIR);
78 }
79
80 @Test
81 public void testNoArgs() {
82 jmod()
83 .assertFailure()
84 .resultChecker(r ->
Chris Hegarty6d2dd6f2016-12-10 14:19:53 +000085 assertContains(r.output, "Error: one of create, extract, list, describe, or hash must be specified")
Alan Batemandb4d3832016-03-17 19:04:16 +000086 );
87 }
88
89 @Test
90 public void testBadAction() {
91 jmod("badAction")
92 .assertFailure()
93 .resultChecker(r ->
Chris Hegarty6d2dd6f2016-12-10 14:19:53 +000094 assertContains(r.output, "Error: mode must be one of create, extract, list, describe, or hash")
Alan Batemandb4d3832016-03-17 19:04:16 +000095 );
96
97 jmod("--badOption")
98 .assertFailure()
99 .resultChecker(r ->
100 assertContains(r.output, "Error: 'badOption' is not a recognized option")
101 );
102 }
103
104 @Test
105 public void testTooManyArgs() throws IOException {
106 Path jmod = MODS_DIR.resolve("doesNotExist.jmod");
107 FileUtils.deleteFileIfExistsWithRetry(jmod);
108
109 jmod("create",
110 jmod.toString(),
111 "AAA")
112 .assertFailure()
113 .resultChecker(r ->
114 assertContains(r.output, "Error: unknown option(s): [AAA]")
115 );
116 }
117
118 @Test
119 public void testCreateNoArgs() {
120 jmod("create")
121 .assertFailure()
122 .resultChecker(r ->
123 assertContains(r.output, "Error: jmod-file must be specified")
124 );
125 }
126
127 @Test
128 public void testListNoArgs() {
129 jmod("list")
130 .assertFailure()
131 .resultChecker(r ->
132 assertContains(r.output, "Error: jmod-file must be specified")
133 );
134 }
135
136 @Test
137 public void testListFileDoesNotExist() throws IOException {
138 Path jmod = MODS_DIR.resolve("doesNotExist.jmod");
139 FileUtils.deleteFileIfExistsWithRetry(jmod);
140
141 jmod("list",
142 jmod.toString())
143 .assertFailure()
144 .resultChecker(r ->
145 assertContains(r.output, "Error: no jmod file found: "
146 + jmod.toString())
147 );
148 }
149
150 @Test
151 public void testListJmodIsDir() throws IOException {
152 Path jmod = MODS_DIR.resolve("testListJmodIsDir.jmod");
153 if (Files.notExists(jmod))
154 Files.createDirectory(jmod);
155
156 jmod("list",
157 jmod.toString())
158 .assertFailure()
159 .resultChecker(r ->
160 assertContains(r.output, "Error: error opening jmod file")
161 );
162 }
163
164 @Test
165 public void testlistJmodMalformed() throws IOException {
166 Path jmod = MODS_DIR.resolve("testlistJmodMalformed.jmod");
167 if (Files.notExists(jmod))
168 Files.createFile(jmod);
169
170 jmod("list",
171 jmod.toString())
172 .assertFailure()
173 .resultChecker(r ->
174 assertContains(r.output, "Error: error opening jmod file")
175 );
176 }
177
178 @Test
Alan Bateman36e08202016-05-03 09:09:57 +0100179 public void testHashModulesModulePathNotSpecified() {
Alan Batemandb4d3832016-03-17 19:04:16 +0000180 jmod("create",
Alan Bateman36e08202016-05-03 09:09:57 +0100181 "--hash-modules", "anyPattern.*",
Alan Batemandb4d3832016-03-17 19:04:16 +0000182 "output.jmod")
183 .assertFailure()
184 .resultChecker(r ->
185 assertContains(r.output, "Error: --module-path must be "
Alan Bateman36e08202016-05-03 09:09:57 +0100186 +"specified when hashing modules")
Alan Batemandb4d3832016-03-17 19:04:16 +0000187 );
188 }
189
190 @Test
191 public void testCreateJmodAlreadyExists() throws IOException {
192 Path jmod = MODS_DIR.resolve("testCreateJmodAlreadyExists.jmod");
193 if (Files.notExists(jmod))
194 Files.createFile(jmod);
195
196 jmod("create",
197 "--class-path", Paths.get(".").toString(), // anything that exists
198 jmod.toString())
199 .assertFailure()
200 .resultChecker(r ->
201 assertContains(r.output, "Error: file already exists: " + jmod.toString())
202 );
203 }
204
205 @Test
206 public void testCreateJmodIsDir() throws IOException {
207 Path jmod = MODS_DIR.resolve("testCreateJmodAlreadyExists");
208 if (Files.notExists(jmod))
209 Files.createDirectory(jmod);
210
211 jmod("create",
212 "--class-path", Paths.get(".").toString(), // anything that exists
213 jmod.toString())
214 .assertFailure()
215 .resultChecker(r ->
216 assertContains(r.output, "Error: file already exists: " + jmod.toString())
217 );
218 }
219
220 @Test
221 public void testInvalidModuleVersion() throws IOException {
222 Path jmod = MODS_DIR.resolve("testEmptyModuleVersion.jmod");
223 FileUtils.deleteFileIfExistsWithRetry(jmod);
224 String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
225
226 for (String version : new String[] { "", "NOT_A_VALID_VERSION" }) {
227 jmod("create",
228 "--class-path", cp,
229 "--module-version", version,
230 jmod.toString())
231 .assertFailure()
232 .resultChecker(r ->
233 assertContains(r.output, "Error: invalid module version")
234 );
235 }
236 }
237
Alan Batemandb4d3832016-03-17 19:04:16 +0000238 @Test
239 public void testEmptyFileInClasspath() throws IOException {
240 Path jmod = MODS_DIR.resolve("testEmptyFileInClasspath.jmod");
241 FileUtils.deleteFileIfExistsWithRetry(jmod);
242 Path jar = MODS_DIR.resolve("NotARealJar_Empty.jar");
243 FileUtils.deleteFileIfExistsWithRetry(jar);
244 Files.createFile(jar);
245
246 jmod("create",
247 "--class-path", jar.toString(),
248 jmod.toString())
249 .assertFailure()
250 .resultChecker(r ->
251 assertContains(r.output, "Error: module-info.class not found")
252 );
253 }
254
255 @Test
256 public void testEmptyJarInClasspath() throws IOException {
257 Path jmod = MODS_DIR.resolve("testEmptyJarInClasspath.jmod");
258 FileUtils.deleteFileIfExistsWithRetry(jmod);
259 Path jar = MODS_DIR.resolve("empty.jar");
260 FileUtils.deleteFileIfExistsWithRetry(jar);
261 try (FileOutputStream fos = new FileOutputStream(jar.toFile());
262 ZipOutputStream zos = new ZipOutputStream(fos)) {
263 // empty
264 }
265
266 jmod("create",
267 "--class-path", jar.toString(),
268 jmod.toString())
269 .assertFailure()
270 .resultChecker(r ->
271 assertContains(r.output, "Error: module-info.class not found")
272 );
273 }
274
275 @Test
276 public void testModuleInfoNotFound() throws IOException {
277 Path jmod = MODS_DIR.resolve("output.jmod");
278 FileUtils.deleteFileIfExistsWithRetry(jmod);
279 Path jar = MODS_DIR.resolve("empty");
280 FileUtils.deleteFileIfExistsWithRetry(jar);
281 Files.createDirectory(jar);
282
283 jmod("create",
284 "--class-path", jar.toString(),
285 jmod.toString())
286 .assertFailure()
287 .resultChecker(r ->
288 assertContains(r.output, "Error: module-info.class not found")
289 );
290 }
291
292 @Test
293 public void testModuleInfoIsDir() throws IOException {
294 Path jmod = MODS_DIR.resolve("output.jmod");
295 FileUtils.deleteFileIfExistsWithRetry(jmod);
296 Path cp = MODS_DIR.resolve("module-info.class");
297 FileUtils.deleteFileIfExistsWithRetry(cp);
298 Files.createDirectory(cp);
299 Files.createFile(cp.resolve("nada.txt"));
300
301 jmod("create",
302 "--class-path", cp.toString(),
303 jmod.toString())
304 .assertFailure()
305 .resultChecker(r ->
306 assertContains(r.output, "Error: module-info.class not found")
307 );
308 }
309
310 @Test
Alan Bateman36e08202016-05-03 09:09:57 +0100311 public void testNoModuleHash() throws IOException {
Alan Batemandb4d3832016-03-17 19:04:16 +0000312 Path jmod = MODS_DIR.resolve("output.jmod");
313 FileUtils.deleteFileIfExistsWithRetry(jmod);
314 Path emptyDir = Paths.get("empty");
315 if (Files.exists(emptyDir))
316 FileUtils.deleteFileTreeWithRetry(emptyDir);
317 Files.createDirectory(emptyDir);
318 String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
319
320 jmod("create",
321 "--class-path", cp,
Alan Bateman36e08202016-05-03 09:09:57 +0100322 "--hash-modules", ".*",
Mandy Chunge2a0ff32016-08-10 15:51:25 -0700323 "--module-path", emptyDir.toString(),
Alan Batemandb4d3832016-03-17 19:04:16 +0000324 jmod.toString())
Alan Batemandb4d3832016-03-17 19:04:16 +0000325 .resultChecker(r ->
Alan Bateman36e08202016-05-03 09:09:57 +0100326 assertContains(r.output, "No hashes recorded: " +
327 "no module specified for hashing depends on foo")
Alan Batemandb4d3832016-03-17 19:04:16 +0000328 );
329 }
330
331 @Test
332 public void testEmptyFileInModulePath() throws IOException {
333 Path jmod = MODS_DIR.resolve("output.jmod");
334 FileUtils.deleteFileIfExistsWithRetry(jmod);
335 Path empty = MODS_DIR.resolve("emptyFile.jmod");
336 FileUtils.deleteFileIfExistsWithRetry(empty);
337 Files.createFile(empty);
338 try {
339 String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
340
341 jmod("create",
342 "--class-path", cp,
Alan Bateman36e08202016-05-03 09:09:57 +0100343 "--hash-modules", ".*",
Mandy Chunge2a0ff32016-08-10 15:51:25 -0700344 "--module-path", MODS_DIR.toString(),
Alan Batemandb4d3832016-03-17 19:04:16 +0000345 jmod.toString())
Alan Bateman36e08202016-05-03 09:09:57 +0100346 .assertFailure();
Alan Batemandb4d3832016-03-17 19:04:16 +0000347 } finally {
348 FileUtils.deleteFileWithRetry(empty);
349 }
350 }
351
352 @Test
353 public void testFileInModulePath() throws IOException {
354 Path jmod = MODS_DIR.resolve("output.jmod");
355 FileUtils.deleteFileIfExistsWithRetry(jmod);
356 Path file = MODS_DIR.resolve("testFileInModulePath.txt");
357 FileUtils.deleteFileIfExistsWithRetry(file);
358 Files.createFile(file);
359
360 jmod("create",
Alan Bateman36e08202016-05-03 09:09:57 +0100361 "--hash-modules", ".*",
Mandy Chunge2a0ff32016-08-10 15:51:25 -0700362 "--module-path", file.toString(),
Alan Batemandb4d3832016-03-17 19:04:16 +0000363 jmod.toString())
364 .assertFailure()
365 .resultChecker(r ->
366 assertContains(r.output, "Error: path must be a directory")
367 );
368 }
369
370 @DataProvider(name = "pathDoesNotExist")
371 public Object[][] pathDoesNotExist() throws IOException {
372 Path jmod = MODS_DIR.resolve("output.jmod");
373 FileUtils.deleteFileIfExistsWithRetry(jmod);
374 FileUtils.deleteFileIfExistsWithRetry(Paths.get("doesNotExist"));
375
376 List<Supplier<JmodResult>> tasks = Arrays.asList(
377 () -> jmod("create",
Alan Bateman36e08202016-05-03 09:09:57 +0100378 "--hash-modules", "anyPattern",
Mandy Chunge2a0ff32016-08-10 15:51:25 -0700379 "--module-path", "doesNotExist",
Alan Batemandb4d3832016-03-17 19:04:16 +0000380 "output.jmod"),
381 () -> jmod("create",
382 "--class-path", "doesNotExist",
383 "output.jmod"),
384 () -> jmod("create",
385 "--class-path", "doesNotExist.jar",
386 "output.jmod"),
387 () -> jmod("create",
388 "--cmds", "doesNotExist",
389 "output.jmod"),
390 () -> jmod("create",
391 "--config", "doesNotExist",
392 "output.jmod"),
393 () -> jmod("create",
394 "--libs", "doesNotExist",
395 "output.jmod") );
396
397 String errMsg = "Error: path not found: doesNotExist";
398 return tasks.stream().map(t -> new Object[] {t, errMsg} )
399 .toArray(Object[][]::new);
400 }
401
402 @Test(dataProvider = "pathDoesNotExist")
403 public void testPathDoesNotExist(Supplier<JmodResult> supplier,
404 String errMsg)
405 {
406 supplier.get()
407 .assertFailure()
408 .resultChecker(r -> {
409 assertContains(r.output, errMsg);
410 });
411 }
412
413 @DataProvider(name = "partOfPathDoesNotExist")
414 public Object[][] partOfPathDoesNotExist() throws IOException {
415 Path jmod = MODS_DIR.resolve("output.jmod");
416 FileUtils.deleteFileIfExistsWithRetry(jmod);
417 FileUtils.deleteFileIfExistsWithRetry(Paths.get("doesNotExist"));
418
419 Path emptyDir = Paths.get("empty");
420 if (Files.exists(emptyDir))
421 FileUtils.deleteFileTreeWithRetry(emptyDir);
422 Files.createDirectory(emptyDir);
423
424 List<Supplier<JmodResult>> tasks = Arrays.asList(
425 () -> jmod("create",
Alan Bateman36e08202016-05-03 09:09:57 +0100426 "--hash-modules", "anyPattern",
Mandy Chunge2a0ff32016-08-10 15:51:25 -0700427 "--module-path","empty" + pathSeparator + "doesNotExist",
Alan Batemandb4d3832016-03-17 19:04:16 +0000428 "output.jmod"),
429 () -> jmod("create",
430 "--class-path", "empty" + pathSeparator + "doesNotExist",
431 "output.jmod"),
432 () -> jmod("create",
433 "--class-path", "empty" + pathSeparator + "doesNotExist.jar",
434 "output.jmod"),
435 () -> jmod("create",
436 "--cmds", "empty" + pathSeparator + "doesNotExist",
437 "output.jmod"),
438 () -> jmod("create",
439 "--config", "empty" + pathSeparator + "doesNotExist",
440 "output.jmod"),
441 () -> jmod("create",
442 "--libs", "empty" + pathSeparator + "doesNotExist",
443 "output.jmod") );
444
445 String errMsg = "Error: path not found: doesNotExist";
446 return tasks.stream().map(t -> new Object[] {t, errMsg} )
447 .toArray(Object[][]::new);
448 }
449
450 @Test(dataProvider = "partOfPathDoesNotExist")
451 public void testPartOfPathNotExist(Supplier<JmodResult> supplier,
452 String errMsg)
453 {
454 supplier.get()
455 .assertFailure()
456 .resultChecker(r -> {
457 assertContains(r.output, errMsg);
458 });
459 }
460
461 @DataProvider(name = "pathIsFile")
462 public Object[][] pathIsFile() throws IOException {
463 Path jmod = MODS_DIR.resolve("output.jmod");
464 FileUtils.deleteFileIfExistsWithRetry(jmod);
465 Path aFile = Paths.get("aFile.txt");
466 if (Files.exists(aFile) && !Files.isRegularFile(aFile))
467 throw new InternalError("Unexpected file:" + aFile);
468 else
469 Files.createFile(aFile);
470
471 List<Supplier<JmodResult>> tasks = Arrays.asList(
472 () -> jmod("create",
473 "--class-path", "aFile.txt",
474 "output.jmod"),
475 () -> jmod("create",
Mandy Chunge2a0ff32016-08-10 15:51:25 -0700476 "--module-path", "aFile.txt",
Alan Batemandb4d3832016-03-17 19:04:16 +0000477 "output.jmod"),
478 () -> jmod("create",
479 "--cmds", "aFile.txt",
480 "output.jmod"),
481 () -> jmod("create",
482 "--config", "aFile.txt",
483 "output.jmod"),
484 () -> jmod("create",
485 "--libs", "aFile.txt",
486 "output.jmod") );
487
488 String errMsg = "Error: path must be a directory: aFile.txt";
489 Object[][] a = tasks.stream().map(t -> new Object[] {t, errMsg} )
490 .toArray(Object[][]::new);
491 a[0][1] = "invalid class path entry: aFile.txt"; // class path err msg
492 return a;
493 }
494
495 @Test(dataProvider = "pathIsFile")
496 public void testPathIsFile(Supplier<JmodResult> supplier,
497 String errMsg)
498 {
499 supplier.get()
500 .assertFailure()
501 .resultChecker(r -> {
502 assertContains(r.output, errMsg);
503 });
504 }
505
506 // ---
507
508 static boolean compileModule(String name, Path dest) throws IOException {
509 return CompilerUtils.compile(SRC_DIR.resolve(name), dest);
510 }
511
512 static void assertContains(String output, String subString) {
513 if (output.contains(subString))
514 assertTrue(true);
515 else
516 assertTrue(false,"Expected to find [" + subString + "], in output ["
517 + output + "]");
518 }
519
520 static JmodResult jmod(String... args) {
521 ByteArrayOutputStream baos = new ByteArrayOutputStream();
522 PrintStream ps = new PrintStream(baos);
523 System.out.println("jmod " + Arrays.asList(args));
Mandy Chung44a7c1b2016-10-12 15:41:00 -0700524 int ec = JMOD_TOOL.run(ps, ps, args);
Alan Batemandb4d3832016-03-17 19:04:16 +0000525 return new JmodResult(ec, new String(baos.toByteArray(), UTF_8));
526 }
527
528 static class JmodResult {
529 final int exitCode;
530 final String output;
531
532 JmodResult(int exitValue, String output) {
533 this.exitCode = exitValue;
534 this.output = output;
535 }
536 JmodResult assertFailure() { assertTrue(exitCode != 0, output); return this; }
537 JmodResult resultChecker(Consumer<JmodResult> r) { r.accept(this); return this; }
538 }
539}