oat_file_assistant_test.cc revision d91b8a2464b99625efe03caf7d30c8372bc378ed
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,
19193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler                           const std::string& odex_location) {
19293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // To generate an un-relocated odex file, we first compile a relocated
19393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // version of the file, then manually call patchoat to make it look as if
19493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // it is unrelocated.
19593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::string relocated_odex_location = odex_location + ".relocated";
19693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::vector<std::string> args;
19793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--dex-file=" + dex_location);
19893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--oat-file=" + relocated_odex_location);
19993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--include-patch-information");
20093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
20193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // We need to use the quick compiler to generate non-PIC code, because
20293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // the optimizing compiler always generates PIC.
20393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--compiler-backend=Quick");
20493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
20593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::string error_msg;
20693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
20793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
20893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // Use patchoat to unrelocate the relocated odex file.
20993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    Runtime* runtime = Runtime::Current();
21093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::vector<std::string> argv;
21193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back(runtime->GetPatchoatExecutable());
21293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA)));
21393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back("--input-oat-file=" + relocated_odex_location);
21493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back("--output-oat-file=" + odex_location);
21593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    argv.push_back("--base-offset-delta=0x00008000");
21693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::string command_line(Join(argv, ' '));
21793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    ASSERT_TRUE(Exec(argv, &error_msg)) << error_msg;
21893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
21993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // Verify the odex file was generated as expected and really is
22093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // unrelocated.
22193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    std::unique_ptr<OatFile> odex_file(OatFile::Open(
22293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler        odex_location.c_str(), odex_location.c_str(), nullptr, nullptr,
22393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler        false, dex_location.c_str(), &error_msg));
22493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
22593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
226dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao    const std::vector<gc::space::ImageSpace*> image_spaces =
227dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao        runtime->GetHeap()->GetBootImageSpaces();
228dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao    ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr);
229dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao    const ImageHeader& image_header = image_spaces[0]->GetImageHeader();
23093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    const OatHeader& oat_header = odex_file->GetOatHeader();
23193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    EXPECT_FALSE(odex_file->IsPic());
23293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    EXPECT_EQ(image_header.GetOatChecksum(), oat_header.GetImageFileLocationOatChecksum());
23393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()),
23493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler        oat_header.GetImageFileLocationOatDataBegin());
23593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta());
23693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler  }
23793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler
23893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler  void GeneratePicOdexForTest(const std::string& dex_location,
23993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler                              const std::string& odex_location) {
24093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // Temporarily redirect the dalvik cache so dex2oat doesn't find the
24193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    // relocated image file.
24266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp";
24366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    setenv("ANDROID_DATA", android_data_tmp.c_str(), 1);
24466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::string> args;
24566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("--dex-file=" + dex_location);
24666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("--oat-file=" + odex_location);
24793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    args.push_back("--compile-pic");
24866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("--runtime-arg");
24966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("-Xnorelocate");
25066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string error_msg;
251b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
25266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    setenv("ANDROID_DATA", android_data_.c_str(), 1);
25394f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler
25494f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler    // Verify the odex file was generated as expected.
25594f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler    std::unique_ptr<OatFile> odex_file(OatFile::Open(
25694f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler        odex_location.c_str(), odex_location.c_str(), nullptr, nullptr,
257b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        false, dex_location.c_str(), &error_msg));
25894f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
25993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler    EXPECT_TRUE(odex_file->IsPic());
26066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
26166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
262ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  void GenerateExtractOnlyOdexForTest(const std::string& dex_location,
263d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle                                      const std::string& odex_location) {
264ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    std::vector<std::string> args;
265ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    args.push_back("--dex-file=" + dex_location);
266ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    args.push_back("--oat-file=" + odex_location);
267ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    args.push_back("--compiler-filter=verify-at-runtime");
268ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    std::string error_msg;
269ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
270ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
271ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    // Verify the odex file was generated as expected.
272ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    std::unique_ptr<OatFile> odex_file(OatFile::Open(
273ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil        odex_location.c_str(), odex_location.c_str(), nullptr, nullptr,
274ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil        false, dex_location.c_str(), &error_msg));
275ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
276ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    EXPECT_TRUE(odex_file->IsExtractOnly());
277ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    EXPECT_EQ(odex_file->GetOatHeader().GetImageFileLocationOatChecksum(), 0u);
278ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    EXPECT_EQ(odex_file->GetOatHeader().GetImageFileLocationOatDataBegin(), 0u);
279ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil    EXPECT_EQ(odex_file->GetOatHeader().GetImagePatchDelta(), 0);
280d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  }
281d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
282d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  void GenerateProfileGuideOdexForTest(const std::string& dex_location,
283d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle                                       const std::string& odex_location) {
284d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    std::vector<std::string> args;
285d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    args.push_back("--dex-file=" + dex_location);
286d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    args.push_back("--oat-file=" + odex_location);
287d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    ScratchFile profile_file;
288d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    args.push_back("--profile-file=" + profile_file.GetFilename());
289d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    std::string error_msg;
290d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
291d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
292d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    // Verify the odex file was generated as expected.
293d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    std::unique_ptr<OatFile> odex_file(OatFile::Open(
294d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle        odex_location.c_str(), odex_location.c_str(), nullptr, nullptr,
295d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle        false, dex_location.c_str(), &error_msg));
296d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    printf("error %s", error_msg.c_str());
297d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
298d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    EXPECT_TRUE(odex_file->IsProfileGuideCompiled());
299d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  }
300ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
30166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private:
30266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reserve memory around where the image will be loaded so other memory
30366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // won't conflict when it comes time to load the image.
30466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // This can be called with an already loaded image to reserve the space
30566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // around it.
30666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void ReserveImageSpace() {
30766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    MemMap::Init();
30866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
30966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Ensure a chunk of memory is reserved for the image space.
31066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    uintptr_t reservation_start = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MIN_DELTA;
31166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    uintptr_t reservation_end = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MAX_DELTA
3123dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi        // Include the main space that has to come right after the
3133dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi        // image in case of the GSS collector.
3143dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi        + 384 * MB;
31566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
31666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
31766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
31866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    for (BacktraceMap::const_iterator it = map->begin();
31966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reservation_start < reservation_end && it != map->end(); ++it) {
3203efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end));
3213efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      reservation_start = std::max(reservation_start, it->end);
3223efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    }
3233efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    ReserveImageSpaceChunk(reservation_start, reservation_end);
3243efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  }
32566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
3263efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  // Reserve a chunk of memory for the image space in the given range.
3273efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  // Only has effect for chunks with a positive number of bytes.
3283efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) {
3293efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    if (start < end) {
3303efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      std::string error_msg;
33166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      image_reservation_.push_back(std::unique_ptr<MemMap>(
33266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          MemMap::MapAnonymous("image reservation",
3333efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler              reinterpret_cast<uint8_t*>(start), end - start,
334b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin              PROT_NONE, false, false, &error_msg)));
33566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
33666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      LOG(INFO) << "Reserved space for image " <<
33766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
33866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reinterpret_cast<void*>(image_reservation_.back()->End());
33966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
34066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
34166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
34266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
34366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Unreserve any memory reserved by ReserveImageSpace. This should be called
34466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // before the image is loaded.
34566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void UnreserveImageSpace() {
34666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    image_reservation_.clear();
34766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
34866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
34966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string scratch_dir_;
3506343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_oat_dir_;
3516343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_dir_;
35266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<MemMap>> image_reservation_;
35366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
35466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
35566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass OatFileAssistantNoDex2OatTest : public OatFileAssistantTest {
35666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
35766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
35866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    OatFileAssistantTest::SetUpRuntimeOptions(options);
35966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    options->push_back(std::make_pair("-Xnodex2oat", nullptr));
36066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
36166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
36266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
36366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Generate an oat file for the purposes of test, as opposed to testing
36466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// generation of oat files.
36566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstatic void GenerateOatForTest(const char* dex_location) {
366d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location,
367d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
36866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
36966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
370b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  ASSERT_TRUE(oat_file_assistant.GenerateOatFile(&error_msg)) << error_msg;
37166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
37266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
37366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, but no OAT file for it.
37495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
37566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexNoOat) {
37666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
37766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
37866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
379d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
380d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
38166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
38295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
38366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
38466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
38566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
38666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
38766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
38866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
38995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
39066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
39166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
39266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
39366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
39495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
3959b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
39666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
39766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
39866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have no DEX file and no OAT file.
3999b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
40066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NoDexNoOat) {
40166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
40266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
403d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
404d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
40566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4069b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
4079b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
4089b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
4099b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Trying to make the oat file up to date should not fail or crash.
4109b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  std::string error_msg;
411b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  EXPECT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg));
4129b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
4139b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Trying to get the best oat file should fail, but not crash.
41466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
41566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(nullptr, oat_file.get());
41666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
41766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
41866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
41995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded.
42066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatUpToDate) {
42166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
42266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
42366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
42466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
425d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
426d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
42766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
42895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
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.OdexFileIsUpToDate());
43366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
43466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
43566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
43666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
43795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
4389b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
43966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
44066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
44166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it.
44295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded and we load all dex files.
44366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
44466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
44566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
44666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
44766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
448d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
449d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
45095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
4519b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
45295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
45395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Verify we can load both dex files.
454e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
455e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
456e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
457e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
458e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
459e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ(2u, dex_files.size());
460e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler}
461e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
46267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Case: We have a MultiDEX file where the secondary dex file is out of date.
46367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Expect: The status is kDex2OatNeeded.
46467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard UhlerTEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) {
46567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar";
46667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
46767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Compile code for GetMultiDexSrc1.
46867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  Copy(GetMultiDexSrc1(), dex_location);
46967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  GenerateOatForTest(dex_location.c_str());
47067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
47167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
47267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // is out of date.
47367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  Copy(GetMultiDexSrc2(), dex_location);
47467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
475d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
476d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
47767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
4789b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
47967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler}
48067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
481e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it with relative
482e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// encoded dex locations.
48395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The oat file status is kNoDexOptNeeded.
484e5fed03772144595c0904faf3d6974cc55214c8cRichard UhlerTEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
485e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
4866343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
487e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
488e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Create the dex file
489e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
490e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
491e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Create the oat file with relative encoded dex location.
492e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::vector<std::string> args;
493e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--dex-file=" + dex_location);
494e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
495e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--oat-file=" + oat_location);
496e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
497e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::string error_msg;
498b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
499e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
500e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Verify we can load both dex files.
501e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
502e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                                      oat_location.c_str(),
503d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle                                      OatFileAssistant::kFullCompilation,
504e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                                      kRuntimeISA, true);
505e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
50666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
50766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
50866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
509e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
51066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(2u, dex_files.size());
51166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
51266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
51395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file and out-of-date OAT file.
51495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
51566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatOutOfDate) {
51666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar";
51766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
51866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // We create a dex, generate an oat for it, then overwrite the dex with a
51966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // different dex to make the oat out of date.
52066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
52166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
52266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc2(), dex_location);
52366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
524d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
525d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
52695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
52766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
52866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
52966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
53066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
53166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
53266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
53366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
53466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
5359b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
53666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
53766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
53866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, but no OAT file.
53995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded.
54066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexOdexNoOat) {
54166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
5426343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
54366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
54466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
54566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
54666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
54766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
54866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
549d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
550d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
55166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
55295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
55366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
55466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
55566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
55666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
55766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
55866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
55966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
56066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
56166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
5629b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
5635f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler
5645f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  // We should still be able to get the non-executable odex file to run from.
5655f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
5665f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
56766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
56866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
56966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a stripped DEX file and an ODEX file, but no OAT file.
57095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded
57166d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
57266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
5736343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
57466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
57566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
57666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
57766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
57866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
57966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Strip the dex file
58066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
58166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
58266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
583d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
584d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
58566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
58695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
58766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
58866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
58966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
59066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
59166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
59266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
59366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
59466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
5959b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
59666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
59766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Make the oat file up to date.
59866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
599b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
60066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
60195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
60266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
60366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
60466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
60566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
60666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
60766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
60866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
60966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
6109b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
61166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
61266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify we can load the dex files from it.
61366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
61466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
61566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
61666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
61766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
61866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
61966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
62066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
62195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file.
62295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded.
62366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
62466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
6256343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
62666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
62766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the oat file from a different dex file so it looks out of date.
62866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc2(), dex_location);
62966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
63066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
63166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the odex file
63266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
63366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
63466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
63566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Strip the dex file.
63666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
63766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
63866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
639d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
640d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
64166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
64295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
64366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
64466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
64566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
64666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
64766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
64866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
64966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
65066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
65166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
6529b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
65366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
65466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Make the oat file up to date.
65566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
656b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
65766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
65895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
65966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
66066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
66166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
66266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
66366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
66466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
66566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
66666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
66766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
66866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
6699b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
67066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
67166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify we can load the dex files from it.
67266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
67366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
67466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
67566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
67666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
67766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
67866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
67966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6809b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
6819b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// OAT file. Expect: The status is kNoDexOptNeeded.
6829b994ea841eaaefbdda652251894a74db9cefcc8Richard UhlerTEST_F(OatFileAssistantTest, ResourceOnlyDex) {
6839b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
6849b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6859b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
6869b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6879b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Verify the status.
688d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
689d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
6909b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6919b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
6929b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
6939b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
6949b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
6959b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
6969b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
6979b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
6989b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
6999b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
7009b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
7019b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
7029b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
7039b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Make the oat file up to date. This should have no effect.
7049b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  std::string error_msg;
705b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  EXPECT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
7069b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
7079b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
7089b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
7099b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
7109b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
7119b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
7129b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
7139b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
7149b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
7159b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
7169b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
7179b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
7189b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler}
7199b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
72095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file, no ODEX file and an OAT file that needs
72195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// relocation.
72295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kSelfPatchOatNeeded.
72395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerTEST_F(OatFileAssistantTest, SelfRelocation) {
72495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string dex_location = GetScratchDir() + "/SelfRelocation.jar";
72595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string oat_location = GetOdexDir() + "/SelfRelocation.oat";
72695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
72795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Create the dex and odex files
72895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  Copy(GetDexSrc1(), dex_location);
72995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  GenerateOdexForTest(dex_location, oat_location);
73095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
73195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
732d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      oat_location.c_str(), OatFileAssistant::kFullCompilation, kRuntimeISA, true);
73395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
73495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
73595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
73695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
73795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
73895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
73995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
74095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
74195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
74295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation());
74395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
74495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
7459b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
74695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
74795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Make the oat file up to date.
74895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string error_msg;
749b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
75095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
75195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
75295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
75395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
75495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
75595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
75695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
75795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
75895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
75995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
76095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
76195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
7629b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
76395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
76495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
76595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
76695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
76795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
76895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
76995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(1u, dex_files.size());
77095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler}
77195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
77266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
77366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// OAT files both have patch delta of 0.
77495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: It shouldn't crash, and status is kPatchOatNeeded.
77566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OdexOatOverlap) {
77666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
7776343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
7786343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
77966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
78166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
78266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
78366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the oat file by copying the odex so they are located in the same
78566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // place in memory.
78666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(odex_location, oat_location);
78766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify things don't go bad.
78966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
790d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      oat_location.c_str(), OatFileAssistant::kFullCompilation, kRuntimeISA, true);
79166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
79295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
79366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
79466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
79566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
79666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
79766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
79866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
79966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
80066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
8019b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
80266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
80366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Things aren't relocated, so it should fall back to interpreted.
80466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
80566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
806f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler
80766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
80866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
80966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
81066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
81166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
81266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
81366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
81495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
81566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
81666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
8176343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
81866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
81966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
82066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
82166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GeneratePicOdexForTest(dex_location, odex_location);
82266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
82366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
824d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
825d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
82666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
82795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
82866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
82966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
830ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
831ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
832ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
833ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.OatFileExists());
834ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
835ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
836ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
837ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil}
838ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
839ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil// Case: We have a DEX file and a ExtractOnly ODEX file, but no OAT file.
840ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil// Expect: The status is kNoDexOptNeeded, because ExtractOnly contains no code.
841ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid BrazdilTEST_F(OatFileAssistantTest, DexExtractOnlyOdexNoOat) {
842ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  std::string dex_location = GetScratchDir() + "/DexExtractOnlyOdexNoOat.jar";
843ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  std::string odex_location = GetOdexDir() + "/DexExtractOnlyOdexNoOat.odex";
844ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
845ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  // Create the dex and odex files
846ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  Copy(GetDexSrc1(), dex_location);
847ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  GenerateExtractOnlyOdexForTest(dex_location, odex_location);
848ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
849ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  // Verify the status.
850d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
851d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation | OatFileAssistant::kExtractOnly,
852d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      kRuntimeISA, false);
853ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
854ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
855ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil
856ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
85766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
85866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
85966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
86066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
86166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
86266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
8639b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
86466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
86566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
86666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
86766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file.
86866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadOatUpToDate) {
86966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
87066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
87166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
87266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
87366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
87466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an oat file assistant.
875d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
876d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
87766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
87866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
87966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
88066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
88166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
88266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
88366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
88466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
88566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
88666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
88766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Loading non-executable should load the oat non-executable.
88866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
88966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
89066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
89166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
89266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
89366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
89466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an oat file assistant.
895d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
896d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
89766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
89866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
89966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
90066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
90166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
90266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
90366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
90466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
90566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
90666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file.
90766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file from an alternative oat
90866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// location.
90966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
91066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
91166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
91266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
91366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
91466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
91566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(
916d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      dex_location.c_str(), oat_location.c_str(),
917d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
91866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
919b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
92066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
92166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
92266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
92366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
92466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
92566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
92666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
92766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
92866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
92966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
93066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify it didn't create an oat in the default location.
931d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant ofm(dex_location.c_str(),
932d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
93366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(ofm.OatFileExists());
93466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
93566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9368327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We have a DEX file but can't write the oat file.
9378327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to make the oat file up to date.
9388327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) {
9398327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar";
9408327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9418327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  // Make the oat location unwritable by inserting some non-existent
9428327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  // intermediate directories.
9438327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat";
9448327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9458327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  Copy(GetDexSrc1(), dex_location);
9468327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9478327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  OatFileAssistant oat_file_assistant(
948d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      dex_location.c_str(), oat_location.c_str(),
949d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
9508327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string error_msg;
9518327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  ASSERT_FALSE(oat_file_assistant.MakeUpToDate(&error_msg));
9528327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9538327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
9548327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  ASSERT_TRUE(oat_file.get() == nullptr);
9558327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler}
9568327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9578327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We don't have a DEX file and can't write the oat file.
9588327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to generate the oat file without crashing.
9598327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, GenNoDex) {
9608327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
9618327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string oat_location = GetScratchDir() + "/GenNoDex.oat";
9628327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
9638327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  OatFileAssistant oat_file_assistant(
964d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      dex_location.c_str(), oat_location.c_str(),
965d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
9668327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::string error_msg;
9678327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  ASSERT_FALSE(oat_file_assistant.GenerateOatFile(&error_msg));
9688327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler}
9698327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
97066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Turn an absolute path into a path relative to the current working
97166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// directory.
97266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstatic std::string MakePathRelative(std::string target) {
97366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  char buf[MAXPATHLEN];
97466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string cwd = getcwd(buf, MAXPATHLEN);
97566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
97666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Split the target and cwd paths into components.
97766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> target_path;
97866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> cwd_path;
97966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Split(target, '/', &target_path);
98066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Split(cwd, '/', &cwd_path);
98166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
98266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reverse the path components, so we can use pop_back().
98366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(target_path.begin(), target_path.end());
98466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(cwd_path.begin(), cwd_path.end());
98566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
98666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Drop the common prefix of the paths. Because we reversed the path
98766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // components, this becomes the common suffix of target_path and cwd_path.
98866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  while (!target_path.empty() && !cwd_path.empty()
98966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      && target_path.back() == cwd_path.back()) {
99066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    target_path.pop_back();
99166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cwd_path.pop_back();
99266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
99366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
99466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // For each element of the remaining cwd_path, add '..' to the beginning
99566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // of the target path. Because we reversed the path components, we add to
99666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // the end of target_path.
99766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (unsigned int i = 0; i < cwd_path.size(); i++) {
99866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    target_path.push_back("..");
99966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
100066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
100166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reverse again to get the right path order, and join to get the result.
100266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(target_path.begin(), target_path.end());
100366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return Join(target_path, '/');
100466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
100566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
100666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-absolute path to Dex location.
100766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Not sure, but it shouldn't crash.
100866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
100966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
101066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), abs_dex_location);
101166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
101266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = MakePathRelative(abs_dex_location);
1013d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
1014d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
101566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
101666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
101795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
101866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
101966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
102066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
102166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
102266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
102366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
102466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
102566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
102666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Very short, non-existent Dex location.
10279b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: kNoDexOptNeeded.
102866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, ShortDexLocation) {
102966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = "/xx";
103066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1031d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
1032d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
103366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
103466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
10359b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
103666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
103766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
103866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
103966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
104066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
104166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
10429b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
104366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10449b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Trying to make it up to date should have no effect.
104566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
1046b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  EXPECT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg));
10479b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  EXPECT_TRUE(error_msg.empty());
104866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
104966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
105066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-standard extension for dex file.
105195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
105266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LongDexExtension) {
105366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
105466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
105566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1056d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
1057d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
105866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
105995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
106066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
106166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
106266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
106366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
106466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
106566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
106666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
106766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
106866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
106966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
107066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// A task to generate a dex location. Used by the RaceToGenerate test.
107166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass RaceGenerateTask : public Task {
107266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
107366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
107466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    : dex_location_(dex_location), oat_location_(oat_location),
107566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      loaded_oat_file_(nullptr)
107666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  {}
107766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10784b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain  void Run(Thread* self ATTRIBUTE_UNUSED) {
107966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Load the dex files, and save a pointer to the loaded oat file, so that
108066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // we can verify only one oat file was loaded for the dex location.
108166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::unique_ptr<const DexFile>> dex_files;
108266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::string> error_msgs;
1083e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier    const OatFile* oat_file = nullptr;
1084f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
1085f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier        dex_location_.c_str(),
1086f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier        oat_location_.c_str(),
1087fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        /*class_loader*/nullptr,
1088fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        /*dex_elements*/nullptr,
1089e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier        &oat_file,
1090f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier        &error_msgs);
109166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
109207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
109307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
1094e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier    CHECK_EQ(loaded_oat_file_, oat_file);
109566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
109666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
109766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile* GetLoadedOatFile() const {
109866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return loaded_oat_file_;
109966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
110066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
110166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private:
110266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location_;
110366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string oat_location_;
110466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile* loaded_oat_file_;
110566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
110666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
110766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Test the case where multiple processes race to generate an oat file.
110866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// This simulates multiple processes using multiple threads.
110966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//
1110f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// We want unique Oat files to be loaded even when there is a race to load.
1111f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// TODO: The test case no longer tests locking the way it was intended since we now get multiple
1112f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// copies of the same Oat files mapped at different locations.
111366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, RaceToGenerate) {
111466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
11156343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
111666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
111766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // We use the lib core dex file, because it's large, and hopefully should
111866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // take a while to generate.
1119d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath  Copy(GetLibCoreDexFileNames()[0], dex_location);
112066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
112166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const int kNumThreads = 32;
112266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Thread* self = Thread::Current();
112366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
112466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
112566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (int i = 0; i < kNumThreads; i++) {
112666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
112766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    thread_pool.AddTask(self, task.get());
112866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    tasks.push_back(std::move(task));
112966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
113066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  thread_pool.StartWorkers(self);
113166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  thread_pool.Wait(self, true, false);
113266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1133f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier  // Verify every task got a unique oat file.
1134f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier  std::set<const OatFile*> oat_files;
113566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (auto& task : tasks) {
1136f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    const OatFile* oat_file = task->GetLoadedOatFile();
1137f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
1138f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier    oat_files.insert(oat_file);
113966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
114066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
114166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
114266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
114366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled.
114466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable.
114566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
114666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
11476343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
114866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
114966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
115066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
115166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
115266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
115366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an executable oat file assistant.
1154d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
1155d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
115666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
115766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
115866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
115966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
116066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
116166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
116266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
116366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
116466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
116566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
116666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled.
116766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable.
116866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
116966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
11706343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
117166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
117266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
117366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
117466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
117566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
117666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an executable oat file assistant.
1177d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant oat_file_assistant(dex_location.c_str(),
1178d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, true);
117966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
118066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
118166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
118266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
118366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
118466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
118566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(2u, dex_files.size());
118666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
118766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
118866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) {
118966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
119066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string odex_file;
119166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
119266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
1193b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
11946343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
119566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
119666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
1197b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
11986343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
119966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
120066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
1201b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "nopath.jar", kArm, &odex_file, &error_msg));
120266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
1203b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
120466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
120566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1206d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle// Case: We have a DEX file, extract-only ODEX, and fully compiled OAT.
1207d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle// Expect: The status depends on the target compilation type mask.
1208d91b8a2464b99625efe03caf7d30c8372bc378edCalin JuravleTEST_F(OatFileAssistantTest, TargetCompilationType) {
1209d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  std::string dex_location = GetScratchDir() + "/TargetCompilationType.jar";
1210d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  std::string odex_location = GetOdexDir() + "/TargetCompilationType.odex";
1211d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  Copy(GetDexSrc1(), dex_location);
1212d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  GenerateExtractOnlyOdexForTest(dex_location, odex_location);
1213d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  GenerateOatForTest(dex_location.c_str());
1214d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
1215d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant ofa_full(dex_location.c_str(),
1216d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation, kRuntimeISA, false);
1217d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, ofa_full.GetDexOptNeeded());
1218d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_FALSE(ofa_full.IsInBootClassPath());
1219d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_TRUE(ofa_full.OdexFileIsOutOfDate());
1220d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_TRUE(ofa_full.OatFileIsUpToDate());
1221d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
1222d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant ofa_extract(dex_location.c_str(),
1223d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kExtractOnly, kRuntimeISA, false);
1224d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, ofa_extract.GetDexOptNeeded());
1225d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_FALSE(ofa_extract.IsInBootClassPath());
1226d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_TRUE(ofa_extract.OdexFileIsUpToDate());
1227d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_TRUE(ofa_extract.OatFileIsOutOfDate());
1228d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
1229d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant ofa_profile(dex_location.c_str(),
1230d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kProfileGuideCompilation, kRuntimeISA, false);
1231d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, ofa_profile.GetDexOptNeeded());
1232d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_FALSE(ofa_profile.IsInBootClassPath());
1233d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_TRUE(ofa_profile.OdexFileIsOutOfDate());
1234d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_TRUE(ofa_profile.OatFileIsOutOfDate());
1235d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
1236d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  OatFileAssistant ofa_extract_full(dex_location.c_str(),
1237d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      OatFileAssistant::kFullCompilation | OatFileAssistant::kExtractOnly,
1238d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      kRuntimeISA, false);
1239d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, ofa_extract_full.GetDexOptNeeded());
1240d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_FALSE(ofa_extract_full.IsInBootClassPath());
1241d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_TRUE(ofa_extract_full.OdexFileIsUpToDate());
1242d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_TRUE(ofa_extract_full.OatFileIsUpToDate());
1243d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle}
1244d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
124523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// Verify the dexopt status values from dalvik.system.DexFile
124623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// match the OatFileAssistant::DexOptStatus values.
124723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard UhlerTEST_F(OatFileAssistantTest, DexOptStatusValues) {
124823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ScopedObjectAccess soa(Thread::Current());
124923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  StackHandleScope<1> hs(soa.Self());
125023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ClassLinker* linker = Runtime::Current()->GetClassLinker();
125123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  Handle<mirror::Class> dexfile(
125223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
125323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(dexfile.Get() == nullptr);
125423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  linker->EnsureInitialized(soa.Self(), dexfile, true, true);
125523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1256c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
125723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I");
125823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(no_dexopt_needed == nullptr);
125923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
126023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get()));
126123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1262c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* dex2oat_needed = mirror::Class::FindStaticField(
126323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "DEX2OAT_NEEDED", "I");
126423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(dex2oat_needed == nullptr);
126523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
126623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get()));
126723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1268c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* patchoat_needed = mirror::Class::FindStaticField(
126923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "PATCHOAT_NEEDED", "I");
127023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(patchoat_needed == nullptr);
127123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
127223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get()));
127323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1274c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
127523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I");
127623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(self_patchoat_needed == nullptr);
127723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
127823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get()));
1279d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
1280d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle    ArtField* compilation_type_full = mirror::Class::FindStaticField(
1281d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      soa.Self(), dexfile, "COMPILATION_TYPE_FULL", "I");
1282d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  ASSERT_FALSE(compilation_type_full == nullptr);
1283d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(compilation_type_full->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1284d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(OatFileAssistant::kFullCompilation, compilation_type_full->GetInt(dexfile.Get()));
1285d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
1286d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  ArtField* compilation_type_profile_guide = mirror::Class::FindStaticField(
1287d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      soa.Self(), dexfile, "COMPILATION_TYPE_PROFILE_GUIDE", "I");
1288d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  ASSERT_FALSE(compilation_type_profile_guide == nullptr);
1289d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(compilation_type_profile_guide->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1290d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(OatFileAssistant::kProfileGuideCompilation,
1291d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle            compilation_type_profile_guide->GetInt(dexfile.Get()));
1292d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle
1293d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  ArtField* compilation_type_extract_only = mirror::Class::FindStaticField(
1294d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle      soa.Self(), dexfile, "COMPILATION_TYPE_EXTRACT_ONLY", "I");
1295d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  ASSERT_FALSE(compilation_type_extract_only == nullptr);
1296d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(compilation_type_extract_only->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1297d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle  EXPECT_EQ(OatFileAssistant::kExtractOnly, compilation_type_extract_only->GetInt(dexfile.Get()));
129823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler}
129966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
130066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// TODO: More Tests:
130166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test class linker falls back to unquickened dex for DexNoOat
130266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test class linker falls back to unquickened dex for MultiDexNoOat
130366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test using secondary isa
130466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test for status of oat while oat is being generated (how?)
130566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test case where 32 and 64 bit boot class paths differ,
130666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//      and we ask IsInBootClassPath for a class in exactly one of the 32 or
130766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//      64 bit boot class paths.
130866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test unexpected scenarios (?):
130966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    - Dex is stripped, don't have odex.
131066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    - Oat file corrupted after status check, before reload unexecutable
131166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    because it's unrelocated and no dex2oat
1312d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle//  * Test unrelocated specific target compilation type can be relocated to
1313d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle//    make it up to date.
131466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
131566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}  // namespace art
1316