xref: /aosp_15_r20/art/odrefresh/odr_fs_utils_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include <fcntl.h>
18*795d594fSAndroid Build Coastguard Worker #include <string.h>
19*795d594fSAndroid Build Coastguard Worker #include <sys/stat.h>
20*795d594fSAndroid Build Coastguard Worker 
21*795d594fSAndroid Build Coastguard Worker #include <iosfwd>
22*795d594fSAndroid Build Coastguard Worker #include <memory>
23*795d594fSAndroid Build Coastguard Worker #include <string>
24*795d594fSAndroid Build Coastguard Worker #include <vector>
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/bit_utils.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/common_art_test.h"
29*795d594fSAndroid Build Coastguard Worker #include "base/os.h"
30*795d594fSAndroid Build Coastguard Worker #include "base/unix_file/fd_file.h"
31*795d594fSAndroid Build Coastguard Worker #include "odr_fs_utils.h"
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker namespace art {
34*795d594fSAndroid Build Coastguard Worker namespace odrefresh {
35*795d594fSAndroid Build Coastguard Worker 
36*795d594fSAndroid Build Coastguard Worker class OdrFsUtilsTest : public CommonArtTest {};
37*795d594fSAndroid Build Coastguard Worker namespace {
38*795d594fSAndroid Build Coastguard Worker 
CreateFile(const char * file_path,size_t bytes)39*795d594fSAndroid Build Coastguard Worker static bool CreateFile(const char* file_path, size_t bytes) {
40*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<File> fp(OS::CreateEmptyFile(file_path));
41*795d594fSAndroid Build Coastguard Worker   if (!fp) {
42*795d594fSAndroid Build Coastguard Worker     return false;
43*795d594fSAndroid Build Coastguard Worker   }
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker   std::vector<char> buffer(bytes, 0xa5);
46*795d594fSAndroid Build Coastguard Worker   if (!fp->WriteFully(buffer.data(), buffer.size())) {
47*795d594fSAndroid Build Coastguard Worker     fp->Erase();
48*795d594fSAndroid Build Coastguard Worker     return false;
49*795d594fSAndroid Build Coastguard Worker   }
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker   if (fp->FlushClose() != 0) {
52*795d594fSAndroid Build Coastguard Worker     fp->Erase();
53*795d594fSAndroid Build Coastguard Worker     return false;
54*795d594fSAndroid Build Coastguard Worker   }
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker   return true;
57*795d594fSAndroid Build Coastguard Worker }
58*795d594fSAndroid Build Coastguard Worker 
59*795d594fSAndroid Build Coastguard Worker }  // namespace
60*795d594fSAndroid Build Coastguard Worker 
TEST_F(OdrFsUtilsTest,RemoveDirectory)61*795d594fSAndroid Build Coastguard Worker TEST_F(OdrFsUtilsTest, RemoveDirectory) {
62*795d594fSAndroid Build Coastguard Worker   ScratchDir scratch_dir(/*keep_files=*/false);
63*795d594fSAndroid Build Coastguard Worker 
64*795d594fSAndroid Build Coastguard Worker   // Create some sub-directories and files
65*795d594fSAndroid Build Coastguard Worker   const std::string dir_paths[] = {
66*795d594fSAndroid Build Coastguard Worker       scratch_dir.GetPath() + "/a",
67*795d594fSAndroid Build Coastguard Worker       scratch_dir.GetPath() + "/b",
68*795d594fSAndroid Build Coastguard Worker       scratch_dir.GetPath() + "/b/c",
69*795d594fSAndroid Build Coastguard Worker       scratch_dir.GetPath() + "/d"
70*795d594fSAndroid Build Coastguard Worker   };
71*795d594fSAndroid Build Coastguard Worker   for (const auto& dir_path : dir_paths) {
72*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0, mkdir(dir_path.c_str(), S_IRWXU));
73*795d594fSAndroid Build Coastguard Worker   }
74*795d594fSAndroid Build Coastguard Worker 
75*795d594fSAndroid Build Coastguard Worker   const std::string file_paths[] = {
76*795d594fSAndroid Build Coastguard Worker       scratch_dir.GetPath() + "/zero.txt",
77*795d594fSAndroid Build Coastguard Worker       scratch_dir.GetPath() + "/a/one.txt",
78*795d594fSAndroid Build Coastguard Worker       scratch_dir.GetPath() + "/b/two.txt",
79*795d594fSAndroid Build Coastguard Worker       scratch_dir.GetPath() + "/b/c/three.txt",
80*795d594fSAndroid Build Coastguard Worker       scratch_dir.GetPath() + "/b/c/four.txt",
81*795d594fSAndroid Build Coastguard Worker   };
82*795d594fSAndroid Build Coastguard Worker   for (const auto& file_path : file_paths) {
83*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(CreateFile(file_path.c_str(), 4096));
84*795d594fSAndroid Build Coastguard Worker   }
85*795d594fSAndroid Build Coastguard Worker 
86*795d594fSAndroid Build Coastguard Worker   // Remove directory, all files and sub-directories
87*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(RemoveDirectory(scratch_dir.GetPath()));
88*795d594fSAndroid Build Coastguard Worker 
89*795d594fSAndroid Build Coastguard Worker   // Check nothing we created remains.
90*795d594fSAndroid Build Coastguard Worker   for (const auto& dir_path : dir_paths) {
91*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(OS::DirectoryExists(dir_path.c_str()));
92*795d594fSAndroid Build Coastguard Worker   }
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker   for (const auto& file_path : file_paths) {
95*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(OS::FileExists(file_path.c_str(), true));
96*795d594fSAndroid Build Coastguard Worker   }
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker   // And the original directory is also gone
99*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(OS::DirectoryExists(scratch_dir.GetPath().c_str()));
100*795d594fSAndroid Build Coastguard Worker }
101*795d594fSAndroid Build Coastguard Worker 
TEST_F(OdrFsUtilsTest,EnsureDirectoryExistsBadPath)102*795d594fSAndroid Build Coastguard Worker TEST_F(OdrFsUtilsTest, EnsureDirectoryExistsBadPath) {
103*795d594fSAndroid Build Coastguard Worker   // Pick a path where not even a root test runner can write.
104*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(EnsureDirectoryExists("/proc/unlikely/to/be/writable"));
105*795d594fSAndroid Build Coastguard Worker }
106*795d594fSAndroid Build Coastguard Worker 
TEST_F(OdrFsUtilsTest,EnsureDirectoryExistsEmptyPath)107*795d594fSAndroid Build Coastguard Worker TEST_F(OdrFsUtilsTest, EnsureDirectoryExistsEmptyPath) {
108*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(EnsureDirectoryExists(""));
109*795d594fSAndroid Build Coastguard Worker }
110*795d594fSAndroid Build Coastguard Worker 
TEST_F(OdrFsUtilsTest,EnsureDirectoryExistsRelativePath)111*795d594fSAndroid Build Coastguard Worker TEST_F(OdrFsUtilsTest, EnsureDirectoryExistsRelativePath) {
112*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(EnsureDirectoryExists("a/b/c"));
113*795d594fSAndroid Build Coastguard Worker }
114*795d594fSAndroid Build Coastguard Worker 
TEST_F(OdrFsUtilsTest,EnsureDirectoryExistsSubDirs)115*795d594fSAndroid Build Coastguard Worker TEST_F(OdrFsUtilsTest, EnsureDirectoryExistsSubDirs) {
116*795d594fSAndroid Build Coastguard Worker   ScratchDir scratch_dir(/*keep_files=*/false);
117*795d594fSAndroid Build Coastguard Worker 
118*795d594fSAndroid Build Coastguard Worker   const char* relative_sub_dirs[] = {"a", "b/c", "d/e/f/"};
119*795d594fSAndroid Build Coastguard Worker   for (const char* relative_sub_dir : relative_sub_dirs) {
120*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(EnsureDirectoryExists(scratch_dir.GetPath() + "/" + relative_sub_dir));
121*795d594fSAndroid Build Coastguard Worker   }
122*795d594fSAndroid Build Coastguard Worker }
123*795d594fSAndroid Build Coastguard Worker 
TEST_F(OdrFsUtilsTest,DISABLED_GetUsedSpace)124*795d594fSAndroid Build Coastguard Worker TEST_F(OdrFsUtilsTest, DISABLED_GetUsedSpace) {
125*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kFirstFileBytes = 1;
126*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kSecondFileBytes = 16111;
127*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kBytesPerBlock = 512;
128*795d594fSAndroid Build Coastguard Worker 
129*795d594fSAndroid Build Coastguard Worker   ScratchDir scratch_dir(/*keep_files=*/false);
130*795d594fSAndroid Build Coastguard Worker 
131*795d594fSAndroid Build Coastguard Worker   const std::string first_file_path = scratch_dir.GetPath() + "/1.dat";
132*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateFile(first_file_path.c_str(), kFirstFileBytes));
133*795d594fSAndroid Build Coastguard Worker 
134*795d594fSAndroid Build Coastguard Worker   struct stat sb;
135*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0, stat(first_file_path.c_str(), &sb));
136*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(kFirstFileBytes, static_cast<decltype(kFirstFileBytes)>(sb.st_size));
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   uint64_t bytes_used = 0;
139*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(GetUsedSpace(scratch_dir.GetPath(), &bytes_used));
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker   const std::string second_file_path = scratch_dir.GetPath() + "/2.dat";
142*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateFile(second_file_path.c_str(), kSecondFileBytes));
143*795d594fSAndroid Build Coastguard Worker 
144*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(GetUsedSpace(scratch_dir.GetPath(), &bytes_used));
145*795d594fSAndroid Build Coastguard Worker   uint64_t expected_bytes_used = RoundUp(kFirstFileBytes, sb.st_blocks * kBytesPerBlock) +
146*795d594fSAndroid Build Coastguard Worker                                  RoundUp(kSecondFileBytes, sb.st_blocks * kBytesPerBlock);
147*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(expected_bytes_used, bytes_used);
148*795d594fSAndroid Build Coastguard Worker 
149*795d594fSAndroid Build Coastguard Worker   const std::string sub_dir_path = scratch_dir.GetPath() + "/sub";
150*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(EnsureDirectoryExists(sub_dir_path));
151*795d594fSAndroid Build Coastguard Worker   for (size_t i = 1; i < 32768; i *= 17) {
152*795d594fSAndroid Build Coastguard Worker     const std::string path = android::base::StringPrintf("%s/%zu", sub_dir_path.c_str(), i);
153*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(CreateFile(path.c_str(), i));
154*795d594fSAndroid Build Coastguard Worker     expected_bytes_used += RoundUp(i, sb.st_blocks * kBytesPerBlock);
155*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(GetUsedSpace(scratch_dir.GetPath(), &bytes_used));
156*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(expected_bytes_used, bytes_used);
157*795d594fSAndroid Build Coastguard Worker   }
158*795d594fSAndroid Build Coastguard Worker }
159*795d594fSAndroid Build Coastguard Worker 
TEST_F(OdrFsUtilsTest,GetUsedSpaceBadPath)160*795d594fSAndroid Build Coastguard Worker TEST_F(OdrFsUtilsTest, GetUsedSpaceBadPath) {
161*795d594fSAndroid Build Coastguard Worker   ScratchDir scratch_dir(/*keep_files=*/false);
162*795d594fSAndroid Build Coastguard Worker   const std::string bad_path = scratch_dir.GetPath() + "/bad_path";
163*795d594fSAndroid Build Coastguard Worker   uint64_t bytes_used = ~0ull;
164*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(GetUsedSpace(bad_path, &bytes_used));
165*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0ull, bytes_used);
166*795d594fSAndroid Build Coastguard Worker }
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker }  // namespace odrefresh
169*795d594fSAndroid Build Coastguard Worker }  // namespace art
170