oat_file_assistant_test.cc revision ff0274bd8a67e3512ff85cc05b77fd01df368638
18d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes/*
28d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Copyright (C) 2014 The Android Open Source Project
38d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *
48d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
58d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * you may not use this file except in compliance with the License.
68d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * You may obtain a copy of the License at
78d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *
88d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
98d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *
108d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Unless required by applicable law or agreed to in writing, software
118d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
128d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * See the License for the specific language governing permissions and
148d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * limitations under the License.
158d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes */
160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#include "oat_file_assistant.h"
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom
190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <algorithm>
2002b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes#include <fstream>
21306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers#include <string>
22a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include <vector>
23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <sys/param.h>
24700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers
258ce6b9040747054b444a7fa706503cd257801936Dave Allison#include <backtrace/BacktraceMap.h>
268daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <gtest/gtest.h>
27b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
284dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang#include "art_field-inl.h"
29d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "class_linker-inl.h"
30b8e087e0dfd619df90cbb56534478a60bc859ebfIan Rogers#include "common_runtime_test.h"
31761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "compiler_callbacks.h"
32719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "gc/space/image_space.h"
33848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers#include "mem_map.h"
34848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers#include "oat_file_manager.h"
357655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "os.h"
36578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "scoped_thread_state_change.h"
37eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier#include "thread-inl.h"
38956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes#include "utils.h"
39306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers
4083c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartiernamespace art {
41578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
429d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesclass OatFileAssistantTest : public CommonRuntimeTest {
4368e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes public:
442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  virtual void SetUp() {
45b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    ReserveImageSpace();
460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro    CommonRuntimeTest::SetUp();
470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
4815d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier    // Create a scratch directory to work from.
4915d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier    scratch_dir_ = android_data_ + "/OatFileAssistantTest";
5098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang    ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700));
5115d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier
5215d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier    // Create a subdirectory in scratch for odex files.
5315d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier    odex_oat_dir_ = scratch_dir_ + "/oat";
542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700));
55848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers
56848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers    odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA));
57848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers    ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700));
58848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers
59848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers
60848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers    // Verify the environment is as we expect
61848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers    uint32_t checksum;
62848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers    std::string error_msg;
6380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko    ASSERT_TRUE(OS::FileExists(GetImageFile().c_str()))
64848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers      << "Expected pre-compiled boot image to be at: " << GetImageFile();
652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str()))
6612d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier      << "Expected dex file to be at: " << GetDexSrc1();
6712d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier    ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str()))
6812d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier      << "Expected stripped dex file to be at: " << GetStrippedDexSrc1();
6912d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier    ASSERT_FALSE(DexFile::GetChecksum(GetStrippedDexSrc1().c_str(), &checksum, &error_msg))
7012d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier      << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1();
71e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str()))
722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      << "Expected dex file to be at: " << GetDexSrc2();
732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
747a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers    // GetMultiDexSrc2 should have the same primary dex checksum as
75bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    // GetMultiDexSrc1, but a different secondary dex checksum.
761b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers    std::vector<std::unique_ptr<const DexFile>> multi1;
77f795869da0a1fa006fdcdacd8afb6149a63fc1a7Sebastien Hertz    ASSERT_TRUE(DexFile::Open(GetMultiDexSrc1().c_str(),
7881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers          GetMultiDexSrc1().c_str(), &error_msg, &multi1)) << error_msg;
79b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers    ASSERT_GT(multi1.size(), 1u);
8081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers
818daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    std::vector<std::unique_ptr<const DexFile>> multi2;
82b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro    ASSERT_TRUE(DexFile::Open(GetMultiDexSrc2().c_str(),
832b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier          GetMultiDexSrc2().c_str(), &error_msg, &multi2)) << error_msg;
84f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chien    ASSERT_GT(multi2.size(), 1u);
85597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz
86f795869da0a1fa006fdcdacd8afb6149a63fc1a7Sebastien Hertz    ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum());
8740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom    ASSERT_NE(multi1[1]->GetLocationChecksum(), multi2[1]->GetLocationChecksum());
8840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  }
890e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
9034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
9134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes    // options->push_back(std::make_pair("-verbose:oat", nullptr));
9234e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes
9334e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes    // Set up the image location.
9434e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes    options->push_back(std::make_pair("-Ximage:" + GetImageLocation(),
9534e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes          nullptr));
9634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes    // Make sure compilercallbacks are not set so that relocation will be
97fc1d9f581592d54cc14240b9909824af38656931Elliott Hughes    // enabled.
98474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers    callbacks_.reset();
9950ffee20ced9c0c7ac68889c86be8844cf120cf2Ian Rogers  }
10050ffee20ced9c0c7ac68889c86be8844cf120cf2Ian Rogers
10162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void PreRuntimeCreate() {
102474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers    UnreserveImageSpace();
103474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  }
104f795869da0a1fa006fdcdacd8afb6149a63fc1a7Sebastien Hertz
1051f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  virtual void PostRuntimeCreate() {
1061f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang    ReserveImageSpace();
1071f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  }
1081f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
109e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  virtual void TearDown() {
110e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers    ClearDirectory(odex_dir_.c_str());
111648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    ASSERT_EQ(0, rmdir(odex_dir_.c_str()));
112648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison
113648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    ClearDirectory(odex_oat_dir_.c_str());
114648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str()));
115648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison
116648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    ClearDirectory(scratch_dir_.c_str());
117648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    ASSERT_EQ(0, rmdir(scratch_dir_.c_str()));
118648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison
119648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    CommonRuntimeTest::TearDown();
120648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  }
121648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison
122648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  void Copy(std::string src, std::string dst) {
123648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    std::ifstream  src_stream(src, std::ios::binary);
124648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    std::ofstream  dst_stream(dst, std::ios::binary);
125648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison
126648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    dst_stream << src_stream.rdbuf();
127648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  }
128648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison
129648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  // Returns the directory where the pre-compiled core.art can be found.
130648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  // TODO: We should factor out this into common tests somewhere rather than
131648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  // re-hardcoding it here (This was copied originally from the elf writer
132648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  // test).
133648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  std::string GetImageDirectory() {
134648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    if (IsHost()) {
135648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison      const char* host_dir = getenv("ANDROID_HOST_OUT");
136648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison      CHECK(host_dir != nullptr);
137648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison      return std::string(host_dir) + "/framework";
138648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison    } else {
139dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      return std::string("/data/art-test");
14034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes    }
141f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison  }
142f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison
143f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison  std::string GetImageLocation() {
144f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison    return GetImageDirectory() + "/core.art";
145648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  }
1467ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
147f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison  std::string GetImageFile() {
148462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes    return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA)
149462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes      + "/core.art";
15052673ffae0025d86f4023735581f19ebcc477487Ian Rogers  }
15161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
152462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  std::string GetDexSrc1() {
153462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes    return GetTestDexFileName("Main");
154664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier  }
155664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier
156b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex
157caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  // file stripped.
158caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  std::string GetStrippedDexSrc1() {
159caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom    return GetTestDexFileName("MainStripped");
1606f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers  }
1616f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers
1626f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers  std::string GetMultiDexSrc1() {
16302ed4c04468ca5f5540c5b704ac3e2f30eb9e8f4Ian Rogers    return GetTestDexFileName("MultiDex");
1640e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
1657b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers
1667b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  // Returns the path to a multidex file equivalent to GetMultiDexSrc2, but
1677b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  // with the contents of the secondary dex file changed.
1687b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  std::string GetMultiDexSrc2() {
1697b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers    return GetTestDexFileName("MultiDexModifiedSecondary");
1707b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  }
1712b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier
1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  std::string GetDexSrc2() {
173a77f0f68a59870ff027dad654fe31eb3fdaf3d5djeffhao    return GetTestDexFileName("Nested");
174b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  }
175b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers
1762b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier  // Scratch directory, for dex and odex files (oat files will go in the
177a77f0f68a59870ff027dad654fe31eb3fdaf3d5djeffhao  // dalvik cache).
178b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  std::string GetScratchDir() {
179b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    return scratch_dir_;
1808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
18128fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes
182dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Odex directory is the subdirectory in the scratch directory where odex
183dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // files should be located.
18428fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes  std::string GetOdexDir() {
18500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return odex_dir_;
18600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
18700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
18800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Generate a non-PIC odex file for the purposes of test.
18900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // The generated odex file will be un-relocated.
190b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void GenerateOdexForTest(const std::string& dex_location,
191b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                           const std::string& odex_location,
192a09576416788b916095739e43a16917e7948f3a4Elliott Hughes                           CompilerFilter::Filter filter) {
193c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier    // To generate an un-relocated odex file, we first compile a relocated
194c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier    // version of the file, then manually call patchoat to make it look as if
195c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier    // it is unrelocated.
196c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier    std::string relocated_odex_location = odex_location + ".relocated";
1972cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    std::vector<std::string> args;
198abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes    args.push_back("--dex-file=" + dex_location);
19900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    args.push_back("--oat-file=" + relocated_odex_location);
200cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers    args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
201cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers
202abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes    // We need to use the quick compiler to generate non-PIC code, because
203474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers    // the optimizing compiler always generates PIC.
204dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    args.push_back("--compiler-backend=Quick");
205dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    args.push_back("--include-patch-information");
206dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
2070aded089f565008ba5908e395e5914ca4f91f2deDave Allison    std::string error_msg;
2080aded089f565008ba5908e395e5914ca4f91f2deDave Allison    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
209474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers
2108d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes    // Use patchoat to unrelocate the relocated odex file.
21181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers    Runtime* runtime = Runtime::Current();
212dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    std::vector<std::string> argv;
21352673ffae0025d86f4023735581f19ebcc477487Ian Rogers    argv.push_back(runtime->GetPatchoatExecutable());
21452673ffae0025d86f4023735581f19ebcc477487Ian Rogers    argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA)));
21581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers    argv.push_back("--input-oat-file=" + relocated_odex_location);
216dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    argv.push_back("--output-oat-file=" + odex_location);
21700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    argv.push_back("--base-offset-delta=0x00008000");
21800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    std::string command_line(Join(argv, ' '));
219858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier    ASSERT_TRUE(Exec(argv, &error_msg)) << error_msg;
22059cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman
221dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    // Verify the odex file was generated as expected and really is
222858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier    // unrelocated.
223858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier    std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(),
22400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                     odex_location.c_str(),
22500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                     nullptr,
22601ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers                                                     nullptr,
227b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                                                     false,
22800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                     /*low_4gb*/false,
229d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers                                                     dex_location.c_str(),
230d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers                                                     &error_msg));
231858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
2322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    EXPECT_FALSE(odex_file->IsPic());
2332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    EXPECT_TRUE(odex_file->HasPatchInfo());
2342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    EXPECT_EQ(filter, odex_file->GetCompilerFilter());
23500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
23600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (CompilerFilter::IsCompilationEnabled(filter)) {
2379da7f59c9059397182b9a97e898a42ec06d4d646Ian Rogers      const std::vector<gc::space::ImageSpace*> image_spaces =
238b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers        runtime->GetHeap()->GetBootImageSpaces();
239b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr);
24000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      const ImageHeader& image_header = image_spaces[0]->GetImageHeader();
24100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      const OatHeader& oat_header = odex_file->GetOatHeader();
24200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      EXPECT_EQ(image_header.GetOatChecksum(), oat_header.GetImageFileLocationOatChecksum());
243b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()),
244693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers          oat_header.GetImageFileLocationOatDataBegin());
2451ffa32f0be7becec4907b26ead353e4b17e1219cIan Rogers      EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta());
24600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
24700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
24800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
24900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void GeneratePicOdexForTest(const std::string& dex_location,
250b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                              const std::string& odex_location,
251693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers                              CompilerFilter::Filter filter) {
2521ffa32f0be7becec4907b26ead353e4b17e1219cIan Rogers    // Temporarily redirect the dalvik cache so dex2oat doesn't find the
253038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes    // relocated image file.
2540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp";
25552673ffae0025d86f4023735581f19ebcc477487Ian Rogers    setenv("ANDROID_DATA", android_data_tmp.c_str(), 1);
256590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    std::vector<std::string> args;
2572cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    args.push_back("--dex-file=" + dex_location);
258dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    args.push_back("--oat-file=" + odex_location);
259dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
260dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    args.push_back("--compile-pic");
261590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    args.push_back("--runtime-arg");
262590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    args.push_back("-Xnorelocate");
263590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    std::string error_msg;
264590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
26552673ffae0025d86f4023735581f19ebcc477487Ian Rogers    setenv("ANDROID_DATA", android_data_.c_str(), 1);
26652673ffae0025d86f4023735581f19ebcc477487Ian Rogers
2670399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    // Verify the odex file was generated as expected.
26852673ffae0025d86f4023735581f19ebcc477487Ian Rogers    std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(),
269590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                                     odex_location.c_str(),
270dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                     nullptr,
271dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                     nullptr,
272dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                     false,
273dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                     /*low_4gb*/false,
274590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                                     dex_location.c_str(),
2750399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers                                                     &error_msg));
27600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
27700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    EXPECT_TRUE(odex_file->IsPic());
2780399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    EXPECT_EQ(filter, odex_file->GetCompilerFilter());
27900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
280dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Generate a non-PIC odex file without patch information for the purposes
28200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // of test.  The generated odex file will be un-relocated.
283dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // TODO: This won't work correctly if we depend on the boot image being
2845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // randomly relocated by a non-zero amount. We should have a better solution
2858daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // for avoiding that flakiness and duplicating code to generate odex and oat
2868daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // files for test.
2878daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  void GenerateNoPatchOdexForTest(const std::string& dex_location,
2888daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes                                  const std::string& odex_location,
2898daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes                                  CompilerFilter::Filter filter) {
2908daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    // Temporarily redirect the dalvik cache so dex2oat doesn't find the
2918daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    // relocated image file.
2928daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp";
2938daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    setenv("ANDROID_DATA", android_data_tmp.c_str(), 1);
2948daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    std::vector<std::string> args;
2958daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    args.push_back("--dex-file=" + dex_location);
2968daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    args.push_back("--oat-file=" + odex_location);
2978daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
2988daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    args.push_back("--runtime-arg");
2998daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    args.push_back("-Xnorelocate");
3008daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    std::string error_msg;
301d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
302dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    setenv("ANDROID_DATA", android_data_.c_str(), 1);
303b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
304b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro    // Verify the odex file was generated as expected.
305d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes    std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(),
306dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                     odex_location.c_str(),
307d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes                                                     nullptr,
308e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes                                                     nullptr,
3092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier                                                     false,
3102b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier                                                     /*low_4gb*/false,
311b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                                                     dex_location.c_str(),
312899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes                                                     &error_msg));
313ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes    ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
314ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes    EXPECT_FALSE(odex_file->IsPic());
315ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes    EXPECT_FALSE(odex_file->HasPatchInfo());
316ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes    EXPECT_EQ(filter, odex_file->GetCompilerFilter());
317899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  }
318b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers
319fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes private:
32057dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao  // Reserve memory around where the image will be loaded so other memory
32157dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao  // won't conflict when it comes time to load the image.
32257dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao  // This can be called with an already loaded image to reserve the space
3232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // around it.
324dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  void ReserveImageSpace() {
325dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    MemMap::Init();
3268daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
3278daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    // Ensure a chunk of memory is reserved for the image space.
32800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    uintptr_t reservation_start = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MIN_DELTA;
329dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    uintptr_t reservation_end = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MAX_DELTA
33000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        // Include the main space that has to come right after the
33100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        // image in case of the GSS collector.
3329d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes        + 384 * MB;
333dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
3349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes    std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
3359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes    ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
3367dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes    for (BacktraceMap::const_iterator it = map->begin();
3377dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes        reservation_start < reservation_end && it != map->end(); ++it) {
3380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro      ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end));
339dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      reservation_start = std::max(reservation_start, it->end);
3400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro    }
3410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro    ReserveImageSpaceChunk(reservation_start, reservation_end);
34214691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray  }
343dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
3440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Reserve a chunk of memory for the image space in the given range.
3450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Only has effect for chunks with a positive number of bytes.
346d9efea646485fe996c967f4680a3fc4cdc40b251Andreas Gampe  void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) {
347a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier    if (start < end) {
34800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      std::string error_msg;
3498d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier      image_reservation_.push_back(std::unique_ptr<MemMap>(
35000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers          MemMap::MapAnonymous("image reservation",
35114691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray              reinterpret_cast<uint8_t*>(start), end - start,
35262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers              PROT_NONE, false, false, &error_msg)));
3532cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier      ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
354474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers      LOG(INFO) << "Reserved space for image " <<
355dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
3560cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers        reinterpret_cast<void*>(image_reservation_.back()->End());
3570cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    }
358a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov  }
359dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
36094d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao
36194d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao  // Unreserve any memory reserved by ReserveImageSpace. This should be called
362bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // before the image is loaded.
363794ad76e8d5b5b9132819d5b08a0570e27615644Andreas Gampe  void UnreserveImageSpace() {
364bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    image_reservation_.clear();
365bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
3660399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
3674dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang  std::string scratch_dir_;
3684dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang  std::string odex_oat_dir_;
3694dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang  std::string odex_dir_;
3704dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang  std::vector<std::unique_ptr<MemMap>> image_reservation_;
3714dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang};
3724dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang
3734dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yangclass OatFileAssistantNoDex2OatTest : public OatFileAssistantTest {
3744dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang public:
3754dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
3764dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang    OatFileAssistantTest::SetUpRuntimeOptions(options);
3774dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang    options->push_back(std::make_pair("-Xnodex2oat", nullptr));
3784dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang  }
379dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers};
3801a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
3811a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao// Generate an oat file for the purposes of test, as opposed to testing
3826ec8ebd178ed39aa09e4c7fad194900114c4121aAndreas Gampe// generation of oat files.
3836ec8ebd178ed39aa09e4c7fad194900114c4121aAndreas Gampestatic void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) {
384e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  // Use an oat file assistant to find the proper oat location.
385b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  OatFileAssistant ofa(dex_location, kRuntimeISA, false, false);
3860399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  const std::string* oat_location = ofa.OatFileName();
3877642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray  ASSERT_TRUE(oat_location != nullptr);
3887642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray
3897642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray  std::vector<std::string> args;
3907642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray  args.push_back("--dex-file=" + std::string(dex_location));
3917642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray  args.push_back("--oat-file=" + *oat_location);
392e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
393dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  args.push_back("--runtime-arg");
3940e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  args.push_back("-Xnorelocate");
3950e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  std::string error_msg;
39611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
397dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
39811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao  // Verify the oat file was generated as expected.
39911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao  std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location->c_str(),
4000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers                                                  oat_location->c_str(),
401dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                  nullptr,
402dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                                                  nullptr,
403bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers                                                  false,
404bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers                                                  /*low_4gb*/false,
4052cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier                                                  dex_location,
4060aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray                                                  &error_msg));
407b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  ASSERT_TRUE(oat_file.get() != nullptr) << error_msg;
4085cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  EXPECT_EQ(filter, oat_file->GetCompilerFilter());
4092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier}
410a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes
4110aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray// Case: We have a DEX file, but no OAT file for it.
412b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers// Expect: The status is kDex2OatNeeded.
413a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott HughesTEST_F(OatFileAssistantTest, DexNoOat) {
4140aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray  std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
4150aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray  Copy(GetDexSrc1(), dex_location);
416b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers
417a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
4180aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray
419b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4204a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
4212ced6a534157d5d963693346904389c19775d2daElliott Hughes  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
4228a8b9cbe158ee13477f2381f164c519762a06fefElliott Hughes      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
423120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
42479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
425be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
426038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
427c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes
428b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
429b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
43069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
431dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
432b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
433b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
434408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  EXPECT_FALSE(oat_file_assistant.OatFileExists());
4352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
436b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
437a6e7f0872c42009ecbee82d7fbe452deef9ae65bMathieu Chartier  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
438dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
439dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
440dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
441a6e7f0872c42009ecbee82d7fbe452deef9ae65bMathieu Chartier
442dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have no DEX file and no OAT file.
443dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
444dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, NoDexNoOat) {
4458daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
446dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
4478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
448dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
449dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
450dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
451dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
452dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
453dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Trying to make the oat file up to date should not fail or crash.
454dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string error_msg;
455dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
456dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg));
457dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
458dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Trying to get the best oat file should fail, but not crash.
459dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
460dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(nullptr, oat_file.get());
461dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
462dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
463dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file and up-to-date OAT file for it.
464dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kNoDexOptNeeded.
465dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, OatUpToDate) {
466dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
467dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
468dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
469dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
470dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
471dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
472dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
473dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
474dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
475dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
476dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
477dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
478dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
479dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
480dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
481dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
482dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
483dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
484dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
485dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileExists());
486dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
4875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
48868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
489dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
490c143c55718342519db5398e41dda31422cf16c79buzbee  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
491c143c55718342519db5398e41dda31422cf16c79buzbee}
49268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers
493c143c55718342519db5398e41dda31422cf16c79buzbee// Case: We have a DEX file and speed-profile OAT file for it.
494aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers// Expect: The status is kNoDexOptNeeded if the profile hasn't changed.
495ee1d79a603c77c0667b27c075a983579d5c51f7eSebastien HertzTEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
496ee1d79a603c77c0667b27c075a983579d5c51f7eSebastien Hertz  std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
4972b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier  Copy(GetDexSrc1(), dex_location);
498b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
49901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes
50001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
5012cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier
5022cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
50301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
5042b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
5052b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
5062b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier
50753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
50855df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
509bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
5106f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
5114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  EXPECT_TRUE(oat_file_assistant.OatFileExists());
512250455229aa0cc07bbd18174efe510bd52631a99jeffhao  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
513be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
514be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
515be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
516be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
517dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
518dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
519dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file and speed-profile OAT file for it.
520dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kNoDex2OatNeeded if the profile has changed.
521dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, ProfileOatOutOfDate) {
522dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = GetScratchDir() + "/ProfileOatOutOfDate.jar";
523dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
524dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
525dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
526dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true, false);
527dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
528dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
529dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
530dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
531dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
532dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
533dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
534dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
535dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
536dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
537dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileExists());
538dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
539dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
540dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
541dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
542dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
543dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
544dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
545dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a MultiDEX file and up-to-date OAT file for it.
546dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kNoDexOptNeeded and we load all dex files.
547dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
548dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
549dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetMultiDexSrc1(), dex_location);
550dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
551dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
552848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
553848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
554848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
555848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
556848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao
557848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  // Verify we can load both dex files.
558848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
559848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  ASSERT_TRUE(oat_file.get() != nullptr);
560848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  EXPECT_TRUE(oat_file->IsExecutable());
561848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  std::vector<std::unique_ptr<const DexFile>> dex_files;
562dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
563dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(2u, dex_files.size());
564dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
565dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
566dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a MultiDEX file where the secondary dex file is out of date.
567dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kDex2OatNeeded.
568dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) {
569dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar";
570dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
571dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Compile code for GetMultiDexSrc1.
572be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  Copy(GetMultiDexSrc1(), dex_location);
573be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
574dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
575dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
576dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // is out of date.
577dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetMultiDexSrc2(), dex_location);
578be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
579be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
580dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
581dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
582dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
583be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes}
584be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
585dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a MultiDEX file and up-to-date OAT file for it with relative
586dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// encoded dex locations.
587dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The oat file status is kNoDexOptNeeded.
588be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott HughesTEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
589be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
590dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
591dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
592dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Create the dex file
593be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  Copy(GetMultiDexSrc1(), dex_location);
594be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
595dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Create the oat file with relative encoded dex location.
596dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::vector<std::string> args;
597dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  args.push_back("--dex-file=" + dex_location);
598dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
599dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  args.push_back("--oat-file=" + oat_location);
600dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  args.push_back("--compiler-filter=speed");
601dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
602dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string error_msg;
603dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
604dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
605b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison  // Verify we can load both dex files.
606b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison  OatFileAssistant oat_file_assistant(dex_location.c_str(),
607e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi                                      oat_location.c_str(),
608e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi                                      kRuntimeISA, false, true);
609e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
610e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi  ASSERT_TRUE(oat_file.get() != nullptr);
611e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi  EXPECT_TRUE(oat_file->IsExecutable());
612e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi  std::vector<std::unique_ptr<const DexFile>> dex_files;
613e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
614e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi  EXPECT_EQ(2u, dex_files.size());
615e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi}
616e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi
617e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi// Case: We have a DEX file and out-of-date OAT file.
618e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi// Expect: The status is kDex2OatNeeded.
619e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi YamauchiTEST_F(OatFileAssistantTest, OatOutOfDate) {
620e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi  std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar";
621e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi
622932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // We create a dex, generate an oat for it, then overwrite the dex with a
623d752132c73072084a3def9257cca4fcee76047b6jeffhao  // different dex to make the oat out of date.
624dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
625932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
626932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  Copy(GetDexSrc2(), dex_location);
62713735955f39b3b304c37d2b2840663c131262c18Ian Rogers
628535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
629535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
630535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
631535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
632535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
633535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray
634535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
635535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
636535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
63713735955f39b3b304c37d2b2840663c131262c18Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
638dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileExists());
639d752132c73072084a3def9257cca4fcee76047b6jeffhao  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
640d752132c73072084a3def9257cca4fcee76047b6jeffhao  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
641932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
642b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers}
643932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
644932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers// Case: We have a DEX file and an ODEX file, but no OAT file.
645b090a18e4292dc339a3b2668bf6dc855928dee3aDave Allison// Expect: The status is kPatchOatNeeded.
646932746a4f22951abcba7b7c4c94c27b1bf164272Ian RogersTEST_F(OatFileAssistantTest, DexOdexNoOat) {
647932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
648b090a18e4292dc339a3b2668bf6dc855928dee3aDave Allison  std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
649932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
650932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Create the dex and odex files
651f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison  Copy(GetDexSrc1(), dex_location);
652648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
653f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison
654120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  // Verify the status.
655dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
656120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers
657120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
658dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
659dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
660dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
661dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
662be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
663be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
664dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
665dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
666dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
667dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileExists());
668be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
669be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
670dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
671dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
672dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // We should still be able to get the non-executable odex file to run from.
673dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
674dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  ASSERT_TRUE(oat_file.get() != nullptr);
675be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes}
676be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
6770399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers// Case: We have a stripped DEX file and an ODEX file, but no OAT file.
678dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kPatchOatNeeded
6790399dde18753aa9bd2bd0d7cf60beef154d164a4Ian RogersTEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
6800399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
6810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
6820399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
683dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Create the dex and odex files
6840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  Copy(GetDexSrc1(), dex_location);
6850399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
686dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
687bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Strip the dex file
688bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  Copy(GetStrippedDexSrc1(), dex_location);
6890399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
690dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Verify the status.
691de479be99328d2113bf483e082c9ecf235a34d69TDYa  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
692de479be99328d2113bf483e082c9ecf235a34d69TDYa
693de479be99328d2113bf483e082c9ecf235a34d69TDYa  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
694dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
695de479be99328d2113bf483e082c9ecf235a34d69TDYa
696f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chien  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
697dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
698dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
699dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
700dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileExists());
701dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
702d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
703d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
704ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
705ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // Make the oat file up to date.
706dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string error_msg;
7070399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
7080399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
709eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
710eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
7110399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
712eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
713ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
714eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
715c8ccf68b805c92674545f63e0341ba47e8d9701cAndreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
7160399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
7170399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileExists());
718eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
7190399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
720bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
72183c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier
7220399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Verify we can load the dex files from it.
723eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
724eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  ASSERT_TRUE(oat_file.get() != nullptr);
7251f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  EXPECT_TRUE(oat_file->IsExecutable());
7261f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  std::vector<std::unique_ptr<const DexFile>> dex_files;
727eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
72859c07060a6fbb93e455b44f00098cafb8e7e26ccIan Rogers  EXPECT_EQ(1u, dex_files.size());
729eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier}
730eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
731eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file.
732eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Expect: The status is kPatchOatNeeded.
733eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu ChartierTEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
734eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
735eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
736eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
7371f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  // Create the oat file from a different dex file so it looks out of date.
73840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  Copy(GetDexSrc2(), dex_location);
739dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
740eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
741eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  // Create the odex file
742eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  Copy(GetDexSrc1(), dex_location);
743be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
744be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
745dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Strip the dex file.
746dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetStrippedDexSrc1(), dex_location);
747475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes
748475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  // Verify the status.
74961b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
750dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
75161b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
75261b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
7531558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
7541558b577907b613864e98f05862543557263e864Sebastien Hertz      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
7551558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,  // Can't run dex2oat because dex file is stripped.
7561558b577907b613864e98f05862543557263e864Sebastien Hertz      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
7571558b577907b613864e98f05862543557263e864Sebastien Hertz
7581558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
7591558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
7601558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
7611558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
7621558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
7639d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  EXPECT_TRUE(oat_file_assistant.OatFileExists());
7649d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
7659d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
7669d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
7679d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz
7689d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  // Make the oat file up to date.
7699d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  std::string error_msg;
7709d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
7719d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
7729d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz
7739d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
7749d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
775597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,  // Can't run dex2oat because dex file is stripped.
776597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
777597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz
778597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
779597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
780597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
781597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
782597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
7831558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_TRUE(oat_file_assistant.OatFileExists());
784cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
785cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
786cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
7871558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
7881558b577907b613864e98f05862543557263e864Sebastien Hertz
7891558b577907b613864e98f05862543557263e864Sebastien Hertz  // Verify we can load the dex files from it.
790cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
791cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  ASSERT_TRUE(oat_file.get() != nullptr);
7921558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_TRUE(oat_file->IsExecutable());
793597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  std::vector<std::unique_ptr<const DexFile>> dex_files;
794fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
795fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz  EXPECT_EQ(1u, dex_files.size());
796fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz}
797fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz
798fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
7991f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang// OAT file. Expect: The status is kNoDexOptNeeded.
8001f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao YangTEST_F(OatFileAssistantTest, ResourceOnlyDex) {
8011f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
8021f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
8031f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  Copy(GetStrippedDexSrc1(), dex_location);
8041f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
8051f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  // Verify the status.
806714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
8071f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
8081f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8091f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
8101f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8111f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
8121f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8132a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
8141f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
8151f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
8161f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
8171f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
8182a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
81962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
820dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileExists());
821e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
822e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
823e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
824dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
8255ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  // Make the oat file up to date. This should have no effect.
8265ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  std::string error_msg;
827e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
828dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
8295ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao
8305ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8315ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
832dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
8335ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
8345ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
8355ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
836dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
8375ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
8385ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  EXPECT_FALSE(oat_file_assistant.OatFileExists());
83981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
840dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
84100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
84200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}
84381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers
844dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file, no ODEX file and an OAT file that needs
84500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// relocation.
846ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes// Expect: The status is kSelfPatchOatNeeded.
847752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu ChartierTEST_F(OatFileAssistantTest, SelfRelocation) {
848858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  std::string dex_location = GetScratchDir() + "/SelfRelocation.jar";
849858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  std::string oat_location = GetOdexDir() + "/SelfRelocation.oat";
850dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
851858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  // Create the dex and odex files
852858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  Copy(GetDexSrc1(), dex_location);
8539cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao  GenerateOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
854dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
8559cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao  OatFileAssistant oat_file_assistant(dex_location.c_str(),
8569cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao      oat_location.c_str(), kRuntimeISA, false, true);
8578c1b5f71a8005743756206120624121d7678381fIan Rogers
8588c1b5f71a8005743756206120624121d7678381fIan Rogers  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
8598c1b5f71a8005743756206120624121d7678381fIan Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
860858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded,
8618c1b5f71a8005743756206120624121d7678381fIan Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
8628c1b5f71a8005743756206120624121d7678381fIan Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
8638c1b5f71a8005743756206120624121d7678381fIan Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
864858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier
8653b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
8663b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
867dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
868dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
869dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
870dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileExists());
87113735955f39b3b304c37d2b2840663c131262c18Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation());
872dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
8732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
8742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
8752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi
8762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  // Make the oat file up to date.
8772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  std::string error_msg;
8782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
879dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
880dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
881dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
882dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
883dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
884dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
885dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
886dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
887dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
888dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
889dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileExists());
890dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
891dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
892dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
893dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
894dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
895dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
896cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier  ASSERT_TRUE(oat_file.get() != nullptr);
897cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier  EXPECT_TRUE(oat_file->IsExecutable());
898dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::vector<std::unique_ptr<const DexFile>> dex_files;
899dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
900cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier  EXPECT_EQ(1u, dex_files.size());
901cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier}
902dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
903dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file, no ODEX file and an OAT file that needs
904dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// relocation but doesn't have patch info.
905dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kDex2OatNeeded, because we can't run patchoat.
906dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, NoSelfRelocation) {
90714cc9be4adc652071979395d337d1380763844faMathieu Chartier  std::string dex_location = GetScratchDir() + "/NoSelfRelocation.jar";
908dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string oat_location = GetOdexDir() + "/NoSelfRelocation.oat";
909dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
910dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Create the dex and odex files
911dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
912dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  GenerateNoPatchOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
913dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
914dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  OatFileAssistant oat_file_assistant(dex_location.c_str(),
915dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_location.c_str(), kRuntimeISA, false, true);
916dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
917dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
918dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
919dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
920dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Make the oat file up to date.
9215d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes  std::string error_msg;
922648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
923648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
924648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
925648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
926648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison
927648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
928648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  ASSERT_TRUE(oat_file.get() != nullptr);
929648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  EXPECT_TRUE(oat_file->IsExecutable());
930648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  std::vector<std::unique_ptr<const DexFile>> dex_files;
931648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
932648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  EXPECT_EQ(1u, dex_files.size());
933648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison}
934648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison
935648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
9368ce6b9040747054b444a7fa706503cd257801936Dave Allison// OAT files both have patch delta of 0.
9378ce6b9040747054b444a7fa706503cd257801936Dave Allison// Expect: It shouldn't crash, and status is kPatchOatNeeded.
9388ce6b9040747054b444a7fa706503cd257801936Dave AllisonTEST_F(OatFileAssistantTest, OdexOatOverlap) {
9398ce6b9040747054b444a7fa706503cd257801936Dave Allison  std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
9402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
9412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
9422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi
9432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  // Create the dex and odex files
944d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartier  Copy(GetDexSrc1(), dex_location);
945d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartier  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
94612d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier
947848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  // Create the oat file by copying the odex so they are located in the same
948848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  // place in memory.
949dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(odex_location, oat_location);
95052673ffae0025d86f4023735581f19ebcc477487Ian Rogers
951b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  // Verify things don't go bad.
952b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  OatFileAssistant oat_file_assistant(dex_location.c_str(),
953c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes      oat_location.c_str(), kRuntimeISA, false, true);
9540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
955365c10235438607541fa2259a5fec48061b90bd8Ian Rogers  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
9565fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
957d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
958d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
959d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
960d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
961d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
96262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileExists());
96362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
964474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
965474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
966dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
967c747cffa950b8398cb8844d47e2253214c855750Ian Rogers  // Things aren't relocated, so it should fall back to interpreted.
968c747cffa950b8398cb8844d47e2253214c855750Ian Rogers  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
969c747cffa950b8398cb8844d47e2253214c855750Ian Rogers  ASSERT_TRUE(oat_file.get() != nullptr);
97004d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers
97104d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers  EXPECT_FALSE(oat_file->IsExecutable());
972cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  std::vector<std::unique_ptr<const DexFile>> dex_files;
97300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
974b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  EXPECT_EQ(1u, dex_files.size());
975b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers}
976d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
977accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
9787934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
97900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan RogersTEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
980b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
981accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes  std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
98293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes
98393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  // Create the dex and odex files
984cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  Copy(GetDexSrc1(), dex_location);
985cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
986cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers
987accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes  // Verify the status.
988449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
989449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe
990449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
991449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
992449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
993449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
994449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe
995449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
996449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
9975d76c435082332ef79a22962386fa92a0870e378Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
998b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
9991efa0a9d6cd5f5b40b8a21d39f1103a3610250eeAlexei Zavjalov  EXPECT_FALSE(oat_file_assistant.OatFileExists());
1000848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
1001caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
1002caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
1003f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers}
1004be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
1005d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
1006d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
1007d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott HughesTEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
1008474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
1009474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
101059cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman
101159cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman  // Create the dex and odex files
1012df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogers  Copy(GetDexSrc1(), dex_location);
101330e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime);
101430e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers
101530e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers  // Verify the status.
101630e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
101730e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers
101830e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
101930e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
102001ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
102130e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1022b8e087e0dfd619df90cbb56534478a60bc859ebfIan Rogers
102301ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
102459cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
102559cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
102659cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
102759cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman  EXPECT_FALSE(oat_file_assistant.OatFileExists());
102859cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
1029474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
1030575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe  EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
1031474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers}
1032dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
10330399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers// Case: We have a DEX file and up-to-date OAT file for it.
1034dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: We should load an executable dex file.
1035dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, LoadOatUpToDate) {
10360399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
1037dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1038dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
10390399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
1040dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1041dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Load the oat using an oat file assistant.
10420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
1043dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1044dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1045dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  ASSERT_TRUE(oat_file.get() != nullptr);
10460399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  EXPECT_TRUE(oat_file->IsExecutable());
1047dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::vector<std::unique_ptr<const DexFile>> dex_files;
1048dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1049dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(1u, dex_files.size());
1050dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
1051dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1052dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file and up-to-date interpret-only OAT file for it.
1053f37a88b8e6db6c587fa449a12e40cb46be1689fcZuo Wang// Expect: We should still load the oat file as executable.
1054dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
1055dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
1056dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1057dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
1058dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kInterpretOnly);
1059dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1060dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Load the oat using an oat file assistant.
10611f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
10621f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
10639d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1064dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  ASSERT_TRUE(oat_file.get() != nullptr);
10650399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  EXPECT_TRUE(oat_file->IsExecutable());
1066dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::vector<std::unique_ptr<const DexFile>> dex_files;
1067575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1068575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe  EXPECT_EQ(1u, dex_files.size());
10690399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers}
1070dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1071dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file and up-to-date OAT file for it.
1072dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: Loading non-executable should load the oat non-executable.
10730399dde18753aa9bd2bd0d7cf60beef154d164a4Ian RogersTEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
1074dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
1075dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1076dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
10770399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
1078dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1079dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Load the oat using an oat file assistant.
1080dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
1081dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1082dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1083dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  ASSERT_TRUE(oat_file.get() != nullptr);
10840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  EXPECT_FALSE(oat_file->IsExecutable());
1085dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::vector<std::unique_ptr<const DexFile>> dex_files;
1086dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1087d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  EXPECT_EQ(1u, dex_files.size());
1088dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
1089dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1090d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers// Case: We have a DEX file.
1091dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: We should load an executable dex file from an alternative oat
1092dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// location.
1093b033c75ebda80ac75f936366fe78d1edf5cec937Ian RogersTEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
1094dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
1095dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
1096d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
1097dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
1098dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
10999f1020305292a21fd14a402b189c765a125226abSebastien Hertz  OatFileAssistant oat_file_assistant(
1100648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
1101648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  std::string error_msg;
1102648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison  ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
11031f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg;
11041f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
11051f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
11061f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  ASSERT_TRUE(oat_file.get() != nullptr);
11072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  EXPECT_TRUE(oat_file->IsExecutable());
11082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  std::vector<std::unique_ptr<const DexFile>> dex_files;
11092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
11102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  EXPECT_EQ(1u, dex_files.size());
11111558b577907b613864e98f05862543557263e864Sebastien Hertz
11121558b577907b613864e98f05862543557263e864Sebastien Hertz  EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
11131558b577907b613864e98f05862543557263e864Sebastien Hertz
11141558b577907b613864e98f05862543557263e864Sebastien Hertz  // Verify it didn't create an oat in the default location.
11151558b577907b613864e98f05862543557263e864Sebastien Hertz  OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false, false);
11169d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  EXPECT_FALSE(ofm.OatFileExists());
11179d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz}
11189d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz
11199d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz// Case: We have a DEX file but can't write the oat file.
1120dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: We should fail to make the oat file up to date.
112162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian RogersTEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) {
1122dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar";
1123dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1124dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Make the oat location unwritable by inserting some non-existent
1125d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  // intermediate directories.
1126dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat";
1127dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1128dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
1129dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1130dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  OatFileAssistant oat_file_assistant(
1131dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
1132dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string error_msg;
1133dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  ASSERT_EQ(OatFileAssistant::kUpdateNotAttempted,
1134dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg));
1135dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1136dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1137449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe  ASSERT_TRUE(oat_file.get() == nullptr);
1138449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe}
1139dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1140eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Case: We don't have a DEX file and can't write the oat file.
1141dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: We should fail to generate the oat file without crashing.
11421f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao YangTEST_F(OatFileAssistantTest, GenNoDex) {
11431f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
11441f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  std::string oat_location = GetScratchDir() + "/GenNoDex.oat";
1145dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
11467b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  OatFileAssistant oat_file_assistant(
114712d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true);
114812d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier  std::string error_msg;
1149dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
1150d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers      oat_file_assistant.GenerateOatFile(CompilerFilter::kSpeed, &error_msg));
1151dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
115213735955f39b3b304c37d2b2840663c131262c18Ian Rogers
11535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes// Turn an absolute path into a path relative to the current working
11542cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier// directory.
1155dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersstatic std::string MakePathRelative(std::string target) {
1156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  char buf[MAXPATHLEN];
1157dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string cwd = getcwd(buf, MAXPATHLEN);
1158dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
115913735955f39b3b304c37d2b2840663c131262c18Ian Rogers  // Split the target and cwd paths into components.
116069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  std::vector<std::string> target_path;
1161dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::vector<std::string> cwd_path;
1162dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Split(target, '/', &target_path);
116345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  Split(cwd, '/', &cwd_path);
1164dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1165dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Reverse the path components, so we can use pop_back().
1166dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::reverse(target_path.begin(), target_path.end());
1167c143c55718342519db5398e41dda31422cf16c79buzbee  std::reverse(cwd_path.begin(), cwd_path.end());
1168dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1169dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // Drop the common prefix of the paths. Because we reversed the path
1170bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // components, this becomes the common suffix of target_path and cwd_path.
1171449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe  while (!target_path.empty() && !cwd_path.empty()
1172449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe      && target_path.back() == cwd_path.back()) {
1173449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe    target_path.pop_back();
1174449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe    cwd_path.pop_back();
1175dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1176dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1177dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // For each element of the remaining cwd_path, add '..' to the beginning
1178dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  // of the target path. Because we reversed the path components, we add to
1179726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes  // the end of target_path.
1180dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  for (unsigned int i = 0; i < cwd_path.size(); i++) {
1181dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    target_path.push_back("..");
1182dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1183dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
11840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Reverse again to get the right path order, and join to get the result.
1185dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::reverse(target_path.begin(), target_path.end());
118613735955f39b3b304c37d2b2840663c131262c18Ian Rogers  return Join(target_path, '/');
1187475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes}
1188dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1189dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: Non-absolute path to Dex location.
119061b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz// Expect: Not sure, but it shouldn't crash.
1191dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
1192e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
1193e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  Copy(GetDexSrc1(), abs_dex_location);
11942cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier
1195dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = MakePathRelative(abs_dex_location);
1196899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
1197dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1198dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
119952673ffae0025d86f4023735581f19ebcc477487Ian Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
12002cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1201eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
12020d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  EXPECT_FALSE(oat_file_assistant.OatFileExists());
1203dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
1204dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
120568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
1206ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
1207dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
1208dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
120952673ffae0025d86f4023735581f19ebcc477487Ian Rogers// Case: Very short, non-existent Dex location.
1210dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: kNoDexOptNeeded.
1211dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, ShortDexLocation) {
1212dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string dex_location = "/xx";
12135d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes
1214dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
1215dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
12160aded089f565008ba5908e395e5914ca4f91f2deDave Allison  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
1217dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1218dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1219858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
12201f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_FALSE(oat_file_assistant.OatFileExists());
12211f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
12221f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
12231f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
122422f454c7d349c439c774c5d79b32514b190fd531Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
12251f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
12261f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
12272a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe  // Trying to make it up to date should have no effect.
1228dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  std::string error_msg;
1229dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
1230b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison      oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg));
1231dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(error_msg.empty());
1232dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
1233b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison
1234dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: Non-standard extension for dex file.
1235dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kDex2OatNeeded.
1236f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi YamauchiTEST_F(OatFileAssistantTest, LongDexExtension) {
12372cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
1238dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Copy(GetDexSrc1(), dex_location);
1239dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1240f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false);
1241dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1242dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
1243dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1244dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1245dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
1246f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
1247dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
124813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
124913735955f39b3b304c37d2b2840663c131262c18Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileExists());
125013735955f39b3b304c37d2b2840663c131262c18Ian Rogers  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
1251dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
1252dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}
12530651d41e41341fb2e9ef3ee41dc1f1bfc832dbbbMathieu Chartier
1254e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers// A task to generate a dex location. Used by the RaceToGenerate test.
1255dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersclass RaceGenerateTask : public Task {
1256dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers public:
1257cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier  explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
1258cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier    : dex_location_(dex_location), oat_location_(oat_location),
12599e36931cc79ca665908db9575126881d1cfdea5aChao-ying Fu      loaded_oat_file_(nullptr)
12609e36931cc79ca665908db9575126881d1cfdea5aChao-ying Fu  {}
12619e36931cc79ca665908db9575126881d1cfdea5aChao-ying Fu
12628ce6b9040747054b444a7fa706503cd257801936Dave Allison  void Run(Thread* self ATTRIBUTE_UNUSED) {
12638ce6b9040747054b444a7fa706503cd257801936Dave Allison    // Load the dex files, and save a pointer to the loaded oat file, so that
12648ce6b9040747054b444a7fa706503cd257801936Dave Allison    // we can verify only one oat file was loaded for the dex location.
12652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    std::vector<std::unique_ptr<const DexFile>> dex_files;
12662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    std::vector<std::string> error_msgs;
12672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    const OatFile* oat_file = nullptr;
126812d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier    dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
126912d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier        dex_location_.c_str(),
127012d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier        oat_location_.c_str(),
1271dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        /*class_loader*/nullptr,
1272dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        /*dex_elements*/nullptr,
1273dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        &oat_file,
1274dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        &error_msgs);
1275dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
1276dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
1277dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
12782cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    CHECK_EQ(loaded_oat_file_, oat_file);
1279dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  }
1280dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers
1281dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  const OatFile* GetLoadedOatFile() const {
1282dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    return loaded_oat_file_;
1283f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  }
1284e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier
128515d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier private:
1286692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier  std::string dex_location_;
12875cf98196d488437acd1e989c08a554ef697fded1Ian Rogers  std::string oat_location_;
1288692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier  const OatFile* loaded_oat_file_;
1289119c6bd97f7ac24b64eaf4e9333abb44acbf780fMathieu Chartier};
1290692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier
1291692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier// Test the case where multiple processes race to generate an oat file.
12924352b4556c138eb9f583367d678531930b5b8fb0Andreas Gampe// This simulates multiple processes using multiple threads.
12934352b4556c138eb9f583367d678531930b5b8fb0Andreas Gampe//
12940e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro// We want unique Oat files to be loaded even when there is a race to load.
12950e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro// TODO: The test case no longer tests locking the way it was intended since we now get multiple
1296bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers// copies of the same Oat files mapped at different locations.
12972d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu ChartierTEST_F(OatFileAssistantTest, RaceToGenerate) {
12982d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
12992d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
13002d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier
13012d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  // We use the lib core dex file, because it's large, and hopefully should
13022d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  // take a while to generate.
13032d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  Copy(GetLibCoreDexFileNames()[0], dex_location);
13042d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier
13052d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  const int kNumThreads = 32;
13062d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  Thread* self = Thread::Current();
13072d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
13082d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
13092d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  for (int i = 0; i < kNumThreads; i++) {
13102d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier    std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
1311f2247513a54300cfa6a2f23fdbbafead115c99b2Ian Rogers    thread_pool.AddTask(self, task.get());
13122d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier    tasks.push_back(std::move(task));
13132d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier  }
13141f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  thread_pool.StartWorkers(self);
13151f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  thread_pool.Wait(self, true, false);
13161f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
13171f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  // Verify every task got a unique oat file.
13181f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  std::set<const OatFile*> oat_files;
13191f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  for (auto& task : tasks) {
13201f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang    const OatFile* oat_file = task->GetLoadedOatFile();
13211f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang    EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
13221f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang    oat_files.insert(oat_file);
13231f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  }
13241f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang}
13251f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang
13261f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
13271f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang// disabled.
13281f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang// Expect: We should load the odex file non-executable.
13291f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao YangTEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
13301f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang  std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
1331330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughes  std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
1332f795869da0a1fa006fdcdacd8afb6149a63fc1a7Sebastien Hertz
13330e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  // Create the dex and odex files
13340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  Copy(GetDexSrc1(), dex_location);
13350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
1336fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom
1337  // Load the oat using an executable oat file assistant.
1338  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
1339
1340  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1341  ASSERT_TRUE(oat_file.get() != nullptr);
1342  EXPECT_FALSE(oat_file->IsExecutable());
1343  std::vector<std::unique_ptr<const DexFile>> dex_files;
1344  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1345  EXPECT_EQ(1u, dex_files.size());
1346}
1347
1348// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
1349// disabled.
1350// Expect: We should load the odex file non-executable.
1351TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
1352  std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
1353  std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
1354
1355  // Create the dex and odex files
1356  Copy(GetMultiDexSrc1(), dex_location);
1357  GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
1358
1359  // Load the oat using an executable oat file assistant.
1360  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true);
1361
1362  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1363  ASSERT_TRUE(oat_file.get() != nullptr);
1364  EXPECT_FALSE(oat_file->IsExecutable());
1365  std::vector<std::unique_ptr<const DexFile>> dex_files;
1366  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1367  EXPECT_EQ(2u, dex_files.size());
1368}
1369
1370TEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) {
1371  std::string error_msg;
1372  std::string odex_file;
1373
1374  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
1375        "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
1376  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
1377
1378  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
1379        "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
1380  EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
1381
1382  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
1383        "nopath.jar", kArm, &odex_file, &error_msg));
1384  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
1385        "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
1386}
1387
1388// Verify the dexopt status values from dalvik.system.DexFile
1389// match the OatFileAssistant::DexOptStatus values.
1390TEST_F(OatFileAssistantTest, DexOptStatusValues) {
1391  ScopedObjectAccess soa(Thread::Current());
1392  StackHandleScope<1> hs(soa.Self());
1393  ClassLinker* linker = Runtime::Current()->GetClassLinker();
1394  Handle<mirror::Class> dexfile(
1395      hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
1396  ASSERT_FALSE(dexfile.Get() == nullptr);
1397  linker->EnsureInitialized(soa.Self(), dexfile, true, true);
1398
1399  ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
1400      soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I");
1401  ASSERT_FALSE(no_dexopt_needed == nullptr);
1402  EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1403  EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get()));
1404
1405  ArtField* dex2oat_needed = mirror::Class::FindStaticField(
1406      soa.Self(), dexfile, "DEX2OAT_NEEDED", "I");
1407  ASSERT_FALSE(dex2oat_needed == nullptr);
1408  EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1409  EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get()));
1410
1411  ArtField* patchoat_needed = mirror::Class::FindStaticField(
1412      soa.Self(), dexfile, "PATCHOAT_NEEDED", "I");
1413  ASSERT_FALSE(patchoat_needed == nullptr);
1414  EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1415  EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get()));
1416
1417  ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
1418      soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I");
1419  ASSERT_FALSE(self_patchoat_needed == nullptr);
1420  EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1421  EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get()));
1422}
1423
1424// TODO: More Tests:
1425//  * Image checksum change is out of date for kIntepretOnly, but not
1426//    kVerifyAtRuntime. But target of kVerifyAtRuntime still says current
1427//    kInterpretOnly is out of date.
1428//  * Test class linker falls back to unquickened dex for DexNoOat
1429//  * Test class linker falls back to unquickened dex for MultiDexNoOat
1430//  * Test using secondary isa
1431//  * Test for status of oat while oat is being generated (how?)
1432//  * Test case where 32 and 64 bit boot class paths differ,
1433//      and we ask IsInBootClassPath for a class in exactly one of the 32 or
1434//      64 bit boot class paths.
1435//  * Test unexpected scenarios (?):
1436//    - Dex is stripped, don't have odex.
1437//    - Oat file corrupted after status check, before reload unexecutable
1438//    because it's unrelocated and no dex2oat
1439//  * Test unrelocated specific target compilation type can be relocated to
1440//    make it up to date.
1441
1442}  // namespace art
1443