diff --git a/dex2oat/dex2oat_cts_test.cc b/dex2oat/dex2oat_cts_test.cc index 41c7015090..254126446d 100644 --- a/dex2oat/dex2oat_cts_test.cc +++ b/dex2oat/dex2oat_cts_test.cc @@ -14,11 +14,54 @@ * limitations under the License. */ +#include "base/file_utils.h" #include "dex2oat_environment_test.h" namespace art { -class Dex2oatCtsTest : public Dex2oatEnvironmentTest {}; +class Dex2oatCtsTest : public CommonArtTest, public Dex2oatScratchDirs { + public: + void SetUp() override { + CommonArtTest::SetUp(); + Dex2oatScratchDirs::SetUp(android_data_); + } + + void TearDown() override { + Dex2oatScratchDirs::TearDown(); + CommonArtTest::TearDown(); + } + + protected: + // Stripped down counterpart to Dex2oatEnvironmentTest::Dex2Oat that only adds + // enough arguments for our purposes. + int Dex2Oat(const std::vector& dex2oat_args, + std::string* output, + std::string* error_msg) { + // This command line should work regardless of bitness, ISA, etc. + std::vector argv = {std::string(kAndroidArtApexDefaultPath) + "/bin/dex2oat"}; + argv.insert(argv.end(), dex2oat_args.begin(), dex2oat_args.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)); + + // We need dex2oat to actually log things. + auto post_fork_fn = []() { return setenv("ANDROID_LOG_TAGS", "*:d", 1) == 0; }; + ForkAndExecResult res = ForkAndExec(argv, post_fork_fn, output); + if (res.stage != ForkAndExecResult::kFinished) { + *error_msg = strerror(errno); + ::testing::AssertionFailure() << "Failed to finish dex2oat invocation: " << *error_msg; + } + + if (!res.StandardSuccess()) { + // We cannot use ASSERT_TRUE since the method returns an int and not void. + ::testing::AssertionFailure() << "dex2oat fork/exec failed: " << *error_msg; + } + + return res.status_code; + } +}; // Run dex2oat with --enable-palette-compilation-hooks to force calls to // PaletteNotify{Start,End}Dex2oatCompilation. diff --git a/libartbase/base/common_art_test.h b/libartbase/base/common_art_test.h index fccb217143..f4935ccf4e 100644 --- a/libartbase/base/common_art_test.h +++ b/libartbase/base/common_art_test.h @@ -146,6 +146,8 @@ class CommonArtTestImpl { static void TearDownAndroidDataDir(const std::string& android_data, bool fail_on_error); + static void ClearDirectory(const char* dirpath, bool recursive = true); + // Get the names of the libcore modules. virtual std::vector GetLibCoreModuleNames() const; @@ -238,8 +240,6 @@ class CommonArtTestImpl { std::unique_ptr LoadExpectSingleDexFile(const char* location); - void ClearDirectory(const char* dirpath, bool recursive = true); - // Open a file (allows reading of framework jars). std::vector> OpenDexFiles(const char* filename); diff --git a/runtime/dex2oat_environment_test.h b/runtime/dex2oat_environment_test.h index 166464f28d..9ebc68dd21 100644 --- a/runtime/dex2oat_environment_test.h +++ b/runtime/dex2oat_environment_test.h @@ -41,21 +41,17 @@ namespace art { static constexpr bool kDebugArgs = false; -// Test class that provides some helpers to set a test up for compilation using dex2oat. -class Dex2oatEnvironmentTest : public CommonRuntimeTest { +class Dex2oatScratchDirs { public: - void SetUp() override { - CommonRuntimeTest::SetUp(); - const ArtDexFileLoader dex_file_loader; - + void SetUp(const std::string& android_data) { // Create a scratch directory to work from. // Get the realpath of the android data. The oat dir should always point to real location // when generating oat files in dalvik-cache. This avoids complicating the unit tests // when matching the expected paths. - UniqueCPtr android_data_real(realpath(android_data_.c_str(), nullptr)); + UniqueCPtr android_data_real(realpath(android_data.c_str(), nullptr)); ASSERT_TRUE(android_data_real != nullptr) - << "Could not get the realpath of the android data" << android_data_ << strerror(errno); + << "Could not get the realpath of the android data" << android_data << strerror(errno); scratch_dir_.assign(android_data_real.get()); scratch_dir_ += "/Dex2oatEnvironmentTest"; @@ -67,6 +63,41 @@ class Dex2oatEnvironmentTest : public CommonRuntimeTest { odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA)); ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700)); + } + + void TearDown() { + CommonArtTest::ClearDirectory(odex_dir_.c_str()); + ASSERT_EQ(0, rmdir(odex_dir_.c_str())); + + CommonArtTest::ClearDirectory(odex_oat_dir_.c_str()); + ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str())); + + CommonArtTest::ClearDirectory(scratch_dir_.c_str()); + ASSERT_EQ(0, rmdir(scratch_dir_.c_str())); + } + + // Scratch directory, for dex and odex files (oat files will go in the + // dalvik cache). + const std::string& GetScratchDir() const { return scratch_dir_; } + + // Odex directory is the subdirectory in the scratch directory where odex + // files should be located. + const std::string& GetOdexDir() const { return odex_dir_; } + + private: + std::string scratch_dir_; + std::string odex_oat_dir_; + std::string odex_dir_; +}; + +// Test class that provides some helpers to set a test up for compilation using dex2oat. +class Dex2oatEnvironmentTest : public Dex2oatScratchDirs, public CommonRuntimeTest { + public: + void SetUp() override { + CommonRuntimeTest::SetUp(); + Dex2oatScratchDirs::SetUp(android_data_); + + const ArtDexFileLoader dex_file_loader; // Verify the environment is as we expect std::vector checksums; @@ -122,15 +153,7 @@ class Dex2oatEnvironmentTest : public CommonRuntimeTest { } void TearDown() override { - ClearDirectory(odex_dir_.c_str()); - ASSERT_EQ(0, rmdir(odex_dir_.c_str())); - - ClearDirectory(odex_oat_dir_.c_str()); - ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str())); - - ClearDirectory(scratch_dir_.c_str()); - ASSERT_EQ(0, rmdir(scratch_dir_.c_str())); - + Dex2oatScratchDirs::TearDown(); CommonRuntimeTest::TearDown(); } @@ -165,18 +188,6 @@ class Dex2oatEnvironmentTest : public CommonRuntimeTest { return GetTestDexFileName("Nested"); } - // Scratch directory, for dex and odex files (oat files will go in the - // dalvik cache). - const std::string& GetScratchDir() const { - return scratch_dir_; - } - - // Odex directory is the subdirectory in the scratch directory where odex - // files should be located. - const std::string& GetOdexDir() const { - return odex_dir_; - } - int Dex2Oat(const std::vector& dex2oat_args, std::string* output, std::string* error_msg) { @@ -249,11 +260,6 @@ class Dex2oatEnvironmentTest : public CommonRuntimeTest { fflush(file); fclose(file); } - - private: - std::string scratch_dir_; - std::string odex_oat_dir_; - std::string odex_dir_; }; } // namespace art