Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * 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 :
34 : #include <grpc/support/slice.h>
35 :
36 : #include <string.h>
37 :
38 : #include <grpc/support/alloc.h>
39 : #include <grpc/support/log.h>
40 : #include "test/core/util/test_config.h"
41 :
42 : #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x);
43 :
44 1 : static void test_slice_malloc_returns_something_sensible(void) {
45 : /* Calls gpr_slice_create for various lengths and verifies the internals for
46 : consistency. */
47 : size_t length;
48 : size_t i;
49 : gpr_slice slice;
50 :
51 1 : LOG_TEST_NAME("test_slice_malloc_returns_something_sensible");
52 :
53 1026 : for (length = 0; length <= 1024; length++) {
54 1025 : slice = gpr_slice_malloc(length);
55 : /* If there is a length, slice.data must be non-NULL. If length is zero
56 : we don't care. */
57 1025 : if (length) {
58 1024 : GPR_ASSERT(GPR_SLICE_START_PTR(slice));
59 : }
60 : /* Returned slice length must be what was requested. */
61 1025 : GPR_ASSERT(GPR_SLICE_LENGTH(slice) == length);
62 : /* If the slice has a refcount, it must be destroyable. */
63 1025 : if (slice.refcount) {
64 1009 : GPR_ASSERT(slice.refcount->ref != NULL);
65 1009 : GPR_ASSERT(slice.refcount->unref != NULL);
66 : }
67 : /* We must be able to write to every byte of the data */
68 525825 : for (i = 0; i < length; i++) {
69 524800 : GPR_SLICE_START_PTR(slice)[i] = (gpr_uint8)i;
70 : }
71 : /* And finally we must succeed in destroying the slice */
72 1025 : gpr_slice_unref(slice);
73 : }
74 1 : }
75 :
76 1 : static void do_nothing(void *ignored) {}
77 :
78 1 : static void test_slice_new_returns_something_sensible(void) {
79 : gpr_uint8 x;
80 :
81 1 : gpr_slice slice = gpr_slice_new(&x, 1, do_nothing);
82 1 : GPR_ASSERT(slice.refcount);
83 1 : GPR_ASSERT(slice.data.refcounted.bytes == &x);
84 1 : GPR_ASSERT(slice.data.refcounted.length == 1);
85 1 : gpr_slice_unref(slice);
86 1 : }
87 :
88 : static int do_nothing_with_len_1_calls = 0;
89 :
90 1 : static void do_nothing_with_len_1(void *ignored, size_t len) {
91 1 : GPR_ASSERT(len == 1);
92 1 : do_nothing_with_len_1_calls++;
93 1 : }
94 :
95 1 : static void test_slice_new_with_len_returns_something_sensible(void) {
96 : gpr_uint8 x;
97 :
98 1 : gpr_slice slice = gpr_slice_new_with_len(&x, 1, do_nothing_with_len_1);
99 1 : GPR_ASSERT(slice.refcount);
100 1 : GPR_ASSERT(slice.data.refcounted.bytes == &x);
101 1 : GPR_ASSERT(slice.data.refcounted.length == 1);
102 1 : GPR_ASSERT(do_nothing_with_len_1_calls == 0);
103 1 : gpr_slice_unref(slice);
104 1 : GPR_ASSERT(do_nothing_with_len_1_calls == 1);
105 1 : }
106 :
107 128 : static void test_slice_sub_works(unsigned length) {
108 : gpr_slice slice;
109 : gpr_slice sub;
110 : unsigned i, j, k;
111 :
112 128 : LOG_TEST_NAME("test_slice_sub_works");
113 128 : gpr_log(GPR_INFO, "length=%d", length);
114 :
115 : /* Create a slice in which each byte is equal to the distance from it to the
116 : beginning of the slice. */
117 128 : slice = gpr_slice_malloc(length);
118 8256 : for (i = 0; i < length; i++) {
119 8128 : GPR_SLICE_START_PTR(slice)[i] = (gpr_uint8)i;
120 : }
121 :
122 : /* Ensure that for all subsets length is correct and that we start on the
123 : correct byte. Additionally check that no copies were made. */
124 8256 : for (i = 0; i < length; i++) {
125 357632 : for (j = i; j < length; j++) {
126 349504 : sub = gpr_slice_sub(slice, i, j);
127 349504 : GPR_ASSERT(GPR_SLICE_LENGTH(sub) == j - i);
128 11358880 : for (k = 0; k < j - i; k++) {
129 11009376 : GPR_ASSERT(GPR_SLICE_START_PTR(sub)[k] == (gpr_uint8)(i + k));
130 : }
131 349504 : gpr_slice_unref(sub);
132 : }
133 : }
134 128 : gpr_slice_unref(slice);
135 128 : }
136 :
137 16256 : static void check_head_tail(gpr_slice slice, gpr_slice head, gpr_slice tail) {
138 16256 : GPR_ASSERT(GPR_SLICE_LENGTH(slice) ==
139 : GPR_SLICE_LENGTH(head) + GPR_SLICE_LENGTH(tail));
140 16256 : GPR_ASSERT(0 == memcmp(GPR_SLICE_START_PTR(slice), GPR_SLICE_START_PTR(head),
141 : GPR_SLICE_LENGTH(head)));
142 16256 : GPR_ASSERT(0 == memcmp(GPR_SLICE_START_PTR(slice) + GPR_SLICE_LENGTH(head),
143 : GPR_SLICE_START_PTR(tail), GPR_SLICE_LENGTH(tail)));
144 16256 : }
145 :
146 128 : static void test_slice_split_head_works(size_t length) {
147 : gpr_slice slice;
148 : gpr_slice head, tail;
149 : size_t i;
150 :
151 128 : LOG_TEST_NAME("test_slice_split_head_works");
152 128 : gpr_log(GPR_INFO, "length=%d", length);
153 :
154 : /* Create a slice in which each byte is equal to the distance from it to the
155 : beginning of the slice. */
156 128 : slice = gpr_slice_malloc(length);
157 8256 : for (i = 0; i < length; i++) {
158 8128 : GPR_SLICE_START_PTR(slice)[i] = (gpr_uint8)i;
159 : }
160 :
161 : /* Ensure that for all subsets length is correct and that we start on the
162 : correct byte. Additionally check that no copies were made. */
163 8256 : for (i = 0; i < length; i++) {
164 8128 : tail = gpr_slice_ref(slice);
165 8128 : head = gpr_slice_split_head(&tail, i);
166 8128 : check_head_tail(slice, head, tail);
167 8128 : gpr_slice_unref(tail);
168 8128 : gpr_slice_unref(head);
169 : }
170 :
171 128 : gpr_slice_unref(slice);
172 128 : }
173 :
174 128 : static void test_slice_split_tail_works(size_t length) {
175 : gpr_slice slice;
176 : gpr_slice head, tail;
177 : size_t i;
178 :
179 128 : LOG_TEST_NAME("test_slice_split_tail_works");
180 128 : gpr_log(GPR_INFO, "length=%d", length);
181 :
182 : /* Create a slice in which each byte is equal to the distance from it to the
183 : beginning of the slice. */
184 128 : slice = gpr_slice_malloc(length);
185 8256 : for (i = 0; i < length; i++) {
186 8128 : GPR_SLICE_START_PTR(slice)[i] = (gpr_uint8)i;
187 : }
188 :
189 : /* Ensure that for all subsets length is correct and that we start on the
190 : correct byte. Additionally check that no copies were made. */
191 8256 : for (i = 0; i < length; i++) {
192 8128 : head = gpr_slice_ref(slice);
193 8128 : tail = gpr_slice_split_tail(&head, i);
194 8128 : check_head_tail(slice, head, tail);
195 8128 : gpr_slice_unref(tail);
196 8128 : gpr_slice_unref(head);
197 : }
198 :
199 128 : gpr_slice_unref(slice);
200 128 : }
201 :
202 1 : static void test_slice_from_copied_string_works(void) {
203 : static const char *text = "HELLO WORLD!";
204 : gpr_slice slice;
205 :
206 1 : LOG_TEST_NAME("test_slice_from_copied_string_works");
207 :
208 1 : slice = gpr_slice_from_copied_string(text);
209 1 : GPR_ASSERT(strlen(text) == GPR_SLICE_LENGTH(slice));
210 1 : GPR_ASSERT(0 ==
211 : memcmp(text, GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice)));
212 1 : gpr_slice_unref(slice);
213 1 : }
214 :
215 1 : int main(int argc, char **argv) {
216 : unsigned length;
217 1 : grpc_test_init(argc, argv);
218 1 : test_slice_malloc_returns_something_sensible();
219 1 : test_slice_new_returns_something_sensible();
220 1 : test_slice_new_with_len_returns_something_sensible();
221 129 : for (length = 0; length < 128; length++) {
222 128 : test_slice_sub_works(length);
223 128 : test_slice_split_head_works(length);
224 128 : test_slice_split_tail_works(length);
225 : }
226 1 : test_slice_from_copied_string_works();
227 1 : return 0;
228 : }
|