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