mirror of
https://github.com/chatmail/core.git
synced 2026-05-16 21:36:30 +03:00
refactor: Make SystemTimeTools::shift() async
It's a more stable interface, if `shift()` suddenly will need to wait for smth like finalisation of parallel running critical sections assuming there are no time jumps, we don't need to fix all its usages.
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -1283,6 +1283,9 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "deltachat-time"
|
name = "deltachat-time"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deltachat_derive"
|
name = "deltachat_derive"
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ strum_macros = "0.26"
|
|||||||
tagger = "4.3.4"
|
tagger = "4.3.4"
|
||||||
textwrap = "0.16.1"
|
textwrap = "0.16.1"
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
tokio = { version = "1.37.0", features = ["fs", "rt-multi-thread", "macros"] }
|
tokio = { workspace = true }
|
||||||
tokio-io-timeout = "1.2.0"
|
tokio-io-timeout = "1.2.0"
|
||||||
tokio-stream = { version = "0.1.15", features = ["fs"] }
|
tokio-stream = { version = "0.1.15", features = ["fs"] }
|
||||||
tokio-tar = { version = "0.3" } # TODO: integrate tokio into async-tar
|
tokio-tar = { version = "0.3" } # TODO: integrate tokio into async-tar
|
||||||
@@ -162,6 +162,9 @@ harness = false
|
|||||||
name = "send_events"
|
name = "send_events"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
|
[workspace.dependencies]
|
||||||
|
tokio = { version = "1.37.0", features = ["fs", "rt-multi-thread", "macros", "sync"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["vendored"]
|
default = ["vendored"]
|
||||||
internals = []
|
internals = []
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ edition = "2021"
|
|||||||
license = "MPL-2.0"
|
license = "MPL-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
tokio = { workspace = true }
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ impl SystemTimeTools {
|
|||||||
pub const UNIX_EPOCH: SystemTime = SystemTime::UNIX_EPOCH;
|
pub const UNIX_EPOCH: SystemTime = SystemTime::UNIX_EPOCH;
|
||||||
|
|
||||||
pub fn now() -> SystemTime {
|
pub fn now() -> SystemTime {
|
||||||
return SystemTime::now() + *SYSTEM_TIME_SHIFT.read().unwrap();
|
SystemTime::now() + *SYSTEM_TIME_SHIFT.read().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Simulates a system clock forward adjustment by `duration`.
|
/// Simulates a system clock forward adjustment by `duration`.
|
||||||
pub fn shift(duration: Duration) {
|
pub async fn shift(duration: Duration) {
|
||||||
*SYSTEM_TIME_SHIFT.write().unwrap() += duration;
|
*SYSTEM_TIME_SHIFT.write().unwrap() += duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,9 +26,9 @@ impl SystemTimeTools {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
fn it_works() {
|
async fn it_works() {
|
||||||
SystemTimeTools::shift(Duration::from_secs(60));
|
SystemTimeTools::shift(Duration::from_secs(60)).await;
|
||||||
let t = SystemTimeTools::now();
|
let t = SystemTimeTools::now();
|
||||||
assert!(t > SystemTime::now());
|
assert!(t > SystemTime::now());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4831,7 +4831,7 @@ mod tests {
|
|||||||
// Bob receives a msg about Alice adding Claire to the group.
|
// Bob receives a msg about Alice adding Claire to the group.
|
||||||
bob.recv_msg(&alice_sent_add_msg).await;
|
bob.recv_msg(&alice_sent_add_msg).await;
|
||||||
|
|
||||||
SystemTime::shift(Duration::from_secs(3600));
|
SystemTime::shift(Duration::from_secs(3600)).await;
|
||||||
// This adds Bob because they left quite long ago.
|
// This adds Bob because they left quite long ago.
|
||||||
let alice_sent_msg = alice.send_text(alice_chat_id, "What a silence!").await;
|
let alice_sent_msg = alice.send_text(alice_chat_id, "What a silence!").await;
|
||||||
bob.recv_msg(&alice_sent_msg).await;
|
bob.recv_msg(&alice_sent_msg).await;
|
||||||
@@ -4884,7 +4884,7 @@ mod tests {
|
|||||||
let sent_msg = alice.send_text(alice_chat_id, "Welcome, Fiona!").await;
|
let sent_msg = alice.send_text(alice_chat_id, "Welcome, Fiona!").await;
|
||||||
bob.recv_msg(&sent_msg).await;
|
bob.recv_msg(&sent_msg).await;
|
||||||
|
|
||||||
SystemTime::shift(Duration::from_secs(3600));
|
SystemTime::shift(Duration::from_secs(3600)).await;
|
||||||
let sent_msg = alice.send_text(alice_chat_id, "Welcome back, Fiona!").await;
|
let sent_msg = alice.send_text(alice_chat_id, "Welcome back, Fiona!").await;
|
||||||
bob.recv_msg(&sent_msg).await;
|
bob.recv_msg(&sent_msg).await;
|
||||||
bob.golden_test_chat(bob_chat_id, "chat_test_msg_with_implicit_member_add")
|
bob.golden_test_chat(bob_chat_id, "chat_test_msg_with_implicit_member_add")
|
||||||
|
|||||||
@@ -2852,7 +2852,7 @@ Hi."#;
|
|||||||
|
|
||||||
// Wait for `was_seen_recently()` to turn off.
|
// Wait for `was_seen_recently()` to turn off.
|
||||||
while bob.evtracker.try_recv().is_ok() {}
|
while bob.evtracker.try_recv().is_ok() {}
|
||||||
SystemTime::shift(Duration::from_secs(SEEN_RECENTLY_SECONDS as u64 * 2));
|
SystemTime::shift(Duration::from_secs(SEEN_RECENTLY_SECONDS as u64 * 2)).await;
|
||||||
recently_seen_loop.interrupt(ContactId::UNDEFINED, 0).await;
|
recently_seen_loop.interrupt(ContactId::UNDEFINED, 0).await;
|
||||||
let contact = Contact::get_by_id(&bob, *contacts.first().unwrap()).await?;
|
let contact = Contact::get_by_id(&bob, *contacts.first().unwrap()).await?;
|
||||||
assert!(!contact.was_seen_recently());
|
assert!(!contact.was_seen_recently());
|
||||||
|
|||||||
@@ -644,7 +644,7 @@ Here's my footer -- bob@example.net"
|
|||||||
let bob_msg1 = bob.recv_msg(&alice_msg1).await;
|
let bob_msg1 = bob.recv_msg(&alice_msg1).await;
|
||||||
|
|
||||||
// Bob reacts to Alice's message, this is shown in the summaries
|
// Bob reacts to Alice's message, this is shown in the summaries
|
||||||
SystemTime::shift(Duration::from_secs(10));
|
SystemTime::shift(Duration::from_secs(10)).await;
|
||||||
bob_msg1.chat_id.accept(&bob).await?;
|
bob_msg1.chat_id.accept(&bob).await?;
|
||||||
send_reaction(&bob, bob_msg1.id, "👍").await?;
|
send_reaction(&bob, bob_msg1.id, "👍").await?;
|
||||||
let bob_send_reaction = bob.pop_sent_msg().await;
|
let bob_send_reaction = bob.pop_sent_msg().await;
|
||||||
@@ -661,7 +661,7 @@ Here's my footer -- bob@example.net"
|
|||||||
assert_summary(&alice, "BOB reacted 👍 to \"Party?\"").await;
|
assert_summary(&alice, "BOB reacted 👍 to \"Party?\"").await;
|
||||||
|
|
||||||
// Alice reacts to own message as well
|
// Alice reacts to own message as well
|
||||||
SystemTime::shift(Duration::from_secs(10));
|
SystemTime::shift(Duration::from_secs(10)).await;
|
||||||
send_reaction(&alice, alice_msg1.sender_msg_id, "🍿").await?;
|
send_reaction(&alice, alice_msg1.sender_msg_id, "🍿").await?;
|
||||||
let alice_send_reaction = alice.pop_sent_msg().await;
|
let alice_send_reaction = alice.pop_sent_msg().await;
|
||||||
bob.recv_msg(&alice_send_reaction).await;
|
bob.recv_msg(&alice_send_reaction).await;
|
||||||
@@ -670,7 +670,7 @@ Here's my footer -- bob@example.net"
|
|||||||
assert_summary(&bob, "ALICE reacted 🍿 to \"Party?\"").await;
|
assert_summary(&bob, "ALICE reacted 🍿 to \"Party?\"").await;
|
||||||
|
|
||||||
// Alice sends a newer message, this overwrites reaction summaries
|
// Alice sends a newer message, this overwrites reaction summaries
|
||||||
SystemTime::shift(Duration::from_secs(10));
|
SystemTime::shift(Duration::from_secs(10)).await;
|
||||||
let alice_msg2 = alice.send_text(alice_chat.id, "kewl").await;
|
let alice_msg2 = alice.send_text(alice_chat.id, "kewl").await;
|
||||||
bob.recv_msg(&alice_msg2).await;
|
bob.recv_msg(&alice_msg2).await;
|
||||||
|
|
||||||
@@ -678,7 +678,7 @@ Here's my footer -- bob@example.net"
|
|||||||
assert_summary(&bob, "kewl").await;
|
assert_summary(&bob, "kewl").await;
|
||||||
|
|
||||||
// Reactions to older messages still overwrite newer messages
|
// Reactions to older messages still overwrite newer messages
|
||||||
SystemTime::shift(Duration::from_secs(10));
|
SystemTime::shift(Duration::from_secs(10)).await;
|
||||||
send_reaction(&alice, alice_msg1.sender_msg_id, "🤘").await?;
|
send_reaction(&alice, alice_msg1.sender_msg_id, "🤘").await?;
|
||||||
let alice_send_reaction = alice.pop_sent_msg().await;
|
let alice_send_reaction = alice.pop_sent_msg().await;
|
||||||
bob.recv_msg(&alice_send_reaction).await;
|
bob.recv_msg(&alice_send_reaction).await;
|
||||||
@@ -687,7 +687,7 @@ Here's my footer -- bob@example.net"
|
|||||||
assert_summary(&bob, "ALICE reacted 🤘 to \"Party?\"").await;
|
assert_summary(&bob, "ALICE reacted 🤘 to \"Party?\"").await;
|
||||||
|
|
||||||
// Retracted reactions remove all summary reactions
|
// Retracted reactions remove all summary reactions
|
||||||
SystemTime::shift(Duration::from_secs(10));
|
SystemTime::shift(Duration::from_secs(10)).await;
|
||||||
send_reaction(&alice, alice_msg1.sender_msg_id, "").await?;
|
send_reaction(&alice, alice_msg1.sender_msg_id, "").await?;
|
||||||
let alice_remove_reaction = alice.pop_sent_msg().await;
|
let alice_remove_reaction = alice.pop_sent_msg().await;
|
||||||
bob.recv_msg(&alice_remove_reaction).await;
|
bob.recv_msg(&alice_remove_reaction).await;
|
||||||
@@ -696,7 +696,7 @@ Here's my footer -- bob@example.net"
|
|||||||
assert_summary(&bob, "kewl").await;
|
assert_summary(&bob, "kewl").await;
|
||||||
|
|
||||||
// Alice adds another reaction and then deletes the message reacted to; this will also delete reaction summary
|
// Alice adds another reaction and then deletes the message reacted to; this will also delete reaction summary
|
||||||
SystemTime::shift(Duration::from_secs(10));
|
SystemTime::shift(Duration::from_secs(10)).await;
|
||||||
send_reaction(&alice, alice_msg1.sender_msg_id, "🧹").await?;
|
send_reaction(&alice, alice_msg1.sender_msg_id, "🧹").await?;
|
||||||
assert_summary(&alice, "You reacted 🧹 to \"Party?\"").await;
|
assert_summary(&alice, "You reacted 🧹 to \"Party?\"").await;
|
||||||
|
|
||||||
@@ -718,7 +718,7 @@ Here's my footer -- bob@example.net"
|
|||||||
assert_summary(&alice, "foo").await;
|
assert_summary(&alice, "foo").await;
|
||||||
|
|
||||||
// Alice reacts to that message
|
// Alice reacts to that message
|
||||||
SystemTime::shift(Duration::from_secs(10));
|
SystemTime::shift(Duration::from_secs(10)).await;
|
||||||
send_reaction(&alice, msg_id, "🐫").await?;
|
send_reaction(&alice, msg_id, "🐫").await?;
|
||||||
assert_summary(&alice, "You reacted 🐫 to \"foo\"").await;
|
assert_summary(&alice, "You reacted 🐫 to \"foo\"").await;
|
||||||
let reactions = get_msg_reactions(&alice, msg_id).await?;
|
let reactions = get_msg_reactions(&alice, msg_id).await?;
|
||||||
@@ -736,7 +736,7 @@ Here's my footer -- bob@example.net"
|
|||||||
|
|
||||||
// Alice reacts to forwarded message:
|
// Alice reacts to forwarded message:
|
||||||
// For reaction summary neither original message author nor "Forwarded" prefix is shown
|
// For reaction summary neither original message author nor "Forwarded" prefix is shown
|
||||||
SystemTime::shift(Duration::from_secs(10));
|
SystemTime::shift(Duration::from_secs(10)).await;
|
||||||
send_reaction(&alice, forwarded_msg_id, "🐳").await?;
|
send_reaction(&alice, forwarded_msg_id, "🐳").await?;
|
||||||
assert_summary(&alice, "You reacted 🐳 to \"foo\"").await;
|
assert_summary(&alice, "You reacted 🐳 to \"foo\"").await;
|
||||||
let reactions = get_msg_reactions(&alice, msg_id).await?;
|
let reactions = get_msg_reactions(&alice, msg_id).await?;
|
||||||
@@ -754,7 +754,7 @@ Here's my footer -- bob@example.net"
|
|||||||
let msg_id = send_text_msg(&alice0, chat.id, "mom's birthday!".to_string()).await?;
|
let msg_id = send_text_msg(&alice0, chat.id, "mom's birthday!".to_string()).await?;
|
||||||
alice1.recv_msg(&alice0.pop_sent_msg().await).await;
|
alice1.recv_msg(&alice0.pop_sent_msg().await).await;
|
||||||
|
|
||||||
SystemTime::shift(Duration::from_secs(10));
|
SystemTime::shift(Duration::from_secs(10)).await;
|
||||||
send_reaction(&alice0, msg_id, "👆").await?;
|
send_reaction(&alice0, msg_id, "👆").await?;
|
||||||
let sync = alice0.pop_sent_msg().await;
|
let sync = alice0.pop_sent_msg().await;
|
||||||
receive_imf(&alice1, sync.payload().as_bytes(), false).await?;
|
receive_imf(&alice1, sync.payload().as_bytes(), false).await?;
|
||||||
|
|||||||
@@ -3664,7 +3664,7 @@ async fn test_ignore_outdated_membership_changes() -> Result<()> {
|
|||||||
send_text_msg(bob, bob_chat_id, "i'm bob".to_string()).await?;
|
send_text_msg(bob, bob_chat_id, "i'm bob".to_string()).await?;
|
||||||
let msg = &bob.pop_sent_msg().await;
|
let msg = &bob.pop_sent_msg().await;
|
||||||
|
|
||||||
SystemTime::shift(Duration::from_secs(3600));
|
SystemTime::shift(Duration::from_secs(3600)).await;
|
||||||
|
|
||||||
// Alice leaves.
|
// Alice leaves.
|
||||||
remove_contact_from_chat(alice, alice_chat_id, ContactId::SELF).await?;
|
remove_contact_from_chat(alice, alice_chat_id, ContactId::SELF).await?;
|
||||||
@@ -3675,7 +3675,7 @@ async fn test_ignore_outdated_membership_changes() -> Result<()> {
|
|||||||
alice.recv_msg(msg).await;
|
alice.recv_msg(msg).await;
|
||||||
assert!(!is_contact_in_chat(alice, alice_chat_id, ContactId::SELF).await?);
|
assert!(!is_contact_in_chat(alice, alice_chat_id, ContactId::SELF).await?);
|
||||||
|
|
||||||
SystemTime::shift(Duration::from_secs(3600));
|
SystemTime::shift(Duration::from_secs(3600)).await;
|
||||||
|
|
||||||
// Bob replies again adding Alice back.
|
// Bob replies again adding Alice back.
|
||||||
send_text_msg(bob, bob_chat_id, "i'm bob".to_string()).await?;
|
send_text_msg(bob, bob_chat_id, "i'm bob".to_string()).await?;
|
||||||
@@ -3728,7 +3728,7 @@ async fn test_dont_recreate_contacts_on_add_remove() -> Result<()> {
|
|||||||
alice.recv_msg(&bob.pop_sent_msg().await).await;
|
alice.recv_msg(&bob.pop_sent_msg().await).await;
|
||||||
assert_eq!(get_chat_contacts(&alice, alice_chat_id).await?.len(), 3);
|
assert_eq!(get_chat_contacts(&alice, alice_chat_id).await?.len(), 3);
|
||||||
|
|
||||||
SystemTime::shift(Duration::from_secs(3600));
|
SystemTime::shift(Duration::from_secs(3600)).await;
|
||||||
send_text_msg(
|
send_text_msg(
|
||||||
&alice,
|
&alice,
|
||||||
alice_chat_id,
|
alice_chat_id,
|
||||||
@@ -3811,7 +3811,7 @@ async fn test_dont_readd_with_normal_msg() -> Result<()> {
|
|||||||
remove_contact_from_chat(&bob, bob_chat_id, ContactId::SELF).await?;
|
remove_contact_from_chat(&bob, bob_chat_id, ContactId::SELF).await?;
|
||||||
assert_eq!(get_chat_contacts(&bob, bob_chat_id).await?.len(), 1);
|
assert_eq!(get_chat_contacts(&bob, bob_chat_id).await?.len(), 1);
|
||||||
|
|
||||||
SystemTime::shift(Duration::from_secs(3600));
|
SystemTime::shift(Duration::from_secs(3600)).await;
|
||||||
add_contact_to_chat(
|
add_contact_to_chat(
|
||||||
&alice,
|
&alice,
|
||||||
alice_chat_id,
|
alice_chat_id,
|
||||||
|
|||||||
@@ -929,7 +929,7 @@ mod tests {
|
|||||||
assert_eq!(contact_bob.is_verified(&alice.ctx).await.unwrap(), false);
|
assert_eq!(contact_bob.is_verified(&alice.ctx).await.unwrap(), false);
|
||||||
|
|
||||||
if case == SetupContactCase::CheckProtectionTimestamp {
|
if case == SetupContactCase::CheckProtectionTimestamp {
|
||||||
SystemTime::shift(Duration::from_secs(3600));
|
SystemTime::shift(Duration::from_secs(3600)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5+6: Alice receives vc-request-with-auth, sends vc-contact-confirm
|
// Step 5+6: Alice receives vc-request-with-auth, sends vc-contact-confirm
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ async fn check_verified_oneonone_chat(broken_by_classical_email: bool) {
|
|||||||
bob2.set_name("bob2");
|
bob2.set_name("bob2");
|
||||||
bob2.configure_addr("bob@example.net").await;
|
bob2.configure_addr("bob@example.net").await;
|
||||||
|
|
||||||
SystemTime::shift(std::time::Duration::from_secs(3600));
|
SystemTime::shift(std::time::Duration::from_secs(3600)).await;
|
||||||
tcm.send_recv(&bob2, &alice, "Using another device now")
|
tcm.send_recv(&bob2, &alice, "Using another device now")
|
||||||
.await;
|
.await;
|
||||||
let contact = alice.add_or_lookup_contact(&bob).await;
|
let contact = alice.add_or_lookup_contact(&bob).await;
|
||||||
@@ -71,7 +71,7 @@ async fn check_verified_oneonone_chat(broken_by_classical_email: bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tcm.section("Bob sends another message from DC");
|
tcm.section("Bob sends another message from DC");
|
||||||
SystemTime::shift(std::time::Duration::from_secs(3600));
|
SystemTime::shift(std::time::Duration::from_secs(3600)).await;
|
||||||
tcm.send_recv(&bob, &alice, "Using DC again").await;
|
tcm.send_recv(&bob, &alice, "Using DC again").await;
|
||||||
|
|
||||||
// Bob's chat is marked as verified again
|
// Bob's chat is marked as verified again
|
||||||
@@ -797,7 +797,7 @@ async fn test_create_protected_grp_multidev() -> Result<()> {
|
|||||||
let sent = alice.send_text(group_id, "Hey").await;
|
let sent = alice.send_text(group_id, "Hey").await;
|
||||||
// This time shift is necessary to reproduce the bug when the original message is sorted over
|
// This time shift is necessary to reproduce the bug when the original message is sorted over
|
||||||
// the "protection enabled" message so that these messages have different timestamps.
|
// the "protection enabled" message so that these messages have different timestamps.
|
||||||
SystemTime::shift(std::time::Duration::from_secs(3600));
|
SystemTime::shift(std::time::Duration::from_secs(3600)).await;
|
||||||
let msg = alice1.recv_msg(&sent).await;
|
let msg = alice1.recv_msg(&sent).await;
|
||||||
let group1 = Chat::load_from_db(alice1, msg.chat_id).await?;
|
let group1 = Chat::load_from_db(alice1, msg.chat_id).await?;
|
||||||
assert_eq!(group1.get_type(), Chattype::Group);
|
assert_eq!(group1.get_type(), Chattype::Group);
|
||||||
|
|||||||
@@ -2669,7 +2669,7 @@ sth_for_the = "future""#
|
|||||||
let alice_instance = send_webxdc_instance(alice, alice_chat.id).await?;
|
let alice_instance = send_webxdc_instance(alice, alice_chat.id).await?;
|
||||||
let bob_instance = bob.recv_msg(&alice.pop_sent_msg().await).await;
|
let bob_instance = bob.recv_msg(&alice.pop_sent_msg().await).await;
|
||||||
|
|
||||||
SystemTime::shift(Duration::from_secs(1800));
|
SystemTime::shift(Duration::from_secs(1800)).await;
|
||||||
let mut update = Message {
|
let mut update = Message {
|
||||||
chat_id: alice_chat.id,
|
chat_id: alice_chat.id,
|
||||||
viewtype: Viewtype::Text,
|
viewtype: Viewtype::Text,
|
||||||
@@ -2690,7 +2690,7 @@ sth_for_the = "future""#
|
|||||||
r#"[{"payload":{"foo":"bar"},"serial":1,"max_serial":1}]"#
|
r#"[{"payload":{"foo":"bar"},"serial":1,"max_serial":1}]"#
|
||||||
);
|
);
|
||||||
|
|
||||||
SystemTime::shift(Duration::from_secs(2700));
|
SystemTime::shift(Duration::from_secs(2700)).await;
|
||||||
ephemeral::delete_expired_messages(bob, tools::time()).await?;
|
ephemeral::delete_expired_messages(bob, tools::time()).await?;
|
||||||
let bob_instance = Message::load_from_db(bob, bob_instance.id).await?;
|
let bob_instance = Message::load_from_db(bob, bob_instance.id).await?;
|
||||||
assert_eq!(bob_instance.chat_id.is_trash(), false);
|
assert_eq!(bob_instance.chat_id.is_trash(), false);
|
||||||
|
|||||||
Reference in New Issue
Block a user