mirror of https://github.com/grpc/grpc.git
parent
c7e1a2a38d
commit
93b944785c
11 changed files with 284 additions and 534 deletions
@ -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; |
||||
} |
@ -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; |
||||
} |
@ -1,116 +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/stream_op.h" |
||||
|
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/log.h> |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
static void assert_slices_equal(gpr_slice a, gpr_slice b) { |
||||
GPR_ASSERT(a.refcount == b.refcount); |
||||
if (a.refcount) { |
||||
GPR_ASSERT(a.data.refcounted.bytes == b.data.refcounted.bytes); |
||||
GPR_ASSERT(a.data.refcounted.length == b.data.refcounted.length); |
||||
} else { |
||||
GPR_ASSERT(a.data.inlined.length == b.data.inlined.length); |
||||
GPR_ASSERT(0 == memcmp(a.data.inlined.bytes, b.data.inlined.bytes, |
||||
a.data.inlined.length)); |
||||
} |
||||
} |
||||
|
||||
int main(int argc, char **argv) { |
||||
/* some basic test data */ |
||||
gpr_slice test_slice_1 = gpr_slice_malloc(1); |
||||
gpr_slice test_slice_2 = gpr_slice_malloc(2); |
||||
gpr_slice test_slice_3 = gpr_slice_malloc(3); |
||||
gpr_slice test_slice_4 = gpr_slice_malloc(4); |
||||
unsigned i; |
||||
|
||||
grpc_stream_op_buffer buf; |
||||
grpc_stream_op_buffer buf2; |
||||
|
||||
grpc_test_init(argc, argv); |
||||
/* initialize one of our buffers */ |
||||
grpc_sopb_init(&buf); |
||||
/* it should start out empty */ |
||||
GPR_ASSERT(buf.nops == 0); |
||||
|
||||
/* add some data to the buffer */ |
||||
grpc_sopb_add_begin_message(&buf, 1, 2); |
||||
grpc_sopb_add_slice(&buf, test_slice_1); |
||||
grpc_sopb_add_slice(&buf, test_slice_2); |
||||
grpc_sopb_add_slice(&buf, test_slice_3); |
||||
grpc_sopb_add_slice(&buf, test_slice_4); |
||||
grpc_sopb_add_no_op(&buf); |
||||
|
||||
/* verify that the data went in ok */ |
||||
GPR_ASSERT(buf.nops == 6); |
||||
GPR_ASSERT(buf.ops[0].type == GRPC_OP_BEGIN_MESSAGE); |
||||
GPR_ASSERT(buf.ops[0].data.begin_message.length == 1); |
||||
GPR_ASSERT(buf.ops[0].data.begin_message.flags == 2); |
||||
GPR_ASSERT(buf.ops[1].type == GRPC_OP_SLICE); |
||||
assert_slices_equal(buf.ops[1].data.slice, test_slice_1); |
||||
GPR_ASSERT(buf.ops[2].type == GRPC_OP_SLICE); |
||||
assert_slices_equal(buf.ops[2].data.slice, test_slice_2); |
||||
GPR_ASSERT(buf.ops[3].type == GRPC_OP_SLICE); |
||||
assert_slices_equal(buf.ops[3].data.slice, test_slice_3); |
||||
GPR_ASSERT(buf.ops[4].type == GRPC_OP_SLICE); |
||||
assert_slices_equal(buf.ops[4].data.slice, test_slice_4); |
||||
GPR_ASSERT(buf.ops[5].type == GRPC_NO_OP); |
||||
|
||||
/* initialize the second buffer */ |
||||
grpc_sopb_init(&buf2); |
||||
/* add a no-op, and then the original buffer */ |
||||
grpc_sopb_add_no_op(&buf2); |
||||
grpc_sopb_append(&buf2, buf.ops, buf.nops); |
||||
/* should be one element bigger than the original */ |
||||
GPR_ASSERT(buf2.nops == buf.nops + 1); |
||||
GPR_ASSERT(buf2.ops[0].type == GRPC_NO_OP); |
||||
/* and the tail should be the same */ |
||||
for (i = 0; i < buf.nops; i++) { |
||||
GPR_ASSERT(buf2.ops[i + 1].type == buf.ops[i].type); |
||||
} |
||||
|
||||
/* destroy the buffers */ |
||||
grpc_sopb_destroy(&buf); |
||||
grpc_sopb_destroy(&buf2); |
||||
|
||||
gpr_slice_unref(test_slice_1); |
||||
gpr_slice_unref(test_slice_2); |
||||
gpr_slice_unref(test_slice_3); |
||||
gpr_slice_unref(test_slice_4); |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue