blob: 15724a1027574ef3b484197177c6ff34373c38b9 [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
Alex Lighta01b5242017-03-27 10:15:27 -070071static const uint8_t kBase64Map[256] = {
72 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
73 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
74 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
75 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
76 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
77 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
78 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
79 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
80 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
81 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
82 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
83 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
84 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
85 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
86 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
87 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
88 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
89 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
91 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
92 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
93 255, 255, 255, 255
94};
95
96uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
97 CHECK(dst_size != nullptr);
98 std::vector<uint8_t> tmp;
99 uint32_t t = 0, y = 0;
100 int g = 3;
101 for (size_t i = 0; src[i] != '\0'; ++i) {
102 uint8_t c = kBase64Map[src[i] & 0xFF];
103 if (c == 255) continue;
104 // the final = symbols are read and used to trim the remaining bytes
105 if (c == 254) {
106 c = 0;
107 // prevent g < 0 which would potentially allow an overflow later
108 if (--g < 0) {
109 *dst_size = 0;
110 return nullptr;
111 }
112 } else if (g != 3) {
113 // we only allow = to be at the end
114 *dst_size = 0;
115 return nullptr;
116 }
117 t = (t << 6) | c;
118 if (++y == 4) {
119 tmp.push_back((t >> 16) & 255);
120 if (g > 1) {
121 tmp.push_back((t >> 8) & 255);
122 }
123 if (g > 2) {
124 tmp.push_back(t & 255);
125 }
126 y = t = 0;
127 }
128 }
129 if (y != 0) {
130 *dst_size = 0;
131 return nullptr;
132 }
133 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
134 *dst_size = tmp.size();
135 std::copy(tmp.begin(), tmp.end(), dst.get());
136 return dst.release();
137}
138
Ian Rogerse63db272014-07-15 15:36:11 -0700139ScratchFile::ScratchFile() {
140 // ANDROID_DATA needs to be set
141 CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
142 "Are you subclassing RuntimeTest?";
143 filename_ = getenv("ANDROID_DATA");
144 filename_ += "/TmpFile-XXXXXX";
145 int fd = mkstemp(&filename_[0]);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000146 CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
Andreas Gampe4303ba92014-11-06 01:00:46 -0800147 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700148}
149
Mathieu Chartier866d8742016-09-21 15:24:18 -0700150ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
151 : ScratchFile(other.GetFilename() + suffix) {}
152
153ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
Ian Rogerse63db272014-07-15 15:36:11 -0700154 int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
155 CHECK_NE(-1, fd);
Andreas Gampe4303ba92014-11-06 01:00:46 -0800156 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700157}
158
159ScratchFile::ScratchFile(File* file) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700160 CHECK(file != nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700161 filename_ = file->GetPath();
162 file_.reset(file);
163}
164
Mathieu Chartier866d8742016-09-21 15:24:18 -0700165ScratchFile::ScratchFile(ScratchFile&& other) {
166 *this = std::move(other);
167}
168
169ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
170 if (GetFile() != other.GetFile()) {
171 std::swap(filename_, other.filename_);
172 std::swap(file_, other.file_);
173 }
174 return *this;
175}
176
Ian Rogerse63db272014-07-15 15:36:11 -0700177ScratchFile::~ScratchFile() {
178 Unlink();
179}
180
181int ScratchFile::GetFd() const {
182 return file_->Fd();
183}
184
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800185void ScratchFile::Close() {
Andreas Gampe4303ba92014-11-06 01:00:46 -0800186 if (file_.get() != nullptr) {
187 if (file_->FlushCloseOrErase() != 0) {
188 PLOG(WARNING) << "Error closing scratch file.";
189 }
190 }
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800191}
192
193void ScratchFile::Unlink() {
194 if (!OS::FileExists(filename_.c_str())) {
195 return;
196 }
197 Close();
Ian Rogerse63db272014-07-15 15:36:11 -0700198 int unlink_result = unlink(filename_.c_str());
199 CHECK_EQ(0, unlink_result);
200}
201
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700202static bool unstarted_initialized_ = false;
203
Andreas Gampe48864112017-01-19 17:23:17 -0800204CommonRuntimeTestImpl::CommonRuntimeTestImpl()
205 : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
206}
Mathieu Chartier91c91162016-01-15 09:48:15 -0800207
208CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800209 // Ensure the dex files are cleaned up before the runtime.
210 loaded_dex_files_.clear();
211 runtime_.reset();
212}
Ian Rogerse63db272014-07-15 15:36:11 -0700213
Mathieu Chartier91c91162016-01-15 09:48:15 -0800214void CommonRuntimeTestImpl::SetUpAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700215 if (IsHost()) {
216 // $ANDROID_ROOT is set on the device, but not necessarily on the host.
217 // But it needs to be set so that icu4c can find its locale data.
218 const char* android_root_from_env = getenv("ANDROID_ROOT");
219 if (android_root_from_env == nullptr) {
220 // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
221 const char* android_host_out = getenv("ANDROID_HOST_OUT");
222 if (android_host_out != nullptr) {
223 setenv("ANDROID_ROOT", android_host_out, 1);
224 } else {
225 // Build it from ANDROID_BUILD_TOP or cwd
226 std::string root;
227 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
228 if (android_build_top != nullptr) {
229 root += android_build_top;
230 } else {
231 // Not set by build server, so default to current directory
232 char* cwd = getcwd(nullptr, 0);
233 setenv("ANDROID_BUILD_TOP", cwd, 1);
234 root += cwd;
235 free(cwd);
236 }
237#if defined(__linux__)
238 root += "/out/host/linux-x86";
239#elif defined(__APPLE__)
240 root += "/out/host/darwin-x86";
241#else
242#error unsupported OS
243#endif
244 setenv("ANDROID_ROOT", root.c_str(), 1);
245 }
246 }
247 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
248
249 // Not set by build server, so default
250 if (getenv("ANDROID_HOST_OUT") == nullptr) {
251 setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
252 }
253 }
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700254}
Ian Rogerse63db272014-07-15 15:36:11 -0700255
Mathieu Chartier91c91162016-01-15 09:48:15 -0800256void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
Ian Rogerse63db272014-07-15 15:36:11 -0700257 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
Andreas Gampe5a79fde2014-08-06 13:12:26 -0700258 if (IsHost()) {
259 const char* tmpdir = getenv("TMPDIR");
260 if (tmpdir != nullptr && tmpdir[0] != 0) {
261 android_data = tmpdir;
262 } else {
263 android_data = "/tmp";
264 }
265 } else {
266 android_data = "/data/dalvik-cache";
267 }
268 android_data += "/art-data-XXXXXX";
Ian Rogerse63db272014-07-15 15:36:11 -0700269 if (mkdtemp(&android_data[0]) == nullptr) {
270 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
271 }
272 setenv("ANDROID_DATA", android_data.c_str(), 1);
273}
274
Mathieu Chartier91c91162016-01-15 09:48:15 -0800275void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
276 bool fail_on_error) {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700277 if (fail_on_error) {
278 ASSERT_EQ(rmdir(android_data.c_str()), 0);
279 } else {
280 rmdir(android_data.c_str());
281 }
282}
283
David Srbecky3e52aa42015-04-12 07:45:18 +0100284// Helper - find directory with the following format:
285// ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
286static std::string GetAndroidToolsDir(const std::string& subdir1,
287 const std::string& subdir2,
288 const std::string& subdir3) {
289 std::string root;
290 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
291 if (android_build_top != nullptr) {
292 root = android_build_top;
293 } else {
294 // Not set by build server, so default to current directory
295 char* cwd = getcwd(nullptr, 0);
296 setenv("ANDROID_BUILD_TOP", cwd, 1);
297 root = cwd;
298 free(cwd);
299 }
300
301 std::string toolsdir = root + "/" + subdir1;
302 std::string founddir;
303 DIR* dir;
304 if ((dir = opendir(toolsdir.c_str())) != nullptr) {
305 float maxversion = 0;
306 struct dirent* entry;
307 while ((entry = readdir(dir)) != nullptr) {
308 std::string format = subdir2 + "-%f";
309 float version;
310 if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
311 if (version > maxversion) {
312 maxversion = version;
313 founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
314 }
315 }
316 }
317 closedir(dir);
318 }
319
320 if (founddir.empty()) {
Roland Levillain91d65e02016-01-19 15:59:16 +0000321 ADD_FAILURE() << "Cannot find Android tools directory.";
David Srbecky3e52aa42015-04-12 07:45:18 +0100322 }
323 return founddir;
324}
325
Mathieu Chartier91c91162016-01-15 09:48:15 -0800326std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
David Srbecky3e52aa42015-04-12 07:45:18 +0100327 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
328 "x86_64-linux-glibc2.15",
329 "x86_64-linux");
330}
331
Mathieu Chartier91c91162016-01-15 09:48:15 -0800332std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
David Srbecky3e52aa42015-04-12 07:45:18 +0100333 switch (isa) {
334 case kArm:
335 case kThumb2:
336 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
337 "arm-linux-androideabi",
338 "arm-linux-androideabi");
339 case kArm64:
340 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
341 "aarch64-linux-android",
342 "aarch64-linux-android");
343 case kX86:
344 case kX86_64:
345 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
346 "x86_64-linux-android",
347 "x86_64-linux-android");
348 case kMips:
349 case kMips64:
350 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
351 "mips64el-linux-android",
352 "mips64el-linux-android");
353 case kNone:
354 break;
355 }
356 ADD_FAILURE() << "Invalid isa " << isa;
357 return "";
358}
359
Mathieu Chartier91c91162016-01-15 09:48:15 -0800360std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800361 return GetCoreFileLocation("art");
362}
363
Mathieu Chartier91c91162016-01-15 09:48:15 -0800364std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800365 return GetCoreFileLocation("oat");
366}
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700367
Mathieu Chartier91c91162016-01-15 09:48:15 -0800368std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
369 const char* location) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800370 std::vector<std::unique_ptr<const DexFile>> dex_files;
Ian Rogerse63db272014-07-15 15:36:11 -0700371 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800372 MemMap::Init();
Aart Bik37d6a3b2016-06-21 18:30:10 -0700373 static constexpr bool kVerifyChecksum = true;
374 if (!DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files)) {
Ian Rogerse63db272014-07-15 15:36:11 -0700375 LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800376 UNREACHABLE();
Ian Rogerse63db272014-07-15 15:36:11 -0700377 } else {
378 CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800379 return std::move(dex_files[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700380 }
381}
382
Mathieu Chartier91c91162016-01-15 09:48:15 -0800383void CommonRuntimeTestImpl::SetUp() {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700384 SetUpAndroidRoot();
385 SetUpAndroidData(android_data_);
Ian Rogerse63db272014-07-15 15:36:11 -0700386 dalvik_cache_.append(android_data_.c_str());
387 dalvik_cache_.append("/dalvik-cache");
388 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
389 ASSERT_EQ(mkdir_result, 0);
390
Ian Rogerse63db272014-07-15 15:36:11 -0700391 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
392 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
393
Ian Rogerse63db272014-07-15 15:36:11 -0700394
395 RuntimeOptions options;
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000396 std::string boot_class_path_string = "-Xbootclasspath";
397 for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
398 boot_class_path_string += ":";
399 boot_class_path_string += core_dex_file_name;
400 }
401
Richard Uhlerc2752592015-01-02 13:28:22 -0800402 options.push_back(std::make_pair(boot_class_path_string, nullptr));
Ian Rogerse63db272014-07-15 15:36:11 -0700403 options.push_back(std::make_pair("-Xcheck:jni", nullptr));
Richard Uhlerc2752592015-01-02 13:28:22 -0800404 options.push_back(std::make_pair(min_heap_string, nullptr));
405 options.push_back(std::make_pair(max_heap_string, nullptr));
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700406
407 callbacks_.reset(new NoopCompilerCallbacks());
408
Ian Rogerse63db272014-07-15 15:36:11 -0700409 SetUpRuntimeOptions(&options);
Igor Murashkinaaebaa02015-01-26 10:55:53 -0800410
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700411 // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
412 if (callbacks_.get() != nullptr) {
413 options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
414 }
415
Richard Uhler66d874d2015-01-15 09:37:19 -0800416 PreRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700417 if (!Runtime::Create(options, false)) {
418 LOG(FATAL) << "Failed to create runtime";
419 return;
420 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800421 PostRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700422 runtime_.reset(Runtime::Current());
423 class_linker_ = runtime_->GetClassLinker();
424 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700425
Andreas Gampea00f0122015-12-16 16:54:35 -0800426 // Runtime::Create acquired the mutator_lock_ that is normally given away when we
427 // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
428 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
429
430 // Get the boot class path from the runtime so it can be used in tests.
431 boot_class_path_ = class_linker_->GetBootClassPath();
432 ASSERT_FALSE(boot_class_path_.empty());
433 java_lang_dex_file_ = boot_class_path_[0];
434
435 FinalizeSetup();
436}
437
Mathieu Chartier91c91162016-01-15 09:48:15 -0800438void CommonRuntimeTestImpl::FinalizeSetup() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700439 // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
440 // set up.
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700441 if (!unstarted_initialized_) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700442 interpreter::UnstartedRuntime::Initialize();
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700443 unstarted_initialized_ = true;
444 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700445
Andreas Gampea00f0122015-12-16 16:54:35 -0800446 {
447 ScopedObjectAccess soa(Thread::Current());
448 class_linker_->RunRootClinits();
449 }
Ian Rogerse63db272014-07-15 15:36:11 -0700450
451 // We're back in native, take the opportunity to initialize well known classes.
452 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
453
454 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
455 // pool is created by the runtime.
456 runtime_->GetHeap()->CreateThreadPool();
457 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Hiroshi Yamauchi4460a842015-03-09 11:57:48 -0700458 // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
459 runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
Ian Rogerse63db272014-07-15 15:36:11 -0700460}
461
Mathieu Chartier91c91162016-01-15 09:48:15 -0800462void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath) {
Alex Lighta59dd802014-07-02 16:28:08 -0700463 ASSERT_TRUE(dirpath != nullptr);
464 DIR* dir = opendir(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700465 ASSERT_TRUE(dir != nullptr);
466 dirent* e;
Alex Lighta59dd802014-07-02 16:28:08 -0700467 struct stat s;
Ian Rogerse63db272014-07-15 15:36:11 -0700468 while ((e = readdir(dir)) != nullptr) {
469 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
470 continue;
471 }
Jeff Haof0a3f092014-07-24 16:26:09 -0700472 std::string filename(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700473 filename.push_back('/');
474 filename.append(e->d_name);
Alex Lighta59dd802014-07-02 16:28:08 -0700475 int stat_result = lstat(filename.c_str(), &s);
476 ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
477 if (S_ISDIR(s.st_mode)) {
478 ClearDirectory(filename.c_str());
479 int rmdir_result = rmdir(filename.c_str());
480 ASSERT_EQ(0, rmdir_result) << filename;
481 } else {
482 int unlink_result = unlink(filename.c_str());
483 ASSERT_EQ(0, unlink_result) << filename;
484 }
Ian Rogerse63db272014-07-15 15:36:11 -0700485 }
486 closedir(dir);
Alex Lighta59dd802014-07-02 16:28:08 -0700487}
488
Mathieu Chartier91c91162016-01-15 09:48:15 -0800489void CommonRuntimeTestImpl::TearDown() {
Alex Lighta59dd802014-07-02 16:28:08 -0700490 const char* android_data = getenv("ANDROID_DATA");
491 ASSERT_TRUE(android_data != nullptr);
492 ClearDirectory(dalvik_cache_.c_str());
Ian Rogerse63db272014-07-15 15:36:11 -0700493 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
494 ASSERT_EQ(0, rmdir_cache_result);
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700495 TearDownAndroidData(android_data_, true);
Andreas Gampe3f41a012016-02-18 16:53:41 -0800496 dalvik_cache_.clear();
Ian Rogerse63db272014-07-15 15:36:11 -0700497
Andreas Gampe48864112017-01-19 17:23:17 -0800498 if (runtime_ != nullptr) {
499 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
500 }
Ian Rogerse63db272014-07-15 15:36:11 -0700501}
502
Andreas Gampec7d4a582015-09-30 11:52:02 -0700503static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
504 std::string path;
505 if (host) {
Ian Rogerse63db272014-07-15 15:36:11 -0700506 const char* host_dir = getenv("ANDROID_HOST_OUT");
507 CHECK(host_dir != nullptr);
Andreas Gampec7d4a582015-09-30 11:52:02 -0700508 path = host_dir;
509 } else {
510 path = GetAndroidRoot();
Ian Rogerse63db272014-07-15 15:36:11 -0700511 }
Andreas Gampec7d4a582015-09-30 11:52:02 -0700512
513 std::string suffix = host
514 ? "-hostdex" // The host version.
515 : "-testdex"; // The unstripped target version.
516
517 return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
518}
519
Mathieu Chartier91c91162016-01-15 09:48:15 -0800520std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
Andreas Gampec7d4a582015-09-30 11:52:02 -0700521 return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
522 GetDexFileName("core-libart", IsHost())});
Ian Rogerse63db272014-07-15 15:36:11 -0700523}
524
Mathieu Chartier91c91162016-01-15 09:48:15 -0800525std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700526 if (IsHost()) {
527 const char* host_dir = getenv("ANDROID_HOST_OUT");
528 CHECK(host_dir != nullptr);
529 return host_dir;
530 }
531 return GetAndroidRoot();
532}
533
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700534// Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
535#ifdef ART_TARGET
536#ifndef ART_TARGET_NATIVETEST_DIR
537#error "ART_TARGET_NATIVETEST_DIR not set."
538#endif
539// Wrap it as a string literal.
540#define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
541#else
542#define ART_TARGET_NATIVETEST_DIR_STRING ""
543#endif
544
Andreas Gampee1459ae2016-06-29 09:36:30 -0700545std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
Ian Rogerse63db272014-07-15 15:36:11 -0700546 CHECK(name != nullptr);
547 std::string filename;
548 if (IsHost()) {
549 filename += getenv("ANDROID_HOST_OUT");
550 filename += "/framework/";
551 } else {
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700552 filename += ART_TARGET_NATIVETEST_DIR_STRING;
Ian Rogerse63db272014-07-15 15:36:11 -0700553 }
554 filename += "art-gtest-";
555 filename += name;
556 filename += ".jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800557 return filename;
558}
559
Mathieu Chartier91c91162016-01-15 09:48:15 -0800560std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
561 const char* name) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800562 std::string filename = GetTestDexFileName(name);
Aart Bik37d6a3b2016-06-21 18:30:10 -0700563 static constexpr bool kVerifyChecksum = true;
Ian Rogerse63db272014-07-15 15:36:11 -0700564 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800565 std::vector<std::unique_ptr<const DexFile>> dex_files;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700566 bool success = DexFile::Open(
567 filename.c_str(), filename.c_str(), kVerifyChecksum, &error_msg, &dex_files);
Ian Rogerse63db272014-07-15 15:36:11 -0700568 CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800569 for (auto& dex_file : dex_files) {
Ian Rogerse63db272014-07-15 15:36:11 -0700570 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
571 CHECK(dex_file->IsReadOnly());
572 }
Ian Rogerse63db272014-07-15 15:36:11 -0700573 return dex_files;
574}
575
Mathieu Chartier91c91162016-01-15 09:48:15 -0800576std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800577 std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
Ian Rogerse63db272014-07-15 15:36:11 -0700578 EXPECT_EQ(1U, vector.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800579 return std::move(vector[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700580}
581
Mathieu Chartier91c91162016-01-15 09:48:15 -0800582std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700583 std::vector<const DexFile*> ret;
584
585 ScopedObjectAccess soa(Thread::Current());
586
Mathieu Chartierc7853442015-03-27 14:35:38 -0700587 StackHandleScope<2> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700588 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700589 soa.Decode<mirror::ClassLoader>(jclass_loader));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700590
591 DCHECK_EQ(class_loader->GetClass(),
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700592 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700593 DCHECK_EQ(class_loader->GetParent()->GetClass(),
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700594 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700595
596 // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
597 // We need to get the DexPathList and loop through it.
Andreas Gampe08883de2016-11-08 13:20:52 -0800598 ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700599 ArtField* dex_file_field =
Andreas Gampe08883de2016-11-08 13:20:52 -0800600 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700601 ObjPtr<mirror::Object> dex_path_list =
Andreas Gampe08883de2016-11-08 13:20:52 -0800602 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
603 GetObject(class_loader.Get());
Mathieu Chartierc7853442015-03-27 14:35:38 -0700604 if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700605 // DexPathList has an array dexElements of Elements[] which each contain a dex file.
Mathieu Chartier3398c782016-09-30 10:27:43 -0700606 ObjPtr<mirror::Object> dex_elements_obj =
Andreas Gampe08883de2016-11-08 13:20:52 -0800607 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
608 GetObject(dex_path_list);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700609 // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
610 // at the mCookie which is a DexFile vector.
611 if (dex_elements_obj != nullptr) {
612 Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
613 hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
614 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700615 ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700616 if (element == nullptr) {
617 // Should never happen, fall back to java code to throw a NPE.
618 break;
619 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700620 ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700621 if (dex_file != nullptr) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700622 ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700623 DCHECK(long_array != nullptr);
624 int32_t long_array_size = long_array->GetLength();
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700625 for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700626 const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
627 long_array->GetWithoutChecks(j)));
628 if (cp_dex_file == nullptr) {
629 LOG(WARNING) << "Null DexFile";
630 continue;
631 }
632 ret.push_back(cp_dex_file);
633 }
634 }
635 }
636 }
637 }
638
639 return ret;
640}
641
Mathieu Chartier91c91162016-01-15 09:48:15 -0800642const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700643 std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
644 DCHECK(!tmp.empty());
645 const DexFile* ret = tmp[0];
646 DCHECK(ret != nullptr);
647 return ret;
648}
649
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100650jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
651 const char* second_dex_name) {
652 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
653 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
654 std::vector<const DexFile*> class_path;
655 CHECK_NE(0U, first_dex_files.size());
656 CHECK_NE(0U, second_dex_files.size());
657 for (auto& dex_file : first_dex_files) {
658 class_path.push_back(dex_file.get());
659 loaded_dex_files_.push_back(std::move(dex_file));
660 }
661 for (auto& dex_file : second_dex_files) {
662 class_path.push_back(dex_file.get());
663 loaded_dex_files_.push_back(std::move(dex_file));
664 }
665
666 Thread* self = Thread::Current();
667 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
668 class_path);
669 self->SetClassLoaderOverride(class_loader);
670 return class_loader;
671}
672
Mathieu Chartier91c91162016-01-15 09:48:15 -0800673jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800674 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name);
675 std::vector<const DexFile*> class_path;
Ian Rogerse63db272014-07-15 15:36:11 -0700676 CHECK_NE(0U, dex_files.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800677 for (auto& dex_file : dex_files) {
678 class_path.push_back(dex_file.get());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800679 loaded_dex_files_.push_back(std::move(dex_file));
Ian Rogerse63db272014-07-15 15:36:11 -0700680 }
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700681
Ian Rogers68d8b422014-07-17 11:09:10 -0700682 Thread* self = Thread::Current();
Mathieu Chartier673ed3d2015-08-28 14:56:43 -0700683 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
Mathieu Chartier966878d2016-01-14 14:33:29 -0800684 class_path);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700685 self->SetClassLoaderOverride(class_loader);
Ian Rogerse63db272014-07-15 15:36:11 -0700686 return class_loader;
687}
688
Mathieu Chartier91c91162016-01-15 09:48:15 -0800689std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
Igor Murashkin37743352014-11-13 14:38:00 -0800690 CHECK(suffix != nullptr);
691
692 std::string location;
693 if (IsHost()) {
694 const char* host_dir = getenv("ANDROID_HOST_OUT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700695 CHECK(host_dir != nullptr);
Richard Uhler67e1dc52017-02-06 16:50:17 +0000696 location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800697 } else {
Richard Uhler67e1dc52017-02-06 16:50:17 +0000698 location = StringPrintf("/data/art-test/core.%s", suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800699 }
700
701 return location;
702}
703
Ian Rogerse63db272014-07-15 15:36:11 -0700704CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700705 vm_->SetCheckJniAbortHook(Hook, &actual_);
Ian Rogerse63db272014-07-15 15:36:11 -0700706}
707
708CheckJniAbortCatcher::~CheckJniAbortCatcher() {
Ian Rogers68d8b422014-07-17 11:09:10 -0700709 vm_->SetCheckJniAbortHook(nullptr, nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700710 EXPECT_TRUE(actual_.empty()) << actual_;
711}
712
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700713void CheckJniAbortCatcher::Check(const std::string& expected_text) {
714 Check(expected_text.c_str());
715}
716
Ian Rogerse63db272014-07-15 15:36:11 -0700717void CheckJniAbortCatcher::Check(const char* expected_text) {
718 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
719 << "Expected to find: " << expected_text << "\n"
720 << "In the output : " << actual_;
721 actual_.clear();
722}
723
724void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
725 // We use += because when we're hooking the aborts like this, multiple problems can be found.
726 *reinterpret_cast<std::string*>(data) += reason;
727}
728
729} // namespace art
730
731namespace std {
732
733template <typename T>
734std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
735os << ::art::ToString(rhs);
736return os;
737}
738
739} // namespace std