common_test.h revision 1f87008b165d26541d832ff805250afdc89c253d
1934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom// Copyright 2011 Google Inc. All Rights Reserved. 2934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 3b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <dirent.h> 40af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <dlfcn.h> 5b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/stat.h> 6b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <sys/types.h> 7b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 890a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "UniquePtr.h" 9578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "base64.h" 10578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h" 111f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h" 12578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_file.h" 1390a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "gtest/gtest.h" 141f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "heap.h" 151f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 1690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "stringprintf.h" 1790a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "thread.h" 180af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uclean.h" 190af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include "unicode/uvernum.h" 200af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 21934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstromnamespace art { 22934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 239f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstromstatic inline const DexFile* OpenDexFileBase64(const char* base64, 249f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom const std::string& location) { 25578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom CHECK(base64 != NULL); 26578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom size_t length; 27f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom byte* dex_bytes = DecodeBase64(base64, &length); 28f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom CHECK(dex_bytes != NULL); 299f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom const DexFile* dex_file = DexFile::OpenPtr(dex_bytes, length, location); 30578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom CHECK(dex_file != NULL); 31f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom return dex_file; 32578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom} 33578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 34db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstromclass ScratchFile { 35db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom public: 36db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom ScratchFile() { 3734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes filename_ = getenv("ANDROID_DATA"); 3834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes filename_ += "/TmpFile-XXXXXX"; 3934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes fd_ = mkstemp(&filename_[0]); 40db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom CHECK_NE(-1, fd_); 41db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 42db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 43db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom ~ScratchFile() { 4434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes int unlink_result = unlink(filename_.c_str()); 45db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom CHECK_EQ(0, unlink_result); 46db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom int close_result = close(fd_); 47db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom CHECK_EQ(0, close_result); 48db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 49db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 50db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom const char* GetFilename() const { 5134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes return filename_.c_str(); 52db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 53db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 54db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom int GetFd() const { 55db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom return fd_; 56db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom } 57db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 58db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom private: 5934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes std::string filename_; 60db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom int fd_; 61db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom}; 62db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom 63f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstromclass CommonTest : public testing::Test { 64578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom protected: 65578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom virtual void SetUp() { 664a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom is_host_ = getenv("ANDROID_BUILD_TOP") != NULL; 674a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom 680af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes if (is_host_) { 690af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // $ANDROID_ROOT is set on the device, but not on the host. 700af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // We need to set this so that icu4c can find its locale data. 710af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes std::string root; 720af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes root += getenv("ANDROID_BUILD_TOP"); 730af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes root += "/out/host/linux-x86"; 740af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes setenv("ANDROID_ROOT", root.c_str(), 1); 750af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes } 760af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 7734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes android_data_ = (is_host_ ? "/tmp/art-data-XXXXXX" : "/sdcard/art-data-XXXXXX"); 7834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes ASSERT_TRUE(mkdtemp(&android_data_[0]) != NULL); 7934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes setenv("ANDROID_DATA", android_data_.c_str(), 1); 8034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes art_cache_.append(android_data_.c_str()); 81b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom art_cache_.append("/art-cache"); 82b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int mkdir_result = mkdir(art_cache_.c_str(), 0700); 83b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(mkdir_result, 0); 84b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 85a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes java_lang_dex_file_.reset(GetLibCoreDex()); 86578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 879ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom boot_class_path_.push_back(java_lang_dex_file_.get()); 88578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 899ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom runtime_.reset(Runtime::Create(boot_class_path_)); 9090a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes ASSERT_TRUE(runtime_.get() != NULL); 917a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro class_linker_ = runtime_->GetClassLinker(); 92578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom } 93578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 94b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom virtual void TearDown() { 95b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom const char* android_data = getenv("ANDROID_DATA"); 96b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_TRUE(android_data != NULL); 97b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom DIR* dir = opendir(art_cache_.c_str()); 98b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_TRUE(dir != NULL); 99b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom while (true) { 100b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom struct dirent entry; 101b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom struct dirent* entry_ptr; 102b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int readdir_result = readdir_r(dir, &entry, &entry_ptr); 103b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, readdir_result); 104b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom if (entry_ptr == NULL) { 105b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom break; 106b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 107b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom if ((strcmp(entry_ptr->d_name, ".") == 0) || (strcmp(entry_ptr->d_name, "..") == 0)) { 108b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom continue; 109b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 110b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom std::string filename(art_cache_); 111b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom filename.push_back('/'); 112b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom filename.append(entry_ptr->d_name); 113b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int unlink_result = unlink(filename.c_str()); 114b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, unlink_result); 115b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 116b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom closedir(dir); 117b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int rmdir_cache_result = rmdir(art_cache_.c_str()); 118b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, rmdir_cache_result); 11934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes int rmdir_data_result = rmdir(android_data_.c_str()); 120b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ASSERT_EQ(0, rmdir_data_result); 1210af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 1220af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // icu4c has a fixed 10-element array "gCommonICUDataArray". 1230af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // If we run > 10 tests, we fill that array and u_setCommonData fails. 1240af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // There's a function to clear the array, but it's not public... 1250af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes typedef void (*IcuCleanupFn)(); 1260af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT); 1270af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes CHECK(sym != NULL); 1280af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym); 1290af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes (*icu_cleanup_fn)(); 130b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 131b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 132b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom std::string GetLibCoreDexFileName() { 133b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom if (is_host_) { 134b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom const char* host_dir = getenv("ANDROID_HOST_OUT"); 135b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom CHECK(host_dir != NULL); 136b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom return StringPrintf("%s/framework/core-hostdex.jar", host_dir); 137ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson } 138b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom return std::string("/system/framework/core.jar"); 139b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 140ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson 1419f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom const DexFile* GetLibCoreDex() { 142b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom std::string libcore_dex_file_name = GetLibCoreDexFileName(); 14340ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes return DexFile::OpenZip(libcore_dex_file_name); 144ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson } 145ac5b9e22d32c4f986783a2207b08ade769619f6fJesse Wilson 1468a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const PathClassLoader* AllocPathClassLoader(const DexFile* dex_file) { 1479ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 1489ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom class_linker_->RegisterDexFile(*dex_file); 14974eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom std::vector<const DexFile*> dex_files; 15074eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom dex_files.push_back(dex_file); 1519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom return PathClassLoader::Alloc(dex_files); 15274eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom } 15374eb46ab15c5b9cb39bf15246db84aea7fd4cc27Brian Carlstrom 1549f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom const DexFile* OpenTestDexFile(const char* name) { 1559f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom CHECK(name != NULL); 1569f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom std::string filename; 1579f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom if (is_host_) { 1589f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom // on the host, just read target dex file 1599f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom filename += getenv("ANDROID_PRODUCT_OUT"); 1609f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom } 1619f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom filename += "/system/framework/art-test-dex-"; 1629f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom filename += name; 1639f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom filename += ".jar"; 1649f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom const DexFile* dex_file = DexFile::OpenZip(filename); 1659f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom CHECK(dex_file != NULL) << "Could not open " << filename; 1669f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom return dex_file; 1679f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom } 1689f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom 1694a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom bool is_host_; 17034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes std::string android_data_; 171b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom std::string art_cache_; 17290a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes UniquePtr<const DexFile> java_lang_dex_file_; 1739ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom std::vector<const DexFile*> boot_class_path_; 17490a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes UniquePtr<Runtime> runtime_; 1757a90959d4ef7a69f3bcb7b8763f646e12d9267d3Carl Shapiro ClassLinker* class_linker_; 176578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom}; 177578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 178934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom} // namespace art 17934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes 18034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesnamespace std { 18134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes 18234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes// TODO: isn't gtest supposed to be able to print STL types for itself? 18334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughestemplate <typename T> 18434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughesstd::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) { 18534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes os << "["; 18634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes for (size_t i = 0; i < rhs.size(); ++i) { 18734023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes os << rhs[i]; 18834023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes if (i < rhs.size() - 1) { 18934023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes os << ", "; 19034023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes } 19134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes } 19234023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes os << "]"; 19334023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes return os; 19434023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes} 19534023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes 19634023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes} // namespace std 197