oat_file_assistant_test.cc revision 67ff7d1fd7bcaf4b6b73ecdab6011c8636562b58
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"
3466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "os.h"
3523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler#include "scoped_thread_state_change.h"
3666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "thread-inl.h"
3766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "utils.h"
3866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
3966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlernamespace art {
4066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass OatFileAssistantTest : public CommonRuntimeTest {
4266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
4366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void SetUp() {
4466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ReserveImageSpace();
4566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    CommonRuntimeTest::SetUp();
4666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Create a scratch directory to work from.
4866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    scratch_dir_ = android_data_ + "/OatFileAssistantTest";
4966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700));
5066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
516343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    // Create a subdirectory in scratch for odex files.
526343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    odex_oat_dir_ = scratch_dir_ + "/oat";
536343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700));
546343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler
556343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA));
566343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700));
576343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler
5866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
5966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Verify the environment is as we expect
6066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    uint32_t checksum;
6166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string error_msg;
6266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(OS::FileExists(GetImageFile().c_str()))
6366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected pre-compiled boot image to be at: " << GetImageFile();
6466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str()))
6566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected dex file to be at: " << GetDexSrc1();
6666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str()))
6766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected stripped dex file to be at: " << GetStrippedDexSrc1();
6866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_FALSE(DexFile::GetChecksum(GetStrippedDexSrc1().c_str(), &checksum, &error_msg))
6966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1();
7066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str()))
7166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "Expected dex file to be at: " << GetDexSrc2();
7267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
7367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    // GetMultiDexSrc2 should have the same primary dex checksum as
7467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    // GetMultiDexSrc1, but a different secondary dex checksum.
7567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    std::vector<std::unique_ptr<const DexFile>> multi1;
7667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_TRUE(DexFile::Open(GetMultiDexSrc1().c_str(),
7767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler          GetMultiDexSrc1().c_str(), &error_msg, &multi1)) << error_msg;
7867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_GT(multi1.size(), 1u);
7967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
8067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    std::vector<std::unique_ptr<const DexFile>> multi2;
8167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_TRUE(DexFile::Open(GetMultiDexSrc2().c_str(),
8267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler          GetMultiDexSrc2().c_str(), &error_msg, &multi2)) << error_msg;
8367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_GT(multi2.size(), 1u);
8467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
8567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum());
8667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    ASSERT_NE(multi1[1]->GetLocationChecksum(), multi2[1]->GetLocationChecksum());
8766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
8866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
8966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
90892fc96694b51ac7a896dacd75af5b235f955825Richard Uhler    // options->push_back(std::make_pair("-verbose:oat", nullptr));
9166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Set up the image location.
9366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    options->push_back(std::make_pair("-Ximage:" + GetImageLocation(),
9466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          nullptr));
9566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Make sure compilercallbacks are not set so that relocation will be
9666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // enabled.
97bb9c6b1c55e9e2308b4f5892a398a8837231fdbdAndreas Gampe    callbacks_.reset();
9866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
9966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void PreRuntimeCreate() {
10166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    UnreserveImageSpace();
10266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
10366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void PostRuntimeCreate() {
10566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ReserveImageSpace();
10666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
10766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void TearDown() {
1096343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ClearDirectory(odex_dir_.c_str());
1106343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ASSERT_EQ(0, rmdir(odex_dir_.c_str()));
1116343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler
1126343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ClearDirectory(odex_oat_dir_.c_str());
1136343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str()));
11466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
11566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ClearDirectory(scratch_dir_.c_str());
11666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_EQ(0, rmdir(scratch_dir_.c_str()));
11766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
11866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    CommonRuntimeTest::TearDown();
11966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
12066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void Copy(std::string src, std::string dst) {
12266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::ifstream  src_stream(src, std::ios::binary);
12366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::ofstream  dst_stream(dst, std::ios::binary);
12466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    dst_stream << src_stream.rdbuf();
12666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
12766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Returns the directory where the pre-compiled core.art can be found.
12966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // TODO: We should factor out this into common tests somewhere rather than
13066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // re-hardcoding it here (This was copied originally from the elf writer
13166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // test).
13266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetImageDirectory() {
13366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (IsHost()) {
13466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      const char* host_dir = getenv("ANDROID_HOST_OUT");
1352cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier      CHECK(host_dir != nullptr);
13666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      return std::string(host_dir) + "/framework";
13766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    } else {
13866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      return std::string("/data/art-test");
13966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
14066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
14166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
14266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetImageLocation() {
14366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetImageDirectory() + "/core.art";
14466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
14566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
14666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetImageFile() {
14766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA)
14866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      + "/core.art";
14966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
15066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
15166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetDexSrc1() {
15266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetTestDexFileName("Main");
15366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
15466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
15566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex
15666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // file stripped.
15766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetStrippedDexSrc1() {
15866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetTestDexFileName("MainStripped");
15966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
16066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
16166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetMultiDexSrc1() {
16266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetTestDexFileName("MultiDex");
16366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
16466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
16567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Returns the path to a multidex file equivalent to GetMultiDexSrc2, but
16667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // with the contents of the secondary dex file changed.
16767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  std::string GetMultiDexSrc2() {
16867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler    return GetTestDexFileName("MultiDexModifiedSecondary");
16967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  }
17067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
17166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetDexSrc2() {
17266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return GetTestDexFileName("Nested");
17366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
17466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
17566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Scratch directory, for dex and odex files (oat files will go in the
17666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // dalvik cache).
17766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string GetScratchDir() {
17866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return scratch_dir_;
17966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
18066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1816343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  // Odex directory is the subdirectory in the scratch directory where odex
18266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // files should be located.
1836343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string GetOdexDir() {
1846343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler    return odex_dir_;
18566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
18666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
18766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Generate an odex file for the purposes of test.
18866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // If pic is true, generates a PIC odex.
18966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void GenerateOdexForTest(const std::string& dex_location,
19066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler                           const std::string& odex_location,
19166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler                           bool pic = false) {
19266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // For this operation, we temporarily redirect the dalvik cache so dex2oat
19366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // doesn't find the relocated image file.
19466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp";
19566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    setenv("ANDROID_DATA", android_data_tmp.c_str(), 1);
19666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::string> args;
19766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("--dex-file=" + dex_location);
19866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("--oat-file=" + odex_location);
19966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (pic) {
20066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      args.push_back("--compile-pic");
20166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    } else {
20266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      args.push_back("--include-patch-information");
20305dd8a63e213d2bf025c97b9cd04eee354d0e5b4Richard Uhler
20405dd8a63e213d2bf025c97b9cd04eee354d0e5b4Richard Uhler      // We need to use the quick compiler to generate non-PIC code, because
20505dd8a63e213d2bf025c97b9cd04eee354d0e5b4Richard Uhler      // the optimizing compiler always generates PIC.
20605dd8a63e213d2bf025c97b9cd04eee354d0e5b4Richard Uhler      args.push_back("--compiler-backend=Quick");
20766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
20866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("--runtime-arg");
20966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    args.push_back("-Xnorelocate");
21066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string error_msg;
21166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
21266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    setenv("ANDROID_DATA", android_data_.c_str(), 1);
21366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
21466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
21566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void GeneratePicOdexForTest(const std::string& dex_location,
21666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler                              const std::string& odex_location) {
21766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    GenerateOdexForTest(dex_location, odex_location, true);
21866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
21966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
22066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private:
22166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reserve memory around where the image will be loaded so other memory
22266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // won't conflict when it comes time to load the image.
22366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // This can be called with an already loaded image to reserve the space
22466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // around it.
22566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void ReserveImageSpace() {
22666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    MemMap::Init();
22766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
22866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Ensure a chunk of memory is reserved for the image space.
22966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    uintptr_t reservation_start = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MIN_DELTA;
23066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    uintptr_t reservation_end = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MAX_DELTA
2313dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi        // Include the main space that has to come right after the
2323dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi        // image in case of the GSS collector.
2333dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi        + 384 * MB;
23466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
23566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
23666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
23766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    for (BacktraceMap::const_iterator it = map->begin();
23866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reservation_start < reservation_end && it != map->end(); ++it) {
2393efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end));
2403efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      reservation_start = std::max(reservation_start, it->end);
2413efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    }
2423efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    ReserveImageSpaceChunk(reservation_start, reservation_end);
2433efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  }
24466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2453efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  // Reserve a chunk of memory for the image space in the given range.
2463efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  // Only has effect for chunks with a positive number of bytes.
2473efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler  void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) {
2483efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler    if (start < end) {
2493efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler      std::string error_msg;
25066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      image_reservation_.push_back(std::unique_ptr<MemMap>(
25166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          MemMap::MapAnonymous("image reservation",
2523efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler              reinterpret_cast<uint8_t*>(start), end - start,
25366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler              PROT_NONE, false, false, &error_msg)));
25466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
25566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      LOG(INFO) << "Reserved space for image " <<
25666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
25766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        reinterpret_cast<void*>(image_reservation_.back()->End());
25866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
25966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
26066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
26166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
26266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Unreserve any memory reserved by ReserveImageSpace. This should be called
26366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // before the image is loaded.
26466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void UnreserveImageSpace() {
26566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    image_reservation_.clear();
26666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
26766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
26866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string scratch_dir_;
2696343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_oat_dir_;
2706343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_dir_;
27166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<MemMap>> image_reservation_;
27266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
27366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
27466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass OatFileAssistantNoDex2OatTest : public OatFileAssistantTest {
27566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
27666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
27766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    OatFileAssistantTest::SetUpRuntimeOptions(options);
27866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    options->push_back(std::make_pair("-Xnodex2oat", nullptr));
27966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
28066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
28166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
28266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Generate an oat file for the purposes of test, as opposed to testing
28366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// generation of oat files.
28466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstatic void GenerateOatForTest(const char* dex_location) {
28566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location, kRuntimeISA, false);
28666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
28766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
28866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file_assistant.GenerateOatFile(&error_msg)) << error_msg;
28966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
29066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
29166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, but no OAT file for it.
29295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
29366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexNoOat) {
29466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
29566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
29666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
29766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
29866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
29995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
30066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
30166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
30266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
30366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
30466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
30566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
30695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
30766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
30866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
30966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
31066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
31195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
31266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
31366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
31466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have no DEX file and no OAT file.
31595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: Status is kDex2OatNeeded. Loading should fail, but not crash.
31666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NoDexNoOat) {
31766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
31866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
31966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
32066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
32195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
32266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
32366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(nullptr, oat_file.get());
32466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
32566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
32666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
32795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded.
32866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatUpToDate) {
32966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
33066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
33166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
33266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
33366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
33466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
33595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
33666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
33766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
33866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
33966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
34066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
34166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
34266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
34366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
34495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
34566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
34666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
34766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it.
34895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded and we load all dex files.
34966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
35066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
35166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
35266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
35366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
354e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
35595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
35695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
35795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Verify we can load both dex files.
358e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
359e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
360e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
361e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
362e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
363e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ(2u, dex_files.size());
364e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler}
365e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
36667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Case: We have a MultiDEX file where the secondary dex file is out of date.
36767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Expect: The status is kDex2OatNeeded.
36867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard UhlerTEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) {
36967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar";
37067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
37167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Compile code for GetMultiDexSrc1.
37267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  Copy(GetMultiDexSrc1(), dex_location);
37367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  GenerateOatForTest(dex_location.c_str());
37467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
37567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
37667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  // is out of date.
37767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  Copy(GetMultiDexSrc2(), dex_location);
37867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
37967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
38067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
38167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler}
38267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler
383e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it with relative
384e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// encoded dex locations.
38595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The oat file status is kNoDexOptNeeded.
386e5fed03772144595c0904faf3d6974cc55214c8cRichard UhlerTEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
387e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
3886343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
389e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
390e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Create the dex file
391e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
392e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
393e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Create the oat file with relative encoded dex location.
394e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::vector<std::string> args;
395e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--dex-file=" + dex_location);
396e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
397e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  args.push_back("--oat-file=" + oat_location);
398e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
399e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::string error_msg;
400e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
401e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
402e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  // Verify we can load both dex files.
403e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
404e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                                      oat_location.c_str(),
405e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler                                      kRuntimeISA, true);
406e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
40766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
40866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
40966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
410e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
41166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(2u, dex_files.size());
41266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
41366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
41495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file and out-of-date OAT file.
41595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
41666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatOutOfDate) {
41766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar";
41866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
41966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // We create a dex, generate an oat for it, then overwrite the dex with a
42066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // different dex to make the oat out of date.
42166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
42266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
42366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc2(), dex_location);
42466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
42566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
42695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
42766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
42866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
42966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
43066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
43166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
43266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
43366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
43466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
43566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
43666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
43766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, but no OAT file.
43895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded.
43966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexOdexNoOat) {
44066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
4416343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
44266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
44366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
44466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
44566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
44666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
44766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
44866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
44966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
45095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
45166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
45266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
45366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
45466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
45566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
45666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
45766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
45866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
45966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
46066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
46166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
46266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a stripped DEX file and an ODEX file, but no OAT file.
46395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded
46466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
46566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
4666343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
46766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
46866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
46966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
47066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
47166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
47266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Strip the dex file
47366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
47466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
47566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
47666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
47766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
47895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
47966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
48066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
48166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
48266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
48366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
48466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
48566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
48666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
48766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
48866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Make the oat file up to date.
48966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
49066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
49166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
49295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
49366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
49466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
49566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
49666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
49766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
49866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
49966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
50066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
50166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
50266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify we can load the dex files from it.
50366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
50466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
50566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
50666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
50766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
50866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
50966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
51066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
51195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file.
51295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded.
51366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
51466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
5156343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
51666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
51766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the oat file from a different dex file so it looks out of date.
51866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc2(), dex_location);
51966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
52066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
52166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the odex file
52266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
52366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
52466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
52566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Strip the dex file.
52666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetStrippedDexSrc1(), dex_location);
52766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
52866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
52966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
53066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
53195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
53266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
53366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
53466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
53566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
53666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
53766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
53866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
53966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
54066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
54166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
54266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Make the oat file up to date.
54366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
54466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
54566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
54695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
54766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
54866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
54966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
55066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
55166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
55266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
55366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
55466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
55566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
55666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
55766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
55866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify we can load the dex files from it.
55966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
56066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
56166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
56266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
56366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
56466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
56566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
56666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
56795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file, no ODEX file and an OAT file that needs
56895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// relocation.
56995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kSelfPatchOatNeeded.
57095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerTEST_F(OatFileAssistantTest, SelfRelocation) {
57195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string dex_location = GetScratchDir() + "/SelfRelocation.jar";
57295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string oat_location = GetOdexDir() + "/SelfRelocation.oat";
57395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
57495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Create the dex and odex files
57595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  Copy(GetDexSrc1(), dex_location);
57695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  GenerateOdexForTest(dex_location, oat_location);
57795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
57895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
57995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler      oat_location.c_str(), kRuntimeISA, true);
58095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
58195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
58295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
58395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
58495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
58595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
58695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
58795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
58895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
58995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation());
59095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
59195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
59295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
59395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  // Make the oat file up to date.
59495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::string error_msg;
59595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
59695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
59795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
59895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
59995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
60095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
60195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
60295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
60395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
60495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
60595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
60695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
60795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
60895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
60995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
61095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
61195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
61295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
61395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
61495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(1u, dex_files.size());
61595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler}
61695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
61766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
61866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// OAT files both have patch delta of 0.
61995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: It shouldn't crash, and status is kPatchOatNeeded.
62066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OdexOatOverlap) {
62166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
6226343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
6236343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
62466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
62566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
62666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
62766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
62866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
62966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the oat file by copying the odex so they are located in the same
63066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // place in memory.
63166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(odex_location, oat_location);
63266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
63366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify things don't go bad.
63466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(),
63566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      oat_location.c_str(), kRuntimeISA, true);
63666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
63795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
63866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
63966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
64066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
64166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
64266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
64366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileExists());
64466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
64566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
64666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
64766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Things aren't relocated, so it should fall back to interpreted.
64866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
64966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
650f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler
65166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
65266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
65366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
65466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
655f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler
656f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  // Add some extra checks to help diagnose apparently flaky test failures.
657f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  Runtime* runtime = Runtime::Current();
658f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
659f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  ASSERT_TRUE(image_space != nullptr);
660f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  const ImageHeader& image_header = image_space->GetImageHeader();
661f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  const OatHeader& oat_header = oat_file->GetOatHeader();
662f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  EXPECT_FALSE(oat_file->IsPic());
663f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  EXPECT_EQ(image_header.GetOatChecksum(), oat_header.GetImageFileLocationOatChecksum());
664f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()),
665f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler      oat_header.GetImageFileLocationOatDataBegin());
666f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler  EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta());
66766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
66866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
66966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
67095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
67166d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
67266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
6736343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
67466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
67566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
67666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
67766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GeneratePicOdexForTest(dex_location, odex_location);
67866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
67966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the status.
68066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
68166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
68295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
68366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
68466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
68566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
68666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
68766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
68866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
68966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
69066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
69166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
69266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
69366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
69466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file.
69566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadOatUpToDate) {
69666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
69766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
69866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
69966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
70066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
70166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an oat file assistant.
70266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
70366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
70466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
70566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
70666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
70766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
70866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
70966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
71066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
71166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
71266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it.
71366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Loading non-executable should load the oat non-executable.
71466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
71566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
71666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
71766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
71866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOatForTest(dex_location.c_str());
71966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
72066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an oat file assistant.
72166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
72266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
72366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
72466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
72566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
72666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
72766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
72866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
72966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
73066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
73166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file.
73266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file from an alternative oat
73366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// location.
73466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
73566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
73666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
73766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
73866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
73966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
74066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(
74166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, true);
74266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
74366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
74466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
74566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
74666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
74766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file->IsExecutable());
74866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
74966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
75066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
75166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
75266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
75366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
75466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify it didn't create an oat in the default location.
75566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false);
75666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(ofm.OatFileExists());
75766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
75866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
75966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-existent Dex location.
76066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: The dex code is out of date, and trying to update it fails.
76166d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NonExsistentDexLocation) {
76266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/BadDexLocation.jar";
76366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
76466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
76566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
76666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
76795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
76866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
76966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
77066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
77166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
77266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
77366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
77466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
77566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
77666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.MakeUpToDate(&error_msg));
77766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(error_msg.empty());
77866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
77966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Turn an absolute path into a path relative to the current working
78166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// directory.
78266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstatic std::string MakePathRelative(std::string target) {
78366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  char buf[MAXPATHLEN];
78466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string cwd = getcwd(buf, MAXPATHLEN);
78566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Split the target and cwd paths into components.
78766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> target_path;
78866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> cwd_path;
78966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Split(target, '/', &target_path);
79066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Split(cwd, '/', &cwd_path);
79166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
79266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reverse the path components, so we can use pop_back().
79366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(target_path.begin(), target_path.end());
79466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(cwd_path.begin(), cwd_path.end());
79566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
79666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Drop the common prefix of the paths. Because we reversed the path
79766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // components, this becomes the common suffix of target_path and cwd_path.
79866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  while (!target_path.empty() && !cwd_path.empty()
79966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      && target_path.back() == cwd_path.back()) {
80066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    target_path.pop_back();
80166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cwd_path.pop_back();
80266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
80366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
80466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // For each element of the remaining cwd_path, add '..' to the beginning
80566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // of the target path. Because we reversed the path components, we add to
80666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // the end of target_path.
80766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (unsigned int i = 0; i < cwd_path.size(); i++) {
80866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    target_path.push_back("..");
80966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
81066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
81166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Reverse again to get the right path order, and join to get the result.
81266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::reverse(target_path.begin(), target_path.end());
81366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return Join(target_path, '/');
81466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
81566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
81666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-absolute path to Dex location.
81766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Not sure, but it shouldn't crash.
81866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
81966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
82066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), abs_dex_location);
82166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
82266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = MakePathRelative(abs_dex_location);
82366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
82466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
82566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
82695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
82766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
82866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
82966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
83066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
83166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
83266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
83366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
83466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
83566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Very short, non-existent Dex location.
83666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Dex code is out of date, and trying to update it fails.
83766d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, ShortDexLocation) {
83866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = "/xx";
83966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
84066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
84166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
84266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
84395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
84466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
84566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
84666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
84766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
84866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
84966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
85066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
85166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
85266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.MakeUpToDate(&error_msg));
85366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(error_msg.empty());
85466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
85566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
85666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-standard extension for dex file.
85795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded.
85866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LongDexExtension) {
85966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
86066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
86166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
86266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
86366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
86495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
86566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
86666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
86766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
86866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
86966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
87066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileExists());
87166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
87266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
87366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
87466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
87566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// A task to generate a dex location. Used by the RaceToGenerate test.
87666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass RaceGenerateTask : public Task {
87766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public:
87866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
87966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    : dex_location_(dex_location), oat_location_(oat_location),
88066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      loaded_oat_file_(nullptr)
88166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  {}
88266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
88366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  void Run(Thread* self) {
88466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    UNUSED(self);
88566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
88666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Load the dex files, and save a pointer to the loaded oat file, so that
88766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // we can verify only one oat file was loaded for the dex location.
88866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    ClassLinker* linker = Runtime::Current()->GetClassLinker();
88966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::unique_ptr<const DexFile>> dex_files;
89066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::vector<std::string> error_msgs;
89166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    dex_files = linker->OpenDexFilesFromOat(dex_location_.c_str(), oat_location_.c_str(), &error_msgs);
89266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
89307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
89407b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler    loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
89566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
89666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
89766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile* GetLoadedOatFile() const {
89866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return loaded_oat_file_;
89966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
90066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
90166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private:
90266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location_;
90366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string oat_location_;
90466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile* loaded_oat_file_;
90566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler};
90666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
90766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Test the case where multiple processes race to generate an oat file.
90866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// This simulates multiple processes using multiple threads.
90966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//
91066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// We want only one Oat file to be loaded when there is a race to load, to
91166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// avoid using up the virtual memory address space.
91266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, RaceToGenerate) {
91366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
9146343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
91566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
91666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // We use the lib core dex file, because it's large, and hopefully should
91766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // take a while to generate.
91866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetLibCoreDexFileName(), dex_location);
91966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
92066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const int kNumThreads = 32;
92166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Thread* self = Thread::Current();
92266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
92366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
92466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (int i = 0; i < kNumThreads; i++) {
92566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
92666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    thread_pool.AddTask(self, task.get());
92766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    tasks.push_back(std::move(task));
92866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
92966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  thread_pool.StartWorkers(self);
93066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  thread_pool.Wait(self, true, false);
93166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
93266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify every task got the same pointer.
93366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile* expected = tasks[0]->GetLoadedOatFile();
93466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (auto& task : tasks) {
93566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    EXPECT_EQ(expected, task->GetLoadedOatFile());
93666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
93766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
93866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
93966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
94066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled.
94166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable.
94266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
94366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
9446343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
94566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
94666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
94766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetDexSrc1(), dex_location);
94866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
94966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
95066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an executable oat file assistant.
95166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
95266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
95366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
95466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
95566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
95666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
95766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
95866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(1u, dex_files.size());
95966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
96066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
96166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
96266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled.
96366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable.
96466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
96566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
9666343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
96766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
96866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Create the dex and odex files
96966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Copy(GetMultiDexSrc1(), dex_location);
97066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GenerateOdexForTest(dex_location, odex_location);
97166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
97266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the oat using an executable oat file assistant.
97366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
97466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
97566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
97666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ASSERT_TRUE(oat_file.get() != nullptr);
97766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(oat_file->IsExecutable());
97866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
97966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
98066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_EQ(2u, dex_files.size());
98166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
98266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
98366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) {
98466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
98566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string odex_file;
98666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
98766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
98866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
9896343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
99066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
99166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
99266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
9936343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
99466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
99566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
99666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        "nopath.jar", kArm, &odex_file, &error_msg));
99766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
99866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
99966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
100066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
100123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// Verify the dexopt status values from dalvik.system.DexFile
100223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// match the OatFileAssistant::DexOptStatus values.
100323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard UhlerTEST_F(OatFileAssistantTest, DexOptStatusValues) {
100423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ScopedObjectAccess soa(Thread::Current());
100523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  StackHandleScope<1> hs(soa.Self());
100623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ClassLinker* linker = Runtime::Current()->GetClassLinker();
100723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  Handle<mirror::Class> dexfile(
100823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
100923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(dexfile.Get() == nullptr);
101023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  linker->EnsureInitialized(soa.Self(), dexfile, true, true);
101123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1012c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
101323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I");
101423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(no_dexopt_needed == nullptr);
101523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
101623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get()));
101723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1018c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* dex2oat_needed = mirror::Class::FindStaticField(
101923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "DEX2OAT_NEEDED", "I");
102023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(dex2oat_needed == nullptr);
102123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
102223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get()));
102323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1024c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* patchoat_needed = mirror::Class::FindStaticField(
102523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "PATCHOAT_NEEDED", "I");
102623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(patchoat_needed == nullptr);
102723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
102823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get()));
102923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler
1030c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
103123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler      soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I");
103223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  ASSERT_FALSE(self_patchoat_needed == nullptr);
103323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
103423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get()));
103523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler}
103666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
103766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// TODO: More Tests:
103866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test class linker falls back to unquickened dex for DexNoOat
103966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test class linker falls back to unquickened dex for MultiDexNoOat
104066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test using secondary isa
104166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test with profiling info?
104266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test for status of oat while oat is being generated (how?)
104366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test case where 32 and 64 bit boot class paths differ,
104466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//      and we ask IsInBootClassPath for a class in exactly one of the 32 or
104566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//      64 bit boot class paths.
104666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//  * Test unexpected scenarios (?):
104766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    - Dex is stripped, don't have odex.
104866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    - Oat file corrupted after status check, before reload unexecutable
104966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler//    because it's unrelocated and no dex2oat
105066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
105166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}  // namespace art
1052