| Index: extent_ranges_unittest.cc
|
| diff --git a/extent_ranges_unittest.cc b/extent_ranges_unittest.cc
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..b5a32d96a6501688df198ca0aa96c18d1c7ee492
|
| --- /dev/null
|
| +++ b/extent_ranges_unittest.cc
|
| @@ -0,0 +1,237 @@
|
| +// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <vector>
|
| +
|
| +#include <gtest/gtest.h>
|
| +
|
| +#include "update_engine/extent_ranges.h"
|
| +#include "update_engine/test_utils.h"
|
| +
|
| +using std::vector;
|
| +
|
| +namespace chromeos_update_engine {
|
| +
|
| +class ExtentRangesTest : public ::testing::Test {};
|
| +
|
| +namespace {
|
| +void ExpectRangeEq(const ExtentRanges& ranges,
|
| + uint64_t* expected,
|
| + size_t sz,
|
| + int line) {
|
| + uint64_t blocks = 0;
|
| + for (size_t i = 1; i < sz; i += 2) {
|
| + blocks += expected[i];
|
| + }
|
| + EXPECT_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;
|
| + ++it;
|
| + }
|
| +}
|
| +
|
| +#define EXPECT_RANGE_EQ(ranges, var) \
|
| + do { \
|
| + ExpectRangeEq(ranges, var, arraysize(var), __LINE__); \
|
| + } while (0)
|
| +
|
| +void ExpectRangesOverlapOrTouch(uint64_t a_start, uint64_t a_num,
|
| + uint64_t b_start, uint64_t b_num) {
|
| + EXPECT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(ExtentForRange(a_start,
|
| + a_num),
|
| + ExtentForRange(b_start,
|
| + b_num)));
|
| + EXPECT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(ExtentForRange(b_start,
|
| + b_num),
|
| + ExtentForRange(a_start,
|
| + a_num)));
|
| +}
|
| +
|
| +void ExpectFalseRangesOverlapOrTouch(uint64_t a_start, uint64_t a_num,
|
| + uint64_t b_start, uint64_t b_num) {
|
| + EXPECT_FALSE(ExtentRanges::ExtentsOverlapOrTouch(ExtentForRange(a_start,
|
| + a_num),
|
| + ExtentForRange(b_start,
|
| + b_num)));
|
| + EXPECT_FALSE(ExtentRanges::ExtentsOverlapOrTouch(ExtentForRange(b_start,
|
| + b_num),
|
| + ExtentForRange(a_start,
|
| + a_num)));
|
| + EXPECT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(a_start,
|
| + a_num),
|
| + ExtentForRange(b_start,
|
| + b_num)));
|
| + EXPECT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(b_start,
|
| + b_num),
|
| + ExtentForRange(a_start,
|
| + a_num)));
|
| +}
|
| +
|
| +void ExpectRangesOverlap(uint64_t a_start, uint64_t a_num,
|
| + uint64_t b_start, uint64_t b_num) {
|
| + EXPECT_TRUE(ExtentRanges::ExtentsOverlap(ExtentForRange(a_start,
|
| + a_num),
|
| + ExtentForRange(b_start,
|
| + b_num)));
|
| + EXPECT_TRUE(ExtentRanges::ExtentsOverlap(ExtentForRange(b_start,
|
| + b_num),
|
| + ExtentForRange(a_start,
|
| + a_num)));
|
| + EXPECT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(ExtentForRange(a_start,
|
| + a_num),
|
| + ExtentForRange(b_start,
|
| + b_num)));
|
| + EXPECT_TRUE(ExtentRanges::ExtentsOverlapOrTouch(ExtentForRange(b_start,
|
| + b_num),
|
| + ExtentForRange(a_start,
|
| + a_num)));
|
| +}
|
| +
|
| +void ExpectFalseRangesOverlap(uint64_t a_start, uint64_t a_num,
|
| + uint64_t b_start, uint64_t b_num) {
|
| + EXPECT_FALSE(ExtentRanges::ExtentsOverlap(ExtentForRange(a_start,
|
| + a_num),
|
| + ExtentForRange(b_start,
|
| + b_num)));
|
| + EXPECT_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);
|
| +}
|
| +
|
| +TEST(ExtentRangesTest, SimpleTest) {
|
| + ExtentRanges ranges;
|
| + {
|
| + uint64_t expected[] = {};
|
| + // Can't use arraysize() on 0-length arrays:
|
| + ExpectRangeEq(ranges, expected, 0, __LINE__);
|
| + }
|
| + ranges.SubtractBlock(2);
|
| + {
|
| + uint64_t expected[] = {};
|
| + // Can't use arraysize() on 0-length arrays:
|
| + ExpectRangeEq(ranges, expected, 0, __LINE__);
|
| + }
|
| +
|
| + ranges.AddBlock(0);
|
| + ranges.Dump();
|
| + ranges.AddBlock(1);
|
| + ranges.AddBlock(3);
|
| +
|
| + {
|
| + uint64_t expected[] = {0, 2, 3, 1};
|
| + EXPECT_RANGE_EQ(ranges, expected);
|
| + }
|
| + ranges.AddBlock(2);
|
| + {
|
| + uint64_t expected[] = {0, 4};
|
| + EXPECT_RANGE_EQ(ranges, expected);
|
| + }
|
| + ranges.SubtractBlock(2);
|
| + {
|
| + uint64_t expected[] = {0, 2, 3, 1};
|
| + EXPECT_RANGE_EQ(ranges, expected);
|
| + }
|
| +
|
| + for (uint64_t i = 100; i < 1000; i += 100) {
|
| + ranges.AddExtent(ExtentForRange(i, 50));
|
| + }
|
| + {
|
| + 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);
|
| + }
|
| +
|
| + ranges.SubtractExtent(ExtentForRange(210, 410 - 210));
|
| + {
|
| + 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);
|
| + }
|
| + ranges.AddExtent(ExtentForRange(100000, 0));
|
| + {
|
| + 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);
|
| + }
|
| + ranges.SubtractExtent(ExtentForRange(3, 0));
|
| + {
|
| + 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);
|
| + }
|
| +}
|
| +
|
| +TEST(ExtentRangesTest, MultipleRanges) {
|
| + ExtentRanges ranges_a, ranges_b;
|
| + ranges_a.AddBlock(0);
|
| + ranges_b.AddBlock(4);
|
| + ranges_b.AddBlock(3);
|
| + {
|
| + uint64_t expected[] = {3, 2};
|
| + EXPECT_RANGE_EQ(ranges_b, expected);
|
| + }
|
| + ranges_a.AddRanges(ranges_b);
|
| + {
|
| + uint64_t expected[] = {0, 1, 3, 2};
|
| + EXPECT_RANGE_EQ(ranges_a, expected);
|
| + }
|
| + ranges_a.SubtractRanges(ranges_b);
|
| + {
|
| + uint64_t expected[] = {0, 1};
|
| + EXPECT_RANGE_EQ(ranges_a, expected);
|
| + }
|
| + {
|
| + uint64_t expected[] = {3, 2};
|
| + EXPECT_RANGE_EQ(ranges_b, expected);
|
| + }
|
| +}
|
| +
|
| +TEST(ExtentRangesTest, GetExtentsForBlockCountTest) {
|
| + ExtentRanges ranges;
|
| + ranges.AddExtents(vector<Extent>(1, ExtentForRange(10, 30)));
|
| + {
|
| + vector<Extent> zero_extents = ranges.GetExtentsForBlockCount(0);
|
| + EXPECT_TRUE(zero_extents.empty());
|
| + }
|
| + ::google::protobuf::RepeatedPtrField<Extent> rep_field;
|
| + *rep_field.Add() = ExtentForRange(30, 40);
|
| + ranges.AddRepeatedExtents(rep_field);
|
| + ranges.SubtractExtents(vector<Extent>(1, ExtentForRange(20, 10)));
|
| + *rep_field.Mutable(0) = ExtentForRange(50, 10);
|
| + ranges.SubtractRepeatedExtents(rep_field);
|
| + EXPECT_EQ(40, ranges.blocks());
|
| +
|
| + for (int i = 0; i < 2; i++) {
|
| + vector<Extent> expected(2);
|
| + expected[0] = ExtentForRange(10, 10);
|
| + expected[1] = ExtentForRange(30, i == 0 ? 10 : 20);
|
| + vector<Extent> actual =
|
| + ranges.GetExtentsForBlockCount(10 + expected[1].num_blocks());
|
| + EXPECT_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())
|
| + << "j = " << j;
|
| + EXPECT_EQ(expected[j].num_blocks(), actual[j].num_blocks())
|
| + << "j = " << j;
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace chromeos_update_engine
|
|
|