blob: 09231852b5848f8c50b850d2c8236633204e7c8c [file] [log] [blame]
// Copyright 2024 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 <fidl/fuchsia.debugdata/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/ld/testing/mock-debugdata.h>
#include <zircon/status.h>
#include <string_view>
#include <gtest/gtest.h>
#include "debugdata-tests.h"
namespace {
using ::testing::AllOf;
using ::testing::Not;
using ld::testing::GetKoid;
using ld::testing::kNotIt;
using ld::testing::kSinkName;
using ld::testing::kVmoContents;
using ld::testing::kVmoName;
using ld::testing::MakeEventPair;
using ld::testing::MakeTestVmo;
class LdMockDebugdataTests : public ::testing::Test {
public:
void SetUp() override;
zx::vmo& test_vmo() { return test_vmo_; }
zx::eventpair& test_eventpair_client() { return test_eventpair_client_; }
zx::eventpair& test_eventpair_server() { return test_eventpair_server_; }
zx_koid_t test_vmo_koid() const { return test_vmo_koid_; }
zx_koid_t test_eventpair_server_koid() const { return test_eventpair_server_koid_; }
private:
zx::vmo test_vmo_;
zx::eventpair test_eventpair_client_, test_eventpair_server_;
zx_koid_t test_vmo_koid_, test_eventpair_server_koid_;
};
void LdMockDebugdataTests::SetUp() {
ASSERT_NO_FATAL_FAILURE(MakeTestVmo(test_vmo_));
ASSERT_NO_FATAL_FAILURE(GetKoid(test_vmo_, test_vmo_koid_));
ASSERT_NO_FATAL_FAILURE(MakeEventPair(test_eventpair_client_, test_eventpair_server_));
ASSERT_NO_FATAL_FAILURE(GetKoid(test_eventpair_server_, test_eventpair_server_koid_));
}
// This is really a test of the matchers more than MockDebugdata since it's
// nothing but a gmock method in a FIDL bindings class. There's no point in
// testing that the FIDL bindings work at this layer.
TEST_F(LdMockDebugdataTests, MockDebugdata) {
::testing::StrictMock<ld::testing::MockDebugdata> mock;
EXPECT_CALL(mock, Publish(kSinkName,
AllOf(ld::testing::ObjNameMatches(kVmoName),
Not(ld::testing::ObjNameMatches(kNotIt)),
ld::testing::ObjKoidMatches(test_vmo_koid()),
Not(ld::testing::ObjKoidMatches(ZX_KOID_INVALID)),
Not(ld::testing::ObjKoidMatches(test_eventpair_server_koid())),
ld::testing::VmoContentsMatch(kVmoContents),
Not(ld::testing::VmoContentsMatch(kNotIt))),
AllOf(ld::testing::ObjKoidMatches(test_eventpair_server_koid()),
Not(ld::testing::ObjKoidMatches(ZX_KOID_INVALID)),
Not(ld::testing::ObjKoidMatches(test_vmo_koid())))));
mock.Publish(kSinkName, std::move(test_vmo()), std::move(test_eventpair_server()));
}
// This tests end-to-end via the FIDL server bindings as an integration test
// for the MockSvcDirectory as well as the MockDebugdata.
TEST_F(LdMockDebugdataTests, MockSvcDirectory) {
// First create and prime the mock.
auto mock = std::make_unique<::testing::StrictMock<ld::testing::MockDebugdata>>();
EXPECT_CALL(*mock, Publish(kSinkName,
AllOf(ld::testing::ObjNameMatches(kVmoName),
ld::testing::ObjKoidMatches(test_vmo_koid()),
ld::testing::VmoContentsMatch(kVmoContents)),
ld::testing::ObjKoidMatches(test_eventpair_server_koid())));
// Now move it into the directory.
ld::testing::MockSvcDirectory svc_dir;
ASSERT_NO_FATAL_FAILURE(svc_dir.Init());
ASSERT_NO_FATAL_FAILURE(svc_dir.AddEntry<fuchsia_debugdata::Publisher>(std::move(mock)));
// Make a channel for the debugdata protocol.
fidl::ClientEnd<fuchsia_debugdata::Publisher> debugdata_client_end;
zx::result debugdata_server_end = fidl::CreateEndpoints(&debugdata_client_end);
ASSERT_TRUE(debugdata_server_end.is_ok()) << debugdata_server_end.status_string();
// Stuff the Publish call into the client end.
fidl::SyncClient debugdata_client(std::move(debugdata_client_end));
auto publish_result = debugdata_client->Publish({{
.data_sink{kSinkName},
.data{std::move(test_vmo())},
.vmo_token{std::move(test_eventpair_server())},
}});
ASSERT_TRUE(publish_result.is_ok()) << publish_result.error_value();
// Send the debugdata server end in the Open call to the directory.
fidl::ClientEnd<fuchsia_io::Directory> svc_client_end;
ASSERT_NO_FATAL_FAILURE(svc_dir.Serve(svc_client_end));
fidl::SyncClient svc_client(std::move(svc_client_end));
auto open_result = svc_client->Open({{
.path{fidl::DiscoverableProtocolName<fuchsia_debugdata::Publisher>},
.flags{fuchsia_io::wire::Flags::kProtocolService},
.options{},
.object{debugdata_server_end->TakeChannel()},
}});
ASSERT_TRUE(open_result.is_ok()) << open_result.error_value();
// Now drain the messages so the server code runs before the test ends
// and checks the mock's expectations.
zx_status_t status = svc_dir.loop().RunUntilIdle();
EXPECT_EQ(status, ZX_OK) << zx_status_get_string(status);
}
} // namespace