Home | History | Annotate | Download | only in payload_consumer
      1 //
      2 // Copyright (C) 2017 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 "update_engine/payload_consumer/cached_file_descriptor.h"
     18 
     19 #include <fcntl.h>
     20 
     21 #include <algorithm>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include <gtest/gtest.h>
     26 
     27 #include "update_engine/common/test_utils.h"
     28 #include "update_engine/common/utils.h"
     29 
     30 using chromeos_update_engine::test_utils::ExpectVectorsEq;
     31 using std::min;
     32 using std::string;
     33 using std::vector;
     34 
     35 namespace chromeos_update_engine {
     36 
     37 namespace {
     38 const size_t kCacheSize = 100;
     39 const size_t kFileSize = 1024;
     40 const size_t kRandomIterations = 1000;
     41 }  // namespace
     42 
     43 class CachedFileDescriptorTest : public ::testing::Test {
     44  public:
     45   void Open() {
     46     cfd_.reset(new CachedFileDescriptor(fd_, kCacheSize));
     47     EXPECT_TRUE(cfd_->Open(temp_file_.path().c_str(), O_RDWR, 0600));
     48   }
     49 
     50   void Write(uint8_t* buffer, size_t count) {
     51     size_t total_bytes_wrote = 0;
     52     while (total_bytes_wrote < count) {
     53       auto bytes_wrote =
     54           cfd_->Write(buffer + total_bytes_wrote, count - total_bytes_wrote);
     55       ASSERT_NE(bytes_wrote, -1);
     56       total_bytes_wrote += bytes_wrote;
     57     }
     58   }
     59 
     60   void Close() { EXPECT_TRUE(cfd_->Close()); }
     61 
     62   void SetUp() override {
     63     brillo::Blob zero_blob(kFileSize, 0);
     64     EXPECT_TRUE(utils::WriteFile(
     65         temp_file_.path().c_str(), zero_blob.data(), zero_blob.size()));
     66     Open();
     67   }
     68 
     69   void TearDown() override {
     70     Close();
     71     EXPECT_FALSE(cfd_->IsOpen());
     72   }
     73 
     74  protected:
     75   FileDescriptorPtr fd_{new EintrSafeFileDescriptor};
     76   test_utils::ScopedTempFile temp_file_{"CachedFileDescriptor-file.XXXXXX"};
     77   int value_{1};
     78   FileDescriptorPtr cfd_;
     79 };
     80 
     81 TEST_F(CachedFileDescriptorTest, IsOpenTest) {
     82   EXPECT_TRUE(cfd_->IsOpen());
     83 }
     84 
     85 TEST_F(CachedFileDescriptorTest, SimpleWriteTest) {
     86   EXPECT_EQ(cfd_->Seek(0, SEEK_SET), 0);
     87   brillo::Blob blob_in(kFileSize, value_);
     88   Write(blob_in.data(), blob_in.size());
     89   EXPECT_TRUE(cfd_->Flush());
     90 
     91   brillo::Blob blob_out;
     92   EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &blob_out));
     93   EXPECT_EQ(blob_in, blob_out);
     94 }
     95 
     96 TEST_F(CachedFileDescriptorTest, OneBytePerWriteTest) {
     97   EXPECT_EQ(cfd_->Seek(0, SEEK_SET), 0);
     98   brillo::Blob blob_in(kFileSize, value_);
     99   for (size_t idx = 0; idx < blob_in.size(); idx++) {
    100     Write(&blob_in[idx], 1);
    101   }
    102   EXPECT_TRUE(cfd_->Flush());
    103 
    104   brillo::Blob blob_out;
    105   EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &blob_out));
    106   EXPECT_EQ(blob_in, blob_out);
    107 }
    108 
    109 TEST_F(CachedFileDescriptorTest, RandomWriteTest) {
    110   EXPECT_EQ(cfd_->Seek(0, SEEK_SET), 0);
    111 
    112   brillo::Blob blob_in(kFileSize, 0);
    113   srand(time(nullptr));
    114   uint32_t rand_seed;
    115   for (size_t idx = 0; idx < kRandomIterations; idx++) {
    116     // zero to full size available.
    117     size_t start = rand_r(&rand_seed) % blob_in.size();
    118     size_t size = rand_r(&rand_seed) % (blob_in.size() - start);
    119     std::fill_n(&blob_in[start], size, idx % 256);
    120     EXPECT_EQ(cfd_->Seek(start, SEEK_SET), static_cast<off64_t>(start));
    121     Write(&blob_in[start], size);
    122   }
    123   EXPECT_TRUE(cfd_->Flush());
    124 
    125   brillo::Blob blob_out;
    126   EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &blob_out));
    127   EXPECT_EQ(blob_in, blob_out);
    128 }
    129 
    130 TEST_F(CachedFileDescriptorTest, SeekTest) {
    131   EXPECT_EQ(cfd_->Seek(0, SEEK_SET), 0);
    132   EXPECT_EQ(cfd_->Seek(1, SEEK_SET), 1);
    133   EXPECT_EQ(cfd_->Seek(kFileSize - 1, SEEK_SET),
    134             static_cast<off64_t>(kFileSize - 1));
    135   EXPECT_EQ(cfd_->Seek(kFileSize, SEEK_SET), static_cast<off64_t>(kFileSize));
    136   EXPECT_EQ(cfd_->Seek(kFileSize + 1, SEEK_SET),
    137             static_cast<off64_t>(kFileSize + 1));
    138 
    139   EXPECT_EQ(cfd_->Seek(0, SEEK_SET), 0);
    140   EXPECT_EQ(cfd_->Seek(1, SEEK_CUR), 1);
    141   EXPECT_EQ(cfd_->Seek(1, SEEK_CUR), 2);
    142   EXPECT_EQ(cfd_->Seek(kFileSize - 1, SEEK_SET),
    143             static_cast<off64_t>(kFileSize - 1));
    144   EXPECT_EQ(cfd_->Seek(1, SEEK_CUR), static_cast<off64_t>(kFileSize));
    145   EXPECT_EQ(cfd_->Seek(1, SEEK_CUR), static_cast<off64_t>(kFileSize + 1));
    146 }
    147 
    148 TEST_F(CachedFileDescriptorTest, NoFlushTest) {
    149   EXPECT_EQ(cfd_->Seek(0, SEEK_SET), 0);
    150   brillo::Blob blob_in(kFileSize, value_);
    151   Write(blob_in.data(), blob_in.size());
    152 
    153   brillo::Blob blob_out;
    154   EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &blob_out));
    155   EXPECT_NE(blob_in, blob_out);
    156 }
    157 
    158 TEST_F(CachedFileDescriptorTest, CacheSizeWriteTest) {
    159   off64_t seek = 10;
    160   brillo::Blob blob_in(kFileSize, 0);
    161   std::fill_n(&blob_in[seek], kCacheSize, value_);
    162   // We are writing exactly one cache size; Then it should be commited.
    163   EXPECT_EQ(cfd_->Seek(seek, SEEK_SET), seek);
    164   Write(&blob_in[seek], kCacheSize);
    165 
    166   brillo::Blob blob_out;
    167   EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &blob_out));
    168   EXPECT_EQ(blob_in, blob_out);
    169 }
    170 
    171 TEST_F(CachedFileDescriptorTest, UnderCacheSizeWriteTest) {
    172   off64_t seek = 100;
    173   size_t less_than_cache_size = kCacheSize - 1;
    174   EXPECT_EQ(cfd_->Seek(seek, SEEK_SET), seek);
    175   brillo::Blob blob_in(kFileSize, 0);
    176   std::fill_n(&blob_in[seek], less_than_cache_size, value_);
    177   // We are writing less than one cache size; then it should not be commited.
    178   Write(&blob_in[seek], less_than_cache_size);
    179 
    180   // Revert the changes in |blob_in|.
    181   std::fill_n(&blob_in[seek], less_than_cache_size, 0);
    182   brillo::Blob blob_out;
    183   EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &blob_out));
    184   EXPECT_EQ(blob_in, blob_out);
    185 }
    186 
    187 TEST_F(CachedFileDescriptorTest, SeekAfterWriteTest) {
    188   off64_t seek = 100;
    189   size_t less_than_cache_size = kCacheSize - 3;
    190   EXPECT_EQ(cfd_->Seek(seek, SEEK_SET), seek);
    191   brillo::Blob blob_in(kFileSize, 0);
    192   std::fill_n(&blob_in[seek], less_than_cache_size, value_);
    193   // We are writing less than  one cache size; then it should not be commited.
    194   Write(&blob_in[seek], less_than_cache_size);
    195 
    196   // Then we seek, it should've written the cache after seek.
    197   EXPECT_EQ(cfd_->Seek(200, SEEK_SET), 200);
    198 
    199   brillo::Blob blob_out;
    200   EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &blob_out));
    201   EXPECT_EQ(blob_in, blob_out);
    202 }
    203 
    204 }  // namespace chromeos_update_engine
    205