Public Access
Issue #52: once a newer release is known, wait for a quiet moment, ask for 30 seconds, and install unless the answer is no. The caller says what busy and idle are. Host-tested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0162FokPdvY2KsS4NBfwyWPk
138 lines
4.6 KiB
C++
138 lines
4.6 KiB
C++
#include <unity.h>
|
|
|
|
#include "auto_update.h"
|
|
#include "update_check.h"
|
|
|
|
using namespace roro::release;
|
|
using Action = AutoUpdate::Action;
|
|
|
|
void setUp() {}
|
|
void tearDown() {}
|
|
|
|
namespace {
|
|
constexpr uint32_t kIdle = AutoUpdate::kIdleMs, kAsk = AutoUpdate::kAskMs;
|
|
Release release(const char* tag) {
|
|
Release r;
|
|
r.tag = tag;
|
|
r.otaUrl = "https://git.twis.la/twisla/roro9stack/releases/download/x/x.ota";
|
|
r.otaSize = 1;
|
|
return r;
|
|
}
|
|
} // namespace
|
|
|
|
void test_nothing_happens_without_an_offer() {
|
|
AutoUpdate a;
|
|
TEST_ASSERT_TRUE(a.step(1000, false, kIdle) == Action::None);
|
|
TEST_ASSERT_FALSE(a.waiting());
|
|
TEST_ASSERT_FALSE(a.asking());
|
|
}
|
|
|
|
void test_it_waits_for_a_quiet_moment() {
|
|
AutoUpdate a;
|
|
a.offer("v1.2.0");
|
|
TEST_ASSERT_TRUE(a.waiting());
|
|
TEST_ASSERT_TRUE(a.step(1000, false, kIdle - 1) == Action::None); // a key not long ago
|
|
TEST_ASSERT_TRUE(a.step(2000, true, kIdle * 10) == Action::None); // a Track is recording
|
|
TEST_ASSERT_TRUE(a.step(3000, false, kIdle) == Action::Ask);
|
|
TEST_ASSERT_TRUE(a.asking());
|
|
TEST_ASSERT_EQUAL_STRING("v1.2.0", a.tag().c_str());
|
|
}
|
|
|
|
void test_unanswered_it_installs_after_30_seconds() {
|
|
AutoUpdate a;
|
|
a.offer("v1.2.0");
|
|
a.step(5000, false, kIdle);
|
|
TEST_ASSERT_EQUAL(30, a.secondsLeft(5000));
|
|
TEST_ASSERT_EQUAL(30, a.secondsLeft(5001));
|
|
TEST_ASSERT_EQUAL(1, a.secondsLeft(5000 + kAsk - 1));
|
|
TEST_ASSERT_TRUE(a.step(5000 + kAsk - 1, false, kIdle) == Action::None);
|
|
TEST_ASSERT_TRUE(a.step(5000 + kAsk, false, kIdle) == Action::Install);
|
|
TEST_ASSERT_FALSE(a.asking());
|
|
TEST_ASSERT_TRUE(a.step(5000 + kAsk + 1, false, kIdle) == Action::None); // once
|
|
}
|
|
|
|
void test_accept_installs_at_once() {
|
|
AutoUpdate a;
|
|
a.offer("v1.2.0");
|
|
a.step(0, false, kIdle);
|
|
a.answer(true);
|
|
TEST_ASSERT_TRUE(a.step(100, false, 0) == Action::Install);
|
|
}
|
|
|
|
void test_cancel_drops_it_until_the_next_offer() {
|
|
AutoUpdate a;
|
|
a.offer("v1.2.0");
|
|
a.step(0, false, kIdle);
|
|
a.answer(false);
|
|
TEST_ASSERT_TRUE(a.step(100, false, 0) == Action::Dismiss);
|
|
TEST_ASSERT_TRUE(a.step(kAsk * 2, false, kIdle * 2) == Action::None);
|
|
a.offer("v1.2.0"); // the next day's check
|
|
TEST_ASSERT_TRUE(a.step(kAsk * 3, false, kIdle) == Action::Ask);
|
|
}
|
|
|
|
void test_something_starting_takes_the_question_down() {
|
|
AutoUpdate a;
|
|
a.offer("v1.2.0");
|
|
a.step(0, false, kIdle);
|
|
TEST_ASSERT_TRUE(a.step(1000, true, kIdle) == Action::Dismiss);
|
|
TEST_ASSERT_TRUE(a.waiting());
|
|
TEST_ASSERT_TRUE(a.step(2000, true, kIdle) == Action::None);
|
|
TEST_ASSERT_TRUE(a.step(90000, false, kIdle) == Action::Ask); // and it comes back, with a full count
|
|
TEST_ASSERT_EQUAL(30, a.secondsLeft(90000));
|
|
}
|
|
|
|
void test_the_setting_going_off_withdraws_it() {
|
|
AutoUpdate a;
|
|
a.offer("v1.2.0");
|
|
a.withdraw();
|
|
TEST_ASSERT_TRUE(a.step(0, false, kIdle) == Action::None);
|
|
TEST_ASSERT_FALSE(a.waiting());
|
|
a.offer("v1.2.0");
|
|
a.step(0, false, kIdle);
|
|
a.withdraw();
|
|
TEST_ASSERT_TRUE(a.step(10, false, kIdle) == Action::Dismiss);
|
|
TEST_ASSERT_FALSE(a.asking());
|
|
}
|
|
|
|
void test_an_answer_is_only_for_a_question() {
|
|
AutoUpdate a;
|
|
a.offer("v1.2.0");
|
|
a.answer(true); // nothing was asked yet
|
|
TEST_ASSERT_TRUE(a.step(0, false, kIdle) == Action::Ask);
|
|
TEST_ASSERT_TRUE(a.step(1, false, kIdle) == Action::None);
|
|
}
|
|
|
|
void test_a_newer_offer_replaces_the_tag() {
|
|
AutoUpdate a;
|
|
a.offer("v1.2.0");
|
|
a.offer("v1.3.0");
|
|
a.step(0, false, kIdle);
|
|
TEST_ASSERT_EQUAL_STRING("v1.3.0", a.tag().c_str());
|
|
}
|
|
|
|
void test_what_is_offered() {
|
|
// Newer than what runs, and not a version that rolled back here.
|
|
TEST_ASSERT_TRUE(shouldInstall(release("v1.2.0"), "v1.1.0", ""));
|
|
TEST_ASSERT_FALSE(shouldInstall(release("v1.1.0"), "v1.1.0", ""));
|
|
TEST_ASSERT_FALSE(shouldInstall(release("v1.0.0"), "v1.1.0", ""));
|
|
TEST_ASSERT_FALSE(shouldInstall(release("v1.2.0"), "v1.1.0", "v1.2.0"));
|
|
Release noFile = release("v1.2.0");
|
|
noFile.otaUrl.clear();
|
|
TEST_ASSERT_FALSE(shouldInstall(noFile, "v1.1.0", ""));
|
|
}
|
|
|
|
int main() {
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_nothing_happens_without_an_offer);
|
|
RUN_TEST(test_it_waits_for_a_quiet_moment);
|
|
RUN_TEST(test_unanswered_it_installs_after_30_seconds);
|
|
RUN_TEST(test_accept_installs_at_once);
|
|
RUN_TEST(test_cancel_drops_it_until_the_next_offer);
|
|
RUN_TEST(test_something_starting_takes_the_question_down);
|
|
RUN_TEST(test_the_setting_going_off_withdraws_it);
|
|
RUN_TEST(test_an_answer_is_only_for_a_question);
|
|
RUN_TEST(test_a_newer_offer_replaces_the_tag);
|
|
RUN_TEST(test_what_is_offered);
|
|
return UNITY_END();
|
|
}
|