Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <string>
     18 #include <vector>
     19 #include <sys/param.h>
     20 
     21 #include "android-base/strings.h"
     22 #include <gtest/gtest.h>
     23 
     24 #include "art_field-inl.h"
     25 #include "class_linker-inl.h"
     26 #include "dexopt_test.h"
     27 #include "oat_file_assistant.h"
     28 #include "oat_file_manager.h"
     29 #include "os.h"
     30 #include "scoped_thread_state_change-inl.h"
     31 #include "thread-inl.h"
     32 #include "utils.h"
     33 
     34 namespace art {
     35 
     36 class OatFileAssistantTest : public DexoptTest {};
     37 
     38 class OatFileAssistantNoDex2OatTest : public DexoptTest {
     39  public:
     40   virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
     41     DexoptTest::SetUpRuntimeOptions(options);
     42     options->push_back(std::make_pair("-Xnodex2oat", nullptr));
     43   }
     44 };
     45 
     46 class ScopedNonWritable {
     47  public:
     48   explicit ScopedNonWritable(const std::string& dex_location) {
     49     is_valid_ = false;
     50     size_t pos = dex_location.rfind('/');
     51     if (pos != std::string::npos) {
     52       is_valid_ = true;
     53       dex_parent_ = dex_location.substr(0, pos);
     54       if (chmod(dex_parent_.c_str(), 0555) != 0)  {
     55         PLOG(ERROR) << "Could not change permissions on " << dex_parent_;
     56       }
     57     }
     58   }
     59 
     60   bool IsSuccessful() { return is_valid_ && (access(dex_parent_.c_str(), W_OK) != 0); }
     61 
     62   ~ScopedNonWritable() {
     63     if (is_valid_) {
     64       if (chmod(dex_parent_.c_str(), 0777) != 0) {
     65         PLOG(ERROR) << "Could not restore permissions on " << dex_parent_;
     66       }
     67     }
     68   }
     69 
     70  private:
     71   std::string dex_parent_;
     72   bool is_valid_;
     73 };
     74 
     75 static bool IsExecutedAsRoot() {
     76   return geteuid() == 0;
     77 }
     78 
     79 // Case: We have a DEX file, but no OAT file for it.
     80 // Expect: The status is kDex2OatNeeded.
     81 TEST_F(OatFileAssistantTest, DexNoOat) {
     82   std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
     83   Copy(GetDexSrc1(), dex_location);
     84 
     85   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
     86 
     87   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
     88       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
     89   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
     90       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
     91   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
     92       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
     93   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
     94       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
     95 
     96   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
     97   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
     98   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
     99   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    100 }
    101 
    102 // Case: We have no DEX file and no OAT file.
    103 // Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
    104 TEST_F(OatFileAssistantTest, NoDexNoOat) {
    105   std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
    106 
    107   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    108 
    109   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    110       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    111   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    112 
    113   // Trying to make the oat file up to date should not fail or crash.
    114   std::string error_msg;
    115   EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, oat_file_assistant.MakeUpToDate(false, &error_msg));
    116 
    117   // Trying to get the best oat file should fail, but not crash.
    118   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    119   EXPECT_EQ(nullptr, oat_file.get());
    120 }
    121 
    122 // Case: We have a DEX file and a PIC ODEX file, but no OAT file.
    123 // Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
    124 TEST_F(OatFileAssistantTest, OdexUpToDate) {
    125   std::string dex_location = GetScratchDir() + "/OdexUpToDate.jar";
    126   std::string odex_location = GetOdexDir() + "/OdexUpToDate.odex";
    127   Copy(GetDexSrc1(), dex_location);
    128   GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
    129 
    130   // For the use of oat location by making the dex parent not writable.
    131   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    132 
    133   EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
    134       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    135   EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
    136       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
    137   EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
    138       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    139   EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
    140       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
    141 
    142   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    143   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
    144   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
    145   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    146 }
    147 
    148 // Case: We have a DEX file and a PIC ODEX file, but no OAT file. We load the dex
    149 // file via a symlink.
    150 // Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
    151 TEST_F(OatFileAssistantTest, OdexUpToDateSymLink) {
    152   std::string scratch_dir = GetScratchDir();
    153   std::string dex_location = GetScratchDir() + "/OdexUpToDate.jar";
    154   std::string odex_location = GetOdexDir() + "/OdexUpToDate.odex";
    155 
    156   Copy(GetDexSrc1(), dex_location);
    157   GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
    158 
    159   // Now replace the dex location with a symlink.
    160   std::string link = scratch_dir + "/link";
    161   ASSERT_EQ(0, symlink(scratch_dir.c_str(), link.c_str()));
    162   dex_location = link + "/OdexUpToDate.jar";
    163 
    164   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    165 
    166   EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
    167       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    168   EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
    169       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
    170   EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
    171       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    172   EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
    173       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
    174 
    175   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    176   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
    177   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
    178   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    179 }
    180 
    181 // Case: We have a DEX file and up-to-date OAT file for it.
    182 // Expect: The status is kNoDexOptNeeded.
    183 TEST_F(OatFileAssistantTest, OatUpToDate) {
    184   if (IsExecutedAsRoot()) {
    185     // We cannot simulate non writable locations when executed as root: b/38000545.
    186     LOG(ERROR) << "Test skipped because it's running as root";
    187     return;
    188   }
    189 
    190   std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
    191   Copy(GetDexSrc1(), dex_location);
    192   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    193 
    194   // For the use of oat location by making the dex parent not writable.
    195   ScopedNonWritable scoped_non_writable(dex_location);
    196   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    197 
    198   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    199 
    200   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    201       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    202   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    203       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
    204   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    205       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    206   EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
    207       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
    208 
    209   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    210   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
    211   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
    212   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    213 }
    214 
    215 // Case: We have a DEX file and up-to-date OAT file for it. We load the dex file
    216 // via a symlink.
    217 // Expect: The status is kNoDexOptNeeded.
    218 TEST_F(OatFileAssistantTest, OatUpToDateSymLink) {
    219   if (IsExecutedAsRoot()) {
    220     // We cannot simulate non writable locations when executed as root: b/38000545.
    221     LOG(ERROR) << "Test skipped because it's running as root";
    222     return;
    223   }
    224 
    225   std::string real = GetScratchDir() + "/real";
    226   ASSERT_EQ(0, mkdir(real.c_str(), 0700));
    227   std::string link = GetScratchDir() + "/link";
    228   ASSERT_EQ(0, symlink(real.c_str(), link.c_str()));
    229 
    230   std::string dex_location = real + "/OatUpToDate.jar";
    231 
    232   Copy(GetDexSrc1(), dex_location);
    233   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    234 
    235   // Update the dex location to point to the symlink.
    236   dex_location = link + "/OatUpToDate.jar";
    237 
    238   // For the use of oat location by making the dex parent not writable.
    239   ScopedNonWritable scoped_non_writable(dex_location);
    240   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    241 
    242   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    243 
    244   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    245       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    246   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    247       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
    248   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    249       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    250   EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
    251       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
    252 
    253   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    254   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
    255   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
    256   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    257 }
    258 
    259 // Case: We have a DEX file and up-to-date (ODEX) VDEX file for it, but no
    260 // ODEX file.
    261 TEST_F(OatFileAssistantTest, VdexUpToDateNoOdex) {
    262   // This test case is only meaningful if vdex is enabled.
    263   if (!kIsVdexEnabled) {
    264     return;
    265   }
    266 
    267   std::string dex_location = GetScratchDir() + "/VdexUpToDateNoOdex.jar";
    268   std::string odex_location = GetOdexDir() + "/VdexUpToDateNoOdex.oat";
    269 
    270   Copy(GetDexSrc1(), dex_location);
    271 
    272   // Generating and deleting the oat file should have the side effect of
    273   // creating an up-to-date vdex file.
    274   GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
    275   ASSERT_EQ(0, unlink(odex_location.c_str()));
    276 
    277   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    278 
    279   // Even though the vdex file is up to date, because we don't have the oat
    280   // file, we can't know that the vdex depends on the boot image and is up to
    281   // date with respect to the boot image. Instead we must assume the vdex file
    282   // depends on the boot image and is out of date with respect to the boot
    283   // image.
    284   EXPECT_EQ(-OatFileAssistant::kDex2OatForBootImage,
    285       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    286 
    287   // Make sure we don't crash in this case when we dump the status. We don't
    288   // care what the actual dumped value is.
    289   oat_file_assistant.GetStatusDump();
    290 }
    291 
    292 // Case: We have a DEX file and empty VDEX and ODEX files.
    293 TEST_F(OatFileAssistantTest, EmptyVdexOdex) {
    294   std::string dex_location = GetScratchDir() + "/EmptyVdexOdex.jar";
    295   std::string odex_location = GetOdexDir() + "/EmptyVdexOdex.oat";
    296   std::string vdex_location = GetOdexDir() + "/EmptyVdexOdex.vdex";
    297 
    298   Copy(GetDexSrc1(), dex_location);
    299   ScratchFile vdex_file(vdex_location.c_str());
    300   ScratchFile odex_file(odex_location.c_str());
    301 
    302   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    303   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
    304       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    305 }
    306 
    307 // Case: We have a DEX file and up-to-date (OAT) VDEX file for it, but no OAT
    308 // file.
    309 TEST_F(OatFileAssistantTest, VdexUpToDateNoOat) {
    310   // This test case is only meaningful if vdex is enabled.
    311   if (!kIsVdexEnabled) {
    312     return;
    313   }
    314   if (IsExecutedAsRoot()) {
    315     // We cannot simulate non writable locations when executed as root: b/38000545.
    316     LOG(ERROR) << "Test skipped because it's running as root";
    317     return;
    318   }
    319 
    320   std::string dex_location = GetScratchDir() + "/VdexUpToDateNoOat.jar";
    321   std::string oat_location;
    322   std::string error_msg;
    323   ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename(
    324         dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg;
    325 
    326   Copy(GetDexSrc1(), dex_location);
    327   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    328   ASSERT_EQ(0, unlink(oat_location.c_str()));
    329 
    330   ScopedNonWritable scoped_non_writable(dex_location);
    331   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    332   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    333 
    334   // Even though the vdex file is up to date, because we don't have the oat
    335   // file, we can't know that the vdex depends on the boot image and is up to
    336   // date with respect to the boot image. Instead we must assume the vdex file
    337   // depends on the boot image and is out of date with respect to the boot
    338   // image.
    339   EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
    340       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    341 }
    342 
    343 // Case: We have a DEX file and speed-profile OAT file for it.
    344 // Expect: The status is kNoDexOptNeeded if the profile hasn't changed, but
    345 // kDex2Oat if the profile has changed.
    346 TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
    347   if (IsExecutedAsRoot()) {
    348     // We cannot simulate non writable locations when executed as root: b/38000545.
    349     LOG(ERROR) << "Test skipped because it's running as root";
    350     return;
    351   }
    352 
    353   std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
    354   Copy(GetDexSrc1(), dex_location);
    355   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
    356 
    357   ScopedNonWritable scoped_non_writable(dex_location);
    358   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    359 
    360   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    361 
    362   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    363       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, false));
    364   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    365       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken, false));
    366   EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
    367       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, true));
    368   EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
    369       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken, true));
    370 
    371   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    372   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
    373   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
    374   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    375 }
    376 
    377 // Case: We have a MultiDEX file and up-to-date OAT file for it.
    378 // Expect: The status is kNoDexOptNeeded and we load all dex files.
    379 TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
    380   if (IsExecutedAsRoot()) {
    381     // We cannot simulate non writable locations when executed as root: b/38000545.
    382     LOG(ERROR) << "Test skipped because it's running as root";
    383     return;
    384   }
    385 
    386   std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
    387   Copy(GetMultiDexSrc1(), dex_location);
    388   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    389 
    390   ScopedNonWritable scoped_non_writable(dex_location);
    391   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    392 
    393   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    394   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    395       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
    396   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    397 
    398   // Verify we can load both dex files.
    399   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    400   ASSERT_TRUE(oat_file.get() != nullptr);
    401   EXPECT_TRUE(oat_file->IsExecutable());
    402   std::vector<std::unique_ptr<const DexFile>> dex_files;
    403   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    404   EXPECT_EQ(2u, dex_files.size());
    405 }
    406 
    407 // Case: We have a MultiDEX file where the non-main multdex entry is out of date.
    408 // Expect: The status is kDex2OatNeeded.
    409 TEST_F(OatFileAssistantTest, MultiDexNonMainOutOfDate) {
    410   if (IsExecutedAsRoot()) {
    411     // We cannot simulate non writable locations when executed as root: b/38000545.
    412     LOG(ERROR) << "Test skipped because it's running as root";
    413     return;
    414   }
    415 
    416   std::string dex_location = GetScratchDir() + "/MultiDexNonMainOutOfDate.jar";
    417 
    418   // Compile code for GetMultiDexSrc1.
    419   Copy(GetMultiDexSrc1(), dex_location);
    420   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    421 
    422   // Now overwrite the dex file with GetMultiDexSrc2 so the non-main checksum
    423   // is out of date.
    424   Copy(GetMultiDexSrc2(), dex_location);
    425 
    426   ScopedNonWritable scoped_non_writable(dex_location);
    427   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    428 
    429   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    430   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
    431       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
    432   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    433 }
    434 
    435 // Case: We have a stripped MultiDEX file where the non-main multidex entry is
    436 // out of date with respect to the odex file.
    437 TEST_F(OatFileAssistantTest, StrippedMultiDexNonMainOutOfDate) {
    438   std::string dex_location = GetScratchDir() + "/StrippedMultiDexNonMainOutOfDate.jar";
    439   std::string odex_location = GetOdexDir() + "/StrippedMultiDexNonMainOutOfDate.odex";
    440 
    441   // Compile the oat from GetMultiDexSrc1.
    442   Copy(GetMultiDexSrc1(), dex_location);
    443   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    444 
    445   // Compile the odex from GetMultiDexSrc2, which has a different non-main
    446   // dex checksum.
    447   Copy(GetMultiDexSrc2(), dex_location);
    448   GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kQuicken);
    449 
    450   // Strip the dex file.
    451   Copy(GetStrippedDexSrc1(), dex_location);
    452 
    453   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, /*load_executable*/false);
    454 
    455   // Because the dex file is stripped, the odex file is considered the source
    456   // of truth for the dex checksums. The oat file should be considered
    457   // unusable.
    458   std::unique_ptr<OatFile> best_file = oat_file_assistant.GetBestOatFile();
    459   ASSERT_TRUE(best_file.get() != nullptr);
    460   EXPECT_EQ(best_file->GetLocation(), odex_location);
    461   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    462   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
    463   EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
    464 }
    465 
    466 // Case: We have a MultiDEX file and up-to-date ODEX file for it with relative
    467 // encoded dex locations.
    468 // Expect: The oat file status is kNoDexOptNeeded.
    469 TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
    470   std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
    471   std::string odex_location = GetOdexDir() + "/RelativeEncodedDexLocation.odex";
    472 
    473   // Create the dex file
    474   Copy(GetMultiDexSrc1(), dex_location);
    475 
    476   // Create the oat file with relative encoded dex location.
    477   std::vector<std::string> args;
    478   args.push_back("--dex-file=" + dex_location);
    479   args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
    480   args.push_back("--oat-file=" + odex_location);
    481   args.push_back("--compiler-filter=speed");
    482 
    483   std::string error_msg;
    484   ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
    485 
    486   // Verify we can load both dex files.
    487   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    488 
    489   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    490   ASSERT_TRUE(oat_file.get() != nullptr);
    491   EXPECT_TRUE(oat_file->IsExecutable());
    492   std::vector<std::unique_ptr<const DexFile>> dex_files;
    493   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    494   EXPECT_EQ(2u, dex_files.size());
    495 }
    496 
    497 // Case: We have a DEX file and an OAT file out of date with respect to the
    498 // dex checksum.
    499 TEST_F(OatFileAssistantTest, OatDexOutOfDate) {
    500   if (IsExecutedAsRoot()) {
    501     // We cannot simulate non writable locations when executed as root: b/38000545.
    502     LOG(ERROR) << "Test skipped because it's running as root";
    503     return;
    504   }
    505 
    506   std::string dex_location = GetScratchDir() + "/OatDexOutOfDate.jar";
    507 
    508   // We create a dex, generate an oat for it, then overwrite the dex with a
    509   // different dex to make the oat out of date.
    510   Copy(GetDexSrc1(), dex_location);
    511   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    512   Copy(GetDexSrc2(), dex_location);
    513 
    514   ScopedNonWritable scoped_non_writable(dex_location);
    515   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    516 
    517   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    518   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
    519       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    520   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
    521       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    522 
    523   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    524   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
    525   EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
    526   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    527 }
    528 
    529 // Case: We have a DEX file and an (ODEX) VDEX file out of date with respect
    530 // to the dex checksum, but no ODEX file.
    531 TEST_F(OatFileAssistantTest, VdexDexOutOfDate) {
    532   // This test case is only meaningful if vdex is enabled.
    533   if (!kIsVdexEnabled) {
    534     return;
    535   }
    536 
    537   std::string dex_location = GetScratchDir() + "/VdexDexOutOfDate.jar";
    538   std::string odex_location = GetOdexDir() + "/VdexDexOutOfDate.oat";
    539 
    540   Copy(GetDexSrc1(), dex_location);
    541   GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
    542   ASSERT_EQ(0, unlink(odex_location.c_str()));
    543   Copy(GetDexSrc2(), dex_location);
    544 
    545   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    546 
    547   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
    548       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    549 }
    550 
    551 // Case: We have a MultiDEX (ODEX) VDEX file where the non-main multidex entry
    552 // is out of date and there is no corresponding ODEX file.
    553 TEST_F(OatFileAssistantTest, VdexMultiDexNonMainOutOfDate) {
    554   // This test case is only meaningful if vdex is enabled.
    555   if (!kIsVdexEnabled) {
    556     return;
    557   }
    558 
    559   std::string dex_location = GetScratchDir() + "/VdexMultiDexNonMainOutOfDate.jar";
    560   std::string odex_location = GetOdexDir() + "/VdexMultiDexNonMainOutOfDate.odex";
    561 
    562   Copy(GetMultiDexSrc1(), dex_location);
    563   GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
    564   ASSERT_EQ(0, unlink(odex_location.c_str()));
    565   Copy(GetMultiDexSrc2(), dex_location);
    566 
    567   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    568 
    569   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
    570       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    571 }
    572 
    573 // Case: We have a DEX file and an OAT file out of date with respect to the
    574 // boot image.
    575 TEST_F(OatFileAssistantTest, OatImageOutOfDate) {
    576   if (IsExecutedAsRoot()) {
    577     // We cannot simulate non writable locations when executed as root: b/38000545.
    578     LOG(ERROR) << "Test skipped because it's running as root";
    579     return;
    580   }
    581 
    582   std::string dex_location = GetScratchDir() + "/OatImageOutOfDate.jar";
    583 
    584   Copy(GetDexSrc1(), dex_location);
    585   GenerateOatForTest(dex_location.c_str(),
    586                      CompilerFilter::kSpeed,
    587                      /*relocate*/true,
    588                      /*pic*/false,
    589                      /*with_alternate_image*/true);
    590 
    591   ScopedNonWritable scoped_non_writable(dex_location);
    592   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    593 
    594   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    595   EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
    596       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    597   EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
    598       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
    599   EXPECT_EQ(OatFileAssistant::kDex2OatForBootImage,
    600       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    601 
    602   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    603   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
    604   EXPECT_EQ(OatFileAssistant::kOatBootImageOutOfDate, oat_file_assistant.OatFileStatus());
    605   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    606 }
    607 
    608 // Case: We have a DEX file and a verify-at-runtime OAT file out of date with
    609 // respect to the boot image.
    610 // It shouldn't matter that the OAT file is out of date, because it is
    611 // verify-at-runtime.
    612 TEST_F(OatFileAssistantTest, OatVerifyAtRuntimeImageOutOfDate) {
    613   if (IsExecutedAsRoot()) {
    614     // We cannot simulate non writable locations when executed as root: b/38000545.
    615     LOG(ERROR) << "Test skipped because it's running as root";
    616     return;
    617   }
    618 
    619   std::string dex_location = GetScratchDir() + "/OatVerifyAtRuntimeImageOutOfDate.jar";
    620 
    621   Copy(GetDexSrc1(), dex_location);
    622   GenerateOatForTest(dex_location.c_str(),
    623                      CompilerFilter::kExtract,
    624                      /*relocate*/true,
    625                      /*pic*/false,
    626                      /*with_alternate_image*/true);
    627 
    628   ScopedNonWritable scoped_non_writable(dex_location);
    629   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    630 
    631   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    632   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    633       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    634   EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
    635       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
    636 
    637   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    638   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
    639   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
    640   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    641 }
    642 
    643 // Case: We have a DEX file and an ODEX file, but no OAT file.
    644 TEST_F(OatFileAssistantTest, DexOdexNoOat) {
    645   std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
    646   std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
    647 
    648   // Create the dex and odex files
    649   Copy(GetDexSrc1(), dex_location);
    650   GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
    651 
    652   // Verify the status.
    653   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    654 
    655   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    656       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    657   EXPECT_EQ(-OatFileAssistant::kDex2OatForRelocation,
    658       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    659 
    660   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    661   EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus());
    662   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
    663   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    664 
    665   // We should still be able to get the non-executable odex file to run from.
    666   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    667   ASSERT_TRUE(oat_file.get() != nullptr);
    668 }
    669 
    670 // Case: We have a stripped DEX file and a PIC ODEX file, but no OAT file.
    671 TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
    672   std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
    673   std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
    674 
    675   // Create the dex and odex files
    676   Copy(GetDexSrc1(), dex_location);
    677   GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
    678 
    679   // Strip the dex file
    680   Copy(GetStrippedDexSrc1(), dex_location);
    681 
    682   // Verify the status.
    683   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    684 
    685   EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
    686       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    687 
    688   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    689   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
    690   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
    691   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    692 
    693   // Verify we can load the dex files from it.
    694   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    695   ASSERT_TRUE(oat_file.get() != nullptr);
    696   EXPECT_TRUE(oat_file->IsExecutable());
    697   std::vector<std::unique_ptr<const DexFile>> dex_files;
    698   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    699   EXPECT_EQ(1u, dex_files.size());
    700 }
    701 
    702 // Case: We have a stripped DEX file, a PIC ODEX file, and an out-of-date OAT file.
    703 TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
    704   std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
    705   std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
    706 
    707   // Create the oat file from a different dex file so it looks out of date.
    708   Copy(GetDexSrc2(), dex_location);
    709   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    710 
    711   // Create the odex file
    712   Copy(GetDexSrc1(), dex_location);
    713   GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
    714 
    715   // Strip the dex file.
    716   Copy(GetStrippedDexSrc1(), dex_location);
    717 
    718   // Verify the status.
    719   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    720 
    721   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    722       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    723   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    724       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    725   EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,  // Compiling from the .vdex file
    726       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
    727 
    728   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    729   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
    730   EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus());
    731   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    732 
    733   // Verify we can load the dex files from it.
    734   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    735   ASSERT_TRUE(oat_file.get() != nullptr);
    736   EXPECT_TRUE(oat_file->IsExecutable());
    737   std::vector<std::unique_ptr<const DexFile>> dex_files;
    738   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    739   EXPECT_EQ(1u, dex_files.size());
    740 }
    741 
    742 // Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
    743 // OAT file. Expect: The status is kNoDexOptNeeded.
    744 TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
    745   std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
    746 
    747   Copy(GetStrippedDexSrc1(), dex_location);
    748 
    749   // Verify the status.
    750   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    751 
    752   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    753       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    754   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    755       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    756   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    757       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
    758 
    759   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    760   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
    761   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
    762   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    763 
    764   // Make the oat file up to date. This should have no effect.
    765   std::string error_msg;
    766   Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
    767   EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
    768       oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
    769 
    770   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    771       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    772 
    773   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    774   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
    775   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
    776   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    777 }
    778 
    779 // Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
    780 // OAT files both have patch delta of 0.
    781 // Expect: It shouldn't crash.
    782 TEST_F(OatFileAssistantTest, OdexOatOverlap) {
    783   std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
    784   std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
    785 
    786   // Create the dex, the odex and the oat files.
    787   Copy(GetDexSrc1(), dex_location);
    788   GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
    789   GenerateOatForTest(dex_location.c_str(),
    790                      CompilerFilter::kSpeed,
    791                      /*relocate*/false,
    792                      /*pic*/false,
    793                      /*with_alternate_image*/false);
    794 
    795   // Verify things don't go bad.
    796   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    797 
    798   // -kDex2OatForRelocation is expected rather than kDex2OatForRelocation
    799   // based on the assumption that the odex location is more up-to-date than the oat
    800   // location, even if they both need relocation.
    801   EXPECT_EQ(-OatFileAssistant::kDex2OatForRelocation,
    802       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    803 
    804   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    805   EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus());
    806   EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OatFileStatus());
    807   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    808 
    809   // Things aren't relocated, so it should fall back to interpreted.
    810   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    811   ASSERT_TRUE(oat_file.get() != nullptr);
    812 
    813   EXPECT_FALSE(oat_file->IsExecutable());
    814   std::vector<std::unique_ptr<const DexFile>> dex_files;
    815   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    816   EXPECT_EQ(1u, dex_files.size());
    817 }
    818 
    819 // Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
    820 // Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
    821 TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
    822   std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
    823   std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
    824 
    825   // Create the dex and odex files
    826   Copy(GetDexSrc1(), dex_location);
    827   GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kExtract);
    828 
    829   // Verify the status.
    830   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    831 
    832   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
    833       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kExtract));
    834   EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
    835       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
    836 
    837   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    838   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
    839   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
    840   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    841 }
    842 
    843 // Case: We have a DEX file and up-to-date OAT file for it.
    844 // Expect: We should load an executable dex file.
    845 TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
    846   if (IsExecutedAsRoot()) {
    847     // We cannot simulate non writable locations when executed as root: b/38000545.
    848     LOG(ERROR) << "Test skipped because it's running as root";
    849     return;
    850   }
    851 
    852   std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
    853 
    854   Copy(GetDexSrc1(), dex_location);
    855   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    856 
    857   ScopedNonWritable scoped_non_writable(dex_location);
    858   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    859 
    860   // Load the oat using an oat file assistant.
    861   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    862 
    863   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    864   ASSERT_TRUE(oat_file.get() != nullptr);
    865   EXPECT_TRUE(oat_file->IsExecutable());
    866   std::vector<std::unique_ptr<const DexFile>> dex_files;
    867   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    868   EXPECT_EQ(1u, dex_files.size());
    869 }
    870 
    871 // Case: We have a DEX file and up-to-date quicken OAT file for it.
    872 // Expect: We should still load the oat file as executable.
    873 TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
    874   if (IsExecutedAsRoot()) {
    875     // We cannot simulate non writable locations when executed as root: b/38000545.
    876     LOG(ERROR) << "Test skipped because it's running as root";
    877     return;
    878   }
    879 
    880   std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
    881 
    882   Copy(GetDexSrc1(), dex_location);
    883   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kQuicken);
    884 
    885   ScopedNonWritable scoped_non_writable(dex_location);
    886   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    887 
    888   // Load the oat using an oat file assistant.
    889   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    890 
    891   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    892   ASSERT_TRUE(oat_file.get() != nullptr);
    893   EXPECT_TRUE(oat_file->IsExecutable());
    894   std::vector<std::unique_ptr<const DexFile>> dex_files;
    895   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    896   EXPECT_EQ(1u, dex_files.size());
    897 }
    898 
    899 // Case: We have a DEX file and up-to-date OAT file for it.
    900 // Expect: Loading non-executable should load the oat non-executable.
    901 TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
    902   if (IsExecutedAsRoot()) {
    903     // We cannot simulate non writable locations when executed as root: b/38000545.
    904     LOG(ERROR) << "Test skipped because it's running as root";
    905     return;
    906   }
    907 
    908   std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
    909 
    910   Copy(GetDexSrc1(), dex_location);
    911 
    912   ScopedNonWritable scoped_non_writable(dex_location);
    913   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    914 
    915   GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
    916 
    917   // Load the oat using an oat file assistant.
    918   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    919 
    920   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    921   ASSERT_TRUE(oat_file.get() != nullptr);
    922   EXPECT_FALSE(oat_file->IsExecutable());
    923   std::vector<std::unique_ptr<const DexFile>> dex_files;
    924   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    925   EXPECT_EQ(1u, dex_files.size());
    926 }
    927 
    928 // Case: We don't have a DEX file and can't write the oat file.
    929 // Expect: We should fail to generate the oat file without crashing.
    930 TEST_F(OatFileAssistantTest, GenNoDex) {
    931   if (IsExecutedAsRoot()) {
    932     // We cannot simulate non writable locations when executed as root: b/38000545.
    933     LOG(ERROR) << "Test skipped because it's running as root";
    934     return;
    935   }
    936 
    937   std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
    938 
    939   ScopedNonWritable scoped_non_writable(dex_location);
    940   ASSERT_TRUE(scoped_non_writable.IsSuccessful());
    941 
    942   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    943   std::string error_msg;
    944   Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
    945   // We should get kUpdateSucceeded from MakeUpToDate since there's nothing
    946   // that can be done in this situation.
    947   ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
    948       oat_file_assistant.MakeUpToDate(false, &error_msg));
    949 
    950   // Verify it didn't create an oat in the default location (dalvik-cache).
    951   OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false);
    952   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OatFileStatus());
    953   // Verify it didn't create the odex file in the default location (../oat/isa/...odex)
    954   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OdexFileStatus());
    955 }
    956 
    957 // Turn an absolute path into a path relative to the current working
    958 // directory.
    959 static std::string MakePathRelative(const std::string& target) {
    960   char buf[MAXPATHLEN];
    961   std::string cwd = getcwd(buf, MAXPATHLEN);
    962 
    963   // Split the target and cwd paths into components.
    964   std::vector<std::string> target_path;
    965   std::vector<std::string> cwd_path;
    966   Split(target, '/', &target_path);
    967   Split(cwd, '/', &cwd_path);
    968 
    969   // Reverse the path components, so we can use pop_back().
    970   std::reverse(target_path.begin(), target_path.end());
    971   std::reverse(cwd_path.begin(), cwd_path.end());
    972 
    973   // Drop the common prefix of the paths. Because we reversed the path
    974   // components, this becomes the common suffix of target_path and cwd_path.
    975   while (!target_path.empty() && !cwd_path.empty()
    976       && target_path.back() == cwd_path.back()) {
    977     target_path.pop_back();
    978     cwd_path.pop_back();
    979   }
    980 
    981   // For each element of the remaining cwd_path, add '..' to the beginning
    982   // of the target path. Because we reversed the path components, we add to
    983   // the end of target_path.
    984   for (unsigned int i = 0; i < cwd_path.size(); i++) {
    985     target_path.push_back("..");
    986   }
    987 
    988   // Reverse again to get the right path order, and join to get the result.
    989   std::reverse(target_path.begin(), target_path.end());
    990   return android::base::Join(target_path, '/');
    991 }
    992 
    993 // Case: Non-absolute path to Dex location.
    994 // Expect: Not sure, but it shouldn't crash.
    995 TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
    996   std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
    997   Copy(GetDexSrc1(), abs_dex_location);
    998 
    999   std::string dex_location = MakePathRelative(abs_dex_location);
   1000   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
   1001 
   1002   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
   1003   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
   1004       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
   1005   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
   1006   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
   1007 }
   1008 
   1009 // Case: Very short, non-existent Dex location.
   1010 // Expect: kNoDexOptNeeded.
   1011 TEST_F(OatFileAssistantTest, ShortDexLocation) {
   1012   std::string dex_location = "/xx";
   1013 
   1014   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
   1015 
   1016   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
   1017   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
   1018       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
   1019   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
   1020   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
   1021   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
   1022 
   1023   // Trying to make it up to date should have no effect.
   1024   std::string error_msg;
   1025   Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
   1026   EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
   1027       oat_file_assistant.MakeUpToDate(false, &error_msg));
   1028   EXPECT_TRUE(error_msg.empty());
   1029 }
   1030 
   1031 // Case: Non-standard extension for dex file.
   1032 // Expect: The status is kDex2OatNeeded.
   1033 TEST_F(OatFileAssistantTest, LongDexExtension) {
   1034   std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
   1035   Copy(GetDexSrc1(), dex_location);
   1036 
   1037   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
   1038 
   1039   EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
   1040       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
   1041 
   1042   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
   1043   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
   1044   EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus());
   1045 }
   1046 
   1047 // A task to generate a dex location. Used by the RaceToGenerate test.
   1048 class RaceGenerateTask : public Task {
   1049  public:
   1050   explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
   1051     : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr)
   1052   {}
   1053 
   1054   void Run(Thread* self ATTRIBUTE_UNUSED) {
   1055     // Load the dex files, and save a pointer to the loaded oat file, so that
   1056     // we can verify only one oat file was loaded for the dex location.
   1057     std::vector<std::unique_ptr<const DexFile>> dex_files;
   1058     std::vector<std::string> error_msgs;
   1059     const OatFile* oat_file = nullptr;
   1060     dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
   1061         dex_location_.c_str(),
   1062         /*class_loader*/nullptr,
   1063         /*dex_elements*/nullptr,
   1064         &oat_file,
   1065         &error_msgs);
   1066     CHECK(!dex_files.empty()) << android::base::Join(error_msgs, '\n');
   1067     CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
   1068     loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
   1069     CHECK_EQ(loaded_oat_file_, oat_file);
   1070   }
   1071 
   1072   const OatFile* GetLoadedOatFile() const {
   1073     return loaded_oat_file_;
   1074   }
   1075 
   1076  private:
   1077   std::string dex_location_;
   1078   std::string oat_location_;
   1079   const OatFile* loaded_oat_file_;
   1080 };
   1081 
   1082 // Test the case where multiple processes race to generate an oat file.
   1083 // This simulates multiple processes using multiple threads.
   1084 //
   1085 // We want unique Oat files to be loaded even when there is a race to load.
   1086 // TODO: The test case no longer tests locking the way it was intended since we now get multiple
   1087 // copies of the same Oat files mapped at different locations.
   1088 TEST_F(OatFileAssistantTest, RaceToGenerate) {
   1089   std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
   1090   std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
   1091 
   1092   // We use the lib core dex file, because it's large, and hopefully should
   1093   // take a while to generate.
   1094   Copy(GetLibCoreDexFileNames()[0], dex_location);
   1095 
   1096   const int kNumThreads = 32;
   1097   Thread* self = Thread::Current();
   1098   ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
   1099   std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
   1100   for (int i = 0; i < kNumThreads; i++) {
   1101     std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
   1102     thread_pool.AddTask(self, task.get());
   1103     tasks.push_back(std::move(task));
   1104   }
   1105   thread_pool.StartWorkers(self);
   1106   thread_pool.Wait(self, true, false);
   1107 
   1108   // Verify every task got a unique oat file.
   1109   std::set<const OatFile*> oat_files;
   1110   for (auto& task : tasks) {
   1111     const OatFile* oat_file = task->GetLoadedOatFile();
   1112     EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
   1113     oat_files.insert(oat_file);
   1114   }
   1115 }
   1116 
   1117 // Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
   1118 // disabled.
   1119 // Expect: We should load the odex file non-executable.
   1120 TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
   1121   std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
   1122   std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
   1123 
   1124   // Create the dex and odex files
   1125   Copy(GetDexSrc1(), dex_location);
   1126   GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
   1127 
   1128   // Load the oat using an executable oat file assistant.
   1129   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
   1130 
   1131   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
   1132   ASSERT_TRUE(oat_file.get() != nullptr);
   1133   EXPECT_FALSE(oat_file->IsExecutable());
   1134   std::vector<std::unique_ptr<const DexFile>> dex_files;
   1135   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
   1136   EXPECT_EQ(1u, dex_files.size());
   1137 }
   1138 
   1139 // Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
   1140 // disabled.
   1141 // Expect: We should load the odex file non-executable.
   1142 TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
   1143   std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
   1144   std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
   1145 
   1146   // Create the dex and odex files
   1147   Copy(GetMultiDexSrc1(), dex_location);
   1148   GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
   1149 
   1150   // Load the oat using an executable oat file assistant.
   1151   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
   1152 
   1153   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
   1154   ASSERT_TRUE(oat_file.get() != nullptr);
   1155   EXPECT_FALSE(oat_file->IsExecutable());
   1156   std::vector<std::unique_ptr<const DexFile>> dex_files;
   1157   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
   1158   EXPECT_EQ(2u, dex_files.size());
   1159 }
   1160 
   1161 TEST_F(OatFileAssistantTest, RuntimeCompilerFilterOptionUsed) {
   1162   std::string dex_location = GetScratchDir() + "/RuntimeCompilerFilterOptionUsed.jar";
   1163   Copy(GetDexSrc1(), dex_location);
   1164 
   1165   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
   1166 
   1167   std::string error_msg;
   1168   Runtime::Current()->AddCompilerOption("--compiler-filter=quicken");
   1169   EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
   1170       oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
   1171   EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
   1172       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
   1173   EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
   1174       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
   1175 
   1176   Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
   1177   EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
   1178       oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
   1179   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
   1180       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken));
   1181   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
   1182       oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
   1183 
   1184   Runtime::Current()->AddCompilerOption("--compiler-filter=bogus");
   1185   EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
   1186       oat_file_assistant.MakeUpToDate(false, &error_msg));
   1187 }
   1188 
   1189 TEST(OatFileAssistantUtilsTest, DexLocationToOdexFilename) {
   1190   std::string error_msg;
   1191   std::string odex_file;
   1192 
   1193   EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
   1194         "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
   1195   EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
   1196 
   1197   EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
   1198         "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
   1199   EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
   1200 
   1201   EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
   1202         "nopath.jar", kArm, &odex_file, &error_msg));
   1203   EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
   1204         "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
   1205 }
   1206 
   1207 // Verify the dexopt status values from dalvik.system.DexFile
   1208 // match the OatFileAssistant::DexOptStatus values.
   1209 TEST_F(OatFileAssistantTest, DexOptStatusValues) {
   1210   std::pair<OatFileAssistant::DexOptNeeded, const char*> mapping[] = {
   1211     {OatFileAssistant::kNoDexOptNeeded, "NO_DEXOPT_NEEDED"},
   1212     {OatFileAssistant::kDex2OatFromScratch, "DEX2OAT_FROM_SCRATCH"},
   1213     {OatFileAssistant::kDex2OatForBootImage, "DEX2OAT_FOR_BOOT_IMAGE"},
   1214     {OatFileAssistant::kDex2OatForFilter, "DEX2OAT_FOR_FILTER"},
   1215     {OatFileAssistant::kDex2OatForRelocation, "DEX2OAT_FOR_RELOCATION"},
   1216   };
   1217 
   1218   ScopedObjectAccess soa(Thread::Current());
   1219   StackHandleScope<1> hs(soa.Self());
   1220   ClassLinker* linker = Runtime::Current()->GetClassLinker();
   1221   Handle<mirror::Class> dexfile(
   1222       hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
   1223   ASSERT_FALSE(dexfile == nullptr);
   1224   linker->EnsureInitialized(soa.Self(), dexfile, true, true);
   1225 
   1226   for (std::pair<OatFileAssistant::DexOptNeeded, const char*> field : mapping) {
   1227     ArtField* art_field = mirror::Class::FindStaticField(
   1228         soa.Self(), dexfile.Get(), field.second, "I");
   1229     ASSERT_FALSE(art_field == nullptr);
   1230     EXPECT_EQ(art_field->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
   1231     EXPECT_EQ(field.first, art_field->GetInt(dexfile.Get()));
   1232   }
   1233 }
   1234 
   1235 // Verify that when no compiler filter is passed the default one from OatFileAssistant is used.
   1236 TEST_F(OatFileAssistantTest, DefaultMakeUpToDateFilter) {
   1237   std::string dex_location = GetScratchDir() + "/TestDex.jar";
   1238   Copy(GetDexSrc1(), dex_location);
   1239 
   1240   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
   1241 
   1242   const CompilerFilter::Filter default_filter =
   1243       OatFileAssistant::kDefaultCompilerFilterForDexLoading;
   1244   std::string error_msg;
   1245   EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
   1246       oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
   1247   EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
   1248             oat_file_assistant.GetDexOptNeeded(default_filter));
   1249   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
   1250   EXPECT_NE(nullptr, oat_file.get());
   1251   EXPECT_EQ(default_filter, oat_file->GetCompilerFilter());
   1252 }
   1253 
   1254 // TODO: More Tests:
   1255 //  * Test class linker falls back to unquickened dex for DexNoOat
   1256 //  * Test class linker falls back to unquickened dex for MultiDexNoOat
   1257 //  * Test using secondary isa
   1258 //  * Test for status of oat while oat is being generated (how?)
   1259 //  * Test case where 32 and 64 bit boot class paths differ,
   1260 //      and we ask IsInBootClassPath for a class in exactly one of the 32 or
   1261 //      64 bit boot class paths.
   1262 //  * Test unexpected scenarios (?):
   1263 //    - Dex is stripped, don't have odex.
   1264 //    - Oat file corrupted after status check, before reload unexecutable
   1265 //    because it's unrelocated and no dex2oat
   1266 }  // namespace art
   1267