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) throws IOException {
  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 
  85         final Path tempDir = TKit.createTempDirectory("resources");
  86 
  87         test.addInitializer(cmd -> {
  88             cmd.addArguments("--resource-dir", tempDir);
  89 
  90             appImageScriptData.createScript(cmd);
  91             msiScriptData.createScript(cmd);
  92         });
  93 
  94         switch (packageType) {
  95             case WIN_MSI:
  96                 test.addBundleVerifier((cmd, result) -> {
  97                     appImageScriptData.assertJPackageOutput(result.getOutput());
  98                 });
  99                 break;
 100 
 101             case WIN_EXE:
 102                 test.addBundleVerifier((cmd, result) -> {
 103                     appImageScriptData.assertJPackageOutput(result.getOutput());
 104                     msiScriptData.assertJPackageOutput(result.getOutput());
 105                 });
 106                 break;
 107         }
 108 
 109         test.run();
 110     }
 111 
 112     private static class ScriptData {
 113         ScriptData(PackageType scriptType, int wsfExitCode) {
 114             if (scriptType == PackageType.WIN_MSI) {
 115                 echoText = "post app image wsf";
 116                 envVarName = "JpAppImageDir";
 117                 scriptSuffixName = "post-image";
 118             } else {
 119                 echoText = "post msi wsf";
 120                 envVarName = "JpMsiFile";
 121                 scriptSuffixName = "post-msi";
 122             }
 123             this.wsfExitCode = wsfExitCode;
 124         }
 125 
 126         void assertJPackageOutput(List<String> output) {
 127             TKit.assertTextStream(String.format("jp: %s", echoText))
 128                     .predicate(String::equals)
 129                     .apply(output.stream());
 130 
 131             String cwdPattern = String.format("jp: CWD(%s)=", envVarName);
 132             TKit.assertTextStream(cwdPattern)
 133                     .predicate(String::startsWith)
 134                     .apply(output.stream());
 135             String cwd = output.stream().filter(line -> line.startsWith(
 136                     cwdPattern)).findFirst().get().substring(cwdPattern.length());
 137 
 138             String envVarPattern = String.format("jp: %s=", envVarName);
 139             TKit.assertTextStream(envVarPattern)
 140                     .predicate(String::startsWith)
 141                     .apply(output.stream());
 142             String envVar = output.stream().filter(line -> line.startsWith(
 143                     envVarPattern)).findFirst().get().substring(envVarPattern.length());
 144 
 145             TKit.assertTrue(envVar.startsWith(cwd), String.format(
 146                     "Check value of %s environment variable [%s] starts with the current directory [%s] set for %s script",
 147                     envVarName, envVar, cwd, echoText));
 148         }
 149 
 150         void createScript(JPackageCommand cmd) throws IOException {
 151            IOUtils.createXml(Path.of(cmd.getArgumentValue("--resource-dir"),
 152                     String.format("%s-%s.wsf", cmd.name(), scriptSuffixName)), xml -> {
 153                 xml.writeStartElement("job");
 154                 xml.writeAttribute("id", "main");
 155                 xml.writeStartElement("script");
 156                 xml.writeAttribute("language", "JScript");
 157                 xml.writeCData(String.join("\n", List.of(
 158                     "var shell = new ActiveXObject('WScript.Shell')",
 159                     "WScript.Echo('jp: " + envVarName + "=' + shell.ExpandEnvironmentStrings('%" + envVarName + "%'))",
 160                     "WScript.Echo('jp: CWD(" + envVarName + ")=' + shell.CurrentDirectory)",
 161                     String.format("WScript.Echo('jp: %s')", echoText),
 162                     String.format("WScript.Quit(%d)", wsfExitCode)
 163                 )));
 164                 xml.writeEndElement();
 165                 xml.writeEndElement();
 166             });
 167         }
 168 
 169         private final int wsfExitCode;
 170         private final String scriptSuffixName;
 171         private final String echoText;
 172         private final String envVarName;
 173     }
 174 
 175     private final PackageType packageType;
 176     private PackageTest test;
 177 }