Browse Source

Add a test to verify that just sending random streams to the gearmand server won't do anything.

Brian Aker 12 years ago
parent
commit
72e1ca6637
3 changed files with 95 additions and 9 deletions
  1. 66 6
      libtest/client.cc
  2. 5 3
      libtest/client.hpp
  3. 24 0
      tests/stress_worker.cc

+ 66 - 6
libtest/client.cc

@@ -193,16 +193,13 @@ bool SimpleClient::is_valid()
   return true;
 }
 
-bool SimpleClient::message(const std::string& arg)
+bool SimpleClient::message(const char* ptr, const size_t len)
 {
   if (is_valid())
   {
     if (ready(POLLOUT))
     {
       off_t offset= 0;
-      const char* ptr= arg.c_str();
-      size_t len= arg.size();
-
       do
       {
         ssize_t nw= send(sock_fd, ptr + offset, len - offset, MSG_NOSIGNAL);
@@ -231,9 +228,20 @@ bool SimpleClient::message(const std::string& arg)
 
 bool SimpleClient::send_message(const std::string& arg)
 {
-  if (message(arg) == true)
+  if (message(arg.c_str(), arg.size()) == true)
+  {
+    return message("\r\n", 2);
+  }
+
+  return false;
+}
+
+bool SimpleClient::send_data(const libtest::vchar_t& message_, libtest::vchar_t& response_)
+{
+  requested_message++;
+  if (message(&message_[0], message_.size()))
   {
-    return message("\r\n");
+    return response(response_);
   }
 
   return false;
@@ -250,6 +258,53 @@ bool SimpleClient::send_message(const std::string& message_, std::string& respon
   return false;
 }
 
+bool SimpleClient::response(libtest::vchar_t& response_)
+{
+  response_.clear();
+
+  if (is_valid())
+  {
+    if (ready(POLLIN))
+    {
+      bool more= true;
+      char buffer[2];
+      buffer[1]= 0;
+      do
+      {
+        ssize_t nr= recv(sock_fd, buffer, 1, MSG_NOSIGNAL);
+        if (nr == -1)
+        {
+          if (errno != EINTR)
+          {
+            _error= strerror(errno);
+            return false;
+          }
+        }
+        else if (nr == 0)
+        {
+          close_socket();
+          more= false;
+        }
+        else
+        {
+          response_.reserve(response_.size() + nr +1);
+          fatal_assert(nr == 1);
+          if (buffer[0] == '\n')
+          {
+            more= false;
+          }
+          response_.insert(response_.end(), buffer, buffer +nr);
+        }
+      } while (more);
+
+      return response_.size();
+    }
+  }
+
+  fatal_assert(_error.size());
+  return false;
+}
+
 bool SimpleClient::response(std::string& response_)
 {
   response_.clear();
@@ -272,6 +327,11 @@ bool SimpleClient::response(std::string& response_)
             return false;
           }
         }
+        else if (nr == 0)
+        {
+          close_socket();
+          more= false;
+        }
         else
         {
           fatal_assert(nr == 1);

+ 5 - 3
libtest/client.hpp

@@ -43,9 +43,11 @@ public:
   SimpleClient(const std::string& hostname_, in_port_t port_);
   ~SimpleClient();
 
-  bool send_message(const std::string& arg);
-  bool send_message(const std::string& message_, std::string& response_);
+  bool send_data(const libtest::vchar_t&, libtest::vchar_t&);
+  bool send_message(const std::string&);
+  bool send_message(const std::string&, std::string&);
   bool response(std::string&);
+  bool response(libtest::vchar_t&);
 
   bool is_valid();
 
@@ -63,7 +65,7 @@ private: // Methods
   void close_socket();
   bool instance_connect();
   struct addrinfo* lookup();
-  bool message(const std::string&);
+  bool message(const char* ptr, const size_t len);
   bool ready(int event_);
 
 private:

+ 24 - 0
tests/stress_worker.cc

@@ -197,6 +197,25 @@ static bool join_thread(pthread_t& thread_arg, struct timespec& ts)
   return true;
 }
 
+static test_return_t send_random_port_data_TEST(void* )
+{
+  set_alarm(1200, 0);
+
+  SimpleClient client("localhost", current_server());
+
+  for (size_t x= 0; x < 200; ++x)
+  {
+    libtest::vchar_t message_;
+    libtest::vchar_t response_;
+
+    libtest::vchar::make(message_, size_t(random() % 1024));
+
+    client.send_data(message_, response_);
+  }
+
+  return TEST_SUCCESS;
+}
+
 static test_return_t worker_ramp_exec(const size_t payload_size)
 {
   set_alarm(1200, 0);
@@ -478,6 +497,10 @@ test_st burnin_TESTS[] ={
   {0, 0, 0}
 };
 
+test_st dos_TESTS[] ={
+  {"send random port data", 0, send_random_port_data_TEST },
+  {0, 0, 0}
+};
 
 test_st worker_TESTS[] ={
   {"first pass", 0, worker_ramp_TEST },
@@ -489,6 +512,7 @@ test_st worker_TESTS[] ={
 
 collection_st collection[] ={
   {"burnin", burnin_setup, burnin_cleanup, burnin_TESTS },
+  {"dos", 0, 0, dos_TESTS },
   {"plain", worker_ramp_SETUP, worker_ramp_TEARDOWN, worker_TESTS },
   {"plain against hostile server", hostile_gearmand_SETUP, worker_ramp_TEARDOWN, worker_TESTS },
   {"hostile recv()", recv_SETUP, resv_TEARDOWN, worker_TESTS },