blob: c514814ddc0969922dbc08c760145afbfca07628 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tillerb7f3f6e2016-03-25 17:13:09 -07003 * Copyright 2015-2016, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Craig Tillerc7762a82016-03-28 10:13:08 -070034#include "src/core/ext/transport/chttp2/transport/stream_map.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080035#include <grpc/support/log.h>
36#include "test/core/util/test_config.h"
37
Craig Tiller35696192015-05-24 15:00:37 -070038#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080039
40/* test creation & destruction */
Craig Tiller32946d32015-01-15 11:37:30 -080041static void test_no_op(void) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080042 grpc_chttp2_stream_map map;
43
Craig Tiller35696192015-05-24 15:00:37 -070044 LOG_TEST("test_no_op");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080045
46 grpc_chttp2_stream_map_init(&map, 8);
47 grpc_chttp2_stream_map_destroy(&map);
48}
49
50/* test lookup on an empty map */
Craig Tiller32946d32015-01-15 11:37:30 -080051static void test_empty_find(void) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080052 grpc_chttp2_stream_map map;
53
Craig Tiller35696192015-05-24 15:00:37 -070054 LOG_TEST("test_empty_find");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080055
56 grpc_chttp2_stream_map_init(&map, 8);
57 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 39128));
58 grpc_chttp2_stream_map_destroy(&map);
59}
60
61/* test it's safe to delete twice */
Craig Tiller32946d32015-01-15 11:37:30 -080062static void test_double_deletion(void) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080063 grpc_chttp2_stream_map map;
64
Craig Tiller35696192015-05-24 15:00:37 -070065 LOG_TEST("test_double_deletion");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080066
67 grpc_chttp2_stream_map_init(&map, 8);
68 GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map));
69 grpc_chttp2_stream_map_add(&map, 1, (void *)1);
70 GPR_ASSERT((void *)1 == grpc_chttp2_stream_map_find(&map, 1));
71 GPR_ASSERT(1 == grpc_chttp2_stream_map_size(&map));
72 GPR_ASSERT((void *)1 == grpc_chttp2_stream_map_delete(&map, 1));
73 GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map));
74 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 1));
75 GPR_ASSERT(NULL == grpc_chttp2_stream_map_delete(&map, 1));
76 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 1));
77 GPR_ASSERT(NULL == grpc_chttp2_stream_map_delete(&map, 1));
78 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 1));
79 GPR_ASSERT(NULL == grpc_chttp2_stream_map_delete(&map, 1));
80 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 1));
81 grpc_chttp2_stream_map_destroy(&map);
82}
83
84/* test add & lookup */
Craig Tiller7536af02015-12-22 13:49:30 -080085static void test_basic_add_find(uint32_t n) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080086 grpc_chttp2_stream_map map;
Craig Tiller7536af02015-12-22 13:49:30 -080087 uint32_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080088 size_t got;
89
Craig Tiller35696192015-05-24 15:00:37 -070090 LOG_TEST("test_basic_add_find");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080091 gpr_log(GPR_INFO, "n = %d", n);
92
93 grpc_chttp2_stream_map_init(&map, 8);
94 GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map));
95 for (i = 1; i <= n; i++) {
Craig Tiller7536af02015-12-22 13:49:30 -080096 grpc_chttp2_stream_map_add(&map, i, (void *)(uintptr_t)i);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080097 }
98 GPR_ASSERT(n == grpc_chttp2_stream_map_size(&map));
99 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 0));
100 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, n + 1));
101 for (i = 1; i <= n; i++) {
Craig Tiller7536af02015-12-22 13:49:30 -0800102 got = (uintptr_t)grpc_chttp2_stream_map_find(&map, i);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800103 GPR_ASSERT(i == got);
104 }
105 grpc_chttp2_stream_map_destroy(&map);
106}
107
108/* verify that for_each gets the right values during test_delete_evens_XXX */
Craig Tiller7536af02015-12-22 13:49:30 -0800109static void verify_for_each(void *user_data, uint32_t stream_id, void *ptr) {
110 uint32_t *for_each_check = user_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800111 GPR_ASSERT(ptr);
112 GPR_ASSERT(*for_each_check == stream_id);
113 *for_each_check += 2;
114}
115
Craig Tiller7536af02015-12-22 13:49:30 -0800116static void check_delete_evens(grpc_chttp2_stream_map *map, uint32_t n) {
117 uint32_t for_each_check = 1;
118 uint32_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800119 size_t got;
120
121 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(map, 0));
122 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(map, n + 1));
123 for (i = 1; i <= n; i++) {
124 if (i & 1) {
Craig Tiller7536af02015-12-22 13:49:30 -0800125 got = (uintptr_t)grpc_chttp2_stream_map_find(map, i);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800126 GPR_ASSERT(i == got);
127 } else {
128 GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(map, i));
129 }
130 }
131
132 grpc_chttp2_stream_map_for_each(map, verify_for_each, &for_each_check);
133 if (n & 1) {
134 GPR_ASSERT(for_each_check == n + 2);
135 } else {
136 GPR_ASSERT(for_each_check == n + 1);
137 }
138}
139
140/* add a bunch of keys, delete the even ones, and make sure the map is
141 consistent */
Craig Tiller7536af02015-12-22 13:49:30 -0800142static void test_delete_evens_sweep(uint32_t n) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800143 grpc_chttp2_stream_map map;
Craig Tiller7536af02015-12-22 13:49:30 -0800144 uint32_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800145
Craig Tiller35696192015-05-24 15:00:37 -0700146 LOG_TEST("test_delete_evens_sweep");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800147 gpr_log(GPR_INFO, "n = %d", n);
148
149 grpc_chttp2_stream_map_init(&map, 8);
150 for (i = 1; i <= n; i++) {
Craig Tiller7536af02015-12-22 13:49:30 -0800151 grpc_chttp2_stream_map_add(&map, i, (void *)(uintptr_t)i);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800152 }
153 for (i = 1; i <= n; i++) {
154 if ((i & 1) == 0) {
Craig Tiller7536af02015-12-22 13:49:30 -0800155 GPR_ASSERT((void *)(uintptr_t)i ==
Craig Tillerf96dfc32015-09-10 14:43:18 -0700156 grpc_chttp2_stream_map_delete(&map, i));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800157 }
158 }
159 check_delete_evens(&map, n);
160 grpc_chttp2_stream_map_destroy(&map);
161}
162
163/* add a bunch of keys, delete the even ones immediately, and make sure the map
164 is consistent */
Craig Tiller7536af02015-12-22 13:49:30 -0800165static void test_delete_evens_incremental(uint32_t n) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800166 grpc_chttp2_stream_map map;
Craig Tiller7536af02015-12-22 13:49:30 -0800167 uint32_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800168
Craig Tiller35696192015-05-24 15:00:37 -0700169 LOG_TEST("test_delete_evens_incremental");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800170 gpr_log(GPR_INFO, "n = %d", n);
171
172 grpc_chttp2_stream_map_init(&map, 8);
173 for (i = 1; i <= n; i++) {
Craig Tiller7536af02015-12-22 13:49:30 -0800174 grpc_chttp2_stream_map_add(&map, i, (void *)(uintptr_t)i);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800175 if ((i & 1) == 0) {
176 grpc_chttp2_stream_map_delete(&map, i);
177 }
178 }
179 check_delete_evens(&map, n);
180 grpc_chttp2_stream_map_destroy(&map);
181}
182
183/* add a bunch of keys, delete old ones after some time, ensure the
184 backing array does not grow */
Craig Tiller7536af02015-12-22 13:49:30 -0800185static void test_periodic_compaction(uint32_t n) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800186 grpc_chttp2_stream_map map;
Craig Tiller7536af02015-12-22 13:49:30 -0800187 uint32_t i;
188 uint32_t del;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800189
Craig Tiller35696192015-05-24 15:00:37 -0700190 LOG_TEST("test_periodic_compaction");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800191 gpr_log(GPR_INFO, "n = %d", n);
192
193 grpc_chttp2_stream_map_init(&map, 16);
194 GPR_ASSERT(map.capacity == 16);
195 for (i = 1; i <= n; i++) {
Craig Tiller7536af02015-12-22 13:49:30 -0800196 grpc_chttp2_stream_map_add(&map, i, (void *)(uintptr_t)i);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800197 if (i > 8) {
198 del = i - 8;
Craig Tiller7536af02015-12-22 13:49:30 -0800199 GPR_ASSERT((void *)(uintptr_t)del ==
Craig Tillerf96dfc32015-09-10 14:43:18 -0700200 grpc_chttp2_stream_map_delete(&map, del));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800201 }
202 }
203 GPR_ASSERT(map.capacity == 16);
204 grpc_chttp2_stream_map_destroy(&map);
205}
206
207int main(int argc, char **argv) {
Craig Tiller7536af02015-12-22 13:49:30 -0800208 uint32_t n = 1;
209 uint32_t prev = 1;
210 uint32_t tmp;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800211
212 grpc_test_init(argc, argv);
213
214 test_no_op();
215 test_empty_find();
216 test_double_deletion();
217
Craig Tillerf5065c52015-02-27 16:17:39 -0800218 while (n < 100000) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800219 test_basic_add_find(n);
220 test_delete_evens_sweep(n);
221 test_delete_evens_incremental(n);
222 test_periodic_compaction(n);
223
224 tmp = n;
225 n += prev;
226 prev = tmp;
227 }
228
229 return 0;
Craig Tiller190d3602015-02-18 09:23:38 -0800230}