summaryrefslogtreecommitdiff
path: root/apexd/apexd_utils_test.cpp
diff options
context:
space:
mode:
authorNikita Ioffe <ioffe@google.com>2020-10-05 15:53:16 +0100
committerNikita Ioffe <ioffe@google.com>2021-01-21 21:31:02 +0000
commit66bd61adb95077787c37bf4aa914cb242a52d413 (patch)
treeb83253037c2515255867bf9e24cbbd49191a291f /apexd/apexd_utils_test.cpp
parent22613b7917e90d3f75cbd107bc49f82895381388 (diff)
Fallback to /data/apex/sessions if /metadata partition is absent
There might be devices that support updatable apex, but don't have /metadata partition. For them we need to fallback to storing sessions on /data/apex/sessions. This change implements this logic by introducing GetSessionsDir static method which will pick first existing directory between /metadata/apex/sessions and /data/apex/sessions. The evaluation will happen only once, all other calls to GetSessionsDir will return the cached value. Additionally, the logic for migrating sessions from /data/apex/sessions to /metadata/apex/sessions is changed a little bit. Now apexd will iterate over entires in /data/apex/sessions, and then recursively copy their content to the corresponding directory under /metadata/apex/sessions, and then delete the entry under /data/apex/sessions. This way a directory created by init (/data/apex/sessions) is kept, which makes it easier to write unit tests for apexd. Logic is implemented as function inside apexd_utils.h for the ease of unit testing. Test: atest ApexTestCases Test: atest apexd_host_tests Test: atest CtsStagedInstallHostTestCases Bug: 169932155 Bug: 176314162 Merged-In: Ifea8840ee5f1e56428d80bbb3b4e5e078176a578 Change-Id: Ia5e31e53edb411a023c8b090b7eb53ae977adc3e (cherry picked from commit 7ffc3f6bd74b0b5567e6425090e9d13b6f5d4172) (cherry picked from commit 69e06a1ddf509e4fc0734e044655d2b876b2bf45)
Diffstat (limited to 'apexd/apexd_utils_test.cpp')
-rw-r--r--apexd/apexd_utils_test.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/apexd/apexd_utils_test.cpp b/apexd/apexd_utils_test.cpp
new file mode 100644
index 0000000..06b9c46
--- /dev/null
+++ b/apexd/apexd_utils_test.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <filesystem>
+#include <string>
+
+#include <errno.h>
+
+#include <android-base/file.h>
+#include <android-base/result.h>
+#include <android-base/stringprintf.h>
+#include <gtest/gtest.h>
+
+#include "apexd_test_utils.h"
+#include "apexd_utils.h"
+
+namespace android {
+namespace apex {
+namespace {
+
+using android::apex::testing::IsOk;
+using android::base::Basename;
+using android::base::StringPrintf;
+using ::testing::UnorderedElementsAre;
+using ::testing::UnorderedElementsAreArray;
+
+// TODO(b/170327382): add unit tests for apexd_utils.h
+
+TEST(ApexdUtilTest, FindFirstExistingDirectoryBothExist) {
+ TemporaryDir first_dir;
+ TemporaryDir second_dir;
+ auto result = FindFirstExistingDirectory(first_dir.path, second_dir.path);
+ ASSERT_TRUE(IsOk(result));
+ ASSERT_EQ(*result, first_dir.path);
+}
+
+TEST(ApexdUtilTest, FindFirstExistingDirectoryOnlyFirstExist) {
+ TemporaryDir first_dir;
+ auto second_dir = "/data/local/tmp/does/not/exist";
+ auto result = FindFirstExistingDirectory(first_dir.path, second_dir);
+ ASSERT_TRUE(IsOk(result));
+ ASSERT_EQ(*result, first_dir.path);
+}
+
+TEST(ApexdUtilTest, FindFirstExistingDirectoryOnlySecondExist) {
+ auto first_dir = "/data/local/tmp/does/not/exist";
+ TemporaryDir second_dir;
+ auto result = FindFirstExistingDirectory(first_dir, second_dir.path);
+ ASSERT_TRUE(IsOk(result));
+ ASSERT_EQ(*result, second_dir.path);
+}
+
+TEST(ApexdUtilTest, FindFirstExistingDirectoryNoneExist) {
+ auto first_dir = "/data/local/tmp/does/not/exist";
+ auto second_dir = "/data/local/tmp/also/does/not/exist";
+ auto result = FindFirstExistingDirectory(first_dir, second_dir);
+ ASSERT_FALSE(IsOk(result));
+}
+
+TEST(ApexdUtilTest, FindFirstExistingDirectoryFirstFileSecondDir) {
+ TemporaryFile first_file;
+ TemporaryDir second_dir;
+ auto result = FindFirstExistingDirectory(first_file.path, second_dir.path);
+ ASSERT_TRUE(IsOk(result));
+ ASSERT_EQ(*result, second_dir.path);
+}
+
+TEST(ApexdUtilTest, FindFirstExistingDirectoryFirstDirSecondFile) {
+ TemporaryDir first_dir;
+ TemporaryFile second_file;
+ auto result = FindFirstExistingDirectory(first_dir.path, second_file.path);
+ ASSERT_TRUE(IsOk(result));
+ ASSERT_EQ(*result, first_dir.path);
+}
+
+TEST(ApexdUtilTest, FindFirstExistingDirectoryBothFiles) {
+ TemporaryFile first_file;
+ TemporaryFile second_file;
+ auto result = FindFirstExistingDirectory(first_file.path, second_file.path);
+ ASSERT_FALSE(IsOk(result));
+}
+
+TEST(ApexdUtilTest, FindFirstExistingDirectoryFirstFileSecondDoesNotExist) {
+ TemporaryFile first_file;
+ auto second_dir = "/data/local/tmp/does/not/exist";
+ auto result = FindFirstExistingDirectory(first_file.path, second_dir);
+ ASSERT_FALSE(IsOk(result));
+}
+
+TEST(ApexdUtilTest, FindFirstExistingDirectoryFirsDoesNotExistSecondFile) {
+ auto first_dir = "/data/local/tmp/does/not/exist";
+ TemporaryFile second_file;
+ auto result = FindFirstExistingDirectory(first_dir, second_file.path);
+ ASSERT_FALSE(IsOk(result));
+}
+
+TEST(ApexdUtilTest, MoveDir) {
+ namespace fs = std::filesystem;
+
+ TemporaryDir from;
+ TemporaryDir to;
+
+ TemporaryFile from_1(from.path);
+ auto from_subdir = StringPrintf("%s/subdir", from.path);
+ if (mkdir(from_subdir.c_str(), 07000) != 0) {
+ FAIL() << "Failed to mkdir " << from_subdir << " : " << strerror(errno);
+ }
+ TemporaryFile from_2(from_subdir);
+
+ auto result = MoveDir(from.path, to.path);
+ ASSERT_TRUE(IsOk(result));
+ ASSERT_TRUE(fs::is_empty(from.path));
+
+ std::vector<std::string> content;
+ for (const auto& it : fs::recursive_directory_iterator(to.path)) {
+ content.push_back(it.path());
+ }
+
+ static const std::vector<std::string> expected = {
+ StringPrintf("%s/%s", to.path, Basename(from_1.path).c_str()),
+ StringPrintf("%s/subdir", to.path),
+ StringPrintf("%s/subdir/%s", to.path, Basename(from_2.path).c_str()),
+ };
+ ASSERT_THAT(content, UnorderedElementsAreArray(expected));
+}
+
+TEST(ApexdUtilTest, MoveDirFromIsNotDirectory) {
+ TemporaryFile from;
+ TemporaryDir to;
+ ASSERT_FALSE(IsOk(MoveDir(from.path, to.path)));
+}
+
+TEST(ApexdUtilTest, MoveDirToIsNotDirectory) {
+ TemporaryDir from;
+ TemporaryFile to;
+ TemporaryFile from_1(from.path);
+ ASSERT_FALSE(IsOk(MoveDir(from.path, to.path)));
+}
+
+TEST(ApexdUtilTest, MoveDirFromDoesNotExist) {
+ TemporaryDir to;
+ ASSERT_FALSE(IsOk(MoveDir("/data/local/tmp/does/not/exist", to.path)));
+}
+
+TEST(ApexdUtilTest, MoveDirToDoesNotExist) {
+ namespace fs = std::filesystem;
+
+ TemporaryDir from;
+ TemporaryFile from_1(from.path);
+ auto from_subdir = StringPrintf("%s/subdir", from.path);
+ if (mkdir(from_subdir.c_str(), 07000) != 0) {
+ FAIL() << "Failed to mkdir " << from_subdir << " : " << strerror(errno);
+ }
+ TemporaryFile from_2(from_subdir);
+
+ ASSERT_FALSE(IsOk(MoveDir(from.path, "/data/local/tmp/does/not/exist")));
+
+ // Check that |from| directory is not empty.
+ std::vector<std::string> content;
+ for (const auto& it : fs::recursive_directory_iterator(from.path)) {
+ content.push_back(it.path());
+ }
+
+ ASSERT_THAT(content,
+ UnorderedElementsAre(from_1.path, from_subdir, from_2.path));
+}
+
+} // namespace
+} // namespace apex
+} // namespace android