test: Log the number of the test account if there are multiple alices (#7087)

In order to debug some test failures wrt broadcast channels, I need to
read the log of some tests that have an alice0 and an alice1.

It's currently not possible to tell whether a line was logged by alice0
or alice1, so, I would like to change that with this PR.

Edit: Turns out that there are more tests that call their profiles
"alice1"/"alice2" (or "alice"/"alice2") than "alice0"/"alice1". So, I
changed the logging to count "alice", "alice2", "alice3", ….

Not sure whether I should adapt old tests; it might save someone some
confusion in the future, but I might also make a mistake and make it so
that the test doesn't properly test anymore.
This commit is contained in:
Hocuri
2025-08-12 10:51:23 +02:00
committed by GitHub
parent 45f1da82fe
commit b3c5787ec8

View File

@@ -1,7 +1,7 @@
//! Utilities to help writing tests. //! Utilities to help writing tests.
//! //!
//! This private module is only compiled for test runs. //! This private module is only compiled for test runs.
use std::collections::{BTreeMap, HashSet}; use std::collections::{BTreeMap, BTreeSet, HashSet};
use std::env::current_dir; use std::env::current_dir;
use std::fmt::Write; use std::fmt::Write;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
@@ -70,19 +70,22 @@ static CONTEXT_NAMES: LazyLock<std::sync::RwLock<BTreeMap<u32, String>>> =
/// [`TestContext`]s without managing your own [`LogSink`]. /// [`TestContext`]s without managing your own [`LogSink`].
pub struct TestContextManager { pub struct TestContextManager {
log_sink: LogSink, log_sink: LogSink,
used_names: BTreeSet<String>,
} }
impl TestContextManager { impl TestContextManager {
pub fn new() -> Self { pub fn new() -> Self {
let log_sink = LogSink::new(); Self {
Self { log_sink } log_sink: LogSink::new(),
used_names: BTreeSet::new(),
}
} }
pub async fn alice(&mut self) -> TestContext { pub async fn alice(&mut self) -> TestContext {
TestContext::builder() TestContext::builder()
.configure_alice() .configure_alice()
.with_log_sink(self.log_sink.clone()) .with_log_sink(self.log_sink.clone())
.build() .build(Some(&mut self.used_names))
.await .await
} }
@@ -90,7 +93,7 @@ impl TestContextManager {
TestContext::builder() TestContext::builder()
.configure_bob() .configure_bob()
.with_log_sink(self.log_sink.clone()) .with_log_sink(self.log_sink.clone())
.build() .build(Some(&mut self.used_names))
.await .await
} }
@@ -98,7 +101,7 @@ impl TestContextManager {
TestContext::builder() TestContext::builder()
.configure_charlie() .configure_charlie()
.with_log_sink(self.log_sink.clone()) .with_log_sink(self.log_sink.clone())
.build() .build(Some(&mut self.used_names))
.await .await
} }
@@ -106,7 +109,7 @@ impl TestContextManager {
TestContext::builder() TestContext::builder()
.configure_dom() .configure_dom()
.with_log_sink(self.log_sink.clone()) .with_log_sink(self.log_sink.clone())
.build() .build(Some(&mut self.used_names))
.await .await
} }
@@ -114,7 +117,7 @@ impl TestContextManager {
TestContext::builder() TestContext::builder()
.configure_elena() .configure_elena()
.with_log_sink(self.log_sink.clone()) .with_log_sink(self.log_sink.clone())
.build() .build(Some(&mut self.used_names))
.await .await
} }
@@ -122,7 +125,7 @@ impl TestContextManager {
TestContext::builder() TestContext::builder()
.configure_fiona() .configure_fiona()
.with_log_sink(self.log_sink.clone()) .with_log_sink(self.log_sink.clone())
.build() .build(Some(&mut self.used_names))
.await .await
} }
@@ -130,7 +133,7 @@ impl TestContextManager {
pub async fn unconfigured(&mut self) -> TestContext { pub async fn unconfigured(&mut self) -> TestContext {
TestContext::builder() TestContext::builder()
.with_log_sink(self.log_sink.clone()) .with_log_sink(self.log_sink.clone())
.build() .build(Some(&mut self.used_names))
.await .await
} }
@@ -326,7 +329,7 @@ impl TestContextBuilder {
} }
/// Builds the [`TestContext`]. /// Builds the [`TestContext`].
pub async fn build(self) -> TestContext { pub async fn build(self, used_names: Option<&mut BTreeSet<String>>) -> TestContext {
if let Some(key_pair) = self.key_pair { if let Some(key_pair) = self.key_pair {
let userid = { let userid = {
let public_key = &key_pair.public; let public_key = &key_pair.public;
@@ -340,7 +343,19 @@ impl TestContextBuilder {
.addr; .addr;
let name = EmailAddress::new(&addr).unwrap().local; let name = EmailAddress::new(&addr).unwrap().local;
let test_context = TestContext::new_internal(Some(name), self.log_sink).await; let mut unused_name = name.clone();
if let Some(used_names) = used_names {
assert!(used_names.len() < 100);
// If there are multiple Alices, call them 'alice', 'alice2', 'alice3', ...
let mut i = 1;
while used_names.contains(&unused_name) {
i += 1;
unused_name = format!("{name}{i}");
}
used_names.insert(unused_name.clone());
}
let test_context = TestContext::new_internal(Some(unused_name), self.log_sink).await;
test_context.configure_addr(&addr).await; test_context.configure_addr(&addr).await;
key::store_self_keypair(&test_context, &key_pair) key::store_self_keypair(&test_context, &key_pair)
.await .await
@@ -394,21 +409,21 @@ impl TestContext {
/// ///
/// This is a shortcut which configures alice@example.org with a fixed key. /// This is a shortcut which configures alice@example.org with a fixed key.
pub async fn new_alice() -> Self { pub async fn new_alice() -> Self {
Self::builder().configure_alice().build().await Self::builder().configure_alice().build(None).await
} }
/// Creates a new configured [`TestContext`]. /// Creates a new configured [`TestContext`].
/// ///
/// This is a shortcut which configures bob@example.net with a fixed key. /// This is a shortcut which configures bob@example.net with a fixed key.
pub async fn new_bob() -> Self { pub async fn new_bob() -> Self {
Self::builder().configure_bob().build().await Self::builder().configure_bob().build(None).await
} }
/// Creates a new configured [`TestContext`]. /// Creates a new configured [`TestContext`].
/// ///
/// This is a shortcut which configures fiona@example.net with a fixed key. /// This is a shortcut which configures fiona@example.net with a fixed key.
pub async fn new_fiona() -> Self { pub async fn new_fiona() -> Self {
Self::builder().configure_fiona().build().await Self::builder().configure_fiona().build(None).await
} }
/// Print current chat state. /// Print current chat state.
@@ -1585,14 +1600,14 @@ mod tests {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)] #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_with_alice() { async fn test_with_alice() {
let alice = TestContext::builder().configure_alice().build().await; let alice = TestContext::builder().configure_alice().build(None).await;
alice.ctx.emit_event(EventType::Info("hello".into())); alice.ctx.emit_event(EventType::Info("hello".into()));
// panic!("Alice fails"); // panic!("Alice fails");
} }
#[tokio::test(flavor = "multi_thread", worker_threads = 2)] #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_with_bob() { async fn test_with_bob() {
let bob = TestContext::builder().configure_bob().build().await; let bob = TestContext::builder().configure_bob().build(None).await;
bob.ctx.emit_event(EventType::Info("there".into())); bob.ctx.emit_event(EventType::Info("there".into()));
// panic!("Bob fails"); // panic!("Bob fails");
} }