| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2020 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 <map> | 
|  | 18 | #include <memory> | 
|  | 19 | #include <string> | 
|  | 20 |  | 
|  | 21 | #include <android-base/logging.h> | 
|  | 22 |  | 
|  | 23 | #include <gtest/gtest.h> | 
|  | 24 |  | 
|  | 25 | #include "execv_helper.h" | 
|  | 26 | #include "run_dex2oat.h" | 
| Victor Hsieh | cb35a06 | 2020-08-13 16:11:13 -0700 | [diff] [blame] | 27 | #include "unique_file.h" | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 28 |  | 
|  | 29 | namespace android { | 
|  | 30 | namespace installd { | 
|  | 31 |  | 
|  | 32 | class RunDex2OatTest : public testing::Test { | 
|  | 33 | public: | 
|  | 34 | static constexpr const char* INPUT_PATH = "/dir/input/basename.apk"; | 
|  | 35 | static constexpr const char* OUTPUT_PATH = "/dir/output/basename.oat"; | 
|  | 36 | static constexpr const char* FLAG_UNUSED = "{{FLAG_UNUSED}}"; | 
|  | 37 |  | 
| Victor Hsieh | cb35a06 | 2020-08-13 16:11:13 -0700 | [diff] [blame] | 38 | // UniqueFile closes FD. Avoid using standard I/O since the test is expected to print gtest | 
|  | 39 | // results. Alternatively, mock out UniqueFile to avoid the side effect of close(2). | 
|  | 40 | static constexpr int ZIP_FD = 3; | 
|  | 41 | static constexpr int OAT_FD = 4; | 
|  | 42 | static constexpr int INPUT_VDEX_FD = 5; | 
|  | 43 | static constexpr int OUTPUT_VDEX_FD = 6; | 
|  | 44 | static constexpr int IMAGE_FD = 7; | 
|  | 45 | static constexpr int PROFILE_FD = 8; | 
|  | 46 | static constexpr int DEX_METADATA_FD = 9; | 
|  | 47 | static constexpr int SWAP_FD = 10; | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 48 |  | 
|  | 49 | using FakeSystemProperties = std::map<std::string, std::string>; | 
|  | 50 |  | 
|  | 51 | // A fake RunDex2Oat that allows to override (fake) system properties and starts with none. | 
|  | 52 | class FakeRunDex2Oat : public RunDex2Oat { | 
|  | 53 | private: | 
|  | 54 | static constexpr const char* TRUE_STR = "true"; | 
|  | 55 | static constexpr const char* FALSE_STR = "false"; | 
|  | 56 |  | 
|  | 57 | public: | 
|  | 58 | FakeRunDex2Oat(ExecVHelper* execv_helper, FakeSystemProperties* properties) | 
|  | 59 | : RunDex2Oat("/dir/bin/dex2oat", execv_helper), properties_(properties) { } | 
|  | 60 |  | 
|  | 61 | virtual ~FakeRunDex2Oat() {} | 
|  | 62 |  | 
|  | 63 | virtual std::string GetProperty(const std::string& key, | 
|  | 64 | const std::string& default_value) override { | 
|  | 65 | if (!properties_) { | 
|  | 66 | return default_value; | 
|  | 67 | } | 
|  | 68 | auto iter = properties_->find(key); | 
|  | 69 | if (iter == properties_->end()) { | 
|  | 70 | return default_value; | 
|  | 71 | } | 
|  | 72 | return iter->second; | 
|  | 73 | } | 
|  | 74 |  | 
|  | 75 | virtual bool GetBoolProperty(const std::string& key, bool default_value) override { | 
|  | 76 | std::string value = GetProperty(key, ""); | 
|  | 77 | if (value == "") { | 
|  | 78 | return default_value; | 
|  | 79 | } | 
|  | 80 | return value == TRUE_STR; | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | private: | 
|  | 84 | FakeSystemProperties* properties_; | 
|  | 85 | }; | 
|  | 86 |  | 
|  | 87 | struct RunDex2OatArgs { | 
|  | 88 | static std::unique_ptr<RunDex2OatArgs> MakeDefaultTestArgs() { | 
|  | 89 | auto args = std::make_unique<RunDex2OatArgs>(); | 
| Victor Hsieh | cb35a06 | 2020-08-13 16:11:13 -0700 | [diff] [blame] | 90 | args->input_dex.reset(ZIP_FD, INPUT_PATH); | 
|  | 91 | args->output_oat.reset(OAT_FD, OUTPUT_PATH); | 
|  | 92 | args->input_vdex.reset(INPUT_VDEX_FD, "UNUSED_PATH"); | 
|  | 93 | args->output_vdex.reset(OUTPUT_VDEX_FD, "UNUSED_PATH"); | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 94 | args->instruction_set = "arm64"; | 
|  | 95 | args->compilation_reason = "rundex2oattest"; | 
|  | 96 | return args; | 
|  | 97 | } | 
|  | 98 |  | 
| Victor Hsieh | cb35a06 | 2020-08-13 16:11:13 -0700 | [diff] [blame] | 99 | UniqueFile output_oat; | 
|  | 100 | UniqueFile output_vdex; | 
|  | 101 | UniqueFile output_image; | 
|  | 102 | UniqueFile input_dex; | 
|  | 103 | UniqueFile input_vdex; | 
|  | 104 | UniqueFile dex_metadata; | 
|  | 105 | UniqueFile profile; | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 106 | int swap_fd = -1; | 
|  | 107 | const char* instruction_set = nullptr; | 
|  | 108 | const char* compiler_filter = "extract"; | 
|  | 109 | bool debuggable = false; | 
|  | 110 | bool post_bootcomplete = false; | 
|  | 111 | bool for_restore = false; | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 112 | const char* class_loader_context = nullptr; | 
|  | 113 | std::string class_loader_context_fds; | 
|  | 114 | int target_sdk_version = 0; | 
|  | 115 | bool enable_hidden_api_checks = false; | 
|  | 116 | bool generate_compact_dex = true; | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 117 | bool use_jitzygote_image = false; | 
|  | 118 | const char* compilation_reason = nullptr; | 
|  | 119 | }; | 
|  | 120 |  | 
|  | 121 | class FakeExecVHelper : public ExecVHelper { | 
|  | 122 | public: | 
|  | 123 | bool HasArg(const std::string& arg) const { | 
|  | 124 | auto end = argv_.end() - 1;  // To exclude the terminating nullptr | 
|  | 125 | return find(argv_.begin(), end, arg) != end; | 
|  | 126 | } | 
|  | 127 |  | 
|  | 128 | bool FlagNotUsed(const std::string& flag) const { | 
|  | 129 | auto has_prefix = [flag](const char* arg) { | 
|  | 130 | return strncmp(arg, flag.c_str(), flag.size()) == 0; | 
|  | 131 | }; | 
|  | 132 | auto end = argv_.end() - 1;  // To exclude the terminating nullptr | 
|  | 133 | return find_if(argv_.begin(), end, has_prefix) == end; | 
|  | 134 | } | 
|  | 135 |  | 
|  | 136 | virtual void Exec(int exit_code) override { | 
|  | 137 | std::string cmd; | 
|  | 138 | for (auto arg : argv_) { | 
|  | 139 | if (arg == nullptr) { | 
|  | 140 | continue; | 
|  | 141 | } | 
|  | 142 | cmd += arg; | 
|  | 143 | cmd += " "; | 
|  | 144 | } | 
| Victor Hsieh | cb35a06 | 2020-08-13 16:11:13 -0700 | [diff] [blame] | 145 | LOG(DEBUG) << "FakeExecVHelper exit_code: " << exit_code << " cmd: " << cmd << "\n"; | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 146 | } | 
|  | 147 | }; | 
|  | 148 |  | 
|  | 149 | virtual void SetUp() override { | 
|  | 150 | execv_helper_.reset(new FakeExecVHelper()); | 
|  | 151 | system_properties_.clear(); | 
|  | 152 | initializeDefaultExpectedFlags(); | 
|  | 153 | } | 
|  | 154 |  | 
|  | 155 | // Initializes the default flags expected to a run.  It currently matches to the expected flags | 
|  | 156 | // with RunDex2OatArgs::MakeDefaultTestArgs. | 
|  | 157 | // | 
|  | 158 | // default_expected_flags_ defines a mapping of <flag_name, expected_value>, where flag_name is | 
|  | 159 | // something like "--flag-name", and expected_value can be "=value" or ":value" (depending on | 
|  | 160 | // its delimiter), "" (if no value is needed), or a special value of FLAG_UNUSED to indicates | 
|  | 161 | // that it should not be used. | 
|  | 162 | void initializeDefaultExpectedFlags() { | 
|  | 163 | default_expected_flags_.clear(); | 
|  | 164 |  | 
|  | 165 | // Files | 
|  | 166 | default_expected_flags_["--zip-fd"] = "=" + std::to_string(ZIP_FD); | 
|  | 167 | default_expected_flags_["--zip-location"] = "=basename.apk"; | 
|  | 168 | default_expected_flags_["--oat-fd"] = "=" + std::to_string(OAT_FD); | 
|  | 169 | default_expected_flags_["--oat-location"] = "=" + std::string(OUTPUT_PATH); | 
|  | 170 | default_expected_flags_["--input-vdex-fd"] = "=" + std::to_string(INPUT_VDEX_FD); | 
|  | 171 | default_expected_flags_["--output-vdex-fd"] = "=" + std::to_string(OUTPUT_VDEX_FD); | 
|  | 172 | default_expected_flags_["--classpath-dir"] = "=/dir/input"; | 
|  | 173 | default_expected_flags_["--app-image-fd"] = FLAG_UNUSED; | 
|  | 174 | default_expected_flags_["--profile-file-fd"] = FLAG_UNUSED; | 
|  | 175 | default_expected_flags_["--swap-fd"] = FLAG_UNUSED; | 
|  | 176 | default_expected_flags_["--class-loader-context"] = FLAG_UNUSED; | 
|  | 177 | default_expected_flags_["--class-loader-context-fds"] = FLAG_UNUSED; | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 178 |  | 
|  | 179 | // Arch | 
|  | 180 | default_expected_flags_["--instruction-set"] = "=arm64"; | 
|  | 181 | default_expected_flags_["--instruction-set-features"] = FLAG_UNUSED; | 
|  | 182 | default_expected_flags_["--instruction-set-variant"] = FLAG_UNUSED; | 
|  | 183 | default_expected_flags_["--cpu-set"] = FLAG_UNUSED; | 
|  | 184 |  | 
|  | 185 | // Misc | 
|  | 186 | default_expected_flags_["--compiler-filter"] = "=extract"; | 
|  | 187 | default_expected_flags_["--compilation-reason"] = "=rundex2oattest"; | 
|  | 188 | default_expected_flags_["--compact-dex-level"] = FLAG_UNUSED; | 
|  | 189 | default_expected_flags_["-j"] = FLAG_UNUSED; | 
|  | 190 | default_expected_flags_["--max-image-block-size"] = FLAG_UNUSED; | 
|  | 191 | default_expected_flags_["--very-large-app-threshold"] = FLAG_UNUSED; | 
|  | 192 | default_expected_flags_["--resolve-startup-const-strings"] = FLAG_UNUSED; | 
|  | 193 |  | 
|  | 194 | // Debug | 
|  | 195 | default_expected_flags_["--debuggable"] = FLAG_UNUSED; | 
|  | 196 | default_expected_flags_["--generate-debug-info"] = FLAG_UNUSED; | 
|  | 197 | default_expected_flags_["--generate-mini-debug-info"] = FLAG_UNUSED; | 
|  | 198 |  | 
|  | 199 | // Runtime | 
|  | 200 | // TODO(victorhsieh): Check if the previous flag is actually --runtime-arg. | 
|  | 201 | default_expected_flags_["-Xms"] = FLAG_UNUSED; | 
|  | 202 | default_expected_flags_["-Xmx"] = FLAG_UNUSED; | 
|  | 203 | default_expected_flags_["-Xbootclasspath"] = FLAG_UNUSED; | 
|  | 204 | default_expected_flags_["-Xtarget-sdk-version"] = FLAG_UNUSED; | 
|  | 205 | default_expected_flags_["-Xhidden-api-policy"] = FLAG_UNUSED; | 
|  | 206 | default_expected_flags_["-Xnorelocate"] = FLAG_UNUSED; | 
|  | 207 |  | 
|  | 208 | // Test only | 
|  | 209 | default_expected_flags_["--foo"] = FLAG_UNUSED; | 
|  | 210 | default_expected_flags_["--bar"] = FLAG_UNUSED; | 
|  | 211 | default_expected_flags_["--baz"] = FLAG_UNUSED; | 
|  | 212 | } | 
|  | 213 |  | 
|  | 214 | void SetExpectedFlagUsed(const std::string& flag, const std::string& value) { | 
|  | 215 | auto iter = default_expected_flags_.find(flag); | 
|  | 216 | ASSERT_NE(iter, default_expected_flags_.end()) << "Must define the default value"; | 
|  | 217 | iter->second = value; | 
|  | 218 | } | 
|  | 219 |  | 
|  | 220 | void VerifyExpectedFlags() { | 
|  | 221 | for (auto const& [flag, value] : default_expected_flags_) { | 
|  | 222 | if (value == FLAG_UNUSED) { | 
|  | 223 | EXPECT_TRUE(execv_helper_->FlagNotUsed(flag)) | 
|  | 224 | << "Flag " << flag << " should be unused, but got the value " << value; | 
|  | 225 | } else if (value == "") { | 
|  | 226 | EXPECT_TRUE(execv_helper_->HasArg(flag)) | 
|  | 227 | << "Flag " << flag << " should be specified without value, but got " << value; | 
|  | 228 | } else { | 
|  | 229 | EXPECT_TRUE(execv_helper_->HasArg(flag + value)) | 
| Victor Hsieh | cb35a06 | 2020-08-13 16:11:13 -0700 | [diff] [blame] | 230 | << "Flag " << flag << value << " is not specificed"; | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 231 | } | 
|  | 232 | } | 
|  | 233 | } | 
|  | 234 |  | 
|  | 235 | void setSystemProperty(const std::string& key, const std::string& value) { | 
|  | 236 | system_properties_[key] = value; | 
|  | 237 | } | 
|  | 238 |  | 
|  | 239 | void CallRunDex2Oat(std::unique_ptr<RunDex2OatArgs> args) { | 
|  | 240 | FakeRunDex2Oat runner(execv_helper_.get(), &system_properties_); | 
| Victor Hsieh | cb35a06 | 2020-08-13 16:11:13 -0700 | [diff] [blame] | 241 | runner.Initialize(args->output_oat, | 
|  | 242 | args->output_vdex, | 
|  | 243 | args->output_image, | 
|  | 244 | args->input_dex, | 
|  | 245 | args->input_vdex, | 
|  | 246 | args->dex_metadata, | 
|  | 247 | args->profile, | 
|  | 248 | args->class_loader_context, | 
|  | 249 | args->class_loader_context_fds, | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 250 | args->swap_fd, | 
|  | 251 | args->instruction_set, | 
|  | 252 | args->compiler_filter, | 
|  | 253 | args->debuggable, | 
|  | 254 | args->post_bootcomplete, | 
|  | 255 | args->for_restore, | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 256 | args->target_sdk_version, | 
|  | 257 | args->enable_hidden_api_checks, | 
|  | 258 | args->generate_compact_dex, | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 259 | args->use_jitzygote_image, | 
|  | 260 | args->compilation_reason); | 
|  | 261 | runner.Exec(/*exit_code=*/ 0); | 
|  | 262 | } | 
|  | 263 |  | 
|  | 264 | private: | 
|  | 265 | std::unique_ptr<FakeExecVHelper> execv_helper_; | 
|  | 266 | std::map<std::string, std::string> default_expected_flags_; | 
|  | 267 | FakeSystemProperties system_properties_; | 
|  | 268 | }; | 
|  | 269 |  | 
|  | 270 | TEST_F(RunDex2OatTest, BasicInputOutput) { | 
|  | 271 | auto execv_helper = std::make_unique<FakeExecVHelper>(); | 
|  | 272 | CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs()); | 
|  | 273 |  | 
|  | 274 | VerifyExpectedFlags(); | 
|  | 275 | } | 
|  | 276 |  | 
|  | 277 | TEST_F(RunDex2OatTest, WithAllOtherInputFds) { | 
|  | 278 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
| Victor Hsieh | cb35a06 | 2020-08-13 16:11:13 -0700 | [diff] [blame] | 279 | args->output_image.reset(IMAGE_FD, "UNUSED_PATH"); | 
|  | 280 | args->profile.reset(PROFILE_FD, "UNUSED_PATH"); | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 281 | args->swap_fd = SWAP_FD; | 
|  | 282 | CallRunDex2Oat(std::move(args)); | 
|  | 283 |  | 
|  | 284 | SetExpectedFlagUsed("--app-image-fd", "=" + std::to_string(IMAGE_FD)); | 
|  | 285 | SetExpectedFlagUsed("--profile-file-fd", "=" + std::to_string(PROFILE_FD)); | 
|  | 286 | SetExpectedFlagUsed("--swap-fd", "=" + std::to_string(SWAP_FD)); | 
|  | 287 | VerifyExpectedFlags(); | 
|  | 288 | } | 
|  | 289 |  | 
|  | 290 | TEST_F(RunDex2OatTest, WithClassLoaderContext) { | 
|  | 291 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 292 | args->class_loader_context = "CLASS_LOADER_CONTEXT"; | 
|  | 293 | CallRunDex2Oat(std::move(args)); | 
|  | 294 |  | 
|  | 295 | SetExpectedFlagUsed("--class-loader-context", "=CLASS_LOADER_CONTEXT"); | 
|  | 296 | SetExpectedFlagUsed("--class-loader-context-fds", FLAG_UNUSED); | 
|  | 297 | VerifyExpectedFlags(); | 
|  | 298 | } | 
|  | 299 |  | 
|  | 300 | TEST_F(RunDex2OatTest, WithClassLoaderContextAndFds) { | 
|  | 301 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 302 | args->class_loader_context = "CLASS_LOADER_CONTEXT"; | 
|  | 303 | args->class_loader_context_fds = "CLASS_LOADER_CONTEXT_FDS"; | 
|  | 304 | CallRunDex2Oat(std::move(args)); | 
|  | 305 |  | 
|  | 306 | SetExpectedFlagUsed("--class-loader-context", "=CLASS_LOADER_CONTEXT"); | 
|  | 307 | SetExpectedFlagUsed("--class-loader-context-fds", "=CLASS_LOADER_CONTEXT_FDS"); | 
|  | 308 | VerifyExpectedFlags(); | 
|  | 309 | } | 
|  | 310 |  | 
|  | 311 | TEST_F(RunDex2OatTest, WithOnlyClassLoaderContextFds) { | 
|  | 312 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 313 | args->class_loader_context_fds = "CLASS_LOADER_CONTEXT_FDS"; | 
|  | 314 | CallRunDex2Oat(std::move(args)); | 
|  | 315 |  | 
|  | 316 | SetExpectedFlagUsed("--class-loader-context", FLAG_UNUSED); | 
|  | 317 | SetExpectedFlagUsed("--class-loader-context-fds", FLAG_UNUSED); | 
|  | 318 | VerifyExpectedFlags(); | 
|  | 319 | } | 
|  | 320 |  | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 321 | TEST_F(RunDex2OatTest, DoNotGenerateCompactDex) { | 
|  | 322 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 323 | args->generate_compact_dex = false; | 
|  | 324 | CallRunDex2Oat(std::move(args)); | 
|  | 325 |  | 
|  | 326 | SetExpectedFlagUsed("--compact-dex-level", "=none"); | 
|  | 327 | VerifyExpectedFlags(); | 
|  | 328 | } | 
|  | 329 |  | 
|  | 330 | TEST_F(RunDex2OatTest, DoNotGenerateCompactDexWithVdexInPlaceUpdate) { | 
|  | 331 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 332 | args->generate_compact_dex = true; | 
| Victor Hsieh | cb35a06 | 2020-08-13 16:11:13 -0700 | [diff] [blame] | 333 | args->input_vdex.reset(INPUT_VDEX_FD, "UNUSED_PATH"); | 
|  | 334 | args->output_vdex.reset(INPUT_VDEX_FD, "UNUSED_PATH"); | 
| Victor Hsieh | c9821f1 | 2020-08-07 11:32:29 -0700 | [diff] [blame] | 335 | CallRunDex2Oat(std::move(args)); | 
|  | 336 |  | 
|  | 337 | SetExpectedFlagUsed("--compact-dex-level", "=none"); | 
|  | 338 | SetExpectedFlagUsed("--output-vdex-fd", "=" + std::to_string(INPUT_VDEX_FD)); | 
|  | 339 | VerifyExpectedFlags(); | 
|  | 340 | } | 
|  | 341 |  | 
|  | 342 | TEST_F(RunDex2OatTest, ISA) { | 
|  | 343 | setSystemProperty("dalvik.vm.isa.x86.features", "a-x86-feature"); | 
|  | 344 | setSystemProperty("dalvik.vm.isa.x86.variant", "a-x86-variant"); | 
|  | 345 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 346 | args->instruction_set = "x86"; | 
|  | 347 | CallRunDex2Oat(std::move(args)); | 
|  | 348 |  | 
|  | 349 | SetExpectedFlagUsed("--instruction-set", "=x86"); | 
|  | 350 | SetExpectedFlagUsed("--instruction-set-features", "=a-x86-feature"); | 
|  | 351 | SetExpectedFlagUsed("--instruction-set-variant", "=a-x86-variant"); | 
|  | 352 | VerifyExpectedFlags(); | 
|  | 353 | } | 
|  | 354 |  | 
|  | 355 | TEST_F(RunDex2OatTest, CpuSetPreBootComplete) { | 
|  | 356 | setSystemProperty("dalvik.vm.boot-dex2oat-cpu-set", "1,2"); | 
|  | 357 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 358 | args->post_bootcomplete = false; | 
|  | 359 | CallRunDex2Oat(std::move(args)); | 
|  | 360 |  | 
|  | 361 | SetExpectedFlagUsed("--cpu-set", "=1,2"); | 
|  | 362 | VerifyExpectedFlags(); | 
|  | 363 | } | 
|  | 364 |  | 
|  | 365 | TEST_F(RunDex2OatTest, CpuSetPostBootCompleteNotForRestore) { | 
|  | 366 | setSystemProperty("dalvik.vm.dex2oat-cpu-set", "1,2"); | 
|  | 367 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 368 | args->post_bootcomplete = true; | 
|  | 369 | args->for_restore = false; | 
|  | 370 | CallRunDex2Oat(std::move(args)); | 
|  | 371 |  | 
|  | 372 | SetExpectedFlagUsed("--cpu-set", "=1,2"); | 
|  | 373 | VerifyExpectedFlags(); | 
|  | 374 | } | 
|  | 375 |  | 
|  | 376 | TEST_F(RunDex2OatTest, CpuSetPostBootCompleteForRestore) { | 
|  | 377 | setSystemProperty("dalvik.vm.restore-dex2oat-cpu-set", "1,2"); | 
|  | 378 | setSystemProperty("dalvik.vm.dex2oat-cpu-set", "2,3"); | 
|  | 379 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 380 | args->post_bootcomplete = true; | 
|  | 381 | args->for_restore = true; | 
|  | 382 | CallRunDex2Oat(std::move(args)); | 
|  | 383 |  | 
|  | 384 | SetExpectedFlagUsed("--cpu-set", "=1,2"); | 
|  | 385 | VerifyExpectedFlags(); | 
|  | 386 | } | 
|  | 387 |  | 
|  | 388 | TEST_F(RunDex2OatTest, CpuSetPostBootCompleteForRestore_Backup) { | 
|  | 389 | setSystemProperty("dalvik.vm.restore-dex2oat-cpu-set", ""); | 
|  | 390 | setSystemProperty("dalvik.vm.dex2oat-cpu-set", "1,2"); | 
|  | 391 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 392 | args->post_bootcomplete = true; | 
|  | 393 | args->for_restore = true; | 
|  | 394 | CallRunDex2Oat(std::move(args)); | 
|  | 395 |  | 
|  | 396 | SetExpectedFlagUsed("--cpu-set", "=1,2"); | 
|  | 397 | VerifyExpectedFlags(); | 
|  | 398 | } | 
|  | 399 |  | 
|  | 400 | TEST_F(RunDex2OatTest, Runtime) { | 
|  | 401 | setSystemProperty("dalvik.vm.dex2oat-Xms", "1234m"); | 
|  | 402 | setSystemProperty("dalvik.vm.dex2oat-Xmx", "5678m"); | 
|  | 403 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 404 | args->target_sdk_version = 30; | 
|  | 405 | args->enable_hidden_api_checks = true; | 
|  | 406 | CallRunDex2Oat(std::move(args)); | 
|  | 407 |  | 
|  | 408 | SetExpectedFlagUsed("-Xms", "1234m"); | 
|  | 409 | SetExpectedFlagUsed("-Xmx", "5678m"); | 
|  | 410 | SetExpectedFlagUsed("-Xtarget-sdk-version", ":30"); | 
|  | 411 | SetExpectedFlagUsed("-Xhidden-api-policy", ":enabled"); | 
|  | 412 | SetExpectedFlagUsed("-Xnorelocate", FLAG_UNUSED); | 
|  | 413 | VerifyExpectedFlags(); | 
|  | 414 | } | 
|  | 415 |  | 
|  | 416 | TEST_F(RunDex2OatTest, SkipRelocationInMinFramework) { | 
|  | 417 | setSystemProperty("vold.decrypt", "trigger_restart_min_framework"); | 
|  | 418 | CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs()); | 
|  | 419 |  | 
|  | 420 | SetExpectedFlagUsed("--compiler-filter", "=extract"); | 
|  | 421 | SetExpectedFlagUsed("-Xnorelocate", ""); | 
|  | 422 | VerifyExpectedFlags(); | 
|  | 423 | } | 
|  | 424 |  | 
|  | 425 | TEST_F(RunDex2OatTest, SkipRelocationIfDecryptedWithFullDiskEncryption) { | 
|  | 426 | setSystemProperty("vold.decrypt", "1"); | 
|  | 427 | CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs()); | 
|  | 428 |  | 
|  | 429 | SetExpectedFlagUsed("--compiler-filter", "=extract"); | 
|  | 430 | SetExpectedFlagUsed("-Xnorelocate", ""); | 
|  | 431 | VerifyExpectedFlags(); | 
|  | 432 | } | 
|  | 433 |  | 
|  | 434 | TEST_F(RunDex2OatTest, DalvikVmDex2oatFilter) { | 
|  | 435 | setSystemProperty("dalvik.vm.dex2oat-filter", "speed"); | 
|  | 436 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 437 | args->compiler_filter = nullptr; | 
|  | 438 | CallRunDex2Oat(std::move(args)); | 
|  | 439 |  | 
|  | 440 | SetExpectedFlagUsed("--compiler-filter", "=speed"); | 
|  | 441 | VerifyExpectedFlags(); | 
|  | 442 | } | 
|  | 443 |  | 
|  | 444 | TEST_F(RunDex2OatTest, ResolveStartupStartings) { | 
|  | 445 | setSystemProperty("dalvik.vm.dex2oat-resolve-startup-strings", "false"); | 
|  | 446 | CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs()); | 
|  | 447 |  | 
|  | 448 | SetExpectedFlagUsed("--resolve-startup-const-strings", "=false"); | 
|  | 449 | VerifyExpectedFlags(); | 
|  | 450 | } | 
|  | 451 |  | 
|  | 452 | TEST_F(RunDex2OatTest, ResolveStartupStartingsOverride) { | 
|  | 453 | setSystemProperty("dalvik.vm.dex2oat-resolve-startup-strings", "false"); | 
|  | 454 | setSystemProperty("persist.device_config.runtime.dex2oat_resolve_startup_strings", "true"); | 
|  | 455 | CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs()); | 
|  | 456 |  | 
|  | 457 | SetExpectedFlagUsed("--resolve-startup-const-strings", "=true"); | 
|  | 458 | VerifyExpectedFlags(); | 
|  | 459 | } | 
|  | 460 |  | 
|  | 461 | TEST_F(RunDex2OatTest, ThreadsPreBootComplete) { | 
|  | 462 | setSystemProperty("dalvik.vm.boot-dex2oat-threads", "2"); | 
|  | 463 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 464 | args->post_bootcomplete = false; | 
|  | 465 | CallRunDex2Oat(std::move(args)); | 
|  | 466 |  | 
|  | 467 | SetExpectedFlagUsed("-j", "2"); | 
|  | 468 | VerifyExpectedFlags(); | 
|  | 469 | } | 
|  | 470 |  | 
|  | 471 | TEST_F(RunDex2OatTest, ThreadsPostBootCompleteNotForRestore) { | 
|  | 472 | setSystemProperty("dalvik.vm.dex2oat-threads", "3"); | 
|  | 473 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 474 | args->post_bootcomplete = true; | 
|  | 475 | args->for_restore = false; | 
|  | 476 | CallRunDex2Oat(std::move(args)); | 
|  | 477 |  | 
|  | 478 | SetExpectedFlagUsed("-j", "3"); | 
|  | 479 | VerifyExpectedFlags(); | 
|  | 480 | } | 
|  | 481 |  | 
|  | 482 | TEST_F(RunDex2OatTest, ThreadsPostBootCompleteForRestore) { | 
|  | 483 | setSystemProperty("dalvik.vm.restore-dex2oat-threads", "4"); | 
|  | 484 | setSystemProperty("dalvik.vm.dex2oat-threads", "5"); | 
|  | 485 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 486 | args->post_bootcomplete = true; | 
|  | 487 | args->for_restore = true; | 
|  | 488 | CallRunDex2Oat(std::move(args)); | 
|  | 489 |  | 
|  | 490 | SetExpectedFlagUsed("-j", "4"); | 
|  | 491 | VerifyExpectedFlags(); | 
|  | 492 | } | 
|  | 493 |  | 
|  | 494 | TEST_F(RunDex2OatTest, ThreadsPostBootCompleteForRestore_Backup) { | 
|  | 495 | setSystemProperty("dalvik.vm.restore-dex2oat-threads", ""); | 
|  | 496 | setSystemProperty("dalvik.vm.dex2oat-threads", "5"); | 
|  | 497 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 498 | args->post_bootcomplete = true; | 
|  | 499 | args->for_restore = true; | 
|  | 500 | CallRunDex2Oat(std::move(args)); | 
|  | 501 |  | 
|  | 502 | SetExpectedFlagUsed("-j", "5"); | 
|  | 503 | VerifyExpectedFlags(); | 
|  | 504 | } | 
|  | 505 |  | 
|  | 506 | TEST_F(RunDex2OatTest, Debuggable) { | 
|  | 507 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 508 | args->debuggable = true; | 
|  | 509 | CallRunDex2Oat(std::move(args)); | 
|  | 510 |  | 
|  | 511 | SetExpectedFlagUsed("--debuggable", ""); | 
|  | 512 | VerifyExpectedFlags(); | 
|  | 513 | } | 
|  | 514 |  | 
|  | 515 | TEST_F(RunDex2OatTest, AlwaysDebuggable) { | 
|  | 516 | setSystemProperty("dalvik.vm.always_debuggable", "1"); | 
|  | 517 | CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs()); | 
|  | 518 |  | 
|  | 519 | SetExpectedFlagUsed("--debuggable", ""); | 
|  | 520 | VerifyExpectedFlags(); | 
|  | 521 | } | 
|  | 522 |  | 
|  | 523 | TEST_F(RunDex2OatTest, GenerateDebugInfo) { | 
|  | 524 | setSystemProperty("debug.generate-debug-info", "true"); | 
|  | 525 | CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs()); | 
|  | 526 |  | 
|  | 527 | SetExpectedFlagUsed("--generate-debug-info", ""); | 
|  | 528 | VerifyExpectedFlags(); | 
|  | 529 | } | 
|  | 530 |  | 
|  | 531 | TEST_F(RunDex2OatTest, HiddenApiCheck) { | 
|  | 532 | auto args = RunDex2OatArgs::MakeDefaultTestArgs(); | 
|  | 533 | args->enable_hidden_api_checks = true; | 
|  | 534 | CallRunDex2Oat(std::move(args)); | 
|  | 535 |  | 
|  | 536 | SetExpectedFlagUsed("-Xhidden-api-policy", ":enabled"); | 
|  | 537 | VerifyExpectedFlags(); | 
|  | 538 | } | 
|  | 539 |  | 
|  | 540 | TEST_F(RunDex2OatTest, Misc) { | 
|  | 541 | setSystemProperty("dalvik.vm.dex2oat-max-image-block-size", "524288"); | 
|  | 542 | setSystemProperty("dalvik.vm.dex2oat-very-large", "100000"); | 
|  | 543 | CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs()); | 
|  | 544 |  | 
|  | 545 | SetExpectedFlagUsed("--max-image-block-size", "=524288"); | 
|  | 546 | SetExpectedFlagUsed("--very-large-app-threshold", "=100000"); | 
|  | 547 | VerifyExpectedFlags(); | 
|  | 548 | } | 
|  | 549 |  | 
|  | 550 | TEST_F(RunDex2OatTest, ExtraFlags) { | 
|  | 551 | setSystemProperty("dalvik.vm.dex2oat-flags", "--foo=123 --bar:456 --baz"); | 
|  | 552 | CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs()); | 
|  | 553 |  | 
|  | 554 | SetExpectedFlagUsed("--foo", "=123"); | 
|  | 555 | SetExpectedFlagUsed("--bar", ":456"); | 
|  | 556 | SetExpectedFlagUsed("--baz", ""); | 
|  | 557 | VerifyExpectedFlags(); | 
|  | 558 | } | 
|  | 559 |  | 
|  | 560 | }  // namespace installd | 
|  | 561 | }  // namespace android |