Skip to content

Commit

Permalink
feat!: container-centric API with refactored underlying layer (#575)
Browse files Browse the repository at this point in the history
Quite large refactoring as part of project revamp #563, and also the
long-awaited refactoring #386

Now it's really simple API, e.g:
```rs
let container = GenericImage::new("redis", "latest")
        .with_exposed_port(6379)
        .with_wait_for(WaitFor::message_on_stdout("Ready to accept connections"))
        .start();
```

I find this new API much easier to use, solves a lot of problems, and
seems flexible enough to be extended.
This also works regardless of the tokio runtime flavor (multi-thread vs
current-thread). And the sync API is still available, right under
`blocking` feature (just like `reqwest` does).

From a maintainer's perspective this also simplifies the code, we don't
have to worry about two different clients and their differences.

### Docker host resolution
The host is resolved in the following order:

1. Docker host from the `tc.host` property in the
`~/.testcontainers.properties` file.
2. `DOCKER_HOST` environment variable.
3. Docker host from the "docker.host" property in the
`~/.testcontainers.properties` file.
4. Else, the default Docker socket will be returned.

### Notes
- MSRV was bumped to `1.70` in order to use `std::sync::OnceLock`. This
should NOT be a problem, tests usually executed on more recent versions
(also see [this
ref](https://github.com/testcontainers/testcontainers-rs/pull/503/files#r1242651354)).
- `Cli` client is removed, instead we provide `sync` (under `blocking`
feature) and `async` impls based on HTTP client (bollard)
- tested with
[modules](https://github.com/testcontainers/testcontainers-rs-modules-community)

## Migration guide 

- Sync API migration (`Cli` client)
  - Add `blocking` feature
  - Drop all usages of `clients::Cli`
  - Add `use testcontainers::runners::SyncRunner;`
  - Replace `client.run(image)` with `image.start()`
- Async API migration (`Http` client)
  - Remove `experimental` feature
  - Drop all usages of `clients::Http`
  - Add `use testcontainers::runners::AsyncRunner;`
  - Replace `client.run(image)` with `image.start()`

## References

Closes #386
Closes #326
Closes #475
Closes #508
Closes #392
Closes #561
Closes #559
Closes #564
Closes #538
Closes #507
Closes #89
Closes #198
  • Loading branch information
DDtKey authored Apr 22, 2024
1 parent b68e2b3 commit 9c65640
Show file tree
Hide file tree
Showing 30 changed files with 1,933 additions and 2,032 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ keywords = ["docker", "testcontainers"]
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/testcontainers/testcontainers-rs"
rust-version = "1.66"
rust-version = "1.70"

[workspace.dependencies]
testimages = { path = "testimages" }
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,38 @@ The crate provides an API for working with containers in a test environment.

1. Depend on `testcontainers`
2. Implement `testcontainers::core::Image` for necessary docker-images
3. Run it with any available client `testcontainers::clients::*`
3. Run it with any available runner `testcontainers::runners::*` (use `blocking` feature for synchronous API)

#### Example:

- Blocking API (under `blocking` feature)

```rust
use testcontainers::{core::WaitFor, runners::SyncRunner, GenericImage};

#[test]
fn test_redis() {
let container = GenericImage::new("redis", "7.2.4")
.with_exposed_port(6379)
.with_wait_for(WaitFor::message_on_stdout("Ready to accept connections"))
.start();
}
```

- Async API

```rust
use testcontainers::{core::WaitFor, runners::AsyncRunner, GenericImage};

#[tokio::test]
async fn test_redis() {
let container = GenericImage::new("redis", "7.2.4")
.with_exposed_port(6379)
.with_wait_for(WaitFor::message_on_stdout("Ready to accept connections"))
.start()
.await;
}
```

### Ready-to-use images

Expand Down
21 changes: 13 additions & 8 deletions testcontainers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,30 @@ repository.workspace = true
rust-version.workspace = true
description = "A library for integration-testing against docker containers from within Rust."

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
async-trait = { version = "0.1", optional = true }
bollard = { version = "0.16.1", optional = true }
async-trait = { version = "0.1" }
bollard = { version = "0.16.1", features = ["ssl"] }
bollard-stubs = "=1.44.0-rc.2"
conquer-once = { version = "0.4", optional = true }
dirs = "5.0.1"
futures = "0.3"
hex = "0.4"
hmac = "0.12"
log = "0.4"
rand = "0.8"
serde = { version = "1", features = ["derive"] }
serde-java-properties = "0.1.1"
serde_json = "1"
sha2 = "0.10"
serde_with = "3.7.0"
signal-hook = { version = "0.3", optional = true }
tokio = { version = "1", features = ["macros"], optional = true }
tokio = { version = "1", features = ["macros", "fs", "rt-multi-thread"] }
tokio-util = "0.7.10"
url = { version = "2", features = ["serde"] }

[features]
default = []
experimental = ["async-trait", "bollard", "tokio"]
blocking = []
watchdog = ["signal-hook", "conquer-once"]

[dev-dependencies]
Expand Down
9 changes: 0 additions & 9 deletions testcontainers/src/clients.rs

This file was deleted.

Loading

0 comments on commit 9c65640

Please sign in to comment.