summaryrefslogtreecommitdiff
path: root/runtime/oat_file_assistant_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/oat_file_assistant_test.cc')
-rw-r--r--runtime/oat_file_assistant_test.cc552
1 files changed, 313 insertions, 239 deletions
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 07998dd59f..15182b4a36 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -16,16 +16,17 @@
#include "oat_file_assistant.h"
+#include <fcntl.h>
+#include <gtest/gtest.h>
#include <sys/param.h>
+#include <functional>
+#include <memory>
#include <string>
#include <vector>
-#include <fcntl.h>
-
-#include <gtest/gtest.h>
+#include "android-base/scopeguard.h"
#include "android-base/strings.h"
-
#include "art_field-inl.h"
#include "base/os.h"
#include "base/utils.h"
@@ -42,8 +43,16 @@
namespace art {
-class OatFileAssistantTest : public DexoptTest {
+class OatFileAssistantBaseTest : public DexoptTest {};
+
+class OatFileAssistantTest : public OatFileAssistantBaseTest,
+ public testing::WithParamInterface<bool> {
public:
+ void SetUp() override {
+ DexoptTest::SetUp();
+ with_runtime_ = GetParam();
+ }
+
void VerifyOptimizationStatus(OatFileAssistant* assistant,
const std::string& file,
const std::string& expected_filter,
@@ -54,7 +63,7 @@ class OatFileAssistantTest : public DexoptTest {
std::string compilation_reason1;
OatFileAssistant::GetOptimizationStatus(
- file, kRuntimeISA, &compilation_filter1, &compilation_reason1);
+ file, kRuntimeISA, &compilation_filter1, &compilation_reason1, MaybeCreateRuntimeOptions());
ASSERT_EQ(expected_filter, compilation_filter1);
ASSERT_EQ(expected_reason, compilation_reason1);
@@ -115,7 +124,53 @@ class OatFileAssistantTest : public DexoptTest {
return context;
}
+ // Temporarily disables the pointer to the current runtime if `with_runtime_` is false.
+ // Essentially simulates an environment where there is no active runtime.
+ android::base::ScopeGuard<std::function<void()>> ScopedMaybeWithoutRuntime() {
+ if (!with_runtime_) {
+ Runtime::TestOnlySetCurrent(nullptr);
+ }
+ return android::base::make_scope_guard(
+ [this]() { Runtime::TestOnlySetCurrent(runtime_.get()); });
+ }
+
+ // Returns runtime options if `with_runtime_` is false.
+ std::unique_ptr<OatFileAssistant::RuntimeOptions> MaybeCreateRuntimeOptions() {
+ if (with_runtime_) {
+ return nullptr;
+ } else {
+ return std::make_unique<OatFileAssistant::RuntimeOptions>(OatFileAssistant::RuntimeOptions{
+ .image_locations = runtime_->GetImageLocations(),
+ .boot_class_path = runtime_->GetBootClassPath(),
+ .boot_class_path_locations = runtime_->GetBootClassPathLocations(),
+ .boot_class_path_fds = &runtime_->GetBootClassPathFds(),
+ .use_jit_zygote = runtime_->HasImageWithProfile(),
+ .deny_art_apex_data_files = runtime_->DenyArtApexDataFiles(),
+ .apex_versions = runtime_->GetApexVersions(),
+ });
+ }
+ }
+
+ // A helper function to create OatFileAssistant with some default arguments.
+ OatFileAssistant CreateOatFileAssistant(const char* dex_location,
+ ClassLoaderContext* context = nullptr,
+ bool load_executable = false,
+ int vdex_fd = -1,
+ int oat_fd = -1,
+ int zip_fd = -1) {
+ return OatFileAssistant(dex_location,
+ kRuntimeISA,
+ context != nullptr ? context : default_context_.get(),
+ load_executable,
+ /*only_load_trusted_executable=*/false,
+ MaybeCreateRuntimeOptions(),
+ vdex_fd,
+ oat_fd,
+ zip_fd);
+ }
+
std::unique_ptr<ClassLoaderContext> default_context_ = InitializeDefaultContext();
+ bool with_runtime_;
};
class ScopedNonWritable {
@@ -154,7 +209,7 @@ static bool IsExecutedAsRoot() {
// Case: We have a MultiDEX file and up-to-date ODEX file for it with relative
// encoded dex locations.
// Expect: The oat file status is kNoDexOptNeeded.
-TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
+TEST_P(OatFileAssistantTest, RelativeEncodedDexLocation) {
std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
std::string odex_location = GetOdexDir() + "/RelativeEncodedDexLocation.odex";
@@ -172,21 +227,24 @@ TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
std::string error_msg;
ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Verify we can load both dex files.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/true);
std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
ASSERT_TRUE(oat_file.get() != nullptr);
- EXPECT_TRUE(oat_file->IsExecutable());
+ if (with_runtime_) {
+ EXPECT_TRUE(oat_file->IsExecutable());
+ }
std::vector<std::unique_ptr<const DexFile>> dex_files;
dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
EXPECT_EQ(2u, dex_files.size());
}
-TEST_F(OatFileAssistantTest, MakeUpToDateWithContext) {
+TEST_P(OatFileAssistantTest, MakeUpToDateWithContext) {
std::string dex_location = GetScratchDir() + "/TestDex.jar";
std::string odex_location = GetOdexDir() + "/TestDex.odex";
std::string context_location = GetScratchDir() + "/ContextDex.jar";
@@ -198,8 +256,6 @@ TEST_F(OatFileAssistantTest, MakeUpToDateWithContext) {
ASSERT_TRUE(context != nullptr);
ASSERT_TRUE(context->OpenDexFiles());
- OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, context.get(), false);
-
std::string error_msg;
std::vector<std::string> args;
args.push_back("--dex-file=" + dex_location);
@@ -207,6 +263,10 @@ TEST_F(OatFileAssistantTest, MakeUpToDateWithContext) {
args.push_back("--class-loader-context=" + context_str);
ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(), context.get());
+
std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
ASSERT_NE(nullptr, oat_file.get());
ASSERT_NE(nullptr, oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey));
@@ -214,7 +274,7 @@ TEST_F(OatFileAssistantTest, MakeUpToDateWithContext) {
oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey));
}
-TEST_F(OatFileAssistantTest, GetDexOptNeededWithUpToDateContextRelative) {
+TEST_P(OatFileAssistantTest, GetDexOptNeededWithUpToDateContextRelative) {
std::string dex_location = GetScratchDir() + "/TestDex.jar";
std::string odex_location = GetOdexDir() + "/TestDex.odex";
std::string context_location = GetScratchDir() + "/ContextDex.jar";
@@ -228,11 +288,6 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithUpToDateContextRelative) {
std::vector<int> context_fds;
ASSERT_TRUE(relative_context->OpenDexFiles(GetScratchDir(), context_fds));
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- relative_context.get(),
- false);
-
std::string error_msg;
std::vector<std::string> args;
args.push_back("--dex-file=" + dex_location);
@@ -240,20 +295,24 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithUpToDateContextRelative) {
args.push_back("--class-loader-context=PCL[" + context_location + "]");
ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant =
+ CreateOatFileAssistant(dex_location.c_str(), relative_context.get());
+
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kDefaultCompilerFilter));
}
// Case: We have a DEX file, but no OAT file for it.
// Expect: The status is kDex2OatNeeded.
-TEST_F(OatFileAssistantTest, DexNoOat) {
+TEST_P(OatFileAssistantTest, DexNoOat) {
std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
Copy(GetDexSrc1(), dex_location);
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
@@ -279,13 +338,12 @@ TEST_F(OatFileAssistantTest, DexNoOat) {
// Case: We have no DEX file and no OAT file.
// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
-TEST_F(OatFileAssistantTest, NoDexNoOat) {
+TEST_P(OatFileAssistantTest, NoDexNoOat) {
std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -298,18 +356,16 @@ TEST_F(OatFileAssistantTest, NoDexNoOat) {
// Case: We have a DEX file and an ODEX file, but no OAT file.
// Expect: The status is kNoDexOptNeeded.
-TEST_F(OatFileAssistantTest, OdexUpToDate) {
+TEST_P(OatFileAssistantTest, OdexUpToDate) {
std::string dex_location = GetScratchDir() + "/OdexUpToDate.jar";
std::string odex_location = GetOdexDir() + "/OdexUpToDate.odex";
Copy(GetDexSrc1(), dex_location);
GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed, "install");
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Force the use of oat location by making the dex parent not writable.
- OatFileAssistant oat_file_assistant(
- dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- /*load_executable=*/ false);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -335,7 +391,7 @@ TEST_F(OatFileAssistantTest, OdexUpToDate) {
// Case: We have an ODEX file compiled against partial boot image.
// Expect: The status is kNoDexOptNeeded.
-TEST_F(OatFileAssistantTest, OdexUpToDatePartialBootImage) {
+TEST_P(OatFileAssistantTest, OdexUpToDatePartialBootImage) {
std::string dex_location = GetScratchDir() + "/OdexUpToDate.jar";
std::string odex_location = GetOdexDir() + "/OdexUpToDate.odex";
Copy(GetDexSrc1(), dex_location);
@@ -344,12 +400,10 @@ TEST_F(OatFileAssistantTest, OdexUpToDatePartialBootImage) {
// Insert an extra dex file to the boot class path.
InsertNewBootClasspathEntry();
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Force the use of oat location by making the dex parent not writable.
- OatFileAssistant oat_file_assistant(
- dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- /*load_executable=*/ false);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -376,7 +430,7 @@ TEST_F(OatFileAssistantTest, OdexUpToDatePartialBootImage) {
// Case: We have a DEX file and a PIC ODEX file, but no OAT file. We load the dex
// file via a symlink.
// Expect: The status is kNoDexOptNeeded.
-TEST_F(OatFileAssistantTest, OdexUpToDateSymLink) {
+TEST_P(OatFileAssistantTest, OdexUpToDateSymLink) {
std::string scratch_dir = GetScratchDir();
std::string dex_location = GetScratchDir() + "/OdexUpToDate.jar";
std::string odex_location = GetOdexDir() + "/OdexUpToDate.odex";
@@ -389,10 +443,9 @@ TEST_F(OatFileAssistantTest, OdexUpToDateSymLink) {
ASSERT_EQ(0, symlink(scratch_dir.c_str(), link.c_str()));
dex_location = link + "/OdexUpToDate.jar";
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -411,7 +464,7 @@ TEST_F(OatFileAssistantTest, OdexUpToDateSymLink) {
// Case: We have a DEX file and up-to-date OAT file for it.
// Expect: The status is kNoDexOptNeeded.
-TEST_F(OatFileAssistantTest, OatUpToDate) {
+TEST_P(OatFileAssistantTest, OatUpToDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -426,10 +479,9 @@ TEST_F(OatFileAssistantTest, OatUpToDate) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -455,7 +507,7 @@ TEST_F(OatFileAssistantTest, OatUpToDate) {
// Case: Passing valid file descriptors of updated odex/vdex files along with the dex file.
// Expect: The status is kNoDexOptNeeded.
-TEST_F(OatFileAssistantTest, GetDexOptNeededWithFd) {
+TEST_P(OatFileAssistantTest, GetDexOptNeededWithFd) {
std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
std::string odex_location = GetScratchDir() + "/OatUpToDate.odex";
std::string vdex_location = GetScratchDir() + "/OatUpToDate.vdex";
@@ -470,14 +522,14 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithFd) {
android::base::unique_fd vdex_fd(open(vdex_location.c_str(), O_RDONLY | O_CLOEXEC));
android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY | O_CLOEXEC));
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false,
- false,
- vdex_fd.get(),
- odex_fd.get(),
- zip_fd.get());
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/false,
+ vdex_fd.get(),
+ odex_fd.get(),
+ zip_fd.get());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
@@ -495,7 +547,7 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithFd) {
// Case: Passing invalid odex fd and valid vdex and zip fds.
// Expect: The status should be kDex2OatForBootImage.
-TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidOdexFd) {
+TEST_P(OatFileAssistantTest, GetDexOptNeededWithInvalidOdexFd) {
std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
std::string odex_location = GetScratchDir() + "/OatUpToDate.odex";
std::string vdex_location = GetScratchDir() + "/OatUpToDate.vdex";
@@ -509,14 +561,14 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidOdexFd) {
android::base::unique_fd vdex_fd(open(vdex_location.c_str(), O_RDONLY | O_CLOEXEC));
android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY | O_CLOEXEC));
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false,
- false,
- vdex_fd.get(),
- /* oat_fd= */ -1,
- zip_fd.get());
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/false,
+ vdex_fd.get(),
+ /*oat_fd=*/-1,
+ zip_fd.get());
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
@@ -532,7 +584,7 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidOdexFd) {
// Case: Passing invalid vdex fd and valid odex and zip fds.
// Expect: The status should be kDex2OatFromScratch.
-TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidVdexFd) {
+TEST_P(OatFileAssistantTest, GetDexOptNeededWithInvalidVdexFd) {
std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
std::string odex_location = GetScratchDir() + "/OatUpToDate.odex";
@@ -545,14 +597,14 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidVdexFd) {
android::base::unique_fd odex_fd(open(odex_location.c_str(), O_RDONLY | O_CLOEXEC));
android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY | O_CLOEXEC));
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false,
- false,
- /* vdex_fd= */ -1,
- odex_fd.get(),
- zip_fd.get());
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/false,
+ /*vdex_fd=*/-1,
+ odex_fd.get(),
+ zip_fd.get());
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -564,20 +616,21 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidVdexFd) {
// Case: Passing invalid vdex and odex fd with valid zip fd.
// Expect: The status is kDex2oatFromScratch.
-TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidOdexVdexFd) {
+TEST_P(OatFileAssistantTest, GetDexOptNeededWithInvalidOdexVdexFd) {
std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
Copy(GetDexSrc1(), dex_location);
android::base::unique_fd zip_fd(open(dex_location.c_str(), O_RDONLY | O_CLOEXEC));
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false,
- false,
- /* vdex_fd= */ -1,
- /* oat_fd= */ -1,
- zip_fd);
+
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/false,
+ /*vdex_fd=*/-1,
+ /*oat_fd=*/-1,
+ zip_fd);
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus());
@@ -586,7 +639,7 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithInvalidOdexVdexFd) {
// Case: We have a DEX file and up-to-date VDEX file for it, but no
// ODEX file.
-TEST_F(OatFileAssistantTest, VdexUpToDateNoOdex) {
+TEST_P(OatFileAssistantTest, VdexUpToDateNoOdex) {
std::string dex_location = GetScratchDir() + "/VdexUpToDateNoOdex.jar";
std::string odex_location = GetOdexDir() + "/VdexUpToDateNoOdex.oat";
@@ -597,10 +650,9 @@ TEST_F(OatFileAssistantTest, VdexUpToDateNoOdex) {
GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
ASSERT_EQ(0, unlink(odex_location.c_str()));
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kVerify));
@@ -620,7 +672,7 @@ TEST_F(OatFileAssistantTest, VdexUpToDateNoOdex) {
}
// Case: We have a DEX file and empty VDEX and ODEX files.
-TEST_F(OatFileAssistantTest, EmptyVdexOdex) {
+TEST_P(OatFileAssistantTest, EmptyVdexOdex) {
std::string dex_location = GetScratchDir() + "/EmptyVdexOdex.jar";
std::string odex_location = GetOdexDir() + "/EmptyVdexOdex.oat";
std::string vdex_location = GetOdexDir() + "/EmptyVdexOdex.vdex";
@@ -629,17 +681,16 @@ TEST_F(OatFileAssistantTest, EmptyVdexOdex) {
ScratchFile vdex_file(vdex_location.c_str());
ScratchFile odex_file(odex_location.c_str());
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
}
// Case: We have a DEX file and up-to-date (OAT) VDEX file for it, but no OAT
// file.
-TEST_F(OatFileAssistantTest, VdexUpToDateNoOat) {
+TEST_P(OatFileAssistantTest, VdexUpToDateNoOat) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -650,7 +701,8 @@ TEST_F(OatFileAssistantTest, VdexUpToDateNoOat) {
std::string oat_location;
std::string error_msg;
ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename(
- dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg;
+ dex_location, kRuntimeISA, /* deny_art_apex_data_files= */false, &oat_location, &error_msg))
+ << error_msg;
Copy(GetDexSrc1(), dex_location);
GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
@@ -658,10 +710,10 @@ TEST_F(OatFileAssistantTest, VdexUpToDateNoOat) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -670,7 +722,7 @@ TEST_F(OatFileAssistantTest, VdexUpToDateNoOat) {
// Case: We have a DEX file and speed-profile OAT file for it.
// Expect: The status is kNoDexOptNeeded if the profile hasn't changed, but
// kDex2Oat if the profile has changed.
-TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
+TEST_P(OatFileAssistantTest, ProfileOatUpToDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -684,10 +736,9 @@ TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeedProfile, false));
@@ -706,7 +757,7 @@ TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
// Case: We have a MultiDEX file and up-to-date OAT file for it.
// Expect: The status is kNoDexOptNeeded and we load all dex files.
-TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
+TEST_P(OatFileAssistantTest, MultiDexOatUpToDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -720,10 +771,11 @@ TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/true);
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
EXPECT_TRUE(oat_file_assistant.HasDexFiles());
@@ -731,7 +783,9 @@ TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
// Verify we can load both dex files.
std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
ASSERT_TRUE(oat_file.get() != nullptr);
- EXPECT_TRUE(oat_file->IsExecutable());
+ if (with_runtime_) {
+ EXPECT_TRUE(oat_file->IsExecutable());
+ }
std::vector<std::unique_ptr<const DexFile>> dex_files;
dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
EXPECT_EQ(2u, dex_files.size());
@@ -739,7 +793,7 @@ TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
// Case: We have a MultiDEX file where the non-main multdex entry is out of date.
// Expect: The status is kDex2OatNeeded.
-TEST_F(OatFileAssistantTest, MultiDexNonMainOutOfDate) {
+TEST_P(OatFileAssistantTest, MultiDexNonMainOutOfDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -759,10 +813,9 @@ TEST_F(OatFileAssistantTest, MultiDexNonMainOutOfDate) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
EXPECT_TRUE(oat_file_assistant.HasDexFiles());
@@ -770,7 +823,7 @@ TEST_F(OatFileAssistantTest, MultiDexNonMainOutOfDate) {
// Case: We have a DEX file and an OAT file out of date with respect to the
// dex checksum.
-TEST_F(OatFileAssistantTest, OatDexOutOfDate) {
+TEST_P(OatFileAssistantTest, OatDexOutOfDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -788,10 +841,9 @@ TEST_F(OatFileAssistantTest, OatDexOutOfDate) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
@@ -812,7 +864,7 @@ TEST_F(OatFileAssistantTest, OatDexOutOfDate) {
// Case: We have a DEX file and an (ODEX) VDEX file out of date with respect
// to the dex checksum, but no ODEX file.
-TEST_F(OatFileAssistantTest, VdexDexOutOfDate) {
+TEST_P(OatFileAssistantTest, VdexDexOutOfDate) {
std::string dex_location = GetScratchDir() + "/VdexDexOutOfDate.jar";
std::string odex_location = GetOdexDir() + "/VdexDexOutOfDate.oat";
@@ -821,10 +873,9 @@ TEST_F(OatFileAssistantTest, VdexDexOutOfDate) {
ASSERT_EQ(0, unlink(odex_location.c_str()));
Copy(GetDexSrc2(), dex_location);
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -832,7 +883,7 @@ TEST_F(OatFileAssistantTest, VdexDexOutOfDate) {
// Case: We have a MultiDEX (ODEX) VDEX file where the non-main multidex entry
// is out of date and there is no corresponding ODEX file.
-TEST_F(OatFileAssistantTest, VdexMultiDexNonMainOutOfDate) {
+TEST_P(OatFileAssistantTest, VdexMultiDexNonMainOutOfDate) {
std::string dex_location = GetScratchDir() + "/VdexMultiDexNonMainOutOfDate.jar";
std::string odex_location = GetOdexDir() + "/VdexMultiDexNonMainOutOfDate.odex";
@@ -841,10 +892,9 @@ TEST_F(OatFileAssistantTest, VdexMultiDexNonMainOutOfDate) {
ASSERT_EQ(0, unlink(odex_location.c_str()));
Copy(GetMultiDexSrc2(), dex_location);
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -852,7 +902,7 @@ TEST_F(OatFileAssistantTest, VdexMultiDexNonMainOutOfDate) {
// Case: We have a DEX file and an OAT file out of date with respect to the
// boot image.
-TEST_F(OatFileAssistantTest, OatImageOutOfDate) {
+TEST_P(OatFileAssistantTest, OatImageOutOfDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -869,10 +919,9 @@ TEST_F(OatFileAssistantTest, OatImageOutOfDate) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
@@ -897,7 +946,7 @@ TEST_F(OatFileAssistantTest, OatImageOutOfDate) {
// 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) {
+TEST_P(OatFileAssistantTest, OatVerifyAtRuntimeImageOutOfDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -914,10 +963,9 @@ TEST_F(OatFileAssistantTest, OatVerifyAtRuntimeImageOutOfDate) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
EXPECT_EQ(OatFileAssistant::kDex2OatForFilter,
@@ -930,7 +978,7 @@ TEST_F(OatFileAssistantTest, OatVerifyAtRuntimeImageOutOfDate) {
}
// Case: We have a DEX file and an ODEX file, but no OAT file.
-TEST_F(OatFileAssistantTest, DexOdexNoOat) {
+TEST_P(OatFileAssistantTest, DexOdexNoOat) {
std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
@@ -938,11 +986,10 @@ TEST_F(OatFileAssistantTest, DexOdexNoOat) {
Copy(GetDexSrc1(), dex_location);
GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Verify the status.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
@@ -961,16 +1008,15 @@ TEST_F(OatFileAssistantTest, DexOdexNoOat) {
// Case: We have a resource-only DEX file, no ODEX file and no
// OAT file. Expect: The status is kNoDexOptNeeded.
-TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
+TEST_P(OatFileAssistantTest, ResourceOnlyDex) {
std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
Copy(GetResourceOnlySrc1(), dex_location);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Verify the status.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -995,7 +1041,7 @@ TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
// Case: We have a DEX file, an ODEX file and an OAT file.
// Expect: It shouldn't crash. We should load the odex file executable.
-TEST_F(OatFileAssistantTest, OdexOatOverlap) {
+TEST_P(OatFileAssistantTest, OdexOatOverlap) {
std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
@@ -1004,11 +1050,12 @@ TEST_F(OatFileAssistantTest, OdexOatOverlap) {
GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Verify things don't go bad.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/true);
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -1021,7 +1068,9 @@ TEST_F(OatFileAssistantTest, OdexOatOverlap) {
std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
ASSERT_TRUE(oat_file.get() != nullptr);
- EXPECT_TRUE(oat_file->IsExecutable());
+ if (with_runtime_) {
+ EXPECT_TRUE(oat_file->IsExecutable());
+ }
std::vector<std::unique_ptr<const DexFile>> dex_files;
dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
EXPECT_EQ(1u, dex_files.size());
@@ -1029,7 +1078,7 @@ TEST_F(OatFileAssistantTest, OdexOatOverlap) {
// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
-TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
+TEST_P(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
@@ -1037,11 +1086,10 @@ TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
Copy(GetDexSrc1(), dex_location);
GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kExtract);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Verify the status.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
@@ -1056,7 +1104,7 @@ TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
// Case: We have a DEX file and up-to-date OAT file for it.
// Expect: We should load an executable dex file.
-TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
+TEST_P(OatFileAssistantTest, LoadOatUpToDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -1071,15 +1119,18 @@ TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Load the oat using an oat file assistant.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/true);
std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
ASSERT_TRUE(oat_file.get() != nullptr);
- EXPECT_TRUE(oat_file->IsExecutable());
+ if (with_runtime_) {
+ EXPECT_TRUE(oat_file->IsExecutable());
+ }
std::vector<std::unique_ptr<const DexFile>> dex_files;
dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
EXPECT_EQ(1u, dex_files.size());
@@ -1087,7 +1138,7 @@ TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
// Case: We have a DEX file and up-to-date quicken OAT file for it.
// Expect: We should still load the oat file as executable.
-TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
+TEST_P(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -1102,15 +1153,18 @@ TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
ScopedNonWritable scoped_non_writable(dex_location);
ASSERT_TRUE(scoped_non_writable.IsSuccessful());
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Load the oat using an oat file assistant.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/true);
std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
ASSERT_TRUE(oat_file.get() != nullptr);
- EXPECT_TRUE(oat_file->IsExecutable());
+ if (with_runtime_) {
+ EXPECT_TRUE(oat_file->IsExecutable());
+ }
std::vector<std::unique_ptr<const DexFile>> dex_files;
dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
EXPECT_EQ(1u, dex_files.size());
@@ -1118,7 +1172,7 @@ TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
// Case: We have a DEX file and up-to-date OAT file for it.
// Expect: Loading non-executable should load the oat non-executable.
-TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
+TEST_P(OatFileAssistantTest, LoadNoExecOatUpToDate) {
if (IsExecutedAsRoot()) {
// We cannot simulate non writable locations when executed as root: b/38000545.
LOG(ERROR) << "Test skipped because it's running as root";
@@ -1134,15 +1188,18 @@ TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Load the oat using an oat file assistant.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/true);
std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
ASSERT_TRUE(oat_file.get() != nullptr);
- EXPECT_FALSE(oat_file->IsExecutable());
+ if (with_runtime_) {
+ EXPECT_TRUE(oat_file->IsExecutable());
+ }
std::vector<std::unique_ptr<const DexFile>> dex_files;
dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
EXPECT_EQ(1u, dex_files.size());
@@ -1186,15 +1243,14 @@ static std::string MakePathRelative(const std::string& target) {
// Case: Non-absolute path to Dex location.
// Expect: Not sure, but it shouldn't crash.
-TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
+TEST_P(OatFileAssistantTest, NonAbsoluteDexLocation) {
std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
Copy(GetDexSrc1(), abs_dex_location);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
std::string dex_location = MakePathRelative(abs_dex_location);
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
@@ -1205,13 +1261,12 @@ TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
// Case: Very short, non-existent Dex location.
// Expect: kNoDexOptNeeded.
-TEST_F(OatFileAssistantTest, ShortDexLocation) {
+TEST_P(OatFileAssistantTest, ShortDexLocation) {
std::string dex_location = "/xx";
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
@@ -1223,14 +1278,13 @@ TEST_F(OatFileAssistantTest, ShortDexLocation) {
// Case: Non-standard extension for dex file.
// Expect: The status is kDex2OatNeeded.
-TEST_F(OatFileAssistantTest, LongDexExtension) {
+TEST_P(OatFileAssistantTest, LongDexExtension) {
std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
Copy(GetDexSrc1(), dex_location);
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kSpeed));
@@ -1243,7 +1297,7 @@ TEST_F(OatFileAssistantTest, LongDexExtension) {
// A task to generate a dex location. Used by the RaceToGenerate test.
class RaceGenerateTask : public Task {
public:
- RaceGenerateTask(OatFileAssistantTest& test,
+ RaceGenerateTask(OatFileAssistantBaseTest& test,
const std::string& dex_location,
const std::string& oat_location,
Mutex* lock)
@@ -1251,8 +1305,7 @@ class RaceGenerateTask : public Task {
dex_location_(dex_location),
oat_location_(oat_location),
lock_(lock),
- loaded_oat_file_(nullptr)
- {}
+ loaded_oat_file_(nullptr) {}
void Run(Thread* self ATTRIBUTE_UNUSED) override {
// Load the dex files, and save a pointer to the loaded oat file, so that
@@ -1288,7 +1341,7 @@ class RaceGenerateTask : public Task {
}
private:
- OatFileAssistantTest& test_;
+ OatFileAssistantBaseTest& test_;
std::string dex_location_;
std::string oat_location_;
Mutex* lock_;
@@ -1297,7 +1350,7 @@ class RaceGenerateTask : public Task {
// Test the case where dex2oat invocations race with multiple processes trying to
// load the oat file.
-TEST_F(OatFileAssistantTest, RaceToGenerate) {
+TEST_F(OatFileAssistantBaseTest, RaceToGenerate) {
std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
@@ -1336,7 +1389,7 @@ TEST_F(OatFileAssistantTest, RaceToGenerate) {
// Case: We have a DEX file and an ODEX file, and no OAT file,
// Expect: We should load the odex file executable.
-TEST_F(OatFileAssistantTest, LoadDexOdexNoOat) {
+TEST_P(OatFileAssistantTest, LoadDexOdexNoOat) {
std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
@@ -1344,15 +1397,18 @@ TEST_F(OatFileAssistantTest, LoadDexOdexNoOat) {
Copy(GetDexSrc1(), dex_location);
GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Load the oat using an executable oat file assistant.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/true);
std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
ASSERT_TRUE(oat_file.get() != nullptr);
- EXPECT_TRUE(oat_file->IsExecutable());
+ if (with_runtime_) {
+ EXPECT_TRUE(oat_file->IsExecutable());
+ }
std::vector<std::unique_ptr<const DexFile>> dex_files;
dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
EXPECT_EQ(1u, dex_files.size());
@@ -1360,7 +1416,7 @@ TEST_F(OatFileAssistantTest, LoadDexOdexNoOat) {
// Case: We have a MultiDEX file and an ODEX file, and no OAT file.
// Expect: We should load the odex file executable.
-TEST_F(OatFileAssistantTest, LoadMultiDexOdexNoOat) {
+TEST_P(OatFileAssistantTest, LoadMultiDexOdexNoOat) {
std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
@@ -1368,15 +1424,18 @@ TEST_F(OatFileAssistantTest, LoadMultiDexOdexNoOat) {
Copy(GetMultiDexSrc1(), dex_location);
GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
// Load the oat using an executable oat file assistant.
- OatFileAssistant oat_file_assistant(dex_location.c_str(),
- kRuntimeISA,
- default_context_.get(),
- true);
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str(),
+ /*context=*/nullptr,
+ /*load_executable=*/true);
std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
ASSERT_TRUE(oat_file.get() != nullptr);
- EXPECT_TRUE(oat_file->IsExecutable());
+ if (with_runtime_) {
+ EXPECT_TRUE(oat_file->IsExecutable());
+ }
std::vector<std::unique_ptr<const DexFile>> dex_files;
dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
EXPECT_EQ(2u, dex_files.size());
@@ -1402,7 +1461,7 @@ TEST(OatFileAssistantUtilsTest, DexLocationToOdexFilename) {
// Verify the dexopt status values from dalvik.system.DexFile
// match the OatFileAssistant::DexOptStatus values.
-TEST_F(OatFileAssistantTest, DexOptStatusValues) {
+TEST_F(OatFileAssistantBaseTest, DexOptStatusValues) {
std::pair<OatFileAssistant::DexOptNeeded, const char*> mapping[] = {
{OatFileAssistant::kNoDexOptNeeded, "NO_DEXOPT_NEEDED"},
{OatFileAssistant::kDex2OatFromScratch, "DEX2OAT_FROM_SCRATCH"},
@@ -1426,7 +1485,7 @@ TEST_F(OatFileAssistantTest, DexOptStatusValues) {
}
}
-TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) {
+TEST_P(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) {
std::string dex_location = GetScratchDir() + "/TestDex.jar";
std::string odex_location = GetOdexDir() + "/TestDex.odex";
@@ -1455,8 +1514,11 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) {
ASSERT_TRUE(updated_context != nullptr);
std::vector<int> context_fds;
ASSERT_TRUE(updated_context->OpenDexFiles("", context_fds, /*only_read_checksums*/ true));
- OatFileAssistant oat_file_assistant(
- dex_location.c_str(), kRuntimeISA, updated_context.get(), false);
+
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant =
+ CreateOatFileAssistant(dex_location.c_str(), updated_context.get());
// DexOptNeeded should advise compilation for filter when the context changes.
EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kDefaultCompilerFilter));
@@ -1465,12 +1527,15 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) {
std::unique_ptr<ClassLoaderContext> updated_context = ClassLoaderContext::Create(context_str);
ASSERT_TRUE(updated_context != nullptr);
std::vector<int> context_fds;
- ASSERT_TRUE(updated_context->OpenDexFiles("", context_fds, /*only_read_checksums*/ true));
- OatFileAssistant oat_file_assistant(
- dex_location.c_str(), kRuntimeISA, updated_context.get(), false);
- // Now check that DexOptNeeded does not advise compilation if we only extracted the file.
+ ASSERT_TRUE(updated_context->OpenDexFiles("", context_fds, /*only_read_checksums*/ true));
args.push_back("--compiler-filter=extract");
ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
+
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant =
+ CreateOatFileAssistant(dex_location.c_str(), updated_context.get());
+ // Now check that DexOptNeeded does not advise compilation if we only extracted the file.
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
}
@@ -1478,12 +1543,15 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) {
std::unique_ptr<ClassLoaderContext> updated_context = ClassLoaderContext::Create(context_str);
ASSERT_TRUE(updated_context != nullptr);
std::vector<int> context_fds;
- ASSERT_TRUE(updated_context->OpenDexFiles("", context_fds, /*only_read_checksums*/ true));
- OatFileAssistant oat_file_assistant(
- dex_location.c_str(), kRuntimeISA, updated_context.get(), false);
- // Now check that DexOptNeeded does not advise compilation if we only verify the file.
+ ASSERT_TRUE(updated_context->OpenDexFiles("", context_fds, /*only_read_checksums*/ true));
args.push_back("--compiler-filter=verify");
ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
+
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant =
+ CreateOatFileAssistant(dex_location.c_str(), updated_context.get());
+ // Now check that DexOptNeeded does not advise compilation if we only verify the file.
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
GetDexOptNeeded(&oat_file_assistant, CompilerFilter::kExtract));
}
@@ -1491,7 +1559,7 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) {
// Test that GetLocation of a dex file is the same whether the dex
// filed is backed by an oat file or not.
-TEST_F(OatFileAssistantTest, GetDexLocation) {
+TEST_F(OatFileAssistantBaseTest, GetDexLocation) {
std::string dex_location = GetScratchDir() + "/TestDex.jar";
std::string oat_location = GetOdexDir() + "/TestDex.odex";
std::string art_location = GetOdexDir() + "/TestDex.art";
@@ -1539,7 +1607,7 @@ TEST_F(OatFileAssistantTest, GetDexLocation) {
// Test that a dex file on the platform location gets the right hiddenapi domain,
// regardless of whether it has a backing oat file.
-TEST_F(OatFileAssistantTest, SystemFrameworkDir) {
+TEST_F(OatFileAssistantBaseTest, SystemFrameworkDir) {
std::string filebase = "OatFileAssistantTestSystemFrameworkDir";
std::string dex_location = GetAndroidRoot() + "/framework/" + filebase + ".jar";
Copy(GetDexSrc1(), dex_location);
@@ -1619,7 +1687,7 @@ TEST_F(OatFileAssistantTest, SystemFrameworkDir) {
}
// Make sure OAT files that require app images are not loaded as executable.
-TEST_F(OatFileAssistantTest, LoadOatNoArt) {
+TEST_F(OatFileAssistantBaseTest, LoadOatNoArt) {
std::string dex_location = GetScratchDir() + "/TestDex.jar";
std::string odex_location = GetOdexDir() + "/TestDex.odex";
std::string art_location = GetOdexDir() + "/TestDex.art";
@@ -1653,7 +1721,7 @@ TEST_F(OatFileAssistantTest, LoadOatNoArt) {
EXPECT_FALSE(oat_file->IsExecutable());
}
-TEST_F(OatFileAssistantTest, GetDexOptNeededWithApexVersions) {
+TEST_P(OatFileAssistantTest, GetDexOptNeededWithApexVersions) {
std::string dex_location = GetScratchDir() + "/TestDex.jar";
std::string odex_location = GetOdexDir() + "/TestDex.odex";
Copy(GetDexSrc1(), dex_location);
@@ -1667,8 +1735,9 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithApexVersions) {
args.push_back("--apex-versions=" + Runtime::Current()->GetApexVersions());
ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
- OatFileAssistant oat_file_assistant(
- dex_location.c_str(), kRuntimeISA, default_context_.get(), false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
}
@@ -1681,8 +1750,9 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithApexVersions) {
args.push_back("--apex-versions=" + Runtime::Current()->GetApexVersions().substr(0, 1));
ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
- OatFileAssistant oat_file_assistant(
- dex_location.c_str(), kRuntimeISA, default_context_.get(), false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
}
@@ -1695,8 +1765,9 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithApexVersions) {
args.push_back("--apex-versions=/1/2/3/4");
ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg;
- OatFileAssistant oat_file_assistant(
- dex_location.c_str(), kRuntimeISA, default_context_.get(), false);
+ auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+
+ OatFileAssistant oat_file_assistant = CreateOatFileAssistant(dex_location.c_str());
EXPECT_EQ(OatFileAssistant::kOatBootImageOutOfDate, oat_file_assistant.OdexFileStatus());
}
}
@@ -1713,4 +1784,7 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithApexVersions) {
// - Dex is stripped, don't have odex.
// - Oat file corrupted after status check, before reload unexecutable
// because it's unrelocated and no dex2oat
+
+INSTANTIATE_TEST_SUITE_P(WithOrWithoutRuntime, OatFileAssistantTest, testing::Values(true, false));
+
} // namespace art