Skip to content

Commit

Permalink
refactor!: require the builder pattern for module initalisation (#161)
Browse files Browse the repository at this point in the history
This PR makes sure that the way structs are constructed is consistent
and encourages the builder pattern.
It is based on this question:
#156 (comment)

For the changelog:

We now require you to use the builder pattern (instead of some structs
being [unit structs](https://doc.rust-lang.org/std/keyword.struct.html))
for all modules.
This ensures that if we add a field in the future that this will not
break your existing code.

This change is breaking for these modules:

| Module | before | after |
|--------|--------|--------|
| `cncf_distribution::CncfDistribution` | `CncfDistribution.start()` |
`CncfDistribution::default().start()` |
| `dynamodb_local::DynamoDb` | `DynamoDb.start()` |
`DynamoDb::default().start()` |
| `elasticmq::ElasticMq` | `ElasticMq.start()` |
`ElasticMq::default().start()` |
| ~`mongo::Mongo`~ (see #143) | ~`Mongo.start()`~ |
~`Mongo::default().start()`~ |
| `kwok::KwokCluster` | `KwokCluster.start()` |
`KwokCluster::default().start()` |
| `rabbitmq::RabbitMq` | `RabbitMq.start()` |
`RabbitMq::default().start()` |
| `redis::stack::RedisStack` | `RedisStack.start()` |
`RedisStack::default().start()` |
| `redis::standalone::Redis` | `Redis.start()` |
`Redis::default().start()` |
| `victoria_metrics::VictoriaMetrics` | `VictoriaMetrics.start()` |
`VictoriaMetrics::default().start()` |
  • Loading branch information
CommanderStorm authored Sep 25, 2024
1 parent fab257f commit 7b05300
Show file tree
Hide file tree
Showing 18 changed files with 96 additions and 20 deletions.
15 changes: 12 additions & 3 deletions src/cncf_distribution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ const TAG: &str = "2";
/// ```
/// use testcontainers_modules::{cncf_distribution, testcontainers::runners::SyncRunner};
///
/// let registry = cncf_distribution::CncfDistribution.start().unwrap();
/// let registry = cncf_distribution::CncfDistribution::default()
/// .start()
/// .unwrap();
///
/// let image_name = "test";
/// let image_tag = format!(
Expand All @@ -25,7 +27,12 @@ const TAG: &str = "2";
///
/// [`CNCF Distribution`]: https://distribution.github.io/distribution/
#[derive(Debug, Default, Clone)]
pub struct CncfDistribution;
pub struct CncfDistribution {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

impl Image for CncfDistribution {
fn name(&self) -> &str {
Expand Down Expand Up @@ -56,7 +63,9 @@ mod tests {
#[tokio::test]
async fn distribution_push_pull_image() -> Result<(), Box<dyn std::error::Error + 'static>> {
let _ = pretty_env_logger::try_init();
let distribution_node = cncf_distribution::CncfDistribution.start().await?;
let distribution_node = cncf_distribution::CncfDistribution::default()
.start()
.await?;
let docker = bollard::Docker::connect_with_local_defaults().unwrap();
let image_tag = format!(
"localhost:{}/test:latest",
Expand Down
9 changes: 7 additions & 2 deletions src/dynamodb_local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ const TAG: &str = "2.0.0";
const DEFAULT_WAIT: u64 = 3000;

#[derive(Default, Debug, Clone)]
pub struct DynamoDb;
pub struct DynamoDb {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

impl Image for DynamoDb {
fn name(&self) -> &str {
Expand Down Expand Up @@ -46,7 +51,7 @@ mod tests {
#[tokio::test]
async fn dynamodb_local_create_table() -> Result<(), Box<dyn std::error::Error + 'static>> {
let _ = pretty_env_logger::try_init();
let node = DynamoDb.start().await?;
let node = DynamoDb::default().start().await?;
let host = node.get_host().await?;
let host_port = node.get_host_port_ipv4(8000.tcp()).await?;

Expand Down
3 changes: 3 additions & 0 deletions src/elastic_search/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ pub const ELASTICSEARCH_INTER_NODE_PORT: ContainerPort = ContainerPort::Tcp(9300

#[derive(Debug, Default, Clone)]
pub struct ElasticSearch {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down
9 changes: 7 additions & 2 deletions src/elasticmq/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ const NAME: &str = "softwaremill/elasticmq";
const TAG: &str = "1.5.2";

#[derive(Debug, Default, Clone)]
pub struct ElasticMq;
pub struct ElasticMq {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

impl Image for ElasticMq {
fn name(&self) -> &str {
Expand All @@ -31,7 +36,7 @@ mod tests {

#[tokio::test]
async fn sqs_list_queues() -> Result<(), Box<dyn std::error::Error + 'static>> {
let node = ElasticMq.start().await?;
let node = ElasticMq::default().start().await?;
let host_ip = node.get_host().await?;
let host_port = node.get_host_port_ipv4(9324).await?;
let client = build_sqs_client(host_ip, host_port).await;
Expand Down
9 changes: 7 additions & 2 deletions src/kwok/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ pub const KWOK_CLUSTER_PORT: ContainerPort = ContainerPort::Tcp(8080);
///
/// [`Kwok Cluster`]: https://kwok.sigs.k8s.io/
#[derive(Debug, Default, Clone)]
pub struct KwokCluster;
pub struct KwokCluster {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

impl Image for KwokCluster {
fn name(&self) -> &str {
Expand Down Expand Up @@ -82,7 +87,7 @@ mod test {
.expect("Error initializing rustls provider");
}

let node = KwokCluster.start().await?;
let node = KwokCluster::default().start().await?;
let host_port = node.get_host_port_ipv4(8080.tcp()).await?;

// Create a custom Kubeconfig
Expand Down
3 changes: 3 additions & 0 deletions src/localstack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ const DEFAULT_WAIT: u64 = 3000;
/// No environment variables are required.
#[derive(Default, Debug, Clone)]
pub struct LocalStack {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down
3 changes: 3 additions & 0 deletions src/mariadb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ const TAG: &str = "11.3";
/// [`MariaDB docker image`]: https://hub.docker.com/_/mariadb
#[derive(Debug, Default, Clone)]
pub struct Mariadb {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down
3 changes: 3 additions & 0 deletions src/mosquitto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const TAG: &str = "2.0.18";

#[derive(Debug, Default, Clone)]
pub struct Mosquitto {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down
3 changes: 3 additions & 0 deletions src/mysql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ const TAG: &str = "8.1";
/// [`MySQL docker image`]: https://hub.docker.com/_/mysql
#[derive(Debug, Default, Clone)]
pub struct Mysql {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down
3 changes: 3 additions & 0 deletions src/oracle/free.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub const FREE_PORT: ContainerPort = ContainerPort::Tcp(1521);
/// [`gvenzl/oracle-free:23-slim-faststart`]: https://hub.docker.com/r/gvenzl/oracle-free
#[derive(Debug, Default, Clone)]
pub struct Oracle {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down
3 changes: 3 additions & 0 deletions src/orientdb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const TAG: &str = "3.2.19";

#[derive(Debug, Default, Clone)]
pub struct OrientDb {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down
3 changes: 3 additions & 0 deletions src/parity_parity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const TAG: &str = "v2.5.0";

#[derive(Debug, Default, Clone)]
pub struct ParityEthereum {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down
11 changes: 8 additions & 3 deletions src/rabbitmq/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const TAG: &str = "3.8.22-management";
/// ```
/// use testcontainers_modules::{rabbitmq, testcontainers::runners::SyncRunner};
///
/// let rabbitmq_instance = rabbitmq::RabbitMq.start().unwrap();
/// let rabbitmq_instance = rabbitmq::RabbitMq::default().start().unwrap();
///
/// let amqp_url = format!(
/// "amqp://{}:{}",
Expand All @@ -30,7 +30,12 @@ const TAG: &str = "3.8.22-management";
/// [`RabbitMQ Management HTTP API`]: https://www.rabbitmq.com/management.html#http-api
/// [`RabbitMQ docker image`]: https://hub.docker.com/_/rabbitmq
#[derive(Debug, Default, Clone)]
pub struct RabbitMq;
pub struct RabbitMq {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

impl Image for RabbitMq {
fn name(&self) -> &str {
Expand Down Expand Up @@ -68,7 +73,7 @@ mod tests {
async fn rabbitmq_produce_and_consume_messages(
) -> Result<(), Box<dyn std::error::Error + 'static>> {
let _ = pretty_env_logger::try_init();
let rabbit_node = rabbitmq::RabbitMq.start().await?;
let rabbit_node = rabbitmq::RabbitMq::default().start().await?;

let amqp_url = format!(
"amqp://{}:{}",
Expand Down
11 changes: 8 additions & 3 deletions src/redis/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const TAG: &str = "7.2.0-v8";
/// use serde_json::json;
/// use testcontainers_modules::{testcontainers::runners::SyncRunner, redis::{RedisStack, REDIS_PORT}};
///
/// let redis_instance = RedisStack.start().unwrap();
/// let redis_instance = RedisStack::default().start().unwrap();
/// let host_ip = redis_instance.get_host().unwrap();
/// let host_port = redis_instance.get_host_port_ipv4(REDIS_PORT).unwrap();
///
Expand All @@ -32,7 +32,12 @@ const TAG: &str = "7.2.0-v8";
/// [`Redis reference guide`]: https://redis.io/docs/interact/
/// [`REDIS_PORT`]: super::REDIS_PORT
#[derive(Debug, Default, Clone)]
pub struct RedisStack;
pub struct RedisStack {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

impl Image for RedisStack {
fn name(&self) -> &str {
Expand Down Expand Up @@ -61,7 +66,7 @@ mod tests {
#[test]
fn redis_fetch_an_integer_in_json() -> Result<(), Box<dyn std::error::Error + 'static>> {
let _ = pretty_env_logger::try_init();
let node = RedisStack.start()?;
let node = RedisStack::default().start()?;
let host_ip = node.get_host()?;
let host_port = node.get_host_port_ipv4(REDIS_PORT)?;
let url = format!("redis://{host_ip}:{host_port}");
Expand Down
9 changes: 7 additions & 2 deletions src/redis/standalone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ const TAG: &str = "5.0";
/// [`Redis reference guide`]: https://redis.io/docs/interact/
/// [`REDIS_PORT`]: super::REDIS_PORT
#[derive(Debug, Default, Clone)]
pub struct Redis;
pub struct Redis {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

impl Image for Redis {
fn name(&self) -> &str {
Expand All @@ -59,7 +64,7 @@ mod tests {
#[test]
fn redis_fetch_an_integer() -> Result<(), Box<dyn std::error::Error + 'static>> {
let _ = pretty_env_logger::try_init();
let node = Redis.start()?;
let node = Redis::default().start()?;
let host_ip = node.get_host()?;
let host_port = node.get_host_port_ipv4(6379)?;
let url = format!("redis://{host_ip}:{host_port}");
Expand Down
3 changes: 3 additions & 0 deletions src/solr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const TAG: &str = "9.5.0-slim";
/// [`Solr reference guide`]: https://solr.apache.org/guide/solr/latest/
#[derive(Debug, Default, Clone)]
pub struct Solr {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down
13 changes: 10 additions & 3 deletions src/victoria_metrics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ const TAG: &str = "v1.96.0";
/// ```
/// use testcontainers_modules::{testcontainers::runners::SyncRunner, victoria_metrics};
///
/// let victoria_metrics_instance = victoria_metrics::VictoriaMetrics.start().unwrap();
/// let victoria_metrics_instance = victoria_metrics::VictoriaMetrics::default()
/// .start()
/// .unwrap();
///
/// let import_url = format!(
/// "http://127.0.0.1:{}/api/v1/import",
Expand All @@ -31,7 +33,12 @@ const TAG: &str = "v1.96.0";
/// [`VictoriaMetrics API examples`]: https://docs.victoriametrics.com/url-examples.html#victoriametrics-api-examples
/// [`VictoriaMetrics Docker image`]: https://hub.docker.com/r/victoriametrics/victoria-metrics
#[derive(Debug, Default, Clone)]
pub struct VictoriaMetrics;
pub struct VictoriaMetrics {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

impl Image for VictoriaMetrics {
fn name(&self) -> &str {
Expand Down Expand Up @@ -61,7 +68,7 @@ mod tests {

#[test]
fn query_buildinfo() -> Result<(), Box<dyn std::error::Error + 'static>> {
let node = VictoriaMetricsImage.start()?;
let node = VictoriaMetricsImage::default().start()?;
let host_ip = node.get_host()?;
let host_port = node.get_host_port_ipv4(8428)?;
let url = format!("http://{host_ip}:{host_port}/api/v1/status/buildinfo");
Expand Down
3 changes: 3 additions & 0 deletions src/zookeeper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ const TAG: &str = "3.9.0";
/// [Zookeeper documentation]: https://zookeeper.apache.org/documentation.html
#[derive(Debug, Default, Clone)]
pub struct Zookeeper {
/// (remove if there is another variable)
/// Field is included to prevent this struct to be a unit struct.
/// This allows extending functionality (and thus further variables) without breaking changes
_priv: (),
}

Expand Down

0 comments on commit 7b05300

Please sign in to comment.