1 /*
   2  * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  */
   5 package com.oracle.appbundlers.tests.functionality.jdk9test;
   6 
   7 import java.io.IOException;
   8 import java.nio.file.FileVisitResult;
   9 import java.nio.file.Files;
  10 import java.nio.file.Path;
  11 import java.nio.file.SimpleFileVisitor;
  12 import java.nio.file.StandardCopyOption;
  13 import java.nio.file.attribute.BasicFileAttributes;
  14 import java.util.ArrayList;
  15 import java.util.Arrays;
  16 import java.util.Collections;
  17 import java.util.HashMap;
  18 import java.util.List;
  19 import java.util.Map;
  20 import java.util.concurrent.TimeUnit;
  21 import java.util.logging.Level;
  22 
  23 import org.testng.Assert;
  24 import org.testng.annotations.Test;
  25 
  26 import com.oracle.appbundlers.tests.functionality.functionalinterface.VerifiedOptions;
  27 import com.oracle.appbundlers.tests.functionality.parameters.Parameters;
  28 import com.oracle.appbundlers.utils.AppWrapper;
  29 import com.oracle.appbundlers.utils.BundlingManager;
  30 import com.oracle.appbundlers.utils.ExtensionType;
  31 import com.oracle.appbundlers.utils.SourceFactory;
  32 import com.oracle.appbundlers.utils.Utils;
  33 import com.oracle.appbundlers.utils.installers.AbstractBundlerUtils;
  34 import com.oracle.tools.packager.ConfigException;
  35 
  36 import javafx.util.Pair;
  37 
  38 /**
  39  * @author Ramesh BG
  40  * Aim: To test dependency on different module packages.
  41  * There are three module packages
  42  * 1. Modular Jar
  43  * 2. Jmods
  44  * 3. Exploded Modules
  45  * here is the different permutations for test case
  46  *
  47  * SERVICE_INTERFACE is module which exposes API for service provider.
  48  * CIRCLE and RECTANGLE are modules which provides service for SERVICE_INTERFACE
  49  *
  50  * ==============================================================
  51  * ModularJar            | Jmods             | ExplodedMods
  52  * ==============================================================
  53  * | SERVICE_INTERFACE   |CIRCLE            | RECTANGLE         |
  54  * -------------------------------------------------------------|
  55  * | CIRCLE              |SERVICE_INTERFACE | RECTANGLE         |
  56  * -------------------------------------------------------------|
  57  * | RECTANGLE           |CIRCLE            | SERVICE_INTERFACE |
  58  * -------------------------------------------------------------|
  59  * | RECTANGLE           |SERVICE_INTERFACE | CIRCLE            |
  60  * -------------------------------------------------------------|
  61  * | CIRCLE              |RECTANGLE         | SERVICE_INTERFACE |
  62  * -------------------------------------------------------------|
  63  * | SERVICE_INTERFACE   |RECTANGLE         | CIRCLE            |
  64  * -------------------------------------------------------------|
  65  *
  66  */
  67 public class JmodExplodedModuleAndModularJarDependencyTest extends ModuleTestBase {
  68 
  69     private static String SI = COM_SHAPE_SERVICEINTERFACE_MODULE_NAME;
  70     private static String CIRCLE = COM_SHAPE_SERVICEPROVIDER_CIRCLE_MODULENAME;
  71     private static String RECTANGLE = COM_SHAPE_SERVICEPROVIDER_RECTANGLE_MODULE_NAME;
  72 
  73     private static String[][] array = new String[][] { { SI, CIRCLE, RECTANGLE },
  74             { CIRCLE, SI, RECTANGLE }, { RECTANGLE, CIRCLE, SI },
  75             { RECTANGLE, SI, CIRCLE }, { CIRCLE, RECTANGLE, SI },
  76             { SI, RECTANGLE, CIRCLE } };
  77 
  78     private List<Path> modulePathList = new ArrayList<Path>();
  79 
  80     public AppWrapper getApp() throws IOException {
  81         Map<String, String> hashMap = new HashMap<String, String>();
  82         hashMap.put(COM_SHAPE_SERVICEINTERFACE_SHAPEMAINCLASS_TEMPLATE,
  83                 COM_SHAPE_SERVICEINTERFACE_SHAPEMAINCLASS);
  84 
  85         return new AppWrapper(Utils.getTempSubDir(WORK_DIRECTORY),
  86                 COM_SHAPE_SERVICEINTERFACE_SHAPEMAINCLASS,
  87                 SourceFactory.get_com_shape_serviceinterface_module(hashMap,
  88                         Collections.emptyMap(),
  89                         COM_SHAPE_SERVICEINTERFACE_SHAPEMAINCLASS),
  90                 SourceFactory.get_com_shape_serviceprovider_circle_module(),
  91                 SourceFactory.get_com_shape_serviceprovider_rectangle_module());
  92     }
  93 
  94     @Override
  95     public void overrideParameters(ExtensionType extension) throws IOException {
  96         if (ExtensionType.NormalJar != extension) {
  97             this.currentParameter.setApp(getApp());
  98         }
  99         this.currentParameter.setVerifiedOptions(getVerifiedOptions());
 100     }
 101 
 102     @Override
 103     protected void prepareTestEnvironment() throws Exception {
 104         for (ExtensionType intermediate : ExtensionType.values()) {
 105             this.currentParameter = this.intermediateToParametersMap
 106                     .get(intermediate);
 107             overrideParameters(intermediate);
 108             initializeAndPrepareApp();
 109         }
 110 
 111         Parameters normalJarParameter = intermediateToParametersMap
 112                 .get(ExtensionType.NormalJar);
 113         /*
 114          * create directories mixmods1 ... mixmods6
 115          * copy different ExtensionType format into mixmods* directory
 116          * finally each of mixmods* will be modulepath for test to run.
 117          *
 118          */
 119         for (int i = 0; i < array.length; i++) {
 120             Path mixmodsPath = normalJarParameter.getApp().getWorkDir()
 121                     .resolve("mixmods" + i);
 122             modulePathList.add(mixmodsPath);
 123             Path mixmodsdir = Files.createDirectories(mixmodsPath);
 124             Path modularJarPath = intermediateToParametersMap
 125                     .get(ExtensionType.ModularJar).getApp().getModularJarsDir()
 126                     .resolve(array[i][0] + ".jar");
 127             Path jmodsPath = intermediateToParametersMap
 128                     .get(ExtensionType.Jmods).getApp().getJmodsDir()
 129                     .resolve(array[i][1] + ".jmod");
 130             Path explodedModsPath = intermediateToParametersMap
 131                     .get(ExtensionType.ExplodedModules).getApp()
 132                     .getExplodedModsDir().resolve(array[i][2]);
 133             Files.copy(modularJarPath, mixmodsdir.resolve(modularJarPath.getFileName()),
 134                     StandardCopyOption.REPLACE_EXISTING);
 135             Files.copy(jmodsPath, mixmodsdir.resolve(jmodsPath.getFileName()),
 136                     StandardCopyOption.REPLACE_EXISTING);
 137             Path explodedDir = mixmodsdir
 138                     .resolve(explodedModsPath.getFileName());
 139 
 140             Files.walkFileTree(explodedModsPath, new SimpleFileVisitor<Path>() {
 141                 @Override
 142                 public FileVisitResult preVisitDirectory(Path dir,
 143                         final BasicFileAttributes attrs) throws IOException {
 144                     Files.createDirectories(explodedDir
 145                             .resolve(explodedModsPath.relativize(dir)));
 146                     return FileVisitResult.CONTINUE;
 147                 }
 148 
 149                 @Override
 150                 public FileVisitResult visitFile(final Path file,
 151                         final BasicFileAttributes attrs) throws IOException {
 152                     Files.copy(file, explodedDir
 153                             .resolve(explodedModsPath.relativize(file)));
 154                     return FileVisitResult.CONTINUE;
 155                 }
 156             });
 157         }
 158     }
 159 
 160     protected Map<String, Object> getAllParams(Path modulepath)
 161             throws Exception {
 162         Map<String, Object> allParams = new HashMap<String, Object>();
 163         allParams.put(APP_NAME, getResultingAppName());
 164         AppWrapper app = this.intermediateToParametersMap
 165                 .get(ExtensionType.ModularJar).getApp();
 166         allParams.put(MAIN_MODULE,
 167                 String.join("/", app.getMainModuleName(), app.getMainClass()));
 168         allParams.put(MODULEPATH, modulepath.toString());
 169         return allParams;
 170     }
 171 
 172     public VerifiedOptions getVerifiedOptions() {
 173         return () -> {
 174             Map<String, Object> hashMap = new HashMap<String, Object>();
 175             hashMap.put(AbstractBundlerUtils.MULTI_OUTPUT_CONTAINS,
 176                     Arrays.asList(CIRCLE_OUTPUT, RECTANGLE_OUTPUT));
 177             return hashMap;
 178         };
 179     }
 180 
 181     @Test(dataProvider = "getBundlers")
 182     public void runTest(BundlingManager bundlingManager) throws Exception {
 183 
 184         for (int i = 0; i < array.length; i++) {
 185             Map<String, Object> allParams = getAllParams(modulePathList.get(i));
 186             String testName = this.getClass().getName() + "::"
 187                     + testMethod.getName() + "$" + bundlingManager.toString();
 188             this.bundlingManager = bundlingManager;
 189             LOG.log(Level.INFO, "Starting test \"{0}\".", testName);
 190 
 191             try {
 192                 validate();
 193                 if (isConfigExceptionExpected(bundlingManager.getBundler())) {
 194                     Assert.fail(
 195                             "ConfigException is expected, but isn't thrown");
 196                 }
 197             } catch (ConfigException ex) {
 198                 if (isConfigExceptionExpected(bundlingManager.getBundler())) {
 199                     return;
 200                 } else {
 201                     LOG.log(Level.SEVERE, "Configuration error: {0}.",
 202                             new Object[] { ex });
 203                     throw ex;
 204                 }
 205             }
 206 
 207             try {
 208                 AppWrapper app = intermediateToParametersMap
 209                 .get(ExtensionType.NormalJar).getApp();
 210                 bundlingManager.execute(allParams,
 211                         app);
 212                 String path = bundlingManager.install(
 213                         app, getResultingAppName(),
 214                         false);
 215                 LOG.log(Level.INFO, "Installed at: {0}", path);
 216 
 217                 Pair<TimeUnit, Integer> tuple = getDelayAfterInstall();
 218                 tuple.getKey().sleep(tuple.getValue());
 219                 AppWrapper app2 = this.currentParameter.getApp();
 220                 this.intermediateToParametersMap
 221                 .get(ExtensionType.NormalJar).getVerifiedOptions().forEach(
 222                         (name, value) -> bundlingManager.verifyOption(name,
 223                                 value, app2, getResultingAppName()));
 224             }
 225 
 226             finally {
 227                 uninstallApp(modulePathList.get(i));
 228                 LOG.log(Level.INFO, "Finished test: {0}", testName);
 229             }
 230         }
 231     }
 232 
 233     private void uninstallApp(Path modulepath) throws Exception {
 234         if (bundlingManager != null) {
 235             String appName = bundlingManager.getAppName(getAllParams(modulepath));
 236             bundlingManager.uninstall(this.intermediateToParametersMap
 237                     .get(ExtensionType.NormalJar).getApp(), appName);
 238         }
 239     }
 240 }