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"
27 #include "unique_file.h"
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
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;
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:
FakeRunDex2Oat(ExecVHelper * execv_helper,FakeSystemProperties * properties)58 FakeRunDex2Oat(ExecVHelper* execv_helper, FakeSystemProperties* properties)
59 : RunDex2Oat("/dir/bin/dex2oat", execv_helper), properties_(properties) { }
60
~FakeRunDex2Oat()61 virtual ~FakeRunDex2Oat() {}
62
GetProperty(const std::string & key,const std::string & default_value)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
GetBoolProperty(const std::string & key,bool default_value)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 {
MakeDefaultTestArgsandroid::installd::RunDex2OatTest::RunDex2OatArgs88 static std::unique_ptr<RunDex2OatArgs> MakeDefaultTestArgs() {
89 auto args = std::make_unique<RunDex2OatArgs>();
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");
94 args->instruction_set = "arm64";
95 args->compilation_reason = "rundex2oattest";
96 return args;
97 }
98
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;
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;
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;
117 bool use_jitzygote = false;
118 const char* compilation_reason = nullptr;
119 };
120
121 class FakeExecVHelper : public ExecVHelper {
122 public:
HasArg(const std::string & arg) const123 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
FlagNotUsed(const std::string & flag) const128 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
Exec(int exit_code)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 }
145 LOG(DEBUG) << "FakeExecVHelper exit_code: " << exit_code << " cmd: " << cmd << "\n";
146 }
147 };
148
SetUp()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.
initializeDefaultExpectedFlags()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;
178 default_expected_flags_["--boot-image"] = FLAG_UNUSED;
179
180 // Arch
181 default_expected_flags_["--instruction-set"] = "=arm64";
182 default_expected_flags_["--instruction-set-features"] = FLAG_UNUSED;
183 default_expected_flags_["--instruction-set-variant"] = FLAG_UNUSED;
184 default_expected_flags_["--cpu-set"] = FLAG_UNUSED;
185
186 // Misc
187 default_expected_flags_["--compiler-filter"] = "=extract";
188 default_expected_flags_["--compilation-reason"] = "=rundex2oattest";
189 default_expected_flags_["--compact-dex-level"] = FLAG_UNUSED;
190 default_expected_flags_["-j"] = FLAG_UNUSED;
191 default_expected_flags_["--max-image-block-size"] = FLAG_UNUSED;
192 default_expected_flags_["--very-large-app-threshold"] = FLAG_UNUSED;
193 default_expected_flags_["--resolve-startup-const-strings"] = FLAG_UNUSED;
194 default_expected_flags_["--force-jit-zygote"] = FLAG_UNUSED;
195
196 // Debug
197 default_expected_flags_["--debuggable"] = FLAG_UNUSED;
198 default_expected_flags_["--generate-debug-info"] = FLAG_UNUSED;
199 default_expected_flags_["--generate-mini-debug-info"] = FLAG_UNUSED;
200
201 // Runtime
202 // TODO(victorhsieh): Check if the previous flag is actually --runtime-arg.
203 default_expected_flags_["-Xms"] = FLAG_UNUSED;
204 default_expected_flags_["-Xmx"] = FLAG_UNUSED;
205 default_expected_flags_["-Xbootclasspath"] = FLAG_UNUSED;
206 default_expected_flags_["-Xtarget-sdk-version"] = FLAG_UNUSED;
207 default_expected_flags_["-Xhidden-api-policy"] = FLAG_UNUSED;
208 default_expected_flags_["-Xnorelocate"] = FLAG_UNUSED;
209
210 // Test only
211 default_expected_flags_["--foo"] = FLAG_UNUSED;
212 default_expected_flags_["--bar"] = FLAG_UNUSED;
213 default_expected_flags_["--baz"] = FLAG_UNUSED;
214 }
215
SetExpectedFlagUsed(const std::string & flag,const std::string & value)216 void SetExpectedFlagUsed(const std::string& flag, const std::string& value) {
217 auto iter = default_expected_flags_.find(flag);
218 ASSERT_NE(iter, default_expected_flags_.end()) << "Must define the default value";
219 iter->second = value;
220 }
221
VerifyExpectedFlags()222 void VerifyExpectedFlags() {
223 for (auto const& [flag, value] : default_expected_flags_) {
224 if (value == FLAG_UNUSED) {
225 EXPECT_TRUE(execv_helper_->FlagNotUsed(flag))
226 << "Flag " << flag << " should be unused, but got the value " << value;
227 } else if (value == "") {
228 EXPECT_TRUE(execv_helper_->HasArg(flag))
229 << "Flag " << flag << " should be specified without value, but got " << value;
230 } else {
231 EXPECT_TRUE(execv_helper_->HasArg(flag + value))
232 << "Flag " << flag << value << " is not specificed";
233 }
234 }
235 }
236
setSystemProperty(const std::string & key,const std::string & value)237 void setSystemProperty(const std::string& key, const std::string& value) {
238 system_properties_[key] = value;
239 }
240
CallRunDex2Oat(std::unique_ptr<RunDex2OatArgs> args)241 void CallRunDex2Oat(std::unique_ptr<RunDex2OatArgs> args) {
242 FakeRunDex2Oat runner(execv_helper_.get(), &system_properties_);
243 runner.Initialize(args->output_oat,
244 args->output_vdex,
245 args->output_image,
246 args->input_dex,
247 args->input_vdex,
248 args->dex_metadata,
249 args->profile,
250 args->class_loader_context,
251 args->class_loader_context_fds,
252 args->swap_fd,
253 args->instruction_set,
254 args->compiler_filter,
255 args->debuggable,
256 args->post_bootcomplete,
257 args->for_restore,
258 args->target_sdk_version,
259 args->enable_hidden_api_checks,
260 args->generate_compact_dex,
261 args->use_jitzygote,
262 args->compilation_reason);
263 runner.Exec(/*exit_code=*/ 0);
264 }
265
266 private:
267 std::unique_ptr<FakeExecVHelper> execv_helper_;
268 std::map<std::string, std::string> default_expected_flags_;
269 FakeSystemProperties system_properties_;
270 };
271
TEST_F(RunDex2OatTest,BasicInputOutput)272 TEST_F(RunDex2OatTest, BasicInputOutput) {
273 auto execv_helper = std::make_unique<FakeExecVHelper>();
274 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
275
276 VerifyExpectedFlags();
277 }
278
TEST_F(RunDex2OatTest,WithAllOtherInputFds)279 TEST_F(RunDex2OatTest, WithAllOtherInputFds) {
280 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
281 args->output_image.reset(IMAGE_FD, "UNUSED_PATH");
282 args->profile.reset(PROFILE_FD, "UNUSED_PATH");
283 args->swap_fd = SWAP_FD;
284 CallRunDex2Oat(std::move(args));
285
286 SetExpectedFlagUsed("--app-image-fd", "=" + std::to_string(IMAGE_FD));
287 SetExpectedFlagUsed("--profile-file-fd", "=" + std::to_string(PROFILE_FD));
288 SetExpectedFlagUsed("--swap-fd", "=" + std::to_string(SWAP_FD));
289 VerifyExpectedFlags();
290 }
291
TEST_F(RunDex2OatTest,WithClassLoaderContext)292 TEST_F(RunDex2OatTest, WithClassLoaderContext) {
293 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
294 args->class_loader_context = "CLASS_LOADER_CONTEXT";
295 CallRunDex2Oat(std::move(args));
296
297 SetExpectedFlagUsed("--class-loader-context", "=CLASS_LOADER_CONTEXT");
298 SetExpectedFlagUsed("--class-loader-context-fds", FLAG_UNUSED);
299 VerifyExpectedFlags();
300 }
301
TEST_F(RunDex2OatTest,WithClassLoaderContextAndFds)302 TEST_F(RunDex2OatTest, WithClassLoaderContextAndFds) {
303 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
304 args->class_loader_context = "CLASS_LOADER_CONTEXT";
305 args->class_loader_context_fds = "CLASS_LOADER_CONTEXT_FDS";
306 CallRunDex2Oat(std::move(args));
307
308 SetExpectedFlagUsed("--class-loader-context", "=CLASS_LOADER_CONTEXT");
309 SetExpectedFlagUsed("--class-loader-context-fds", "=CLASS_LOADER_CONTEXT_FDS");
310 VerifyExpectedFlags();
311 }
312
TEST_F(RunDex2OatTest,WithOnlyClassLoaderContextFds)313 TEST_F(RunDex2OatTest, WithOnlyClassLoaderContextFds) {
314 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
315 args->class_loader_context_fds = "CLASS_LOADER_CONTEXT_FDS";
316 CallRunDex2Oat(std::move(args));
317
318 SetExpectedFlagUsed("--class-loader-context", FLAG_UNUSED);
319 SetExpectedFlagUsed("--class-loader-context-fds", FLAG_UNUSED);
320 VerifyExpectedFlags();
321 }
322
TEST_F(RunDex2OatTest,DoNotGenerateCompactDex)323 TEST_F(RunDex2OatTest, DoNotGenerateCompactDex) {
324 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
325 args->generate_compact_dex = false;
326 CallRunDex2Oat(std::move(args));
327
328 SetExpectedFlagUsed("--compact-dex-level", "=none");
329 VerifyExpectedFlags();
330 }
331
TEST_F(RunDex2OatTest,DoNotGenerateCompactDexWithVdexInPlaceUpdate)332 TEST_F(RunDex2OatTest, DoNotGenerateCompactDexWithVdexInPlaceUpdate) {
333 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
334 args->generate_compact_dex = true;
335 args->input_vdex.reset(INPUT_VDEX_FD, "UNUSED_PATH");
336 args->output_vdex.reset(INPUT_VDEX_FD, "UNUSED_PATH");
337 CallRunDex2Oat(std::move(args));
338
339 SetExpectedFlagUsed("--compact-dex-level", "=none");
340 SetExpectedFlagUsed("--output-vdex-fd", "=" + std::to_string(INPUT_VDEX_FD));
341 VerifyExpectedFlags();
342 }
343
TEST_F(RunDex2OatTest,ISA)344 TEST_F(RunDex2OatTest, ISA) {
345 setSystemProperty("dalvik.vm.isa.x86.features", "a-x86-feature");
346 setSystemProperty("dalvik.vm.isa.x86.variant", "a-x86-variant");
347 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
348 args->instruction_set = "x86";
349 CallRunDex2Oat(std::move(args));
350
351 SetExpectedFlagUsed("--instruction-set", "=x86");
352 SetExpectedFlagUsed("--instruction-set-features", "=a-x86-feature");
353 SetExpectedFlagUsed("--instruction-set-variant", "=a-x86-variant");
354 VerifyExpectedFlags();
355 }
356
TEST_F(RunDex2OatTest,CpuSetPreBootComplete)357 TEST_F(RunDex2OatTest, CpuSetPreBootComplete) {
358 setSystemProperty("dalvik.vm.boot-dex2oat-cpu-set", "1,2");
359 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
360 args->post_bootcomplete = false;
361 CallRunDex2Oat(std::move(args));
362
363 SetExpectedFlagUsed("--cpu-set", "=1,2");
364 VerifyExpectedFlags();
365 }
366
TEST_F(RunDex2OatTest,CpuSetPostBootCompleteNotForRestore)367 TEST_F(RunDex2OatTest, CpuSetPostBootCompleteNotForRestore) {
368 setSystemProperty("dalvik.vm.dex2oat-cpu-set", "1,2");
369 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
370 args->post_bootcomplete = true;
371 args->for_restore = false;
372 CallRunDex2Oat(std::move(args));
373
374 SetExpectedFlagUsed("--cpu-set", "=1,2");
375 VerifyExpectedFlags();
376 }
377
TEST_F(RunDex2OatTest,CpuSetPostBootCompleteForRestore)378 TEST_F(RunDex2OatTest, CpuSetPostBootCompleteForRestore) {
379 setSystemProperty("dalvik.vm.restore-dex2oat-cpu-set", "1,2");
380 setSystemProperty("dalvik.vm.dex2oat-cpu-set", "2,3");
381 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
382 args->post_bootcomplete = true;
383 args->for_restore = true;
384 CallRunDex2Oat(std::move(args));
385
386 SetExpectedFlagUsed("--cpu-set", "=1,2");
387 VerifyExpectedFlags();
388 }
389
TEST_F(RunDex2OatTest,CpuSetPostBootCompleteForRestore_Backup)390 TEST_F(RunDex2OatTest, CpuSetPostBootCompleteForRestore_Backup) {
391 setSystemProperty("dalvik.vm.restore-dex2oat-cpu-set", "");
392 setSystemProperty("dalvik.vm.dex2oat-cpu-set", "1,2");
393 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
394 args->post_bootcomplete = true;
395 args->for_restore = true;
396 CallRunDex2Oat(std::move(args));
397
398 SetExpectedFlagUsed("--cpu-set", "=1,2");
399 VerifyExpectedFlags();
400 }
401
TEST_F(RunDex2OatTest,Runtime)402 TEST_F(RunDex2OatTest, Runtime) {
403 setSystemProperty("dalvik.vm.dex2oat-Xms", "1234m");
404 setSystemProperty("dalvik.vm.dex2oat-Xmx", "5678m");
405 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
406 args->target_sdk_version = 30;
407 args->enable_hidden_api_checks = true;
408 CallRunDex2Oat(std::move(args));
409
410 SetExpectedFlagUsed("-Xms", "1234m");
411 SetExpectedFlagUsed("-Xmx", "5678m");
412 SetExpectedFlagUsed("-Xtarget-sdk-version", ":30");
413 SetExpectedFlagUsed("-Xhidden-api-policy", ":enabled");
414 SetExpectedFlagUsed("-Xnorelocate", FLAG_UNUSED);
415 VerifyExpectedFlags();
416 }
417
TEST_F(RunDex2OatTest,SkipRelocationInMinFramework)418 TEST_F(RunDex2OatTest, SkipRelocationInMinFramework) {
419 setSystemProperty("vold.decrypt", "trigger_restart_min_framework");
420 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
421
422 SetExpectedFlagUsed("--compiler-filter", "=extract");
423 SetExpectedFlagUsed("-Xnorelocate", "");
424 VerifyExpectedFlags();
425 }
426
TEST_F(RunDex2OatTest,SkipRelocationIfDecryptedWithFullDiskEncryption)427 TEST_F(RunDex2OatTest, SkipRelocationIfDecryptedWithFullDiskEncryption) {
428 setSystemProperty("vold.decrypt", "1");
429 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
430
431 SetExpectedFlagUsed("--compiler-filter", "=extract");
432 SetExpectedFlagUsed("-Xnorelocate", "");
433 VerifyExpectedFlags();
434 }
435
TEST_F(RunDex2OatTest,DalvikVmDex2oatFilter)436 TEST_F(RunDex2OatTest, DalvikVmDex2oatFilter) {
437 setSystemProperty("dalvik.vm.dex2oat-filter", "speed");
438 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
439 args->compiler_filter = nullptr;
440 CallRunDex2Oat(std::move(args));
441
442 SetExpectedFlagUsed("--compiler-filter", "=speed");
443 VerifyExpectedFlags();
444 }
445
TEST_F(RunDex2OatTest,ResolveStartupStartings)446 TEST_F(RunDex2OatTest, ResolveStartupStartings) {
447 setSystemProperty("dalvik.vm.dex2oat-resolve-startup-strings", "false");
448 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
449
450 SetExpectedFlagUsed("--resolve-startup-const-strings", "=false");
451 VerifyExpectedFlags();
452 }
453
TEST_F(RunDex2OatTest,ResolveStartupStartingsOverride)454 TEST_F(RunDex2OatTest, ResolveStartupStartingsOverride) {
455 setSystemProperty("dalvik.vm.dex2oat-resolve-startup-strings", "false");
456 setSystemProperty("persist.device_config.runtime.dex2oat_resolve_startup_strings", "true");
457 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
458
459 SetExpectedFlagUsed("--resolve-startup-const-strings", "=true");
460 VerifyExpectedFlags();
461 }
462
TEST_F(RunDex2OatTest,ThreadsPreBootComplete)463 TEST_F(RunDex2OatTest, ThreadsPreBootComplete) {
464 setSystemProperty("dalvik.vm.boot-dex2oat-threads", "2");
465 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
466 args->post_bootcomplete = false;
467 CallRunDex2Oat(std::move(args));
468
469 SetExpectedFlagUsed("-j", "2");
470 VerifyExpectedFlags();
471 }
472
TEST_F(RunDex2OatTest,ThreadsPostBootCompleteNotForRestore)473 TEST_F(RunDex2OatTest, ThreadsPostBootCompleteNotForRestore) {
474 setSystemProperty("dalvik.vm.dex2oat-threads", "3");
475 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
476 args->post_bootcomplete = true;
477 args->for_restore = false;
478 CallRunDex2Oat(std::move(args));
479
480 SetExpectedFlagUsed("-j", "3");
481 VerifyExpectedFlags();
482 }
483
TEST_F(RunDex2OatTest,ThreadsPostBootCompleteForRestore)484 TEST_F(RunDex2OatTest, ThreadsPostBootCompleteForRestore) {
485 setSystemProperty("dalvik.vm.restore-dex2oat-threads", "4");
486 setSystemProperty("dalvik.vm.dex2oat-threads", "5");
487 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
488 args->post_bootcomplete = true;
489 args->for_restore = true;
490 CallRunDex2Oat(std::move(args));
491
492 SetExpectedFlagUsed("-j", "4");
493 VerifyExpectedFlags();
494 }
495
TEST_F(RunDex2OatTest,ThreadsPostBootCompleteForRestore_Backup)496 TEST_F(RunDex2OatTest, ThreadsPostBootCompleteForRestore_Backup) {
497 setSystemProperty("dalvik.vm.restore-dex2oat-threads", "");
498 setSystemProperty("dalvik.vm.dex2oat-threads", "5");
499 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
500 args->post_bootcomplete = true;
501 args->for_restore = true;
502 CallRunDex2Oat(std::move(args));
503
504 SetExpectedFlagUsed("-j", "5");
505 VerifyExpectedFlags();
506 }
507
TEST_F(RunDex2OatTest,Debuggable)508 TEST_F(RunDex2OatTest, Debuggable) {
509 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
510 args->debuggable = true;
511 CallRunDex2Oat(std::move(args));
512
513 SetExpectedFlagUsed("--debuggable", "");
514 VerifyExpectedFlags();
515 }
516
TEST_F(RunDex2OatTest,AlwaysDebuggable)517 TEST_F(RunDex2OatTest, AlwaysDebuggable) {
518 setSystemProperty("dalvik.vm.always_debuggable", "1");
519 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
520
521 SetExpectedFlagUsed("--debuggable", "");
522 VerifyExpectedFlags();
523 }
524
TEST_F(RunDex2OatTest,GenerateDebugInfo)525 TEST_F(RunDex2OatTest, GenerateDebugInfo) {
526 setSystemProperty("debug.generate-debug-info", "true");
527 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
528
529 SetExpectedFlagUsed("--generate-debug-info", "");
530 VerifyExpectedFlags();
531 }
532
TEST_F(RunDex2OatTest,HiddenApiCheck)533 TEST_F(RunDex2OatTest, HiddenApiCheck) {
534 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
535 args->enable_hidden_api_checks = true;
536 CallRunDex2Oat(std::move(args));
537
538 SetExpectedFlagUsed("-Xhidden-api-policy", ":enabled");
539 VerifyExpectedFlags();
540 }
541
TEST_F(RunDex2OatTest,Misc)542 TEST_F(RunDex2OatTest, Misc) {
543 setSystemProperty("dalvik.vm.dex2oat-max-image-block-size", "524288");
544 setSystemProperty("dalvik.vm.dex2oat-very-large", "100000");
545 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
546
547 SetExpectedFlagUsed("--max-image-block-size", "=524288");
548 SetExpectedFlagUsed("--very-large-app-threshold", "=100000");
549 VerifyExpectedFlags();
550 }
551
TEST_F(RunDex2OatTest,ExtraFlags)552 TEST_F(RunDex2OatTest, ExtraFlags) {
553 setSystemProperty("dalvik.vm.dex2oat-flags", "--foo=123 --bar:456 --baz");
554 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
555
556 SetExpectedFlagUsed("--foo", "=123");
557 SetExpectedFlagUsed("--bar", ":456");
558 SetExpectedFlagUsed("--baz", "");
559 VerifyExpectedFlags();
560 }
561
TEST_F(RunDex2OatTest,UseJitZygoteImage)562 TEST_F(RunDex2OatTest, UseJitZygoteImage) {
563 auto args = RunDex2OatArgs::MakeDefaultTestArgs();
564 args->use_jitzygote = true;
565 CallRunDex2Oat(std::move(args));
566
567 SetExpectedFlagUsed("--force-jit-zygote", "");
568 VerifyExpectedFlags();
569 }
570
TEST_F(RunDex2OatTest,BootImage)571 TEST_F(RunDex2OatTest, BootImage) {
572 setSystemProperty("dalvik.vm.boot-image", "foo.art:bar.art");
573 CallRunDex2Oat(RunDex2OatArgs::MakeDefaultTestArgs());
574
575 SetExpectedFlagUsed("--boot-image", "=foo.art:bar.art");
576 VerifyExpectedFlags();
577 }
578
579 } // namespace installd
580 } // namespace android
581