Merge lp://staging/~trond-norbye/libmemcached/bugparade into lp://staging/~tangent-org/libmemcached/trunk

Proposed by Trond Norbye
Status: Merged
Merged at revision: not available
Proposed branch: lp://staging/~trond-norbye/libmemcached/bugparade
Merge into: lp://staging/~tangent-org/libmemcached/trunk
Diff against target: 1146 lines
7 files modified
clients/memcapable.c (+714/-41)
libmemcached/memcached_delete.c (+1/-1)
libmemcached/memcached_get.c (+5/-2)
libmemcached/memcached_purge.c (+1/-1)
libmemcached/memcached_response.c (+7/-1)
libmemcached/memcached_stats.c (+2/-2)
tests/function.c (+154/-0)
To merge this branch: bzr merge lp://staging/~trond-norbye/libmemcached/bugparade
Reviewer Review Type Date Requested Status
Brian Aker Needs Fixing
Review via email: mp+12895@code.staging.launchpad.net
To post a comment you must log in.
Revision history for this message
Trond Norbye (trond-norbye) wrote :

 596. By Trond Norbye 11 minutes ago

    Create workaround for warnings generated by a broken C99 compiler

    Some of the flags to turn on extra analysis and warnings in gcc contains
    various bugs related to struct initializations (see section 6.7.8 in C99)
    causing bogus warnings to be generated. Due to the fact that we compile
    with warning == error, this is a showstopper for us. We cannot expect all
    users to be running the latest compilers, so we have to create the workaround
    in our code.

595. By Trond Norbye 1 hour ago

    Fix return type from test functions (should be TEST_SUCCESS and not 0)

594. By Trond Norbye 1 hour ago

    Strip trailing whitespaces

593. By Trond Norbye 1 hour ago

    Update protocol due to review comments:

    * Typedef the structs in the public interface
    * Removed the EVENT enum, and replaced it with a bitmask of it's own type
    * Added support for PAUSE events in the _binary_ protocol. ASCII is on the
      todo list :-)

592. By Trond Norbye 3 hours ago

    Move libmemcachedutil to libmemcached/util where it belongs

591. By Trond Norbye 4 hours ago

    Fix compilation failure on 32 bit systems caused by macro redefinition

597. By Trond Norbye <tn202803@tor01>

Bug #434843: Large multigets with binary protocol may hang client

598. By Trond Norbye

Bug 421108: memstat reports same value for bytes, bytes_read and bytes_written

Revision history for this message
Brian Aker (brianaker) wrote :

Build failure on gaz. Your const int does not compare directly to counter which is unsigned.

review: Needs Fixing
599. By Trond Norbye

Fix compilation warnings reported by gcc

600. By Trond Norbye

Initial support for the ASCII protocol in memcapable

601. By Trond Norbye

Flush does not reset the bytes stat, so we have no idea of the value

602. By Trond Norbye <tn202803@tor01>

Merge Eric

603. By Trond Norbye <tn202803@tor01>

Bug #442914: 'delete noreply' may hang the client

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'clients/memcapable.c'
--- clients/memcapable.c 2009-09-28 22:25:10 +0000
+++ clients/memcapable.c 2009-10-08 14:12:13 +0000
@@ -19,6 +19,7 @@
19#include <stdbool.h>19#include <stdbool.h>
20#include <unistd.h>20#include <unistd.h>
21#include <poll.h>21#include <poll.h>
22#include <ctype.h>
2223
23#include <libmemcached/memcached/protocol_binary.h>24#include <libmemcached/memcached/protocol_binary.h>
24#include <libmemcached/byteorder.h>25#include <libmemcached/byteorder.h>
@@ -168,7 +169,7 @@
168 ret= read(fd, buf, len);169 ret= read(fd, buf, len);
169170
170 if (ret == -1 && errno == EWOULDBLOCK) {171 if (ret == -1 && errno == EWOULDBLOCK) {
171 struct pollfd fds = {172 struct pollfd fds= {
172 .events= direction,173 .events= direction,
173 .fd= fd174 .fd= fd
174 };175 };
@@ -183,7 +184,7 @@
183 }184 }
184 else if (err == 0)185 else if (err == 0)
185 {186 {
186 errno = ETIMEDOUT;187 errno= ETIMEDOUT;
187 }188 }
188 else189 else
189 {190 {
@@ -206,7 +207,7 @@
206 if (!val)207 if (!val)
207 {208 {
208 if (verbose)209 if (verbose)
209 fprintf(stderr, "%s:%u: %s\n", file, line, expression);210 fprintf(stderr, "\n%s:%u: %s", file, line, expression);
210211
211 if (do_core)212 if (do_core)
212 abort();213 abort();
@@ -639,7 +640,7 @@
639 cmd.set.message.header.request.opcode= PROTOCOL_BINARY_CMD_SET;640 cmd.set.message.header.request.opcode= PROTOCOL_BINARY_CMD_SET;
640 execute(resend_packet(&cmd));641 execute(resend_packet(&cmd));
641 execute(recv_packet(&rsp));642 execute(recv_packet(&rsp));
642 verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_SET, 643 verify(validate_response_header(&rsp, PROTOCOL_BINARY_CMD_SET,
643 PROTOCOL_BINARY_RESPONSE_SUCCESS));644 PROTOCOL_BINARY_RESPONSE_SUCCESS));
644 cmd.set.message.header.request.opcode= PROTOCOL_BINARY_CMD_SETQ;645 cmd.set.message.header.request.opcode= PROTOCOL_BINARY_CMD_SETQ;
645 }646 }
@@ -720,7 +721,7 @@
720 return test_binary_add_impl("test_binary_addq", PROTOCOL_BINARY_CMD_ADDQ);721 return test_binary_add_impl("test_binary_addq", PROTOCOL_BINARY_CMD_ADDQ);
721}722}
722723
723static enum test_return set_item(const char *key, const char *value)724static enum test_return binary_set_item(const char *key, const char *value)
724{725{
725 command cmd;726 command cmd;
726 response rsp;727 response rsp;
@@ -761,7 +762,7 @@
761 verify(validate_response_header(&rsp, cc, expected_result));762 verify(validate_response_header(&rsp, cc, expected_result));
762763
763 if (ii == 0)764 if (ii == 0)
764 execute(set_item(key, key));765 execute(binary_set_item(key, key));
765 }766 }
766 else767 else
767 execute(test_binary_noop());768 execute(test_binary_noop());
@@ -810,7 +811,7 @@
810 execute(send_packet(&cmd));811 execute(send_packet(&cmd));
811 execute(recv_packet(&rsp));812 execute(recv_packet(&rsp));
812 verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT));813 verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT));
813 execute(set_item(key, key));814 execute(binary_set_item(key, key));
814815
815 /* The item should be present now, resend*/816 /* The item should be present now, resend*/
816 execute(resend_packet(&cmd));817 execute(resend_packet(&cmd));
@@ -851,7 +852,7 @@
851 else852 else
852 execute(test_binary_noop());853 execute(test_binary_noop());
853854
854 execute(set_item(key, key));855 execute(binary_set_item(key, key));
855 execute(resend_packet(&cmd));856 execute(resend_packet(&cmd));
856 execute(recv_packet(&rsp));857 execute(recv_packet(&rsp));
857 verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));858 verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
@@ -993,7 +994,7 @@
993994
994 for (int ii= 0; ii < 2; ++ii)995 for (int ii= 0; ii < 2; ++ii)
995 {996 {
996 execute(set_item(key, key));997 execute(binary_set_item(key, key));
997 flush_command(&cmd, cc, 0, ii == 0);998 flush_command(&cmd, cc, 0, ii == 0);
998 execute(send_packet(&cmd));999 execute(send_packet(&cmd));
9991000
@@ -1036,7 +1037,7 @@
1036 else1037 else
1037 value=" world";1038 value=" world";
10381039
1039 execute(set_item(key, value));1040 execute(binary_set_item(key, value));
10401041
1041 if (cc == PROTOCOL_BINARY_CMD_APPEND || cc == PROTOCOL_BINARY_CMD_APPENDQ)1042 if (cc == PROTOCOL_BINARY_CMD_APPEND || cc == PROTOCOL_BINARY_CMD_APPENDQ)
1042 value=" world";1043 value=" world";
@@ -1117,7 +1118,650 @@
1117 ++cc;1118 ++cc;
1118 }1119 }
11191120
1120 return TEST_PASS;1121 return TEST_PASS_RECONNECT;
1122}
1123
1124static enum test_return send_string(const char *cmd)
1125{
1126 execute(retry_write(cmd, strlen(cmd)));
1127 return TEST_PASS;
1128}
1129
1130static enum test_return receive_line(char *buffer, size_t size)
1131{
1132 size_t offset= 0;
1133 while (offset < size)
1134 {
1135 execute(retry_read(buffer + offset, 1));
1136 if (buffer[offset] == '\n')
1137 {
1138 if (offset + 1 < size)
1139 {
1140 buffer[offset + 1]= '\0';
1141 return TEST_PASS;
1142 }
1143 else
1144 return TEST_FAIL;
1145 }
1146 ++offset;
1147 }
1148
1149 return TEST_FAIL;
1150}
1151
1152static enum test_return receive_response(const char *msg) {
1153 char buffer[80];
1154 execute(receive_line(buffer, sizeof(buffer)));
1155 verify(strcmp(msg, buffer) == 0);
1156 return TEST_PASS;
1157}
1158
1159static enum test_return test_ascii_quit(void)
1160{
1161 /* Verify that quit handles unknown options */
1162 execute(send_string("quit foo bar\r\n"));
1163 execute(receive_response("ERROR\r\n"));
1164
1165 /* quit doesn't support noreply */
1166 execute(send_string("quit noreply\r\n"));
1167 execute(receive_response("ERROR\r\n"));
1168
1169 /* Verify that quit works */
1170 execute(send_string("quit\r\n"));
1171
1172 /* Socket should be closed now, read should return 0 */
1173 char buffer[80];
1174 verify(timeout_io_op(sock, POLLIN, buffer, sizeof(buffer)) == 0);
1175 return TEST_PASS_RECONNECT;
1176
1177}
1178
1179static enum test_return test_ascii_version(void)
1180{
1181 /* Verify that version command handles unknown options */
1182 execute(send_string("version foo bar\r\n"));
1183 execute(receive_response("ERROR\r\n"));
1184
1185 /* version doesn't support noreply */
1186 execute(send_string("version noreply\r\n"));
1187 execute(receive_response("ERROR\r\n"));
1188
1189 /* Verify that verify works */
1190 execute(send_string("version\r\n"));
1191 char buffer[256];
1192 execute(receive_line(buffer, sizeof(buffer)));
1193 verify(strncmp(buffer, "VERSION ", 8) == 0);
1194
1195 return TEST_PASS;
1196}
1197
1198static enum test_return test_ascii_verbosity(void)
1199{
1200 /* This command does not adhere to the spec! */
1201 execute(send_string("verbosity foo bar my\r\n"));
1202 execute(receive_response("ERROR\r\n"));
1203
1204 execute(send_string("verbosity noreply\r\n"));
1205 execute(test_ascii_version());
1206
1207 execute(send_string("verbosity 0 noreply\r\n"));
1208 execute(test_ascii_version());
1209
1210 execute(send_string("verbosity\r\n"));
1211 execute(receive_response("ERROR\r\n"));
1212
1213 execute(send_string("verbosity 1\r\n"));
1214 execute(receive_response("OK\r\n"));
1215
1216 execute(send_string("verbosity 0\r\n"));
1217 execute(receive_response("OK\r\n"));
1218
1219 return TEST_PASS;
1220}
1221
1222
1223
1224static enum test_return test_ascii_set_impl(const char* key, bool noreply)
1225{
1226 /* @todo add tests for bogus format! */
1227 char buffer[1024];
1228 sprintf(buffer, "set %s 0 0 5%s\r\nvalue\r\n", key,
1229 noreply ? " noreply" : "");
1230 execute(send_string(buffer));
1231
1232 if (!noreply)
1233 execute(receive_response("STORED\r\n"));
1234
1235 return test_ascii_version();
1236}
1237
1238static enum test_return test_ascii_set(void)
1239{
1240 return test_ascii_set_impl("test_ascii_set", false);
1241}
1242
1243static enum test_return test_ascii_set_noreply(void)
1244{
1245 return test_ascii_set_impl("test_ascii_set_noreply", true);
1246}
1247
1248static enum test_return test_ascii_add_impl(const char* key, bool noreply)
1249{
1250 /* @todo add tests for bogus format! */
1251 char buffer[1024];
1252 sprintf(buffer, "add %s 0 0 5%s\r\nvalue\r\n", key,
1253 noreply ? " noreply" : "");
1254 execute(send_string(buffer));
1255
1256 if (!noreply)
1257 execute(receive_response("STORED\r\n"));
1258
1259 execute(send_string(buffer));
1260
1261 if (!noreply)
1262 execute(receive_response("NOT_STORED\r\n"));
1263
1264 return test_ascii_version();
1265}
1266
1267static enum test_return test_ascii_add(void)
1268{
1269 return test_ascii_add_impl("test_ascii_add", false);
1270}
1271
1272static enum test_return test_ascii_add_noreply(void)
1273{
1274 return test_ascii_add_impl("test_ascii_add_noreply", true);
1275}
1276
1277static enum test_return ascii_get_value(const char *key, const char *value)
1278{
1279
1280 char buffer[1024];
1281 size_t datasize= strlen(value);
1282
1283 verify(datasize < sizeof(buffer));
1284 execute(receive_line(buffer, sizeof(buffer)));
1285 verify(strncmp(buffer, "VALUE ", 6) == 0);
1286 verify(strncmp(buffer + 6, key, strlen(key)) == 0);
1287 char *ptr= buffer + 6 + strlen(key) + 1;
1288 char *end;
1289
1290 unsigned long val= strtoul(ptr, &end, 10); /* flags */
1291 verify(ptr != end);
1292 verify(val == 0);
1293 verify(end != NULL);
1294 val= strtoul(end, &end, 10); /* size */
1295 verify(ptr != end);
1296 verify(val == datasize);
1297 verify(end != NULL);
1298 while (*end != '\n' && isspace(*end))
1299 ++end;
1300 verify(*end == '\n');
1301
1302 execute(retry_read(buffer, datasize));
1303 verify(memcmp(buffer, value, datasize) == 0);
1304
1305 execute(retry_read(buffer, 2));
1306 verify(memcmp(buffer, "\r\n", 2) == 0);
1307
1308 return TEST_PASS;
1309}
1310
1311static enum test_return ascii_get_item(const char *key, const char *value,
1312 bool exist)
1313{
1314 char buffer[1024];
1315 size_t datasize= 0;
1316 if (value != NULL)
1317 datasize= strlen(value);
1318
1319 verify(datasize < sizeof(buffer));
1320 sprintf(buffer, "get %s\r\n", key);
1321 execute(send_string(buffer));
1322
1323 if (exist)
1324 execute(ascii_get_value(key, value));
1325
1326 execute(retry_read(buffer, 5));
1327 verify(memcmp(buffer, "END\r\n", 5) == 0);
1328
1329 return TEST_PASS;
1330}
1331
1332static enum test_return ascii_gets_value(const char *key, const char *value,
1333 unsigned long *cas)
1334{
1335
1336 char buffer[1024];
1337 size_t datasize= strlen(value);
1338
1339 verify(datasize < sizeof(buffer));
1340 execute(receive_line(buffer, sizeof(buffer)));
1341 verify(strncmp(buffer, "VALUE ", 6) == 0);
1342 verify(strncmp(buffer + 6, key, strlen(key)) == 0);
1343 char *ptr= buffer + 6 + strlen(key) + 1;
1344 char *end;
1345
1346 unsigned long val= strtoul(ptr, &end, 10); /* flags */
1347 verify(ptr != end);
1348 verify(val == 0);
1349 verify(end != NULL);
1350 val= strtoul(end, &end, 10); /* size */
1351 verify(ptr != end);
1352 verify(val == datasize);
1353 verify(end != NULL);
1354 *cas= strtoul(end, &end, 10); /* cas */
1355 verify(ptr != end);
1356 verify(val == datasize);
1357 verify(end != NULL);
1358
1359 while (*end != '\n' && isspace(*end))
1360 ++end;
1361 verify(*end == '\n');
1362
1363 execute(retry_read(buffer, datasize));
1364 verify(memcmp(buffer, value, datasize) == 0);
1365
1366 execute(retry_read(buffer, 2));
1367 verify(memcmp(buffer, "\r\n", 2) == 0);
1368
1369 return TEST_PASS;
1370}
1371
1372static enum test_return ascii_gets_item(const char *key, const char *value,
1373 bool exist, unsigned long *cas)
1374{
1375 char buffer[1024];
1376 size_t datasize= 0;
1377 if (value != NULL)
1378 datasize= strlen(value);
1379
1380 verify(datasize < sizeof(buffer));
1381 sprintf(buffer, "gets %s\r\n", key);
1382 execute(send_string(buffer));
1383
1384 if (exist)
1385 execute(ascii_gets_value(key, value, cas));
1386
1387 execute(retry_read(buffer, 5));
1388 verify(memcmp(buffer, "END\r\n", 5) == 0);
1389
1390 return TEST_PASS;
1391}
1392
1393static enum test_return ascii_set_item(const char *key, const char *value)
1394{
1395 char buffer[300];
1396 size_t len= strlen(value);
1397 sprintf(buffer, "set %s 0 0 %u\r\n", key, (unsigned int)len);
1398 execute(send_string(buffer));
1399 execute(retry_write(value, len));
1400 execute(send_string("\r\n"));
1401 execute(receive_response("STORED\r\n"));
1402 return TEST_PASS;
1403}
1404
1405static enum test_return test_ascii_replace_impl(const char* key, bool noreply)
1406{
1407 char buffer[1024];
1408 sprintf(buffer, "replace %s 0 0 5%s\r\nvalue\r\n", key,
1409 noreply ? " noreply" : "");
1410 execute(send_string(buffer));
1411
1412 if (noreply)
1413 execute(test_ascii_version());
1414 else
1415 execute(receive_response("NOT_STORED\r\n"));
1416
1417 execute(ascii_set_item(key, "value"));
1418 execute(ascii_get_item(key, "value", true));
1419
1420
1421 execute(send_string(buffer));
1422
1423 if (noreply)
1424 execute(test_ascii_version());
1425 else
1426 execute(receive_response("STORED\r\n"));
1427
1428 return test_ascii_version();
1429}
1430
1431static enum test_return test_ascii_replace(void)
1432{
1433 return test_ascii_replace_impl("test_ascii_replace", false);
1434}
1435
1436static enum test_return test_ascii_replace_noreply(void)
1437{
1438 return test_ascii_replace_impl("test_ascii_replace_noreply", true);
1439}
1440
1441static enum test_return test_ascii_cas_impl(const char* key, bool noreply)
1442{
1443 char buffer[1024];
1444 unsigned long cas;
1445
1446 execute(ascii_set_item(key, "value"));
1447 execute(ascii_gets_item(key, "value", true, &cas));
1448
1449 sprintf(buffer, "cas %s 0 0 6 %lu%s\r\nvalue2\r\n", key, cas,
1450 noreply ? " noreply" : "");
1451 execute(send_string(buffer));
1452
1453 if (noreply)
1454 execute(test_ascii_version());
1455 else
1456 execute(receive_response("STORED\r\n"));
1457
1458 /* reexecute the same command should fail due to illegal cas */
1459 execute(send_string(buffer));
1460
1461 if (noreply)
1462 execute(test_ascii_version());
1463 else
1464 execute(receive_response("EXISTS\r\n"));
1465
1466 return test_ascii_version();
1467}
1468
1469static enum test_return test_ascii_cas(void)
1470{
1471 return test_ascii_cas_impl("test_ascii_cas", false);
1472}
1473
1474static enum test_return test_ascii_cas_noreply(void)
1475{
1476 return test_ascii_cas_impl("test_ascii_cas_noreply", true);
1477}
1478
1479static enum test_return test_ascii_delete_impl(const char *key, bool noreply)
1480{
1481 execute(ascii_set_item(key, "value"));
1482
1483 execute(send_string("delete\r\n"));
1484 execute(receive_response("ERROR\r\n"));
1485 /* BUG: the server accepts delete a b */
1486 execute(send_string("delete a b c d e\r\n"));
1487 execute(receive_response("ERROR\r\n"));
1488
1489 char buffer[1024];
1490 sprintf(buffer, "delete %s%s\r\n", key, noreply ? " noreply" : "");
1491 execute(send_string(buffer));
1492
1493 if (noreply)
1494 execute(test_ascii_version());
1495 else
1496 execute(receive_response("DELETED\r\n"));
1497
1498 execute(ascii_get_item(key, "value", false));
1499 execute(send_string(buffer));
1500 if (noreply)
1501 execute(test_ascii_version());
1502 else
1503 execute(receive_response("NOT_FOUND\r\n"));
1504
1505 return TEST_PASS;
1506}
1507
1508static enum test_return test_ascii_delete(void)
1509{
1510 return test_ascii_delete_impl("test_ascii_delete", false);
1511}
1512
1513static enum test_return test_ascii_delete_noreply(void)
1514{
1515 return test_ascii_delete_impl("test_ascii_delete_noreply", true);
1516}
1517
1518static enum test_return test_ascii_get(void)
1519{
1520 execute(ascii_set_item("test_ascii_get", "value"));
1521
1522 execute(send_string("get\r\n"));
1523 execute(receive_response("ERROR\r\n"));
1524 execute(ascii_get_item("test_ascii_get", "value", true));
1525 execute(ascii_get_item("test_ascii_get_notfound", "value", false));
1526
1527 return TEST_PASS;
1528}
1529
1530static enum test_return test_ascii_gets(void)
1531{
1532 execute(ascii_set_item("test_ascii_gets", "value"));
1533
1534 execute(send_string("gets\r\n"));
1535 execute(receive_response("ERROR\r\n"));
1536 unsigned long cas;
1537 execute(ascii_gets_item("test_ascii_gets", "value", true, &cas));
1538 execute(ascii_gets_item("test_ascii_gets_notfound", "value", false, &cas));
1539
1540 return TEST_PASS;
1541}
1542
1543static enum test_return test_ascii_mget(void)
1544{
1545 execute(ascii_set_item("test_ascii_mget1", "value"));
1546 execute(ascii_set_item("test_ascii_mget2", "value"));
1547 execute(ascii_set_item("test_ascii_mget3", "value"));
1548 execute(ascii_set_item("test_ascii_mget4", "value"));
1549 execute(ascii_set_item("test_ascii_mget5", "value"));
1550
1551 execute(send_string("get test_ascii_mget1 test_ascii_mget2 test_ascii_mget3 "
1552 "test_ascii_mget4 test_ascii_mget5 "
1553 "test_ascii_mget6\r\n"));
1554 execute(ascii_get_value("test_ascii_mget1", "value"));
1555 execute(ascii_get_value("test_ascii_mget2", "value"));
1556 execute(ascii_get_value("test_ascii_mget3", "value"));
1557 execute(ascii_get_value("test_ascii_mget4", "value"));
1558 execute(ascii_get_value("test_ascii_mget5", "value"));
1559
1560 char buffer[5];
1561 execute(retry_read(buffer, 5));
1562 verify(memcmp(buffer, "END\r\n", 5) == 0);
1563 return TEST_PASS;
1564}
1565
1566static enum test_return test_ascii_incr_impl(const char* key, bool noreply)
1567{
1568 char cmd[300];
1569 sprintf(cmd, "incr %s 1%s\r\n", key, noreply ? " noreply" : "");
1570
1571 execute(ascii_set_item(key, "0"));
1572 for (int x= 1; x < 11; ++x)
1573 {
1574 execute(send_string(cmd));
1575
1576 if (noreply)
1577 execute(test_ascii_version());
1578 else
1579 {
1580 char buffer[80];
1581 execute(receive_line(buffer, sizeof(buffer)));
1582 int val= atoi(buffer);
1583 verify(val == x);
1584 }
1585 }
1586
1587 execute(ascii_get_item(key, "10", true));
1588
1589 return TEST_PASS;
1590}
1591
1592static enum test_return test_ascii_incr(void)
1593{
1594 return test_ascii_incr_impl("test_ascii_incr", false);
1595}
1596
1597static enum test_return test_ascii_incr_noreply(void)
1598{
1599 return test_ascii_incr_impl("test_ascii_incr_noreply", true);
1600}
1601
1602static enum test_return test_ascii_decr_impl(const char* key, bool noreply)
1603{
1604 char cmd[300];
1605 sprintf(cmd, "decr %s 1%s\r\n", key, noreply ? " noreply" : "");
1606
1607 execute(ascii_set_item(key, "9"));
1608 for (int x= 8; x > -1; --x)
1609 {
1610 execute(send_string(cmd));
1611
1612 if (noreply)
1613 execute(test_ascii_version());
1614 else
1615 {
1616 char buffer[80];
1617 execute(receive_line(buffer, sizeof(buffer)));
1618 int val= atoi(buffer);
1619 verify(val == x);
1620 }
1621 }
1622
1623 execute(ascii_get_item(key, "0", true));
1624
1625 /* verify that it doesn't wrap */
1626 execute(send_string(cmd));
1627 if (noreply)
1628 execute(test_ascii_version());
1629 else
1630 {
1631 char buffer[80];
1632 execute(receive_line(buffer, sizeof(buffer)));
1633 }
1634 execute(ascii_get_item(key, "0", true));
1635
1636 return TEST_PASS;
1637}
1638
1639static enum test_return test_ascii_decr(void)
1640{
1641 return test_ascii_decr_impl("test_ascii_decr", false);
1642}
1643
1644static enum test_return test_ascii_decr_noreply(void)
1645{
1646 return test_ascii_decr_impl("test_ascii_decr_noreply", true);
1647}
1648
1649
1650static enum test_return test_ascii_flush_impl(const char *key, bool noreply)
1651{
1652#if 0
1653 /* Verify that the flush_all command handles unknown options */
1654 /* Bug in the current memcached server! */
1655 execute(send_string("flush_all foo bar\r\n"));
1656 execute(receive_response("ERROR\r\n"));
1657#endif
1658
1659 execute(ascii_set_item(key, key));
1660 execute(ascii_get_item(key, key, true));
1661
1662 if (noreply)
1663 {
1664 execute(send_string("flush_all noreply\r\n"));
1665 execute(test_ascii_version());
1666 }
1667 else
1668 {
1669 execute(send_string("flush_all\r\n"));
1670 execute(receive_response("OK\r\n"));
1671 }
1672
1673 execute(ascii_get_item(key, key, false));
1674
1675 return TEST_PASS;
1676}
1677
1678static enum test_return test_ascii_flush(void)
1679{
1680 return test_ascii_flush_impl("test_ascii_flush", false);
1681}
1682
1683static enum test_return test_ascii_flush_noreply(void)
1684{
1685 return test_ascii_flush_impl("test_ascii_flush_noreply", true);
1686}
1687
1688static enum test_return test_ascii_concat_impl(const char *key,
1689 bool append,
1690 bool noreply)
1691{
1692 const char *value;
1693
1694 if (append)
1695 value="hello";
1696 else
1697 value=" world";
1698
1699 execute(ascii_set_item(key, value));
1700
1701 if (append)
1702 value=" world";
1703 else
1704 value="hello";
1705
1706 char cmd[400];
1707 sprintf(cmd, "%s %s 0 0 %u%s\r\n%s\r\n",
1708 append ? "append" : "prepend",
1709 key, (unsigned int)strlen(value), noreply ? " noreply" : "",
1710 value);
1711 execute(send_string(cmd));
1712
1713 if (noreply)
1714 execute(test_ascii_version());
1715 else
1716 execute(receive_response("STORED\r\n"));
1717
1718 execute(ascii_get_item(key, "hello world", true));
1719
1720 sprintf(cmd, "%s %s_notfound 0 0 %u%s\r\n%s\r\n",
1721 append ? "append" : "prepend",
1722 key, (unsigned int)strlen(value), noreply ? " noreply" : "",
1723 value);
1724 execute(send_string(cmd));
1725
1726 if (noreply)
1727 execute(test_ascii_version());
1728 else
1729 execute(receive_response("NOT_STORED\r\n"));
1730
1731 return TEST_PASS;
1732}
1733
1734static enum test_return test_ascii_append(void)
1735{
1736 return test_ascii_concat_impl("test_ascii_append", true, false);
1737}
1738
1739static enum test_return test_ascii_prepend(void)
1740{
1741 return test_ascii_concat_impl("test_ascii_prepend", false, false);
1742}
1743
1744static enum test_return test_ascii_append_noreply(void)
1745{
1746 return test_ascii_concat_impl("test_ascii_append_noreply", true, true);
1747}
1748
1749static enum test_return test_ascii_prepend_noreply(void)
1750{
1751 return test_ascii_concat_impl("test_ascii_prepend_noreply", false, true);
1752}
1753
1754static enum test_return test_ascii_stat(void)
1755{
1756 execute(send_string("stats noreply\r\n"));
1757 execute(receive_response("ERROR\r\n"));
1758 execute(send_string("stats\r\n"));
1759 char buffer[1024];
1760 do {
1761 execute(receive_line(buffer, sizeof(buffer)));
1762 } while (strcmp(buffer, "END\r\n") != 0);
1763
1764 return TEST_PASS_RECONNECT;
1121}1765}
11221766
1123typedef enum test_return(*TEST_FUNC)(void);1767typedef enum test_return(*TEST_FUNC)(void);
@@ -1129,34 +1773,61 @@
1129};1773};
11301774
1131struct testcase testcases[]= {1775struct testcase testcases[]= {
1132 { "noop", test_binary_noop},1776 { "ascii quit", test_ascii_quit },
1133 { "quit", test_binary_quit},1777 { "ascii version", test_ascii_version },
1134 { "quitq", test_binary_quitq},1778 { "ascii verbosity", test_ascii_verbosity },
1135 { "set", test_binary_set},1779 { "ascii set", test_ascii_set },
1136 { "setq", test_binary_setq},1780 { "ascii set noreply", test_ascii_set_noreply },
1137 { "flush", test_binary_flush},1781 { "ascii get", test_ascii_get },
1138 { "flushq", test_binary_flushq},1782 { "ascii gets", test_ascii_gets },
1139 { "add", test_binary_add},1783 { "ascii mget", test_ascii_mget },
1140 { "addq", test_binary_addq},1784 { "ascii flush", test_ascii_flush },
1141 { "replace", test_binary_replace},1785 { "ascii flush noreply", test_ascii_flush_noreply },
1142 { "replaceq", test_binary_replaceq},1786 { "ascii add", test_ascii_add },
1143 { "delete", test_binary_delete},1787 { "ascii add noreply", test_ascii_add_noreply },
1144 { "deleteq", test_binary_deleteq},1788 { "ascii replace", test_ascii_replace },
1145 { "get", test_binary_get},1789 { "ascii replace noreply", test_ascii_replace_noreply },
1146 { "getq", test_binary_getq},1790 { "ascii cas", test_ascii_cas },
1147 { "getk", test_binary_getk},1791 { "ascii cas noreply", test_ascii_cas_noreply },
1148 { "getkq", test_binary_getkq},1792 { "ascii delete", test_ascii_delete },
1149 { "incr", test_binary_incr},1793 { "ascii delete noreply", test_ascii_delete_noreply },
1150 { "incrq", test_binary_incrq},1794 { "ascii incr", test_ascii_incr },
1151 { "decr", test_binary_decr},1795 { "ascii incr noreply", test_ascii_incr_noreply },
1152 { "decrq", test_binary_decrq},1796 { "ascii decr", test_ascii_decr },
1153 { "version", test_binary_version},1797 { "ascii decr noreply", test_ascii_decr_noreply },
1154 { "append", test_binary_append},1798 { "ascii append", test_ascii_append },
1155 { "appendq", test_binary_appendq},1799 { "ascii append noreply", test_ascii_append_noreply },
1156 { "prepend", test_binary_prepend},1800 { "ascii prepend", test_ascii_prepend },
1157 { "prependq", test_binary_prependq},1801 { "ascii prepend noreply", test_ascii_prepend_noreply },
1158 { "stat", test_binary_stat},1802 { "ascii stat", test_ascii_stat },
1159 { "illegal", test_binary_illegal},1803 { "binary noop", test_binary_noop },
1804 { "binary quit", test_binary_quit },
1805 { "binary quitq", test_binary_quitq },
1806 { "binary set", test_binary_set },
1807 { "binary setq", test_binary_setq },
1808 { "binary flush", test_binary_flush },
1809 { "binary flushq", test_binary_flushq },
1810 { "binary add", test_binary_add },
1811 { "binary addq", test_binary_addq },
1812 { "binary replace", test_binary_replace },
1813 { "binary replaceq", test_binary_replaceq },
1814 { "binary delete", test_binary_delete },
1815 { "binary deleteq", test_binary_deleteq },
1816 { "binary get", test_binary_get },
1817 { "binary getq", test_binary_getq },
1818 { "binary getk", test_binary_getk },
1819 { "binary getkq", test_binary_getkq },
1820 { "binary incr", test_binary_incr },
1821 { "binary incrq", test_binary_incrq },
1822 { "binary decr", test_binary_decr },
1823 { "binary decrq", test_binary_decrq },
1824 { "binary version", test_binary_version },
1825 { "binary append", test_binary_append },
1826 { "binary appendq", test_binary_appendq },
1827 { "binary prepend", test_binary_prepend },
1828 { "binary prependq", test_binary_prependq },
1829 { "binary stat", test_binary_stat },
1830 { "binary illegal", test_binary_illegal },
1160 { NULL, NULL}1831 { NULL, NULL}
1161};1832};
11621833
@@ -1209,20 +1880,22 @@
1209 for (int ii= 0; testcases[ii].description != NULL; ++ii)1880 for (int ii= 0; testcases[ii].description != NULL; ++ii)
1210 {1881 {
1211 ++total;1882 ++total;
1212 fprintf(stdout, "%s\t\t", testcases[ii].description);1883 fprintf(stdout, "%-40s", testcases[ii].description);
1213 fflush(stdout);1884 fflush(stdout);
12141885
1215 bool reconnect= false;1886 bool reconnect= false;
1216 enum test_return ret= testcases[ii].function();1887 enum test_return ret= testcases[ii].function();
1217 fprintf(stderr, "%s\n", status_msg[ret]);
1218 if (ret == TEST_FAIL)1888 if (ret == TEST_FAIL)
1219 {1889 {
1220 reconnect= true;1890 reconnect= true;
1221 ++failed;1891 ++failed;
1892 if (verbose)
1893 fprintf(stderr, "\n");
1222 }1894 }
1223 else if (ret == TEST_PASS_RECONNECT)1895 else if (ret == TEST_PASS_RECONNECT)
1224 reconnect= true;1896 reconnect= true;
12251897
1898 fprintf(stderr, "%s\n", status_msg[ret]);
1226 if (reconnect)1899 if (reconnect)
1227 {1900 {
1228 (void) close(sock);1901 (void) close(sock);
12291902
=== modified file 'libmemcached/memcached_delete.c'
--- libmemcached/memcached_delete.c 2009-07-18 17:09:59 +0000
+++ libmemcached/memcached_delete.c 2009-10-08 14:12:13 +0000
@@ -36,7 +36,7 @@
36 return MEMCACHED_NO_SERVERS;36 return MEMCACHED_NO_SERVERS;
3737
38 server_key= memcached_generate_hash(ptr, master_key, master_key_length);38 server_key= memcached_generate_hash(ptr, master_key, master_key_length);
39 to_write= (uint8_t) (ptr->flags & MEM_BUFFER_REQUESTS) ? 0 : 1;39 to_write= (uint8_t)((ptr->flags & MEM_BUFFER_REQUESTS) ? 0 : 1);
40 bool no_reply= (ptr->flags & MEM_NOREPLY);40 bool no_reply= (ptr->flags & MEM_NOREPLY);
41 41
42 if (ptr->flags & MEM_BINARY_PROTOCOL) 42 if (ptr->flags & MEM_BINARY_PROTOCOL)
4343
=== modified file 'libmemcached/memcached_get.c'
--- libmemcached/memcached_get.c 2009-09-19 12:24:37 +0000
+++ libmemcached/memcached_get.c 2009-10-08 14:12:13 +0000
@@ -338,6 +338,9 @@
338 rc= MEMCACHED_SOME_ERRORS;338 rc= MEMCACHED_SOME_ERRORS;
339 continue;339 continue;
340 }340 }
341
342 /* We just want one pending response per server */
343 memcached_server_response_reset(&ptr->hosts[server_key]);
341 memcached_server_response_increment(&ptr->hosts[server_key]); 344 memcached_server_response_increment(&ptr->hosts[server_key]);
342 if ((x > 0 && x == ptr->io_key_prefetch) &&345 if ((x > 0 && x == ptr->io_key_prefetch) &&
343 memcached_flush_buffers(ptr) != MEMCACHED_SUCCESS)346 memcached_flush_buffers(ptr) != MEMCACHED_SUCCESS)
@@ -371,7 +374,6 @@
371 memcached_io_reset(&ptr->hosts[x]);374 memcached_io_reset(&ptr->hosts[x]);
372 rc= MEMCACHED_SOME_ERRORS;375 rc= MEMCACHED_SOME_ERRORS;
373 }376 }
374 memcached_server_response_increment(&ptr->hosts[x]);
375 }377 }
376 }378 }
377379
@@ -438,6 +440,8 @@
438 success= false;440 success= false;
439 continue;441 continue;
440 }442 }
443 /* we just want one pending response per server */
444 memcached_server_response_reset(&ptr->hosts[server]);
441 memcached_server_response_increment(&ptr->hosts[server]);445 memcached_server_response_increment(&ptr->hosts[server]);
442 }446 }
443447
@@ -461,7 +465,6 @@
461 dead_servers[x]= true;465 dead_servers[x]= true;
462 success= false;466 success= false;
463 }467 }
464 memcached_server_response_increment(&ptr->hosts[x]);
465468
466 /* mark all of the messages bound for this server as sent! */469 /* mark all of the messages bound for this server as sent! */
467 for (x= 0; x < number_of_keys; ++x)470 for (x= 0; x < number_of_keys; ++x)
468471
=== modified file 'libmemcached/memcached_purge.c'
--- libmemcached/memcached_purge.c 2009-07-18 17:37:40 +0000
+++ libmemcached/memcached_purge.c 2009-10-08 14:12:13 +0000
@@ -10,7 +10,7 @@
10 if (ptr->root->purging || /* already purging */10 if (ptr->root->purging || /* already purging */
11 (memcached_server_response_count(ptr) < ptr->root->io_msg_watermark &&11 (memcached_server_response_count(ptr) < ptr->root->io_msg_watermark &&
12 ptr->io_bytes_sent < ptr->root->io_bytes_watermark) ||12 ptr->io_bytes_sent < ptr->root->io_bytes_watermark) ||
13 (ptr->io_bytes_sent > ptr->root->io_bytes_watermark &&13 (ptr->io_bytes_sent >= ptr->root->io_bytes_watermark &&
14 memcached_server_response_count(ptr) < 2))14 memcached_server_response_count(ptr) < 2))
15 {15 {
16 return MEMCACHED_SUCCESS;16 return MEMCACHED_SUCCESS;
1717
=== modified file 'libmemcached/memcached_response.c'
--- libmemcached/memcached_response.c 2009-09-22 08:26:38 +0000
+++ libmemcached/memcached_response.c 2009-10-08 14:12:13 +0000
@@ -356,8 +356,14 @@
356 {356 {
357 switch (header.response.opcode)357 switch (header.response.opcode)
358 {358 {
359 case PROTOCOL_BINARY_CMD_GETKQ:
360 /*
361 * We didn't increment the response counter for the GETKQ packet
362 * (only the final NOOP), so we need to increment the counter again.
363 */
364 memcached_server_response_increment(ptr);
365 /* FALLTHROUGH */
359 case PROTOCOL_BINARY_CMD_GETK:366 case PROTOCOL_BINARY_CMD_GETK:
360 case PROTOCOL_BINARY_CMD_GETKQ:
361 {367 {
362 uint16_t keylen= header.response.keylen;368 uint16_t keylen= header.response.keylen;
363 memcached_result_reset(result);369 memcached_result_reset(result);
364370
=== modified file 'libmemcached/memcached_stats.c'
--- libmemcached/memcached_stats.c 2009-07-18 17:37:40 +0000
+++ libmemcached/memcached_stats.c 2009-10-08 14:12:13 +0000
@@ -185,8 +185,6 @@
185 length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->curr_items);185 length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->curr_items);
186 else if (!memcmp("total_items", key, strlen("total_items")))186 else if (!memcmp("total_items", key, strlen("total_items")))
187 length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->total_items);187 length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->total_items);
188 else if (!memcmp("bytes", key, strlen("bytes")))
189 length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->bytes);
190 else if (!memcmp("curr_connections", key, strlen("curr_connections")))188 else if (!memcmp("curr_connections", key, strlen("curr_connections")))
191 length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->curr_connections);189 length= snprintf(buffer, SMALL_STRING_LEN,"%u", memc_stat->curr_connections);
192 else if (!memcmp("total_connections", key, strlen("total_connections")))190 else if (!memcmp("total_connections", key, strlen("total_connections")))
@@ -207,6 +205,8 @@
207 length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->bytes_read);205 length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->bytes_read);
208 else if (!memcmp("bytes_written", key, strlen("bytes_written")))206 else if (!memcmp("bytes_written", key, strlen("bytes_written")))
209 length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->bytes_written);207 length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->bytes_written);
208 else if (!memcmp("bytes", key, strlen("bytes")))
209 length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->bytes);
210 else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes")))210 else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes")))
211 length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->limit_maxbytes);211 length= snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)memc_stat->limit_maxbytes);
212 else if (!memcmp("threads", key, strlen("threads")))212 else if (!memcmp("threads", key, strlen("threads")))
213213
=== modified file 'tests/function.c'
--- tests/function.c 2009-10-05 21:04:26 +0000
+++ tests/function.c 2009-10-08 14:12:13 +0000
@@ -4505,6 +4505,156 @@
4505 return TEST_SUCCESS;4505 return TEST_SUCCESS;
4506}4506}
45074507
4508static test_return regression_bug_434843(memcached_st *memc)
4509{
4510 if (pre_binary(memc) != TEST_SUCCESS)
4511 return TEST_SUCCESS;
4512
4513 memcached_return rc;
4514 unsigned int counter= 0;
4515 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
4516
4517 /*
4518 * I only want to hit only _one_ server so I know the number of requests I'm
4519 * sending in the pipleine to the server. Let's try to do a multiget of
4520 * 10240 (that should satisfy most users don't you tink?)
4521 */
4522 uint32_t number_of_hosts= memc->number_of_hosts;
4523 memc->number_of_hosts= 1;
4524 const size_t max_keys= 10240;
4525 char **keys= calloc(max_keys, sizeof(char*));
4526 size_t *key_length=calloc(max_keys, sizeof(size_t));
4527
4528 for (int x= 0; x < (int)max_keys; ++x)
4529 {
4530 char k[251];
4531 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
4532 keys[x]= strdup(k);
4533 assert(keys[x] != NULL);
4534 }
4535
4536 /*
4537 * Run two times.. the first time we should have 100% cache miss,
4538 * and the second time we should have 100% cache hits
4539 */
4540 for (int y= 0; y < 2; ++y)
4541 {
4542 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
4543 assert(rc == MEMCACHED_SUCCESS);
4544 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
4545 if (y == 0)
4546 {
4547 /* The first iteration should give me a 100% cache miss. verify that*/
4548 assert(counter == 0);
4549 char blob[1024];
4550 for (int x= 0; x < (int)max_keys; ++x)
4551 {
4552 rc= memcached_add(memc, keys[x], key_length[x],
4553 blob, sizeof(blob), 0, 0);
4554 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4555 }
4556 }
4557 else
4558 {
4559 /* Verify that we received all of the key/value pairs */
4560 assert(counter == (unsigned int)max_keys);
4561 }
4562 }
4563
4564 /* Release allocated resources */
4565 for (size_t x= 0; x < max_keys; ++x)
4566 free(keys[x]);
4567 free(keys);
4568 free(key_length);
4569
4570 memc->number_of_hosts= number_of_hosts;
4571 return TEST_SUCCESS;
4572}
4573
4574static test_return regression_bug_434843_buffered(memcached_st *memc)
4575{
4576 memcached_return rc;
4577 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4578 assert(rc == MEMCACHED_SUCCESS);
4579
4580 return regression_bug_434843(memc);
4581}
4582
4583static test_return regression_bug_421108(memcached_st *memc)
4584{
4585 memcached_return rc;
4586 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
4587 assert(rc == MEMCACHED_SUCCESS);
4588
4589 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
4590 assert(rc == MEMCACHED_SUCCESS);
4591 assert(bytes != NULL);
4592 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
4593 "bytes_read", &rc);
4594 assert(rc == MEMCACHED_SUCCESS);
4595 assert(bytes_read != NULL);
4596
4597 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
4598 "bytes_written", &rc);
4599 assert(rc == MEMCACHED_SUCCESS);
4600 assert(bytes_written != NULL);
4601
4602 assert(strcmp(bytes, bytes_read) != 0);
4603 assert(strcmp(bytes, bytes_written) != 0);
4604
4605 /* Release allocated resources */
4606 free(bytes);
4607 free(bytes_read);
4608 free(bytes_written);
4609 memcached_stat_free(NULL, memc_stat);
4610 return TEST_SUCCESS;
4611}
4612
4613/*
4614 * The test case isn't obvious so I should probably document why
4615 * it works the way it does. Bug 442914 was caused by a bug
4616 * in the logic in memcached_purge (it did not handle the case
4617 * where the number of bytes sent was equal to the watermark).
4618 * In this test case, create messages so that we hit that case
4619 * and then disable noreply mode and issue a new command to
4620 * verify that it isn't stuck. If we change the format for the
4621 * delete command or the watermarks, we need to update this
4622 * test....
4623 */
4624static test_return regression_bug_442914(memcached_st *memc)
4625{
4626 memcached_return rc;
4627 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4628 assert(rc == MEMCACHED_SUCCESS);
4629 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
4630
4631 uint32_t number_of_hosts= memc->number_of_hosts;
4632 memc->number_of_hosts= 1;
4633
4634 char k[250];
4635 size_t len;
4636
4637 for (int x= 0; x < 250; ++x)
4638 {
4639 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
4640 rc= memcached_delete(memc, k, len, 0);
4641 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4642 }
4643
4644 len= (size_t)snprintf(k, sizeof(k), "%037u", 251);
4645 rc= memcached_delete(memc, k, len, 0);
4646 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4647
4648 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
4649 assert(rc == MEMCACHED_SUCCESS);
4650 rc= memcached_delete(memc, k, len, 0);
4651 assert(rc == MEMCACHED_NOTFOUND);
4652
4653 memc->number_of_hosts= number_of_hosts;
4654
4655 return TEST_SUCCESS;
4656}
4657
4508test_st udp_setup_server_tests[] ={4658test_st udp_setup_server_tests[] ={
4509 {"set_udp_behavior_test", 0, set_udp_behavior_test},4659 {"set_udp_behavior_test", 0, set_udp_behavior_test},
4510 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},4660 {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test},
@@ -4666,6 +4816,10 @@
4666 */4816 */
4667test_st regression_tests[]= {4817test_st regression_tests[]= {
4668 {"lp:434484", 1, regression_bug_434484 },4818 {"lp:434484", 1, regression_bug_434484 },
4819 {"lp:434843", 1, regression_bug_434843 },
4820 {"lp:434843 buffered", 1, regression_bug_434843_buffered },
4821 {"lp:421108", 1, regression_bug_421108 },
4822 {"lp:442914", 1, regression_bug_442914 },
4669 {0, 0, 0}4823 {0, 0, 0}
4670};4824};
46714825

Subscribers

People subscribed via source and target branches

to all changes: