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 
  32 import java.io.ByteArrayOutputStream;
  33 import java.io.IOException;
  34 import java.io.InputStream;
  35 import java.lang.module.InvalidModuleDescriptorException;
  36 import java.lang.module.ModuleDescriptor;
  37 import java.lang.module.ModuleDescriptor.Builder;
  38 import java.lang.module.ModuleDescriptor.Exports;
  39 import java.lang.module.ModuleDescriptor.Opens;
  40 import java.lang.module.ModuleDescriptor.Requires;
  41 import java.lang.module.ModuleDescriptor.Provides;
  42 import java.lang.module.ModuleDescriptor.Requires.Modifier;
  43 import java.lang.module.ModuleDescriptor.Version;
  44 import java.nio.ByteBuffer;
  45 import java.util.ArrayList;
  46 import java.util.Collections;
  47 import java.util.EnumSet;
  48 import java.util.HashSet;
  49 import java.util.Iterator;
  50 import java.util.List;
  51 import java.util.Objects;
  52 import java.util.Optional;
  53 import java.util.Set;
  54 import java.util.stream.Collectors;
  55 
  56 import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
  57 
  58 import jdk.internal.misc.JavaLangModuleAccess;
  59 import jdk.internal.misc.SharedSecrets;
  60 import jdk.internal.module.ModuleInfoWriter;
  61 import org.testng.annotations.DataProvider;
  62 import org.testng.annotations.Test;
  63 import static org.testng.Assert.*;
  64 
  65 @Test
  66 public 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 }