arcanemachine

arcanemachine

To workaround this issue, this is what I have come up with so far that allows the seed file to be loaded during application startup. It’s not the most elegant, but it works on both initial startup and when restarting the application. It can be tweaked as needed, but does what is required. (Just make sure to test your seeds file manually first…)

Paste this snippet (just the part with the Testcontainers stuff :wink: ) into your project (make sure it comes after starting YourApp.Repo):

lib/your_app/application.ex

    children = [
      # Start the Ecto repository
      YourApp.Repo,

      # If using Testcontainers, import the seeds file
      {Task,
       fn ->
         if Application.get_env(:testcontainers, :enabled) == true &&
              File.exists?("priv/repo/seeds.exs") do
           try do
             Logger.info("Loading seed data into the database...")
             Code.eval_file("priv/repo/seeds.exs")
           rescue
             _ ->
               Logger.warning(
                 "Could not load the seeds file. " <>
                   "It may have already been loaded during a previous run."
               )
           end
         end
       end},

      # Start the Telemetry supervisor
      YourAppWeb.Telemetry,
      # Start the PubSub system
      {Phoenix.PubSub, name: ContactService.PubSub},
     
      # ...
    ]

Now, when you start your application with mix phx.server, it should either load the seeds file (during the first run after creating the DB), or fail gracefully and show a logger message that suggests that it has already been loaded (during subsequent runs when using a persistent Docker volume).

Again, not perfect, but better than doing it manually IMO.

2
Post #21
jarlah

jarlah OP

Proud to announce v1.8.0 which brings support for two new technologies, RabbitMq and Emqx.

There are a lot of new contributors in this release and this is really encouraging.

Key features that has been implemented is private registry support and proper user agent is sent to docker engine api.

:raised_hands:

4
Post #22
jarlah

jarlah OP

i see you updated GitHub issue. Nice!

1
Post #23
jarlah

jarlah OP

this is so silly, that i havent thought about using mix tasks to wrap testcontainers around a test execution before now … its coming folks .. soon. In a version near you

0
Post #24
jarlah

jarlah OP

if anyone is interested in early access preview of the feature, here is the PR

https://github.com/testcontainers/testcontainers-elixir/pull/124

feel free to comment/shame the PR

2
Post #25
jarlah

jarlah OP

New release v1.9.0 is out!

Check it out.

With mix task feature. And some dependabot updates.

3
Post #26
jarlah

jarlah OP

Soon … reuse is coming … in mix task too …

0
Post #27
jarlah

jarlah OP

New release v1.10.0 is out! Small but important :muscle:

Check it out.

With experimental container reuse. Not too documented yet. But it works the same way as with the java library, it reads a property “testcontainers.reuse.enable” from ~/.testcontainer.properties

1
Post #28
jarlah

jarlah OP

A couple of bugfixes later I can now testify that the testcontainers library is actually usable now. With the introduction of the mix task and its reuse and watch functionality, i can attest for its usefulness.

If you are using it already, do a mix deps.update testcontainers and it will update the patch version. If not, adding it to deps with {:testcontainers, "~> 1.10", only: [:dev, :test], runtime: false} and running mix deps.get will get you up and running. Dont need to add anything in the test_helper.exs.

To use the testcontainers.test task you will need to adjust the config/test.exs so it reads db environment variables. From the readme, it can look like this:

config :my_app, MyApp.Repo,
  username: System.get_env("DB_USER") || "postgres",
  password: System.get_env("DB_PASSWORD") || "postgres",
  hostname: System.get_env("DB_HOST") || "localhost",
  port: System.get_env("DB_PORT") || "5432",
  database: "my_app_test#{System.get_env("MIX_TEST_PARTITION")}",
  pool: Ecto.Adapters.SQL.Sandbox,
  pool_size: System.schedulers_online() * 2

If you want to reuse the database container, add testcontainers.reuse.enable=true in ~/.testcontainers.properties.

Now you can run

mix testcontainers.test

It doesnt look as pretty as normal test runs, because it streams output from a System.cmd call to stdout, but its better than having to struggle with mix test.watch which have many unresolved issues. At least for me.

If you want to watch files for changes and rerun the tests when changed, run this instead:

mix testcontainers.test --watch lib --watch test

Its not a very complicated task, so if you cancel before the test run completes, it will run in the background as a separate os process. If you rerun the command above before its complete, and if you have reuse enabled in properties, you might encounter many fun issues.

I usually have another terminal open where i monitor docker:

watch docker ps

Any feedback on the mix task and the watching functionality would be wonderful :slight_smile: <3

3
Post #29
dimitarvp

dimitarvp

Just to give an unsolicited suggestion: I like ctop for Docker a lot.

It doesn’t work seamlessly with everything f.ex. I use Colima on my Mac so I have to do this:

DOCKER_HOST=unix:///Users/dimi/.colima/default/docker.sock ctop -a

And then it works perfect.

Just a tidbit if you are interested in being able to look at more detailed stats and (terminal) load graphs.

1
Post #30