1 //
2 //
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include <grpc/slice.h>
20 #include <grpc/slice_buffer.h>
21 #include <grpc/support/alloc.h>
22 #include <stddef.h>
23
24 #include "gtest/gtest.h"
25 #include "src/core/lib/slice/slice_internal.h"
26 #include "test/core/test_util/test_config.h"
27
28 static constexpr size_t kTotalDataLength = 4096;
29
test_slice_buffer_add()30 void test_slice_buffer_add() {
31 grpc_slice_buffer buf;
32 grpc_slice aaa = grpc_slice_from_copied_string("aaa");
33 grpc_slice bb = grpc_slice_from_copied_string("bb");
34 size_t i;
35
36 grpc_slice_buffer_init(&buf);
37 for (i = 0; i < 10; i++) {
38 grpc_slice_ref(aaa);
39 grpc_slice_ref(bb);
40 grpc_slice_buffer_add(&buf, aaa);
41 grpc_slice_buffer_add(&buf, bb);
42 }
43 ASSERT_GT(buf.count, 0);
44 ASSERT_EQ(buf.length, 50);
45 grpc_slice_buffer_reset_and_unref(&buf);
46 ASSERT_EQ(buf.count, 0);
47 ASSERT_EQ(buf.length, 0);
48 for (i = 0; i < 10; i++) {
49 grpc_slice_ref(aaa);
50 grpc_slice_ref(bb);
51 grpc_slice_buffer_add(&buf, aaa);
52 grpc_slice_buffer_add(&buf, bb);
53 }
54 ASSERT_GT(buf.count, 0);
55 ASSERT_EQ(buf.length, 50);
56 for (i = 0; i < 10; i++) {
57 grpc_slice_buffer_pop(&buf);
58 grpc_slice_unref(aaa);
59 grpc_slice_unref(bb);
60 }
61 ASSERT_EQ(buf.count, 0);
62 ASSERT_EQ(buf.length, 0);
63 grpc_slice_buffer_destroy(&buf);
64 }
65
free_data(void * data,size_t len)66 static void free_data(void* data, size_t len) {
67 ASSERT_EQ(len, kTotalDataLength);
68 gpr_free(data);
69 }
70
test_slice_buffer_add_contiguous_slices()71 void test_slice_buffer_add_contiguous_slices() {
72 grpc_slice_buffer buf;
73 grpc_slice_buffer_init(&buf);
74 char* data = reinterpret_cast<char*>(gpr_malloc(kTotalDataLength));
75 ASSERT_NE(data, nullptr);
76 grpc_slice a = grpc_slice_new_with_len(data, kTotalDataLength, free_data);
77 grpc_slice s1 = grpc_slice_split_head(&a, kTotalDataLength / 4);
78 grpc_slice s2 = grpc_slice_split_head(&a, kTotalDataLength / 4);
79 grpc_slice s3 = grpc_slice_split_head(&a, kTotalDataLength / 4);
80 grpc_slice_buffer_add(&buf, s1);
81 ASSERT_EQ(buf.count, 1);
82 ASSERT_EQ(buf.length, kTotalDataLength / 4);
83 grpc_slice_buffer_add(&buf, s2);
84 ASSERT_EQ(buf.count, 1);
85 ASSERT_EQ(buf.length, kTotalDataLength / 2);
86 grpc_slice_buffer_add(&buf, s3);
87 ASSERT_EQ(buf.count, 1);
88 ASSERT_EQ(buf.length, 3 * kTotalDataLength / 4);
89 grpc_slice_buffer_add(&buf, a);
90 ASSERT_EQ(buf.count, 1);
91 ASSERT_EQ(buf.length, kTotalDataLength);
92 grpc_slice_buffer_destroy(&buf);
93 }
94
test_slice_buffer_move_first()95 void test_slice_buffer_move_first() {
96 grpc_slice slices[3];
97 grpc_slice_buffer src;
98 grpc_slice_buffer dst;
99 int idx = 0;
100 size_t src_len = 0;
101 size_t dst_len = 0;
102
103 slices[0] = grpc_slice_from_copied_string("aaa");
104 slices[1] = grpc_slice_from_copied_string("bbbb");
105 slices[2] = grpc_slice_from_copied_string("ccc");
106
107 grpc_slice_buffer_init(&src);
108 grpc_slice_buffer_init(&dst);
109 for (idx = 0; idx < 3; idx++) {
110 grpc_slice_ref(slices[idx]);
111 // For this test, it is important that we add each slice at a new
112 // slice index
113 grpc_slice_buffer_add_indexed(&src, slices[idx]);
114 grpc_slice_buffer_add_indexed(&dst, slices[idx]);
115 }
116
117 // Case 1: Move more than the first slice's length from src to dst
118 src_len = src.length;
119 dst_len = dst.length;
120 grpc_slice_buffer_move_first(&src, 4, &dst);
121 src_len -= 4;
122 dst_len += 4;
123 ASSERT_EQ(src.length, src_len);
124 ASSERT_EQ(dst.length, dst_len);
125
126 // src now has two slices ["bbb"] and ["ccc"]
127 // Case 2: Move the first slice from src to dst
128 grpc_slice_buffer_move_first(&src, 3, &dst);
129 src_len -= 3;
130 dst_len += 3;
131 ASSERT_EQ(src.length, src_len);
132 ASSERT_EQ(dst.length, dst_len);
133
134 // src now has one slice ["ccc"]
135 // Case 3: Move less than the first slice's length from src to dst
136 grpc_slice_buffer_move_first(&src, 2, &dst);
137 src_len -= 2;
138 dst_len += 2;
139 ASSERT_EQ(src.length, src_len);
140 ASSERT_EQ(dst.length, dst_len);
141 }
142
test_slice_buffer_first()143 void test_slice_buffer_first() {
144 grpc_slice slices[3];
145 slices[0] = grpc_slice_from_copied_string("aaa");
146 slices[1] = grpc_slice_from_copied_string("bbbb");
147 slices[2] = grpc_slice_from_copied_string("ccccc");
148
149 grpc_slice_buffer buf;
150 grpc_slice_buffer_init(&buf);
151 for (int idx = 0; idx < 3; ++idx) {
152 grpc_slice_ref(slices[idx]);
153 grpc_slice_buffer_add_indexed(&buf, slices[idx]);
154 }
155
156 grpc_slice* first = grpc_slice_buffer_peek_first(&buf);
157 ASSERT_EQ(GRPC_SLICE_LENGTH(*first), GRPC_SLICE_LENGTH(slices[0]));
158 ASSERT_EQ(buf.count, 3);
159 ASSERT_EQ(buf.length, 12);
160
161 grpc_slice_buffer_sub_first(&buf, 1, 2);
162 first = grpc_slice_buffer_peek_first(&buf);
163 ASSERT_EQ(GRPC_SLICE_LENGTH(*first), 1);
164 ASSERT_EQ(buf.count, 3);
165 ASSERT_EQ(buf.length, 10);
166
167 grpc_slice_buffer_remove_first(&buf);
168 first = grpc_slice_buffer_peek_first(&buf);
169 ASSERT_EQ(GRPC_SLICE_LENGTH(*first), GRPC_SLICE_LENGTH(slices[1]));
170 ASSERT_EQ(buf.count, 2);
171 ASSERT_EQ(buf.length, 9);
172
173 grpc_slice_buffer_remove_first(&buf);
174 first = grpc_slice_buffer_peek_first(&buf);
175 ASSERT_EQ(GRPC_SLICE_LENGTH(*first), GRPC_SLICE_LENGTH(slices[2]));
176 ASSERT_EQ(buf.count, 1);
177 ASSERT_EQ(buf.length, 5);
178
179 grpc_slice_buffer_remove_first(&buf);
180 ASSERT_EQ(buf.count, 0);
181 ASSERT_EQ(buf.length, 0);
182 }
183
main(int argc,char ** argv)184 int main(int argc, char** argv) {
185 grpc::testing::TestEnvironment env(&argc, argv);
186 ::testing::InitGoogleTest(&argc, argv);
187 grpc::testing::TestGrpcScope grpc_scope;
188 return RUN_ALL_TESTS();
189 }
190