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 {
testCommon()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 
testCustomDebianCopyright()118     public static void testCustomDebianCopyright() {
119         new CustomDebianCopyrightTest().run();
120     }
121 
testCustomDebianCopyrightSubst()122     public static void testCustomDebianCopyrightSubst() {
123         new CustomDebianCopyrightTest().withSubstitution(true).run();
124     }
125 
rpmLicenseFile(JPackageCommand cmd)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 
linuxLicenseFile(JPackageCommand cmd)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 
debLicenseFile(JPackageCommand cmd)152     private static Path debLicenseFile(JPackageCommand cmd) {
153         return cmd.appInstallationDirectory().resolve("share/doc/copyright");
154     }
155 
verifyLicenseFileInLinuxPackage(JPackageCommand cmd, Path expectedLicensePath)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 
verifyLicenseFileInstalledRpm(Path licenseFile)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 
verifyLicenseFileInstalledDebian(Path licenseFile)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 
verifyLicenseFileNotInstalledLinux(Path licenseFile)192     private static void verifyLicenseFileNotInstalledLinux(Path licenseFile) {
193         TKit.assertPathExists(licenseFile.getParent(), false);
194     }
195 
196     private static class CustomDebianCopyrightTest {
CustomDebianCopyrightTest()197         CustomDebianCopyrightTest() {
198             withSubstitution(false);
199         }
200 
licenseFileText(String copyright, String licenseText)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 
licenseFileText()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 
expetedLicenseFileText()220         private List<String> expetedLicenseFileText() {
221             return licenseFileText(copyright, licenseText);
222         }
223 
withSubstitution(boolean v)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 
run()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 }
282