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