oat_file_assistant_test.cc revision 5872d7cd6ceffe67550d0b021191ec66f1a34c5d
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 "oat_file_assistant.h"
1866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <algorithm>
2066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <fstream>
2166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <string>
2266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <vector>
2366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/param.h>
2466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <backtrace/BacktraceMap.h>
2666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <gtest/gtest.h>
2766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
28c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h"
293481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h"
3066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "common_runtime_test.h"
31bb9c6b1c55e9e2308b4f5892a398a8837231fdbdAndreas Gampe#include "compiler_callbacks.h"
32f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler#include "gc/space/image_space.h"
3366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "mem_map.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
4266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass OatFileAssistantTest : public CommonRuntimeTest {
4366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
4466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void SetUp() {
4566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ReserveImageSpace();
4666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    CommonRuntimeTest::SetUp();
4766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Create a scratch directory to work from.
4966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    scratch_dir_ = android_data_ + "/OatFileAssistantTest";
5066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700));
5166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
526343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    // Create a subdirectory in scratch for odex files.
536343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    odex_oat_dir_ = scratch_dir_ + "/oat";
546343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700));
556343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler
566343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA));
576343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700));
586343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler
5966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Verify the environment is as we expect
6166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    uint32_t checksum;
6266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string error_msg;
6366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(OS::FileExists(GetImageFile().c_str()))
6466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected pre-compiled boot image to be at: " << GetImageFile();
6566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str()))
6666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected dex file to be at: " << GetDexSrc1();
6766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str()))
6866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected stripped dex file to be at: " << GetStrippedDexSrc1();
69b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin    ASSERT_FALSE(DexFile::GetChecksum(GetStrippedDexSrc1().c_str(), &checksum, &error_msg))
7066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1();
7166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str()))
7266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected dex file to be at: " << GetDexSrc2();
7367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
7467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    // GetMultiDexSrc2 should have the same primary dex checksum as
7567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    // GetMultiDexSrc1, but a different secondary dex checksum.
7667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    std::vector<std::unique_ptr<const DexFile>> multi1;
7767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_TRUE(DexFile::Open(GetMultiDexSrc1().c_str(),
78b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin          GetMultiDexSrc1().c_str(), &error_msg, &multi1)) << error_msg;
7967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_GT(multi1.size(), 1u);
8067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
8167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    std::vector<std::unique_ptr<const DexFile>> multi2;
8267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_TRUE(DexFile::Open(GetMultiDexSrc2().c_str(),
83b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin          GetMultiDexSrc2().c_str(), &error_msg, &multi2)) << error_msg;
8467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_GT(multi2.size(), 1u);
8567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
8667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum());
8767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_NE(multi1[1]->GetLocationChecksum(), multi2[1]->GetLocationChecksum());
8866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
8966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
91892fc96694b51ac7a896dacd75af5b235f955825Richard Uhler    // options->push_back(std::make_pair("-verbose:oat", nullptr));
9266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Set up the image location.
9466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    options->push_back(std::make_pair("-Ximage:" + GetImageLocation(),
9566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          nullptr));
9666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Make sure compilercallbacks are not set so that relocation will be
9766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // enabled.
98bb9c6b1c55e9e2308b4f5892a398a8837231fdbdAndreas Gampe    callbacks_.reset();
9966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
10066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void PreRuntimeCreate() {
10266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    UnreserveImageSpace();
10366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
10466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void PostRuntimeCreate() {
10666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ReserveImageSpace();
10766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
10866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void TearDown() {
1106343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ClearDirectory(odex_dir_.c_str());
1116343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ASSERT_EQ(0, rmdir(odex_dir_.c_str()));
1126343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler
1136343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ClearDirectory(odex_oat_dir_.c_str());
1146343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str()));
11566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
11666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ClearDirectory(scratch_dir_.c_str());
11766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_EQ(0, rmdir(scratch_dir_.c_str()));
11866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
11966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    CommonRuntimeTest::TearDown();
12066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
12166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void Copy(std::string src, std::string dst) {
12366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::ifstream  src_stream(src, std::ios::binary);
12466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::ofstream  dst_stream(dst, std::ios::binary);
12566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    dst_stream << src_stream.rdbuf();
12766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
12866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Returns the directory where the pre-compiled core.art can be found.
13066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // TODO: We should factor out this into common tests somewhere rather than
13166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // re-hardcoding it here (This was copied originally from the elf writer
13266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // test).
13366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetImageDirectory() {
13466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (IsHost()) {
13566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      const char* host_dir = getenv("ANDROID_HOST_OUT");
1362cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier      CHECK(host_dir != nullptr);
13766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      return std::string(host_dir) + "/framework";
13866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    } else {
13966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      return std::string("/data/art-test");
14066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
14166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
14266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
14366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetImageLocation() {
14466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetImageDirectory() + "/core.art";
14566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
14666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
14766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetImageFile() {
14866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA)
14966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      + "/core.art";
15066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
15166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
15266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetDexSrc1() {
15366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetTestDexFileName("Main");
15466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
15566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
15666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex
15766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // file stripped.
15866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetStrippedDexSrc1() {
15966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetTestDexFileName("MainStripped");
16066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
16166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
16266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetMultiDexSrc1() {
16366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetTestDexFileName("MultiDex");
16466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
16566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
16667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Returns the path to a multidex file equivalent to GetMultiDexSrc2, but
16767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // with the contents of the secondary dex file changed.
16867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  std::string GetMultiDexSrc2() {
16967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    return GetTestDexFileName("MultiDexModifiedSecondary");
17067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  }
17167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
17266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetDexSrc2() {
17366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetTestDexFileName("Nested");
17466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
17566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
17666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Scratch directory, for dex and odex files (oat files will go in the
17766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // dalvik cache).
17866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetScratchDir() {
17966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return scratch_dir_;
18066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
18166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1826343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  // Odex directory is the subdirectory in the scratch directory where odex
18366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // files should be located.
1846343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string GetOdexDir() {
1856343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    return odex_dir_;
18666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
18766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
18893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler  // Generate a non-PIC odex file for the purposes of test.
18994f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler  // The generated odex file will be un-relocated.
19066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void GenerateOdexForTest(const std::string& dex_location,
1917bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                           const std::string& odex_location,
1927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                           CompilerFilter::Filter filter) {
19393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // To generate an un-relocated odex file, we first compile a relocated
19493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // version of the file, then manually call patchoat to make it look as if
19593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // it is unrelocated.
19693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::string relocated_odex_location = odex_location + ".relocated";
19793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::vector<std::string> args;
19893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--dex-file=" + dex_location);
19993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--oat-file=" + relocated_odex_location);
2007bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
20193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
20293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // We need to use the quick compiler to generate non-PIC code, because
20393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // the optimizing compiler always generates PIC.
20493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--compiler-backend=Quick");
2057bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    args.push_back("--include-patch-information");
20693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
20793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::string error_msg;
20893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
20993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
21093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // Use patchoat to unrelocate the relocated odex file.
21193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    Runtime* runtime = Runtime::Current();
21293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::vector<std::string> argv;
21393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back(runtime->GetPatchoatExecutable());
21493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA)));
21593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back("--input-oat-file=" + relocated_odex_location);
21693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back("--output-oat-file=" + odex_location);
21793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back("--base-offset-delta=0x00008000");
21893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::string command_line(Join(argv, ' '));
21993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    ASSERT_TRUE(Exec(argv, &error_msg)) << error_msg;
22093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
22193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // Verify the odex file was generated as expected and really is
22293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // unrelocated.
223bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier    std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(),
224bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     odex_location.c_str(),
225bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     nullptr,
226bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     nullptr,
227bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     false,
228bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     /*low_4gb*/false,
229bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     dex_location.c_str(),
230bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     &error_msg));
23193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
2327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    EXPECT_FALSE(odex_file->IsPic());
2331c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    EXPECT_TRUE(odex_file->HasPatchInfo());
2347bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    EXPECT_EQ(filter, odex_file->GetCompilerFilter());
23593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
2367bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    if (CompilerFilter::IsCompilationEnabled(filter)) {
2377bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      const std::vector<gc::space::ImageSpace*> image_spaces =
238dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao        runtime->GetHeap()->GetBootImageSpaces();
2397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr);
2407bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      const ImageHeader& image_header = image_spaces[0]->GetImageHeader();
2417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      const OatHeader& oat_header = odex_file->GetOatHeader();
2424f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao      uint32_t combined_checksum = OatFileAssistant::CalculateCombinedImageChecksum();
2434f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao      EXPECT_EQ(combined_checksum, oat_header.GetImageFileLocationOatChecksum());
2447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()),
2457bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe          oat_header.GetImageFileLocationOatDataBegin());
2467bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta());
2477bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    }
24893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler  }
24993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
25093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler  void GeneratePicOdexForTest(const std::string& dex_location,
2517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                              const std::string& odex_location,
2527bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                              CompilerFilter::Filter filter) {
25393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // Temporarily redirect the dalvik cache so dex2oat doesn't find the
25493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // relocated image file.
25566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp";
25666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    setenv("ANDROID_DATA", android_data_tmp.c_str(), 1);
25766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::string> args;
25866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("--dex-file=" + dex_location);
25966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("--oat-file=" + odex_location);
2607bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
26193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--compile-pic");
26266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("--runtime-arg");
26366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("-Xnorelocate");
26466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string error_msg;
265b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
26666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    setenv("ANDROID_DATA", android_data_.c_str(), 1);
26794f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler
26894f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler    // Verify the odex file was generated as expected.
269bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier    std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(),
270bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     odex_location.c_str(),
271bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     nullptr,
272bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     nullptr,
273bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     false,
274bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     /*low_4gb*/false,
275bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     dex_location.c_str(),
276bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier                                                     &error_msg));
27794f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
27893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    EXPECT_TRUE(odex_file->IsPic());
2797bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe    EXPECT_EQ(filter, odex_file->GetCompilerFilter());
280d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  }
281ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
2821c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // Generate a non-PIC odex file without patch information for the purposes
2831c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // of test.  The generated odex file will be un-relocated.
2841c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // TODO: This won't work correctly if we depend on the boot image being
2851c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // randomly relocated by a non-zero amount. We should have a better solution
2861c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // for avoiding that flakiness and duplicating code to generate odex and oat
2871c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // files for test.
2881c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  void GenerateNoPatchOdexForTest(const std::string& dex_location,
2891c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                  const std::string& odex_location,
2901c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                  CompilerFilter::Filter filter) {
2911c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    // Temporarily redirect the dalvik cache so dex2oat doesn't find the
2921c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    // relocated image file.
2931c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp";
2941c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    setenv("ANDROID_DATA", android_data_tmp.c_str(), 1);
2951c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    std::vector<std::string> args;
2961c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    args.push_back("--dex-file=" + dex_location);
2971c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    args.push_back("--oat-file=" + odex_location);
2981c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
2991c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    args.push_back("--runtime-arg");
3001c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    args.push_back("-Xnorelocate");
3011c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    std::string error_msg;
3021c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
3031c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    setenv("ANDROID_DATA", android_data_.c_str(), 1);
3041c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
3051c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    // Verify the odex file was generated as expected.
3061c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(),
3071c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                                     odex_location.c_str(),
3081c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                                     nullptr,
3091c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                                     nullptr,
3101c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                                     false,
3111c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                                     /*low_4gb*/false,
3121c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                                     dex_location.c_str(),
3131c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler                                                     &error_msg));
3141c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
3151c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    EXPECT_FALSE(odex_file->IsPic());
3161c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    EXPECT_FALSE(odex_file->HasPatchInfo());
3171c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler    EXPECT_EQ(filter, odex_file->GetCompilerFilter());
3181c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  }
3191c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
32066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private:
32166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reserve memory around where the image will be loaded so other memory
32266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // won't conflict when it comes time to load the image.
32366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // This can be called with an already loaded image to reserve the space
32466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // around it.
32566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void ReserveImageSpace() {
32666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    MemMap::Init();
32766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
32866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Ensure a chunk of memory is reserved for the image space.
32966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    uintptr_t reservation_start = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MIN_DELTA;
33066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    uintptr_t reservation_end = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MAX_DELTA
3313dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi        // Include the main space that has to come right after the
3323dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi        // image in case of the GSS collector.
3333dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi        + 384 * MB;
33466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
33566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
33666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
33766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    for (BacktraceMap::const_iterator it = map->begin();
33866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reservation_start < reservation_end && it != map->end(); ++it) {
3393efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end));
3403efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      reservation_start = std::max(reservation_start, it->end);
3413efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    }
3423efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    ReserveImageSpaceChunk(reservation_start, reservation_end);
3433efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  }
34466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
3453efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  // Reserve a chunk of memory for the image space in the given range.
3463efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  // Only has effect for chunks with a positive number of bytes.
3473efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) {
3483efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    if (start < end) {
3493efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      std::string error_msg;
35066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      image_reservation_.push_back(std::unique_ptr<MemMap>(
35166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          MemMap::MapAnonymous("image reservation",
3523efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler              reinterpret_cast<uint8_t*>(start), end - start,
353b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin              PROT_NONE, false, false, &error_msg)));
35466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
35566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      LOG(INFO) << "Reserved space for image " <<
35666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
35766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reinterpret_cast<void*>(image_reservation_.back()->End());
35866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
35966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
36066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
36166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
36266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Unreserve any memory reserved by ReserveImageSpace. This should be called
36366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // before the image is loaded.
36466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void UnreserveImageSpace() {
36566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    image_reservation_.clear();
36666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
36766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
36866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string scratch_dir_;
3696343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_oat_dir_;
3706343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_dir_;
37166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<MemMap>> image_reservation_;
37266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
37366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
37466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass OatFileAssistantNoDex2OatTest : public OatFileAssistantTest {
37566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
37666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
37766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    OatFileAssistantTest::SetUpRuntimeOptions(options);
37866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    options->push_back(std::make_pair("-Xnodex2oat", nullptr));
37966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
38066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
38166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
38266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Generate an oat file for the purposes of test, as opposed to testing
38366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// generation of oat files.
3847bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampestatic void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) {
3857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  // Use an oat file assistant to find the proper oat location.
3867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant ofa(dex_location, kRuntimeISA, false, false);
3877bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  const std::string* oat_location = ofa.OatFileName();
3887bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  ASSERT_TRUE(oat_location != nullptr);
38966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
3907bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::vector<std::string> args;
3917bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--dex-file=" + std::string(dex_location));
3927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--oat-file=" + *oat_location);
3937bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
3947bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--runtime-arg");
3957bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("-Xnorelocate");
39666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
3977bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
3987bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
3997bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  // Verify the oat file was generated as expected.
4007bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location->c_str(),
4017bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  oat_location->c_str(),
4027bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  nullptr,
4037bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  nullptr,
4047bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  false,
4057bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  /*low_4gb*/false,
4067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  dex_location,
4077bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                                  &error_msg));
4087bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  ASSERT_TRUE(oat_file.get() != nullptr) << error_msg;
4097bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(filter, oat_file->GetCompilerFilter());
41066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
41166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
41266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, but no OAT file for it.
41395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
41466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexNoOat) {
41566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
41666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
41766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4187bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
41966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4207bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4217bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
4227bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4237bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
4247bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4257bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
4267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4277bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
42866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
42966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
43066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
43166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
43266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
43366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
43495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
43566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
43666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
43766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
43866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
43995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
4409b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
44166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
44266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
44366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have no DEX file and no OAT file.
4449b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
44566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NoDexNoOat) {
44666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
44766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4487bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
44966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4507bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
4517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
4529b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
4539b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
4549b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Trying to make the oat file up to date should not fail or crash.
4559b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  std::string error_msg;
456ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
457ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg));
4589b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
4599b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Trying to get the best oat file should fail, but not crash.
46066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
46166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(nullptr, oat_file.get());
46266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
46366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
46466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
46595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded.
46666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatUpToDate) {
46766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
46866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
4697bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
47066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4717bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
4727bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
4737bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
4747bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
4757bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
4767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
4777bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
4787bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
4797bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4807bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
48166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
48266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
48366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
48466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
48566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
48666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
48766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
48866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
48966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
49095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
4919b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
49266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
49366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4947bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and speed-profile OAT file for it.
4957bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: The status is kNoDexOptNeeded if the profile hasn't changed.
4967bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
4977bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
4987bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  Copy(GetDexSrc1(), dex_location);
4997bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
5007bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
5017bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
5027bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
5037bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
5047bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
5057bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
5067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
5077bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
5087bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
5097bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
5107bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
5117bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
5127bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OatFileExists());
5137bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
5147bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
5157bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
5167bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
5177bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
5187bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe}
5197bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
5207bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and speed-profile OAT file for it.
5217bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: The status is kNoDex2OatNeeded if the profile has changed.
5227bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, ProfileOatOutOfDate) {
5237bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string dex_location = GetScratchDir() + "/ProfileOatOutOfDate.jar";
5247bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  Copy(GetDexSrc1(), dex_location);
5257bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
5267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
5277bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true, false);
5287bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
5297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
5307bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
5317bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
5327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
5337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
5347bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
5357bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
5367bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
5377bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
5387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OatFileExists());
5397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
5407bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
5417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
5427bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
5437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
5447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe}
5457bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
54666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it.
54795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded and we load all dex files.
54866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
54966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
55066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
5517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
55266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
5537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
5547bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
5557bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
5569b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
55795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
55895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Verify we can load both dex files.
559e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
560e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
561e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
562e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
563e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
564e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ(2u, dex_files.size());
565e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler}
566e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
56767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Case: We have a MultiDEX file where the secondary dex file is out of date.
56867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Expect: The status is kDex2OatNeeded.
56967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard UhlerTEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) {
57067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar";
57167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
57267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Compile code for GetMultiDexSrc1.
57367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  Copy(GetMultiDexSrc1(), dex_location);
5747bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
57567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
57667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
57767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // is out of date.
57867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  Copy(GetMultiDexSrc2(), dex_location);
57967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
5807bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
5817bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
5827bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
5839b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
58467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler}
58567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
586e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it with relative
587e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// encoded dex locations.
58895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The oat file status is kNoDexOptNeeded.
589e5fed03772144595c0904faf3d6974cc55214c8cRichard UhlerTEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
590e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
5916343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
592e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
593e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Create the dex file
594e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
595e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
596e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Create the oat file with relative encoded dex location.
597e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::vector<std::string> args;
598e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--dex-file=" + dex_location);
599e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
600e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--oat-file=" + oat_location);
6017bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  args.push_back("--compiler-filter=speed");
602e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
603e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::string error_msg;
604b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
605e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
606e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Verify we can load both dex files.
607e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
608e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                                      oat_location.c_str(),
6097bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe                                      kRuntimeISA, false, true);
610e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
61166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
61266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
61366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
614e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
61566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(2u, dex_files.size());
61666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
61766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
61895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file and out-of-date OAT file.
61995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
62066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatOutOfDate) {
62166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar";
62266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
62366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // We create a dex, generate an oat for it, then overwrite the dex with a
62466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // different dex to make the oat out of date.
62566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
6267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
62766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc2(), dex_location);
62866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
6307bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
6317bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
6327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
6337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
63466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
63566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
63666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
63766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
63866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
63966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
64066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
64166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
6429b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
64366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
64466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
64566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, but no OAT file.
64695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded.
64766d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexOdexNoOat) {
64866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
6496343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
65066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
65166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
65266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
6537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
65466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
65566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
6567bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
65766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
6597bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
6607bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
6617bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
66266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
66366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
66466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
66566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
66666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
66766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
66866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
66966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
67066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
6719b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
6725f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler
6735f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  // We should still be able to get the non-executable odex file to run from.
6745f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
6755f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
67666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
67766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
67866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a stripped DEX file and an ODEX file, but no OAT file.
67995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded
68066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
68166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
6826343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
68366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
68466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
68566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
6867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
68766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
68866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Strip the dex file
68966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
69066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
69166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
6927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
69366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6947bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
6957bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
69666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
69766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
69866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
69966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
70066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
70166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
70266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
70366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
7049b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
70566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
70666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Make the oat file up to date.
70766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
708ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
709ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
71066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
7117bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
7127bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
71366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
71466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
71566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
71666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
71766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
71866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
71966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
72066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
7219b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
72266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
72366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify we can load the dex files from it.
72466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
72566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
72666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
72766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
72866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
72966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
73066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
73166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
73295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file.
73395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded.
73466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
73566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
7366343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
73766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
73866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the oat file from a different dex file so it looks out of date.
73966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc2(), dex_location);
7407bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
74166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
74266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the odex file
74366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
7447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
74566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
74666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Strip the dex file.
74766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
74866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
74966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
7507bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
75166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
7527bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
7537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
7547bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
7557bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
7567bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,  // Can't run dex2oat because dex file is stripped.
7577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
75866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
75966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
76066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
76166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
76266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
76366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
76466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
76566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
76666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
7679b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
76866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
76966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Make the oat file up to date.
77066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
771ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
772ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
77366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
7747bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
7757bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
7767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,  // Can't run dex2oat because dex file is stripped.
7777bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
77866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
77966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
78066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
78166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
78266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
78366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
78466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
78566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
78666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
78766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
7889b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
78966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
79066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify we can load the dex files from it.
79166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
79266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
79366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
79466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
79566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
79666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
79766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
79866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
7999b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
8009b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// OAT file. Expect: The status is kNoDexOptNeeded.
8019b994ea841eaaefbdda652251894a74db9cefcc8Richard UhlerTEST_F(OatFileAssistantTest, ResourceOnlyDex) {
8029b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
8039b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
8049b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
8059b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
8069b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Verify the status.
8077bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
8089b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
8097bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8107bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
8117bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8127bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
8137bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8147bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
8159b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
8169b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
8179b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
8189b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
8199b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
8209b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
8219b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
8229b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
8239b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
8249b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
8259b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
8269b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Make the oat file up to date. This should have no effect.
8279b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  std::string error_msg;
828ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
829ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
8309b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
8317bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
8339b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
8349b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
8359b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
8369b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
8379b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
8389b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
8399b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
8409b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
8419b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
8429b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
8439b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler}
8449b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
84595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file, no ODEX file and an OAT file that needs
84695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// relocation.
84795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kSelfPatchOatNeeded.
84895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerTEST_F(OatFileAssistantTest, SelfRelocation) {
84995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string dex_location = GetScratchDir() + "/SelfRelocation.jar";
85095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string oat_location = GetOdexDir() + "/SelfRelocation.oat";
85195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
85295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Create the dex and odex files
85395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  Copy(GetDexSrc1(), dex_location);
8547bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
85595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
85695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
8577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_location.c_str(), kRuntimeISA, false, true);
85895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
8597bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8607bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
8617bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded,
8627bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
8637bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
8647bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
86595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
86695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
86795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
86895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
86995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
87095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
87195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
87295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation());
87395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
87495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
8759b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
87695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
87795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Make the oat file up to date.
87895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string error_msg;
879ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
880ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
88195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
8827bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8837bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
88495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
88595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
88695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
88795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
88895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
88995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
89095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
89195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
89295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
89395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
8949b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
89595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
89695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
89795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
89895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
89995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
90095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
90195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(1u, dex_files.size());
90295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler}
90395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
9041c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler// Case: We have a DEX file, no ODEX file and an OAT file that needs
9051c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler// relocation but doesn't have patch info.
9061c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler// Expect: The status is kDex2OatNeeded, because we can't run patchoat.
9071c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard UhlerTEST_F(OatFileAssistantTest, NoSelfRelocation) {
9081c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::string dex_location = GetScratchDir() + "/NoSelfRelocation.jar";
9091c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::string oat_location = GetOdexDir() + "/NoSelfRelocation.oat";
9101c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
9111c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // Create the dex and odex files
9121c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  Copy(GetDexSrc1(), dex_location);
9131c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  GenerateNoPatchOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
9141c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
9151c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
9161c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler      oat_location.c_str(), kRuntimeISA, false, true);
9171c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
9181c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
9191c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
9201c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
9211c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  // Make the oat file up to date.
9221c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::string error_msg;
923ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
924ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
9251c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
9261c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
9271c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
9281c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
9291c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
9301c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
9311c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
9321c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
9331c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler  EXPECT_EQ(1u, dex_files.size());
9341c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler}
9351c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler
93666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
93766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// OAT files both have patch delta of 0.
93895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: It shouldn't crash, and status is kPatchOatNeeded.
93966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OdexOatOverlap) {
94066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
9416343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
9426343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
94366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
94466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
94566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
9467bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
94766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
94866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the oat file by copying the odex so they are located in the same
94966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // place in memory.
95066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(odex_location, oat_location);
95166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
95266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify things don't go bad.
95366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
9547bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_location.c_str(), kRuntimeISA, false, true);
95566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9567bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
9577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
95866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
95966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
96066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
96166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
96266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
96366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
96466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
96566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
9669b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
96766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
96866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Things aren't relocated, so it should fall back to interpreted.
96966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
97066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
971f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler
97266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
97366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
97466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
97566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
97666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
97766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
97866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
97995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
98066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
98166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
9826343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
98366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
98466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
98566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
9867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
98766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
98866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
9897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
99066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9917bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
9927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
9937bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
9947bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
99566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
99666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
997ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
998ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
999ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
1000ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.OatFileExists());
1001ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
1002ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
1003ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
1004ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil}
1005ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
10067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
10077bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
10087bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
10097bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
10107bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
1011ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
1012ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  // Create the dex and odex files
1013ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  Copy(GetDexSrc1(), dex_location);
10147bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime);
1015ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
1016ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  // Verify the status.
10177bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
1018ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
10197bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
10207bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
10217bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
10227bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1023ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
1024ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
102566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
102666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
102766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
102866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
102966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
103066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
10319b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
103266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
103366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
103466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
103566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file.
103666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadOatUpToDate) {
103766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
103866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
103966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
10407bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
104166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
104266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an oat file assistant.
10437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
10447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
10457bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
10467bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  ASSERT_TRUE(oat_file.get() != nullptr);
10477bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_TRUE(oat_file->IsExecutable());
10487bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::vector<std::unique_ptr<const DexFile>> dex_files;
10497bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
10507bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(1u, dex_files.size());
10517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe}
10527bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
10537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and up-to-date interpret-only OAT file for it.
10547bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: We should still load the oat file as executable.
10557bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
10567bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
10577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
10587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  Copy(GetDexSrc1(), dex_location);
10597bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kInterpretOnly);
10607bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe
10617bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  // Load the oat using an oat file assistant.
10627bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
106366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
106466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
106566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
106666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
106766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
106866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
106966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
107066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
107166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
107266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
107366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Loading non-executable should load the oat non-executable.
107466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
107566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
107666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
107766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
10787bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
107966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
108066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an oat file assistant.
10817bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
108266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
108366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
108466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
108566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
108666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
108766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
108866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
108966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
109066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
109166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file.
109266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file from an alternative oat
109366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// location.
109466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
109566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
109666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
109766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
109866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
109966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
110066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(
11017bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
110266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
1103ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
1104ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
110566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
110666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
110766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
110866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
110966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
111066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
111166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
111266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
111366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
111466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
111566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify it didn't create an oat in the default location.
11167bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false, false);
111766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(ofm.OatFileExists());
111866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
111966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
11208327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We have a DEX file but can't write the oat file.
11218327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to make the oat file up to date.
11228327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) {
11238327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar";
11248327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
11258327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  // Make the oat location unwritable by inserting some non-existent
11268327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  // intermediate directories.
11278327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat";
11288327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
11298327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  Copy(GetDexSrc1(), dex_location);
11308327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
11318327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  OatFileAssistant oat_file_assistant(
11327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
11338327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string error_msg;
1134ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  ASSERT_EQ(OatFileAssistant::kUpdateNotAttempted,
1135ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg));
11368327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
11378327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
11388327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  ASSERT_TRUE(oat_file.get() == nullptr);
11398327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler}
11408327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
11418327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We don't have a DEX file and can't write the oat file.
11428327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to generate the oat file without crashing.
11438327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, GenNoDex) {
11448327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
11458327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string oat_location = GetScratchDir() + "/GenNoDex.oat";
11468327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
11478327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  OatFileAssistant oat_file_assistant(
11487bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
11498327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string error_msg;
1150ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
1151ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.GenerateOatFile(CompilerFilter::kSpeed, &error_msg));
11528327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler}
11538327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
115466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Turn an absolute path into a path relative to the current working
115566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// directory.
115666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstatic std::string MakePathRelative(std::string target) {
115766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  char buf[MAXPATHLEN];
115866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string cwd = getcwd(buf, MAXPATHLEN);
115966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
116066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Split the target and cwd paths into components.
116166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> target_path;
116266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> cwd_path;
116366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Split(target, '/', &target_path);
116466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Split(cwd, '/', &cwd_path);
116566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
116666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reverse the path components, so we can use pop_back().
116766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(target_path.begin(), target_path.end());
116866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(cwd_path.begin(), cwd_path.end());
116966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
117066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Drop the common prefix of the paths. Because we reversed the path
117166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // components, this becomes the common suffix of target_path and cwd_path.
117266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  while (!target_path.empty() && !cwd_path.empty()
117366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      && target_path.back() == cwd_path.back()) {
117466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    target_path.pop_back();
117566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cwd_path.pop_back();
117666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
117766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
117866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // For each element of the remaining cwd_path, add '..' to the beginning
117966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // of the target path. Because we reversed the path components, we add to
118066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // the end of target_path.
118166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (unsigned int i = 0; i < cwd_path.size(); i++) {
118266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    target_path.push_back("..");
118366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
118466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
118566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reverse again to get the right path order, and join to get the result.
118666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(target_path.begin(), target_path.end());
118766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return Join(target_path, '/');
118866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
118966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
119066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-absolute path to Dex location.
119166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Not sure, but it shouldn't crash.
119266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
119366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
119466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), abs_dex_location);
119566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
119666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = MakePathRelative(abs_dex_location);
11977bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
119866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
119966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
12007bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
12017bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
120266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
120366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
120466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
120566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
120666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
120766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
120866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
120966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
121066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Very short, non-existent Dex location.
12119b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: kNoDexOptNeeded.
121266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, ShortDexLocation) {
121366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = "/xx";
121466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12157bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
121666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
121766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
12187bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
12197bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
122066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
122166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
122266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
122366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
122466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
122566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
12269b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
122766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12289b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Trying to make it up to date should have no effect.
122966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
1230ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler  EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
1231ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg));
12329b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(error_msg.empty());
123366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
123466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
123566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-standard extension for dex file.
123695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
123766d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LongDexExtension) {
123866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
123966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
124066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
124266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
12447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
124566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
124666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
124766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
124866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
124966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
125066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
125166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
125266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
125366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
125466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
125566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// A task to generate a dex location. Used by the RaceToGenerate test.
125666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass RaceGenerateTask : public Task {
125766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
125866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
12595872d7cd6ceffe67550d0b021191ec66f1a34c5dJeff Hao    : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr)
126066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  {}
126166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12624b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain  void Run(Thread* self ATTRIBUTE_UNUSED) {
126366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Load the dex files, and save a pointer to the loaded oat file, so that
126466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // we can verify only one oat file was loaded for the dex location.
126566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::unique_ptr<const DexFile>> dex_files;
126666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::string> error_msgs;
1267e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier    const OatFile* oat_file = nullptr;
1268f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
1269f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier        dex_location_.c_str(),
1270f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier        oat_location_.c_str(),
1271fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        /*class_loader*/nullptr,
1272fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        /*dex_elements*/nullptr,
1273e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier        &oat_file,
1274f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier        &error_msgs);
127566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
127607b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
127707b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
1278e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier    CHECK_EQ(loaded_oat_file_, oat_file);
127966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
128066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
128166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile* GetLoadedOatFile() const {
128266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return loaded_oat_file_;
128366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
128466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
128566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private:
128666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location_;
128766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string oat_location_;
128866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile* loaded_oat_file_;
128966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
129066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
129166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Test the case where multiple processes race to generate an oat file.
129266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// This simulates multiple processes using multiple threads.
129366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//
1294f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// We want unique Oat files to be loaded even when there is a race to load.
1295f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// TODO: The test case no longer tests locking the way it was intended since we now get multiple
1296f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// copies of the same Oat files mapped at different locations.
129766d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, RaceToGenerate) {
129866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
12996343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
130066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
130166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // We use the lib core dex file, because it's large, and hopefully should
130266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // take a while to generate.
1303d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  Copy(GetLibCoreDexFileNames()[0], dex_location);
130466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
130566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const int kNumThreads = 32;
130666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Thread* self = Thread::Current();
130766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
130866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
130966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (int i = 0; i < kNumThreads; i++) {
131066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
131166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    thread_pool.AddTask(self, task.get());
131266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    tasks.push_back(std::move(task));
131366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
131466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  thread_pool.StartWorkers(self);
131566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  thread_pool.Wait(self, true, false);
131666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1317f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier  // Verify every task got a unique oat file.
1318f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier  std::set<const OatFile*> oat_files;
131966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (auto& task : tasks) {
1320f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    const OatFile* oat_file = task->GetLoadedOatFile();
1321f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
1322f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    oat_files.insert(oat_file);
132366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
132466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
132566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
132666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
132766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled.
132866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable.
132966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
133066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
13316343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
133266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
133366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
133466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
13357bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
133666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
133766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an executable oat file assistant.
13387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
133966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
134066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
134166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
134266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
134366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
134466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
134566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
134666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
134766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
134866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
134966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled.
135066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable.
135166d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
135266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
13536343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
135466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
135566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
135666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
13577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
135866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
135966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an executable oat file assistant.
13607bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
136166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
136266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
136366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
136466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
136566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
136666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
136766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(2u, dex_files.size());
136866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
136966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
137066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) {
137166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
137266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string odex_file;
137366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
137466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
1375b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
13766343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
137766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
137866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
1379b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
13806343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
138166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
138266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
1383b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "nopath.jar", kArm, &odex_file, &error_msg));
138466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
1385b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
138666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
138766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
138823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// Verify the dexopt status values from dalvik.system.DexFile
138923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// match the OatFileAssistant::DexOptStatus values.
139023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard UhlerTEST_F(OatFileAssistantTest, DexOptStatusValues) {
139123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ScopedObjectAccess soa(Thread::Current());
139223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  StackHandleScope<1> hs(soa.Self());
139323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ClassLinker* linker = Runtime::Current()->GetClassLinker();
139423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  Handle<mirror::Class> dexfile(
139523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
139623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(dexfile.Get() == nullptr);
139723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  linker->EnsureInitialized(soa.Self(), dexfile, true, true);
139823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1399c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
140023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I");
140123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(no_dexopt_needed == nullptr);
140223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
140323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get()));
140423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1405c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* dex2oat_needed = mirror::Class::FindStaticField(
140623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "DEX2OAT_NEEDED", "I");
140723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(dex2oat_needed == nullptr);
140823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
140923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get()));
141023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1411c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* patchoat_needed = mirror::Class::FindStaticField(
141223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "PATCHOAT_NEEDED", "I");
141323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(patchoat_needed == nullptr);
141423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
141523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get()));
141623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1417c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
141823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I");
141923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(self_patchoat_needed == nullptr);
142023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
142123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get()));
142223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler}
142366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
142466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// TODO: More Tests:
14257bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe//  * Image checksum change is out of date for kIntepretOnly, but not
14267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe//    kVerifyAtRuntime. But target of kVerifyAtRuntime still says current
14277bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe//    kInterpretOnly is out of date.
142866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test class linker falls back to unquickened dex for DexNoOat
142966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test class linker falls back to unquickened dex for MultiDexNoOat
143066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test using secondary isa
143166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test for status of oat while oat is being generated (how?)
143266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test case where 32 and 64 bit boot class paths differ,
143366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//      and we ask IsInBootClassPath for a class in exactly one of the 32 or
143466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//      64 bit boot class paths.
143566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test unexpected scenarios (?):
143666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    - Dex is stripped, don't have odex.
143766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    - Oat file corrupted after status check, before reload unexecutable
143866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    because it's unrelocated and no dex2oat
1439d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle//  * Test unrelocated specific target compilation type can be relocated to
1440d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle//    make it up to date.
144166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
144266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}  // namespace art
1443