• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~RandomAccessFileTest()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 
SetUp()39   virtual void SetUp() {
40     art::CommonTest::SetEnvironmentVariables(android_data_);
41   }
42 
GetTmpPath(const std::string & name)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.
ReadString(RandomAccessFile * f,std::string * s)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 
TestRead()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 
TestReadContent(const std::string & content,RandomAccessFile * file)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 
TestSetLength()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 
TestWrite()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