summaryrefslogtreecommitdiff
path: root/apexd/apex_database_test.cpp
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2019-03-26 11:38:36 -0700
committerAndreas Gampe <agampe@google.com>2019-03-27 13:16:40 -0700
commit51bb99d9eb4dc2cc161bddf330ae75c521d82b1c (patch)
tree0dac2971553d8b0a9a5146d910aaa7240c3a2856 /apexd/apex_database_test.cpp
parent02e149d4dbfb717a60a97b846b5787c8e27537c3 (diff)
Apexd: Add database duplicates check
Add a check for duplicate loop and dm devices. As we are correctly tearing them down now, this becomes important. Add tests. Bug: 116593293 Bug: 129347238 Test: atest apex_database_test Change-Id: I7bf34420cec3808181a8baad0bd725e5c7e685ae
Diffstat (limited to 'apexd/apex_database_test.cpp')
-rw-r--r--apexd/apex_database_test.cpp115
1 files changed, 87 insertions, 28 deletions
diff --git a/apexd/apex_database_test.cpp b/apexd/apex_database_test.cpp
index 3ef8ce5..c43bfc2 100644
--- a/apexd/apex_database_test.cpp
+++ b/apexd/apex_database_test.cpp
@@ -15,6 +15,7 @@
*/
#include <string>
+#include <tuple>
#include <android-base/macros.h>
#include <gtest/gtest.h>
@@ -28,30 +29,53 @@ namespace {
using MountedApexData = MountedApexDatabase::MountedApexData;
TEST(MountedApexDataTest, LinearOrder) {
- constexpr const char* kLoopName[] = {"loop1", "loop1", "loop2", "loop2",
- "loop3", "loop3", "loop3", "loop3"};
- constexpr const char* kPath[] = {"path1", "path2", "path1", "path2",
- "path1", "path3", "path3", "path3"};
- constexpr const char* kMountPoint[] = {"point1", "point1", "point1",
- "point1", "point1", "point1",
- "point1", "point2"};
- constexpr const char* kDeviceName[] = {"dev1", "dev1", "dev1", "dev1",
- "dev1", "dev1", "dev2", "dev1"};
-
- constexpr size_t kCount = arraysize(kLoopName);
+ constexpr const char* kLoopName[] = {"loop1", "loop2", "loop3"};
+ constexpr const char* kPath[] = {"path1", "path2", "path3"};
+ constexpr const char* kMount[] = {"mount1", "mount2", "mount3"};
+ constexpr const char* kDm[] = {"dm1", "dm2", "dm3"};
+ constexpr size_t kCount = arraysize(kLoopName) * arraysize(kPath) *
+ arraysize(kMount) * arraysize(kDm);
+
+ auto index_fn = [&](size_t i) {
+ const size_t loop_index = i % arraysize(kLoopName);
+ const size_t loop_rest = i / arraysize(kLoopName);
+ const size_t path_index = loop_rest % arraysize(kPath);
+ const size_t path_rest = loop_rest / arraysize(kPath);
+ const size_t mount_index = path_rest % arraysize(kMount);
+ const size_t mount_rest = path_rest / arraysize(kMount);
+ ;
+ const size_t dm_index = mount_rest % arraysize(kDm);
+ CHECK_EQ(mount_rest / arraysize(kDm), 0u);
+ return std::make_tuple(loop_index, path_index, mount_index, dm_index);
+ };
MountedApexData data[kCount];
for (size_t i = 0; i < kCount; ++i) {
- data[i] =
- MountedApexData(kLoopName[i], kPath[i], kMountPoint[i], kDeviceName[i]);
+ size_t loop_idx, path_idx, mount_idx, dm_idx;
+ std::tie(loop_idx, path_idx, mount_idx, dm_idx) = index_fn(i);
+ data[i] = MountedApexData(kLoopName[loop_idx], kPath[path_idx],
+ kMount[mount_idx], kDm[dm_idx]);
}
for (size_t i = 0; i < kCount; ++i) {
+ size_t loop_idx_i, path_idx_i, mount_idx_i, dm_idx_i;
+ std::tie(loop_idx_i, path_idx_i, mount_idx_i, dm_idx_i) = index_fn(i);
for (size_t j = i; j < kCount; ++j) {
- if (i != j) {
- EXPECT_TRUE(data[i] < data[j]) << i << " < " << j;
+ size_t loop_idx_j, path_idx_j, mount_idx_j, dm_idx_j;
+ std::tie(loop_idx_j, path_idx_j, mount_idx_j, dm_idx_j) = index_fn(j);
+ if (loop_idx_i != loop_idx_j) {
+ EXPECT_EQ(loop_idx_i < loop_idx_j, data[i] < data[j]);
+ continue;
}
- EXPECT_FALSE(data[j] < data[i]) << "! " << j << " < " << i;
+ if (path_idx_i != path_idx_j) {
+ EXPECT_EQ(path_idx_i < path_idx_j, data[i] < data[j]);
+ continue;
+ }
+ if (mount_idx_i != mount_idx_j) {
+ EXPECT_EQ(mount_idx_i < mount_idx_j, data[i] < data[j]);
+ continue;
+ }
+ EXPECT_EQ(dm_idx_i < dm_idx_j, data[i] < data[j]);
}
}
}
@@ -79,12 +103,13 @@ bool Contains(const MountedApexDatabase& db, const std::string& package,
}
bool ContainsPackage(const MountedApexDatabase& db, const std::string& package,
- const std::string& loop_name,
- const std::string& full_path) {
+ const std::string& loop_name, const std::string& full_path,
+ const std::string& mount_point, const std::string& dm) {
bool found = false;
db.ForallMountedApexes(
package, [&](const MountedApexData& d, bool b ATTRIBUTE_UNUSED) {
- if (loop_name == d.loop_name && full_path == d.full_path) {
+ if (loop_name == d.loop_name && full_path == d.full_path &&
+ dm == d.device_name) {
found = true;
}
});
@@ -105,21 +130,23 @@ TEST(ApexDatabaseTest, AddRemovedMountedApex) {
kDeviceName);
ASSERT_TRUE(
Contains(db, kPackage, kLoopName, kPath, kMountPoint, kDeviceName));
- ASSERT_TRUE(ContainsPackage(db, kPackage, kLoopName, kPath));
+ ASSERT_TRUE(ContainsPackage(db, kPackage, kLoopName, kPath, kMountPoint,
+ kDeviceName));
db.RemoveMountedApex(kPackage, kPath);
EXPECT_FALSE(
Contains(db, kPackage, kLoopName, kPath, kMountPoint, kDeviceName));
- EXPECT_FALSE(ContainsPackage(db, kPackage, kLoopName, kPath));
+ EXPECT_FALSE(ContainsPackage(db, kPackage, kLoopName, kPath, kMountPoint,
+ kDeviceName));
}
TEST(ApexDatabaseTest, MountMultiple) {
constexpr const char* kPackage[] = {"package", "package", "package",
"package"};
- constexpr const char* kLoopName[] = {"loop", "loop", "loop3", "loop4"};
+ constexpr const char* kLoopName[] = {"loop", "loop2", "loop3", "loop4"};
constexpr const char* kPath[] = {"path", "path2", "path", "path4"};
constexpr const char* kMountPoint[] = {"mount", "mount2", "mount", "mount4"};
- constexpr const char* kDeviceName[] = {"dev", "dev2", "dev", "dev4"};
+ constexpr const char* kDeviceName[] = {"dev", "dev2", "dev3", "dev4"};
MountedApexDatabase db;
ASSERT_EQ(CountPackages(db), 0u);
@@ -133,24 +160,56 @@ TEST(ApexDatabaseTest, MountMultiple) {
for (size_t i = 0; i < arraysize(kPackage); ++i) {
ASSERT_TRUE(Contains(db, kPackage[i], kLoopName[i], kPath[i],
kMountPoint[i], kDeviceName[i]));
- ASSERT_TRUE(ContainsPackage(db, kPackage[i], kLoopName[i], kPath[i]));
+ ASSERT_TRUE(ContainsPackage(db, kPackage[i], kLoopName[i], kPath[i],
+ kMountPoint[i], kDeviceName[i]));
}
db.RemoveMountedApex(kPackage[0], kPath[0]);
EXPECT_FALSE(Contains(db, kPackage[0], kLoopName[0], kPath[0], kMountPoint[0],
kDeviceName[0]));
- EXPECT_FALSE(ContainsPackage(db, kPackage[0], kLoopName[0], kPath[0]));
+ EXPECT_FALSE(ContainsPackage(db, kPackage[0], kLoopName[0], kPath[0],
+ kMountPoint[0], kDeviceName[0]));
EXPECT_TRUE(Contains(db, kPackage[1], kLoopName[1], kPath[1], kMountPoint[1],
kDeviceName[1]));
- EXPECT_TRUE(ContainsPackage(db, kPackage[1], kLoopName[1], kPath[1]));
+ EXPECT_TRUE(ContainsPackage(db, kPackage[1], kLoopName[1], kPath[1],
+ kMountPoint[1], kDeviceName[1]));
EXPECT_TRUE(Contains(db, kPackage[2], kLoopName[2], kPath[2], kMountPoint[2],
kDeviceName[2]));
- EXPECT_TRUE(ContainsPackage(db, kPackage[2], kLoopName[2], kPath[2]));
+ EXPECT_TRUE(ContainsPackage(db, kPackage[2], kLoopName[2], kPath[2],
+ kMountPoint[2], kDeviceName[2]));
EXPECT_TRUE(Contains(db, kPackage[3], kLoopName[3], kPath[3], kMountPoint[3],
kDeviceName[3]));
- EXPECT_TRUE(ContainsPackage(db, kPackage[3], kLoopName[3], kPath[3]));
+ EXPECT_TRUE(ContainsPackage(db, kPackage[3], kLoopName[3], kPath[3],
+ kMountPoint[3], kDeviceName[3]));
+}
+
+#pragma clang diagnostic push
+// error: 'ReturnSentinel' was marked unused but was used
+// [-Werror,-Wused-but-marked-unused]
+#pragma clang diagnostic ignored "-Wused-but-marked-unused"
+
+TEST(MountedApexDataTest, NoDuplicateLoop) {
+ ASSERT_DEATH(
+ {
+ MountedApexDatabase db;
+ db.AddMountedApex("package", false, "loop", "path", "mount", "dm");
+ db.AddMountedApex("package2", false, "loop", "path2", "mount2", "dm2");
+ },
+ "Duplicate loop device: loop");
}
+TEST(MountedApexDataTest, NoDuplicateDm) {
+ ASSERT_DEATH(
+ {
+ MountedApexDatabase db;
+ db.AddMountedApex("package", false, "loop", "path", "mount", "dm");
+ db.AddMountedApex("package2", false, "loop2", "path2", "mount2", "dm");
+ },
+ "Duplicate dm device: dm");
+}
+
+#pragma clang diagnostic pop
+
} // namespace
} // namespace apex
} // namespace android