blob: 1ecdd0d77e7204d6ecfebc763f8aa58c615b3f2d [file] [log] [blame]
Richard Uhler66d874d2015-01-15 09:37:19 -08001/*
2 * Copyright (C) 2014 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
Richard Uhler66d874d2015-01-15 09:37:19 -080017#include <string>
18#include <vector>
19#include <sys/param.h>
20
Andreas Gampe9186ced2016-12-12 14:28:21 -080021#include "android-base/strings.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080022#include <gtest/gtest.h>
23
Mathieu Chartierc7853442015-03-27 14:35:38 -070024#include "art_field-inl.h"
Vladimir Marko3481ba22015-04-13 12:22:36 +010025#include "class_linker-inl.h"
Jeff Hao0cb17282017-07-12 14:51:49 -070026#include "common_runtime_test.h"
Calin Juravle36eb3132017-01-13 16:32:38 -080027#include "dexopt_test.h"
Andreas Gampee1459ae2016-06-29 09:36:30 -070028#include "oat_file_assistant.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070029#include "oat_file_manager.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080030#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070031#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070032#include "thread-current-inl.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080033#include "utils.h"
34
35namespace art {
36
Calin Juravle36eb3132017-01-13 16:32:38 -080037class OatFileAssistantTest : public DexoptTest {};
Richard Uhler66d874d2015-01-15 09:37:19 -080038
Calin Juravle36eb3132017-01-13 16:32:38 -080039class OatFileAssistantNoDex2OatTest : public DexoptTest {
Richard Uhler66d874d2015-01-15 09:37:19 -080040 public:
41 virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
Calin Juravle36eb3132017-01-13 16:32:38 -080042 DexoptTest::SetUpRuntimeOptions(options);
Richard Uhler66d874d2015-01-15 09:37:19 -080043 options->push_back(std::make_pair("-Xnodex2oat", nullptr));
44 }
45};
46
Calin Juravle357c66d2017-05-04 01:57:17 +000047class ScopedNonWritable {
48 public:
49 explicit ScopedNonWritable(const std::string& dex_location) {
50 is_valid_ = false;
51 size_t pos = dex_location.rfind('/');
52 if (pos != std::string::npos) {
53 is_valid_ = true;
54 dex_parent_ = dex_location.substr(0, pos);
55 if (chmod(dex_parent_.c_str(), 0555) != 0) {
56 PLOG(ERROR) << "Could not change permissions on " << dex_parent_;
57 }
58 }
59 }
60
61 bool IsSuccessful() { return is_valid_ && (access(dex_parent_.c_str(), W_OK) != 0); }
62
63 ~ScopedNonWritable() {
64 if (is_valid_) {
65 if (chmod(dex_parent_.c_str(), 0777) != 0) {
66 PLOG(ERROR) << "Could not restore permissions on " << dex_parent_;
67 }
68 }
69 }
70
71 private:
72 std::string dex_parent_;
73 bool is_valid_;
74};
75
76static bool IsExecutedAsRoot() {
77 return geteuid() == 0;
78}
Calin Juravle36eb3132017-01-13 16:32:38 -080079
Richard Uhler66d874d2015-01-15 09:37:19 -080080// Case: We have a DEX file, but no OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -070081// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -080082TEST_F(OatFileAssistantTest, DexNoOat) {
83 std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
84 Copy(GetDexSrc1(), dex_location);
85
Richard Uhlerd1472a22016-04-15 15:18:56 -070086 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -080087
Richard Uhler7225a8d2016-11-22 10:12:03 +000088 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Nicolas Geoffray49cda062017-04-21 13:08:25 +010089 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +000090 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Nicolas Geoffray49cda062017-04-21 13:08:25 +010091 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhler7225a8d2016-11-22 10:12:03 +000092 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +000093 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
Richard Uhler7225a8d2016-11-22 10:12:03 +000094 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +000095 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -080096
97 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +000098 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
99 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700100 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800101}
102
103// Case: We have no DEX file and no OAT file.
Richard Uhler9b994ea2015-06-24 08:44:19 -0700104// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800105TEST_F(OatFileAssistantTest, NoDexNoOat) {
106 std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
107
Richard Uhlerd1472a22016-04-15 15:18:56 -0700108 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800109
Andreas Gampe29d38e72016-03-23 15:31:51 +0000110 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
111 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700112 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
113
114 // Trying to make the oat file up to date should not fail or crash.
115 std::string error_msg;
Richard Uhlerd1472a22016-04-15 15:18:56 -0700116 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700117
118 // Trying to get the best oat file should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800119 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
120 EXPECT_EQ(nullptr, oat_file.get());
121}
122
Calin Juravle357c66d2017-05-04 01:57:17 +0000123// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
124// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
125TEST_F(OatFileAssistantTest, OdexUpToDate) {
126 std::string dex_location = GetScratchDir() + "/OdexUpToDate.jar";
127 std::string odex_location = GetOdexDir() + "/OdexUpToDate.odex";
128 Copy(GetDexSrc1(), dex_location);
129 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
130
131 // For the use of oat location by making the dex parent not writable.
132 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
133
134 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
135 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
136 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
137 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
138 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
139 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
140 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
141 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
142
143 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
144 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
145 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
146 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
147}
148
149// Case: We have a DEX file and a PIC ODEX file, but no OAT file. We load the dex
150// file via a symlink.
151// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
152TEST_F(OatFileAssistantTest, OdexUpToDateSymLink) {
153 std::string scratch_dir = GetScratchDir();
154 std::string dex_location = GetScratchDir() + "/OdexUpToDate.jar";
155 std::string odex_location = GetOdexDir() + "/OdexUpToDate.odex";
156
157 Copy(GetDexSrc1(), dex_location);
158 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
159
160 // Now replace the dex location with a symlink.
161 std::string link = scratch_dir + "/link";
162 ASSERT_EQ(0, symlink(scratch_dir.c_str(), link.c_str()));
163 dex_location = link + "/OdexUpToDate.jar";
164
165 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
166
167 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
168 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
169 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
170 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
171 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
172 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
173 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
174 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
175
176 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
177 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
178 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
179 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
180}
181
Richard Uhler66d874d2015-01-15 09:37:19 -0800182// Case: We have a DEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700183// Expect: The status is kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800184TEST_F(OatFileAssistantTest, OatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000185 if (IsExecutedAsRoot()) {
186 // We cannot simulate non writable locations when executed as root: b/38000545.
187 LOG(ERROR) << "Test skipped because it's running as root";
188 return;
189 }
190
Richard Uhler66d874d2015-01-15 09:37:19 -0800191 std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
192 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000193 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800194
Calin Juravle357c66d2017-05-04 01:57:17 +0000195 // For the use of oat location by making the dex parent not writable.
196 ScopedNonWritable scoped_non_writable(dex_location);
197 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
198
199 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
200
201 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
202 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
203 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
204 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
205 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
206 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
207 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
208 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
209
210 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
211 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
212 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
213 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
214}
215
216// Case: We have a DEX file and up-to-date OAT file for it. We load the dex file
217// via a symlink.
218// Expect: The status is kNoDexOptNeeded.
219TEST_F(OatFileAssistantTest, OatUpToDateSymLink) {
220 if (IsExecutedAsRoot()) {
221 // We cannot simulate non writable locations when executed as root: b/38000545.
222 LOG(ERROR) << "Test skipped because it's running as root";
223 return;
224 }
225
226 std::string real = GetScratchDir() + "/real";
227 ASSERT_EQ(0, mkdir(real.c_str(), 0700));
228 std::string link = GetScratchDir() + "/link";
229 ASSERT_EQ(0, symlink(real.c_str(), link.c_str()));
230
231 std::string dex_location = real + "/OatUpToDate.jar";
232
233 Copy(GetDexSrc1(), dex_location);
234 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
235
236 // Update the dex location to point to the symlink.
237 dex_location = link + "/OatUpToDate.jar";
238
239 // For the use of oat location by making the dex parent not writable.
240 ScopedNonWritable scoped_non_writable(dex_location);
241 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
242
Richard Uhlerd1472a22016-04-15 15:18:56 -0700243 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800244
Andreas Gampe29d38e72016-03-23 15:31:51 +0000245 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
246 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
247 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100248 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000249 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100250 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000251 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000252 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
253
Richard Uhler66d874d2015-01-15 09:37:19 -0800254 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000255 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
Richard Uhler95abd042015-03-24 09:51:28 -0700256 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700257 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800258}
259
Richard Uhler2f27abd2017-01-31 14:02:34 +0000260// Case: We have a DEX file and up-to-date (ODEX) VDEX file for it, but no
261// ODEX file.
262TEST_F(OatFileAssistantTest, VdexUpToDateNoOdex) {
263 // This test case is only meaningful if vdex is enabled.
264 if (!kIsVdexEnabled) {
265 return;
266 }
Richard Uhler9a37efc2016-08-05 16:32:55 -0700267
Richard Uhler2f27abd2017-01-31 14:02:34 +0000268 std::string dex_location = GetScratchDir() + "/VdexUpToDateNoOdex.jar";
Calin Juravle357c66d2017-05-04 01:57:17 +0000269 std::string odex_location = GetOdexDir() + "/VdexUpToDateNoOdex.oat";
Richard Uhler2f27abd2017-01-31 14:02:34 +0000270
Richard Uhler9a37efc2016-08-05 16:32:55 -0700271 Copy(GetDexSrc1(), dex_location);
272
Richard Uhler2f27abd2017-01-31 14:02:34 +0000273 // Generating and deleting the oat file should have the side effect of
274 // creating an up-to-date vdex file.
Calin Juravle357c66d2017-05-04 01:57:17 +0000275 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
276 ASSERT_EQ(0, unlink(odex_location.c_str()));
Richard Uhler2f27abd2017-01-31 14:02:34 +0000277
Calin Juravle357c66d2017-05-04 01:57:17 +0000278 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler2f27abd2017-01-31 14:02:34 +0000279
280 // Even though the vdex file is up to date, because we don't have the oat
281 // file, we can't know that the vdex depends on the boot image and is up to
282 // date with respect to the boot image. Instead we must assume the vdex file
283 // depends on the boot image and is out of date with respect to the boot
284 // image.
285 EXPECT_EQ(-OatFileAssistant::kDex2OatForBootImage,
286 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
287
288 // Make sure we don't crash in this case when we dump the status. We don't
289 // care what the actual dumped value is.
290 oat_file_assistant.GetStatusDump();
291}
292
293// Case: We have a DEX file and empty VDEX and ODEX files.
294TEST_F(OatFileAssistantTest, EmptyVdexOdex) {
295 std::string dex_location = GetScratchDir() + "/EmptyVdexOdex.jar";
296 std::string odex_location = GetOdexDir() + "/EmptyVdexOdex.oat";
297 std::string vdex_location = GetOdexDir() + "/EmptyVdexOdex.vdex";
298
299 Copy(GetDexSrc1(), dex_location);
Richard Uhler5cd59292017-02-01 12:54:23 +0000300 ScratchFile vdex_file(vdex_location.c_str());
301 ScratchFile odex_file(odex_location.c_str());
Richard Uhler2f27abd2017-01-31 14:02:34 +0000302
303 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
304 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
305 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
306}
307
308// Case: We have a DEX file and up-to-date (OAT) VDEX file for it, but no OAT
309// file.
310TEST_F(OatFileAssistantTest, VdexUpToDateNoOat) {
311 // This test case is only meaningful if vdex is enabled.
312 if (!kIsVdexEnabled) {
313 return;
314 }
Calin Juravle357c66d2017-05-04 01:57:17 +0000315 if (IsExecutedAsRoot()) {
316 // We cannot simulate non writable locations when executed as root: b/38000545.
317 LOG(ERROR) << "Test skipped because it's running as root";
318 return;
319 }
Richard Uhler2f27abd2017-01-31 14:02:34 +0000320
321 std::string dex_location = GetScratchDir() + "/VdexUpToDateNoOat.jar";
322 std::string oat_location;
323 std::string error_msg;
324 ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename(
325 dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg;
326
327 Copy(GetDexSrc1(), dex_location);
328 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
329 ASSERT_EQ(0, unlink(oat_location.c_str()));
330
Calin Juravle357c66d2017-05-04 01:57:17 +0000331 ScopedNonWritable scoped_non_writable(dex_location);
332 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
Richard Uhler9a37efc2016-08-05 16:32:55 -0700333 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
334
Richard Uhler2f27abd2017-01-31 14:02:34 +0000335 // Even though the vdex file is up to date, because we don't have the oat
336 // file, we can't know that the vdex depends on the boot image and is up to
337 // date with respect to the boot image. Instead we must assume the vdex file
338 // depends on the boot image and is out of date with respect to the boot
339 // image.
340 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Richard Uhler9a37efc2016-08-05 16:32:55 -0700341 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9a37efc2016-08-05 16:32:55 -0700342}
343
Andreas Gampe29d38e72016-03-23 15:31:51 +0000344// Case: We have a DEX file and speed-profile OAT file for it.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700345// Expect: The status is kNoDexOptNeeded if the profile hasn't changed, but
346// kDex2Oat if the profile has changed.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000347TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000348 if (IsExecutedAsRoot()) {
349 // We cannot simulate non writable locations when executed as root: b/38000545.
350 LOG(ERROR) << "Test skipped because it's running as root";
351 return;
352 }
353
Andreas Gampe29d38e72016-03-23 15:31:51 +0000354 std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
355 Copy(GetDexSrc1(), dex_location);
356 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
357
Calin Juravle357c66d2017-05-04 01:57:17 +0000358 ScopedNonWritable scoped_non_writable(dex_location);
359 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
360
Richard Uhlerd1472a22016-04-15 15:18:56 -0700361 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000362
363 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700364 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, false));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000365 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100366 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken, false));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000367 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700368 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, true));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000369 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100370 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken, true));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000371
372 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000373 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000374 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
375 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
376}
377
Richard Uhler66d874d2015-01-15 09:37:19 -0800378// Case: We have a MultiDEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700379// Expect: The status is kNoDexOptNeeded and we load all dex files.
Richard Uhler66d874d2015-01-15 09:37:19 -0800380TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000381 if (IsExecutedAsRoot()) {
382 // We cannot simulate non writable locations when executed as root: b/38000545.
383 LOG(ERROR) << "Test skipped because it's running as root";
384 return;
385 }
386
Richard Uhler66d874d2015-01-15 09:37:19 -0800387 std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
388 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000389 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800390
Calin Juravle357c66d2017-05-04 01:57:17 +0000391 ScopedNonWritable scoped_non_writable(dex_location);
392 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
393
Richard Uhlerd1472a22016-04-15 15:18:56 -0700394 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000395 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700396 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700397 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler95abd042015-03-24 09:51:28 -0700398
399 // Verify we can load both dex files.
Richard Uhlere5fed032015-03-18 08:21:11 -0700400 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
Richard Uhler66d874d2015-01-15 09:37:19 -0800401 ASSERT_TRUE(oat_file.get() != nullptr);
402 EXPECT_TRUE(oat_file->IsExecutable());
403 std::vector<std::unique_ptr<const DexFile>> dex_files;
Richard Uhlere5fed032015-03-18 08:21:11 -0700404 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
405 EXPECT_EQ(2u, dex_files.size());
406}
407
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000408// Case: We have a MultiDEX file where the non-main multdex entry is out of date.
Richard Uhler67ff7d12015-05-14 13:21:13 -0700409// Expect: The status is kDex2OatNeeded.
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000410TEST_F(OatFileAssistantTest, MultiDexNonMainOutOfDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000411 if (IsExecutedAsRoot()) {
412 // We cannot simulate non writable locations when executed as root: b/38000545.
413 LOG(ERROR) << "Test skipped because it's running as root";
414 return;
415 }
416
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000417 std::string dex_location = GetScratchDir() + "/MultiDexNonMainOutOfDate.jar";
Richard Uhler67ff7d12015-05-14 13:21:13 -0700418
419 // Compile code for GetMultiDexSrc1.
420 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000421 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler67ff7d12015-05-14 13:21:13 -0700422
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000423 // Now overwrite the dex file with GetMultiDexSrc2 so the non-main checksum
Richard Uhler67ff7d12015-05-14 13:21:13 -0700424 // is out of date.
425 Copy(GetMultiDexSrc2(), dex_location);
426
Calin Juravle357c66d2017-05-04 01:57:17 +0000427 ScopedNonWritable scoped_non_writable(dex_location);
428 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
429
Richard Uhlerd1472a22016-04-15 15:18:56 -0700430 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler7225a8d2016-11-22 10:12:03 +0000431 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700432 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700433 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler67ff7d12015-05-14 13:21:13 -0700434}
435
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000436// Case: We have a stripped MultiDEX file where the non-main multidex entry is
437// out of date with respect to the odex file.
438TEST_F(OatFileAssistantTest, StrippedMultiDexNonMainOutOfDate) {
439 std::string dex_location = GetScratchDir() + "/StrippedMultiDexNonMainOutOfDate.jar";
440 std::string odex_location = GetOdexDir() + "/StrippedMultiDexNonMainOutOfDate.odex";
441
442 // Compile the oat from GetMultiDexSrc1.
443 Copy(GetMultiDexSrc1(), dex_location);
444 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
445
446 // Compile the odex from GetMultiDexSrc2, which has a different non-main
447 // dex checksum.
448 Copy(GetMultiDexSrc2(), dex_location);
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100449 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kQuicken);
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000450
451 // Strip the dex file.
452 Copy(GetStrippedDexSrc1(), dex_location);
453
454 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, /*load_executable*/false);
455
456 // Because the dex file is stripped, the odex file is considered the source
457 // of truth for the dex checksums. The oat file should be considered
458 // unusable.
459 std::unique_ptr<OatFile> best_file = oat_file_assistant.GetBestOatFile();
460 ASSERT_TRUE(best_file.get() != nullptr);
461 EXPECT_EQ(best_file->GetLocation(), odex_location);
462 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
463 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
464 EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
465}
466
Calin Juravle357c66d2017-05-04 01:57:17 +0000467// Case: We have a MultiDEX file and up-to-date ODEX file for it with relative
Richard Uhlere5fed032015-03-18 08:21:11 -0700468// encoded dex locations.
Richard Uhler95abd042015-03-24 09:51:28 -0700469// Expect: The oat file status is kNoDexOptNeeded.
Richard Uhlere5fed032015-03-18 08:21:11 -0700470TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
471 std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
Calin Juravle357c66d2017-05-04 01:57:17 +0000472 std::string odex_location = GetOdexDir() + "/RelativeEncodedDexLocation.odex";
Richard Uhlere5fed032015-03-18 08:21:11 -0700473
474 // Create the dex file
475 Copy(GetMultiDexSrc1(), dex_location);
476
477 // Create the oat file with relative encoded dex location.
478 std::vector<std::string> args;
479 args.push_back("--dex-file=" + dex_location);
480 args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
Calin Juravle357c66d2017-05-04 01:57:17 +0000481 args.push_back("--oat-file=" + odex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000482 args.push_back("--compiler-filter=speed");
Richard Uhlere5fed032015-03-18 08:21:11 -0700483
484 std::string error_msg;
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700485 ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
Richard Uhlere5fed032015-03-18 08:21:11 -0700486
487 // Verify we can load both dex files.
Calin Juravle357c66d2017-05-04 01:57:17 +0000488 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
489
Richard Uhlere5fed032015-03-18 08:21:11 -0700490 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
491 ASSERT_TRUE(oat_file.get() != nullptr);
492 EXPECT_TRUE(oat_file->IsExecutable());
493 std::vector<std::unique_ptr<const DexFile>> dex_files;
494 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
Richard Uhler66d874d2015-01-15 09:37:19 -0800495 EXPECT_EQ(2u, dex_files.size());
496}
497
Richard Uhler03bc6592016-11-22 09:42:04 +0000498// Case: We have a DEX file and an OAT file out of date with respect to the
499// dex checksum.
500TEST_F(OatFileAssistantTest, OatDexOutOfDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000501 if (IsExecutedAsRoot()) {
502 // We cannot simulate non writable locations when executed as root: b/38000545.
503 LOG(ERROR) << "Test skipped because it's running as root";
504 return;
505 }
506
Richard Uhler03bc6592016-11-22 09:42:04 +0000507 std::string dex_location = GetScratchDir() + "/OatDexOutOfDate.jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800508
509 // We create a dex, generate an oat for it, then overwrite the dex with a
510 // different dex to make the oat out of date.
511 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000512 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800513 Copy(GetDexSrc2(), dex_location);
514
Calin Juravle357c66d2017-05-04 01:57:17 +0000515 ScopedNonWritable scoped_non_writable(dex_location);
516 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
517
Richard Uhlerd1472a22016-04-15 15:18:56 -0700518 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler7225a8d2016-11-22 10:12:03 +0000519 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100520 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000521 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000522 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800523
524 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000525 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
526 EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
527 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
528}
529
Richard Uhler2f27abd2017-01-31 14:02:34 +0000530// Case: We have a DEX file and an (ODEX) VDEX file out of date with respect
531// to the dex checksum, but no ODEX file.
532TEST_F(OatFileAssistantTest, VdexDexOutOfDate) {
533 // This test case is only meaningful if vdex is enabled.
534 if (!kIsVdexEnabled) {
535 return;
536 }
537
538 std::string dex_location = GetScratchDir() + "/VdexDexOutOfDate.jar";
Calin Juravle357c66d2017-05-04 01:57:17 +0000539 std::string odex_location = GetOdexDir() + "/VdexDexOutOfDate.oat";
Richard Uhler2f27abd2017-01-31 14:02:34 +0000540
541 Copy(GetDexSrc1(), dex_location);
Calin Juravle357c66d2017-05-04 01:57:17 +0000542 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
543 ASSERT_EQ(0, unlink(odex_location.c_str()));
Richard Uhler2f27abd2017-01-31 14:02:34 +0000544 Copy(GetDexSrc2(), dex_location);
545
Calin Juravle357c66d2017-05-04 01:57:17 +0000546 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler2f27abd2017-01-31 14:02:34 +0000547
548 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
549 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
550}
551
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000552// Case: We have a MultiDEX (ODEX) VDEX file where the non-main multidex entry
553// is out of date and there is no corresponding ODEX file.
554TEST_F(OatFileAssistantTest, VdexMultiDexNonMainOutOfDate) {
Richard Uhler2f27abd2017-01-31 14:02:34 +0000555 // This test case is only meaningful if vdex is enabled.
556 if (!kIsVdexEnabled) {
557 return;
558 }
559
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000560 std::string dex_location = GetScratchDir() + "/VdexMultiDexNonMainOutOfDate.jar";
Calin Juravle357c66d2017-05-04 01:57:17 +0000561 std::string odex_location = GetOdexDir() + "/VdexMultiDexNonMainOutOfDate.odex";
Richard Uhler2f27abd2017-01-31 14:02:34 +0000562
563 Copy(GetMultiDexSrc1(), dex_location);
Calin Juravle357c66d2017-05-04 01:57:17 +0000564 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
565 ASSERT_EQ(0, unlink(odex_location.c_str()));
Richard Uhler2f27abd2017-01-31 14:02:34 +0000566 Copy(GetMultiDexSrc2(), dex_location);
567
Calin Juravle357c66d2017-05-04 01:57:17 +0000568 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler2f27abd2017-01-31 14:02:34 +0000569
570 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
571 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
572}
573
Richard Uhler03bc6592016-11-22 09:42:04 +0000574// Case: We have a DEX file and an OAT file out of date with respect to the
575// boot image.
576TEST_F(OatFileAssistantTest, OatImageOutOfDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000577 if (IsExecutedAsRoot()) {
578 // We cannot simulate non writable locations when executed as root: b/38000545.
579 LOG(ERROR) << "Test skipped because it's running as root";
580 return;
581 }
582
Richard Uhler03bc6592016-11-22 09:42:04 +0000583 std::string dex_location = GetScratchDir() + "/OatImageOutOfDate.jar";
584
585 Copy(GetDexSrc1(), dex_location);
586 GenerateOatForTest(dex_location.c_str(),
587 CompilerFilter::kSpeed,
588 /*relocate*/true,
589 /*pic*/false,
Richard Uhler03bc6592016-11-22 09:42:04 +0000590 /*with_alternate_image*/true);
591
Calin Juravle357c66d2017-05-04 01:57:17 +0000592 ScopedNonWritable scoped_non_writable(dex_location);
593 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
594
Richard Uhler03bc6592016-11-22 09:42:04 +0000595 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler7225a8d2016-11-22 10:12:03 +0000596 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100597 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000598 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100599 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000600 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Richard Uhler03bc6592016-11-22 09:42:04 +0000601 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
602
603 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
604 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
605 EXPECT_EQ(OatFileAssistant::kOatBootImageOutOfDate, oat_file_assistant.OatFileStatus());
606 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
607}
608
609// Case: We have a DEX file and a verify-at-runtime OAT file out of date with
610// respect to the boot image.
611// It shouldn't matter that the OAT file is out of date, because it is
612// verify-at-runtime.
613TEST_F(OatFileAssistantTest, OatVerifyAtRuntimeImageOutOfDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000614 if (IsExecutedAsRoot()) {
615 // We cannot simulate non writable locations when executed as root: b/38000545.
616 LOG(ERROR) << "Test skipped because it's running as root";
617 return;
618 }
619
Richard Uhler03bc6592016-11-22 09:42:04 +0000620 std::string dex_location = GetScratchDir() + "/OatVerifyAtRuntimeImageOutOfDate.jar";
621
622 Copy(GetDexSrc1(), dex_location);
623 GenerateOatForTest(dex_location.c_str(),
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100624 CompilerFilter::kExtract,
Richard Uhler03bc6592016-11-22 09:42:04 +0000625 /*relocate*/true,
626 /*pic*/false,
Richard Uhler03bc6592016-11-22 09:42:04 +0000627 /*with_alternate_image*/true);
628
Calin Juravle357c66d2017-05-04 01:57:17 +0000629 ScopedNonWritable scoped_non_writable(dex_location);
630 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
631
Richard Uhler03bc6592016-11-22 09:42:04 +0000632 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
633 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100634 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000635 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100636 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhler03bc6592016-11-22 09:42:04 +0000637
638 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
639 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
640 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700641 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800642}
643
644// Case: We have a DEX file and an ODEX file, but no OAT file.
Richard Uhler66d874d2015-01-15 09:37:19 -0800645TEST_F(OatFileAssistantTest, DexOdexNoOat) {
646 std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700647 std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800648
649 // Create the dex and odex files
650 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000651 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800652
653 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700654 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800655
Andreas Gampe29d38e72016-03-23 15:31:51 +0000656 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100657 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler5923b522016-12-08 09:48:01 +0000658 EXPECT_EQ(-OatFileAssistant::kDex2OatForRelocation,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000659 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800660
661 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000662 EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus());
663 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700664 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler5f946da2015-07-17 12:28:32 -0700665
666 // We should still be able to get the non-executable odex file to run from.
667 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
668 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhler66d874d2015-01-15 09:37:19 -0800669}
670
Richard Uhler5923b522016-12-08 09:48:01 +0000671// Case: We have a stripped DEX file and a PIC ODEX file, but no OAT file.
Richard Uhler66d874d2015-01-15 09:37:19 -0800672TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
673 std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700674 std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800675
676 // Create the dex and odex files
677 Copy(GetDexSrc1(), dex_location);
Richard Uhler5923b522016-12-08 09:48:01 +0000678 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800679
680 // Strip the dex file
681 Copy(GetStrippedDexSrc1(), dex_location);
682
683 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700684 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800685
Richard Uhler5923b522016-12-08 09:48:01 +0000686 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000687 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800688
689 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler5923b522016-12-08 09:48:01 +0000690 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
Richard Uhler03bc6592016-11-22 09:42:04 +0000691 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700692 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800693
Richard Uhler66d874d2015-01-15 09:37:19 -0800694 // Verify we can load the dex files from it.
695 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
696 ASSERT_TRUE(oat_file.get() != nullptr);
697 EXPECT_TRUE(oat_file->IsExecutable());
698 std::vector<std::unique_ptr<const DexFile>> dex_files;
699 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
700 EXPECT_EQ(1u, dex_files.size());
701}
702
Richard Uhler5923b522016-12-08 09:48:01 +0000703// Case: We have a stripped DEX file, a PIC ODEX file, and an out-of-date OAT file.
Richard Uhler66d874d2015-01-15 09:37:19 -0800704TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
705 std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700706 std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800707
708 // Create the oat file from a different dex file so it looks out of date.
709 Copy(GetDexSrc2(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000710 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800711
712 // Create the odex file
713 Copy(GetDexSrc1(), dex_location);
Richard Uhler5923b522016-12-08 09:48:01 +0000714 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800715
716 // Strip the dex file.
717 Copy(GetStrippedDexSrc1(), dex_location);
718
719 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700720 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800721
Andreas Gampe29d38e72016-03-23 15:31:51 +0000722 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100723 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000724 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
725 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Nicolas Geoffray08e9eed2017-04-25 17:36:51 +0100726 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter, // Compiling from the .vdex file
Andreas Gampe29d38e72016-03-23 15:31:51 +0000727 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800728
729 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler5923b522016-12-08 09:48:01 +0000730 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
731 EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700732 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800733
734 // Verify we can load the dex files from it.
735 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
736 ASSERT_TRUE(oat_file.get() != nullptr);
737 EXPECT_TRUE(oat_file->IsExecutable());
738 std::vector<std::unique_ptr<const DexFile>> dex_files;
739 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
740 EXPECT_EQ(1u, dex_files.size());
741}
742
Richard Uhler9b994ea2015-06-24 08:44:19 -0700743// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
744// OAT file. Expect: The status is kNoDexOptNeeded.
745TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
746 std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
747
748 Copy(GetStrippedDexSrc1(), dex_location);
749
750 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700751 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler9b994ea2015-06-24 08:44:19 -0700752
Andreas Gampe29d38e72016-03-23 15:31:51 +0000753 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
754 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
755 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100756 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000757 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100758 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700759
760 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000761 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
762 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700763 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
764
765 // Make the oat file up to date. This should have no effect.
766 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700767 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700768 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700769 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhler9b994ea2015-06-24 08:44:19 -0700770
Andreas Gampe29d38e72016-03-23 15:31:51 +0000771 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
772 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700773
774 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000775 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
776 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700777 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
778}
779
Richard Uhler66d874d2015-01-15 09:37:19 -0800780// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
781// OAT files both have patch delta of 0.
Richard Uhler5923b522016-12-08 09:48:01 +0000782// Expect: It shouldn't crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800783TEST_F(OatFileAssistantTest, OdexOatOverlap) {
784 std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700785 std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800786
Calin Juravle357c66d2017-05-04 01:57:17 +0000787 // Create the dex, the odex and the oat files.
Richard Uhler66d874d2015-01-15 09:37:19 -0800788 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000789 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Calin Juravle357c66d2017-05-04 01:57:17 +0000790 GenerateOatForTest(dex_location.c_str(),
791 CompilerFilter::kSpeed,
792 /*relocate*/false,
793 /*pic*/false,
794 /*with_alternate_image*/false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800795
796 // Verify things don't go bad.
Calin Juravle357c66d2017-05-04 01:57:17 +0000797 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800798
Calin Juravle357c66d2017-05-04 01:57:17 +0000799 // -kDex2OatForRelocation is expected rather than kDex2OatForRelocation
800 // based on the assumption that the odex location is more up-to-date than the oat
Richard Uhler70a84262016-11-08 16:51:51 +0000801 // location, even if they both need relocation.
Calin Juravle357c66d2017-05-04 01:57:17 +0000802 EXPECT_EQ(-OatFileAssistant::kDex2OatForRelocation,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000803 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800804
805 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000806 EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus());
807 EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700808 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800809
810 // Things aren't relocated, so it should fall back to interpreted.
811 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
812 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhlerf16d5722015-05-11 09:32:47 -0700813
Richard Uhler66d874d2015-01-15 09:37:19 -0800814 EXPECT_FALSE(oat_file->IsExecutable());
815 std::vector<std::unique_ptr<const DexFile>> dex_files;
816 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
817 EXPECT_EQ(1u, dex_files.size());
818}
819
Andreas Gampe29d38e72016-03-23 15:31:51 +0000820// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
821// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
822TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
823 std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
824 std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
David Brazdilce4b0ba2016-01-28 15:05:49 +0000825
826 // Create the dex and odex files
827 Copy(GetDexSrc1(), dex_location);
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100828 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kExtract);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000829
830 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700831 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000832
Andreas Gampe29d38e72016-03-23 15:31:51 +0000833 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100834 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000835 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000836 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
David Brazdilce4b0ba2016-01-28 15:05:49 +0000837
838 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000839 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
Richard Uhler03bc6592016-11-22 09:42:04 +0000840 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
David Brazdilce4b0ba2016-01-28 15:05:49 +0000841 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
842}
843
Richard Uhler66d874d2015-01-15 09:37:19 -0800844// Case: We have a DEX file and up-to-date OAT file for it.
845// Expect: We should load an executable dex file.
846TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000847 if (IsExecutedAsRoot()) {
848 // We cannot simulate non writable locations when executed as root: b/38000545.
849 LOG(ERROR) << "Test skipped because it's running as root";
850 return;
851 }
852
Richard Uhler66d874d2015-01-15 09:37:19 -0800853 std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
854
855 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000856 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800857
Calin Juravle357c66d2017-05-04 01:57:17 +0000858 ScopedNonWritable scoped_non_writable(dex_location);
859 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
860
Richard Uhler66d874d2015-01-15 09:37:19 -0800861 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700862 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000863
864 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
865 ASSERT_TRUE(oat_file.get() != nullptr);
866 EXPECT_TRUE(oat_file->IsExecutable());
867 std::vector<std::unique_ptr<const DexFile>> dex_files;
868 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
869 EXPECT_EQ(1u, dex_files.size());
870}
871
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100872// Case: We have a DEX file and up-to-date quicken OAT file for it.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000873// Expect: We should still load the oat file as executable.
874TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000875 if (IsExecutedAsRoot()) {
876 // We cannot simulate non writable locations when executed as root: b/38000545.
877 LOG(ERROR) << "Test skipped because it's running as root";
878 return;
879 }
880
Andreas Gampe29d38e72016-03-23 15:31:51 +0000881 std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
882
883 Copy(GetDexSrc1(), dex_location);
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100884 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kQuicken);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000885
Calin Juravle357c66d2017-05-04 01:57:17 +0000886 ScopedNonWritable scoped_non_writable(dex_location);
887 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
888
Andreas Gampe29d38e72016-03-23 15:31:51 +0000889 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700890 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800891
892 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
893 ASSERT_TRUE(oat_file.get() != nullptr);
894 EXPECT_TRUE(oat_file->IsExecutable());
895 std::vector<std::unique_ptr<const DexFile>> dex_files;
896 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
897 EXPECT_EQ(1u, dex_files.size());
898}
899
900// Case: We have a DEX file and up-to-date OAT file for it.
901// Expect: Loading non-executable should load the oat non-executable.
902TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000903 if (IsExecutedAsRoot()) {
904 // We cannot simulate non writable locations when executed as root: b/38000545.
905 LOG(ERROR) << "Test skipped because it's running as root";
906 return;
907 }
908
Richard Uhler66d874d2015-01-15 09:37:19 -0800909 std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
910
911 Copy(GetDexSrc1(), dex_location);
Calin Juravle357c66d2017-05-04 01:57:17 +0000912
913 ScopedNonWritable scoped_non_writable(dex_location);
914 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
915
Andreas Gampe29d38e72016-03-23 15:31:51 +0000916 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800917
918 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700919 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800920
921 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
922 ASSERT_TRUE(oat_file.get() != nullptr);
923 EXPECT_FALSE(oat_file->IsExecutable());
924 std::vector<std::unique_ptr<const DexFile>> dex_files;
925 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
926 EXPECT_EQ(1u, dex_files.size());
927}
928
Richard Uhler8327cf72015-10-13 16:34:59 -0700929// Case: We don't have a DEX file and can't write the oat file.
930// Expect: We should fail to generate the oat file without crashing.
931TEST_F(OatFileAssistantTest, GenNoDex) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000932 if (IsExecutedAsRoot()) {
933 // We cannot simulate non writable locations when executed as root: b/38000545.
934 LOG(ERROR) << "Test skipped because it's running as root";
935 return;
936 }
Richard Uhler8327cf72015-10-13 16:34:59 -0700937
Calin Juravle357c66d2017-05-04 01:57:17 +0000938 std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
939
940 ScopedNonWritable scoped_non_writable(dex_location);
941 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
942
943 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler8327cf72015-10-13 16:34:59 -0700944 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700945 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Calin Juravle357c66d2017-05-04 01:57:17 +0000946 // We should get kUpdateSucceeded from MakeUpToDate since there's nothing
947 // that can be done in this situation.
948 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
949 oat_file_assistant.MakeUpToDate(false, &error_msg));
950
951 // Verify it didn't create an oat in the default location (dalvik-cache).
952 OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false);
953 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OatFileStatus());
954 // Verify it didn't create the odex file in the default location (../oat/isa/...odex)
955 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OdexFileStatus());
Richard Uhler8327cf72015-10-13 16:34:59 -0700956}
957
Richard Uhler66d874d2015-01-15 09:37:19 -0800958// Turn an absolute path into a path relative to the current working
959// directory.
Andreas Gampeca620d72016-11-08 08:09:33 -0800960static std::string MakePathRelative(const std::string& target) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800961 char buf[MAXPATHLEN];
962 std::string cwd = getcwd(buf, MAXPATHLEN);
963
964 // Split the target and cwd paths into components.
965 std::vector<std::string> target_path;
966 std::vector<std::string> cwd_path;
967 Split(target, '/', &target_path);
968 Split(cwd, '/', &cwd_path);
969
970 // Reverse the path components, so we can use pop_back().
971 std::reverse(target_path.begin(), target_path.end());
972 std::reverse(cwd_path.begin(), cwd_path.end());
973
974 // Drop the common prefix of the paths. Because we reversed the path
975 // components, this becomes the common suffix of target_path and cwd_path.
976 while (!target_path.empty() && !cwd_path.empty()
977 && target_path.back() == cwd_path.back()) {
978 target_path.pop_back();
979 cwd_path.pop_back();
980 }
981
982 // For each element of the remaining cwd_path, add '..' to the beginning
983 // of the target path. Because we reversed the path components, we add to
984 // the end of target_path.
985 for (unsigned int i = 0; i < cwd_path.size(); i++) {
986 target_path.push_back("..");
987 }
988
989 // Reverse again to get the right path order, and join to get the result.
990 std::reverse(target_path.begin(), target_path.end());
Andreas Gampe9186ced2016-12-12 14:28:21 -0800991 return android::base::Join(target_path, '/');
Richard Uhler66d874d2015-01-15 09:37:19 -0800992}
993
994// Case: Non-absolute path to Dex location.
995// Expect: Not sure, but it shouldn't crash.
996TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
997 std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
998 Copy(GetDexSrc1(), abs_dex_location);
999
1000 std::string dex_location = MakePathRelative(abs_dex_location);
Richard Uhlerd1472a22016-04-15 15:18:56 -07001001 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001002
1003 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler7225a8d2016-11-22 10:12:03 +00001004 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +00001005 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler03bc6592016-11-22 09:42:04 +00001006 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
1007 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -08001008}
1009
1010// Case: Very short, non-existent Dex location.
Richard Uhler9b994ea2015-06-24 08:44:19 -07001011// Expect: kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -08001012TEST_F(OatFileAssistantTest, ShortDexLocation) {
1013 std::string dex_location = "/xx";
1014
Richard Uhlerd1472a22016-04-15 15:18:56 -07001015 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001016
1017 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Andreas Gampe29d38e72016-03-23 15:31:51 +00001018 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1019 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler03bc6592016-11-22 09:42:04 +00001020 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
1021 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -07001022 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -08001023
Richard Uhler9b994ea2015-06-24 08:44:19 -07001024 // Trying to make it up to date should have no effect.
Richard Uhler66d874d2015-01-15 09:37:19 -08001025 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001026 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -07001027 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -07001028 oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -07001029 EXPECT_TRUE(error_msg.empty());
Richard Uhler66d874d2015-01-15 09:37:19 -08001030}
1031
1032// Case: Non-standard extension for dex file.
Richard Uhler95abd042015-03-24 09:51:28 -07001033// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -08001034TEST_F(OatFileAssistantTest, LongDexExtension) {
1035 std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
1036 Copy(GetDexSrc1(), dex_location);
1037
Richard Uhlerd1472a22016-04-15 15:18:56 -07001038 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -08001039
Richard Uhler7225a8d2016-11-22 10:12:03 +00001040 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +00001041 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -08001042
1043 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +00001044 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
1045 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -08001046}
1047
1048// A task to generate a dex location. Used by the RaceToGenerate test.
1049class RaceGenerateTask : public Task {
1050 public:
1051 explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
Jeff Haof0192c82016-03-28 20:39:50 -07001052 : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr)
Richard Uhler66d874d2015-01-15 09:37:19 -08001053 {}
1054
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001055 void Run(Thread* self ATTRIBUTE_UNUSED) {
Richard Uhler66d874d2015-01-15 09:37:19 -08001056 // Load the dex files, and save a pointer to the loaded oat file, so that
1057 // we can verify only one oat file was loaded for the dex location.
Richard Uhler66d874d2015-01-15 09:37:19 -08001058 std::vector<std::unique_ptr<const DexFile>> dex_files;
1059 std::vector<std::string> error_msgs;
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001060 const OatFile* oat_file = nullptr;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001061 dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
1062 dex_location_.c_str(),
Jeff Hao0cb17282017-07-12 14:51:49 -07001063 Runtime::Current()->GetSystemClassLoader(),
Mathieu Chartierfbc31082016-01-24 11:59:56 -08001064 /*dex_elements*/nullptr,
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001065 &oat_file,
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001066 &error_msgs);
Andreas Gampe9186ced2016-12-12 14:28:21 -08001067 CHECK(!dex_files.empty()) << android::base::Join(error_msgs, '\n');
Richard Uhler07b3c232015-03-31 15:57:54 -07001068 CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
1069 loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001070 CHECK_EQ(loaded_oat_file_, oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001071 }
1072
1073 const OatFile* GetLoadedOatFile() const {
1074 return loaded_oat_file_;
1075 }
1076
1077 private:
1078 std::string dex_location_;
1079 std::string oat_location_;
1080 const OatFile* loaded_oat_file_;
1081};
1082
1083// Test the case where multiple processes race to generate an oat file.
1084// This simulates multiple processes using multiple threads.
1085//
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001086// We want unique Oat files to be loaded even when there is a race to load.
1087// TODO: The test case no longer tests locking the way it was intended since we now get multiple
1088// copies of the same Oat files mapped at different locations.
Richard Uhler66d874d2015-01-15 09:37:19 -08001089TEST_F(OatFileAssistantTest, RaceToGenerate) {
1090 std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001091 std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
Richard Uhler66d874d2015-01-15 09:37:19 -08001092
Jeff Hao0cb17282017-07-12 14:51:49 -07001093 // Start the runtime to initialize the system's class loader.
1094 Thread::Current()->TransitionFromSuspendedToRunnable();
1095 runtime_->Start();
1096
Richard Uhler66d874d2015-01-15 09:37:19 -08001097 // We use the lib core dex file, because it's large, and hopefully should
1098 // take a while to generate.
Narayan Kamathd1ef4362015-11-12 11:49:06 +00001099 Copy(GetLibCoreDexFileNames()[0], dex_location);
Richard Uhler66d874d2015-01-15 09:37:19 -08001100
1101 const int kNumThreads = 32;
1102 Thread* self = Thread::Current();
1103 ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
1104 std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
1105 for (int i = 0; i < kNumThreads; i++) {
1106 std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
1107 thread_pool.AddTask(self, task.get());
1108 tasks.push_back(std::move(task));
1109 }
1110 thread_pool.StartWorkers(self);
1111 thread_pool.Wait(self, true, false);
1112
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001113 // Verify every task got a unique oat file.
1114 std::set<const OatFile*> oat_files;
Richard Uhler66d874d2015-01-15 09:37:19 -08001115 for (auto& task : tasks) {
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001116 const OatFile* oat_file = task->GetLoadedOatFile();
1117 EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
1118 oat_files.insert(oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001119 }
1120}
1121
1122// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
1123// disabled.
1124// Expect: We should load the odex file non-executable.
1125TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
1126 std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001127 std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -08001128
1129 // Create the dex and odex files
1130 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001131 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001132
1133 // Load the oat using an executable oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -07001134 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001135
1136 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1137 ASSERT_TRUE(oat_file.get() != nullptr);
1138 EXPECT_FALSE(oat_file->IsExecutable());
1139 std::vector<std::unique_ptr<const DexFile>> dex_files;
1140 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1141 EXPECT_EQ(1u, dex_files.size());
1142}
1143
1144// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
1145// disabled.
1146// Expect: We should load the odex file non-executable.
1147TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
1148 std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001149 std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -08001150
1151 // Create the dex and odex files
1152 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001153 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001154
1155 // Load the oat using an executable oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -07001156 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001157
1158 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1159 ASSERT_TRUE(oat_file.get() != nullptr);
1160 EXPECT_FALSE(oat_file->IsExecutable());
1161 std::vector<std::unique_ptr<const DexFile>> dex_files;
1162 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1163 EXPECT_EQ(2u, dex_files.size());
1164}
1165
Richard Uhlerf4b34872016-04-13 11:03:46 -07001166TEST_F(OatFileAssistantTest, RuntimeCompilerFilterOptionUsed) {
1167 std::string dex_location = GetScratchDir() + "/RuntimeCompilerFilterOptionUsed.jar";
1168 Copy(GetDexSrc1(), dex_location);
1169
Richard Uhlerd1472a22016-04-15 15:18:56 -07001170 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhlerf4b34872016-04-13 11:03:46 -07001171
1172 std::string error_msg;
Nicolas Geoffray49cda062017-04-21 13:08:25 +01001173 Runtime::Current()->AddCompilerOption("--compiler-filter=quicken");
Richard Uhlerf4b34872016-04-13 11:03:46 -07001174 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -07001175 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Calin Juravle357c66d2017-05-04 01:57:17 +00001176 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +01001177 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Calin Juravle357c66d2017-05-04 01:57:17 +00001178 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
Richard Uhlerf4b34872016-04-13 11:03:46 -07001179 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1180
1181 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
1182 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -07001183 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001184 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +01001185 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhlerf4b34872016-04-13 11:03:46 -07001186 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1187 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1188
1189 Runtime::Current()->AddCompilerOption("--compiler-filter=bogus");
1190 EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
Richard Uhlerd1472a22016-04-15 15:18:56 -07001191 oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhlerf4b34872016-04-13 11:03:46 -07001192}
1193
Richard Uhlerb81881d2016-04-19 13:08:04 -07001194TEST(OatFileAssistantUtilsTest, DexLocationToOdexFilename) {
Richard Uhler66d874d2015-01-15 09:37:19 -08001195 std::string error_msg;
1196 std::string odex_file;
1197
Richard Uhlerb81881d2016-04-19 13:08:04 -07001198 EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001199 "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -07001200 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001201
Richard Uhlerb81881d2016-04-19 13:08:04 -07001202 EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001203 "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -07001204 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001205
Richard Uhlerb81881d2016-04-19 13:08:04 -07001206 EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001207 "nopath.jar", kArm, &odex_file, &error_msg));
Richard Uhlerb81881d2016-04-19 13:08:04 -07001208 EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001209 "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
Richard Uhler66d874d2015-01-15 09:37:19 -08001210}
1211
Richard Uhler23cedd22015-04-08 13:17:29 -07001212// Verify the dexopt status values from dalvik.system.DexFile
1213// match the OatFileAssistant::DexOptStatus values.
1214TEST_F(OatFileAssistantTest, DexOptStatusValues) {
Richard Uhler7225a8d2016-11-22 10:12:03 +00001215 std::pair<OatFileAssistant::DexOptNeeded, const char*> mapping[] = {
1216 {OatFileAssistant::kNoDexOptNeeded, "NO_DEXOPT_NEEDED"},
1217 {OatFileAssistant::kDex2OatFromScratch, "DEX2OAT_FROM_SCRATCH"},
1218 {OatFileAssistant::kDex2OatForBootImage, "DEX2OAT_FOR_BOOT_IMAGE"},
1219 {OatFileAssistant::kDex2OatForFilter, "DEX2OAT_FOR_FILTER"},
1220 {OatFileAssistant::kDex2OatForRelocation, "DEX2OAT_FOR_RELOCATION"},
Richard Uhler7225a8d2016-11-22 10:12:03 +00001221 };
1222
Richard Uhler23cedd22015-04-08 13:17:29 -07001223 ScopedObjectAccess soa(Thread::Current());
1224 StackHandleScope<1> hs(soa.Self());
1225 ClassLinker* linker = Runtime::Current()->GetClassLinker();
1226 Handle<mirror::Class> dexfile(
1227 hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001228 ASSERT_FALSE(dexfile == nullptr);
Richard Uhler23cedd22015-04-08 13:17:29 -07001229 linker->EnsureInitialized(soa.Self(), dexfile, true, true);
1230
Richard Uhler7225a8d2016-11-22 10:12:03 +00001231 for (std::pair<OatFileAssistant::DexOptNeeded, const char*> field : mapping) {
1232 ArtField* art_field = mirror::Class::FindStaticField(
Vladimir Marko19a4d372016-12-08 14:41:46 +00001233 soa.Self(), dexfile.Get(), field.second, "I");
Richard Uhler7225a8d2016-11-22 10:12:03 +00001234 ASSERT_FALSE(art_field == nullptr);
1235 EXPECT_EQ(art_field->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1236 EXPECT_EQ(field.first, art_field->GetInt(dexfile.Get()));
1237 }
Richard Uhler23cedd22015-04-08 13:17:29 -07001238}
Richard Uhler66d874d2015-01-15 09:37:19 -08001239
Calin Juravle07c6d722017-06-07 17:06:12 +00001240// Verify that when no compiler filter is passed the default one from OatFileAssistant is used.
1241TEST_F(OatFileAssistantTest, DefaultMakeUpToDateFilter) {
1242 std::string dex_location = GetScratchDir() + "/TestDex.jar";
1243 Copy(GetDexSrc1(), dex_location);
1244
1245 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
1246
1247 const CompilerFilter::Filter default_filter =
1248 OatFileAssistant::kDefaultCompilerFilterForDexLoading;
1249 std::string error_msg;
1250 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
1251 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
1252 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
1253 oat_file_assistant.GetDexOptNeeded(default_filter));
1254 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1255 EXPECT_NE(nullptr, oat_file.get());
1256 EXPECT_EQ(default_filter, oat_file->GetCompilerFilter());
1257}
1258
Richard Uhler66d874d2015-01-15 09:37:19 -08001259// TODO: More Tests:
1260// * Test class linker falls back to unquickened dex for DexNoOat
1261// * Test class linker falls back to unquickened dex for MultiDexNoOat
Richard Uhler66d874d2015-01-15 09:37:19 -08001262// * Test using secondary isa
Richard Uhler66d874d2015-01-15 09:37:19 -08001263// * Test for status of oat while oat is being generated (how?)
1264// * Test case where 32 and 64 bit boot class paths differ,
1265// and we ask IsInBootClassPath for a class in exactly one of the 32 or
1266// 64 bit boot class paths.
1267// * Test unexpected scenarios (?):
1268// - Dex is stripped, don't have odex.
1269// - Oat file corrupted after status check, before reload unexecutable
1270// because it's unrelocated and no dex2oat
Richard Uhler66d874d2015-01-15 09:37:19 -08001271} // namespace art