xref: /aosp_15_r20/external/libbrillo/brillo/streams/memory_containers_test.cc (revision 1a96fba65179ea7d3f56207137718607415c5953)
1 // Copyright 2015 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <brillo/streams/memory_containers.h>
6 
7 #include <limits>
8 #include <memory>
9 
10 #include <brillo/streams/mock_stream.h>
11 #include <brillo/streams/stream_errors.h>
12 #include <gmock/gmock.h>
13 #include <gtest/gtest.h>
14 
15 using testing::DoAll;
16 using testing::Invoke;
17 using testing::InSequence;
18 using testing::Return;
19 using testing::WithArgs;
20 using testing::_;
21 
22 namespace brillo {
23 
24 namespace {
25 class MockContiguousBuffer : public data_container::ContiguousBufferBase {
26  public:
27   MockContiguousBuffer() = default;
28 
29   MOCK_METHOD(bool, Resize, (size_t, ErrorPtr*), (override));
30   MOCK_METHOD(size_t, GetSize, (), (const, override));
31   MOCK_METHOD(bool, IsReadOnly, (), (const, override));
32 
33   MOCK_METHOD(const void*,
34               GetReadOnlyBuffer,
35               (size_t, ErrorPtr*),
36               (const, override));
37   MOCK_METHOD(void*, GetBuffer, (size_t, ErrorPtr*), (override));
38 
39   MOCK_METHOD(void,
40               CopyMemoryBlock,
41               (void*, const void*, size_t),
42               (const, override));
43 
44  private:
45   DISALLOW_COPY_AND_ASSIGN(MockContiguousBuffer);
46 };
47 }  // anonymous namespace
48 
49 class MemoryContainerTest : public testing::Test {
50  public:
IntToPtr(int addr)51   inline static void* IntToPtr(int addr) {
52     return reinterpret_cast<void*>(addr);
53   }
54 
IntToConstPtr(int addr)55   inline static const void* IntToConstPtr(int addr) {
56     return reinterpret_cast<const void*>(addr);
57   }
58 
59   // Dummy buffer pointer values used as external data source/destination for
60   // read/write operations.
61   void* const test_read_buffer_ = IntToPtr(12345);
62   const void* const test_write_buffer_ = IntToConstPtr(67890);
63 
64   // Dummy buffer pointer values used for internal buffer owned by the
65   // memory buffer container class.
66   const void* const const_buffer_ = IntToConstPtr(123);
67   void* const buffer_ = IntToPtr(456);
68 
69   MockContiguousBuffer container_;
70 };
71 
TEST_F(MemoryContainerTest,Read_WithinBuffer)72 TEST_F(MemoryContainerTest, Read_WithinBuffer) {
73   {
74     InSequence s;
75     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
76     EXPECT_CALL(container_, GetReadOnlyBuffer(10, _))
77       .WillOnce(Return(const_buffer_));
78     EXPECT_CALL(container_,
79                 CopyMemoryBlock(test_read_buffer_, const_buffer_, 50)).Times(1);
80   }
81   size_t read = 0;
82   ErrorPtr error;
83   EXPECT_TRUE(container_.Read(test_read_buffer_, 50, 10, &read, &error));
84   EXPECT_EQ(50, read);
85   EXPECT_EQ(nullptr, error.get());
86 }
87 
TEST_F(MemoryContainerTest,Read_PastEndOfBuffer)88 TEST_F(MemoryContainerTest, Read_PastEndOfBuffer) {
89   {
90     InSequence s;
91     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
92     EXPECT_CALL(container_, GetReadOnlyBuffer(80, _))
93       .WillOnce(Return(const_buffer_));
94     EXPECT_CALL(container_,
95                 CopyMemoryBlock(test_read_buffer_, const_buffer_, 20)).Times(1);
96   }
97   size_t read = 0;
98   EXPECT_TRUE(container_.Read(test_read_buffer_, 50, 80, &read, nullptr));
99   EXPECT_EQ(20, read);
100 }
101 
TEST_F(MemoryContainerTest,Read_OutsideBuffer)102 TEST_F(MemoryContainerTest, Read_OutsideBuffer) {
103   EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
104   size_t read = 0;
105   EXPECT_TRUE(container_.Read(test_read_buffer_, 50, 100, &read, nullptr));
106   EXPECT_EQ(0, read);
107 }
108 
TEST_F(MemoryContainerTest,Read_Error)109 TEST_F(MemoryContainerTest, Read_Error) {
110   auto OnReadError = [](ErrorPtr* error) {
111     Error::AddTo(error, FROM_HERE, "domain", "read_error", "read error");
112   };
113 
114   {
115     InSequence s;
116     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
117     EXPECT_CALL(container_, GetReadOnlyBuffer(0, _))
118       .WillOnce(DoAll(WithArgs<1>(Invoke(OnReadError)), Return(nullptr)));
119   }
120   size_t read = 0;
121   ErrorPtr error;
122   EXPECT_FALSE(container_.Read(test_read_buffer_, 10, 0, &read, &error));
123   EXPECT_EQ(0, read);
124   EXPECT_NE(nullptr, error.get());
125   EXPECT_EQ("domain", error->GetDomain());
126   EXPECT_EQ("read_error", error->GetCode());
127   EXPECT_EQ("read error", error->GetMessage());
128 }
129 
TEST_F(MemoryContainerTest,Write_WithinBuffer)130 TEST_F(MemoryContainerTest, Write_WithinBuffer) {
131   {
132     InSequence s;
133     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
134     EXPECT_CALL(container_, GetBuffer(10, _))
135       .WillOnce(Return(buffer_));
136     EXPECT_CALL(container_,
137                 CopyMemoryBlock(buffer_, test_write_buffer_, 50)).Times(1);
138   }
139   size_t written = 0;
140   ErrorPtr error;
141   EXPECT_TRUE(container_.Write(test_write_buffer_, 50, 10, &written, &error));
142   EXPECT_EQ(50, written);
143   EXPECT_EQ(nullptr, error.get());
144 }
145 
TEST_F(MemoryContainerTest,Write_PastEndOfBuffer)146 TEST_F(MemoryContainerTest, Write_PastEndOfBuffer) {
147   {
148     InSequence s;
149     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
150     EXPECT_CALL(container_, Resize(130, _)).WillOnce(Return(true));
151     EXPECT_CALL(container_, GetBuffer(80, _))
152       .WillOnce(Return(buffer_));
153     EXPECT_CALL(container_,
154                 CopyMemoryBlock(buffer_, test_write_buffer_, 50)).Times(1);
155   }
156   size_t written = 0;
157   EXPECT_TRUE(container_.Write(test_write_buffer_, 50, 80, &written, nullptr));
158   EXPECT_EQ(50, written);
159 }
160 
TEST_F(MemoryContainerTest,Write_OutsideBuffer)161 TEST_F(MemoryContainerTest, Write_OutsideBuffer) {
162   {
163     InSequence s;
164     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
165     EXPECT_CALL(container_, Resize(160, _)).WillOnce(Return(true));
166     EXPECT_CALL(container_, GetBuffer(110, _))
167       .WillOnce(Return(buffer_));
168     EXPECT_CALL(container_,
169                 CopyMemoryBlock(buffer_, test_write_buffer_, 50)).Times(1);
170   }
171   size_t written = 0;
172   EXPECT_TRUE(container_.Write(test_write_buffer_, 50, 110, &written, nullptr));
173   EXPECT_EQ(50, written);
174 }
175 
TEST_F(MemoryContainerTest,Write_Error_Resize)176 TEST_F(MemoryContainerTest, Write_Error_Resize) {
177   auto OnWriteError = [](ErrorPtr* error) {
178     Error::AddTo(error, FROM_HERE, "domain", "write_error", "resize error");
179   };
180 
181   {
182     InSequence s;
183     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
184     EXPECT_CALL(container_, Resize(160, _))
185       .WillOnce(DoAll(WithArgs<1>(Invoke(OnWriteError)), Return(false)));
186   }
187   size_t written = 0;
188   ErrorPtr error;
189   EXPECT_FALSE(container_.Write(test_write_buffer_, 50, 110, &written, &error));
190   EXPECT_EQ(0, written);
191   EXPECT_NE(nullptr, error.get());
192   EXPECT_EQ("domain", error->GetDomain());
193   EXPECT_EQ("write_error", error->GetCode());
194   EXPECT_EQ("resize error", error->GetMessage());
195 }
196 
TEST_F(MemoryContainerTest,Write_Error)197 TEST_F(MemoryContainerTest, Write_Error) {
198   auto OnWriteError = [](ErrorPtr* error) {
199     Error::AddTo(error, FROM_HERE, "domain", "write_error", "write error");
200   };
201 
202   {
203     InSequence s;
204     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
205     EXPECT_CALL(container_, Resize(160, _)).WillOnce(Return(true));
206     EXPECT_CALL(container_, GetBuffer(110, _))
207       .WillOnce(DoAll(WithArgs<1>(Invoke(OnWriteError)), Return(nullptr)));
208   }
209   size_t written = 0;
210   ErrorPtr error;
211   EXPECT_FALSE(container_.Write(test_write_buffer_, 50, 110, &written, &error));
212   EXPECT_EQ(0, written);
213   EXPECT_NE(nullptr, error.get());
214   EXPECT_EQ("domain", error->GetDomain());
215   EXPECT_EQ("write_error", error->GetCode());
216   EXPECT_EQ("write error", error->GetMessage());
217 }
218 
219 }  // namespace brillo
220 
221