ModuleSourcePathTest.java revision 4118:8b68fb0d8159
1157196Sdeischen/*
2157196Sdeischen * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
3157196Sdeischen * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4157196Sdeischen *
5157196Sdeischen * This code is free software; you can redistribute it and/or modify it
6157196Sdeischen * under the terms of the GNU General Public License version 2 only, as
7157196Sdeischen * published by the Free Software Foundation.
8157196Sdeischen *
9157196Sdeischen * This code is distributed in the hope that it will be useful, but WITHOUT
10157196Sdeischen * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11157196Sdeischen * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12157196Sdeischen * version 2 for more details (a copy is included in the LICENSE file that
13157196Sdeischen * accompanied this code).
14157196Sdeischen *
15157196Sdeischen * You should have received a copy of the GNU General Public License version
16157196Sdeischen * 2 along with this work; if not, write to the Free Software Foundation,
17157196Sdeischen * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18157196Sdeischen *
19157196Sdeischen * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20157196Sdeischen * or visit www.oracle.com if you need additional information or have any
21157196Sdeischen * questions.
22157196Sdeischen */
23157196Sdeischen
24157196Sdeischen/*
25157196Sdeischen * @test
26157196Sdeischen * @summary tests for --module-source-path
27157196Sdeischen * @library /tools/lib
28157196Sdeischen * @modules
29157196Sdeischen *      jdk.compiler/com.sun.tools.javac.api
30157196Sdeischen *      jdk.compiler/com.sun.tools.javac.main
31157196Sdeischen * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
32157196Sdeischen * @run main ModuleSourcePathTest
33157196Sdeischen */
34157196Sdeischen
35157196Sdeischenimport java.io.File;
36157196Sdeischenimport java.io.IOException;
37157196Sdeischenimport java.nio.file.Files;
38157196Sdeischenimport java.nio.file.Path;
39157196Sdeischenimport java.nio.file.Paths;
40157196Sdeischenimport java.util.ArrayList;
41157196Sdeischenimport java.util.Arrays;
42157196Sdeischenimport java.util.List;
43157196Sdeischenimport java.util.stream.Collectors;
44157196Sdeischenimport java.util.stream.Stream;
45157196Sdeischen
46157196Sdeischenimport javax.tools.JavaCompiler;
47157196Sdeischenimport javax.tools.JavaFileManager.Location;
48157196Sdeischenimport javax.tools.StandardJavaFileManager;
49157196Sdeischenimport javax.tools.StandardLocation;
50157196Sdeischenimport javax.tools.ToolProvider;
51157196Sdeischen
52157196Sdeischenimport toolbox.JavacTask;
53157196Sdeischenimport toolbox.Task;
54157196Sdeischenimport toolbox.ToolBox;
55157196Sdeischen
56157196Sdeischenpublic class ModuleSourcePathTest extends ModuleTestBase {
57157196Sdeischen
58157196Sdeischen    public static final char PATH_SEP = File.pathSeparatorChar;
59157196Sdeischen
60157196Sdeischen    public static void main(String... args) throws Exception {
61157196Sdeischen        ModuleSourcePathTest t = new ModuleSourcePathTest();
62157196Sdeischen        t.runTests();
63157196Sdeischen    }
64157196Sdeischen
65157196Sdeischen    @Test
66157196Sdeischen    public void testSourcePathConflict(Path base) throws Exception {
67157196Sdeischen        Path sp = base.resolve("src");
68157196Sdeischen        Path msp = base.resolve("srcmodules");
69157196Sdeischen
70157196Sdeischen        String log = new JavacTask(tb, Task.Mode.CMDLINE)
71157196Sdeischen                .options("-XDrawDiagnostics",
72157196Sdeischen                        "--source-path", sp.toString().replace('/', File.separatorChar),
73157196Sdeischen                        "--module-source-path", msp.toString().replace('/', File.separatorChar),
74157196Sdeischen                        "dummyClass")
75157196Sdeischen                .run(Task.Expect.FAIL)
76157196Sdeischen                .writeAll()
77157196Sdeischen                .getOutput(Task.OutputKind.DIRECT);
78157196Sdeischen
79157196Sdeischen        if (!log.contains("cannot specify both --source-path and --module-source-path"))
80157196Sdeischen            throw new Exception("expected diagnostic not found");
81157196Sdeischen    }
82157196Sdeischen
83157196Sdeischen    @Test
84157196Sdeischen    public void testUnnormalizedPath1(Path base) throws Exception {
85157196Sdeischen        Path src = base.resolve("src");
86157196Sdeischen        Path src_m1 = src.resolve("m1x");
87157196Sdeischen        tb.writeJavaFiles(src_m1, "module m1x { }");
88157196Sdeischen        Path modules = base.resolve("modules");
89157196Sdeischen        Files.createDirectories(modules);
90157196Sdeischen
91157196Sdeischen        new JavacTask(tb, Task.Mode.CMDLINE)
92157196Sdeischen                .options("-XDrawDiagnostics",
93157196Sdeischen                        "--module-source-path", src.toString())
94157196Sdeischen                .outdir(modules)
95157196Sdeischen                .files(prefixAll(findJavaFiles(src), Paths.get("./")))
96157196Sdeischen                .run()
97157196Sdeischen                .writeAll();
98157196Sdeischen    }
99157196Sdeischen
100157196Sdeischen    @Test
101157196Sdeischen    public void testUnnormalizedPath2(Path base) throws Exception {
102157196Sdeischen        Path src = base.resolve("src");
103157196Sdeischen        Path src_m1 = src.resolve("m1x");
104157196Sdeischen        tb.writeJavaFiles(src_m1, "module m1x { }");
105157196Sdeischen        Path modules = base.resolve("modules");
106157196Sdeischen        Files.createDirectories(modules);
107157196Sdeischen
108157196Sdeischen        new JavacTask(tb, Task.Mode.CMDLINE)
109157196Sdeischen                .options("-XDrawDiagnostics",
110157196Sdeischen                        "--module-source-path", "./" + src)
111157196Sdeischen                .outdir(modules)
112157196Sdeischen                .files(findJavaFiles(src))
113157196Sdeischen                .run()
114157196Sdeischen                .writeAll();
115157196Sdeischen    }
116157196Sdeischen
117157196Sdeischen    private Path[] prefixAll(Path[] paths, Path prefix) {
118157196Sdeischen        return Stream.of(paths)
119157196Sdeischen                .map(prefix::resolve)
120157196Sdeischen                .collect(Collectors.toList())
121157196Sdeischen                .toArray(new Path[paths.length]);
122157196Sdeischen    }
123157196Sdeischen
124157196Sdeischen    @Test
125157196Sdeischen    public void regularBraces(Path base) throws Exception {
126157196Sdeischen        generateModules(base, "src1", "src2/inner_dir");
127157196Sdeischen
128157196Sdeischen        final Path modules = base.resolve("modules");
129157196Sdeischen        tb.createDirectories(modules);
130157196Sdeischen
131157196Sdeischen        new JavacTask(tb, Task.Mode.CMDLINE)
132157196Sdeischen                .options("-XDrawDiagnostics",
133157196Sdeischen                        "--module-source-path", base + "/{src1,src2/inner_dir}")
134157196Sdeischen                .files(base.resolve("src1/m0x/pkg0/A.java"), base.resolve("src2/inner_dir/m1x/pkg1/A.java"))
135157196Sdeischen                .outdir(modules)
136157196Sdeischen                .run()
137165855Sdas                .writeAll();
138157196Sdeischen
139157196Sdeischen        checkFiles(modules.resolve("m0x/pkg0/A.class"),
140157196Sdeischen                modules.resolve("m1x/pkg1/A.class"),
141157196Sdeischen                modules.resolve("m0x/module-info.class"),
142157196Sdeischen                modules.resolve("m1x/module-info.class"));
143157196Sdeischen    }
144157196Sdeischen
145157196Sdeischen    @Test
146157196Sdeischen    public void mismatchedBraces(Path base) throws Exception {
147157196Sdeischen        final List<String> sourcePaths = Arrays.asList(
148157196Sdeischen                "{",
149157196Sdeischen                "}",
150157196Sdeischen                "}{",
151157196Sdeischen                "./}",
152157196Sdeischen                ".././{./",
153157196Sdeischen                "src{}}",
154157196Sdeischen                "{{}{}}{}}",
155157196Sdeischen                "src/{a,b}/{",
156157196Sdeischen                "src/{a,{,{}}",
157157196Sdeischen                "{.,..{}/src",
158157196Sdeischen                "*}{",
159157196Sdeischen                "{}*}"
160157196Sdeischen        );
161157196Sdeischen        for (String sourcepath : sourcePaths) {
162157196Sdeischen            String log = new JavacTask(tb, Task.Mode.CMDLINE)
163157196Sdeischen                    .options("-XDrawDiagnostics",
164157196Sdeischen                            "--module-source-path", sourcepath.replace('/', File.separatorChar))
165157196Sdeischen                    .run(Task.Expect.FAIL)
166157196Sdeischen                    .writeAll()
167157196Sdeischen                    .getOutput(Task.OutputKind.DIRECT);
168157196Sdeischen
169157196Sdeischen            if (!log.contains("- compiler.err.illegal.argument.for.option: --module-source-path, mismatched braces"))
170157196Sdeischen                throw new Exception("expected output for path [" + sourcepath + "] not found");
171157196Sdeischen        }
172157196Sdeischen    }
173157196Sdeischen
174157196Sdeischen    @Test
175157196Sdeischen    public void deepBraces(Path base) throws Exception {
176157196Sdeischen        String[] modulePaths = {"src/src1",
177157196Sdeischen                "src/src2",
178157196Sdeischen                "src/src3",
179157196Sdeischen                "src/srcB/src1",
180157196Sdeischen                "src/srcB/src2/srcXX",
181157196Sdeischen                "src/srcB/src2/srcXY",
182                "src/srcC/src1",
183                "src/srcC/src2/srcXX",
184                "src/srcC/src2/srcXY"};
185        generateModules(base, modulePaths);
186
187        final Path modules = base.resolve("modules");
188        tb.createDirectories(modules);
189
190        new JavacTask(tb, Task.Mode.CMDLINE)
191                .options("-XDrawDiagnostics",
192                        "--module-source-path",
193                        base + "/{src/{{src1,src2,src3},{srcB,srcC}/{src1,src2/srcX{X,Y}/}},.}"
194                                .replace('/', File.separatorChar))
195                .files(findJavaFiles(base.resolve(modulePaths[modulePaths.length - 1])))
196                .outdir(modules)
197                .run()
198                .writeAll();
199
200        for (int i = 0; i < modulePaths.length; i++) {
201            checkFiles(modules.resolve("m" + i + "x/module-info.class"));
202        }
203        checkFiles(modules.resolve("m8x/pkg8/A.class"));
204    }
205
206    @Test
207    public void fileInPath(Path base) throws Exception {
208        Path src = base.resolve("src");
209        tb.writeJavaFiles(src.resolve("kettle$"), "module kettle$ { }", "package electric; class Heater { }");
210        tb.writeFile(base.resolve("dummy.txt"), "");
211
212        final Path modules = base.resolve("modules");
213        tb.createDirectories(modules);
214
215        new JavacTask(tb, Task.Mode.CMDLINE)
216                .options("-XDrawDiagnostics",
217                        "--module-source-path", base + "/{dummy.txt,src}")
218                .files(src.resolve("kettle$/electric/Heater.java"))
219                .outdir(modules)
220                .run()
221                .writeAll();
222
223        checkFiles(modules.resolve("kettle$/electric/Heater.class"));
224        checkFiles(modules.resolve("kettle$/module-info.class"));
225    }
226
227    @Test
228    public void noAlternative(Path base) throws Exception {
229        Path src = base.resolve("src");
230        tb.writeJavaFiles(src.resolve("kettle$"), "module kettle$ { }", "package electric; class Heater { }");
231
232        final Path modules = base.resolve("modules");
233        tb.createDirectories(modules);
234
235        new JavacTask(tb, Task.Mode.CMDLINE)
236                .options("-XDrawDiagnostics",
237                        "--module-source-path", base + "/{src}")
238                .files(src.resolve("kettle$/electric/Heater.java"))
239                .outdir(modules)
240                .run()
241                .writeAll();
242
243        checkFiles(modules.resolve("kettle$/electric/Heater.class"));
244        checkFiles(modules.resolve("kettle$/module-info.class"));
245    }
246
247    @Test
248    public void noChoice(Path base) throws Exception {
249        tb.writeJavaFiles(base.resolve("kettle$"), "module kettle$ { }", "package electric; class Heater { }");
250
251        final Path modules = base.resolve("modules");
252        tb.createDirectories(modules);
253
254        new JavacTask(tb, Task.Mode.CMDLINE)
255                .options("-XDrawDiagnostics",
256                        "--module-source-path", base + "/{}")
257                .files(base.resolve("kettle$/electric/Heater.java"))
258                .outdir(modules)
259                .run()
260                .writeAll();
261
262        checkFiles(modules.resolve("kettle$/electric/Heater.class"));
263        checkFiles(modules.resolve("kettle$/module-info.class"));
264    }
265
266    @Test
267    public void nestedModules(Path src) throws Exception {
268        Path carModule = src.resolve("car");
269        tb.writeJavaFiles(carModule, "module car { }", "package light; class Headlight { }");
270        tb.writeJavaFiles(carModule.resolve("engine"), "module engine { }", "package flat; class Piston { }");
271
272        final Path modules = src.resolve("modules");
273        tb.createDirectories(modules);
274
275        new JavacTask(tb, Task.Mode.CMDLINE)
276                .options("-XDrawDiagnostics",
277                        "--module-source-path", "{" + src + "," + src + "/car}")
278                .files(findJavaFiles(src))
279                .outdir(modules)
280                .run()
281                .writeAll();
282        checkFiles(modules.resolve("car/light/Headlight.class"));
283        checkFiles(modules.resolve("engine/flat/Piston.class"));
284    }
285
286    @Test
287    public void relativePaths(Path base) throws Exception {
288        Path src = base.resolve("src");
289        tb.writeJavaFiles(src.resolve("kettle"), "module kettle { }", "package electric; class Heater { }");
290
291        final Path modules = base.resolve("modules");
292        tb.createDirectories(modules);
293
294        new JavacTask(tb, Task.Mode.CMDLINE)
295                .options("-XDrawDiagnostics",
296                        "--module-source-path", base + "/src/./../src")
297                .files(src.resolve("kettle/electric/Heater.java"))
298                .outdir(modules)
299                .run()
300                .writeAll();
301        checkFiles(modules.resolve("kettle/electric/Heater.class"));
302        checkFiles(modules.resolve("kettle/module-info.class"));
303    }
304
305    @Test
306    public void duplicatePaths(Path base) throws Exception {
307        Path src = base.resolve("src");
308        tb.writeJavaFiles(src.resolve("m1x"), "module m1x { }", "package a; class A { }");
309
310        final Path modules = base.resolve("modules");
311        tb.createDirectories(modules);
312
313        new JavacTask(tb, Task.Mode.CMDLINE)
314                .options("-XDrawDiagnostics",
315                        "--module-source-path", base + "/{src,src,src}")
316                .files(src.resolve("m1x/a/A.java"))
317                .outdir(modules)
318                .run()
319                .writeAll();
320
321        checkFiles(modules.resolve("m1x/module-info.class"));
322    }
323
324    @Test
325    public void notExistentPaths(Path base) throws Exception {
326        tb.writeJavaFiles(base.resolve("m1x"), "module m1x { requires m0x; }", "package a; class A { }");
327
328        final Path modules = base.resolve("modules");
329        tb.createDirectories(modules);
330
331        String log = new JavacTask(tb, Task.Mode.CMDLINE)
332                .options("-XDrawDiagnostics",
333                        "--module-source-path", base + "/not_exist" + PATH_SEP + base + "/{not_exist,}")
334                .files(base.resolve("m1x/a/A.java"))
335                .outdir(modules)
336                .run(Task.Expect.FAIL)
337                .writeAll()
338                .getOutput(Task.OutputKind.DIRECT);
339        if (!log.contains("compiler.err.module.not.found: m0x"))
340            throw new Exception("expected output for not existent module source path not found");
341    }
342
343    @Test
344    public void notExistentPathShouldBeSkipped(Path base) throws Exception {
345        tb.writeJavaFiles(base.resolve("m1x"), "module m1x { }", "package a; class A { }");
346
347        final Path modules = base.resolve("modules");
348        tb.createDirectories(modules);
349
350        new JavacTask(tb, Task.Mode.CMDLINE)
351                .options("-XDrawDiagnostics",
352                        "--module-source-path", base + "{/not_exist,/}")
353                .files(base.resolve("m1x/a/A.java"))
354                .outdir(modules)
355                .run()
356                .writeAll();
357
358        checkFiles(modules.resolve("m1x/module-info.class"));
359    }
360
361    @Test
362    public void commas(Path base) throws Exception {
363        Path src = base.resolve("src");
364        tb.writeJavaFiles(src.resolve("m1x"), "module m1x { }", "package a; class A { }");
365
366        final Path modules = base.resolve("modules");
367        tb.createDirectories(modules);
368
369        new JavacTask(tb, Task.Mode.CMDLINE)
370                .options("-XDrawDiagnostics",
371                        "--module-source-path", base + "/{,{,,,,src,,,}}")
372                .files(src.resolve("m1x/a/A.java"))
373                .outdir(modules)
374                .run()
375                .writeAll();
376
377        checkFiles(modules.resolve("m1x/module-info.class"));
378    }
379
380    @Test
381    public void asterisk(Path base) throws Exception {
382        tb.writeJavaFiles(base.resolve("kettle").resolve("classes"), "module kettle { }",
383                "package electric; class Heater { }");
384
385        final Path modules = base.resolve("modules");
386        tb.createDirectories(modules);
387
388        new JavacTask(tb, Task.Mode.CMDLINE)
389                .options("-XDrawDiagnostics",
390                        "--module-source-path", base + "/*/classes/")
391                .files(base.resolve("kettle/classes/electric/Heater.java"))
392                .outdir(modules)
393                .run()
394                .writeAll();
395
396        checkFiles(modules.resolve("kettle/electric/Heater.class"));
397        checkFiles(modules.resolve("kettle/module-info.class"));
398    }
399
400    @Test
401    public void asteriskInDifferentSets(Path base) throws Exception {
402        Path src = base.resolve("src");
403        final Path module = src.resolve("kettle");
404        tb.writeJavaFiles(module.resolve("classes"), "module kettle { }", "package electric; class Heater { }");
405        tb.writeJavaFiles(module.resolve("gensrc"), "package model; class Java { }");
406        tb.writeJavaFiles(module.resolve("special/classes"), "package gas; class Heater { }");
407
408        final Path modules = base.resolve("modules");
409        tb.createDirectories(modules);
410
411        new JavacTask(tb, Task.Mode.CMDLINE)
412                .options("-XDrawDiagnostics",
413                        "--module-source-path", src + "{/*/gensrc/,/*/classes/}" + PATH_SEP
414                                + src + "/*/special/classes")
415                .files(findJavaFiles(src))
416                .outdir(modules)
417                .run()
418                .writeAll();
419
420        checkFiles(modules.resolve("kettle/electric/Heater.class"));
421        checkFiles(modules.resolve("kettle/gas/Heater.class"));
422        checkFiles(modules.resolve("kettle/model/Java.class"));
423        checkFiles(modules.resolve("kettle/module-info.class"));
424    }
425
426    @Test
427    public void asteriskIllegalUse(Path base) throws Exception {
428        final List<String> sourcePaths = Arrays.asList(
429                "*",
430                "**",
431                "***",
432                "*.*",
433                ".*",
434                "*.",
435                "src/*/*/",
436                "{*,*}",
437                "src/module*/"
438        );
439        for (String sourcepath : sourcePaths) {
440            String log = new JavacTask(tb, Task.Mode.CMDLINE)
441                    .options("-XDrawDiagnostics",
442                            "--module-source-path", sourcepath.replace('/', File.separatorChar))
443                    .run(Task.Expect.FAIL)
444                    .writeAll()
445                    .getOutput(Task.OutputKind.DIRECT);
446
447            if (!log.contains("- compiler.err.illegal.argument.for.option: --module-source-path, illegal use of *"))
448                throw new Exception("expected output for path [" + sourcepath + "] not found");
449        }
450    }
451
452    @Test
453    public void setLocation(Path base) throws Exception {
454        Path src = base.resolve("src");
455        tb.writeJavaFiles(src.resolve("m1x"), "module m1x { }", "package a; class A { }");
456        Path modules = base.resolve("modules");
457        tb.createDirectories(modules);
458
459        JavaCompiler c = ToolProvider.getSystemJavaCompiler();
460        try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
461            fm.setLocationFromPaths(StandardLocation.MODULE_SOURCE_PATH, List.of(src));
462            new JavacTask(tb)
463                    .options("-XDrawDiagnostics")
464                    .fileManager(fm)
465                    .outdir(modules)
466                    .files(findJavaFiles(src))
467                    .run()
468                    .writeAll();
469
470            checkFiles(modules.resolve("m1x/module-info.class"), modules.resolve("m1x/a/A.class"));
471        }
472    }
473
474    @Test
475    public void getLocation_valid(Path base) throws Exception {
476        Path src1 = base.resolve("src1");
477        tb.writeJavaFiles(src1.resolve("m1x"), "module m1x { }", "package a; class A { }");
478        Path src2 = base.resolve("src2");
479        tb.writeJavaFiles(src1.resolve("m2x"), "module m2x { }", "package b; class B { }");
480
481        JavaCompiler c = ToolProvider.getSystemJavaCompiler();
482        try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
483            fm.setLocationFromPaths(StandardLocation.MODULE_SOURCE_PATH, List.of(src1, src2));
484            checkLocation(fm.getLocationAsPaths(StandardLocation.MODULE_SOURCE_PATH), List.of(src1, src2));
485        }
486    }
487
488    @Test
489    public void getLocation_ISA(Path base) throws Exception {
490        Path src1 = base.resolve("src1");
491        tb.writeJavaFiles(src1.resolve("m1x"), "module m1x { }", "package a; class A { }");
492        Path src2 = base.resolve("src2");
493        tb.writeJavaFiles(src2.resolve("m2x").resolve("extra"), "module m2x { }", "package b; class B { }");
494        Path modules = base.resolve("modules");
495        tb.createDirectories(modules);
496
497        String FS = File.separator;
498        String PS = File.pathSeparator;
499        JavaCompiler c = ToolProvider.getSystemJavaCompiler();
500        try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
501            fm.handleOption("--module-source-path",
502                    List.of(src1 + PS + src2 + FS + "*" + FS + "extra").iterator());
503
504            try {
505                Iterable<? extends Path> paths = fm.getLocationAsPaths(StandardLocation.MODULE_SOURCE_PATH);
506                out.println("result: " + asList(paths));
507                throw new Exception("expected IllegalStateException not thrown");
508            } catch (IllegalStateException e) {
509                out.println("Exception thrown, as expected: " + e);
510            }
511
512            // even if we can't do getLocation for the MODULE_SOURCE_PATH, we should be able
513            // to do getLocation for the modules, which will additionally confirm the option
514            // was effective as intended.
515            Location locn1 = fm.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, "m1x");
516            checkLocation(fm.getLocationAsPaths(locn1), List.of(src1.resolve("m1x")));
517            Location locn2 = fm.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, "m2x");
518            checkLocation(fm.getLocationAsPaths(locn2), List.of(src2.resolve("m2x").resolve("extra")));
519        }
520    }
521
522    private void generateModules(Path base, String... paths) throws IOException {
523        for (int i = 0; i < paths.length; i++) {
524            String moduleName = "m" + i + "x";
525            String dependency = i > 0 ? "requires m" + (i - 1) + "x;" : "";
526            tb.writeJavaFiles(base.resolve(paths[i]).resolve(moduleName),
527                    "module " + moduleName + " { " + dependency + " }",
528                    "package pkg" + i + "; class A { }");
529        }
530    }
531
532    private void checkFiles(Path... files) throws Exception {
533        for (Path file : files) {
534            if (!Files.exists(file)) {
535                throw new Exception("File not found: " + file);
536            }
537        }
538    }
539
540    private void checkLocation(Iterable<? extends Path> locn, List<Path> ref) throws Exception {
541        List<Path> list = asList(locn);
542        if (!list.equals(ref)) {
543            out.println("expect: " + ref);
544            out.println(" found: " + list);
545            throw new Exception("location not as expected");
546        }
547    }
548
549    private <T> List<T> asList(Iterable<? extends T> iter) {
550        List<T> list = new ArrayList<>();
551        for (T item : iter) {
552            list.add(item);
553        }
554        return list;
555    }
556}
557