slice_test.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  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. #include <grpc/support/port_platform.h>
  19. #include "src/core/lib/slice/slice.h"
  20. #include <inttypes.h>
  21. #include <string.h>
  22. #include <random>
  23. #include <gtest/gtest.h>
  24. #include <grpc/grpc.h>
  25. #include <grpc/slice.h>
  26. #include <grpc/support/alloc.h>
  27. #include <grpc/support/log.h>
  28. #include "src/core/lib/gprpp/memory.h"
  29. #include "src/core/lib/slice/slice_internal.h"
  30. #include "test/core/util/build.h"
  31. TEST(GrpcSliceTest, MallocReturnsSomethingSensible) {
  32. /* Calls grpc_slice_create for various lengths and verifies the internals for
  33. consistency. */
  34. size_t length;
  35. size_t i;
  36. grpc_slice slice;
  37. for (length = 0; length <= 1024; length++) {
  38. slice = grpc_slice_malloc(length);
  39. /* If there is a length, slice.data must be non-NULL. If length is zero
  40. we don't care. */
  41. if (length > GRPC_SLICE_INLINED_SIZE) {
  42. EXPECT_NE(slice.data.refcounted.bytes, nullptr);
  43. }
  44. /* Returned slice length must be what was requested. */
  45. EXPECT_EQ(GRPC_SLICE_LENGTH(slice), length);
  46. /* We must be able to write to every byte of the data */
  47. for (i = 0; i < length; i++) {
  48. GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i);
  49. }
  50. /* And finally we must succeed in destroying the slice */
  51. grpc_slice_unref_internal(slice);
  52. }
  53. }
  54. static void do_nothing(void* /*ignored*/) {}
  55. TEST(GrpcSliceTest, SliceNewReturnsSomethingSensible) {
  56. uint8_t x;
  57. grpc_slice slice = grpc_slice_new(&x, 1, do_nothing);
  58. EXPECT_NE(slice.refcount, nullptr);
  59. EXPECT_EQ(slice.data.refcounted.bytes, &x);
  60. EXPECT_EQ(slice.data.refcounted.length, 1);
  61. grpc_slice_unref_internal(slice);
  62. }
  63. /* destroy function that sets a mark to indicate it was called. */
  64. static void set_mark(void* p) { *(static_cast<int*>(p)) = 1; }
  65. TEST(GrpcSliceTest, SliceNewWithUserData) {
  66. int marker = 0;
  67. uint8_t buf[2];
  68. grpc_slice slice;
  69. buf[0] = 0;
  70. buf[1] = 1;
  71. slice = grpc_slice_new_with_user_data(buf, 2, set_mark, &marker);
  72. EXPECT_EQ(marker, 0);
  73. EXPECT_EQ(GRPC_SLICE_LENGTH(slice), 2);
  74. EXPECT_EQ(GRPC_SLICE_START_PTR(slice)[0], 0);
  75. EXPECT_EQ(GRPC_SLICE_START_PTR(slice)[1], 1);
  76. /* unref should cause destroy function to run. */
  77. grpc_slice_unref_internal(slice);
  78. EXPECT_EQ(marker, 1);
  79. }
  80. static int do_nothing_with_len_1_calls = 0;
  81. static void do_nothing_with_len_1(void* /*ignored*/, size_t len) {
  82. EXPECT_EQ(len, 1);
  83. do_nothing_with_len_1_calls++;
  84. }
  85. TEST(GrpcSliceTest, SliceNewWithLenReturnsSomethingSensible) {
  86. uint8_t x;
  87. int num_refs = 5; /* To test adding/removing an arbitrary number of refs */
  88. int i;
  89. grpc_slice slice = grpc_slice_new_with_len(&x, 1, do_nothing_with_len_1);
  90. EXPECT_NE(slice.refcount,
  91. nullptr); /* ref count is initialized to 1 at this point */
  92. EXPECT_EQ(slice.data.refcounted.bytes, &x);
  93. EXPECT_EQ(slice.data.refcounted.length, 1);
  94. EXPECT_EQ(do_nothing_with_len_1_calls, 0);
  95. /* Add an arbitrary number of refs to the slice and remoe the refs. This is to
  96. make sure that that the destroy callback (i.e do_nothing_with_len_1()) is
  97. not called until the last unref operation */
  98. for (i = 0; i < num_refs; i++) {
  99. grpc_slice_ref_internal(slice);
  100. }
  101. for (i = 0; i < num_refs; i++) {
  102. grpc_slice_unref_internal(slice);
  103. }
  104. EXPECT_EQ(do_nothing_with_len_1_calls, 0); /* Shouldn't be called yet */
  105. /* last unref */
  106. grpc_slice_unref_internal(slice);
  107. EXPECT_EQ(do_nothing_with_len_1_calls, 1);
  108. }
  109. class GrpcSliceSizedTest : public ::testing::TestWithParam<size_t> {};
  110. TEST_P(GrpcSliceSizedTest, SliceSubWorks) {
  111. const auto length = GetParam();
  112. grpc_slice slice;
  113. grpc_slice sub;
  114. unsigned i, j, k;
  115. /* Create a slice in which each byte is equal to the distance from it to the
  116. beginning of the slice. */
  117. slice = grpc_slice_malloc(length);
  118. for (i = 0; i < length; i++) {
  119. GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i);
  120. }
  121. /* Ensure that for all subsets length is correct and that we start on the
  122. correct byte. Additionally check that no copies were made. */
  123. for (i = 0; i < length; i++) {
  124. for (j = i; j < length; j++) {
  125. sub = grpc_slice_sub(slice, i, j);
  126. EXPECT_EQ(GRPC_SLICE_LENGTH(sub), j - i);
  127. for (k = 0; k < j - i; k++) {
  128. EXPECT_EQ(GRPC_SLICE_START_PTR(sub)[k], (uint8_t)(i + k));
  129. }
  130. grpc_slice_unref_internal(sub);
  131. }
  132. }
  133. grpc_slice_unref_internal(slice);
  134. }
  135. static void check_head_tail(grpc_slice slice, grpc_slice head,
  136. grpc_slice tail) {
  137. EXPECT_EQ(GRPC_SLICE_LENGTH(slice),
  138. GRPC_SLICE_LENGTH(head) + GRPC_SLICE_LENGTH(tail));
  139. EXPECT_EQ(0, memcmp(GRPC_SLICE_START_PTR(slice), GRPC_SLICE_START_PTR(head),
  140. GRPC_SLICE_LENGTH(head)));
  141. EXPECT_EQ(0, memcmp(GRPC_SLICE_START_PTR(slice) + GRPC_SLICE_LENGTH(head),
  142. GRPC_SLICE_START_PTR(tail), GRPC_SLICE_LENGTH(tail)));
  143. }
  144. TEST_P(GrpcSliceSizedTest, SliceSplitHeadWorks) {
  145. const auto length = GetParam();
  146. grpc_slice slice;
  147. grpc_slice head, tail;
  148. size_t i;
  149. gpr_log(GPR_INFO, "length=%" PRIuPTR, length);
  150. /* Create a slice in which each byte is equal to the distance from it to the
  151. beginning of the slice. */
  152. slice = grpc_slice_malloc(length);
  153. for (i = 0; i < length; i++) {
  154. GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i);
  155. }
  156. /* Ensure that for all subsets length is correct and that we start on the
  157. correct byte. Additionally check that no copies were made. */
  158. for (i = 0; i < length; i++) {
  159. tail = grpc_slice_ref_internal(slice);
  160. head = grpc_slice_split_head(&tail, i);
  161. check_head_tail(slice, head, tail);
  162. grpc_slice_unref_internal(tail);
  163. grpc_slice_unref_internal(head);
  164. }
  165. grpc_slice_unref_internal(slice);
  166. }
  167. TEST_P(GrpcSliceSizedTest, SliceSplitTailWorks) {
  168. const auto length = GetParam();
  169. grpc_slice slice;
  170. grpc_slice head, tail;
  171. size_t i;
  172. gpr_log(GPR_INFO, "length=%" PRIuPTR, length);
  173. /* Create a slice in which each byte is equal to the distance from it to the
  174. beginning of the slice. */
  175. slice = grpc_slice_malloc(length);
  176. for (i = 0; i < length; i++) {
  177. GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i);
  178. }
  179. /* Ensure that for all subsets length is correct and that we start on the
  180. correct byte. Additionally check that no copies were made. */
  181. for (i = 0; i < length; i++) {
  182. head = grpc_slice_ref_internal(slice);
  183. tail = grpc_slice_split_tail(&head, i);
  184. check_head_tail(slice, head, tail);
  185. grpc_slice_unref_internal(tail);
  186. grpc_slice_unref_internal(head);
  187. }
  188. grpc_slice_unref_internal(slice);
  189. }
  190. INSTANTIATE_TEST_SUITE_P(GrpcSliceSizedTest, GrpcSliceSizedTest,
  191. ::testing::ValuesIn([] {
  192. std::vector<size_t> out;
  193. for (size_t i = 0; i < 128; i++) {
  194. out.push_back(i);
  195. }
  196. return out;
  197. }()),
  198. [](const testing::TestParamInfo<size_t>& info) {
  199. return std::to_string(info.param);
  200. });
  201. TEST(GrpcSliceTest, SliceFromCopiedString) {
  202. static const char* text = "HELLO WORLD!";
  203. grpc_slice slice;
  204. slice = grpc_slice_from_copied_string(text);
  205. EXPECT_EQ(strlen(text), GRPC_SLICE_LENGTH(slice));
  206. EXPECT_EQ(
  207. 0, memcmp(text, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice)));
  208. grpc_slice_unref_internal(slice);
  209. }
  210. TEST(GrpcSliceTest, MovedStringSlice) {
  211. // Small string should be inlined.
  212. constexpr char kSmallStr[] = "hello12345";
  213. char* small_ptr = strdup(kSmallStr);
  214. grpc_slice small =
  215. grpc_slice_from_moved_string(grpc_core::UniquePtr<char>(small_ptr));
  216. EXPECT_EQ(GRPC_SLICE_LENGTH(small), strlen(kSmallStr));
  217. EXPECT_NE(GRPC_SLICE_START_PTR(small), reinterpret_cast<uint8_t*>(small_ptr));
  218. grpc_slice_unref_internal(small);
  219. // Large string should be move the reference.
  220. constexpr char kSLargeStr[] = "hello123456789123456789123456789";
  221. char* large_ptr = strdup(kSLargeStr);
  222. grpc_slice large =
  223. grpc_slice_from_moved_string(grpc_core::UniquePtr<char>(large_ptr));
  224. EXPECT_EQ(GRPC_SLICE_LENGTH(large), strlen(kSLargeStr));
  225. EXPECT_EQ(GRPC_SLICE_START_PTR(large), reinterpret_cast<uint8_t*>(large_ptr));
  226. grpc_slice_unref_internal(large);
  227. // Moved buffer must respect the provided length not the actual length of the
  228. // string.
  229. large_ptr = strdup(kSLargeStr);
  230. small = grpc_slice_from_moved_buffer(grpc_core::UniquePtr<char>(large_ptr),
  231. strlen(kSmallStr));
  232. EXPECT_EQ(GRPC_SLICE_LENGTH(small), strlen(kSmallStr));
  233. EXPECT_NE(GRPC_SLICE_START_PTR(small), reinterpret_cast<uint8_t*>(large_ptr));
  234. grpc_slice_unref_internal(small);
  235. }
  236. TEST(GrpcSliceTest, StringViewFromSlice) {
  237. constexpr char kStr[] = "foo";
  238. absl::string_view sv(
  239. grpc_core::StringViewFromSlice(grpc_slice_from_static_string(kStr)));
  240. EXPECT_EQ(sv, kStr);
  241. }
  242. namespace grpc_core {
  243. namespace {
  244. TEST(SliceTest, FromSmallCopiedString) {
  245. Slice slice = Slice::FromCopiedString("hello");
  246. EXPECT_EQ(slice[0], 'h');
  247. EXPECT_EQ(slice[1], 'e');
  248. EXPECT_EQ(slice[2], 'l');
  249. EXPECT_EQ(slice[3], 'l');
  250. EXPECT_EQ(slice[4], 'o');
  251. EXPECT_EQ(slice.size(), 5);
  252. EXPECT_EQ(slice.length(), 5);
  253. EXPECT_EQ(slice.as_string_view(), "hello");
  254. EXPECT_EQ(0, memcmp(slice.data(), "hello", 5));
  255. }
  256. class SliceSizedTest : public ::testing::TestWithParam<size_t> {};
  257. std::string RandomString(size_t length) {
  258. std::string str;
  259. std::random_device r;
  260. for (size_t i = 0; i < length; ++i) {
  261. str.push_back(char(r()));
  262. }
  263. return str;
  264. }
  265. TEST_P(SliceSizedTest, FromCopiedString) {
  266. const std::string str = RandomString(GetParam());
  267. Slice slice = Slice::FromCopiedString(str);
  268. EXPECT_EQ(slice.size(), str.size());
  269. EXPECT_EQ(slice.length(), str.size());
  270. EXPECT_EQ(slice.as_string_view(), str);
  271. EXPECT_EQ(0, memcmp(slice.data(), str.data(), str.size()));
  272. for (size_t i = 0; i < str.size(); ++i) {
  273. EXPECT_EQ(slice[i], uint8_t(str[i]));
  274. }
  275. EXPECT_TRUE(slice.is_equivalent(slice.Ref()));
  276. EXPECT_TRUE(slice.is_equivalent(slice.AsOwned()));
  277. EXPECT_TRUE(slice.is_equivalent(slice.Ref().TakeOwned()));
  278. }
  279. INSTANTIATE_TEST_SUITE_P(SliceSizedTest, SliceSizedTest,
  280. ::testing::ValuesIn([] {
  281. std::vector<size_t> out;
  282. size_t i = 1;
  283. size_t j = 1;
  284. while (i < 1024 * 1024) {
  285. out.push_back(j);
  286. size_t n = i + j;
  287. i = j;
  288. j = n;
  289. }
  290. return out;
  291. }()),
  292. [](const testing::TestParamInfo<size_t>& info) {
  293. return std::to_string(info.param);
  294. });
  295. size_t SumSlice(const Slice& slice) {
  296. size_t x = 0;
  297. for (size_t i = 0; i < slice.size(); ++i) {
  298. x += slice[i];
  299. }
  300. return x;
  301. }
  302. TEST(SliceTest, ExternalAsOwned) {
  303. auto external_string = absl::make_unique<std::string>(RandomString(1024));
  304. Slice slice = Slice::FromExternalString(*external_string);
  305. const auto initial_sum = SumSlice(slice);
  306. Slice owned = slice.AsOwned();
  307. EXPECT_EQ(initial_sum, SumSlice(owned));
  308. external_string.reset();
  309. // In ASAN (where we can be sure that it'll crash), go ahead and read the
  310. // bytes we just deleted.
  311. if (BuiltUnderAsan()) {
  312. ASSERT_DEATH({ SumSlice(slice); }, "");
  313. }
  314. EXPECT_EQ(initial_sum, SumSlice(owned));
  315. }
  316. TEST(SliceTest, ExternalTakeOwned) {
  317. std::unique_ptr<std::string> external_string(
  318. new std::string(RandomString(1024)));
  319. SumSlice(Slice::FromExternalString(*external_string).TakeOwned());
  320. }
  321. TEST(SliceTest, StaticSlice) {
  322. static const char* hello = "hello";
  323. StaticSlice slice = StaticSlice::FromStaticString(hello);
  324. EXPECT_EQ(slice[0], 'h');
  325. EXPECT_EQ(slice[1], 'e');
  326. EXPECT_EQ(slice[2], 'l');
  327. EXPECT_EQ(slice[3], 'l');
  328. EXPECT_EQ(slice[4], 'o');
  329. EXPECT_EQ(slice.size(), 5);
  330. EXPECT_EQ(slice.length(), 5);
  331. EXPECT_EQ(slice.as_string_view(), "hello");
  332. EXPECT_EQ(0, memcmp(slice.data(), "hello", 5));
  333. EXPECT_EQ(reinterpret_cast<const uint8_t*>(hello), slice.data());
  334. }
  335. TEST(SliceTest, SliceEquality) {
  336. auto a = Slice::FromCopiedString(
  337. "hello world 123456789123456789123456789123456789123456789");
  338. auto b = Slice::FromCopiedString(
  339. "hello world 123456789123456789123456789123456789123456789");
  340. auto c = Slice::FromCopiedString(
  341. "this is not the same as the other two strings!!!!!!!!!!!!");
  342. EXPECT_FALSE(a.is_equivalent(b));
  343. EXPECT_FALSE(b.is_equivalent(a));
  344. EXPECT_EQ(a, b);
  345. EXPECT_NE(a, c);
  346. EXPECT_NE(b, c);
  347. EXPECT_EQ(a, "hello world 123456789123456789123456789123456789123456789");
  348. EXPECT_NE(a, "pfoooey");
  349. EXPECT_EQ(c, "this is not the same as the other two strings!!!!!!!!!!!!");
  350. EXPECT_EQ("hello world 123456789123456789123456789123456789123456789", a);
  351. EXPECT_NE("pfoooey", a);
  352. EXPECT_EQ("this is not the same as the other two strings!!!!!!!!!!!!", c);
  353. }
  354. TEST(SliceTest, LetsGetMutable) {
  355. auto slice = MutableSlice::FromCopiedString("hello");
  356. EXPECT_EQ(slice[0], 'h');
  357. EXPECT_EQ(slice[1], 'e');
  358. EXPECT_EQ(slice[2], 'l');
  359. EXPECT_EQ(slice[3], 'l');
  360. EXPECT_EQ(slice[4], 'o');
  361. EXPECT_EQ(slice.size(), 5);
  362. EXPECT_EQ(slice.length(), 5);
  363. EXPECT_EQ(slice.as_string_view(), "hello");
  364. EXPECT_EQ(0, memcmp(slice.data(), "hello", 5));
  365. slice[2] = 'm';
  366. EXPECT_EQ(slice.as_string_view(), "hemlo");
  367. for (auto& c : slice) c++;
  368. EXPECT_EQ(slice.as_string_view(), "ifnmp");
  369. }
  370. } // namespace
  371. } // namespace grpc_core
  372. int main(int argc, char** argv) {
  373. ::testing::InitGoogleTest(&argc, argv);
  374. return RUN_ALL_TESTS();
  375. }