• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdlib.h>
18 #include <string.h>
19 
20 #include <gtest/gtest.h>
21 
22 #include <nvram/messages/io.h>
23 
24 namespace nvram {
25 
26 namespace {
27 
28 // A simple |InputStreamBuffer| implementation that sets up a sequence of
29 // windows of |sizes| specified by the template parameters. Each byte read from
30 // the buffer has a value corresponding to its position in the stream.
31 template<size_t... sizes>
32 class TestInputStreamBuffer : public InputStreamBuffer {
33  public:
TestInputStreamBuffer()34   TestInputStreamBuffer() {
35     Advance();
36   }
37 
38  private:
Advance()39   bool Advance() override {
40     if (index_ >= (sizeof(kSizes) / sizeof(kSizes[0]))) {
41       return false;
42     }
43 
44     memset(buffer, 0xff, kMaxSize);
45     const size_t size = kSizes[index_] < kMaxSize ? kSizes[index_] : kMaxSize;
46     pos_ = buffer;
47     end_ = buffer + size;
48     for (uint8_t* p = buffer; p < end_; ++p) {
49       *p = static_cast<uint8_t>(count_++ % 256);
50     }
51     ++index_;
52     return true;
53   }
54 
55   static constexpr size_t kMaxSize = 256;
56   static constexpr size_t kSizes[] = { sizes... };
57 
58   uint8_t buffer[kMaxSize];
59   size_t index_ = 0;
60   size_t count_ = 0;
61 };
62 
63 template<size_t... sizes>
64 constexpr size_t TestInputStreamBuffer<sizes...>::kSizes[];
65 
66 // Tests whether a read of the given size returns the correct data, i.e. bytes
67 // with consecutive values starting at |pos|.
CheckRead(InputStreamBuffer * buffer,size_t size,size_t pos)68 void CheckRead(InputStreamBuffer* buffer, size_t size, size_t pos) {
69   uint8_t data[256];
70   ASSERT_LE(size, sizeof(data));
71   EXPECT_TRUE(buffer->Read(data, size));
72   for (uint8_t* p = data; p < data + size; ++p) {
73     EXPECT_EQ(pos++ % 256, *p);
74   }
75 }
76 
77 }  // namespace
78 
TEST(InputStreamBufferTest,Basic)79 TEST(InputStreamBufferTest, Basic) {
80   TestInputStreamBuffer<10> buf;
81   EXPECT_FALSE(buf.Done());
82 
83   uint8_t byte = 0;
84   EXPECT_TRUE(buf.ReadByte(&byte));
85   EXPECT_EQ(0, byte);
86   EXPECT_FALSE(buf.Done());
87 
88   CheckRead(&buf, 6, 1);
89   EXPECT_FALSE(buf.Done());
90 
91   EXPECT_TRUE(buf.Skip(3));
92   EXPECT_TRUE(buf.Done());
93 }
94 
TEST(InputStreamBufferTest,Empty)95 TEST(InputStreamBufferTest, Empty) {
96   InputStreamBuffer buf(nullptr, nullptr);
97   EXPECT_TRUE(buf.Done());
98   uint8_t byte = 0;
99   EXPECT_FALSE(buf.ReadByte(&byte));
100 }
101 
TEST(InputStreamBufferTest,LargeRead)102 TEST(InputStreamBufferTest, LargeRead) {
103   TestInputStreamBuffer<10> buf;
104   uint8_t read_buf[10];
105   EXPECT_FALSE(buf.Read(read_buf, SIZE_MAX));
106 }
107 
TEST(InputStreamBufferTest,LargeSkip)108 TEST(InputStreamBufferTest, LargeSkip) {
109   TestInputStreamBuffer<10> buf;
110   EXPECT_FALSE(buf.Skip(SIZE_MAX));
111 }
112 
TEST(InputStreamBufferTest,OverlappingReadByte)113 TEST(InputStreamBufferTest, OverlappingReadByte) {
114   TestInputStreamBuffer<1, 1> buf;
115 
116   uint8_t byte = 0;
117   EXPECT_TRUE(buf.ReadByte(&byte));
118   EXPECT_EQ(0, byte);
119   EXPECT_FALSE(buf.Done());
120 
121   EXPECT_TRUE(buf.ReadByte(&byte));
122   EXPECT_EQ(1, byte);
123   EXPECT_TRUE(buf.Done());
124 }
125 
TEST(InputStreamBufferTest,OverlappingRead)126 TEST(InputStreamBufferTest, OverlappingRead) {
127   TestInputStreamBuffer<10, 10, 10> buf;
128   CheckRead(&buf, 15, 0);
129   CheckRead(&buf, 10, 15);
130   CheckRead(&buf, 5, 25);
131   EXPECT_TRUE(buf.Done());
132 }
133 
TEST(InputStreamBufferTest,OverlappingSkip)134 TEST(InputStreamBufferTest, OverlappingSkip) {
135   TestInputStreamBuffer<10, 10, 10> buf;
136   EXPECT_TRUE(buf.Skip(15));
137   EXPECT_TRUE(buf.Skip(10));
138   EXPECT_TRUE(buf.Skip(5));
139   EXPECT_TRUE(buf.Done());
140 }
141 
TEST(NestedInputStreamBufferTest,Large)142 TEST(NestedInputStreamBufferTest, Large) {
143   TestInputStreamBuffer<10> buf;
144   NestedInputStreamBuffer nested(&buf, SIZE_MAX);
145   EXPECT_FALSE(nested.Skip(SIZE_MAX));
146 }
147 
TEST(NestedInputStreamBufferTest,Short)148 TEST(NestedInputStreamBufferTest, Short) {
149   TestInputStreamBuffer<10> buf;
150   NestedInputStreamBuffer nested(&buf, 5);
151   CheckRead(&nested, 5, 0);
152   EXPECT_TRUE(nested.Done());
153   EXPECT_FALSE(nested.Skip(1));
154 }
155 
TEST(NestedInputStreamBufferTest,Matching)156 TEST(NestedInputStreamBufferTest, Matching) {
157   TestInputStreamBuffer<10, 5> buf;
158   NestedInputStreamBuffer nested(&buf, 10);
159   CheckRead(&nested, 10, 0);
160   EXPECT_TRUE(nested.Done());
161   EXPECT_FALSE(nested.Skip(1));
162 }
163 
TEST(NestedInputStreamBufferTest,Overlapping)164 TEST(NestedInputStreamBufferTest, Overlapping) {
165   TestInputStreamBuffer<2, 3, 5, 8> buf;
166   NestedInputStreamBuffer nested(&buf, 16);
167   CheckRead(&nested, 8, 0);
168   EXPECT_FALSE(nested.Done());
169   CheckRead(&nested, 8, 8);
170   EXPECT_TRUE(nested.Done());
171   EXPECT_FALSE(nested.Skip(1));
172 }
173 
174 namespace {
175 
176 // An |OutputStreamBuffer| implementation backed by a sequence of buffer windows
177 // of |sizes| specified as template parameters. The output is expected to be
178 // sequential byte values starting at 0.
179 template<size_t... sizes>
180 class TestOutputStreamBuffer : public OutputStreamBuffer {
181  public:
TestOutputStreamBuffer()182   TestOutputStreamBuffer() {
183     Advance();
184   }
185 
~TestOutputStreamBuffer()186   ~TestOutputStreamBuffer() {
187     EXPECT_TRUE(Verify());
188   }
189 
Verify()190   bool Verify() {
191     for (; check_pos_ < pos_; check_pos_++, count_++) {
192       data_matches_ &= *check_pos_ == (count_ % 256);
193     }
194 
195     return data_matches_;
196   }
197 
198  private:
Advance()199   bool Advance() override {
200     if (index_ >= (sizeof(kSizes) / sizeof(kSizes[0]))) {
201       return false;
202     }
203 
204     pos_ = end_;
205     Verify();
206 
207     memset(buffer, 0xff, kMaxSize);
208     const size_t size = kSizes[index_] < kMaxSize ? kSizes[index_] : kMaxSize;
209     pos_ = buffer;
210     check_pos_ = buffer;
211     end_ = buffer + size;
212     ++index_;
213     return true;
214   }
215 
216   static constexpr size_t kMaxSize = 256;
217   static constexpr size_t kSizes[] = { sizes... };
218 
219   uint8_t buffer[kMaxSize];
220   size_t index_ = 0;
221 
222   // The pointer in buffer until which the data has been checked to match the
223   // expectations.
224   uint8_t* check_pos_ = nullptr;
225 
226   // The counter that determines the expected value for the buffer bytes.
227   size_t count_ = 0;
228 
229   // Whether all bytes that have been checked so far had the expected value.
230   bool data_matches_ = true;
231 };
232 
233 template<size_t... sizes>
234 constexpr size_t TestOutputStreamBuffer<sizes...>::kSizes[];
235 
236 // Writes a buffer of |size| to |buf|. The buffer contains consecutive byte
237 // value starting at pos.
WriteBuf(OutputStreamBuffer * buffer,size_t size,size_t pos)238 void WriteBuf(OutputStreamBuffer* buffer, size_t size, size_t pos) {
239   uint8_t data[1024];
240   ASSERT_LE(size, sizeof(data));
241   for (uint8_t* p = data; p < data + size; ++p) {
242     *p = pos++ % 256;
243   }
244   EXPECT_TRUE(buffer->Write(data, size));
245 }
246 
247 }  // namespace
248 
TEST(OutputStreamBufferTest,Basic)249 TEST(OutputStreamBufferTest, Basic) {
250   TestOutputStreamBuffer<10> buf;
251   EXPECT_FALSE(buf.Done());
252 
253   EXPECT_TRUE(buf.WriteByte(0));
254   EXPECT_TRUE(buf.WriteByte(1));
255   EXPECT_FALSE(buf.Done());
256   EXPECT_TRUE(buf.Verify());
257 
258   WriteBuf(&buf, 6, 2);
259   EXPECT_FALSE(buf.Done());
260   EXPECT_TRUE(buf.Verify());
261 
262   WriteBuf(&buf, 2, 8);
263   EXPECT_TRUE(buf.Done());
264 }
265 
TEST(OutputStreamBufferTest,Empty)266 TEST(OutputStreamBufferTest, Empty) {
267   OutputStreamBuffer buf(nullptr, nullptr);
268   EXPECT_TRUE(buf.Done());
269   EXPECT_FALSE(buf.WriteByte(0));
270 }
271 
TEST(OutputStreamBufferTest,ShortWrite)272 TEST(OutputStreamBufferTest, ShortWrite) {
273   TestOutputStreamBuffer<10> buf;
274   WriteBuf(&buf, 5, 0);
275 }
276 
TEST(OutputStreamBufferTest,LargeWrite)277 TEST(OutputStreamBufferTest, LargeWrite) {
278   TestOutputStreamBuffer<5> buf;
279   uint8_t data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
280   EXPECT_FALSE(buf.Write(data, sizeof(data)));
281 }
282 
TEST(OutputStreamBufferTest,OverlappingWriteByte)283 TEST(OutputStreamBufferTest, OverlappingWriteByte) {
284   TestOutputStreamBuffer<1, 1> buf;
285   EXPECT_TRUE(buf.WriteByte(0));
286   EXPECT_FALSE(buf.Done());
287   EXPECT_TRUE(buf.WriteByte(1));
288   EXPECT_TRUE(buf.Done());
289 }
290 
TEST(OutputStreamBufferTest,OverlappingWrite)291 TEST(OutputStreamBufferTest, OverlappingWrite) {
292   TestOutputStreamBuffer<10, 10, 10> buf;
293   WriteBuf(&buf, 15, 0);
294   EXPECT_FALSE(buf.Done());
295   WriteBuf(&buf, 10, 15);
296   EXPECT_FALSE(buf.Done());
297   WriteBuf(&buf, 5, 25);
298   EXPECT_TRUE(buf.Done());
299 }
300 
TEST(CountingOutputStreamBuffer,Basic)301 TEST(CountingOutputStreamBuffer, Basic) {
302   CountingOutputStreamBuffer buf;
303   EXPECT_EQ(0U, buf.bytes_written());
304   EXPECT_FALSE(buf.Done());
305 
306   WriteBuf(&buf, 15, 0);
307   EXPECT_EQ(15U, buf.bytes_written());
308   EXPECT_FALSE(buf.Done());
309 
310   EXPECT_TRUE(buf.WriteByte(0));
311   EXPECT_EQ(16U, buf.bytes_written());
312   EXPECT_FALSE(buf.Done());
313 
314   WriteBuf(&buf, 1024, 0);
315   EXPECT_EQ(1040U, buf.bytes_written());
316   EXPECT_FALSE(buf.Done());
317 }
318 
TEST(BlobOutputStreamBuffer,Basic)319 TEST(BlobOutputStreamBuffer, Basic) {
320   Blob blob;
321   ASSERT_TRUE(blob.Resize(1024 * 1024));
322   BlobOutputStreamBuffer buf(&blob);
323 
324   WriteBuf(&buf, 15, 0);
325   EXPECT_FALSE(buf.Done());
326 
327   EXPECT_TRUE(buf.WriteByte(15));
328   EXPECT_FALSE(buf.Done());
329 
330   EXPECT_TRUE(buf.Truncate());
331   EXPECT_EQ(16U, blob.size());
332   for (size_t i = 0; i < blob.size(); ++i) {
333     EXPECT_EQ(i % 256, blob.data()[i]);
334   }
335 
336   WriteBuf(&buf, 1024, 16);
337   EXPECT_FALSE(buf.Done());
338 
339   EXPECT_TRUE(buf.Truncate());
340   EXPECT_EQ(1040U, blob.size());
341   for (size_t i = 0; i < blob.size(); ++i) {
342     EXPECT_EQ(i % 256, blob.data()[i]);
343   }
344 }
345 
346 }  // namespace nvram
347