Home | History | Annotate | Download | only in tests
      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:
     34   TestInputStreamBuffer() {
     35     Advance();
     36   }
     37 
     38  private:
     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|.
     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 
     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 
     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 
    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 
    108 TEST(InputStreamBufferTest, LargeSkip) {
    109   TestInputStreamBuffer<10> buf;
    110   EXPECT_FALSE(buf.Skip(SIZE_MAX));
    111 }
    112 
    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 
    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 
    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 
    142 TEST(NestedInputStreamBufferTest, Large) {
    143   TestInputStreamBuffer<10> buf;
    144   NestedInputStreamBuffer nested(&buf, SIZE_MAX);
    145   EXPECT_FALSE(nested.Skip(SIZE_MAX));
    146 }
    147 
    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 
    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 
    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:
    182   TestOutputStreamBuffer() {
    183     Advance();
    184   }
    185 
    186   ~TestOutputStreamBuffer() {
    187     EXPECT_TRUE(Verify());
    188   }
    189 
    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:
    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.
    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 
    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 
    266 TEST(OutputStreamBufferTest, Empty) {
    267   OutputStreamBuffer buf(nullptr, nullptr);
    268   EXPECT_TRUE(buf.Done());
    269   EXPECT_FALSE(buf.WriteByte(0));
    270 }
    271 
    272 TEST(OutputStreamBufferTest, ShortWrite) {
    273   TestOutputStreamBuffer<10> buf;
    274   WriteBuf(&buf, 5, 0);
    275 }
    276 
    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 
    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 
    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 
    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 
    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