blob: 5b1ffd66d53a485194ff541a218809c98a7133d7 [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "pw_async/fake_dispatcher_fixture.h"
#include "gtest/gtest.h"
#include "pw_async_fuchsia/dispatcher.h"
#define ASSERT_OK(status) ASSERT_EQ(OkStatus(), status)
#define ASSERT_CANCELLED(status) ASSERT_EQ(Status::Cancelled(), status)
using namespace std::chrono_literals;
namespace pw::async::fuchsia {
namespace {
using FakeDispatcherFuchsiaFixture = async::test::FakeDispatcherFixture;
TEST_F(FakeDispatcherFuchsiaFixture, PostTasks) {
int c = 0;
auto inc_count = [&c](Context& /*ctx*/, Status status) {
ASSERT_OK(status);
++c;
};
Task task(inc_count);
dispatcher().Post(task);
ASSERT_EQ(c, 0);
RunUntilIdle();
ASSERT_EQ(c, 1);
}
TEST_F(FakeDispatcherFuchsiaFixture, DelayedTasks) {
int c = 0;
pw::async::Task first([&c](pw::async::Context& ctx, Status status) {
ASSERT_OK(status);
c = c * 10 + 1;
});
pw::async::Task second([&c](pw::async::Context& ctx, Status status) {
ASSERT_OK(status);
c = c * 10 + 2;
});
pw::async::Task third([&c](pw::async::Context& ctx, Status status) {
ASSERT_OK(status);
c = c * 10 + 3;
});
dispatcher().PostAfter(third, 20ms);
dispatcher().PostAfter(first, 5ms);
dispatcher().PostAfter(second, 10ms);
RunFor(25ms);
EXPECT_EQ(c, 123);
}
TEST_F(FakeDispatcherFuchsiaFixture, CancelTask) {
pw::async::Task task([](pw::async::Context& ctx, Status status) { FAIL(); });
dispatcher().Post(task);
EXPECT_TRUE(dispatcher().Cancel(task));
RunUntilIdle();
}
TEST_F(FakeDispatcherFuchsiaFixture, HeapAllocatedTasks) {
int c = 0;
for (int i = 0; i < 3; i++) {
pw_async_fuchsia::Post(&dispatcher(), [&c](Context& ctx, Status status) {
ASSERT_OK(status);
c++;
});
}
RunUntilIdle();
EXPECT_EQ(c, 3);
}
TEST_F(FakeDispatcherFuchsiaFixture, ChainedTasks) {
int c = 0;
pw_async_fuchsia::Post(&dispatcher(), [&c](Context& ctx, Status status) {
ASSERT_OK(status);
c++;
pw_async_fuchsia::Post(ctx.dispatcher, [&c](Context& ctx, Status status) {
ASSERT_OK(status);
c++;
pw_async_fuchsia::Post(ctx.dispatcher, [&c](Context& ctx, Status status) {
ASSERT_OK(status);
c++;
});
});
});
RunUntilIdle();
EXPECT_EQ(c, 3);
}
TEST_F(FakeDispatcherFuchsiaFixture, DestroyLoopInsideTask) {
int c = 0;
auto inc_count = [&c](Context& ctx, Status status) {
ASSERT_CANCELLED(status);
++c;
};
// These tasks are never executed and cleaned up in DestroyLoop().
Task task0(inc_count), task1(inc_count);
dispatcher().PostAfter(task0, 20ms);
dispatcher().PostAfter(task1, 21ms);
Task stop_task([&c](Context& ctx, Status status) {
ASSERT_OK(status);
++c;
static_cast<test::FakeDispatcher*>(ctx.dispatcher)->RequestStop();
// Stop has been requested; now drive the Dispatcher so it destroys the loop.
static_cast<test::FakeDispatcher*>(ctx.dispatcher)->RunUntilIdle();
});
dispatcher().Post(stop_task);
RunUntilIdle();
EXPECT_EQ(c, 3);
}
} // namespace
} // namespace pw::async::fuchsia