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 
  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
  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")
  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 {
 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 
 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 
 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 }