From 8f23757ad42352f57db0b2ab9fc8b6e92eeaedd9 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Sun, 26 Mar 2017 13:36:49 -0700 Subject: Move parse_range() and range_overlaps() into RangeSet. Also move RangeSet into a header file to make it testable, and add unit tests. In RangeSet::Parse() (the former parse_range()), use libbase logging to do assertions. This has the same effect as the previous exit(EXIT_FAILURE) to terminate the updater process and abort an update. The difference lies in the exit status code (i.e. WEXITSTATUS(status) in install.cpp), which changes from 1 (i.e. EXIT_FAILURE) to 0. Test: recovery_unit_test Test: Apply an incremental update with the new updater. Change-Id: Ie8393c78b0d8ae0fd5f0ca0646d871308d71fff0 --- tests/unit/rangeset_test.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/unit/rangeset_test.cpp (limited to 'tests/unit/rangeset_test.cpp') diff --git a/tests/unit/rangeset_test.cpp b/tests/unit/rangeset_test.cpp new file mode 100644 index 000000000..e66da20e4 --- /dev/null +++ b/tests/unit/rangeset_test.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include + +#include "updater/rangeset.h" + +TEST(RangeSetTest, Parse_smoke) { + RangeSet rs = RangeSet::Parse("2,1,10"); + ASSERT_EQ(static_cast(1), rs.count); + ASSERT_EQ((std::vector{ 1, 10 }), rs.pos); + ASSERT_EQ(static_cast(9), rs.size); + + RangeSet rs2 = RangeSet::Parse("4,15,20,1,10"); + ASSERT_EQ(static_cast(2), rs2.count); + ASSERT_EQ((std::vector{ 15, 20, 1, 10 }), rs2.pos); + ASSERT_EQ(static_cast(14), rs2.size); + + // Leading zeros are fine. But android::base::ParseUint() doesn't like trailing zeros like "10 ". + ASSERT_EQ(rs, RangeSet::Parse(" 2, 1, 10")); + ASSERT_EXIT(RangeSet::Parse("2,1,10 "), ::testing::KilledBySignal(SIGABRT), ""); +} + +TEST(RangeSetTest, Parse_InvalidCases) { + // Insufficient number of tokens. + ASSERT_EXIT(RangeSet::Parse(""), ::testing::KilledBySignal(SIGABRT), ""); + ASSERT_EXIT(RangeSet::Parse("2,1"), ::testing::KilledBySignal(SIGABRT), ""); + + // The first token (i.e. the number of following tokens) is invalid. + ASSERT_EXIT(RangeSet::Parse("a,1,1"), ::testing::KilledBySignal(SIGABRT), ""); + ASSERT_EXIT(RangeSet::Parse("3,1,1"), ::testing::KilledBySignal(SIGABRT), ""); + ASSERT_EXIT(RangeSet::Parse("-3,1,1"), ::testing::KilledBySignal(SIGABRT), ""); + ASSERT_EXIT(RangeSet::Parse("2,1,2,3"), ::testing::KilledBySignal(SIGABRT), ""); + + // Invalid tokens. + ASSERT_EXIT(RangeSet::Parse("2,1,10a"), ::testing::KilledBySignal(SIGABRT), ""); + ASSERT_EXIT(RangeSet::Parse("2,,10"), ::testing::KilledBySignal(SIGABRT), ""); + + // Empty or negative range. + ASSERT_EXIT(RangeSet::Parse("2,2,2"), ::testing::KilledBySignal(SIGABRT), ""); + ASSERT_EXIT(RangeSet::Parse("2,2,1"), ::testing::KilledBySignal(SIGABRT), ""); +} + +TEST(RangeSetTest, Overlaps) { + RangeSet r1 = RangeSet::Parse("2,1,6"); + RangeSet r2 = RangeSet::Parse("2,5,10"); + ASSERT_TRUE(r1.Overlaps(r2)); + ASSERT_TRUE(r2.Overlaps(r1)); + + r2 = RangeSet::Parse("2,6,10"); + ASSERT_FALSE(r1.Overlaps(r2)); + ASSERT_FALSE(r2.Overlaps(r1)); + + ASSERT_FALSE(RangeSet::Parse("2,3,5").Overlaps(RangeSet::Parse("2,5,7"))); + ASSERT_FALSE(RangeSet::Parse("2,5,7").Overlaps(RangeSet::Parse("2,3,5"))); +} + +TEST(RangeSetTest, GetBlockNumber) { + RangeSet rs = RangeSet::Parse("2,1,10"); + ASSERT_EQ(static_cast(1), rs.GetBlockNumber(0)); + ASSERT_EQ(static_cast(6), rs.GetBlockNumber(5)); + ASSERT_EQ(static_cast(9), rs.GetBlockNumber(8)); + + // Out of bound. + ASSERT_EXIT(rs.GetBlockNumber(9), ::testing::KilledBySignal(SIGABRT), ""); +} -- cgit v1.2.3 From bf5b77dbf73eef715bb49b43e113833efbcb2994 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Thu, 30 Mar 2017 16:57:29 -0700 Subject: Change the internal representation in RangeSet. This CL makes the following changes to RangeSet: - Uses std::pair to represent a Range; - Uses std::vector to represent a RangeSet; - Provides const iterators (forward and reverse); - Provides const accessor; - 'blocks()' returns the number of blocks (formerly 'size'); - 'size()' returns the number of Range's (formerly 'count'). Test: recovery_unit_test Test: Apply an incremental update with the new updater. Change-Id: Ia1fbb343370a152e1f7aa050cf914c2da09b1396 --- tests/unit/rangeset_test.cpp | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'tests/unit/rangeset_test.cpp') diff --git a/tests/unit/rangeset_test.cpp b/tests/unit/rangeset_test.cpp index e66da20e4..3c6d77ef5 100644 --- a/tests/unit/rangeset_test.cpp +++ b/tests/unit/rangeset_test.cpp @@ -25,14 +25,15 @@ TEST(RangeSetTest, Parse_smoke) { RangeSet rs = RangeSet::Parse("2,1,10"); - ASSERT_EQ(static_cast(1), rs.count); - ASSERT_EQ((std::vector{ 1, 10 }), rs.pos); - ASSERT_EQ(static_cast(9), rs.size); + ASSERT_EQ(static_cast(1), rs.size()); + ASSERT_EQ((Range{ 1, 10 }), rs[0]); + ASSERT_EQ(static_cast(9), rs.blocks()); RangeSet rs2 = RangeSet::Parse("4,15,20,1,10"); - ASSERT_EQ(static_cast(2), rs2.count); - ASSERT_EQ((std::vector{ 15, 20, 1, 10 }), rs2.pos); - ASSERT_EQ(static_cast(14), rs2.size); + ASSERT_EQ(static_cast(2), rs2.size()); + ASSERT_EQ((Range{ 15, 20 }), rs2[0]); + ASSERT_EQ((Range{ 1, 10 }), rs2[1]); + ASSERT_EQ(static_cast(14), rs2.blocks()); // Leading zeros are fine. But android::base::ParseUint() doesn't like trailing zeros like "10 ". ASSERT_EQ(rs, RangeSet::Parse(" 2, 1, 10")); @@ -82,3 +83,30 @@ TEST(RangeSetTest, GetBlockNumber) { // Out of bound. ASSERT_EXIT(rs.GetBlockNumber(9), ::testing::KilledBySignal(SIGABRT), ""); } + +TEST(RangeSetTest, equality) { + ASSERT_EQ(RangeSet::Parse("2,1,6"), RangeSet::Parse("2,1,6")); + + ASSERT_NE(RangeSet::Parse("2,1,6"), RangeSet::Parse("2,1,7")); + ASSERT_NE(RangeSet::Parse("2,1,6"), RangeSet::Parse("2,2,7")); + + // The orders of Range's matter. "4,1,5,8,10" != "4,8,10,1,5". + ASSERT_NE(RangeSet::Parse("4,1,5,8,10"), RangeSet::Parse("4,8,10,1,5")); +} + +TEST(RangeSetTest, iterators) { + RangeSet rs = RangeSet::Parse("4,1,5,8,10"); + std::vector ranges; + for (const auto& range : rs) { + ranges.push_back(range); + } + ASSERT_EQ((std::vector{ Range{ 1, 5 }, Range{ 8, 10 } }), ranges); + + ranges.clear(); + + // Reverse iterators. + for (auto it = rs.crbegin(); it != rs.crend(); it++) { + ranges.push_back(*it); + } + ASSERT_EQ((std::vector{ Range{ 8, 10 }, Range{ 1, 5 } }), ranges); +} -- cgit v1.2.3