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 #include "base/unix_file/fd_file.h"
18 #include "base/unix_file/random_access_file_test.h"
19 #include "common_runtime_test.h"  // For ScratchFile
20 #include "gtest/gtest.h"
21 
22 namespace unix_file {
23 
24 class FdFileTest : public RandomAccessFileTest {
25  protected:
MakeTestFile()26   virtual RandomAccessFile* MakeTestFile() {
27     return new FdFile(fileno(tmpfile()), false);
28   }
29 };
30 
TEST_F(FdFileTest,Read)31 TEST_F(FdFileTest, Read) {
32   TestRead();
33 }
34 
TEST_F(FdFileTest,SetLength)35 TEST_F(FdFileTest, SetLength) {
36   TestSetLength();
37 }
38 
TEST_F(FdFileTest,Write)39 TEST_F(FdFileTest, Write) {
40   TestWrite();
41 }
42 
TEST_F(FdFileTest,UnopenedFile)43 TEST_F(FdFileTest, UnopenedFile) {
44   FdFile file;
45   EXPECT_EQ(-1, file.Fd());
46   EXPECT_FALSE(file.IsOpened());
47   EXPECT_TRUE(file.GetPath().empty());
48 }
49 
TEST_F(FdFileTest,OpenClose)50 TEST_F(FdFileTest, OpenClose) {
51   std::string good_path(GetTmpPath("some-file.txt"));
52   FdFile file;
53   ASSERT_TRUE(file.Open(good_path, O_CREAT | O_WRONLY));
54   EXPECT_GE(file.Fd(), 0);
55   EXPECT_TRUE(file.IsOpened());
56   EXPECT_EQ(0, file.Flush());
57   EXPECT_EQ(0, file.Close());
58   EXPECT_EQ(-1, file.Fd());
59   EXPECT_FALSE(file.IsOpened());
60   EXPECT_TRUE(file.Open(good_path,  O_RDONLY));
61   EXPECT_GE(file.Fd(), 0);
62   EXPECT_TRUE(file.IsOpened());
63 
64   ASSERT_EQ(file.Close(), 0);
65   ASSERT_EQ(unlink(good_path.c_str()), 0);
66 }
67 
TEST_F(FdFileTest,ReadFullyEmptyFile)68 TEST_F(FdFileTest, ReadFullyEmptyFile) {
69   // New scratch file, zero-length.
70   art::ScratchFile tmp;
71   FdFile file;
72   ASSERT_TRUE(file.Open(tmp.GetFilename(), O_RDONLY));
73   EXPECT_GE(file.Fd(), 0);
74   EXPECT_TRUE(file.IsOpened());
75   uint8_t buffer[16];
76   EXPECT_FALSE(file.ReadFully(&buffer, 4));
77 }
78 
79 template <size_t Size>
NullTerminateCharArray(char (& array)[Size])80 static void NullTerminateCharArray(char (&array)[Size]) {
81   array[Size - 1] = '\0';
82 }
83 
TEST_F(FdFileTest,ReadFullyWithOffset)84 TEST_F(FdFileTest, ReadFullyWithOffset) {
85   // New scratch file, zero-length.
86   art::ScratchFile tmp;
87   FdFile file;
88   ASSERT_TRUE(file.Open(tmp.GetFilename(), O_RDWR));
89   EXPECT_GE(file.Fd(), 0);
90   EXPECT_TRUE(file.IsOpened());
91 
92   char ignore_prefix[20] = {'a', };
93   NullTerminateCharArray(ignore_prefix);
94   char read_suffix[10] = {'b', };
95   NullTerminateCharArray(read_suffix);
96 
97   off_t offset = 0;
98   // Write scratch data to file that we can read back into.
99   EXPECT_TRUE(file.Write(ignore_prefix, sizeof(ignore_prefix), offset));
100   offset += sizeof(ignore_prefix);
101   EXPECT_TRUE(file.Write(read_suffix, sizeof(read_suffix), offset));
102 
103   ASSERT_EQ(file.Flush(), 0);
104 
105   // Reading at an offset should only produce 'bbbb...', since we ignore the 'aaa...' prefix.
106   char buffer[sizeof(read_suffix)];
107   EXPECT_TRUE(file.PreadFully(buffer, sizeof(read_suffix), offset));
108   EXPECT_STREQ(&read_suffix[0], &buffer[0]);
109 
110   ASSERT_EQ(file.Close(), 0);
111 }
112 
113 }  // namespace unix_file
114