| // Copyright 2019 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 "src/developer/kcounter_inspect/vmo_file_with_update.h" |
| |
| #include <lib/syslog/cpp/macros.h> |
| |
| #include <gtest/gtest.h> |
| |
| #include "fuchsia/kernel/cpp/fidl.h" |
| #include "lib/fidl/cpp/binding_set.h" |
| #include "lib/fidl/cpp/interface_handle.h" |
| #include "lib/gtest/real_loop_fixture.h" |
| #include "lib/sys/cpp/testing/service_directory_provider.h" |
| |
| namespace { |
| |
| // Stub fuchsia.kernel.Counter service that returns canned respo |
| class StubKcounter : public fuchsia::kernel::Counter { |
| public: |
| StubKcounter() { EXPECT_EQ(zx::vmo::create(kSize, 0, &vmo_), ZX_OK); } |
| |
| void GetInspectVmo(GetInspectVmoCallback callback) override { |
| zx::vmo ret; |
| EXPECT_EQ(vmo_.duplicate(ZX_RIGHT_SAME_RIGHTS, &ret), ZX_OK); |
| fuchsia::mem::Buffer buffer{.vmo = std::move(ret), .size = kSize}; |
| callback(ZX_OK, std::move(buffer)); |
| } |
| |
| void UpdateInspectVmo(UpdateInspectVmoCallback callback) override { |
| ++update_count_; |
| callback(ZX_OK); |
| } |
| |
| fidl::InterfaceRequestHandler<fuchsia::kernel::Counter> GetHandler() { |
| return bindings_.GetHandler(this); |
| } |
| |
| int update_count() const { return update_count_; } |
| |
| private: |
| static constexpr size_t kSize = 4096; |
| |
| fidl::BindingSet<fuchsia::kernel::Counter> bindings_; |
| zx::vmo vmo_; |
| int update_count_ = 0; |
| }; |
| |
| class VmoFileWithUpdateTest : public gtest::RealLoopFixture { |
| public: |
| void SetUp() override { |
| EXPECT_EQ(loop_.StartThread(), ZX_OK); |
| service_directory_provider_.reset( |
| new ::sys::testing::ServiceDirectoryProvider(loop_.dispatcher())); |
| stub_kcounter_.reset(new StubKcounter); |
| FX_CHECK(service_directory_provider_->AddService(stub_kcounter_->GetHandler()) == ZX_OK); |
| } |
| |
| void TearDown() override { |
| loop_.Quit(); |
| loop_.JoinThreads(); |
| } |
| |
| async::Loop loop_{&kAsyncLoopConfigNoAttachToCurrentThread}; |
| std::unique_ptr<::sys::testing::ServiceDirectoryProvider> service_directory_provider_; |
| std::unique_ptr<StubKcounter> stub_kcounter_; |
| thrd_t thread_; |
| }; |
| |
| TEST_F(VmoFileWithUpdateTest, DoNothing) { VmoFileWithUpdate noop(zx::vmo(), 0, 0, nullptr); } |
| |
| TEST_F(VmoFileWithUpdateTest, EnsureUpdateCalled) { |
| fuchsia::kernel::CounterSyncPtr kcounter; |
| ASSERT_EQ(service_directory_provider_->service_directory()->Connect<fuchsia::kernel::Counter>( |
| kcounter.NewRequest()), |
| ZX_OK); |
| |
| zx_status_t status; |
| fuchsia::mem::Buffer buffer; |
| EXPECT_EQ(kcounter->GetInspectVmo(&status, &buffer), ZX_OK); |
| |
| auto vmo_file = |
| std::make_unique<VmoFileWithUpdate>(std::move(buffer.vmo), 0, buffer.size, &kcounter); |
| EXPECT_EQ(stub_kcounter_->update_count(), 0); |
| |
| std::vector<uint8_t> data; |
| EXPECT_EQ(vmo_file->ReadAt(128 /*any amount, doesn't really matter*/, 0, &data), ZX_OK); |
| EXPECT_EQ(stub_kcounter_->update_count(), 1); |
| |
| fuchsia::io::NodeInfo node_info; |
| vmo_file->Describe(&node_info); |
| EXPECT_EQ(stub_kcounter_->update_count(), 2); |
| } |
| |
| } // namespace |