From 8d1193b9d30d4123ad2710878f494537a5befbf8 Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Wed, 20 Jul 2011 15:33:23 -0700 Subject: [PATCH] test/admin_socket: test message 0 Signed-off-by: Colin McCabe --- src/common/admin_socket_client.cc | 127 ++++++++++++++++++++---------- src/common/admin_socket_client.h | 5 +- src/test/admin_socket.cc | 11 ++- 3 files changed, 98 insertions(+), 45 deletions(-) diff --git a/src/common/admin_socket_client.cc b/src/common/admin_socket_client.cc index bef873ab32f53..513b79f494fd1 100644 --- a/src/common/admin_socket_client.cc +++ b/src/common/admin_socket_client.cc @@ -38,31 +38,8 @@ using std::ostringstream; -/* Helper class used to time out the client after a certain amount of time - * passes. - */ -class Alarm +static std::string asok_connect(const std::string &path, int *fd) { -public: - Alarm(int s) { - alarm(s); - } - ~Alarm() { - alarm(0); - } -}; - -AdminSocketClient:: -AdminSocketClient(const std::string &path) - : m_path(path) -{ -} - -std::string AdminSocketClient:: -get_message(std::string *message) -{ - Alarm my_alarm(300); - int socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); if(socket_fd < 0) { int err = errno; @@ -74,9 +51,9 @@ get_message(std::string *message) struct sockaddr_un address; memset(&address, 0, sizeof(struct sockaddr_un)); address.sun_family = AF_UNIX; - snprintf(address.sun_path, sizeof(address.sun_path), "%s", m_path.c_str()); + snprintf(address.sun_path, sizeof(address.sun_path), "%s", path.c_str()); - if (connect(socket_fd, (struct sockaddr *) &address, + if (::connect(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) { int err = errno; ostringstream oss; @@ -85,43 +62,107 @@ get_message(std::string *message) return oss.str(); } - std::vector vec(65536, 0); - uint8_t *buffer = &vec[0]; + struct timeval timer; + timer.tv_sec = 5; + timer.tv_usec = 0; + if (::setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &timer, sizeof(timer))) { + int err = errno; + ostringstream oss; + oss << "setsockopt(" << socket_fd << ", SO_RCVTIMEO) failed: " + << cpp_strerror(err); + close(socket_fd); + return oss.str(); + } + timer.tv_sec = 5; + timer.tv_usec = 0; + if (::setsockopt(socket_fd, SOL_SOCKET, SO_SNDTIMEO, &timer, sizeof(timer))) { + int err = errno; + ostringstream oss; + oss << "setsockopt(" << socket_fd << ", SO_SNDTIMEO) failed: " + << cpp_strerror(err); + close(socket_fd); + return oss.str(); + } + + *fd = socket_fd; + return ""; +} - uint32_t request = htonl(0x1); - ssize_t res = safe_write(socket_fd, &request, sizeof(request)); +static std::string asok_request(int socket_fd, uint32_t request_id) +{ + uint32_t request_id_raw = htonl(0x1); + ssize_t res = safe_write(socket_fd, &request_id_raw, sizeof(request_id_raw)); if (res < 0) { int err = res; ostringstream oss; oss << "safe_write(" << socket_fd << ") failed to write request code: " << cpp_strerror(err); - close(socket_fd); return oss.str(); } + return ""; +} + +AdminSocketClient:: +AdminSocketClient(const std::string &path) + : m_path(path) +{ +} + +std::string AdminSocketClient:: +send_noop() +{ + int socket_fd; + std::string err = asok_connect(m_path, &socket_fd); + if (!err.empty()) { + goto done; + } + err = asok_request(socket_fd, 0x0); + if (!err.empty()) { + goto done; + } +done: + close(socket_fd); + return err; +} + +std::string AdminSocketClient:: +get_message(std::string *message) +{ + int socket_fd, res; + std::vector vec(65536, 0); + uint8_t *buffer = &vec[0]; + uint32_t message_size_raw, message_size; - uint32_t message_size_raw; + std::string err = asok_connect(m_path, &socket_fd); + if (!err.empty()) { + goto done; + } + err = asok_request(socket_fd, 0x1); + if (!err.empty()) { + goto done; + } res = safe_read_exact(socket_fd, &message_size_raw, sizeof(message_size_raw)); if (res < 0) { - int err = res; + int e = res; ostringstream oss; oss << "safe_read(" << socket_fd << ") failed to read message size: " - << cpp_strerror(err); - close(socket_fd); - return oss.str(); + << cpp_strerror(e); + err = oss.str(); + goto done; } - uint32_t message_size = ntohl(message_size_raw); + message_size = ntohl(message_size_raw); res = safe_read_exact(socket_fd, buffer, message_size); if (res < 0) { - int err = res; + int e = res; ostringstream oss; - oss << "safe_read(" << socket_fd << ") failed: " << cpp_strerror(err); - close(socket_fd); - return oss.str(); + oss << "safe_read(" << socket_fd << ") failed: " << cpp_strerror(e); + err = oss.str(); + goto done; } - //printf("MESSAGE FROM SERVER: %s\n", buffer); message->assign((const char*)buffer); +done: close(socket_fd); - return ""; + return err; } diff --git a/src/common/admin_socket_client.h b/src/common/admin_socket_client.h index 6e636d1a4d5ca..a40682f262b60 100644 --- a/src/common/admin_socket_client.h +++ b/src/common/admin_socket_client.h @@ -17,11 +17,14 @@ #include -// TODO: restructure in terms of open/send +/* This is a simple client that talks to an AdminSocket using blocking I/O. + * We put a 5-second timeout on send and recv operations. + */ class AdminSocketClient { public: AdminSocketClient(const std::string &path); + std::string send_noop(); std::string get_message(std::string *message); private: std::string m_path; diff --git a/src/test/admin_socket.cc b/src/test/admin_socket.cc index 9ab136049ee59..8acf5941788aa 100644 --- a/src/test/admin_socket.cc +++ b/src/test/admin_socket.cc @@ -76,4 +76,13 @@ TEST(AdminSocket, TeardownSetup) { ASSERT_EQ(true, asoct.shutdown()); } -// TODO: test sending message 0 +TEST(AdminSocket, SendNoOp) { + std::auto_ptr + asokc(new AdminSocketConfigObs(g_ceph_context)); + AdminSocketTest asoct(asokc.get()); + ASSERT_EQ(true, asoct.shutdown()); + ASSERT_EQ(true, asoct.init(get_socket_path())); + AdminSocketClient client(get_socket_path()); + ASSERT_EQ("", client.send_noop()); + ASSERT_EQ(true, asoct.shutdown()); +} -- 2.39.5