166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler/*
266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * Copyright (C) 2014 The Android Open Source Project
366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *
466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * Licensed under the Apache License, Version 2.0 (the "License");
566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * you may not use this file except in compliance with the License.
666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * You may obtain a copy of the License at
766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *
866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *      http://www.apache.org/licenses/LICENSE-2.0
966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *
1066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * Unless required by applicable law or agreed to in writing, software
1166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * distributed under the License is distributed on an "AS IS" BASIS,
1266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * See the License for the specific language governing permissions and
1466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * limitations under the License.
1566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler */
1666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <algorithm>
1866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <fstream>
1966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <string>
2066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <vector>
2166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/param.h>
2266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <backtrace/BacktraceMap.h>
2466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <gtest/gtest.h>
2566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
26c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h"
273481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h"
2866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "common_runtime_test.h"
29bb9c6b1c55e9e2308b4f5892a398a8837231fdbdAndreas Gampe#include "compiler_callbacks.h"
3025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "dex2oat_environment_test.h"
31f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler#include "gc/space/image_space.h"
3266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "mem_map.h"
3325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "oat_file_assistant.h"
34f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "oat_file_manager.h"
3566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "os.h"
3623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler#include "scoped_thread_state_change.h"
3766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "thread-inl.h"
3866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "utils.h"
3966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlernamespace art {
4166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampeclass OatFileAssistantTest : public Dex2oatEnvironmentTest {
4366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
4425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe  virtual void SetUp() OVERRIDE {
4566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ReserveImageSpace();
4625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe    Dex2oatEnvironmentTest::SetUp();
4766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
4866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
497dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler  // Pre-Relocate the image to a known non-zero offset so we don't have to
507dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler  // deal with the runtime randomly relocating the image by 0 and messing up
517dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler  // the expected results of the tests.
527dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler  bool PreRelocateImage(std::string* error_msg) {
537dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    std::string image;
547dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    if (!GetCachedImageFile(&image, error_msg)) {
557dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler      return false;
567dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    }
577dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler
587dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    std::string patchoat = GetAndroidRoot();
597dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    patchoat += kIsDebugBuild ? "/bin/patchoatd" : "/bin/patchoat";
607dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler
617dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    std::vector<std::string> argv;
627dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    argv.push_back(patchoat);
637dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    argv.push_back("--input-image-location=" + GetImageLocation());
647dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    argv.push_back("--output-image-file=" + image);
657dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA)));
667dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    argv.push_back("--base-offset-delta=0x00008000");
677dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    return Exec(argv, error_msg);
687dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler  }
697dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler
7066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void PreRuntimeCreate() {
717dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    std::string error_msg;
727dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    ASSERT_TRUE(PreRelocateImage(&error_msg)) << error_msg;
737dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler
7466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    UnreserveImageSpace();
7566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
7666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
7725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe  virtual void PostRuntimeCreate() OVERRIDE {
7866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ReserveImageSpace();
7966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
8066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
8193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler  // Generate a non-PIC odex file for the purposes of test.
8294f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler  // The generated odex file will be un-relocated.
8366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void GenerateOdexForTest(const std::string& dex_location,
847bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                           const std::string& odex_location,
857dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler                           CompilerFilter::Filter filter,
867dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler                           bool pic = false,
877dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler                           bool with_patch_info = true) {
887dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    // Temporarily redirect the dalvik cache so dex2oat doesn't find the
897dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    // relocated image file.
900e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr    std::string dalvik_cache = GetDalvikCache(GetInstructionSetString(kRuntimeISA));
910e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr    std::string dalvik_cache_tmp = dalvik_cache + ".redirected";
920e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr    ASSERT_EQ(0, rename(dalvik_cache.c_str(), dalvik_cache_tmp.c_str())) << strerror(errno);
930e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr
9493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::vector<std::string> args;
9593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--dex-file=" + dex_location);
967dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    args.push_back("--oat-file=" + odex_location);
977bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
987dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    args.push_back("--runtime-arg");
997dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    args.push_back("-Xnorelocate");
10093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
1017dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    if (pic) {
1027dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler      args.push_back("--compile-pic");
1037dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    }
1047dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler
1057dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    if (with_patch_info) {
1067dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler      args.push_back("--include-patch-information");
1077dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    }
10893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
10993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::string error_msg;
11093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
1110e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr    ASSERT_EQ(0, rename(dalvik_cache_tmp.c_str(), dalvik_cache.c_str())) << strerror(errno);
11293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
11393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // Verify the odex file was generated as expected and really is
11493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // unrelocated.
115bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier    std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(),
116bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     odex_location.c_str(),
117bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     nullptr,
118bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     nullptr,
119bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     false,
120bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     /*low_4gb*/false,
121bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     dex_location.c_str(),
122bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     &error_msg));
12393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
1247dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    EXPECT_EQ(pic, odex_file->IsPic());
1257dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    EXPECT_EQ(with_patch_info, odex_file->HasPatchInfo());
1267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    EXPECT_EQ(filter, odex_file->GetCompilerFilter());
12793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
1288c185bf0c6f18a5349bc87a7e3751ba06d90f461Vladimir Marko    if (CompilerFilter::IsBytecodeCompilationEnabled(filter)) {
1297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      const std::vector<gc::space::ImageSpace*> image_spaces =
1307dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler        Runtime::Current()->GetHeap()->GetBootImageSpaces();
1317bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr);
1327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      const ImageHeader& image_header = image_spaces[0]->GetImageHeader();
1337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      const OatHeader& oat_header = odex_file->GetOatHeader();
1344f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao      uint32_t combined_checksum = OatFileAssistant::CalculateCombinedImageChecksum();
1354f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao      EXPECT_EQ(combined_checksum, oat_header.GetImageFileLocationOatChecksum());
1367bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()),
1377bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe          oat_header.GetImageFileLocationOatDataBegin());
1387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta());
1397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    }
14093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler  }
14193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
14293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler  void GeneratePicOdexForTest(const std::string& dex_location,
1437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                              const std::string& odex_location,
1447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                              CompilerFilter::Filter filter) {
1457dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    GenerateOdexForTest(dex_location, odex_location, filter, true, false);
146d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  }
147ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
1481c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // Generate a non-PIC odex file without patch information for the purposes
1491c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // of test.  The generated odex file will be un-relocated.
1501c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  void GenerateNoPatchOdexForTest(const std::string& dex_location,
1511c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                  const std::string& odex_location,
1521c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                  CompilerFilter::Filter filter) {
1537dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    GenerateOdexForTest(dex_location, odex_location, filter, false, false);
1541c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  }
1551c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
15666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private:
15766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reserve memory around where the image will be loaded so other memory
15866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // won't conflict when it comes time to load the image.
15966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // This can be called with an already loaded image to reserve the space
16066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // around it.
16166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void ReserveImageSpace() {
16266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    MemMap::Init();
16366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
16466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Ensure a chunk of memory is reserved for the image space.
1657dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    // The reservation_end includes room for the main space that has to come
1667dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    // right after the image in case of the GSS collector.
1677dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    uintptr_t reservation_start = ART_BASE_ADDRESS;
1687dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler    uintptr_t reservation_end = ART_BASE_ADDRESS + 384 * MB;
16966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
17066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
17166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
17266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    for (BacktraceMap::const_iterator it = map->begin();
17366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reservation_start < reservation_end && it != map->end(); ++it) {
1743efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end));
1753efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      reservation_start = std::max(reservation_start, it->end);
1763efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    }
1773efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    ReserveImageSpaceChunk(reservation_start, reservation_end);
1783efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  }
17966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1803efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  // Reserve a chunk of memory for the image space in the given range.
1813efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  // Only has effect for chunks with a positive number of bytes.
1823efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) {
1833efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    if (start < end) {
1843efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      std::string error_msg;
18566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      image_reservation_.push_back(std::unique_ptr<MemMap>(
18666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          MemMap::MapAnonymous("image reservation",
1873efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler              reinterpret_cast<uint8_t*>(start), end - start,
188b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin              PROT_NONE, false, false, &error_msg)));
18966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
19066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      LOG(INFO) << "Reserved space for image " <<
19166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
19266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reinterpret_cast<void*>(image_reservation_.back()->End());
19366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
19466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
19566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
19666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
19766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Unreserve any memory reserved by ReserveImageSpace. This should be called
19866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // before the image is loaded.
19966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void UnreserveImageSpace() {
20066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    image_reservation_.clear();
20166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
20266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
20366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<MemMap>> image_reservation_;
20466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
20566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
20666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass OatFileAssistantNoDex2OatTest : public OatFileAssistantTest {
20766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
20866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
20966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    OatFileAssistantTest::SetUpRuntimeOptions(options);
21066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    options->push_back(std::make_pair("-Xnodex2oat", nullptr));
21166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
21266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
21366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
21466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Generate an oat file for the purposes of test, as opposed to testing
21566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// generation of oat files.
2167bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampestatic void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) {
2177bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  // Use an oat file assistant to find the proper oat location.
2187bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant ofa(dex_location, kRuntimeISA, false, false);
2197bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  const std::string* oat_location = ofa.OatFileName();
2207bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  ASSERT_TRUE(oat_location != nullptr);
22166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2227bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::vector<std::string> args;
2237bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--dex-file=" + std::string(dex_location));
2247bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--oat-file=" + *oat_location);
2257bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
2267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--runtime-arg");
2277bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("-Xnorelocate");
22866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
2297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
2307bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
2317bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  // Verify the oat file was generated as expected.
2327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location->c_str(),
2337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  oat_location->c_str(),
2347bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  nullptr,
2357bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  nullptr,
2367bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  false,
2377bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  /*low_4gb*/false,
2387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  dex_location,
2397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  &error_msg));
2407bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  ASSERT_TRUE(oat_file.get() != nullptr) << error_msg;
2417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(filter, oat_file->GetCompilerFilter());
24266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
24366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
24466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, but no OAT file for it.
24595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
24666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexNoOat) {
24766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
24866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
24966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2507bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
25166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2527bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
2537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
2547bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
2557bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
2567bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
2577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
2587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
2597bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
26066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
26166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
26266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
26366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
26466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
26566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
26695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
26766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
26866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
26966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
27066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
27195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
2729b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
27366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
27466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
27566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have no DEX file and no OAT file.
2769b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
27766d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NoDexNoOat) {
27866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
27966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2807bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
28166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2827bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
2837bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
2849b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
2859b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
2869b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Trying to make the oat file up to date should not fail or crash.
2879b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  std::string error_msg;
288ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
289ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg));
2909b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
2919b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Trying to get the best oat file should fail, but not crash.
29266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
29366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(nullptr, oat_file.get());
29466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
29566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
29666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
29795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded.
29866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatUpToDate) {
29966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
30066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
3017bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
30266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
3037bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
3047bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
3057bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
3067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
3077bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
3087bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
3097bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
3107bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
3117bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
3127bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
31366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
31466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
31566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
31666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
31766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
31866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
31966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
32066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
32166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
32295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
3239b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
32466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
32566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
3267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and speed-profile OAT file for it.
3277bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: The status is kNoDexOptNeeded if the profile hasn't changed.
3287bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
3297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
3307bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  Copy(GetDexSrc1(), dex_location);
3317bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
3327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
3337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
3347bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
3357bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
3367bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
3377bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
3387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
3397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
3407bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
3417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
3427bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
3437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
3447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OatFileExists());
3457bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
3467bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
3477bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
3487bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
3497bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
3507bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe}
3517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
3527bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and speed-profile OAT file for it.
3537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: The status is kNoDex2OatNeeded if the profile has changed.
3547bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, ProfileOatOutOfDate) {
3557bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string dex_location = GetScratchDir() + "/ProfileOatOutOfDate.jar";
3567bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  Copy(GetDexSrc1(), dex_location);
3577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
3587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
3597bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true, false);
3607bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
3617bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
3627bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
3637bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
3647bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
3657bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
3667bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
3677bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
3687bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
3697bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
3707bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OatFileExists());
3717bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
3727bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
3737bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
3747bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
3757bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
3767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe}
3777bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
37866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it.
37995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded and we load all dex files.
38066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
38166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
38266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
3837bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
38466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
3857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
3867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
3877bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
3889b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
38995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
39095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Verify we can load both dex files.
391e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
392e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
393e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
394e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
395e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
396e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ(2u, dex_files.size());
397e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler}
398e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
39967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Case: We have a MultiDEX file where the secondary dex file is out of date.
40067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Expect: The status is kDex2OatNeeded.
40167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard UhlerTEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) {
40267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar";
40367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
40467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Compile code for GetMultiDexSrc1.
40567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  Copy(GetMultiDexSrc1(), dex_location);
4067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
40767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
40867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
40967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // is out of date.
41067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  Copy(GetMultiDexSrc2(), dex_location);
41167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
4127bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
4137bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4147bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
4159b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
41667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler}
41767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
418e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it with relative
419e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// encoded dex locations.
42095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The oat file status is kNoDexOptNeeded.
421e5fed03772144595c0904faf3d6974cc55214c8cRichard UhlerTEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
422e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
4236343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
424e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
425e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Create the dex file
426e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
427e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
428e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Create the oat file with relative encoded dex location.
429e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::vector<std::string> args;
430e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--dex-file=" + dex_location);
431e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
432e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--oat-file=" + oat_location);
4337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--compiler-filter=speed");
434e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
435e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::string error_msg;
436b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
437e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
438e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Verify we can load both dex files.
439e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
440e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                                      oat_location.c_str(),
4417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                      kRuntimeISA, false, true);
442e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
44366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
44466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
44566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
446e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
44766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(2u, dex_files.size());
44866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
44966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
45095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file and out-of-date OAT file.
45195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
45266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatOutOfDate) {
45366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar";
45466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
45566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // We create a dex, generate an oat for it, then overwrite the dex with a
45666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // different dex to make the oat out of date.
45766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
4587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
45966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc2(), dex_location);
46066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4617bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
4627bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4637bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
4647bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4657bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
46666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
46766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
46866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
46966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
47066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
47166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
47266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
47366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
4749b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
47566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
47666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
47766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, but no OAT file.
47895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded.
47966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexOdexNoOat) {
48066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
4816343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
48266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
48366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
48466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
4857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
48666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
48766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
4887bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
48966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4907bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
4917bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
4927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
4937bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
49466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
49566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
49666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
49766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
49866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
49966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
50066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
50166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
50266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
5039b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
5045f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler
5055f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  // We should still be able to get the non-executable odex file to run from.
5065f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
5075f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
50866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
50966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
51066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a stripped DEX file and an ODEX file, but no OAT file.
51195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded
51266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
51366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
5146343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
51566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
51666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
51766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
5187bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
51966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
52066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Strip the dex file
52166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
52266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
52366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
5247bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
52566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
5267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
5277bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
52866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
52966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
53066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
53166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
53266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
53366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
53466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
53566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
5369b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
53766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
53866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Make the oat file up to date.
53966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
540ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
541ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
54266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
5437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
5447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
54566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
54666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
54766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
54866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
54966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
55066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
55166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
55266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
5539b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
55466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
55566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify we can load the dex files from it.
55666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
55766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
55866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
55966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
56066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
56166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
56266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
56366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
56495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file.
56595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded.
56666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
56766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
5686343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
56966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
57066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the oat file from a different dex file so it looks out of date.
57166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc2(), dex_location);
5727bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
57366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
57466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the odex file
57566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
5767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
57766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
57866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Strip the dex file.
57966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
58066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
58166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
5827bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
58366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
5847bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
5857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
5867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
5877bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
5887bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,  // Can't run dex2oat because dex file is stripped.
5897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
59066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
59166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
59266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
59366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
59466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
59566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
59666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
59766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
59866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
5999b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
60066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
60166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Make the oat file up to date.
60266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
603ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
604ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
60566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
6077bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
6087bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,  // Can't run dex2oat because dex file is stripped.
6097bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
61066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
61166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
61266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
61366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
61466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
61566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
61666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
61766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
61866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
61966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
6209b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
62166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
62266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify we can load the dex files from it.
62366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
62466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
62566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
62666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
62766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
62866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
62966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
63066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6319b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
6329b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// OAT file. Expect: The status is kNoDexOptNeeded.
6339b994ea841eaaefbdda652251894a74db9cefcc8Richard UhlerTEST_F(OatFileAssistantTest, ResourceOnlyDex) {
6349b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
6359b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6369b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
6379b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6389b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Verify the status.
6397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
6409b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
6427bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
6437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
6447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
6457bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
6467bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
6479b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6489b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
6499b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
6509b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
6519b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
6529b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
6539b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
6549b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
6559b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
6569b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
6579b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6589b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Make the oat file up to date. This should have no effect.
6599b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  std::string error_msg;
660ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
661ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
6629b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6637bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
6647bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
6659b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6669b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
6679b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
6689b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
6699b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
6709b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
6719b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
6729b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
6739b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
6749b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
6759b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler}
6769b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
67795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file, no ODEX file and an OAT file that needs
67895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// relocation.
67995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kSelfPatchOatNeeded.
68095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerTEST_F(OatFileAssistantTest, SelfRelocation) {
68195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string dex_location = GetScratchDir() + "/SelfRelocation.jar";
68295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string oat_location = GetOdexDir() + "/SelfRelocation.oat";
68395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
68495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Create the dex and odex files
68595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  Copy(GetDexSrc1(), dex_location);
6867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
68795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
68895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
6897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_location.c_str(), kRuntimeISA, false, true);
69095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
6917bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
6927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
6937bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded,
6947bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
6957bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
6967bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
69795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
69895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
69995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
70095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
70195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
70295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
70395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
70495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation());
70595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
70695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
7079b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
70895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
70995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Make the oat file up to date.
71095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string error_msg;
711ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
712ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
71395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
7147bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
7157bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
71695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
71795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
71895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
71995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
72095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
72195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
72295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
72395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
72495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
72595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
7269b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
72795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
72895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
72995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
73095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
73195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
73295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
73395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(1u, dex_files.size());
73495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler}
73595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
7361c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler// Case: We have a DEX file, no ODEX file and an OAT file that needs
7371c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler// relocation but doesn't have patch info.
7381c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler// Expect: The status is kDex2OatNeeded, because we can't run patchoat.
7391c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard UhlerTEST_F(OatFileAssistantTest, NoSelfRelocation) {
7401c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::string dex_location = GetScratchDir() + "/NoSelfRelocation.jar";
7411c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::string oat_location = GetOdexDir() + "/NoSelfRelocation.oat";
7421c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
7431c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // Create the dex and odex files
7441c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  Copy(GetDexSrc1(), dex_location);
7451c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  GenerateNoPatchOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
7461c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
7471c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
7481c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler      oat_location.c_str(), kRuntimeISA, false, true);
7491c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
7501c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
7511c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
7521c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
7531c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // Make the oat file up to date.
7541c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::string error_msg;
755ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
756ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
7571c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
7581c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
7591c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
7601c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
7611c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
7621c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
7631c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
7641c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
7651c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  EXPECT_EQ(1u, dex_files.size());
7661c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler}
7671c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
76866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
76966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// OAT files both have patch delta of 0.
77095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: It shouldn't crash, and status is kPatchOatNeeded.
77166d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OdexOatOverlap) {
77266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
7736343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
7746343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
77566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
77666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
77766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
7787bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
77966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the oat file by copying the odex so they are located in the same
78166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // place in memory.
78266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(odex_location, oat_location);
78366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify things don't go bad.
78566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
7867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_location.c_str(), kRuntimeISA, false, true);
78766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
7887bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
7897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
79066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
79166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
79266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
79366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
79466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
79566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
79666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
79766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
7989b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
79966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
80066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Things aren't relocated, so it should fall back to interpreted.
80166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
80266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
803f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler
80466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
80566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
80666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
80766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
80866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
80966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
81066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
81195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
81266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
81366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
8146343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
81566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
81666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
81766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
8187bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
81966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
82066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
8217bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
82266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
8237bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8247bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
8257bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
8267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
82766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
82866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
829ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
830ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
831ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
832ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.OatFileExists());
833ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
834ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
835ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
836ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil}
837ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
8387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
8397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
8407bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
8417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
8427bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
843ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
844ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  // Create the dex and odex files
845ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  Copy(GetDexSrc1(), dex_location);
8467bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime);
847ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
848ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  // Verify the status.
8497bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
850ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
8517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8527bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
8537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
8547bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
855ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
856ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
85766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
85866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
85966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
86066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
86166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
86266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
8639b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
86466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
86566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
86666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
86766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file.
86866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadOatUpToDate) {
86966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
87066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
87166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
8727bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
87366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
87466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an oat file assistant.
8757bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
8767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
8777bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
8787bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  ASSERT_TRUE(oat_file.get() != nullptr);
8797bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file->IsExecutable());
8807bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::vector<std::unique_ptr<const DexFile>> dex_files;
8817bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
8827bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(1u, dex_files.size());
8837bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe}
8847bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
8857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and up-to-date interpret-only OAT file for it.
8867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: We should still load the oat file as executable.
8877bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
8887bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
8897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
8907bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  Copy(GetDexSrc1(), dex_location);
8917bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kInterpretOnly);
8927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
8937bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  // Load the oat using an oat file assistant.
8947bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
89566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
89666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
89766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
89866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
89966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
90066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
90166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
90266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
90366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
90466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
90566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Loading non-executable should load the oat non-executable.
90666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
90766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
90866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
90966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
9107bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
91166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
91266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an oat file assistant.
9137bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
91466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
91566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
91666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
91766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
91866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
91966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
92066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
92166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
92266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
92366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file.
92466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file from an alternative oat
92566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// location.
92666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
92766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
92866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
92966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
93066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
93166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
93266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(
9337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
93466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
935ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
936ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
93766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
93866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
93966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
94066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
94166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
94266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
94366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
94466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
94566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
94666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
94766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify it didn't create an oat in the default location.
9487bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false, false);
94966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(ofm.OatFileExists());
95066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
95166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9528327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We have a DEX file but can't write the oat file.
9538327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to make the oat file up to date.
9548327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) {
9558327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar";
9568327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9578327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  // Make the oat location unwritable by inserting some non-existent
9588327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  // intermediate directories.
9598327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat";
9608327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9618327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  Copy(GetDexSrc1(), dex_location);
9628327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9638327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  OatFileAssistant oat_file_assistant(
9647bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
9658327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string error_msg;
966ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateNotAttempted,
967ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg));
9688327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9698327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
9708327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  ASSERT_TRUE(oat_file.get() == nullptr);
9718327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler}
9728327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9738327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We don't have a DEX file and can't write the oat file.
9748327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to generate the oat file without crashing.
9758327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, GenNoDex) {
9768327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
9778327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string oat_location = GetScratchDir() + "/GenNoDex.oat";
9788327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9798327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  OatFileAssistant oat_file_assistant(
9807bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
9818327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string error_msg;
982ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
983ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.GenerateOatFile(CompilerFilter::kSpeed, &error_msg));
9848327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler}
9858327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
98666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Turn an absolute path into a path relative to the current working
98766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// directory.
98866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstatic std::string MakePathRelative(std::string target) {
98966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  char buf[MAXPATHLEN];
99066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string cwd = getcwd(buf, MAXPATHLEN);
99166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
99266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Split the target and cwd paths into components.
99366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> target_path;
99466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> cwd_path;
99566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Split(target, '/', &target_path);
99666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Split(cwd, '/', &cwd_path);
99766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
99866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reverse the path components, so we can use pop_back().
99966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(target_path.begin(), target_path.end());
100066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(cwd_path.begin(), cwd_path.end());
100166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
100266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Drop the common prefix of the paths. Because we reversed the path
100366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // components, this becomes the common suffix of target_path and cwd_path.
100466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  while (!target_path.empty() && !cwd_path.empty()
100566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      && target_path.back() == cwd_path.back()) {
100666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    target_path.pop_back();
100766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cwd_path.pop_back();
100866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
100966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
101066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // For each element of the remaining cwd_path, add '..' to the beginning
101166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // of the target path. Because we reversed the path components, we add to
101266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // the end of target_path.
101366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (unsigned int i = 0; i < cwd_path.size(); i++) {
101466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    target_path.push_back("..");
101566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
101666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
101766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reverse again to get the right path order, and join to get the result.
101866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(target_path.begin(), target_path.end());
101966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return Join(target_path, '/');
102066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
102166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
102266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-absolute path to Dex location.
102366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Not sure, but it shouldn't crash.
102466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
102566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
102666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), abs_dex_location);
102766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
102866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = MakePathRelative(abs_dex_location);
10297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
103066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
103166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
10327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
10337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
103466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
103566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
103666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
103766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
103866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
103966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
104066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
104166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
104266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Very short, non-existent Dex location.
10439b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: kNoDexOptNeeded.
104466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, ShortDexLocation) {
104566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = "/xx";
104666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10477bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
104866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
104966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
10507bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
10517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
105266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
105366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
105466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
105566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
105666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
105766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
10589b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
105966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10609b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Trying to make it up to date should have no effect.
106166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
1062ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
1063ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg));
10649b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(error_msg.empty());
106566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
106666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
106766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-standard extension for dex file.
106895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
106966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LongDexExtension) {
107066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
107166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
107266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10737bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
107466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10757bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
10767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
107766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
107866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
107966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
108066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
108166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
108266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
108366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
108466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
108566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
108666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
108766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// A task to generate a dex location. Used by the RaceToGenerate test.
108866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass RaceGenerateTask : public Task {
108966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
109066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
10915872d7cd6ceffe67550d0b021191ec66f1a34c5dJeff Hao    : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr)
109266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  {}
109366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10944b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain  void Run(Thread* self ATTRIBUTE_UNUSED) {
109566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Load the dex files, and save a pointer to the loaded oat file, so that
109666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // we can verify only one oat file was loaded for the dex location.
109766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::unique_ptr<const DexFile>> dex_files;
109866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::string> error_msgs;
1099e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier    const OatFile* oat_file = nullptr;
1100f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
1101f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier        dex_location_.c_str(),
1102f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier        oat_location_.c_str(),
1103fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        /*class_loader*/nullptr,
1104fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        /*dex_elements*/nullptr,
1105e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier        &oat_file,
1106f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier        &error_msgs);
110766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
110807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
110907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
1110e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier    CHECK_EQ(loaded_oat_file_, oat_file);
111166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
111266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
111366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile* GetLoadedOatFile() const {
111466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return loaded_oat_file_;
111566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
111666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
111766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private:
111866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location_;
111966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string oat_location_;
112066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile* loaded_oat_file_;
112166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
112266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
112366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Test the case where multiple processes race to generate an oat file.
112466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// This simulates multiple processes using multiple threads.
112566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//
1126f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// We want unique Oat files to be loaded even when there is a race to load.
1127f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// TODO: The test case no longer tests locking the way it was intended since we now get multiple
1128f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// copies of the same Oat files mapped at different locations.
112966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, RaceToGenerate) {
113066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
11316343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
113266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
113366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // We use the lib core dex file, because it's large, and hopefully should
113466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // take a while to generate.
1135d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  Copy(GetLibCoreDexFileNames()[0], dex_location);
113666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
113766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const int kNumThreads = 32;
113866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Thread* self = Thread::Current();
113966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
114066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
114166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (int i = 0; i < kNumThreads; i++) {
114266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
114366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    thread_pool.AddTask(self, task.get());
114466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    tasks.push_back(std::move(task));
114566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
114666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  thread_pool.StartWorkers(self);
114766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  thread_pool.Wait(self, true, false);
114866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1149f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier  // Verify every task got a unique oat file.
1150f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier  std::set<const OatFile*> oat_files;
115166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (auto& task : tasks) {
1152f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    const OatFile* oat_file = task->GetLoadedOatFile();
1153f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
1154f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    oat_files.insert(oat_file);
115566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
115666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
115766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
115866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
115966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled.
116066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable.
116166d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
116266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
11636343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
116466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
116566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
116666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
11677bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
116866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
116966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an executable oat file assistant.
11707bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
117166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
117266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
117366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
117466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
117566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
117666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
117766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
117866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
117966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
118066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
118166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled.
118266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable.
118366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
118466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
11856343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
118666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
118766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
118866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
11897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
119066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
119166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an executable oat file assistant.
11927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
119366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
119466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
119566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
119666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
119766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
119866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
119966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(2u, dex_files.size());
120066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
120166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
120266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) {
120366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
120466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string odex_file;
120566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
120666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
1207b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
12086343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
120966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
121066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
1211b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
12126343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
121366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
121466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
1215b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "nopath.jar", kArm, &odex_file, &error_msg));
121666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
1217b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
121866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
121966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
122023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// Verify the dexopt status values from dalvik.system.DexFile
122123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// match the OatFileAssistant::DexOptStatus values.
122223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard UhlerTEST_F(OatFileAssistantTest, DexOptStatusValues) {
122323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ScopedObjectAccess soa(Thread::Current());
122423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  StackHandleScope<1> hs(soa.Self());
122523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ClassLinker* linker = Runtime::Current()->GetClassLinker();
122623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  Handle<mirror::Class> dexfile(
122723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
122823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(dexfile.Get() == nullptr);
122923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  linker->EnsureInitialized(soa.Self(), dexfile, true, true);
123023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1231c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
123223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I");
123323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(no_dexopt_needed == nullptr);
123423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
123523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get()));
123623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1237c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* dex2oat_needed = mirror::Class::FindStaticField(
123823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "DEX2OAT_NEEDED", "I");
123923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(dex2oat_needed == nullptr);
124023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
124123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get()));
124223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1243c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* patchoat_needed = mirror::Class::FindStaticField(
124423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "PATCHOAT_NEEDED", "I");
124523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(patchoat_needed == nullptr);
124623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
124723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get()));
124823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1249c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
125023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I");
125123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(self_patchoat_needed == nullptr);
125223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
125323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get()));
125423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler}
125566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
125666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// TODO: More Tests:
12577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe//  * Image checksum change is out of date for kIntepretOnly, but not
12587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe//    kVerifyAtRuntime. But target of kVerifyAtRuntime still says current
12597bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe//    kInterpretOnly is out of date.
126066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test class linker falls back to unquickened dex for DexNoOat
126166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test class linker falls back to unquickened dex for MultiDexNoOat
126266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test using secondary isa
126366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test for status of oat while oat is being generated (how?)
126466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test case where 32 and 64 bit boot class paths differ,
126566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//      and we ask IsInBootClassPath for a class in exactly one of the 32 or
126666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//      64 bit boot class paths.
126766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test unexpected scenarios (?):
126866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    - Dex is stripped, don't have odex.
126966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    - Oat file corrupted after status check, before reload unexecutable
127066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    because it's unrelocated and no dex2oat
1271d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle//  * Test unrelocated specific target compilation type can be relocated to
1272d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle//    make it up to date.
127366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
127466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}  // namespace art
1275