Home | History | Annotate | Download | only in unix_file
      1 /*
      2  * Copyright (C) 2009 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 #ifndef ART_RUNTIME_BASE_UNIX_FILE_RANDOM_ACCESS_FILE_TEST_H_
     18 #define ART_RUNTIME_BASE_UNIX_FILE_RANDOM_ACCESS_FILE_TEST_H_
     19 
     20 #include <errno.h>
     21 
     22 #include <string>
     23 
     24 #include "common_test.h"
     25 #include "gtest/gtest.h"
     26 #include "UniquePtr.h"
     27 
     28 namespace unix_file {
     29 
     30 class RandomAccessFileTest : public testing::Test {
     31  protected:
     32   virtual ~RandomAccessFileTest() {
     33   }
     34 
     35   // Override this to return an instance of the subclass under test that's
     36   // backed by a temporary file.
     37   virtual RandomAccessFile* MakeTestFile() = 0;
     38 
     39   virtual void SetUp() {
     40     art::CommonTest::SetEnvironmentVariables(android_data_);
     41   }
     42 
     43   std::string GetTmpPath(const std::string& name) {
     44     std::string path;
     45     path = android_data_;
     46     path += "/";
     47     path += name;
     48     return path;
     49   }
     50 
     51   // TODO(enh): ReadString (and WriteString) might be generally useful.
     52   static bool ReadString(RandomAccessFile* f, std::string* s) {
     53     s->clear();
     54     char buf[256];
     55     int64_t n = 0;
     56     int64_t offset = 0;
     57     while ((n = f->Read(buf, sizeof(buf), offset)) > 0) {
     58       s->append(buf, n);
     59       offset += n;
     60     }
     61     return n != -1;
     62   }
     63 
     64   void TestRead() {
     65     char buf[256];
     66     UniquePtr<RandomAccessFile> file(MakeTestFile());
     67 
     68     // Reading from the start of an empty file gets you zero bytes, however many
     69     // you ask for.
     70     ASSERT_EQ(0, file->Read(buf, 0, 0));
     71     ASSERT_EQ(0, file->Read(buf, 123, 0));
     72 
     73     const std::string content("hello");
     74     ASSERT_EQ(content.size(), file->Write(content.data(), content.size(), 0));
     75 
     76     TestReadContent(content, file.get());
     77   }
     78 
     79   void TestReadContent(const std::string& content, RandomAccessFile* file) {
     80     const int buf_size = content.size() + 10;
     81     UniquePtr<char> buf(new char[buf_size]);
     82     // Can't read from a negative offset.
     83     ASSERT_EQ(-EINVAL, file->Read(buf.get(), 0, -123));
     84 
     85     // Reading too much gets us just what's in the file.
     86     ASSERT_EQ(content.size(), file->Read(buf.get(), buf_size, 0));
     87     ASSERT_EQ(std::string(buf.get(), content.size()), content);
     88 
     89     // We only get as much as we ask for.
     90     const size_t short_request = 2;
     91     ASSERT_LT(short_request, content.size());
     92     ASSERT_EQ(short_request, file->Read(buf.get(), short_request, 0));
     93     ASSERT_EQ(std::string(buf.get(), short_request),
     94               content.substr(0, short_request));
     95 
     96     // We don't have to start at the beginning.
     97     const int non_zero_offset = 2;
     98     ASSERT_GT(non_zero_offset, 0);
     99     ASSERT_EQ(short_request,
    100               file->Read(buf.get(), short_request, non_zero_offset));
    101     ASSERT_EQ(std::string(buf.get(), short_request),
    102               content.substr(non_zero_offset, short_request));
    103 
    104     // Reading past the end gets us nothing.
    105     ASSERT_EQ(0, file->Read(buf.get(), buf_size, file->GetLength()));
    106     ASSERT_EQ(0, file->Read(buf.get(), buf_size, file->GetLength() + 1));
    107   }
    108 
    109   void TestSetLength() {
    110     const std::string content("hello");
    111     UniquePtr<RandomAccessFile> file(MakeTestFile());
    112     ASSERT_EQ(content.size(), file->Write(content.data(), content.size(), 0));
    113     ASSERT_EQ(content.size(), file->GetLength());
    114 
    115     // Can't give a file a negative length.
    116     ASSERT_EQ(-EINVAL, file->SetLength(-123));
    117 
    118     // Can truncate the file.
    119     int64_t new_length = 2;
    120     ASSERT_EQ(0, file->SetLength(new_length));
    121     ASSERT_EQ(new_length, file->GetLength());
    122     std::string new_content;
    123     ASSERT_TRUE(ReadString(file.get(), &new_content));
    124     ASSERT_EQ(content.substr(0, 2), new_content);
    125 
    126     // Expanding the file appends zero bytes.
    127     new_length = file->GetLength() + 1;
    128     ASSERT_EQ(0, file->SetLength(new_length));
    129     ASSERT_EQ(new_length, file->GetLength());
    130     ASSERT_TRUE(ReadString(file.get(), &new_content));
    131     ASSERT_EQ('\0', new_content[new_length - 1]);
    132   }
    133 
    134   void TestWrite() {
    135     const std::string content("hello");
    136     UniquePtr<RandomAccessFile> file(MakeTestFile());
    137 
    138     // Can't write to a negative offset.
    139     ASSERT_EQ(-EINVAL, file->Write(content.data(), 0, -123));
    140 
    141     // Writing zero bytes of data is a no-op.
    142     ASSERT_EQ(0, file->Write(content.data(), 0, 0));
    143     ASSERT_EQ(0, file->GetLength());
    144 
    145     // We can write data.
    146     ASSERT_EQ(content.size(), file->Write(content.data(), content.size(), 0));
    147     ASSERT_EQ(content.size(), file->GetLength());
    148     std::string new_content;
    149     ASSERT_TRUE(ReadString(file.get(), &new_content));
    150     ASSERT_EQ(new_content, content);
    151 
    152     // We can read it back.
    153     char buf[256];
    154     ASSERT_EQ(content.size(), file->Read(buf, sizeof(buf), 0));
    155     ASSERT_EQ(std::string(buf, content.size()), content);
    156 
    157     // We can append data past the end.
    158     ASSERT_EQ(content.size(),
    159     file->Write(content.data(), content.size(), file->GetLength() + 1));
    160     int64_t new_length = 2*content.size() + 1;
    161     ASSERT_EQ(file->GetLength(), new_length);
    162     ASSERT_TRUE(ReadString(file.get(), &new_content));
    163     ASSERT_EQ(std::string("hello\0hello", new_length), new_content);
    164   }
    165 
    166  protected:
    167   std::string android_data_;
    168 };
    169 
    170 }  // namespace unix_file
    171 
    172 #endif  // ART_RUNTIME_BASE_UNIX_FILE_RANDOM_ACCESS_FILE_TEST_H_
    173