blob: 78ba6e75102e42896f3b08d6f3f075240e5e4c1d [file] [log] [blame]
Elliott Hugheseb02a122012-06-12 11:35:40 -07001/*
2 * Copyright (C) 2012 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
Ian Rogerse63db272014-07-15 15:36:11 -070017#include "common_runtime_test.h"
18
David Srbecky3e52aa42015-04-12 07:45:18 +010019#include <cstdio>
Ian Rogerse63db272014-07-15 15:36:11 -070020#include <dirent.h>
21#include <dlfcn.h>
22#include <fcntl.h>
23#include <ScopedLocalRef.h>
Andreas Gampe369810a2015-01-14 19:53:31 -080024#include <stdlib.h>
Ian Rogerse63db272014-07-15 15:36:11 -070025
26#include "../../external/icu/icu4c/source/common/unicode/uvernum.h"
Andreas Gampe46ee31b2016-12-14 10:11:49 -080027#include "android-base/stringprintf.h"
28
Mathieu Chartiere401d142015-04-22 13:56:20 -070029#include "art_field-inl.h"
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -070030#include "base/macros.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080031#include "base/logging.h"
Ian Rogerse63db272014-07-15 15:36:11 -070032#include "base/stl_util.h"
Ian Rogerse63db272014-07-15 15:36:11 -070033#include "base/unix_file/fd_file.h"
34#include "class_linker.h"
35#include "compiler_callbacks.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070036#include "dex_file-inl.h"
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -070037#include "gc_root-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070038#include "gc/heap.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070039#include "gtest/gtest.h"
Andreas Gampe81c6f8d2015-03-25 17:19:53 -070040#include "handle_scope-inl.h"
Andreas Gampe9b5cba42015-03-11 09:53:50 -070041#include "interpreter/unstarted_runtime.h"
Ian Rogerse63db272014-07-15 15:36:11 -070042#include "jni_internal.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070043#include "mirror/class-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070044#include "mirror/class_loader.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080045#include "mem_map.h"
Mathieu Chartiere58991b2015-10-13 07:59:34 -070046#include "native/dalvik_system_DexFile.h"
Ian Rogerse63db272014-07-15 15:36:11 -070047#include "noop_compiler_callbacks.h"
48#include "os.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070049#include "primitive.h"
Ian Rogerse63db272014-07-15 15:36:11 -070050#include "runtime-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070051#include "scoped_thread_state_change-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070052#include "thread.h"
53#include "well_known_classes.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070054
55int main(int argc, char **argv) {
Andreas Gampe369810a2015-01-14 19:53:31 -080056 // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
57 // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
58 // everything else. In case you want to see all messages, comment out the line.
Nicolas Geoffraya7a47592015-11-24 09:17:30 +000059 setenv("ANDROID_LOG_TAGS", "*:e", 1);
Andreas Gampe369810a2015-01-14 19:53:31 -080060
David Sehrf57589f2016-10-17 10:09:33 -070061 art::InitLogging(argv, art::Runtime::Aborter);
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070062 LOG(INFO) << "Running main() from common_runtime_test.cc...";
Elliott Hugheseb02a122012-06-12 11:35:40 -070063 testing::InitGoogleTest(&argc, argv);
64 return RUN_ALL_TESTS();
65}
Ian Rogerse63db272014-07-15 15:36:11 -070066
67namespace art {
68
Andreas Gampe46ee31b2016-12-14 10:11:49 -080069using android::base::StringPrintf;
70
Ian Rogerse63db272014-07-15 15:36:11 -070071ScratchFile::ScratchFile() {
72 // ANDROID_DATA needs to be set
73 CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
74 "Are you subclassing RuntimeTest?";
75 filename_ = getenv("ANDROID_DATA");
76 filename_ += "/TmpFile-XXXXXX";
77 int fd = mkstemp(&filename_[0]);
Andreas Gampe29d38e72016-03-23 15:31:51 +000078 CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
Andreas Gampe4303ba92014-11-06 01:00:46 -080079 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -070080}
81
Mathieu Chartier866d8742016-09-21 15:24:18 -070082ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
83 : ScratchFile(other.GetFilename() + suffix) {}
84
85ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
Ian Rogerse63db272014-07-15 15:36:11 -070086 int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
87 CHECK_NE(-1, fd);
Andreas Gampe4303ba92014-11-06 01:00:46 -080088 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -070089}
90
91ScratchFile::ScratchFile(File* file) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070092 CHECK(file != nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -070093 filename_ = file->GetPath();
94 file_.reset(file);
95}
96
Mathieu Chartier866d8742016-09-21 15:24:18 -070097ScratchFile::ScratchFile(ScratchFile&& other) {
98 *this = std::move(other);
99}
100
101ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
102 if (GetFile() != other.GetFile()) {
103 std::swap(filename_, other.filename_);
104 std::swap(file_, other.file_);
105 }
106 return *this;
107}
108
Ian Rogerse63db272014-07-15 15:36:11 -0700109ScratchFile::~ScratchFile() {
110 Unlink();
111}
112
113int ScratchFile::GetFd() const {
114 return file_->Fd();
115}
116
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800117void ScratchFile::Close() {
Andreas Gampe4303ba92014-11-06 01:00:46 -0800118 if (file_.get() != nullptr) {
119 if (file_->FlushCloseOrErase() != 0) {
120 PLOG(WARNING) << "Error closing scratch file.";
121 }
122 }
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800123}
124
125void ScratchFile::Unlink() {
126 if (!OS::FileExists(filename_.c_str())) {
127 return;
128 }
129 Close();
Ian Rogerse63db272014-07-15 15:36:11 -0700130 int unlink_result = unlink(filename_.c_str());
131 CHECK_EQ(0, unlink_result);
132}
133
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700134static bool unstarted_initialized_ = false;
135
Andreas Gampe48864112017-01-19 17:23:17 -0800136CommonRuntimeTestImpl::CommonRuntimeTestImpl()
137 : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
138}
Mathieu Chartier91c91162016-01-15 09:48:15 -0800139
140CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800141 // Ensure the dex files are cleaned up before the runtime.
142 loaded_dex_files_.clear();
143 runtime_.reset();
144}
Ian Rogerse63db272014-07-15 15:36:11 -0700145
Mathieu Chartier91c91162016-01-15 09:48:15 -0800146void CommonRuntimeTestImpl::SetUpAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700147 if (IsHost()) {
148 // $ANDROID_ROOT is set on the device, but not necessarily on the host.
149 // But it needs to be set so that icu4c can find its locale data.
150 const char* android_root_from_env = getenv("ANDROID_ROOT");
151 if (android_root_from_env == nullptr) {
152 // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
153 const char* android_host_out = getenv("ANDROID_HOST_OUT");
154 if (android_host_out != nullptr) {
155 setenv("ANDROID_ROOT", android_host_out, 1);
156 } else {
157 // Build it from ANDROID_BUILD_TOP or cwd
158 std::string root;
159 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
160 if (android_build_top != nullptr) {
161 root += android_build_top;
162 } else {
163 // Not set by build server, so default to current directory
164 char* cwd = getcwd(nullptr, 0);
165 setenv("ANDROID_BUILD_TOP", cwd, 1);
166 root += cwd;
167 free(cwd);
168 }
169#if defined(__linux__)
170 root += "/out/host/linux-x86";
171#elif defined(__APPLE__)
172 root += "/out/host/darwin-x86";
173#else
174#error unsupported OS
175#endif
176 setenv("ANDROID_ROOT", root.c_str(), 1);
177 }
178 }
179 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
180
181 // Not set by build server, so default
182 if (getenv("ANDROID_HOST_OUT") == nullptr) {
183 setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
184 }
185 }
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700186}
Ian Rogerse63db272014-07-15 15:36:11 -0700187
Mathieu Chartier91c91162016-01-15 09:48:15 -0800188void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
Ian Rogerse63db272014-07-15 15:36:11 -0700189 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
Andreas Gampe5a79fde2014-08-06 13:12:26 -0700190 if (IsHost()) {
191 const char* tmpdir = getenv("TMPDIR");
192 if (tmpdir != nullptr && tmpdir[0] != 0) {
193 android_data = tmpdir;
194 } else {
195 android_data = "/tmp";
196 }
197 } else {
198 android_data = "/data/dalvik-cache";
199 }
200 android_data += "/art-data-XXXXXX";
Ian Rogerse63db272014-07-15 15:36:11 -0700201 if (mkdtemp(&android_data[0]) == nullptr) {
202 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
203 }
204 setenv("ANDROID_DATA", android_data.c_str(), 1);
205}
206
Mathieu Chartier91c91162016-01-15 09:48:15 -0800207void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
208 bool fail_on_error) {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700209 if (fail_on_error) {
210 ASSERT_EQ(rmdir(android_data.c_str()), 0);
211 } else {
212 rmdir(android_data.c_str());
213 }
214}
215
David Srbecky3e52aa42015-04-12 07:45:18 +0100216// Helper - find directory with the following format:
217// ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
218static std::string GetAndroidToolsDir(const std::string& subdir1,
219 const std::string& subdir2,
220 const std::string& subdir3) {
221 std::string root;
222 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
223 if (android_build_top != nullptr) {
224 root = android_build_top;
225 } else {
226 // Not set by build server, so default to current directory
227 char* cwd = getcwd(nullptr, 0);
228 setenv("ANDROID_BUILD_TOP", cwd, 1);
229 root = cwd;
230 free(cwd);
231 }
232
233 std::string toolsdir = root + "/" + subdir1;
234 std::string founddir;
235 DIR* dir;
236 if ((dir = opendir(toolsdir.c_str())) != nullptr) {
237 float maxversion = 0;
238 struct dirent* entry;
239 while ((entry = readdir(dir)) != nullptr) {
240 std::string format = subdir2 + "-%f";
241 float version;
242 if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
243 if (version > maxversion) {
244 maxversion = version;
245 founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
246 }
247 }
248 }
249 closedir(dir);
250 }
251
252 if (founddir.empty()) {
Roland Levillain91d65e02016-01-19 15:59:16 +0000253 ADD_FAILURE() << "Cannot find Android tools directory.";
David Srbecky3e52aa42015-04-12 07:45:18 +0100254 }
255 return founddir;
256}
257
Mathieu Chartier91c91162016-01-15 09:48:15 -0800258std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
David Srbecky3e52aa42015-04-12 07:45:18 +0100259 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
260 "x86_64-linux-glibc2.15",
261 "x86_64-linux");
262}
263
Mathieu Chartier91c91162016-01-15 09:48:15 -0800264std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
David Srbecky3e52aa42015-04-12 07:45:18 +0100265 switch (isa) {
266 case kArm:
267 case kThumb2:
268 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
269 "arm-linux-androideabi",
270 "arm-linux-androideabi");
271 case kArm64:
272 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
273 "aarch64-linux-android",
274 "aarch64-linux-android");
275 case kX86:
276 case kX86_64:
277 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
278 "x86_64-linux-android",
279 "x86_64-linux-android");
280 case kMips:
281 case kMips64:
282 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
283 "mips64el-linux-android",
284 "mips64el-linux-android");
285 case kNone:
286 break;
287 }
288 ADD_FAILURE() << "Invalid isa " << isa;
289 return "";
290}
291
Mathieu Chartier91c91162016-01-15 09:48:15 -0800292std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800293 return GetCoreFileLocation("art");
294}
295
Mathieu Chartier91c91162016-01-15 09:48:15 -0800296std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800297 return GetCoreFileLocation("oat");
298}
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700299
Mathieu Chartier91c91162016-01-15 09:48:15 -0800300std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
301 const char* location) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800302 std::vector<std::unique_ptr<const DexFile>> dex_files;
Ian Rogerse63db272014-07-15 15:36:11 -0700303 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800304 MemMap::Init();
Aart Bik37d6a3b2016-06-21 18:30:10 -0700305 static constexpr bool kVerifyChecksum = true;
306 if (!DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files)) {
Ian Rogerse63db272014-07-15 15:36:11 -0700307 LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800308 UNREACHABLE();
Ian Rogerse63db272014-07-15 15:36:11 -0700309 } else {
310 CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800311 return std::move(dex_files[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700312 }
313}
314
Mathieu Chartier91c91162016-01-15 09:48:15 -0800315void CommonRuntimeTestImpl::SetUp() {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700316 SetUpAndroidRoot();
317 SetUpAndroidData(android_data_);
Ian Rogerse63db272014-07-15 15:36:11 -0700318 dalvik_cache_.append(android_data_.c_str());
319 dalvik_cache_.append("/dalvik-cache");
320 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
321 ASSERT_EQ(mkdir_result, 0);
322
Ian Rogerse63db272014-07-15 15:36:11 -0700323 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
324 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
325
Ian Rogerse63db272014-07-15 15:36:11 -0700326
327 RuntimeOptions options;
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000328 std::string boot_class_path_string = "-Xbootclasspath";
329 for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
330 boot_class_path_string += ":";
331 boot_class_path_string += core_dex_file_name;
332 }
333
Richard Uhlerc2752592015-01-02 13:28:22 -0800334 options.push_back(std::make_pair(boot_class_path_string, nullptr));
Ian Rogerse63db272014-07-15 15:36:11 -0700335 options.push_back(std::make_pair("-Xcheck:jni", nullptr));
Richard Uhlerc2752592015-01-02 13:28:22 -0800336 options.push_back(std::make_pair(min_heap_string, nullptr));
337 options.push_back(std::make_pair(max_heap_string, nullptr));
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700338
339 callbacks_.reset(new NoopCompilerCallbacks());
340
Ian Rogerse63db272014-07-15 15:36:11 -0700341 SetUpRuntimeOptions(&options);
Igor Murashkinaaebaa02015-01-26 10:55:53 -0800342
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700343 // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
344 if (callbacks_.get() != nullptr) {
345 options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
346 }
347
Richard Uhler66d874d2015-01-15 09:37:19 -0800348 PreRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700349 if (!Runtime::Create(options, false)) {
350 LOG(FATAL) << "Failed to create runtime";
351 return;
352 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800353 PostRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700354 runtime_.reset(Runtime::Current());
355 class_linker_ = runtime_->GetClassLinker();
356 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700357
Andreas Gampea00f0122015-12-16 16:54:35 -0800358 // Runtime::Create acquired the mutator_lock_ that is normally given away when we
359 // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
360 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
361
362 // Get the boot class path from the runtime so it can be used in tests.
363 boot_class_path_ = class_linker_->GetBootClassPath();
364 ASSERT_FALSE(boot_class_path_.empty());
365 java_lang_dex_file_ = boot_class_path_[0];
366
367 FinalizeSetup();
368}
369
Mathieu Chartier91c91162016-01-15 09:48:15 -0800370void CommonRuntimeTestImpl::FinalizeSetup() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700371 // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
372 // set up.
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700373 if (!unstarted_initialized_) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700374 interpreter::UnstartedRuntime::Initialize();
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700375 unstarted_initialized_ = true;
376 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700377
Andreas Gampea00f0122015-12-16 16:54:35 -0800378 {
379 ScopedObjectAccess soa(Thread::Current());
380 class_linker_->RunRootClinits();
381 }
Ian Rogerse63db272014-07-15 15:36:11 -0700382
383 // We're back in native, take the opportunity to initialize well known classes.
384 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
385
386 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
387 // pool is created by the runtime.
388 runtime_->GetHeap()->CreateThreadPool();
389 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Hiroshi Yamauchi4460a842015-03-09 11:57:48 -0700390 // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
391 runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
Ian Rogerse63db272014-07-15 15:36:11 -0700392}
393
Mathieu Chartier91c91162016-01-15 09:48:15 -0800394void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath) {
Alex Lighta59dd802014-07-02 16:28:08 -0700395 ASSERT_TRUE(dirpath != nullptr);
396 DIR* dir = opendir(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700397 ASSERT_TRUE(dir != nullptr);
398 dirent* e;
Alex Lighta59dd802014-07-02 16:28:08 -0700399 struct stat s;
Ian Rogerse63db272014-07-15 15:36:11 -0700400 while ((e = readdir(dir)) != nullptr) {
401 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
402 continue;
403 }
Jeff Haof0a3f092014-07-24 16:26:09 -0700404 std::string filename(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700405 filename.push_back('/');
406 filename.append(e->d_name);
Alex Lighta59dd802014-07-02 16:28:08 -0700407 int stat_result = lstat(filename.c_str(), &s);
408 ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
409 if (S_ISDIR(s.st_mode)) {
410 ClearDirectory(filename.c_str());
411 int rmdir_result = rmdir(filename.c_str());
412 ASSERT_EQ(0, rmdir_result) << filename;
413 } else {
414 int unlink_result = unlink(filename.c_str());
415 ASSERT_EQ(0, unlink_result) << filename;
416 }
Ian Rogerse63db272014-07-15 15:36:11 -0700417 }
418 closedir(dir);
Alex Lighta59dd802014-07-02 16:28:08 -0700419}
420
Mathieu Chartier91c91162016-01-15 09:48:15 -0800421void CommonRuntimeTestImpl::TearDown() {
Alex Lighta59dd802014-07-02 16:28:08 -0700422 const char* android_data = getenv("ANDROID_DATA");
423 ASSERT_TRUE(android_data != nullptr);
424 ClearDirectory(dalvik_cache_.c_str());
Ian Rogerse63db272014-07-15 15:36:11 -0700425 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
426 ASSERT_EQ(0, rmdir_cache_result);
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700427 TearDownAndroidData(android_data_, true);
Andreas Gampe3f41a012016-02-18 16:53:41 -0800428 dalvik_cache_.clear();
Ian Rogerse63db272014-07-15 15:36:11 -0700429
Andreas Gampe48864112017-01-19 17:23:17 -0800430 if (runtime_ != nullptr) {
431 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
432 }
Ian Rogerse63db272014-07-15 15:36:11 -0700433}
434
Andreas Gampec7d4a582015-09-30 11:52:02 -0700435static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
436 std::string path;
437 if (host) {
Ian Rogerse63db272014-07-15 15:36:11 -0700438 const char* host_dir = getenv("ANDROID_HOST_OUT");
439 CHECK(host_dir != nullptr);
Andreas Gampec7d4a582015-09-30 11:52:02 -0700440 path = host_dir;
441 } else {
442 path = GetAndroidRoot();
Ian Rogerse63db272014-07-15 15:36:11 -0700443 }
Andreas Gampec7d4a582015-09-30 11:52:02 -0700444
445 std::string suffix = host
446 ? "-hostdex" // The host version.
447 : "-testdex"; // The unstripped target version.
448
449 return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
450}
451
Mathieu Chartier91c91162016-01-15 09:48:15 -0800452std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
Andreas Gampec7d4a582015-09-30 11:52:02 -0700453 return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
454 GetDexFileName("core-libart", IsHost())});
Ian Rogerse63db272014-07-15 15:36:11 -0700455}
456
Mathieu Chartier91c91162016-01-15 09:48:15 -0800457std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700458 if (IsHost()) {
459 const char* host_dir = getenv("ANDROID_HOST_OUT");
460 CHECK(host_dir != nullptr);
461 return host_dir;
462 }
463 return GetAndroidRoot();
464}
465
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700466// Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
467#ifdef ART_TARGET
468#ifndef ART_TARGET_NATIVETEST_DIR
469#error "ART_TARGET_NATIVETEST_DIR not set."
470#endif
471// Wrap it as a string literal.
472#define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
473#else
474#define ART_TARGET_NATIVETEST_DIR_STRING ""
475#endif
476
Andreas Gampee1459ae2016-06-29 09:36:30 -0700477std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
Ian Rogerse63db272014-07-15 15:36:11 -0700478 CHECK(name != nullptr);
479 std::string filename;
480 if (IsHost()) {
481 filename += getenv("ANDROID_HOST_OUT");
482 filename += "/framework/";
483 } else {
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700484 filename += ART_TARGET_NATIVETEST_DIR_STRING;
Ian Rogerse63db272014-07-15 15:36:11 -0700485 }
486 filename += "art-gtest-";
487 filename += name;
488 filename += ".jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800489 return filename;
490}
491
Mathieu Chartier91c91162016-01-15 09:48:15 -0800492std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
493 const char* name) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800494 std::string filename = GetTestDexFileName(name);
Aart Bik37d6a3b2016-06-21 18:30:10 -0700495 static constexpr bool kVerifyChecksum = true;
Ian Rogerse63db272014-07-15 15:36:11 -0700496 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800497 std::vector<std::unique_ptr<const DexFile>> dex_files;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700498 bool success = DexFile::Open(
499 filename.c_str(), filename.c_str(), kVerifyChecksum, &error_msg, &dex_files);
Ian Rogerse63db272014-07-15 15:36:11 -0700500 CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800501 for (auto& dex_file : dex_files) {
Ian Rogerse63db272014-07-15 15:36:11 -0700502 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
503 CHECK(dex_file->IsReadOnly());
504 }
Ian Rogerse63db272014-07-15 15:36:11 -0700505 return dex_files;
506}
507
Mathieu Chartier91c91162016-01-15 09:48:15 -0800508std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800509 std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
Ian Rogerse63db272014-07-15 15:36:11 -0700510 EXPECT_EQ(1U, vector.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800511 return std::move(vector[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700512}
513
Mathieu Chartier91c91162016-01-15 09:48:15 -0800514std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700515 std::vector<const DexFile*> ret;
516
517 ScopedObjectAccess soa(Thread::Current());
518
Mathieu Chartierc7853442015-03-27 14:35:38 -0700519 StackHandleScope<2> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700520 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700521 soa.Decode<mirror::ClassLoader>(jclass_loader));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700522
523 DCHECK_EQ(class_loader->GetClass(),
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700524 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700525 DCHECK_EQ(class_loader->GetParent()->GetClass(),
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700526 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700527
528 // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
529 // We need to get the DexPathList and loop through it.
Andreas Gampe08883de2016-11-08 13:20:52 -0800530 ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700531 ArtField* dex_file_field =
Andreas Gampe08883de2016-11-08 13:20:52 -0800532 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700533 ObjPtr<mirror::Object> dex_path_list =
Andreas Gampe08883de2016-11-08 13:20:52 -0800534 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
535 GetObject(class_loader.Get());
Mathieu Chartierc7853442015-03-27 14:35:38 -0700536 if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700537 // DexPathList has an array dexElements of Elements[] which each contain a dex file.
Mathieu Chartier3398c782016-09-30 10:27:43 -0700538 ObjPtr<mirror::Object> dex_elements_obj =
Andreas Gampe08883de2016-11-08 13:20:52 -0800539 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
540 GetObject(dex_path_list);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700541 // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
542 // at the mCookie which is a DexFile vector.
543 if (dex_elements_obj != nullptr) {
544 Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
545 hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
546 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700547 ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700548 if (element == nullptr) {
549 // Should never happen, fall back to java code to throw a NPE.
550 break;
551 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700552 ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700553 if (dex_file != nullptr) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700554 ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700555 DCHECK(long_array != nullptr);
556 int32_t long_array_size = long_array->GetLength();
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700557 for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700558 const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
559 long_array->GetWithoutChecks(j)));
560 if (cp_dex_file == nullptr) {
561 LOG(WARNING) << "Null DexFile";
562 continue;
563 }
564 ret.push_back(cp_dex_file);
565 }
566 }
567 }
568 }
569 }
570
571 return ret;
572}
573
Mathieu Chartier91c91162016-01-15 09:48:15 -0800574const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700575 std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
576 DCHECK(!tmp.empty());
577 const DexFile* ret = tmp[0];
578 DCHECK(ret != nullptr);
579 return ret;
580}
581
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100582jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
583 const char* second_dex_name) {
584 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
585 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
586 std::vector<const DexFile*> class_path;
587 CHECK_NE(0U, first_dex_files.size());
588 CHECK_NE(0U, second_dex_files.size());
589 for (auto& dex_file : first_dex_files) {
590 class_path.push_back(dex_file.get());
591 loaded_dex_files_.push_back(std::move(dex_file));
592 }
593 for (auto& dex_file : second_dex_files) {
594 class_path.push_back(dex_file.get());
595 loaded_dex_files_.push_back(std::move(dex_file));
596 }
597
598 Thread* self = Thread::Current();
599 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
600 class_path);
601 self->SetClassLoaderOverride(class_loader);
602 return class_loader;
603}
604
Mathieu Chartier91c91162016-01-15 09:48:15 -0800605jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800606 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name);
607 std::vector<const DexFile*> class_path;
Ian Rogerse63db272014-07-15 15:36:11 -0700608 CHECK_NE(0U, dex_files.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800609 for (auto& dex_file : dex_files) {
610 class_path.push_back(dex_file.get());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800611 loaded_dex_files_.push_back(std::move(dex_file));
Ian Rogerse63db272014-07-15 15:36:11 -0700612 }
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700613
Ian Rogers68d8b422014-07-17 11:09:10 -0700614 Thread* self = Thread::Current();
Mathieu Chartier673ed3d2015-08-28 14:56:43 -0700615 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
Mathieu Chartier966878d2016-01-14 14:33:29 -0800616 class_path);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700617 self->SetClassLoaderOverride(class_loader);
Ian Rogerse63db272014-07-15 15:36:11 -0700618 return class_loader;
619}
620
Mathieu Chartier91c91162016-01-15 09:48:15 -0800621std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
Igor Murashkin37743352014-11-13 14:38:00 -0800622 CHECK(suffix != nullptr);
623
624 std::string location;
625 if (IsHost()) {
626 const char* host_dir = getenv("ANDROID_HOST_OUT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700627 CHECK(host_dir != nullptr);
Richard Uhler67e1dc52017-02-06 16:50:17 +0000628 location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800629 } else {
Richard Uhler67e1dc52017-02-06 16:50:17 +0000630 location = StringPrintf("/data/art-test/core.%s", suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800631 }
632
633 return location;
634}
635
Ian Rogerse63db272014-07-15 15:36:11 -0700636CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700637 vm_->SetCheckJniAbortHook(Hook, &actual_);
Ian Rogerse63db272014-07-15 15:36:11 -0700638}
639
640CheckJniAbortCatcher::~CheckJniAbortCatcher() {
Ian Rogers68d8b422014-07-17 11:09:10 -0700641 vm_->SetCheckJniAbortHook(nullptr, nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700642 EXPECT_TRUE(actual_.empty()) << actual_;
643}
644
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700645void CheckJniAbortCatcher::Check(const std::string& expected_text) {
646 Check(expected_text.c_str());
647}
648
Ian Rogerse63db272014-07-15 15:36:11 -0700649void CheckJniAbortCatcher::Check(const char* expected_text) {
650 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
651 << "Expected to find: " << expected_text << "\n"
652 << "In the output : " << actual_;
653 actual_.clear();
654}
655
656void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
657 // We use += because when we're hooking the aborts like this, multiple problems can be found.
658 *reinterpret_cast<std::string*>(data) += reason;
659}
660
661} // namespace art
662
663namespace std {
664
665template <typename T>
666std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
667os << ::art::ToString(rhs);
668return os;
669}
670
671} // namespace std