Source:
<code>protected void testWithNbFiles(int nbDocs) throws IOException, OperationException, InterruptedException { DocumentModelList docs = new DocumentModelListImpl(); for (int i = 0; i < nbDocs; i++) { DocumentModel doc = session.createDocumentModel("/", "TestFile" + i, "File"); doc.setProperty("dublincore", "title", "TestTitle" + i); Blob blob1 = Blobs.createBlob("test" + i); String blobFilename = "test" + i + ".txt"; blob1.setFilename(blobFilename); BlobHolder bh1 = doc.getAdapter(BlobHolder.class); bh1.setBlob(blob1); doc = session.createDocument(doc); session.save(); docs.add(doc); } TransactionHelper.commitOrRollbackTransaction(); <START> TransactionHelper.startTransaction(); <END> OperationChain chain = new OperationChain("test-chain"); chain.add(BulkDownload.ID); OperationContext ctx = new OperationContext(session); ctx.setInput(docs); Blob resultBlob = (Blob) automationService.run(ctx, BulkDownload.ID); assertNotNull(resultBlob); awaitZipWorks(); if (resultBlob instanceof AsyncBlob) { TransientStoreService tss = Framework.getService(TransientStoreService.class); TransientStore ts = tss.getStore(DownloadService.TRANSIENT_STORE_STORE_NAME); List<Blob> blobs = ts.getBlobs(((AsyncBlob) resultBlob).getKey()); assertNotNull(blobs); assertEquals(1, blobs.size()); resultBlob = blobs.get(0); assertTrue(resultBlob instanceof FileBlob); } assertTrue(resultBlob.getLength() > 0); assertEquals("application/zip", resultBlob.getMimeType()); try (CloseableFile source = resultBlob.getCloseableFile()) { try (ZipFile zip = new ZipFile(source.getFile())) { assertEquals(nbDocs, zip.size()); } } }</code><technical_language>TransactionalFeature#nextTransaction CoreFeature#waitForAsyncCompletion async works</technical_language>

Target:
protected void testWithNbFiles(int nbDocs) throws IOException, OperationException, InterruptedException { DocumentModelList docs = new DocumentModelListImpl(); for (int i = 0; i < nbDocs; i++) { DocumentModel doc = session.createDocumentModel("/", "TestFile" + i, "File"); doc.setProperty("dublincore", "title", "TestTitle" + i); Blob blob1 = Blobs.createBlob("test" + i); String blobFilename = "test" + i + ".txt"; blob1.setFilename(blobFilename); BlobHolder bh1 = doc.getAdapter(BlobHolder.class); bh1.setBlob(blob1); doc = session.createDocument(doc); session.save(); docs.add(doc); } coreFeature.waitForAsyncCompletion(); OperationChain chain = new OperationChain("test-chain"); chain.add(BulkDownload.ID); OperationContext ctx = new OperationContext(session); ctx.setInput(docs); Blob resultBlob = (Blob) automationService.run(ctx, BulkDownload.ID); assertNotNull(resultBlob); coreFeature.waitForAsyncCompletion(); if (resultBlob instanceof AsyncBlob) { TransientStoreService tss = Framework.getService(TransientStoreService.class); TransientStore ts = tss.getStore(DownloadService.TRANSIENT_STORE_STORE_NAME); List<Blob> blobs = ts.getBlobs(((AsyncBlob) resultBlob).getKey()); assertNotNull(blobs); assertEquals(1, blobs.size()); resultBlob = blobs.get(0); assertTrue(resultBlob instanceof FileBlob); } assertTrue(resultBlob.getLength() > 0); assertEquals("application/zip", resultBlob.getMimeType()); try (CloseableFile source = resultBlob.getCloseableFile()) { try (ZipFile zip = new ZipFile(source.getFile())) { assertEquals(nbDocs, zip.size()); } } }