1 /*
   2  * Copyright (c) 2018, 2019, 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 import java.io.IOException;
  25 import java.nio.file.Files;
  26 import java.nio.file.Path;
  27 import java.nio.file.StandardCopyOption;
  28 import java.util.List;
  29 import java.util.ArrayList;
  30 import java.util.Arrays;
  31 import java.util.function.Function;
  32 import java.util.stream.Collectors;
  33 import jdk.jpackage.test.JPackageCommand;
  34 import jdk.jpackage.test.PackageType;
  35 import jdk.jpackage.test.PackageTest;
  36 import jdk.jpackage.test.LinuxHelper;
  37 import jdk.jpackage.test.Executor;
  38 import jdk.jpackage.test.TKit;
  39 
  40 /**
  41  * Test --license-file parameter. Output of the test should be commonlicensetest*.*
  42  * package bundle. The output package should provide the same functionality as
  43  * the default package and also incorporate license information from
  44  * test/jdk/tools/jpackage/resources/license.txt file from OpenJDK repo.
  45  *
  46  * deb:
  47  *
  48  * Package should install license file /opt/commonlicensetest/share/doc/copyright
  49  * file.
  50  *
  51  * rpm:
  52  *
  53  * Package should install license file in
  54  * %{_defaultlicensedir}/licensetest-1.0/license.txt file.
  55  *
  56  * Mac:
  57  *
  58  * Windows
  59  *
  60  * Installer should display license text matching contents of the license file
  61  * during installation.
  62  */
  63 
  64 /*
  65  * @test
  66  * @summary jpackage with --license-file
  67  * @library ../helpers
  68  * @key jpackagePlatformPackage
  69  * @build jdk.jpackage.test.*
  70  * @compile LicenseTest.java
  71  * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal
  72  * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
  73  *  --jpt-run=LicenseTest.testCommon
  74  */
  75 
  76 /*
  77  * @test
  78  * @summary jpackage with --license-file
  79  * @library ../helpers
  80  * @key jpackagePlatformPackage
  81  * @compile LicenseTest.java
  82  * @requires (os.family == "linux")
  83  * @requires (jpackage.test.SQETest == null)
  84  * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal
  85  * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
  86  *  --jpt-run=LicenseTest.testCustomDebianCopyright
  87  *  --jpt-run=LicenseTest.testCustomDebianCopyrightSubst
  88  */
  89 
  90 public class LicenseTest {
  91     public static void testCommon() {
  92         new PackageTest().configureHelloApp()
  93         .addInitializer(cmd -> {
  94             cmd.addArguments("--license-file", TKit.createRelativePathCopy(
  95                     LICENSE_FILE));
  96         })
  97         .forTypes(PackageType.LINUX)
  98         .addBundleVerifier(cmd -> {
  99             verifyLicenseFileInLinuxPackage(cmd, linuxLicenseFile(cmd));
 100         })
 101         .addInstallVerifier(cmd -> {
 102             Path path = linuxLicenseFile(cmd);
 103             if (path != null) {
 104                 TKit.assertReadableFileExists(path);
 105             }
 106         })
 107         .addUninstallVerifier(cmd -> {
 108             verifyLicenseFileNotInstalledLinux(linuxLicenseFile(cmd));
 109         })
 110         .forTypes(PackageType.LINUX_DEB)
 111         .addInstallVerifier(cmd -> {
 112             verifyLicenseFileInstalledDebian(debLicenseFile(cmd));
 113         })
 114         .forTypes(PackageType.LINUX_RPM)
 115         .addInstallVerifier(cmd -> {
 116             Path path = rpmLicenseFile(cmd);
 117             if (path != null) {
 118                 verifyLicenseFileInstalledRpm(path);
 119             }
 120         })
 121         .run();
 122     }
 123 
 124     public static void testCustomDebianCopyright() {
 125         new CustomDebianCopyrightTest().run();
 126     }
 127 
 128     public static void testCustomDebianCopyrightSubst() {
 129         new CustomDebianCopyrightTest().withSubstitution(true).run();
 130     }
 131 
 132     private static Path rpmLicenseFile(JPackageCommand cmd) {
 133         if (cmd.isPackageUnpacked("Not checking for rpm license file")) {
 134             return null;
 135         }
 136 
 137         final Path licenseRoot = Path.of(
 138                 new Executor()
 139                 .setExecutable("rpm")
 140                 .addArguments("--eval", "%{_defaultlicensedir}")
 141                 .executeAndGetFirstLineOfOutput());
 142         final Path licensePath = licenseRoot.resolve(String.format("%s-%s",
 143                 LinuxHelper.getPackageName(cmd), cmd.version())).resolve(
 144                 LICENSE_FILE.getFileName());
 145         return licensePath;
 146     }
 147 
 148     private static Path linuxLicenseFile(JPackageCommand cmd) {
 149         cmd.verifyIsOfType(PackageType.LINUX);
 150         switch (cmd.packageType()) {
 151             case LINUX_DEB:
 152                 return debLicenseFile(cmd);
 153 
 154             case LINUX_RPM:
 155                 return rpmLicenseFile(cmd);
 156 
 157             default:
 158                 return null;
 159         }
 160     }
 161 
 162     private static Path debLicenseFile(JPackageCommand cmd) {
 163         return cmd.appInstallationDirectory().resolve("share/doc/copyright");
 164     }
 165 
 166     private static void verifyLicenseFileInLinuxPackage(JPackageCommand cmd,
 167             Path expectedLicensePath) {
 168         TKit.assertTrue(LinuxHelper.getPackageFiles(cmd).filter(path -> path.equals(
 169                 expectedLicensePath)).findFirst().orElse(null) != null,
 170                 String.format("Check license file [%s] is in %s package",
 171                         expectedLicensePath, LinuxHelper.getPackageName(cmd)));
 172     }
 173 
 174     private static void verifyLicenseFileInstalledRpm(Path licenseFile) throws
 175             IOException {
 176         TKit.assertStringListEquals(Files.readAllLines(LICENSE_FILE),
 177                 Files.readAllLines(licenseFile), String.format(
 178                 "Check contents of package license file [%s] are the same as contents of source license file [%s]",
 179                 licenseFile, LICENSE_FILE));
 180     }
 181 
 182     private static void verifyLicenseFileInstalledDebian(Path licenseFile)
 183             throws IOException {
 184 
 185         List<String> actualLines = Files.readAllLines(licenseFile).stream().dropWhile(
 186                 line -> !line.startsWith("License:")).collect(
 187                         Collectors.toList());
 188         // Remove leading `License:` followed by the whitespace from the first text line.
 189         actualLines.set(0, actualLines.get(0).split("\\s+", 2)[1]);
 190 
 191         actualLines = DEBIAN_COPYRIGT_FILE_STRIPPER.apply(actualLines);
 192 
 193         TKit.assertNotEquals(0, String.join("\n", actualLines).length(),
 194                 "Check stripped license text is not empty");
 195 
 196         TKit.assertStringListEquals(DEBIAN_COPYRIGT_FILE_STRIPPER.apply(
 197                 Files.readAllLines(LICENSE_FILE)), actualLines, String.format(
 198                 "Check subset of package license file [%s] is a match of the source license file [%s]",
 199                 licenseFile, LICENSE_FILE));
 200     }
 201 
 202     private static void verifyLicenseFileNotInstalledLinux(Path licenseFile) {
 203         TKit.assertPathExists(licenseFile.getParent(), false);
 204     }
 205 
 206     private static class CustomDebianCopyrightTest {
 207         CustomDebianCopyrightTest() {
 208             withSubstitution(false);
 209         }
 210 
 211         private List<String> licenseFileText(String copyright, String licenseText) {
 212             List<String> lines = new ArrayList(List.of(
 213                     String.format("Copyright=%s", copyright),
 214                     "Foo",
 215                     "Bar",
 216                     "Buz"));
 217             lines.addAll(List.of(licenseText.split("\\R", -1)));
 218             return lines;
 219         }
 220 
 221         private List<String> licenseFileText() {
 222             if (withSubstitution) {
 223                 return licenseFileText("APPLICATION_COPYRIGHT",
 224                         "APPLICATION_LICENSE_TEXT");
 225             } else {
 226                 return expetedLicenseFileText();
 227             }
 228         }
 229 
 230         private List<String> expetedLicenseFileText() {
 231             return licenseFileText(copyright, licenseText);
 232         }
 233 
 234         CustomDebianCopyrightTest withSubstitution(boolean v) {
 235             withSubstitution = v;
 236             // Different values just to make easy to figure out from the test log which test was executed.
 237             if (v) {
 238                 copyright = "Duke (C)";
 239                 licenseText = "The quick brown fox\n jumps over the lazy dog";
 240             } else {
 241                 copyright = "Java (C)";
 242                 licenseText = "How vexingly quick daft zebras jump!";
 243             }
 244             return this;
 245         }
 246 
 247         void run() {
 248             final Path srcLicenseFile = TKit.workDir().resolve("license");
 249             new PackageTest().forTypes(PackageType.LINUX_DEB).configureHelloApp()
 250             .addInitializer(cmd -> {
 251                 // Create source license file.
 252                 Files.write(srcLicenseFile, List.of(
 253                         licenseText.split("\\R", -1)));
 254 
 255                 cmd.setFakeRuntime();
 256                 cmd.setArgumentValue("--name", String.format("%s%s",
 257                         withSubstitution ? "CustomDebianCopyrightWithSubst" : "CustomDebianCopyright",
 258                         cmd.name()));
 259                 cmd.addArguments("--license-file", srcLicenseFile);
 260                 cmd.addArguments("--copyright", copyright);
 261                 cmd.addArguments("--resource-dir", RESOURCE_DIR);
 262 
 263                 // Create copyright template file in a resource dir.
 264                 Files.createDirectories(RESOURCE_DIR);
 265                 Files.write(RESOURCE_DIR.resolve("copyright"),
 266                         licenseFileText());
 267             })
 268             .addInstallVerifier(cmd -> {
 269                 Path installedLicenseFile = debLicenseFile(cmd);
 270                 TKit.assertStringListEquals(expetedLicenseFileText(),
 271                         DEBIAN_COPYRIGT_FILE_STRIPPER.apply(Files.readAllLines(
 272                                 installedLicenseFile)), String.format(
 273                                 "Check contents of package license file [%s] are the same as contents of source license file [%s]",
 274                                 installedLicenseFile, srcLicenseFile));
 275             })
 276             .run();
 277         }
 278 
 279         private boolean withSubstitution;
 280         private String copyright;
 281         private String licenseText;
 282 
 283         private final Path RESOURCE_DIR = TKit.workDir().resolve("resources");
 284     }
 285 
 286     private static final Path LICENSE_FILE = TKit.TEST_SRC_ROOT.resolve(
 287             Path.of("resources", "license.txt"));
 288 
 289     private static final Function<List<String>, List<String>> DEBIAN_COPYRIGT_FILE_STRIPPER = (lines) -> Arrays.asList(
 290             String.join("\n", lines).stripTrailing().split("\n"));
 291 }