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