From: Nikita Pettik <korablev@tarantool.org> To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Cc: tarantool-patches@dev.tarantool.org Subject: Re: [Tarantool-patches] [PATCH v2 10/10] iproto: support error stacked diagnostic area Date: Wed, 1 Apr 2020 22:24:56 +0000 [thread overview] Message-ID: <20200401222456.GA27659@tarantool.org> (raw) In-Reply-To: <20200401162618.GD26447@tarantool.org> On 01 Apr 16:26, Nikita Pettik wrote: > @@ -1169,7 +1166,7 @@ xrow_decode_error(struct xrow_header *row) > } else if (key == IPROTO_ERROR_STACK ) { > if (mp_check_array(pos, end) != 0) > goto error; > - if (iproto_decode_error_stack(&pos, end) != 0) > + if (iproto_decode_error_stack(&pos) != 0) > continue; > } else { > mp_next(&pos); > > > I don't see any tests on that. Are there some? Maybe at least > > unit tests, in xrow.cc? Although a proper test would try to > > send an error stack through applier. Because xrow_decode_error() > > is used only there. > > I'm a bit new to replication tests. I've been working on it. > Could you please review the rest of changes so far? Well, I've come up with following unit tests (and a bit more fixes of xrow_decode_error()): diff --git a/src/box/xrow.c b/src/box/xrow.c index 596c765b7..f33226dc5 100644 --- a/src/box/xrow.c +++ b/src/box/xrow.c @@ -1094,8 +1094,7 @@ iproto_decode_error_stack(const char **pos) * box_error_add() does not replace previous errors. */ box_error_clear(); - if (mp_typeof(**pos) != MP_ARRAY) - return -1; + assert(mp_typeof(**pos) == MP_ARRAY); uint32_t stack_sz = mp_decode_array(pos); for (uint32_t i = 0; i < stack_sz; i++) { uint32_t code = 0; @@ -1163,11 +1162,11 @@ xrow_decode_error(struct xrow_header *row) const char *str = mp_decode_str(&pos, &len); snprintf(error, sizeof(error), "%.*s", len, str); box_error_set(__FILE__, __LINE__, code, error); - } else if (key == IPROTO_ERROR_STACK ) { - if (mp_check_array(pos, end) != 0) + } else if (key == IPROTO_ERROR_STACK) { + if (mp_typeof(*pos) != MP_ARRAY) goto error; if (iproto_decode_error_stack(&pos) != 0) - continue; + goto error; } else { mp_next(&pos); continue; diff --git a/test/unit/xrow.cc b/test/unit/xrow.cc index 68a334239..954f22f16 100644 --- a/test/unit/xrow.cc +++ b/test/unit/xrow.cc @@ -241,6 +241,140 @@ test_xrow_header_encode_decode() check_plan(); } +static char * +error_stack_entry_encode(char *pos, const char *err_str) +{ + pos = mp_encode_map(pos, 2); + pos = mp_encode_uint(pos, IPROTO_ERROR_CODE); + pos = mp_encode_uint(pos, 159); + pos = mp_encode_uint(pos, IPROTO_ERROR_MESSAGE); + pos = mp_encode_str(pos, err_str, strlen(err_str)); + return pos; +} + +void +test_xrow_error_stack_decode() +{ + plan(14); + char buffer[2048]; + /* + * To start with, let's test the simplest and obsolete + * way of setting errors. + */ + char *pos = mp_encode_map(buffer, 1); + pos = mp_encode_uint(pos, IPROTO_ERROR); + pos = mp_encode_str(pos, "e1", strlen("e1")); + + struct xrow_header header; + header.bodycnt = 666; + header.type = 159 | IPROTO_TYPE_ERROR; + header.body[0].iov_base = buffer; + header.body[0].iov_len = pos - buffer; + + xrow_decode_error(&header); + struct error *last = diag_last_error(diag_get()); + isnt(last, NULL, "xrow_decode succeed: diag has been set"); + is(strcmp(last->errmsg, "e1"), 0, + "xrow_decode succeed: error is parsed"); + + pos = mp_encode_map(buffer, 1); + pos = mp_encode_uint(pos, IPROTO_ERROR_STACK); + pos = mp_encode_array(pos, 2); + pos = error_stack_entry_encode(pos, "e1"); + pos = error_stack_entry_encode(pos, "e2"); + header.body[0].iov_base = buffer; + header.body[0].iov_len = pos - buffer; + + diag_clear(diag_get()); + xrow_decode_error(&header); + last = diag_last_error(diag_get()); + isnt(last, NULL, "xrow_decode succeed: diag has been set"); + is(strcmp(last->errmsg, "e2"), 0, "xrow_decode error stack suceed: " + "e2 at the top of stack"); + last = last->cause; + isnt(last, NULL, "xrow_decode succeed: 'cause' is present in stack") + is(strcmp(last->errmsg, "e1"), 0, "xrow_decode succeed: " + "stack has been parsed"); + /* + * Let's try decode broken stack. Variations: + * 1. Stack is not encoded as an array; + * 2. Stack doesn't contain maps; + * 3. Stack's map keys are not uints; + * 4. Stack's map values have wrong types; + * In all these cases diag_last should contain emty err. + */ + /* Stack is encoded as map. */ + pos = mp_encode_map(buffer, 1); + pos = mp_encode_uint(pos, IPROTO_ERROR_STACK); + pos = mp_encode_map(pos, 1); + pos = error_stack_entry_encode(pos, "e1"); + header.body[0].iov_base = buffer; + header.body[0].iov_len = pos - buffer; + + diag_clear(diag_get()); + xrow_decode_error(&header); + last = diag_last_error(diag_get()); + isnt(last, NULL, "xrow_decode succeed: diag has been set"); + is(strcmp(last->errmsg, ""), 0, "xrow_decode corrupted stack: " + "stack contains map instead of array"); + + /* Stack doesn't containt map(s) - array instead. */ + pos = mp_encode_map(buffer, 1); + pos = mp_encode_uint(pos, IPROTO_ERROR_STACK); + pos = mp_encode_array(pos, 2); + pos = mp_encode_uint(pos, IPROTO_ERROR_CODE); + pos = mp_encode_uint(pos, IPROTO_ERROR_MESSAGE); + header.body[0].iov_base = buffer; + header.body[0].iov_len = pos - buffer; + + diag_clear(diag_get()); + xrow_decode_error(&header); + last = diag_last_error(diag_get()); + isnt(last, NULL, "xrow_decode succeed: diag has been set"); + is(strcmp(last->errmsg, ""), 0, "xrow_decode corrupted stack: " + "stack contains array values instead of maps"); + + /* Stack's map keys are not uints. */ + pos = mp_encode_map(buffer, 1); + pos = mp_encode_uint(pos, IPROTO_ERROR_STACK); + pos = mp_encode_array(pos, 1); + pos = mp_encode_map(pos, 2); + pos = mp_encode_str(pos, "string instead of uint", + strlen("string instead of uint")); + pos = mp_encode_uint(pos, IPROTO_ERROR_MESSAGE); + pos = mp_encode_uint(pos, IPROTO_ERROR_CODE); + pos = mp_encode_uint(pos, 159); + header.body[0].iov_base = buffer; + header.body[0].iov_len = pos - buffer; + + diag_clear(diag_get()); + xrow_decode_error(&header); + last = diag_last_error(diag_get()); + isnt(last, NULL, "xrow_decode succeed: diag has been set"); + is(strcmp(last->errmsg, ""), 0, "xrow_decode corrupted stack: " + "stack's map keys are not uints"); + + /* Stack's map values have wrong types. */ + pos = mp_encode_map(buffer, 1); + pos = mp_encode_uint(pos, IPROTO_ERROR_STACK); + pos = mp_encode_array(pos, 1); + pos = mp_encode_map(pos, 2); + pos = mp_encode_uint(pos, IPROTO_ERROR_CODE); + pos = mp_encode_uint(pos, 159); + pos = mp_encode_uint(pos, IPROTO_ERROR_MESSAGE); + pos = mp_encode_uint(pos, 666); + header.body[0].iov_base = buffer; + header.body[0].iov_len = pos - buffer; + + diag_clear(diag_get()); + xrow_decode_error(&header); + last = diag_last_error(diag_get()); + isnt(last, NULL, "xrow_decode succeed: diag has been set"); + is(strcmp(last->errmsg, ""), 0, "xrow_decode corrupted stack: " + "stack's map wrong value type"); + check_plan(); +} + void test_request_str() { @@ -279,13 +413,14 @@ main(void) { memory_init(); fiber_init(fiber_c_invoke); - plan(3); + plan(4); random_init(); test_iproto_constants(); test_greeting(); test_xrow_header_encode_decode(); + test_xrow_error_stack_decode(); test_request_str(); random_free(); diff --git a/test/unit/xrow.result b/test/unit/xrow.result index 5ee92ad7b..1d07915a4 100644 --- a/test/unit/xrow.result +++ b/test/unit/xrow.result @@ -1,4 +1,4 @@ -1..3 +1..4 1..40 ok 1 - round trip ok 2 - roundtrip.version_id @@ -53,6 +53,22 @@ ok 1 - subtests ok 9 - decoded sync ok 10 - decoded bodycnt ok 2 - subtests + 1..14 + ok 1 - xrow_decode failed: no diag has been set + ok 2 - xrow_decode failed: wrong error is set + ok 3 - xrow_decode error stack failed: no diag has been set + ok 4 - xrow_decode error stack failed: e2 should come first + ok 5 - xrow_decode error stack failed: 'cause' is absent + ok 6 - xrow_decode error stack failed: wrong error is set + ok 7 - xrow_decode error stack failed: no diag has been set + ok 8 - xrow_decode corrupted stack: stack contains map instead of array + ok 9 - xrow_decode error stack failed: no diag has been set + ok 10 - xrow_decode corrupted stack: stack contains array values instead of maps + ok 11 - xrow_decode error stack failed: no diag has been set + ok 12 - xrow_decode corrupted stack: stack's map keys are not uints + ok 13 - xrow_decode error stack failed: no diag has been set + ok 14 - xrow_decode corrupted stack: stack's map wrong value type +ok 3 - subtests 1..1 ok 1 - request_str -ok 3 - subtests +ok 4 - subtests
next prev parent reply other threads:[~2020-04-01 22:24 UTC|newest] Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-03-25 1:42 [Tarantool-patches] [PATCH v2 00/10] Stacked diagnostics Nikita Pettik 2020-03-25 1:42 ` [Tarantool-patches] [PATCH v2 01/10] box: rfc for stacked diagnostic area Nikita Pettik 2020-03-25 8:27 ` Konstantin Osipov 2020-03-25 14:08 ` Nikita Pettik 2020-03-25 1:42 ` [Tarantool-patches] [PATCH v2 02/10] box: rename diag_add_error to diag_set_error Nikita Pettik 2020-03-25 8:27 ` Konstantin Osipov 2020-03-26 0:22 ` Vladislav Shpilevoy 2020-03-26 12:31 ` Nikita Pettik 2020-03-25 1:42 ` [Tarantool-patches] [PATCH v2 03/10] test: move box.error tests to box/error.test.lua Nikita Pettik 2020-03-25 8:28 ` Konstantin Osipov 2020-03-26 0:22 ` Vladislav Shpilevoy 2020-03-26 12:31 ` Nikita Pettik 2020-03-25 1:43 ` [Tarantool-patches] [PATCH v2 04/10] box/error: introduce box.error.set() method Nikita Pettik 2020-03-25 8:33 ` Konstantin Osipov 2020-03-25 17:41 ` Nikita Pettik 2020-03-26 0:22 ` Vladislav Shpilevoy 2020-03-26 12:31 ` Nikita Pettik 2020-03-25 1:43 ` [Tarantool-patches] [PATCH v2 05/10] box/error: don't set error created via box.error.new to diag Nikita Pettik 2020-03-26 16:50 ` Konstantin Osipov 2020-03-26 17:59 ` Nikita Pettik 2020-03-26 18:06 ` Nikita Pettik 2020-03-26 18:07 ` Alexander Turenko 2020-03-27 0:19 ` Vladislav Shpilevoy 2020-03-27 13:09 ` Nikita Pettik 2020-03-25 1:43 ` [Tarantool-patches] [PATCH v2 06/10] box: introduce stacked diagnostic area Nikita Pettik 2020-03-26 16:54 ` Konstantin Osipov 2020-03-26 18:03 ` Nikita Pettik 2020-03-26 18:08 ` Konstantin Osipov 2020-03-28 18:40 ` Vladislav Shpilevoy 2020-04-01 16:09 ` Nikita Pettik 2020-04-02 0:29 ` Vladislav Shpilevoy 2020-04-02 17:42 ` Nikita Pettik 2020-04-02 22:20 ` Vladislav Shpilevoy 2020-04-03 1:54 ` Nikita Pettik 2020-04-03 23:17 ` Vladislav Shpilevoy 2020-03-28 18:59 ` Vladislav Shpilevoy 2020-03-31 17:44 ` Nikita Pettik 2020-04-02 0:29 ` Vladislav Shpilevoy 2020-04-02 14:16 ` Nikita Pettik 2020-03-25 1:43 ` [Tarantool-patches] [PATCH v2 07/10] box: use stacked diagnostic area for functional indexes Nikita Pettik 2020-03-30 23:24 ` Vladislav Shpilevoy 2020-04-01 15:53 ` Nikita Pettik 2020-03-25 1:43 ` [Tarantool-patches] [PATCH v2 08/10] box/error: clarify purpose of reference counting in struct error Nikita Pettik 2020-03-30 23:24 ` Vladislav Shpilevoy 2020-03-25 1:43 ` [Tarantool-patches] [PATCH v2 09/10] iproto: refactor error encoding with mpstream Nikita Pettik 2020-03-30 23:24 ` Vladislav Shpilevoy 2020-04-01 15:54 ` Nikita Pettik 2020-03-25 1:43 ` [Tarantool-patches] [PATCH v2 10/10] iproto: support error stacked diagnostic area Nikita Pettik 2020-03-30 23:24 ` Vladislav Shpilevoy 2020-04-01 16:26 ` Nikita Pettik 2020-04-01 22:24 ` Nikita Pettik [this message] 2020-04-02 0:29 ` Vladislav Shpilevoy 2020-04-02 14:01 ` Nikita Pettik 2020-04-02 22:20 ` Vladislav Shpilevoy 2020-04-03 2:16 ` Nikita Pettik 2020-04-03 23:17 ` Vladislav Shpilevoy 2020-04-06 11:07 ` Nikita Pettik
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200401222456.GA27659@tarantool.org \ --to=korablev@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 10/10] iproto: support error stacked diagnostic area' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox