Updated pandora-build files to version 0.171
[awesomized/libmemcached] / clients / memcapable.c
index 2527861739c00c3e7f618558944968c99433aa1f..a5a8185a2eeeb3ad33f05f28d6044468d7d637dd 100644 (file)
@@ -303,6 +303,7 @@ static enum test_return retry_read(void *buf, size_t len)
     ssize_t nr= timeout_io_op(sock, POLLIN, ((char*) buf) + offset, len - offset);
     switch (nr) {
     case -1 :
+       fprintf(stderr, "Errno: %d %s\n", get_socket_errno(), strerror(errno));
       verify(get_socket_errno() == EINTR || get_socket_errno() == EAGAIN);
       break;
     case 0:
@@ -321,7 +322,7 @@ static enum test_return retry_read(void *buf, size_t len)
  */
 static enum test_return recv_packet(response *rsp)
 {
-  execute(retry_read(rsp, sizeof (protocol_binary_response_no_extras)));
+  execute(retry_read(rsp, sizeof(protocol_binary_response_no_extras)));
 
   /* Fix the byte order in the packet header */
   rsp->plain.message.header.response.keylen=
@@ -693,10 +694,12 @@ static enum test_return test_binary_set_impl(const char* key, uint8_t cc)
   cmd.plain.message.header.request.cas=
           htonll(rsp.plain.message.header.response.cas - 1);
   execute(resend_packet(&cmd));
+  execute(send_binary_noop());
   execute(recv_packet(&rsp));
   verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS));
+  execute(receive_binary_noop());
 
-  return test_binary_noop();
+  return TEST_PASS;
 }
 
 static enum test_return test_binary_set(void)
@@ -733,7 +736,9 @@ static enum test_return test_binary_add_impl(const char* key, uint8_t cc)
       else
         expected_result= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
 
+      execute(send_binary_noop());
       execute(recv_packet(&rsp));
+      execute(receive_binary_noop());
       verify(validate_response_header(&rsp, cc, expected_result));
     }
     else
@@ -790,7 +795,9 @@ static enum test_return test_binary_replace_impl(const char* key, uint8_t cc)
       else
         expected_result=PROTOCOL_BINARY_RESPONSE_SUCCESS;
 
+      execute(send_binary_noop());
       execute(recv_packet(&rsp));
+      execute(receive_binary_noop());
       verify(validate_response_header(&rsp, cc, expected_result));
 
       if (ii == 0)
@@ -817,7 +824,9 @@ static enum test_return test_binary_replace_impl(const char* key, uint8_t cc)
   cmd.plain.message.header.request.cas=
           htonll(rsp.plain.message.header.response.cas - 1);
   execute(resend_packet(&cmd));
+  execute(send_binary_noop());
   execute(recv_packet(&rsp));
+  execute(receive_binary_noop());
   verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS));
 
   return TEST_PASS;
@@ -841,8 +850,10 @@ static enum test_return test_binary_delete_impl(const char *key, uint8_t cc)
 
   /* The delete shouldn't work the first time, because the item isn't there */
   execute(send_packet(&cmd));
+  execute(send_binary_noop());
   execute(recv_packet(&rsp));
   verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT));
+  execute(receive_binary_noop());
   execute(binary_set_item(key, key));
 
   /* The item should be present now, resend*/
@@ -1305,6 +1316,41 @@ static enum test_return test_ascii_add_noreply(void)
   return test_ascii_add_impl("test_ascii_add_noreply", true);
 }
 
+static enum test_return ascii_get_unknown_value(char **key, char **value, ssize_t *ndata)
+{
+  char buffer[1024];
+
+  execute(receive_line(buffer, sizeof(buffer)));
+  verify(strncmp(buffer, "VALUE ", 6) == 0);
+  char *end= strchr(buffer + 6, ' ');
+  verify(end != NULL);
+  *end= '\0';
+  *key= strdup(buffer + 6);
+  verify(*key != NULL);
+  char *ptr= end + 1;
+
+  unsigned long val= strtoul(ptr, &end, 10); /* flags */
+  verify(ptr != end);
+  verify(val == 0);
+  verify(end != NULL);
+  *ndata = (ssize_t)strtoul(end, &end, 10); /* size */
+  verify(ptr != end);
+  verify(end != NULL);
+  while (*end != '\n' && isspace(*end))
+    ++end;
+  verify(*end == '\n');
+
+  *value= malloc((size_t)*ndata);
+  verify(*value != NULL);
+
+  execute(retry_read(*value, (size_t)*ndata));
+
+  execute(retry_read(buffer, 2));
+  verify(memcmp(buffer, "\r\n", 2) == 0);
+
+  return TEST_PASS;
+}
+
 static enum test_return ascii_get_value(const char *key, const char *value)
 {
 
@@ -1573,25 +1619,59 @@ static enum test_return test_ascii_gets(void)
 
 static enum test_return test_ascii_mget(void)
 {
-  execute(ascii_set_item("test_ascii_mget1", "value"));
-  execute(ascii_set_item("test_ascii_mget2", "value"));
-  execute(ascii_set_item("test_ascii_mget3", "value"));
-  execute(ascii_set_item("test_ascii_mget4", "value"));
-  execute(ascii_set_item("test_ascii_mget5", "value"));
+  const uint32_t nkeys= 5;
+  const char * const keys[]= {
+    "test_ascii_mget1",
+    "test_ascii_mget2",
+    /* test_ascii_mget_3 does not exist :) */
+    "test_ascii_mget4",
+    "test_ascii_mget5",
+    "test_ascii_mget6"
+  };
+
+  for (uint32_t x= 0; x < nkeys; ++x)
+    execute(ascii_set_item(keys[x], "value"));
 
+  /* Ask for a key that doesn't exist as well */
   execute(send_string("get test_ascii_mget1 test_ascii_mget2 test_ascii_mget3 "
                       "test_ascii_mget4 test_ascii_mget5 "
                       "test_ascii_mget6\r\n"));
-  execute(ascii_get_value("test_ascii_mget1", "value"));
-  execute(ascii_get_value("test_ascii_mget2", "value"));
-  execute(ascii_get_value("test_ascii_mget3", "value"));
-  execute(ascii_get_value("test_ascii_mget4", "value"));
-  execute(ascii_get_value("test_ascii_mget5", "value"));
+
+  char *returned[nkeys];
+
+  for (uint32_t x= 0; x < nkeys; ++x)
+  {
+    ssize_t nbytes = 0;
+    char *v= NULL;
+    execute(ascii_get_unknown_value(&returned[x], &v, &nbytes));
+    verify(nbytes == 5);
+    verify(memcmp(v, "value", 5) == 0);
+    free(v);
+  }
 
   char buffer[5];
   execute(retry_read(buffer, 5));
   verify(memcmp(buffer, "END\r\n", 5) == 0);
- return TEST_PASS;
+
+  /* verify that we got all the keys we expected */
+  for (uint32_t x= 0; x < nkeys; ++x)
+  {
+    bool found= false;
+    for (uint32_t y= 0; y < nkeys; ++y)
+    {
+      if (strcmp(keys[x], returned[y]) == 0)
+      {
+        found = true;
+        break;
+      }
+    }
+    verify(found);
+  }
+
+  for (uint32_t x= 0; x < nkeys; ++x)
+    free(returned[x]);
+
+  return TEST_PASS;
 }
 
 static enum test_return test_ascii_incr_impl(const char* key, bool noreply)
@@ -1869,8 +1949,10 @@ int main(int argc, char **argv)
   const char *hostname= "localhost";
   const char *port= "11211";
   int cmd;
+  bool prompt= false;
+  const char *testname= NULL;
 
-  while ((cmd= getopt(argc, argv, "t:vch:p:?")) != EOF)
+  while ((cmd= getopt(argc, argv, "t:vch:p:PT:?")) != EOF)
   {
     switch (cmd) {
     case 't':
@@ -1889,11 +1971,21 @@ int main(int argc, char **argv)
       break;
     case 'p': port= optarg;
       break;
+    case 'P': prompt= true;
+      break;
+    case 'T': testname= optarg;
+       break;
     default:
-      fprintf(stderr, "Usage: %s [-h hostname] [-p port] [-c] [-v] [-t n]\n"
+      fprintf(stderr, "Usage: %s [-h hostname] [-p port] [-c] [-v] [-t n]"
+              " [-P] [-T testname]'\n"
               "\t-c\tGenerate coredump if a test fails\n"
               "\t-v\tVerbose test output (print out the assertion)\n"
-              "\t-t n\tSet the timeout for io-operations to n seconds\n",
+              "\t-t n\tSet the timeout for io-operations to n seconds\n"
+              "\t-P\tPrompt the user before starting a test.\n"
+              "\t\t\t\"skip\" will skip the test\n"
+              "\t\t\t\"quit\" will terminate memcapable\n"
+              "\t\t\tEverything else will start the test\n"
+              "\t-T n\tJust run the test named n\n",
               argv[0]);
       return 1;
     }
@@ -1910,10 +2002,33 @@ int main(int argc, char **argv)
 
   for (int ii= 0; testcases[ii].description != NULL; ++ii)
   {
+    if (testname != NULL && strcmp(testcases[ii].description, testname) != 0)
+       continue;
+
     ++total;
     fprintf(stdout, "%-40s", testcases[ii].description);
     fflush(stdout);
 
+    if (prompt)
+    {
+      fprintf(stdout, "\nPress <return> when you are ready? ");
+      char buffer[80] = {0};
+      if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
+        if (strncmp(buffer, "skip", 4) == 0)
+        {
+          fprintf(stdout, "%-40s%s\n", testcases[ii].description,
+                  status_msg[TEST_SKIP]);
+          fflush(stdout);
+          continue;
+        }
+        if (strncmp(buffer, "quit", 4) == 0)
+          exit(0);
+      }
+
+      fprintf(stdout, "%-40s", testcases[ii].description);
+      fflush(stdout);
+    }
+
     bool reconnect= false;
     enum test_return ret= testcases[ii].function();
     if (ret == TEST_FAIL)