diff --git a/AGENTS.md b/AGENTS.md index 043db2c2d..52b8c6fa3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -28,6 +28,9 @@ It captures practical rules that prevent avoidable CI and PR churn. - In docs Markdown, keep `` blocks tight with no blank lines between the markers and the include line, or the rendered snippet will contain blank lines between code lines. - Tests should verify observable behavior changes, not only internal/config state. - Example: for a security option, assert a real secure/insecure behavior difference. +- Tests should not pull container images that the test suite does not already pull. + - Every extra image increases how long the tests take to run and how much storage they need. + - Reuse an image the tests already use, for example `cristianrgreco/testcontainer:1.1.14` in `packages/testcontainers`, or the module's own image. - When adding a regression test for a bug fix, follow a red-green-refactor workflow. - Run the focused test against the pre-fix implementation and confirm it fails for the expected reason. - Apply the implementation change, rerun the same test, and confirm it passes. diff --git a/biome.json b/biome.json index d4cafe1fe..e1744c9a7 100644 --- a/biome.json +++ b/biome.json @@ -25,6 +25,9 @@ "preset": "recommended", "correctness": { "noUndeclaredDependencies": "error" + }, + "nursery": { + "noFloatingPromises": "error" } } }, diff --git a/packages/modules/nats/src/nats-container.test.ts b/packages/modules/nats/src/nats-container.test.ts index 5714572e1..39800661c 100644 --- a/packages/modules/nats/src/nats-container.test.ts +++ b/packages/modules/nats/src/nats-container.test.ts @@ -18,16 +18,18 @@ describe("NatsContainer", { timeout: 180_000 }, () => { const sub = nc.subscribe(SUBJECT); - (async () => { + const received = (async () => { + const messages: string[] = []; for await (const m of sub) { - const actual = TD.decode(m.data); - expect(actual).toEqual(PAYLOAD); + messages.push(TD.decode(m.data)); } - })().then(); + return messages; + })(); nc.publish(SUBJECT, TE.encode(PAYLOAD)); await nc.drain(); + expect(await received).toEqual([PAYLOAD]); await nc.close(); // } }); diff --git a/packages/testcontainers/smoke-test.js b/packages/testcontainers/smoke-test.js index 0da0d1d0f..021310b93 100644 --- a/packages/testcontainers/smoke-test.js +++ b/packages/testcontainers/smoke-test.js @@ -1,7 +1,12 @@ const { GenericContainer } = require("./build/index"); -(async () => { - const container = await new GenericContainer("alpine:3.12").withCommand(["sleep", "infinity"]).start(); +void (async () => { + try { + const container = await new GenericContainer("alpine:3.12").withCommand(["sleep", "infinity"]).start(); - await container.stop(); + await container.stop(); + } catch (err) { + console.error(err); + process.exit(1); + } })(); diff --git a/packages/testcontainers/src/generic-container/generic-container-dockerfile.test.ts b/packages/testcontainers/src/generic-container/generic-container-dockerfile.test.ts index a747bf0c1..37ae3e42f 100644 --- a/packages/testcontainers/src/generic-container/generic-container-dockerfile.test.ts +++ b/packages/testcontainers/src/generic-container/generic-container-dockerfile.test.ts @@ -86,7 +86,7 @@ describe("GenericContainer Dockerfile", { timeout: 180_000 }, () => { await using dockerEventStream = await getDockerEventStream(); const dockerPullEventPromise = waitForDockerEvent(dockerEventStream.events, "pull"); let hasResolved = false; - dockerPullEventPromise.then(() => (hasResolved = true)); + void dockerPullEventPromise.then(() => (hasResolved = true)); await containerSpec.build(); expect(hasResolved).toBeFalsy(); diff --git a/packages/testcontainers/src/generic-container/generic-container.ts b/packages/testcontainers/src/generic-container/generic-container.ts index c44793ff7..7d74006c1 100644 --- a/packages/testcontainers/src/generic-container/generic-container.ts +++ b/packages/testcontainers/src/generic-container/generic-container.ts @@ -206,8 +206,10 @@ export class GenericContainer implements TestContainer { if (this.filesToCopy.length > 0 || this.directoriesToCopy.length > 0 || this.contentsToCopy.length > 0) { const archive = await this.createArchiveToCopyToContainer(); - archive.finalize(); - await client.container.putArchive(container, archive, "/", this.copyToContainerOptions); + await Promise.all([ + archive.finalize(), + client.container.putArchive(container, archive, "/", this.copyToContainerOptions), + ]); } for (const archive of this.archivesToCopy) { diff --git a/packages/testcontainers/src/generic-container/started-generic-container.ts b/packages/testcontainers/src/generic-container/started-generic-container.ts index e68e7018b..3abceb934 100644 --- a/packages/testcontainers/src/generic-container/started-generic-container.ts +++ b/packages/testcontainers/src/generic-container/started-generic-container.ts @@ -204,8 +204,7 @@ export class StartedGenericContainer implements StartedTestContainer { filesToCopyWithStats.forEach(({ source, target, mode, stats }) => { tar.file(source, { name: target, mode, stats }); }); - tar.finalize(); - await client.container.putArchive(this.container, tar, "/"); + await Promise.all([tar.finalize(), client.container.putArchive(this.container, tar, "/")]); log.debug(`Copied files to container`, { containerId: this.container.id }); } @@ -216,8 +215,7 @@ export class StartedGenericContainer implements StartedTestContainer { directoriesToCopy.forEach(({ source, target }) => { tar.directory(source, target); }); - tar.finalize(); - await client.container.putArchive(this.container, tar, "/"); + await Promise.all([tar.finalize(), client.container.putArchive(this.container, tar, "/")]); log.debug(`Copied directories to container`, { containerId: this.container.id }); } @@ -228,8 +226,7 @@ export class StartedGenericContainer implements StartedTestContainer { contentsToCopy.forEach(({ content, target, mode }) => { tar.append(content, { name: target, mode: mode }); }); - tar.finalize(); - await client.container.putArchive(this.container, tar, "/"); + await Promise.all([tar.finalize(), client.container.putArchive(this.container, tar, "/")]); log.debug(`Copied content to container`, { containerId: this.container.id }); }