blob: 3ecd1b516d8168124cee06cdfcea5db0e47bf5f4 [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
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070017#include "oat_file_assistant.h"
18
Richard Uhler66d874d2015-01-15 09:37:19 -080019#include <sys/param.h>
20
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070021#include <string>
22#include <vector>
23
Richard Uhler66d874d2015-01-15 09:37:19 -080024#include <gtest/gtest.h>
25
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070026#include "android-base/strings.h"
27
Mathieu Chartierc7853442015-03-27 14:35:38 -070028#include "art_field-inl.h"
Vladimir Marko3481ba22015-04-13 12:22:36 +010029#include "class_linker-inl.h"
Calin Juravle27e0d1f2017-07-26 00:16:07 -070030#include "class_loader_context.h"
Jeff Hao0cb17282017-07-12 14:51:49 -070031#include "common_runtime_test.h"
Calin Juravle36eb3132017-01-13 16:32:38 -080032#include "dexopt_test.h"
Calin Juravle27e0d1f2017-07-26 00:16:07 -070033#include "oat_file.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070034#include "oat_file_manager.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080035#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070036#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070037#include "thread-current-inl.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080038#include "utils.h"
39
40namespace art {
41
Calin Juravle27e0d1f2017-07-26 00:16:07 -070042static const std::string kSpecialSharedLibrary = "&";
Calin Juravle44e5efa2017-09-12 00:54:26 -070043static ClassLoaderContext* kSpecialSharedLibraryContext = nullptr;
Calin Juravle27e0d1f2017-07-26 00:16:07 -070044
Calin Juravle36eb3132017-01-13 16:32:38 -080045class OatFileAssistantTest : public DexoptTest {};
Richard Uhler66d874d2015-01-15 09:37:19 -080046
Calin Juravle36eb3132017-01-13 16:32:38 -080047class OatFileAssistantNoDex2OatTest : public DexoptTest {
Richard Uhler66d874d2015-01-15 09:37:19 -080048 public:
49 virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
Calin Juravle36eb3132017-01-13 16:32:38 -080050 DexoptTest::SetUpRuntimeOptions(options);
Richard Uhler66d874d2015-01-15 09:37:19 -080051 options->push_back(std::make_pair("-Xnodex2oat", nullptr));
52 }
53};
54
Calin Juravle357c66d2017-05-04 01:57:17 +000055class ScopedNonWritable {
56 public:
57 explicit ScopedNonWritable(const std::string& dex_location) {
58 is_valid_ = false;
59 size_t pos = dex_location.rfind('/');
60 if (pos != std::string::npos) {
61 is_valid_ = true;
62 dex_parent_ = dex_location.substr(0, pos);
63 if (chmod(dex_parent_.c_str(), 0555) != 0) {
64 PLOG(ERROR) << "Could not change permissions on " << dex_parent_;
65 }
66 }
67 }
68
69 bool IsSuccessful() { return is_valid_ && (access(dex_parent_.c_str(), W_OK) != 0); }
70
71 ~ScopedNonWritable() {
72 if (is_valid_) {
73 if (chmod(dex_parent_.c_str(), 0777) != 0) {
74 PLOG(ERROR) << "Could not restore permissions on " << dex_parent_;
75 }
76 }
77 }
78
79 private:
80 std::string dex_parent_;
81 bool is_valid_;
82};
83
84static bool IsExecutedAsRoot() {
85 return geteuid() == 0;
86}
Calin Juravle36eb3132017-01-13 16:32:38 -080087
Richard Uhler66d874d2015-01-15 09:37:19 -080088// Case: We have a DEX file, but no OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -070089// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -080090TEST_F(OatFileAssistantTest, DexNoOat) {
91 std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
92 Copy(GetDexSrc1(), dex_location);
93
Richard Uhlerd1472a22016-04-15 15:18:56 -070094 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -080095
Richard Uhler7225a8d2016-11-22 10:12:03 +000096 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Nicolas Geoffray49cda062017-04-21 13:08:25 +010097 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +000098 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Nicolas Geoffray49cda062017-04-21 13:08:25 +010099 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000100 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000101 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000102 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000103 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800104
105 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000106 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
107 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700108 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800109}
110
111// Case: We have no DEX file and no OAT file.
Richard Uhler9b994ea2015-06-24 08:44:19 -0700112// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800113TEST_F(OatFileAssistantTest, NoDexNoOat) {
114 std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
115
Richard Uhlerd1472a22016-04-15 15:18:56 -0700116 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800117
Andreas Gampe29d38e72016-03-23 15:31:51 +0000118 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
119 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700120 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
121
122 // Trying to make the oat file up to date should not fail or crash.
123 std::string error_msg;
Calin Juravle27e0d1f2017-07-26 00:16:07 -0700124 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Calin Juravle44e5efa2017-09-12 00:54:26 -0700125 oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700126
127 // Trying to get the best oat file should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800128 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
129 EXPECT_EQ(nullptr, oat_file.get());
130}
131
Calin Juravle357c66d2017-05-04 01:57:17 +0000132// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
133// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
134TEST_F(OatFileAssistantTest, OdexUpToDate) {
135 std::string dex_location = GetScratchDir() + "/OdexUpToDate.jar";
136 std::string odex_location = GetOdexDir() + "/OdexUpToDate.odex";
137 Copy(GetDexSrc1(), dex_location);
138 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
139
140 // For the use of oat location by making the dex parent not writable.
141 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
142
143 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
144 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
145 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
146 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
147 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
148 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
149 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
150 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
151
152 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
153 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
154 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
155 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
156}
157
158// Case: We have a DEX file and a PIC ODEX file, but no OAT file. We load the dex
159// file via a symlink.
160// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
161TEST_F(OatFileAssistantTest, OdexUpToDateSymLink) {
162 std::string scratch_dir = GetScratchDir();
163 std::string dex_location = GetScratchDir() + "/OdexUpToDate.jar";
164 std::string odex_location = GetOdexDir() + "/OdexUpToDate.odex";
165
166 Copy(GetDexSrc1(), dex_location);
167 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
168
169 // Now replace the dex location with a symlink.
170 std::string link = scratch_dir + "/link";
171 ASSERT_EQ(0, symlink(scratch_dir.c_str(), link.c_str()));
172 dex_location = link + "/OdexUpToDate.jar";
173
174 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
175
176 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
177 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
178 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
179 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
180 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
181 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
182 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
183 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
184
185 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
186 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
187 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
188 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
189}
190
Richard Uhler66d874d2015-01-15 09:37:19 -0800191// Case: We have a DEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700192// Expect: The status is kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800193TEST_F(OatFileAssistantTest, OatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000194 if (IsExecutedAsRoot()) {
195 // We cannot simulate non writable locations when executed as root: b/38000545.
196 LOG(ERROR) << "Test skipped because it's running as root";
197 return;
198 }
199
Richard Uhler66d874d2015-01-15 09:37:19 -0800200 std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
201 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000202 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800203
Calin Juravle357c66d2017-05-04 01:57:17 +0000204 // For the use of oat location by making the dex parent not writable.
205 ScopedNonWritable scoped_non_writable(dex_location);
206 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
207
208 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
209
210 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
211 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
212 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
213 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
214 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
215 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
216 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
217 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
218
219 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
220 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
221 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
222 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
223}
224
225// Case: We have a DEX file and up-to-date OAT file for it. We load the dex file
226// via a symlink.
227// Expect: The status is kNoDexOptNeeded.
228TEST_F(OatFileAssistantTest, OatUpToDateSymLink) {
229 if (IsExecutedAsRoot()) {
230 // We cannot simulate non writable locations when executed as root: b/38000545.
231 LOG(ERROR) << "Test skipped because it's running as root";
232 return;
233 }
234
235 std::string real = GetScratchDir() + "/real";
236 ASSERT_EQ(0, mkdir(real.c_str(), 0700));
237 std::string link = GetScratchDir() + "/link";
238 ASSERT_EQ(0, symlink(real.c_str(), link.c_str()));
239
240 std::string dex_location = real + "/OatUpToDate.jar";
241
242 Copy(GetDexSrc1(), dex_location);
243 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
244
245 // Update the dex location to point to the symlink.
246 dex_location = link + "/OatUpToDate.jar";
247
248 // For the use of oat location by making the dex parent not writable.
249 ScopedNonWritable scoped_non_writable(dex_location);
250 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
251
Richard Uhlerd1472a22016-04-15 15:18:56 -0700252 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800253
Andreas Gampe29d38e72016-03-23 15:31:51 +0000254 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
255 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
256 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100257 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000258 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100259 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000260 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000261 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
262
Richard Uhler66d874d2015-01-15 09:37:19 -0800263 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000264 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
Richard Uhler95abd042015-03-24 09:51:28 -0700265 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700266 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800267}
268
Richard Uhler2f27abd2017-01-31 14:02:34 +0000269// Case: We have a DEX file and up-to-date (ODEX) VDEX file for it, but no
270// ODEX file.
271TEST_F(OatFileAssistantTest, VdexUpToDateNoOdex) {
272 // This test case is only meaningful if vdex is enabled.
273 if (!kIsVdexEnabled) {
274 return;
275 }
Richard Uhler9a37efc2016-08-05 16:32:55 -0700276
Richard Uhler2f27abd2017-01-31 14:02:34 +0000277 std::string dex_location = GetScratchDir() + "/VdexUpToDateNoOdex.jar";
Calin Juravle357c66d2017-05-04 01:57:17 +0000278 std::string odex_location = GetOdexDir() + "/VdexUpToDateNoOdex.oat";
Richard Uhler2f27abd2017-01-31 14:02:34 +0000279
Richard Uhler9a37efc2016-08-05 16:32:55 -0700280 Copy(GetDexSrc1(), dex_location);
281
Richard Uhler2f27abd2017-01-31 14:02:34 +0000282 // Generating and deleting the oat file should have the side effect of
283 // creating an up-to-date vdex file.
Calin Juravle357c66d2017-05-04 01:57:17 +0000284 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
285 ASSERT_EQ(0, unlink(odex_location.c_str()));
Richard Uhler2f27abd2017-01-31 14:02:34 +0000286
Calin Juravle357c66d2017-05-04 01:57:17 +0000287 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler2f27abd2017-01-31 14:02:34 +0000288
289 // Even though the vdex file is up to date, because we don't have the oat
290 // file, we can't know that the vdex depends on the boot image and is up to
291 // date with respect to the boot image. Instead we must assume the vdex file
292 // depends on the boot image and is out of date with respect to the boot
293 // image.
294 EXPECT_EQ(-OatFileAssistant::kDex2OatForBootImage,
295 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
296
297 // Make sure we don't crash in this case when we dump the status. We don't
298 // care what the actual dumped value is.
299 oat_file_assistant.GetStatusDump();
300}
301
302// Case: We have a DEX file and empty VDEX and ODEX files.
303TEST_F(OatFileAssistantTest, EmptyVdexOdex) {
304 std::string dex_location = GetScratchDir() + "/EmptyVdexOdex.jar";
305 std::string odex_location = GetOdexDir() + "/EmptyVdexOdex.oat";
306 std::string vdex_location = GetOdexDir() + "/EmptyVdexOdex.vdex";
307
308 Copy(GetDexSrc1(), dex_location);
Richard Uhler5cd59292017-02-01 12:54:23 +0000309 ScratchFile vdex_file(vdex_location.c_str());
310 ScratchFile odex_file(odex_location.c_str());
Richard Uhler2f27abd2017-01-31 14:02:34 +0000311
312 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
313 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
314 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
315}
316
317// Case: We have a DEX file and up-to-date (OAT) VDEX file for it, but no OAT
318// file.
319TEST_F(OatFileAssistantTest, VdexUpToDateNoOat) {
320 // This test case is only meaningful if vdex is enabled.
321 if (!kIsVdexEnabled) {
322 return;
323 }
Calin Juravle357c66d2017-05-04 01:57:17 +0000324 if (IsExecutedAsRoot()) {
325 // We cannot simulate non writable locations when executed as root: b/38000545.
326 LOG(ERROR) << "Test skipped because it's running as root";
327 return;
328 }
Richard Uhler2f27abd2017-01-31 14:02:34 +0000329
330 std::string dex_location = GetScratchDir() + "/VdexUpToDateNoOat.jar";
331 std::string oat_location;
332 std::string error_msg;
333 ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename(
334 dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg;
335
336 Copy(GetDexSrc1(), dex_location);
337 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
338 ASSERT_EQ(0, unlink(oat_location.c_str()));
339
Calin Juravle357c66d2017-05-04 01:57:17 +0000340 ScopedNonWritable scoped_non_writable(dex_location);
341 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
Richard Uhler9a37efc2016-08-05 16:32:55 -0700342 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
343
Richard Uhler2f27abd2017-01-31 14:02:34 +0000344 // Even though the vdex file is up to date, because we don't have the oat
345 // file, we can't know that the vdex depends on the boot image and is up to
346 // date with respect to the boot image. Instead we must assume the vdex file
347 // depends on the boot image and is out of date with respect to the boot
348 // image.
349 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Richard Uhler9a37efc2016-08-05 16:32:55 -0700350 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9a37efc2016-08-05 16:32:55 -0700351}
352
Andreas Gampe29d38e72016-03-23 15:31:51 +0000353// Case: We have a DEX file and speed-profile OAT file for it.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700354// Expect: The status is kNoDexOptNeeded if the profile hasn't changed, but
355// kDex2Oat if the profile has changed.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000356TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000357 if (IsExecutedAsRoot()) {
358 // We cannot simulate non writable locations when executed as root: b/38000545.
359 LOG(ERROR) << "Test skipped because it's running as root";
360 return;
361 }
362
Andreas Gampe29d38e72016-03-23 15:31:51 +0000363 std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
364 Copy(GetDexSrc1(), dex_location);
365 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
366
Calin Juravle357c66d2017-05-04 01:57:17 +0000367 ScopedNonWritable scoped_non_writable(dex_location);
368 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
369
Richard Uhlerd1472a22016-04-15 15:18:56 -0700370 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000371
372 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700373 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, false));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000374 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100375 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken, false));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000376 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700377 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, true));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000378 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100379 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken, true));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000380
381 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000382 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000383 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
384 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
385}
386
Richard Uhler66d874d2015-01-15 09:37:19 -0800387// Case: We have a MultiDEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700388// Expect: The status is kNoDexOptNeeded and we load all dex files.
Richard Uhler66d874d2015-01-15 09:37:19 -0800389TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000390 if (IsExecutedAsRoot()) {
391 // We cannot simulate non writable locations when executed as root: b/38000545.
392 LOG(ERROR) << "Test skipped because it's running as root";
393 return;
394 }
395
Richard Uhler66d874d2015-01-15 09:37:19 -0800396 std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
397 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000398 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800399
Calin Juravle357c66d2017-05-04 01:57:17 +0000400 ScopedNonWritable scoped_non_writable(dex_location);
401 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
402
Richard Uhlerd1472a22016-04-15 15:18:56 -0700403 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000404 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700405 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700406 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler95abd042015-03-24 09:51:28 -0700407
408 // Verify we can load both dex files.
Richard Uhlere5fed032015-03-18 08:21:11 -0700409 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
Richard Uhler66d874d2015-01-15 09:37:19 -0800410 ASSERT_TRUE(oat_file.get() != nullptr);
411 EXPECT_TRUE(oat_file->IsExecutable());
412 std::vector<std::unique_ptr<const DexFile>> dex_files;
Richard Uhlere5fed032015-03-18 08:21:11 -0700413 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
414 EXPECT_EQ(2u, dex_files.size());
415}
416
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000417// Case: We have a MultiDEX file where the non-main multdex entry is out of date.
Richard Uhler67ff7d12015-05-14 13:21:13 -0700418// Expect: The status is kDex2OatNeeded.
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000419TEST_F(OatFileAssistantTest, MultiDexNonMainOutOfDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000420 if (IsExecutedAsRoot()) {
421 // We cannot simulate non writable locations when executed as root: b/38000545.
422 LOG(ERROR) << "Test skipped because it's running as root";
423 return;
424 }
425
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000426 std::string dex_location = GetScratchDir() + "/MultiDexNonMainOutOfDate.jar";
Richard Uhler67ff7d12015-05-14 13:21:13 -0700427
428 // Compile code for GetMultiDexSrc1.
429 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000430 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler67ff7d12015-05-14 13:21:13 -0700431
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000432 // Now overwrite the dex file with GetMultiDexSrc2 so the non-main checksum
Richard Uhler67ff7d12015-05-14 13:21:13 -0700433 // is out of date.
434 Copy(GetMultiDexSrc2(), dex_location);
435
Calin Juravle357c66d2017-05-04 01:57:17 +0000436 ScopedNonWritable scoped_non_writable(dex_location);
437 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
438
Richard Uhlerd1472a22016-04-15 15:18:56 -0700439 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler7225a8d2016-11-22 10:12:03 +0000440 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700441 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700442 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler67ff7d12015-05-14 13:21:13 -0700443}
444
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000445// Case: We have a stripped MultiDEX file where the non-main multidex entry is
446// out of date with respect to the odex file.
447TEST_F(OatFileAssistantTest, StrippedMultiDexNonMainOutOfDate) {
448 std::string dex_location = GetScratchDir() + "/StrippedMultiDexNonMainOutOfDate.jar";
449 std::string odex_location = GetOdexDir() + "/StrippedMultiDexNonMainOutOfDate.odex";
450
451 // Compile the oat from GetMultiDexSrc1.
452 Copy(GetMultiDexSrc1(), dex_location);
453 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
454
455 // Compile the odex from GetMultiDexSrc2, which has a different non-main
456 // dex checksum.
457 Copy(GetMultiDexSrc2(), dex_location);
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100458 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kQuicken);
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000459
460 // Strip the dex file.
461 Copy(GetStrippedDexSrc1(), dex_location);
462
463 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, /*load_executable*/false);
464
465 // Because the dex file is stripped, the odex file is considered the source
466 // of truth for the dex checksums. The oat file should be considered
467 // unusable.
468 std::unique_ptr<OatFile> best_file = oat_file_assistant.GetBestOatFile();
469 ASSERT_TRUE(best_file.get() != nullptr);
470 EXPECT_EQ(best_file->GetLocation(), odex_location);
471 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
472 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
473 EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
474}
475
Calin Juravle357c66d2017-05-04 01:57:17 +0000476// Case: We have a MultiDEX file and up-to-date ODEX file for it with relative
Richard Uhlere5fed032015-03-18 08:21:11 -0700477// encoded dex locations.
Richard Uhler95abd042015-03-24 09:51:28 -0700478// Expect: The oat file status is kNoDexOptNeeded.
Richard Uhlere5fed032015-03-18 08:21:11 -0700479TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
480 std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
Calin Juravle357c66d2017-05-04 01:57:17 +0000481 std::string odex_location = GetOdexDir() + "/RelativeEncodedDexLocation.odex";
Richard Uhlere5fed032015-03-18 08:21:11 -0700482
483 // Create the dex file
484 Copy(GetMultiDexSrc1(), dex_location);
485
486 // Create the oat file with relative encoded dex location.
487 std::vector<std::string> args;
488 args.push_back("--dex-file=" + dex_location);
489 args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
Calin Juravle357c66d2017-05-04 01:57:17 +0000490 args.push_back("--oat-file=" + odex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000491 args.push_back("--compiler-filter=speed");
Richard Uhlere5fed032015-03-18 08:21:11 -0700492
493 std::string error_msg;
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700494 ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
Richard Uhlere5fed032015-03-18 08:21:11 -0700495
496 // Verify we can load both dex files.
Calin Juravle357c66d2017-05-04 01:57:17 +0000497 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
498
Richard Uhlere5fed032015-03-18 08:21:11 -0700499 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
500 ASSERT_TRUE(oat_file.get() != nullptr);
501 EXPECT_TRUE(oat_file->IsExecutable());
502 std::vector<std::unique_ptr<const DexFile>> dex_files;
503 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
Richard Uhler66d874d2015-01-15 09:37:19 -0800504 EXPECT_EQ(2u, dex_files.size());
505}
506
Richard Uhler03bc6592016-11-22 09:42:04 +0000507// Case: We have a DEX file and an OAT file out of date with respect to the
508// dex checksum.
509TEST_F(OatFileAssistantTest, OatDexOutOfDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000510 if (IsExecutedAsRoot()) {
511 // We cannot simulate non writable locations when executed as root: b/38000545.
512 LOG(ERROR) << "Test skipped because it's running as root";
513 return;
514 }
515
Richard Uhler03bc6592016-11-22 09:42:04 +0000516 std::string dex_location = GetScratchDir() + "/OatDexOutOfDate.jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800517
518 // We create a dex, generate an oat for it, then overwrite the dex with a
519 // different dex to make the oat out of date.
520 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000521 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800522 Copy(GetDexSrc2(), dex_location);
523
Calin Juravle357c66d2017-05-04 01:57:17 +0000524 ScopedNonWritable scoped_non_writable(dex_location);
525 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
526
Richard Uhlerd1472a22016-04-15 15:18:56 -0700527 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler7225a8d2016-11-22 10:12:03 +0000528 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100529 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000530 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000531 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800532
533 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000534 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
535 EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
536 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
537}
538
Richard Uhler2f27abd2017-01-31 14:02:34 +0000539// Case: We have a DEX file and an (ODEX) VDEX file out of date with respect
540// to the dex checksum, but no ODEX file.
541TEST_F(OatFileAssistantTest, VdexDexOutOfDate) {
542 // This test case is only meaningful if vdex is enabled.
543 if (!kIsVdexEnabled) {
544 return;
545 }
546
547 std::string dex_location = GetScratchDir() + "/VdexDexOutOfDate.jar";
Calin Juravle357c66d2017-05-04 01:57:17 +0000548 std::string odex_location = GetOdexDir() + "/VdexDexOutOfDate.oat";
Richard Uhler2f27abd2017-01-31 14:02:34 +0000549
550 Copy(GetDexSrc1(), dex_location);
Calin Juravle357c66d2017-05-04 01:57:17 +0000551 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
552 ASSERT_EQ(0, unlink(odex_location.c_str()));
Richard Uhler2f27abd2017-01-31 14:02:34 +0000553 Copy(GetDexSrc2(), dex_location);
554
Calin Juravle357c66d2017-05-04 01:57:17 +0000555 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler2f27abd2017-01-31 14:02:34 +0000556
557 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
558 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
559}
560
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000561// Case: We have a MultiDEX (ODEX) VDEX file where the non-main multidex entry
562// is out of date and there is no corresponding ODEX file.
563TEST_F(OatFileAssistantTest, VdexMultiDexNonMainOutOfDate) {
Richard Uhler2f27abd2017-01-31 14:02:34 +0000564 // This test case is only meaningful if vdex is enabled.
565 if (!kIsVdexEnabled) {
566 return;
567 }
568
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000569 std::string dex_location = GetScratchDir() + "/VdexMultiDexNonMainOutOfDate.jar";
Calin Juravle357c66d2017-05-04 01:57:17 +0000570 std::string odex_location = GetOdexDir() + "/VdexMultiDexNonMainOutOfDate.odex";
Richard Uhler2f27abd2017-01-31 14:02:34 +0000571
572 Copy(GetMultiDexSrc1(), dex_location);
Calin Juravle357c66d2017-05-04 01:57:17 +0000573 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
574 ASSERT_EQ(0, unlink(odex_location.c_str()));
Richard Uhler2f27abd2017-01-31 14:02:34 +0000575 Copy(GetMultiDexSrc2(), dex_location);
576
Calin Juravle357c66d2017-05-04 01:57:17 +0000577 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler2f27abd2017-01-31 14:02:34 +0000578
579 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
580 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
581}
582
Richard Uhler03bc6592016-11-22 09:42:04 +0000583// Case: We have a DEX file and an OAT file out of date with respect to the
584// boot image.
585TEST_F(OatFileAssistantTest, OatImageOutOfDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000586 if (IsExecutedAsRoot()) {
587 // We cannot simulate non writable locations when executed as root: b/38000545.
588 LOG(ERROR) << "Test skipped because it's running as root";
589 return;
590 }
591
Richard Uhler03bc6592016-11-22 09:42:04 +0000592 std::string dex_location = GetScratchDir() + "/OatImageOutOfDate.jar";
593
594 Copy(GetDexSrc1(), dex_location);
595 GenerateOatForTest(dex_location.c_str(),
596 CompilerFilter::kSpeed,
597 /*relocate*/true,
598 /*pic*/false,
Richard Uhler03bc6592016-11-22 09:42:04 +0000599 /*with_alternate_image*/true);
600
Calin Juravle357c66d2017-05-04 01:57:17 +0000601 ScopedNonWritable scoped_non_writable(dex_location);
602 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
603
Richard Uhler03bc6592016-11-22 09:42:04 +0000604 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler7225a8d2016-11-22 10:12:03 +0000605 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100606 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000607 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100608 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000609 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Richard Uhler03bc6592016-11-22 09:42:04 +0000610 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
611
612 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
613 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
614 EXPECT_EQ(OatFileAssistant::kOatBootImageOutOfDate, oat_file_assistant.OatFileStatus());
615 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
616}
617
618// Case: We have a DEX file and a verify-at-runtime OAT file out of date with
619// respect to the boot image.
620// It shouldn't matter that the OAT file is out of date, because it is
621// verify-at-runtime.
622TEST_F(OatFileAssistantTest, OatVerifyAtRuntimeImageOutOfDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000623 if (IsExecutedAsRoot()) {
624 // We cannot simulate non writable locations when executed as root: b/38000545.
625 LOG(ERROR) << "Test skipped because it's running as root";
626 return;
627 }
628
Richard Uhler03bc6592016-11-22 09:42:04 +0000629 std::string dex_location = GetScratchDir() + "/OatVerifyAtRuntimeImageOutOfDate.jar";
630
631 Copy(GetDexSrc1(), dex_location);
632 GenerateOatForTest(dex_location.c_str(),
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100633 CompilerFilter::kExtract,
Richard Uhler03bc6592016-11-22 09:42:04 +0000634 /*relocate*/true,
635 /*pic*/false,
Richard Uhler03bc6592016-11-22 09:42:04 +0000636 /*with_alternate_image*/true);
637
Calin Juravle357c66d2017-05-04 01:57:17 +0000638 ScopedNonWritable scoped_non_writable(dex_location);
639 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
640
Richard Uhler03bc6592016-11-22 09:42:04 +0000641 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
642 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100643 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000644 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100645 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhler03bc6592016-11-22 09:42:04 +0000646
647 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
648 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
649 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700650 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800651}
652
653// Case: We have a DEX file and an ODEX file, but no OAT file.
Richard Uhler66d874d2015-01-15 09:37:19 -0800654TEST_F(OatFileAssistantTest, DexOdexNoOat) {
655 std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700656 std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800657
658 // Create the dex and odex files
659 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000660 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800661
662 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700663 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800664
Andreas Gampe29d38e72016-03-23 15:31:51 +0000665 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100666 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler5923b522016-12-08 09:48:01 +0000667 EXPECT_EQ(-OatFileAssistant::kDex2OatForRelocation,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000668 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800669
670 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000671 EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus());
672 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700673 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler5f946da2015-07-17 12:28:32 -0700674
675 // We should still be able to get the non-executable odex file to run from.
676 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
677 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhler66d874d2015-01-15 09:37:19 -0800678}
679
Richard Uhler5923b522016-12-08 09:48:01 +0000680// Case: We have a stripped DEX file and a PIC ODEX file, but no OAT file.
Richard Uhler66d874d2015-01-15 09:37:19 -0800681TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
682 std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700683 std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800684
685 // Create the dex and odex files
686 Copy(GetDexSrc1(), dex_location);
Richard Uhler5923b522016-12-08 09:48:01 +0000687 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800688
689 // Strip the dex file
690 Copy(GetStrippedDexSrc1(), dex_location);
691
692 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700693 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800694
Richard Uhler5923b522016-12-08 09:48:01 +0000695 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000696 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800697
698 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler5923b522016-12-08 09:48:01 +0000699 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
Richard Uhler03bc6592016-11-22 09:42:04 +0000700 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700701 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800702
Richard Uhler66d874d2015-01-15 09:37:19 -0800703 // Verify we can load the dex files from it.
704 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
705 ASSERT_TRUE(oat_file.get() != nullptr);
706 EXPECT_TRUE(oat_file->IsExecutable());
707 std::vector<std::unique_ptr<const DexFile>> dex_files;
708 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
709 EXPECT_EQ(1u, dex_files.size());
710}
711
Richard Uhler5923b522016-12-08 09:48:01 +0000712// 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 -0800713TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
714 std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700715 std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800716
717 // Create the oat file from a different dex file so it looks out of date.
718 Copy(GetDexSrc2(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000719 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800720
721 // Create the odex file
722 Copy(GetDexSrc1(), dex_location);
Richard Uhler5923b522016-12-08 09:48:01 +0000723 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800724
725 // Strip the dex file.
726 Copy(GetStrippedDexSrc1(), dex_location);
727
728 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700729 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800730
Andreas Gampe29d38e72016-03-23 15:31:51 +0000731 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100732 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000733 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
734 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Nicolas Geoffray08e9eed2017-04-25 17:36:51 +0100735 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter, // Compiling from the .vdex file
Andreas Gampe29d38e72016-03-23 15:31:51 +0000736 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800737
738 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler5923b522016-12-08 09:48:01 +0000739 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
740 EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700741 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800742
743 // Verify we can load the dex files from it.
744 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
745 ASSERT_TRUE(oat_file.get() != nullptr);
746 EXPECT_TRUE(oat_file->IsExecutable());
747 std::vector<std::unique_ptr<const DexFile>> dex_files;
748 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
749 EXPECT_EQ(1u, dex_files.size());
750}
751
Richard Uhler9b994ea2015-06-24 08:44:19 -0700752// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
753// OAT file. Expect: The status is kNoDexOptNeeded.
754TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
755 std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
756
757 Copy(GetStrippedDexSrc1(), dex_location);
758
759 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700760 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler9b994ea2015-06-24 08:44:19 -0700761
Andreas Gampe29d38e72016-03-23 15:31:51 +0000762 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
763 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
764 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100765 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000766 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100767 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700768
769 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000770 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
771 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700772 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
773
774 // Make the oat file up to date. This should have no effect.
775 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700776 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700777 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Calin Juravle44e5efa2017-09-12 00:54:26 -0700778 oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)) <<
Calin Juravle27e0d1f2017-07-26 00:16:07 -0700779 error_msg;
Richard Uhler9b994ea2015-06-24 08:44:19 -0700780
Andreas Gampe29d38e72016-03-23 15:31:51 +0000781 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
782 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700783
784 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000785 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
786 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700787 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
788}
789
Richard Uhler66d874d2015-01-15 09:37:19 -0800790// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
791// OAT files both have patch delta of 0.
Richard Uhler5923b522016-12-08 09:48:01 +0000792// Expect: It shouldn't crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800793TEST_F(OatFileAssistantTest, OdexOatOverlap) {
794 std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700795 std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800796
Calin Juravle357c66d2017-05-04 01:57:17 +0000797 // Create the dex, the odex and the oat files.
Richard Uhler66d874d2015-01-15 09:37:19 -0800798 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000799 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Calin Juravle357c66d2017-05-04 01:57:17 +0000800 GenerateOatForTest(dex_location.c_str(),
801 CompilerFilter::kSpeed,
802 /*relocate*/false,
803 /*pic*/false,
804 /*with_alternate_image*/false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800805
806 // Verify things don't go bad.
Calin Juravle357c66d2017-05-04 01:57:17 +0000807 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800808
Calin Juravle357c66d2017-05-04 01:57:17 +0000809 // -kDex2OatForRelocation is expected rather than kDex2OatForRelocation
810 // based on the assumption that the odex location is more up-to-date than the oat
Richard Uhler70a84262016-11-08 16:51:51 +0000811 // location, even if they both need relocation.
Calin Juravle357c66d2017-05-04 01:57:17 +0000812 EXPECT_EQ(-OatFileAssistant::kDex2OatForRelocation,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000813 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800814
815 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000816 EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus());
817 EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700818 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800819
820 // Things aren't relocated, so it should fall back to interpreted.
821 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
822 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhlerf16d5722015-05-11 09:32:47 -0700823
Richard Uhler66d874d2015-01-15 09:37:19 -0800824 EXPECT_FALSE(oat_file->IsExecutable());
825 std::vector<std::unique_ptr<const DexFile>> dex_files;
826 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
827 EXPECT_EQ(1u, dex_files.size());
828}
829
Andreas Gampe29d38e72016-03-23 15:31:51 +0000830// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
831// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
832TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
833 std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
834 std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
David Brazdilce4b0ba2016-01-28 15:05:49 +0000835
836 // Create the dex and odex files
837 Copy(GetDexSrc1(), dex_location);
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100838 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kExtract);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000839
840 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700841 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000842
Andreas Gampe29d38e72016-03-23 15:31:51 +0000843 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100844 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000845 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000846 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
David Brazdilce4b0ba2016-01-28 15:05:49 +0000847
848 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000849 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
Richard Uhler03bc6592016-11-22 09:42:04 +0000850 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
David Brazdilce4b0ba2016-01-28 15:05:49 +0000851 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
852}
853
Richard Uhler66d874d2015-01-15 09:37:19 -0800854// Case: We have a DEX file and up-to-date OAT file for it.
855// Expect: We should load an executable dex file.
856TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000857 if (IsExecutedAsRoot()) {
858 // We cannot simulate non writable locations when executed as root: b/38000545.
859 LOG(ERROR) << "Test skipped because it's running as root";
860 return;
861 }
862
Richard Uhler66d874d2015-01-15 09:37:19 -0800863 std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
864
865 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000866 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800867
Calin Juravle357c66d2017-05-04 01:57:17 +0000868 ScopedNonWritable scoped_non_writable(dex_location);
869 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
870
Richard Uhler66d874d2015-01-15 09:37:19 -0800871 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700872 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000873
874 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
875 ASSERT_TRUE(oat_file.get() != nullptr);
876 EXPECT_TRUE(oat_file->IsExecutable());
877 std::vector<std::unique_ptr<const DexFile>> dex_files;
878 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
879 EXPECT_EQ(1u, dex_files.size());
880}
881
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100882// Case: We have a DEX file and up-to-date quicken OAT file for it.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000883// Expect: We should still load the oat file as executable.
884TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000885 if (IsExecutedAsRoot()) {
886 // We cannot simulate non writable locations when executed as root: b/38000545.
887 LOG(ERROR) << "Test skipped because it's running as root";
888 return;
889 }
890
Andreas Gampe29d38e72016-03-23 15:31:51 +0000891 std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
892
893 Copy(GetDexSrc1(), dex_location);
Nicolas Geoffray49cda062017-04-21 13:08:25 +0100894 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kQuicken);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000895
Calin Juravle357c66d2017-05-04 01:57:17 +0000896 ScopedNonWritable scoped_non_writable(dex_location);
897 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
898
Andreas Gampe29d38e72016-03-23 15:31:51 +0000899 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700900 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800901
902 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
903 ASSERT_TRUE(oat_file.get() != nullptr);
904 EXPECT_TRUE(oat_file->IsExecutable());
905 std::vector<std::unique_ptr<const DexFile>> dex_files;
906 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
907 EXPECT_EQ(1u, dex_files.size());
908}
909
910// Case: We have a DEX file and up-to-date OAT file for it.
911// Expect: Loading non-executable should load the oat non-executable.
912TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000913 if (IsExecutedAsRoot()) {
914 // We cannot simulate non writable locations when executed as root: b/38000545.
915 LOG(ERROR) << "Test skipped because it's running as root";
916 return;
917 }
918
Richard Uhler66d874d2015-01-15 09:37:19 -0800919 std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
920
921 Copy(GetDexSrc1(), dex_location);
Calin Juravle357c66d2017-05-04 01:57:17 +0000922
923 ScopedNonWritable scoped_non_writable(dex_location);
924 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
925
Andreas Gampe29d38e72016-03-23 15:31:51 +0000926 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800927
928 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700929 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800930
931 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
932 ASSERT_TRUE(oat_file.get() != nullptr);
933 EXPECT_FALSE(oat_file->IsExecutable());
934 std::vector<std::unique_ptr<const DexFile>> dex_files;
935 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
936 EXPECT_EQ(1u, dex_files.size());
937}
938
Richard Uhler8327cf72015-10-13 16:34:59 -0700939// Case: We don't have a DEX file and can't write the oat file.
940// Expect: We should fail to generate the oat file without crashing.
941TEST_F(OatFileAssistantTest, GenNoDex) {
Calin Juravle357c66d2017-05-04 01:57:17 +0000942 if (IsExecutedAsRoot()) {
943 // We cannot simulate non writable locations when executed as root: b/38000545.
944 LOG(ERROR) << "Test skipped because it's running as root";
945 return;
946 }
Richard Uhler8327cf72015-10-13 16:34:59 -0700947
Calin Juravle357c66d2017-05-04 01:57:17 +0000948 std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
949
950 ScopedNonWritable scoped_non_writable(dex_location);
951 ASSERT_TRUE(scoped_non_writable.IsSuccessful());
952
953 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler8327cf72015-10-13 16:34:59 -0700954 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700955 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Calin Juravle357c66d2017-05-04 01:57:17 +0000956 // We should get kUpdateSucceeded from MakeUpToDate since there's nothing
957 // that can be done in this situation.
958 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Calin Juravle44e5efa2017-09-12 00:54:26 -0700959 oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg));
Calin Juravle357c66d2017-05-04 01:57:17 +0000960
961 // Verify it didn't create an oat in the default location (dalvik-cache).
962 OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false);
963 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OatFileStatus());
964 // Verify it didn't create the odex file in the default location (../oat/isa/...odex)
965 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OdexFileStatus());
Richard Uhler8327cf72015-10-13 16:34:59 -0700966}
967
Richard Uhler66d874d2015-01-15 09:37:19 -0800968// Turn an absolute path into a path relative to the current working
969// directory.
Andreas Gampeca620d72016-11-08 08:09:33 -0800970static std::string MakePathRelative(const std::string& target) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800971 char buf[MAXPATHLEN];
972 std::string cwd = getcwd(buf, MAXPATHLEN);
973
974 // Split the target and cwd paths into components.
975 std::vector<std::string> target_path;
976 std::vector<std::string> cwd_path;
977 Split(target, '/', &target_path);
978 Split(cwd, '/', &cwd_path);
979
980 // Reverse the path components, so we can use pop_back().
981 std::reverse(target_path.begin(), target_path.end());
982 std::reverse(cwd_path.begin(), cwd_path.end());
983
984 // Drop the common prefix of the paths. Because we reversed the path
985 // components, this becomes the common suffix of target_path and cwd_path.
986 while (!target_path.empty() && !cwd_path.empty()
987 && target_path.back() == cwd_path.back()) {
988 target_path.pop_back();
989 cwd_path.pop_back();
990 }
991
992 // For each element of the remaining cwd_path, add '..' to the beginning
993 // of the target path. Because we reversed the path components, we add to
994 // the end of target_path.
995 for (unsigned int i = 0; i < cwd_path.size(); i++) {
996 target_path.push_back("..");
997 }
998
999 // Reverse again to get the right path order, and join to get the result.
1000 std::reverse(target_path.begin(), target_path.end());
Andreas Gampe9186ced2016-12-12 14:28:21 -08001001 return android::base::Join(target_path, '/');
Richard Uhler66d874d2015-01-15 09:37:19 -08001002}
1003
1004// Case: Non-absolute path to Dex location.
1005// Expect: Not sure, but it shouldn't crash.
1006TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
1007 std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
1008 Copy(GetDexSrc1(), abs_dex_location);
1009
1010 std::string dex_location = MakePathRelative(abs_dex_location);
Richard Uhlerd1472a22016-04-15 15:18:56 -07001011 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001012
1013 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler7225a8d2016-11-22 10:12:03 +00001014 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +00001015 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler03bc6592016-11-22 09:42:04 +00001016 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
1017 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -08001018}
1019
1020// Case: Very short, non-existent Dex location.
Richard Uhler9b994ea2015-06-24 08:44:19 -07001021// Expect: kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -08001022TEST_F(OatFileAssistantTest, ShortDexLocation) {
1023 std::string dex_location = "/xx";
1024
Richard Uhlerd1472a22016-04-15 15:18:56 -07001025 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001026
1027 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Andreas Gampe29d38e72016-03-23 15:31:51 +00001028 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1029 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler03bc6592016-11-22 09:42:04 +00001030 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
1031 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -07001032 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -08001033
Richard Uhler9b994ea2015-06-24 08:44:19 -07001034 // Trying to make it up to date should have no effect.
Richard Uhler66d874d2015-01-15 09:37:19 -08001035 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001036 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -07001037 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Calin Juravle44e5efa2017-09-12 00:54:26 -07001038 oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -07001039 EXPECT_TRUE(error_msg.empty());
Richard Uhler66d874d2015-01-15 09:37:19 -08001040}
1041
1042// Case: Non-standard extension for dex file.
Richard Uhler95abd042015-03-24 09:51:28 -07001043// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -08001044TEST_F(OatFileAssistantTest, LongDexExtension) {
1045 std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
1046 Copy(GetDexSrc1(), dex_location);
1047
Richard Uhlerd1472a22016-04-15 15:18:56 -07001048 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -08001049
Richard Uhler7225a8d2016-11-22 10:12:03 +00001050 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +00001051 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -08001052
1053 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +00001054 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
1055 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -08001056}
1057
1058// A task to generate a dex location. Used by the RaceToGenerate test.
1059class RaceGenerateTask : public Task {
1060 public:
1061 explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
Jeff Haof0192c82016-03-28 20:39:50 -07001062 : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr)
Richard Uhler66d874d2015-01-15 09:37:19 -08001063 {}
1064
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001065 void Run(Thread* self ATTRIBUTE_UNUSED) {
Richard Uhler66d874d2015-01-15 09:37:19 -08001066 // Load the dex files, and save a pointer to the loaded oat file, so that
1067 // we can verify only one oat file was loaded for the dex location.
Richard Uhler66d874d2015-01-15 09:37:19 -08001068 std::vector<std::unique_ptr<const DexFile>> dex_files;
1069 std::vector<std::string> error_msgs;
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001070 const OatFile* oat_file = nullptr;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001071 dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
1072 dex_location_.c_str(),
Jeff Hao0cb17282017-07-12 14:51:49 -07001073 Runtime::Current()->GetSystemClassLoader(),
Mathieu Chartierfbc31082016-01-24 11:59:56 -08001074 /*dex_elements*/nullptr,
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001075 &oat_file,
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001076 &error_msgs);
Andreas Gampe9186ced2016-12-12 14:28:21 -08001077 CHECK(!dex_files.empty()) << android::base::Join(error_msgs, '\n');
Richard Uhler07b3c232015-03-31 15:57:54 -07001078 CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
1079 loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001080 CHECK_EQ(loaded_oat_file_, oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001081 }
1082
1083 const OatFile* GetLoadedOatFile() const {
1084 return loaded_oat_file_;
1085 }
1086
1087 private:
1088 std::string dex_location_;
1089 std::string oat_location_;
1090 const OatFile* loaded_oat_file_;
1091};
1092
1093// Test the case where multiple processes race to generate an oat file.
1094// This simulates multiple processes using multiple threads.
1095//
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001096// We want unique Oat files to be loaded even when there is a race to load.
1097// TODO: The test case no longer tests locking the way it was intended since we now get multiple
1098// copies of the same Oat files mapped at different locations.
Richard Uhler66d874d2015-01-15 09:37:19 -08001099TEST_F(OatFileAssistantTest, RaceToGenerate) {
1100 std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001101 std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
Richard Uhler66d874d2015-01-15 09:37:19 -08001102
Jeff Hao0cb17282017-07-12 14:51:49 -07001103 // Start the runtime to initialize the system's class loader.
1104 Thread::Current()->TransitionFromSuspendedToRunnable();
1105 runtime_->Start();
1106
Richard Uhler66d874d2015-01-15 09:37:19 -08001107 // We use the lib core dex file, because it's large, and hopefully should
1108 // take a while to generate.
Narayan Kamathd1ef4362015-11-12 11:49:06 +00001109 Copy(GetLibCoreDexFileNames()[0], dex_location);
Richard Uhler66d874d2015-01-15 09:37:19 -08001110
1111 const int kNumThreads = 32;
1112 Thread* self = Thread::Current();
1113 ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
1114 std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
1115 for (int i = 0; i < kNumThreads; i++) {
1116 std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
1117 thread_pool.AddTask(self, task.get());
1118 tasks.push_back(std::move(task));
1119 }
1120 thread_pool.StartWorkers(self);
1121 thread_pool.Wait(self, true, false);
1122
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001123 // Verify every task got a unique oat file.
1124 std::set<const OatFile*> oat_files;
Richard Uhler66d874d2015-01-15 09:37:19 -08001125 for (auto& task : tasks) {
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001126 const OatFile* oat_file = task->GetLoadedOatFile();
1127 EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
1128 oat_files.insert(oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001129 }
1130}
1131
1132// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
1133// disabled.
1134// Expect: We should load the odex file non-executable.
1135TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
1136 std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001137 std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -08001138
1139 // Create the dex and odex files
1140 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001141 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001142
1143 // Load the oat using an executable oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -07001144 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001145
1146 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1147 ASSERT_TRUE(oat_file.get() != nullptr);
1148 EXPECT_FALSE(oat_file->IsExecutable());
1149 std::vector<std::unique_ptr<const DexFile>> dex_files;
1150 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1151 EXPECT_EQ(1u, dex_files.size());
1152}
1153
1154// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
1155// disabled.
1156// Expect: We should load the odex file non-executable.
1157TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
1158 std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001159 std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -08001160
1161 // Create the dex and odex files
1162 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001163 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001164
1165 // Load the oat using an executable oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -07001166 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001167
1168 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1169 ASSERT_TRUE(oat_file.get() != nullptr);
1170 EXPECT_FALSE(oat_file->IsExecutable());
1171 std::vector<std::unique_ptr<const DexFile>> dex_files;
1172 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1173 EXPECT_EQ(2u, dex_files.size());
1174}
1175
Richard Uhlerf4b34872016-04-13 11:03:46 -07001176TEST_F(OatFileAssistantTest, RuntimeCompilerFilterOptionUsed) {
1177 std::string dex_location = GetScratchDir() + "/RuntimeCompilerFilterOptionUsed.jar";
1178 Copy(GetDexSrc1(), dex_location);
1179
Richard Uhlerd1472a22016-04-15 15:18:56 -07001180 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhlerf4b34872016-04-13 11:03:46 -07001181
1182 std::string error_msg;
Nicolas Geoffray49cda062017-04-21 13:08:25 +01001183 Runtime::Current()->AddCompilerOption("--compiler-filter=quicken");
Richard Uhlerf4b34872016-04-13 11:03:46 -07001184 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Calin Juravle44e5efa2017-09-12 00:54:26 -07001185 oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)) <<
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001186 error_msg;
Calin Juravle357c66d2017-05-04 01:57:17 +00001187 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +01001188 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Calin Juravle357c66d2017-05-04 01:57:17 +00001189 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
Richard Uhlerf4b34872016-04-13 11:03:46 -07001190 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1191
1192 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
1193 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Calin Juravle44e5efa2017-09-12 00:54:26 -07001194 oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg))
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001195 << error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001196 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Nicolas Geoffray49cda062017-04-21 13:08:25 +01001197 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
Richard Uhlerf4b34872016-04-13 11:03:46 -07001198 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1199 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1200
1201 Runtime::Current()->AddCompilerOption("--compiler-filter=bogus");
1202 EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
Calin Juravle44e5efa2017-09-12 00:54:26 -07001203 oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg));
Richard Uhlerf4b34872016-04-13 11:03:46 -07001204}
1205
Richard Uhlerb81881d2016-04-19 13:08:04 -07001206TEST(OatFileAssistantUtilsTest, DexLocationToOdexFilename) {
Richard Uhler66d874d2015-01-15 09:37:19 -08001207 std::string error_msg;
1208 std::string odex_file;
1209
Richard Uhlerb81881d2016-04-19 13:08:04 -07001210 EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001211 "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -07001212 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001213
Richard Uhlerb81881d2016-04-19 13:08:04 -07001214 EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001215 "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -07001216 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001217
Richard Uhlerb81881d2016-04-19 13:08:04 -07001218 EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001219 "nopath.jar", kArm, &odex_file, &error_msg));
Richard Uhlerb81881d2016-04-19 13:08:04 -07001220 EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001221 "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
Richard Uhler66d874d2015-01-15 09:37:19 -08001222}
1223
Richard Uhler23cedd22015-04-08 13:17:29 -07001224// Verify the dexopt status values from dalvik.system.DexFile
1225// match the OatFileAssistant::DexOptStatus values.
1226TEST_F(OatFileAssistantTest, DexOptStatusValues) {
Richard Uhler7225a8d2016-11-22 10:12:03 +00001227 std::pair<OatFileAssistant::DexOptNeeded, const char*> mapping[] = {
1228 {OatFileAssistant::kNoDexOptNeeded, "NO_DEXOPT_NEEDED"},
1229 {OatFileAssistant::kDex2OatFromScratch, "DEX2OAT_FROM_SCRATCH"},
1230 {OatFileAssistant::kDex2OatForBootImage, "DEX2OAT_FOR_BOOT_IMAGE"},
1231 {OatFileAssistant::kDex2OatForFilter, "DEX2OAT_FOR_FILTER"},
1232 {OatFileAssistant::kDex2OatForRelocation, "DEX2OAT_FOR_RELOCATION"},
Richard Uhler7225a8d2016-11-22 10:12:03 +00001233 };
1234
Richard Uhler23cedd22015-04-08 13:17:29 -07001235 ScopedObjectAccess soa(Thread::Current());
1236 StackHandleScope<1> hs(soa.Self());
1237 ClassLinker* linker = Runtime::Current()->GetClassLinker();
1238 Handle<mirror::Class> dexfile(
1239 hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001240 ASSERT_FALSE(dexfile == nullptr);
Richard Uhler23cedd22015-04-08 13:17:29 -07001241 linker->EnsureInitialized(soa.Self(), dexfile, true, true);
1242
Richard Uhler7225a8d2016-11-22 10:12:03 +00001243 for (std::pair<OatFileAssistant::DexOptNeeded, const char*> field : mapping) {
1244 ArtField* art_field = mirror::Class::FindStaticField(
Vladimir Marko19a4d372016-12-08 14:41:46 +00001245 soa.Self(), dexfile.Get(), field.second, "I");
Richard Uhler7225a8d2016-11-22 10:12:03 +00001246 ASSERT_FALSE(art_field == nullptr);
1247 EXPECT_EQ(art_field->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1248 EXPECT_EQ(field.first, art_field->GetInt(dexfile.Get()));
1249 }
Richard Uhler23cedd22015-04-08 13:17:29 -07001250}
Richard Uhler66d874d2015-01-15 09:37:19 -08001251
Calin Juravle07c6d722017-06-07 17:06:12 +00001252// Verify that when no compiler filter is passed the default one from OatFileAssistant is used.
1253TEST_F(OatFileAssistantTest, DefaultMakeUpToDateFilter) {
1254 std::string dex_location = GetScratchDir() + "/TestDex.jar";
1255 Copy(GetDexSrc1(), dex_location);
1256
1257 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
1258
1259 const CompilerFilter::Filter default_filter =
1260 OatFileAssistant::kDefaultCompilerFilterForDexLoading;
1261 std::string error_msg;
1262 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Calin Juravle44e5efa2017-09-12 00:54:26 -07001263 oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)) <<
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001264 error_msg;
Calin Juravle07c6d722017-06-07 17:06:12 +00001265 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
1266 oat_file_assistant.GetDexOptNeeded(default_filter));
1267 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1268 EXPECT_NE(nullptr, oat_file.get());
1269 EXPECT_EQ(default_filter, oat_file->GetCompilerFilter());
1270}
1271
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001272TEST_F(OatFileAssistantTest, MakeUpToDateWithSpecialSharedLibrary) {
1273 std::string dex_location = GetScratchDir() + "/TestDex.jar";
1274 Copy(GetDexSrc1(), dex_location);
1275
1276 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
1277
1278 const CompilerFilter::Filter default_filter =
1279 OatFileAssistant::kDefaultCompilerFilterForDexLoading;
1280 std::string error_msg;
Calin Juravle44e5efa2017-09-12 00:54:26 -07001281 int status = oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg);
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001282 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg;
1283 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
1284 oat_file_assistant.GetDexOptNeeded(default_filter));
1285 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1286 EXPECT_NE(nullptr, oat_file.get());
1287 EXPECT_EQ(kSpecialSharedLibrary,
1288 oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey));
1289}
1290
1291TEST_F(OatFileAssistantTest, MakeUpToDateWithContext) {
1292 std::string dex_location = GetScratchDir() + "/TestDex.jar";
1293 std::string context_location = GetScratchDir() + "/ContextDex.jar";
1294 Copy(GetDexSrc1(), dex_location);
1295 Copy(GetDexSrc2(), context_location);
1296
1297 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
1298
1299 const CompilerFilter::Filter default_filter =
1300 OatFileAssistant::kDefaultCompilerFilterForDexLoading;
1301 std::string error_msg;
1302 std::string context_str = "PCL[" + context_location + "]";
Calin Juravle44e5efa2017-09-12 00:54:26 -07001303 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_str);
1304 ASSERT_TRUE(context != nullptr);
1305 ASSERT_TRUE(context->OpenDexFiles(kRuntimeISA, ""));
1306
1307 int status = oat_file_assistant.MakeUpToDate(false, context.get(), &error_msg);
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001308 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg;
1309 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
Calin Juravle44e5efa2017-09-12 00:54:26 -07001310 oat_file_assistant.GetDexOptNeeded(default_filter, false, false, context.get()));
1311
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001312 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1313 EXPECT_NE(nullptr, oat_file.get());
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001314 EXPECT_EQ(context->EncodeContextForOatFile(""),
1315 oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey));
1316}
1317
Calin Juravle44e5efa2017-09-12 00:54:26 -07001318TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) {
1319 std::string dex_location = GetScratchDir() + "/TestDex.jar";
1320 std::string context_location = GetScratchDir() + "/ContextDex.jar";
1321 Copy(GetDexSrc1(), dex_location);
1322 Copy(GetDexSrc2(), context_location);
1323
1324 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
1325
1326 const CompilerFilter::Filter default_filter =
1327 OatFileAssistant::kDefaultCompilerFilterForDexLoading;
1328 std::string error_msg;
1329 std::string context_str = "PCL[" + context_location + "]";
1330 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_str);
1331 ASSERT_TRUE(context != nullptr);
1332 ASSERT_TRUE(context->OpenDexFiles(kRuntimeISA, ""));
1333
1334 int status = oat_file_assistant.MakeUpToDate(false, context.get(), &error_msg);
1335 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg;
1336 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
1337 oat_file_assistant.GetDexOptNeeded(default_filter, false, false, context.get()));
1338
1339 // Update the context by overriding the jar file.
1340 Copy(GetMultiDexSrc2(), context_location);
1341 std::unique_ptr<ClassLoaderContext> updated_context = ClassLoaderContext::Create(context_str);
1342 ASSERT_TRUE(updated_context != nullptr);
1343 // DexOptNeeded should advise compilation from scratch.
1344 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
1345 oat_file_assistant.GetDexOptNeeded(
1346 default_filter, false, false, updated_context.get()));
1347}
1348
Richard Uhler66d874d2015-01-15 09:37:19 -08001349// TODO: More Tests:
1350// * Test class linker falls back to unquickened dex for DexNoOat
1351// * Test class linker falls back to unquickened dex for MultiDexNoOat
Richard Uhler66d874d2015-01-15 09:37:19 -08001352// * Test using secondary isa
Richard Uhler66d874d2015-01-15 09:37:19 -08001353// * Test for status of oat while oat is being generated (how?)
1354// * Test case where 32 and 64 bit boot class paths differ,
1355// and we ask IsInBootClassPath for a class in exactly one of the 32 or
1356// 64 bit boot class paths.
1357// * Test unexpected scenarios (?):
1358// - Dex is stripped, don't have odex.
1359// - Oat file corrupted after status check, before reload unexecutable
1360// because it's unrelocated and no dex2oat
Richard Uhler66d874d2015-01-15 09:37:19 -08001361} // namespace art