1 /* 2 * Copyright (C) 2017 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 <stdio.h> 18 #include <sys/cdefs.h> 19 20 #include <string> 21 #include <vector> 22 23 #include <android-base/file.h> 24 #include <android-base/macros.h> 25 #include <android-base/strings.h> 26 #include <android-base/stringprintf.h> 27 #include <gtest/gtest.h> 28 #include <private/android_filesystem_config.h> 29 #include <private/fs_config.h> 30 31 #include "android_filesystem_config_test_data.h" 32 33 // must run test in the test directory 34 const static char fs_config_generate_command[] = "./fs_config_generate_test"; 35 36 static std::string popenToString(std::string command) { 37 std::string ret; 38 39 FILE* fp = popen(command.c_str(), "r"); 40 if (fp) { 41 if (!android::base::ReadFdToString(fileno(fp), &ret)) ret = ""; 42 pclose(fp); 43 } 44 return ret; 45 } 46 47 static void confirm(std::string&& data, const fs_path_config* config, 48 ssize_t num_config) { 49 const struct fs_path_config_from_file* pc = 50 reinterpret_cast<const fs_path_config_from_file*>(data.c_str()); 51 size_t len = data.size(); 52 53 ASSERT_TRUE(config != NULL); 54 ASSERT_LT(0, num_config); 55 56 while (len > 0) { 57 uint16_t host_len = pc->len; 58 if (host_len > len) break; 59 60 EXPECT_EQ(config->mode, pc->mode); 61 EXPECT_EQ(config->uid, pc->uid); 62 EXPECT_EQ(config->gid, pc->gid); 63 EXPECT_EQ(config->capabilities, pc->capabilities); 64 EXPECT_STREQ(config->prefix, pc->prefix); 65 66 EXPECT_LT(0, num_config); 67 --num_config; 68 if (num_config >= 0) ++config; 69 pc = reinterpret_cast<const fs_path_config_from_file*>( 70 reinterpret_cast<const char*>(pc) + host_len); 71 len -= host_len; 72 } 73 EXPECT_EQ(0, num_config); 74 } 75 76 /* See local android_filesystem_config.h for test data */ 77 78 TEST(fs_conf_test, dirs) { 79 confirm(popenToString( 80 android::base::StringPrintf("%s -D", fs_config_generate_command)), 81 android_device_dirs, arraysize(android_device_dirs)); 82 } 83 84 TEST(fs_conf_test, files) { 85 confirm(popenToString( 86 android::base::StringPrintf("%s -F", fs_config_generate_command)), 87 android_device_files, arraysize(android_device_files)); 88 } 89 90 static const char vendor_str[] = "vendor/"; 91 static const char vendor_alt_str[] = "system/vendor/"; 92 static const char oem_str[] = "oem/"; 93 static const char oem_alt_str[] = "system/oem/"; 94 static const char odm_str[] = "odm/"; 95 static const char odm_alt_str[] = "system/odm/"; 96 97 TEST(fs_conf_test, system_dirs) { 98 std::vector<fs_path_config> dirs; 99 const fs_path_config* config = android_device_dirs; 100 for (size_t num = arraysize(android_device_dirs); num; --num) { 101 if (!android::base::StartsWith(config->prefix, vendor_str) && 102 !android::base::StartsWith(config->prefix, vendor_alt_str) && 103 !android::base::StartsWith(config->prefix, oem_str) && 104 !android::base::StartsWith(config->prefix, oem_alt_str) && 105 !android::base::StartsWith(config->prefix, odm_str) && 106 !android::base::StartsWith(config->prefix, odm_alt_str)) { 107 dirs.emplace_back(*config); 108 } 109 ++config; 110 } 111 confirm(popenToString(android::base::StringPrintf( 112 "%s -D -P -vendor,-oem,-odm", fs_config_generate_command)), 113 &dirs[0], dirs.size()); 114 } 115 116 TEST(fs_conf_test, vendor_dirs) { 117 std::vector<fs_path_config> dirs; 118 const fs_path_config* config = android_device_dirs; 119 for (size_t num = arraysize(android_device_dirs); num; --num) { 120 if (android::base::StartsWith(config->prefix, vendor_str) || 121 android::base::StartsWith(config->prefix, vendor_alt_str)) { 122 dirs.emplace_back(*config); 123 } 124 ++config; 125 } 126 confirm(popenToString(android::base::StringPrintf( 127 "%s -D -P vendor", fs_config_generate_command)), 128 &dirs[0], dirs.size()); 129 } 130 131 TEST(fs_conf_test, oem_dirs) { 132 std::vector<fs_path_config> dirs; 133 const fs_path_config* config = android_device_dirs; 134 for (size_t num = arraysize(android_device_dirs); num; --num) { 135 if (android::base::StartsWith(config->prefix, oem_str) || 136 android::base::StartsWith(config->prefix, oem_alt_str)) { 137 dirs.emplace_back(*config); 138 } 139 ++config; 140 } 141 confirm(popenToString(android::base::StringPrintf( 142 "%s -D -P oem", fs_config_generate_command)), 143 &dirs[0], dirs.size()); 144 } 145 146 TEST(fs_conf_test, odm_dirs) { 147 std::vector<fs_path_config> dirs; 148 const fs_path_config* config = android_device_dirs; 149 for (size_t num = arraysize(android_device_dirs); num; --num) { 150 if (android::base::StartsWith(config->prefix, odm_str) || 151 android::base::StartsWith(config->prefix, odm_alt_str)) { 152 dirs.emplace_back(*config); 153 } 154 ++config; 155 } 156 confirm(popenToString(android::base::StringPrintf( 157 "%s -D -P odm", fs_config_generate_command)), 158 &dirs[0], dirs.size()); 159 } 160 161 TEST(fs_conf_test, system_files) { 162 std::vector<fs_path_config> files; 163 const fs_path_config* config = android_device_files; 164 for (size_t num = arraysize(android_device_files); num; --num) { 165 if (!android::base::StartsWith(config->prefix, vendor_str) && 166 !android::base::StartsWith(config->prefix, vendor_alt_str) && 167 !android::base::StartsWith(config->prefix, oem_str) && 168 !android::base::StartsWith(config->prefix, oem_alt_str) && 169 !android::base::StartsWith(config->prefix, odm_str) && 170 !android::base::StartsWith(config->prefix, odm_alt_str)) { 171 files.emplace_back(*config); 172 } 173 ++config; 174 } 175 confirm(popenToString(android::base::StringPrintf( 176 "%s -F -P -vendor,-oem,-odm", fs_config_generate_command)), 177 &files[0], files.size()); 178 } 179 180 TEST(fs_conf_test, vendor_files) { 181 std::vector<fs_path_config> files; 182 const fs_path_config* config = android_device_files; 183 for (size_t num = arraysize(android_device_files); num; --num) { 184 if (android::base::StartsWith(config->prefix, vendor_str) || 185 android::base::StartsWith(config->prefix, vendor_alt_str)) { 186 files.emplace_back(*config); 187 } 188 ++config; 189 } 190 confirm(popenToString(android::base::StringPrintf( 191 "%s -F -P vendor", fs_config_generate_command)), 192 &files[0], files.size()); 193 } 194 195 TEST(fs_conf_test, oem_files) { 196 std::vector<fs_path_config> files; 197 const fs_path_config* config = android_device_files; 198 for (size_t num = arraysize(android_device_files); num; --num) { 199 if (android::base::StartsWith(config->prefix, oem_str) || 200 android::base::StartsWith(config->prefix, oem_alt_str)) { 201 files.emplace_back(*config); 202 } 203 ++config; 204 } 205 confirm(popenToString(android::base::StringPrintf( 206 "%s -F -P oem", fs_config_generate_command)), 207 &files[0], files.size()); 208 } 209 210 TEST(fs_conf_test, odm_files) { 211 std::vector<fs_path_config> files; 212 const fs_path_config* config = android_device_files; 213 for (size_t num = arraysize(android_device_files); num; --num) { 214 if (android::base::StartsWith(config->prefix, odm_str) || 215 android::base::StartsWith(config->prefix, odm_alt_str)) { 216 files.emplace_back(*config); 217 } 218 ++config; 219 } 220 confirm(popenToString(android::base::StringPrintf( 221 "%s -F -P odm", fs_config_generate_command)), 222 &files[0], files.size()); 223 } 224