1 /*
   2  * Copyright (c) 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  * @summary Tests split packages
  27  * @library ../lib
  28  * @build CompilerUtils JdepsUtil
  29  * @modules jdk.jdeps/com.sun.tools.jdeps
  30  * @run testng CheckModuleTest
  31  */
  32 
  33 import java.lang.module.ModuleDescriptor;
  34 import java.nio.file.Path;
  35 import java.nio.file.Paths;
  36 import java.util.Map;
  37 import java.util.Set;
  38 
  39 import com.sun.tools.jdeps.ModuleAnalyzer;
  40 import org.testng.annotations.BeforeTest;
  41 import org.testng.annotations.DataProvider;
  42 import org.testng.annotations.Test;
  43 
  44 import static org.testng.Assert.assertTrue;
  45 import static org.testng.Assert.assertEquals;
  46 
  47 
  48 public class CheckModuleTest {
  49     private static final String TEST_SRC = System.getProperty("test.src");
  50     private static final String TEST_CLASSES = System.getProperty("test.classes");
  51 
  52     private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
  53     private static final Path MODS_DIR = Paths.get("mods");
  54 
  55     // m4 and m5 are analyzed.  Others are compiled to make sure they are present
  56     // on the module path for analysis
  57     private static final Set<String> modules = Set.of("unsafe", "m4", "m5", "m6", "m7", "m8");
  58 
  59     private static final String JAVA_BASE = "java.base";
  60 
  61     /**
  62      * Compiles classes used by the test
  63      */
  64     @BeforeTest
  65     public void compileAll() throws Exception {
  66         CompilerUtils.cleanDir(MODS_DIR);
  67         modules.forEach(mn ->
  68             assertTrue(CompilerUtils.compileModule(SRC_DIR, MODS_DIR, mn)));
  69     }
  70 
  71     @DataProvider(name = "javaBase")
  72     public Object[][] base() {
  73         return new Object[][] {
  74             { JAVA_BASE, new ModuleMetaData(JAVA_BASE)
  75             },
  76         };
  77     };
  78 
  79     @Test(dataProvider = "javaBase")
  80     public void testJavaBase(String name, ModuleMetaData data) throws Exception {
  81         String cmd = String.format("jdeps -check %s -mp %s%n", name, MODS_DIR);
  82         try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd)) {
  83             jdeps.appModulePath(MODS_DIR.toString());
  84 
  85             ModuleAnalyzer analyzer = jdeps.getModuleAnalyzer(Set.of(name));
  86             assertTrue(analyzer.run());
  87             jdeps.dumpOutput(System.err);
  88 
  89             ModuleDescriptor[] descriptors = analyzer.descriptors(name);
  90             for (int i = 0; i < 3; i++) {
  91                 descriptors[i].requires().stream()
  92                     .forEach(req -> data.checkRequires(req));
  93             }
  94         }
  95     }
  96 
  97     @DataProvider(name = "modules")
  98     public Object[][] unnamed() {
  99         return new Object[][]{
 100             { "m4", new ModuleMetaData[] {
 101                         // original
 102                         new ModuleMetaData("m4")
 103                             .requiresPublic("java.compiler")
 104                             .requires("java.logging")
 105                             // unnused exports
 106                             .exports("p4.internal", Set.of("m6", "m7")),
 107                         // suggested version
 108                         new ModuleMetaData("m4")
 109                             .requires("java.compiler"),
 110                         // reduced version
 111                         new ModuleMetaData("m4")
 112                             .requires("java.compiler")
 113                     }
 114             },
 115             { "m5", new ModuleMetaData[] {
 116                         // original
 117                         new ModuleMetaData("m5")
 118                             .requiresPublic("java.compiler")
 119                             .requiresPublic("java.logging")
 120                             .requires("java.sql")
 121                             .requiresPublic("m4"),
 122                         // suggested version
 123                         new ModuleMetaData("m5")
 124                             .requiresPublic("java.compiler")
 125                             .requires("java.logging")
 126                             .requiresPublic("java.sql")
 127                             .requiresPublic("m4"),
 128                         // reduced version
 129                         new ModuleMetaData("m5")
 130                             .requiresPublic("java.compiler")
 131                             .requiresPublic("java.sql")
 132                             .requiresPublic("m4"),
 133                     }
 134             },
 135         };
 136     }
 137 
 138     @Test(dataProvider = "modules")
 139     public void modularTest(String name, ModuleMetaData[] data) throws Exception {
 140         String cmd = String.format("jdeps -check %s -mp %s%n", name, MODS_DIR);
 141 
 142         try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd)) {
 143             jdeps.appModulePath(MODS_DIR.toString());
 144 
 145             ModuleAnalyzer analyzer = jdeps.getModuleAnalyzer(Set.of(name));
 146             assertTrue(analyzer.run());
 147             jdeps.dumpOutput(System.err);
 148 
 149             // compare the module descriptors and the suggested versions
 150             ModuleDescriptor[] descriptors = analyzer.descriptors(name);
 151             for (int i = 0; i < 3; i++) {
 152                 ModuleMetaData metaData = data[i];
 153                 descriptors[i].requires().stream()
 154                     .forEach(req -> metaData.checkRequires(req));
 155             }
 156 
 157             Map<String, Set<String>> unused = analyzer.unusedQualifiedExports(name);
 158             // verify unuused qualified exports
 159             assertEquals(unused, data[0].exports);
 160         }
 161     }
 162 
 163 }