Skip to content

Commit

Permalink
Don't spin up the ART runtime in art_standalone_dex2oat_cts_tests.
Browse files Browse the repository at this point in the history
It was mistakenly based on CommonRuntimeTest, which starts a runtime
through unstable APIs. The test should only run dex2oat with minimal
arguments to make --force-palette-compilation-hooks work.

Some refactoring in Dex2oatEnvironmentTest and CommonArtTest to
separate out the scratch directory creation code.

Test: atest Dex2oatCtsTest
  Check with temporary logging in
  system/libartpalette/palette_android_partner.cc that
  PaletteNotify(Start|End)Dex2oatCompilation still gets called.
Bug: 253937792
Change-Id: Ieaea0faeef9571c0a269d565acd105d0f74f3d13
  • Loading branch information
marstj committed Oct 28, 2022
1 parent 1316d3a commit 2847729
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 37 deletions.
45 changes: 44 additions & 1 deletion dex2oat/dex2oat_cts_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string>& dex2oat_args,
std::string* output,
std::string* error_msg) {
// This command line should work regardless of bitness, ISA, etc.
std::vector<std::string> 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.
Expand Down
4 changes: 2 additions & 2 deletions libartbase/base/common_art_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string> GetLibCoreModuleNames() const;

Expand Down Expand Up @@ -238,8 +240,6 @@ class CommonArtTestImpl {

std::unique_ptr<const DexFile> LoadExpectSingleDexFile(const char* location);

void ClearDirectory(const char* dirpath, bool recursive = true);

// Open a file (allows reading of framework jars).
std::vector<std::unique_ptr<const DexFile>> OpenDexFiles(const char* filename);

Expand Down
74 changes: 40 additions & 34 deletions runtime/dex2oat_environment_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<const char[]> android_data_real(realpath(android_data_.c_str(), nullptr));
UniqueCPtr<const char[]> 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";
Expand All @@ -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<uint32_t> checksums;
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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<std::string>& dex2oat_args,
std::string* output,
std::string* error_msg) {
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 2847729

Please sign in to comment.