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