core/slice/slice_test.cc
Go to the documentation of this file.
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 
20 
22 
23 #include <inttypes.h>
24 #include <string.h>
25 
26 #include <random>
27 
28 #include <gtest/gtest.h>
29 
30 #include "absl/memory/memory.h"
31 
32 #include <grpc/grpc.h>
33 #include <grpc/slice.h>
34 #include <grpc/support/alloc.h>
35 #include <grpc/support/log.h>
36 
39 #include "test/core/util/build.h"
40 
41 TEST(GrpcSliceTest, MallocReturnsSomethingSensible) {
42  /* Calls grpc_slice_create for various lengths and verifies the internals for
43  consistency. */
44  size_t length;
45  size_t i;
47 
48  for (length = 0; length <= 1024; length++) {
50  /* If there is a length, slice.data must be non-NULL. If length is zero
51  we don't care. */
54  }
55  /* Returned slice length must be what was requested. */
57  /* We must be able to write to every byte of the data */
58  for (i = 0; i < length; i++) {
59  GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i);
60  }
61  /* And finally we must succeed in destroying the slice */
63  }
64 }
65 
66 static void do_nothing(void* /*ignored*/) {}
67 
68 TEST(GrpcSliceTest, SliceNewReturnsSomethingSensible) {
69  uint8_t x;
70 
72  EXPECT_NE(slice.refcount, nullptr);
76 }
77 
78 /* destroy function that sets a mark to indicate it was called. */
79 static void set_mark(void* p) { *(static_cast<int*>(p)) = 1; }
80 
81 TEST(GrpcSliceTest, SliceNewWithUserData) {
82  int marker = 0;
83  uint8_t buf[2];
85 
86  buf[0] = 0;
87  buf[1] = 1;
89  EXPECT_EQ(marker, 0);
93 
94  /* unref should cause destroy function to run. */
96  EXPECT_EQ(marker, 1);
97 }
98 
100 
101 static void do_nothing_with_len_1(void* /*ignored*/, size_t len) {
102  EXPECT_EQ(len, 1);
104 }
105 
106 TEST(GrpcSliceTest, SliceNewWithLenReturnsSomethingSensible) {
107  uint8_t x;
108  int num_refs = 5; /* To test adding/removing an arbitrary number of refs */
109  int i;
110 
113  nullptr); /* ref count is initialized to 1 at this point */
117 
118  /* Add an arbitrary number of refs to the slice and remoe the refs. This is to
119  make sure that that the destroy callback (i.e do_nothing_with_len_1()) is
120  not called until the last unref operation */
121  for (i = 0; i < num_refs; i++) {
123  }
124  for (i = 0; i < num_refs; i++) {
126  }
127  EXPECT_EQ(do_nothing_with_len_1_calls, 0); /* Shouldn't be called yet */
128 
129  /* last unref */
132 }
133 
135 
136 TEST_P(GrpcSliceSizedTest, SliceSubWorks) {
137  const auto length = GetParam();
138 
140  grpc_slice sub;
141  unsigned i, j, k;
142 
143  /* Create a slice in which each byte is equal to the distance from it to the
144  beginning of the slice. */
146  for (i = 0; i < length; i++) {
147  GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i);
148  }
149 
150  /* Ensure that for all subsets length is correct and that we start on the
151  correct byte. Additionally check that no copies were made. */
152  for (i = 0; i < length; i++) {
153  for (j = i; j < length; j++) {
154  sub = grpc_slice_sub(slice, i, j);
155  EXPECT_EQ(GRPC_SLICE_LENGTH(sub), j - i);
156  for (k = 0; k < j - i; k++) {
157  EXPECT_EQ(GRPC_SLICE_START_PTR(sub)[k], (uint8_t)(i + k));
158  }
160  }
161  }
163 }
164 
166  grpc_slice tail) {
168  GRPC_SLICE_LENGTH(head) + GRPC_SLICE_LENGTH(tail));
170  GRPC_SLICE_LENGTH(head)));
173 }
174 
175 TEST_P(GrpcSliceSizedTest, SliceSplitHeadWorks) {
176  const auto length = GetParam();
177 
179  grpc_slice head, tail;
180  size_t i;
181 
182  gpr_log(GPR_INFO, "length=%" PRIuPTR, length);
183 
184  /* Create a slice in which each byte is equal to the distance from it to the
185  beginning of the slice. */
187  for (i = 0; i < length; i++) {
188  GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i);
189  }
190 
191  /* Ensure that for all subsets length is correct and that we start on the
192  correct byte. Additionally check that no copies were made. */
193  for (i = 0; i < length; i++) {
195  head = grpc_slice_split_head(&tail, i);
196  check_head_tail(slice, head, tail);
199  }
200 
202 }
203 
204 TEST_P(GrpcSliceSizedTest, SliceSplitTailWorks) {
205  const auto length = GetParam();
206 
208  grpc_slice head, tail;
209  size_t i;
210 
211  gpr_log(GPR_INFO, "length=%" PRIuPTR, length);
212 
213  /* Create a slice in which each byte is equal to the distance from it to the
214  beginning of the slice. */
216  for (i = 0; i < length; i++) {
217  GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i);
218  }
219 
220  /* Ensure that for all subsets length is correct and that we start on the
221  correct byte. Additionally check that no copies were made. */
222  for (i = 0; i < length; i++) {
224  tail = grpc_slice_split_tail(&head, i);
225  check_head_tail(slice, head, tail);
228  }
229 
231 }
232 
234  ::testing::ValuesIn([] {
235  std::vector<size_t> out;
236  for (size_t i = 0; i < 128; i++) {
237  out.push_back(i);
238  }
239  return out;
240  }()),
241  [](const testing::TestParamInfo<size_t>& info) {
242  return std::to_string(info.param);
243  });
244 
245 TEST(GrpcSliceTest, SliceFromCopiedString) {
246  static const char* text = "HELLO WORLD!";
248 
251  EXPECT_EQ(
254 }
255 
256 TEST(GrpcSliceTest, MovedStringSlice) {
257  // Small string should be inlined.
258  constexpr char kSmallStr[] = "hello12345";
259  char* small_ptr = strdup(kSmallStr);
260  grpc_slice small =
262  EXPECT_EQ(GRPC_SLICE_LENGTH(small), strlen(kSmallStr));
263  EXPECT_NE(GRPC_SLICE_START_PTR(small), reinterpret_cast<uint8_t*>(small_ptr));
265 
266  // Large string should be move the reference.
267  constexpr char kSLargeStr[] = "hello123456789123456789123456789";
268  char* large_ptr = strdup(kSLargeStr);
269  grpc_slice large =
271  EXPECT_EQ(GRPC_SLICE_LENGTH(large), strlen(kSLargeStr));
272  EXPECT_EQ(GRPC_SLICE_START_PTR(large), reinterpret_cast<uint8_t*>(large_ptr));
274 
275  // Moved buffer must respect the provided length not the actual length of the
276  // string.
277  large_ptr = strdup(kSLargeStr);
279  strlen(kSmallStr));
280  EXPECT_EQ(GRPC_SLICE_LENGTH(small), strlen(kSmallStr));
281  EXPECT_NE(GRPC_SLICE_START_PTR(small), reinterpret_cast<uint8_t*>(large_ptr));
283 }
284 
285 TEST(GrpcSliceTest, StringViewFromSlice) {
286  constexpr char kStr[] = "foo";
289  EXPECT_EQ(sv, kStr);
290 }
291 
292 namespace grpc_core {
293 namespace {
294 
295 TEST(SliceTest, FromSmallCopiedString) {
296  Slice slice = Slice::FromCopiedString("hello");
297  EXPECT_EQ(slice[0], 'h');
298  EXPECT_EQ(slice[1], 'e');
299  EXPECT_EQ(slice[2], 'l');
300  EXPECT_EQ(slice[3], 'l');
301  EXPECT_EQ(slice[4], 'o');
302  EXPECT_EQ(slice.size(), 5);
303  EXPECT_EQ(slice.length(), 5);
304  EXPECT_EQ(slice.as_string_view(), "hello");
305  EXPECT_EQ(0, memcmp(slice.data(), "hello", 5));
306 }
307 
308 class SliceSizedTest : public ::testing::TestWithParam<size_t> {};
309 
310 std::string RandomString(size_t length) {
312  std::random_device r;
313  for (size_t i = 0; i < length; ++i) {
314  str.push_back(char(r()));
315  }
316  return str;
317 }
318 
319 TEST_P(SliceSizedTest, FromCopiedString) {
320  const std::string str = RandomString(GetParam());
322 
323  EXPECT_EQ(slice.size(), str.size());
324  EXPECT_EQ(slice.length(), str.size());
325  EXPECT_EQ(slice.as_string_view(), str);
326  EXPECT_EQ(0, memcmp(slice.data(), str.data(), str.size()));
327  for (size_t i = 0; i < str.size(); ++i) {
328  EXPECT_EQ(slice[i], uint8_t(str[i]));
329  }
330 
331  EXPECT_TRUE(slice.is_equivalent(slice.Ref()));
332  EXPECT_TRUE(slice.is_equivalent(slice.AsOwned()));
333  EXPECT_TRUE(slice.is_equivalent(slice.Ref().TakeOwned()));
334 }
335 
336 INSTANTIATE_TEST_SUITE_P(SliceSizedTest, SliceSizedTest,
337  ::testing::ValuesIn([] {
338  std::vector<size_t> out;
339  size_t i = 1;
340  size_t j = 1;
341  while (i < 1024 * 1024) {
342  out.push_back(j);
343  size_t n = i + j;
344  i = j;
345  j = n;
346  }
347  return out;
348  }()),
349  [](const testing::TestParamInfo<size_t>& info) {
350  return std::to_string(info.param);
351  });
352 
353 size_t SumSlice(const Slice& slice) {
354  size_t x = 0;
355  for (size_t i = 0; i < slice.size(); ++i) {
356  x += slice[i];
357  }
358  return x;
359 }
360 
361 TEST(SliceTest, ExternalAsOwned) {
362  auto external_string = absl::make_unique<std::string>(RandomString(1024));
363  Slice slice = Slice::FromExternalString(*external_string);
364  const auto initial_sum = SumSlice(slice);
365  Slice owned = slice.AsOwned();
366  EXPECT_EQ(initial_sum, SumSlice(owned));
367  external_string.reset();
368  // In ASAN (where we can be sure that it'll crash), go ahead and read the
369  // bytes we just deleted.
370  if (BuiltUnderAsan()) {
371  ASSERT_DEATH({ SumSlice(slice); }, "");
372  }
373  EXPECT_EQ(initial_sum, SumSlice(owned));
374 }
375 
376 TEST(SliceTest, ExternalTakeOwned) {
377  std::unique_ptr<std::string> external_string(
378  new std::string(RandomString(1024)));
379  SumSlice(Slice::FromExternalString(*external_string).TakeOwned());
380 }
381 
382 TEST(SliceTest, StaticSlice) {
383  static const char* hello = "hello";
385  EXPECT_EQ(slice[0], 'h');
386  EXPECT_EQ(slice[1], 'e');
387  EXPECT_EQ(slice[2], 'l');
388  EXPECT_EQ(slice[3], 'l');
389  EXPECT_EQ(slice[4], 'o');
390  EXPECT_EQ(slice.size(), 5);
391  EXPECT_EQ(slice.length(), 5);
392  EXPECT_EQ(slice.as_string_view(), "hello");
393  EXPECT_EQ(0, memcmp(slice.data(), "hello", 5));
394  EXPECT_EQ(reinterpret_cast<const uint8_t*>(hello), slice.data());
395 }
396 
397 TEST(SliceTest, SliceEquality) {
398  auto a = Slice::FromCopiedString(
399  "hello world 123456789123456789123456789123456789123456789");
400  auto b = Slice::FromCopiedString(
401  "hello world 123456789123456789123456789123456789123456789");
402  auto c = Slice::FromCopiedString(
403  "this is not the same as the other two strings!!!!!!!!!!!!");
404  EXPECT_FALSE(a.is_equivalent(b));
405  EXPECT_FALSE(b.is_equivalent(a));
406  EXPECT_EQ(a, b);
407  EXPECT_NE(a, c);
408  EXPECT_NE(b, c);
409  EXPECT_EQ(a, "hello world 123456789123456789123456789123456789123456789");
410  EXPECT_NE(a, "pfoooey");
411  EXPECT_EQ(c, "this is not the same as the other two strings!!!!!!!!!!!!");
412  EXPECT_EQ("hello world 123456789123456789123456789123456789123456789", a);
413  EXPECT_NE("pfoooey", a);
414  EXPECT_EQ("this is not the same as the other two strings!!!!!!!!!!!!", c);
415 }
416 
417 TEST(SliceTest, LetsGetMutable) {
418  auto slice = MutableSlice::FromCopiedString("hello");
419  EXPECT_EQ(slice[0], 'h');
420  EXPECT_EQ(slice[1], 'e');
421  EXPECT_EQ(slice[2], 'l');
422  EXPECT_EQ(slice[3], 'l');
423  EXPECT_EQ(slice[4], 'o');
424  EXPECT_EQ(slice.size(), 5);
425  EXPECT_EQ(slice.length(), 5);
426  EXPECT_EQ(slice.as_string_view(), "hello");
427  EXPECT_EQ(0, memcmp(slice.data(), "hello", 5));
428  slice[2] = 'm';
429  EXPECT_EQ(slice.as_string_view(), "hemlo");
430  for (auto& c : slice) c++;
431  EXPECT_EQ(slice.as_string_view(), "ifnmp");
432 }
433 
434 } // namespace
435 } // namespace grpc_core
436 
437 int main(int argc, char** argv) {
438  ::testing::InitGoogleTest(&argc, argv);
439  return RUN_ALL_TESTS();
440 }
xds_interop_client.str
str
Definition: xds_interop_client.py:487
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
slice.h
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
log.h
absl::str_format_internal::LengthMod::j
@ j
grpc_slice::refcount
struct grpc_slice_refcount * refcount
Definition: include/grpc/impl/codegen/slice.h:66
grpc_slice_ref_internal
const grpc_slice & grpc_slice_ref_internal(const grpc_slice &slice)
Definition: slice_refcount.h:32
BuiltUnderAsan
bool BuiltUnderAsan()
Definition: build.cc:39
fix_build_deps.c
list c
Definition: fix_build_deps.py:490
grpc_slice_from_moved_string
grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr< char > p)
Definition: slice/slice.cc:197
grpc_slice_from_copied_string
GPRAPI grpc_slice grpc_slice_from_copied_string(const char *source)
Definition: slice/slice.cc:177
slice.h
grpc_slice::grpc_slice_data::grpc_slice_refcounted::length
size_t length
Definition: include/grpc/impl/codegen/slice.h:69
grpc_core
Definition: call_metric_recorder.h:31
large
int large
Definition: bloaty/third_party/zlib/examples/enough.c:172
grpc_slice_new
GPRAPI grpc_slice grpc_slice_new(void *p, size_t len, void(*destroy)(void *))
Definition: slice/slice.cc:103
string.h
grpc_core::slice_detail::StaticConstructors< StaticSlice >::FromStaticString
static StaticSlice FromStaticString(const char *s)
Definition: src/core/lib/slice/slice.h:201
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
grpc::SliceFromCopiedString
grpc_slice SliceFromCopiedString(const std::string &str)
Definition: include/grpcpp/impl/codegen/slice.h:149
grpc_core::StringViewFromSlice
absl::string_view StringViewFromSlice(const grpc_slice &slice)
Definition: slice_internal.h:93
INSTANTIATE_TEST_SUITE_P
INSTANTIATE_TEST_SUITE_P(GrpcSliceSizedTest, GrpcSliceSizedTest, ::testing::ValuesIn([] { std::vector< size_t > out;for(size_t i=0;i< 128;i++) { out.push_back(i);} return out;}()), [](const testing::TestParamInfo< size_t > &info) { return std::to_string(info.param);})
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc_core::TEST
TEST(AvlTest, NoOp)
Definition: avl_test.cc:21
testing::TestParamInfo
Definition: bloaty/third_party/googletest/googletest/include/gtest/internal/gtest-param-util.h:56
grpc_slice_sub
GPRAPI grpc_slice grpc_slice_sub(grpc_slice s, size_t begin, size_t end)
Definition: slice/slice.cc:268
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
xds_manager.p
p
Definition: xds_manager.py:60
check_head_tail
static void check_head_tail(grpc_slice slice, grpc_slice head, grpc_slice tail)
Definition: core/slice/slice_test.cc:165
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
setup.k
k
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
grpc_slice_malloc
GPRAPI grpc_slice grpc_slice_malloc(size_t length)
Definition: slice/slice.cc:227
testing::TestWithParam
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1883
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
memory.h
set_mark
static void set_mark(void *p)
Definition: core/slice/slice_test.cc:79
hello
static z_const char hello[]
Definition: bloaty/third_party/zlib/test/example.c:29
build.h
TEST
TEST(GrpcSliceTest, MallocReturnsSomethingSensible)
Definition: core/slice/slice_test.cc:41
grpc_core::slice_detail::CopyConstructors< Slice >::FromCopiedString
static Slice FromCopiedString(const char *s)
Definition: src/core/lib/slice/slice.h:173
gen_server_registered_method_bad_client_test_body.text
def text
Definition: gen_server_registered_method_bad_client_test_body.py:50
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
slice
grpc_slice slice
Definition: src/core/lib/surface/server.cc:467
TEST_P
TEST_P(GrpcSliceSizedTest, SliceSubWorks)
Definition: core/slice/slice_test.cc:136
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
grpc_core::Slice::TakeOwned
Slice TakeOwned()
Definition: src/core/lib/slice/slice.h:310
grpc.h
GRPC_SLICE_START_PTR
#define GRPC_SLICE_START_PTR(slice)
Definition: include/grpc/impl/codegen/slice.h:101
grpc_slice_from_static_string
GPRAPI grpc_slice grpc_slice_from_static_string(const char *source)
Definition: slice/slice.cc:89
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
main
int main(int argc, char **argv)
Definition: core/slice/slice_test.cc:437
GrpcSliceSizedTest
Definition: core/slice/slice_test.cc:134
slice_internal.h
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
grpc_core::UniquePtr
std::unique_ptr< T, DefaultDeleteChar > UniquePtr
Definition: src/core/lib/gprpp/memory.h:43
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
GRPC_SLICE_LENGTH
#define GRPC_SLICE_LENGTH(slice)
Definition: include/grpc/impl/codegen/slice.h:104
grpc_slice_new_with_user_data
GPRAPI grpc_slice grpc_slice_new_with_user_data(void *p, size_t len, void(*destroy)(void *), void *user_data)
Definition: slice/slice.cc:93
do_nothing_with_len_1
static void do_nothing_with_len_1(void *, size_t len)
Definition: core/slice/slice_test.cc:101
grpc_slice::grpc_slice_data::refcounted
struct grpc_slice::grpc_slice_data::grpc_slice_refcounted refcounted
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
do_nothing
static void do_nothing(void *)
Definition: core/slice/slice_test.cc:66
grpc_core::Slice::FromExternalString
static Slice FromExternalString(absl::string_view str)
Definition: src/core/lib/slice/slice.h:382
alloc.h
fix_build_deps.r
r
Definition: fix_build_deps.py:491
grpc_slice::data
union grpc_slice::grpc_slice_data data
GRPC_SLICE_INLINED_SIZE
#define GRPC_SLICE_INLINED_SIZE
Definition: include/grpc/impl/codegen/slice.h:49
grpc_slice_split_head
GPRAPI grpc_slice grpc_slice_split_head(grpc_slice *s, size_t split)
Definition: slice/slice.cc:347
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
grpc_slice::grpc_slice_data::grpc_slice_refcounted::bytes
uint8_t * bytes
Definition: include/grpc/impl/codegen/slice.h:70
testing::ValuesIn
internal::ParamGenerator< typename std::iterator_traits< ForwardIterator >::value_type > ValuesIn(ForwardIterator begin, ForwardIterator end)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:297
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
to_string
static bool to_string(zval *from)
Definition: protobuf/php/ext/google/protobuf/convert.c:333
grpc_slice_from_moved_buffer
grpc_slice grpc_slice_from_moved_buffer(grpc_core::UniquePtr< char > p, size_t len)
Definition: slice/slice.cc:181
do_nothing_with_len_1_calls
static int do_nothing_with_len_1_calls
Definition: core/slice/slice_test.cc:99
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
grpc_slice_unref_internal
void grpc_slice_unref_internal(const grpc_slice &slice)
Definition: slice_refcount.h:39
grpc_slice_new_with_len
GPRAPI grpc_slice grpc_slice_new_with_len(void *p, size_t len, void(*destroy)(void *, size_t))
Definition: slice/slice.cc:161
grpc_slice_split_tail
GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice *s, size_t split)
Definition: slice/slice.cc:343
owned
bool owned
Definition: src/php/ext/grpc/call.h:31
strdup
#define strdup(ptr)
Definition: acountry.c:55
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:13