diff options
Diffstat (limited to 'test/core/compression/message_compress_test.c')
-rw-r--r-- | test/core/compression/message_compress_test.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c new file mode 100644 index 0000000000..583f187a23 --- /dev/null +++ b/test/core/compression/message_compress_test.c @@ -0,0 +1,193 @@ +/* + * + * Copyright 2014, 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/compression/message_compress.h" + +#include <stdlib.h> +#include <string.h> + +#include "test/core/util/test_config.h" +#include "src/core/support/murmur_hash.h" +#include <grpc/support/log.h> +#include <grpc/support/useful.h> +#include "test/core/util/slice_splitter.h" + +typedef enum { ONE_A = 0, ONE_KB_A, ONE_MB_A, TEST_VALUE_COUNT } test_value; + +typedef enum { + SHOULD_NOT_COMPRESS, + SHOULD_COMPRESS, + MAYBE_COMPRESSES +} compressability; + +static void assert_passthrough(gpr_slice value, + grpc_compression_algorithm algorithm, + grpc_slice_split_mode uncompressed_split_mode, + grpc_slice_split_mode compressed_split_mode, + compressability compress_result_check) { + gpr_slice_buffer input; + gpr_slice_buffer compressed_raw; + gpr_slice_buffer compressed; + gpr_slice_buffer output; + gpr_slice final; + int was_compressed; + + gpr_log(GPR_INFO, + "assert_passthrough: value_length=%d value_hash=0x%08x " + "algorithm='%s' uncompressed_split='%s' compressed_split='%s'", + GPR_SLICE_LENGTH(value), gpr_murmur_hash3(GPR_SLICE_START_PTR(value), + GPR_SLICE_LENGTH(value), 0), + grpc_compression_algorithm_name(algorithm), + grpc_slice_split_mode_name(uncompressed_split_mode), + grpc_slice_split_mode_name(compressed_split_mode)); + + gpr_slice_buffer_init(&input); + gpr_slice_buffer_init(&compressed_raw); + gpr_slice_buffer_init(&compressed); + gpr_slice_buffer_init(&output); + + grpc_split_slices_to_buffer(uncompressed_split_mode, &value, 1, &input); + + was_compressed = grpc_msg_compress(algorithm, &input, &compressed_raw); + GPR_ASSERT(input.count > 0); + + switch (compress_result_check) { + case SHOULD_NOT_COMPRESS: + GPR_ASSERT(was_compressed == 0); + break; + case SHOULD_COMPRESS: + GPR_ASSERT(was_compressed == 1); + break; + case MAYBE_COMPRESSES: + /* no check */ + break; + } + + grpc_split_slice_buffer(compressed_split_mode, &compressed_raw, &compressed); + + GPR_ASSERT(grpc_msg_decompress( + was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed, &output)); + + final = grpc_slice_merge(output.slices, output.count); + GPR_ASSERT(0 == gpr_slice_cmp(value, final)); + + gpr_slice_buffer_destroy(&input); + gpr_slice_buffer_destroy(&compressed); + gpr_slice_buffer_destroy(&compressed_raw); + gpr_slice_buffer_destroy(&output); + gpr_slice_unref(final); +} + +static gpr_slice repeated(char c, size_t length) { + gpr_slice out = gpr_slice_malloc(length); + memset(GPR_SLICE_START_PTR(out), c, length); + return out; +} + +static compressability get_compressability( + test_value id, grpc_compression_algorithm algorithm) { + if (algorithm == GRPC_COMPRESS_NONE) return SHOULD_NOT_COMPRESS; + switch (id) { + case ONE_A: + return SHOULD_NOT_COMPRESS; + case ONE_KB_A: + case ONE_MB_A: + return SHOULD_COMPRESS; + case TEST_VALUE_COUNT: + abort(); + break; + } + return MAYBE_COMPRESSES; +} + +static gpr_slice create_test_value(test_value id) { + switch (id) { + case ONE_A: + return gpr_slice_from_copied_string("a"); + case ONE_KB_A: + return repeated('a', 1024); + case ONE_MB_A: + return repeated('a', 1024 * 1024); + case TEST_VALUE_COUNT: + abort(); + break; + } + return gpr_slice_from_copied_string("bad value"); +} + +static void test_bad_data() { + gpr_slice_buffer input; + gpr_slice_buffer output; + int i; + + gpr_slice_buffer_init(&input); + gpr_slice_buffer_init(&output); + gpr_slice_buffer_add(&input, gpr_slice_from_copied_string( + "this is not valid compressed input")); + + for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { + if (i == GRPC_COMPRESS_NONE) continue; + GPR_ASSERT(0 == grpc_msg_decompress(i, &input, &output)); + GPR_ASSERT(0 == output.count); + } + + gpr_slice_buffer_destroy(&input); + gpr_slice_buffer_destroy(&output); +} + +int main(int argc, char **argv) { + int i, j, k, m; + grpc_slice_split_mode uncompressed_split_modes[] = { + GRPC_SLICE_SPLIT_IDENTITY, GRPC_SLICE_SPLIT_ONE_BYTE}; + grpc_slice_split_mode compressed_split_modes[] = {GRPC_SLICE_SPLIT_MERGE_ALL, + GRPC_SLICE_SPLIT_IDENTITY, + GRPC_SLICE_SPLIT_ONE_BYTE}; + + grpc_test_init(argc, argv); + + for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { + for (j = 0; j < GPR_ARRAY_SIZE(uncompressed_split_modes); j++) { + for (k = 0; k < GPR_ARRAY_SIZE(compressed_split_modes); k++) { + for (m = 0; m < TEST_VALUE_COUNT; m++) { + gpr_slice slice = create_test_value(m); + assert_passthrough(slice, i, j, k, get_compressability(m, i)); + gpr_slice_unref(slice); + } + } + } + } + + test_bad_data(); + + return 0; +} |