diff --git a/CMakeLists.txt b/CMakeLists.txt index 566d9a01..c1480cb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,6 @@ SET(valkey_sources src/sockcompat.c src/valkey.c src/valkeycluster.c - src/vkarray.c src/vkutil.c) IF(WIN32) diff --git a/src/command.c b/src/command.c index f56675d6..577e43d2 100644 --- a/src/command.c +++ b/src/command.c @@ -40,19 +40,18 @@ #else #include #endif +#include #include #include "alloc.h" #include "command.h" -#include "vkarray.h" +#include "sds.h" #include "vkutil.h" #include "win32.h" #define LF (uint8_t)10 #define CR (uint8_t)13 -static uint64_t cmd_id = 0; /* command id counter */ - typedef enum { KEYPOS_NONE, KEYPOS_UNKNOWN, @@ -93,9 +92,8 @@ static inline void to_upper(char *dst, const char *src, uint32_t len) { } /* Looks up a command or subcommand in the command table. Arg0 and arg1 are used - * to lookup the command. The function returns CMD_UNKNOWN on failure. On - * success, the command type is returned and *firstkey and *arity are - * populated. */ + * to lookup the command. The function returns the cmddef for a found command, + * or NULL on failure. */ cmddef *valkey_lookup_cmd(const char *arg0, uint32_t arg0_len, const char *arg1, uint32_t arg1_len) { int num_commands = sizeof(server_commands) / sizeof(cmddef); @@ -167,15 +165,6 @@ char *valkey_parse_bulk(char *p, char *end, char **str, uint32_t *len) { return p; } -static inline int push_keypos(struct cmd *r, char *arg, uint32_t arglen) { - struct keypos *kpos = vkarray_push(r->keys); - if (kpos == NULL) - return 0; - kpos->start = arg; - kpos->end = arg + arglen; - return 1; -} - /* * Reference: https://valkey.io/docs/topics/protocol/ * @@ -217,7 +206,6 @@ void valkey_parse_cmd(struct cmd *r) { goto error; if (rnarg == 0) goto error; - r->narg = rnarg; /* Parse the first two args. */ if ((p = valkey_parse_bulk(p, end, &arg0, &arg0_len)) == NULL) @@ -232,7 +220,6 @@ void valkey_parse_cmd(struct cmd *r) { /* Lookup command. */ if ((info = valkey_lookup_cmd(arg0, arg0_len, arg1, arg1_len)) == NULL) goto error; /* Command not found. */ - r->type = info->type; /* Arity check (negative arity means minimum num args) */ if ((info->arity >= 0 && (int)rnarg != info->arity) || @@ -251,10 +238,10 @@ void valkey_parse_cmd(struct cmd *r) { /* Keyword-based first key position */ const char *keyword; int startfrom; - if (r->type == CMD_REQ_VALKEY_XREAD) { + if (info->type == CMD_REQ_VALKEY_XREAD) { keyword = "STREAMS"; startfrom = 1; - } else if (r->type == CMD_REQ_VALKEY_XREADGROUP) { + } else if (info->type == CMD_REQ_VALKEY_XREADGROUP) { keyword = "STREAMS"; startfrom = 4; } else { @@ -274,8 +261,9 @@ void valkey_parse_cmd(struct cmd *r) { /* Keyword found. Now the first key is the next arg. */ if ((p = valkey_parse_bulk(p, end, &arg, &arglen)) == NULL) goto error; - if (!push_keypos(r, arg, arglen)) - goto oom; + /* Keep found key. */ + r->key.start = arg; + r->key.len = arglen; goto done; } } @@ -317,9 +305,9 @@ void valkey_parse_cmd(struct cmd *r) { * from the end of the command line. This is not implemented. */ goto error; } - - if (!push_keypos(r, arg, arglen)) - goto oom; + /* Keep found key. */ + r->key.start = arg; + r->key.len = arglen; done: ASSERT(r->type > CMD_UNKNOWN && r->type < CMD_SENTINEL); @@ -333,7 +321,8 @@ void valkey_parse_cmd(struct cmd *r) { if (r->errstr == NULL) { r->errstr = vk_malloc(errmaxlen); if (r->errstr == NULL) { - goto oom; + r->result = CMD_PARSE_ENOMEM; + return; } } @@ -343,17 +332,14 @@ void valkey_parse_cmd(struct cmd *r) { else if (info != NULL) snprintf(r->errstr, errmaxlen, "Failed to find keys of command %s", info->name); - else if (r->type == CMD_UNKNOWN && arg0 != NULL && arg1 != NULL) + else if (info == NULL && arg0 != NULL && arg1 != NULL) snprintf(r->errstr, errmaxlen, "Unknown command %.*s %.*s", arg0_len, arg0, arg1_len, arg1); - else if (r->type == CMD_UNKNOWN && arg0 != NULL) + else if (info == NULL && arg0 != NULL) snprintf(r->errstr, errmaxlen, "Unknown command %.*s", arg0_len, arg0); else snprintf(r->errstr, errmaxlen, "Command parse error"); return; - -oom: - r->result = CMD_PARSE_ENOMEM; } struct cmd *command_get(void) { @@ -363,27 +349,15 @@ struct cmd *command_get(void) { return NULL; } - command->id = ++cmd_id; command->result = CMD_PARSE_OK; command->errstr = NULL; - command->type = CMD_UNKNOWN; command->cmd = NULL; command->clen = 0; - command->keys = NULL; - command->narg = 0; - command->quit = 0; - command->noforward = 0; + command->key.start = NULL; + command->key.len = 0; command->slot_num = -1; - command->frag_seq = NULL; - command->reply = NULL; command->node_addr = NULL; - command->keys = vkarray_create(1, sizeof(struct keypos)); - if (command->keys == NULL) { - vk_free(command); - return NULL; - } - return command; } @@ -402,19 +376,6 @@ void command_destroy(struct cmd *command) { command->errstr = NULL; } - if (command->keys != NULL) { - command->keys->nelem = 0; - vkarray_destroy(command->keys); - command->keys = NULL; - } - - if (command->frag_seq != NULL) { - vk_free(command->frag_seq); - command->frag_seq = NULL; - } - - freeReplyObject(command->reply); - if (command->node_addr != NULL) { sdsfree(command->node_addr); command->node_addr = NULL; diff --git a/src/command.h b/src/command.h index eafd90a3..bc62d017 100644 --- a/src/command.h +++ b/src/command.h @@ -34,9 +34,6 @@ #include -#include "adlist.h" -#include "valkey.h" - typedef enum cmd_parse_result { CMD_PARSE_OK, /* parsing ok */ CMD_PARSE_ENOMEM, /* out of memory */ @@ -62,41 +59,24 @@ typedef enum cmd_type { } cmd_type_t; struct keypos { - char *start; /* key start pos */ - char *end; /* key end pos */ - uint32_t remain_len; /* remain length after keypos->end for more key-value - pairs in command, like mset */ + char *start; /* key start pos */ + uint32_t len; /* Length of key */ }; struct cmd { - - uint64_t id; /* command id */ - cmd_parse_result_t result; /* command parsing result */ char *errstr; /* error info when the command parse failed */ - cmd_type_t type; /* command type */ - char *cmd; uint32_t clen; /* command length */ - struct vkarray *keys; /* array of keypos, for req */ - - uint32_t narg; /* # arguments (valkey) */ - - unsigned quit : 1; /* quit request? */ - unsigned noforward : 1; /* not need forward (example: ping) */ + struct keypos key; /* First found key in command. */ /* Command destination */ int slot_num; /* Command should be sent to slot. * Set to -1 if command is sent to a given node, * or if a slot can not be found or calculated. */ char *node_addr; /* Command sent to this node address */ - - struct cmd * - *frag_seq; /* sequence of fragment command, map from keys to fragments*/ - - valkeyReply *reply; }; void valkey_parse_cmd(struct cmd *r); diff --git a/src/valkeycluster.c b/src/valkeycluster.c index 03fa592d..1ca0327e 100644 --- a/src/valkeycluster.c +++ b/src/valkeycluster.c @@ -43,7 +43,6 @@ #include "command.h" #include "dict.h" #include "valkeycluster.h" -#include "vkarray.h" #include "vkutil.h" #include "win32.h" @@ -2302,15 +2301,13 @@ static int prepareCommand(valkeyClusterContext *cc, struct cmd *command) { __valkeyClusterSetError(cc, VALKEY_ERR_PROTOCOL, command->errstr); return VALKEY_ERR; } - if (vkarray_n(command->keys) <= 0) { + if (command->key.len == 0) { __valkeyClusterSetError( cc, VALKEY_ERR_OTHER, "No keys in command(must have keys for valkey cluster mode)"); return VALKEY_ERR; } - - struct keypos *kp = vkarray_get(command->keys, 0); - command->slot_num = keyHashSlot(kp->start, kp->end - kp->start); + command->slot_num = keyHashSlot(command->key.start, command->key.len); return VALKEY_OK; } diff --git a/src/vkarray.c b/src/vkarray.c deleted file mode 100644 index 7acd40af..00000000 --- a/src/vkarray.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2015-2017, Ieshen Zheng - * Copyright (c) 2020, Nick - * Copyright (c) 2020-2021, Bjorn Svensson - * Copyright (c) 2020-2021, Viktor Söderqvist - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#include - -#include "alloc.h" -#include "vkarray.h" -#include "vkutil.h" - -struct vkarray *vkarray_create(uint32_t n, size_t size) { - struct vkarray *a; - - ASSERT(n != 0 && size != 0); - - a = vk_malloc(sizeof(*a)); - if (a == NULL) { - return NULL; - } - - a->elem = vk_malloc(n * size); - if (a->elem == NULL) { - vk_free(a); - return NULL; - } - - a->nelem = 0; - a->size = size; - a->nalloc = n; - - return a; -} - -void vkarray_destroy(struct vkarray *a) { - vkarray_deinit(a); - vk_free(a); -} - -void vkarray_deinit(struct vkarray *a) { - ASSERT(a->nelem == 0); - - vk_free(a->elem); - a->elem = NULL; -} - -uint32_t vkarray_idx(struct vkarray *a, void *elem) { - uint8_t *p, *q; - uint32_t off, idx; - - ASSERT(elem >= a->elem); - - p = a->elem; - q = elem; - off = (uint32_t)(q - p); - - ASSERT(off % (uint32_t)a->size == 0); - - idx = off / (uint32_t)a->size; - - return idx; -} - -void *vkarray_push(struct vkarray *a) { - void *elem, *new; - size_t size; - - if (a->nelem == a->nalloc) { - - /* the array is full; allocate new array */ - size = a->size * a->nalloc; - new = vk_realloc(a->elem, 2 * size); - if (new == NULL) { - return NULL; - } - - a->elem = new; - a->nalloc *= 2; - } - - elem = (uint8_t *)a->elem + a->size * a->nelem; - a->nelem++; - - return elem; -} - -void *vkarray_pop(struct vkarray *a) { - void *elem; - - ASSERT(a->nelem != 0); - - a->nelem--; - elem = (uint8_t *)a->elem + a->size * a->nelem; - - return elem; -} - -void *vkarray_get(struct vkarray *a, uint32_t idx) { - void *elem; - - ASSERT(a->nelem != 0); - ASSERT(idx < a->nelem); - - elem = (uint8_t *)a->elem + (a->size * idx); - - return elem; -} - -void *vkarray_top(struct vkarray *a) { - ASSERT(a->nelem != 0); - - return vkarray_get(a, a->nelem - 1); -} - -void vkarray_swap(struct vkarray *a, struct vkarray *b) { - struct vkarray tmp; - - tmp = *a; - *a = *b; - *b = tmp; -} - -/* - * Sort nelem elements of the array in ascending order based on the - * compare comparator. - */ -void vkarray_sort(struct vkarray *a, vkarray_compare_t compare) { - ASSERT(a->nelem != 0); - - qsort(a->elem, a->nelem, a->size, compare); -} - -/* - * Calls the func once for each element in the array as long as func returns - * success. On failure short-circuits and returns the error status. - */ -int vkarray_each(struct vkarray *a, vkarray_each_t func, void *data) { - uint32_t i, nelem; - - ASSERT(vkarray_n(a) != 0); - ASSERT(func != NULL); - - for (i = 0, nelem = vkarray_n(a); i < nelem; i++) { - void *elem = vkarray_get(a, i); - rstatus_t status; - - status = func(elem, data); - if (status != VK_OK) { - return status; - } - } - - return VK_OK; -} diff --git a/src/vkarray.h b/src/vkarray.h deleted file mode 100644 index 4f5f02ed..00000000 --- a/src/vkarray.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2015-2017, Ieshen Zheng - * Copyright (c) 2020-2021, Bjorn Svensson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __VKARRAY_H_ -#define __VKARRAY_H_ - -#include - -typedef int (*vkarray_compare_t)(const void *, const void *); -typedef int (*vkarray_each_t)(void *, void *); - -struct vkarray { - uint32_t nelem; /* # element */ - void *elem; /* element */ - size_t size; /* element size */ - uint32_t nalloc; /* # allocated element */ -}; - -#define null_vkarray \ - { 0, NULL, 0, 0 } - -static inline void vkarray_null(struct vkarray *a) { - a->nelem = 0; - a->elem = NULL; - a->size = 0; - a->nalloc = 0; -} - -static inline void vkarray_set(struct vkarray *a, void *elem, size_t size, - uint32_t nalloc) { - a->nelem = 0; - a->elem = elem; - a->size = size; - a->nalloc = nalloc; -} - -static inline uint32_t vkarray_n(const struct vkarray *a) { return a->nelem; } - -struct vkarray *vkarray_create(uint32_t n, size_t size); -void vkarray_destroy(struct vkarray *a); -void vkarray_deinit(struct vkarray *a); - -uint32_t vkarray_idx(struct vkarray *a, void *elem); -void *vkarray_push(struct vkarray *a); -void *vkarray_pop(struct vkarray *a); -void *vkarray_get(struct vkarray *a, uint32_t idx); -void *vkarray_top(struct vkarray *a); -void vkarray_swap(struct vkarray *a, struct vkarray *b); -void vkarray_sort(struct vkarray *a, vkarray_compare_t compare); -int vkarray_each(struct vkarray *a, vkarray_each_t func, void *data); - -#endif diff --git a/src/vkutil.h b/src/vkutil.h index 06f7d0f3..2d289946 100644 --- a/src/vkutil.h +++ b/src/vkutil.h @@ -36,12 +36,9 @@ #include #include -#define VK_OK 0 #define VK_ERROR -1 #define VK_EAGAIN -2 -typedef int rstatus_t; /* return type */ - #define VK_INET4_ADDRSTRLEN (sizeof("255.255.255.255") - 1) #define VK_INET6_ADDRSTRLEN \ (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") - 1) diff --git a/tests/ct_out_of_memory_handling.c b/tests/ct_out_of_memory_handling.c index c1fa837d..64e5618f 100644 --- a/tests/ct_out_of_memory_handling.c +++ b/tests/ct_out_of_memory_handling.c @@ -184,14 +184,14 @@ void test_alloc_failure_handling(void) { valkeyReply *reply; const char *cmd = "SET key value"; - for (int i = 0; i < 35; ++i) { + for (int i = 0; i < 33; ++i) { prepare_allocation_test(cc, i); reply = (valkeyReply *)valkeyClusterCommand(cc, cmd); assert(reply == NULL); ASSERT_STR_EQ(cc->errstr, "Out of memory"); } - prepare_allocation_test(cc, 35); + prepare_allocation_test(cc, 33); reply = (valkeyReply *)valkeyClusterCommand(cc, cmd); CHECK_REPLY_OK(cc, reply); freeReplyObject(reply); @@ -225,7 +225,7 @@ void test_alloc_failure_handling(void) { valkeyReply *reply; const char *cmd = "SET foo one"; - for (int i = 0; i < 36; ++i) { + for (int i = 0; i < 34; ++i) { prepare_allocation_test(cc, i); result = valkeyClusterAppendCommand(cc, cmd); assert(result == VALKEY_ERR); @@ -237,7 +237,7 @@ void test_alloc_failure_handling(void) { for (int i = 0; i < 4; ++i) { // Appended command lost when receiving error from valkey // during a GetReply, needs a new append for each test loop - prepare_allocation_test(cc, 36); + prepare_allocation_test(cc, 34); result = valkeyClusterAppendCommand(cc, cmd); assert(result == VALKEY_OK); @@ -249,7 +249,7 @@ void test_alloc_failure_handling(void) { valkeyClusterReset(cc); } - prepare_allocation_test(cc, 36); + prepare_allocation_test(cc, 34); result = valkeyClusterAppendCommand(cc, cmd); assert(result == VALKEY_OK); @@ -269,7 +269,7 @@ void test_alloc_failure_handling(void) { assert(node); // OOM failing appends - for (int i = 0; i < 37; ++i) { + for (int i = 0; i < 35; ++i) { prepare_allocation_test(cc, i); result = valkeyClusterAppendCommandToNode(cc, node, cmd); assert(result == VALKEY_ERR); @@ -281,7 +281,7 @@ void test_alloc_failure_handling(void) { // OOM failing GetResults for (int i = 0; i < 4; ++i) { // First a successful append - prepare_allocation_test(cc, 37); + prepare_allocation_test(cc, 35); result = valkeyClusterAppendCommandToNode(cc, node, cmd); assert(result == VALKEY_OK); @@ -294,7 +294,7 @@ void test_alloc_failure_handling(void) { } // Successful append and GetReply - prepare_allocation_test(cc, 37); + prepare_allocation_test(cc, 35); result = valkeyClusterAppendCommandToNode(cc, node, cmd); assert(result == VALKEY_OK); @@ -354,7 +354,7 @@ void test_alloc_failure_handling(void) { freeReplyObject(reply); /* Test ASK reply handling with OOM */ - for (int i = 0; i < 49; ++i) { + for (int i = 0; i < 47; ++i) { prepare_allocation_test(cc, i); reply = valkeyClusterCommand(cc, "GET foo"); assert(reply == NULL); @@ -362,7 +362,7 @@ void test_alloc_failure_handling(void) { } /* Test ASK reply handling without OOM */ - prepare_allocation_test(cc, 49); + prepare_allocation_test(cc, 47); reply = valkeyClusterCommand(cc, "GET foo"); CHECK_REPLY_STR(cc, reply, "one"); freeReplyObject(reply); @@ -383,7 +383,7 @@ void test_alloc_failure_handling(void) { freeReplyObject(reply); /* Test MOVED reply handling with OOM */ - for (int i = 0; i < 33; ++i) { + for (int i = 0; i < 31; ++i) { prepare_allocation_test(cc, i); reply = valkeyClusterCommand(cc, "GET foo"); assert(reply == NULL); @@ -391,7 +391,7 @@ void test_alloc_failure_handling(void) { } /* Test MOVED reply handling without OOM */ - prepare_allocation_test(cc, 33); + prepare_allocation_test(cc, 31); reply = valkeyClusterCommand(cc, "GET foo"); CHECK_REPLY_STR(cc, reply, "one"); freeReplyObject(reply); @@ -539,18 +539,18 @@ void test_alloc_failure_handling_async(void) { { const char *cmd1 = "SET foo one"; - for (int i = 0; i < 37; ++i) { + for (int i = 0; i < 35; ++i) { prepare_allocation_test_async(acc, i); result = valkeyClusterAsyncCommand(acc, commandCallback, &r1, cmd1); assert(result == VALKEY_ERR); - if (i != 35) { + if (i != 33) { ASSERT_STR_EQ(acc->errstr, "Out of memory"); } else { ASSERT_STR_EQ(acc->errstr, "Failed to attach event adapter"); } } - prepare_allocation_test_async(acc, 37); + prepare_allocation_test_async(acc, 35); result = valkeyClusterAsyncCommand(acc, commandCallback, &r1, cmd1); ASSERT_MSG(result == VALKEY_OK, acc->errstr); } @@ -561,16 +561,16 @@ void test_alloc_failure_handling_async(void) { { const char *cmd2 = "GET foo"; - for (int i = 0; i < 14; ++i) { + for (int i = 0; i < 12; ++i) { prepare_allocation_test_async(acc, i); result = valkeyClusterAsyncCommand(acc, commandCallback, &r2, cmd2); assert(result == VALKEY_ERR); ASSERT_STR_EQ(acc->errstr, "Out of memory"); } - /* Skip iteration 14, errstr not set by libvalkey when valkeyFormatSdsCommandArgv() fails. */ + /* Skip iteration 12, errstr not set by libvalkey when valkeyFormatSdsCommandArgv() fails. */ - prepare_allocation_test_async(acc, 15); + prepare_allocation_test_async(acc, 13); result = valkeyClusterAsyncCommand(acc, commandCallback, &r2, cmd2); ASSERT_MSG(result == VALKEY_OK, acc->errstr); } diff --git a/tests/ut_parse_cmd.c b/tests/ut_parse_cmd.c index 8c3532d3..d9637dde 100644 --- a/tests/ut_parse_cmd.c +++ b/tests/ut_parse_cmd.c @@ -3,47 +3,34 @@ #include "command.h" #include "test_utils.h" #include "valkeycluster.h" -#include "vkarray.h" #include "win32.h" #include #include #include #include -/* Helper for the macro ASSERT_KEYS below. */ -void check_keys(char **keys, int numkeys, struct cmd *command, char *file, - int line) { +/* Helper for the macro ASSERT_KEY below. */ +void check_key(char *key, struct cmd *command, char *file, int line) { if (command->result != CMD_PARSE_OK) { fprintf(stderr, "%s:%d: Command parsing failed: %s\n", file, line, command->errstr); assert(0); } - int actual_numkeys = (int)vkarray_n(command->keys); - if (actual_numkeys != numkeys) { - fprintf(stderr, "%s:%d: Expected %d keys but got %d\n", file, line, - numkeys, actual_numkeys); - assert(actual_numkeys == numkeys); - } - for (int i = 0; i < numkeys; i++) { - struct keypos *kpos = vkarray_get(command->keys, i); - char *actual_key = kpos->start; - int actual_keylen = (int)(kpos->end - kpos->start); - if ((int)strlen(keys[i]) != actual_keylen || - strncmp(keys[i], actual_key, actual_keylen)) { - fprintf(stderr, - "%s:%d: Expected key %d to be \"%s\" but got \"%.*s\"\n", - file, line, i, keys[i], actual_keylen, actual_key); - assert(0); - } + char *actual_key = command->key.start; + int actual_keylen = command->key.len; + if ((int)strlen(key) != actual_keylen || + strncmp(key, actual_key, actual_keylen)) { + fprintf(stderr, + "%s:%d: Expected key to be \"%s\" but got \"%.*s\"\n", + file, line, key, actual_keylen, actual_key); + assert(0); } } -/* Checks that a command (struct cmd *) has the given keys (strings). */ -#define ASSERT_KEYS(command, ...) \ - do { \ - char *expected_keys[] = {__VA_ARGS__}; \ - size_t n = sizeof(expected_keys) / sizeof(char *); \ - check_keys(expected_keys, n, command, __FILE__, __LINE__); \ +/* Checks that a command (struct cmd *) has the given key (string). */ +#define ASSERT_KEY(command, key) \ + do { \ + check_key(key, command, __FILE__, __LINE__); \ } while (0) void test_valkey_parse_error_nonresp(void) { @@ -64,7 +51,7 @@ void test_valkey_parse_cmd_get(void) { c->clen = len; valkey_parse_cmd(c); ASSERT_MSG(c->result == CMD_PARSE_OK, "Parse not OK"); - ASSERT_KEYS(c, "foo"); + ASSERT_KEY(c, "foo"); command_destroy(c); } @@ -75,7 +62,7 @@ void test_valkey_parse_cmd_mset(void) { c->clen = len; valkey_parse_cmd(c); ASSERT_MSG(c->result == CMD_PARSE_OK, "Parse not OK"); - ASSERT_KEYS(c, "foo"); + ASSERT_KEY(c, "foo"); command_destroy(c); } @@ -86,7 +73,7 @@ void test_valkey_parse_cmd_eval_1(void) { c->clen = len; valkey_parse_cmd(c); ASSERT_MSG(c->result == CMD_PARSE_OK, "Parse not OK"); - ASSERT_KEYS(c, "foo"); + ASSERT_KEY(c, "foo"); command_destroy(c); } @@ -97,7 +84,7 @@ void test_valkey_parse_cmd_eval_0(void) { c->clen = len; valkey_parse_cmd(c); ASSERT_MSG(c->result == CMD_PARSE_OK, "Parse not OK"); - ASSERT_MSG(vkarray_n(c->keys) == 0, "Nonzero number of keys"); + ASSERT_MSG(c->key.len == 0, "Unexpected key found"); command_destroy(c); } @@ -132,7 +119,7 @@ void test_valkey_parse_cmd_xgroup_destroy_ok(void) { ASSERT_MSG(len >= 0, "Format command error"); c->clen = len; valkey_parse_cmd(c); - ASSERT_KEYS(c, "mystream"); + ASSERT_KEY(c, "mystream"); command_destroy(c); } @@ -145,7 +132,7 @@ void test_valkey_parse_cmd_xreadgroup_ok(void) { ASSERT_MSG(len >= 0, "Format command error"); c->clen = len; valkey_parse_cmd(c); - ASSERT_KEYS(c, "mystream"); + ASSERT_KEY(c, "mystream"); command_destroy(c); } @@ -156,7 +143,7 @@ void test_valkey_parse_cmd_xread_ok(void) { ASSERT_MSG(len >= 0, "Format command error"); c->clen = len; valkey_parse_cmd(c); - ASSERT_KEYS(c, "mystream"); + ASSERT_KEY(c, "mystream"); command_destroy(c); } @@ -168,7 +155,7 @@ void test_valkey_parse_cmd_restore_ok(void) { ASSERT_MSG(len >= 0, "Format command error"); c->clen = len; valkey_parse_cmd(c); - ASSERT_KEYS(c, "k"); + ASSERT_KEY(c, "k"); command_destroy(c); } @@ -180,7 +167,7 @@ void test_valkey_parse_cmd_restore_asking_ok(void) { ASSERT_MSG(len >= 0, "Format command error"); c->clen = len; valkey_parse_cmd(c); - ASSERT_KEYS(c, "k"); + ASSERT_KEY(c, "k"); command_destroy(c); } @@ -192,7 +179,7 @@ void test_valkey_parse_cmd_georadius_ro_ok(void) { ASSERT_MSG(len >= 0, "Format command error"); c->clen = len; valkey_parse_cmd(c); - ASSERT_KEYS(c, "k"); + ASSERT_KEY(c, "k"); command_destroy(c); }