125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe/* 225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * Copyright (C) 2014 The Android Open Source Project 325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * 425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * Licensed under the Apache License, Version 2.0 (the "License"); 525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * you may not use this file except in compliance with the License. 625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * You may obtain a copy of the License at 725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * 825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * http://www.apache.org/licenses/LICENSE-2.0 925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * 1025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * Unless required by applicable law or agreed to in writing, software 1125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * distributed under the License is distributed on an "AS IS" BASIS, 1225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * See the License for the specific language governing permissions and 1425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe * limitations under the License. 1525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe */ 1625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 1725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#ifndef ART_RUNTIME_DEX2OAT_ENVIRONMENT_TEST_H_ 1825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#define ART_RUNTIME_DEX2OAT_ENVIRONMENT_TEST_H_ 1925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 2025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include <fstream> 2125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include <string> 2225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include <vector> 2325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 2425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include <gtest/gtest.h> 2525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 2625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "common_runtime_test.h" 2725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "compiler_callbacks.h" 2825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "gc/heap.h" 2925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "gc/space/image_space.h" 3025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "oat_file_assistant.h" 3125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "os.h" 3225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "runtime.h" 3325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "utils.h" 3425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 3525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampenamespace art { 3625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 3725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe// Test class that provides some helpers to set a test up for compilation using dex2oat. 3825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampeclass Dex2oatEnvironmentTest : public CommonRuntimeTest { 3925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe public: 4025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe virtual void SetUp() OVERRIDE { 4125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe CommonRuntimeTest::SetUp(); 4225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 4325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Create a scratch directory to work from. 4425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe scratch_dir_ = android_data_ + "/Dex2oatEnvironmentTest"; 4525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700)); 4625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 4725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Create a subdirectory in scratch for odex files. 4825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe odex_oat_dir_ = scratch_dir_ + "/oat"; 4925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700)); 5025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 5125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA)); 5225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700)); 5325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 5425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Verify the environment is as we expect 5525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe uint32_t checksum; 5625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string error_msg; 5725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_TRUE(OS::FileExists(GetSystemImageFile().c_str())) 5825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe << "Expected pre-compiled boot image to be at: " << GetSystemImageFile(); 5925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str())) 6025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe << "Expected dex file to be at: " << GetDexSrc1(); 6125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str())) 6225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe << "Expected stripped dex file to be at: " << GetStrippedDexSrc1(); 6325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_FALSE(DexFile::GetChecksum(GetStrippedDexSrc1().c_str(), &checksum, &error_msg)) 6425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1(); 6525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str())) 6625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe << "Expected dex file to be at: " << GetDexSrc2(); 6725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 6825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // GetMultiDexSrc2 should have the same primary dex checksum as 6925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // GetMultiDexSrc1, but a different secondary dex checksum. 7025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::vector<std::unique_ptr<const DexFile>> multi1; 7125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_TRUE(DexFile::Open(GetMultiDexSrc1().c_str(), 7225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe GetMultiDexSrc1().c_str(), &error_msg, &multi1)) << error_msg; 7325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_GT(multi1.size(), 1u); 7425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 7525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::vector<std::unique_ptr<const DexFile>> multi2; 7625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_TRUE(DexFile::Open(GetMultiDexSrc2().c_str(), 7725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe GetMultiDexSrc2().c_str(), &error_msg, &multi2)) << error_msg; 7825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_GT(multi2.size(), 1u); 7925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 8025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum()); 8125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_NE(multi1[1]->GetLocationChecksum(), multi2[1]->GetLocationChecksum()); 8225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 8325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 8425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe virtual void SetUpRuntimeOptions(RuntimeOptions* options) OVERRIDE { 8525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // options->push_back(std::make_pair("-verbose:oat", nullptr)); 8625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 8725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Set up the image location. 8825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe options->push_back(std::make_pair("-Ximage:" + GetImageLocation(), 8925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe nullptr)); 9025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Make sure compilercallbacks are not set so that relocation will be 9125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // enabled. 9225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe callbacks_.reset(); 9325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 9425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 9525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe virtual void TearDown() OVERRIDE { 9625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ClearDirectory(odex_dir_.c_str()); 9725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_EQ(0, rmdir(odex_dir_.c_str())); 9825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 9925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ClearDirectory(odex_oat_dir_.c_str()); 10025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str())); 10125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 10225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ClearDirectory(scratch_dir_.c_str()); 10325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe ASSERT_EQ(0, rmdir(scratch_dir_.c_str())); 10425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 10525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe CommonRuntimeTest::TearDown(); 10625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 10725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 10825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe static void Copy(const std::string& src, const std::string& dst) { 10925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::ifstream src_stream(src, std::ios::binary); 11025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::ofstream dst_stream(dst, std::ios::binary); 11125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 11225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe dst_stream << src_stream.rdbuf(); 11325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 11425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 11525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Returns the directory where the pre-compiled core.art can be found. 11625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // TODO: We should factor out this into common tests somewhere rather than 11725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // re-hardcoding it here (This was copied originally from the elf writer 11825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // test). 11925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string GetImageDirectory() const { 12025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe if (IsHost()) { 12125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe const char* host_dir = getenv("ANDROID_HOST_OUT"); 12225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe CHECK(host_dir != nullptr); 12325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return std::string(host_dir) + "/framework"; 12425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } else { 12525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return std::string("/data/art-test"); 12625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 12725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 12825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 12925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string GetImageLocation() const { 13025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return GetImageDirectory() + "/core.art"; 13125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 13225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 13325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string GetSystemImageFile() const { 13425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA) 13525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe + "/core.art"; 13625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 13725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 13825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe bool GetCachedImageFile(/*out*/std::string* image, std::string* error_msg) const { 13925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string cache = GetDalvikCache(GetInstructionSetString(kRuntimeISA), true); 14025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return GetDalvikCacheFilename(GetImageLocation().c_str(), cache.c_str(), image, error_msg); 14125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 14225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 14325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string GetDexSrc1() const { 14425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return GetTestDexFileName("Main"); 14525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 14625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 14725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex 14825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // file stripped. 14925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string GetStrippedDexSrc1() const { 15025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return GetTestDexFileName("MainStripped"); 15125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 15225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 15325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string GetMultiDexSrc1() const { 15425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return GetTestDexFileName("MultiDex"); 15525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 15625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 15725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Returns the path to a multidex file equivalent to GetMultiDexSrc2, but 15825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // with the contents of the secondary dex file changed. 15925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string GetMultiDexSrc2() const { 16025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return GetTestDexFileName("MultiDexModifiedSecondary"); 16125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 16225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 16325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string GetDexSrc2() const { 16425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return GetTestDexFileName("Nested"); 16525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 16625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 16725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Scratch directory, for dex and odex files (oat files will go in the 16825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // dalvik cache). 16925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe const std::string& GetScratchDir() const { 17025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return scratch_dir_; 17125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 17225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 17325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // Odex directory is the subdirectory in the scratch directory where odex 17425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe // files should be located. 17525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe const std::string& GetOdexDir() const { 17625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe return odex_dir_; 17725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe } 17825a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 17925a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe private: 18025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string scratch_dir_; 18125a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string odex_oat_dir_; 18225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe std::string odex_dir_; 18325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe}; 18425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 18525a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe} // namespace art 18625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe 18725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#endif // ART_RUNTIME_DEX2OAT_ENVIRONMENT_TEST_H_ 188