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.Path;
26 import java.util.List;
27 import java.util.ArrayList;
28 import jdk.incubator.jpackage.internal.IOUtils;
29 import jdk.jpackage.test.TKit;
30 import jdk.jpackage.test.PackageTest;
31 import jdk.jpackage.test.PackageType;
32 import jdk.jpackage.test.Annotations.Test;
33 import jdk.jpackage.test.Annotations.Parameter;
34 import jdk.jpackage.test.Annotations.Parameters;
35 import jdk.jpackage.test.JPackageCommand;
36 
37 /*
38  * @test usage of scripts from resource dir
39  * @summary jpackage with
40  * @library ../helpers
41  * @build jdk.jpackage.test.*
42  * @requires (os.family == "windows")
43  * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal
44  * @compile WinScriptTest.java
45  * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
46  *  --jpt-run=WinScriptTest
47  */
48 
49 public class WinScriptTest {
50 
WinScriptTest(PackageType type)51     public WinScriptTest(PackageType type) {
52         this.packageType = type;
53 
54         test = new PackageTest()
55         .forTypes(type)
56         .configureHelloApp()
57         .addInitializer(cmd -> {
58             cmd.setFakeRuntime().saveConsoleOutput(true);
59         });
60     }
61 
62     @Parameters
data()63     public static List<Object[]> data() {
64         return List.of(new Object[][]{
65             {PackageType.WIN_MSI},
66             {PackageType.WIN_EXE}
67         });
68     }
69 
70     @Test
71     @Parameter("0")
72     @Parameter("10")
test(int wsfExitCode)73     public void test(int wsfExitCode) {
74         final ScriptData appImageScriptData;
75         if (wsfExitCode != 0 && packageType == PackageType.WIN_EXE) {
76             appImageScriptData = new ScriptData(PackageType.WIN_MSI, 0);
77         } else {
78             appImageScriptData = new ScriptData(PackageType.WIN_MSI, wsfExitCode);
79         }
80 
81         final ScriptData msiScriptData = new ScriptData(PackageType.WIN_EXE, wsfExitCode);
82 
83         test.setExpectedExitCode(wsfExitCode == 0 ? 0 : 1);
84         TKit.withTempDirectory("resources", tempDir -> {
85             test.addInitializer(cmd -> {
86                 cmd.addArguments("--resource-dir", tempDir);
87 
88                 appImageScriptData.createScript(cmd);
89                 msiScriptData.createScript(cmd);
90             });
91 
92             if (packageType == PackageType.WIN_MSI) {
93                 test.addBundleVerifier((cmd, result) -> {
94                     appImageScriptData.assertJPackageOutput(result.getOutput());
95                 });
96             }
97 
98             if (packageType == PackageType.WIN_EXE) {
99                 test.addBundleVerifier((cmd, result) -> {
100                     appImageScriptData.assertJPackageOutput(result.getOutput());
101                     msiScriptData.assertJPackageOutput(result.getOutput());
102                 });
103             }
104 
105             test.run();
106         });
107     }
108 
109     private static class ScriptData {
ScriptData(PackageType scriptType, int wsfExitCode)110         ScriptData(PackageType scriptType, int wsfExitCode) {
111             if (scriptType == PackageType.WIN_MSI) {
112                 echoText = "post app image wsf";
113                 envVarName = "JpAppImageDir";
114                 scriptSuffixName = "post-image";
115             } else {
116                 echoText = "post msi wsf";
117                 envVarName = "JpMsiFile";
118                 scriptSuffixName = "post-msi";
119             }
120             this.wsfExitCode = wsfExitCode;
121         }
122 
assertJPackageOutput(List<String> output)123         void assertJPackageOutput(List<String> output) {
124             TKit.assertTextStream(String.format("jp: %s", echoText))
125                     .predicate(String::equals)
126                     .apply(output.stream());
127 
128             String cwdPattern = String.format("jp: CWD(%s)=", envVarName);
129             TKit.assertTextStream(cwdPattern)
130                     .predicate(String::startsWith)
131                     .apply(output.stream());
132             String cwd = output.stream().filter(line -> line.startsWith(
133                     cwdPattern)).findFirst().get().substring(cwdPattern.length());
134 
135             String envVarPattern = String.format("jp: %s=", envVarName);
136             TKit.assertTextStream(envVarPattern)
137                     .predicate(String::startsWith)
138                     .apply(output.stream());
139             String envVar = output.stream().filter(line -> line.startsWith(
140                     envVarPattern)).findFirst().get().substring(envVarPattern.length());
141 
142             TKit.assertTrue(envVar.startsWith(cwd), String.format(
143                     "Check value of %s environment variable [%s] starts with the current directory [%s] set for %s script",
144                     envVarName, envVar, cwd, echoText));
145         }
146 
createScript(JPackageCommand cmd)147         void createScript(JPackageCommand cmd) throws IOException {
148            IOUtils.createXml(Path.of(cmd.getArgumentValue("--resource-dir"),
149                     String.format("%s-%s.wsf", cmd.name(), scriptSuffixName)), xml -> {
150                 xml.writeStartElement("job");
151                 xml.writeAttribute("id", "main");
152                 xml.writeStartElement("script");
153                 xml.writeAttribute("language", "JScript");
154                 xml.writeCData(String.join("\n", List.of(
155                     "var shell = new ActiveXObject('WScript.Shell')",
156                     "WScript.Echo('jp: " + envVarName + "=' + shell.ExpandEnvironmentStrings('%" + envVarName + "%'))",
157                     "WScript.Echo('jp: CWD(" + envVarName + ")=' + shell.CurrentDirectory)",
158                     String.format("WScript.Echo('jp: %s')", echoText),
159                     String.format("WScript.Quit(%d)", wsfExitCode)
160                 )));
161                 xml.writeEndElement();
162                 xml.writeEndElement();
163             });
164         }
165 
166         private final int wsfExitCode;
167         private final String scriptSuffixName;
168         private final String echoText;
169         private final String envVarName;
170     }
171 
172     private final PackageType packageType;
173     private PackageTest test;
174 }
175