@Test
public void testProcessInstallableQueue_singleRepoInitInstallable_fails() throws Exception {

    final String expectScript = "create user testProcessInstallableQueue_singleRepoInitInstallable";
    final JcrPackageManager manager = mock(JcrPackageManager.class);
    final Session session = mock(Session.class);
    final PackageId root = PackageId.fromString("my_packages:subsubtest");
    final OsgiConfigInstallable installable = new OsgiConfigInstallable(
            root, "/repoInit",
            Collections.singletonMap(SlingRepoInitScripts.CONFIG_SCRIPTS,
                    Collections.singletonList(expectScript)),
            "init", SlingRepoInitScripts.REPO_INIT_FACTORY_PID);
    final List<OsgiConfigInstallable> installables = new ArrayList<>();
    installables.add(installable);
    final SlingSimulatorBackend installWatcher = mock(SlingSimulatorBackend.class);
    final List<Optional<OsgiConfigInstallable>> dequeuedValues = new ArrayList<>();
    doAnswer(call -> {
        if (installables.isEmpty()) {
            dequeuedValues.add(Optional.empty());
            return null;
        } else {
            OsgiConfigInstallable toReturn = installables.remove(0);
            dequeuedValues.add(Optional.ofNullable(toReturn));
            return toReturn;
        }
    }).when(installWatcher).dequeueInstallable();
    final CompletableFuture<Reader> readerSlot = new CompletableFuture<>();
    final OakMachine.RepoInitProcessor repoInitProcessor = (Session sess, Reader read) -> {
        readerSlot.complete(read);
        throw new NullPointerException("for some reason");
    };
    final CompletableFuture<Throwable> eLatch = new CompletableFuture<>();
    final CompletableFuture<List> scriptsLatch = new CompletableFuture<>();
    final CompletableFuture<String> scriptLatch = new CompletableFuture<>();
    final CompletableFuture<SlingInstallable> installableLatch = new CompletableFuture<>();
    final ErrorListener errorListener = mock(ErrorListener.class);
    doAnswer(call -> {
        eLatch.complete(call.getArgument(0, Throwable.class));
        scriptsLatch.complete(call.getArgument(1, List.class));
        scriptLatch.complete(call.getArgument(2, String.class));
        installableLatch.complete(call.getArgument(3, SlingInstallable.class));
        return true;
    }).when(errorListener).onSlingRepoInitScriptsError(any(Throwable.class), nullable(List.class), nullable(String.class),
            any(SlingInstallable.class));
    new OakMachine.Builder()
            .withErrorListener(errorListener)
            .withRepoInitProcesser(repoInitProcessor)
            .withSlingSimulator(installWatcher)
            .build().processInstallableQueue(session, manager, root, false);
    assertEquals("expect dequeued values",
            Arrays.asList(Optional.of(installable), Optional.empty()), dequeuedValues);
    assertTrue("expect reader is complete", readerSlot.isDone());
    assertTrue("error is of type", eLatch.getNow(null) instanceof NullPointerException);
    assertEquals("scripts is", Collections.singletonList(expectScript), scriptsLatch.getNow(null));
    assertEquals("failedScript is", expectScript, scriptLatch.getNow(null));
    assertSame("expect same installable in error", installable, installableLatch.getNow(null));
}