Imported Upstream version 1.46.0
[platform/upstream/nghttp2.git] / tests / nghttp2_map_test.c
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2017 ngtcp2 contributors
5  * Copyright (c) 2012 nghttp2 contributors
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 #include "nghttp2_map_test.h"
27
28 #include <CUnit/CUnit.h>
29
30 #include "nghttp2_map.h"
31
32 typedef struct strentry {
33   nghttp2_map_key_type key;
34   const char *str;
35 } strentry;
36
37 static void strentry_init(strentry *entry, nghttp2_map_key_type key,
38                           const char *str) {
39   entry->key = key;
40   entry->str = str;
41 }
42
43 void test_nghttp2_map(void) {
44   strentry foo, FOO, bar, baz, shrubbery;
45   nghttp2_map map;
46   nghttp2_map_init(&map, nghttp2_mem_default());
47
48   strentry_init(&foo, 1, "foo");
49   strentry_init(&FOO, 1, "FOO");
50   strentry_init(&bar, 2, "bar");
51   strentry_init(&baz, 3, "baz");
52   strentry_init(&shrubbery, 4, "shrubbery");
53
54   CU_ASSERT(0 == nghttp2_map_insert(&map, foo.key, &foo));
55   CU_ASSERT(strcmp("foo", ((strentry *)nghttp2_map_find(&map, 1))->str) == 0);
56   CU_ASSERT(1 == nghttp2_map_size(&map));
57
58   CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
59             nghttp2_map_insert(&map, FOO.key, &FOO));
60
61   CU_ASSERT(1 == nghttp2_map_size(&map));
62   CU_ASSERT(strcmp("foo", ((strentry *)nghttp2_map_find(&map, 1))->str) == 0);
63
64   CU_ASSERT(0 == nghttp2_map_insert(&map, bar.key, &bar));
65   CU_ASSERT(2 == nghttp2_map_size(&map));
66
67   CU_ASSERT(0 == nghttp2_map_insert(&map, baz.key, &baz));
68   CU_ASSERT(3 == nghttp2_map_size(&map));
69
70   CU_ASSERT(0 == nghttp2_map_insert(&map, shrubbery.key, &shrubbery));
71   CU_ASSERT(4 == nghttp2_map_size(&map));
72
73   CU_ASSERT(strcmp("baz", ((strentry *)nghttp2_map_find(&map, 3))->str) == 0);
74
75   nghttp2_map_remove(&map, 3);
76   CU_ASSERT(3 == nghttp2_map_size(&map));
77   CU_ASSERT(NULL == nghttp2_map_find(&map, 3));
78
79   nghttp2_map_remove(&map, 1);
80   CU_ASSERT(2 == nghttp2_map_size(&map));
81   CU_ASSERT(NULL == nghttp2_map_find(&map, 1));
82
83   /* Erasing non-existent entry */
84   nghttp2_map_remove(&map, 1);
85   CU_ASSERT(2 == nghttp2_map_size(&map));
86   CU_ASSERT(NULL == nghttp2_map_find(&map, 1));
87
88   CU_ASSERT(strcmp("bar", ((strentry *)nghttp2_map_find(&map, 2))->str) == 0);
89   CU_ASSERT(strcmp("shrubbery", ((strentry *)nghttp2_map_find(&map, 4))->str) ==
90             0);
91
92   nghttp2_map_free(&map);
93 }
94
95 static void shuffle(int *a, int n) {
96   int i;
97   for (i = n - 1; i >= 1; --i) {
98     size_t j = (size_t)((double)(i + 1) * rand() / (RAND_MAX + 1.0));
99     int t = a[j];
100     a[j] = a[i];
101     a[i] = t;
102   }
103 }
104
105 static int eachfun(void *data, void *ptr) {
106   (void)data;
107   (void)ptr;
108
109   return 0;
110 }
111
112 #define NUM_ENT 6000
113 static strentry arr[NUM_ENT];
114 static int order[NUM_ENT];
115
116 void test_nghttp2_map_functional(void) {
117   nghttp2_map map;
118   int i;
119   strentry *ent;
120
121   nghttp2_map_init(&map, nghttp2_mem_default());
122   for (i = 0; i < NUM_ENT; ++i) {
123     strentry_init(&arr[i], (nghttp2_map_key_type)(i + 1), "foo");
124     order[i] = i + 1;
125   }
126   /* insertion */
127   shuffle(order, NUM_ENT);
128   for (i = 0; i < NUM_ENT; ++i) {
129     ent = &arr[order[i] - 1];
130     CU_ASSERT(0 == nghttp2_map_insert(&map, ent->key, ent));
131   }
132
133   CU_ASSERT(NUM_ENT == nghttp2_map_size(&map));
134
135   /* traverse */
136   nghttp2_map_each(&map, eachfun, NULL);
137   /* find */
138   shuffle(order, NUM_ENT);
139   for (i = 0; i < NUM_ENT; ++i) {
140     CU_ASSERT(NULL != nghttp2_map_find(&map, (nghttp2_map_key_type)order[i]));
141   }
142   /* remove */
143   for (i = 0; i < NUM_ENT; ++i) {
144     CU_ASSERT(0 == nghttp2_map_remove(&map, (nghttp2_map_key_type)order[i]));
145   }
146
147   /* each_free (but no op function for testing purpose) */
148   for (i = 0; i < NUM_ENT; ++i) {
149     strentry_init(&arr[i], (nghttp2_map_key_type)(i + 1), "foo");
150   }
151   /* insert once again */
152   for (i = 0; i < NUM_ENT; ++i) {
153     ent = &arr[i];
154     CU_ASSERT(0 == nghttp2_map_insert(&map, ent->key, ent));
155   }
156   nghttp2_map_each_free(&map, eachfun, NULL);
157   nghttp2_map_free(&map);
158 }
159
160 static int entry_free(void *data, void *ptr) {
161   const nghttp2_mem *mem = ptr;
162
163   mem->free(data, NULL);
164   return 0;
165 }
166
167 void test_nghttp2_map_each_free(void) {
168   const nghttp2_mem *mem = nghttp2_mem_default();
169   strentry *foo = mem->malloc(sizeof(strentry), NULL),
170            *bar = mem->malloc(sizeof(strentry), NULL),
171            *baz = mem->malloc(sizeof(strentry), NULL),
172            *shrubbery = mem->malloc(sizeof(strentry), NULL);
173   nghttp2_map map;
174   nghttp2_map_init(&map, nghttp2_mem_default());
175
176   strentry_init(foo, 1, "foo");
177   strentry_init(bar, 2, "bar");
178   strentry_init(baz, 3, "baz");
179   strentry_init(shrubbery, 4, "shrubbery");
180
181   nghttp2_map_insert(&map, foo->key, foo);
182   nghttp2_map_insert(&map, bar->key, bar);
183   nghttp2_map_insert(&map, baz->key, baz);
184   nghttp2_map_insert(&map, shrubbery->key, shrubbery);
185
186   nghttp2_map_each_free(&map, entry_free, (void *)mem);
187   nghttp2_map_free(&map);
188 }
189
190 void test_nghttp2_map_clear(void) {
191   nghttp2_mem *mem = nghttp2_mem_default();
192   nghttp2_map map;
193   strentry foo;
194
195   strentry_init(&foo, 1, "foo");
196
197   nghttp2_map_init(&map, mem);
198
199   CU_ASSERT(0 == nghttp2_map_insert(&map, foo.key, &foo));
200
201   nghttp2_map_clear(&map);
202
203   CU_ASSERT(0 == nghttp2_map_size(&map));
204
205   nghttp2_map_free(&map);
206 }