    @Test
    public void testRollback(@Named("stuff") Provider<MongoCollection<Document>> stuff, @Named("migrations") Provider<MongoCollection<Document>> migrations, Provider<MongoDatabase> db, Provider<MongoClient> client, Provider<Dependencies> deps) throws InterruptedException, Throwable {

        Function<Class<? extends MigrationWorker>, MigrationWorker> convert = deps.get()::getInstance;

        Migration[] m = new Migration[1];
        new MigrationBuilder("stuff-new", 12, (mig) -> {
            m[0] = (Migration) mig;
            return null;
        }).backup("stuff", new Document("index", new Document("$lte", 150)))
                .migrateCollection("stuff", Failer.class).build();
        assertNotNull(m[0]);
        CompletableFuture<Document> cf = new CompletableFuture<>();
        CompletableFuture<Document> res = m[0].migrate(cf, client.get(), db.get(), convert);
        Document[] ds = new Document[1];
        Throwable[] thr = new Throwable[1];
        CountDownLatch latch = new CountDownLatch(1);
        res.whenCompleteAsync((doc, thrown) -> {
            thr[0] = thrown;
            ds[0] = doc;
            latch.countDown();
        });
        cf.complete(new Document());
        latch.await(20, TimeUnit.SECONDS);
        assertNotNull(thr[0]);
        assertTrue(thr[0] instanceof CompletionException);
        if (!(thr[0].getCause() instanceof FooException)) {
            throw thr[0];
        }
        assertEquals("Failed", thr[0].getCause().getMessage());
        assertNull(ds[0]);
        Thread.sleep(750);
        TestSupport.await(ts -> {
            stuff.get().find().forEach(d -> {
                assertFalse(d.toString(), d.containsKey("author"));
                assertTrue(d.toString(), d.containsKey("created"));
                assertFalse(d.toString(), d.containsKey("ix"));
                assertTrue(d.toString(), d.containsKey("index"));
            }, ts.doneCallback());
        });
    }