Skip to content

Commit 0e1b10a

Browse files
committed
iequidoo's review: Make sure statistics are sent again after rewound system time
1 parent 7ed5654 commit 0e1b10a

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

deltachat-time/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ impl SystemTimeTools {
2020
pub fn shift(duration: Duration) {
2121
*SYSTEM_TIME_SHIFT.write().unwrap() += duration;
2222
}
23+
24+
/// Simulates the system clock being rewound by `duration`.
25+
pub fn shift_backwards(duration: Duration) {
26+
*SYSTEM_TIME_SHIFT.write().unwrap() -= duration;
27+
}
2328
}
2429

2530
#[cfg(test)]

src/statistics.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,19 @@ pub async fn maybe_send_statistics(context: &Context) -> Result<Option<ChatId>>
159159
let last_sending_time = context.get_config_i64(Config::StatsLastSent).await?;
160160
let next_sending_time = last_sending_time.saturating_add(SENDING_INTERVAL_SECONDS);
161161
if next_sending_time <= time() {
162+
// Setting this config at the beginning avoids endless loops when things do not
163+
// work out for whatever reason.
164+
context
165+
.set_config_internal(Config::StatsLastSent, Some(&time().to_string()))
166+
.await?;
167+
162168
return Ok(Some(send_statistics(context).await?));
169+
} else if time() < last_sending_time {
170+
// The clock was rewound.
171+
// Reset the config, so that the statistics will be sent normally in a week.
172+
context
173+
.set_config_internal(Config::StatsLastSent, Some(&time().to_string()))
174+
.await?;
163175
}
164176
}
165177
Ok(None)
@@ -184,14 +196,6 @@ pub(crate) async fn should_send_statistics(context: &Context) -> Result<bool> {
184196
async fn send_statistics(context: &Context) -> Result<ChatId> {
185197
info!(context, "Sending statistics.");
186198

187-
// Setting this config at the beginning avoids endless loops when things do not
188-
// work out for whatever reason.
189-
context
190-
.set_config_internal(Config::StatsLastSent, Some(&time().to_string()))
191-
.await
192-
.log_err(context)
193-
.ok();
194-
195199
let chat_id = get_statistics_bot(context).await?;
196200

197201
let mut msg = Message::new(Viewtype::File);

src/statistics/statistics_tests.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,28 @@ async fn test_maybe_send_statistics() -> Result<()> {
4343
Ok(())
4444
}
4545

46+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
47+
async fn test_rewound_time() -> Result<()> {
48+
let alice = &TestContext::new_alice().await;
49+
alice.set_config_bool(Config::StatsSending, true).await?;
50+
51+
const EIGHT_DAYS: Duration = Duration::from_secs(3600 * 24 * 14);
52+
SystemTime::shift(EIGHT_DAYS);
53+
54+
maybe_send_statistics(alice).await?.unwrap();
55+
56+
// The system's time is rewound
57+
SystemTime::shift_backwards(EIGHT_DAYS);
58+
59+
assert!(maybe_send_statistics(alice).await?.is_none());
60+
61+
// After eight days pass again, statistics are sent again
62+
SystemTime::shift(EIGHT_DAYS);
63+
maybe_send_statistics(alice).await?.unwrap();
64+
65+
Ok(())
66+
}
67+
4668
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
4769
async fn test_statistics_one_contact() -> Result<()> {
4870
let mut tcm = TestContextManager::new();

0 commit comments

Comments
 (0)