DefaultSlingSimulator implements SlingSimulatorBackend, SlingSimulator { <T extends SlingInstallable> Optional<T> createInstallableOrReport(final @NotNull SlingInstallableParams<T> params, final @NotNull PackageId parentPackageId, final @NotNull String jcrPath) { try { return Optional.of(params.createInstallable(parentPackageId, jcrPath)); } catch (Exception e) { errorListener.onSlingCreateInstallableError(e, params.getInstallableType(), parentPackageId, jcrPath); return Optional.empty(); } }  static SlingSimulatorBackend instance(); @Override void startedScan(); @Override void setSession(final Session session); @Override void setPackageManager(final JcrPackageManager packageManager); @Override void setErrorListener(final ErrorListener errorListener); @Override @Nullable SlingInstallable dequeueInstallable(); @SuppressWarnings("unchecked") @Override @NotNull Fun.ThrowingSupplier<ResourceType> open(@NotNull final SlingOpenable<ResourceType> installable); @NotNull JcrPackage openEmbeddedPackage(@NotNull final EmbeddedPackageInstallable installable); @Override @Nullable SlingInstallable addInstallableNode(final @NotNull PackageId parentPackageId,
                                                         final @NotNull Node node);  }
@Test public void testCreateInstallableOrReport() throws Exception { ErrorListener errorListener = mock(ErrorListener.class); slingSimulator.setErrorListener(errorListener); final CompletableFuture<Exception> eLatch = new CompletableFuture<>(); final CompletableFuture<Class<?>> tLatch = new CompletableFuture<>(); final CompletableFuture<PackageId> idLatch = new CompletableFuture<>(); final CompletableFuture<String> pathLatch = new CompletableFuture<>(); doAnswer(call -> { eLatch.complete(call.getArgument(0, Exception.class)); tLatch.complete(call.getArgument(1, Class.class)); idLatch.complete(call.getArgument(2, PackageId.class)); pathLatch.complete(call.getArgument(3, String.class)); return true; }).when(errorListener).onSlingCreateInstallableError( any(Exception.class), any(Class.class), any(PackageId.class), anyString()); final Exception expectError = new IOException("you yamled when you should have jsoned!"); final Class<?> expectType = OsgiConfigInstallable.class; final PackageId expectId = PackageId.fromString("test"); final String expectPath = "/some/path-id.cfg.json"; final OsgiConfigInstallableParams goodParams = new OsgiConfigInstallableParams(Collections.emptyMap(), "id", "path", null); final OsgiConfigInstallableParams badParams = new OsgiConfigInstallableParams(Collections.emptyMap(), "id", "path", expectError); OsgiConfigInstallable goodInstallable = slingSimulator.createInstallableOrReport(goodParams, expectId, expectPath) .orElse(null); assertNotNull("expect non null installable for goodParams", goodInstallable); assertFalse("eLatch is not done", eLatch.isDone()); assertFalse("tLatch is not done", tLatch.isDone()); assertFalse("idLatch is not done", idLatch.isDone()); assertFalse("pathLatch is not done", pathLatch.isDone()); OsgiConfigInstallable badInstallable = slingSimulator.createInstallableOrReport(badParams, expectId, expectPath) .orElse(null); assertNull("expect null installable for badParams", badInstallable); assertSame("expect same error", expectError, eLatch.getNow(null)); assertSame("expect same type", expectType, tLatch.getNow(null)); assertSame("expect same parentId", expectId, idLatch.getNow(null)); assertSame("expect same path", expectPath, pathLatch.getNow(null)); }