Add event call assertions in tests

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/25/head
trivernis 3 years ago
parent f70563d099
commit cda472d3a9
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

1
Cargo.lock generated

@ -43,6 +43,7 @@ dependencies = [
"async-trait",
"byteorder",
"criterion",
"crossbeam-utils",
"futures",
"lazy_static",
"rmp-serde",

@ -40,6 +40,7 @@ features = ["net", "io-std", "io-util", "sync", "time"]
[dev-dependencies]
rmp-serde = "0.15.4"
crossbeam-utils = "0.8.5"
[dev-dependencies.serde]
version = "1.0.130"

@ -1,17 +1,99 @@
mod test_protocol;
use bromine::prelude::*;
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::sync::atomic::{AtomicU8, AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;
use test_protocol::*;
use tokio::sync::oneshot::channel;
use tokio::sync::RwLock;
use typemap_rev::TypeMapKey;
async fn handle_ping_event(ctx: &Context, event: Event) -> IPCResult<()> {
ctx.emitter.emit_response(event.id(), "pong", ()).await?;
#[tokio::test]
async fn it_sends_events() {
let port = get_free_port();
let ctx = get_client_with_server(port).await;
let counters = {
let data = ctx.data.read().await;
data.get::<CallCounterKey>().unwrap().clone()
};
ctx.emitter.emit("ping", ()).await.unwrap();
Ok(())
// allow the event to be processed
tokio::time::sleep(Duration::from_millis(10)).await;
assert_eq!(counters.get("ping").await, 1);
assert_eq!(counters.get("pong").await, 1);
}
async fn handle_pong_event(_ctx: &Context, _event: Event) -> IPCResult<()> {
Ok(())
struct CallCounterKey;
impl TypeMapKey for CallCounterKey {
type Value = CallCounter;
}
#[derive(Clone, Default, Debug)]
struct CallCounter {
inner: Arc<RwLock<HashMap<String, AtomicUsize>>>,
}
impl CallCounter {
pub async fn incr(&self, name: &str) {
{
let calls = self.inner.read().await;
if let Some(call) = calls.get(name) {
call.fetch_add(1, Ordering::Relaxed);
return;
}
}
{
let mut calls = self.inner.write().await;
calls.insert(name.to_string(), AtomicUsize::new(1));
}
}
pub async fn get(&self, name: &str) -> usize {
let calls = self.inner.read().await;
calls
.get(name)
.map(|n| n.load(Ordering::SeqCst))
.unwrap_or(0)
}
}
fn get_free_port() -> u8 {
lazy_static! {
static ref PORT_COUNTER: Arc<AtomicU8> = Arc::new(AtomicU8::new(0));
}
PORT_COUNTER.fetch_add(1, Ordering::Relaxed)
}
async fn get_client_with_server(port: u8) -> Context {
let counters = CallCounter::default();
let (sender, receiver) = channel::<()>();
tokio::task::spawn({
let counters = counters.clone();
async move {
sender.send(()).unwrap();
get_builder(port)
.insert::<CallCounterKey>(counters)
.build_server()
.await
.unwrap()
}
});
receiver.await.unwrap();
get_builder(port)
.insert::<CallCounterKey>(counters)
.build_client()
.await
.unwrap()
}
fn get_builder(port: u8) -> IPCBuilder<TestProtocolListener> {
@ -36,16 +118,22 @@ fn get_builder(port: u8) -> IPCBuilder<TestProtocolListener> {
)
}
#[tokio::test]
async fn it_passes_events() {
tokio::task::spawn(async { get_builder(0).build_server().await.unwrap() });
tokio::time::sleep(Duration::from_millis(100)).await;
let ctx = get_builder(0).build_client().await.unwrap();
ctx.emitter
.emit("ping", ())
.await
async fn increment_counter_for_event(ctx: &Context, event: &Event) {
let data = ctx.data.read().await;
data.get::<CallCounterKey>()
.unwrap()
.await_reply(&ctx)
.await
.unwrap();
.incr(event.name())
.await;
}
async fn handle_ping_event(ctx: &Context, event: Event) -> IPCResult<()> {
increment_counter_for_event(ctx, &event).await;
ctx.emitter.emit_response(event.id(), "pong", ()).await?;
Ok(())
}
async fn handle_pong_event(ctx: &Context, event: Event) -> IPCResult<()> {
increment_counter_for_event(ctx, &event).await;
Ok(())
}

Loading…
Cancel
Save