1 /*
2  * Copyright (C) 2019 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 <unistd.h>
18 
19 #include <algorithm>
20 #include <future>
21 #include <string>
22 #include <thread>
23 
24 #include <android-base/strings.h>
25 #include <base/files/file_util.h>
26 
27 #include "fs_avb_test_util.h"
28 #include "util.h"
29 
30 // Target functions to test:
31 using android::fs_mgr::BytesToHex;
32 using android::fs_mgr::FileWaitMode;
33 using android::fs_mgr::HexToBytes;
34 using android::fs_mgr::ListFiles;
35 using android::fs_mgr::NibbleValue;
36 using android::fs_mgr::WaitForFile;
37 
38 namespace fs_avb_host_test {
39 
TEST(BasicUtilTest,NibbleValue09)40 TEST(BasicUtilTest, NibbleValue09) {
41     uint8_t value;
42 
43     EXPECT_TRUE(NibbleValue('0', &value));
44     EXPECT_EQ(0, value);
45     EXPECT_TRUE(NibbleValue('1', &value));
46     EXPECT_EQ(1, value);
47     EXPECT_TRUE(NibbleValue('2', &value));
48     EXPECT_EQ(2, value);
49     EXPECT_TRUE(NibbleValue('3', &value));
50     EXPECT_EQ(3, value);
51     EXPECT_TRUE(NibbleValue('4', &value));
52     EXPECT_EQ(4, value);
53     EXPECT_TRUE(NibbleValue('5', &value));
54     EXPECT_EQ(5, value);
55     EXPECT_TRUE(NibbleValue('6', &value));
56     EXPECT_EQ(6, value);
57     EXPECT_TRUE(NibbleValue('7', &value));
58     EXPECT_EQ(7, value);
59     EXPECT_TRUE(NibbleValue('8', &value));
60     EXPECT_EQ(8, value);
61     EXPECT_TRUE(NibbleValue('9', &value));
62     EXPECT_EQ(9, value);
63 }
64 
TEST(BasicUtilTest,NibbleValueAF)65 TEST(BasicUtilTest, NibbleValueAF) {
66     uint8_t value;
67 
68     EXPECT_TRUE(NibbleValue('a', &value));
69     EXPECT_EQ(10, value);
70     EXPECT_TRUE(NibbleValue('b', &value));
71     EXPECT_EQ(11, value);
72     EXPECT_TRUE(NibbleValue('c', &value));
73     EXPECT_EQ(12, value);
74     EXPECT_TRUE(NibbleValue('d', &value));
75     EXPECT_EQ(13, value);
76     EXPECT_TRUE(NibbleValue('e', &value));
77     EXPECT_EQ(14, value);
78     EXPECT_TRUE(NibbleValue('f', &value));
79     EXPECT_EQ(15, value);
80 
81     EXPECT_TRUE(NibbleValue('A', &value));
82     EXPECT_EQ(10, value);
83     EXPECT_TRUE(NibbleValue('B', &value));
84     EXPECT_EQ(11, value);
85     EXPECT_TRUE(NibbleValue('C', &value));
86     EXPECT_EQ(12, value);
87     EXPECT_TRUE(NibbleValue('D', &value));
88     EXPECT_EQ(13, value);
89     EXPECT_TRUE(NibbleValue('E', &value));
90     EXPECT_EQ(14, value);
91     EXPECT_TRUE(NibbleValue('F', &value));
92     EXPECT_EQ(15, value);
93 }
94 
TEST(BasicUtilTest,NibbleValueInvalid)95 TEST(BasicUtilTest, NibbleValueInvalid) {
96     uint8_t value;
97 
98     EXPECT_FALSE(NibbleValue('G', &value));
99     EXPECT_FALSE(NibbleValue('H', &value));
100     EXPECT_FALSE(NibbleValue('I', &value));
101     EXPECT_FALSE(NibbleValue('x', &value));
102     EXPECT_FALSE(NibbleValue('y', &value));
103     EXPECT_FALSE(NibbleValue('z', &value));
104 }
105 
TEST(BasicUtilTest,HexToBytes)106 TEST(BasicUtilTest, HexToBytes) {
107     std::string hex = "000102030405060708090A0B0C0D0E0F";
108     uint8_t bytes[16];
109 
110     EXPECT_TRUE(HexToBytes((uint8_t*)bytes, sizeof(bytes), hex));
111     for (size_t i = 0; i < sizeof(bytes); i++) {
112         EXPECT_EQ(i, bytes[i]);
113     }
114 }
115 
TEST(BasicUtilTest,HexToBytes2)116 TEST(BasicUtilTest, HexToBytes2) {
117     std::string hex = "101112131415161718191A1B1C1D1E1F";
118     uint8_t bytes[16];
119 
120     EXPECT_TRUE(HexToBytes((uint8_t*)bytes, sizeof(bytes), hex));
121     for (size_t i = 0; i < sizeof(bytes); i++) {
122         EXPECT_EQ(16 + i, bytes[i]);
123     }
124 }
125 
TEST(BasicUtilTest,BytesToHex)126 TEST(BasicUtilTest, BytesToHex) {
127     const uint8_t bytes[16]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
128 
129     EXPECT_EQ("0102", BytesToHex((uint8_t*)bytes, 2));
130     EXPECT_EQ("01020304", BytesToHex((uint8_t*)bytes, 4));
131     EXPECT_EQ("0102030405060708", BytesToHex((uint8_t*)bytes, 8));
132     EXPECT_EQ("0102030405060708090a0b0c0d0e0f10", BytesToHex((uint8_t*)bytes, 16));
133 
134     EXPECT_EQ("01", BytesToHex((uint8_t*)bytes, 1));
135     EXPECT_EQ("010203", BytesToHex((uint8_t*)bytes, 3));
136     EXPECT_EQ("0102030405", BytesToHex((uint8_t*)bytes, 5));
137 }
138 
TEST(BasicUtilTest,HexToBytesInValidOddLenHex)139 TEST(BasicUtilTest, HexToBytesInValidOddLenHex) {
140     std::string hex = "12345";
141     uint8_t bytes[16];
142 
143     EXPECT_FALSE(HexToBytes((uint8_t*)bytes, sizeof(bytes), hex));
144 }
145 
TEST(BasicUtilTest,HexToBytesInsufficientByteLen)146 TEST(BasicUtilTest, HexToBytesInsufficientByteLen) {
147     std::string hex = "101112131415161718191A1B1C1D1E1F";
148     uint8_t bytes[8];
149 
150     EXPECT_FALSE(HexToBytes((uint8_t*)bytes, sizeof(bytes), hex));
151 }
152 
TEST(BasicUtilTest,WaitForFile)153 TEST(BasicUtilTest, WaitForFile) {
154     // Gets system tmp dir.
155     base::FilePath tmp_dir;
156     ASSERT_TRUE(GetTempDir(&tmp_dir));
157 
158     // Waits this path.
159     base::FilePath wait_path = tmp_dir.Append("libfs_avb-test-exist-dir");
160     ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */));
161 
162     EXPECT_TRUE(base::CreateDirectory(wait_path));
163     EXPECT_TRUE(WaitForFile(wait_path.value(), 1s));
164 
165     // Removes the wait_path.
166     ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */));
167 }
168 
TEST(BasicUtilTest,WaitForFileNonExist)169 TEST(BasicUtilTest, WaitForFileNonExist) {
170     base::FilePath wait_path("/path/not/exist");
171     EXPECT_FALSE(WaitForFile(wait_path.value(), 200ms));
172 }
173 
TEST(BasicUtilTest,WaitForFileDeferCreation)174 TEST(BasicUtilTest, WaitForFileDeferCreation) {
175     // Gets system tmp dir.
176     base::FilePath tmp_dir;
177     ASSERT_TRUE(GetTempDir(&tmp_dir));
178 
179     // Waits this path.
180     base::FilePath wait_path = tmp_dir.Append("libfs_avb-test-exist-dir");
181     ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */));
182     auto wait_file = std::async(WaitForFile, wait_path.value(), 500ms, FileWaitMode::Exists);
183 
184     // Sleeps 100ms before creating the wait_path.
185     std::this_thread::sleep_for(100ms);
186     EXPECT_TRUE(base::CreateDirectory(wait_path));
187 
188     // Checks WaitForFile() returns success.
189     EXPECT_TRUE(wait_file.get());
190 
191     // Removes the wait_path.
192     ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */));
193 }
194 
TEST(BasicUtilTest,WaitForFileDeferCreationFailure)195 TEST(BasicUtilTest, WaitForFileDeferCreationFailure) {
196     // Gets system tmp dir.
197     base::FilePath tmp_dir;
198     ASSERT_TRUE(GetTempDir(&tmp_dir));
199 
200     // Waits this path.
201     base::FilePath wait_path = tmp_dir.Append("libfs_avb-test-exist-dir");
202     ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */));
203     auto wait_file = std::async(WaitForFile, wait_path.value(), 50ms, FileWaitMode::Exists);
204 
205     // Sleeps 100ms before creating the wait_path.
206     std::this_thread::sleep_for(100ms);
207     EXPECT_TRUE(base::CreateDirectory(wait_path));
208 
209     // Checks WaitForFile() returns failure, because it only waits 50ms.
210     EXPECT_FALSE(wait_file.get());
211 
212     // Removes the wait_path.
213     ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */));
214 }
215 
TEST(BasicUtilTest,ListFiles)216 TEST(BasicUtilTest, ListFiles) {
217     // Gets system tmp dir.
218     base::FilePath tmp_dir;
219     ASSERT_TRUE(GetTempDir(&tmp_dir));
220 
221     // Creates a test dir for ListFiles testing.
222     base::FilePath test_dir;
223     ASSERT_TRUE(base::CreateTemporaryDirInDir(tmp_dir, "list-file-tests.", &test_dir));
224 
225     // Generates test files to list.
226     base::FilePath file_path_1 = test_dir.Append("1.txt");
227     ASSERT_TRUE(base::WriteFile(file_path_1, "1", 1));
228     base::FilePath file_path_2 = test_dir.Append("2.txt");
229     ASSERT_TRUE(base::WriteFile(file_path_2, "22", 2));
230     base::FilePath file_path_3 = test_dir.Append("3.txt");
231     ASSERT_TRUE(base::WriteFile(file_path_3, "333", 3));
232 
233     // List files for comparison.
234     auto result = ListFiles(test_dir.value());
235     ASSERT_RESULT_OK(result);
236     auto files = result.value();
237     EXPECT_EQ(3UL, files.size());
238     // Sort them offline for comparison.
239     std::sort(files.begin(), files.end());
240     EXPECT_EQ(file_path_1.value(), files[0]);
241     EXPECT_EQ(file_path_2.value(), files[1]);
242     EXPECT_EQ(file_path_3.value(), files[2]);
243 
244     ASSERT_TRUE(base::DeleteFile(test_dir, true /* resursive */));
245 }
246 
TEST(BasicUtilTest,ListFilesShouldDiscardSymlink)247 TEST(BasicUtilTest, ListFilesShouldDiscardSymlink) {
248     // Gets system tmp dir.
249     base::FilePath tmp_dir;
250     ASSERT_TRUE(GetTempDir(&tmp_dir));
251 
252     // Creates a test dir for ListFiles testing.
253     base::FilePath test_dir;
254     ASSERT_TRUE(base::CreateTemporaryDirInDir(tmp_dir, "list-file-tests.", &test_dir));
255 
256     // Generates test files to list.
257     base::FilePath file_path_1 = test_dir.Append("1.txt");
258     ASSERT_TRUE(base::WriteFile(file_path_1, "1", 1));
259     base::FilePath file_path_2 = test_dir.Append("2.txt");
260     ASSERT_TRUE(base::WriteFile(file_path_2, "22", 2));
261     // Creates a symlink and checks it won't be returned by ListFiles.
262     base::FilePath file_path_3 = test_dir.Append("3.txt");
263     base::FilePath non_existent_target = test_dir.Append("non_existent_target.txt");
264     ASSERT_TRUE(base::CreateSymbolicLink(non_existent_target, file_path_3));
265 
266     // List files for comparison.
267     auto result = ListFiles(test_dir.value());
268     ASSERT_RESULT_OK(result);
269     auto files = result.value();
270     EXPECT_EQ(2UL, files.size());  // Should not include the symlink file.
271     // Sort them offline for comparison.
272     std::sort(files.begin(), files.end());
273     EXPECT_EQ(file_path_1.value(), files[0]);
274     EXPECT_EQ(file_path_2.value(), files[1]);
275 
276     ASSERT_TRUE(base::DeleteFile(test_dir, true /* resursive */));
277 }
278 
TEST(BasicUtilTest,ListFilesOpenDirFailure)279 TEST(BasicUtilTest, ListFilesOpenDirFailure) {
280     // Gets system tmp dir.
281     base::FilePath tmp_dir;
282     ASSERT_TRUE(GetTempDir(&tmp_dir));
283 
284     // Generates test files to list.
285     base::FilePath no_such_dir = tmp_dir.Append("not_such_dir");
286 
287     auto fail = ListFiles(no_such_dir.value());
288     ASSERT_FALSE(fail.ok());
289     EXPECT_EQ(ENOENT, fail.error().code());
290     EXPECT_TRUE(android::base::StartsWith(fail.error().message(), "Failed to opendir: "));
291 }
292 
TEST(BasicUtilTest,ListFilesEmptyDir)293 TEST(BasicUtilTest, ListFilesEmptyDir) {
294     // Gets system tmp dir.
295     base::FilePath tmp_dir;
296     ASSERT_TRUE(GetTempDir(&tmp_dir));
297 
298     // Creates a test dir for ListFiles testing.
299     base::FilePath test_dir;
300     ASSERT_TRUE(base::CreateTemporaryDirInDir(tmp_dir, "list-file-tests.", &test_dir));
301 
302     // List files without sorting.
303     auto result = ListFiles(test_dir.value());
304     ASSERT_RESULT_OK(result);
305     auto files = result.value();
306     EXPECT_EQ(0UL, files.size());
307 
308     ASSERT_TRUE(base::DeleteFile(test_dir, true /* resursive */));
309 }
310 
311 }  // namespace fs_avb_host_test
312