#![cfg(feature = "testing")]
use std::time::Duration;
use ruststream::conformance::harness::InProcessBroker;
use ruststream::conformance::{capabilities, harness};
use ruststream::nonzero;
use ruststream_fred::{
DelayedRetry, RedisBroker, RedisList, RedisListPublish, RedisPubSub, RedisPubSubPattern,
RedisPubSubPublish, RedisStream,
};
mod live;
const URL: &str = "redis://localhost:6379";
fn in_process() -> InProcessBroker<RedisBroker> {
InProcessBroker::new(RedisBroker::standalone(URL))
}
fn burst_pubsub(channel: &str) -> RedisPubSub {
RedisPubSub::new(channel).buffer(nonzero!(64))
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_conformance_suite() {
Box::pin(harness::run_suite(|| {
RedisBroker::standalone(URL).default_group("conformance")
}))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_lifecycle() {
Box::pin(harness::lifecycle(
in_process,
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
fn delayed(key: &str) -> RedisStream {
RedisStream::new(key)
.group("conformance")
.delayed_retry(DelayedRetry::DurableZset {
key: format!("{key}.delayed"),
ttl: None,
})
.block(Duration::from_millis(50))
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_delayed_retry_lifecycle() {
Box::pin(harness::lifecycle(in_process, delayed, |connected| {
connected.publisher()
}))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_list_lifecycle() {
Box::pin(harness::lifecycle(
in_process,
|key| RedisList::new(key).reliable(),
|connected| connected.list_publisher(RedisListPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_pubsub_lifecycle() {
Box::pin(harness::lifecycle(in_process, burst_pubsub, |connected| {
connected.pubsub_publisher(RedisPubSubPublish::new())
}))
.await;
}
fn burst_pattern(channel: &str) -> RedisPubSubPattern {
RedisPubSubPattern::new(channel).buffer(nonzero!(64))
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_pattern_lifecycle() {
Box::pin(harness::lifecycle(in_process, burst_pattern, |connected| {
connected.pubsub_publisher(RedisPubSubPublish::new())
}))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_pattern_batches() {
Box::pin(capabilities::batches(
in_process,
|channel| RedisPubSubPattern::new(channel),
|connected| connected.pubsub_publisher(RedisPubSubPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_pattern_lifecycle() {
let Some(url) = redis_url() else {
return;
};
Box::pin(harness::lifecycle(
move || RedisBroker::standalone(url.clone()),
burst_pattern,
|connected| connected.pubsub_publisher(RedisPubSubPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_pattern_batches() {
let Some(url) = redis_url() else {
return;
};
Box::pin(capabilities::batches(
|| RedisBroker::standalone(url.clone()),
|channel| RedisPubSubPattern::new(channel),
|connected| connected.pubsub_publisher(RedisPubSubPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_addresses_stream_copies() {
Box::pin(harness::redelivery_address(
in_process,
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_addresses_list_copies() {
Box::pin(harness::redelivery_address(
in_process,
|key| RedisList::new(key).reliable(),
|connected| connected.list_publisher(RedisListPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_addresses_pubsub_copies() {
Box::pin(harness::redelivery_address(
in_process,
|channel| RedisPubSub::new(channel),
|connected| connected.pubsub_publisher(RedisPubSubPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_batches() {
Box::pin(capabilities::batches(
in_process,
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_pubsub_batches() {
Box::pin(capabilities::batches(
in_process,
|channel| RedisPubSub::new(channel),
|connected| connected.pubsub_publisher(RedisPubSubPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_list_batches() {
Box::pin(capabilities::batches(
in_process,
|key| RedisList::new(key),
|connected| connected.list_publisher(RedisListPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_transactions() {
Box::pin(capabilities::transactions(
in_process,
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_owned_transactions() {
Box::pin(capabilities::owned_transactions(
in_process,
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn in_process_passes_seeking() {
Box::pin(capabilities::seeking(
in_process,
|key| {
RedisStream::new(key)
.group("conformance")
.block(Duration::from_millis(50))
},
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_lifecycle() {
let Some(url) = redis_url() else {
return;
};
Box::pin(harness::lifecycle(
move || RedisBroker::standalone(url.clone()),
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_delayed_retry_lifecycle() {
let Some(url) = redis_url() else {
return;
};
Box::pin(harness::lifecycle(
move || RedisBroker::standalone(url.clone()),
delayed,
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_list_lifecycle() {
let Some(url) = redis_url() else {
return;
};
Box::pin(harness::lifecycle(
move || RedisBroker::standalone(url.clone()),
|key| RedisList::new(key).reliable(),
|connected| connected.list_publisher(RedisListPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_pubsub_lifecycle() {
let Some(url) = redis_url() else {
return;
};
Box::pin(harness::lifecycle(
move || RedisBroker::standalone(url.clone()),
burst_pubsub,
|connected| connected.pubsub_publisher(RedisPubSubPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn addresses_stream_copies() {
let Some(url) = redis_url() else {
return;
};
Box::pin(harness::redelivery_address(
|| RedisBroker::standalone(url.clone()),
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn addresses_list_copies() {
let Some(url) = redis_url() else {
return;
};
Box::pin(harness::redelivery_address(
|| RedisBroker::standalone(url.clone()),
|key| RedisList::new(key).reliable(),
|connected| connected.list_publisher(RedisListPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn addresses_pubsub_copies() {
let Some(url) = redis_url() else {
return;
};
Box::pin(harness::redelivery_address(
|| RedisBroker::standalone(url.clone()),
|channel| RedisPubSub::new(channel),
|connected| connected.pubsub_publisher(RedisPubSubPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_batches() {
let Some(url) = redis_url() else {
return;
};
Box::pin(capabilities::batches(
|| RedisBroker::standalone(url.clone()),
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_pubsub_batches() {
let Some(url) = redis_url() else {
return;
};
Box::pin(capabilities::batches(
|| RedisBroker::standalone(url.clone()),
|channel| RedisPubSub::new(channel),
|connected| connected.pubsub_publisher(RedisPubSubPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_list_batches() {
let Some(url) = redis_url() else {
return;
};
Box::pin(capabilities::batches(
|| RedisBroker::standalone(url.clone()),
|key| RedisList::new(key),
|connected| connected.list_publisher(RedisListPublish::new()),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_transactions() {
let Some(url) = redis_url() else {
return;
};
Box::pin(capabilities::transactions(
|| RedisBroker::standalone(url.clone()),
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_owned_transactions() {
let Some(url) = redis_url() else {
return;
};
Box::pin(capabilities::owned_transactions(
|| RedisBroker::standalone(url.clone()),
|key| RedisStream::new(key).group("conformance"),
|connected| connected.publisher(),
))
.await;
}
#[allow(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn passes_seeking() {
let Some(url) = redis_url() else {
return;
};
Box::pin(capabilities::seeking(
|| RedisBroker::standalone(url.clone()),
|key| {
RedisStream::new(key)
.group("conformance")
.block(Duration::from_millis(50))
},
|connected| connected.publisher(),
))
.await;
}
fn redis_url() -> Option<String> {
live::url("REDIS_TEST_URL")
}