• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_METHOD2(Resize, bool(size_t, ErrorPtr*));
30   MOCK_CONST_METHOD0(GetSize, size_t());
31   MOCK_CONST_METHOD0(IsReadOnly, bool());
32 
33   MOCK_CONST_METHOD2(GetReadOnlyBuffer, const void*(size_t, ErrorPtr*));
34   MOCK_METHOD2(GetBuffer, void*(size_t, ErrorPtr*));
35 
36   MOCK_CONST_METHOD3(CopyMemoryBlock, void(void*, const void*, size_t));
37 
38  private:
39   DISALLOW_COPY_AND_ASSIGN(MockContiguousBuffer);
40 };
41 }  // anonymous namespace
42 
43 class MemoryContainerTest : public testing::Test {
44  public:
IntToPtr(int addr)45   inline static void* IntToPtr(int addr) {
46     return reinterpret_cast<void*>(addr);
47   }
48 
IntToConstPtr(int addr)49   inline static const void* IntToConstPtr(int addr) {
50     return reinterpret_cast<const void*>(addr);
51   }
52 
53   // Dummy buffer pointer values used as external data source/destination for
54   // read/write operations.
55   void* const test_read_buffer_ = IntToPtr(12345);
56   const void* const test_write_buffer_ = IntToConstPtr(67890);
57 
58   // Dummy buffer pointer values used for internal buffer owned by the
59   // memory buffer container class.
60   const void* const const_buffer_ = IntToConstPtr(123);
61   void* const buffer_ = IntToPtr(456);
62 
63   MockContiguousBuffer container_;
64 };
65 
TEST_F(MemoryContainerTest,Read_WithinBuffer)66 TEST_F(MemoryContainerTest, Read_WithinBuffer) {
67   {
68     InSequence s;
69     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
70     EXPECT_CALL(container_, GetReadOnlyBuffer(10, _))
71       .WillOnce(Return(const_buffer_));
72     EXPECT_CALL(container_,
73                 CopyMemoryBlock(test_read_buffer_, const_buffer_, 50)).Times(1);
74   }
75   size_t read = 0;
76   ErrorPtr error;
77   EXPECT_TRUE(container_.Read(test_read_buffer_, 50, 10, &read, &error));
78   EXPECT_EQ(50, read);
79   EXPECT_EQ(nullptr, error.get());
80 }
81 
TEST_F(MemoryContainerTest,Read_PastEndOfBuffer)82 TEST_F(MemoryContainerTest, Read_PastEndOfBuffer) {
83   {
84     InSequence s;
85     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
86     EXPECT_CALL(container_, GetReadOnlyBuffer(80, _))
87       .WillOnce(Return(const_buffer_));
88     EXPECT_CALL(container_,
89                 CopyMemoryBlock(test_read_buffer_, const_buffer_, 20)).Times(1);
90   }
91   size_t read = 0;
92   EXPECT_TRUE(container_.Read(test_read_buffer_, 50, 80, &read, nullptr));
93   EXPECT_EQ(20, read);
94 }
95 
TEST_F(MemoryContainerTest,Read_OutsideBuffer)96 TEST_F(MemoryContainerTest, Read_OutsideBuffer) {
97   EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
98   size_t read = 0;
99   EXPECT_TRUE(container_.Read(test_read_buffer_, 50, 100, &read, nullptr));
100   EXPECT_EQ(0, read);
101 }
102 
TEST_F(MemoryContainerTest,Read_Error)103 TEST_F(MemoryContainerTest, Read_Error) {
104   auto OnReadError = [](ErrorPtr* error) {
105     Error::AddTo(error, FROM_HERE, "domain", "read_error", "read error");
106   };
107 
108   {
109     InSequence s;
110     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
111     EXPECT_CALL(container_, GetReadOnlyBuffer(0, _))
112       .WillOnce(DoAll(WithArgs<1>(Invoke(OnReadError)), Return(nullptr)));
113   }
114   size_t read = 0;
115   ErrorPtr error;
116   EXPECT_FALSE(container_.Read(test_read_buffer_, 10, 0, &read, &error));
117   EXPECT_EQ(0, read);
118   EXPECT_NE(nullptr, error.get());
119   EXPECT_EQ("domain", error->GetDomain());
120   EXPECT_EQ("read_error", error->GetCode());
121   EXPECT_EQ("read error", error->GetMessage());
122 }
123 
TEST_F(MemoryContainerTest,Write_WithinBuffer)124 TEST_F(MemoryContainerTest, Write_WithinBuffer) {
125   {
126     InSequence s;
127     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
128     EXPECT_CALL(container_, GetBuffer(10, _))
129       .WillOnce(Return(buffer_));
130     EXPECT_CALL(container_,
131                 CopyMemoryBlock(buffer_, test_write_buffer_, 50)).Times(1);
132   }
133   size_t written = 0;
134   ErrorPtr error;
135   EXPECT_TRUE(container_.Write(test_write_buffer_, 50, 10, &written, &error));
136   EXPECT_EQ(50, written);
137   EXPECT_EQ(nullptr, error.get());
138 }
139 
TEST_F(MemoryContainerTest,Write_PastEndOfBuffer)140 TEST_F(MemoryContainerTest, Write_PastEndOfBuffer) {
141   {
142     InSequence s;
143     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
144     EXPECT_CALL(container_, Resize(130, _)).WillOnce(Return(true));
145     EXPECT_CALL(container_, GetBuffer(80, _))
146       .WillOnce(Return(buffer_));
147     EXPECT_CALL(container_,
148                 CopyMemoryBlock(buffer_, test_write_buffer_, 50)).Times(1);
149   }
150   size_t written = 0;
151   EXPECT_TRUE(container_.Write(test_write_buffer_, 50, 80, &written, nullptr));
152   EXPECT_EQ(50, written);
153 }
154 
TEST_F(MemoryContainerTest,Write_OutsideBuffer)155 TEST_F(MemoryContainerTest, Write_OutsideBuffer) {
156   {
157     InSequence s;
158     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
159     EXPECT_CALL(container_, Resize(160, _)).WillOnce(Return(true));
160     EXPECT_CALL(container_, GetBuffer(110, _))
161       .WillOnce(Return(buffer_));
162     EXPECT_CALL(container_,
163                 CopyMemoryBlock(buffer_, test_write_buffer_, 50)).Times(1);
164   }
165   size_t written = 0;
166   EXPECT_TRUE(container_.Write(test_write_buffer_, 50, 110, &written, nullptr));
167   EXPECT_EQ(50, written);
168 }
169 
TEST_F(MemoryContainerTest,Write_Error_Resize)170 TEST_F(MemoryContainerTest, Write_Error_Resize) {
171   auto OnWriteError = [](ErrorPtr* error) {
172     Error::AddTo(error, FROM_HERE, "domain", "write_error", "resize error");
173   };
174 
175   {
176     InSequence s;
177     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
178     EXPECT_CALL(container_, Resize(160, _))
179       .WillOnce(DoAll(WithArgs<1>(Invoke(OnWriteError)), Return(false)));
180   }
181   size_t written = 0;
182   ErrorPtr error;
183   EXPECT_FALSE(container_.Write(test_write_buffer_, 50, 110, &written, &error));
184   EXPECT_EQ(0, written);
185   EXPECT_NE(nullptr, error.get());
186   EXPECT_EQ("domain", error->GetDomain());
187   EXPECT_EQ("write_error", error->GetCode());
188   EXPECT_EQ("resize error", error->GetMessage());
189 }
190 
TEST_F(MemoryContainerTest,Write_Error)191 TEST_F(MemoryContainerTest, Write_Error) {
192   auto OnWriteError = [](ErrorPtr* error) {
193     Error::AddTo(error, FROM_HERE, "domain", "write_error", "write error");
194   };
195 
196   {
197     InSequence s;
198     EXPECT_CALL(container_, GetSize()).WillOnce(Return(100));
199     EXPECT_CALL(container_, Resize(160, _)).WillOnce(Return(true));
200     EXPECT_CALL(container_, GetBuffer(110, _))
201       .WillOnce(DoAll(WithArgs<1>(Invoke(OnWriteError)), Return(nullptr)));
202   }
203   size_t written = 0;
204   ErrorPtr error;
205   EXPECT_FALSE(container_.Write(test_write_buffer_, 50, 110, &written, &error));
206   EXPECT_EQ(0, written);
207   EXPECT_NE(nullptr, error.get());
208   EXPECT_EQ("domain", error->GetDomain());
209   EXPECT_EQ("write_error", error->GetCode());
210   EXPECT_EQ("write error", error->GetMessage());
211 }
212 
213 }  // namespace brillo
214 
215