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             TKit.assertReadableFileExists(linuxLicenseFile(cmd));
 103         })
 104         .addUninstallVerifier(cmd -> {
 105             verifyLicenseFileNotInstalledLinux(linuxLicenseFile(cmd));
 106         })
 107         .forTypes(PackageType.LINUX_DEB)
 108         .addInstallVerifier(cmd -> {
 109             verifyLicenseFileInstalledDebian(debLicenseFile(cmd));
 110         })
 111         .forTypes(PackageType.LINUX_RPM)
 112         .addInstallVerifier(cmd -> {
 113             verifyLicenseFileInstalledRpm(rpmLicenseFile(cmd));
 114         })
 115         .run();
 116     }
 117 
 118     public static void testCustomDebianCopyright() {
 119         new CustomDebianCopyrightTest().run();
 120     }
 121 
 122     public static void testCustomDebianCopyrightSubst() {
 123         new CustomDebianCopyrightTest().withSubstitution(true).run();
 124     }
 125 
 126     private static Path rpmLicenseFile(JPackageCommand cmd) {
 127         final Path licenseRoot = Path.of(
 128                 new Executor()
 129                 .setExecutable("rpm")
 130                 .addArguments("--eval", "%{_defaultlicensedir}")
 131                 .executeAndGetFirstLineOfOutput());
 132         final Path licensePath = licenseRoot.resolve(String.format("%s-%s",
 133                 LinuxHelper.getPackageName(cmd), cmd.version())).resolve(
 134                 LICENSE_FILE.getFileName());
 135         return licensePath;
 136     }
 137 
 138     private static Path linuxLicenseFile(JPackageCommand cmd) {
 139         cmd.verifyIsOfType(PackageType.LINUX);
 140         switch (cmd.packageType()) {
 141             case LINUX_DEB:
 142                 return debLicenseFile(cmd);
 143 
 144             case LINUX_RPM:
 145                 return rpmLicenseFile(cmd);
 146 
 147             default:
 148                 return null;
 149         }
 150     }
 151 
 152     private static Path debLicenseFile(JPackageCommand cmd) {
 153         return cmd.appInstallationDirectory().resolve("share/doc/copyright");
 154     }
 155 
 156     private static void verifyLicenseFileInLinuxPackage(JPackageCommand cmd,
 157             Path expectedLicensePath) {
 158         TKit.assertTrue(LinuxHelper.getPackageFiles(cmd).filter(path -> path.equals(
 159                 expectedLicensePath)).findFirst().orElse(null) != null,
 160                 String.format("Check license file [%s] is in %s package",
 161                         expectedLicensePath, LinuxHelper.getPackageName(cmd)));
 162     }
 163 
 164     private static void verifyLicenseFileInstalledRpm(Path licenseFile) throws
 165             IOException {
 166         TKit.assertStringListEquals(Files.readAllLines(LICENSE_FILE),
 167                 Files.readAllLines(licenseFile), String.format(
 168                 "Check contents of package license file [%s] are the same as contents of source license file [%s]",
 169                 licenseFile, LICENSE_FILE));
 170     }
 171 
 172     private static void verifyLicenseFileInstalledDebian(Path licenseFile)
 173             throws IOException {
 174 
 175         List<String> actualLines = Files.readAllLines(licenseFile).stream().dropWhile(
 176                 line -> !line.startsWith("License:")).collect(
 177                         Collectors.toList());
 178         // Remove leading `License:` followed by the whitespace from the first text line.
 179         actualLines.set(0, actualLines.get(0).split("\\s+", 2)[1]);
 180 
 181         actualLines = DEBIAN_COPYRIGT_FILE_STRIPPER.apply(actualLines);
 182 
 183         TKit.assertNotEquals(0, String.join("\n", actualLines).length(),
 184                 "Check stripped license text is not empty");
 185 
 186         TKit.assertStringListEquals(DEBIAN_COPYRIGT_FILE_STRIPPER.apply(
 187                 Files.readAllLines(LICENSE_FILE)), actualLines, String.format(
 188                 "Check subset of package license file [%s] is a match of the source license file [%s]",
 189                 licenseFile, LICENSE_FILE));
 190     }
 191 
 192     private static void verifyLicenseFileNotInstalledLinux(Path licenseFile) {
 193         TKit.assertPathExists(licenseFile.getParent(), false);
 194     }
 195 
 196     private static class CustomDebianCopyrightTest {
 197         CustomDebianCopyrightTest() {
 198             withSubstitution(false);
 199         }
 200 
 201         private List<String> licenseFileText(String copyright, String licenseText) {
 202             List<String> lines = new ArrayList(List.of(
 203                     String.format("Copyright=%s", copyright),
 204                     "Foo",
 205                     "Bar",
 206                     "Buz"));
 207             lines.addAll(List.of(licenseText.split("\\R", -1)));
 208             return lines;
 209         }
 210 
 211         private List<String> licenseFileText() {
 212             if (withSubstitution) {
 213                 return licenseFileText("APPLICATION_COPYRIGHT",
 214                         "APPLICATION_LICENSE_TEXT");
 215             } else {
 216                 return expetedLicenseFileText();
 217             }
 218         }
 219 
 220         private List<String> expetedLicenseFileText() {
 221             return licenseFileText(copyright, licenseText);
 222         }
 223 
 224         CustomDebianCopyrightTest withSubstitution(boolean v) {
 225             withSubstitution = v;
 226             // Different values just to make easy to figure out from the test log which test was executed.
 227             if (v) {
 228                 copyright = "Duke (C)";
 229                 licenseText = "The quick brown fox\n jumps over the lazy dog";
 230             } else {
 231                 copyright = "Java (C)";
 232                 licenseText = "How vexingly quick daft zebras jump!";
 233             }
 234             return this;
 235         }
 236 
 237         void run() {
 238             final Path srcLicenseFile = TKit.workDir().resolve("license");
 239             new PackageTest().configureHelloApp().forTypes(PackageType.LINUX_DEB)
 240             .addInitializer(cmd -> {
 241                 // Create source license file.
 242                 Files.write(srcLicenseFile, List.of(
 243                         licenseText.split("\\R", -1)));
 244 
 245                 cmd.setFakeRuntime();
 246                 cmd.setArgumentValue("--name", String.format("%s%s",
 247                         withSubstitution ? "CustomDebianCopyrightWithSubst" : "CustomDebianCopyright",
 248                         cmd.name()));
 249                 cmd.addArguments("--license-file", srcLicenseFile);
 250                 cmd.addArguments("--copyright", copyright);
 251                 cmd.addArguments("--resource-dir", RESOURCE_DIR);
 252 
 253                 // Create copyright template file in a resource dir.
 254                 Files.createDirectories(RESOURCE_DIR);
 255                 Files.write(RESOURCE_DIR.resolve("copyright"),
 256                         licenseFileText());
 257             })
 258             .addInstallVerifier(cmd -> {
 259                 Path installedLicenseFile = debLicenseFile(cmd);
 260                 TKit.assertStringListEquals(expetedLicenseFileText(),
 261                         DEBIAN_COPYRIGT_FILE_STRIPPER.apply(Files.readAllLines(
 262                                 installedLicenseFile)), String.format(
 263                                 "Check contents of package license file [%s] are the same as contents of source license file [%s]",
 264                                 installedLicenseFile, srcLicenseFile));
 265             })
 266             .run();
 267         }
 268 
 269         private boolean withSubstitution;
 270         private String copyright;
 271         private String licenseText;
 272 
 273         private final Path RESOURCE_DIR = TKit.workDir().resolve("resources");
 274     }
 275 
 276     private static final Path LICENSE_FILE = TKit.TEST_SRC_ROOT.resolve(
 277             Path.of("resources", "license.txt"));
 278 
 279     private static final Function<List<String>, List<String>> DEBIAN_COPYRIGT_FILE_STRIPPER = (lines) -> Arrays.asList(
 280             String.join("\n", lines).stripTrailing().split("\n"));
 281 }