diff options
author | Andreas Gampe <agampe@google.com> | 2019-03-26 11:38:36 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2019-03-27 13:16:40 -0700 |
commit | 51bb99d9eb4dc2cc161bddf330ae75c521d82b1c (patch) | |
tree | 0dac2971553d8b0a9a5146d910aaa7240c3a2856 /apexd/apex_database_test.cpp | |
parent | 02e149d4dbfb717a60a97b846b5787c8e27537c3 (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.cpp | 115 |
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 |