Make sure ExtentRanges don't merge extents

When querying for XOR merge ops, we want the unmerged extents. E.g.
[5-9] and [10-14] should not be merged into 1 extent, because they could
correspond to different merge ops.

Test: th
Change-Id: I14c4c9fd6bf6361af6cd1e31264bdf860127a75b
diff --git a/payload_generator/extent_ranges.cc b/payload_generator/extent_ranges.cc
index 4cc2d6f..b742611 100644
--- a/payload_generator/extent_ranges.cc
+++ b/payload_generator/extent_ranges.cc
@@ -56,6 +56,7 @@
 }
 
 void ExtentRanges::AddBlock(uint64_t block) {
+  // Remember to respect |merge_touching_extents_| setting
   AddExtent(ExtentForRange(block, 1));
 }
 
@@ -86,7 +87,10 @@
   for (ExtentSet::iterator it = extent_set_.begin(), e = extent_set_.end();
        it != e;
        ++it) {
-    if (ExtentsOverlapOrTouch(*it, extent)) {
+    const bool should_merge = merge_touching_extents_
+                                  ? ExtentsOverlapOrTouch(*it, extent)
+                                  : ExtentsOverlap(*it, extent);
+    if (should_merge) {
       end_del = it;
       ++end_del;
       del_blocks += it->num_blocks();
@@ -155,6 +159,7 @@
 }
 
 void ExtentRanges::AddRanges(const ExtentRanges& ranges) {
+  // Remember to respect |merge_touching_extents_| setting
   for (ExtentSet::const_iterator it = ranges.extent_set_.begin(),
                                  e = ranges.extent_set_.end();
        it != e;
@@ -173,6 +178,7 @@
 }
 
 void ExtentRanges::AddExtents(const vector<Extent>& extents) {
+  // Remember to respect |merge_touching_extents_| setting
   for (vector<Extent>::const_iterator it = extents.begin(), e = extents.end();
        it != e;
        ++it) {
@@ -190,6 +196,7 @@
 
 void ExtentRanges::AddRepeatedExtents(
     const ::google::protobuf::RepeatedPtrField<Extent>& exts) {
+  // Remember to respect |merge_touching_extents_| setting
   for (int i = 0, e = exts.size(); i != e; ++i) {
     AddExtent(exts.Get(i));
   }
diff --git a/payload_generator/extent_ranges.h b/payload_generator/extent_ranges.h
index 8e3e261..a16947e 100644
--- a/payload_generator/extent_ranges.h
+++ b/payload_generator/extent_ranges.h
@@ -53,7 +53,14 @@
  public:
   typedef std::set<Extent, ExtentLess> ExtentSet;
 
-  ExtentRanges() : blocks_(0) {}
+  ExtentRanges() = default;
+  // When |merge_touching_extents| is set to false, extents that are only
+  // touching but not overlapping won't be merged. This slightly decreases
+  // space/time efficiency, but should not impact correctness.
+  // Only intended usecase is for VABC XOR.
+  // E.g. [5-9] and [10-14] will be merged iff |merge_touching_extents| is true
+  explicit ExtentRanges(bool merge_touching_extents)
+      : merge_touching_extents_(merge_touching_extents) {}
   void AddBlock(uint64_t block);
   void SubtractBlock(uint64_t block);
   void AddExtent(Extent extent);
@@ -102,7 +109,8 @@
 
  private:
   ExtentSet extent_set_;
-  uint64_t blocks_;
+  uint64_t blocks_ = 0;
+  const bool merge_touching_extents_ = true;
 };
 
 // Filters out from the passed list of extents |extents| all the blocks in the
diff --git a/payload_generator/extent_ranges_unittest.cc b/payload_generator/extent_ranges_unittest.cc
index 314ec54..a2053aa 100644
--- a/payload_generator/extent_ranges_unittest.cc
+++ b/payload_generator/extent_ranges_unittest.cc
@@ -40,30 +40,28 @@
   for (size_t i = 1; i < sz; i += 2) {
     blocks += expected[i];
   }
-  EXPECT_EQ(blocks, ranges.blocks()) << "line: " << line;
+  ASSERT_EQ(blocks, ranges.blocks()) << "line: " << line;
 
   const ExtentRanges::ExtentSet& result = ranges.extent_set();
   ExtentRanges::ExtentSet::const_iterator it = result.begin();
   for (size_t i = 0; i < sz; i += 2) {
-    EXPECT_FALSE(it == result.end()) << "line: " << line;
-    EXPECT_EQ(expected[i], it->start_block()) << "line: " << line;
-    EXPECT_EQ(expected[i + 1], it->num_blocks()) << "line: " << line;
+    ASSERT_FALSE(it == result.end()) << "line: " << line;
+    ASSERT_EQ(expected[i], it->start_block()) << "line: " << line;
+    ASSERT_EQ(expected[i + 1], it->num_blocks()) << "line: " << line;
     ++it;
   }
 }
 
-#define EXPECT_RANGE_EQ(ranges, var)                       \
-  do {                                                     \
-    ExpectRangeEq(ranges, var, base::size(var), __LINE__); \
-  } while (0)
+#define ASSERT_RANGE_EQ(ranges, var) \
+  ASSERT_NO_FATAL_FAILURE(ExpectRangeEq(ranges, var, base::size(var), __LINE__))
 
 void ExpectRangesOverlapOrTouch(uint64_t a_start,
                                 uint64_t a_num,
                                 uint64_t b_start,
                                 uint64_t b_num) {
-  EXPECT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(
+  ASSERT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(
       ExtentForRange(a_start, a_num), ExtentForRange(b_start, b_num)));
-  EXPECT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(
+  ASSERT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(
       ExtentForRange(b_start, b_num), ExtentForRange(a_start, a_num)));
 }
 
@@ -71,13 +69,13 @@
                                      uint64_t a_num,
                                      uint64_t b_start,
                                      uint64_t b_num) {
-  EXPECT_FALSE(ExtentRanges::ExtentsOverlapOrTouch(
+  ASSERT_FALSE(ExtentRanges::ExtentsOverlapOrTouch(
       ExtentForRange(a_start, a_num), ExtentForRange(b_start, b_num)));
-  EXPECT_FALSE(ExtentRanges::ExtentsOverlapOrTouch(
+  ASSERT_FALSE(ExtentRanges::ExtentsOverlapOrTouch(
       ExtentForRange(b_start, b_num), ExtentForRange(a_start, a_num)));
-  EXPECT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(a_start, a_num),
+  ASSERT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(a_start, a_num),
                                             ExtentForRange(b_start, b_num)));
-  EXPECT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(b_start, b_num),
+  ASSERT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(b_start, b_num),
                                             ExtentForRange(a_start, a_num)));
 }
 
@@ -85,13 +83,13 @@
                          uint64_t a_num,
                          uint64_t b_start,
                          uint64_t b_num) {
-  EXPECT_TRUE(ExtentRanges::ExtentsOverlap(ExtentForRange(a_start, a_num),
+  ASSERT_TRUE(ExtentRanges::ExtentsOverlap(ExtentForRange(a_start, a_num),
                                            ExtentForRange(b_start, b_num)));
-  EXPECT_TRUE(ExtentRanges::ExtentsOverlap(ExtentForRange(b_start, b_num),
+  ASSERT_TRUE(ExtentRanges::ExtentsOverlap(ExtentForRange(b_start, b_num),
                                            ExtentForRange(a_start, a_num)));
-  EXPECT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(
+  ASSERT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(
       ExtentForRange(a_start, a_num), ExtentForRange(b_start, b_num)));
-  EXPECT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(
+  ASSERT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(
       ExtentForRange(b_start, b_num), ExtentForRange(a_start, a_num)));
 }
 
@@ -99,41 +97,44 @@
                               uint64_t a_num,
                               uint64_t b_start,
                               uint64_t b_num) {
-  EXPECT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(a_start, a_num),
+  ASSERT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(a_start, a_num),
                                             ExtentForRange(b_start, b_num)));
-  EXPECT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(b_start, b_num),
+  ASSERT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(b_start, b_num),
                                             ExtentForRange(a_start, a_num)));
 }
 
 }  // namespace
 
 TEST(ExtentRangesTest, ExtentsOverlapTest) {
-  ExpectRangesOverlapOrTouch(10, 20, 30, 10);
-  ExpectRangesOverlap(10, 20, 25, 10);
-  ExpectFalseRangesOverlapOrTouch(10, 20, 35, 10);
-  ExpectFalseRangesOverlap(10, 20, 30, 10);
-  ExpectRangesOverlap(12, 4, 12, 3);
+  ASSERT_NO_FATAL_FAILURE(ExpectRangesOverlapOrTouch(10, 20, 30, 10));
+  ASSERT_NO_FATAL_FAILURE(ExpectRangesOverlap(10, 20, 25, 10));
+  ASSERT_NO_FATAL_FAILURE(ExpectFalseRangesOverlapOrTouch(10, 20, 35, 10));
+  ASSERT_NO_FATAL_FAILURE(ExpectFalseRangesOverlap(10, 20, 30, 10));
+  ASSERT_NO_FATAL_FAILURE(ExpectRangesOverlap(12, 4, 12, 3));
 
-  ExpectRangesOverlapOrTouch(kSparseHole, 2, kSparseHole, 3);
-  ExpectRangesOverlap(kSparseHole, 2, kSparseHole, 3);
-  ExpectFalseRangesOverlapOrTouch(kSparseHole, 2, 10, 3);
-  ExpectFalseRangesOverlapOrTouch(10, 2, kSparseHole, 3);
-  ExpectFalseRangesOverlap(kSparseHole, 2, 10, 3);
-  ExpectFalseRangesOverlap(10, 2, kSparseHole, 3);
+  ASSERT_NO_FATAL_FAILURE(
+      ExpectRangesOverlapOrTouch(kSparseHole, 2, kSparseHole, 3));
+  ASSERT_NO_FATAL_FAILURE(ExpectRangesOverlap(kSparseHole, 2, kSparseHole, 3));
+  ASSERT_NO_FATAL_FAILURE(
+      ExpectFalseRangesOverlapOrTouch(kSparseHole, 2, 10, 3));
+  ASSERT_NO_FATAL_FAILURE(
+      ExpectFalseRangesOverlapOrTouch(10, 2, kSparseHole, 3));
+  ASSERT_NO_FATAL_FAILURE(ExpectFalseRangesOverlap(kSparseHole, 2, 10, 3));
+  ASSERT_NO_FATAL_FAILURE(ExpectFalseRangesOverlap(10, 2, kSparseHole, 3));
 }
 
 TEST(ExtentRangesTest, SimpleTest) {
   ExtentRanges ranges;
   {
-    static const uint64_t expected[] = {};
+    static constexpr uint64_t expected[] = {};
     // Can't use arraysize() on 0-length arrays:
-    ExpectRangeEq(ranges, expected, 0, __LINE__);
+    ASSERT_NO_FATAL_FAILURE(ExpectRangeEq(ranges, expected, 0, __LINE__));
   }
   ranges.SubtractBlock(2);
   {
-    static const uint64_t expected[] = {};
+    static constexpr uint64_t expected[] = {};
     // Can't use arraysize() on 0-length arrays:
-    ExpectRangeEq(ranges, expected, 0, __LINE__);
+    ASSERT_NO_FATAL_FAILURE(ExpectRangeEq(ranges, expected, 0, __LINE__));
   }
 
   ranges.AddBlock(0);
@@ -142,54 +143,54 @@
   ranges.AddBlock(3);
 
   {
-    static const uint64_t expected[] = {0, 2, 3, 1};
-    EXPECT_RANGE_EQ(ranges, expected);
+    static constexpr uint64_t expected[] = {0, 2, 3, 1};
+    ASSERT_RANGE_EQ(ranges, expected);
   }
   ranges.AddBlock(2);
   {
-    static const uint64_t expected[] = {0, 4};
-    EXPECT_RANGE_EQ(ranges, expected);
+    static constexpr uint64_t expected[] = {0, 4};
+    ASSERT_RANGE_EQ(ranges, expected);
     ranges.AddBlock(kSparseHole);
-    EXPECT_RANGE_EQ(ranges, expected);
+    ASSERT_RANGE_EQ(ranges, expected);
     ranges.SubtractBlock(kSparseHole);
-    EXPECT_RANGE_EQ(ranges, expected);
+    ASSERT_RANGE_EQ(ranges, expected);
   }
   ranges.SubtractBlock(2);
   {
-    static const uint64_t expected[] = {0, 2, 3, 1};
-    EXPECT_RANGE_EQ(ranges, expected);
+    static constexpr uint64_t expected[] = {0, 2, 3, 1};
+    ASSERT_RANGE_EQ(ranges, expected);
   }
 
   for (uint64_t i = 100; i < 1000; i += 100) {
     ranges.AddExtent(ExtentForRange(i, 50));
   }
   {
-    static const uint64_t expected[] = {0,   2,  3,   1,  100, 50, 200, 50,
-                                        300, 50, 400, 50, 500, 50, 600, 50,
-                                        700, 50, 800, 50, 900, 50};
-    EXPECT_RANGE_EQ(ranges, expected);
+    static constexpr uint64_t expected[] = {0,   2,  3,   1,  100, 50, 200, 50,
+                                            300, 50, 400, 50, 500, 50, 600, 50,
+                                            700, 50, 800, 50, 900, 50};
+    ASSERT_RANGE_EQ(ranges, expected);
   }
 
   ranges.SubtractExtent(ExtentForRange(210, 410 - 210));
   {
-    static const uint64_t expected[] = {0,   2,   3,   1,   100, 50,  200,
-                                        10,  410, 40,  500, 50,  600, 50,
-                                        700, 50,  800, 50,  900, 50};
-    EXPECT_RANGE_EQ(ranges, expected);
+    static constexpr uint64_t expected[] = {0,   2,   3,   1,   100, 50,  200,
+                                            10,  410, 40,  500, 50,  600, 50,
+                                            700, 50,  800, 50,  900, 50};
+    ASSERT_RANGE_EQ(ranges, expected);
   }
   ranges.AddExtent(ExtentForRange(100000, 0));
   {
-    static const uint64_t expected[] = {0,   2,   3,   1,   100, 50,  200,
-                                        10,  410, 40,  500, 50,  600, 50,
-                                        700, 50,  800, 50,  900, 50};
-    EXPECT_RANGE_EQ(ranges, expected);
+    static constexpr uint64_t expected[] = {0,   2,   3,   1,   100, 50,  200,
+                                            10,  410, 40,  500, 50,  600, 50,
+                                            700, 50,  800, 50,  900, 50};
+    ASSERT_RANGE_EQ(ranges, expected);
   }
   ranges.SubtractExtent(ExtentForRange(3, 0));
   {
-    static const uint64_t expected[] = {0,   2,   3,   1,   100, 50,  200,
-                                        10,  410, 40,  500, 50,  600, 50,
-                                        700, 50,  800, 50,  900, 50};
-    EXPECT_RANGE_EQ(ranges, expected);
+    static constexpr uint64_t expected[] = {0,   2,   3,   1,   100, 50,  200,
+                                            10,  410, 40,  500, 50,  600, 50,
+                                            700, 50,  800, 50,  900, 50};
+    ASSERT_RANGE_EQ(ranges, expected);
   }
 }
 
@@ -199,22 +200,22 @@
   ranges_b.AddBlock(4);
   ranges_b.AddBlock(3);
   {
-    uint64_t expected[] = {3, 2};
-    EXPECT_RANGE_EQ(ranges_b, expected);
+    constexpr uint64_t expected[] = {3, 2};
+    ASSERT_RANGE_EQ(ranges_b, expected);
   }
   ranges_a.AddRanges(ranges_b);
   {
-    uint64_t expected[] = {0, 1, 3, 2};
-    EXPECT_RANGE_EQ(ranges_a, expected);
+    constexpr uint64_t expected[] = {0, 1, 3, 2};
+    ASSERT_RANGE_EQ(ranges_a, expected);
   }
   ranges_a.SubtractRanges(ranges_b);
   {
-    uint64_t expected[] = {0, 1};
-    EXPECT_RANGE_EQ(ranges_a, expected);
+    constexpr uint64_t expected[] = {0, 1};
+    ASSERT_RANGE_EQ(ranges_a, expected);
   }
   {
-    uint64_t expected[] = {3, 2};
-    EXPECT_RANGE_EQ(ranges_b, expected);
+    constexpr uint64_t expected[] = {3, 2};
+    ASSERT_RANGE_EQ(ranges_b, expected);
   }
 }
 
@@ -223,7 +224,7 @@
   ranges.AddExtents(vector<Extent>(1, ExtentForRange(10, 30)));
   {
     vector<Extent> zero_extents = ranges.GetExtentsForBlockCount(0);
-    EXPECT_TRUE(zero_extents.empty());
+    ASSERT_TRUE(zero_extents.empty());
   }
   ::google::protobuf::RepeatedPtrField<Extent> rep_field;
   *rep_field.Add() = ExtentForRange(30, 40);
@@ -231,7 +232,7 @@
   ranges.SubtractExtents(vector<Extent>(1, ExtentForRange(20, 10)));
   *rep_field.Mutable(0) = ExtentForRange(50, 10);
   ranges.SubtractRepeatedExtents(rep_field);
-  EXPECT_EQ(40U, ranges.blocks());
+  ASSERT_EQ(40U, ranges.blocks());
 
   for (int i = 0; i < 2; i++) {
     vector<Extent> expected(2);
@@ -239,11 +240,11 @@
     expected[1] = ExtentForRange(30, i == 0 ? 10 : 20);
     vector<Extent> actual =
         ranges.GetExtentsForBlockCount(10 + expected[1].num_blocks());
-    EXPECT_EQ(expected.size(), actual.size());
+    ASSERT_EQ(expected.size(), actual.size());
     for (vector<Extent>::size_type j = 0, e = expected.size(); j != e; ++j) {
-      EXPECT_EQ(expected[j].start_block(), actual[j].start_block())
+      ASSERT_EQ(expected[j].start_block(), actual[j].start_block())
           << "j = " << j;
-      EXPECT_EQ(expected[j].num_blocks(), actual[j].num_blocks())
+      ASSERT_EQ(expected[j].num_blocks(), actual[j].num_blocks())
           << "j = " << j;
     }
   }
@@ -251,30 +252,30 @@
 
 TEST(ExtentRangesTest, ContainsBlockTest) {
   ExtentRanges ranges;
-  EXPECT_FALSE(ranges.ContainsBlock(123));
+  ASSERT_FALSE(ranges.ContainsBlock(123));
 
   ranges.AddExtent(ExtentForRange(10, 10));
   ranges.AddExtent(ExtentForRange(100, 1));
 
-  EXPECT_FALSE(ranges.ContainsBlock(9));
-  EXPECT_TRUE(ranges.ContainsBlock(10));
-  EXPECT_TRUE(ranges.ContainsBlock(15));
-  EXPECT_TRUE(ranges.ContainsBlock(19));
-  EXPECT_FALSE(ranges.ContainsBlock(20));
+  ASSERT_FALSE(ranges.ContainsBlock(9));
+  ASSERT_TRUE(ranges.ContainsBlock(10));
+  ASSERT_TRUE(ranges.ContainsBlock(15));
+  ASSERT_TRUE(ranges.ContainsBlock(19));
+  ASSERT_FALSE(ranges.ContainsBlock(20));
 
   // Test for an extent with just the block we are requesting.
-  EXPECT_FALSE(ranges.ContainsBlock(99));
-  EXPECT_TRUE(ranges.ContainsBlock(100));
-  EXPECT_FALSE(ranges.ContainsBlock(101));
+  ASSERT_FALSE(ranges.ContainsBlock(99));
+  ASSERT_TRUE(ranges.ContainsBlock(100));
+  ASSERT_FALSE(ranges.ContainsBlock(101));
 }
 
 TEST(ExtentRangesTest, FilterExtentRangesEmptyRanges) {
   ExtentRanges ranges;
-  EXPECT_EQ(vector<Extent>(), FilterExtentRanges(vector<Extent>(), ranges));
-  EXPECT_EQ(vector<Extent>{ExtentForRange(50, 10)},
+  ASSERT_EQ(vector<Extent>(), FilterExtentRanges(vector<Extent>(), ranges));
+  ASSERT_EQ(vector<Extent>{ExtentForRange(50, 10)},
             FilterExtentRanges(vector<Extent>{ExtentForRange(50, 10)}, ranges));
   // Check that the empty Extents are ignored.
-  EXPECT_EQ((vector<Extent>{ExtentForRange(10, 10), ExtentForRange(20, 10)}),
+  ASSERT_EQ((vector<Extent>{ExtentForRange(10, 10), ExtentForRange(20, 10)}),
             FilterExtentRanges(vector<Extent>{ExtentForRange(10, 10),
                                               ExtentForRange(3, 0),
                                               ExtentForRange(20, 10)},
@@ -291,7 +292,7 @@
   ranges.AddExtent(ExtentForRange(70, 10));
   // This overlaps the end of the second extent.
   ranges.AddExtent(ExtentForRange(108, 6));
-  EXPECT_EQ((vector<Extent>{// For the first extent:
+  ASSERT_EQ((vector<Extent>{// For the first extent:
                             ExtentForRange(10, 18),
                             ExtentForRange(31, 19),
                             ExtentForRange(60, 10),
@@ -309,7 +310,7 @@
   ranges.AddExtent(ExtentForRange(10, 3));
   ranges.AddExtent(ExtentForRange(20, 5));
   // Requested extent overlaps with one of the ranges.
-  EXPECT_EQ(vector<Extent>(),
+  ASSERT_EQ(vector<Extent>(),
             FilterExtentRanges(
                 vector<Extent>{ExtentForRange(10, 1), ExtentForRange(22, 1)},
                 ranges));
@@ -331,4 +332,48 @@
   ASSERT_EQ(ret4.num_blocks(), 0UL);
 }
 
+TEST(ExtentRangesTest, ContainsBlockSameStart) {
+  ExtentRanges ranges{false};
+  ranges.AddExtent(ExtentForRange(5, 4));
+  ranges.AddExtent(ExtentForRange(10, 5));
+  ranges.AddExtent(ExtentForRange(15, 5));
+  ranges.AddExtent(ExtentForRange(20, 5));
+  ranges.AddExtent(ExtentForRange(25, 5));
+
+  ASSERT_TRUE(ranges.ContainsBlock(10));
+  ASSERT_TRUE(ranges.ContainsBlock(15));
+  ASSERT_TRUE(ranges.ContainsBlock(20));
+  ASSERT_TRUE(ranges.ContainsBlock(25));
+  ASSERT_TRUE(ranges.ContainsBlock(29));
+  ASSERT_FALSE(ranges.ContainsBlock(30));
+  ASSERT_FALSE(ranges.ContainsBlock(9));
+}
+
+TEST(ExtentRangesTest, OverlapsWithExtentSameStart) {
+  ExtentRanges ranges{false};
+  ranges.AddExtent(ExtentForRange(5, 4));
+  ranges.AddExtent(ExtentForRange(10, 5));
+  ranges.AddExtent(ExtentForRange(15, 5));
+  ranges.AddExtent(ExtentForRange(20, 5));
+  ranges.AddExtent(ExtentForRange(25, 5));
+
+  ASSERT_TRUE(ranges.OverlapsWithExtent(ExtentForRange(9, 2)));
+  ASSERT_TRUE(ranges.OverlapsWithExtent(ExtentForRange(12, 5)));
+  ASSERT_TRUE(ranges.OverlapsWithExtent(ExtentForRange(14, 5)));
+  ASSERT_TRUE(ranges.OverlapsWithExtent(ExtentForRange(10, 9)));
+  ASSERT_TRUE(ranges.OverlapsWithExtent(ExtentForRange(11, 20)));
+  ASSERT_FALSE(ranges.OverlapsWithExtent(ExtentForRange(0, 5)));
+  ASSERT_FALSE(ranges.OverlapsWithExtent(ExtentForRange(30, 20)));
+  ASSERT_FALSE(ranges.OverlapsWithExtent(ExtentForRange(9, 1)));
+
+  ranges.SubtractExtent(ExtentForRange(12, 5));
+  ASSERT_FALSE(ranges.OverlapsWithExtent(ExtentForRange(12, 5)));
+  ASSERT_FALSE(ranges.OverlapsWithExtent(ExtentForRange(13, 3)));
+  ASSERT_FALSE(ranges.OverlapsWithExtent(ExtentForRange(15, 2)));
+  ASSERT_TRUE(ranges.OverlapsWithExtent(ExtentForRange(14, 5)));
+  ASSERT_TRUE(ranges.OverlapsWithExtent(ExtentForRange(17, 1)));
+  ASSERT_TRUE(ranges.OverlapsWithExtent(ExtentForRange(8, 5)));
+  ASSERT_TRUE(ranges.OverlapsWithExtent(ExtentForRange(8, 4)));
+}
+
 }  // namespace chromeos_update_engine