From f77e6aa5c81f3b37af411ce9d30f23eadac7d351 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Mon, 11 Jan 2021 13:39:42 -0800 Subject: [PATCH] test: add client tests For alternate_name, so far. Signed-off-by: Patrick Donnelly --- src/test/CMakeLists.txt | 1 + src/test/client/CMakeLists.txt | 16 +++ src/test/client/TestClient.h | 85 +++++++++++++ src/test/client/alternate_name.cc | 197 ++++++++++++++++++++++++++++++ src/test/client/main.cc | 29 +++++ 5 files changed, 328 insertions(+) create mode 100644 src/test/client/CMakeLists.txt create mode 100644 src/test/client/TestClient.h create mode 100644 src/test/client/alternate_name.cc create mode 100644 src/test/client/main.cc diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index dd2011066f73e..708e13ceae593 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -61,6 +61,7 @@ if(NOT WIN32) add_subdirectory(filestore) add_subdirectory(fs) add_subdirectory(libcephfs) + add_subdirectory(client) add_subdirectory(mon) add_subdirectory(mgr) add_subdirectory(msgr) diff --git a/src/test/client/CMakeLists.txt b/src/test/client/CMakeLists.txt new file mode 100644 index 0000000000000..66d403c7e9e53 --- /dev/null +++ b/src/test/client/CMakeLists.txt @@ -0,0 +1,16 @@ +if(${WITH_CEPHFS}) + add_executable(ceph_test_client + main.cc + alternate_name.cc + ) + target_link_libraries(ceph_test_client + client + global + ceph-common + ${UNITTEST_LIBS} + ${EXTRALIBS} + ${CMAKE_DL_LIBS} + ) + install(TARGETS ceph_test_client + DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif(${WITH_CEPHFS}) diff --git a/src/test/client/TestClient.h b/src/test/client/TestClient.h new file mode 100644 index 0000000000000..e1c0199b3105b --- /dev/null +++ b/src/test/client/TestClient.h @@ -0,0 +1,85 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2021 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "gtest/gtest.h" + +#include "common/async/context_pool.h" +#include "global/global_context.h" + +#include "msg/Messenger.h" +#include "mon/MonClient.h" +#include "osdc/ObjectCacher.h" + +#include "client/Client.h" + +class TestClient : public ::testing::Test { +public: + static void SetUpTestSuite() { + icp.start(g_ceph_context->_conf.get_val("client_asio_thread_count")); + } + static void TearDownTestSuite() { + icp.stop(); + } + void SetUp() override { + messenger = Messenger::create_client_messenger(g_ceph_context, "client"); + if (messenger->start() != 0) { + throw std::runtime_error("failed to start messenger"); + } + + mc = new MonClient(g_ceph_context, icp); + if (mc->build_initial_monmap() < 0) { + throw std::runtime_error("build monmap"); + } + mc->set_messenger(messenger); + mc->set_want_keys(CEPH_ENTITY_TYPE_MDS | CEPH_ENTITY_TYPE_OSD); + if (mc->init() < 0) { + throw std::runtime_error("init monclient"); + } + + objecter = new Objecter(g_ceph_context, messenger, mc, icp); + objecter->set_client_incarnation(0); + objecter->init(); + messenger->add_dispatcher_tail(objecter); + objecter->start(); + + client = new Client(messenger, mc, objecter); + client->init(); + client->mount("/", myperm, true); + } + void TearDown() override { + if (client->is_mounted()) + client->unmount(); + client->shutdown(); + objecter->shutdown(); + mc->shutdown(); + messenger->shutdown(); + messenger->wait(); + + delete client; + client = nullptr; + delete objecter; + objecter = nullptr; + delete mc; + mc = nullptr; + delete messenger; + messenger = nullptr; + } +protected: + static inline ceph::async::io_context_pool icp; + static inline UserPerm myperm{0,0}; + MonClient* mc = nullptr; + Messenger* messenger = nullptr; + Objecter* objecter = nullptr; + Client* client = nullptr; +}; diff --git a/src/test/client/alternate_name.cc b/src/test/client/alternate_name.cc new file mode 100644 index 0000000000000..7671eff9aecd0 --- /dev/null +++ b/src/test/client/alternate_name.cc @@ -0,0 +1,197 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2021 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include + +#include +#include + +#include + +#include "test/client/TestClient.h" + +TEST_F(TestClient, AlternateNameRemount) { + auto altname = std::string("foo"); + auto dir = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid()); + ASSERT_EQ(0, client->mkdir(dir.c_str(), 0777, myperm, altname)); + + client->unmount(); + TearDown(); + SetUp(); + client->mount("/", myperm, true); + + { + Client::walk_dentry_result wdr; + ASSERT_EQ(0, client->walk(dir.c_str(), &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, altname); + } + + ASSERT_EQ(0, client->rmdir(dir.c_str(), myperm)); +} + + +TEST_F(TestClient, AlternateNameMkdir) { + auto dir = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid()); + ASSERT_EQ(0, client->mkdir(dir.c_str(), 0777, myperm, "foo")); + + { + Client::walk_dentry_result wdr; + ASSERT_EQ(0, client->walk(dir.c_str(), &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, "foo"s); + } + + ASSERT_EQ(0, client->rmdir(dir.c_str(), myperm)); +} + +TEST_F(TestClient, AlternateNameLong) { + auto altname = std::string(4096+1024, '-'); + auto dir = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid()); + ASSERT_EQ(0, client->mkdir(dir.c_str(), 0777, myperm, altname)); + + { + Client::walk_dentry_result wdr; + ASSERT_EQ(0, client->walk(dir.c_str(), &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, altname); + } + + ASSERT_EQ(0, client->rmdir(dir.c_str(), myperm)); +} + +TEST_F(TestClient, AlternateNameCreat) { + auto altname = std::string("foo"); + auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid()); + int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname); + ASSERT_LE(0, fd); + ASSERT_EQ(3, client->write(fd, "baz", 3, 0)); + ASSERT_EQ(0, client->close(fd)); + + { + Client::walk_dentry_result wdr; + ASSERT_EQ(0, client->walk(file, &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, altname); + } +} + +TEST_F(TestClient, AlternateNameSymlink) { + auto altname = std::string("foo"); + auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid()); + int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname); + ASSERT_LE(0, fd); + ASSERT_EQ(3, client->write(fd, "baz", 3, 0)); + ASSERT_EQ(0, client->close(fd)); + + auto file2 = file+"2"; + auto altname2 = altname+"2"; + ASSERT_EQ(0, client->symlink(file.c_str(), file2.c_str(), myperm, altname2)); + + { + Client::walk_dentry_result wdr; + ASSERT_EQ(0, client->walk(file2, &wdr, myperm, false)); + ASSERT_EQ(wdr.alternate_name, altname2); + ASSERT_EQ(0, client->walk(file, &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, altname); + } +} + +TEST_F(TestClient, AlternateNameRename) { + auto altname = std::string("foo"); + auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid()); + int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname); + ASSERT_LE(0, fd); + ASSERT_EQ(3, client->write(fd, "baz", 3, 0)); + ASSERT_EQ(0, client->close(fd)); + + auto file2 = file+"2"; + auto altname2 = altname+"2"; + + ASSERT_EQ(0, client->rename(file.c_str(), file2.c_str(), myperm, altname2)); + + { + Client::walk_dentry_result wdr; + ASSERT_EQ(0, client->walk(file2, &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, altname2); + } +} + +TEST_F(TestClient, AlternateNameRenameExistMatch) { + auto altname = std::string("foo"); + auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid()); + int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname); + ASSERT_LE(0, fd); + ASSERT_EQ(3, client->write(fd, "baz", 3, 0)); + ASSERT_EQ(0, client->close(fd)); + + auto file2 = file+"2"; + auto altname2 = altname+"2"; + + fd = client->open(file2.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname2); + ASSERT_LE(0, fd); + ASSERT_EQ(3, client->write(fd, "baz", 3, 0)); + ASSERT_EQ(0, client->close(fd)); + + ASSERT_EQ(0, client->rename(file.c_str(), file2.c_str(), myperm, altname2)); + + { + Client::walk_dentry_result wdr; + ASSERT_EQ(0, client->walk(file2, &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, altname2); + } +} + +TEST_F(TestClient, AlternateNameRenameExistMisMatch) { + auto altname = std::string("foo"); + auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid()); + int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname); + ASSERT_LE(0, fd); + ASSERT_EQ(3, client->write(fd, "baz", 3, 0)); + ASSERT_EQ(0, client->close(fd)); + + auto file2 = file+"2"; + auto altname2 = altname+"2"; + + fd = client->open(file2.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname+"mismatch"); + ASSERT_LE(0, fd); + ASSERT_EQ(3, client->write(fd, "baz", 3, 0)); + ASSERT_EQ(0, client->close(fd)); + + ASSERT_EQ(-EINVAL, client->rename(file.c_str(), file2.c_str(), myperm, altname2)); + + { + Client::walk_dentry_result wdr; + ASSERT_EQ(0, client->walk(file2, &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, altname+"mismatch"); + } +} + +TEST_F(TestClient, AlternateNameLink) { + auto altname = std::string("foo"); + auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid()); + int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname); + ASSERT_LE(0, fd); + ASSERT_EQ(3, client->write(fd, "baz", 3, 0)); + ASSERT_EQ(0, client->close(fd)); + + auto file2 = file+"2"; + auto altname2 = altname+"2"; + + ASSERT_EQ(0, client->link(file.c_str(), file2.c_str(), myperm, altname2)); + + { + Client::walk_dentry_result wdr; + ASSERT_EQ(0, client->walk(file2, &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, altname2); + ASSERT_EQ(0, client->walk(file, &wdr, myperm)); + ASSERT_EQ(wdr.alternate_name, altname); + } +} diff --git a/src/test/client/main.cc b/src/test/client/main.cc new file mode 100644 index 0000000000000..437ff722d5dee --- /dev/null +++ b/src/test/client/main.cc @@ -0,0 +1,29 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * Copyright (C) 2016 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "gtest/gtest.h" + +#include "common/ceph_argparse.h" +#include "global/global_init.h" +#include "global/global_context.h" + +int main(int argc, char **argv) +{ + vector args; + argv_to_vec(argc, (const char **)argv, args); + [[maybe_unused]] auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} -- 2.39.5