blob: 577200847a2a1903956d2ad2437eb261cb05ba03 [file] [log] [blame]
Richard Uhler66d874d2015-01-15 09:37:19 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Richard Uhler66d874d2015-01-15 09:37:19 -080017#include <string>
18#include <vector>
19#include <sys/param.h>
20
Andreas Gampe9186ced2016-12-12 14:28:21 -080021#include "android-base/strings.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080022#include <gtest/gtest.h>
23
Mathieu Chartierc7853442015-03-27 14:35:38 -070024#include "art_field-inl.h"
Vladimir Marko3481ba22015-04-13 12:22:36 +010025#include "class_linker-inl.h"
Calin Juravle36eb3132017-01-13 16:32:38 -080026#include "dexopt_test.h"
Andreas Gampee1459ae2016-06-29 09:36:30 -070027#include "oat_file_assistant.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070028#include "oat_file_manager.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080029#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070030#include "scoped_thread_state_change-inl.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080031#include "thread-inl.h"
32#include "utils.h"
33
34namespace art {
35
Calin Juravle36eb3132017-01-13 16:32:38 -080036class OatFileAssistantTest : public DexoptTest {};
Richard Uhler66d874d2015-01-15 09:37:19 -080037
Calin Juravle36eb3132017-01-13 16:32:38 -080038class OatFileAssistantNoDex2OatTest : public DexoptTest {
Richard Uhler66d874d2015-01-15 09:37:19 -080039 public:
40 virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
Calin Juravle36eb3132017-01-13 16:32:38 -080041 DexoptTest::SetUpRuntimeOptions(options);
Richard Uhler66d874d2015-01-15 09:37:19 -080042 options->push_back(std::make_pair("-Xnodex2oat", nullptr));
43 }
44};
45
Calin Juravle36eb3132017-01-13 16:32:38 -080046
Richard Uhler66d874d2015-01-15 09:37:19 -080047// Case: We have a DEX file, but no OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -070048// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -080049TEST_F(OatFileAssistantTest, DexNoOat) {
50 std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
51 Copy(GetDexSrc1(), dex_location);
52
Richard Uhlerd1472a22016-04-15 15:18:56 -070053 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -080054
Richard Uhler7225a8d2016-11-22 10:12:03 +000055 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +000056 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
Richard Uhler7225a8d2016-11-22 10:12:03 +000057 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +000058 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
Richard Uhler7225a8d2016-11-22 10:12:03 +000059 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +000060 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
Richard Uhler7225a8d2016-11-22 10:12:03 +000061 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +000062 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -080063
64 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +000065 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
66 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -070067 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -080068}
69
70// Case: We have no DEX file and no OAT file.
Richard Uhler9b994ea2015-06-24 08:44:19 -070071// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -080072TEST_F(OatFileAssistantTest, NoDexNoOat) {
73 std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
74
Richard Uhlerd1472a22016-04-15 15:18:56 -070075 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -080076
Andreas Gampe29d38e72016-03-23 15:31:51 +000077 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
78 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -070079 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
80
81 // Trying to make the oat file up to date should not fail or crash.
82 std::string error_msg;
Richard Uhlerd1472a22016-04-15 15:18:56 -070083 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -070084
85 // Trying to get the best oat file should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -080086 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
87 EXPECT_EQ(nullptr, oat_file.get());
88}
89
90// Case: We have a DEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -070091// Expect: The status is kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -080092TEST_F(OatFileAssistantTest, OatUpToDate) {
93 std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
94 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +000095 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -080096
Richard Uhlerd1472a22016-04-15 15:18:56 -070097 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -080098
Andreas Gampe29d38e72016-03-23 15:31:51 +000099 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
100 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
101 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
102 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
103 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
104 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000105 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000106 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
107
Richard Uhler66d874d2015-01-15 09:37:19 -0800108 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000109 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
Richard Uhler95abd042015-03-24 09:51:28 -0700110 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700111 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800112}
113
Richard Uhler9a37efc2016-08-05 16:32:55 -0700114// Case: We have a DEX file and ODEX file for a different dex location.
115// Expect: The status is kDex2OatNeeded.
116TEST_F(OatFileAssistantTest, OatForDifferentDex) {
117 // Generate an odex file for OatForDifferentDex_A.jar
118 std::string dex_location_a = GetScratchDir() + "/OatForDifferentDex_A.jar";
119 std::string odex_location = GetOdexDir() + "/OatForDifferentDex.odex";
120 Copy(GetDexSrc1(), dex_location_a);
121 GenerateOdexForTest(dex_location_a, odex_location, CompilerFilter::kSpeed);
122
123 // Try to use that odex file for OatForDifferentDex.jar
124 std::string dex_location = GetScratchDir() + "/OatForDifferentDex.jar";
125 Copy(GetDexSrc1(), dex_location);
126
127 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
128
Richard Uhler7225a8d2016-11-22 10:12:03 +0000129 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Richard Uhler9a37efc2016-08-05 16:32:55 -0700130 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
131
132 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000133 EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OdexFileStatus());
134 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9a37efc2016-08-05 16:32:55 -0700135}
136
Andreas Gampe29d38e72016-03-23 15:31:51 +0000137// Case: We have a DEX file and speed-profile OAT file for it.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700138// Expect: The status is kNoDexOptNeeded if the profile hasn't changed, but
139// kDex2Oat if the profile has changed.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000140TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
141 std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
142 Copy(GetDexSrc1(), dex_location);
143 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
144
Richard Uhlerd1472a22016-04-15 15:18:56 -0700145 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000146
147 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700148 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, false));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000149 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700150 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly, false));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000151 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700152 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, true));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000153 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700154 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly, true));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000155
156 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000157 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000158 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
159 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
160}
161
Richard Uhler66d874d2015-01-15 09:37:19 -0800162// Case: We have a MultiDEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700163// Expect: The status is kNoDexOptNeeded and we load all dex files.
Richard Uhler66d874d2015-01-15 09:37:19 -0800164TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
165 std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
166 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000167 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800168
Richard Uhlerd1472a22016-04-15 15:18:56 -0700169 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000170 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700171 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700172 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler95abd042015-03-24 09:51:28 -0700173
174 // Verify we can load both dex files.
Richard Uhlere5fed032015-03-18 08:21:11 -0700175 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
Richard Uhler66d874d2015-01-15 09:37:19 -0800176 ASSERT_TRUE(oat_file.get() != nullptr);
177 EXPECT_TRUE(oat_file->IsExecutable());
178 std::vector<std::unique_ptr<const DexFile>> dex_files;
Richard Uhlere5fed032015-03-18 08:21:11 -0700179 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
180 EXPECT_EQ(2u, dex_files.size());
181}
182
Richard Uhler67ff7d12015-05-14 13:21:13 -0700183// Case: We have a MultiDEX file where the secondary dex file is out of date.
184// Expect: The status is kDex2OatNeeded.
185TEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) {
186 std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar";
187
188 // Compile code for GetMultiDexSrc1.
189 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000190 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler67ff7d12015-05-14 13:21:13 -0700191
192 // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
193 // is out of date.
194 Copy(GetMultiDexSrc2(), dex_location);
195
Richard Uhlerd1472a22016-04-15 15:18:56 -0700196 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler7225a8d2016-11-22 10:12:03 +0000197 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700198 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700199 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler67ff7d12015-05-14 13:21:13 -0700200}
201
Richard Uhlere5fed032015-03-18 08:21:11 -0700202// Case: We have a MultiDEX file and up-to-date OAT file for it with relative
203// encoded dex locations.
Richard Uhler95abd042015-03-24 09:51:28 -0700204// Expect: The oat file status is kNoDexOptNeeded.
Richard Uhlere5fed032015-03-18 08:21:11 -0700205TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
206 std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700207 std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
Richard Uhlere5fed032015-03-18 08:21:11 -0700208
209 // Create the dex file
210 Copy(GetMultiDexSrc1(), dex_location);
211
212 // Create the oat file with relative encoded dex location.
213 std::vector<std::string> args;
214 args.push_back("--dex-file=" + dex_location);
215 args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
216 args.push_back("--oat-file=" + oat_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000217 args.push_back("--compiler-filter=speed");
Richard Uhlere5fed032015-03-18 08:21:11 -0700218
219 std::string error_msg;
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700220 ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
Richard Uhlere5fed032015-03-18 08:21:11 -0700221
222 // Verify we can load both dex files.
223 OatFileAssistant oat_file_assistant(dex_location.c_str(),
224 oat_location.c_str(),
Richard Uhlerd1472a22016-04-15 15:18:56 -0700225 kRuntimeISA, true);
Richard Uhlere5fed032015-03-18 08:21:11 -0700226 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
227 ASSERT_TRUE(oat_file.get() != nullptr);
228 EXPECT_TRUE(oat_file->IsExecutable());
229 std::vector<std::unique_ptr<const DexFile>> dex_files;
230 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
Richard Uhler66d874d2015-01-15 09:37:19 -0800231 EXPECT_EQ(2u, dex_files.size());
232}
233
Richard Uhler03bc6592016-11-22 09:42:04 +0000234// Case: We have a DEX file and an OAT file out of date with respect to the
235// dex checksum.
236TEST_F(OatFileAssistantTest, OatDexOutOfDate) {
237 std::string dex_location = GetScratchDir() + "/OatDexOutOfDate.jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800238
239 // We create a dex, generate an oat for it, then overwrite the dex with a
240 // different dex to make the oat out of date.
241 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000242 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800243 Copy(GetDexSrc2(), dex_location);
244
Richard Uhlerd1472a22016-04-15 15:18:56 -0700245 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler7225a8d2016-11-22 10:12:03 +0000246 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000247 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000248 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000249 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800250
251 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000252 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
253 EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
254 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
255}
256
257// Case: We have a DEX file and an OAT file out of date with respect to the
258// boot image.
259TEST_F(OatFileAssistantTest, OatImageOutOfDate) {
260 std::string dex_location = GetScratchDir() + "/OatImageOutOfDate.jar";
261
262 Copy(GetDexSrc1(), dex_location);
263 GenerateOatForTest(dex_location.c_str(),
264 CompilerFilter::kSpeed,
265 /*relocate*/true,
266 /*pic*/false,
Richard Uhler03bc6592016-11-22 09:42:04 +0000267 /*with_alternate_image*/true);
268
269 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler7225a8d2016-11-22 10:12:03 +0000270 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Richard Uhler03bc6592016-11-22 09:42:04 +0000271 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000272 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Richard Uhler03bc6592016-11-22 09:42:04 +0000273 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000274 EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
Richard Uhler03bc6592016-11-22 09:42:04 +0000275 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
276
277 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
278 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
279 EXPECT_EQ(OatFileAssistant::kOatBootImageOutOfDate, oat_file_assistant.OatFileStatus());
280 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
281}
282
283// Case: We have a DEX file and a verify-at-runtime OAT file out of date with
284// respect to the boot image.
285// It shouldn't matter that the OAT file is out of date, because it is
286// verify-at-runtime.
287TEST_F(OatFileAssistantTest, OatVerifyAtRuntimeImageOutOfDate) {
288 std::string dex_location = GetScratchDir() + "/OatVerifyAtRuntimeImageOutOfDate.jar";
289
290 Copy(GetDexSrc1(), dex_location);
291 GenerateOatForTest(dex_location.c_str(),
292 CompilerFilter::kVerifyAtRuntime,
293 /*relocate*/true,
294 /*pic*/false,
Richard Uhler03bc6592016-11-22 09:42:04 +0000295 /*with_alternate_image*/true);
296
297 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
298 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
299 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000300 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Richard Uhler03bc6592016-11-22 09:42:04 +0000301 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
302
303 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
304 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
305 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700306 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800307}
308
309// Case: We have a DEX file and an ODEX file, but no OAT file.
Richard Uhler66d874d2015-01-15 09:37:19 -0800310TEST_F(OatFileAssistantTest, DexOdexNoOat) {
311 std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700312 std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800313
314 // Create the dex and odex files
315 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000316 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800317
318 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700319 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800320
Andreas Gampe29d38e72016-03-23 15:31:51 +0000321 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
322 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
Richard Uhler5923b522016-12-08 09:48:01 +0000323 EXPECT_EQ(-OatFileAssistant::kDex2OatForRelocation,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000324 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800325
326 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000327 EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus());
328 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700329 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler5f946da2015-07-17 12:28:32 -0700330
331 // We should still be able to get the non-executable odex file to run from.
332 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
333 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhler66d874d2015-01-15 09:37:19 -0800334}
335
Richard Uhler5923b522016-12-08 09:48:01 +0000336// Case: We have a stripped DEX file and a PIC ODEX file, but no OAT file.
Richard Uhler66d874d2015-01-15 09:37:19 -0800337TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
338 std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700339 std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800340
341 // Create the dex and odex files
342 Copy(GetDexSrc1(), dex_location);
Richard Uhler5923b522016-12-08 09:48:01 +0000343 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800344
345 // Strip the dex file
346 Copy(GetStrippedDexSrc1(), dex_location);
347
348 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700349 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800350
Richard Uhler5923b522016-12-08 09:48:01 +0000351 EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000352 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800353
354 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler5923b522016-12-08 09:48:01 +0000355 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
Richard Uhler03bc6592016-11-22 09:42:04 +0000356 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700357 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800358
Richard Uhler66d874d2015-01-15 09:37:19 -0800359 // Verify we can load the dex files from it.
360 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
361 ASSERT_TRUE(oat_file.get() != nullptr);
362 EXPECT_TRUE(oat_file->IsExecutable());
363 std::vector<std::unique_ptr<const DexFile>> dex_files;
364 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
365 EXPECT_EQ(1u, dex_files.size());
366}
367
Richard Uhler5923b522016-12-08 09:48:01 +0000368// 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 -0800369TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
370 std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700371 std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800372
373 // Create the oat file from a different dex file so it looks out of date.
374 Copy(GetDexSrc2(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000375 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800376
377 // Create the odex file
378 Copy(GetDexSrc1(), dex_location);
Richard Uhler5923b522016-12-08 09:48:01 +0000379 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800380
381 // Strip the dex file.
382 Copy(GetStrippedDexSrc1(), dex_location);
383
384 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700385 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800386
Andreas Gampe29d38e72016-03-23 15:31:51 +0000387 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
388 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000389 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
390 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
391 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped.
392 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800393
394 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler5923b522016-12-08 09:48:01 +0000395 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
396 EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700397 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800398
399 // Verify we can load the dex files from it.
400 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
401 ASSERT_TRUE(oat_file.get() != nullptr);
402 EXPECT_TRUE(oat_file->IsExecutable());
403 std::vector<std::unique_ptr<const DexFile>> dex_files;
404 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
405 EXPECT_EQ(1u, dex_files.size());
406}
407
Richard Uhler9b994ea2015-06-24 08:44:19 -0700408// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
409// OAT file. Expect: The status is kNoDexOptNeeded.
410TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
411 std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
412
413 Copy(GetStrippedDexSrc1(), dex_location);
414
415 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700416 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler9b994ea2015-06-24 08:44:19 -0700417
Andreas Gampe29d38e72016-03-23 15:31:51 +0000418 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
419 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
420 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
421 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
422 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
423 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700424
425 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000426 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
427 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700428 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
429
430 // Make the oat file up to date. This should have no effect.
431 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700432 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700433 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700434 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhler9b994ea2015-06-24 08:44:19 -0700435
Andreas Gampe29d38e72016-03-23 15:31:51 +0000436 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
437 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700438
439 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000440 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
441 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700442 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
443}
444
Richard Uhler66d874d2015-01-15 09:37:19 -0800445// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
446// OAT files both have patch delta of 0.
Richard Uhler5923b522016-12-08 09:48:01 +0000447// Expect: It shouldn't crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800448TEST_F(OatFileAssistantTest, OdexOatOverlap) {
449 std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700450 std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
451 std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
Richard Uhler66d874d2015-01-15 09:37:19 -0800452
453 // Create the dex and odex files
454 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000455 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800456
457 // Create the oat file by copying the odex so they are located in the same
458 // place in memory.
459 Copy(odex_location, oat_location);
460
461 // Verify things don't go bad.
462 OatFileAssistant oat_file_assistant(dex_location.c_str(),
Richard Uhlerd1472a22016-04-15 15:18:56 -0700463 oat_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800464
Richard Uhler5923b522016-12-08 09:48:01 +0000465 // kDex2OatForRelocation is expected rather than -kDex2OatForRelocation
Richard Uhler7225a8d2016-11-22 10:12:03 +0000466 // based on the assumption that the oat location is more up-to-date than the odex
Richard Uhler70a84262016-11-08 16:51:51 +0000467 // location, even if they both need relocation.
Richard Uhler5923b522016-12-08 09:48:01 +0000468 EXPECT_EQ(OatFileAssistant::kDex2OatForRelocation,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000469 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800470
471 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000472 EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus());
473 EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700474 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800475
476 // Things aren't relocated, so it should fall back to interpreted.
477 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
478 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhlerf16d5722015-05-11 09:32:47 -0700479
Richard Uhler66d874d2015-01-15 09:37:19 -0800480 EXPECT_FALSE(oat_file->IsExecutable());
481 std::vector<std::unique_ptr<const DexFile>> dex_files;
482 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
483 EXPECT_EQ(1u, dex_files.size());
484}
485
486// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
Richard Uhler95abd042015-03-24 09:51:28 -0700487// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
Richard Uhler66d874d2015-01-15 09:37:19 -0800488TEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
489 std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700490 std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800491
492 // Create the dex and odex files
493 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000494 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800495
496 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700497 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800498
Andreas Gampe29d38e72016-03-23 15:31:51 +0000499 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
500 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000501 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000502 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800503
504 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000505 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
Richard Uhler03bc6592016-11-22 09:42:04 +0000506 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700507 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800508}
509
Andreas Gampe29d38e72016-03-23 15:31:51 +0000510// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
511// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
512TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
513 std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
514 std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
David Brazdilce4b0ba2016-01-28 15:05:49 +0000515
516 // Create the dex and odex files
517 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000518 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000519
520 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700521 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000522
Andreas Gampe29d38e72016-03-23 15:31:51 +0000523 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
524 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000525 EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000526 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
David Brazdilce4b0ba2016-01-28 15:05:49 +0000527
528 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000529 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
Richard Uhler03bc6592016-11-22 09:42:04 +0000530 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
David Brazdilce4b0ba2016-01-28 15:05:49 +0000531 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
532}
533
Richard Uhler66d874d2015-01-15 09:37:19 -0800534// Case: We have a DEX file and up-to-date OAT file for it.
535// Expect: We should load an executable dex file.
536TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
537 std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
538
539 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000540 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800541
542 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700543 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000544
545 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
546 ASSERT_TRUE(oat_file.get() != nullptr);
547 EXPECT_TRUE(oat_file->IsExecutable());
548 std::vector<std::unique_ptr<const DexFile>> dex_files;
549 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
550 EXPECT_EQ(1u, dex_files.size());
551}
552
553// Case: We have a DEX file and up-to-date interpret-only OAT file for it.
554// Expect: We should still load the oat file as executable.
555TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
556 std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
557
558 Copy(GetDexSrc1(), dex_location);
559 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kInterpretOnly);
560
561 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700562 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800563
564 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
565 ASSERT_TRUE(oat_file.get() != nullptr);
566 EXPECT_TRUE(oat_file->IsExecutable());
567 std::vector<std::unique_ptr<const DexFile>> dex_files;
568 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
569 EXPECT_EQ(1u, dex_files.size());
570}
571
572// Case: We have a DEX file and up-to-date OAT file for it.
573// Expect: Loading non-executable should load the oat non-executable.
574TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
575 std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
576
577 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000578 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800579
580 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700581 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800582
583 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
584 ASSERT_TRUE(oat_file.get() != nullptr);
585 EXPECT_FALSE(oat_file->IsExecutable());
586 std::vector<std::unique_ptr<const DexFile>> dex_files;
587 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
588 EXPECT_EQ(1u, dex_files.size());
589}
590
591// Case: We have a DEX file.
592// Expect: We should load an executable dex file from an alternative oat
593// location.
594TEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
595 std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
596 std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
597
598 Copy(GetDexSrc1(), dex_location);
599
600 OatFileAssistant oat_file_assistant(
Richard Uhlerd1472a22016-04-15 15:18:56 -0700601 dex_location.c_str(), oat_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800602 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700603 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700604 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700605 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800606
607 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
608 ASSERT_TRUE(oat_file.get() != nullptr);
609 EXPECT_TRUE(oat_file->IsExecutable());
610 std::vector<std::unique_ptr<const DexFile>> dex_files;
611 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
612 EXPECT_EQ(1u, dex_files.size());
613
614 EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
615
616 // Verify it didn't create an oat in the default location.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700617 OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler03bc6592016-11-22 09:42:04 +0000618 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OatFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800619}
620
Richard Uhler8327cf72015-10-13 16:34:59 -0700621// Case: We have a DEX file but can't write the oat file.
622// Expect: We should fail to make the oat file up to date.
623TEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) {
624 std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar";
625
626 // Make the oat location unwritable by inserting some non-existent
627 // intermediate directories.
628 std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat";
629
630 Copy(GetDexSrc1(), dex_location);
631
632 OatFileAssistant oat_file_assistant(
Richard Uhlerd1472a22016-04-15 15:18:56 -0700633 dex_location.c_str(), oat_location.c_str(), kRuntimeISA, true);
Richard Uhler8327cf72015-10-13 16:34:59 -0700634 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700635 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700636 ASSERT_EQ(OatFileAssistant::kUpdateNotAttempted,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700637 oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhler8327cf72015-10-13 16:34:59 -0700638
639 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
640 ASSERT_TRUE(oat_file.get() == nullptr);
641}
642
643// Case: We don't have a DEX file and can't write the oat file.
644// Expect: We should fail to generate the oat file without crashing.
645TEST_F(OatFileAssistantTest, GenNoDex) {
646 std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
647 std::string oat_location = GetScratchDir() + "/GenNoDex.oat";
648
649 OatFileAssistant oat_file_assistant(
Richard Uhlerd1472a22016-04-15 15:18:56 -0700650 dex_location.c_str(), oat_location.c_str(), kRuntimeISA, true);
Richard Uhler8327cf72015-10-13 16:34:59 -0700651 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700652 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700653 EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
Richard Uhlerf4b34872016-04-13 11:03:46 -0700654 oat_file_assistant.GenerateOatFile(&error_msg));
Richard Uhler8327cf72015-10-13 16:34:59 -0700655}
656
Richard Uhler66d874d2015-01-15 09:37:19 -0800657// Turn an absolute path into a path relative to the current working
658// directory.
Andreas Gampeca620d72016-11-08 08:09:33 -0800659static std::string MakePathRelative(const std::string& target) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800660 char buf[MAXPATHLEN];
661 std::string cwd = getcwd(buf, MAXPATHLEN);
662
663 // Split the target and cwd paths into components.
664 std::vector<std::string> target_path;
665 std::vector<std::string> cwd_path;
666 Split(target, '/', &target_path);
667 Split(cwd, '/', &cwd_path);
668
669 // Reverse the path components, so we can use pop_back().
670 std::reverse(target_path.begin(), target_path.end());
671 std::reverse(cwd_path.begin(), cwd_path.end());
672
673 // Drop the common prefix of the paths. Because we reversed the path
674 // components, this becomes the common suffix of target_path and cwd_path.
675 while (!target_path.empty() && !cwd_path.empty()
676 && target_path.back() == cwd_path.back()) {
677 target_path.pop_back();
678 cwd_path.pop_back();
679 }
680
681 // For each element of the remaining cwd_path, add '..' to the beginning
682 // of the target path. Because we reversed the path components, we add to
683 // the end of target_path.
684 for (unsigned int i = 0; i < cwd_path.size(); i++) {
685 target_path.push_back("..");
686 }
687
688 // Reverse again to get the right path order, and join to get the result.
689 std::reverse(target_path.begin(), target_path.end());
Andreas Gampe9186ced2016-12-12 14:28:21 -0800690 return android::base::Join(target_path, '/');
Richard Uhler66d874d2015-01-15 09:37:19 -0800691}
692
693// Case: Non-absolute path to Dex location.
694// Expect: Not sure, but it shouldn't crash.
695TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
696 std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
697 Copy(GetDexSrc1(), abs_dex_location);
698
699 std::string dex_location = MakePathRelative(abs_dex_location);
Richard Uhlerd1472a22016-04-15 15:18:56 -0700700 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800701
702 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler7225a8d2016-11-22 10:12:03 +0000703 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000704 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler03bc6592016-11-22 09:42:04 +0000705 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
706 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800707}
708
709// Case: Very short, non-existent Dex location.
Richard Uhler9b994ea2015-06-24 08:44:19 -0700710// Expect: kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800711TEST_F(OatFileAssistantTest, ShortDexLocation) {
712 std::string dex_location = "/xx";
713
Richard Uhlerd1472a22016-04-15 15:18:56 -0700714 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800715
716 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000717 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
718 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler03bc6592016-11-22 09:42:04 +0000719 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
720 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700721 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800722
Richard Uhler9b994ea2015-06-24 08:44:19 -0700723 // Trying to make it up to date should have no effect.
Richard Uhler66d874d2015-01-15 09:37:19 -0800724 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700725 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700726 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700727 oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700728 EXPECT_TRUE(error_msg.empty());
Richard Uhler66d874d2015-01-15 09:37:19 -0800729}
730
731// Case: Non-standard extension for dex file.
Richard Uhler95abd042015-03-24 09:51:28 -0700732// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800733TEST_F(OatFileAssistantTest, LongDexExtension) {
734 std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
735 Copy(GetDexSrc1(), dex_location);
736
Richard Uhlerd1472a22016-04-15 15:18:56 -0700737 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800738
Richard Uhler7225a8d2016-11-22 10:12:03 +0000739 EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000740 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800741
742 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Richard Uhler03bc6592016-11-22 09:42:04 +0000743 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
744 EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800745}
746
747// A task to generate a dex location. Used by the RaceToGenerate test.
748class RaceGenerateTask : public Task {
749 public:
750 explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
Jeff Haof0192c82016-03-28 20:39:50 -0700751 : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr)
Richard Uhler66d874d2015-01-15 09:37:19 -0800752 {}
753
Roland Levillain4b8f1ec2015-08-26 18:34:03 +0100754 void Run(Thread* self ATTRIBUTE_UNUSED) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800755 // Load the dex files, and save a pointer to the loaded oat file, so that
756 // we can verify only one oat file was loaded for the dex location.
Richard Uhler66d874d2015-01-15 09:37:19 -0800757 std::vector<std::unique_ptr<const DexFile>> dex_files;
758 std::vector<std::string> error_msgs;
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700759 const OatFile* oat_file = nullptr;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700760 dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
761 dex_location_.c_str(),
762 oat_location_.c_str(),
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800763 /*class_loader*/nullptr,
764 /*dex_elements*/nullptr,
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700765 &oat_file,
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700766 &error_msgs);
Andreas Gampe9186ced2016-12-12 14:28:21 -0800767 CHECK(!dex_files.empty()) << android::base::Join(error_msgs, '\n');
Richard Uhler07b3c232015-03-31 15:57:54 -0700768 CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
769 loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700770 CHECK_EQ(loaded_oat_file_, oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -0800771 }
772
773 const OatFile* GetLoadedOatFile() const {
774 return loaded_oat_file_;
775 }
776
777 private:
778 std::string dex_location_;
779 std::string oat_location_;
780 const OatFile* loaded_oat_file_;
781};
782
783// Test the case where multiple processes race to generate an oat file.
784// This simulates multiple processes using multiple threads.
785//
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700786// We want unique Oat files to be loaded even when there is a race to load.
787// TODO: The test case no longer tests locking the way it was intended since we now get multiple
788// copies of the same Oat files mapped at different locations.
Richard Uhler66d874d2015-01-15 09:37:19 -0800789TEST_F(OatFileAssistantTest, RaceToGenerate) {
790 std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700791 std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
Richard Uhler66d874d2015-01-15 09:37:19 -0800792
793 // We use the lib core dex file, because it's large, and hopefully should
794 // take a while to generate.
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000795 Copy(GetLibCoreDexFileNames()[0], dex_location);
Richard Uhler66d874d2015-01-15 09:37:19 -0800796
797 const int kNumThreads = 32;
798 Thread* self = Thread::Current();
799 ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
800 std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
801 for (int i = 0; i < kNumThreads; i++) {
802 std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
803 thread_pool.AddTask(self, task.get());
804 tasks.push_back(std::move(task));
805 }
806 thread_pool.StartWorkers(self);
807 thread_pool.Wait(self, true, false);
808
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700809 // Verify every task got a unique oat file.
810 std::set<const OatFile*> oat_files;
Richard Uhler66d874d2015-01-15 09:37:19 -0800811 for (auto& task : tasks) {
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700812 const OatFile* oat_file = task->GetLoadedOatFile();
813 EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
814 oat_files.insert(oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -0800815 }
816}
817
818// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
819// disabled.
820// Expect: We should load the odex file non-executable.
821TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
822 std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700823 std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800824
825 // Create the dex and odex files
826 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000827 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800828
829 // Load the oat using an executable oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700830 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800831
832 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
833 ASSERT_TRUE(oat_file.get() != nullptr);
834 EXPECT_FALSE(oat_file->IsExecutable());
835 std::vector<std::unique_ptr<const DexFile>> dex_files;
836 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
837 EXPECT_EQ(1u, dex_files.size());
838}
839
840// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
841// disabled.
842// Expect: We should load the odex file non-executable.
843TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
844 std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700845 std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800846
847 // Create the dex and odex files
848 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000849 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800850
851 // Load the oat using an executable oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700852 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800853
854 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
855 ASSERT_TRUE(oat_file.get() != nullptr);
856 EXPECT_FALSE(oat_file->IsExecutable());
857 std::vector<std::unique_ptr<const DexFile>> dex_files;
858 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
859 EXPECT_EQ(2u, dex_files.size());
860}
861
Richard Uhlerf4b34872016-04-13 11:03:46 -0700862TEST_F(OatFileAssistantTest, RuntimeCompilerFilterOptionUsed) {
863 std::string dex_location = GetScratchDir() + "/RuntimeCompilerFilterOptionUsed.jar";
864 Copy(GetDexSrc1(), dex_location);
865
Richard Uhlerd1472a22016-04-15 15:18:56 -0700866 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhlerf4b34872016-04-13 11:03:46 -0700867
868 std::string error_msg;
869 Runtime::Current()->AddCompilerOption("--compiler-filter=interpret-only");
870 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700871 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700872 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
873 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
Richard Uhler7225a8d2016-11-22 10:12:03 +0000874 EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
Richard Uhlerf4b34872016-04-13 11:03:46 -0700875 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
876
877 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
878 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700879 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700880 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
881 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
882 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
883 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
884
885 Runtime::Current()->AddCompilerOption("--compiler-filter=bogus");
886 EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700887 oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhlerf4b34872016-04-13 11:03:46 -0700888}
889
Richard Uhlerb81881d2016-04-19 13:08:04 -0700890TEST(OatFileAssistantUtilsTest, DexLocationToOdexFilename) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800891 std::string error_msg;
892 std::string odex_file;
893
Richard Uhlerb81881d2016-04-19 13:08:04 -0700894 EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700895 "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -0700896 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -0800897
Richard Uhlerb81881d2016-04-19 13:08:04 -0700898 EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700899 "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -0700900 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -0800901
Richard Uhlerb81881d2016-04-19 13:08:04 -0700902 EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700903 "nopath.jar", kArm, &odex_file, &error_msg));
Richard Uhlerb81881d2016-04-19 13:08:04 -0700904 EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700905 "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
Richard Uhler66d874d2015-01-15 09:37:19 -0800906}
907
Richard Uhler23cedd22015-04-08 13:17:29 -0700908// Verify the dexopt status values from dalvik.system.DexFile
909// match the OatFileAssistant::DexOptStatus values.
910TEST_F(OatFileAssistantTest, DexOptStatusValues) {
Richard Uhler7225a8d2016-11-22 10:12:03 +0000911 std::pair<OatFileAssistant::DexOptNeeded, const char*> mapping[] = {
912 {OatFileAssistant::kNoDexOptNeeded, "NO_DEXOPT_NEEDED"},
913 {OatFileAssistant::kDex2OatFromScratch, "DEX2OAT_FROM_SCRATCH"},
914 {OatFileAssistant::kDex2OatForBootImage, "DEX2OAT_FOR_BOOT_IMAGE"},
915 {OatFileAssistant::kDex2OatForFilter, "DEX2OAT_FOR_FILTER"},
916 {OatFileAssistant::kDex2OatForRelocation, "DEX2OAT_FOR_RELOCATION"},
Richard Uhler7225a8d2016-11-22 10:12:03 +0000917 };
918
Richard Uhler23cedd22015-04-08 13:17:29 -0700919 ScopedObjectAccess soa(Thread::Current());
920 StackHandleScope<1> hs(soa.Self());
921 ClassLinker* linker = Runtime::Current()->GetClassLinker();
922 Handle<mirror::Class> dexfile(
923 hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
924 ASSERT_FALSE(dexfile.Get() == nullptr);
925 linker->EnsureInitialized(soa.Self(), dexfile, true, true);
926
Richard Uhler7225a8d2016-11-22 10:12:03 +0000927 for (std::pair<OatFileAssistant::DexOptNeeded, const char*> field : mapping) {
928 ArtField* art_field = mirror::Class::FindStaticField(
Vladimir Marko19a4d372016-12-08 14:41:46 +0000929 soa.Self(), dexfile.Get(), field.second, "I");
Richard Uhler7225a8d2016-11-22 10:12:03 +0000930 ASSERT_FALSE(art_field == nullptr);
931 EXPECT_EQ(art_field->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
932 EXPECT_EQ(field.first, art_field->GetInt(dexfile.Get()));
933 }
Richard Uhler23cedd22015-04-08 13:17:29 -0700934}
Richard Uhler66d874d2015-01-15 09:37:19 -0800935
936// TODO: More Tests:
937// * Test class linker falls back to unquickened dex for DexNoOat
938// * Test class linker falls back to unquickened dex for MultiDexNoOat
Richard Uhler66d874d2015-01-15 09:37:19 -0800939// * Test using secondary isa
Richard Uhler66d874d2015-01-15 09:37:19 -0800940// * Test for status of oat while oat is being generated (how?)
941// * Test case where 32 and 64 bit boot class paths differ,
942// and we ask IsInBootClassPath for a class in exactly one of the 32 or
943// 64 bit boot class paths.
944// * Test unexpected scenarios (?):
945// - Dex is stripped, don't have odex.
946// - Oat file corrupted after status check, before reload unexecutable
947// because it's unrelocated and no dex2oat
Calin Juravleb077e152016-02-18 18:47:37 +0000948// * Test unrelocated specific target compilation type can be relocated to
949// make it up to date.
Richard Uhler66d874d2015-01-15 09:37:19 -0800950} // namespace art