1 /*
   2  * Copyright (c) 2013, 2016, 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  * @run testng ModuleDescriptorTest
  28  * @summary Basic test for java.lang.module.ModuleDescriptor and its builder
  29  */
  30 
  31 import java.io.ByteArrayOutputStream;
  32 import java.io.IOException;
  33 import java.io.InputStream;
  34 import java.lang.module.InvalidModuleDescriptorException;
  35 import java.lang.module.ModuleDescriptor;
  36 import java.lang.module.ModuleDescriptor.Builder;
  37 import java.lang.module.ModuleDescriptor.Exports;
  38 import java.lang.module.ModuleDescriptor.Opens;
  39 import java.lang.module.ModuleDescriptor.Requires;
  40 import java.lang.module.ModuleDescriptor.Provides;
  41 import java.lang.module.ModuleDescriptor.Requires.Modifier;
  42 import java.lang.module.ModuleDescriptor.Version;
  43 import java.lang.reflect.Module;
  44 import java.nio.ByteBuffer;
  45 import java.util.Collections;
  46 import java.util.EnumSet;
  47 import java.util.HashSet;
  48 import java.util.List;
  49 import java.util.Set;
  50 
  51 import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
  52 
  53 import jdk.internal.module.ModuleInfoWriter;
  54 import org.testng.annotations.DataProvider;
  55 import org.testng.annotations.Test;
  56 import static org.testng.Assert.*;
  57 
  58 @Test
  59 public class ModuleDescriptorTest {
  60 
  61     @DataProvider(name = "invalidjavaidentifiers")
  62     public Object[][] invalidJavaIdentifiers() {
  63         return new Object[][]{
  64 
  65             { null,             null },
  66             { "1",              null },
  67             { "1foo",           null },
  68             { ".foo",           null },
  69             { "foo.",           null },
  70             { "[foo]",          null },
  71             { "foo.1",          null },
  72             { "1foo.bar",       null },
  73             { "foo.1bar",       null },
  74             { "foo.[bar]",      null },
  75             { "foo..bar",       null },
  76             { "foo.bar.1",      null },
  77             { "foo.bar.1gus",   null },
  78             { "foo.bar.[gus]",  null },
  79 
  80         };
  81     }
  82 
  83 
  84     // requires
  85 
  86     private Requires requires(Set<Modifier> mods, String mn) {
  87         return ModuleDescriptor.module("m")
  88             .requires(mods, mn)
  89             .build()
  90             .requires()
  91             .iterator()
  92             .next();
  93     }
  94 
  95     private Requires requires(Set<Modifier> mods, String mn, Version v) {
  96         return ModuleDescriptor.module("m")
  97             .requires(mods, mn, v)
  98             .build()
  99             .requires()
 100             .iterator()
 101             .next();
 102     }
 103 
 104     private Requires requires(String mn) {
 105         return requires(Collections.emptySet(), mn);
 106     }
 107 
 108     public void testRequiresWithRequires() {
 109         Requires r1 = requires("foo");
 110         ModuleDescriptor descriptor = ModuleDescriptor.module("m").requires(r1).build();
 111         Requires r2 = descriptor.requires().iterator().next();
 112         assertEquals(r1, r2);
 113     }
 114 
 115     public void testRequiresWithNoModifiers() {
 116         Requires r = requires(EnumSet.noneOf(Requires.Modifier.class), "foo");
 117         assertEquals(r, r);
 118         assertTrue(r.compareTo(r) == 0);
 119         assertTrue(r.modifiers().isEmpty());
 120         assertEquals(r.name(), "foo");
 121         assertFalse(r.compiledVersion().isPresent());
 122     }
 123 
 124     public void testRequiresWithOneModifier() {
 125         Requires r = requires(EnumSet.of(TRANSITIVE), "foo");
 126         assertEquals(r, r);
 127         assertTrue(r.compareTo(r) == 0);
 128         assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE));
 129         assertEquals(r.name(), "foo");
 130         assertFalse(r.compiledVersion().isPresent());
 131     }
 132 
 133     public void testRequiresWithTwoModifiers() {
 134         Requires r = requires(EnumSet.of(TRANSITIVE, SYNTHETIC), "foo");
 135         assertEquals(r, r);
 136         assertTrue(r.compareTo(r) == 0);
 137         assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, SYNTHETIC));
 138         assertEquals(r.name(), "foo");
 139         assertFalse(r.compiledVersion().isPresent());
 140     }
 141 
 142     public void testRequiresWithAllModifiers() {
 143         Requires r = requires(EnumSet.allOf(Modifier.class), "foo");
 144         assertEquals(r, r);
 145         assertTrue(r.compareTo(r) == 0);
 146         assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, STATIC, SYNTHETIC, MANDATED));
 147         assertEquals(r.name(), "foo");
 148         assertFalse(r.compiledVersion().isPresent());
 149     }
 150 
 151     public void testRequiresWithCompiledVersion() {
 152         Version v = Version.parse("1.0");
 153         Requires r = requires(Set.of(), "foo", v);
 154         assertEquals(r, r);
 155         assertTrue(r.compareTo(r) == 0);
 156         assertEquals(r.modifiers(), Set.of());
 157         assertEquals(r.name(), "foo");
 158         assertTrue(r.compiledVersion().isPresent());
 159         assertEquals(r.compiledVersion().get().toString(), "1.0");
 160     }
 161 
 162     @Test(expectedExceptions = IllegalStateException.class)
 163     public void testRequiresWithDuplicatesRequires() {
 164         Requires r = requires("foo");
 165         ModuleDescriptor.module("m").requires(r).requires(r);
 166     }
 167 
 168     @Test(expectedExceptions = IllegalArgumentException.class)
 169     public void testRequiresSelfWithRequires() {
 170         Requires r = requires("foo");
 171         ModuleDescriptor.module("foo").requires(r);
 172     }
 173 
 174     @Test(expectedExceptions = IllegalArgumentException.class)
 175     public void testRequiresSelfWithNoModifier() {
 176         ModuleDescriptor.module("m").requires("m");
 177     }
 178 
 179     @Test(expectedExceptions = IllegalArgumentException.class)
 180     public void testRequiresSelfWithOneModifier() {
 181         ModuleDescriptor.module("m").requires(Set.of(TRANSITIVE), "m");
 182     }
 183 
 184     @Test(expectedExceptions = IllegalArgumentException.class)
 185     public void testRequiresSelfWithAllModifiers() {
 186         ModuleDescriptor.module("m").requires(EnumSet.allOf(Modifier.class), "m");
 187     }
 188 
 189     @Test(dataProvider = "invalidjavaidentifiers",
 190           expectedExceptions = IllegalArgumentException.class )
 191     public void testRequiresWithBadModuleName(String mn, String ignore) {
 192         requires(EnumSet.noneOf(Modifier.class), mn);
 193     }
 194 
 195     @Test(expectedExceptions = NullPointerException.class)
 196     public void testRequiresWithNullRequires() {
 197         ModuleDescriptor.module("m").requires((Requires) null);
 198     }
 199 
 200     @Test(expectedExceptions = NullPointerException.class)
 201     public void testRequiresWithNullModifiers() {
 202         ModuleDescriptor.module("m").requires(null, "foo");
 203     }
 204 
 205     @Test(expectedExceptions = NullPointerException.class)
 206     public void testRequiresWithNullVersion() {
 207         ModuleDescriptor.module("m").requires(Set.of(), "foo", null);
 208     }
 209 
 210     public void testRequiresCompare() {
 211         Requires r1 = requires(EnumSet.noneOf(Modifier.class), "foo");
 212         Requires r2 = requires(EnumSet.noneOf(Modifier.class), "bar");
 213         int n = "foo".compareTo("bar");
 214         assertTrue(r1.compareTo(r2) == n);
 215         assertTrue(r2.compareTo(r1) == -n);
 216     }
 217 
 218     public void testRequiresCompareWithDifferentModifiers() {
 219         Requires r1 = requires(EnumSet.of(TRANSITIVE), "foo");
 220         Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo");
 221         int n = Integer.compare(1 << TRANSITIVE.ordinal(), 1 << SYNTHETIC.ordinal());
 222         assertTrue(r1.compareTo(r2) == n);
 223         assertTrue(r2.compareTo(r1) == -n);
 224     }
 225 
 226     public void testRequiresCompareWithSameModifiers() {
 227         Requires r1 = requires(EnumSet.of(SYNTHETIC), "foo");
 228         Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo");
 229         assertTrue(r1.compareTo(r2) == 0);
 230         assertTrue(r2.compareTo(r1) == 0);
 231     }
 232 
 233     public void testRequiresCompareWithSameCompiledVersion() {
 234         Requires r1 = requires(Set.of(), "foo", Version.parse("2.0"));
 235         Requires r2 = requires(Set.of(), "foo", Version.parse("2.0"));
 236         assertTrue(r1.compareTo(r2) == 0);
 237         assertTrue(r2.compareTo(r1) == 0);
 238     }
 239 
 240     public void testRequiresCompareWithDifferentCompiledVersion() {
 241         Requires r1 = requires(Set.of(), "foo", Version.parse("1.0"));
 242         Requires r2 = requires(Set.of(), "foo", Version.parse("2.0"));
 243         assertTrue(r1.compareTo(r2) < 0);
 244         assertTrue(r2.compareTo(r1) > 0);
 245     }
 246 
 247     public void testRequiresEqualsAndHashCode() {
 248         Requires r1 = requires("foo");
 249         Requires r2 = requires("foo");
 250         assertEquals(r1, r2);
 251         assertTrue(r1.hashCode() == r2.hashCode());
 252 
 253         r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
 254         r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
 255         assertEquals(r1, r2);
 256         assertTrue(r1.hashCode() == r2.hashCode());
 257 
 258         r1 = requires("foo");
 259         r2 = requires("bar");
 260         assertNotEquals(r1, r2);
 261 
 262         r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
 263         r2 = requires(Set.of(), "foo");
 264         assertNotEquals(r1, r2);
 265 
 266         Version v1 = Version.parse("1.0");
 267         r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
 268         r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
 269         assertEquals(r1, r2);
 270         assertTrue(r1.hashCode() == r2.hashCode());
 271 
 272         Version v2 = Version.parse("2.0");
 273         r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1);
 274         r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v2);
 275         assertNotEquals(r1, r2);
 276     }
 277 
 278     public void testRequiresToString() {
 279         Requires r = requires(EnumSet.noneOf(Modifier.class), "foo");
 280         assertTrue(r.toString().contains("foo"));
 281     }
 282 
 283 
 284     // exports
 285 
 286     private Exports exports(Set<Exports.Modifier> mods, String pn) {
 287         return ModuleDescriptor.module("foo")
 288             .exports(mods, pn)
 289             .build()
 290             .exports()
 291             .iterator()
 292             .next();
 293     }
 294 
 295     private Exports exports(String pn) {
 296         return exports(Set.of(), pn);
 297     }
 298 
 299     private Exports exports(Set<Exports.Modifier> mods, String pn, String target) {
 300         return ModuleDescriptor.module("foo")
 301             .exports(mods, pn, Set.of(target))
 302             .build()
 303             .exports()
 304             .iterator()
 305             .next();
 306     }
 307 
 308     private Exports exports(String pn, String target) {
 309         return exports(Set.of(), pn, target);
 310     }
 311 
 312 
 313     public void testExportsExports() {
 314         Exports e1 = exports("p");
 315         ModuleDescriptor descriptor = ModuleDescriptor.module("m").exports(e1).build();
 316         Exports e2 = descriptor.exports().iterator().next();
 317         assertEquals(e1, e2);
 318     }
 319 
 320     public void testExportsToAll() {
 321         Exports e = exports("p");
 322         assertEquals(e, e);
 323         assertTrue(e.modifiers().isEmpty());
 324         assertEquals(e.source(), "p");
 325         assertFalse(e.isQualified());
 326         assertTrue(e.targets().isEmpty());
 327     }
 328 
 329     public void testExportsToTarget() {
 330         Exports e = exports("p", "bar");
 331         assertEquals(e, e);
 332         assertTrue(e.modifiers().isEmpty());
 333         assertEquals(e.source(), "p");
 334         assertTrue(e.isQualified());
 335         assertTrue(e.targets().size() == 1);
 336         assertTrue(e.targets().contains("bar"));
 337     }
 338 
 339     public void testExportsToTargets() {
 340         Set<String> targets = new HashSet<>();
 341         targets.add("bar");
 342         targets.add("gus");
 343         Exports e
 344             = ModuleDescriptor.module("foo")
 345                 .exports("p", targets)
 346                 .build()
 347                 .exports()
 348                 .iterator()
 349                 .next();
 350         assertEquals(e, e);
 351         assertTrue(e.modifiers().isEmpty());
 352         assertEquals(e.source(), "p");
 353         assertTrue(e.isQualified());
 354         assertTrue(e.targets().size() == 2);
 355         assertTrue(e.targets().contains("bar"));
 356         assertTrue(e.targets().contains("gus"));
 357     }
 358 
 359     public void testExportsToAllWithModifier() {
 360         Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 361         assertEquals(e, e);
 362         assertTrue(e.modifiers().size() == 1);
 363         assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
 364         assertEquals(e.source(), "p");
 365         assertFalse(e.isQualified());
 366         assertTrue(e.targets().isEmpty());
 367     }
 368 
 369     public void testExportsToTargetWithModifier() {
 370         Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", "bar");
 371         assertEquals(e, e);
 372         assertTrue(e.modifiers().size() == 1);
 373         assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
 374         assertEquals(e.source(), "p");
 375         assertTrue(e.isQualified());
 376         assertTrue(e.targets().size() == 1);
 377         assertTrue(e.targets().contains("bar"));
 378     }
 379 
 380     @Test(expectedExceptions = IllegalStateException.class)
 381     public void testExportsWithDuplicate1() {
 382         Exports e = exports("p");
 383         ModuleDescriptor.module("foo").exports(e).exports(e);
 384     }
 385 
 386     @Test(expectedExceptions = IllegalStateException.class)
 387     public void testExportsWithDuplicate2() {
 388         ModuleDescriptor.module("foo").exports("p").exports("p");
 389     }
 390 
 391     @Test(expectedExceptions = IllegalStateException.class)
 392     public void testExportsOnContainedPackage() {
 393         ModuleDescriptor.module("foo").contains("p").exports("p");
 394     }
 395 
 396     @Test(expectedExceptions = IllegalStateException.class)
 397     public void testExportsToTargetOnContainedPackage() {
 398         ModuleDescriptor.module("foo").contains("p").exports("p", Set.of("bar"));
 399     }
 400 
 401     @Test(expectedExceptions = IllegalArgumentException.class )
 402     public void testExportsWithEmptySet() {
 403         ModuleDescriptor.module("foo").exports("p", Collections.emptySet());
 404     }
 405 
 406     @Test(dataProvider = "invalidjavaidentifiers",
 407           expectedExceptions = IllegalArgumentException.class )
 408     public void testExportsWithBadName(String pn, String ignore) {
 409         ModuleDescriptor.module("foo").exports(pn);
 410     }
 411 
 412     @Test(expectedExceptions = NullPointerException.class )
 413     public void testExportsWithNullExports() {
 414         ModuleDescriptor.module("foo").exports((Exports) null);
 415     }
 416 
 417     @Test(expectedExceptions = NullPointerException.class )
 418     public void testExportsWithNullTargets() {
 419         ModuleDescriptor.module("foo").exports("p", (Set<String>) null);
 420     }
 421 
 422     public void testExportsEqualsAndHashCode() {
 423         Exports e1, e2;
 424 
 425         e1 = exports("p");
 426         e2 = exports("p");
 427         assertEquals(e1, e2);
 428         assertTrue(e1.hashCode() == e2.hashCode());
 429 
 430         e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 431         e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 432         assertEquals(e1, e2);
 433         assertTrue(e1.hashCode() == e2.hashCode());
 434 
 435         e1 = exports("p");
 436         e2 = exports("q");
 437         assertNotEquals(e1, e2);
 438 
 439         e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 440         e2 = exports(Set.of(), "p");
 441         assertNotEquals(e1, e2);
 442     }
 443 
 444     public void testExportsToString() {
 445         String s = ModuleDescriptor.module("foo")
 446             .exports("p1", Set.of("bar"))
 447             .build()
 448             .exports()
 449             .iterator()
 450             .next()
 451             .toString();
 452         assertTrue(s.contains("p1"));
 453         assertTrue(s.contains("bar"));
 454     }
 455 
 456 
 457     // opens
 458 
 459     private Opens opens(Set<Opens.Modifier> mods, String pn) {
 460         return ModuleDescriptor.module("foo")
 461                 .opens(mods, pn)
 462                 .build()
 463                 .opens()
 464                 .iterator()
 465                 .next();
 466     }
 467 
 468     private Opens opens(String pn) {
 469         return opens(Set.of(), pn);
 470     }
 471 
 472     private Opens opens(Set<Opens.Modifier> mods, String pn, String target) {
 473         return ModuleDescriptor.module("foo")
 474                 .opens(mods, pn, Set.of(target))
 475                 .build()
 476                 .opens()
 477                 .iterator()
 478                 .next();
 479     }
 480 
 481     private Opens opens(String pn, String target) {
 482         return opens(Set.of(), pn, target);
 483     }
 484 
 485     public void testOpensOpens() {
 486         Opens o1 = opens("p");
 487         ModuleDescriptor descriptor = ModuleDescriptor.module("m").opens(o1).build();
 488         Opens o2 = descriptor.opens().iterator().next();
 489         assertEquals(o1, o2);
 490     }
 491 
 492     public void testOpensToAll() {
 493         Opens o = opens("p");
 494         assertEquals(o, o);
 495         assertTrue(o.modifiers().isEmpty());
 496         assertEquals(o.source(), "p");
 497         assertFalse(o.isQualified());
 498         assertTrue(o.targets().isEmpty());
 499     }
 500 
 501 
 502     public void testOpensToTarget() {
 503         Opens o = opens("p", "bar");
 504         assertEquals(o, o);
 505         assertTrue(o.modifiers().isEmpty());
 506         assertEquals(o.source(), "p");
 507         assertTrue(o.isQualified());
 508         assertTrue(o.targets().size() == 1);
 509         assertTrue(o.targets().contains("bar"));
 510     }
 511 
 512     public void testOpensToTargets() {
 513         Set<String> targets = new HashSet<>();
 514         targets.add("bar");
 515         targets.add("gus");
 516         Opens o = ModuleDescriptor.module("foo")
 517                 .opens("p", targets)
 518                 .build()
 519                 .opens()
 520                 .iterator()
 521                 .next();
 522         assertEquals(o, o);
 523         assertTrue(o.modifiers().isEmpty());
 524         assertEquals(o.source(), "p");
 525         assertTrue(o.isQualified());
 526         assertTrue(o.targets().size() == 2);
 527         assertTrue(o.targets().contains("bar"));
 528         assertTrue(o.targets().contains("gus"));
 529     }
 530 
 531     /*
 532 
 533     public void testOpensToAllWithModifier() {
 534         Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 535         assertEquals(e, e);
 536         assertTrue(e.modifiers().size() == 1);
 537         assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
 538         assertEquals(e.source(), "p");
 539         assertFalse(e.isQualified());
 540         assertTrue(e.targets().isEmpty());
 541     }
 542 
 543     public void testOpensToTargetWithModifier() {
 544         Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", Set.of("bar"));
 545         assertEquals(e, e);
 546         assertTrue(e.modifiers().size() == 1);
 547         assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
 548         assertEquals(e.source(), "p");
 549         assertTrue(e.isQualified());
 550         assertTrue(e.targets().size() == 1);
 551         assertTrue(e.targets().contains("bar"));
 552     }
 553 
 554 
 555     */
 556 
 557     @Test(expectedExceptions = IllegalStateException.class)
 558     public void testOpensWithDuplicate1() {
 559         Opens o = opens("p");
 560         ModuleDescriptor.module("foo").opens(o).opens(o);
 561     }
 562 
 563     @Test(expectedExceptions = IllegalStateException.class)
 564     public void testOpensWithDuplicate2() {
 565         ModuleDescriptor.module("foo").opens("p").opens("p");
 566     }
 567 
 568     @Test(expectedExceptions = IllegalStateException.class)
 569     public void testOpensOnContainedPackage() {
 570         ModuleDescriptor.module("foo").contains("p").opens("p");
 571     }
 572 
 573     @Test(expectedExceptions = IllegalStateException.class)
 574     public void testOpensToTargetOnContainedPackage() {
 575         ModuleDescriptor.module("foo").contains("p").opens("p", Set.of("bar"));
 576     }
 577 
 578     @Test(expectedExceptions = IllegalArgumentException.class )
 579     public void testOpensWithEmptySet() {
 580         ModuleDescriptor.module("foo").opens("p", Collections.emptySet());
 581     }
 582 
 583     @Test(dataProvider = "invalidjavaidentifiers",
 584             expectedExceptions = IllegalArgumentException.class )
 585     public void testOpensWithBadName(String pn, String ignore) {
 586         ModuleDescriptor.module("foo").opens(pn);
 587     }
 588 
 589     @Test(expectedExceptions = NullPointerException.class )
 590     public void testOpensWithNullExports() {
 591         ModuleDescriptor.module("foo").opens((Opens) null);
 592     }
 593 
 594     @Test(expectedExceptions = NullPointerException.class )
 595     public void testOpensWithNullTargets() {
 596         ModuleDescriptor.module("foo").opens("p", (Set<String>) null);
 597     }
 598 
 599     public void testOpensEqualsAndHashCode() {
 600         Opens o1, o2;
 601 
 602         o1 = opens("p");
 603         o2 = opens("p");
 604         assertEquals(o1, o2);
 605         assertTrue(o1.hashCode() == o1.hashCode());
 606 
 607         o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
 608         o2 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
 609         assertEquals(o1, o2);
 610         assertTrue(o1.hashCode() == o2.hashCode());
 611 
 612         o1 = opens("p");
 613         o2 = opens("q");
 614         assertNotEquals(o1, o2);
 615 
 616         o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
 617         o2 = opens(Set.of(), "p");
 618         assertNotEquals(o1, o2);
 619     }
 620 
 621     public void testOpensToString() {
 622         String s = ModuleDescriptor.module("foo")
 623                 .opens("p1", Set.of("bar"))
 624                 .build()
 625                 .opens()
 626                 .iterator()
 627                 .next()
 628                 .toString();
 629         assertTrue(s.contains("p1"));
 630         assertTrue(s.contains("bar"));
 631     }
 632 
 633 
 634     // uses
 635 
 636     public void testUses() {
 637         Set<String> uses
 638             = ModuleDescriptor.module("foo")
 639                 .uses("p.S")
 640                 .uses("q.S")
 641                 .build()
 642                 .uses();
 643         assertTrue(uses.size() == 2);
 644         assertTrue(uses.contains("p.S"));
 645         assertTrue(uses.contains("q.S"));
 646     }
 647 
 648     @Test(expectedExceptions = IllegalStateException.class)
 649     public void testUsesWithDuplicate() {
 650         ModuleDescriptor.module("foo").uses("p.S").uses("p.S");
 651     }
 652 
 653     @Test(dataProvider = "invalidjavaidentifiers",
 654           expectedExceptions = IllegalArgumentException.class )
 655     public void testUsesWithBadName(String service, String ignore) {
 656         ModuleDescriptor.module("foo").uses(service);
 657     }
 658 
 659 
 660     // provides
 661 
 662     private Provides provides(String st, String pc) {
 663         return ModuleDescriptor.module("foo")
 664             .provides(st, pc)
 665             .build()
 666             .provides()
 667             .iterator()
 668             .next();
 669     }
 670 
 671     public void testProvidesWithProvides() {
 672         Provides p1 = provides("p.S", "q.S1");
 673         ModuleDescriptor descriptor = ModuleDescriptor.module("m")
 674                 .provides(p1)
 675                 .build();
 676         Provides p2 = descriptor.provides().iterator().next();
 677         assertEquals(p1, p2);
 678     }
 679 
 680 
 681     public void testProvides() {
 682         Set<Provides> set = ModuleDescriptor.module("foo")
 683                 .provides("p.S", List.of("q.P1", "q.P2"))
 684                 .build()
 685                 .provides();
 686         assertTrue(set.size() == 1);
 687 
 688         Provides p = set.iterator().next();
 689         assertEquals(p, p);
 690         assertEquals(p.service(), "p.S");
 691         assertTrue(p.providers().size() == 2);
 692         assertEquals(p.providers().get(0), "q.P1");
 693         assertEquals(p.providers().get(1), "q.P2");
 694     }
 695 
 696     @Test(expectedExceptions = IllegalStateException.class )
 697     public void testProvidesWithDuplicateProvides() {
 698         Provides p = provides("p.S", "q.S2");
 699         ModuleDescriptor.module("m").provides("p.S", "q.S1").provides(p);
 700     }
 701 
 702     @Test(expectedExceptions = IllegalArgumentException.class )
 703     public void testProvidesWithEmptySet() {
 704         ModuleDescriptor.module("foo").provides("p.Service", Collections.emptyList());
 705     }
 706 
 707     @Test(dataProvider = "invalidjavaidentifiers",
 708           expectedExceptions = IllegalArgumentException.class )
 709     public void testProvidesWithBadService(String service, String ignore) {
 710         ModuleDescriptor.module("foo").provides(service, "p.Provider");
 711     }
 712 
 713     @Test(dataProvider = "invalidjavaidentifiers",
 714           expectedExceptions = IllegalArgumentException.class )
 715     public void testProvidesWithBadProvider(String provider, String ignore) {
 716         ModuleDescriptor.module("foo").provides("p.Service", provider);
 717     }
 718 
 719     @Test(expectedExceptions = NullPointerException.class )
 720     public void testProvidesWithNullProvides() {
 721         ModuleDescriptor.module("foo").provides((Provides) null);
 722     }
 723 
 724     @Test(expectedExceptions = NullPointerException.class )
 725     public void testProvidesWithNullProviders() {
 726         ModuleDescriptor.module("foo").provides("p.S", (List<String>) null);
 727     }
 728 
 729     public void testProvidesEqualsAndHashCode() {
 730         Provides p1, p2;
 731 
 732         p1 = provides("p.S", "q.S1");
 733         p2 = provides("p.S", "q.S1");
 734         assertEquals(p1, p2);
 735         assertTrue(p1.hashCode() == p2.hashCode());
 736 
 737         p1 = provides("p.S", "q.S1");
 738         p2 = provides("p.S", "q.S2");
 739         assertNotEquals(p1, p2);
 740 
 741         p1 = provides("p.S", "q.S1");
 742         p2 = provides("p.S2", "q.S1");
 743         assertNotEquals(p1, p2);
 744     }
 745 
 746     // contains
 747 
 748     public void testContains() {
 749         Set<String> packages = ModuleDescriptor.module("foo")
 750                 .contains("p")
 751                 .contains("q")
 752                 .build()
 753                 .packages();
 754         assertTrue(packages.size() == 2);
 755         assertTrue(packages.contains("p"));
 756         assertTrue(packages.contains("q"));
 757     }
 758 
 759     public void testContainsWithEmptySet() {
 760         Set<String> packages = ModuleDescriptor.module("foo")
 761                 .contains(Collections.emptySet())
 762                 .build()
 763                 .packages();
 764         assertTrue(packages.size() == 0);
 765     }
 766 
 767     @Test(expectedExceptions = IllegalStateException.class)
 768     public void testContainsWithDuplicate() {
 769         ModuleDescriptor.module("foo").contains("p").contains("p");
 770     }
 771 
 772     @Test(expectedExceptions = IllegalStateException.class)
 773     public void testContainsWithExportedPackage() {
 774         ModuleDescriptor.module("foo").exports("p").contains("p");
 775     }
 776 
 777     @Test(dataProvider = "invalidjavaidentifiers",
 778           expectedExceptions = IllegalArgumentException.class )
 779     public void testContainsWithBadName(String pn, String ignore) {
 780         ModuleDescriptor.module("foo").contains(pn);
 781     }
 782 
 783 
 784     // packages
 785 
 786     public void testPackages() {
 787         Set<String> packages = ModuleDescriptor.module("foo")
 788                 .exports("p")
 789                 .contains("q")
 790                 .build()
 791                 .packages();
 792         assertTrue(packages.size() == 2);
 793         assertTrue(packages.contains("p"));
 794         assertTrue(packages.contains("q"));
 795     }
 796 
 797 
 798     // name
 799 
 800     public void testModuleName() {
 801         String mn = ModuleDescriptor.module("foo").build().name();
 802         assertEquals(mn, "foo");
 803     }
 804 
 805     @Test(dataProvider = "invalidjavaidentifiers",
 806           expectedExceptions = IllegalArgumentException.class )
 807     public void testBadModuleName(String mn, String ignore) {
 808         ModuleDescriptor.module(mn);
 809     }
 810 
 811 
 812     // version
 813 
 814     public void testVersion1() {
 815         Version v1 = Version.parse("1.0");
 816         Version v2 = ModuleDescriptor.module("foo")
 817                 .version(v1)
 818                 .build()
 819                 .version()
 820                 .get();
 821         assertEquals(v1, v2);
 822     }
 823 
 824     public void testVersion2() {
 825         String vs = "1.0";
 826         Version v1 = ModuleDescriptor.module("foo")
 827                 .version(vs)
 828                 .build()
 829                 .version()
 830                 .get();
 831         Version v2 = Version.parse(vs);
 832         assertEquals(v1, v2);
 833     }
 834 
 835     @Test(expectedExceptions = NullPointerException.class )
 836     public void testNullVersion1() {
 837         ModuleDescriptor.module("foo").version((Version) null);
 838     }
 839 
 840     @Test(expectedExceptions = IllegalArgumentException.class )
 841     public void testNullVersion2() {
 842         ModuleDescriptor.module("foo").version((String) null);
 843     }
 844 
 845     @Test(expectedExceptions = IllegalArgumentException.class )
 846     public void testEmptyVersion() {
 847         ModuleDescriptor.module("foo").version("");
 848     }
 849 
 850 
 851     // toNameAndVersion
 852 
 853     public void testToNameAndVersion() {
 854         ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
 855         assertEquals(md1.toNameAndVersion(), "foo");
 856 
 857         ModuleDescriptor md2 = ModuleDescriptor.module("foo").version("1.0").build();
 858         assertEquals(md2.toNameAndVersion(), "foo@1.0");
 859     }
 860 
 861 
 862     // open modules
 863 
 864     public void testOpenModules() {
 865         ModuleDescriptor descriptor = ModuleDescriptor.openModule("m")
 866                 .requires("java.base")
 867                 .contains("p")
 868                 .build();
 869         assertTrue(descriptor.isOpen());
 870         assertTrue(descriptor.packages().size() == 1);
 871         assertTrue(descriptor.packages().contains("p"));
 872         assertTrue(descriptor.exports().isEmpty());
 873     }
 874 
 875     @Test(expectedExceptions = IllegalStateException.class)
 876     public void testOpensOnWeakModule1() {
 877         ModuleDescriptor.openModule("foo").opens("p");
 878     }
 879 
 880     @Test(expectedExceptions = IllegalStateException.class)
 881     public void testOpensOnWeakModule2() {
 882         ModuleDescriptor.openModule("foo").opens("p", Set.of("bar"));
 883     }
 884 
 885     public void testIsOpen() {
 886         assertFalse(ModuleDescriptor.module("m").build().isOpen());
 887         assertFalse(ModuleDescriptor.automaticModule("m").build().isOpen());
 888         assertTrue(ModuleDescriptor.openModule("m").build().isOpen());
 889     }
 890 
 891 
 892     // automatic modules
 893 
 894     public void testIsAutomatic() {
 895         ModuleDescriptor descriptor1 = ModuleDescriptor.module("foo").build();
 896         assertFalse(descriptor1.isAutomatic());
 897 
 898         ModuleDescriptor descriptor2 = ModuleDescriptor.openModule("foo").build();
 899         assertFalse(descriptor2.isAutomatic());
 900 
 901         ModuleDescriptor descriptor3 = ModuleDescriptor.automaticModule("foo").build();
 902         assertTrue(descriptor3.isAutomatic());
 903     }
 904 
 905     // isSynthetic
 906     public void testIsSynthetic() {
 907         assertFalse(Object.class.getModule().getDescriptor().isSynthetic());
 908 
 909         ModuleDescriptor descriptor1 = ModuleDescriptor.module("foo").build();
 910         assertFalse(descriptor1.isSynthetic());
 911 
 912         ModuleDescriptor descriptor2 = ModuleDescriptor.openModule("foo").build();
 913         assertFalse(descriptor2.isSynthetic());
 914 
 915         ModuleDescriptor descriptor3 = ModuleDescriptor.automaticModule("foo").build();
 916         assertFalse(descriptor3.isSynthetic());
 917     }
 918 
 919 
 920     // mainClass
 921 
 922     public void testMainClass() {
 923         String mainClass
 924             = ModuleDescriptor.module("foo").mainClass("p.Main").build().mainClass().get();
 925         assertEquals(mainClass, "p.Main");
 926     }
 927 
 928     @Test(dataProvider = "invalidjavaidentifiers",
 929           expectedExceptions = IllegalArgumentException.class )
 930     public void testMainClassWithBadName(String mainClass, String ignore) {
 931         Builder builder = ModuleDescriptor.module("foo");
 932         builder.mainClass(mainClass);
 933     }
 934 
 935 
 936     // osName
 937 
 938     public void testOsName() {
 939         String osName = ModuleDescriptor.module("foo").osName("Linux").build().osName().get();
 940         assertEquals(osName, "Linux");
 941     }
 942 
 943     @Test(expectedExceptions = IllegalArgumentException.class)
 944     public void testNullOsName() {
 945         ModuleDescriptor.module("foo").osName(null);
 946     }
 947 
 948     @Test(expectedExceptions = IllegalArgumentException.class)
 949     public void testEmptyOsName() {
 950         ModuleDescriptor.module("foo").osName("");
 951     }
 952 
 953 
 954     // osArch
 955 
 956     public void testOsArch() {
 957         String osArch = ModuleDescriptor.module("foo").osName("arm").build().osName().get();
 958         assertEquals(osArch, "arm");
 959     }
 960 
 961     @Test(expectedExceptions = IllegalArgumentException.class)
 962     public void testNullOsArch() {
 963         ModuleDescriptor.module("foo").osArch(null);
 964     }
 965 
 966     @Test(expectedExceptions = IllegalArgumentException.class)
 967     public void testEmptyOsArch() {
 968         ModuleDescriptor.module("foo").osArch("");
 969     }
 970 
 971 
 972     // osVersion
 973 
 974     public void testOsVersion() {
 975         String osVersion = ModuleDescriptor.module("foo").osName("11.2").build().osName().get();
 976         assertEquals(osVersion, "11.2");
 977     }
 978 
 979     @Test(expectedExceptions = IllegalArgumentException.class)
 980     public void testNullOsVersion() {
 981         ModuleDescriptor.module("foo").osVersion(null);
 982     }
 983 
 984     @Test(expectedExceptions = IllegalArgumentException.class)
 985     public void testEmptyOsVersion() {
 986         ModuleDescriptor.module("foo").osVersion("");
 987     }
 988 
 989     // reads
 990 
 991     private static InputStream EMPTY_INPUT_STREAM = new InputStream() {
 992         @Override
 993         public int read() {
 994             return -1;
 995         }
 996     };
 997 
 998     private static InputStream FAILING_INPUT_STREAM = new InputStream() {
 999         @Override
1000         public int read() throws IOException {
1001             throw new IOException();
1002         }
1003     };
1004 
1005     // basic test reading module-info.class
1006     public void testRead() throws Exception {
1007         Module base = Object.class.getModule();
1008 
1009         try (InputStream in = base.getResourceAsStream("module-info.class")) {
1010             ModuleDescriptor descriptor = ModuleDescriptor.read(in);
1011             assertTrue(in.read() == -1); // all bytes read
1012             assertEquals(descriptor.name(), "java.base");
1013         }
1014 
1015         try (InputStream in = base.getResourceAsStream("module-info.class")) {
1016             ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes());
1017             ModuleDescriptor descriptor = ModuleDescriptor.read(bb);
1018             assertFalse(bb.hasRemaining()); // no more remaining bytes
1019             assertEquals(descriptor.name(), "java.base");
1020         }
1021     }
1022     /**
1023      * Test ModuleDescriptor with a packager finder
1024      */
1025     public void testReadsWithPackageFinder() throws Exception {
1026         ModuleDescriptor descriptor = ModuleDescriptor.module("foo")
1027                 .requires("java.base")
1028                 .build();
1029 
1030         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1031         ModuleInfoWriter.write(descriptor, baos);
1032         ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
1033 
1034         descriptor = ModuleDescriptor.read(bb, () -> Set.of("p", "q"));
1035 
1036         assertTrue(descriptor.packages().size() == 2);
1037         assertTrue(descriptor.packages().contains("p"));
1038         assertTrue(descriptor.packages().contains("q"));
1039     }
1040 
1041     /**
1042      * Test ModuleDescriptor with a packager finder that doesn't return the
1043      * complete set of packages.
1044      */
1045     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1046     public void testReadsWithBadPackageFinder() throws Exception {
1047         ModuleDescriptor descriptor = ModuleDescriptor.module("foo")
1048                 .requires("java.base")
1049                 .exports("p")
1050                 .build();
1051 
1052         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1053         ModuleInfoWriter.write(descriptor, baos);
1054         ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
1055 
1056         // package finder returns a set that doesn't include p
1057         ModuleDescriptor.read(bb, () -> Set.of("q"));
1058     }
1059 
1060     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1061     public void testReadFromEmptyInputStream() throws Exception {
1062         ModuleDescriptor.read(EMPTY_INPUT_STREAM);
1063     }
1064 
1065     @Test(expectedExceptions = IOException.class)
1066     public void testReadFromFailingInputStream() throws Exception {
1067         ModuleDescriptor.read(FAILING_INPUT_STREAM);
1068     }
1069 
1070     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1071     public void testReadFromEmptyBuffer() {
1072         ByteBuffer bb = ByteBuffer.allocate(0);
1073         ModuleDescriptor.read(bb);
1074     }
1075 
1076     // The requires table for java.base must be 0 length
1077     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1078     public void testReadOfJavaBaseWithRequires() {
1079         ModuleDescriptor descriptor
1080             = ModuleDescriptor.module("java.base")
1081                 .requires("other")
1082                 .build();
1083         ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1084         ModuleDescriptor.read(bb);
1085     }
1086 
1087     // The requires table must have an entry for java.base
1088     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1089     public void testReadWithEmptyRequires() {
1090         ModuleDescriptor descriptor = ModuleDescriptor.module("m1").build();
1091         ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1092         ModuleDescriptor.read(bb);
1093     }
1094 
1095     // The requires table must have an entry for java.base
1096     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1097     public void testReadWithNoRequiresBase() {
1098         ModuleDescriptor descriptor
1099             = ModuleDescriptor.module("m1")
1100                 .requires("m2")
1101                 .build();
1102         ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1103         ModuleDescriptor.read(bb);
1104     }
1105 
1106     public void testReadWithNull() throws Exception {
1107         Module base = Object.class.getModule();
1108 
1109         try {
1110             ModuleDescriptor.read((InputStream)null);
1111             assertTrue(false);
1112         } catch (NullPointerException expected) { }
1113 
1114 
1115         try (InputStream in = base.getResourceAsStream("module-info.class")) {
1116             try {
1117                 ModuleDescriptor.read(in, null);
1118                 assertTrue(false);
1119             } catch (NullPointerException expected) { }
1120         }
1121 
1122         try {
1123             ModuleDescriptor.read((ByteBuffer)null);
1124             assertTrue(false);
1125         } catch (NullPointerException expected) { }
1126 
1127 
1128         try (InputStream in = base.getResourceAsStream("module-info.class")) {
1129             ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes());
1130             try {
1131                 ModuleDescriptor.read(bb, null);
1132                 assertTrue(false);
1133             } catch (NullPointerException expected) { }
1134         }
1135     }
1136 
1137 
1138     // equals/hashCode/compareTo/toString
1139 
1140     public void testEqualsAndHashCode() {
1141         ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
1142         ModuleDescriptor md2 = ModuleDescriptor.module("foo").build();
1143         assertEquals(md1, md1);
1144         assertEquals(md1.hashCode(), md2.hashCode());
1145     }
1146 
1147     public void testCompare() {
1148         ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
1149         ModuleDescriptor md2 = ModuleDescriptor.module("bar").build();
1150         int n = "foo".compareTo("bar");
1151         assertTrue(md1.compareTo(md2) == n);
1152         assertTrue(md2.compareTo(md1) == -n);
1153     }
1154 
1155     public void testToString() {
1156         String s = ModuleDescriptor.module("m1").requires("m2").exports("p1").build().toString();
1157         assertTrue(s.contains("m1"));
1158         assertTrue(s.contains("m2"));
1159         assertTrue(s.contains("p1"));
1160     }
1161 
1162 }