/Users/deen/code/yugabyte-db/src/yb/rpc/growable_buffer-test.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | // |
15 | | |
16 | | #include <gtest/gtest.h> |
17 | | |
18 | | #include "yb/rpc/growable_buffer.h" |
19 | | |
20 | | #include "yb/util/result.h" |
21 | | #include "yb/util/test_macros.h" |
22 | | #include "yb/util/test_util.h" |
23 | | |
24 | | namespace yb { |
25 | | namespace rpc { |
26 | | |
27 | | constexpr size_t kBlockSize = 0x100; |
28 | | constexpr size_t kSizeLimit = 0x1000; |
29 | | |
30 | | class GrowableBufferTest : public YBTest { |
31 | | protected: |
32 | | GrowableBufferAllocator allocator_{kBlockSize, MemTrackerPtr()}; |
33 | | }; |
34 | | |
35 | 1 | TEST_F(GrowableBufferTest, TestLimit) { |
36 | 1 | GrowableBuffer buffer(&allocator_, kSizeLimit); |
37 | | |
38 | 1 | ASSERT_EQ(buffer.capacity_left(), kBlockSize); |
39 | 4.09k | for (;;) { |
40 | 4.09k | auto result = buffer.PrepareAppend(); |
41 | 8.19k | ASSERT_EQ(result.ok(), buffer.size() < buffer.limit()) |
42 | 0 | << "Status: " << (result.ok() ? Status::OK() : result.status()); |
43 | 4.09k | if (!result.ok()) { |
44 | 1 | break; |
45 | 1 | } |
46 | 4.09k | buffer.DataAppended(1); |
47 | 4.09k | } |
48 | | |
49 | 1 | ASSERT_EQ(buffer.capacity_left(), 0); |
50 | 1 | } |
51 | | |
52 | 1 | TEST_F(GrowableBufferTest, TestPrepareRead) { |
53 | 1 | GrowableBuffer buffer(&allocator_, kSizeLimit); |
54 | | |
55 | 1 | unsigned int seed = SeedRandom(); |
56 | | |
57 | 34 | while (buffer.size() != buffer.limit()) { |
58 | 33 | auto status = buffer.PrepareAppend(); |
59 | 33 | ASSERT_OK(status); |
60 | 33 | size_t step = 1 + rand_r(&seed) % buffer.capacity_left(); |
61 | 33 | buffer.DataAppended(step); |
62 | 33 | } |
63 | | |
64 | 1 | ASSERT_EQ(buffer.capacity_left(), 0); |
65 | 1 | } |
66 | | |
67 | 1 | TEST_F(GrowableBufferTest, TestConsume) { |
68 | 1 | GrowableBuffer buffer(&allocator_, kSizeLimit); |
69 | | |
70 | 1 | int counter = 0; |
71 | | |
72 | 1 | unsigned int seed = SeedRandom(); |
73 | 1 | size_t consumed = 0; |
74 | | |
75 | 10.0k | for (auto i = 10000; i--;) { |
76 | 10.0k | size_t step = 1 + rand_r(&seed) % (buffer.limit() - buffer.size()); |
77 | 10.0k | size_t appended = 0; |
78 | 10.0k | { |
79 | 10.0k | auto iov = ASSERT_RESULT(buffer.PrepareAppend()); |
80 | 10.0k | size_t idx = 0; |
81 | 10.0k | auto* data = static_cast<uint8_t*>(iov[0].iov_base); |
82 | 10.0k | int start = 0; |
83 | 2.50M | for (size_t j = 0; j != step; ++j) { |
84 | 2.50M | if (j - start >= iov[idx].iov_len) { |
85 | 9.74k | start += iov[idx].iov_len; |
86 | 9.74k | ++idx; |
87 | 9.74k | if (idx >= iov.size()) { |
88 | 9.31k | break; |
89 | 9.31k | } |
90 | 431 | data = static_cast<uint8_t*>(iov[idx].iov_base); |
91 | 431 | } |
92 | 2.49M | data[j - start] = static_cast<uint8_t>(counter++); |
93 | 2.49M | ++appended; |
94 | 2.49M | } |
95 | 10.0k | } |
96 | 10.0k | buffer.DataAppended(appended); |
97 | 10.0k | ASSERT_EQ(consumed + buffer.size(), counter); |
98 | 10.0k | size_t consume_size = 1 + rand_r(&seed) % buffer.size(); |
99 | 10.0k | buffer.Consume(consume_size, Slice()); |
100 | 10.0k | consumed += consume_size; |
101 | 10.0k | ASSERT_EQ(consumed + buffer.size(), counter); |
102 | 10.0k | auto iovs = buffer.AppendedVecs(); |
103 | 10.0k | auto value = consumed; |
104 | 15.5k | for (const auto& iov : iovs) { |
105 | 15.5k | const auto* data = static_cast<const uint8_t*>(iov.iov_base); |
106 | 2.53M | for (size_t j = 0; j != iov.iov_len; ++j) { |
107 | 2.51M | ASSERT_EQ(data[j], static_cast<uint8_t>(value++)); |
108 | 2.51M | } |
109 | 15.5k | } |
110 | 10.0k | } |
111 | 1 | } |
112 | | |
113 | | } // namespace rpc |
114 | | } // namespace yb |