blob: dcfec027a4381d7266af5937a50909f2f9948722 [file] [log] [blame]
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 "bloaty.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <tuple>
namespace bloaty {
class RangeMapTest : public ::testing::Test {
protected:
void CheckConsistencyFor(const bloaty::RangeMap& /*map*/) {
uint64_t last_end = 0;
for (const auto& entry : map_.mappings_) {
ASSERT_GT(entry.second.end, entry.first);
ASSERT_GE(entry.first, last_end);
}
}
void CheckConsistency() {
CheckConsistencyFor(map_);
CheckConsistencyFor(map2_);
}
typedef std::tuple<uint64_t, uint64_t, uint64_t, std::string> Entry;
void AssertMapEquals(const bloaty::RangeMap& map,
const std::vector<Entry>& entries) {
auto iter = map.mappings_.begin();
size_t i = 0;
for (; i < entries.size() && iter != map.mappings_.end(); ++i, ++iter) {
const auto& entry = entries[i];
ASSERT_EQ(std::get<0>(entry), iter->first) << i;
ASSERT_EQ(std::get<1>(entry), iter->second.end) << i;
ASSERT_EQ(std::get<2>(entry), iter->second.other_start) << i;
ASSERT_EQ(std::get<3>(entry), iter->second.label) << i;
}
ASSERT_EQ(i, entries.size());
ASSERT_EQ(iter, map.mappings_.end());
}
void AssertMainMapEquals(const std::vector<Entry>& entries) {
AssertMapEquals(map_, entries);
}
bloaty::RangeMap map_;
bloaty::RangeMap map2_;
bloaty::RangeMap map3_;
};
TEST_F(RangeMapTest, AddRange) {
CheckConsistency();
AssertMainMapEquals({});
map_.AddRange(4, 3, "foo");
CheckConsistency();
AssertMainMapEquals({
std::make_tuple(4, 7, UINT64_MAX, "foo")
});
map_.AddRange(30, 5, "bar");
CheckConsistency();
AssertMainMapEquals({
std::make_tuple(4, 7, UINT64_MAX, "foo"),
std::make_tuple(30, 35, UINT64_MAX, "bar")
});
map_.AddRange(50, 0, "baz"); // No-op due to 0 size.
CheckConsistency();
AssertMainMapEquals({
std::make_tuple(4, 7, UINT64_MAX, "foo"),
std::make_tuple(30, 35, UINT64_MAX, "bar")
});
map_.AddRange(20, 5, "baz");
map_.AddRange(25, 5, "baz2");
map_.AddRange(40, 5, "quux");
CheckConsistency();
AssertMainMapEquals({
std::make_tuple(4, 7, UINT64_MAX, "foo"),
std::make_tuple(20, 25, UINT64_MAX, "baz"),
std::make_tuple(25, 30, UINT64_MAX, "baz2"),
std::make_tuple(30, 35, UINT64_MAX, "bar"),
std::make_tuple(40, 45, UINT64_MAX, "quux")
});
map_.AddRange(21, 25, "overlapping");
CheckConsistency();
AssertMainMapEquals({
std::make_tuple(4, 7, UINT64_MAX, "foo"),
std::make_tuple(20, 25, UINT64_MAX, "baz"),
std::make_tuple(25, 30, UINT64_MAX, "baz2"),
std::make_tuple(30, 35, UINT64_MAX, "bar"),
std::make_tuple(35, 40, UINT64_MAX, "overlapping"),
std::make_tuple(40, 45, UINT64_MAX, "quux"),
std::make_tuple(45, 46, UINT64_MAX, "overlapping")
});
map_.AddRange(21, 25, "overlapping no-op");
CheckConsistency();
AssertMainMapEquals({
std::make_tuple(4, 7, UINT64_MAX, "foo"),
std::make_tuple(20, 25, UINT64_MAX, "baz"),
std::make_tuple(25, 30, UINT64_MAX, "baz2"),
std::make_tuple(30, 35, UINT64_MAX, "bar"),
std::make_tuple(35, 40, UINT64_MAX, "overlapping"),
std::make_tuple(40, 45, UINT64_MAX, "quux"),
std::make_tuple(45, 46, UINT64_MAX, "overlapping")
});
map_.AddRange(0, 100, "overlap everything");
CheckConsistency();
AssertMainMapEquals({
std::make_tuple(0, 4, UINT64_MAX, "overlap everything"),
std::make_tuple(4, 7, UINT64_MAX, "foo"),
std::make_tuple(7, 20, UINT64_MAX, "overlap everything"),
std::make_tuple(20, 25, UINT64_MAX, "baz"),
std::make_tuple(25, 30, UINT64_MAX, "baz2"),
std::make_tuple(30, 35, UINT64_MAX, "bar"),
std::make_tuple(35, 40, UINT64_MAX, "overlapping"),
std::make_tuple(40, 45, UINT64_MAX, "quux"),
std::make_tuple(45, 46, UINT64_MAX, "overlapping"),
std::make_tuple(46, 100, UINT64_MAX, "overlap everything"),
});
}
TEST_F(RangeMapTest, Translation) {
map_.AddDualRange(20, 5, 120, "foo");
CheckConsistency();
AssertMainMapEquals({
std::make_tuple(20, 25, 120, "foo")
});
map2_.AddRangeWithTranslation(15, 15, "translate me", map_, &map3_);
CheckConsistency();
AssertMapEquals(map2_, {
std::make_tuple(15, 30, UINT64_MAX, "translate me")
});
AssertMapEquals(map3_, {
std::make_tuple(120, 125, UINT64_MAX, "translate me")
});
map_.AddDualRange(1000, 30, 1100, "bar");
map2_.AddRangeWithTranslation(1000, 5, "translate me2", map_, &map3_);
AssertMapEquals(map2_, {
std::make_tuple(15, 30, UINT64_MAX, "translate me"),
std::make_tuple(1000, 1005, UINT64_MAX, "translate me2")
});
AssertMapEquals(map3_, {
std::make_tuple(120, 125, UINT64_MAX, "translate me"),
std::make_tuple(1100, 1105, UINT64_MAX, "translate me2")
});
}
TEST_F(RangeMapTest, Translation2) {
map_.AddRange(5, 5, "foo");
map_.AddDualRange(20, 5, 120, "bar");
map_.AddRange(25, 5, "baz");
map_.AddDualRange(30, 5, 130, "quux");
CheckConsistency();
AssertMainMapEquals({
std::make_tuple(5, 10, UINT64_MAX, "foo"),
std::make_tuple(20, 25, 120, "bar"),
std::make_tuple(25, 30, UINT64_MAX, "baz"),
std::make_tuple(30, 35, 130, "quux")
});
map2_.AddRangeWithTranslation(0, 50, "translate me", map_, &map3_);
CheckConsistency();
AssertMapEquals(map2_, {
std::make_tuple(0, 50, UINT64_MAX, "translate me")
});
AssertMapEquals(map3_, {
std::make_tuple(120, 125, UINT64_MAX, "translate me"),
std::make_tuple(130, 135, UINT64_MAX, "translate me")
});
}
} // namespace bloaty