AU: Delta Performer: properly detect idempotent operations

Idempotent operations can be restarted after being aborted. This CL
enables the delta performer to find many idempotent operations. The
algorithm given is pretty good, tho it may incorrectly mark some
idempotent operations as non-idempotent. For example, a BSDIFF
operation may write a block that it reads with the same data; that's
idempotent, but missed by this algorithm. This function just looks to
see if the src/dst blocks are non-intersecting and, if non
intersecting, declares it idempotent.

BUG=7394
TEST=unittest

Review URL: http://codereview.chromium.org/3591019
diff --git a/delta_performer_unittest.cc b/delta_performer_unittest.cc
index 07fd8cc..b8d6554 100755
--- a/delta_performer_unittest.cc
+++ b/delta_performer_unittest.cc
@@ -16,6 +16,7 @@
 
 #include "update_engine/delta_diff_generator.h"
 #include "update_engine/delta_performer.h"
+#include "update_engine/extent_ranges.h"
 #include "update_engine/graph_types.h"
 #include "update_engine/payload_signer.h"
 #include "update_engine/prefs_mock.h"
@@ -359,4 +360,20 @@
   }
 }
 
+TEST(DeltaPerformerTest, IsIdempotentOperationTest) {
+  DeltaArchiveManifest_InstallOperation op;
+  EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
+  *(op.add_dst_extents()) = ExtentForRange(0, 5);
+  EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
+  *(op.add_src_extents()) = ExtentForRange(4, 1);
+  EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
+  op.clear_src_extents();
+  *(op.add_src_extents()) = ExtentForRange(5, 3);
+  EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
+  *(op.add_dst_extents()) = ExtentForRange(20, 6);
+  EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
+  *(op.add_src_extents()) = ExtentForRange(19, 2);
+  EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
+}
+
 }  // namespace chromeos_update_engine