186 System.err.println("Could not clean up " + tmpBase.toString());
187 }
188 }
189
190
191 @Test
192 public void testValidateVersion() {
193 MacAppBundler b = new MacAppBundler();
194 String validVersions[] = {"1", "255", "1.0", "1.0.0", "255.255.0", "255.255.6000"};
195 String invalidVersions[] = {null, "alpha", "1.0-alpha", "0.300", "-300", "1.-1", "1.1.-1"};
196
197 for(String v: validVersions) {
198 assertTrue("Expect to be valid ["+v+"]",
199 MacAppBundler.validCFBundleVersion(v));
200 try {
201 Map<String, Object> params = new HashMap<>();
202 params.put(BUILD_ROOT.getID(), tmpBase);
203 params.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
204
205 if (runtimeJdk != null) {
206 params.put(MAC_RUNTIME.getID(), runtimeJdk);
207 }
208
209 params.put(VERSION.getID(), v);
210 b.validate(params);
211 } catch (ConfigException ce) {
212 ce.printStackTrace();
213 assertTrue("Expect to be valid via '" + VERSION.getID() + "' ["+v+"]",
214 false);
215 } catch (UnsupportedPlatformException ignore) {
216 }
217 try {
218 Map<String, Object> params = new HashMap<>();
219 params.put(BUILD_ROOT.getID(), tmpBase);
220 params.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
221
222 if (runtimeJdk != null) {
223 params.put(MAC_RUNTIME.getID(), runtimeJdk);
224 }
225
226 params.put(MAC_CF_BUNDLE_VERSION.getID(), v);
227 b.validate(params);
228 } catch (ConfigException ce) {
229 assertTrue("Expect to be valid via '" + VERSION.getID() + "' ["+v+"]",
230 false);
231 } catch (UnsupportedPlatformException ignore) {
232 }
233 }
234
235 for(String v: invalidVersions) {
236 assertFalse("Expect to be invalid ["+v+"]",
237 MacAppBundler.validCFBundleVersion(v));
238 try {
239 Map<String, Object> params = new HashMap<>();
240 params.put(BUILD_ROOT.getID(), tmpBase);
241 params.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
242
243 if (runtimeJdk != null) {
244 params.put(MAC_RUNTIME.getID(), runtimeJdk);
245 }
246
247 params.put(VERSION.getID(), v);
248 b.validate(params);
249 assertFalse("Invalid appVersion is not the mac.CFBundleVersion", MAC_CF_BUNDLE_VERSION.fetchFrom(params).equals(VERSION.fetchFrom(params)));
250 } catch (ConfigException ce) {
251 ce.printStackTrace();
252 assertTrue("Expect to be ignored when invalid via '" + VERSION.getID() + "' ["+v+"]",
253 false);
254 } catch (UnsupportedPlatformException ignore) {
255 }
256 try {
257 Map<String, Object> params = new HashMap<>();
258 params.put(BUILD_ROOT.getID(), tmpBase);
259 params.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
260
261 if (runtimeJdk != null) {
262 params.put(MAC_RUNTIME.getID(), runtimeJdk);
263 }
264
265 params.put(MAC_CF_BUNDLE_VERSION.getID(), v);
266 b.validate(params);
267 assertTrue("Expect to be invalid via '" + VERSION.getID() + "' ["+v+"]",
268 false);
269 } catch (ConfigException | UnsupportedPlatformException ignore) {
270 }
271 }
272 }
273
274
275 /**
276 * See if smoke comes out
277 */
278 @Test
279 public void smokeTest() throws IOException, ConfigException, UnsupportedPlatformException {
280 AbstractBundler bundler = new MacAppBundler();
281
282 assertNotNull(bundler.getName());
285 //assertNotNull(bundler.getBundleParameters());
286
287 Map<String, Object> bundleParams = new HashMap<>();
288
289 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
290
291 bundleParams.put(APP_NAME.getID(), "Smoke Test App");
292 bundleParams.put(MAC_CF_BUNDLE_NAME.getID(), "Smoke");
293 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
294 bundleParams.put(PREFERENCES_ID.getID(), "the/really/long/preferences/id");
295 bundleParams.put(MAIN_JAR.getID(),
296 new RelativeFileSet(fakeMainJar.getParentFile(),
297 new HashSet<>(Arrays.asList(fakeMainJar)))
298 );
299 bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
300 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
301 bundleParams.put(VERBOSE.getID(), true);
302 bundleParams.put(SIGN_BUNDLE.getID(), false);
303
304 if (runtimeJdk != null) {
305 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
306 }
307
308 boolean valid = bundler.validate(bundleParams);
309 assertTrue(valid);
310
311 File result = bundler.execute(bundleParams, new File(workDir, "smoke"));
312 System.err.println("Bundle at - " + result);
313 assertNotNull(result);
314 assertTrue(result.exists());
315 }
316
317 /**
318 * Set File Association
319 */
320 @Test
321 public void testFileAssociation()
322 throws IOException, ConfigException, UnsupportedPlatformException
323 {
324 // only run the bundle with full tests
325 Assume.assumeTrue(Boolean.parseBoolean(System.getProperty("FULL_TEST")));
385 private void testFileAssociationMultiples(String appName, String[] description, String[] extensions,
386 String[] contentType, File[] icon)
387 throws IOException, ConfigException, UnsupportedPlatformException
388 {
389 assertEquals("Sanity: description same length as extensions", description.length, extensions.length);
390 assertEquals("Sanity: extensions same length as contentType", extensions.length, contentType.length);
391 assertEquals("Sanity: contentType same length as icon", contentType.length, icon.length);
392
393 AbstractBundler bundler = new MacAppBundler();
394
395 assertNotNull(bundler.getName());
396 assertNotNull(bundler.getID());
397 assertNotNull(bundler.getDescription());
398 //assertNotNull(bundler.getBundleParameters());
399
400 Map<String, Object> bundleParams = new HashMap<>();
401
402 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
403
404 if (runtimeJdk != null) {
405 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
406 }
407
408 bundleParams.put(APP_NAME.getID(), appName);
409 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
410 bundleParams.put(MAIN_JAR.getID(),
411 new RelativeFileSet(fakeMainJar.getParentFile(),
412 new HashSet<>(Arrays.asList(fakeMainJar)))
413 );
414 bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
415 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
416 bundleParams.put(VERBOSE.getID(), true);
417 bundleParams.put(SIGN_BUNDLE.getID(), false);
418
419 List<Map<String, Object>> associations = new ArrayList<>();
420
421 for (int i = 0; i < description.length; i++) {
422 Map<String, Object> fileAssociation = new HashMap<>();
423 fileAssociation.put(FA_DESCRIPTION.getID(), description[i]);
424 fileAssociation.put(FA_EXTENSIONS.getID(), extensions[i]);
425 fileAssociation.put(FA_CONTENT_TYPE.getID(), contentType[i]);
446 public void quarantinedAppTest() throws IOException, ConfigException, UnsupportedPlatformException {
447 AbstractBundler bundler = new MacAppBundler();
448
449 assertNotNull(bundler.getName());
450 assertNotNull(bundler.getID());
451 assertNotNull(bundler.getDescription());
452 //assertNotNull(bundler.getBundleParameters());
453
454 Map<String, Object> bundleParams = new HashMap<>();
455
456 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
457
458 bundleParams.put(APP_NAME.getID(), "Quarantined Test App");
459 bundleParams.put(MAC_CF_BUNDLE_NAME.getID(), "Quarantine");
460 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
461 bundleParams.put(PREFERENCES_ID.getID(), "the/really/long/preferences/id");
462 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
463 bundleParams.put(VERBOSE.getID(), true);
464
465 if (runtimeJdk != null) {
466 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
467 }
468
469 if (!signingKeysPresent) {
470 String keychain = createFakeCerts(bundleParams);
471 Assume.assumeNotNull(keychain);
472 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain);
473 }
474
475 boolean valid = bundler.validate(bundleParams);
476 assertTrue(valid);
477
478 File result = bundler.execute(bundleParams, new File(workDir, "quarantine"));
479 System.err.println("Bundle at - " + result);
480 assertNotNull(result);
481 assertTrue(result.exists());
482 validateSignatures(result);
483
484 // mark it as though it's been downloaded
485 ProcessBuilder pb = new ProcessBuilder(
486 "xattr", "-w", "com.apple.quarantine",
493 * The bare minimum configuration needed to make it work
494 * <ul>
495 * <li>Where to build it</li>
496 * <li>The jar containing the application (with a main-class attribute)</li>
497 * </ul>
498 *
499 * All other values will be driven off of those two values.
500 */
501 @Test
502 public void minimumConfig() throws IOException, ConfigException, UnsupportedPlatformException {
503 Bundler bundler = new MacAppBundler();
504
505 Map<String, Object> bundleParams = new HashMap<>();
506
507 // not part of the typical setup, for testing
508 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
509
510 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
511
512 if (runtimeJdk != null) {
513 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
514 }
515
516 String keychain = null;
517 if (!signingKeysPresent) {
518 keychain = createFakeCerts(bundleParams);
519 if (keychain != null) {
520 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain);
521 }
522 }
523
524 File output = bundler.execute(bundleParams, new File(workDir, "BareMinimum"));
525 System.err.println("Bundle at - " + output);
526 assertNotNull(output);
527 assertTrue(output.exists());
528 if (signingKeysPresent || keychain != null) {
529 validateSignatures(output);
530 }
531 }
532
533 /**
534 * Test with unicode in places we expect it to be
535 */
536 @Test
537 public void unicodeConfig() throws IOException, ConfigException, UnsupportedPlatformException {
538 Bundler bundler = new MacAppBundler();
539
540 Map<String, Object> bundleParams = new HashMap<>();
541
542 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
543
544 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
545
546 bundleParams.put(APP_NAME.getID(), "хелловорлд");
547 bundleParams.put(TITLE.getID(), "ХеллоВорлд аппликейшн");
548 bundleParams.put(VENDOR.getID(), "Оракл девелопмент");
549 bundleParams.put(DESCRIPTION.getID(), "крайне большое описание со странными символами");
550
551 if (runtimeJdk != null) {
552 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
553 }
554
555 String keychain = null;
556 if (!signingKeysPresent) {
557 keychain = createFakeCerts(bundleParams);
558 if (keychain != null) {
559 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain);
560 }
561 }
562
563 bundler.validate(bundleParams);
564
565 File output = bundler.execute(bundleParams, new File(workDir, "Unicode"));
566 System.err.println("Bundle at - " + output);
567 assertNotNull(output);
568 assertTrue(output.exists());
569 if (signingKeysPresent || keychain != null) {
570 validateSignatures(output);
571 }
572 }
573
574 /**
575 * Test a misconfiguration where the runtime is misconfigured.
576 */
577 @Test(expected = ConfigException.class)
578 public void runtimeBad() throws IOException, ConfigException, UnsupportedPlatformException {
579 Bundler bundler = new MacAppBundler();
580
581 Map<String, Object> bundleParams = new HashMap<>();
582
583 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
584 bundleParams.put(VERBOSE.getID(), true);
585
586 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
587 bundleParams.put(MAC_RUNTIME.getID(), APP_RESOURCES.fetchFrom(bundleParams));
588
589 bundler.validate(bundleParams);
590 }
591
592 /**
593 * Test a misconfiguration where signature is requested but no key is kept.
594 */
595 @Test(expected = ConfigException.class)
596 public void signButNoCert() throws IOException, ConfigException, UnsupportedPlatformException {
597 Bundler bundler = new MacAppBundler();
598
599 Map<String, Object> bundleParams = new HashMap<>();
600
601 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
602 bundleParams.put(VERBOSE.getID(), true);
603
604 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
605
606 bundleParams.put(SIGN_BUNDLE.getID(), true);
607 bundleParams.put(DEVELOPER_ID_APP_SIGNING_KEY.getID(), null);
612 @Test
613 public void configureEverything() throws Exception {
614 AbstractBundler bundler = new MacAppBundler();
615 Collection<BundlerParamInfo<?>> parameters = bundler.getBundleParameters();
616
617 Map<String, Object> bundleParams = new HashMap<>();
618
619 bundleParams.put(APP_NAME.getID(), "Everything App Name");
620 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
621 bundleParams.put(ARGUMENTS.getID(), Arrays.asList("He Said", "She Said"));
622 bundleParams.put(BUNDLE_ID_SIGNING_PREFIX.getID(), "everything.signing.prefix.");
623 bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
624 bundleParams.put(DEVELOPER_ID_APP_SIGNING_KEY.getID(), "Developer ID Application");
625 bundleParams.put(ICON_ICNS.getID(), hdpiIcon);
626 bundleParams.put(JVM_OPTIONS.getID(), "-Xms128M");
627 bundleParams.put(JVM_PROPERTIES.getID(), "everything.jvm.property=everything.jvm.property.value");
628 bundleParams.put(MAC_CATEGORY.getID(), "public.app-category.developer-tools");
629 bundleParams.put(MAC_CF_BUNDLE_IDENTIFIER.getID(), "com.example.everything.cf-bundle-identifier");
630 bundleParams.put(MAC_CF_BUNDLE_NAME.getID(), "Everything CF Bundle Name");
631 bundleParams.put(MAC_CF_BUNDLE_VERSION.getID(), "8.2.0");
632 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk == null ? System.getProperty("java.home") : runtimeJdk);
633 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
634 bundleParams.put(MAIN_JAR.getID(), "mainApp.jar");
635 bundleParams.put(PREFERENCES_ID.getID(), "everything/preferences/id");
636 bundleParams.put(PRELOADER_CLASS.getID(), "hello.HelloPreloader");
637 bundleParams.put(SIGNING_KEYCHAIN.getID(), "");
638 bundleParams.put(USER_JVM_OPTIONS.getID(), "-Xmx=256M\n");
639 bundleParams.put(VERSION.getID(), "1.2.3.4");
640
641 // assert they are set
642 for (BundlerParamInfo bi :parameters) {
643 assertTrue("Bundle args should contain " + bi.getID(), bundleParams.containsKey(bi.getID()));
644 }
645
646 // and only those are set
647 bundleParamLoop:
648 for (String s :bundleParams.keySet()) {
649 for (BundlerParamInfo<?> bpi : parameters) {
650 if (s.equals(bpi.getID())) {
651 continue bundleParamLoop;
652 }
690
691 Map<String, Object> bundleParams = new HashMap<>();
692
693 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
694
695 bundleParams.put(APP_NAME.getID(), "User JVM Options App - " + name);
696 bundleParams.put(MAC_CF_BUNDLE_NAME.getID(), name + ".application");
697 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
698 bundleParams.put(IDENTIFIER.getID(), name);
699 bundleParams.put(PREFERENCES_ID.getID(), name.replace(".", "/"));
700 bundleParams.put(MAIN_JAR.getID(),
701 new RelativeFileSet(fakeMainJar.getParentFile(),
702 new HashSet<>(Arrays.asList(fakeMainJar)))
703 );
704 bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
705 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
706 bundleParams.put(VERBOSE.getID(), true);
707 bundleParams.put(SIGN_BUNDLE.getID(), false); // force no signing
708
709 if (runtimeJdk != null) {
710 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
711 }
712
713 boolean valid = bundler.validate(bundleParams);
714 assertTrue(valid);
715
716 File result = bundler.execute(bundleParams, new File(workDir, "UserOpts-" + name.replace(".", "-")));
717 System.err.println("Bundle at - " + result);
718 assertNotNull(result);
719 assertTrue(result.exists());
720 }
721 }
722
723
724 /**
725 * User a JRE instead of a JDK
726 */
727 @Test
728 public void testJRE() throws IOException, ConfigException, UnsupportedPlatformException {
729 String jre = runtimeJre == null ? "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/" : runtimeJre;
730 Assume.assumeTrue(new File(jre).isDirectory());
731
732 Bundler bundler = new MacAppBundler();
733
734 Map<String, Object> bundleParams = new HashMap<>();
735
736 // not part of the typical setup, for testing
737 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
738
739 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
740 bundleParams.put(MAC_RUNTIME.getID(), jre);
741
742 String keychain = null;
743 if (!signingKeysPresent) {
744 keychain = createFakeCerts(bundleParams);
745 if (keychain != null) {
746 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain);
747 }
748 }
749
750 boolean valid = bundler.validate(bundleParams);
751 assertTrue(valid);
752
753 File output = bundler.execute(bundleParams, new File(workDir, "JRETest"));
754 System.err.println("Bundle at - " + output);
755 assertNotNull(output);
756 assertTrue(output.exists());
757 if (signingKeysPresent || keychain != null) {
758 validateSignatures(output);
759 }
760 }
762 /**
763 * Turn on AppCDS
764 */
765 @Ignore@Test
766 public void testAppCDS() throws IOException, ConfigException, UnsupportedPlatformException {
767 Bundler bundler = new MacAppBundler();
768
769 Map<String, Object> bundleParams = new HashMap<>();
770
771 // not part of the typical setup, for testing
772 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
773 bundleParams.put(VERBOSE.getID(), true);
774
775 bundleParams.put(APP_NAME.getID(), "AppCDSTest");
776 bundleParams.put(IDENTIFIER.getID(), "com.example.appcds.Test");
777 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
778 bundleParams.put(UNLOCK_COMMERCIAL_FEATURES.getID(), true);
779 bundleParams.put(ENABLE_APP_CDS.getID(), true);
780
781 if (runtimeJdk != null) {
782 bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
783 }
784
785 boolean valid = bundler.validate(bundleParams);
786 assertTrue(valid);
787
788 File output = bundler.execute(bundleParams, new File(workDir, "CDSTest"));
789 System.err.println("Bundle at - " + output);
790 assertNotNull(output);
791 assertTrue(output.exists());
792 }
793
794 /**
795 * Verify a match on too many keys doesn't blow things up
796 */
797 @Test
798 public void testTooManyKeyMatches() {
799 Assume.assumeTrue(MacBaseInstallerBundler.findKey("Developer ID Application:", null, true) != null);
800 Assume.assumeTrue(MacBaseInstallerBundler.findKey("Developer ID Installer:", null, true) != null);
801 assertTrue(MacBaseInstallerBundler.findKey("Developer", null, true) == null);
802 assertTrue(MacBaseInstallerBundler.findKey("A completely bogus key that should never realistically exist unless we are attempting to falsely break the tests", null, true) == null);
|
186 System.err.println("Could not clean up " + tmpBase.toString());
187 }
188 }
189
190
191 @Test
192 public void testValidateVersion() {
193 MacAppBundler b = new MacAppBundler();
194 String validVersions[] = {"1", "255", "1.0", "1.0.0", "255.255.0", "255.255.6000"};
195 String invalidVersions[] = {null, "alpha", "1.0-alpha", "0.300", "-300", "1.-1", "1.1.-1"};
196
197 for(String v: validVersions) {
198 assertTrue("Expect to be valid ["+v+"]",
199 MacAppBundler.validCFBundleVersion(v));
200 try {
201 Map<String, Object> params = new HashMap<>();
202 params.put(BUILD_ROOT.getID(), tmpBase);
203 params.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
204
205 if (runtimeJdk != null) {
206 //FIXME params.put(MAC_RUNTIME.getID(), runtimeJdk);
207 }
208
209 params.put(VERSION.getID(), v);
210 b.validate(params);
211 } catch (ConfigException ce) {
212 ce.printStackTrace();
213 assertTrue("Expect to be valid via '" + VERSION.getID() + "' ["+v+"]",
214 false);
215 } catch (UnsupportedPlatformException ignore) {
216 }
217 try {
218 Map<String, Object> params = new HashMap<>();
219 params.put(BUILD_ROOT.getID(), tmpBase);
220 params.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
221
222 if (runtimeJdk != null) {
223 //FIXME params.put(MAC_RUNTIME.getID(), runtimeJdk);
224 }
225
226 params.put(MAC_CF_BUNDLE_VERSION.getID(), v);
227 b.validate(params);
228 } catch (ConfigException ce) {
229 assertTrue("Expect to be valid via '" + VERSION.getID() + "' ["+v+"]",
230 false);
231 } catch (UnsupportedPlatformException ignore) {
232 }
233 }
234
235 for(String v: invalidVersions) {
236 assertFalse("Expect to be invalid ["+v+"]",
237 MacAppBundler.validCFBundleVersion(v));
238 try {
239 Map<String, Object> params = new HashMap<>();
240 params.put(BUILD_ROOT.getID(), tmpBase);
241 params.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
242
243 if (runtimeJdk != null) {
244 //FIXME params.put(MAC_RUNTIME.getID(), runtimeJdk);
245 }
246
247 params.put(VERSION.getID(), v);
248 b.validate(params);
249 assertFalse("Invalid appVersion is not the mac.CFBundleVersion", MAC_CF_BUNDLE_VERSION.fetchFrom(params).equals(VERSION.fetchFrom(params)));
250 } catch (ConfigException ce) {
251 ce.printStackTrace();
252 assertTrue("Expect to be ignored when invalid via '" + VERSION.getID() + "' ["+v+"]",
253 false);
254 } catch (UnsupportedPlatformException ignore) {
255 }
256 try {
257 Map<String, Object> params = new HashMap<>();
258 params.put(BUILD_ROOT.getID(), tmpBase);
259 params.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
260
261 if (runtimeJdk != null) {
262 //FIXME params.put(MAC_RUNTIME.getID(), runtimeJdk);
263 }
264
265 params.put(MAC_CF_BUNDLE_VERSION.getID(), v);
266 b.validate(params);
267 assertTrue("Expect to be invalid via '" + VERSION.getID() + "' ["+v+"]",
268 false);
269 } catch (ConfigException | UnsupportedPlatformException ignore) {
270 }
271 }
272 }
273
274
275 /**
276 * See if smoke comes out
277 */
278 @Test
279 public void smokeTest() throws IOException, ConfigException, UnsupportedPlatformException {
280 AbstractBundler bundler = new MacAppBundler();
281
282 assertNotNull(bundler.getName());
285 //assertNotNull(bundler.getBundleParameters());
286
287 Map<String, Object> bundleParams = new HashMap<>();
288
289 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
290
291 bundleParams.put(APP_NAME.getID(), "Smoke Test App");
292 bundleParams.put(MAC_CF_BUNDLE_NAME.getID(), "Smoke");
293 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
294 bundleParams.put(PREFERENCES_ID.getID(), "the/really/long/preferences/id");
295 bundleParams.put(MAIN_JAR.getID(),
296 new RelativeFileSet(fakeMainJar.getParentFile(),
297 new HashSet<>(Arrays.asList(fakeMainJar)))
298 );
299 bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
300 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
301 bundleParams.put(VERBOSE.getID(), true);
302 bundleParams.put(SIGN_BUNDLE.getID(), false);
303
304 if (runtimeJdk != null) {
305 //FIXME bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
306 }
307
308 boolean valid = bundler.validate(bundleParams);
309 assertTrue(valid);
310
311 File result = bundler.execute(bundleParams, new File(workDir, "smoke"));
312 System.err.println("Bundle at - " + result);
313 assertNotNull(result);
314 assertTrue(result.exists());
315 }
316
317 /**
318 * Set File Association
319 */
320 @Test
321 public void testFileAssociation()
322 throws IOException, ConfigException, UnsupportedPlatformException
323 {
324 // only run the bundle with full tests
325 Assume.assumeTrue(Boolean.parseBoolean(System.getProperty("FULL_TEST")));
385 private void testFileAssociationMultiples(String appName, String[] description, String[] extensions,
386 String[] contentType, File[] icon)
387 throws IOException, ConfigException, UnsupportedPlatformException
388 {
389 assertEquals("Sanity: description same length as extensions", description.length, extensions.length);
390 assertEquals("Sanity: extensions same length as contentType", extensions.length, contentType.length);
391 assertEquals("Sanity: contentType same length as icon", contentType.length, icon.length);
392
393 AbstractBundler bundler = new MacAppBundler();
394
395 assertNotNull(bundler.getName());
396 assertNotNull(bundler.getID());
397 assertNotNull(bundler.getDescription());
398 //assertNotNull(bundler.getBundleParameters());
399
400 Map<String, Object> bundleParams = new HashMap<>();
401
402 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
403
404 if (runtimeJdk != null) {
405 //FIXME bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
406 }
407
408 bundleParams.put(APP_NAME.getID(), appName);
409 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
410 bundleParams.put(MAIN_JAR.getID(),
411 new RelativeFileSet(fakeMainJar.getParentFile(),
412 new HashSet<>(Arrays.asList(fakeMainJar)))
413 );
414 bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
415 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
416 bundleParams.put(VERBOSE.getID(), true);
417 bundleParams.put(SIGN_BUNDLE.getID(), false);
418
419 List<Map<String, Object>> associations = new ArrayList<>();
420
421 for (int i = 0; i < description.length; i++) {
422 Map<String, Object> fileAssociation = new HashMap<>();
423 fileAssociation.put(FA_DESCRIPTION.getID(), description[i]);
424 fileAssociation.put(FA_EXTENSIONS.getID(), extensions[i]);
425 fileAssociation.put(FA_CONTENT_TYPE.getID(), contentType[i]);
446 public void quarantinedAppTest() throws IOException, ConfigException, UnsupportedPlatformException {
447 AbstractBundler bundler = new MacAppBundler();
448
449 assertNotNull(bundler.getName());
450 assertNotNull(bundler.getID());
451 assertNotNull(bundler.getDescription());
452 //assertNotNull(bundler.getBundleParameters());
453
454 Map<String, Object> bundleParams = new HashMap<>();
455
456 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
457
458 bundleParams.put(APP_NAME.getID(), "Quarantined Test App");
459 bundleParams.put(MAC_CF_BUNDLE_NAME.getID(), "Quarantine");
460 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
461 bundleParams.put(PREFERENCES_ID.getID(), "the/really/long/preferences/id");
462 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
463 bundleParams.put(VERBOSE.getID(), true);
464
465 if (runtimeJdk != null) {
466 //FIXME bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
467 }
468
469 if (!signingKeysPresent) {
470 String keychain = createFakeCerts(bundleParams);
471 Assume.assumeNotNull(keychain);
472 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain);
473 }
474
475 boolean valid = bundler.validate(bundleParams);
476 assertTrue(valid);
477
478 File result = bundler.execute(bundleParams, new File(workDir, "quarantine"));
479 System.err.println("Bundle at - " + result);
480 assertNotNull(result);
481 assertTrue(result.exists());
482 validateSignatures(result);
483
484 // mark it as though it's been downloaded
485 ProcessBuilder pb = new ProcessBuilder(
486 "xattr", "-w", "com.apple.quarantine",
493 * The bare minimum configuration needed to make it work
494 * <ul>
495 * <li>Where to build it</li>
496 * <li>The jar containing the application (with a main-class attribute)</li>
497 * </ul>
498 *
499 * All other values will be driven off of those two values.
500 */
501 @Test
502 public void minimumConfig() throws IOException, ConfigException, UnsupportedPlatformException {
503 Bundler bundler = new MacAppBundler();
504
505 Map<String, Object> bundleParams = new HashMap<>();
506
507 // not part of the typical setup, for testing
508 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
509
510 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
511
512 if (runtimeJdk != null) {
513 //FIXME bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
514 }
515
516 String keychain = null;
517 if (!signingKeysPresent) {
518 keychain = createFakeCerts(bundleParams);
519 if (keychain != null) {
520 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain);
521 }
522 }
523
524 File output = bundler.execute(bundleParams, new File(workDir, "BareMinimum"));
525 System.err.println("Bundle at - " + output);
526 assertNotNull(output);
527 assertTrue(output.exists());
528 if (signingKeysPresent || keychain != null) {
529 validateSignatures(output);
530 }
531 }
532
533 /**
534 * Test with unicode in places we expect it to be
535 */
536 @Test
537 public void unicodeConfig() throws IOException, ConfigException, UnsupportedPlatformException {
538 Bundler bundler = new MacAppBundler();
539
540 Map<String, Object> bundleParams = new HashMap<>();
541
542 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
543
544 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
545
546 bundleParams.put(APP_NAME.getID(), "хелловорлд");
547 bundleParams.put(TITLE.getID(), "ХеллоВорлд аппликейшн");
548 bundleParams.put(VENDOR.getID(), "Оракл девелопмент");
549 bundleParams.put(DESCRIPTION.getID(), "крайне большое описание со странными символами");
550
551 if (runtimeJdk != null) {
552 //FIXME bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
553 }
554
555 String keychain = null;
556 if (!signingKeysPresent) {
557 keychain = createFakeCerts(bundleParams);
558 if (keychain != null) {
559 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain);
560 }
561 }
562
563 bundler.validate(bundleParams);
564
565 File output = bundler.execute(bundleParams, new File(workDir, "Unicode"));
566 System.err.println("Bundle at - " + output);
567 assertNotNull(output);
568 assertTrue(output.exists());
569 if (signingKeysPresent || keychain != null) {
570 validateSignatures(output);
571 }
572 }
573
574 /**
575 * Test a misconfiguration where the runtime is misconfigured.
576 */
577 @Test(expected = ConfigException.class)
578 public void runtimeBad() throws IOException, ConfigException, UnsupportedPlatformException {
579 Bundler bundler = new MacAppBundler();
580
581 Map<String, Object> bundleParams = new HashMap<>();
582
583 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
584 bundleParams.put(VERBOSE.getID(), true);
585
586 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
587 //FIXME bundleParams.put(MAC_RUNTIME.getID(), APP_RESOURCES.fetchFrom(bundleParams));
588
589 bundler.validate(bundleParams);
590 }
591
592 /**
593 * Test a misconfiguration where signature is requested but no key is kept.
594 */
595 @Test(expected = ConfigException.class)
596 public void signButNoCert() throws IOException, ConfigException, UnsupportedPlatformException {
597 Bundler bundler = new MacAppBundler();
598
599 Map<String, Object> bundleParams = new HashMap<>();
600
601 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
602 bundleParams.put(VERBOSE.getID(), true);
603
604 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
605
606 bundleParams.put(SIGN_BUNDLE.getID(), true);
607 bundleParams.put(DEVELOPER_ID_APP_SIGNING_KEY.getID(), null);
612 @Test
613 public void configureEverything() throws Exception {
614 AbstractBundler bundler = new MacAppBundler();
615 Collection<BundlerParamInfo<?>> parameters = bundler.getBundleParameters();
616
617 Map<String, Object> bundleParams = new HashMap<>();
618
619 bundleParams.put(APP_NAME.getID(), "Everything App Name");
620 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
621 bundleParams.put(ARGUMENTS.getID(), Arrays.asList("He Said", "She Said"));
622 bundleParams.put(BUNDLE_ID_SIGNING_PREFIX.getID(), "everything.signing.prefix.");
623 bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
624 bundleParams.put(DEVELOPER_ID_APP_SIGNING_KEY.getID(), "Developer ID Application");
625 bundleParams.put(ICON_ICNS.getID(), hdpiIcon);
626 bundleParams.put(JVM_OPTIONS.getID(), "-Xms128M");
627 bundleParams.put(JVM_PROPERTIES.getID(), "everything.jvm.property=everything.jvm.property.value");
628 bundleParams.put(MAC_CATEGORY.getID(), "public.app-category.developer-tools");
629 bundleParams.put(MAC_CF_BUNDLE_IDENTIFIER.getID(), "com.example.everything.cf-bundle-identifier");
630 bundleParams.put(MAC_CF_BUNDLE_NAME.getID(), "Everything CF Bundle Name");
631 bundleParams.put(MAC_CF_BUNDLE_VERSION.getID(), "8.2.0");
632 //FIXME bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk == null ? System.getProperty("java.home") : runtimeJdk);
633 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
634 bundleParams.put(MAIN_JAR.getID(), "mainApp.jar");
635 bundleParams.put(PREFERENCES_ID.getID(), "everything/preferences/id");
636 bundleParams.put(PRELOADER_CLASS.getID(), "hello.HelloPreloader");
637 bundleParams.put(SIGNING_KEYCHAIN.getID(), "");
638 bundleParams.put(USER_JVM_OPTIONS.getID(), "-Xmx=256M\n");
639 bundleParams.put(VERSION.getID(), "1.2.3.4");
640
641 // assert they are set
642 for (BundlerParamInfo bi :parameters) {
643 assertTrue("Bundle args should contain " + bi.getID(), bundleParams.containsKey(bi.getID()));
644 }
645
646 // and only those are set
647 bundleParamLoop:
648 for (String s :bundleParams.keySet()) {
649 for (BundlerParamInfo<?> bpi : parameters) {
650 if (s.equals(bpi.getID())) {
651 continue bundleParamLoop;
652 }
690
691 Map<String, Object> bundleParams = new HashMap<>();
692
693 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
694
695 bundleParams.put(APP_NAME.getID(), "User JVM Options App - " + name);
696 bundleParams.put(MAC_CF_BUNDLE_NAME.getID(), name + ".application");
697 bundleParams.put(MAIN_CLASS.getID(), "hello.HelloRectangle");
698 bundleParams.put(IDENTIFIER.getID(), name);
699 bundleParams.put(PREFERENCES_ID.getID(), name.replace(".", "/"));
700 bundleParams.put(MAIN_JAR.getID(),
701 new RelativeFileSet(fakeMainJar.getParentFile(),
702 new HashSet<>(Arrays.asList(fakeMainJar)))
703 );
704 bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
705 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
706 bundleParams.put(VERBOSE.getID(), true);
707 bundleParams.put(SIGN_BUNDLE.getID(), false); // force no signing
708
709 if (runtimeJdk != null) {
710 //FIXME bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
711 }
712
713 boolean valid = bundler.validate(bundleParams);
714 assertTrue(valid);
715
716 File result = bundler.execute(bundleParams, new File(workDir, "UserOpts-" + name.replace(".", "-")));
717 System.err.println("Bundle at - " + result);
718 assertNotNull(result);
719 assertTrue(result.exists());
720 }
721 }
722
723
724 /**
725 * User a JRE instead of a JDK
726 */
727 @Test
728 public void testJRE() throws IOException, ConfigException, UnsupportedPlatformException {
729 String jre = runtimeJre == null ? "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/" : runtimeJre;
730 Assume.assumeTrue(new File(jre).isDirectory());
731
732 Bundler bundler = new MacAppBundler();
733
734 Map<String, Object> bundleParams = new HashMap<>();
735
736 // not part of the typical setup, for testing
737 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
738
739 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
740 //FIXME bundleParams.put(MAC_RUNTIME.getID(), jre);
741
742 String keychain = null;
743 if (!signingKeysPresent) {
744 keychain = createFakeCerts(bundleParams);
745 if (keychain != null) {
746 bundleParams.put(SIGNING_KEYCHAIN.getID(), keychain);
747 }
748 }
749
750 boolean valid = bundler.validate(bundleParams);
751 assertTrue(valid);
752
753 File output = bundler.execute(bundleParams, new File(workDir, "JRETest"));
754 System.err.println("Bundle at - " + output);
755 assertNotNull(output);
756 assertTrue(output.exists());
757 if (signingKeysPresent || keychain != null) {
758 validateSignatures(output);
759 }
760 }
762 /**
763 * Turn on AppCDS
764 */
765 @Ignore@Test
766 public void testAppCDS() throws IOException, ConfigException, UnsupportedPlatformException {
767 Bundler bundler = new MacAppBundler();
768
769 Map<String, Object> bundleParams = new HashMap<>();
770
771 // not part of the typical setup, for testing
772 bundleParams.put(BUILD_ROOT.getID(), tmpBase);
773 bundleParams.put(VERBOSE.getID(), true);
774
775 bundleParams.put(APP_NAME.getID(), "AppCDSTest");
776 bundleParams.put(IDENTIFIER.getID(), "com.example.appcds.Test");
777 bundleParams.put(APP_RESOURCES.getID(), new RelativeFileSet(appResourcesDir, appResources));
778 bundleParams.put(UNLOCK_COMMERCIAL_FEATURES.getID(), true);
779 bundleParams.put(ENABLE_APP_CDS.getID(), true);
780
781 if (runtimeJdk != null) {
782 //FIXME bundleParams.put(MAC_RUNTIME.getID(), runtimeJdk);
783 }
784
785 boolean valid = bundler.validate(bundleParams);
786 assertTrue(valid);
787
788 File output = bundler.execute(bundleParams, new File(workDir, "CDSTest"));
789 System.err.println("Bundle at - " + output);
790 assertNotNull(output);
791 assertTrue(output.exists());
792 }
793
794 /**
795 * Verify a match on too many keys doesn't blow things up
796 */
797 @Test
798 public void testTooManyKeyMatches() {
799 Assume.assumeTrue(MacBaseInstallerBundler.findKey("Developer ID Application:", null, true) != null);
800 Assume.assumeTrue(MacBaseInstallerBundler.findKey("Developer ID Installer:", null, true) != null);
801 assertTrue(MacBaseInstallerBundler.findKey("Developer", null, true) == null);
802 assertTrue(MacBaseInstallerBundler.findKey("A completely bogus key that should never realistically exist unless we are attempting to falsely break the tests", null, true) == null);
|