[async-testutils] Allow giving a seed in TestLoop's constructor
This allows passing the TEST_LOOP_RANDOM_SEED through other means if the
environment is not usable.
Test: async-testutils-test
Change-Id: I51396388a232546dd1cdea583df2f944390af870
diff --git a/system/ulib/async-testutils/include/lib/async-testutils/test_loop.h b/system/ulib/async-testutils/include/lib/async-testutils/test_loop.h
index 400168b..e10acba 100644
--- a/system/ulib/async-testutils/include/lib/async-testutils/test_loop.h
+++ b/system/ulib/async-testutils/include/lib/async-testutils/test_loop.h
@@ -19,11 +19,15 @@
virtual async_dispatcher_t* dispatcher() = 0;
};
-
// A message loop with a fake clock, to be controlled within a test setting.
class TestLoop {
public:
+ // Constructs a TestLoop with a seed from the environment, or a random
+ // seed if absent.
TestLoop();
+ // If state is nonzero, constructs a TestLoop with the given seed.
+ // Otherwise, uses a seed from the environment or a random seed.
+ TestLoop(uint32_t state);
~TestLoop();
// Returns the test loop's asynchronous dispatcher.
diff --git a/system/ulib/async-testutils/test_loop.cpp b/system/ulib/async-testutils/test_loop.cpp
index 343086d..4cd32cb 100644
--- a/system/ulib/async-testutils/test_loop.cpp
+++ b/system/ulib/async-testutils/test_loop.cpp
@@ -43,7 +43,6 @@
zx_cprng_draw(&random_seed, sizeof(uint32_t));
}
- printf("\nTEST_LOOP_RANDOM_SEED=\"%u\"\n", random_seed);
return random_seed;
}
@@ -147,10 +146,15 @@
TestLoopDispatcher* dispatcher_;
};
-TestLoop::TestLoop()
- : time_keeper_(new TestLoopTimeKeeper()), initial_state_(GetRandomSeed()), state_(initial_state_) {
+TestLoop::TestLoop() : TestLoop(0) {}
+
+TestLoop::TestLoop(uint32_t state)
+ : time_keeper_(new TestLoopTimeKeeper()),
+ initial_state_((state != 0)? state : GetRandomSeed()), state_(initial_state_) {
dispatchers_.push_back(fbl::make_unique<TestLoopDispatcher>(time_keeper_.get()));
async_set_default_dispatcher(dispatchers_[0].get());
+
+ printf("\nTEST_LOOP_RANDOM_SEED=\"%u\"\n", initial_state_);
}
TestLoop::~TestLoop() {
diff --git a/system/utest/async-testutils/test_loop_tests.cpp b/system/utest/async-testutils/test_loop_tests.cpp
index e15c41d..e2721a6 100644
--- a/system/utest/async-testutils/test_loop_tests.cpp
+++ b/system/utest/async-testutils/test_loop_tests.cpp
@@ -14,6 +14,7 @@
#include <unittest/unittest.h>
#include <zircon/syscalls.h>
+#include <memory>
#include <utility>
namespace {
@@ -525,15 +526,13 @@
// Populates |order| with the order in which two tasks and two waits on four
-// loops were dispatched, given a |random_seed|.
-bool DetermineDispatchOrder(const char* random_seed, int (*order)[4]) {
+// loops were dispatched, given a |loop|.
+ bool DetermineDispatchOrder(std::unique_ptr<async::TestLoop> loop, int (*order)[4]) {
BEGIN_HELPER;
- ASSERT_EQ(0, setenv("TEST_LOOP_RANDOM_SEED", random_seed, 1));
- async::TestLoop loop;
- auto loopA = loop.StartNewLoop();
- auto loopB = loop.StartNewLoop();
- auto loopC = loop.StartNewLoop();
+ auto loopA = loop->StartNewLoop();
+ auto loopB = loop->StartNewLoop();
+ auto loopC = loop->StartNewLoop();
async::Wait wait;
async::Wait waitB;
zx::event event;
@@ -546,11 +545,11 @@
InitWait(&waitB, [&] { (*order)[2] = ++i; }, event, ZX_USER_SIGNAL_0);
async::PostTask(loopC->dispatcher(), [&] { (*order)[3] = ++i; });
- ASSERT_EQ(ZX_OK, wait.Begin(loop.dispatcher()));
+ ASSERT_EQ(ZX_OK, wait.Begin(loop->dispatcher()));
ASSERT_EQ(ZX_OK, waitB.Begin(loopB->dispatcher()));
ASSERT_EQ(ZX_OK, event.signal(0u, ZX_USER_SIGNAL_0));
- loop.RunUntilIdle();
+ loop->RunUntilIdle();
EXPECT_EQ(4, i);
EXPECT_NE(0, (*order)[0]);
@@ -558,24 +557,44 @@
EXPECT_NE(0, (*order)[2]);
EXPECT_NE(0, (*order)[3]);
- ASSERT_EQ(0, unsetenv("TEST_LOOP_RANDOM_SEED"));
+ END_HELPER;
+}
+
+bool SeedTestLoopWithEnv(uint32_t random_seed, std::unique_ptr<async::TestLoop>* loop) {
+ BEGIN_HELPER;
+
+ char buf[12];
+ snprintf(buf, sizeof(buf), "%u", random_seed);
+ EXPECT_EQ(0, setenv("TEST_LOOP_RANDOM_SEED", buf, 1));
+ *loop = std::make_unique<async::TestLoop>();
+ EXPECT_EQ(0, unsetenv("TEST_LOOP_RANDOM_SEED"));
END_HELPER;
}
-bool DispatchOrderIsDeterministicFor(const char* random_seed) {
+bool DispatchOrderIsDeterministicFor(uint32_t random_seed) {
BEGIN_HELPER;
int expected_order[4] = {0, 0, 0, 0};
- EXPECT_TRUE(DetermineDispatchOrder(random_seed, &expected_order));
+ std::unique_ptr<async::TestLoop> loop;
+
+ EXPECT_TRUE(SeedTestLoopWithEnv(random_seed, &loop));
+ EXPECT_TRUE(DetermineDispatchOrder(std::move(loop), &expected_order));
for (int i = 0; i < 5; ++i) {
- int actual_order[4] = {0, 0, 0, 0};
- EXPECT_TRUE(DetermineDispatchOrder(random_seed, &actual_order));
- EXPECT_EQ(expected_order[0], actual_order[0]);
- EXPECT_EQ(expected_order[1], actual_order[1]);
- EXPECT_EQ(expected_order[2], actual_order[2]);
- EXPECT_EQ(expected_order[3], actual_order[3]);
+ for (int j = 0; j < 2; j++) {
+ int actual_order[4] = {0, 0, 0, 0};
+ if (j == 0) {
+ EXPECT_TRUE(SeedTestLoopWithEnv(random_seed, &loop));
+ } else {
+ loop = std::make_unique<async::TestLoop>(random_seed);
+ }
+ EXPECT_TRUE(DetermineDispatchOrder(std::move(loop), &actual_order));
+ EXPECT_EQ(expected_order[0], actual_order[0]);
+ EXPECT_EQ(expected_order[1], actual_order[1]);
+ EXPECT_EQ(expected_order[2], actual_order[2]);
+ EXPECT_EQ(expected_order[3], actual_order[3]);
+ }
}
END_HELPER;
@@ -585,15 +604,15 @@
bool DispatchOrderIsDeterministic() {
BEGIN_TEST;
- EXPECT_TRUE(DispatchOrderIsDeterministicFor("1"));
- EXPECT_TRUE(DispatchOrderIsDeterministicFor("43"));
- EXPECT_TRUE(DispatchOrderIsDeterministicFor("893"));
- EXPECT_TRUE(DispatchOrderIsDeterministicFor("39408"));
- EXPECT_TRUE(DispatchOrderIsDeterministicFor("844018"));
- EXPECT_TRUE(DispatchOrderIsDeterministicFor("83018299"));
- EXPECT_TRUE(DispatchOrderIsDeterministicFor("3213"));
- EXPECT_TRUE(DispatchOrderIsDeterministicFor("139133113"));
- EXPECT_TRUE(DispatchOrderIsDeterministicFor("1323234373"));
+ EXPECT_TRUE(DispatchOrderIsDeterministicFor(1));
+ EXPECT_TRUE(DispatchOrderIsDeterministicFor(43));
+ EXPECT_TRUE(DispatchOrderIsDeterministicFor(893));
+ EXPECT_TRUE(DispatchOrderIsDeterministicFor(39408));
+ EXPECT_TRUE(DispatchOrderIsDeterministicFor(844018));
+ EXPECT_TRUE(DispatchOrderIsDeterministicFor(83018299));
+ EXPECT_TRUE(DispatchOrderIsDeterministicFor(3213));
+ EXPECT_TRUE(DispatchOrderIsDeterministicFor(139133113));
+ EXPECT_TRUE(DispatchOrderIsDeterministicFor(1323234373));
END_TEST;
}