blob: e3cc77f2c09b391536166e1efcd8908baf83e0ab [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
17#include "oat_file_assistant.h"
18
19#include <algorithm>
20#include <fstream>
21#include <string>
22#include <vector>
23#include <sys/param.h>
24
25#include <backtrace/BacktraceMap.h>
26#include <gtest/gtest.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"
Richard Uhler66d874d2015-01-15 09:37:19 -080030#include "common_runtime_test.h"
Andreas Gampebb9c6b12015-03-29 13:56:36 -070031#include "compiler_callbacks.h"
Richard Uhlerf16d5722015-05-11 09:32:47 -070032#include "gc/space/image_space.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080033#include "mem_map.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"
Richard Uhler23cedd22015-04-08 13:17:29 -070036#include "scoped_thread_state_change.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080037#include "thread-inl.h"
38#include "utils.h"
39
40namespace art {
41
42class OatFileAssistantTest : public CommonRuntimeTest {
43 public:
44 virtual void SetUp() {
45 ReserveImageSpace();
46 CommonRuntimeTest::SetUp();
47
48 // Create a scratch directory to work from.
49 scratch_dir_ = android_data_ + "/OatFileAssistantTest";
50 ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700));
51
Richard Uhler63434112015-03-16 14:32:16 -070052 // Create a subdirectory in scratch for odex files.
53 odex_oat_dir_ = scratch_dir_ + "/oat";
54 ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700));
55
56 odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA));
57 ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700));
58
Richard Uhler66d874d2015-01-15 09:37:19 -080059 // Verify the environment is as we expect
60 uint32_t checksum;
61 std::string error_msg;
Richard Uhlera48403e2016-04-26 10:24:38 -070062 ASSERT_TRUE(OS::FileExists(GetSystemImageFile().c_str()))
63 << "Expected pre-compiled boot image to be at: " << GetSystemImageFile();
Richard Uhler66d874d2015-01-15 09:37:19 -080064 ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str()))
65 << "Expected dex file to be at: " << GetDexSrc1();
66 ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str()))
67 << "Expected stripped dex file to be at: " << GetStrippedDexSrc1();
Igor Murashkinb1d8c312015-08-04 11:18:43 -070068 ASSERT_FALSE(DexFile::GetChecksum(GetStrippedDexSrc1().c_str(), &checksum, &error_msg))
Richard Uhler66d874d2015-01-15 09:37:19 -080069 << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1();
Richard Uhler66d874d2015-01-15 09:37:19 -080070 ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str()))
71 << "Expected dex file to be at: " << GetDexSrc2();
Richard Uhler67ff7d12015-05-14 13:21:13 -070072
73 // GetMultiDexSrc2 should have the same primary dex checksum as
74 // GetMultiDexSrc1, but a different secondary dex checksum.
Aart Bik37d6a3b2016-06-21 18:30:10 -070075 static constexpr bool kVerifyChecksum = true;
Richard Uhler67ff7d12015-05-14 13:21:13 -070076 std::vector<std::unique_ptr<const DexFile>> multi1;
77 ASSERT_TRUE(DexFile::Open(GetMultiDexSrc1().c_str(),
Aart Bik37d6a3b2016-06-21 18:30:10 -070078 GetMultiDexSrc1().c_str(), kVerifyChecksum, &error_msg, &multi1)) << error_msg;
Richard Uhler67ff7d12015-05-14 13:21:13 -070079 ASSERT_GT(multi1.size(), 1u);
80
81 std::vector<std::unique_ptr<const DexFile>> multi2;
82 ASSERT_TRUE(DexFile::Open(GetMultiDexSrc2().c_str(),
Aart Bik37d6a3b2016-06-21 18:30:10 -070083 GetMultiDexSrc2().c_str(), kVerifyChecksum, &error_msg, &multi2)) << error_msg;
Richard Uhler67ff7d12015-05-14 13:21:13 -070084 ASSERT_GT(multi2.size(), 1u);
85
86 ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum());
87 ASSERT_NE(multi1[1]->GetLocationChecksum(), multi2[1]->GetLocationChecksum());
Richard Uhler66d874d2015-01-15 09:37:19 -080088 }
89
Richard Uhlera48403e2016-04-26 10:24:38 -070090 // Pre-Relocate the image to a known non-zero offset so we don't have to
91 // deal with the runtime randomly relocating the image by 0 and messing up
92 // the expected results of the tests.
93 bool PreRelocateImage(std::string* error_msg) {
94 std::string image;
95 if (!GetCachedImageFile(&image, error_msg)) {
96 return false;
97 }
98
99 std::string patchoat = GetAndroidRoot();
100 patchoat += kIsDebugBuild ? "/bin/patchoatd" : "/bin/patchoat";
101
102 std::vector<std::string> argv;
103 argv.push_back(patchoat);
104 argv.push_back("--input-image-location=" + GetImageLocation());
105 argv.push_back("--output-image-file=" + image);
106 argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA)));
107 argv.push_back("--base-offset-delta=0x00008000");
108 return Exec(argv, error_msg);
109 }
110
Richard Uhler66d874d2015-01-15 09:37:19 -0800111 virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
Richard Uhler892fc962015-03-10 16:57:05 +0000112 // options->push_back(std::make_pair("-verbose:oat", nullptr));
Richard Uhler66d874d2015-01-15 09:37:19 -0800113
114 // Set up the image location.
115 options->push_back(std::make_pair("-Ximage:" + GetImageLocation(),
116 nullptr));
117 // Make sure compilercallbacks are not set so that relocation will be
118 // enabled.
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700119 callbacks_.reset();
Richard Uhler66d874d2015-01-15 09:37:19 -0800120 }
121
122 virtual void PreRuntimeCreate() {
Richard Uhlera48403e2016-04-26 10:24:38 -0700123 std::string error_msg;
124 ASSERT_TRUE(PreRelocateImage(&error_msg)) << error_msg;
125
Richard Uhler66d874d2015-01-15 09:37:19 -0800126 UnreserveImageSpace();
127 }
128
129 virtual void PostRuntimeCreate() {
130 ReserveImageSpace();
131 }
132
133 virtual void TearDown() {
Richard Uhler63434112015-03-16 14:32:16 -0700134 ClearDirectory(odex_dir_.c_str());
135 ASSERT_EQ(0, rmdir(odex_dir_.c_str()));
136
137 ClearDirectory(odex_oat_dir_.c_str());
138 ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str()));
Richard Uhler66d874d2015-01-15 09:37:19 -0800139
140 ClearDirectory(scratch_dir_.c_str());
141 ASSERT_EQ(0, rmdir(scratch_dir_.c_str()));
142
143 CommonRuntimeTest::TearDown();
144 }
145
146 void Copy(std::string src, std::string dst) {
147 std::ifstream src_stream(src, std::ios::binary);
148 std::ofstream dst_stream(dst, std::ios::binary);
149
150 dst_stream << src_stream.rdbuf();
151 }
152
153 // Returns the directory where the pre-compiled core.art can be found.
154 // TODO: We should factor out this into common tests somewhere rather than
155 // re-hardcoding it here (This was copied originally from the elf writer
156 // test).
157 std::string GetImageDirectory() {
158 if (IsHost()) {
159 const char* host_dir = getenv("ANDROID_HOST_OUT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700160 CHECK(host_dir != nullptr);
Richard Uhler66d874d2015-01-15 09:37:19 -0800161 return std::string(host_dir) + "/framework";
162 } else {
163 return std::string("/data/art-test");
164 }
165 }
166
167 std::string GetImageLocation() {
168 return GetImageDirectory() + "/core.art";
169 }
170
Richard Uhlera48403e2016-04-26 10:24:38 -0700171 std::string GetSystemImageFile() {
Richard Uhler66d874d2015-01-15 09:37:19 -0800172 return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA)
173 + "/core.art";
174 }
175
Richard Uhlera48403e2016-04-26 10:24:38 -0700176 bool GetCachedImageFile(/*out*/std::string* image, std::string* error_msg) {
177 std::string cache = GetDalvikCache(GetInstructionSetString(kRuntimeISA), true);
178 return GetDalvikCacheFilename(GetImageLocation().c_str(), cache.c_str(), image, error_msg);
179 }
180
Richard Uhler66d874d2015-01-15 09:37:19 -0800181 std::string GetDexSrc1() {
182 return GetTestDexFileName("Main");
183 }
184
185 // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex
186 // file stripped.
187 std::string GetStrippedDexSrc1() {
188 return GetTestDexFileName("MainStripped");
189 }
190
191 std::string GetMultiDexSrc1() {
192 return GetTestDexFileName("MultiDex");
193 }
194
Richard Uhler67ff7d12015-05-14 13:21:13 -0700195 // Returns the path to a multidex file equivalent to GetMultiDexSrc2, but
196 // with the contents of the secondary dex file changed.
197 std::string GetMultiDexSrc2() {
198 return GetTestDexFileName("MultiDexModifiedSecondary");
199 }
200
Richard Uhler66d874d2015-01-15 09:37:19 -0800201 std::string GetDexSrc2() {
202 return GetTestDexFileName("Nested");
203 }
204
205 // Scratch directory, for dex and odex files (oat files will go in the
206 // dalvik cache).
207 std::string GetScratchDir() {
208 return scratch_dir_;
209 }
210
Richard Uhler63434112015-03-16 14:32:16 -0700211 // Odex directory is the subdirectory in the scratch directory where odex
Richard Uhler66d874d2015-01-15 09:37:19 -0800212 // files should be located.
Richard Uhler63434112015-03-16 14:32:16 -0700213 std::string GetOdexDir() {
214 return odex_dir_;
Richard Uhler66d874d2015-01-15 09:37:19 -0800215 }
216
Richard Uhler93aa2102015-08-10 14:47:41 -0700217 // Generate a non-PIC odex file for the purposes of test.
Richard Uhler94f5bda2015-07-22 08:25:11 -0700218 // The generated odex file will be un-relocated.
Richard Uhler66d874d2015-01-15 09:37:19 -0800219 void GenerateOdexForTest(const std::string& dex_location,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000220 const std::string& odex_location,
Richard Uhlera48403e2016-04-26 10:24:38 -0700221 CompilerFilter::Filter filter,
222 bool pic = false,
223 bool with_patch_info = true) {
224 // Temporarily redirect the dalvik cache so dex2oat doesn't find the
225 // relocated image file.
226 std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp";
227 setenv("ANDROID_DATA", android_data_tmp.c_str(), 1);
Richard Uhler93aa2102015-08-10 14:47:41 -0700228 std::vector<std::string> args;
229 args.push_back("--dex-file=" + dex_location);
Richard Uhlera48403e2016-04-26 10:24:38 -0700230 args.push_back("--oat-file=" + odex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000231 args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
Richard Uhlera48403e2016-04-26 10:24:38 -0700232 args.push_back("--runtime-arg");
233 args.push_back("-Xnorelocate");
Richard Uhler93aa2102015-08-10 14:47:41 -0700234
Richard Uhlera48403e2016-04-26 10:24:38 -0700235 if (pic) {
236 args.push_back("--compile-pic");
237 }
238
239 if (with_patch_info) {
240 args.push_back("--include-patch-information");
241 }
Richard Uhler93aa2102015-08-10 14:47:41 -0700242
243 std::string error_msg;
244 ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
Richard Uhlera48403e2016-04-26 10:24:38 -0700245 setenv("ANDROID_DATA", android_data_.c_str(), 1);
Richard Uhler93aa2102015-08-10 14:47:41 -0700246
247 // Verify the odex file was generated as expected and really is
248 // unrelocated.
Mathieu Chartier0b4cbd02016-03-08 16:49:58 -0800249 std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(),
250 odex_location.c_str(),
251 nullptr,
252 nullptr,
253 false,
254 /*low_4gb*/false,
255 dex_location.c_str(),
256 &error_msg));
Richard Uhler93aa2102015-08-10 14:47:41 -0700257 ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
Richard Uhlera48403e2016-04-26 10:24:38 -0700258 EXPECT_EQ(pic, odex_file->IsPic());
259 EXPECT_EQ(with_patch_info, odex_file->HasPatchInfo());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000260 EXPECT_EQ(filter, odex_file->GetCompilerFilter());
261
Vladimir Markof6d1e0f2016-05-23 15:32:42 +0100262 if (CompilerFilter::IsBytecodeCompilationEnabled(filter)) {
Andreas Gampe29d38e72016-03-23 15:31:51 +0000263 const std::vector<gc::space::ImageSpace*> image_spaces =
Richard Uhlera48403e2016-04-26 10:24:38 -0700264 Runtime::Current()->GetHeap()->GetBootImageSpaces();
Andreas Gampe29d38e72016-03-23 15:31:51 +0000265 ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr);
266 const ImageHeader& image_header = image_spaces[0]->GetImageHeader();
267 const OatHeader& oat_header = odex_file->GetOatHeader();
Jeff Haob11ffb72016-04-07 15:40:54 -0700268 uint32_t combined_checksum = OatFileAssistant::CalculateCombinedImageChecksum();
269 EXPECT_EQ(combined_checksum, oat_header.GetImageFileLocationOatChecksum());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000270 EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()),
271 oat_header.GetImageFileLocationOatDataBegin());
272 EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta());
273 }
Richard Uhler93aa2102015-08-10 14:47:41 -0700274 }
275
276 void GeneratePicOdexForTest(const std::string& dex_location,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000277 const std::string& odex_location,
278 CompilerFilter::Filter filter) {
Richard Uhlera48403e2016-04-26 10:24:38 -0700279 GenerateOdexForTest(dex_location, odex_location, filter, true, false);
Calin Juravleb077e152016-02-18 18:47:37 +0000280 }
David Brazdilce4b0ba2016-01-28 15:05:49 +0000281
Richard Uhlerd1537b52016-03-29 13:27:41 -0700282 // Generate a non-PIC odex file without patch information for the purposes
283 // of test. The generated odex file will be un-relocated.
Richard Uhlerd1537b52016-03-29 13:27:41 -0700284 void GenerateNoPatchOdexForTest(const std::string& dex_location,
285 const std::string& odex_location,
286 CompilerFilter::Filter filter) {
Richard Uhlera48403e2016-04-26 10:24:38 -0700287 GenerateOdexForTest(dex_location, odex_location, filter, false, false);
Richard Uhlerd1537b52016-03-29 13:27:41 -0700288 }
289
Richard Uhler66d874d2015-01-15 09:37:19 -0800290 private:
291 // Reserve memory around where the image will be loaded so other memory
292 // won't conflict when it comes time to load the image.
293 // This can be called with an already loaded image to reserve the space
294 // around it.
295 void ReserveImageSpace() {
296 MemMap::Init();
297
298 // Ensure a chunk of memory is reserved for the image space.
Richard Uhlera48403e2016-04-26 10:24:38 -0700299 // The reservation_end includes room for the main space that has to come
300 // right after the image in case of the GSS collector.
301 uintptr_t reservation_start = ART_BASE_ADDRESS;
302 uintptr_t reservation_end = ART_BASE_ADDRESS + 384 * MB;
Richard Uhler66d874d2015-01-15 09:37:19 -0800303
Richard Uhler66d874d2015-01-15 09:37:19 -0800304 std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
305 ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
306 for (BacktraceMap::const_iterator it = map->begin();
307 reservation_start < reservation_end && it != map->end(); ++it) {
Richard Uhler3efe9792015-03-30 16:18:03 -0700308 ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end));
309 reservation_start = std::max(reservation_start, it->end);
310 }
311 ReserveImageSpaceChunk(reservation_start, reservation_end);
312 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800313
Richard Uhler3efe9792015-03-30 16:18:03 -0700314 // Reserve a chunk of memory for the image space in the given range.
315 // Only has effect for chunks with a positive number of bytes.
316 void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) {
317 if (start < end) {
318 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800319 image_reservation_.push_back(std::unique_ptr<MemMap>(
320 MemMap::MapAnonymous("image reservation",
Richard Uhler3efe9792015-03-30 16:18:03 -0700321 reinterpret_cast<uint8_t*>(start), end - start,
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700322 PROT_NONE, false, false, &error_msg)));
Richard Uhler66d874d2015-01-15 09:37:19 -0800323 ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
324 LOG(INFO) << "Reserved space for image " <<
325 reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
326 reinterpret_cast<void*>(image_reservation_.back()->End());
Richard Uhler66d874d2015-01-15 09:37:19 -0800327 }
328 }
329
330
331 // Unreserve any memory reserved by ReserveImageSpace. This should be called
332 // before the image is loaded.
333 void UnreserveImageSpace() {
334 image_reservation_.clear();
335 }
336
337 std::string scratch_dir_;
Richard Uhler63434112015-03-16 14:32:16 -0700338 std::string odex_oat_dir_;
339 std::string odex_dir_;
Richard Uhler66d874d2015-01-15 09:37:19 -0800340 std::vector<std::unique_ptr<MemMap>> image_reservation_;
341};
342
343class OatFileAssistantNoDex2OatTest : public OatFileAssistantTest {
344 public:
345 virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
346 OatFileAssistantTest::SetUpRuntimeOptions(options);
347 options->push_back(std::make_pair("-Xnodex2oat", nullptr));
348 }
349};
350
351// Generate an oat file for the purposes of test, as opposed to testing
352// generation of oat files.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000353static void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) {
354 // Use an oat file assistant to find the proper oat location.
355 OatFileAssistant ofa(dex_location, kRuntimeISA, false, false);
356 const std::string* oat_location = ofa.OatFileName();
357 ASSERT_TRUE(oat_location != nullptr);
Richard Uhler66d874d2015-01-15 09:37:19 -0800358
Andreas Gampe29d38e72016-03-23 15:31:51 +0000359 std::vector<std::string> args;
360 args.push_back("--dex-file=" + std::string(dex_location));
361 args.push_back("--oat-file=" + *oat_location);
362 args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
363 args.push_back("--runtime-arg");
364 args.push_back("-Xnorelocate");
Richard Uhler66d874d2015-01-15 09:37:19 -0800365 std::string error_msg;
Andreas Gampe29d38e72016-03-23 15:31:51 +0000366 ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
367
368 // Verify the oat file was generated as expected.
369 std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location->c_str(),
370 oat_location->c_str(),
371 nullptr,
372 nullptr,
373 false,
374 /*low_4gb*/false,
375 dex_location,
376 &error_msg));
377 ASSERT_TRUE(oat_file.get() != nullptr) << error_msg;
378 EXPECT_EQ(filter, oat_file->GetCompilerFilter());
Richard Uhler66d874d2015-01-15 09:37:19 -0800379}
380
381// Case: We have a DEX file, but no OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700382// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800383TEST_F(OatFileAssistantTest, DexNoOat) {
384 std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
385 Copy(GetDexSrc1(), dex_location);
386
Andreas Gampe29d38e72016-03-23 15:31:51 +0000387 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800388
Andreas Gampe29d38e72016-03-23 15:31:51 +0000389 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
390 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
391 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
392 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
393 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
394 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
395 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
396 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800397
398 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
399 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
400 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
401 EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
402 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
Richard Uhler95abd042015-03-24 09:51:28 -0700403 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800404 EXPECT_FALSE(oat_file_assistant.OatFileExists());
405 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
406 EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
407 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler95abd042015-03-24 09:51:28 -0700408 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700409 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800410}
411
412// Case: We have no DEX file and no OAT file.
Richard Uhler9b994ea2015-06-24 08:44:19 -0700413// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800414TEST_F(OatFileAssistantTest, NoDexNoOat) {
415 std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
416
Andreas Gampe29d38e72016-03-23 15:31:51 +0000417 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800418
Andreas Gampe29d38e72016-03-23 15:31:51 +0000419 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
420 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700421 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
422
423 // Trying to make the oat file up to date should not fail or crash.
424 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700425 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, oat_file_assistant.MakeUpToDate(&error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700426
427 // Trying to get the best oat file should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800428 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
429 EXPECT_EQ(nullptr, oat_file.get());
430}
431
432// Case: We have a DEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700433// Expect: The status is kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800434TEST_F(OatFileAssistantTest, OatUpToDate) {
435 std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
436 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000437 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800438
Andreas Gampe29d38e72016-03-23 15:31:51 +0000439 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800440
Andreas Gampe29d38e72016-03-23 15:31:51 +0000441 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
442 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
443 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
444 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
445 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
446 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
447 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
448 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
449
Richard Uhler66d874d2015-01-15 09:37:19 -0800450 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
451 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
452 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
453 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
454 EXPECT_TRUE(oat_file_assistant.OatFileExists());
455 EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
456 EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
457 EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler95abd042015-03-24 09:51:28 -0700458 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700459 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800460}
461
Andreas Gampe29d38e72016-03-23 15:31:51 +0000462// Case: We have a DEX file and speed-profile OAT file for it.
463// Expect: The status is kNoDexOptNeeded if the profile hasn't changed.
464TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
465 std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
466 Copy(GetDexSrc1(), dex_location);
467 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
468
469 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
470
471 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
472 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
473 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
474 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
475
476 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
477 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
478 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
479 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
480 EXPECT_TRUE(oat_file_assistant.OatFileExists());
481 EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
482 EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
483 EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
484 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
485 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
486}
487
488// Case: We have a DEX file and speed-profile OAT file for it.
489// Expect: The status is kNoDex2OatNeeded if the profile has changed.
490TEST_F(OatFileAssistantTest, ProfileOatOutOfDate) {
491 std::string dex_location = GetScratchDir() + "/ProfileOatOutOfDate.jar";
492 Copy(GetDexSrc1(), dex_location);
493 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
494
495 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true, false);
496
497 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
498 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
499 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
500 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
501
502 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
503 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
504 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
505 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
506 EXPECT_TRUE(oat_file_assistant.OatFileExists());
507 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
508 EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
509 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
510 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
511 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
512}
513
Richard Uhler66d874d2015-01-15 09:37:19 -0800514// Case: We have a MultiDEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700515// Expect: The status is kNoDexOptNeeded and we load all dex files.
Richard Uhler66d874d2015-01-15 09:37:19 -0800516TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
517 std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
518 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000519 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800520
Andreas Gampe29d38e72016-03-23 15:31:51 +0000521 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
522 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
523 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700524 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler95abd042015-03-24 09:51:28 -0700525
526 // Verify we can load both dex files.
Richard Uhlere5fed032015-03-18 08:21:11 -0700527 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
Richard Uhler66d874d2015-01-15 09:37:19 -0800528 ASSERT_TRUE(oat_file.get() != nullptr);
529 EXPECT_TRUE(oat_file->IsExecutable());
530 std::vector<std::unique_ptr<const DexFile>> dex_files;
Richard Uhlere5fed032015-03-18 08:21:11 -0700531 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
532 EXPECT_EQ(2u, dex_files.size());
533}
534
Richard Uhler67ff7d12015-05-14 13:21:13 -0700535// Case: We have a MultiDEX file where the secondary dex file is out of date.
536// Expect: The status is kDex2OatNeeded.
537TEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) {
538 std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar";
539
540 // Compile code for GetMultiDexSrc1.
541 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000542 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler67ff7d12015-05-14 13:21:13 -0700543
544 // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
545 // is out of date.
546 Copy(GetMultiDexSrc2(), dex_location);
547
Andreas Gampe29d38e72016-03-23 15:31:51 +0000548 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
549 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
550 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700551 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler67ff7d12015-05-14 13:21:13 -0700552}
553
Richard Uhlere5fed032015-03-18 08:21:11 -0700554// Case: We have a MultiDEX file and up-to-date OAT file for it with relative
555// encoded dex locations.
Richard Uhler95abd042015-03-24 09:51:28 -0700556// Expect: The oat file status is kNoDexOptNeeded.
Richard Uhlere5fed032015-03-18 08:21:11 -0700557TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
558 std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700559 std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
Richard Uhlere5fed032015-03-18 08:21:11 -0700560
561 // Create the dex file
562 Copy(GetMultiDexSrc1(), dex_location);
563
564 // Create the oat file with relative encoded dex location.
565 std::vector<std::string> args;
566 args.push_back("--dex-file=" + dex_location);
567 args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
568 args.push_back("--oat-file=" + oat_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000569 args.push_back("--compiler-filter=speed");
Richard Uhlere5fed032015-03-18 08:21:11 -0700570
571 std::string error_msg;
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700572 ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
Richard Uhlere5fed032015-03-18 08:21:11 -0700573
574 // Verify we can load both dex files.
575 OatFileAssistant oat_file_assistant(dex_location.c_str(),
576 oat_location.c_str(),
Andreas Gampe29d38e72016-03-23 15:31:51 +0000577 kRuntimeISA, false, true);
Richard Uhlere5fed032015-03-18 08:21:11 -0700578 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
579 ASSERT_TRUE(oat_file.get() != nullptr);
580 EXPECT_TRUE(oat_file->IsExecutable());
581 std::vector<std::unique_ptr<const DexFile>> dex_files;
582 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
Richard Uhler66d874d2015-01-15 09:37:19 -0800583 EXPECT_EQ(2u, dex_files.size());
584}
585
Richard Uhler95abd042015-03-24 09:51:28 -0700586// Case: We have a DEX file and out-of-date OAT file.
587// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800588TEST_F(OatFileAssistantTest, OatOutOfDate) {
589 std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar";
590
591 // We create a dex, generate an oat for it, then overwrite the dex with a
592 // different dex to make the oat out of date.
593 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000594 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800595 Copy(GetDexSrc2(), dex_location);
596
Andreas Gampe29d38e72016-03-23 15:31:51 +0000597 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
598 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
599 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
600 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
601 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800602
603 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
604 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
605 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
606 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
607 EXPECT_TRUE(oat_file_assistant.OatFileExists());
608 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
609 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700610 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800611}
612
613// Case: We have a DEX file and an ODEX file, but no OAT file.
Richard Uhler95abd042015-03-24 09:51:28 -0700614// Expect: The status is kPatchOatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800615TEST_F(OatFileAssistantTest, DexOdexNoOat) {
616 std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700617 std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800618
619 // Create the dex and odex files
620 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000621 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800622
623 // Verify the status.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000624 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800625
Andreas Gampe29d38e72016-03-23 15:31:51 +0000626 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
627 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
628 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
629 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800630
631 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
632 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
633 EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
634 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
635 EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
Richard Uhler66d874d2015-01-15 09:37:19 -0800636 EXPECT_FALSE(oat_file_assistant.OatFileExists());
637 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
638 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700639 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler5f946da2015-07-17 12:28:32 -0700640
641 // We should still be able to get the non-executable odex file to run from.
642 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
643 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhler66d874d2015-01-15 09:37:19 -0800644}
645
646// Case: We have a stripped DEX file and an ODEX file, but no OAT file.
Richard Uhler95abd042015-03-24 09:51:28 -0700647// Expect: The status is kPatchOatNeeded
Richard Uhler66d874d2015-01-15 09:37:19 -0800648TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
649 std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700650 std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800651
652 // Create the dex and odex files
653 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000654 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800655
656 // Strip the dex file
657 Copy(GetStrippedDexSrc1(), dex_location);
658
659 // Verify the status.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000660 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800661
Andreas Gampe29d38e72016-03-23 15:31:51 +0000662 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
663 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800664
665 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
666 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
667 EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
668 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
669 EXPECT_FALSE(oat_file_assistant.OatFileExists());
670 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
671 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700672 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800673
674 // Make the oat file up to date.
675 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700676 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700677 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerf4b34872016-04-13 11:03:46 -0700678 oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800679
Andreas Gampe29d38e72016-03-23 15:31:51 +0000680 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
681 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800682
683 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
684 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
685 EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
686 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
687 EXPECT_TRUE(oat_file_assistant.OatFileExists());
688 EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
689 EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700690 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800691
692 // Verify we can load the dex files from it.
693 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
694 ASSERT_TRUE(oat_file.get() != nullptr);
695 EXPECT_TRUE(oat_file->IsExecutable());
696 std::vector<std::unique_ptr<const DexFile>> dex_files;
697 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
698 EXPECT_EQ(1u, dex_files.size());
699}
700
Richard Uhler95abd042015-03-24 09:51:28 -0700701// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file.
702// Expect: The status is kPatchOatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800703TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
704 std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700705 std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800706
707 // Create the oat file from a different dex file so it looks out of date.
708 Copy(GetDexSrc2(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000709 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800710
711 // Create the odex file
712 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000713 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800714
715 // Strip the dex file.
716 Copy(GetStrippedDexSrc1(), dex_location);
717
718 // Verify the status.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000719 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800720
Andreas Gampe29d38e72016-03-23 15:31:51 +0000721 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
722 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
723 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
724 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
725 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped.
726 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800727
728 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
729 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
730 EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
731 EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
732 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
733 EXPECT_TRUE(oat_file_assistant.OatFileExists());
734 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
735 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700736 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800737
738 // Make the oat file up to date.
739 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700740 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700741 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerf4b34872016-04-13 11:03:46 -0700742 oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800743
Andreas Gampe29d38e72016-03-23 15:31:51 +0000744 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
745 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
746 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped.
747 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800748
749 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
750 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
751 EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
752 EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
753 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
754 EXPECT_TRUE(oat_file_assistant.OatFileExists());
755 EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
756 EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
757 EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700758 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800759
760 // Verify we can load the dex files from it.
761 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
762 ASSERT_TRUE(oat_file.get() != nullptr);
763 EXPECT_TRUE(oat_file->IsExecutable());
764 std::vector<std::unique_ptr<const DexFile>> dex_files;
765 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
766 EXPECT_EQ(1u, dex_files.size());
767}
768
Richard Uhler9b994ea2015-06-24 08:44:19 -0700769// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
770// OAT file. Expect: The status is kNoDexOptNeeded.
771TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
772 std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
773
774 Copy(GetStrippedDexSrc1(), dex_location);
775
776 // Verify the status.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000777 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
Richard Uhler9b994ea2015-06-24 08:44:19 -0700778
Andreas Gampe29d38e72016-03-23 15:31:51 +0000779 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
780 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
781 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
782 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
783 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
784 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700785
786 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
787 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
788 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
789 EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
790 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
791 EXPECT_FALSE(oat_file_assistant.OatFileExists());
792 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
793 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
794 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
795
796 // Make the oat file up to date. This should have no effect.
797 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700798 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700799 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerf4b34872016-04-13 11:03:46 -0700800 oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
Richard Uhler9b994ea2015-06-24 08:44:19 -0700801
Andreas Gampe29d38e72016-03-23 15:31:51 +0000802 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
803 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700804
805 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
806 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
807 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
808 EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
809 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
810 EXPECT_FALSE(oat_file_assistant.OatFileExists());
811 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
812 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
813 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
814}
815
Richard Uhler95abd042015-03-24 09:51:28 -0700816// Case: We have a DEX file, no ODEX file and an OAT file that needs
817// relocation.
818// Expect: The status is kSelfPatchOatNeeded.
819TEST_F(OatFileAssistantTest, SelfRelocation) {
820 std::string dex_location = GetScratchDir() + "/SelfRelocation.jar";
821 std::string oat_location = GetOdexDir() + "/SelfRelocation.oat";
822
823 // Create the dex and odex files
824 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000825 GenerateOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
Richard Uhler95abd042015-03-24 09:51:28 -0700826
827 OatFileAssistant oat_file_assistant(dex_location.c_str(),
Andreas Gampe29d38e72016-03-23 15:31:51 +0000828 oat_location.c_str(), kRuntimeISA, false, true);
Richard Uhler95abd042015-03-24 09:51:28 -0700829
Andreas Gampe29d38e72016-03-23 15:31:51 +0000830 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
831 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
832 EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded,
833 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
834 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
835 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler95abd042015-03-24 09:51:28 -0700836
837 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
838 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
839 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
840 EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
841 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
842 EXPECT_TRUE(oat_file_assistant.OatFileExists());
843 EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation());
844 EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
845 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700846 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler95abd042015-03-24 09:51:28 -0700847
848 // Make the oat file up to date.
849 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700850 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700851 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerf4b34872016-04-13 11:03:46 -0700852 oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
Richard Uhler95abd042015-03-24 09:51:28 -0700853
Andreas Gampe29d38e72016-03-23 15:31:51 +0000854 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
855 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler95abd042015-03-24 09:51:28 -0700856
857 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
858 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
859 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
860 EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
861 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
862 EXPECT_TRUE(oat_file_assistant.OatFileExists());
863 EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
864 EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
865 EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700866 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler95abd042015-03-24 09:51:28 -0700867
868 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
869 ASSERT_TRUE(oat_file.get() != nullptr);
870 EXPECT_TRUE(oat_file->IsExecutable());
871 std::vector<std::unique_ptr<const DexFile>> dex_files;
872 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
873 EXPECT_EQ(1u, dex_files.size());
874}
875
Richard Uhlerd1537b52016-03-29 13:27:41 -0700876// Case: We have a DEX file, no ODEX file and an OAT file that needs
877// relocation but doesn't have patch info.
878// Expect: The status is kDex2OatNeeded, because we can't run patchoat.
879TEST_F(OatFileAssistantTest, NoSelfRelocation) {
880 std::string dex_location = GetScratchDir() + "/NoSelfRelocation.jar";
881 std::string oat_location = GetOdexDir() + "/NoSelfRelocation.oat";
882
883 // Create the dex and odex files
884 Copy(GetDexSrc1(), dex_location);
885 GenerateNoPatchOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
886
887 OatFileAssistant oat_file_assistant(dex_location.c_str(),
888 oat_location.c_str(), kRuntimeISA, false, true);
889
890 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
891 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
892
893 // Make the oat file up to date.
894 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700895 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700896 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerf4b34872016-04-13 11:03:46 -0700897 oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
Richard Uhlerd1537b52016-03-29 13:27:41 -0700898 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
899 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
900
901 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
902 ASSERT_TRUE(oat_file.get() != nullptr);
903 EXPECT_TRUE(oat_file->IsExecutable());
904 std::vector<std::unique_ptr<const DexFile>> dex_files;
905 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
906 EXPECT_EQ(1u, dex_files.size());
907}
908
Richard Uhler66d874d2015-01-15 09:37:19 -0800909// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
910// OAT files both have patch delta of 0.
Richard Uhler95abd042015-03-24 09:51:28 -0700911// Expect: It shouldn't crash, and status is kPatchOatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800912TEST_F(OatFileAssistantTest, OdexOatOverlap) {
913 std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700914 std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
915 std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
Richard Uhler66d874d2015-01-15 09:37:19 -0800916
917 // Create the dex and odex files
918 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000919 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800920
921 // Create the oat file by copying the odex so they are located in the same
922 // place in memory.
923 Copy(odex_location, oat_location);
924
925 // Verify things don't go bad.
926 OatFileAssistant oat_file_assistant(dex_location.c_str(),
Andreas Gampe29d38e72016-03-23 15:31:51 +0000927 oat_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800928
Andreas Gampe29d38e72016-03-23 15:31:51 +0000929 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
930 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800931
932 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
933 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
934 EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
935 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
936 EXPECT_TRUE(oat_file_assistant.OatFileExists());
937 EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
938 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700939 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800940
941 // Things aren't relocated, so it should fall back to interpreted.
942 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
943 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhlerf16d5722015-05-11 09:32:47 -0700944
Richard Uhler66d874d2015-01-15 09:37:19 -0800945 EXPECT_FALSE(oat_file->IsExecutable());
946 std::vector<std::unique_ptr<const DexFile>> dex_files;
947 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
948 EXPECT_EQ(1u, dex_files.size());
949}
950
951// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
Richard Uhler95abd042015-03-24 09:51:28 -0700952// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
Richard Uhler66d874d2015-01-15 09:37:19 -0800953TEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
954 std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700955 std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800956
957 // Create the dex and odex files
958 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000959 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800960
961 // Verify the status.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000962 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800963
Andreas Gampe29d38e72016-03-23 15:31:51 +0000964 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
965 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
966 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
967 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800968
969 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
970 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
971 EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
972 EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
973 EXPECT_FALSE(oat_file_assistant.OatFileExists());
974 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
975 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700976 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800977}
978
Andreas Gampe29d38e72016-03-23 15:31:51 +0000979// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
980// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
981TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
982 std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
983 std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
David Brazdilce4b0ba2016-01-28 15:05:49 +0000984
985 // Create the dex and odex files
986 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000987 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000988
989 // Verify the status.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000990 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000991
Andreas Gampe29d38e72016-03-23 15:31:51 +0000992 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
993 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
994 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
995 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
David Brazdilce4b0ba2016-01-28 15:05:49 +0000996
997 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
998 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
999 EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
Nicolas Geoffray845e5062016-03-23 06:42:05 +00001000 EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
David Brazdilce4b0ba2016-01-28 15:05:49 +00001001 EXPECT_FALSE(oat_file_assistant.OatFileExists());
1002 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
1003 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
1004 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
1005}
1006
Richard Uhler66d874d2015-01-15 09:37:19 -08001007// Case: We have a DEX file and up-to-date OAT file for it.
1008// Expect: We should load an executable dex file.
1009TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
1010 std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
1011
1012 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001013 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001014
1015 // Load the oat using an oat file assistant.
Andreas Gampe29d38e72016-03-23 15:31:51 +00001016 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
1017
1018 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1019 ASSERT_TRUE(oat_file.get() != nullptr);
1020 EXPECT_TRUE(oat_file->IsExecutable());
1021 std::vector<std::unique_ptr<const DexFile>> dex_files;
1022 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1023 EXPECT_EQ(1u, dex_files.size());
1024}
1025
1026// Case: We have a DEX file and up-to-date interpret-only OAT file for it.
1027// Expect: We should still load the oat file as executable.
1028TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
1029 std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
1030
1031 Copy(GetDexSrc1(), dex_location);
1032 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kInterpretOnly);
1033
1034 // Load the oat using an oat file assistant.
1035 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001036
1037 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1038 ASSERT_TRUE(oat_file.get() != nullptr);
1039 EXPECT_TRUE(oat_file->IsExecutable());
1040 std::vector<std::unique_ptr<const DexFile>> dex_files;
1041 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1042 EXPECT_EQ(1u, dex_files.size());
1043}
1044
1045// Case: We have a DEX file and up-to-date OAT file for it.
1046// Expect: Loading non-executable should load the oat non-executable.
1047TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
1048 std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
1049
1050 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001051 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001052
1053 // Load the oat using an oat file assistant.
Andreas Gampe29d38e72016-03-23 15:31:51 +00001054 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
Richard Uhler66d874d2015-01-15 09:37:19 -08001055
1056 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1057 ASSERT_TRUE(oat_file.get() != nullptr);
1058 EXPECT_FALSE(oat_file->IsExecutable());
1059 std::vector<std::unique_ptr<const DexFile>> dex_files;
1060 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1061 EXPECT_EQ(1u, dex_files.size());
1062}
1063
1064// Case: We have a DEX file.
1065// Expect: We should load an executable dex file from an alternative oat
1066// location.
1067TEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
1068 std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
1069 std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
1070
1071 Copy(GetDexSrc1(), dex_location);
1072
1073 OatFileAssistant oat_file_assistant(
Andreas Gampe29d38e72016-03-23 15:31:51 +00001074 dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001075 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001076 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -07001077 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerf4b34872016-04-13 11:03:46 -07001078 oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -08001079
1080 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1081 ASSERT_TRUE(oat_file.get() != nullptr);
1082 EXPECT_TRUE(oat_file->IsExecutable());
1083 std::vector<std::unique_ptr<const DexFile>> dex_files;
1084 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1085 EXPECT_EQ(1u, dex_files.size());
1086
1087 EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
1088
1089 // Verify it didn't create an oat in the default location.
Andreas Gampe29d38e72016-03-23 15:31:51 +00001090 OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false, false);
Richard Uhler66d874d2015-01-15 09:37:19 -08001091 EXPECT_FALSE(ofm.OatFileExists());
1092}
1093
Richard Uhler8327cf72015-10-13 16:34:59 -07001094// Case: We have a DEX file but can't write the oat file.
1095// Expect: We should fail to make the oat file up to date.
1096TEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) {
1097 std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar";
1098
1099 // Make the oat location unwritable by inserting some non-existent
1100 // intermediate directories.
1101 std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat";
1102
1103 Copy(GetDexSrc1(), dex_location);
1104
1105 OatFileAssistant oat_file_assistant(
Andreas Gampe29d38e72016-03-23 15:31:51 +00001106 dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
Richard Uhler8327cf72015-10-13 16:34:59 -07001107 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001108 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -07001109 ASSERT_EQ(OatFileAssistant::kUpdateNotAttempted,
Richard Uhlerf4b34872016-04-13 11:03:46 -07001110 oat_file_assistant.MakeUpToDate(&error_msg));
Richard Uhler8327cf72015-10-13 16:34:59 -07001111
1112 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1113 ASSERT_TRUE(oat_file.get() == nullptr);
1114}
1115
1116// Case: We don't have a DEX file and can't write the oat file.
1117// Expect: We should fail to generate the oat file without crashing.
1118TEST_F(OatFileAssistantTest, GenNoDex) {
1119 std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
1120 std::string oat_location = GetScratchDir() + "/GenNoDex.oat";
1121
1122 OatFileAssistant oat_file_assistant(
Andreas Gampe29d38e72016-03-23 15:31:51 +00001123 dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
Richard Uhler8327cf72015-10-13 16:34:59 -07001124 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001125 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -07001126 EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
Richard Uhlerf4b34872016-04-13 11:03:46 -07001127 oat_file_assistant.GenerateOatFile(&error_msg));
Richard Uhler8327cf72015-10-13 16:34:59 -07001128}
1129
Richard Uhler66d874d2015-01-15 09:37:19 -08001130// Turn an absolute path into a path relative to the current working
1131// directory.
1132static std::string MakePathRelative(std::string target) {
1133 char buf[MAXPATHLEN];
1134 std::string cwd = getcwd(buf, MAXPATHLEN);
1135
1136 // Split the target and cwd paths into components.
1137 std::vector<std::string> target_path;
1138 std::vector<std::string> cwd_path;
1139 Split(target, '/', &target_path);
1140 Split(cwd, '/', &cwd_path);
1141
1142 // Reverse the path components, so we can use pop_back().
1143 std::reverse(target_path.begin(), target_path.end());
1144 std::reverse(cwd_path.begin(), cwd_path.end());
1145
1146 // Drop the common prefix of the paths. Because we reversed the path
1147 // components, this becomes the common suffix of target_path and cwd_path.
1148 while (!target_path.empty() && !cwd_path.empty()
1149 && target_path.back() == cwd_path.back()) {
1150 target_path.pop_back();
1151 cwd_path.pop_back();
1152 }
1153
1154 // For each element of the remaining cwd_path, add '..' to the beginning
1155 // of the target path. Because we reversed the path components, we add to
1156 // the end of target_path.
1157 for (unsigned int i = 0; i < cwd_path.size(); i++) {
1158 target_path.push_back("..");
1159 }
1160
1161 // Reverse again to get the right path order, and join to get the result.
1162 std::reverse(target_path.begin(), target_path.end());
1163 return Join(target_path, '/');
1164}
1165
1166// Case: Non-absolute path to Dex location.
1167// Expect: Not sure, but it shouldn't crash.
1168TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
1169 std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
1170 Copy(GetDexSrc1(), abs_dex_location);
1171
1172 std::string dex_location = MakePathRelative(abs_dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001173 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001174
1175 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Andreas Gampe29d38e72016-03-23 15:31:51 +00001176 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
1177 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -08001178 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
1179 EXPECT_FALSE(oat_file_assistant.OatFileExists());
1180 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
1181 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
1182 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
1183 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
1184}
1185
1186// Case: Very short, non-existent Dex location.
Richard Uhler9b994ea2015-06-24 08:44:19 -07001187// Expect: kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -08001188TEST_F(OatFileAssistantTest, ShortDexLocation) {
1189 std::string dex_location = "/xx";
1190
Andreas Gampe29d38e72016-03-23 15:31:51 +00001191 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001192
1193 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Andreas Gampe29d38e72016-03-23 15:31:51 +00001194 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1195 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -08001196 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
1197 EXPECT_FALSE(oat_file_assistant.OatFileExists());
1198 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
1199 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
1200 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
1201 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
Richard Uhler9b994ea2015-06-24 08:44:19 -07001202 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -08001203
Richard Uhler9b994ea2015-06-24 08:44:19 -07001204 // Trying to make it up to date should have no effect.
Richard Uhler66d874d2015-01-15 09:37:19 -08001205 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001206 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -07001207 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerf4b34872016-04-13 11:03:46 -07001208 oat_file_assistant.MakeUpToDate(&error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -07001209 EXPECT_TRUE(error_msg.empty());
Richard Uhler66d874d2015-01-15 09:37:19 -08001210}
1211
1212// Case: Non-standard extension for dex file.
Richard Uhler95abd042015-03-24 09:51:28 -07001213// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -08001214TEST_F(OatFileAssistantTest, LongDexExtension) {
1215 std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
1216 Copy(GetDexSrc1(), dex_location);
1217
Andreas Gampe29d38e72016-03-23 15:31:51 +00001218 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
Richard Uhler66d874d2015-01-15 09:37:19 -08001219
Andreas Gampe29d38e72016-03-23 15:31:51 +00001220 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
1221 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -08001222
1223 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
1224 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
1225 EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
1226 EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
1227 EXPECT_FALSE(oat_file_assistant.OatFileExists());
1228 EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
1229 EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
1230}
1231
1232// A task to generate a dex location. Used by the RaceToGenerate test.
1233class RaceGenerateTask : public Task {
1234 public:
1235 explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
Jeff Haof0192c82016-03-28 20:39:50 -07001236 : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr)
Richard Uhler66d874d2015-01-15 09:37:19 -08001237 {}
1238
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001239 void Run(Thread* self ATTRIBUTE_UNUSED) {
Richard Uhler66d874d2015-01-15 09:37:19 -08001240 // Load the dex files, and save a pointer to the loaded oat file, so that
1241 // we can verify only one oat file was loaded for the dex location.
Richard Uhler66d874d2015-01-15 09:37:19 -08001242 std::vector<std::unique_ptr<const DexFile>> dex_files;
1243 std::vector<std::string> error_msgs;
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001244 const OatFile* oat_file = nullptr;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001245 dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
1246 dex_location_.c_str(),
1247 oat_location_.c_str(),
Mathieu Chartierfbc31082016-01-24 11:59:56 -08001248 /*class_loader*/nullptr,
1249 /*dex_elements*/nullptr,
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001250 &oat_file,
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001251 &error_msgs);
Richard Uhler66d874d2015-01-15 09:37:19 -08001252 CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
Richard Uhler07b3c232015-03-31 15:57:54 -07001253 CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
1254 loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001255 CHECK_EQ(loaded_oat_file_, oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001256 }
1257
1258 const OatFile* GetLoadedOatFile() const {
1259 return loaded_oat_file_;
1260 }
1261
1262 private:
1263 std::string dex_location_;
1264 std::string oat_location_;
1265 const OatFile* loaded_oat_file_;
1266};
1267
1268// Test the case where multiple processes race to generate an oat file.
1269// This simulates multiple processes using multiple threads.
1270//
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001271// We want unique Oat files to be loaded even when there is a race to load.
1272// TODO: The test case no longer tests locking the way it was intended since we now get multiple
1273// copies of the same Oat files mapped at different locations.
Richard Uhler66d874d2015-01-15 09:37:19 -08001274TEST_F(OatFileAssistantTest, RaceToGenerate) {
1275 std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001276 std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
Richard Uhler66d874d2015-01-15 09:37:19 -08001277
1278 // We use the lib core dex file, because it's large, and hopefully should
1279 // take a while to generate.
Narayan Kamathd1ef4362015-11-12 11:49:06 +00001280 Copy(GetLibCoreDexFileNames()[0], dex_location);
Richard Uhler66d874d2015-01-15 09:37:19 -08001281
1282 const int kNumThreads = 32;
1283 Thread* self = Thread::Current();
1284 ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
1285 std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
1286 for (int i = 0; i < kNumThreads; i++) {
1287 std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
1288 thread_pool.AddTask(self, task.get());
1289 tasks.push_back(std::move(task));
1290 }
1291 thread_pool.StartWorkers(self);
1292 thread_pool.Wait(self, true, false);
1293
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001294 // Verify every task got a unique oat file.
1295 std::set<const OatFile*> oat_files;
Richard Uhler66d874d2015-01-15 09:37:19 -08001296 for (auto& task : tasks) {
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001297 const OatFile* oat_file = task->GetLoadedOatFile();
1298 EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
1299 oat_files.insert(oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001300 }
1301}
1302
1303// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
1304// disabled.
1305// Expect: We should load the odex file non-executable.
1306TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
1307 std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001308 std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -08001309
1310 // Create the dex and odex files
1311 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001312 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001313
1314 // Load the oat using an executable oat file assistant.
Andreas Gampe29d38e72016-03-23 15:31:51 +00001315 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001316
1317 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1318 ASSERT_TRUE(oat_file.get() != nullptr);
1319 EXPECT_FALSE(oat_file->IsExecutable());
1320 std::vector<std::unique_ptr<const DexFile>> dex_files;
1321 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1322 EXPECT_EQ(1u, dex_files.size());
1323}
1324
1325// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
1326// disabled.
1327// Expect: We should load the odex file non-executable.
1328TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
1329 std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001330 std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -08001331
1332 // Create the dex and odex files
1333 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001334 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001335
1336 // Load the oat using an executable oat file assistant.
Andreas Gampe29d38e72016-03-23 15:31:51 +00001337 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001338
1339 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1340 ASSERT_TRUE(oat_file.get() != nullptr);
1341 EXPECT_FALSE(oat_file->IsExecutable());
1342 std::vector<std::unique_ptr<const DexFile>> dex_files;
1343 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1344 EXPECT_EQ(2u, dex_files.size());
1345}
1346
Richard Uhlerf4b34872016-04-13 11:03:46 -07001347TEST_F(OatFileAssistantTest, RuntimeCompilerFilterOptionUsed) {
1348 std::string dex_location = GetScratchDir() + "/RuntimeCompilerFilterOptionUsed.jar";
1349 Copy(GetDexSrc1(), dex_location);
1350
1351 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
1352
1353 std::string error_msg;
1354 Runtime::Current()->AddCompilerOption("--compiler-filter=interpret-only");
1355 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
1356 oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
1357 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1358 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
1359 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
1360 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1361
1362 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
1363 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
1364 oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
1365 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1366 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
1367 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1368 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1369
1370 Runtime::Current()->AddCompilerOption("--compiler-filter=bogus");
1371 EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
1372 oat_file_assistant.MakeUpToDate(&error_msg));
1373}
1374
Richard Uhler66d874d2015-01-15 09:37:19 -08001375TEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) {
1376 std::string error_msg;
1377 std::string odex_file;
1378
1379 EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001380 "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -07001381 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001382
1383 EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001384 "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -07001385 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001386
1387 EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001388 "nopath.jar", kArm, &odex_file, &error_msg));
Richard Uhler66d874d2015-01-15 09:37:19 -08001389 EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001390 "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
Richard Uhler66d874d2015-01-15 09:37:19 -08001391}
1392
Richard Uhler23cedd22015-04-08 13:17:29 -07001393// Verify the dexopt status values from dalvik.system.DexFile
1394// match the OatFileAssistant::DexOptStatus values.
1395TEST_F(OatFileAssistantTest, DexOptStatusValues) {
1396 ScopedObjectAccess soa(Thread::Current());
1397 StackHandleScope<1> hs(soa.Self());
1398 ClassLinker* linker = Runtime::Current()->GetClassLinker();
1399 Handle<mirror::Class> dexfile(
1400 hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
1401 ASSERT_FALSE(dexfile.Get() == nullptr);
1402 linker->EnsureInitialized(soa.Self(), dexfile, true, true);
1403
Mathieu Chartierc7853442015-03-27 14:35:38 -07001404 ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
Richard Uhler23cedd22015-04-08 13:17:29 -07001405 soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I");
1406 ASSERT_FALSE(no_dexopt_needed == nullptr);
1407 EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1408 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get()));
1409
Mathieu Chartierc7853442015-03-27 14:35:38 -07001410 ArtField* dex2oat_needed = mirror::Class::FindStaticField(
Richard Uhler23cedd22015-04-08 13:17:29 -07001411 soa.Self(), dexfile, "DEX2OAT_NEEDED", "I");
1412 ASSERT_FALSE(dex2oat_needed == nullptr);
1413 EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1414 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get()));
1415
Mathieu Chartierc7853442015-03-27 14:35:38 -07001416 ArtField* patchoat_needed = mirror::Class::FindStaticField(
Richard Uhler23cedd22015-04-08 13:17:29 -07001417 soa.Self(), dexfile, "PATCHOAT_NEEDED", "I");
1418 ASSERT_FALSE(patchoat_needed == nullptr);
1419 EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1420 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get()));
1421
Mathieu Chartierc7853442015-03-27 14:35:38 -07001422 ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
Richard Uhler23cedd22015-04-08 13:17:29 -07001423 soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I");
1424 ASSERT_FALSE(self_patchoat_needed == nullptr);
1425 EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1426 EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get()));
1427}
Richard Uhler66d874d2015-01-15 09:37:19 -08001428
1429// TODO: More Tests:
Andreas Gampe29d38e72016-03-23 15:31:51 +00001430// * Image checksum change is out of date for kIntepretOnly, but not
1431// kVerifyAtRuntime. But target of kVerifyAtRuntime still says current
1432// kInterpretOnly is out of date.
Richard Uhler66d874d2015-01-15 09:37:19 -08001433// * Test class linker falls back to unquickened dex for DexNoOat
1434// * Test class linker falls back to unquickened dex for MultiDexNoOat
Richard Uhler66d874d2015-01-15 09:37:19 -08001435// * Test using secondary isa
Richard Uhler66d874d2015-01-15 09:37:19 -08001436// * Test for status of oat while oat is being generated (how?)
1437// * Test case where 32 and 64 bit boot class paths differ,
1438// and we ask IsInBootClassPath for a class in exactly one of the 32 or
1439// 64 bit boot class paths.
1440// * Test unexpected scenarios (?):
1441// - Dex is stripped, don't have odex.
1442// - Oat file corrupted after status check, before reload unexecutable
1443// because it's unrelocated and no dex2oat
Calin Juravleb077e152016-02-18 18:47:37 +00001444// * Test unrelocated specific target compilation type can be relocated to
1445// make it up to date.
Richard Uhler66d874d2015-01-15 09:37:19 -08001446
1447} // namespace art