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:
*/
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=
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)
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
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)
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;
/* 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*/
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)
{
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)
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':
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;
}
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)