diff options
| author | 2016-11-22 09:42:04 +0000 | |
|---|---|---|
| committer | 2016-11-24 16:49:27 +0000 | |
| commit | 03bc659b04fefab6e1c9e08c5bd28fe8168c863f (patch) | |
| tree | 1e27d6e28fd18479bd812f2abf4a88dbd36092e0 | |
| parent | 88bc673b146cb5fda01b4139b6e8ceec5221f106 (diff) | |
Refine OatStatus enum.
Replace Exists() with a separate OatStatus code, and distinguish
between the oat file being out of date due to the dex being out of
date or the image being out of date.
Bug: 30937355
Test: oat_file_assistant_test
Change-Id: Ia3853e461beb07f0b417276b9277b9c562b20865
| -rw-r--r-- | build/Android.gtest.mk | 4 | ||||
| -rw-r--r-- | runtime/dex2oat_environment_test.h | 13 | ||||
| -rw-r--r-- | runtime/oat_file_assistant.cc | 85 | ||||
| -rw-r--r-- | runtime/oat_file_assistant.h | 65 | ||||
| -rw-r--r-- | runtime/oat_file_assistant_test.cc | 358 |
5 files changed, 312 insertions, 213 deletions
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk index 4fce235b83..990262844c 100644 --- a/build/Android.gtest.mk +++ b/build/Android.gtest.mk @@ -116,10 +116,14 @@ ART_GTEST_elf_writer_test_TARGET_DEPS := $(TARGET_CORE_IMAGE_optimizing_no-pic_6 ART_GTEST_dex2oat_environment_tests_HOST_DEPS := \ $(HOST_CORE_IMAGE_optimizing_pic_64) \ $(HOST_CORE_IMAGE_optimizing_pic_32) \ + $(HOST_CORE_IMAGE_optimizing_no-pic_64) \ + $(HOST_CORE_IMAGE_optimizing_no-pic_32) \ $(HOST_OUT_EXECUTABLES)/patchoatd ART_GTEST_dex2oat_environment_tests_TARGET_DEPS := \ $(TARGET_CORE_IMAGE_optimizing_pic_64) \ $(TARGET_CORE_IMAGE_optimizing_pic_32) \ + $(TARGET_CORE_IMAGE_optimizing_no-pic_64) \ + $(TARGET_CORE_IMAGE_optimizing_no-pic_32) \ $(TARGET_OUT_EXECUTABLES)/patchoatd ART_GTEST_oat_file_assistant_test_HOST_DEPS := \ diff --git a/runtime/dex2oat_environment_test.h b/runtime/dex2oat_environment_test.h index d717ec0fcb..b0c4597d73 100644 --- a/runtime/dex2oat_environment_test.h +++ b/runtime/dex2oat_environment_test.h @@ -136,7 +136,9 @@ class Dex2oatEnvironmentTest : public CommonRuntimeTest { + "/core.art"; } - bool GetCachedImageFile(/*out*/std::string* image, std::string* error_msg) const { + bool GetCachedImageFile(const std::string& image_location, + /*out*/std::string* image, + /*out*/std::string* error_msg) const { std::string cache; bool have_android_data; bool dalvik_cache_exists; @@ -151,7 +153,14 @@ class Dex2oatEnvironmentTest : public CommonRuntimeTest { *error_msg = "Failed to create dalvik cache"; return false; } - return GetDalvikCacheFilename(GetImageLocation().c_str(), cache.c_str(), image, error_msg); + return GetDalvikCacheFilename(image_location.c_str(), cache.c_str(), image, error_msg); + } + + // Returns the path to an image location whose contents differ from the + // image at GetImageLocation(). This is used for testing mismatched + // image checksums in the oat_file_assistant_tests. + std::string GetImageLocation2() const { + return GetImageDirectory() + "/core-npic.art"; } std::string GetDexSrc1() const { diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index c4ad98d5fa..6197120d63 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -36,15 +36,21 @@ namespace art { std::ostream& operator << (std::ostream& stream, const OatFileAssistant::OatStatus status) { switch (status) { - case OatFileAssistant::kOatOutOfDate: - stream << "kOatOutOfDate"; + case OatFileAssistant::kOatCannotOpen: + stream << "kOatCannotOpen"; + break; + case OatFileAssistant::kOatDexOutOfDate: + stream << "kOatDexOutOfDate"; + break; + case OatFileAssistant::kOatBootImageOutOfDate: + stream << "kOatBootImageOutOfDate"; + break; + case OatFileAssistant::kOatRelocationOutOfDate: + stream << "kOatRelocationOutOfDate"; break; case OatFileAssistant::kOatUpToDate: stream << "kOatUpToDate"; break; - case OatFileAssistant::kOatNeedsRelocation: - stream << "kOatNeedsRelocation"; - break; default: UNREACHABLE(); } @@ -204,20 +210,28 @@ std::string OatFileAssistant::GetStatusDump() { std::ostringstream status; bool oat_file_exists = false; bool odex_file_exists = false; - if (oat_.Exists()) { + if (oat_.Status() != kOatCannotOpen) { + // If we can open the file, neither Filename nor GetFile should return null. + CHECK(oat_.Filename() != nullptr); + CHECK(oat_.GetFile() != nullptr); + oat_file_exists = true; status << *oat_.Filename() << " [compilation_filter="; - status << CompilerFilter::NameOfFilter(oat_.CompilerFilter()); + status << CompilerFilter::NameOfFilter(oat_.GetFile()->GetCompilerFilter()); status << ", status=" << oat_.Status(); } - if (odex_.Exists()) { + if (odex_.Status() != kOatCannotOpen) { + // If we can open the file, neither Filename nor GetFile should return null. + CHECK(odex_.Filename() != nullptr); + CHECK(odex_.GetFile() != nullptr); + odex_file_exists = true; if (oat_file_exists) { status << "] "; } status << *odex_.Filename() << " [compilation_filter="; - status << CompilerFilter::NameOfFilter(odex_.CompilerFilter()); + status << CompilerFilter::NameOfFilter(odex_.GetFile()->GetCompilerFilter()); status << ", status=" << odex_.Status(); } @@ -276,18 +290,10 @@ bool OatFileAssistant::HasOriginalDexFiles() { return has_original_dex_files_; } -bool OatFileAssistant::OdexFileExists() { - return odex_.Exists(); -} - OatFileAssistant::OatStatus OatFileAssistant::OdexFileStatus() { return odex_.Status(); } -bool OatFileAssistant::OatFileExists() { - return oat_.Exists(); -} - OatFileAssistant::OatStatus OatFileAssistant::OatFileStatus() { return oat_.Status(); } @@ -302,7 +308,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& dex_location_.c_str(), dex_checksum_pointer, &error_msg); if (oat_dex_file == nullptr) { VLOG(oat) << error_msg; - return kOatOutOfDate; + return kOatDexOutOfDate; } // Verify the dex checksums for any secondary multidex files @@ -325,7 +331,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& << secondary_dex_location << ". Expected: " << expected_secondary_checksum << ", Actual: " << actual_secondary_checksum; - return kOatOutOfDate; + return kOatDexOutOfDate; } } else { // If we can't get the checksum for the secondary location, we assume @@ -344,7 +350,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& VLOG(oat) << "No image for oat image checksum to match against."; if (HasOriginalDexFiles()) { - return kOatOutOfDate; + return kOatBootImageOutOfDate; } // If there is no original dex file to fall back to, grudgingly accept @@ -358,7 +364,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& } else if (file.GetOatHeader().GetImageFileLocationOatChecksum() != GetCombinedImageChecksum()) { VLOG(oat) << "Oat image checksum does not match image checksum."; - return kOatOutOfDate; + return kOatBootImageOutOfDate; } } else { VLOG(oat) << "Image checksum test skipped for compiler filter " << current_compiler_filter; @@ -369,7 +375,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& const ImageInfo* image_info = GetImageInfo(); if (image_info == nullptr) { VLOG(oat) << "No image to check oat relocation against."; - return kOatNeedsRelocation; + return kOatRelocationOutOfDate; } // Verify the oat_data_begin recorded for the image in the oat file matches @@ -381,7 +387,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& ": Oat file image oat_data_begin (" << oat_data_begin << ")" << " does not match actual image oat_data_begin (" << image_info->oat_data_begin << ")"; - return kOatNeedsRelocation; + return kOatRelocationOutOfDate; } // Verify the oat_patch_delta recorded for the image in the oat file matches @@ -392,7 +398,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& ": Oat file image patch delta (" << oat_patch_delta << ")" << " does not match actual image patch delta (" << image_info->patch_delta << ")"; - return kOatNeedsRelocation; + return kOatRelocationOutOfDate; } } else { // Oat files compiled in PIC mode do not require relocation. @@ -761,7 +767,8 @@ uint32_t OatFileAssistant::GetCombinedImageChecksum() { } OatFileAssistant::OatFileInfo& OatFileAssistant::GetBestInfo() { - return oat_.Status() != kOatOutOfDate ? oat_ : odex_; + bool use_oat = oat_.IsUseable() || odex_.Status() == kOatCannotOpen; + return use_oat ? oat_ : odex_; } std::unique_ptr<gc::space::ImageSpace> OatFileAssistant::OpenImageSpace(const OatFile* oat_file) { @@ -793,8 +800,16 @@ const std::string* OatFileAssistant::OatFileInfo::Filename() { return filename_provided_ ? &filename_ : nullptr; } -bool OatFileAssistant::OatFileInfo::Exists() { - return GetFile() != nullptr; +bool OatFileAssistant::OatFileInfo::IsUseable() { + switch (Status()) { + case kOatCannotOpen: + case kOatDexOutOfDate: + case kOatBootImageOutOfDate: return false; + + case kOatRelocationOutOfDate: + case kOatUpToDate: return true; + } + UNREACHABLE(); } OatFileAssistant::OatStatus OatFileAssistant::OatFileInfo::Status() { @@ -802,7 +817,7 @@ OatFileAssistant::OatStatus OatFileAssistant::OatFileInfo::Status() { status_attempted_ = true; const OatFile* file = GetFile(); if (file == nullptr) { - status_ = kOatOutOfDate; + status_ = kOatCannotOpen; } else { status_ = oat_file_assistant_->GivenOatFileStatus(*file); VLOG(oat) << file->GetLocation() << " is " << status_ @@ -812,12 +827,6 @@ OatFileAssistant::OatStatus OatFileAssistant::OatFileInfo::Status() { return status_; } -CompilerFilter::Filter OatFileAssistant::OatFileInfo::CompilerFilter() { - const OatFile* file = GetFile(); - CHECK(file != nullptr); - return file->GetCompilerFilter(); -} - OatFileAssistant::DexOptNeeded OatFileAssistant::OatFileInfo::GetDexOptNeeded( CompilerFilter::Filter target, bool profile_changed) { bool compilation_desired = CompilerFilter::IsBytecodeCompilationEnabled(target); @@ -828,7 +837,7 @@ OatFileAssistant::DexOptNeeded OatFileAssistant::OatFileInfo::GetDexOptNeeded( return kNoDexOptNeeded; } - if (Status() == kOatNeedsRelocation) { + if (Status() == kOatRelocationOutOfDate) { if (!compilation_desired) { // If no compilation is desired, then it doesn't matter if the oat // file needs relocation. It's in good shape as is. @@ -919,18 +928,18 @@ std::unique_ptr<OatFile> OatFileAssistant::OatFileInfo::ReleaseFileForUse() { VLOG(oat) << "Oat File Assistant: No relocated oat file found," << " attempting to fall back to interpreting oat file instead."; - if (Status() == kOatNeedsRelocation && !IsExecutable()) { + if (Status() == kOatRelocationOutOfDate && !IsExecutable()) { return ReleaseFile(); } - if (Status() == kOatNeedsRelocation) { + if (Status() == kOatRelocationOutOfDate) { // We are loading an oat file for runtime use that needs relocation. // Reload the file non-executable to ensure that we interpret out of the // dex code in the oat file rather than trying to execute the unrelocated // compiled code. oat_file_assistant_->load_executable_ = false; Reset(); - if (Status() != kOatOutOfDate) { + if (IsUseable()) { CHECK(!IsExecutable()); return ReleaseFile(); } diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h index 14bd82fb68..3a838d7275 100644 --- a/runtime/oat_file_assistant.h +++ b/runtime/oat_file_assistant.h @@ -70,19 +70,26 @@ class OatFileAssistant { }; enum OatStatus { - // kOatOutOfDate - An oat file is said to be out of date if the file does - // not exist, is out of date with respect to the dex file or boot image, - // or does not meet the target compilation type. - kOatOutOfDate, - - // kOatNeedsRelocation - An oat file is said to need relocation if the - // code is up to date, but not yet properly relocated for address space - // layout randomization (ASLR). In this case, the oat file is neither - // "out of date" nor "up to date". - kOatNeedsRelocation, - - // kOatUpToDate - An oat file is said to be up to date if it is not out of - // date and has been properly relocated for the purposes of ASLR. + // kOatCannotOpen - The oat file cannot be opened, because it does not + // exist, is unreadable, or otherwise corrupted. + kOatCannotOpen, + + // kOatDexOutOfDate - The oat file is out of date with respect to the dex file. + kOatDexOutOfDate, + + // kOatBootImageOutOfDate - The oat file is up to date with respect to the + // dex file, but is out of date with respect to the boot image. + kOatBootImageOutOfDate, + + // kOatRelocationOutOfDate - The oat file is up to date with respect to + // the dex file and boot image, but contains compiled code that has the + // wrong patch delta with respect to the boot image. Patchoat should be + // run on the oat file to update the patch delta of the compiled code to + // match the boot image. + kOatRelocationOutOfDate, + + // kOatUpToDate - The oat file is completely up to date with respect to + // the dex file and boot image. kOatUpToDate, }; @@ -209,23 +216,17 @@ class OatFileAssistant { // really an oat file. The odex file will often, but not always, have a // patch delta of 0 and need to be relocated before use for the purposes of // ASLR. The odex file is treated as if it were read-only. - // These methods return the location and status of the odex file for the dex - // location. - bool OdexFileExists(); + // + // Returns the status of the odex file for the dex location. OatStatus OdexFileStatus(); // When the dex files is compiled on the target device, the oat file is the // result. The oat file will have been relocated to some // (possibly-out-of-date) offset for ASLR. - // These methods return the location and status of the target oat file for - // the dex location. - bool OatFileExists(); + // + // Returns the status of the oat file for the dex location. OatStatus OatFileStatus(); - // Return the status for a given opened oat file with respect to the dex - // location. - OatStatus GivenOatFileStatus(const OatFile& file); - // Generates the oat file by relocation from the named input file. // This does not check the current status before attempting to relocate the // oat file. @@ -301,11 +302,17 @@ class OatFileAssistant { bool IsOatLocation(); const std::string* Filename(); - bool Exists(); + + // Returns true if this oat file can be used for running code. The oat + // file can be used for running code as long as it is not out of date with + // respect to the dex code or boot image. An oat file that is out of date + // with respect to relocation is considered useable, because it's possible + // to interpret the dex code rather than run the unrelocated compiled + // code. + bool IsUseable(); + + // Returns the status of this oat file. OatStatus Status(); - // Must only be called if the associated file exists, i.e, if - // |Exists() == true|. - CompilerFilter::Filter CompilerFilter(); // Return the DexOptNeeded value for this oat file with respect to the // given target_compilation_filter. @@ -381,6 +388,10 @@ class OatFileAssistant { // Return info for the best oat file. OatFileInfo& GetBestInfo(); + // Return the status for a given opened oat file with respect to the dex + // location. + OatStatus GivenOatFileStatus(const OatFile& file); + // Returns the current image location. // Returns an empty string if the image location could not be retrieved. // diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc index abd3b963c5..18482557df 100644 --- a/runtime/oat_file_assistant_test.cc +++ b/runtime/oat_file_assistant_test.cc @@ -49,9 +49,9 @@ class OatFileAssistantTest : public Dex2oatEnvironmentTest { // Pre-Relocate the image to a known non-zero offset so we don't have to // deal with the runtime randomly relocating the image by 0 and messing up // the expected results of the tests. - bool PreRelocateImage(std::string* error_msg) { + bool PreRelocateImage(const std::string& image_location, std::string* error_msg) { std::string image; - if (!GetCachedImageFile(&image, error_msg)) { + if (!GetCachedImageFile(image_location, &image, error_msg)) { return false; } @@ -60,7 +60,7 @@ class OatFileAssistantTest : public Dex2oatEnvironmentTest { std::vector<std::string> argv; argv.push_back(patchoat); - argv.push_back("--input-image-location=" + GetImageLocation()); + argv.push_back("--input-image-location=" + image_location); argv.push_back("--output-image-file=" + image); argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA))); argv.push_back("--base-offset-delta=0x00008000"); @@ -69,8 +69,8 @@ class OatFileAssistantTest : public Dex2oatEnvironmentTest { virtual void PreRuntimeCreate() { std::string error_msg; - ASSERT_TRUE(PreRelocateImage(&error_msg)) << error_msg; - + ASSERT_TRUE(PreRelocateImage(GetImageLocation(), &error_msg)) << error_msg; + ASSERT_TRUE(PreRelocateImage(GetImageLocation2(), &error_msg)) << error_msg; UnreserveImageSpace(); } @@ -78,24 +78,32 @@ class OatFileAssistantTest : public Dex2oatEnvironmentTest { ReserveImageSpace(); } - // Generate a non-PIC odex file for the purposes of test. - // The generated odex file will be un-relocated. - void GenerateOdexForTest(const std::string& dex_location, - const std::string& odex_location, - CompilerFilter::Filter filter, - bool pic = false, - bool with_patch_info = true) { - // Temporarily redirect the dalvik cache so dex2oat doesn't find the - // relocated image file. + // Generate an oat file for the purposes of test. + void GenerateOatForTest(const std::string& dex_location, + const std::string& oat_location, + CompilerFilter::Filter filter, + bool relocate, + bool pic, + bool with_patch_info, + bool with_alternate_image) { std::string dalvik_cache = GetDalvikCache(GetInstructionSetString(kRuntimeISA)); std::string dalvik_cache_tmp = dalvik_cache + ".redirected"; - ASSERT_EQ(0, rename(dalvik_cache.c_str(), dalvik_cache_tmp.c_str())) << strerror(errno); + + if (!relocate) { + // Temporarily redirect the dalvik cache so dex2oat doesn't find the + // relocated image file. + ASSERT_EQ(0, rename(dalvik_cache.c_str(), dalvik_cache_tmp.c_str())) << strerror(errno); + } std::vector<std::string> args; args.push_back("--dex-file=" + dex_location); - args.push_back("--oat-file=" + odex_location); + args.push_back("--oat-file=" + oat_location); args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter)); args.push_back("--runtime-arg"); + + // Use -Xnorelocate regardless of the relocate argument. + // We control relocation by redirecting the dalvik cache when needed + // rather than use this flag. args.push_back("-Xnorelocate"); if (pic) { @@ -106,14 +114,22 @@ class OatFileAssistantTest : public Dex2oatEnvironmentTest { args.push_back("--include-patch-information"); } + std::string image_location = GetImageLocation(); + if (with_alternate_image) { + args.push_back("--boot-image=" + GetImageLocation2()); + } + std::string error_msg; ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; - ASSERT_EQ(0, rename(dalvik_cache_tmp.c_str(), dalvik_cache.c_str())) << strerror(errno); - // Verify the odex file was generated as expected and really is - // unrelocated. - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), - odex_location.c_str(), + if (!relocate) { + // Restore the dalvik cache if needed. + ASSERT_EQ(0, rename(dalvik_cache_tmp.c_str(), dalvik_cache.c_str())) << strerror(errno); + } + + // Verify the odex file was generated as expected. + std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_location.c_str(), + oat_location.c_str(), nullptr, nullptr, false, @@ -125,24 +141,59 @@ class OatFileAssistantTest : public Dex2oatEnvironmentTest { EXPECT_EQ(with_patch_info, odex_file->HasPatchInfo()); EXPECT_EQ(filter, odex_file->GetCompilerFilter()); + std::unique_ptr<ImageHeader> image_header( + gc::space::ImageSpace::ReadImageHeader(image_location.c_str(), + kRuntimeISA, + &error_msg)); + ASSERT_TRUE(image_header != nullptr) << error_msg; + const OatHeader& oat_header = odex_file->GetOatHeader(); + uint32_t combined_checksum = OatFileAssistant::CalculateCombinedImageChecksum(); + + if (CompilerFilter::DependsOnImageChecksum(filter)) { + if (with_alternate_image) { + EXPECT_NE(combined_checksum, oat_header.GetImageFileLocationOatChecksum()); + } else { + EXPECT_EQ(combined_checksum, oat_header.GetImageFileLocationOatChecksum()); + } + } + if (CompilerFilter::IsBytecodeCompilationEnabled(filter)) { - const std::vector<gc::space::ImageSpace*> image_spaces = - Runtime::Current()->GetHeap()->GetBootImageSpaces(); - ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr); - const ImageHeader& image_header = image_spaces[0]->GetImageHeader(); - const OatHeader& oat_header = odex_file->GetOatHeader(); - uint32_t combined_checksum = OatFileAssistant::CalculateCombinedImageChecksum(); - EXPECT_EQ(combined_checksum, oat_header.GetImageFileLocationOatChecksum()); - EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()), - oat_header.GetImageFileLocationOatDataBegin()); - EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta()); + if (relocate) { + EXPECT_EQ(reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin()), + oat_header.GetImageFileLocationOatDataBegin()); + EXPECT_EQ(image_header->GetPatchDelta(), oat_header.GetImagePatchDelta()); + } else { + EXPECT_NE(reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin()), + oat_header.GetImageFileLocationOatDataBegin()); + EXPECT_NE(image_header->GetPatchDelta(), oat_header.GetImagePatchDelta()); + } } } + // Generate a non-PIC odex file for the purposes of test. + // The generated odex file will be un-relocated. + void GenerateOdexForTest(const std::string& dex_location, + const std::string& odex_location, + CompilerFilter::Filter filter) { + GenerateOatForTest(dex_location, + odex_location, + filter, + /*relocate*/false, + /*pic*/false, + /*with_patch_info*/true, + /*with_alternate_image*/false); + } + void GeneratePicOdexForTest(const std::string& dex_location, const std::string& odex_location, CompilerFilter::Filter filter) { - GenerateOdexForTest(dex_location, odex_location, filter, true, false); + GenerateOatForTest(dex_location, + odex_location, + filter, + /*relocate*/false, + /*pic*/true, + /*with_patch_info*/false, + /*with_alternate_image*/false); } // Generate a non-PIC odex file without patch information for the purposes @@ -150,7 +201,43 @@ class OatFileAssistantTest : public Dex2oatEnvironmentTest { void GenerateNoPatchOdexForTest(const std::string& dex_location, const std::string& odex_location, CompilerFilter::Filter filter) { - GenerateOdexForTest(dex_location, odex_location, filter, false, false); + GenerateOatForTest(dex_location, + odex_location, + filter, + /*relocate*/false, + /*pic*/false, + /*with_patch_info*/false, + /*with_alternate_image*/false); + } + + // Generate an oat file in the oat location. + void GenerateOatForTest(const char* dex_location, + CompilerFilter::Filter filter, + bool relocate, + bool pic, + bool with_patch_info, + bool with_alternate_image) { + std::string oat_location; + std::string error_msg; + ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename( + dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg; + GenerateOatForTest(dex_location, + oat_location, + filter, + relocate, + pic, + with_patch_info, + with_alternate_image); + } + + // Generate a standard oat file in the oat location. + void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) { + GenerateOatForTest(dex_location, + filter, + /*relocate*/true, + /*pic*/false, + /*with_patch_info*/false, + /*with_alternate_image*/false); } private: @@ -211,36 +298,6 @@ class OatFileAssistantNoDex2OatTest : public OatFileAssistantTest { } }; -// Generate an oat file for the purposes of test, as opposed to testing -// generation of oat files. -static void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) { - // Use an oat file assistant to find the proper oat location. - std::string oat_location; - std::string error_msg; - ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename( - dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg; - - std::vector<std::string> args; - args.push_back("--dex-file=" + std::string(dex_location)); - args.push_back("--oat-file=" + oat_location); - args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter)); - args.push_back("--runtime-arg"); - args.push_back("-Xnorelocate"); - ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; - - // Verify the oat file was generated as expected. - std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location.c_str(), - oat_location.c_str(), - nullptr, - nullptr, - false, - /*low_4gb*/false, - dex_location, - &error_msg)); - ASSERT_TRUE(oat_file.get() != nullptr) << error_msg; - EXPECT_EQ(filter, oat_file->GetCompilerFilter()); -} - // Case: We have a DEX file, but no OAT file for it. // Expect: The status is kDex2OatNeeded. TEST_F(OatFileAssistantTest, DexNoOat) { @@ -259,10 +316,8 @@ TEST_F(OatFileAssistantTest, DexNoOat) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); } @@ -305,9 +360,7 @@ TEST_F(OatFileAssistantTest, OatUpToDate) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_TRUE(oat_file_assistant.OatFileExists()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); } @@ -331,10 +384,8 @@ TEST_F(OatFileAssistantTest, OatForDifferentDex) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_TRUE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); } // Case: We have a DEX file and speed-profile OAT file for it. @@ -357,9 +408,7 @@ TEST_F(OatFileAssistantTest, ProfileOatUpToDate) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly, true)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_TRUE(oat_file_assistant.OatFileExists()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); } @@ -436,10 +485,10 @@ TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) { EXPECT_EQ(2u, dex_files.size()); } -// Case: We have a DEX file and out-of-date OAT file. -// Expect: The status is kDex2OatNeeded. -TEST_F(OatFileAssistantTest, OatOutOfDate) { - std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar"; +// Case: We have a DEX file and an OAT file out of date with respect to the +// dex checksum. +TEST_F(OatFileAssistantTest, OatDexOutOfDate) { + std::string dex_location = GetScratchDir() + "/OatDexOutOfDate.jar"; // We create a dex, generate an oat for it, then overwrite the dex with a // different dex to make the oat out of date. @@ -454,10 +503,62 @@ TEST_F(OatFileAssistantTest, OatOutOfDate) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_TRUE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); +} + +// Case: We have a DEX file and an OAT file out of date with respect to the +// boot image. +TEST_F(OatFileAssistantTest, OatImageOutOfDate) { + std::string dex_location = GetScratchDir() + "/OatImageOutOfDate.jar"; + + Copy(GetDexSrc1(), dex_location); + GenerateOatForTest(dex_location.c_str(), + CompilerFilter::kSpeed, + /*relocate*/true, + /*pic*/false, + /*with_patch_info*/false, + /*with_alternate_image*/true); + + OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); + EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, + oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); + EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, + oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); + EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, + oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); + + EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatBootImageOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); +} + +// Case: We have a DEX file and a verify-at-runtime OAT file out of date with +// respect to the boot image. +// It shouldn't matter that the OAT file is out of date, because it is +// verify-at-runtime. +TEST_F(OatFileAssistantTest, OatVerifyAtRuntimeImageOutOfDate) { + std::string dex_location = GetScratchDir() + "/OatVerifyAtRuntimeImageOutOfDate.jar"; + + Copy(GetDexSrc1(), dex_location); + GenerateOatForTest(dex_location.c_str(), + CompilerFilter::kVerifyAtRuntime, + /*relocate*/true, + /*pic*/false, + /*with_patch_info*/false, + /*with_alternate_image*/true); + + OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); + EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, + oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); + EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, + oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); + + EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); } @@ -480,10 +581,8 @@ TEST_F(OatFileAssistantTest, DexOdexNoOat) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_TRUE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); // We should still be able to get the non-executable odex file to run from. @@ -511,10 +610,8 @@ TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_TRUE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); // Make the oat file up to date. @@ -527,9 +624,7 @@ TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_TRUE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus()); - EXPECT_TRUE(oat_file_assistant.OatFileExists()); + EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus()); EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); @@ -570,10 +665,8 @@ TEST_F(OatFileAssistantTest, StrippedDexOdexOat) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_TRUE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus()); - EXPECT_TRUE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus()); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); // Make the oat file up to date. @@ -588,10 +681,7 @@ TEST_F(OatFileAssistantTest, StrippedDexOdexOat) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_TRUE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus()); - - EXPECT_TRUE(oat_file_assistant.OatFileExists()); + EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus()); EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); @@ -622,10 +712,8 @@ TEST_F(OatFileAssistantTest, ResourceOnlyDex) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); // Make the oat file up to date. This should have no effect. @@ -638,10 +726,8 @@ TEST_F(OatFileAssistantTest, ResourceOnlyDex) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); } @@ -667,10 +753,8 @@ TEST_F(OatFileAssistantTest, SelfRelocation) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_TRUE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); // Make the oat file up to date. @@ -683,9 +767,7 @@ TEST_F(OatFileAssistantTest, SelfRelocation) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_TRUE(oat_file_assistant.OatFileExists()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); @@ -757,10 +839,8 @@ TEST_F(OatFileAssistantTest, OdexOatOverlap) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_TRUE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus()); - EXPECT_TRUE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatRelocationOutOfDate, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); // Things aren't relocated, so it should fall back to interpreted. @@ -792,10 +872,8 @@ TEST_F(OatFileAssistantTest, DexPicOdexNoOat) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_TRUE(oat_file_assistant.OdexFileExists()); EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); } @@ -818,10 +896,8 @@ TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_TRUE(oat_file_assistant.OdexFileExists()); EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); } @@ -909,7 +985,7 @@ TEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) { // Verify it didn't create an oat in the default location. OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false); - EXPECT_FALSE(ofm.OatFileExists()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OatFileStatus()); } // Case: We have a DEX file but can't write the oat file. @@ -996,10 +1072,8 @@ TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) { EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); } // Case: Very short, non-existent Dex location. @@ -1012,10 +1086,8 @@ TEST_F(OatFileAssistantTest, ShortDexLocation) { EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); // Trying to make it up to date should have no effect. @@ -1038,10 +1110,8 @@ TEST_F(OatFileAssistantTest, LongDexExtension) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); - EXPECT_FALSE(oat_file_assistant.OdexFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); - EXPECT_FALSE(oat_file_assistant.OatFileExists()); - EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); + EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); } // A task to generate a dex location. Used by the RaceToGenerate test. @@ -1242,9 +1312,6 @@ TEST_F(OatFileAssistantTest, DexOptStatusValues) { } // TODO: More Tests: -// * Image checksum change is out of date for kIntepretOnly, but not -// kVerifyAtRuntime. But target of kVerifyAtRuntime still says current -// kInterpretOnly is out of date. // * Test class linker falls back to unquickened dex for DexNoOat // * Test class linker falls back to unquickened dex for MultiDexNoOat // * Test using secondary isa @@ -1258,5 +1325,4 @@ TEST_F(OatFileAssistantTest, DexOptStatusValues) { // because it's unrelocated and no dex2oat // * Test unrelocated specific target compilation type can be relocated to // make it up to date. - } // namespace art |