testcontainers / testcontainers-node

Testcontainers is a NodeJS library that supports tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
https://testcontainers.com
MIT License
1.87k stars 183 forks source link

"Could not find a working container runtime strategy" when starting MySqlContainer in node inside a container #793

Closed tizueh closed 3 months ago

tizueh commented 3 months ago

Expected Behaviour Testcontainers to be able to start a MySqlContainer without problem.

Actual Behaviour It shows the error "Could not find a working container runtime strategy".

Testcontainer Logs Error: Could not find a working container runtime strategy 12 13 // Test non-root user > 14 const container = await new MySqlContainer() ^ 15 .withUsername(username) 16 .withUserPassword(password) 17 .withDatabase(database)
at getContainerRuntimeClient (/app/node_modules/testcontainers/src/container-runtime/clients/client.ts:61:9)
at MySqlContainer.start (/app/node_modules/testcontainers/src/generic-container/generic-container.ts:81:20)
at MySqlContainer.start (/app/node_modules/@testcontainers/mysql/src/mysql-container.ts:44:7)
at /app/src/index.test.ts:14:21

Steps to Reproduce

  1. clone https://github.com/timonkrebs/docker-express-react-playwright/tree/testcontainers
  2. run it with act act pull_request
  3. Error: Could not find a working container runtime strategy

Environment Information

timonkrebs commented 3 months ago

When run with env var DEBUG=testcontainers* i get:

| OCI runtime exec failed: exec failed: unable to start container process: chdir to cwd ("/mnt/c/Projects/E2E/docker-express-react-playwright/e2ev") set in config.json failed: no such file or directory: unknown

cristianrgreco commented 3 months ago

Hi, it's actually working for me, could you give more info?

[E2E Tests/e2e-tests] ⭐ Run Main Run E2E tests against local environment
[E2E Tests/e2e-tests]   🐳  docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/3] user= workdir=e2e
| yarn run v1.22.22
| $ CI=true yarn e2etest
| $ playwright test ./src
|
| Running 1 test using 1 worker
|
|   ✓  1 [chromium] › index.test.ts:5:5 › should display "Hello, TypeScript Express!" text on page (407ms)
|
|   1 passed (738ms)
| Done in 6.76s.
[E2E Tests/e2e-tests]   ✅  Success - Main Run E2E tests against local environment

Also, I didn't know about act, it's awesome! Thanks for sharing 😄

timonkrebs commented 3 months ago

@cristianrgreco did you checkout the testcontainer branch?

cristianrgreco commented 3 months ago

@cristianrgreco did you checkout the testcontainer branch?

I have now and see your issue. This code:

docker run -v $(pwd)/e2e-report:/app/e2e-report --name playwright-tests --network=host playwright-tests yarn e2etest:ci

Is running inside a container. This code will execute Testcontainers which talks to Docker to try and spin up a MySQL container. However within this container there is no access to Docker. You can mount the Docker socket from the host by adding a volume mount: -v /var/run/docker.sock:/var/run/docker.sock, which Testcontainers will find and use

tizueh commented 3 months ago

Thanks, that helped. Is it expected, that starting the MySqlContainer takes about 10 seconds? Is there a way to improve that?

cristianrgreco commented 3 months ago

@tizueh Starting a container with await container.start() will make Testcontainers start the container, and wait until the wait strategy completes. The wait strategy determines when the container is ready to be used.

In the case of MySQL, the wait strategy is to wait until until port 3306 is ready to accept connections. If it is taking 10s for the container to start, then that is simply how long the MySQL container takes to start and make that port available. If this doesn't fit your use case, you can specify your own wait strategy, but I would be careful not to introduce a case where you attempt to use the container before it is ready.

What makes you say that 10s is a long time for the container to start?

tizueh commented 3 months ago

For starting up a MySql container 10s seems quite good. But if I do that for every test the overhead gets significant. So if there is no way to improve that I think I have to keep the container alive for longer than only one test.

cristianrgreco commented 3 months ago

Ah I see, yes there are several ways to reuse the same container across tests. If you are using Jest/Vitest or another test framework that supports startup/shutdown hooks I'd recommend you start the container there, so it will be reused across all tests. If not there is a withReuse option, so if you have multiple tests which all attempt to start the MySQL container, if the container configuration is the same and Testcontainers detects that a suitable container is already running, it will reuse it, and if not start it.