Skip to content

Commit ec8a5c2

Browse files
Merge branch 'main' into feat/opentelemetry-sdk/version-number-constant
2 parents 255010c + 68af3bb commit ec8a5c2

File tree

8 files changed

+179
-50
lines changed

8 files changed

+179
-50
lines changed

.cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"shoppingcart",
6565
"struct",
6666
"Tescher",
67+
"testcontainers",
6768
"testresults",
6869
"thiserror",
6970
"tracerprovider",

opentelemetry-otlp/tests/integration_test/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ testcontainers = { version = "0.23.1", features = ["http_wait"]}
1414
once_cell.workspace = true
1515
anyhow = "1.0.94"
1616
ctor = "0.2.9"
17+
uuid = { version = "1.3", features = ["v4"] }
1718
tracing-subscriber = { workspace = true, features = ["env-filter","registry", "std", "fmt"] }
1819
tracing = {workspace = true}
1920

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ fn init_tracing() {
5252
// Initialize the tracing subscriber with the OpenTelemetry layer and the
5353
// Fmt layer.
5454
tracing_subscriber::registry().with(fmt_layer).init();
55-
otel_info!(name: "tracing initializing completed!");
55+
otel_info!(name: "tracing::fmt initializing completed! SDK internal logs will be printed to stdout.");
5656
});
5757
}
5858

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

Lines changed: 134 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22

33
use anyhow::Result;
44
use ctor::dtor;
5-
use integration_test_runner::logs_asserter::{read_logs_from_json, LogsAsserter};
65
use integration_test_runner::test_utils;
76
use opentelemetry_otlp::LogExporter;
87
use opentelemetry_sdk::logs::LoggerProvider;
98
use opentelemetry_sdk::{logs as sdklogs, Resource};
109
use std::fs::File;
11-
use std::os::unix::fs::MetadataExt;
10+
use std::io::Read;
1211

13-
fn init_logs() -> Result<sdklogs::LoggerProvider> {
12+
fn init_logs(is_simple: bool) -> Result<sdklogs::LoggerProvider> {
1413
let exporter_builder = LogExporter::builder();
1514
#[cfg(feature = "tonic-client")]
1615
let exporter_builder = exporter_builder.with_tonic();
@@ -24,24 +23,43 @@ fn init_logs() -> Result<sdklogs::LoggerProvider> {
2423

2524
let exporter = exporter_builder.build()?;
2625

27-
Ok(LoggerProvider::builder()
28-
.with_batch_exporter(exporter)
26+
let mut logger_provider_builder = LoggerProvider::builder();
27+
if is_simple {
28+
logger_provider_builder = logger_provider_builder.with_simple_exporter(exporter)
29+
} else {
30+
logger_provider_builder = logger_provider_builder.with_batch_exporter(exporter)
31+
};
32+
33+
let logger_provider = logger_provider_builder
2934
.with_resource(
3035
Resource::builder_empty()
3136
.with_service_name("logs-integration-test")
3237
.build(),
3338
)
34-
.build())
39+
.build();
40+
41+
Ok(logger_provider)
3542
}
3643

3744
#[cfg(test)]
3845
mod logtests {
46+
// TODO: The tests in this mod works like below: Emit a log with a UUID,
47+
// then read the logs from the file and check if the UUID is present in the
48+
// logs. This makes it easy to validate with a single collector and its
49+
// output. This is a very simple test but good enough to validate that OTLP
50+
// Exporter did work! A more comprehensive test would be to validate the
51+
// entire Payload. The infra for it already exists (logs_asserter.rs), the
52+
// TODO here is to write a test that validates the entire payload.
53+
3954
use super::*;
4055
use integration_test_runner::logs_asserter::{read_logs_from_json, LogsAsserter};
56+
use integration_test_runner::test_utils;
57+
use opentelemetry_appender_tracing::layer;
4158
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
4259
use std::{fs::File, time::Duration};
4360
use tracing::info;
4461
use tracing_subscriber::layer::SubscriberExt;
62+
use uuid::Uuid;
4563

4664
#[test]
4765
#[should_panic(expected = "assertion `left == right` failed: body does not match")]
@@ -68,41 +86,91 @@ mod logtests {
6886
}
6987

7088
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
71-
#[cfg(not(feature = "hyper-client"))]
72-
#[cfg(not(feature = "reqwest-client"))]
73-
pub async fn test_logs() -> Result<()> {
74-
// Make sure the container is running
89+
#[cfg(any(feature = "tonic-client", feature = "reqwest-blocking-client"))]
90+
pub async fn logs_batch_tokio_multi_thread() -> Result<()> {
91+
logs_batch_tokio_helper().await
92+
}
7593

76-
use integration_test_runner::test_utils;
77-
use opentelemetry_appender_tracing::layer;
78-
use tracing::info;
79-
use tracing_subscriber::layer::SubscriberExt;
94+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
95+
#[cfg(any(feature = "tonic-client", feature = "reqwest-blocking-client"))]
96+
pub async fn logs_batch_tokio_multi_with_one_worker() -> Result<()> {
97+
logs_batch_tokio_helper().await
98+
}
8099

100+
#[tokio::test(flavor = "current_thread")]
101+
#[cfg(any(feature = "tonic-client", feature = "reqwest-blocking-client"))]
102+
pub async fn logs_batch_tokio_current() -> Result<()> {
103+
logs_batch_tokio_helper().await
104+
}
105+
106+
async fn logs_batch_tokio_helper() -> Result<()> {
81107
use crate::{assert_logs_results, init_logs};
82108
test_utils::start_collector_container().await?;
83109

84-
let logger_provider = init_logs().unwrap();
85-
let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
110+
let logger_provider = init_logs(false).unwrap();
111+
let layer = OpenTelemetryTracingBridge::new(&logger_provider);
86112
let subscriber = tracing_subscriber::registry().with(layer);
113+
// generate a random uuid and store it to expected guid
114+
let expected_uuid = Uuid::new_v4().to_string();
87115
{
88116
let _guard = tracing::subscriber::set_default(subscriber);
89-
info!(target: "my-target", "hello from {}. My price is {}.", "banana", 2.99);
117+
info!(target: "my-target", uuid = expected_uuid, "hello from {}. My price is {}.", "banana", 2.99);
90118
}
91-
// TODO: remove below wait before calling logger_provider.shutdown()
92-
// tokio::time::sleep(Duration::from_secs(10)).await;
119+
93120
let _ = logger_provider.shutdown();
121+
tokio::time::sleep(Duration::from_secs(5)).await;
122+
assert_logs_results(test_utils::LOGS_FILE, expected_uuid.as_str())?;
123+
Ok(())
124+
}
94125

95-
tokio::time::sleep(Duration::from_secs(10)).await;
126+
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
127+
#[cfg(any(feature = "tonic-client", feature = "reqwest-client"))]
128+
pub async fn logs_simple_tokio_multi_thread() -> Result<()> {
129+
logs_simple_tokio_helper().await
130+
}
131+
132+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
133+
#[cfg(any(feature = "tonic-client", feature = "reqwest-client"))]
134+
pub async fn logs_simple_tokio_multi_with_one_worker() -> Result<()> {
135+
logs_simple_tokio_helper().await
136+
}
137+
138+
// Ignored, to be investigated
139+
#[ignore]
140+
#[tokio::test(flavor = "current_thread")]
141+
#[cfg(any(feature = "tonic-client", feature = "reqwest-client"))]
142+
pub async fn logs_simple_tokio_current() -> Result<()> {
143+
logs_simple_tokio_helper().await
144+
}
145+
146+
async fn logs_simple_tokio_helper() -> Result<()> {
147+
use crate::{assert_logs_results, init_logs};
148+
test_utils::start_collector_container().await?;
96149

97-
assert_logs_results(test_utils::LOGS_FILE, "expected/logs.json")?;
150+
let logger_provider = init_logs(true).unwrap();
151+
let layer = OpenTelemetryTracingBridge::new(&logger_provider);
152+
let subscriber = tracing_subscriber::registry().with(layer);
153+
info!("Tracing initialized");
154+
// generate a random uuid and store it to expected guid
155+
let expected_uuid = Uuid::new_v4().to_string();
156+
{
157+
let _guard = tracing::subscriber::set_default(subscriber);
158+
info!(target: "my-target", uuid = expected_uuid, "hello from {}. My price is {}.", "banana", 2.99);
159+
}
98160

161+
let _ = logger_provider.shutdown();
162+
tokio::time::sleep(Duration::from_secs(5)).await;
163+
assert_logs_results(test_utils::LOGS_FILE, expected_uuid.as_str())?;
99164
Ok(())
100165
}
101166

102-
#[ignore = "TODO: [Fix Me] Failing on CI. Needs to be investigated and resolved."]
103167
#[test]
104168
#[cfg(any(feature = "tonic-client", feature = "reqwest-blocking-client"))]
105169
pub fn logs_batch_non_tokio_main() -> Result<()> {
170+
logs_batch_non_tokio_helper()
171+
}
172+
173+
fn logs_batch_non_tokio_helper() -> Result<()> {
106174
// Initialize the logger provider inside a tokio runtime
107175
// as this allows tonic client to capture the runtime,
108176
// but actual export occurs from the dedicated std::thread
@@ -111,31 +179,61 @@ mod logtests {
111179
let logger_provider = rt.block_on(async {
112180
// While we're here setup our collector container too, as this needs tokio to run
113181
test_utils::start_collector_container().await?;
114-
init_logs()
182+
init_logs(false)
115183
})?;
116-
117-
info!("LoggerProvider created");
118-
let layer = OpenTelemetryTracingBridge::new(&logger_provider);
184+
let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
119185
let subscriber = tracing_subscriber::registry().with(layer);
186+
// generate a random uuid and store it to expected guid
187+
let expected_uuid = Uuid::new_v4().to_string();
120188
{
121189
let _guard = tracing::subscriber::set_default(subscriber);
122-
info!(target: "my-target", "hello from {}. My price is {}.", "banana", 2.99);
190+
info!(target: "my-target", uuid = expected_uuid, "hello from {}. My price is {}.", "banana", 2.99);
123191
}
124-
let _ = logger_provider.shutdown();
125-
// tokio::time::sleep(Duration::from_secs(10)).await;
126-
assert_logs_results(test_utils::LOGS_FILE, "expected/logs.json")?;
127192

193+
let _ = logger_provider.shutdown();
194+
std::thread::sleep(Duration::from_secs(5));
195+
assert_logs_results(test_utils::LOGS_FILE, expected_uuid.as_str())?;
128196
Ok(())
129197
}
130-
}
131198

132-
pub fn assert_logs_results(result: &str, expected: &str) -> Result<()> {
133-
let left = read_logs_from_json(File::open(expected)?)?;
134-
let right = read_logs_from_json(File::open(result)?)?;
199+
#[test]
200+
#[cfg(any(feature = "tonic-client", feature = "reqwest-blocking-client"))]
201+
pub fn logs_simple_non_tokio_main() -> Result<()> {
202+
logs_simple_non_tokio_helper()
203+
}
135204

136-
LogsAsserter::new(left, right).assert();
205+
fn logs_simple_non_tokio_helper() -> Result<()> {
206+
// Initialize the logger provider inside a tokio runtime
207+
// as this allows tonic client to capture the runtime,
208+
// but actual export occurs from the main non-tokio thread.
209+
let rt = tokio::runtime::Runtime::new()?;
210+
let logger_provider = rt.block_on(async {
211+
// While we're here setup our collector container too, as this needs tokio to run
212+
test_utils::start_collector_container().await?;
213+
init_logs(true)
214+
})?;
215+
let layer = layer::OpenTelemetryTracingBridge::new(&logger_provider);
216+
let subscriber = tracing_subscriber::registry().with(layer);
217+
// generate a random uuid and store it to expected guid
218+
let expected_uuid = Uuid::new_v4().to_string();
219+
{
220+
let _guard = tracing::subscriber::set_default(subscriber);
221+
info!(target: "my-target", uuid = expected_uuid, "hello from {}. My price is {}.", "banana", 2.99);
222+
}
223+
224+
let _ = logger_provider.shutdown();
225+
std::thread::sleep(Duration::from_secs(5));
226+
assert_logs_results(test_utils::LOGS_FILE, expected_uuid.as_str())?;
227+
Ok(())
228+
}
229+
}
137230

138-
assert!(File::open(result).unwrap().metadata().unwrap().size() > 0);
231+
pub fn assert_logs_results(result: &str, expected_content: &str) -> Result<()> {
232+
let file = File::open(result)?;
233+
let mut contents = String::new();
234+
let mut reader = std::io::BufReader::new(&file);
235+
reader.read_to_string(&mut contents)?;
236+
assert!(contents.contains(expected_content));
139237
Ok(())
140238
}
141239

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,8 @@ pub fn validate_metrics_against_results(scope_name: &str) -> Result<()> {
189189
/// TODO - fix this asynchronously.
190190
///
191191
#[cfg(test)]
192-
#[cfg(not(feature = "hyper-client"))]
193-
#[cfg(not(feature = "reqwest-client"))]
194-
mod tests {
192+
#[cfg(any(feature = "tonic-client", feature = "reqwest-blocking-client"))]
193+
mod metrictests {
195194

196195
use super::*;
197196
use opentelemetry::metrics::MeterProvider;
@@ -246,7 +245,6 @@ mod tests {
246245
}
247246

248247
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
249-
// #[ignore] // skip when running unit test
250248
async fn test_histogram() -> Result<()> {
251249
_ = setup_metrics_test().await;
252250
const METER_NAME: &str = "test_histogram_meter";
@@ -263,7 +261,6 @@ mod tests {
263261
}
264262

265263
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
266-
// #[ignore] // skip when running unit test
267264
async fn test_up_down_counter() -> Result<()> {
268265
_ = setup_metrics_test().await;
269266
const METER_NAME: &str = "test_up_down_meter";

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const LEMONS_KEY: Key = Key::from_static_str("lemons");
4848
const ANOTHER_KEY: Key = Key::from_static_str("ex.com/another");
4949

5050
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
51+
#[cfg(any(feature = "tonic-client", feature = "reqwest-blocking-client"))]
5152
pub async fn traces() -> Result<()> {
5253
test_utils::start_collector_container().await?;
5354

0 commit comments

Comments
 (0)