Unverified Commit 95d6297d authored by sundb's avatar sundb Committed by GitHub
Browse files

Add run all test support with define REDIS_TEST (#8570)

1. Add `redis-server test all` support to run all tests.
2. Add redis test to daily ci.
3. Add `--accurate` option to run slow tests for more iterations (so that
   by default we run less cycles (shorter time, and less prints).
4. Move dict benchmark to REDIS_TEST.
5. fix some leaks in tests
6. make quicklist tests run on a specific fill set of options rather than huge ranges
7. move some prints in quicklist test outside their loops to reduce prints
8. removing sds.h from dict.c since it is now used in both redis-server and
   redis-cli (uses hiredis sds)
parent 53774e69
...@@ -17,7 +17,7 @@ jobs: ...@@ -17,7 +17,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: make - name: make
run: make run: make REDIS_CFLAGS='-Werror -DREDIS_TEST'
- name: test - name: test
run: | run: |
sudo apt-get install tcl8.6 sudo apt-get install tcl8.6
...@@ -28,6 +28,8 @@ jobs: ...@@ -28,6 +28,8 @@ jobs:
run: ./runtest-sentinel run: ./runtest-sentinel
- name: cluster tests - name: cluster tests
run: ./runtest-cluster run: ./runtest-cluster
- name: unittest
run: ./src/redis-server test all
test-ubuntu-libc-malloc: test-ubuntu-libc-malloc:
runs-on: ubuntu-latest runs-on: ubuntu-latest
...@@ -76,7 +78,7 @@ jobs: ...@@ -76,7 +78,7 @@ jobs:
- name: make - name: make
run: | run: |
sudo apt-get update && sudo apt-get install libc6-dev-i386 sudo apt-get update && sudo apt-get install libc6-dev-i386
make 32bit make 32bit REDIS_CFLAGS='-Werror -DREDIS_TEST'
- name: test - name: test
run: | run: |
sudo apt-get install tcl8.6 sudo apt-get install tcl8.6
...@@ -89,6 +91,8 @@ jobs: ...@@ -89,6 +91,8 @@ jobs:
run: ./runtest-sentinel run: ./runtest-sentinel
- name: cluster tests - name: cluster tests
run: ./runtest-cluster run: ./runtest-cluster
- name: unittest
run: ./src/redis-server test all
test-ubuntu-tls: test-ubuntu-tls:
runs-on: ubuntu-latest runs-on: ubuntu-latest
...@@ -142,7 +146,7 @@ jobs: ...@@ -142,7 +146,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: make - name: make
run: make valgrind run: make valgrind REDIS_CFLAGS='-Werror -DREDIS_TEST'
- name: test - name: test
run: | run: |
sudo apt-get update sudo apt-get update
...@@ -150,6 +154,10 @@ jobs: ...@@ -150,6 +154,10 @@ jobs:
./runtest --valgrind --verbose --clients 1 --dump-logs ./runtest --valgrind --verbose --clients 1 --dump-logs
- name: module api test - name: module api test
run: ./runtest-moduleapi --valgrind --no-latency --verbose --clients 1 run: ./runtest-moduleapi --valgrind --no-latency --verbose --clients 1
- name: unittest
run: |
valgrind --track-origins=yes --suppressions=./src/valgrind.sup --show-reachable=no --show-possibly-lost=no --leak-check=full --log-file=err.txt ./src/redis-server test all
if grep -q 0x err.txt; then cat err.txt; exit 1; fi
test-valgrind-no-malloc-usable-size: test-valgrind-no-malloc-usable-size:
runs-on: ubuntu-latest runs-on: ubuntu-latest
......
...@@ -351,9 +351,6 @@ $(REDIS_CLI_NAME): $(REDIS_CLI_OBJ) ...@@ -351,9 +351,6 @@ $(REDIS_CLI_NAME): $(REDIS_CLI_OBJ)
$(REDIS_BENCHMARK_NAME): $(REDIS_BENCHMARK_OBJ) $(REDIS_BENCHMARK_NAME): $(REDIS_BENCHMARK_OBJ)
$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/hdr_histogram/hdr_histogram.o $(FINAL_LIBS) $(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/hdr_histogram/hdr_histogram.o $(FINAL_LIBS)
dict-benchmark: dict.c zmalloc.c sds.c siphash.c mt19937-64.c
$(REDIS_CC) $(FINAL_CFLAGS) $^ -D DICT_BENCHMARK_MAIN -o $@ $(FINAL_LIBS)
DEP = $(REDIS_SERVER_OBJ:%.o=%.d) $(REDIS_CLI_OBJ:%.o=%.d) $(REDIS_BENCHMARK_OBJ:%.o=%.d) DEP = $(REDIS_SERVER_OBJ:%.o=%.d) $(REDIS_CLI_OBJ:%.o=%.d) $(REDIS_BENCHMARK_OBJ:%.o=%.d)
-include $(DEP) -include $(DEP)
...@@ -364,7 +361,7 @@ DEP = $(REDIS_SERVER_OBJ:%.o=%.d) $(REDIS_CLI_OBJ:%.o=%.d) $(REDIS_BENCHMARK_OBJ ...@@ -364,7 +361,7 @@ DEP = $(REDIS_SERVER_OBJ:%.o=%.d) $(REDIS_CLI_OBJ:%.o=%.d) $(REDIS_BENCHMARK_OBJ
$(REDIS_CC) -MMD -o $@ -c $< $(REDIS_CC) -MMD -o $@ -c $<
clean: clean:
rm -rf $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME) *.o *.gcda *.gcno *.gcov redis.info lcov-html Makefile.dep dict-benchmark rm -rf $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME) *.o *.gcda *.gcno *.gcov redis.info lcov-html Makefile.dep
rm -f $(DEP) rm -f $(DEP)
.PHONY: clean .PHONY: clean
......
...@@ -127,9 +127,10 @@ uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l) { ...@@ -127,9 +127,10 @@ uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l) {
#include <stdio.h> #include <stdio.h>
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
int crc64Test(int argc, char *argv[]) { int crc64Test(int argc, char *argv[], int accurate) {
UNUSED(argc); UNUSED(argc);
UNUSED(argv); UNUSED(argv);
UNUSED(accurate);
crc64_init(); crc64_init();
printf("[calcula]: e9c6d914c4b8d9ca == %016" PRIx64 "\n", printf("[calcula]: e9c6d914c4b8d9ca == %016" PRIx64 "\n",
(uint64_t)_crc64(0, "123456789", 9)); (uint64_t)_crc64(0, "123456789", 9));
......
...@@ -7,7 +7,7 @@ void crc64_init(void); ...@@ -7,7 +7,7 @@ void crc64_init(void);
uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l); uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l);
#ifdef REDIS_TEST #ifdef REDIS_TEST
int crc64Test(int argc, char *argv[]); int crc64Test(int argc, char *argv[], int accurate);
#endif #endif
#endif #endif
...@@ -45,11 +45,7 @@ ...@@ -45,11 +45,7 @@
#include "dict.h" #include "dict.h"
#include "zmalloc.h" #include "zmalloc.h"
#ifndef DICT_BENCHMARK_MAIN
#include "redisassert.h" #include "redisassert.h"
#else
#include <assert.h>
#endif
/* Using dictEnableResize() / dictDisableResize() we make possible to /* Using dictEnableResize() / dictDisableResize() we make possible to
* enable/disable resizing of the hash table as needed. This is very important * enable/disable resizing of the hash table as needed. This is very important
...@@ -1175,20 +1171,18 @@ void dictGetStats(char *buf, size_t bufsize, dict *d) { ...@@ -1175,20 +1171,18 @@ void dictGetStats(char *buf, size_t bufsize, dict *d) {
/* ------------------------------- Benchmark ---------------------------------*/ /* ------------------------------- Benchmark ---------------------------------*/
#ifdef DICT_BENCHMARK_MAIN #ifdef REDIS_TEST
#include "sds.h"
uint64_t hashCallback(const void *key) { uint64_t hashCallback(const void *key) {
return dictGenHashFunction((unsigned char*)key, sdslen((char*)key)); return dictGenHashFunction((unsigned char*)key, strlen((char*)key));
} }
int compareCallback(void *privdata, const void *key1, const void *key2) { int compareCallback(void *privdata, const void *key1, const void *key2) {
int l1,l2; int l1,l2;
DICT_NOTUSED(privdata); DICT_NOTUSED(privdata);
l1 = sdslen((sds)key1); l1 = strlen((char*)key1);
l2 = sdslen((sds)key2); l2 = strlen((char*)key2);
if (l1 != l2) return 0; if (l1 != l2) return 0;
return memcmp(key1, key2, l1) == 0; return memcmp(key1, key2, l1) == 0;
} }
...@@ -1196,7 +1190,19 @@ int compareCallback(void *privdata, const void *key1, const void *key2) { ...@@ -1196,7 +1190,19 @@ int compareCallback(void *privdata, const void *key1, const void *key2) {
void freeCallback(void *privdata, void *val) { void freeCallback(void *privdata, void *val) {
DICT_NOTUSED(privdata); DICT_NOTUSED(privdata);
sdsfree(val); zfree(val);
}
char *stringFromLongLong(long long value) {
char buf[32];
int len;
char *s;
len = sprintf(buf,"%lld",value);
s = zmalloc(len+1);
memcpy(s, buf, len);
s[len] = '\0';
return s;
} }
dictType BenchmarkDictType = { dictType BenchmarkDictType = {
...@@ -1215,22 +1221,26 @@ dictType BenchmarkDictType = { ...@@ -1215,22 +1221,26 @@ dictType BenchmarkDictType = {
printf(msg ": %ld items in %lld ms\n", count, elapsed); \ printf(msg ": %ld items in %lld ms\n", count, elapsed); \
} while(0) } while(0)
/* dict-benchmark [count] */ /* ./redis-server test dict [<count> | --accurate] */
int main(int argc, char **argv) { int dictTest(int argc, char **argv, int accurate) {
long j; long j;
long long start, elapsed; long long start, elapsed;
dict *dict = dictCreate(&BenchmarkDictType,NULL); dict *dict = dictCreate(&BenchmarkDictType,NULL);
long count = 0; long count = 0;
if (argc == 2) { if (argc == 4) {
count = strtol(argv[1],NULL,10); if (accurate) {
count = 5000000;
} else {
count = strtol(argv[3],NULL,10);
}
} else { } else {
count = 5000000; count = 5000;
} }
start_benchmark(); start_benchmark();
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
int retval = dictAdd(dict,sdsfromlonglong(j),(void*)j); int retval = dictAdd(dict,stringFromLongLong(j),(void*)j);
assert(retval == DICT_OK); assert(retval == DICT_OK);
} }
end_benchmark("Inserting"); end_benchmark("Inserting");
...@@ -1243,28 +1253,28 @@ int main(int argc, char **argv) { ...@@ -1243,28 +1253,28 @@ int main(int argc, char **argv) {
start_benchmark(); start_benchmark();
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
sds key = sdsfromlonglong(j); char *key = stringFromLongLong(j);
dictEntry *de = dictFind(dict,key); dictEntry *de = dictFind(dict,key);
assert(de != NULL); assert(de != NULL);
sdsfree(key); zfree(key);
} }
end_benchmark("Linear access of existing elements"); end_benchmark("Linear access of existing elements");
start_benchmark(); start_benchmark();
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
sds key = sdsfromlonglong(j); char *key = stringFromLongLong(j);
dictEntry *de = dictFind(dict,key); dictEntry *de = dictFind(dict,key);
assert(de != NULL); assert(de != NULL);
sdsfree(key); zfree(key);
} }
end_benchmark("Linear access of existing elements (2nd round)"); end_benchmark("Linear access of existing elements (2nd round)");
start_benchmark(); start_benchmark();
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
sds key = sdsfromlonglong(rand() % count); char *key = stringFromLongLong(rand() % count);
dictEntry *de = dictFind(dict,key); dictEntry *de = dictFind(dict,key);
assert(de != NULL); assert(de != NULL);
sdsfree(key); zfree(key);
} }
end_benchmark("Random access of existing elements"); end_benchmark("Random access of existing elements");
...@@ -1277,17 +1287,17 @@ int main(int argc, char **argv) { ...@@ -1277,17 +1287,17 @@ int main(int argc, char **argv) {
start_benchmark(); start_benchmark();
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
sds key = sdsfromlonglong(rand() % count); char *key = stringFromLongLong(rand() % count);
key[0] = 'X'; key[0] = 'X';
dictEntry *de = dictFind(dict,key); dictEntry *de = dictFind(dict,key);
assert(de == NULL); assert(de == NULL);
sdsfree(key); zfree(key);
} }
end_benchmark("Accessing missing"); end_benchmark("Accessing missing");
start_benchmark(); start_benchmark();
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
sds key = sdsfromlonglong(j); char *key = stringFromLongLong(j);
int retval = dictDelete(dict,key); int retval = dictDelete(dict,key);
assert(retval == DICT_OK); assert(retval == DICT_OK);
key[0] += 17; /* Change first number to letter. */ key[0] += 17; /* Change first number to letter. */
...@@ -1295,5 +1305,7 @@ int main(int argc, char **argv) { ...@@ -1295,5 +1305,7 @@ int main(int argc, char **argv) {
assert(retval == DICT_OK); assert(retval == DICT_OK);
} }
end_benchmark("Removing and adding"); end_benchmark("Removing and adding");
dictRelease(dict);
return 0;
} }
#endif #endif
...@@ -201,4 +201,8 @@ extern dictType dictTypeHeapStringCopyKey; ...@@ -201,4 +201,8 @@ extern dictType dictTypeHeapStringCopyKey;
extern dictType dictTypeHeapStrings; extern dictType dictTypeHeapStrings;
extern dictType dictTypeHeapStringCopyKeyValue; extern dictType dictTypeHeapStringCopyKeyValue;
#ifdef REDIS_TEST
int dictTest(int argc, char *argv[], int accurate);
#endif
#endif /* __DICT_H */ #endif /* __DICT_H */
...@@ -105,11 +105,12 @@ uint64_t intrev64(uint64_t v) { ...@@ -105,11 +105,12 @@ uint64_t intrev64(uint64_t v) {
#include <stdio.h> #include <stdio.h>
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
int endianconvTest(int argc, char *argv[]) { int endianconvTest(int argc, char *argv[], int accurate) {
char buf[32]; char buf[32];
UNUSED(argc); UNUSED(argc);
UNUSED(argv); UNUSED(argv);
UNUSED(accurate);
sprintf(buf,"ciaoroma"); sprintf(buf,"ciaoroma");
memrev16(buf); memrev16(buf);
......
...@@ -72,7 +72,7 @@ uint64_t intrev64(uint64_t v); ...@@ -72,7 +72,7 @@ uint64_t intrev64(uint64_t v);
#endif #endif
#ifdef REDIS_TEST #ifdef REDIS_TEST
int endianconvTest(int argc, char *argv[]); int endianconvTest(int argc, char *argv[], int accurate);
#endif #endif
#endif #endif
...@@ -392,7 +392,7 @@ static void checkConsistency(intset *is) { ...@@ -392,7 +392,7 @@ static void checkConsistency(intset *is) {
} }
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
int intsetTest(int argc, char **argv) { int intsetTest(int argc, char **argv, int accurate) {
uint8_t success; uint8_t success;
int i; int i;
intset *is; intset *is;
...@@ -400,6 +400,7 @@ int intsetTest(int argc, char **argv) { ...@@ -400,6 +400,7 @@ int intsetTest(int argc, char **argv) {
UNUSED(argc); UNUSED(argc);
UNUSED(argv); UNUSED(argv);
UNUSED(accurate);
printf("Value encodings: "); { printf("Value encodings: "); {
assert(_intsetValueEncoding(-32768) == INTSET_ENC_INT16); assert(_intsetValueEncoding(-32768) == INTSET_ENC_INT16);
...@@ -424,6 +425,7 @@ int intsetTest(int argc, char **argv) { ...@@ -424,6 +425,7 @@ int intsetTest(int argc, char **argv) {
is = intsetAdd(is,4,&success); assert(success); is = intsetAdd(is,4,&success); assert(success);
is = intsetAdd(is,4,&success); assert(!success); is = intsetAdd(is,4,&success); assert(!success);
ok(); ok();
zfree(is);
} }
printf("Large number of random adds: "); { printf("Large number of random adds: "); {
...@@ -436,6 +438,7 @@ int intsetTest(int argc, char **argv) { ...@@ -436,6 +438,7 @@ int intsetTest(int argc, char **argv) {
assert(intrev32ifbe(is->length) == inserts); assert(intrev32ifbe(is->length) == inserts);
checkConsistency(is); checkConsistency(is);
ok(); ok();
zfree(is);
} }
printf("Upgrade from int16 to int32: "); { printf("Upgrade from int16 to int32: "); {
...@@ -447,6 +450,7 @@ int intsetTest(int argc, char **argv) { ...@@ -447,6 +450,7 @@ int intsetTest(int argc, char **argv) {
assert(intsetFind(is,32)); assert(intsetFind(is,32));
assert(intsetFind(is,65535)); assert(intsetFind(is,65535));
checkConsistency(is); checkConsistency(is);
zfree(is);
is = intsetNew(); is = intsetNew();
is = intsetAdd(is,32,NULL); is = intsetAdd(is,32,NULL);
...@@ -457,6 +461,7 @@ int intsetTest(int argc, char **argv) { ...@@ -457,6 +461,7 @@ int intsetTest(int argc, char **argv) {
assert(intsetFind(is,-65535)); assert(intsetFind(is,-65535));
checkConsistency(is); checkConsistency(is);
ok(); ok();
zfree(is);
} }
printf("Upgrade from int16 to int64: "); { printf("Upgrade from int16 to int64: "); {
...@@ -468,6 +473,7 @@ int intsetTest(int argc, char **argv) { ...@@ -468,6 +473,7 @@ int intsetTest(int argc, char **argv) {
assert(intsetFind(is,32)); assert(intsetFind(is,32));
assert(intsetFind(is,4294967295)); assert(intsetFind(is,4294967295));
checkConsistency(is); checkConsistency(is);
zfree(is);
is = intsetNew(); is = intsetNew();
is = intsetAdd(is,32,NULL); is = intsetAdd(is,32,NULL);
...@@ -478,6 +484,7 @@ int intsetTest(int argc, char **argv) { ...@@ -478,6 +484,7 @@ int intsetTest(int argc, char **argv) {
assert(intsetFind(is,-4294967295)); assert(intsetFind(is,-4294967295));
checkConsistency(is); checkConsistency(is);
ok(); ok();
zfree(is);
} }
printf("Upgrade from int32 to int64: "); { printf("Upgrade from int32 to int64: "); {
...@@ -489,6 +496,7 @@ int intsetTest(int argc, char **argv) { ...@@ -489,6 +496,7 @@ int intsetTest(int argc, char **argv) {
assert(intsetFind(is,65535)); assert(intsetFind(is,65535));
assert(intsetFind(is,4294967295)); assert(intsetFind(is,4294967295));
checkConsistency(is); checkConsistency(is);
zfree(is);
is = intsetNew(); is = intsetNew();
is = intsetAdd(is,65535,NULL); is = intsetAdd(is,65535,NULL);
...@@ -499,6 +507,7 @@ int intsetTest(int argc, char **argv) { ...@@ -499,6 +507,7 @@ int intsetTest(int argc, char **argv) {
assert(intsetFind(is,-4294967295)); assert(intsetFind(is,-4294967295));
checkConsistency(is); checkConsistency(is);
ok(); ok();
zfree(is);
} }
printf("Stress lookups: "); { printf("Stress lookups: "); {
...@@ -512,6 +521,7 @@ int intsetTest(int argc, char **argv) { ...@@ -512,6 +521,7 @@ int intsetTest(int argc, char **argv) {
for (i = 0; i < num; i++) intsetSearch(is,rand() % ((1<<bits)-1),NULL); for (i = 0; i < num; i++) intsetSearch(is,rand() % ((1<<bits)-1),NULL);
printf("%ld lookups, %ld element set, %lldusec\n", printf("%ld lookups, %ld element set, %lldusec\n",
num,size,usec()-start); num,size,usec()-start);
zfree(is);
} }
printf("Stress add+delete: "); { printf("Stress add+delete: "); {
...@@ -528,6 +538,7 @@ int intsetTest(int argc, char **argv) { ...@@ -528,6 +538,7 @@ int intsetTest(int argc, char **argv) {
} }
checkConsistency(is); checkConsistency(is);
ok(); ok();
zfree(is);
} }
return 0; return 0;
......
...@@ -49,7 +49,7 @@ size_t intsetBlobLen(intset *is); ...@@ -49,7 +49,7 @@ size_t intsetBlobLen(intset *is);
int intsetValidateIntegrity(const unsigned char *is, size_t size, int deep); int intsetValidateIntegrity(const unsigned char *is, size_t size, int deep);
#ifdef REDIS_TEST #ifdef REDIS_TEST
int intsetTest(int argc, char *argv[]); int intsetTest(int argc, char *argv[], int accurate);
#endif #endif
#endif // __INTSET_H #endif // __INTSET_H
...@@ -1520,8 +1520,6 @@ void quicklistBookmarksClear(quicklist *ql) { ...@@ -1520,8 +1520,6 @@ void quicklistBookmarksClear(quicklist *ql) {
#define yell(str, ...) printf("ERROR! " str "\n\n", __VA_ARGS__) #define yell(str, ...) printf("ERROR! " str "\n\n", __VA_ARGS__)
#define OK printf("\tOK\n")
#define ERROR \ #define ERROR \
do { \ do { \
printf("\tERROR!\n"); \ printf("\tERROR!\n"); \
...@@ -1641,7 +1639,6 @@ static int _ql_verify(quicklist *ql, uint32_t len, uint32_t count, ...@@ -1641,7 +1639,6 @@ static int _ql_verify(quicklist *ql, uint32_t len, uint32_t count,
} }
if (ql->len == 0 && !errors) { if (ql->len == 0 && !errors) {
OK;
return errors; return errors;
} }
...@@ -1690,8 +1687,6 @@ static int _ql_verify(quicklist *ql, uint32_t len, uint32_t count, ...@@ -1690,8 +1687,6 @@ static int _ql_verify(quicklist *ql, uint32_t len, uint32_t count,
} }
} }
if (!errors)
OK;
return errors; return errors;
} }
...@@ -1703,9 +1698,10 @@ static char *genstr(char *prefix, int i) { ...@@ -1703,9 +1698,10 @@ static char *genstr(char *prefix, int i) {
} }
/* main test, but callable from other files */ /* main test, but callable from other files */
int quicklistTest(int argc, char *argv[]) { int quicklistTest(int argc, char *argv[], int accurate) {
UNUSED(argc); UNUSED(argc);
UNUSED(argv); UNUSED(argv);
UNUSED(accurate);
unsigned int err = 0; unsigned int err = 0;
int optimize_start = int optimize_start =
...@@ -1714,11 +1710,14 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -1714,11 +1710,14 @@ int quicklistTest(int argc, char *argv[]) {
printf("Starting optimization offset at: %d\n", optimize_start); printf("Starting optimization offset at: %d\n", optimize_start);
int options[] = {0, 1, 2, 3, 4, 5, 6, 10}; int options[] = {0, 1, 2, 3, 4, 5, 6, 10};
int fills[] = {-5, -4, -3, -2, -1, 0,
1, 2, 32, 66, 128, 999};
size_t option_count = sizeof(options) / sizeof(*options); size_t option_count = sizeof(options) / sizeof(*options);
int fill_count = (int)(sizeof(fills) / sizeof(*fills));
long long runtime[option_count]; long long runtime[option_count];
for (int _i = 0; _i < (int)option_count; _i++) { for (int _i = 0; _i < (int)option_count; _i++) {
printf("Testing Option %d\n", options[_i]); printf("Testing Compression option %d\n", options[_i]);
long long start = mstime(); long long start = mstime();
TEST("create list") { TEST("create list") {
...@@ -1743,57 +1742,53 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -1743,57 +1742,53 @@ int quicklistTest(int argc, char *argv[]) {
quicklistRelease(ql); quicklistRelease(ql);
} }
for (int f = optimize_start; f < 32; f++) { TEST_DESC("add to tail 5x at compress %d", options[_i]) {
TEST_DESC("add to tail 5x at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
quicklistPushTail(ql, genstr("hello", i), 32); quicklistPushTail(ql, genstr("hello", i), 32);
if (ql->count != 5) if (ql->count != 5)
ERROR; ERROR;
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 1, 5, 5, 5); ql_verify(ql, 1, 5, 5, 5);
quicklistRelease(ql); quicklistRelease(ql);
} }
} }
for (int f = optimize_start; f < 32; f++) { TEST_DESC("add to head 5x at compress %d", options[_i]) {
TEST_DESC("add to head 5x at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
quicklistPushHead(ql, genstr("hello", i), 32); quicklistPushHead(ql, genstr("hello", i), 32);
if (ql->count != 5) if (ql->count != 5)
ERROR; ERROR;
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 1, 5, 5, 5); ql_verify(ql, 1, 5, 5, 5);
quicklistRelease(ql); quicklistRelease(ql);
} }
} }
for (int f = optimize_start; f < 512; f++) { TEST_DESC("add to tail 500x at compress %d", options[_i]) {
TEST_DESC("add to tail 500x at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
for (int i = 0; i < 500; i++) for (int i = 0; i < 500; i++)
quicklistPushTail(ql, genstr("hello", i), 64); quicklistPushTail(ql, genstr("hello", i), 64);
if (ql->count != 500) if (ql->count != 500)
ERROR; ERROR;
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 16, 500, 32, 20); ql_verify(ql, 16, 500, 32, 20);
quicklistRelease(ql); quicklistRelease(ql);
} }
} }
for (int f = optimize_start; f < 512; f++) { TEST_DESC("add to head 500x at compress %d", options[_i]) {
TEST_DESC("add to head 500x at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
for (int i = 0; i < 500; i++) for (int i = 0; i < 500; i++)
quicklistPushHead(ql, genstr("hello", i), 32); quicklistPushHead(ql, genstr("hello", i), 32);
if (ql->count != 500) if (ql->count != 500)
ERROR; ERROR;
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 16, 500, 20, 32); ql_verify(ql, 16, 500, 20, 32);
quicklistRelease(ql); quicklistRelease(ql);
} }
...@@ -1806,9 +1801,9 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -1806,9 +1801,9 @@ int quicklistTest(int argc, char *argv[]) {
quicklistRelease(ql); quicklistRelease(ql);
} }
for (int f = optimize_start; f < 32; f++) { TEST("rotate one val once") {
TEST("rotate one val once") { for (int f = 0; f < fill_count; f++) {
quicklist *ql = quicklistNew(f, options[_i]); quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklistPushHead(ql, "hello", 6); quicklistPushHead(ql, "hello", 6);
quicklistRotate(ql); quicklistRotate(ql);
/* Ignore compression verify because ziplist is /* Ignore compression verify because ziplist is
...@@ -1818,10 +1813,9 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -1818,10 +1813,9 @@ int quicklistTest(int argc, char *argv[]) {
} }
} }
for (int f = optimize_start; f < 3; f++) { TEST_DESC("rotate 500 val 5000 times at compress %d", options[_i]) {
TEST_DESC("rotate 500 val 5000 times at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
quicklistPushHead(ql, "900", 3); quicklistPushHead(ql, "900", 3);
quicklistPushHead(ql, "7000", 4); quicklistPushHead(ql, "7000", 4);
quicklistPushHead(ql, "-1200", 5); quicklistPushHead(ql, "-1200", 5);
...@@ -1833,11 +1827,11 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -1833,11 +1827,11 @@ int quicklistTest(int argc, char *argv[]) {
ql_info(ql); ql_info(ql);
quicklistRotate(ql); quicklistRotate(ql);
} }
if (f == 1) if (fills[f] == 1)
ql_verify(ql, 504, 504, 1, 1); ql_verify(ql, 504, 504, 1, 1);
else if (f == 2) else if (fills[f] == 2)
ql_verify(ql, 252, 504, 2, 2); ql_verify(ql, 252, 504, 2, 2);
else if (f == 32) else if (fills[f] == 32)
ql_verify(ql, 16, 504, 32, 24); ql_verify(ql, 16, 504, 32, 24);
quicklistRelease(ql); quicklistRelease(ql);
} }
...@@ -2014,11 +2008,10 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2014,11 +2008,10 @@ int quicklistTest(int argc, char *argv[]) {
quicklistRelease(ql); quicklistRelease(ql);
} }
for (int f = optimize_start; f < 12; f++) { TEST_DESC("insert once in elements while iterating at compress %d",
TEST_DESC("insert once in elements while iterating at fill %d at " options[_i]) {
"compress %d\n", for (int f = 0; f < fill_count; f++) {
f, options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
quicklistPushTail(ql, "abc", 3); quicklistPushTail(ql, "abc", 3);
quicklistSetFill(ql, 1); quicklistSetFill(ql, 1);
quicklistPushTail(ql, "def", 3); /* force to unique node */ quicklistPushTail(ql, "def", 3); /* force to unique node */
...@@ -2070,12 +2063,10 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2070,12 +2063,10 @@ int quicklistTest(int argc, char *argv[]) {
} }
} }
for (int f = optimize_start; f < 1024; f++) { TEST_DESC("insert [before] 250 new in middle of 500 elements at compress %d",
TEST_DESC( options[_i]) {
"insert [before] 250 new in middle of 500 elements at fill" for (int f = 0; f < fill_count; f++) {
" %d at compress %d", quicklist *ql = quicklistNew(fills[f], options[_i]);
f, options[_i]) {
quicklist *ql = quicklistNew(f, options[_i]);
for (int i = 0; i < 500; i++) for (int i = 0; i < 500; i++)
quicklistPushTail(ql, genstr("hello", i), 32); quicklistPushTail(ql, genstr("hello", i), 32);
for (int i = 0; i < 250; i++) { for (int i = 0; i < 250; i++) {
...@@ -2083,17 +2074,16 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2083,17 +2074,16 @@ int quicklistTest(int argc, char *argv[]) {
quicklistIndex(ql, 250, &entry); quicklistIndex(ql, 250, &entry);
quicklistInsertBefore(ql, &entry, genstr("abc", i), 32); quicklistInsertBefore(ql, &entry, genstr("abc", i), 32);
} }
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 25, 750, 32, 20); ql_verify(ql, 25, 750, 32, 20);
quicklistRelease(ql); quicklistRelease(ql);
} }
} }
for (int f = optimize_start; f < 1024; f++) { TEST_DESC("insert [after] 250 new in middle of 500 elements at compress %d",
TEST_DESC("insert [after] 250 new in middle of 500 elements at " options[_i]) {
"fill %d at compress %d", for (int f = 0; f < fill_count; f++) {
f, options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
for (int i = 0; i < 500; i++) for (int i = 0; i < 500; i++)
quicklistPushHead(ql, genstr("hello", i), 32); quicklistPushHead(ql, genstr("hello", i), 32);
for (int i = 0; i < 250; i++) { for (int i = 0; i < 250; i++) {
...@@ -2105,7 +2095,7 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2105,7 +2095,7 @@ int quicklistTest(int argc, char *argv[]) {
if (ql->count != 750) if (ql->count != 750)
ERR("List size not 750, but rather %ld", ql->count); ERR("List size not 750, but rather %ld", ql->count);
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 26, 750, 20, 32); ql_verify(ql, 26, 750, 20, 32);
quicklistRelease(ql); quicklistRelease(ql);
} }
...@@ -2143,70 +2133,58 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2143,70 +2133,58 @@ int quicklistTest(int argc, char *argv[]) {
quicklistRelease(copy); quicklistRelease(copy);
} }
for (int f = optimize_start; f < 512; f++) { for (int f = 0; f < fill_count; f++) {
TEST_DESC("index 1,200 from 500 list at fill %d at compress %d", f, TEST_DESC("index 1,200 from 500 list at fill %d at compress %d", f,
options[_i]) { options[_i]) {
quicklist *ql = quicklistNew(f, options[_i]); quicklist *ql = quicklistNew(fills[f], options[_i]);
for (int i = 0; i < 500; i++) for (int i = 0; i < 500; i++)
quicklistPushTail(ql, genstr("hello", i + 1), 32); quicklistPushTail(ql, genstr("hello", i + 1), 32);
quicklistEntry entry; quicklistEntry entry;
quicklistIndex(ql, 1, &entry); quicklistIndex(ql, 1, &entry);
if (!strcmp((char *)entry.value, "hello2")) if (strcmp((char *)entry.value, "hello2") != 0)
OK;
else
ERR("Value: %s", entry.value); ERR("Value: %s", entry.value);
quicklistIndex(ql, 200, &entry); quicklistIndex(ql, 200, &entry);
if (!strcmp((char *)entry.value, "hello201")) if (strcmp((char *)entry.value, "hello201") != 0)
OK;
else
ERR("Value: %s", entry.value); ERR("Value: %s", entry.value);
quicklistRelease(ql); quicklistRelease(ql);
} }
TEST_DESC("index -1,-2 from 500 list at fill %d at compress %d", f, TEST_DESC("index -1,-2 from 500 list at fill %d at compress %d",
options[_i]) { fills[f], options[_i]) {
quicklist *ql = quicklistNew(f, options[_i]); quicklist *ql = quicklistNew(fills[f], options[_i]);
for (int i = 0; i < 500; i++) for (int i = 0; i < 500; i++)
quicklistPushTail(ql, genstr("hello", i + 1), 32); quicklistPushTail(ql, genstr("hello", i + 1), 32);
quicklistEntry entry; quicklistEntry entry;
quicklistIndex(ql, -1, &entry); quicklistIndex(ql, -1, &entry);
if (!strcmp((char *)entry.value, "hello500")) if (strcmp((char *)entry.value, "hello500") != 0)
OK;
else
ERR("Value: %s", entry.value); ERR("Value: %s", entry.value);
quicklistIndex(ql, -2, &entry); quicklistIndex(ql, -2, &entry);
if (!strcmp((char *)entry.value, "hello499")) if (strcmp((char *)entry.value, "hello499") != 0)
OK;
else
ERR("Value: %s", entry.value); ERR("Value: %s", entry.value);
quicklistRelease(ql); quicklistRelease(ql);
} }
TEST_DESC("index -100 from 500 list at fill %d at compress %d", f, TEST_DESC("index -100 from 500 list at fill %d at compress %d",
options[_i]) { fills[f], options[_i]) {
quicklist *ql = quicklistNew(f, options[_i]); quicklist *ql = quicklistNew(fills[f], options[_i]);
for (int i = 0; i < 500; i++) for (int i = 0; i < 500; i++)
quicklistPushTail(ql, genstr("hello", i + 1), 32); quicklistPushTail(ql, genstr("hello", i + 1), 32);
quicklistEntry entry; quicklistEntry entry;
quicklistIndex(ql, -100, &entry); quicklistIndex(ql, -100, &entry);
if (!strcmp((char *)entry.value, "hello401")) if (strcmp((char *)entry.value, "hello401") != 0)
OK;
else
ERR("Value: %s", entry.value); ERR("Value: %s", entry.value);
quicklistRelease(ql); quicklistRelease(ql);
} }
TEST_DESC("index too big +1 from 50 list at fill %d at compress %d", TEST_DESC("index too big +1 from 50 list at fill %d at compress %d",
f, options[_i]) { fills[f], options[_i]) {
quicklist *ql = quicklistNew(f, options[_i]); quicklist *ql = quicklistNew(fills[f], options[_i]);
for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
quicklistPushTail(ql, genstr("hello", i + 1), 32); quicklistPushTail(ql, genstr("hello", i + 1), 32);
quicklistEntry entry; quicklistEntry entry;
if (quicklistIndex(ql, 50, &entry)) if (quicklistIndex(ql, 50, &entry))
ERR("Index found at 50 with 50 list: %.*s", entry.sz, ERR("Index found at 50 with 50 list: %.*s", entry.sz,
entry.value); entry.value);
else
OK;
quicklistRelease(ql); quicklistRelease(ql);
} }
} }
...@@ -2378,12 +2356,11 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2378,12 +2356,11 @@ int quicklistTest(int argc, char *argv[]) {
quicklistReplaceAtIndex(ql, 1, "foo", 3); quicklistReplaceAtIndex(ql, 1, "foo", 3);
quicklistReplaceAtIndex(ql, -1, "bar", 3); quicklistReplaceAtIndex(ql, -1, "bar", 3);
quicklistRelease(ql); quicklistRelease(ql);
OK;
} }
for (int f = optimize_start; f < 16; f++) { TEST_DESC("lrem test at compress %d", options[_i]) {
TEST_DESC("lrem test at fill %d at compress %d", f, options[_i]) { for (int f = 0; f < fill_count; f++) {
quicklist *ql = quicklistNew(f, options[_i]); quicklist *ql = quicklistNew(fills[f], options[_i]);
char *words[] = {"abc", "foo", "bar", "foobar", "foobared", char *words[] = {"abc", "foo", "bar", "foobar", "foobared",
"zap", "bar", "test", "foo"}; "zap", "bar", "test", "foo"};
char *result[] = {"abc", "foo", "foobar", "foobared", char *result[] = {"abc", "foo", "foobar", "foobared",
...@@ -2408,14 +2385,12 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2408,14 +2385,12 @@ int quicklistTest(int argc, char *argv[]) {
/* check result of lrem 0 bar */ /* check result of lrem 0 bar */
iter = quicklistGetIterator(ql, AL_START_HEAD); iter = quicklistGetIterator(ql, AL_START_HEAD);
i = 0; i = 0;
int ok = 1;
while (quicklistNext(iter, &entry)) { while (quicklistNext(iter, &entry)) {
/* Result must be: abc, foo, foobar, foobared, zap, test, /* Result must be: abc, foo, foobar, foobared, zap, test,
* foo */ * foo */
if (strncmp((char *)entry.value, result[i], entry.sz)) { if (strncmp((char *)entry.value, result[i], entry.sz)) {
ERR("No match at position %d, got %.*s instead of %s", ERR("No match at position %d, got %.*s instead of %s",
i, entry.sz, entry.value, result[i]); i, entry.sz, entry.value, result[i]);
ok = 0;
} }
i++; i++;
} }
...@@ -2452,23 +2427,18 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2452,23 +2427,18 @@ int quicklistTest(int argc, char *argv[]) {
entry.sz)) { entry.sz)) {
ERR("No match at position %d, got %.*s instead of %s", ERR("No match at position %d, got %.*s instead of %s",
i, entry.sz, entry.value, resultB[resB - 1 - i]); i, entry.sz, entry.value, resultB[resB - 1 - i]);
ok = 0;
} }
i++; i++;
} }
quicklistReleaseIterator(iter); quicklistReleaseIterator(iter);
/* final result of all tests */
if (ok)
OK;
quicklistRelease(ql); quicklistRelease(ql);
} }
} }
for (int f = optimize_start; f < 16; f++) { TEST_DESC("iterate reverse + delete at compress %d", options[_i]) {
TEST_DESC("iterate reverse + delete at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
quicklistPushTail(ql, "abc", 3); quicklistPushTail(ql, "abc", 3);
quicklistPushTail(ql, "def", 3); quicklistPushTail(ql, "def", 3);
quicklistPushTail(ql, "hij", 3); quicklistPushTail(ql, "hij", 3);
...@@ -2505,10 +2475,9 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2505,10 +2475,9 @@ int quicklistTest(int argc, char *argv[]) {
} }
} }
for (int f = optimize_start; f < 800; f++) { TEST_DESC("iterator at index test at compress %d", options[_i]) {
TEST_DESC("iterator at index test at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
char num[32]; char num[32];
long long nums[5000]; long long nums[5000];
for (int i = 0; i < 760; i++) { for (int i = 0; i < 760; i++) {
...@@ -2532,10 +2501,9 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2532,10 +2501,9 @@ int quicklistTest(int argc, char *argv[]) {
} }
} }
for (int f = optimize_start; f < 40; f++) { TEST_DESC("ltrim test A at compress %d", options[_i]) {
TEST_DESC("ltrim test A at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
char num[32]; char num[32];
long long nums[5000]; long long nums[5000];
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
...@@ -2543,7 +2511,7 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2543,7 +2511,7 @@ int quicklistTest(int argc, char *argv[]) {
int sz = ll2string(num, sizeof(num), nums[i]); int sz = ll2string(num, sizeof(num), nums[i]);
quicklistPushTail(ql, num, sz); quicklistPushTail(ql, num, sz);
} }
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 1, 32, 32, 32); ql_verify(ql, 1, 32, 32, 32);
/* ltrim 25 53 (keep [25,32] inclusive = 7 remaining) */ /* ltrim 25 53 (keep [25,32] inclusive = 7 remaining) */
quicklistDelRange(ql, 0, 25); quicklistDelRange(ql, 0, 25);
...@@ -2556,18 +2524,17 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2556,18 +2524,17 @@ int quicklistTest(int argc, char *argv[]) {
"%lld", "%lld",
entry.longval, nums[25 + i]); entry.longval, nums[25 + i]);
} }
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 1, 7, 7, 7); ql_verify(ql, 1, 7, 7, 7);
quicklistRelease(ql); quicklistRelease(ql);
} }
} }
for (int f = optimize_start; f < 40; f++) { TEST_DESC("ltrim test B at compress %d", options[_i]) {
TEST_DESC("ltrim test B at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) {
/* Force-disable compression because our 33 sequential /* Force-disable compression because our 33 sequential
* integers don't compress and the check always fails. */ * integers don't compress and the check always fails. */
quicklist *ql = quicklistNew(f, QUICKLIST_NOCOMPRESS); quicklist *ql = quicklistNew(fills[f], QUICKLIST_NOCOMPRESS);
char num[32]; char num[32];
long long nums[5000]; long long nums[5000];
for (int i = 0; i < 33; i++) { for (int i = 0; i < 33; i++) {
...@@ -2575,24 +2542,20 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2575,24 +2542,20 @@ int quicklistTest(int argc, char *argv[]) {
int sz = ll2string(num, sizeof(num), nums[i]); int sz = ll2string(num, sizeof(num), nums[i]);
quicklistPushTail(ql, num, sz); quicklistPushTail(ql, num, sz);
} }
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 2, 33, 32, 1); ql_verify(ql, 2, 33, 32, 1);
/* ltrim 5 16 (keep [5,16] inclusive = 12 remaining) */ /* ltrim 5 16 (keep [5,16] inclusive = 12 remaining) */
quicklistDelRange(ql, 0, 5); quicklistDelRange(ql, 0, 5);
quicklistDelRange(ql, -16, 16); quicklistDelRange(ql, -16, 16);
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 1, 12, 12, 12); ql_verify(ql, 1, 12, 12, 12);
quicklistEntry entry; quicklistEntry entry;
quicklistIndex(ql, 0, &entry); quicklistIndex(ql, 0, &entry);
if (entry.longval != 5) if (entry.longval != 5)
ERR("A: longval not 5, but %lld", entry.longval); ERR("A: longval not 5, but %lld", entry.longval);
else
OK;
quicklistIndex(ql, -1, &entry); quicklistIndex(ql, -1, &entry);
if (entry.longval != 16) if (entry.longval != 16)
ERR("B! got instead: %lld", entry.longval); ERR("B! got instead: %lld", entry.longval);
else
OK;
quicklistPushTail(ql, "bobobob", 7); quicklistPushTail(ql, "bobobob", 7);
quicklistIndex(ql, -1, &entry); quicklistIndex(ql, -1, &entry);
if (strncmp((char *)entry.value, "bobobob", 7)) if (strncmp((char *)entry.value, "bobobob", 7))
...@@ -2609,10 +2572,9 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2609,10 +2572,9 @@ int quicklistTest(int argc, char *argv[]) {
} }
} }
for (int f = optimize_start; f < 40; f++) { TEST_DESC("ltrim test C at compress %d", options[_i]) {
TEST_DESC("ltrim test C at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
char num[32]; char num[32];
long long nums[5000]; long long nums[5000];
for (int i = 0; i < 33; i++) { for (int i = 0; i < 33; i++) {
...@@ -2620,28 +2582,25 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2620,28 +2582,25 @@ int quicklistTest(int argc, char *argv[]) {
int sz = ll2string(num, sizeof(num), nums[i]); int sz = ll2string(num, sizeof(num), nums[i]);
quicklistPushTail(ql, num, sz); quicklistPushTail(ql, num, sz);
} }
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 2, 33, 32, 1); ql_verify(ql, 2, 33, 32, 1);
/* ltrim 3 3 (keep [3,3] inclusive = 1 remaining) */ /* ltrim 3 3 (keep [3,3] inclusive = 1 remaining) */
quicklistDelRange(ql, 0, 3); quicklistDelRange(ql, 0, 3);
quicklistDelRange(ql, -29, quicklistDelRange(ql, -29,
4000); /* make sure not loop forever */ 4000); /* make sure not loop forever */
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 1, 1, 1, 1); ql_verify(ql, 1, 1, 1, 1);
quicklistEntry entry; quicklistEntry entry;
quicklistIndex(ql, 0, &entry); quicklistIndex(ql, 0, &entry);
if (entry.longval != -5157318210846258173) if (entry.longval != -5157318210846258173)
ERROR; ERROR;
else
OK;
quicklistRelease(ql); quicklistRelease(ql);
} }
} }
for (int f = optimize_start; f < 40; f++) { TEST_DESC("ltrim test D at compress %d", options[_i]) {
TEST_DESC("ltrim test D at fill %d at compress %d", f, for (int f = 0; f < fill_count; f++) {
options[_i]) { quicklist *ql = quicklistNew(fills[f], options[_i]);
quicklist *ql = quicklistNew(f, options[_i]);
char num[32]; char num[32];
long long nums[5000]; long long nums[5000];
for (int i = 0; i < 33; i++) { for (int i = 0; i < 33; i++) {
...@@ -2649,7 +2608,7 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2649,7 +2608,7 @@ int quicklistTest(int argc, char *argv[]) {
int sz = ll2string(num, sizeof(num), nums[i]); int sz = ll2string(num, sizeof(num), nums[i]);
quicklistPushTail(ql, num, sz); quicklistPushTail(ql, num, sz);
} }
if (f == 32) if (fills[f] == 32)
ql_verify(ql, 2, 33, 32, 1); ql_verify(ql, 2, 33, 32, 1);
quicklistDelRange(ql, -12, 3); quicklistDelRange(ql, -12, 3);
if (ql->count != 30) if (ql->count != 30)
...@@ -2659,9 +2618,8 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2659,9 +2618,8 @@ int quicklistTest(int argc, char *argv[]) {
} }
} }
for (int f = optimize_start; f < 72; f++) { TEST_DESC("create quicklist from ziplist at compress %d", options[_i]) {
TEST_DESC("create quicklist from ziplist at fill %d at compress %d", for (int f = 0; f < fill_count; f++) {
f, options[_i]) {
unsigned char *zl = ziplistNew(); unsigned char *zl = ziplistNew();
long long nums[64]; long long nums[64];
char num[64]; char num[64];
...@@ -2675,12 +2633,12 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2675,12 +2633,12 @@ int quicklistTest(int argc, char *argv[]) {
zl = ziplistPush(zl, (unsigned char *)genstr("hello", i), zl = ziplistPush(zl, (unsigned char *)genstr("hello", i),
32, ZIPLIST_TAIL); 32, ZIPLIST_TAIL);
} }
quicklist *ql = quicklistCreateFromZiplist(f, options[_i], zl); quicklist *ql = quicklistCreateFromZiplist(fills[f], options[_i], zl);
if (f == 1) if (fills[f] == 1)
ql_verify(ql, 66, 66, 1, 1); ql_verify(ql, 66, 66, 1, 1);
else if (f == 32) else if (fills[f] == 32)
ql_verify(ql, 3, 66, 32, 2); ql_verify(ql, 3, 66, 32, 2);
else if (f == 66) else if (fills[f] == 66)
ql_verify(ql, 1, 66, 66, 66); ql_verify(ql, 1, 66, 66, 66);
quicklistRelease(ql); quicklistRelease(ql);
} }
...@@ -2693,16 +2651,14 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2693,16 +2651,14 @@ int quicklistTest(int argc, char *argv[]) {
/* Run a longer test of compression depth outside of primary test loop. */ /* Run a longer test of compression depth outside of primary test loop. */
int list_sizes[] = {250, 251, 500, 999, 1000}; int list_sizes[] = {250, 251, 500, 999, 1000};
long long start = mstime(); long long start = mstime();
for (int list = 0; list < (int)(sizeof(list_sizes) / sizeof(*list_sizes)); int list_count = accurate ? (int)(sizeof(list_sizes) / sizeof(*list_sizes)) : 1;
list++) { for (int list = 0; list < list_count; list++) {
for (int f = optimize_start; f < 128; f++) { TEST_DESC("verify specific compression of interior nodes with %d list ",
for (int depth = 1; depth < 40; depth++) { list_sizes[list]) {
/* skip over many redundant test cases */ for (int f = 0; f < fill_count; f++) {
TEST_DESC("verify specific compression of interior nodes with " for (int depth = 1; depth < 40; depth++) {
"%d list " /* skip over many redundant test cases */
"at fill %d at compress %d", quicklist *ql = quicklistNew(fills[f], depth);
list_sizes[list], f, depth) {
quicklist *ql = quicklistNew(f, depth);
for (int i = 0; i < list_sizes[list]; i++) { for (int i = 0; i < list_sizes[list]; i++) {
quicklistPushTail(ql, genstr("hello TAIL", i + 1), 64); quicklistPushTail(ql, genstr("hello TAIL", i + 1), 64);
quicklistPushHead(ql, genstr("hello HEAD", i + 1), 64); quicklistPushHead(ql, genstr("hello HEAD", i + 1), 64);
...@@ -2712,8 +2668,11 @@ int quicklistTest(int argc, char *argv[]) { ...@@ -2712,8 +2668,11 @@ int quicklistTest(int argc, char *argv[]) {
/* test remove node */ /* test remove node */
if (step == 1) { if (step == 1) {
for (int i = 0; i < list_sizes[list] / 2; i++) { for (int i = 0; i < list_sizes[list] / 2; i++) {
quicklistPop(ql, QUICKLIST_HEAD, NULL, NULL, NULL); unsigned char *data;
quicklistPop(ql, QUICKLIST_TAIL, NULL, NULL, NULL); quicklistPop(ql, QUICKLIST_HEAD, &data, NULL, NULL);
zfree(data);
quicklistPop(ql, QUICKLIST_TAIL, &data, NULL, NULL);
zfree(data);
} }
} }
quicklistNode *node = ql->head; quicklistNode *node = ql->head;
......
...@@ -199,7 +199,7 @@ quicklistNode *quicklistBookmarkFind(quicklist *ql, const char *name); ...@@ -199,7 +199,7 @@ quicklistNode *quicklistBookmarkFind(quicklist *ql, const char *name);
void quicklistBookmarksClear(quicklist *ql); void quicklistBookmarksClear(quicklist *ql);
#ifdef REDIS_TEST #ifdef REDIS_TEST
int quicklistTest(int argc, char *argv[]); int quicklistTest(int argc, char *argv[], int accurate);
#endif #endif
/* Directions for iterators */ /* Directions for iterators */
......
...@@ -1234,9 +1234,10 @@ static sds sdsTestTemplateCallback(sds varname, void *arg) { ...@@ -1234,9 +1234,10 @@ static sds sdsTestTemplateCallback(sds varname, void *arg) {
else return NULL; else return NULL;
} }
int sdsTest(int argc, char **argv) { int sdsTest(int argc, char **argv, int accurate) {
UNUSED(argc); UNUSED(argc);
UNUSED(argv); UNUSED(argv);
UNUSED(accurate);
{ {
sds x = sdsnew("foo"), y; sds x = sdsnew("foo"), y;
......
...@@ -277,7 +277,7 @@ void *sds_realloc(void *ptr, size_t size); ...@@ -277,7 +277,7 @@ void *sds_realloc(void *ptr, size_t size);
void sds_free(void *ptr); void sds_free(void *ptr);
#ifdef REDIS_TEST #ifdef REDIS_TEST
int sdsTest(int argc, char *argv[]); int sdsTest(int argc, char *argv[], int accurate);
#endif #endif
#endif #endif
...@@ -6030,36 +6030,78 @@ int iAmMaster(void) { ...@@ -6030,36 +6030,78 @@ int iAmMaster(void) {
(server.cluster_enabled && nodeIsMaster(server.cluster->myself))); (server.cluster_enabled && nodeIsMaster(server.cluster->myself)));
} }
#ifdef REDIS_TEST
typedef int redisTestProc(int argc, char **argv, int accurate);
struct redisTest {
char *name;
redisTestProc *proc;
int failed;
} redisTests[] = {
{"ziplist", ziplistTest},
{"quicklist", quicklistTest},
{"intset", intsetTest},
{"zipmap", zipmapTest},
{"sha1test", sha1Test},
{"util", utilTest},
{"endianconv", endianconvTest},
{"crc64", crc64Test},
{"zmalloc", zmalloc_test},
{"sds", sdsTest},
{"dict", dictTest}
};
redisTestProc *getTestProcByName(const char *name) {
int numtests = sizeof(redisTests)/sizeof(struct redisTest);
for (int j = 0; j < numtests; j++) {
if (!strcasecmp(name,redisTests[j].name)) {
return redisTests[j].proc;
}
}
return NULL;
}
#endif
int main(int argc, char **argv) { int main(int argc, char **argv) {
struct timeval tv; struct timeval tv;
int j; int j;
char config_from_stdin = 0; char config_from_stdin = 0;
#ifdef REDIS_TEST #ifdef REDIS_TEST
if (argc == 3 && !strcasecmp(argv[1], "test")) { if (argc >= 3 && !strcasecmp(argv[1], "test")) {
if (!strcasecmp(argv[2], "ziplist")) { int accurate = 0;
return ziplistTest(argc, argv); for (j = 3; j < argc; j++) {
} else if (!strcasecmp(argv[2], "quicklist")) { if (!strcasecmp(argv[j], "--accurate")) {
quicklistTest(argc, argv); accurate = 1;
} else if (!strcasecmp(argv[2], "intset")) { }
return intsetTest(argc, argv);
} else if (!strcasecmp(argv[2], "zipmap")) {
return zipmapTest(argc, argv);
} else if (!strcasecmp(argv[2], "sha1test")) {
return sha1Test(argc, argv);
} else if (!strcasecmp(argv[2], "util")) {
return utilTest(argc, argv);
} else if (!strcasecmp(argv[2], "endianconv")) {
return endianconvTest(argc, argv);
} else if (!strcasecmp(argv[2], "crc64")) {
return crc64Test(argc, argv);
} else if (!strcasecmp(argv[2], "zmalloc")) {
return zmalloc_test(argc, argv);
} else if (!strcasecmp(argv[2], "sds")) {
return sdsTest(argc, argv);
} }
return -1; /* test not found */ if (!strcasecmp(argv[2], "all")) {
int numtests = sizeof(redisTests)/sizeof(struct redisTest);
for (j = 0; j < numtests; j++) {
redisTests[j].failed = (redisTests[j].proc(argc,argv,accurate) != 0);
}
/* Report tests result */
int failed_num = 0;
for (j = 0; j < numtests; j++) {
if (redisTests[j].failed) {
failed_num++;
printf("[failed] Test - %s\n", redisTests[j].name);
} else {
printf("[ok] Test - %s\n", redisTests[j].name);
}
}
printf("%d tests, %d passed, %d failed\n", numtests,
numtests-failed_num, failed_num);
return failed_num == 0 ? 0 : 1;
} else {
redisTestProc *proc = getTestProcByName(argv[2]);
if (!proc) return -1; /* test not found */
return proc(argc,argv,accurate);
}
return 0;
} }
#endif #endif
......
...@@ -201,7 +201,7 @@ void SHA1Final(unsigned char digest[20], SHA1_CTX* context) ...@@ -201,7 +201,7 @@ void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
#define BUFSIZE 4096 #define BUFSIZE 4096
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
int sha1Test(int argc, char **argv) int sha1Test(int argc, char **argv, int accurate)
{ {
SHA1_CTX ctx; SHA1_CTX ctx;
unsigned char hash[20], buf[BUFSIZE]; unsigned char hash[20], buf[BUFSIZE];
...@@ -209,6 +209,7 @@ int sha1Test(int argc, char **argv) ...@@ -209,6 +209,7 @@ int sha1Test(int argc, char **argv)
UNUSED(argc); UNUSED(argc);
UNUSED(argv); UNUSED(argv);
UNUSED(accurate);
for(i=0;i<BUFSIZE;i++) for(i=0;i<BUFSIZE;i++)
buf[i] = i; buf[i] = i;
......
...@@ -19,6 +19,6 @@ void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); ...@@ -19,6 +19,6 @@ void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len);
void SHA1Final(unsigned char digest[20], SHA1_CTX* context); void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
#ifdef REDIS_TEST #ifdef REDIS_TEST
int sha1Test(int argc, char **argv); int sha1Test(int argc, char **argv, int accurate);
#endif #endif
#endif #endif
...@@ -946,9 +946,10 @@ static void test_ll2string(void) { ...@@ -946,9 +946,10 @@ static void test_ll2string(void) {
} }
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
int utilTest(int argc, char **argv) { int utilTest(int argc, char **argv, int accurate) {
UNUSED(argc); UNUSED(argc);
UNUSED(argv); UNUSED(argv);
UNUSED(accurate);
test_string2ll(); test_string2ll();
test_string2l(); test_string2l();
......
...@@ -66,7 +66,7 @@ long getTimeZone(void); ...@@ -66,7 +66,7 @@ long getTimeZone(void);
int pathIsBaseName(char *path); int pathIsBaseName(char *path);
#ifdef REDIS_TEST #ifdef REDIS_TEST
int utilTest(int argc, char **argv); int utilTest(int argc, char **argv, int accurate);
#endif #endif
#endif #endif
...@@ -1823,15 +1823,17 @@ static size_t strEntryBytesLarge(size_t slen) { ...@@ -1823,15 +1823,17 @@ static size_t strEntryBytesLarge(size_t slen) {
return slen + zipStorePrevEntryLength(NULL, ZIP_BIG_PREVLEN) + zipStoreEntryEncoding(NULL, 0, slen); return slen + zipStorePrevEntryLength(NULL, ZIP_BIG_PREVLEN) + zipStoreEntryEncoding(NULL, 0, slen);
} }
int ziplistTest(int argc, char **argv) { /* ./redis-server test ziplist <randomseed> --accurate */
int ziplistTest(int argc, char **argv, int accurate) {
unsigned char *zl, *p; unsigned char *zl, *p;
unsigned char *entry; unsigned char *entry;
unsigned int elen; unsigned int elen;
long long value; long long value;
int iteration;
/* If an argument is given, use it as the random seed. */ /* If an argument is given, use it as the random seed. */
if (argc == 2) if (argc >= 4)
srand(atoi(argv[1])); srand(atoi(argv[3]));
zl = createIntList(); zl = createIntList();
ziplistRepr(zl); ziplistRepr(zl);
...@@ -2339,7 +2341,8 @@ int ziplistTest(int argc, char **argv) { ...@@ -2339,7 +2341,8 @@ int ziplistTest(int argc, char **argv) {
unsigned int slen; unsigned int slen;
long long sval; long long sval;
for (i = 0; i < 20000; i++) { iteration = accurate ? 20000 : 20;
for (i = 0; i < iteration; i++) {
zl = ziplistNew(); zl = ziplistNew();
ref = listCreate(); ref = listCreate();
listSetFreeMethod(ref,(void (*)(void*))sdsfree); listSetFreeMethod(ref,(void (*)(void*))sdsfree);
...@@ -2405,15 +2408,17 @@ int ziplistTest(int argc, char **argv) { ...@@ -2405,15 +2408,17 @@ int ziplistTest(int argc, char **argv) {
printf("Stress with variable ziplist size:\n"); printf("Stress with variable ziplist size:\n");
{ {
unsigned long long start = usec(); unsigned long long start = usec();
stress(ZIPLIST_HEAD,100000,16384,256); int maxsize = accurate ? 16384 : 16;
stress(ZIPLIST_TAIL,100000,16384,256); stress(ZIPLIST_HEAD,100000,maxsize,256);
stress(ZIPLIST_TAIL,100000,maxsize,256);
printf("Done. usec=%lld\n\n", usec()-start); printf("Done. usec=%lld\n\n", usec()-start);
} }
/* Benchmarks */ /* Benchmarks */
{ {
zl = ziplistNew(); zl = ziplistNew();
for (int i=0; i<100000; i++) { iteration = accurate ? 100000 : 100;
for (int i=0; i<iteration; i++) {
char buf[4096] = "asdf"; char buf[4096] = "asdf";
zl = ziplistPush(zl, (unsigned char*)buf, 4, ZIPLIST_TAIL); zl = ziplistPush(zl, (unsigned char*)buf, 4, ZIPLIST_TAIL);
zl = ziplistPush(zl, (unsigned char*)buf, 40, ZIPLIST_TAIL); zl = ziplistPush(zl, (unsigned char*)buf, 40, ZIPLIST_TAIL);
...@@ -2462,7 +2467,8 @@ int ziplistTest(int argc, char **argv) { ...@@ -2462,7 +2467,8 @@ int ziplistTest(int argc, char **argv) {
{ {
char data[ZIP_BIG_PREVLEN]; char data[ZIP_BIG_PREVLEN];
zl = ziplistNew(); zl = ziplistNew();
for (int i = 0; i < 100000; i++) { iteration = accurate ? 100000 : 100;
for (int i = 0; i < iteration; i++) {
zl = ziplistPush(zl, (unsigned char*)data, ZIP_BIG_PREVLEN-4, ZIPLIST_TAIL); zl = ziplistPush(zl, (unsigned char*)data, ZIP_BIG_PREVLEN-4, ZIPLIST_TAIL);
} }
unsigned long long start = usec(); unsigned long long start = usec();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment