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.mac; 27 28 import com.oracle.tools.packager.AbstractBundler; 29 import com.oracle.tools.packager.Bundler; 30 import com.oracle.tools.packager.BundlerParamInfo; 31 import com.oracle.tools.packager.ConfigException; 32 import com.oracle.tools.packager.IOUtils; 33 import com.oracle.tools.packager.Log; 34 import com.oracle.tools.packager.RelativeFileSet; 35 import com.oracle.tools.packager.UnsupportedPlatformException; 36 import org.junit.After; 37 import org.junit.Assume; 38 import org.junit.Before; 39 import org.junit.BeforeClass; 40 import org.junit.Test; 41 42 import java.io.File; 43 import java.io.IOException; 44 import java.nio.file.Files; 45 import java.util.Arrays; 46 import java.util.Collection; 47 import java.util.HashMap; 48 import java.util.HashSet; 49 import java.util.Map; 50 import java.util.Set; 51 import java.util.TreeMap; 52 53 import static com.oracle.tools.packager.StandardBundlerParam.*; 54 import static com.oracle.tools.packager.mac.MacAppBundler.*; 55 import static com.oracle.tools.packager.mac.MacBaseInstallerBundler.MAC_APP_IMAGE; 56 import static com.oracle.tools.packager.mac.MacBaseInstallerBundler.SIGNING_KEYCHAIN; 57 import static com.oracle.tools.packager.mac.MacPkgBundler.DEVELOPER_ID_INSTALLER_SIGNING_KEY; 58 import static com.oracle.tools.packager.mac.MacPkgBundler.INSTALLER_SUFFIX; 59 import static org.junit.Assert.*; 60 61 public class MacPkgBundlerTest { 62 63 static final int MIN_SIZE=0x100000; // 1MiB 64 65 static File tmpBase; 66 static File workDir; 67 static File appResourcesDir; 68 static File fakeMainJar; 69 static File hdpiIcon; 70 static String runtimeJdk; 71 static Set<File> appResources; 72 static boolean retain = false; 73 static boolean signingKeysPresent = false; 74 75 static final File FAKE_CERT_ROOT = new File("build/tmp/tests/cert/"); 76 77 @BeforeClass 78 public static void prepareApp() { 79 // only run on mac 80 Assume.assumeTrue(System.getProperty("os.name").toLowerCase().contains("os x")); 81 82 runtimeJdk = System.getenv("PACKAGER_JDK_ROOT"); 83 84 // and only if we have the correct JRE settings 85 String jre = System.getProperty("java.home").toLowerCase(); 86 Assume.assumeTrue(runtimeJdk != null || jre.endsWith("/contents/home/jre") || jre.endsWith("/contents/home/jre")); 87 88 Log.setLogger(new Log.Logger(true)); 89 Log.setDebug(true); 90 91 retain = Boolean.parseBoolean(System.getProperty("RETAIN_PACKAGER_TESTS")); 92 93 workDir = new File("build/tmp/tests", "macpkg"); 94 hdpiIcon = new File("build/tmp/tests", "GenericAppHiDPI.icns"); 95 appResourcesDir = new File("build/tmp/tests", "appResources"); 96 fakeMainJar = new File(appResourcesDir, "mainApp.jar"); 97 98 appResources = new HashSet<>(Arrays.asList(fakeMainJar, 99 new File(appResourcesDir, "LICENSE"), 100 new File(appResourcesDir, "LICENSE2") 101 )); 102 103 signingKeysPresent = DEVELOPER_ID_INSTALLER_SIGNING_KEY.fetchFrom(new TreeMap<>()) != null; 104 } 105 106 @Before 107 public void createTmpDir() throws IOException { 108 if (retain) { 109 tmpBase = new File("build/tmp/tests/macpkg"); 110 } else { 111 tmpBase = BUILD_ROOT.fetchFrom(new TreeMap<>()); 112 } 113 tmpBase.mkdir(); 114 } 115 116 public String createFakeCerts(Map<String, ? super Object> p) { 117 File config = new File(FAKE_CERT_ROOT, "pkg-cert.cfg"); 118 config.getParentFile().mkdirs(); 119 try { 120 // create the config file holding the key config 121 Files.write(config.toPath(), Arrays.<String>asList("[ codesign ]", 122 "keyUsage=critical,digitalSignature", 123 "basicConstraints=critical,CA:false", 124 "extendedKeyUsage=critical,codeSigning", 125 "[ productbuild ]", 126 "basicConstraints=critical,CA:false", 127 "keyUsage=critical,digitalSignature", 128 "extendedKeyUsage=critical,1.2.840.113635.100.4.13", 129 "1.2.840.113635.100.6.1.14=critical,DER:0500")); 130 131 // create the SSL keys 132 ProcessBuilder pb = new ProcessBuilder("openssl", "req", 133 "-newkey", "rsa:2048", 134 "-nodes", 135 "-out", FAKE_CERT_ROOT + "/pkg.csr", 136 "-keyout", FAKE_CERT_ROOT + "/pkg.key", 137 "-subj", "/CN=Developer ID Application: Insecure Test Cert/OU=JavaFX Dev/O=Oracle/C=US"); 138 IOUtils.exec(pb, VERBOSE.fetchFrom(p)); 139 140 // first, for the app 141 // create the cert 142 pb = new ProcessBuilder("openssl", "x509", 143 "-req", 144 "-days", "1", 145 "-in", FAKE_CERT_ROOT + "/pkg.csr", 146 "-signkey", FAKE_CERT_ROOT + "/pkg.key", 147 "-out", FAKE_CERT_ROOT + "/pkg-app.crt", 148 "-extfile", FAKE_CERT_ROOT + "/pkg.cnf", 149 "-extensions", "codesign"); 150 IOUtils.exec(pb, VERBOSE.fetchFrom(p)); 151 152 // create and add it to the keychain 153 pb = new ProcessBuilder("certtool", 154 "i", FAKE_CERT_ROOT + "/pkg-app.crt", 155 "k=" + FAKE_CERT_ROOT + "/pkg.keychain", 156 "r=" + FAKE_CERT_ROOT + "/pkg.key", 157 "c", 158 "p="); 159 IOUtils.exec(pb, VERBOSE.fetchFrom(p)); 160 161 // now for the pkg cert 162 pb = new ProcessBuilder("openssl", "x509", 163 "-req", 164 "-days", "10", 165 "-in", FAKE_CERT_ROOT + "/pkg.csr", 166 "-signkey", FAKE_CERT_ROOT + "/pkg.key", 167 "-out", FAKE_CERT_ROOT + "/pkg-pkg.crt", 168 "-extfile",FAKE_CERT_ROOT + "/png.cnf", 169 "-extensions", "productbuild"); 170 IOUtils.exec(pb, VERBOSE.fetchFrom(p)); 171 172 // create and add it to the keychain 173 pb = new ProcessBuilder("certtool", 174 "i", FAKE_CERT_ROOT + "/pkg-pkg.crt", 175 "k=" + FAKE_CERT_ROOT + "/pkg.keychain", 176 "r=" + FAKE_CERT_ROOT + "/pkg.key"); 177 IOUtils.exec(pb, VERBOSE.fetchFrom(p)); 178 179 return FAKE_CERT_ROOT + "/pkg.keychain"; 180 } catch (IOException e) { 181 e.printStackTrace(); 182 } 183 184 return null; 185 } 186 187 @After 188 public void maybeCleanupTmpDir() { 189 if (!retain) { 190 attemptDelete(tmpBase); 191 } 192 attemptDelete(FAKE_CERT_ROOT); 193 } 194 195 private void attemptDelete(File tmpBase) { 196 if (tmpBase.isDirectory()) { 197 File[] children = tmpBase.listFiles(); 198 if (children != null) { 199 for (File f : children) { 200 attemptDelete(f); 201 } 202 } 203 } 204 boolean success; 205 try { 206 success = !tmpBase.exists() || tmpBase.delete(); 207 } catch (SecurityException se) { 208 success = false; 209 } 210 if (!success) { 211 System.err.println("Could not clean up " + tmpBase.toString()); 212 } 213 } 214 215 /** 216 * See if smoke comes out 217 */ 218 @Test 219 public void smokeTest() throws IOException, ConfigException, UnsupportedPlatformException { 220 AbstractBundler bundler = new MacPkgBundler(); 221 222 assertNotNull(bundler.getName()); 223 assertNotNull(bundler.getID()); 224 assertNotNull(bundler.getDescription()); 225 //assertNotNull(bundler.getBundleParameters()); 226 227 Map<String, Object> bundleParams = new HashMap<>(); 228 229 bundleParams.put(BUILD_ROOT.getID(), tmpBase); 230 231 bundleParams.put(APP_NAME.getID(), "Smoke Test"); 232 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle"); 233 bundleParams.put(PREFERENCES_ID.getID(), "the/really/long/preferences/id"); 234 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources)); 235 bundleParams.put(MAIN_JAR.getID(), 236 new RelativeFileSet(fakeMainJar.getParentFile(), 237 new HashSet<>(Arrays.asList(fakeMainJar))) 238 ); 239 bundleParams.put(CLASSPATH.getID(), "mainApp.jar"); 240 bundleParams.put(VERBOSE.getID(), true); 241 bundleParams.put(LICENSE_FILE.getID(), Arrays.asList("LICENSE", "LICENSE2")); 242 bundleParams.put(SIGN_BUNDLE.getID(), false); // force no signing 243 244 if (runtimeJdk != null) { 245 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk); 246 } 247 248 boolean valid = bundler.validate(bundleParams); 249 assertTrue(valid); 250 251 File result = bundler.execute(bundleParams, new File(workDir, "smoke")); 252 System.err.println("Bundle at - " + result); 253 assertNotNull(result); 254 assertTrue(result.exists()); 255 assertTrue(result.length() > MIN_SIZE); 256 } 257 258 /** 259 * Build smoke test and mark it as quarantined, possibly signed 260 */ 261 @Test 262 public void quarantinedAppTest() throws IOException, ConfigException, UnsupportedPlatformException { 263 264 AbstractBundler bundler = new MacPkgBundler(); 265 266 assertNotNull(bundler.getName()); 267 assertNotNull(bundler.getID()); 268 assertNotNull(bundler.getDescription()); 269 //assertNotNull(bundler.getBundleParameters()); 270 271 Map<String, Object> bundleParams = new HashMap<>(); 272 273 bundleParams.put(BUILD_ROOT.getID(), tmpBase); 274 275 bundleParams.put(APP_NAME.getID(), "Quarantine App"); 276 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle"); 277 bundleParams.put(PREFERENCES_ID.getID(), "the/really/long/preferences/id"); 278 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources)); 279 bundleParams.put(VERBOSE.getID(), true); 280 281 if (runtimeJdk != null) { 282 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk); 283 } 284 285 if (!signingKeysPresent) { 286 String keychain = createFakeCerts(bundleParams); 287 Assume.assumeNotNull(keychain); 288 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain); 289 } 290 291 boolean valid = bundler.validate(bundleParams); 292 assertTrue(valid); 293 294 File result = bundler.execute(bundleParams, new File(workDir, "quarantine")); 295 System.err.println("Bundle at - " + result); 296 assertNotNull(result); 297 assertTrue(result.exists()); 298 assertTrue(result.length() > MIN_SIZE); 299 validateSignatures(result); 300 301 // mark it as though it's been downloaded 302 ProcessBuilder pb = new ProcessBuilder( 303 "xattr", "-w", "com.apple.quarantine", 304 "0000;" + Long.toHexString(System.currentTimeMillis() / 1000L) + ";Java Unit Tests;|com.oracle.jvm.8u", 305 result.toString()); 306 IOUtils.exec(pb, true); 307 } 308 309 /** 310 * The bare minimum configuration needed to make it work 311 * <ul> 312 * <li>Where to build it</li> 313 * <li>The jar containing the application (with a main-class attribute)</li> 314 * </ul> 315 * 316 * All other values will be driven off of those two values. 317 */ 318 @Test 319 public void minimumConfig() throws IOException, ConfigException, UnsupportedPlatformException { 320 Bundler bundler = new MacPkgBundler(); 321 322 Map<String, Object> bundleParams = new HashMap<>(); 323 324 bundleParams.put(BUILD_ROOT.getID(), tmpBase); 325 326 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources)); 327 328 if (runtimeJdk != null) { 329 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk); 330 } 331 332 String keychain = null; 333 if (!signingKeysPresent) { 334 keychain = createFakeCerts(bundleParams); 335 if (keychain != null) { 336 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain); 337 } 338 } 339 340 boolean valid = bundler.validate(bundleParams); 341 assertTrue(valid); 342 343 File output = bundler.execute(bundleParams, new File(workDir, "BareMinimum")); 344 System.err.println("Bundle at - " + output); 345 assertNotNull(output); 346 assertTrue(output.exists()); 347 assertTrue(output.length() > MIN_SIZE); 348 if (signingKeysPresent || keychain != null) { 349 validateSignatures(output); 350 } 351 } 352 353 /** 354 * Test with unicode in places we expect it to be 355 */ 356 @Test 357 public void unicodeConfig() throws IOException, ConfigException, UnsupportedPlatformException { 358 Bundler bundler = new MacPkgBundler(); 359 360 Map<String, Object> bundleParams = new HashMap<>(); 361 362 bundleParams.put(BUILD_ROOT.getID(), tmpBase); 363 364 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources)); 365 366 bundleParams.put(APP_NAME.getID(), "хелловорлд"); 367 bundleParams.put(TITLE.getID(), "ХеллоВорлд аппликейшн"); 368 bundleParams.put(VENDOR.getID(), "Оракл девелопмент"); 369 bundleParams.put(DESCRIPTION.getID(), "крайне большое описание со странными символами"); 370 371 if (runtimeJdk != null) { 372 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk); 373 } 374 375 String keychain = null; 376 if (!signingKeysPresent) { 377 keychain = createFakeCerts(bundleParams); 378 if (keychain != null) { 379 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain); 380 } 381 } 382 383 bundler.validate(bundleParams); 384 385 File output = bundler.execute(bundleParams, new File(workDir, "Unicode")); 386 System.err.println("Bundle at - " + output); 387 assertNotNull(output); 388 assertTrue(output.exists()); 389 if (signingKeysPresent || keychain != null) { 390 validateSignatures(output); 391 } 392 } 393 394 /** 395 * Create a PKG with an external app rather than a self-created one. 396 */ 397 @Test 398 public void externalApp() throws IOException, ConfigException, UnsupportedPlatformException { 399 // only run with full tests 400 Assume.assumeTrue(Boolean.parseBoolean(System.getProperty("FULL_TEST"))); 401 402 // first create the external app 403 Bundler appBundler = new MacAppBundler(); 404 405 Map<String, Object> appBundleParams = new HashMap<>(); 406 407 appBundleParams.put(BUILD_ROOT.getID(), tmpBase); 408 409 appBundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources)); 410 appBundleParams.put(APP_NAME.getID(), "External APP PKG Test"); 411 appBundleParams.put(IDENTIFIER.getID(), "com.example.pkg.external"); 412 appBundleParams.put(VERBOSE.getID(), true); 413 414 if (runtimeJdk != null) { 415 appBundleParams.put(MAC_RUNTIME.getID(), runtimeJdk); 416 } 417 418 String keychain = null; 419 if (!signingKeysPresent) { 420 keychain = createFakeCerts(appBundleParams); 421 if (keychain != null) { 422 appBundleParams.put(SIGNING_KEYCHAIN.getID(), keychain); 423 } 424 } 425 426 boolean valid = appBundler.validate(appBundleParams); 427 assertTrue(valid); 428 429 File appOutput = appBundler.execute(appBundleParams, new File(workDir, "PKGExternalApp1")); 430 System.err.println("App at - " + appOutput); 431 assertNotNull(appOutput); 432 assertTrue(appOutput.exists()); 433 434 // now create the PKG referencing this external app 435 Bundler pkgBundler = new MacPkgBundler(); 436 437 Map<String, Object> pkgBundleParams = new HashMap<>(); 438 439 pkgBundleParams.put(BUILD_ROOT.getID(), tmpBase); 440 441 pkgBundleParams.put(MAC_APP_IMAGE.getID(), appOutput); 442 pkgBundleParams.put(APP_NAME.getID(), "External APP PKG Test"); 443 pkgBundleParams.put(IDENTIFIER.getID(), "com.example.pkg.external"); 444 445 pkgBundleParams.put(VERBOSE.getID(), true); 446 447 if (runtimeJdk != null) { 448 pkgBundleParams.put(MAC_RUNTIME.getID(), runtimeJdk); 449 } 450 if (keychain != null) { 451 pkgBundleParams.put(SIGNING_KEYCHAIN.getID(), keychain); 452 } 453 454 valid = pkgBundler.validate(pkgBundleParams); 455 assertTrue(valid); 456 457 File pkgOutput = pkgBundler.execute(pkgBundleParams, new File(workDir, "PKGExternalApp2")); 458 System.err.println(".pkg at - " + pkgOutput); 459 assertNotNull(pkgOutput); 460 assertTrue(pkgOutput.exists()); 461 assertTrue(pkgOutput.length() > MIN_SIZE); 462 463 if (signingKeysPresent || keychain != null) { 464 validateSignatures(pkgOutput); 465 } 466 467 } 468 469 @Test(expected = ConfigException.class) 470 public void externanNoAppName() throws ConfigException, UnsupportedPlatformException { 471 Bundler pkgBundler = new MacPkgBundler(); 472 473 Map<String, Object> pkgBundleParams = new HashMap<>(); 474 475 pkgBundleParams.put(BUILD_ROOT.getID(), tmpBase); 476 477 pkgBundleParams.put(MAC_APP_IMAGE.getID(), "."); 478 pkgBundleParams.put(IDENTIFIER.getID(), "net.example.bogus"); 479 pkgBundleParams.put(VERBOSE.getID(), true); 480 481 pkgBundler.validate(pkgBundleParams); 482 } 483 484 @Test(expected = ConfigException.class) 485 public void externanNoID() throws ConfigException, UnsupportedPlatformException { 486 Bundler pkgBundler = new MacPkgBundler(); 487 488 Map<String, Object> pkgBundleParams = new HashMap<>(); 489 490 pkgBundleParams.put(BUILD_ROOT.getID(), tmpBase); 491 492 pkgBundleParams.put(MAC_APP_IMAGE.getID(), "."); 493 pkgBundleParams.put(APP_NAME.getID(), "Bogus App"); 494 pkgBundleParams.put(VERBOSE.getID(), true); 495 496 pkgBundler.validate(pkgBundleParams); 497 } 498 499 @Test(expected = ConfigException.class) 500 public void invalidLicenseFile() throws ConfigException, UnsupportedPlatformException { 501 Bundler bundler = new MacPkgBundler(); 502 503 Map<String, Object> bundleParams = new HashMap<>(); 504 505 bundleParams.put(BUILD_ROOT.getID(), tmpBase); 506 507 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources)); 508 bundleParams.put(LICENSE_FILE.getID(), "BOGUS_LICENSE"); 509 510 bundler.validate(bundleParams); 511 } 512 513 /** 514 * Test a misconfiguration where signature is requested but no key is specified. 515 */ 516 @Test 517 public void signButNoCert() throws IOException, ConfigException, UnsupportedPlatformException { 518 // only run with full tests 519 Assume.assumeTrue(Boolean.parseBoolean(System.getProperty("FULL_TEST"))); 520 521 try { 522 // first create the external app 523 Bundler appBundler = new MacAppBundler(); 524 525 Map<String, Object> appBundleParams = new HashMap<>(); 526 527 appBundleParams.put(BUILD_ROOT.getID(), tmpBase); 528 529 appBundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources)); 530 appBundleParams.put(APP_NAME.getID(), "External APP PKG Negative Signature Test"); 531 appBundleParams.put(IDENTIFIER.getID(), "com.example.pkg.external"); 532 appBundleParams.put(VERBOSE.getID(), true); 533 534 if (runtimeJdk != null) { 535 appBundleParams.put(MAC_RUNTIME.getID(), runtimeJdk); 536 } 537 538 boolean valid = appBundler.validate(appBundleParams); 539 assertTrue(valid); 540 541 File appOutput = appBundler.execute(appBundleParams, new File(workDir, "PKGExternalAppSignTest")); 542 System.err.println("App at - " + appOutput); 543 assertNotNull(appOutput); 544 assertTrue(appOutput.exists()); 545 546 // now create the PKG referencing this external app 547 Bundler pkgBundler = new MacPkgBundler(); 548 549 Map<String, Object> pkgBundleParams = new HashMap<>(); 550 551 pkgBundleParams.put(BUILD_ROOT.getID(), tmpBase); 552 553 pkgBundleParams.put(MAC_APP_IMAGE.getID(), appOutput); 554 pkgBundleParams.put(APP_NAME.getID(), "Negative Signature Test"); 555 pkgBundleParams.put(IDENTIFIER.getID(), "com.example.pkg.external"); 556 557 pkgBundleParams.put(SIGN_BUNDLE.getID(), true); 558 pkgBundleParams.put(DEVELOPER_ID_INSTALLER_SIGNING_KEY.getID(), null); 559 560 pkgBundler.validate(pkgBundleParams); 561 562 // if we get here we fail 563 assertTrue("ConfigException should have been thrown", false); 564 } catch (ConfigException ignore) { 565 // expected 566 } 567 } 568 569 @Test 570 public void configureEverything() throws Exception { 571 AbstractBundler bundler = new MacPkgBundler(); 572 Collection<BundlerParamInfo<?>> parameters = bundler.getBundleParameters(); 573 574 Map<String, Object> bundleParams = new HashMap<>(); 575 576 bundleParams.put(APP_NAME.getID(), "Everything App Name"); 577 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources)); 578 bundleParams.put(ARGUMENTS.getID(), Arrays.asList("He Said", "She Said")); 579 bundleParams.put(BUNDLE_ID_SIGNING_PREFIX.getID(), "everything.signing.prefix."); 580 bundleParams.put(CLASSPATH.getID(), "mainApp.jar"); 581 bundleParams.put(ICON_ICNS.getID(), hdpiIcon); 582 bundleParams.put(INSTALLER_SUFFIX.getID(), "-PKG-TEST"); 583 bundleParams.put(JVM_OPTIONS.getID(), "-Xms128M"); 584 bundleParams.put(JVM_PROPERTIES.getID(), "everything.jvm.property=everything.jvm.property.value"); 585 bundleParams.put(MAC_CATEGORY.getID(), "public.app-category.developer-tools"); 586 bundleParams.put(MAC_CF_BUNDLE_IDENTIFIER.getID(), "com.example.everything.cf-bundle-identifier"); 587 bundleParams.put(MAC_CF_BUNDLE_NAME.getID(), "Everything CF Bundle Name"); 588 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk == null ? System.getProperty("java.home") : runtimeJdk); 589 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle"); 590 bundleParams.put(MAIN_JAR.getID(), "mainApp.jar"); 591 bundleParams.put(PREFERENCES_ID.getID(), "everything/preferences/id"); 592 bundleParams.put(PRELOADER_CLASS.getID(), "hello.HelloPreloader"); 593 bundleParams.put(SIGNING_KEYCHAIN.getID(), ""); 594 bundleParams.put(USER_JVM_OPTIONS.getID(), "-Xmx=256M\n"); 595 bundleParams.put(VERSION.getID(), "1.2.3.4"); 596 597 //bundleParams.put(IDENTIFIER.getID(), "com.example.everything.identifier"); 598 bundleParams.put(DEVELOPER_ID_INSTALLER_SIGNING_KEY.getID(), "Developer ID Installer"); 599 bundleParams.put(LICENSE_FILE.getID(), "LICENSE"); 600 //bundleParams.put(SERVICE_HINT.getID(), false); 601 602 // assert they are set 603 for (BundlerParamInfo bi :parameters) { 604 assertNotNull("Bundle args Contains " + bi.getID(), bundleParams.containsKey(bi.getID())); 605 } 606 607 // and only those are set 608 bundleParamLoop: 609 for (String s :bundleParams.keySet()) { 610 for (BundlerParamInfo<?> bpi : parameters) { 611 if (s.equals(bpi.getID())) { 612 continue bundleParamLoop; 613 } 614 } 615 fail("Enumerated parameters does not contain " + s); 616 } 617 618 // assert they resolve 619 for (BundlerParamInfo bi :parameters) { 620 bi.fetchFrom(bundleParams); 621 } 622 623 // add verbose now that we are done scoping out parameters 624 bundleParams.put(BUILD_ROOT.getID(), tmpBase); 625 bundleParams.put(VERBOSE.getID(), true); 626 627 // assert it validates 628 boolean valid = bundler.validate(bundleParams); 629 assertTrue(valid); 630 631 // only run the bundle with full tests 632 Assume.assumeTrue(Boolean.parseBoolean(System.getProperty("FULL_TEST"))); 633 634 // but first remove signing keys, test servers don't have these... 635 bundleParams.remove(DEVELOPER_ID_INSTALLER_SIGNING_KEY.getID()); 636 637 File result = bundler.execute(bundleParams, new File(workDir, "everything")); 638 System.err.println("Bundle at - " + result); 639 assertNotNull(result); 640 assertTrue(result.exists()); 641 assertTrue(result.length() > MIN_SIZE); 642 } 643 644 public void validateSignatures(File appLocation) throws IOException { 645 // Check the signatures with pkgUtil 646 ProcessBuilder pb = new ProcessBuilder( 647 "pkgutil", "--check-signature", 648 appLocation.getCanonicalPath()); 649 IOUtils.exec(pb, true); 650 } 651 652 }