summaryrefslogtreecommitdiff
path: root/artd/artd_test.cc
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2025-03-21 03:40:36 -0700
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2025-03-21 03:40:36 -0700
commita7652079683fc97ef40b793312c39a613523262c (patch)
tree55ac1df9ea1d449630016889fbf480dfb528777c /artd/artd_test.cc
parent09ac8285d7ad56b01982c02fdcc81741a3697ade (diff)
parentaa405ccd29b7317dfe499fa63cc9fdaef2f049fb (diff)
Add an artd method to create an SDC file. am: aa405ccd29
Original change: https://android-review.googlesource.com/c/platform/art/+/3540979 Change-Id: I37d556aa308550170f8cf8ec8a0e8ccd2b99944e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'artd/artd_test.cc')
-rw-r--r--artd/artd_test.cc150
1 files changed, 116 insertions, 34 deletions
diff --git a/artd/artd_test.cc b/artd/artd_test.cc
index 76167c58fb..10116c7994 100644
--- a/artd/artd_test.cc
+++ b/artd/artd_test.cc
@@ -43,6 +43,7 @@
#include "aidl/com/android/server/art/ArtConstants.h"
#include "aidl/com/android/server/art/BnArtd.h"
+#include "aidl/com/android/server/art/OutputArtifacts.h"
#include "android-base/collections.h"
#include "android-base/errors.h"
#include "android-base/file.h"
@@ -58,6 +59,7 @@
#include "base/common_art_test.h"
#include "base/macros.h"
#include "base/pidfd.h"
+#include "base/time_utils.h"
#include "exec_utils.h"
#include "file_utils.h"
#include "gmock/gmock.h"
@@ -94,6 +96,7 @@ using ::aidl::com::android::server::art::OutputProfile;
using ::aidl::com::android::server::art::PriorityClass;
using ::aidl::com::android::server::art::ProfilePath;
using ::aidl::com::android::server::art::RuntimeArtifactsPath;
+using ::aidl::com::android::server::art::SecureDexMetadataWithCompanionPaths;
using ::aidl::com::android::server::art::VdexPath;
using ::android::base::Append;
using ::android::base::Dirname;
@@ -130,10 +133,12 @@ using ::testing::Property;
using ::testing::ResultOf;
using ::testing::Return;
using ::testing::SetArgPointee;
+using ::testing::StartsWith;
using ::testing::StrEq;
using ::testing::UnorderedElementsAreArray;
using ::testing::WithArg;
+using PermissionSettings = OutputArtifacts::PermissionSettings;
using PrimaryCurProfilePath = ProfilePath::PrimaryCurProfilePath;
using PrimaryRefProfilePath = ProfilePath::PrimaryRefProfilePath;
using TmpProfilePath = ProfilePath::TmpProfilePath;
@@ -153,10 +158,10 @@ ScopeGuard<std::function<void()>> ScopedSetLogger(android::base::LogFunction&& l
});
}
-void CheckContent(const std::string& path, const std::string& expected_content) {
+void CheckContent(const std::string& path, const Matcher<std::string>& expected_content_matcher) {
std::string actual_content;
ASSERT_TRUE(ReadFileToString(path, &actual_content));
- EXPECT_EQ(actual_content, expected_content);
+ EXPECT_THAT(actual_content, expected_content_matcher);
}
void CheckOtherReadable(const std::string& path, bool expected_value) {
@@ -384,24 +389,24 @@ class ArtdTest : public CommonArtTest {
};
struct stat st;
ASSERT_EQ(stat(scratch_path_.c_str(), &st), 0);
+ permission_settings_ = {
+ .dirFsPermission =
+ FsPermission{
+ .uid = static_cast<int32_t>(st.st_uid),
+ .gid = static_cast<int32_t>(st.st_gid),
+ .isOtherReadable = true,
+ .isOtherExecutable = true,
+ },
+ .fileFsPermission =
+ FsPermission{
+ .uid = static_cast<int32_t>(st.st_uid),
+ .gid = static_cast<int32_t>(st.st_gid),
+ .isOtherReadable = true,
+ },
+ };
output_artifacts_ = OutputArtifacts{
.artifactsPath = artifacts_path_,
- .permissionSettings =
- OutputArtifacts::PermissionSettings{
- .dirFsPermission =
- FsPermission{
- .uid = static_cast<int32_t>(st.st_uid),
- .gid = static_cast<int32_t>(st.st_gid),
- .isOtherReadable = true,
- .isOtherExecutable = true,
- },
- .fileFsPermission =
- FsPermission{
- .uid = static_cast<int32_t>(st.st_uid),
- .gid = static_cast<int32_t>(st.st_gid),
- .isOtherReadable = true,
- },
- },
+ .permissionSettings = permission_settings_,
};
clc_1_ = GetTestDexFileName("Main");
clc_2_ = GetTestDexFileName("Nested");
@@ -417,6 +422,12 @@ class ArtdTest : public CommonArtTest {
dm_path_ = DexMetadataPath{.dexPath = dex_file_};
std::filesystem::create_directories(
std::filesystem::path(OR_FATAL(BuildFinalProfilePath(tmp_profile_path_))).parent_path());
+
+ sdm_sdc_paths_ = {
+ .dexPath = dex_file_,
+ .isa = isa_,
+ .isInDalvikCache = false,
+ };
}
void TearDown() override {
@@ -547,6 +558,7 @@ class ArtdTest : public CommonArtTest {
std::string dex_file_;
std::string isa_;
ArtifactsPath artifacts_path_;
+ PermissionSettings permission_settings_;
OutputArtifacts output_artifacts_;
std::string clc_1_;
std::string clc_2_;
@@ -561,6 +573,8 @@ class ArtdTest : public CommonArtTest {
bool dex_file_other_readable_ = true;
bool profile_other_readable_ = true;
+ SecureDexMetadataWithCompanionPaths sdm_sdc_paths_;
+
private:
void InitFilesBeforeDexopt() {
// Required files.
@@ -701,6 +715,79 @@ TEST_F(ArtdTest, deleteArtifactsFileIsDir) {
EXPECT_FALSE(std::filesystem::exists(oat_dir + "/b.art"));
}
+TEST_F(ArtdTest, maybeCreateSdc) {
+ // Unable to create OatFileAssistantContext on host to get APEX versions.
+ TEST_DISABLED_FOR_HOST();
+
+ std::string sdm_file = OR_FAIL(BuildSdmPath(sdm_sdc_paths_));
+ std::string sdc_file = OR_FAIL(BuildSdcPath(sdm_sdc_paths_));
+ CreateFile(sdm_file);
+
+ ASSERT_STATUS_OK(artd_->maybeCreateSdc(
+ {.sdcPath = sdm_sdc_paths_, .permissionSettings = permission_settings_}));
+
+ CheckContent(sdc_file, StartsWith("sdm-timestamp-ns="));
+}
+
+TEST_F(ArtdTest, maybeCreateSdcAlreadyCreated) {
+ // Unable to create OatFileAssistantContext on host to get APEX versions.
+ TEST_DISABLED_FOR_HOST();
+
+ std::string sdm_file = OR_FAIL(BuildSdmPath(sdm_sdc_paths_));
+ std::string sdc_file = OR_FAIL(BuildSdcPath(sdm_sdc_paths_));
+ CreateFile(sdm_file);
+
+ ASSERT_STATUS_OK(artd_->maybeCreateSdc(
+ {.sdcPath = sdm_sdc_paths_, .permissionSettings = permission_settings_}));
+
+ struct stat sdc_st;
+ ASSERT_EQ(stat(sdc_file.c_str(), &sdc_st), 0);
+
+ ASSERT_STATUS_OK(artd_->maybeCreateSdc(
+ {.sdcPath = sdm_sdc_paths_, .permissionSettings = permission_settings_}));
+
+ struct stat new_sdc_st;
+ ASSERT_EQ(stat(sdc_file.c_str(), &new_sdc_st), 0);
+
+ EXPECT_EQ(TimeSpecToNs(sdc_st.st_mtim), TimeSpecToNs(new_sdc_st.st_mtim));
+}
+
+TEST_F(ArtdTest, maybeCreateSdcOutdatedTimestamp) {
+ // Unable to create OatFileAssistantContext on host to get APEX versions.
+ TEST_DISABLED_FOR_HOST();
+
+ std::string sdm_file = OR_FAIL(BuildSdmPath(sdm_sdc_paths_));
+ std::string sdc_file = OR_FAIL(BuildSdcPath(sdm_sdc_paths_));
+ CreateFile(sdm_file);
+
+ ASSERT_STATUS_OK(artd_->maybeCreateSdc(
+ {.sdcPath = sdm_sdc_paths_, .permissionSettings = permission_settings_}));
+
+ struct stat sdc_st;
+ ASSERT_EQ(stat(sdc_file.c_str(), &sdc_st), 0);
+
+ // Simulate that the SDM file is updated.
+ CreateFile(sdm_file);
+
+ ASSERT_STATUS_OK(artd_->maybeCreateSdc(
+ {.sdcPath = sdm_sdc_paths_, .permissionSettings = permission_settings_}));
+
+ struct stat new_sdc_st;
+ ASSERT_EQ(stat(sdc_file.c_str(), &new_sdc_st), 0);
+
+ // The SDC file should be updated.
+ EXPECT_LT(TimeSpecToNs(sdc_st.st_mtim), TimeSpecToNs(new_sdc_st.st_mtim));
+}
+
+TEST_F(ArtdTest, maybeCreateSdcNoSdm) {
+ std::string sdc_file = OR_FAIL(BuildSdcPath(sdm_sdc_paths_));
+
+ ASSERT_STATUS_OK(artd_->maybeCreateSdc(
+ {.sdcPath = sdm_sdc_paths_, .permissionSettings = permission_settings_}));
+
+ EXPECT_FALSE(std::filesystem::exists(sdc_file));
+}
+
TEST_F(ArtdTest, dexopt) {
dexopt_options_.generateAppImage = true;
@@ -2413,6 +2500,8 @@ TEST_F(ArtdTest, deleteRuntimeArtifactsAndroidDataNotExist) {
EXPECT_EQ(aidl_return, 0);
}
+// Verifies that `deleteRuntimeArtifacts` doesn't treat "*" as a wildcard. It should either treat it
+// as a normal character in the path or reject it. The caller is never supposed to use a wildcard.
TEST_F(ArtdTest, deleteRuntimeArtifactsSpecialChars) {
std::vector<std::string> removed_files;
std::vector<std::string> kept_files;
@@ -2430,25 +2519,18 @@ TEST_F(ArtdTest, deleteRuntimeArtifactsSpecialChars) {
CreateKeptFile(android_data_ + "/user/0/com.android.foo/cache/oat_primary/arm64/base.art");
CreateRemovedFile(android_data_ + "/user/0/*/cache/oat_primary/arm64/base.art");
- CreateRemovedFile(android_data_ + "/user/0/com.android.foo/cache/oat_primary/*/base.art");
CreateRemovedFile(android_data_ + "/user/0/com.android.foo/cache/oat_primary/arm64/*.art");
int64_t aidl_return;
- ASSERT_TRUE(
- artd_
- ->deleteRuntimeArtifacts({.packageName = "*", .dexPath = "/a/b/base.apk", .isa = "arm64"},
- &aidl_return)
- .isOk());
- ASSERT_TRUE(artd_
- ->deleteRuntimeArtifacts(
- {.packageName = "com.android.foo", .dexPath = "/a/b/*.apk", .isa = "arm64"},
- &aidl_return)
- .isOk());
- ASSERT_TRUE(artd_
- ->deleteRuntimeArtifacts(
- {.packageName = "com.android.foo", .dexPath = "/a/b/base.apk", .isa = "*"},
- &aidl_return)
- .isOk());
+ ASSERT_STATUS_OK(artd_->deleteRuntimeArtifacts(
+ {.packageName = "*", .dexPath = "/a/b/base.apk", .isa = "arm64"}, &aidl_return));
+ ASSERT_STATUS_OK(artd_->deleteRuntimeArtifacts(
+ {.packageName = "com.android.foo", .dexPath = "/a/b/*.apk", .isa = "arm64"}, &aidl_return));
+ ASSERT_FALSE(artd_
+ ->deleteRuntimeArtifacts(
+ {.packageName = "com.android.foo", .dexPath = "/a/b/base.apk", .isa = "*"},
+ &aidl_return)
+ .isOk());
for (const std::string& path : removed_files) {
EXPECT_FALSE(std::filesystem::exists(path)) << ART_FORMAT("'{}' should be removed", path);