#include "msg/Messenger.h"
#include "mon/MonClient.h"
#include "osdc/ObjectCacher.h"
-
+#include "client/MetaRequest.h"
#include "client/Client.h"
+#include "messages/MClientReclaim.h"
+#include "messages/MClientSession.h"
+#include "common/async/blocked_completion.h"
+
+#define dout_subsys ceph_subsys_client
+
+namespace bs = boost::system;
+namespace ca = ceph::async;
+
+class ClientScaffold : public Client {
+public:
+ ClientScaffold(Messenger *m, MonClient *mc, Objecter *objecter_) : Client(m, mc, objecter_) {}
+ virtual ~ClientScaffold()
+ { }
+ int check_dummy_op(const UserPerm& perms){
+ RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
+ if (!mref_reader.is_state_satisfied()) {
+ return -CEPHFS_ENOTCONN;
+ }
+ std::scoped_lock l(client_lock);
+ MetaRequest *req = new MetaRequest(CEPH_MDS_OP_DUMMY);
+ int res = make_request(req, perms);
+ ldout(cct, 10) << __func__ << " result=" << res << dendl;
+ return res;
+ }
+ int send_unknown_session_op(int op) {
+ RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
+ if (!mref_reader.is_state_satisfied()) {
+ return -CEPHFS_ENOTCONN;
+ }
+ std::scoped_lock l(client_lock);
+ auto session = _get_or_open_mds_session(0);
+ auto msg = make_message<MClientSession>(op, session->seq);
+ int res = session->con->send_message2(std::move(msg));
+ ldout(cct, 10) << __func__ << " result=" << res << dendl;
+ return res;
+ }
+ bool check_client_blocklisted() {
+ RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
+ if (!mref_reader.is_state_satisfied()) {
+ return -CEPHFS_ENOTCONN;
+ }
+ std::scoped_lock l(client_lock);
+ bs::error_code ec;
+ ldout(cct, 20) << __func__ << ": waiting for latest osdmap" << dendl;
+ objecter->wait_for_latest_osdmap(ca::use_blocked[ec]);
+ ldout(cct, 20) << __func__ << ": got latest osdmap: " << ec << dendl;
+ const auto myaddrs = messenger->get_myaddrs();
+ return objecter->with_osdmap([&](const OSDMap& o) {return o.is_blocklisted(myaddrs);});
+ }
+ bool check_unknown_reclaim_flag(uint32_t flag) {
+ RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
+ if (!mref_reader.is_state_satisfied()) {
+ return -CEPHFS_ENOTCONN;
+ }
+ std::scoped_lock l(client_lock);
+ char uuid[256];
+ sprintf(uuid, "unknownreclaimflag:%x", getpid());
+ auto session = _get_or_open_mds_session(0);
+ auto m = make_message<MClientReclaim>(uuid, flag);
+ ceph_assert(session->con->send_message2(std::move(m)) == 0);
+ wait_on_list(waiting_for_reclaim);
+ return session->reclaim_state == MetaSession::RECLAIM_FAIL ? true : false;
+ }
+};
class TestClient : public ::testing::Test {
public:
messenger->add_dispatcher_tail(objecter);
objecter->start();
- client = new Client(messenger, mc, objecter);
+ client = new ClientScaffold(messenger, mc, objecter);
client->init();
client->mount("/", myperm, true);
}
MonClient* mc = nullptr;
Messenger* messenger = nullptr;
Objecter* objecter = nullptr;
- Client* client = nullptr;
+ ClientScaffold* client = nullptr;
};
--- /dev/null
+// -*- 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) 2022 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 <iostream>
+#include <errno.h>
+#include "TestClient.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "gtest/gtest-spi.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock-more-matchers.h"
+
+TEST_F(TestClient, CheckDummyOP) {
+ ASSERT_EQ(client->check_dummy_op(myperm), -EOPNOTSUPP);
+}
+
+TEST_F(TestClient, CheckUnknownSessionOp) {
+ ASSERT_EQ(client->send_unknown_session_op(-1), 0);
+ sleep(5);
+ ASSERT_EQ(client->check_client_blocklisted(), true);
+}
+
+TEST_F(TestClient, CheckZeroReclaimFlag) {
+ ASSERT_EQ(client->check_unknown_reclaim_flag(0), true);
+}
+TEST_F(TestClient, CheckUnknownReclaimFlag) {
+ ASSERT_EQ(client->check_unknown_reclaim_flag(-1 & ~MClientReclaim::FLAG_FINISH), true);
+}