| // 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 "src/storage/fshost/fshost_integration_test.h" |
| |
| #include <sys/statfs.h> |
| |
| namespace devmgr { |
| |
| void FshostIntegrationTest::SetUp() { |
| std::string service_name = std::string("/svc/") + fuchsia::sys2::Realm::Name_; |
| auto status = zx::make_status( |
| fdio_service_connect(service_name.c_str(), realm_.NewRequest().TakeChannel().get())); |
| ASSERT_TRUE(status.is_ok()); |
| |
| fuchsia::sys2::Realm_CreateChild_Result create_result; |
| fuchsia::sys2::ChildDecl child_decl; |
| child_decl.set_name("test-fshost") |
| .set_url("fuchsia-pkg://fuchsia.com/fshost-tests#meta/test-fshost.cm") |
| .set_startup(fuchsia::sys2::StartupMode::LAZY); |
| status = |
| zx::make_status(realm_->CreateChild(fuchsia::sys2::CollectionRef{.name = "fshost-collection"}, |
| std::move(child_decl), &create_result)); |
| ASSERT_TRUE(status.is_ok() && !create_result.is_err()); |
| |
| fuchsia::sys2::Realm_BindChild_Result bind_result; |
| status = zx::make_status(realm_->BindChild( |
| fuchsia::sys2::ChildRef{.name = "test-fshost", .collection = "fshost-collection"}, |
| exposed_dir_.NewRequest(), &bind_result)); |
| ASSERT_TRUE(status.is_ok() && !bind_result.is_err()); |
| |
| // Describe so that we discover errors early. |
| fuchsia::io::NodeInfo info; |
| ASSERT_EQ(exposed_dir_->Describe(&info), ZX_OK); |
| |
| zx::channel request; |
| status = zx::make_status(zx::channel::create(0, &watcher_channel_, &request)); |
| ASSERT_EQ(status.status_value(), ZX_OK); |
| status = zx::make_status( |
| exposed_dir_->Open(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE, 0, |
| llcpp::fuchsia::fshost::BlockWatcher::Name, |
| fidl::InterfaceRequest<fuchsia::io::Node>(std::move(request)))); |
| ASSERT_EQ(status.status_value(), ZX_OK); |
| } |
| |
| void FshostIntegrationTest::TearDown() { |
| fuchsia::sys2::Realm_DestroyChild_Result destroy_result; |
| auto status = zx::make_status(realm_->DestroyChild( |
| fuchsia::sys2::ChildRef{.name = "test-fshost", .collection = "fshost-collection"}, |
| &destroy_result)); |
| ASSERT_TRUE(status.is_ok() && !destroy_result.is_err()); |
| } |
| |
| void FshostIntegrationTest::PauseWatcher() const { |
| auto result = llcpp::fuchsia::fshost::BlockWatcher::Call::Pause(watcher_channel_.borrow()); |
| ASSERT_EQ(result.status(), ZX_OK); |
| ASSERT_EQ(result->status, ZX_OK); |
| } |
| |
| void FshostIntegrationTest::ResumeWatcher() const { |
| auto result = llcpp::fuchsia::fshost::BlockWatcher::Call::Resume(watcher_channel_.borrow()); |
| ASSERT_EQ(result.status(), ZX_OK); |
| ASSERT_EQ(result->status, ZX_OK); |
| } |
| |
| fbl::unique_fd FshostIntegrationTest::WaitForMount(const std::string& name, |
| uint64_t expected_fs_type) { |
| // The mount point will always exist so we expect open() to work regardless of whether the device |
| // is actually mounted. We retry until the mount point has the expected filesystem type. Retry 10 |
| // times and then give up. |
| for (int i = 0; i < 10; i++) { |
| fidl::SynchronousInterfacePtr<fuchsia::io::Node> root; |
| zx_status_t status = |
| exposed_dir()->Open(fuchsia::io::OPEN_RIGHT_READABLE, 0, name, root.NewRequest()); |
| EXPECT_EQ(ZX_OK, status); |
| if (status != ZX_OK) |
| return fbl::unique_fd(); |
| |
| fbl::unique_fd fd; |
| status = fdio_fd_create(root.Unbind().TakeChannel().release(), fd.reset_and_get_address()); |
| EXPECT_EQ(ZX_OK, status); |
| if (status != ZX_OK) |
| return fbl::unique_fd(); |
| |
| struct statfs buf; |
| EXPECT_EQ(fstatfs(fd.get(), &buf), 0); |
| if (buf.f_type == expected_fs_type) |
| return fd; |
| |
| sleep(1); |
| } |
| |
| return fbl::unique_fd(); |
| } |
| |
| } // namespace devmgr |