use std::time::Duration;
use camel_api::Value;
use camel_builder::{RouteBuilder, StepAccumulator};
use camel_component_direct::DirectComponent;
use camel_test::CamelTestContext;
#[tokio::test]
async fn test_harness_basic_timer_to_mock() {
let h = CamelTestContext::builder()
.with_timer()
.with_mock()
.build()
.await;
let route = RouteBuilder::from("timer:tick?period=50&repeatCount=3")
.route_id("harness-test-1")
.to("mock:result")
.build()
.unwrap();
h.add_route(route).await.unwrap();
h.start().await;
tokio::time::sleep(Duration::from_millis(300)).await;
h.mock()
.get_endpoint("result")
.unwrap()
.assert_exchange_count(3)
.await;
}
#[tokio::test]
async fn test_harness_with_direct_component() {
let h = CamelTestContext::builder()
.with_timer()
.with_mock()
.with_component(DirectComponent::new())
.build()
.await;
let sub = RouteBuilder::from("direct:sub")
.route_id("harness-test-2-sub")
.to("mock:sub-result")
.build()
.unwrap();
let main = RouteBuilder::from("timer:tick?period=50&repeatCount=2")
.route_id("harness-test-2-main")
.to("direct:sub")
.build()
.unwrap();
h.add_route(sub).await.unwrap();
h.add_route(main).await.unwrap();
h.start().await;
tokio::time::sleep(Duration::from_millis(300)).await;
h.mock()
.get_endpoint("sub-result")
.unwrap()
.assert_exchange_count(2)
.await;
}
#[tokio::test]
async fn test_harness_multiple_routes() {
let h = CamelTestContext::builder()
.with_timer()
.with_mock()
.build()
.await;
let route_a = RouteBuilder::from("timer:a?period=50&repeatCount=2")
.route_id("harness-test-3-a")
.set_header("route", Value::String("A".into()))
.to("mock:result-a")
.build()
.unwrap();
let route_b = RouteBuilder::from("timer:b?period=50&repeatCount=3")
.route_id("harness-test-3-b")
.set_header("route", Value::String("B".into()))
.to("mock:result-b")
.build()
.unwrap();
h.add_route(route_a).await.unwrap();
h.add_route(route_b).await.unwrap();
h.start().await;
tokio::time::sleep(Duration::from_millis(400)).await;
h.mock()
.get_endpoint("result-a")
.unwrap()
.assert_exchange_count(2)
.await;
h.mock()
.get_endpoint("result-b")
.unwrap()
.assert_exchange_count(3)
.await;
}
#[tokio::test]
async fn test_no_double_stop_on_explicit_plus_drop() {
let h = CamelTestContext::builder()
.with_timer()
.with_mock()
.build()
.await;
let route = RouteBuilder::from("timer:tick?period=50&repeatCount=1")
.route_id("harness-test-4")
.to("mock:result")
.build()
.unwrap();
h.add_route(route).await.unwrap();
h.start().await;
tokio::time::sleep(Duration::from_millis(150)).await;
h.stop().await; }
#[tokio::test]
async fn test_time_control_advances_timer() {
let (h, time) = CamelTestContext::builder()
.with_timer()
.with_mock()
.with_time_control()
.build()
.await;
let route = RouteBuilder::from("timer:tick?period=50&repeatCount=3")
.route_id("harness-test-5")
.to("mock:result")
.build()
.unwrap();
h.add_route(route).await.unwrap();
h.start().await;
for _ in 0..10 {
tokio::task::yield_now().await;
}
for _ in 0..4 {
time.advance(Duration::from_millis(50)).await;
for _ in 0..30 {
tokio::task::yield_now().await;
}
}
h.mock()
.get_endpoint("result")
.unwrap()
.assert_exchange_count(3)
.await;
}
#[tokio::test]
async fn test_time_control_exact_tick_count() {
let (h, time) = CamelTestContext::builder()
.with_timer()
.with_mock()
.with_time_control()
.build()
.await;
let route = RouteBuilder::from("timer:tick?period=100&repeatCount=10")
.route_id("harness-test-6")
.to("mock:result")
.build()
.unwrap();
h.add_route(route).await.unwrap();
h.start().await;
for _ in 0..10 {
tokio::task::yield_now().await;
}
for _ in 0..2 {
time.advance(Duration::from_millis(100)).await;
for _ in 0..20 {
tokio::task::yield_now().await;
}
}
let ep = h.mock().get_endpoint("result").unwrap();
let count = ep.get_received_exchanges().await.len();
assert_eq!(
count, 2,
"expected exactly 2 ticks for 200ms advance with 100ms period"
);
}
#[tokio::test]
async fn test_shutdown_consumes_and_stops() {
let h = CamelTestContext::builder()
.with_timer()
.with_mock()
.build()
.await;
let route = RouteBuilder::from("timer:tick?period=50&repeatCount=1")
.route_id("harness-test-7")
.to("mock:result")
.build()
.unwrap();
h.add_route(route).await.unwrap();
h.start().await;
tokio::time::sleep(Duration::from_millis(150)).await;
h.shutdown().await;
}
#[tokio::test]
async fn test_time_control_resume() {
let (_h, time) = CamelTestContext::builder()
.with_timer()
.with_mock()
.with_time_control()
.build()
.await;
time.resume();
}