diff options
author | Craig Tiller <ctiller@google.com> | 2015-11-02 14:18:30 -0800 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2015-11-02 14:18:30 -0800 |
commit | 93b944785c9fe9b6fd0d1781027fb072fe818496 (patch) | |
tree | 2b7e3f4bb093ab39871ef809fa9131aa6a2102f7 /test/core/transport/chttp2 | |
parent | c7e1a2a38d856762cab3e7dea9f59b4d651eec80 (diff) |
stream_op cleanup: test fixes and updates
Diffstat (limited to 'test/core/transport/chttp2')
-rw-r--r-- | test/core/transport/chttp2/hpack_encoder_test.c | 200 | ||||
-rw-r--r-- | test/core/transport/chttp2/stream_encoder_test.c | 359 |
2 files changed, 200 insertions, 359 deletions
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c new file mode 100644 index 0000000000..6553e0da20 --- /dev/null +++ b/test/core/transport/chttp2/hpack_encoder_test.c @@ -0,0 +1,200 @@ +/* + * + * Copyright 2015, Google Inc. + * 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 Google Inc. 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 "src/core/transport/chttp2/hpack_encoder.h" + +#include <stdio.h> + +#include "src/core/support/string.h" +#include "src/core/transport/chttp2/hpack_parser.h" +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include "test/core/util/parse_hexstring.h" +#include "test/core/util/slice_splitter.h" +#include "test/core/util/test_config.h" + +#define TEST(x) run_test(x, #x) + +grpc_mdctx *g_mdctx; +grpc_chttp2_hpack_compressor g_compressor; +int g_failure = 0; + +void **to_delete = NULL; +size_t num_to_delete = 0; +size_t cap_to_delete = 0; + +/* verify that the output generated by encoding the stream matches the + hexstring passed in */ +static void verify(size_t window_available, int eof, size_t expect_window_used, + const char *expected, size_t nheaders, ...) { + gpr_slice_buffer output; + gpr_slice merged; + gpr_slice expect = parse_hexstring(expected); + size_t i; + va_list l; + grpc_linked_mdelem *e = gpr_malloc(sizeof(*e) * nheaders); + grpc_metadata_batch b; + + grpc_metadata_batch_init(&b); + + va_start(l, nheaders); + for (i = 0; i < nheaders; i++) { + char *key = va_arg(l, char *); + char *value = va_arg(l, char *); + if (i) { + e[i - 1].next = &e[i]; + e[i].prev = &e[i - 1]; + } + e[i].md = grpc_mdelem_from_strings(g_mdctx, key, value); + } + e[0].prev = NULL; + e[nheaders - 1].next = NULL; + va_end(l); + + b.list.head = &e[0]; + b.list.tail = &e[nheaders - 1]; + + if (cap_to_delete == num_to_delete) { + cap_to_delete = GPR_MAX(2 * cap_to_delete, 1000); + to_delete = gpr_realloc(to_delete, sizeof(*to_delete) * cap_to_delete); + } + to_delete[num_to_delete++] = e; + + gpr_slice_buffer_init(&output); + + grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, &output); + merged = grpc_slice_merge(output.slices, output.count); + gpr_slice_buffer_destroy(&output); + grpc_metadata_batch_destroy(&b); + + if (0 != gpr_slice_cmp(merged, expect)) { + char *expect_str = gpr_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII); + char *got_str = gpr_dump_slice(merged, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_ERROR, "mismatched output for %s", expected); + gpr_log(GPR_ERROR, "EXPECT: %s", expect_str); + gpr_log(GPR_ERROR, "GOT: %s", got_str); + gpr_free(expect_str); + gpr_free(got_str); + g_failure = 1; + } + + gpr_slice_unref(merged); + gpr_slice_unref(expect); +} + +static void test_basic_headers(void) { + int i; + + verify(0, 0, 0, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a"); + verify(0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a"); + verify(0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a"); + verify(0, 0, 0, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a", "b", + "c"); + verify(0, 0, 0, "000002 0104 deadbeef bf be", 2, "a", "a", "b", "c"); + verify(0, 0, 0, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d"); + + /* flush out what's there to make a few values look very popular */ + for (i = 0; i < 350; i++) { + verify(0, 0, 0, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b", "c", "a", + "d"); + } + + verify(0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a", "k", + "v"); + /* this could be 000004 0104 deadbeef 0f 30 0176 also */ + verify(0, 0, 0, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v"); +} + +static void encode_int_to_str(int i, char *p) { + p[0] = (char)('a' + i % 26); + i /= 26; + GPR_ASSERT(i < 26); + p[1] = (char)('a' + i); + p[2] = 0; +} + +static void test_decode_table_overflow(void) { + int i; + char key[3], value[3]; + char *expect; + + for (i = 0; i < 114; i++) { + encode_int_to_str(i, key); + encode_int_to_str(i + 1, value); + + if (i + 61 >= 127) { + gpr_asprintf(&expect, + "000009 0104 deadbeef ff%02x 40 02%02x%02x 02%02x%02x", + i + 61 - 127, key[0], key[1], value[0], value[1]); + } else if (i > 0) { + gpr_asprintf(&expect, + "000008 0104 deadbeef %02x 40 02%02x%02x 02%02x%02x", + 0x80 + 61 + i, key[0], key[1], value[0], value[1]); + } else { + gpr_asprintf(&expect, "000007 0104 deadbeef 40 02%02x%02x 02%02x%02x", + key[0], key[1], value[0], value[1]); + } + + if (i > 0) { + verify(0, 0, 0, expect, 2, "aa", "ba", key, value); + } else { + verify(0, 0, 0, expect, 1, key, value); + } + gpr_free(expect); + } + + /* if the above passes, then we must have just knocked this pair out of the + decoder stack, and so we'll be forced to re-encode it */ + verify(0, 0, 0, "000007 0104 deadbeef 40 026161 026261", 1, "aa", "ba"); +} + +static void run_test(void (*test)(), const char *name) { + gpr_log(GPR_INFO, "RUN TEST: %s", name); + g_mdctx = grpc_mdctx_create_with_seed(0); + grpc_chttp2_hpack_compressor_init(&g_compressor, g_mdctx); + test(); + grpc_chttp2_hpack_compressor_destroy(&g_compressor); + grpc_mdctx_unref(g_mdctx); +} + +int main(int argc, char **argv) { + size_t i; + grpc_test_init(argc, argv); + TEST(test_basic_headers); + TEST(test_decode_table_overflow); + for (i = 0; i < num_to_delete; i++) { + gpr_free(to_delete[i]); + } + return g_failure; +} diff --git a/test/core/transport/chttp2/stream_encoder_test.c b/test/core/transport/chttp2/stream_encoder_test.c deleted file mode 100644 index 71db98c69e..0000000000 --- a/test/core/transport/chttp2/stream_encoder_test.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * 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 Google Inc. 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 "src/core/transport/chttp2/stream_encoder.h" - -#include <stdio.h> - -#include "src/core/support/string.h" -#include "src/core/transport/chttp2/hpack_parser.h" -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include "test/core/util/parse_hexstring.h" -#include "test/core/util/slice_splitter.h" -#include "test/core/util/test_config.h" - -#define TEST(x) run_test(x, #x) - -grpc_mdctx *g_mdctx; -grpc_chttp2_hpack_compressor g_compressor; -int g_failure = 0; -grpc_stream_op_buffer g_sopb; - -void **to_delete = NULL; -size_t num_to_delete = 0; -size_t cap_to_delete = 0; - -static gpr_slice create_test_slice(size_t length) { - gpr_slice slice = gpr_slice_malloc(length); - size_t i; - for (i = 0; i < length; i++) { - GPR_SLICE_START_PTR(slice)[i] = (gpr_uint8)i; - } - return slice; -} - -/* verify that the output generated by encoding the stream matches the - hexstring passed in */ -static void verify_sopb(size_t window_available, int eof, - size_t expect_window_used, const char *expected) { - gpr_slice_buffer output; - grpc_stream_op_buffer encops; - gpr_slice merged; - gpr_slice expect = parse_hexstring(expected); - gpr_slice_buffer_init(&output); - grpc_sopb_init(&encops); - GPR_ASSERT(expect_window_used == - grpc_chttp2_preencode(g_sopb.ops, &g_sopb.nops, - (gpr_uint32)window_available, &encops)); - grpc_chttp2_encode(encops.ops, encops.nops, eof, 0xdeadbeef, &g_compressor, - &output); - encops.nops = 0; - merged = grpc_slice_merge(output.slices, output.count); - gpr_slice_buffer_destroy(&output); - grpc_sopb_destroy(&encops); - - if (0 != gpr_slice_cmp(merged, expect)) { - char *expect_str = gpr_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII); - char *got_str = gpr_dump_slice(merged, GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_ERROR, "mismatched output for %s", expected); - gpr_log(GPR_ERROR, "EXPECT: %s", expect_str); - gpr_log(GPR_ERROR, "GOT: %s", got_str); - gpr_free(expect_str); - gpr_free(got_str); - g_failure = 1; - } - - gpr_slice_unref(merged); - gpr_slice_unref(expect); -} - -static void test_small_data_framing(void) { - grpc_sopb_add_no_op(&g_sopb); - verify_sopb(10, 0, 0, ""); - - grpc_sopb_add_slice(&g_sopb, create_test_slice(3)); - verify_sopb(10, 0, 3, "000003 0000 deadbeef 000102"); - - grpc_sopb_add_slice(&g_sopb, create_test_slice(4)); - verify_sopb(10, 0, 4, "000004 0000 deadbeef 00010203"); - - grpc_sopb_add_slice(&g_sopb, create_test_slice(3)); - grpc_sopb_add_slice(&g_sopb, create_test_slice(4)); - verify_sopb(10, 0, 7, "000007 0000 deadbeef 000102 00010203"); - - grpc_sopb_add_slice(&g_sopb, create_test_slice(0)); - grpc_sopb_add_slice(&g_sopb, create_test_slice(0)); - grpc_sopb_add_slice(&g_sopb, create_test_slice(0)); - grpc_sopb_add_slice(&g_sopb, create_test_slice(0)); - grpc_sopb_add_slice(&g_sopb, create_test_slice(3)); - verify_sopb(10, 0, 3, "000003 0000 deadbeef 000102"); - - verify_sopb(10, 1, 0, "000000 0001 deadbeef"); - - grpc_sopb_add_begin_message(&g_sopb, 255, 0); - verify_sopb(10, 0, 5, "000005 0000 deadbeef 00000000ff"); -} - -static void add_sopb_headers(size_t n, ...) { - size_t i; - grpc_metadata_batch b; - va_list l; - grpc_linked_mdelem *e = gpr_malloc(sizeof(*e) * n); - - grpc_metadata_batch_init(&b); - - va_start(l, n); - for (i = 0; i < n; i++) { - char *key = va_arg(l, char *); - char *value = va_arg(l, char *); - if (i) { - e[i - 1].next = &e[i]; - e[i].prev = &e[i - 1]; - } - e[i].md = grpc_mdelem_from_strings(g_mdctx, key, value); - } - e[0].prev = NULL; - e[n - 1].next = NULL; - va_end(l); - - b.list.head = &e[0]; - b.list.tail = &e[n - 1]; - - if (cap_to_delete == num_to_delete) { - cap_to_delete = GPR_MAX(2 * cap_to_delete, 1000); - to_delete = gpr_realloc(to_delete, sizeof(*to_delete) * cap_to_delete); - } - to_delete[num_to_delete++] = e; - - grpc_sopb_add_metadata(&g_sopb, b); -} - -static void test_basic_headers(void) { - int i; - - add_sopb_headers(1, "a", "a"); - verify_sopb(0, 0, 0, "000005 0104 deadbeef 40 0161 0161"); - - add_sopb_headers(1, "a", "a"); - verify_sopb(0, 0, 0, "000001 0104 deadbeef be"); - - add_sopb_headers(1, "a", "a"); - verify_sopb(0, 0, 0, "000001 0104 deadbeef be"); - - add_sopb_headers(2, "a", "a", "b", "c"); - verify_sopb(0, 0, 0, "000006 0104 deadbeef be 40 0162 0163"); - - add_sopb_headers(2, "a", "a", "b", "c"); - verify_sopb(0, 0, 0, "000002 0104 deadbeef bf be"); - - add_sopb_headers(1, "a", "d"); - verify_sopb(0, 0, 0, "000004 0104 deadbeef 7f 00 0164"); - - /* flush out what's there to make a few values look very popular */ - for (i = 0; i < 350; i++) { - add_sopb_headers(3, "a", "a", "b", "c", "a", "d"); - verify_sopb(0, 0, 0, "000003 0104 deadbeef c0 bf be"); - } - - add_sopb_headers(2, "a", "a", "k", "v"); - verify_sopb(0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176"); - - add_sopb_headers(1, "a", "v"); - /* this could be 000004 0104 deadbeef 0f 30 0176 also */ - verify_sopb(0, 0, 0, "000004 0104 deadbeef 0f 2f 0176"); -} - -static void encode_int_to_str(int i, char *p) { - p[0] = (char)('a' + i % 26); - i /= 26; - GPR_ASSERT(i < 26); - p[1] = (char)('a' + i); - p[2] = 0; -} - -static void test_decode_table_overflow(void) { - int i; - char key[3], value[3]; - char *expect; - - for (i = 0; i < 114; i++) { - if (i > 0) { - add_sopb_headers(1, "aa", "ba"); - } - - encode_int_to_str(i, key); - encode_int_to_str(i + 1, value); - - if (i + 61 >= 127) { - gpr_asprintf(&expect, - "000002 0104 deadbeef ff%02x 000007 0104 deadbeef 40 " - "02%02x%02x 02%02x%02x", - i + 61 - 127, key[0], key[1], value[0], value[1]); - } else if (i > 0) { - gpr_asprintf(&expect, - "000001 0104 deadbeef %02x 000007 0104 deadbeef 40 " - "02%02x%02x 02%02x%02x", - 0x80 + 61 + i, key[0], key[1], value[0], value[1]); - } else { - gpr_asprintf(&expect, "000007 0104 deadbeef 40 02%02x%02x 02%02x%02x", - key[0], key[1], value[0], value[1]); - } - - add_sopb_headers(1, key, value); - verify_sopb(0, 0, 0, expect); - gpr_free(expect); - } - - /* if the above passes, then we must have just knocked this pair out of the - decoder stack, and so we'll be forced to re-encode it */ - add_sopb_headers(1, "aa", "ba"); - verify_sopb(0, 0, 0, "000007 0104 deadbeef 40 026161 026261"); -} - -static void randstr(char *p, int bufsz) { - int i; - int len = 1 + rand() % bufsz; - for (i = 0; i < len; i++) { - p[i] = (char)('a' + rand() % 26); - } - p[len] = 0; -} - -typedef struct { - char key[300]; - char value[300]; - int got_hdr; -} test_decode_random_header_state; - -static void chk_hdr(void *p, grpc_mdelem *el) { - test_decode_random_header_state *st = p; - GPR_ASSERT(0 == gpr_slice_str_cmp(el->key->slice, st->key)); - GPR_ASSERT(0 == gpr_slice_str_cmp(el->value->slice, st->value)); - st->got_hdr = 1; - GRPC_MDELEM_UNREF(el); -} - -static void test_decode_random_headers_inner(int max_len) { - int i; - test_decode_random_header_state st; - gpr_slice_buffer output; - gpr_slice merged; - grpc_stream_op_buffer encops; - grpc_chttp2_hpack_parser parser; - - grpc_chttp2_hpack_parser_init(&parser, g_mdctx); - grpc_sopb_init(&encops); - - gpr_log(GPR_INFO, "max_len = %d", max_len); - - for (i = 0; i < 10000; i++) { - randstr(st.key, max_len); - randstr(st.value, max_len); - - add_sopb_headers(1, st.key, st.value); - gpr_slice_buffer_init(&output); - GPR_ASSERT(0 == - grpc_chttp2_preencode(g_sopb.ops, &g_sopb.nops, 0, &encops)); - grpc_chttp2_encode(encops.ops, encops.nops, 0, 0xdeadbeef, &g_compressor, - &output); - encops.nops = 0; - merged = grpc_slice_merge(output.slices, output.count); - gpr_slice_buffer_destroy(&output); - - st.got_hdr = 0; - parser.on_header = chk_hdr; - parser.on_header_user_data = &st; - grpc_chttp2_hpack_parser_parse(&parser, GPR_SLICE_START_PTR(merged) + 9, - GPR_SLICE_END_PTR(merged)); - GPR_ASSERT(st.got_hdr); - - gpr_slice_unref(merged); - } - - grpc_chttp2_hpack_parser_destroy(&parser); - grpc_sopb_destroy(&encops); -} - -#define DECL_TEST_DECODE_RANDOM_HEADERS(n) \ - static void test_decode_random_headers_##n(void) { \ - test_decode_random_headers_inner(n); \ - } \ - int keeps_formatting_correct_##n - -DECL_TEST_DECODE_RANDOM_HEADERS(1); -DECL_TEST_DECODE_RANDOM_HEADERS(2); -DECL_TEST_DECODE_RANDOM_HEADERS(3); -DECL_TEST_DECODE_RANDOM_HEADERS(5); -DECL_TEST_DECODE_RANDOM_HEADERS(8); -DECL_TEST_DECODE_RANDOM_HEADERS(13); -DECL_TEST_DECODE_RANDOM_HEADERS(21); -DECL_TEST_DECODE_RANDOM_HEADERS(34); -DECL_TEST_DECODE_RANDOM_HEADERS(55); -DECL_TEST_DECODE_RANDOM_HEADERS(89); -DECL_TEST_DECODE_RANDOM_HEADERS(144); - -static void run_test(void (*test)(), const char *name) { - gpr_log(GPR_INFO, "RUN TEST: %s", name); - g_mdctx = grpc_mdctx_create_with_seed(0); - grpc_chttp2_hpack_compressor_init(&g_compressor, g_mdctx); - grpc_sopb_init(&g_sopb); - test(); - grpc_chttp2_hpack_compressor_destroy(&g_compressor); - grpc_mdctx_unref(g_mdctx); - grpc_sopb_destroy(&g_sopb); -} - -int main(int argc, char **argv) { - size_t i; - grpc_test_init(argc, argv); - TEST(test_small_data_framing); - TEST(test_basic_headers); - TEST(test_decode_table_overflow); - TEST(test_decode_random_headers_1); - TEST(test_decode_random_headers_2); - TEST(test_decode_random_headers_3); - TEST(test_decode_random_headers_5); - TEST(test_decode_random_headers_8); - TEST(test_decode_random_headers_13); - TEST(test_decode_random_headers_21); - TEST(test_decode_random_headers_34); - TEST(test_decode_random_headers_55); - TEST(test_decode_random_headers_89); - TEST(test_decode_random_headers_144); - for (i = 0; i < num_to_delete; i++) { - gpr_free(to_delete[i]); - } - return g_failure; -} |