summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author David Srbecky <dsrbecky@google.com> 2020-02-05 16:25:36 +0000
committer David Srbecky <dsrbecky@google.com> 2020-02-07 00:34:58 +0000
commitcf0c6ef642517fba3bc9a211acaed742ff39b86d (patch)
tree045be891d40e7671edf55444d84bb371d1347c04
parent7c2f69e42e5347820ada07c88de5a79f355c61be (diff)
Device gtests: Use boot.art instead of core.art.
They are essentially the same. We can use boot.art to run gtests since it is already part of the apex, including the jar files. This will make it easier to run the tests in atest, since we will not have to worry about copying core.art to the device. The long-term goal is to avoid generating core.art altogether. Couple of tests also require "alternate" image which has no compiled code. The tests now generate it on-demand in code. The host gtests still use core.art for now (as there is no boot.art on host). The plan is to add it in future CLs. Test: m test-art-host-gtest Test: ./art/tools/run-gtests.sh Bug: 147817606 Change-Id: I3a750bb8e60eea0b4a7df1491285feffd5a0161c
-rw-r--r--dex2oat/dex2oat_image_test.cc111
-rw-r--r--dexlayout/dexdiag_test.cc2
-rw-r--r--libartbase/base/common_art_test.cc40
-rw-r--r--libartbase/base/common_art_test.h16
-rw-r--r--runtime/common_runtime_test.cc90
-rw-r--r--runtime/common_runtime_test.h18
-rw-r--r--runtime/dex2oat_environment_test.h7
-rw-r--r--runtime/dexopt_test.cc27
-rw-r--r--runtime/dexopt_test.h2
-rwxr-xr-xtools/buildbot-sync.sh1
10 files changed, 194 insertions, 120 deletions
diff --git a/dex2oat/dex2oat_image_test.cc b/dex2oat/dex2oat_image_test.cc
index 9f0ea33b8b..9fd632f0c2 100644
--- a/dex2oat/dex2oat_image_test.cc
+++ b/dex2oat/dex2oat_image_test.cc
@@ -164,21 +164,17 @@ class Dex2oatImageTest : public CommonRuntimeTest {
ImageSizes CompileImageAndGetSizes(ArrayRef<const std::string> dex_files,
const std::vector<std::string>& extra_args) {
ImageSizes ret;
- ScratchFile scratch;
- std::string scratch_dir = scratch.GetFilename();
- while (!scratch_dir.empty() && scratch_dir.back() != '/') {
- scratch_dir.pop_back();
- }
- CHECK(!scratch_dir.empty()) << "No directory " << scratch.GetFilename();
+ ScratchDir scratch;
+ std::string filename_prefix = scratch.GetPath() + "boot";
std::vector<std::string> local_extra_args = extra_args;
local_extra_args.push_back(android::base::StringPrintf("--base=0x%08x", kBaseAddress));
std::string error_msg;
- if (!CompileBootImage(local_extra_args, scratch.GetFilename(), dex_files, &error_msg)) {
- LOG(ERROR) << "Failed to compile image " << scratch.GetFilename() << error_msg;
+ if (!CompileBootImage(local_extra_args, filename_prefix, dex_files, &error_msg)) {
+ LOG(ERROR) << "Failed to compile image " << filename_prefix << error_msg;
}
- std::string art_file = scratch.GetFilename() + ".art";
- std::string oat_file = scratch.GetFilename() + ".oat";
- std::string vdex_file = scratch.GetFilename() + ".vdex";
+ std::string art_file = filename_prefix + ".art";
+ std::string oat_file = filename_prefix + ".oat";
+ std::string vdex_file = filename_prefix + ".vdex";
int64_t art_size = OS::GetFileSizeBytes(art_file.c_str());
int64_t oat_size = OS::GetFileSizeBytes(oat_file.c_str());
int64_t vdex_size = OS::GetFileSizeBytes(vdex_file.c_str());
@@ -188,88 +184,9 @@ class Dex2oatImageTest : public CommonRuntimeTest {
ret.art_size = art_size;
ret.oat_size = oat_size;
ret.vdex_size = vdex_size;
- scratch.Close();
- // Clear image files since we compile the image multiple times and don't want to leave any
- // artifacts behind.
- ClearDirectory(scratch_dir.c_str(), /*recursive=*/ false);
return ret;
}
- bool CompileBootImage(const std::vector<std::string>& extra_args,
- const std::string& image_file_name_prefix,
- ArrayRef<const std::string> dex_files,
- std::string* error_msg,
- const std::string& use_fd_prefix = "") {
- Runtime* const runtime = Runtime::Current();
- std::vector<std::string> argv;
- argv.push_back(runtime->GetCompilerExecutable());
- AddRuntimeArg(argv, "-Xms64m");
- AddRuntimeArg(argv, "-Xmx64m");
- for (const std::string& dex_file : dex_files) {
- argv.push_back("--dex-file=" + dex_file);
- argv.push_back("--dex-location=" + dex_file);
- }
- if (runtime->IsJavaDebuggable()) {
- argv.push_back("--debuggable");
- }
- runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
-
- AddRuntimeArg(argv, "-Xverify:softfail");
-
- if (!kIsTargetBuild) {
- argv.push_back("--host");
- }
-
- std::unique_ptr<File> art_file;
- std::unique_ptr<File> vdex_file;
- std::unique_ptr<File> oat_file;
- if (!use_fd_prefix.empty()) {
- art_file.reset(OS::CreateEmptyFile((use_fd_prefix + ".art").c_str()));
- vdex_file.reset(OS::CreateEmptyFile((use_fd_prefix + ".vdex").c_str()));
- oat_file.reset(OS::CreateEmptyFile((use_fd_prefix + ".oat").c_str()));
- argv.push_back("--image-fd=" + std::to_string(art_file->Fd()));
- argv.push_back("--output-vdex-fd=" + std::to_string(vdex_file->Fd()));
- argv.push_back("--oat-fd=" + std::to_string(oat_file->Fd()));
- argv.push_back("--oat-location=" + image_file_name_prefix + ".oat");
- } else {
- argv.push_back("--image=" + image_file_name_prefix + ".art");
- argv.push_back("--oat-file=" + image_file_name_prefix + ".oat");
- argv.push_back("--oat-location=" + image_file_name_prefix + ".oat");
- }
-
- std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
- argv.insert(argv.end(), compiler_options.begin(), compiler_options.end());
-
- // We must set --android-root.
- const char* android_root = getenv("ANDROID_ROOT");
- CHECK(android_root != nullptr);
- argv.push_back("--android-root=" + std::string(android_root));
- argv.insert(argv.end(), extra_args.begin(), extra_args.end());
-
- bool result = RunDex2Oat(argv, error_msg);
- if (art_file != nullptr) {
- CHECK_EQ(0, art_file->FlushClose());
- }
- if (vdex_file != nullptr) {
- CHECK_EQ(0, vdex_file->FlushClose());
- }
- if (oat_file != nullptr) {
- CHECK_EQ(0, oat_file->FlushClose());
- }
- return result;
- }
-
- bool RunDex2Oat(const std::vector<std::string>& args, std::string* error_msg) {
- // We only want fatal logging for the error message.
- auto post_fork_fn = []() { return setenv("ANDROID_LOG_TAGS", "*:f", 1) == 0; };
- ForkAndExecResult res = ForkAndExec(args, post_fork_fn, error_msg);
- if (res.stage != ForkAndExecResult::kFinished) {
- *error_msg = strerror(errno);
- return false;
- }
- return res.StandardSuccess();
- }
-
MemMap ReserveCoreImageAddressSpace(/*out*/std::string* error_msg) {
constexpr size_t kReservationSize = 256 * MB; // This should be enough for the compiled images.
// Extend to both directions for maximum relocation difference.
@@ -293,6 +210,7 @@ class Dex2oatImageTest : public CommonRuntimeTest {
CHECK(EndsWith(dir, "/"));
for (std::string& dex_file : *dex_files) {
size_t slash_pos = dex_file.rfind('/');
+ CHECK(OS::FileExists(dex_file.c_str())) << dex_file;
CHECK_NE(std::string::npos, slash_pos);
std::string new_location = dir + dex_file.substr(slash_pos + 1u);
std::ifstream src_stream(dex_file, std::ios::binary);
@@ -415,13 +333,10 @@ TEST_F(Dex2oatImageTest, TestExtension) {
MemMap reservation = ReserveCoreImageAddressSpace(&error_msg);
ASSERT_TRUE(reservation.IsValid()) << error_msg;
- ScratchFile scratch;
- std::string scratch_dir = scratch.GetFilename() + "-d";
- int mkdir_result = mkdir(scratch_dir.c_str(), 0700);
- ASSERT_EQ(0, mkdir_result);
- scratch_dir += '/';
+ ScratchDir scratch;
+ const std::string& scratch_dir = scratch.GetPath();
std::string image_dir = scratch_dir + GetInstructionSetString(kRuntimeISA);
- mkdir_result = mkdir(image_dir.c_str(), 0700);
+ int mkdir_result = mkdir(image_dir.c_str(), 0700);
ASSERT_EQ(0, mkdir_result);
std::string filename_prefix = image_dir + "/core";
@@ -824,10 +739,6 @@ TEST_F(Dex2oatImageTest, TestExtension) {
DisableImageDex2Oat();
}
-
- ClearDirectory(scratch_dir.c_str());
- int rmdir_result = rmdir(scratch_dir.c_str());
- ASSERT_EQ(0, rmdir_result);
}
} // namespace art
diff --git a/dexlayout/dexdiag_test.cc b/dexlayout/dexdiag_test.cc
index 9cf0f07820..27ac402120 100644
--- a/dexlayout/dexdiag_test.cc
+++ b/dexlayout/dexdiag_test.cc
@@ -25,7 +25,7 @@
namespace art {
-static const char* kDexDiagContains = "--contains=core.vdex";
+static const char* kDexDiagContains = "--contains=boot.vdex";
static const char* kDexDiagContainsFails = "--contains=anything_other_than_core.vdex";
static const char* kDexDiagHelp = "--help";
static const char* kDexDiagVerbose = "--verbose";
diff --git a/libartbase/base/common_art_test.cc b/libartbase/base/common_art_test.cc
index 7101ca479b..978f69ca26 100644
--- a/libartbase/base/common_art_test.cc
+++ b/libartbase/base/common_art_test.cc
@@ -19,6 +19,7 @@
#include <dirent.h>
#include <dlfcn.h>
#include <fcntl.h>
+#include <ftw.h>
#include <stdlib.h>
#include <unistd.h>
#include <cstdio>
@@ -51,6 +52,29 @@ namespace art {
using android::base::StringPrintf;
+ScratchDir::ScratchDir() {
+ // ANDROID_DATA needs to be set
+ CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
+ "Are you subclassing RuntimeTest?";
+ path_ = getenv("ANDROID_DATA");
+ path_ += "/tmp-XXXXXX";
+ bool ok = (mkdtemp(&path_[0]) != nullptr);
+ CHECK(ok) << strerror(errno) << " for " << path_;
+ path_ += "/";
+}
+
+ScratchDir::~ScratchDir() {
+ // Recursively delete the directory and all its content.
+ nftw(path_.c_str(), [](const char* name, const struct stat*, int type, struct FTW *) {
+ if (type == FTW_F) {
+ unlink(name);
+ } else if (type == FTW_DP) {
+ rmdir(name);
+ }
+ return 0;
+ }, 256 /* max open file descriptors */, FTW_DEPTH);
+}
+
ScratchFile::ScratchFile() {
// ANDROID_DATA needs to be set
CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
@@ -364,13 +388,13 @@ void CommonArtTestImpl::TearDown() {
}
static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
- std::string path = GetAndroidRoot();
-
- std::string suffix = host
- ? "-hostdex" // The host version.
- : "-testdex"; // The unstripped target version.
-
- return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
+ if (host) {
+ std::string path = GetAndroidRoot();
+ return StringPrintf("%s/framework/%s-hostdex.jar", path.c_str(), jar_prefix.c_str());
+ } else {
+ const char* apex = (jar_prefix == "conscrypt") ? "com.android.conscrypt" : "com.android.art";
+ return StringPrintf("/apex/%s/javalib/%s.jar", apex, jar_prefix.c_str());
+ }
}
std::vector<std::string> CommonArtTestImpl::GetLibCoreModuleNames() const {
@@ -504,7 +528,7 @@ std::string CommonArtTestImpl::GetCoreFileLocation(const char* suffix) {
std::string host_dir = GetAndroidRoot();
location = StringPrintf("%s/framework/core.%s", host_dir.c_str(), suffix);
} else {
- location = StringPrintf("/data/art-test/core.%s", suffix);
+ location = StringPrintf("/apex/com.android.art/javalib/boot.%s", suffix);
}
return location;
diff --git a/libartbase/base/common_art_test.h b/libartbase/base/common_art_test.h
index 41af711019..8d2693f784 100644
--- a/libartbase/base/common_art_test.h
+++ b/libartbase/base/common_art_test.h
@@ -42,6 +42,22 @@ using ScopedLogSeverity = android::base::ScopedLogSeverity;
class DexFile;
+class ScratchDir {
+ public:
+ ScratchDir();
+
+ ~ScratchDir();
+
+ const std::string& GetPath() const {
+ return path_;
+ }
+
+ private:
+ std::string path_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScratchDir);
+};
+
class ScratchFile {
public:
ScratchFile();
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 135dc7be73..64d2503801 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -433,22 +433,106 @@ bool CommonRuntimeTestImpl::StartDex2OatCommandLine(/*out*/std::vector<std::stri
return true;
}
+bool CommonRuntimeTestImpl::CompileBootImage(const std::vector<std::string>& extra_args,
+ const std::string& image_file_name_prefix,
+ ArrayRef<const std::string> dex_files,
+ ArrayRef<const std::string> dex_locations,
+ std::string* error_msg,
+ const std::string& use_fd_prefix) {
+ Runtime* const runtime = Runtime::Current();
+ std::vector<std::string> argv {
+ runtime->GetCompilerExecutable(),
+ "--runtime-arg",
+ "-Xms64m",
+ "--runtime-arg",
+ "-Xmx64m",
+ "--runtime-arg",
+ "-Xverify:softfail",
+ };
+ CHECK_EQ(dex_files.size(), dex_locations.size());
+ for (const std::string& dex_file : dex_files) {
+ argv.push_back("--dex-file=" + dex_file);
+ }
+ for (const std::string& dex_location : dex_locations) {
+ argv.push_back("--dex-location=" + dex_location);
+ }
+ if (runtime->IsJavaDebuggable()) {
+ argv.push_back("--debuggable");
+ }
+ runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
+
+ if (!kIsTargetBuild) {
+ argv.push_back("--host");
+ }
+
+ std::unique_ptr<File> art_file;
+ std::unique_ptr<File> vdex_file;
+ std::unique_ptr<File> oat_file;
+ if (!use_fd_prefix.empty()) {
+ art_file.reset(OS::CreateEmptyFile((use_fd_prefix + ".art").c_str()));
+ vdex_file.reset(OS::CreateEmptyFile((use_fd_prefix + ".vdex").c_str()));
+ oat_file.reset(OS::CreateEmptyFile((use_fd_prefix + ".oat").c_str()));
+ argv.push_back("--image-fd=" + std::to_string(art_file->Fd()));
+ argv.push_back("--output-vdex-fd=" + std::to_string(vdex_file->Fd()));
+ argv.push_back("--oat-fd=" + std::to_string(oat_file->Fd()));
+ argv.push_back("--oat-location=" + image_file_name_prefix + ".oat");
+ } else {
+ argv.push_back("--image=" + image_file_name_prefix + ".art");
+ argv.push_back("--oat-file=" + image_file_name_prefix + ".oat");
+ argv.push_back("--oat-location=" + image_file_name_prefix + ".oat");
+ }
+
+ std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
+ argv.insert(argv.end(), compiler_options.begin(), compiler_options.end());
+
+ // We must set --android-root.
+ const char* android_root = getenv("ANDROID_ROOT");
+ CHECK(android_root != nullptr);
+ argv.push_back("--android-root=" + std::string(android_root));
+ argv.insert(argv.end(), extra_args.begin(), extra_args.end());
+
+ bool result = RunDex2Oat(argv, error_msg);
+ if (art_file != nullptr) {
+ CHECK_EQ(0, art_file->FlushClose());
+ }
+ if (vdex_file != nullptr) {
+ CHECK_EQ(0, vdex_file->FlushClose());
+ }
+ if (oat_file != nullptr) {
+ CHECK_EQ(0, oat_file->FlushClose());
+ }
+ return result;
+}
+
+bool CommonRuntimeTestImpl::RunDex2Oat(const std::vector<std::string>& args,
+ std::string* error_msg) {
+ // We only want fatal logging for the error message.
+ auto post_fork_fn = []() { return setenv("ANDROID_LOG_TAGS", "*:f", 1) == 0; };
+ ForkAndExecResult res = ForkAndExec(args, post_fork_fn, error_msg);
+ if (res.stage != ForkAndExecResult::kFinished) {
+ *error_msg = strerror(errno);
+ return false;
+ }
+ return res.StandardSuccess();
+}
+
std::string CommonRuntimeTestImpl::GetImageDirectory() {
if (IsHost()) {
const char* host_dir = getenv("ANDROID_HOST_OUT");
CHECK(host_dir != nullptr);
return std::string(host_dir) + "/framework";
} else {
- return std::string("/data/art-test");
+ return std::string("/apex/com.android.art/javalib");
}
}
std::string CommonRuntimeTestImpl::GetImageLocation() {
- return GetImageDirectory() + "/core.art";
+ return GetImageDirectory() + (IsHost() ? "/core.art" : "/boot.art");
}
std::string CommonRuntimeTestImpl::GetSystemImageFile() {
- return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA) + "/core.art";
+ std::string isa = GetInstructionSetString(kRuntimeISA);
+ return GetImageDirectory() + "/" + isa + (IsHost() ? "/core.art" : "/boot.art");
}
void CommonRuntimeTestImpl::EnterTransactionMode() {
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index c87d317a81..2e9e078be9 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -113,6 +113,24 @@ class CommonRuntimeTestImpl : public CommonArtTestImpl {
bool StartDex2OatCommandLine(/*out*/std::vector<std::string>* argv,
/*out*/std::string* error_msg);
+ bool CompileBootImage(const std::vector<std::string>& extra_args,
+ const std::string& image_file_name_prefix,
+ ArrayRef<const std::string> dex_files,
+ ArrayRef<const std::string> dex_locations,
+ std::string* error_msg,
+ const std::string& use_fd_prefix = "");
+
+ bool CompileBootImage(const std::vector<std::string>& extra_args,
+ const std::string& image_file_name_prefix,
+ ArrayRef<const std::string> dex_files,
+ std::string* error_msg,
+ const std::string& use_fd_prefix = "") {
+ return CompileBootImage(
+ extra_args, image_file_name_prefix, dex_files, dex_files, error_msg, use_fd_prefix);
+ }
+
+ bool RunDex2Oat(const std::vector<std::string>& args, std::string* error_msg);
+
protected:
// Allow subclases such as CommonCompilerTest to add extra options.
virtual void SetUpRuntimeOptions(RuntimeOptions* options ATTRIBUTE_UNUSED) {}
diff --git a/runtime/dex2oat_environment_test.h b/runtime/dex2oat_environment_test.h
index 0d74dbb936..fb8a760862 100644
--- a/runtime/dex2oat_environment_test.h
+++ b/runtime/dex2oat_environment_test.h
@@ -137,13 +137,6 @@ class Dex2oatEnvironmentTest : public CommonRuntimeTest {
dst_stream << src_stream.rdbuf();
}
- // 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-interpreter.art";
- }
-
std::string GetDexSrc1() const {
return GetTestDexFileName("Main");
}
diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc
index afbd053e95..8ba6f3ec1d 100644
--- a/runtime/dexopt_test.cc
+++ b/runtime/dexopt_test.cc
@@ -69,6 +69,28 @@ bool DexoptTest::Dex2Oat(const std::vector<std::string>& args, std::string* erro
return Exec(argv, error_msg);
}
+std::string DexoptTest::GenerateAlternateImage(const std::string& scratch_dir) {
+ std::vector<std::string> libcore_dex_files = GetLibCoreDexFileNames();
+ std::vector<std::string> libcore_dex_locations = GetLibCoreDexLocations();
+
+ std::string image_dir = scratch_dir + GetInstructionSetString(kRuntimeISA);
+ int mkdir_result = mkdir(image_dir.c_str(), 0700);
+ CHECK_EQ(0, mkdir_result) << image_dir.c_str();
+
+ std::vector<std::string> extra_args {
+ "--compiler-filter=verify",
+ android::base::StringPrintf("--base=0x%08x", ART_BASE_ADDRESS),
+ };
+ std::string filename_prefix = image_dir + "/boot-interpreter";
+ ArrayRef<const std::string> dex_files(libcore_dex_files);
+ ArrayRef<const std::string> dex_locations(libcore_dex_locations);
+ std::string error_msg;
+ bool ok = CompileBootImage(extra_args, filename_prefix, dex_files, dex_locations, &error_msg);
+ EXPECT_TRUE(ok) << error_msg;
+
+ return scratch_dir + "boot-interpreter.art";
+}
+
void DexoptTest::GenerateOatForTest(const std::string& dex_location,
const std::string& oat_location,
CompilerFilter::Filter filter,
@@ -92,8 +114,11 @@ void DexoptTest::GenerateOatForTest(const std::string& dex_location,
}
std::string image_location = GetImageLocation();
+ std::optional<ScratchDir> scratch;
if (with_alternate_image) {
- args.push_back("--boot-image=" + GetImageLocation2());
+ scratch.emplace(); // Create the scratch directory for the generated boot image.
+ std::string alternate_image_location = GenerateAlternateImage(scratch->GetPath());
+ args.push_back("--boot-image=" + alternate_image_location);
}
if (compilation_reason != nullptr) {
diff --git a/runtime/dexopt_test.h b/runtime/dexopt_test.h
index bfae8a180d..a2363939ea 100644
--- a/runtime/dexopt_test.h
+++ b/runtime/dexopt_test.h
@@ -32,6 +32,8 @@ class DexoptTest : public Dex2oatEnvironmentTest {
void PostRuntimeCreate() override;
+ std::string GenerateAlternateImage(const std::string& scratch_dir);
+
// Generate an oat file for the purposes of test.
// The oat file will be generated for dex_location in the given oat_location
// with the following configuration:
diff --git a/tools/buildbot-sync.sh b/tools/buildbot-sync.sh
index 705d88aec2..4c718ee765 100755
--- a/tools/buildbot-sync.sh
+++ b/tools/buildbot-sync.sh
@@ -173,6 +173,7 @@ activate_apex com.android.art.testing com.android.art
activate_apex com.android.i18n
activate_apex com.android.runtime
activate_apex com.android.tzdata
+activate_apex com.android.conscrypt
# Adjust the linker configuration file (if needed).
#