1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_DEX2OAT_ENVIRONMENT_TEST_H_ 18 #define ART_RUNTIME_DEX2OAT_ENVIRONMENT_TEST_H_ 19 20 #include <fstream> 21 #include <string> 22 #include <vector> 23 24 #include <gtest/gtest.h> 25 26 #include "base/stl_util.h" 27 #include "common_runtime_test.h" 28 #include "compiler_callbacks.h" 29 #include "exec_utils.h" 30 #include "gc/heap.h" 31 #include "gc/space/image_space.h" 32 #include "oat_file_assistant.h" 33 #include "os.h" 34 #include "runtime.h" 35 #include "utils.h" 36 37 namespace art { 38 39 // Test class that provides some helpers to set a test up for compilation using dex2oat. 40 class Dex2oatEnvironmentTest : public CommonRuntimeTest { 41 public: SetUp()42 virtual void SetUp() OVERRIDE { 43 CommonRuntimeTest::SetUp(); 44 45 // Create a scratch directory to work from. 46 47 // Get the realpath of the android data. The oat dir should always point to real location 48 // when generating oat files in dalvik-cache. This avoids complicating the unit tests 49 // when matching the expected paths. 50 UniqueCPtr<const char[]> android_data_real(realpath(android_data_.c_str(), nullptr)); 51 ASSERT_TRUE(android_data_real != nullptr) 52 << "Could not get the realpath of the android data" << android_data_ << strerror(errno); 53 54 scratch_dir_.assign(android_data_real.get()); 55 scratch_dir_ += "/Dex2oatEnvironmentTest"; 56 ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700)); 57 58 // Create a subdirectory in scratch for odex files. 59 odex_oat_dir_ = scratch_dir_ + "/oat"; 60 ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700)); 61 62 odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA)); 63 ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700)); 64 65 // Verify the environment is as we expect 66 std::vector<uint32_t> checksums; 67 std::string error_msg; 68 ASSERT_TRUE(OS::FileExists(GetSystemImageFile().c_str())) 69 << "Expected pre-compiled boot image to be at: " << GetSystemImageFile(); 70 ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str())) 71 << "Expected dex file to be at: " << GetDexSrc1(); 72 ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str())) 73 << "Expected stripped dex file to be at: " << GetStrippedDexSrc1(); 74 ASSERT_FALSE(DexFile::GetMultiDexChecksums(GetStrippedDexSrc1().c_str(), &checksums, &error_msg)) 75 << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1(); 76 ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str())) 77 << "Expected dex file to be at: " << GetDexSrc2(); 78 79 // GetMultiDexSrc2 should have the same primary dex checksum as 80 // GetMultiDexSrc1, but a different secondary dex checksum. 81 static constexpr bool kVerifyChecksum = true; 82 std::vector<std::unique_ptr<const DexFile>> multi1; 83 ASSERT_TRUE(DexFile::Open(GetMultiDexSrc1().c_str(), 84 GetMultiDexSrc1().c_str(), kVerifyChecksum, &error_msg, &multi1)) << error_msg; 85 ASSERT_GT(multi1.size(), 1u); 86 87 std::vector<std::unique_ptr<const DexFile>> multi2; 88 ASSERT_TRUE(DexFile::Open(GetMultiDexSrc2().c_str(), 89 GetMultiDexSrc2().c_str(), kVerifyChecksum, &error_msg, &multi2)) << error_msg; 90 ASSERT_GT(multi2.size(), 1u); 91 92 ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum()); 93 ASSERT_NE(multi1[1]->GetLocationChecksum(), multi2[1]->GetLocationChecksum()); 94 } 95 SetUpRuntimeOptions(RuntimeOptions * options)96 virtual void SetUpRuntimeOptions(RuntimeOptions* options) OVERRIDE { 97 // options->push_back(std::make_pair("-verbose:oat", nullptr)); 98 99 // Set up the image location. 100 options->push_back(std::make_pair("-Ximage:" + GetImageLocation(), 101 nullptr)); 102 // Make sure compilercallbacks are not set so that relocation will be 103 // enabled. 104 callbacks_.reset(); 105 } 106 TearDown()107 virtual void TearDown() OVERRIDE { 108 ClearDirectory(odex_dir_.c_str()); 109 ASSERT_EQ(0, rmdir(odex_dir_.c_str())); 110 111 ClearDirectory(odex_oat_dir_.c_str()); 112 ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str())); 113 114 ClearDirectory(scratch_dir_.c_str()); 115 ASSERT_EQ(0, rmdir(scratch_dir_.c_str())); 116 117 CommonRuntimeTest::TearDown(); 118 } 119 Copy(const std::string & src,const std::string & dst)120 static void Copy(const std::string& src, const std::string& dst) { 121 std::ifstream src_stream(src, std::ios::binary); 122 std::ofstream dst_stream(dst, std::ios::binary); 123 124 dst_stream << src_stream.rdbuf(); 125 } 126 127 // Returns the directory where the pre-compiled core.art can be found. 128 // TODO: We should factor out this into common tests somewhere rather than 129 // re-hardcoding it here (This was copied originally from the elf writer 130 // test). GetImageDirectory()131 std::string GetImageDirectory() const { 132 if (IsHost()) { 133 const char* host_dir = getenv("ANDROID_HOST_OUT"); 134 CHECK(host_dir != nullptr); 135 return std::string(host_dir) + "/framework"; 136 } else { 137 return std::string("/data/art-test"); 138 } 139 } 140 GetImageLocation()141 std::string GetImageLocation() const { 142 return GetImageDirectory() + "/core.art"; 143 } 144 GetSystemImageFile()145 std::string GetSystemImageFile() const { 146 return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA) 147 + "/core.art"; 148 } 149 GetCachedImageFile(const std::string & image_location,std::string * image,std::string * error_msg)150 bool GetCachedImageFile(const std::string& image_location, 151 /*out*/std::string* image, 152 /*out*/std::string* error_msg) const { 153 std::string cache; 154 bool have_android_data; 155 bool dalvik_cache_exists; 156 bool is_global_cache; 157 GetDalvikCache(GetInstructionSetString(kRuntimeISA), 158 true, 159 &cache, 160 &have_android_data, 161 &dalvik_cache_exists, 162 &is_global_cache); 163 if (!dalvik_cache_exists) { 164 *error_msg = "Failed to create dalvik cache"; 165 return false; 166 } 167 return GetDalvikCacheFilename(image_location.c_str(), cache.c_str(), image, error_msg); 168 } 169 170 // Returns the path to an image location whose contents differ from the 171 // image at GetImageLocation(). This is used for testing mismatched 172 // image checksums in the oat_file_assistant_tests. GetImageLocation2()173 std::string GetImageLocation2() const { 174 return GetImageDirectory() + "/core-interpreter.art"; 175 } 176 GetDexSrc1()177 std::string GetDexSrc1() const { 178 return GetTestDexFileName("Main"); 179 } 180 181 // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex 182 // file stripped. GetStrippedDexSrc1()183 std::string GetStrippedDexSrc1() const { 184 return GetTestDexFileName("MainStripped"); 185 } 186 GetMultiDexSrc1()187 std::string GetMultiDexSrc1() const { 188 return GetTestDexFileName("MultiDex"); 189 } 190 191 // Returns the path to a multidex file equivalent to GetMultiDexSrc2, but 192 // with the contents of the secondary dex file changed. GetMultiDexSrc2()193 std::string GetMultiDexSrc2() const { 194 return GetTestDexFileName("MultiDexModifiedSecondary"); 195 } 196 GetDexSrc2()197 std::string GetDexSrc2() const { 198 return GetTestDexFileName("Nested"); 199 } 200 201 // Scratch directory, for dex and odex files (oat files will go in the 202 // dalvik cache). GetScratchDir()203 const std::string& GetScratchDir() const { 204 return scratch_dir_; 205 } 206 207 // Odex directory is the subdirectory in the scratch directory where odex 208 // files should be located. GetOdexDir()209 const std::string& GetOdexDir() const { 210 return odex_dir_; 211 } 212 213 private: 214 std::string scratch_dir_; 215 std::string odex_oat_dir_; 216 std::string odex_dir_; 217 }; 218 219 } // namespace art 220 221 #endif // ART_RUNTIME_DEX2OAT_ENVIRONMENT_TEST_H_ 222