blob: 1be639522fa4d3d97f29b5e1c158565a4470d256 [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 "test-utils.h"
#include <lib/async-loop/default.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>
#include <gmock/gmock.h>
#include "remote.h"
namespace fuzzing {
using ::testing::Eq;
std::atomic<TestBase*> TestBase::current_(nullptr);
TestBase::TestBase() : loop_(&kAsyncLoopConfigNoAttachToCurrentThread), provider_(dispatcher()) {}
// gTest methods
void TestBase::SetUp() {
ASSERT_EQ(current_.exchange(this), nullptr);
::testing::Test::SetUp();
loop_.StartThread();
context_ = provider_.TakeContext();
sync_completion_reset(&sync_);
}
void TestBase::TearDown() {
ASSERT_FALSE(sync_completion_signaled(&sync_));
loop_.Quit();
loop_.JoinThreads();
ASSERT_EQ(loop_.ResetQuit(), ZX_OK);
::testing::Test::TearDown();
ASSERT_EQ(current_.exchange(nullptr), this);
}
// Sync methods
void TestBase::Signal() {
ASSERT_FALSE(sync_completion_signaled(&sync_));
sync_completion_signal(&sync_);
}
void TestBase::Wait() {
ASSERT_EQ(sync_completion_wait(&sync_, ZX_TIME_INFINITE), ZX_OK);
sync_completion_reset(&sync_);
}
// Eventpair methods
void TestBase::SignalPeer(zx_signals_t signals) {
ASSERT_EQ(ep_.signal_peer(0, signals & ZX_USER_SIGNAL_ALL), ZX_OK);
}
zx_signals_t TestBase::WaitOne() {
zx_signals_t observed;
if (ep_.wait_one(ZX_USER_SIGNAL_ALL, zx::time::infinite(), &observed) != ZX_OK ||
ep_.signal(observed, 0) != ZX_OK) {
return zx_signals_t(0);
}
return observed;
}
// Recording methods
TestBase* TestBase::Record(const std::string& func) {
auto* current = current_.load();
FX_CHECK(current);
std::lock_guard<std::mutex> lock(current->mutex_);
current->recorded_ = func;
return current;
}
const char* TestBase::GetRecorded() {
std::lock_guard<std::mutex> lock(mutex_);
return recorded_.c_str();
}
void TestBase::SetU64(const std::string& key, uint64_t val) {
std::lock_guard<std::mutex> lock(mutex_);
u64s_[key] = val;
}
uint64_t TestBase::GetU64(const std::string& key) {
std::lock_guard<std::mutex> lock(mutex_);
auto i = u64s_.find(key);
FX_CHECK(i != u64s_.end());
return i->second;
}
void TestBase::SetBytes(const std::string& key, const uint8_t* buf, size_t buf_len) {
std::lock_guard<std::mutex> lock(mutex_);
auto& bytes = bytes_[key];
bytes.clear();
bytes.insert(bytes.end(), buf, buf + buf_len);
}
std::vector<uint8_t> TestBase::GetBytes(const std::string& key) {
std::lock_guard<std::mutex> lock(mutex_);
auto i = bytes_.find(key);
if (i == bytes_.end()) {
return std::vector<uint8_t>();
}
return i->second;
}
void TestBase::MatchBytes(const std::string& key, const std::vector<uint8_t>& bytes) {
std::lock_guard<std::mutex> lock(mutex_);
auto i = bytes_.find(key);
ASSERT_NE(i, bytes_.end());
EXPECT_THAT(i->second, Eq(bytes));
}
} // namespace fuzzing