1 /*
   2  * Copyright (c) 2014, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.oracle.tools.packager;
  27 
  28 import com.oracle.tools.packager.Bundler;
  29 import com.oracle.tools.packager.BundlerParamInfo;
  30 import com.oracle.tools.packager.Bundlers;
  31 import com.oracle.tools.packager.StandardBundlerParam;
  32 import com.oracle.tools.packager.ConfigException;
  33 import com.oracle.tools.packager.UnsupportedPlatformException;
  34 import com.oracle.tools.packager.windows.WinExeBundler;
  35 import com.oracle.tools.packager.windows.WinMsiBundler;
  36 import org.junit.Test;
  37 
  38 import java.io.File;
  39 import java.io.IOException;
  40 import java.nio.file.Files;
  41 import java.util.*;
  42 import java.util.function.Function;
  43 import java.util.stream.Collectors;
  44 
  45 import static org.junit.Assert.*;
  46 import static org.junit.Assume.assumeTrue;
  47 
  48 public class BundlersTest {
  49 
  50     // walking the params creates the temp packaging directories,
  51     // so we need to clean them up.
  52     //@AfterClass
  53     public static void cleanupTmpDir() throws IOException {
  54         // paint a broad brush: delete all fxpackager junk in the temp dir
  55         File tmpBase = Files.createTempDirectory("fxbundler").toFile().getParentFile();
  56         File[] children = tmpBase.listFiles();
  57         if (children != null) {
  58             for (File f : children) {
  59                 if (f.getName().startsWith("fxbundler")) {
  60                     attemptDelete(f);
  61                 }
  62             }
  63         }
  64     }
  65 
  66     private static void attemptDelete(File tmpBase) {
  67         if (tmpBase.isDirectory()) {
  68             File[] children = tmpBase.listFiles();
  69             if (children != null) {
  70                 for (File f : children) {
  71                     attemptDelete(f);
  72                 }
  73             }
  74         }
  75         boolean success;
  76         try {
  77             success = !tmpBase.exists() || tmpBase.delete();
  78         } catch (SecurityException se) {
  79             success = false;
  80         }
  81         if (!success) {
  82             System.err.println("Could not clean up " + tmpBase.toString());
  83         }
  84     }
  85 
  86 
  87     @Test
  88     public void testCommonBundlersDeclareParameters() {
  89         boolean hasNullParams = false;
  90         for (Bundler bundler : Bundlers.createBundlersInstance().getBundlers()) {
  91             Collection<BundlerParamInfo<?>> params = bundler.getBundleParameters();
  92             if (params == null) {
  93                 System.err.println("Bundler '" + bundler.getID() + "' has a null parameter set");
  94                 hasNullParams = true;
  95             }
  96         }
  97 
  98         assumeTrue(!hasNullParams); // deleteme when fixed
  99         assertTrue("All common bundlers have parameters.", !hasNullParams);
 100     }
 101 
 102 
 103     @Test
 104     public void testCommonBundlerParameterDuplicates() {
 105         boolean duplicateFound = false;
 106         for (Bundler bundler : Bundlers.createBundlersInstance().getBundlers()) {
 107             Collection<BundlerParamInfo<?>> params = bundler.getBundleParameters();
 108             if (params == null) continue; // caught by another test
 109             
 110             Map<String, List<BundlerParamInfo<?>>> paramsGroupMap = params.stream().collect(Collectors.groupingBy(BundlerParamInfo::getID));
 111             
 112             for (Map.Entry<String, List<BundlerParamInfo<?>>> paramGroupEntry : paramsGroupMap.entrySet()) {
 113                 if (paramGroupEntry.getValue().size() > 1) {
 114                     System.err.println("Duplicate param '" + paramGroupEntry.getKey() + "' for bundler '" + bundler.getID() + "'");
 115                     duplicateFound = true;
 116                 }
 117             }
 118         }
 119 
 120         assertFalse("Parameter list within a bundler has a duplicate ID.", duplicateFound);
 121     }
 122     
 123     boolean assertMetadata(Bundler bundler, BundlerParamInfo<?> bpi, String checkDescription, Function<BundlerParamInfo, Boolean> check) {
 124         if (!check.apply(bpi)) {
 125             System.err.println("Bundler '" + bundler.getID() + "' parameter '" + bpi.getID() + "' failed metadata check: " + checkDescription);
 126             return false;
 127         } else {
 128             return true;
 129         }
 130     }
 131     
 132     @Test
 133     public void testCommonBundlerParameterMetadata() {
 134         boolean metadataValid = true;
 135         for (Bundler bundler : Bundlers.createBundlersInstance().getBundlers()) {
 136             Collection<BundlerParamInfo<?>> params = bundler.getBundleParameters();
 137             if (params == null) continue; // caught by another test
 138 
 139             for (BundlerParamInfo<?> bpi : params) {
 140                 System.err.println("Checking '" + bundler.getID() + "' param '" + bpi.getID() + "'");
 141                 metadataValid &= assertMetadata(bundler, bpi, "Name is not null", param -> param.getName() != null);
 142                 metadataValid &= assertMetadata(bundler, bpi, "ID is not null", param -> param.getID() != null);
 143                 metadataValid &= assertMetadata(bundler, bpi, "Description is not null", param -> param.getDescription() != null);
 144                 metadataValid &= assertMetadata(bundler, bpi, "ValueType is not null", param -> param.getValueType() != null);
 145             }
 146         }
 147 
 148         assertTrue("Metadata on pre-packaged bundlers is valid.", metadataValid);
 149     }
 150 
 151 
 152     // for all bundlers that can be found, assert
 153     //  they have the requisite metadata
 154     //  for the parameters they declare
 155     //   * ? They all include a substantial portion of the standard parameters (90%?) ?
 156 
 157 
 158     @Test
 159     public void getBundlersPlatformTest() {
 160         Collection<String> bundlerIDs = new ArrayList<>();
 161         for (Bundler bundler : Bundlers.createBundlersInstance().getBundlers()) {
 162             try {
 163                 bundler.validate(new HashMap<>());
 164             } catch (UnsupportedPlatformException upe) {
 165                 // don't list bundlers this platform cannot run
 166                 continue;
 167             } catch (ConfigException ignore) {
 168                 // but requiring more than an empty map is perfectly fine.
 169             }
 170             bundlerIDs.add(bundler.getID());
 171         }
 172 
 173         boolean mac = System.getProperty("os.name").toLowerCase().contains("os x");
 174         assertEquals(mac, bundlerIDs.contains("mac.app"));
 175         assertEquals(mac, bundlerIDs.contains("dmg"));
 176         assertEquals(mac, bundlerIDs.contains("pkg"));
 177 
 178         boolean linux = System.getProperty("os.name").toLowerCase().startsWith("linux");
 179         assertEquals(linux, bundlerIDs.contains("linux.app"));
 180         assertEquals(linux, bundlerIDs.contains("deb"));
 181         assertEquals(linux, bundlerIDs.contains("rpm"));
 182         
 183         boolean windows = System.getProperty("os.name").toLowerCase().startsWith("win");
 184         assertEquals(windows, bundlerIDs.contains("windows.app"));
 185         assertEquals(windows, bundlerIDs.contains("msi"));
 186         assertEquals(windows, bundlerIDs.contains("exe"));
 187     }
 188 
 189     @Test
 190     public void noNullBundlerIDs() {
 191         Collection<String> bundlerIDs = getBundlerIDs();
 192         
 193         assertFalse(bundlerIDs.contains(null));
 194         assertFalse(bundlerIDs.contains("null"));
 195     }
 196 
 197 
 198     @Test
 199     public void noDuplicateBundlerIDs() {
 200         Collection<Bundler> bundlers = Bundlers.createBundlersInstance().getBundlers();
 201 
 202         Map<String, List<Bundler>> paramsGroupMap = bundlers.stream().collect(Collectors.groupingBy(Bundler::getID));
 203 
 204         boolean duplicateFound = false;
 205         for (Map.Entry<String, List<Bundler>> paramGroupEntry : paramsGroupMap.entrySet()) {
 206             if (paramGroupEntry.getValue().size() > 1) {
 207                 System.err.println("Duplicate bundler ID '" + paramGroupEntry.getKey() + "'.");
 208                 duplicateFound = true;
 209             }
 210         }
 211         
 212         assertFalse("Bundlers have a duplicate ID", duplicateFound);
 213     }
 214 
 215     public List<String> getBundlerIDs() {
 216         Collection<Bundler> bundlers = Bundlers.createBundlersInstance().getBundlers();
 217 
 218         return Arrays.asList(
 219                 bundlers.stream().map(Bundler::getID).toArray(String[]::new));
 220     }
 221 
 222     @Test
 223     public void customParamFallbackTests() {
 224         Map<String, ? super Object> params;
 225 
 226         params = new TreeMap<>();
 227         assertTrue(WinMsiBundler.MSI_SYSTEM_WIDE.fetchFrom(params));
 228         assertFalse(WinExeBundler.EXE_SYSTEM_WIDE.fetchFrom(params));
 229 
 230         params = new TreeMap<>();
 231         params.put(StandardBundlerParam.SYSTEM_WIDE.getID(), "false");
 232         assertFalse(WinMsiBundler.MSI_SYSTEM_WIDE.fetchFrom(params));
 233         assertFalse(WinExeBundler.EXE_SYSTEM_WIDE.fetchFrom(params));
 234 
 235         params = new TreeMap<>();
 236         params.put(StandardBundlerParam.SYSTEM_WIDE.getID(), "true");
 237         assertTrue(WinMsiBundler.MSI_SYSTEM_WIDE.fetchFrom(params));
 238         assertTrue(WinExeBundler.EXE_SYSTEM_WIDE.fetchFrom(params));
 239     }
 240 }