blob: 3f3eae5487f1de967adc38a814534f24cbd9d303 [file] [log] [blame]
// Copyright 2022 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.
#ifndef SRC_TESTS_FIDL_DYNSUITE_SERVER_SUITE_HARNESS_HARNESS_H_
#define SRC_TESTS_FIDL_DYNSUITE_SERVER_SUITE_HARNESS_HARNESS_H_
#include <fidl/fidl.serversuite/cpp/fidl.h>
#include <fidl/fidl.serversuite/cpp/markers.h>
#include <fidl/fidl.serversuite/cpp/natural_types.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/fidl/cpp/client.h>
#include <optional>
#include <gtest/gtest.h>
#include "src/tests/fidl/dynsuite/channel_util/channel.h"
namespace server_suite {
// Defines a server test using GoogleTest.
// Use {CLOSED,AJAR,OPEN}_SERVER_TEST for the {Closed,Ajar,Open}Target protocol.
// (1) test_number must be a fidl.serversuite/Test enum member value.
// (2) test_name must be the enum member's name in UpperCamelCase.
// We include (1) to make it easier to correlate logs when a test fails.
#define CLOSED_SERVER_TEST(test_number, test_name) \
SERVER_TEST_IMPL(test_number, test_name, fidl_serversuite::AnyTarget::Tag::kClosed)
#define AJAR_SERVER_TEST(test_number, test_name) \
SERVER_TEST_IMPL(test_number, test_name, fidl_serversuite::AnyTarget::Tag::kAjar)
#define OPEN_SERVER_TEST(test_number, test_name) \
SERVER_TEST_IMPL(test_number, test_name, fidl_serversuite::AnyTarget::Tag::kOpen)
#define SERVER_TEST_IMPL(test_number, test_name, target_kind) \
static_assert((test_number) == static_cast<uint32_t>(fidl_serversuite::Test::k##test_name), \
"In SERVER_TEST macro: test number " #test_number \
" does not match test name \"" #test_name "\""); \
struct ServerTest_##test_number : public ServerTest { \
explicit ServerTest_##test_number() \
: ServerTest(fidl_serversuite::Test::k##test_name, target_kind) {} \
}; \
/* NOLINTNEXTLINE(google-readability-avoid-underscore-in-googletest-name) */ \
TEST_F(ServerTest_##test_number, test_name)
// Skips the test if Runner.GetVersion() is older than min_version.
#define SKIP_IF_VERSION_OLDER_THAN(min_version) \
if (runner_version() < (min_version)) { \
GTEST_SKIP() << "Skipping because Runner.GetVersion() returned " << runner_version() \
<< " which is older than the minimum version " << (min_version); \
}
// Asserts that a fit::result<fidl::Error> is ok. Useful for Runner FIDL calls.
#define ASSERT_RESULT_OK(result) \
{ \
auto the_result = (result); \
ASSERT_TRUE(the_result.is_ok()) << "Error: " << the_result.error_value(); \
}
// X macro for Runner event names.
#define X_RUNNER_EVENT_NAMES \
X(OnTeardown) \
X(OnReceivedUnknownMethod) \
X(OnReceivedClosedTargetOneWayNoPayload) \
X(OnReceivedOpenTargetStrictOneWay) \
X(OnReceivedOpenTargetFlexibleOneWay)
// Enum of events on the Runner protocol.
enum struct RunnerEvent : uint8_t {
#define X(name) k##name,
X_RUNNER_EVENT_NAMES
#undef X
};
// Variant of payload types for RunnerEvent.
using RunnerEventPayload = std::variant<std::monostate, fidl_serversuite::TeardownReason,
fidl_serversuite::UnknownMethodInfo>;
// Asserts that the harness receives the given RunnerEvent.
#define ASSERT_RUNNER_EVENT(expected_event) \
{ \
SCOPED_TRACE("ASSERT_RUNNER_EVENT failed"); \
AssertRunnerEventImpl(expected_event); \
if (HasFatalFailure()) \
return; \
}
// Asserts that the Target server bindings get torn down. This tests both the
// external behavior (observed PEER_CLOSED on the client end) and the internal
// behavior (Runner sent OnTeardown event reporting the reason).
//
// By default, the test fixture automatically does this at the end of each test:
//
// client_end().reset();
// ASSERT_SERVER_TEARDOWN(fidl_serversuite::TeardownReason::kPeerClosed);
//
// It won't do that if the test calls ASSERT_SERVER_TEARDOWN manually.
#define ASSERT_SERVER_TEARDOWN(expected_reason) \
{ \
SCOPED_TRACE("ASSERT_SERVER_TEARDOWN failed"); \
AssertServerTeardownImpl(expected_reason); \
if (HasFatalFailure()) \
return; \
}
// The test fixture used by the SERVER_TEST macros.
class ServerTest : public testing::Test {
public:
explicit ServerTest(fidl_serversuite::Test test, fidl_serversuite::AnyTarget::Tag target_kind)
: test_(test), target_kind_(target_kind) {}
void SetUp() override;
void TearDown() override;
// Returns the sync client for the Runner.
const fidl::SyncClient<fidl_serversuite::Runner>& runner() { return runner_; }
// Returns the client end of the Target channel.
channel_util::Channel& client_end() { return client_end_; }
// This can be accessed after ASSERT_RUNNER_EVENT.
const RunnerEventPayload& runner_event_payload() { return runner_event_payload_; }
// Do not call these directly. Use the macros instead.
uint64_t runner_version() { return runner_version_.value(); }
void AssertRunnerEventImpl(RunnerEvent expected_event);
void AssertServerTeardownImpl(fidl_serversuite::TeardownReason expected_reason);
private:
fidl_serversuite::Test test_;
fidl_serversuite::AnyTarget::Tag target_kind_;
fidl::SyncClient<fidl_serversuite::Runner> runner_;
std::optional<uint64_t> runner_version_;
channel_util::Channel client_end_;
bool asserted_teardown_ = false;
RunnerEventPayload runner_event_payload_;
};
} // namespace server_suite
#endif // SRC_TESTS_FIDL_DYNSUITE_SERVER_SUITE_HARNESS_HARNESS_H_