1 /*
   2  * Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  */
   5 
   6 /* @test
   7 
   8 @summary Testcases that show different possibilities of resource bundling.
   9 
  10 @library
  11 /appBundlerTests/lib/ant-javafx.jar
  12 /appBundlerTests/src
  13 /appBundlerTests/test
  14 
  15 @build
  16 BundlerTest
  17 com.oracle.appbundlers.utils.AppWrapper
  18 com.oracle.appbundlers.utils.Utils
  19 com.oracle.appbundlers.utils.Config
  20 com.oracle.appbundlers.utils.VerificationUtil
  21 com.oracle.appbundlers.utils.installers.Installer
  22 
  23 @run testng com.oracle.appbundlers.tests.functionality.TestBase
  24 */
  25 package com.oracle.appbundlers.tests.functionality;
  26 
  27 import static com.oracle.appbundlers.utils.Utils.isLinux;
  28 import static com.oracle.appbundlers.utils.Utils.isWindows;
  29 import static java.util.stream.Collectors.toList;
  30 
  31 import java.io.IOException;
  32 import java.lang.reflect.Method;
  33 import java.util.HashMap;
  34 import java.util.Iterator;
  35 import java.util.List;
  36 import java.util.Map;
  37 import java.util.concurrent.ExecutionException;
  38 import java.util.concurrent.TimeUnit;
  39 import java.util.logging.Level;
  40 import java.util.logging.Logger;
  41 import java.util.stream.Collectors;
  42 import java.util.stream.Stream;
  43 
  44 import org.testng.Assert;
  45 import org.testng.annotations.AfterClass;
  46 import org.testng.annotations.BeforeClass;
  47 import org.testng.annotations.BeforeMethod;
  48 import org.testng.annotations.DataProvider;
  49 import org.testng.annotations.Test;
  50 
  51 import com.oracle.appbundlers.tests.BundlerProvider;
  52 import com.oracle.appbundlers.tests.functionality.parameters.ExplodedModuleParameters;
  53 import com.oracle.appbundlers.tests.functionality.parameters.JmodParameters;
  54 import com.oracle.appbundlers.tests.functionality.parameters.ModularJarParameters;
  55 import com.oracle.appbundlers.tests.functionality.parameters.NormalJarParameters;
  56 import com.oracle.appbundlers.tests.functionality.parameters.Parameters;
  57 import com.oracle.appbundlers.utils.AppWrapper;
  58 import com.oracle.appbundlers.utils.BundlerUtils;
  59 import com.oracle.appbundlers.utils.BundlingManager;
  60 import com.oracle.appbundlers.utils.BundlingManagers;
  61 import com.oracle.appbundlers.utils.Constants;
  62 import com.oracle.appbundlers.utils.ExtensionType;
  63 import com.oracle.appbundlers.utils.PackageTypeFilter;
  64 import com.oracle.appbundlers.utils.PackagerApiFilter;
  65 import com.oracle.appbundlers.utils.Utils;
  66 import com.oracle.appbundlers.utils.installers.AbstractBundlerUtils;
  67 import com.oracle.tools.packager.Bundler;
  68 import com.oracle.tools.packager.ConfigException;
  69 import com.oracle.tools.packager.Log;
  70 
  71 import javafx.util.Pair;
  72 
  73 /**
  74  * @author Dmitry Ginzburg <dmitry.x.ginzburg@oracle.com>
  75  * @author Dmitry Zinkevich <dmitry.zinkevich@oracle.com>
  76  */
  77 public abstract class TestBase implements Constants {
  78 
  79     protected BundlingManager bundlingManager;
  80     protected Parameters currentParameter;
  81     protected Map<ExtensionType, Parameters> intermediateToParametersMap = new HashMap<ExtensionType, Parameters>() {
  82         /**
  83          * serial version UID
  84          */
  85         private static final long serialVersionUID = -9110787670838081437L;
  86 
  87         {
  88             put(ExtensionType.NormalJar, new NormalJarParameters());
  89             put(ExtensionType.ModularJar, new ModularJarParameters());
  90             put(ExtensionType.ExplodedModules, new ExplodedModuleParameters());
  91             put(ExtensionType.Jmods, new JmodParameters());
  92         }
  93     };
  94 
  95     protected static final Logger LOG = Logger
  96             .getLogger(TestBase.class.getName());
  97 
  98     protected Method testMethod = null;
  99 
 100     // method block: should be overridden in some tests
 101     // all these implementations are just "default-values"
 102     protected BundlerUtils[] getBundlerUtils() {
 103         return BundlerUtils.values();
 104     }
 105 
 106     protected BundlingManagers[] getBundlingManagers() {
 107         return BundlingManagers.values();
 108     }
 109 
 110     /**
 111      * return App Name
 112      */
 113     public String getResultingAppName() {
 114         return this.getClass().getSimpleName();
 115     }
 116 
 117     protected boolean isConfigExceptionExpected(Bundler bundler) {
 118         return false;
 119     }
 120 
 121     protected void prepareApp(final AppWrapper app, ExtensionType extension)
 122             throws IOException, ExecutionException {
 123         app.preinstallApp(extension);
 124         app.writeSourcesToAppDirectory();
 125         app.compileApp();
 126         app.jarApp(extension);
 127     }
 128 
 129     @BeforeClass
 130     public void setupApplication() throws Exception {
 131         Log.setLogger(new Log.Logger(true));
 132         prepareTestEnvironment();
 133         customBeforeClassHook();
 134     }
 135 
 136     public void customBeforeClassHook() throws Exception {
 137     }
 138 
 139     protected void prepareTestEnvironment() throws Exception {
 140         for (ExtensionType intermediate : ExtensionType.values()) {
 141             this.currentParameter = this.intermediateToParametersMap
 142                     .get(intermediate);
 143             overrideParameters(intermediate);
 144             initializeAndPrepareApp();
 145         }
 146     }
 147 
 148     protected void initializeAndPrepareApp() throws Exception {
 149         if (this.currentParameter.getApp() == null) {
 150             this.currentParameter.initializeDefaultApp();
 151         }
 152         prepareApp(this.currentParameter.getApp(),
 153                 this.currentParameter.getExtension());
 154     }
 155 
 156     @BeforeMethod
 157     public void saveTestMethod(Method method) throws IOException {
 158         testMethod = method;
 159     }
 160 
 161     @Test(dataProvider = "getBundlers")
 162     public void runTest(BundlingManager bundlingManager) throws Exception {
 163         for (ExtensionType extension : getExtensionArray()) {
 164             this.currentParameter = intermediateToParametersMap
 165                     .get(extension);
 166             if (!isTestCaseApplicableForExtensionType(extension)) {
 167                 continue;
 168             }
 169 
 170             Map<String, Object> allParams = getAllParams(extension);
 171             String testName = this.getClass().getName() + "::"
 172                     + testMethod.getName() + "$" + bundlingManager.toString();
 173             this.bundlingManager = bundlingManager;
 174             LOG.log(Level.INFO, "Starting test \"{0}\".", testName);
 175             try {
 176                 validate();
 177                 if (isConfigExceptionExpected(bundlingManager.getBundler())) {
 178                     Assert.fail(
 179                             "ConfigException is expected, but isn't thrown");
 180                 }
 181             } catch (ConfigException ex) {
 182                 if (isConfigExceptionExpected(bundlingManager.getBundler())) {
 183                     return;
 184                 } else {
 185                     LOG.log(Level.SEVERE, "Configuration error: {0}.",
 186                             new Object[] { ex });
 187                     throw ex;
 188                 }
 189             }
 190 
 191             try {
 192                 bundlingManager.execute(allParams,
 193                         this.currentParameter.getApp());
 194                 String path = bundlingManager.install(
 195                         this.currentParameter.getApp(), getResultingAppName(),
 196                         false);
 197                 LOG.log(Level.INFO, "Installed at: {0}", path);
 198 
 199                 Pair<TimeUnit, Integer> tuple = getDelayAfterInstall();
 200                 tuple.getKey().sleep(tuple.getValue());
 201                 AppWrapper app2 = this.currentParameter.getApp();
 202                 this.currentParameter.getVerifiedOptions().forEach(
 203                         (name, value) -> bundlingManager.verifyOption(name,
 204                                 value, app2, getResultingAppName()));
 205             }
 206 
 207             finally {
 208                 uninstallApp(extension);
 209                 LOG.log(Level.INFO, "Finished test: {0}", testName);
 210             }
 211         }
 212     }
 213 
 214     public boolean isTestCaseApplicableForExtensionType(
 215             ExtensionType extension) {
 216         return true;
 217     }
 218 
 219     public ExtensionType[] getExtensionArray() {
 220         return ExtensionType.values();
 221     }
 222 
 223     protected void uninstallApp(ExtensionType intermediate) throws Exception {
 224         if (bundlingManager != null) {
 225             String appName = bundlingManager
 226                     .getAppName(getAllParams(intermediate));
 227             bundlingManager.uninstall(this.currentParameter.getApp(), appName);
 228         }
 229     }
 230 
 231     @AfterClass
 232     protected void cleanUp() throws IOException {
 233         try {
 234             LOG.log(Level.INFO, "Removing temporary files: ");
 235         } finally {
 236             for (Parameters parameters : intermediateToParametersMap.values()) {
 237                 Utils.tryRemoveRecursive(parameters.getApp().getWorkDir());
 238             }
 239         }
 240     }
 241 
 242     public void overrideParameters(ExtensionType intermediate)
 243             throws Exception {
 244 
 245     }
 246 
 247     @DataProvider(name = "getBundlers")
 248     public Iterator<Object[]> getBundlers() {
 249 
 250         List<BundlingManagers> packagerInterfaces = Stream
 251                 .of(getBundlingManagers()).filter(PackagerApiFilter::accept)
 252                 .collect(Collectors.toList());
 253 
 254         final List<AbstractBundlerUtils> installationPackageTypes = Stream
 255                 .of(getBundlerUtils()).filter(BundlerUtils::isSupported)
 256                 .filter(PackageTypeFilter::accept)
 257                 .map(BundlerUtils::getBundlerUtils).collect(toList());
 258 
 259         return BundlerProvider.createBundlingManagers(installationPackageTypes,
 260                 packagerInterfaces);
 261     }
 262 
 263     public boolean mustBeSupported(String bundlerId) {
 264         if (isLinux()) {
 265             return bundlerId.equals("linux.app") || bundlerId.equals("deb")
 266                     || bundlerId.equals("rpm");
 267         } else if (isWindows()) {
 268             return bundlerId.equals("windows.app") || bundlerId.equals("exe")
 269                     || bundlerId.equals("msi");
 270         } else {
 271             return bundlerId.equals("mac.app")
 272                     || bundlerId.equals("mac.appStore")
 273                     || bundlerId.equals("dmg");
 274         }
 275     }
 276 
 277     protected Pair<TimeUnit, Integer> getDelayAfterInstall() {
 278         return new Pair<TimeUnit, Integer>(TimeUnit.MILLISECONDS, 100);
 279     }
 280 
 281     protected Map<String, Object> getAllParams(ExtensionType intermediate)
 282             throws Exception {
 283         Map<String, Object> basicParams = this.currentParameter
 284                 .getBasicParams();
 285         Map<String, Object> allParams = new HashMap<String, Object>();
 286         allParams.put(APP_NAME, getResultingAppName());
 287         allParams.putAll(basicParams);
 288         allParams.putAll(this.currentParameter.getAdditionalParams());
 289         return allParams;
 290     }
 291 
 292     public void validate() throws Exception {
 293         bundlingManager.validate(this.currentParameter.getBasicParams());
 294     }
 295 
 296     public Parameters getParameters() {
 297         return this.currentParameter;
 298     }
 299 }