1/*
2 * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
3 * 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
26 * @modules java.base/jdk.internal.module
27 *          java.base/jdk.internal.misc
28 * @run testng ModuleDescriptorTest
29 * @summary Basic test for java.lang.module.ModuleDescriptor and its builder
30 */
31
32import java.io.ByteArrayOutputStream;
33import java.io.IOException;
34import java.io.InputStream;
35import java.lang.module.InvalidModuleDescriptorException;
36import java.lang.module.ModuleDescriptor;
37import java.lang.module.ModuleDescriptor.Builder;
38import java.lang.module.ModuleDescriptor.Exports;
39import java.lang.module.ModuleDescriptor.Opens;
40import java.lang.module.ModuleDescriptor.Requires;
41import java.lang.module.ModuleDescriptor.Provides;
42import java.lang.module.ModuleDescriptor.Requires.Modifier;
43import java.lang.module.ModuleDescriptor.Version;
44import java.nio.ByteBuffer;
45import java.util.ArrayList;
46import java.util.Collections;
47import java.util.EnumSet;
48import java.util.HashSet;
49import java.util.Iterator;
50import java.util.List;
51import java.util.Objects;
52import java.util.Optional;
53import java.util.Set;
54import java.util.stream.Collectors;
55
56import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
57
58import jdk.internal.misc.JavaLangModuleAccess;
59import jdk.internal.misc.SharedSecrets;
60import jdk.internal.module.ModuleInfoWriter;
61import org.testng.annotations.DataProvider;
62import org.testng.annotations.Test;
63import static org.testng.Assert.*;
64
65@Test
66public class ModuleDescriptorTest {
67
68    @DataProvider(name = "invalidNames")
69    public Object[][] invalidNames() {
70        return new Object[][]{
71
72            { null,             null },
73            { "1",              null },
74            { "1foo",           null },
75            { ".foo",           null },
76            { "foo.",           null },
77            { "[foo]",          null },
78            { "foo.1",          null },
79            { "1foo.bar",       null },
80            { "foo.1bar",       null },
81            { "foo.[bar]",      null },
82            { "foo..bar",       null },
83            { "foo.bar.1",      null },
84            { "foo.bar.1gus",   null },
85            { "foo.bar.[gus]",  null },
86
87            { "class",          null },
88            { "interface",      null },
89            { "true",           null },
90            { "false",          null },
91            { "null",           null },
92
93            { "x.class",        null },
94            { "x.interface",    null },
95            { "x.true",         null },
96            { "x.false",        null },
97            { "x.null",         null },
98
99            { "class.x",        null },
100            { "interface.x",    null },
101            { "true.x",         null },
102            { "false.x",        null },
103            { "null.x",         null },
104
105            { "x.class.x",      null },
106            { "x.interface.x",  null },
107            { "x.true.x",       null },
108            { "x.false.x",      null },
109            { "x.null.x",       null },
110
111            { "_",              null },
112
113        };
114    }
115
116
117    // requires
118
119    private Requires requires(Set<Modifier> mods, String mn) {
120        return requires(mods, mn, null);
121    }
122
123    private Requires requires(Set<Modifier> mods, String mn, Version v) {
124        Builder builder = ModuleDescriptor.newModule("m");
125        if (v == null) {
126            builder.requires(mods, mn);
127        } else {
128            builder.requires(mods, mn, v);
129        }
130        Set<Requires> requires = builder.build().requires();
131        assertTrue(requires.size() == 2);
132        Iterator<Requires> iterator = requires.iterator();
133        Requires r = iterator.next();
134        if (r.name().equals("java.base")) {
135            r = iterator.next();
136        } else {
137            Requires other = iterator.next();
138            assertEquals(other.name(), "java.base");
139        }
140        return r;
141    }
142
143    private Requires requires(String mn) {
144        return requires(Collections.emptySet(), mn);
145    }
146
147    public void testRequiresWithRequires() {
148        Requires r1 = requires("foo");
149        ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").requires(r1).build();
150        Requires r2 = descriptor.requires().iterator().next();
151        assertEquals(r1, r2);
152    }
153
154    public void testRequiresWithNoModifiers() {
155        Requires r = requires(EnumSet.noneOf(Requires.Modifier.class), "foo");
156        assertEquals(r, r);
157        assertTrue(r.compareTo(r) == 0);
158        assertTrue(r.modifiers().isEmpty());
159        assertEquals(r.name(), "foo");
160        assertFalse(r.compiledVersion().isPresent());
161    }
162
163    public void testRequiresWithOneModifier() {
164        Requires r = requires(EnumSet.of(TRANSITIVE), "foo");
165        assertEquals(r, r);
166        assertTrue(r.compareTo(r) == 0);
167        assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE));
168        assertEquals(r.name(), "foo");
169        assertFalse(r.compiledVersion().isPresent());
170    }
171
172    public void testRequiresWithTwoModifiers() {
173        Requires r = requires(EnumSet.of(TRANSITIVE, SYNTHETIC), "foo");
174        assertEquals(r, r);
175        assertTrue(r.compareTo(r) == 0);
176        assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, SYNTHETIC));
177        assertEquals(r.name(), "foo");
178        assertFalse(r.compiledVersion().isPresent());
179    }
180
181    public void testRequiresWithAllModifiers() {
182        Requires r = requires(EnumSet.allOf(Modifier.class), "foo");
183        assertEquals(r, r);
184        assertTrue(r.compareTo(r) == 0);
185        assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, STATIC, SYNTHETIC, MANDATED));
186        assertEquals(r.name(), "foo");
187        assertFalse(r.compiledVersion().isPresent());
188    }
189
190    public void testRequiresWithCompiledVersion() {
191        Version v = Version.parse("1.0");
192        Requires r = requires(Set.of(), "foo", v);
193        assertEquals(r, r);
194        assertTrue(r.compareTo(r) == 0);
195        assertEquals(r.modifiers(), Set.of());
196        assertEquals(r.name(), "foo");
197        assertTrue(r.compiledVersion().isPresent());
198        assertEquals(r.compiledVersion().get().toString(), "1.0");
199    }
200
201    @Test(expectedExceptions = IllegalStateException.class)
202    public void testRequiresWithDuplicatesRequires() {
203        Requires r = requires("foo");
204        ModuleDescriptor.newModule("m").requires(r).requires(r);
205    }
206
207    @Test(expectedExceptions = IllegalArgumentException.class)
208    public void testRequiresSelfWithRequires() {
209        Requires r = requires("foo");
210        ModuleDescriptor.newModule("foo").requires(r);
211    }
212
213    @Test(expectedExceptions = IllegalArgumentException.class)
214    public void testRequiresSelfWithNoModifier() {
215        ModuleDescriptor.newModule("m").requires("m");
216    }
217
218    @Test(expectedExceptions = IllegalArgumentException.class)
219    public void testRequiresSelfWithOneModifier() {
220        ModuleDescriptor.newModule("m").requires(Set.of(TRANSITIVE), "m");
221    }
222
223    @Test(expectedExceptions = IllegalArgumentException.class)
224    public void testRequiresSelfWithAllModifiers() {
225        ModuleDescriptor.newModule("m").requires(EnumSet.allOf(Modifier.class), "m");
226    }
227
228    @Test(dataProvider = "invalidNames",
229          expectedExceptions = IllegalArgumentException.class )
230    public void testRequiresWithBadModuleName(String mn, String ignore) {
231        requires(EnumSet.noneOf(Modifier.class), mn);
232    }
233
234    @Test(expectedExceptions = NullPointerException.class)
235    public void testRequiresWithNullRequires() {
236        ModuleDescriptor.newModule("m").requires((Requires) null);
237    }
238
239    @Test(expectedExceptions = NullPointerException.class)
240    public void testRequiresWithNullModifiers() {
241        ModuleDescriptor.newModule("m").requires(null, "foo");
242    }
243
244    @Test(expectedExceptions = NullPointerException.class)
245    public void testRequiresWithNullVersion() {
246        ModuleDescriptor.newModule("m").requires(Set.of(), "foo", null);
247    }
248
249    public void testRequiresCompare() {
250        Requires r1 = requires(EnumSet.noneOf(Modifier.class), "foo");
251        Requires r2 = requires(EnumSet.noneOf(Modifier.class), "bar");
252        int n = "foo".compareTo("bar");
253        assertTrue(r1.compareTo(r2) == n);
254        assertTrue(r2.compareTo(r1) == -n);
255    }
256
257    public void testRequiresCompareWithDifferentModifiers() {
258        Requires r1 = requires(EnumSet.of(TRANSITIVE), "foo");
259        Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo");
260        int n = Integer.compare(1 << TRANSITIVE.ordinal(), 1 << SYNTHETIC.ordinal());
261        assertTrue(r1.compareTo(r2) == n);
262        assertTrue(r2.compareTo(r1) == -n);
263    }
264
265    public void testRequiresCompareWithSameModifiers() {
266        Requires r1 = requires(EnumSet.of(SYNTHETIC), "foo");
267        Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo");
268        assertTrue(r1.compareTo(r2) == 0);
269        assertTrue(r2.compareTo(r1) == 0);
270    }
271
272    public void testRequiresCompareWithSameCompiledVersion() {
273        Requires r1 = requires(Set.of(), "foo", Version.parse("2.0"));
274        Requires r2 = requires(Set.of(), "foo", Version.parse("2.0"));
275        assertTrue(r1.compareTo(r2) == 0);
276        assertTrue(r2.compareTo(r1) == 0);
277    }
278
279    public void testRequiresCompareWithDifferentCompiledVersion() {
280        Requires r1 = requires(Set.of(), "foo", Version.parse("1.0"));
281        Requires r2 = requires(Set.of(), "foo", Version.parse("2.0"));
282        assertTrue(r1.compareTo(r2) < 0);
283        assertTrue(r2.compareTo(r1) > 0);
284    }
285
286    public void testRequiresEqualsAndHashCode() {
287        Requires r1 = requires("foo");
288        Requires r2 = requires("foo");
289        assertEquals(r1, r2);
290        assertTrue(r1.hashCode() == r2.hashCode());
291
292        r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
293        r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
294        assertEquals(r1, r2);
295        assertTrue(r1.hashCode() == r2.hashCode());
296
297        r1 = requires("foo");
298        r2 = requires("bar");
299        assertNotEquals(r1, r2);
300
301        r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
302        r2 = requires(Set.of(), "foo");
303        assertNotEquals(r1, r2);
304
305        Version v1 = Version.parse("1.0");
306        r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
307        r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
308        assertEquals(r1, r2);
309        assertTrue(r1.hashCode() == r2.hashCode());
310
311        Version v2 = Version.parse("2.0");
312        r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
313        r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v2);
314        assertNotEquals(r1, r2);
315    }
316
317    public void testRequiresToString() {
318        Requires r = requires(EnumSet.noneOf(Modifier.class), "foo");
319        assertTrue(r.toString().contains("foo"));
320    }
321
322
323    // exports
324
325    private Exports exports(Set<Exports.Modifier> mods, String pn) {
326        return ModuleDescriptor.newModule("foo")
327            .exports(mods, pn)
328            .build()
329            .exports()
330            .iterator()
331            .next();
332    }
333
334    private Exports exports(String pn) {
335        return exports(Set.of(), pn);
336    }
337
338    private Exports exports(Set<Exports.Modifier> mods, String pn, String target) {
339        return ModuleDescriptor.newModule("foo")
340            .exports(mods, pn, Set.of(target))
341            .build()
342            .exports()
343            .iterator()
344            .next();
345    }
346
347    private Exports exports(String pn, String target) {
348        return exports(Set.of(), pn, target);
349    }
350
351
352    public void testExportsExports() {
353        Exports e1 = exports("p");
354        ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").exports(e1).build();
355        Exports e2 = descriptor.exports().iterator().next();
356        assertEquals(e1, e2);
357    }
358
359    public void testExportsToAll() {
360        Exports e = exports("p");
361        assertEquals(e, e);
362        assertTrue(e.modifiers().isEmpty());
363        assertEquals(e.source(), "p");
364        assertFalse(e.isQualified());
365        assertTrue(e.targets().isEmpty());
366    }
367
368    public void testExportsToTarget() {
369        Exports e = exports("p", "bar");
370        assertEquals(e, e);
371        assertTrue(e.modifiers().isEmpty());
372        assertEquals(e.source(), "p");
373        assertTrue(e.isQualified());
374        assertTrue(e.targets().size() == 1);
375        assertTrue(e.targets().contains("bar"));
376    }
377
378    public void testExportsToTargets() {
379        Set<String> targets = new HashSet<>();
380        targets.add("bar");
381        targets.add("gus");
382        Exports e
383            = ModuleDescriptor.newModule("foo")
384                .exports("p", targets)
385                .build()
386                .exports()
387                .iterator()
388                .next();
389        assertEquals(e, e);
390        assertTrue(e.modifiers().isEmpty());
391        assertEquals(e.source(), "p");
392        assertTrue(e.isQualified());
393        assertTrue(e.targets().size() == 2);
394        assertTrue(e.targets().contains("bar"));
395        assertTrue(e.targets().contains("gus"));
396    }
397
398    public void testExportsToAllWithModifier() {
399        Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
400        assertEquals(e, e);
401        assertTrue(e.modifiers().size() == 1);
402        assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
403        assertEquals(e.source(), "p");
404        assertFalse(e.isQualified());
405        assertTrue(e.targets().isEmpty());
406    }
407
408    public void testExportsToTargetWithModifier() {
409        Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", "bar");
410        assertEquals(e, e);
411        assertTrue(e.modifiers().size() == 1);
412        assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
413        assertEquals(e.source(), "p");
414        assertTrue(e.isQualified());
415        assertTrue(e.targets().size() == 1);
416        assertTrue(e.targets().contains("bar"));
417    }
418
419    @Test(expectedExceptions = IllegalStateException.class)
420    public void testExportsWithDuplicate1() {
421        Exports e = exports("p");
422        ModuleDescriptor.newModule("foo").exports(e).exports(e);
423    }
424
425    @Test(expectedExceptions = IllegalStateException.class)
426    public void testExportsWithDuplicate2() {
427        ModuleDescriptor.newModule("foo").exports("p").exports("p");
428    }
429
430    @Test(expectedExceptions = IllegalArgumentException.class )
431    public void testExportsWithEmptySet() {
432        ModuleDescriptor.newModule("foo").exports("p", Collections.emptySet());
433    }
434
435    @Test(dataProvider = "invalidNames",
436          expectedExceptions = IllegalArgumentException.class )
437    public void testExportsWithBadName(String pn, String ignore) {
438        ModuleDescriptor.newModule("foo").exports(pn);
439    }
440
441    @Test(expectedExceptions = NullPointerException.class )
442    public void testExportsWithNullExports() {
443        ModuleDescriptor.newModule("foo").exports((Exports) null);
444    }
445
446    @Test(expectedExceptions = NullPointerException.class )
447    public void testExportsWithNullTargets() {
448        ModuleDescriptor.newModule("foo").exports("p", (Set<String>) null);
449    }
450
451    public void testExportsCompare() {
452        Exports e1 = exports("p");
453        Exports e2 = exports("p");
454        assertEquals(e1, e2);
455        assertTrue(e1.hashCode() == e2.hashCode());
456        assertTrue(e1.compareTo(e2) == 0);
457        assertTrue(e2.compareTo(e1) == 0);
458    }
459
460    public void testExportsCompareWithSameModifiers() {
461        Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
462        Exports e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
463        assertEquals(e1, e2);
464        assertTrue(e1.hashCode() == e2.hashCode());
465        assertTrue(e1.compareTo(e2) == 0);
466        assertTrue(e2.compareTo(e1) == 0);
467    }
468
469    public void testExportsCompareWithDifferentModifiers() {
470        Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
471        Exports e2 = exports("p");
472        assertNotEquals(e1, e2);
473        assertTrue(e1.compareTo(e2) == 1);
474        assertTrue(e2.compareTo(e1) == -1);
475    }
476
477    public void testExportsCompareWithSameTargets() {
478        Exports e1 = exports("p", "x");
479        Exports e2 = exports("p", "x");
480        assertEquals(e1, e2);
481        assertTrue(e1.hashCode() == e2.hashCode());
482        assertTrue(e1.compareTo(e2) == 0);
483        assertTrue(e2.compareTo(e1) == 0);
484    }
485
486    public void testExportsCompareWithDifferentTargets() {
487        Exports e1 = exports("p", "y");
488        Exports e2 = exports("p", "x");
489        assertNotEquals(e1, e2);
490        assertTrue(e1.compareTo(e2) == 1);
491        assertTrue(e2.compareTo(e1) == -1);
492    }
493
494    public void testExportsToString() {
495        String s = ModuleDescriptor.newModule("foo")
496            .exports("p1", Set.of("bar"))
497            .build()
498            .exports()
499            .iterator()
500            .next()
501            .toString();
502        assertTrue(s.contains("p1"));
503        assertTrue(s.contains("bar"));
504    }
505
506
507    // opens
508
509    private Opens opens(Set<Opens.Modifier> mods, String pn) {
510        return ModuleDescriptor.newModule("foo")
511                .opens(mods, pn)
512                .build()
513                .opens()
514                .iterator()
515                .next();
516    }
517
518    private Opens opens(String pn) {
519        return opens(Set.of(), pn);
520    }
521
522    private Opens opens(Set<Opens.Modifier> mods, String pn, String target) {
523        return ModuleDescriptor.newModule("foo")
524                .opens(mods, pn, Set.of(target))
525                .build()
526                .opens()
527                .iterator()
528                .next();
529    }
530
531    private Opens opens(String pn, String target) {
532        return opens(Set.of(), pn, target);
533    }
534
535    public void testOpensOpens() {
536        Opens o1 = opens("p");
537        ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").opens(o1).build();
538        Opens o2 = descriptor.opens().iterator().next();
539        assertEquals(o1, o2);
540    }
541
542    public void testOpensToAll() {
543        Opens o = opens("p");
544        assertEquals(o, o);
545        assertTrue(o.modifiers().isEmpty());
546        assertEquals(o.source(), "p");
547        assertFalse(o.isQualified());
548        assertTrue(o.targets().isEmpty());
549    }
550
551
552    public void testOpensToTarget() {
553        Opens o = opens("p", "bar");
554        assertEquals(o, o);
555        assertTrue(o.modifiers().isEmpty());
556        assertEquals(o.source(), "p");
557        assertTrue(o.isQualified());
558        assertTrue(o.targets().size() == 1);
559        assertTrue(o.targets().contains("bar"));
560    }
561
562    public void testOpensToTargets() {
563        Set<String> targets = new HashSet<>();
564        targets.add("bar");
565        targets.add("gus");
566        Opens o = ModuleDescriptor.newModule("foo")
567                .opens("p", targets)
568                .build()
569                .opens()
570                .iterator()
571                .next();
572        assertEquals(o, o);
573        assertTrue(o.modifiers().isEmpty());
574        assertEquals(o.source(), "p");
575        assertTrue(o.isQualified());
576        assertTrue(o.targets().size() == 2);
577        assertTrue(o.targets().contains("bar"));
578        assertTrue(o.targets().contains("gus"));
579    }
580
581    @Test(expectedExceptions = IllegalStateException.class)
582    public void testOpensWithDuplicate1() {
583        Opens o = opens("p");
584        ModuleDescriptor.newModule("foo").opens(o).opens(o);
585    }
586
587    @Test(expectedExceptions = IllegalStateException.class)
588    public void testOpensWithDuplicate2() {
589        ModuleDescriptor.newModule("foo").opens("p").opens("p");
590    }
591
592    @Test(expectedExceptions = IllegalArgumentException.class )
593    public void testOpensWithEmptySet() {
594        ModuleDescriptor.newModule("foo").opens("p", Collections.emptySet());
595    }
596
597    @Test(dataProvider = "invalidNames",
598            expectedExceptions = IllegalArgumentException.class )
599    public void testOpensWithBadName(String pn, String ignore) {
600        ModuleDescriptor.newModule("foo").opens(pn);
601    }
602
603    @Test(expectedExceptions = NullPointerException.class )
604    public void testOpensWithNullExports() {
605        ModuleDescriptor.newModule("foo").opens((Opens) null);
606    }
607
608    @Test(expectedExceptions = NullPointerException.class )
609    public void testOpensWithNullTargets() {
610        ModuleDescriptor.newModule("foo").opens("p", (Set<String>) null);
611    }
612
613    public void testOpensCompare() {
614        Opens o1 = opens("p");
615        Opens o2 = opens("p");
616        assertEquals(o1, o2);
617        assertTrue(o1.hashCode() == o2.hashCode());
618        assertTrue(o1.compareTo(o2) == 0);
619        assertTrue(o2.compareTo(o1) == 0);
620    }
621
622    public void testOpensCompareWithSameModifiers() {
623        Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
624        Opens o2 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
625        assertEquals(o1, o2);
626        assertTrue(o1.hashCode() == o2.hashCode());
627        assertTrue(o1.compareTo(o2) == 0);
628        assertTrue(o2.compareTo(o1) == 0);
629    }
630
631    public void testOpensCompareWithDifferentModifiers() {
632        Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
633        Opens o2 = opens("p");
634        assertNotEquals(o1, o2);
635        assertTrue(o1.compareTo(o2) == 1);
636        assertTrue(o2.compareTo(o1) == -1);
637    }
638
639    public void testOpensCompareWithSameTargets() {
640        Opens o1 = opens("p", "x");
641        Opens o2 = opens("p", "x");
642        assertEquals(o1, o2);
643        assertTrue(o1.hashCode() == o2.hashCode());
644        assertTrue(o1.compareTo(o2) == 0);
645        assertTrue(o2.compareTo(o1) == 0);
646    }
647
648    public void testOpensCompareWithDifferentTargets() {
649        Opens o1 = opens("p", "y");
650        Opens o2 = opens("p", "x");
651        assertNotEquals(o1, o2);
652        assertTrue(o1.compareTo(o2) == 1);
653        assertTrue(o2.compareTo(o1) == -1);
654    }
655
656    public void testOpensToString() {
657        String s = ModuleDescriptor.newModule("foo")
658                .opens("p1", Set.of("bar"))
659                .build()
660                .opens()
661                .iterator()
662                .next()
663                .toString();
664        assertTrue(s.contains("p1"));
665        assertTrue(s.contains("bar"));
666    }
667
668
669    // uses
670
671    public void testUses() {
672        Set<String> uses
673            = ModuleDescriptor.newModule("foo")
674                .uses("p.S")
675                .uses("q.S")
676                .build()
677                .uses();
678        assertTrue(uses.size() == 2);
679        assertTrue(uses.contains("p.S"));
680        assertTrue(uses.contains("q.S"));
681    }
682
683    @Test(expectedExceptions = IllegalStateException.class)
684    public void testUsesWithDuplicate() {
685        ModuleDescriptor.newModule("foo").uses("p.S").uses("p.S");
686    }
687
688    @Test(expectedExceptions = IllegalArgumentException.class)
689    public void testUsesWithSimpleIdentifier() {
690        ModuleDescriptor.newModule("foo").uses("S");
691    }
692
693    @Test(dataProvider = "invalidNames",
694          expectedExceptions = IllegalArgumentException.class )
695    public void testUsesWithBadName(String service, String ignore) {
696        ModuleDescriptor.newModule("foo").uses(service);
697    }
698
699
700    // provides
701
702    private Provides provides(String st, String pc) {
703        return ModuleDescriptor.newModule("foo")
704            .provides(st, List.of(pc))
705            .build()
706            .provides()
707            .iterator()
708            .next();
709    }
710
711    private Provides provides(String st, List<String> pns) {
712        return ModuleDescriptor.newModule("foo")
713                .provides(st, pns)
714                .build()
715                .provides()
716                .iterator()
717                .next();
718    }
719
720    public void testProvidesWithProvides() {
721        Provides p1 = provides("p.S", "q.S1");
722        ModuleDescriptor descriptor = ModuleDescriptor.newModule("m")
723                .provides(p1)
724                .build();
725        Provides p2 = descriptor.provides().iterator().next();
726        assertEquals(p1, p2);
727    }
728
729
730    public void testProvides() {
731        Set<Provides> set = ModuleDescriptor.newModule("foo")
732                .provides("p.S", List.of("q.P1", "q.P2"))
733                .build()
734                .provides();
735        assertTrue(set.size() == 1);
736
737        Provides p = set.iterator().next();
738        assertEquals(p, p);
739        assertEquals(p.service(), "p.S");
740        assertTrue(p.providers().size() == 2);
741        assertEquals(p.providers().get(0), "q.P1");
742        assertEquals(p.providers().get(1), "q.P2");
743    }
744
745    @Test(expectedExceptions = IllegalStateException.class )
746    public void testProvidesWithDuplicateProvides() {
747        Provides p = provides("p.S", "q.S2");
748        ModuleDescriptor.newModule("m").provides("p.S", List.of("q.S1")).provides(p);
749    }
750
751    @Test(expectedExceptions = IllegalArgumentException.class )
752    public void testProvidesWithEmptySet() {
753        ModuleDescriptor.newModule("foo").provides("p.Service", Collections.emptyList());
754    }
755
756    @Test(expectedExceptions = IllegalArgumentException.class )
757    public void testProvidesWithSimpleIdentifier1() {
758        ModuleDescriptor.newModule("foo").provides("S", List.of("q.P"));
759    }
760
761    @Test(expectedExceptions = IllegalArgumentException.class )
762    public void testProvidesWithSimpleIdentifier2() {
763        ModuleDescriptor.newModule("foo").provides("p.S", List.of("P"));
764    }
765
766    @Test(dataProvider = "invalidNames",
767          expectedExceptions = IllegalArgumentException.class )
768    public void testProvidesWithBadService(String service, String ignore) {
769        ModuleDescriptor.newModule("foo").provides(service, List.of("p.Provider"));
770    }
771
772    @Test(dataProvider = "invalidNames",
773          expectedExceptions = IllegalArgumentException.class )
774    public void testProvidesWithBadProvider(String provider, String ignore) {
775        List<String> names = new ArrayList<>(); // allows nulls
776        names.add(provider);
777        ModuleDescriptor.newModule("foo").provides("p.Service", names);
778    }
779
780    @Test(expectedExceptions = NullPointerException.class )
781    public void testProvidesWithNullProvides() {
782        ModuleDescriptor.newModule("foo").provides((Provides) null);
783    }
784
785    @Test(expectedExceptions = NullPointerException.class )
786    public void testProvidesWithNullProviders() {
787        ModuleDescriptor.newModule("foo").provides("p.S", (List<String>) null);
788    }
789
790    public void testProvidesCompare() {
791        Provides p1 = provides("p.S", "q.S1");
792        Provides p2 = provides("p.S", "q.S1");
793        assertEquals(p1, p2);
794        assertTrue(p1.hashCode() == p2.hashCode());
795        assertTrue(p1.compareTo(p2) == 0);
796        assertTrue(p2.compareTo(p1) == 0);
797    }
798
799    public void testProvidesCompareWithDifferentService() {
800        Provides p1 = provides("p.S2", "q.S1");
801        Provides p2 = provides("p.S1", "q.S1");
802        assertNotEquals(p1, p2);
803        assertTrue(p1.compareTo(p2) == 1);
804        assertTrue(p2.compareTo(p1) == -1);
805    }
806
807    public void testProvidesCompareWithDifferentProviders1() {
808        Provides p1 = provides("p.S", "q.S2");
809        Provides p2 = provides("p.S", "q.S1");
810        assertNotEquals(p1, p2);
811        assertTrue(p1.compareTo(p2) == 1);
812        assertTrue(p2.compareTo(p1) == -1);
813    }
814
815    public void testProvidesCompareWithDifferentProviders2() {
816        Provides p1 = provides("p.S", List.of("q.S1", "q.S2"));
817        Provides p2 = provides("p.S", "q.S1");
818        assertNotEquals(p1, p2);
819        assertTrue(p1.compareTo(p2) == 1);
820        assertTrue(p2.compareTo(p1) == -1);
821    }
822
823    // packages
824
825    public void testPackages1() {
826        Set<String> packages = ModuleDescriptor.newModule("foo")
827                .packages(Set.of("p", "q"))
828                .build()
829                .packages();
830        assertTrue(packages.size() == 2);
831        assertTrue(packages.contains("p"));
832        assertTrue(packages.contains("q"));
833    }
834
835    public void testPackages2() {
836        Set<String> packages = ModuleDescriptor.newModule("foo")
837                .packages(Set.of("p"))
838                .packages(Set.of("q"))
839                .build()
840                .packages();
841        assertTrue(packages.size() == 2);
842        assertTrue(packages.contains("p"));
843        assertTrue(packages.contains("q"));
844    }
845
846
847    public void testPackagesWithEmptySet() {
848        Set<String> packages = ModuleDescriptor.newModule("foo")
849                .packages(Collections.emptySet())
850                .build()
851                .packages();
852        assertTrue(packages.size() == 0);
853    }
854
855    public void testPackagesDuplicate() {
856        Set<String> packages = ModuleDescriptor.newModule("foo")
857                .packages(Set.of("p"))
858                .packages(Set.of("p"))
859                .build()
860                .packages();
861        assertTrue(packages.size() == 1);
862        assertTrue(packages.contains("p"));
863    }
864
865    public void testPackagesAndExportsPackage1() {
866        Set<String> packages = ModuleDescriptor.newModule("foo")
867                .packages(Set.of("p"))
868                .exports("p")
869                .build()
870                .packages();
871        assertTrue(packages.size() == 1);
872        assertTrue(packages.contains("p"));
873    }
874
875    public void testPackagesAndExportsPackage2() {
876        Set<String> packages = ModuleDescriptor.newModule("foo")
877                .exports("p")
878                .packages(Set.of("p"))
879                .build()
880                .packages();
881        assertTrue(packages.size() == 1);
882        assertTrue(packages.contains("p"));
883    }
884
885    public void testPackagesAndOpensPackage1() {
886        Set<String> packages = ModuleDescriptor.newModule("foo")
887                .packages(Set.of("p"))
888                .opens("p")
889                .build()
890                .packages();
891        assertTrue(packages.size() == 1);
892        assertTrue(packages.contains("p"));
893    }
894
895    public void testPackagesAndOpensPackage2() {
896        Set<String> packages = ModuleDescriptor.newModule("foo")
897                .opens("p")
898                .packages(Set.of("p"))
899                .build()
900                .packages();
901        assertTrue(packages.size() == 1);
902        assertTrue(packages.contains("p"));
903    }
904
905    public void testPackagesAndProvides1() {
906        Set<String> packages = ModuleDescriptor.newModule("foo")
907                .packages(Set.of("p"))
908                .provides("q.S", List.of("p.T"))
909                .build()
910                .packages();
911        assertTrue(packages.size() == 1);
912        assertTrue(packages.contains("p"));
913    }
914
915    public void testPackagesAndProvides2() {
916        Set<String> packages = ModuleDescriptor.newModule("foo")
917                .provides("q.S", List.of("p.T"))
918                .packages(Set.of("p"))
919                .build()
920                .packages();
921        assertTrue(packages.size() == 1);
922        assertTrue(packages.contains("p"));
923    }
924
925    public void testPackagesAndMainClass1() {
926        Set<String> packages = ModuleDescriptor.newModule("foo")
927                .packages(Set.of("p"))
928                .mainClass("p.Main")
929                .build()
930                .packages();
931        assertTrue(packages.size() == 1);
932        assertTrue(packages.contains("p"));
933    }
934
935    public void testPackagesAndMainClass2() {
936        Set<String> packages = ModuleDescriptor.newModule("foo")
937                .mainClass("p.Main")
938                .packages(Set.of("p"))
939                .build()
940                .packages();
941        assertTrue(packages.size() == 1);
942        assertTrue(packages.contains("p"));
943    }
944
945    public void testPackagesAndAll() {
946        Set<String> packages = ModuleDescriptor.newModule("foo")
947                .exports("p1")
948                .opens("p2")
949                .packages(Set.of("p3"))
950                .provides("q.S", List.of("p4.T"))
951                .mainClass("p5.Main")
952                .build()
953                .packages();
954        assertTrue(Objects.equals(packages, Set.of("p1", "p2", "p3", "p4", "p5")));
955    }
956
957    @Test(dataProvider = "invalidNames",
958          expectedExceptions = IllegalArgumentException.class )
959    public void testPackagesWithBadName(String pn, String ignore) {
960        Set<String> pkgs = new HashSet<>();  // allows nulls
961        pkgs.add(pn);
962        ModuleDescriptor.newModule("foo").packages(pkgs);
963    }
964
965    // name
966
967    public void testModuleName() {
968        String mn = ModuleDescriptor.newModule("foo").build().name();
969        assertEquals(mn, "foo");
970    }
971
972    @Test(dataProvider = "invalidNames",
973          expectedExceptions = IllegalArgumentException.class )
974    public void testBadModuleName(String mn, String ignore) {
975        ModuleDescriptor.newModule(mn);
976    }
977
978
979    // version
980
981    public void testVersion1() {
982        Version v1 = Version.parse("1.0");
983        Version v2 = ModuleDescriptor.newModule("foo")
984                .version(v1)
985                .build()
986                .version()
987                .get();
988        assertEquals(v1, v2);
989    }
990
991    public void testVersion2() {
992        String vs = "1.0";
993        Version v1 = ModuleDescriptor.newModule("foo")
994                .version(vs)
995                .build()
996                .version()
997                .get();
998        Version v2 = Version.parse(vs);
999        assertEquals(v1, v2);
1000    }
1001
1002    @Test(expectedExceptions = NullPointerException.class )
1003    public void testNullVersion1() {
1004        ModuleDescriptor.newModule("foo").version((Version) null);
1005    }
1006
1007    @Test(expectedExceptions = IllegalArgumentException.class )
1008    public void testNullVersion2() {
1009        ModuleDescriptor.newModule("foo").version((String) null);
1010    }
1011
1012    @Test(expectedExceptions = IllegalArgumentException.class )
1013    public void testEmptyVersion() {
1014        ModuleDescriptor.newModule("foo").version("");
1015    }
1016
1017
1018    @DataProvider(name = "unparseableVersions")
1019    public Object[][] unparseableVersions() {
1020        return new Object[][]{
1021
1022                { null,  "A1" },    // no version < unparseable
1023                { "A1",  "A2" },    // unparseable < unparseable
1024                { "A1",  "1.0" },   // unparseable < parseable
1025
1026        };
1027    }
1028
1029    /**
1030     * Basic test for unparseable module versions
1031     */
1032    @Test(dataProvider = "unparseableVersions")
1033    public void testUnparseableModuleVersion(String vs1, String vs2) {
1034        ModuleDescriptor descriptor1 = newModule("m", vs1);
1035        ModuleDescriptor descriptor2 = newModule("m", vs2);
1036
1037        if (vs1 != null && !isParsableVersion(vs1)) {
1038            assertFalse(descriptor1.version().isPresent());
1039            assertTrue(descriptor1.rawVersion().isPresent());
1040            assertEquals(descriptor1.rawVersion().get(), vs1);
1041        }
1042
1043        if (vs2 != null && !isParsableVersion(vs2)) {
1044            assertFalse(descriptor2.version().isPresent());
1045            assertTrue(descriptor2.rawVersion().isPresent());
1046            assertEquals(descriptor2.rawVersion().get(), vs2);
1047        }
1048
1049        assertFalse(descriptor1.equals(descriptor2));
1050        assertFalse(descriptor2.equals(descriptor1));
1051        assertTrue(descriptor1.compareTo(descriptor2) == -1);
1052        assertTrue(descriptor2.compareTo(descriptor1) == 1);
1053    }
1054
1055    /**
1056     * Basic test for requiring a module with an unparseable version recorded
1057     * at compile version.
1058     */
1059    @Test(dataProvider = "unparseableVersions")
1060    public void testUnparseableCompiledVersion(String vs1, String vs2) {
1061        Requires r1 = newRequires("m", vs1);
1062        Requires r2 = newRequires("m", vs2);
1063
1064        if (vs1 != null && !isParsableVersion(vs1)) {
1065            assertFalse(r1.compiledVersion().isPresent());
1066            assertTrue(r1.rawCompiledVersion().isPresent());
1067            assertEquals(r1.rawCompiledVersion().get(), vs1);
1068        }
1069
1070        if (vs2 != null && !isParsableVersion(vs2)) {
1071            assertFalse(r2.compiledVersion().isPresent());
1072            assertTrue(r2.rawCompiledVersion().isPresent());
1073            assertEquals(r2.rawCompiledVersion().get(), vs2);
1074        }
1075
1076        assertFalse(r1.equals(r2));
1077        assertFalse(r2.equals(r1));
1078        assertTrue(r1.compareTo(r2) == -1);
1079        assertTrue(r2.compareTo(r1) == 1);
1080    }
1081
1082    private ModuleDescriptor newModule(String name, String vs) {
1083        JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
1084        Builder builder = JLMA.newModuleBuilder(name, false, Set.of());
1085        if (vs != null)
1086            builder.version(vs);
1087        builder.requires("java.base");
1088        ByteBuffer bb = ModuleInfoWriter.toByteBuffer(builder.build());
1089        return ModuleDescriptor.read(bb);
1090    }
1091
1092    private Requires newRequires(String name, String vs) {
1093        JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
1094        Builder builder = JLMA.newModuleBuilder("foo", false, Set.of());
1095        if (vs == null) {
1096            builder.requires(name);
1097        } else {
1098            JLMA.requires(builder, Set.of(), name, vs);
1099        }
1100        Set<ModuleDescriptor.Requires> requires = builder.build().requires();
1101        Iterator<ModuleDescriptor.Requires> iterator = requires.iterator();
1102        ModuleDescriptor.Requires r = iterator.next();
1103        if (r.name().equals("java.base")) {
1104            r = iterator.next();
1105        }
1106        return r;
1107    }
1108
1109    private boolean isParsableVersion(String vs) {
1110        try {
1111            Version.parse(vs);
1112            return true;
1113        } catch (IllegalArgumentException e) {
1114            return false;
1115        }
1116    }
1117
1118
1119    // toNameAndVersion
1120
1121    public void testToNameAndVersion() {
1122        ModuleDescriptor md1 = ModuleDescriptor.newModule("foo").build();
1123        assertEquals(md1.toNameAndVersion(), "foo");
1124
1125        ModuleDescriptor md2 = ModuleDescriptor.newModule("foo").version("1.0").build();
1126        assertEquals(md2.toNameAndVersion(), "foo@1.0");
1127    }
1128
1129
1130    // open modules
1131
1132    public void testOpenModule() {
1133        ModuleDescriptor descriptor = ModuleDescriptor.newOpenModule("foo")
1134                .requires("bar")
1135                .exports("p")
1136                .provides("p.Service", List.of("q.ServiceImpl"))
1137                .build();
1138
1139        // modifiers
1140        assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.OPEN));
1141        assertTrue(descriptor.isOpen());
1142
1143        // requires
1144        assertTrue(descriptor.requires().size() == 2);
1145        Set<String> names = descriptor.requires()
1146                .stream()
1147                .map(Requires::name)
1148                .collect(Collectors.toSet());
1149        assertEquals(names, Set.of("bar", "java.base"));
1150
1151        // packages
1152        assertEquals(descriptor.packages(), Set.of("p", "q"));
1153
1154        // exports
1155        assertTrue(descriptor.exports().size() == 1);
1156        names = descriptor.exports()
1157                .stream()
1158                .map(Exports::source)
1159                .collect(Collectors.toSet());
1160        assertEquals(names, Set.of("p"));
1161
1162        // opens
1163        assertTrue(descriptor.opens().isEmpty());
1164    }
1165
1166    @Test(expectedExceptions = IllegalStateException.class)
1167    public void testOpensOnOpenModule1() {
1168        ModuleDescriptor.newOpenModule("foo").opens("p");
1169    }
1170
1171    @Test(expectedExceptions = IllegalStateException.class)
1172    public void testOpensOnOpenModule2() {
1173        ModuleDescriptor.newOpenModule("foo").opens("p", Set.of("bar"));
1174    }
1175
1176    public void testIsOpen() {
1177        assertFalse(ModuleDescriptor.newModule("m").build().isOpen());
1178        assertFalse(ModuleDescriptor.newAutomaticModule("m").build().isOpen());
1179        assertTrue(ModuleDescriptor.newOpenModule("m").build().isOpen());
1180    }
1181
1182
1183    // automatic modules
1184
1185    public void testAutomaticModule() {
1186        ModuleDescriptor descriptor = ModuleDescriptor.newAutomaticModule("foo")
1187                .packages(Set.of("p"))
1188                .provides("p.Service", List.of("q.ServiceImpl"))
1189                .build();
1190
1191        // modifiers
1192        assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.AUTOMATIC));
1193        assertTrue(descriptor.isAutomatic());
1194
1195        // requires
1196        assertTrue(descriptor.requires().size() == 1);
1197        Set<String> names = descriptor.requires()
1198                .stream()
1199                .map(Requires::name)
1200                .collect(Collectors.toSet());
1201        assertEquals(names, Set.of("java.base"));
1202
1203        // packages
1204        assertEquals(descriptor.packages(), Set.of("p", "q"));
1205        assertTrue(descriptor.exports().isEmpty());
1206        assertTrue(descriptor.opens().isEmpty());
1207    }
1208
1209    @Test(expectedExceptions = IllegalStateException.class)
1210    public void testRequiresOnAutomaticModule() {
1211        ModuleDescriptor.newAutomaticModule("foo").requires("java.base");
1212    }
1213
1214    @Test(expectedExceptions = IllegalStateException.class)
1215    public void testExportsOnAutomaticModule1() {
1216        ModuleDescriptor.newAutomaticModule("foo").exports("p");
1217    }
1218
1219    @Test(expectedExceptions = IllegalStateException.class)
1220    public void testExportsOnAutomaticModule2() {
1221        ModuleDescriptor.newAutomaticModule("foo").exports("p", Set.of("bar"));
1222    }
1223
1224    @Test(expectedExceptions = IllegalStateException.class)
1225    public void testOpensOnAutomaticModule1() {
1226        ModuleDescriptor.newAutomaticModule("foo").opens("p");
1227    }
1228
1229    @Test(expectedExceptions = IllegalStateException.class)
1230    public void testOpensOnAutomaticModule2() {
1231        ModuleDescriptor.newAutomaticModule("foo").opens("p", Set.of("bar"));
1232    }
1233
1234    @Test(expectedExceptions = IllegalStateException.class)
1235    public void testUsesOnAutomaticModule() {
1236        ModuleDescriptor.newAutomaticModule("foo").uses("p.Service");
1237    }
1238
1239    public void testIsAutomatic() {
1240        ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("foo").build();
1241        assertFalse(descriptor1.isAutomatic());
1242
1243        ModuleDescriptor descriptor2 = ModuleDescriptor.newOpenModule("foo").build();
1244        assertFalse(descriptor2.isAutomatic());
1245
1246        ModuleDescriptor descriptor3 = ModuleDescriptor.newAutomaticModule("foo").build();
1247        assertTrue(descriptor3.isAutomatic());
1248    }
1249
1250
1251    // newModule with modifiers
1252
1253    public void testNewModuleToBuildAutomaticModule() {
1254        Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC);
1255        ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build();
1256        assertTrue(descriptor.modifiers().equals(ms));
1257        assertTrue(descriptor.isAutomatic());
1258    }
1259
1260    public void testNewModuleToBuildOpenModule() {
1261        Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.OPEN);
1262        ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build();
1263        assertTrue(descriptor.modifiers().equals(ms));
1264        assertTrue(descriptor.isOpen());
1265
1266        ms = Set.of(ModuleDescriptor.Modifier.OPEN, ModuleDescriptor.Modifier.SYNTHETIC);
1267        descriptor = ModuleDescriptor.newModule("foo", ms).build();
1268        assertTrue(descriptor.modifiers().equals(ms));
1269        assertTrue(descriptor.isOpen());
1270    }
1271
1272    @Test(expectedExceptions = IllegalArgumentException.class)
1273    public void testNewModuleToBuildAutomaticAndOpenModule() {
1274        Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC,
1275                                                   ModuleDescriptor.Modifier.OPEN);
1276        ModuleDescriptor.newModule("foo", ms);
1277    }
1278
1279
1280    // mainClass
1281
1282    public void testMainClass() {
1283        String mainClass
1284            = ModuleDescriptor.newModule("foo").mainClass("p.Main").build().mainClass().get();
1285        assertEquals(mainClass, "p.Main");
1286    }
1287
1288    @Test(expectedExceptions = IllegalArgumentException.class)
1289    public void testMainClassWithSimpleIdentifier() {
1290        ModuleDescriptor.newModule("foo").mainClass("Main");
1291    }
1292
1293    @Test(dataProvider = "invalidNames",
1294          expectedExceptions = IllegalArgumentException.class )
1295    public void testMainClassWithBadName(String mainClass, String ignore) {
1296        Builder builder = ModuleDescriptor.newModule("foo");
1297        builder.mainClass(mainClass);
1298    }
1299
1300
1301    // reads
1302
1303    private static InputStream EMPTY_INPUT_STREAM = new InputStream() {
1304        @Override
1305        public int read() {
1306            return -1;
1307        }
1308    };
1309
1310    private static InputStream FAILING_INPUT_STREAM = new InputStream() {
1311        @Override
1312        public int read() throws IOException {
1313            throw new IOException();
1314        }
1315    };
1316
1317    /**
1318     * Basic test reading module-info.class
1319     */
1320    public void testRead() throws Exception {
1321        Module base = Object.class.getModule();
1322
1323        try (InputStream in = base.getResourceAsStream("module-info.class")) {
1324            ModuleDescriptor descriptor = ModuleDescriptor.read(in);
1325            assertTrue(in.read() == -1); // all bytes read
1326            assertEquals(descriptor.name(), "java.base");
1327        }
1328
1329        try (InputStream in = base.getResourceAsStream("module-info.class")) {
1330            ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes());
1331            ModuleDescriptor descriptor = ModuleDescriptor.read(bb);
1332            assertFalse(bb.hasRemaining()); // no more remaining bytes
1333            assertEquals(descriptor.name(), "java.base");
1334        }
1335    }
1336
1337    /**
1338     * Test ModuleDescriptor with a packager finder
1339     */
1340    public void testReadsWithPackageFinder() throws Exception {
1341        ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
1342                .requires("java.base")
1343                .build();
1344
1345        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1346        ModuleInfoWriter.write(descriptor, baos);
1347        ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
1348
1349        descriptor = ModuleDescriptor.read(bb, () -> Set.of("p", "q"));
1350
1351        assertTrue(descriptor.packages().size() == 2);
1352        assertTrue(descriptor.packages().contains("p"));
1353        assertTrue(descriptor.packages().contains("q"));
1354    }
1355
1356    /**
1357     * Test ModuleDescriptor with a packager finder that doesn't return the
1358     * complete set of packages.
1359     */
1360    @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1361    public void testReadsWithBadPackageFinder() throws Exception {
1362        ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
1363                .requires("java.base")
1364                .exports("p")
1365                .build();
1366
1367        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1368        ModuleInfoWriter.write(descriptor, baos);
1369        ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
1370
1371        // package finder returns a set that doesn't include p
1372        ModuleDescriptor.read(bb, () -> Set.of("q"));
1373    }
1374
1375    @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1376    public void testReadFromEmptyInputStream() throws Exception {
1377        ModuleDescriptor.read(EMPTY_INPUT_STREAM);
1378    }
1379
1380    @Test(expectedExceptions = IOException.class)
1381    public void testReadFromFailingInputStream() throws Exception {
1382        ModuleDescriptor.read(FAILING_INPUT_STREAM);
1383    }
1384
1385    @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1386    public void testReadFromEmptyBuffer() {
1387        ByteBuffer bb = ByteBuffer.allocate(0);
1388        ModuleDescriptor.read(bb);
1389    }
1390
1391    // The requires table for java.base must be 0 length
1392    @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1393    public void testReadOfJavaBaseWithRequires() {
1394        ModuleDescriptor descriptor
1395            = ModuleDescriptor.newModule("java.base")
1396                .requires("other")
1397                .build();
1398        ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1399        ModuleDescriptor.read(bb);
1400    }
1401
1402    // The requires table must have an entry for java.base
1403    @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1404    public void testReadWithEmptyRequires() {
1405        ModuleDescriptor descriptor = SharedSecrets.getJavaLangModuleAccess()
1406                .newModuleBuilder("m1", false, Set.of()).build();
1407        ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1408        ModuleDescriptor.read(bb);
1409    }
1410
1411    // The requires table must have an entry for java.base
1412    @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1413    public void testReadWithNoRequiresBase() {
1414        ModuleDescriptor descriptor = SharedSecrets.getJavaLangModuleAccess()
1415                .newModuleBuilder("m1", false, Set.of()).requires("m2").build();
1416        ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1417        ModuleDescriptor.read(bb);
1418    }
1419
1420    public void testReadWithNull() throws Exception {
1421        Module base = Object.class.getModule();
1422
1423        try {
1424            ModuleDescriptor.read((InputStream)null);
1425            assertTrue(false);
1426        } catch (NullPointerException expected) { }
1427
1428
1429        try (InputStream in = base.getResourceAsStream("module-info.class")) {
1430            try {
1431                ModuleDescriptor.read(in, null);
1432                assertTrue(false);
1433            } catch (NullPointerException expected) { }
1434        }
1435
1436        try {
1437            ModuleDescriptor.read((ByteBuffer)null);
1438            assertTrue(false);
1439        } catch (NullPointerException expected) { }
1440
1441
1442        try (InputStream in = base.getResourceAsStream("module-info.class")) {
1443            ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes());
1444            try {
1445                ModuleDescriptor.read(bb, null);
1446                assertTrue(false);
1447            } catch (NullPointerException expected) { }
1448        }
1449    }
1450
1451
1452    // equals/hashCode/compareTo/toString
1453
1454    public void testEqualsAndHashCode() {
1455        ModuleDescriptor md1 = ModuleDescriptor.newModule("m").build();
1456        ModuleDescriptor md2 = ModuleDescriptor.newModule("m").build();
1457        assertEquals(md1, md1);
1458        assertEquals(md1.hashCode(), md2.hashCode());
1459        assertTrue(md1.compareTo(md2) == 0);
1460        assertTrue(md2.compareTo(md1) == 0);
1461    }
1462
1463    @DataProvider(name = "sortedModuleDescriptors")
1464    public Object[][] sortedModuleDescriptors() {
1465        return new Object[][]{
1466
1467            { ModuleDescriptor.newModule("m2").build(),
1468              ModuleDescriptor.newModule("m1").build()
1469            },
1470
1471            { ModuleDescriptor.newModule("m").version("2").build(),
1472              ModuleDescriptor.newModule("m").version("1").build()
1473            },
1474
1475            { ModuleDescriptor.newModule("m").version("1").build(),
1476              ModuleDescriptor.newModule("m").build()
1477            },
1478
1479            { ModuleDescriptor.newOpenModule("m").build(),
1480              ModuleDescriptor.newModule("m").build()
1481            },
1482
1483        };
1484    }
1485
1486    @Test(dataProvider = "sortedModuleDescriptors")
1487    public void testCompare(ModuleDescriptor md1, ModuleDescriptor md2) {
1488        assertNotEquals(md1, md2);
1489        assertTrue(md1.compareTo(md2) == 1);
1490        assertTrue(md2.compareTo(md1) == -1);
1491    }
1492
1493    public void testToString() {
1494        String s = ModuleDescriptor.newModule("m1")
1495                .requires("m2")
1496                .exports("p1")
1497                .build()
1498                .toString();
1499        assertTrue(s.contains("m1"));
1500        assertTrue(s.contains("m2"));
1501        assertTrue(s.contains("p1"));
1502    }
1503
1504}
1505