blob: aad1c64e95019a069366580f77c06cdfdb1e4ba4 [file] [log] [blame]
// Copyright 2021 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 <lib/async-testing/test_loop.h>
#include <zircon/time.h>
#include <memory>
#include <thread>
#include <zxtest/zxtest.h>
#include "src/iwlwifi/platform/task-internal.h"
namespace wlan::testing {
namespace {
TEST(TaskTest, TaskLifecycle) {
auto test_loop = std::make_unique<::async::TestLoop>();
bool called = false;
auto task = std::make_unique<::wlan::iwlwifi::TaskInternal>(
test_loop->dispatcher(), [](void* data) { *reinterpret_cast<bool*>(data) = true; }, &called);
EXPECT_FALSE(called);
EXPECT_OK(task->Post(ZX_MSEC(1)));
EXPECT_FALSE(called);
test_loop->RunFor(zx::usec(500));
EXPECT_FALSE(called);
test_loop->RunFor(zx::usec(500));
EXPECT_TRUE(called);
called = false;
task.reset();
EXPECT_FALSE(called);
}
TEST(TaskTest, RepostTask) {
auto test_loop = std::make_unique<::async::TestLoop>();
bool called = false;
auto task = std::make_unique<::wlan::iwlwifi::TaskInternal>(
test_loop->dispatcher(), [](void* data) { *reinterpret_cast<bool*>(data) = true; }, &called);
EXPECT_OK(task->Post(ZX_MSEC(1)));
EXPECT_FALSE(called);
test_loop->RunFor(zx::usec(500));
EXPECT_FALSE(called);
// Repost the task with a later deadline.
EXPECT_OK(task->Post(ZX_MSEC(1)));
EXPECT_FALSE(called);
// This will pass the original deadline.
test_loop->RunFor(zx::usec(500));
EXPECT_FALSE(called);
// This will pass the new deadline.
test_loop->RunFor(zx::usec(500));
EXPECT_TRUE(called);
}
TEST(TaskTest, CancelTask) {
auto test_loop = std::make_unique<::async::TestLoop>();
bool called = false;
auto task = std::make_unique<::wlan::iwlwifi::TaskInternal>(
test_loop->dispatcher(), [](void* data) { *reinterpret_cast<bool*>(data) = true; }, &called);
EXPECT_OK(task->Post(ZX_MSEC(1)));
EXPECT_FALSE(called);
test_loop->RunFor(zx::usec(500));
EXPECT_FALSE(called);
// Cancel the task.
EXPECT_OK(task->CancelSync());
EXPECT_FALSE(called);
test_loop->RunFor(zx::usec(500));
EXPECT_FALSE(called);
// Cancelling the task a second time will not find the task.
EXPECT_EQ(ZX_ERR_NOT_FOUND, task->Cancel());
EXPECT_FALSE(called);
}
TEST(TaskTest, WaitTask) {
auto test_loop = std::make_unique<::async::TestLoop>();
bool called = false;
auto task = std::make_unique<::wlan::iwlwifi::TaskInternal>(
test_loop->dispatcher(), [](void* data) { *reinterpret_cast<bool*>(data) = true; }, &called);
bool run_waited = false;
EXPECT_OK(task->Post(ZX_MSEC(1)));
std::thread run_wait_thread([&]() {
EXPECT_OK(task->Wait());
run_waited = true;
});
EXPECT_FALSE(called);
EXPECT_FALSE(run_waited);
test_loop->RunFor(zx::usec(500));
EXPECT_FALSE(called);
EXPECT_FALSE(run_waited);
// Once the full deadline has passed, the wait will unblock and complete.
test_loop->RunFor(zx::usec(500));
run_wait_thread.join();
EXPECT_TRUE(called);
EXPECT_TRUE(run_waited);
called = false;
bool cancel_waited = false;
EXPECT_OK(task->Post(ZX_MSEC(1)));
std::thread cancel_wait_thread([&]() {
EXPECT_OK(task->Wait());
cancel_waited = true;
});
EXPECT_FALSE(called);
EXPECT_FALSE(cancel_waited);
test_loop->RunFor(zx::usec(500));
EXPECT_FALSE(called);
EXPECT_FALSE(cancel_waited);
// Once the task has been cancelled, the wait will unblock and complete.
EXPECT_OK(task->CancelSync());
cancel_wait_thread.join();
EXPECT_FALSE(called);
EXPECT_TRUE(cancel_waited);
}
} // namespace
} // namespace wlan::testing