OakMachine { final void internalProcessSubpackage(final @NotNull Session admin, final @NotNull JcrPackageManager manager, final @NotNull PackageId packageId, final boolean preInstall, final @NotNull Fun.ThrowingSupplier<JcrPackage> jcrPackageSupplier, final @NotNull Fun.ThrowingConsumer<ProgressCheck> identifyEvent, final @NotNull Consumer<Exception> onError) throws RepositoryException { try (JcrPackage jcrPackage = jcrPackageSupplier.tryGet()) { if (jcrPackage != null) { propagateCheckPackageEvent(preInstall, packageId, identifyEvent); processPackage(admin, manager, jcrPackage, preInstall); } else { throw new PackageException("JcrPackageManager returned null package"); } } catch (IOException | PackageException | RepositoryException e) { onError.accept(e); admin.refresh(false); } catch (Exception e) { onError.accept(e); } } private  OakMachine(final Packaging packagingService,
                       final List<ProgressCheck> progressChecks,
                       final ErrorListener errorListener,
                       final List<URL> preInstallUrls,
                       final List<InitStage> initStages,
                       final JcrCustomizer jcrCustomizer,
                       final InstallHookProcessorFactory installHookProcessorFactory,
                       final ClassLoader installHookClassLoader,
                       final boolean enablePreInstallHooks,
                       final InstallHookPolicy scanInstallHookPolicy,
                       final Supplier<NodeStore> nodeStoreSupplier,
                       final SubpackageSilencer subpackageSilencer,
                       final RepoInitProcessor repoInitProcessor,
                       final SlingSimulatorBackend slingSimulator,
                       final Set<String> runModes); List<ProgressCheck> getProgressChecks(); ErrorListener getErrorListener(); @Deprecated List<File> getPreInstallFiles(); List<URL> getPreInstallUrls(); @SuppressWarnings("WeakerAccess") void initAndInspect(final InspectBody<E> inspectBody); void adminInitAndInspect(final InspectBody<E> inspectBody); List<CheckReport> scanPackage(final @NotNull File... file); List<CheckReport> scanPackages(final List<File> files); static Packaging newOakpalPackagingService(); static Packaging newOakpalPackagingService(final @NotNull ClassLoader classLoader); static final String NS_URI_OAKPAL; static final String NS_PREFIX_OAKPAL; static final String LN_UNDECLARED; static final String NT_UNDECLARED; }
@Test public void testInternalProcessSubpackage_nullPackage() throws Exception { final JcrPackageManager manager = mock(JcrPackageManager.class); when(manager.open(any(PackageId.class))).thenReturn(null); final PackageId root = PackageId.fromString("my_packages:subsubtest"); final PackageId sub1 = PackageId.fromString("my_packages:subtest"); final CompletableFuture<Boolean> refreshedLatch = new CompletableFuture<>(); final Session session = mock(Session.class); doAnswer(call -> refreshedLatch.complete(call.getArgument(0))) .when(session).refresh(anyBoolean()); final CompletableFuture<Exception> eLatch = new CompletableFuture<>(); final CompletableFuture<PackageId> idLatch = new CompletableFuture<>(); final ErrorListener errorListener = mock(ErrorListener.class); doAnswer(call -> { eLatch.complete(call.getArgument(0, Exception.class)); idLatch.complete(call.getArgument(1, PackageId.class)); return true; }).when(errorListener).onSubpackageException(any(Exception.class), any(PackageId.class)); builder().withErrorListener(errorListener).build() .internalProcessSubpackage(session, manager, sub1, false, () -> manager.open(sub1), check -> check.identifySubpackage(sub1, root), error -> errorListener.onSubpackageException(error, sub1)); assertTrue("error is of type", eLatch.getNow(null) instanceof PackageException); assertEquals("package id is", sub1, idLatch.getNow(null)); assertFalse("expect session.refresh(false)", refreshedLatch.getNow(true)); }
@Test public void testInternalProcessSubpackage_throwsRuntimeException() throws Exception { final JcrPackageManager manager = mock(JcrPackageManager.class); doThrow(RuntimeException.class).when(manager).open(any(PackageId.class)); final PackageId root = PackageId.fromString("my_packages:subsubtest"); final PackageId sub1 = PackageId.fromString("my_packages:subtest"); final CompletableFuture<Boolean> refreshedLatch = new CompletableFuture<>(); final Session session = mock(Session.class); doAnswer(call -> refreshedLatch.complete(call.getArgument(0))) .when(session).refresh(anyBoolean()); final CompletableFuture<Exception> eLatch = new CompletableFuture<>(); final CompletableFuture<PackageId> idLatch = new CompletableFuture<>(); final ErrorListener errorListener = mock(ErrorListener.class); doAnswer(call -> { eLatch.complete(call.getArgument(0, Exception.class)); idLatch.complete(call.getArgument(1, PackageId.class)); return true; }).when(errorListener).onSubpackageException(any(Exception.class), any(PackageId.class)); builder().withErrorListener(errorListener).build() .internalProcessSubpackage(session, manager, sub1, false, () -> manager.open(sub1), check -> check.identifySubpackage(sub1, root), error -> errorListener.onSubpackageException(error, sub1)); assertTrue("error is of type", eLatch.getNow(null) instanceof RuntimeException); assertEquals("package id is", sub1, idLatch.getNow(null)); assertFalse("expect not called session.refresh(false)", refreshedLatch.isDone()); session.refresh(true); assertTrue("expect session.refresh(true) on cleanup", refreshedLatch.getNow(false)); }