Skip to content

Commit ff61111

Browse files
committed
Migrate testcontainers forward so we can use wait_for with a http check
1 parent 1dd880c commit ff61111

File tree

5 files changed

+32
-69
lines changed

5 files changed

+32
-69
lines changed

opentelemetry-otlp/tests/integration_test/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ opentelemetry-proto = { path = "../../../opentelemetry-proto", features = ["gen-
1111
log = { workspace = true }
1212
tokio = { version = "1.0", features = ["full"] }
1313
serde_json = "1"
14-
testcontainers = "0.15.0"
14+
testcontainers = { version = "0.23.1", features = ["http_wait"]}
1515
once_cell.workspace = true
1616
anyhow = "1.0.94"
1717
ctor = "0.2.9"

opentelemetry-otlp/tests/integration_test/src/test_utils.rs

Lines changed: 24 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,19 @@
1919
#![cfg(unix)]
2020

2121
use std::collections::HashMap;
22+
use std::fs;
2223
use std::fs::File;
2324
use std::os::unix::fs::PermissionsExt;
2425
use std::sync::{Arc, Mutex, Once, OnceLock};
25-
use testcontainers::clients::Cli;
26-
use testcontainers::core::{Port, WaitFor};
27-
use testcontainers::{Container, Image, RunnableImage};
26+
use testcontainers::{core::{IntoContainerPort, WaitFor}, runners::AsyncRunner, ContainerAsync, GenericImage, ImageExt};
27+
use testcontainers::core::{ContainerPort, Mount};
28+
use testcontainers::core::wait::HttpWaitStrategy;
2829
use tracing_subscriber::FmtSubscriber;
2930
use opentelemetry::{otel_debug, otel_info};
31+
use anyhow::Result;
3032

3133
// Static references for container management
32-
static COLLECTOR_ARC: OnceLock<Mutex<Option<Arc<Container<Collector>>>>> = OnceLock::new();
33-
static DOCKER_CLIENT: OnceLock<Cli> = OnceLock::new();
34-
35-
fn init_docker_client() -> Cli {
36-
Cli::default()
37-
}
34+
static COLLECTOR_ARC: OnceLock<Mutex<Option<Arc<ContainerAsync<GenericImage>>>>> = OnceLock::new();
3835

3936
pub static METRICS_FILE: &str = "./actual/metrics.json";
4037
pub static LOGS_FILE: &str = "./actual/logs.json";
@@ -54,10 +51,9 @@ fn init_tracing() {
5451
});
5552
}
5653

57-
pub async fn start_collector_container() {
54+
pub async fn start_collector_container() -> Result<()> {
5855
init_tracing();
5956

60-
let docker = DOCKER_CLIENT.get_or_init(init_docker_client);
6157
let mut arc_guard = COLLECTOR_ARC
6258
.get_or_init(|| Mutex::new(None))
6359
.lock()
@@ -71,24 +67,33 @@ pub async fn start_collector_container() {
7167
upsert_empty_file(LOGS_FILE);
7268

7369
// Start a new container
74-
let image = Collector::default();
75-
let runnable_image =
76-
RunnableImage::from(image)
77-
.with_mapped_port(Port::from((4317, 4317)))
78-
.with_mapped_port(Port::from((4318, 4318)));
70+
let container_instance = GenericImage::new("otel/opentelemetry-collector", "latest")
71+
.with_wait_for(WaitFor::http(
72+
HttpWaitStrategy::new("/")
73+
.with_expected_status_code(404u16)
74+
.with_port(ContainerPort::Tcp(4318))))
75+
.with_mapped_port(4317, ContainerPort::Tcp(4317))
76+
.with_mapped_port(4318, ContainerPort::Tcp(4318))
77+
.with_mount(Mount::bind_mount(fs::canonicalize("./otel-collector-config.yaml")?.to_string_lossy(), "/etc/otelcol/config.yaml"))
78+
.with_mount(Mount::bind_mount(fs::canonicalize("./actual/logs.json")?.to_string_lossy(), "/testresults/logs.json"))
79+
.with_mount(Mount::bind_mount(fs::canonicalize("./actual/metrics.json")?.to_string_lossy(), "/testresults/metrics.json"))
80+
.with_mount(Mount::bind_mount(fs::canonicalize("./actual/traces.json")?.to_string_lossy(), "/testresults/traces.json"))
81+
.start()
82+
.await?;
7983

80-
let container_instance = docker.run(runnable_image);
8184
let container = Arc::new(container_instance);
8285
otel_debug!(
8386
name: "Container started",
84-
ports = format!("{:?}", container.ports()));
87+
ports = format!("{:?}", container.ports().await));
8588

8689
// Give the container a second to stabilize
87-
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
90+
//tokio::time::sleep(std::time::Duration::from_secs(5)).await;
8891

8992
// Store the container in COLLECTOR_ARC
9093
*arc_guard = Some(Arc::clone(&container));
9194
}
95+
96+
Ok(())
9297
}
9398

9499
///
@@ -116,43 +121,3 @@ pub fn stop_collector_container() {
116121
otel_debug!(name: "stop_collector_container::stopped");
117122
}
118123
}
119-
120-
struct Collector {
121-
volumes: HashMap<String, String>,
122-
}
123-
124-
impl Image for Collector {
125-
type Args = ();
126-
127-
fn name(&self) -> String {
128-
"otel/opentelemetry-collector".to_string()
129-
}
130-
131-
fn tag(&self) -> String {
132-
"latest".to_string()
133-
}
134-
135-
fn ready_conditions(&self) -> Vec<WaitFor> {
136-
vec![WaitFor::Nothing]
137-
}
138-
139-
fn volumes(&self) -> Box<dyn Iterator<Item = (&String, &String)> + '_> {
140-
Box::new(self.volumes.iter())
141-
}
142-
}
143-
144-
impl Default for Collector {
145-
fn default() -> Self {
146-
Collector {
147-
volumes: HashMap::from([
148-
(
149-
"./otel-collector-config.yaml".into(),
150-
"/etc/otelcol/config.yaml".into(),
151-
),
152-
(TRACES_FILE.into(), "/testresults/traces.json".into()),
153-
(LOGS_FILE.into(), "/testresults/logs.json".into()),
154-
(METRICS_FILE.into(), "/testresults/metrics.json".into()),
155-
]),
156-
}
157-
}
158-
}

opentelemetry-otlp/tests/integration_test/tests/logs.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use integration_test_runner::logs_asserter::{read_logs_from_json, LogsAsserter};
66
use integration_test_runner::test_utils;
77
use log::{info, Level};
88
use opentelemetry_appender_log::OpenTelemetryLogBridge;
9-
use opentelemetry_otlp::{LogExporter, WithExportConfig};
9+
use opentelemetry_otlp::LogExporter;
1010
use opentelemetry_sdk::logs::LoggerProvider;
1111
use opentelemetry_sdk::{logs as sdklogs, runtime, Resource};
1212
use std::fs::File;
@@ -16,16 +16,14 @@ use std::time::Duration;
1616
fn init_logs() -> Result<sdklogs::LoggerProvider> {
1717
let exporter_builder = LogExporter::builder();
1818
#[cfg(feature = "tonic-client")]
19-
let exporter_builder = exporter_builder.with_tonic()
20-
.with_endpoint("http://127.0.0.1:4317");
19+
let exporter_builder = exporter_builder.with_tonic();
2120
#[cfg(not(feature = "tonic-client"))]
2221
#[cfg(any(
2322
feature = "hyper-client",
2423
feature = "reqwest-client",
2524
feature = "reqwest-blocking-client"
2625
))]
27-
let exporter_builder = exporter_builder.with_http()
28-
.with_endpoint("http://http://127.0.0.1:4318");
26+
let exporter_builder = exporter_builder.with_http();
2927

3028
let exporter = exporter_builder.build()?;
3129

@@ -42,7 +40,7 @@ fn init_logs() -> Result<sdklogs::LoggerProvider> {
4240
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
4341
pub async fn test_logs() -> Result<()> {
4442
// Make sure the container is running
45-
test_utils::start_collector_container().await;
43+
test_utils::start_collector_container().await?;
4644

4745
let logger_provider = init_logs().unwrap();
4846
let otel_log_appender = OpenTelemetryLogBridge::new(&logger_provider);

opentelemetry-otlp/tests/integration_test/tests/metrics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ pub fn fetch_latest_metrics_for_scope(scope_name: &str) -> Result<Value> {
139139
///
140140
async fn setup_metrics_test() {
141141
// Make sure the collector container is running
142-
start_collector_container().await;
142+
start_collector_container().await?;
143143

144144
let mut done = SETUP_DONE.lock().unwrap();
145145
if !*done {
@@ -275,7 +275,7 @@ mod tests {
275275
// and make sure our data is flushed through.
276276

277277
// Make sure the collector is running
278-
start_collector_container().await;
278+
start_collector_container().await?;
279279

280280
// Set up the exporter
281281
let exporter = create_exporter();

opentelemetry-otlp/tests/integration_test/tests/traces.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const ANOTHER_KEY: Key = Key::from_static_str("ex.com/another");
4949

5050
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
5151
pub async fn traces() -> Result<()> {
52-
test_utils::start_collector_container().await;
52+
test_utils::start_collector_container().await?;
5353

5454
let tracer_provider = init_tracer_provider().expect("Failed to initialize tracer provider.");
5555
global::set_tracer_provider(tracer_provider.clone());

0 commit comments

Comments
 (0)