blob: 7340dbf2254bfdbac0a9363f424e10335be640a4 [file] [log] [blame]
// 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 <fuchsia/io/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/default.h>
#include <lib/vfs/cpp/internal/directory_connection.h>
#include <lib/vfs/cpp/internal/file.h>
#include <lib/vfs/cpp/internal/file_connection.h>
#include <lib/vfs/cpp/internal/node.h>
#include <lib/vfs/cpp/internal/node_connection.h>
#include <lib/vfs/cpp/node_kind.h>
#include <lib/vfs/cpp/pseudo_dir.h>
#include <zircon/errors.h>
#include <zircon/types.h>
#include "gtest/gtest.h"
namespace {
class DummyTestFile : public vfs::internal::File {
public:
zx_status_t ReadAt(uint64_t count, uint64_t offset,
std::vector<uint8_t>* out_data) override {
return ZX_OK;
}
zx_status_t WriteAt(std::vector<uint8_t> data, uint64_t offset,
uint64_t* out_actual) override {
return ZX_OK;
}
uint64_t GetLength() override { return 0; }
size_t GetCapacity() override { return 0; }
};
void CallBindTwiceAndTest(vfs::internal::Connection* connection) {
fuchsia::io::NodePtr ptr1;
fuchsia::io::NodePtr ptr2;
ASSERT_EQ(ZX_OK, connection->Bind(ptr1.NewRequest().TakeChannel(),
async_get_default_dispatcher()));
ASSERT_EQ(ZX_ERR_BAD_STATE, connection->Bind(ptr2.NewRequest().TakeChannel(),
async_get_default_dispatcher()));
}
TEST(ConnectionBindCalledTwice, DirectoryConnection) {
vfs::PseudoDir dir;
async::Loop loop(&kAsyncLoopConfigAttachToThread);
vfs::internal::DirectoryConnection connection(0, &dir);
CallBindTwiceAndTest(&connection);
}
TEST(ConnectionBindCalledTwice, FileConnection) {
DummyTestFile file;
async::Loop loop(&kAsyncLoopConfigAttachToThread);
vfs::internal::FileConnection connection(0, &file);
CallBindTwiceAndTest(&connection);
}
TEST(ConnectionBindCalledTwice, NodeConnection) {
vfs::PseudoDir dir;
async::Loop loop(&kAsyncLoopConfigAttachToThread);
vfs::internal::NodeConnection connection(0, &dir);
CallBindTwiceAndTest(&connection);
}
class DummyTestNode : public vfs::internal::Node {
public:
zx_status_t PreClose(vfs::internal::Connection* connection) override {
return ZX_ERR_UNAVAILABLE;
}
void Describe(fuchsia::io::NodeInfo* out_info) override{};
vfs::NodeKind::Type GetKind() const override { return vfs::NodeKind::kFile; }
zx_status_t CreateConnection(
uint32_t flags,
std::unique_ptr<vfs::internal::Connection>* connection) override {
return Node::CreateConnection(flags, connection);
}
};
TEST(ConenctionTest, ConnectionPassedErrorInClose) {
DummyTestNode node;
async::Loop loop(&kAsyncLoopConfigAttachToThread);
loop.StartThread("vfs test thread");
fuchsia::io::NodeSyncPtr ptr;
ASSERT_EQ(ZX_OK,
node.Serve(0, ptr.NewRequest().TakeChannel(), loop.dispatcher()));
zx_status_t status = -1;
ASSERT_EQ(ZX_OK, ptr->Close(&status));
ASSERT_EQ(ZX_ERR_UNAVAILABLE, status);
}
} // namespace