summaryrefslogtreecommitdiff
path: root/dynamic_partition_control_android_unittest.cc
diff options
context:
space:
mode:
authorAlessio Balsini <balsini@google.com>2019-11-25 16:46:51 +0000
committerYifan Hong <elsk@google.com>2019-12-04 04:02:20 +0000
commit2a3b4a22eb6925326e439f820fa91a3976afac10 (patch)
tree895d9d338377f0b8700c8d8352c16f397f9a3f85 /dynamic_partition_control_android_unittest.cc
parent36e2289b82af548128191e7e8a0d94f0ce6bbe30 (diff)
Skip identical SOURCE_COPY operations
When Virtual A/B devices are updated, SOURCE_COPY operations that are copying data from source to destination at the same locations: - are useless; - introduce an overhead for overwritingin identical data; - increase the COW device size when using dm-snapshot. This patch analyzes SOURCE_COPY operations and skips them if applied to Virtual A/B devices and source and destination addresses are identical. Bug: 141207436 Test: DynamicPartitionControlAndroidTest:ShouldSkipOperationTest Depends-On: I146aeba1c8ede35f21cfef8e21d4af62274bda84 Change-Id: Ifec33abaf81b1d4cbd61533293735de68578c9c4 Signed-off-by: Alessio Balsini <balsini@google.com>
Diffstat (limited to 'dynamic_partition_control_android_unittest.cc')
-rw-r--r--dynamic_partition_control_android_unittest.cc82
1 files changed, 82 insertions, 0 deletions
diff --git a/dynamic_partition_control_android_unittest.cc b/dynamic_partition_control_android_unittest.cc
index 10075ed4..fc3d38cb 100644
--- a/dynamic_partition_control_android_unittest.cc
+++ b/dynamic_partition_control_android_unittest.cc
@@ -124,6 +124,10 @@ class DynamicPartitionControlAndroidTest : public ::testing::Test {
}
void SetSlots(const TestParam& slots) { slots_ = slots; }
+ void SetSnapshotEnabled(bool enabled) {
+ dynamicControl().target_supports_snapshot_ = enabled;
+ }
+
struct Listener : public ::testing::MatchResultListener {
explicit Listener(std::ostream* os) : MatchResultListener(os) {}
};
@@ -616,4 +620,82 @@ TEST_F(DynamicPartitionControlAndroidTest, ApplyingToCurrentSlot) {
<< "Should not be able to apply to current slot.";
}
+TEST_F(DynamicPartitionControlAndroidTest, ShouldSkipOperationTest) {
+ InstallOperation iop;
+ Extent *se, *de;
+
+ // Not a SOURCE_COPY operation, cannot skip.
+ iop.set_type(InstallOperation::REPLACE);
+ EXPECT_FALSE(dynamicControl().ShouldSkipOperation(iop));
+
+ iop.set_type(InstallOperation::SOURCE_COPY);
+
+ // By default GetVirtualAbFeatureFlag is disabled. Cannot skip operation.
+ EXPECT_FALSE(dynamicControl().ShouldSkipOperation(iop));
+
+ // Enable GetVirtualAbFeatureFlag in the mock interface.
+ ON_CALL(dynamicControl(), GetVirtualAbFeatureFlag())
+ .WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
+
+ // By default target_supports_snapshot_ is set to false. Cannot skip
+ // operation.
+ EXPECT_FALSE(dynamicControl().ShouldSkipOperation(iop));
+
+ SetSnapshotEnabled(true);
+
+ // Empty source and destination. Skip.
+ EXPECT_TRUE(dynamicControl().ShouldSkipOperation(iop));
+
+ se = iop.add_src_extents();
+ se->set_start_block(0);
+ se->set_num_blocks(1);
+
+ // There is something in sources, but destinations are empty. Cannot skip.
+ EXPECT_FALSE(dynamicControl().ShouldSkipOperation(iop));
+
+ InstallOperation iop2;
+
+ de = iop2.add_dst_extents();
+ de->set_start_block(0);
+ de->set_num_blocks(1);
+
+ // There is something in destinations, but sources are empty. Cannot skip.
+ EXPECT_FALSE(dynamicControl().ShouldSkipOperation(iop2));
+
+ de = iop.add_dst_extents();
+ de->set_start_block(0);
+ de->set_num_blocks(1);
+
+ // Sources and destinations are identical. Skip.
+ EXPECT_TRUE(dynamicControl().ShouldSkipOperation(iop));
+
+ se = iop.add_src_extents();
+ se->set_start_block(1);
+ se->set_num_blocks(5);
+
+ // There is something in source, but not in destination. Cannot skip.
+ EXPECT_FALSE(dynamicControl().ShouldSkipOperation(iop));
+
+ de = iop.add_dst_extents();
+ de->set_start_block(1);
+ de->set_num_blocks(5);
+
+ // There is source and destination are equal. Skip.
+ EXPECT_TRUE(dynamicControl().ShouldSkipOperation(iop));
+
+ de = iop.add_dst_extents();
+ de->set_start_block(6);
+ de->set_num_blocks(5);
+
+ // There is something extra in dest. Cannot skip.
+ EXPECT_FALSE(dynamicControl().ShouldSkipOperation(iop));
+
+ se = iop.add_src_extents();
+ se->set_start_block(6);
+ se->set_num_blocks(5);
+
+ // Source and dest are identical again. Skip.
+ EXPECT_TRUE(dynamicControl().ShouldSkipOperation(iop));
+}
+
} // namespace chromeos_update_engine