1 // Copyright 2016 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "client/simple_address_range_bag.h"
16 
17 #include "gtest/gtest.h"
18 #include "test/gtest_death.h"
19 
20 namespace crashpad {
21 namespace test {
22 namespace {
23 
TEST(SimpleAddressRangeBag,Entry)24 TEST(SimpleAddressRangeBag, Entry) {
25   using TestBag = TSimpleAddressRangeBag<15>;
26   TestBag bag;
27 
28   const TestBag::Entry* entry = TestBag::Iterator(bag).Next();
29   EXPECT_FALSE(entry);
30 
31   bag.Insert(reinterpret_cast<void*>(0x1000), 200);
32   entry = TestBag::Iterator(bag).Next();
33   ASSERT_TRUE(entry);
34   EXPECT_EQ(0x1000u, entry->base);
35   EXPECT_EQ(200u, entry->size);
36 
37   bag.Remove(reinterpret_cast<void*>(0x1000), 200);
38   EXPECT_FALSE(entry->is_active());
39   EXPECT_EQ(0u, entry->base);
40   EXPECT_EQ(0u, entry->size);
41 }
42 
TEST(SimpleAddressRangeBag,SimpleAddressRangeBag)43 TEST(SimpleAddressRangeBag, SimpleAddressRangeBag) {
44   SimpleAddressRangeBag bag;
45 
46   EXPECT_TRUE(bag.Insert(reinterpret_cast<void*>(0x1000), 10));
47   EXPECT_TRUE(bag.Insert(reinterpret_cast<void*>(0x2000), 20));
48   EXPECT_TRUE(bag.Insert(CheckedRange<uint64_t>(0x3000, 30)));
49 
50   EXPECT_EQ(3u, bag.GetCount());
51 
52   // Duplicates added too.
53   EXPECT_TRUE(bag.Insert(CheckedRange<uint64_t>(0x3000, 30)));
54   EXPECT_TRUE(bag.Insert(CheckedRange<uint64_t>(0x3000, 30)));
55   EXPECT_EQ(5u, bag.GetCount());
56 
57   // Can be removed 3 times, but not the 4th time.
58   EXPECT_TRUE(bag.Remove(CheckedRange<uint64_t>(0x3000, 30)));
59   EXPECT_TRUE(bag.Remove(CheckedRange<uint64_t>(0x3000, 30)));
60   EXPECT_TRUE(bag.Remove(CheckedRange<uint64_t>(0x3000, 30)));
61   EXPECT_EQ(2u, bag.GetCount());
62   EXPECT_FALSE(bag.Remove(CheckedRange<uint64_t>(0x3000, 30)));
63   EXPECT_EQ(2u, bag.GetCount());
64 
65   EXPECT_TRUE(bag.Remove(reinterpret_cast<void*>(0x1000), 10));
66   EXPECT_TRUE(bag.Remove(reinterpret_cast<void*>(0x2000), 20));
67   EXPECT_EQ(0u, bag.GetCount());
68 }
69 
TEST(SimpleAddressRangeBag,CopyAndAssign)70 TEST(SimpleAddressRangeBag, CopyAndAssign) {
71   TSimpleAddressRangeBag<10> bag;
72   EXPECT_TRUE(bag.Insert(CheckedRange<uint64_t>(1, 2)));
73   EXPECT_TRUE(bag.Insert(CheckedRange<uint64_t>(3, 4)));
74   EXPECT_TRUE(bag.Insert(CheckedRange<uint64_t>(5, 6)));
75   EXPECT_TRUE(bag.Remove(CheckedRange<uint64_t>(3, 4)));
76   EXPECT_EQ(bag.GetCount(), 2u);
77 
78   // Test copy.
79   TSimpleAddressRangeBag<10> bag_copy(bag);
80   EXPECT_EQ(bag_copy.GetCount(), 2u);
81   EXPECT_TRUE(bag_copy.Remove(CheckedRange<uint64_t>(1, 2)));
82   EXPECT_TRUE(bag_copy.Remove(CheckedRange<uint64_t>(5, 6)));
83   EXPECT_EQ(bag_copy.GetCount(), 0u);
84   EXPECT_EQ(bag.GetCount(), 2u);
85 
86   // Test assign.
87   TSimpleAddressRangeBag<10> bag_assign;
88   bag_assign = bag;
89   EXPECT_EQ(bag_assign.GetCount(), 2u);
90   EXPECT_TRUE(bag_assign.Remove(CheckedRange<uint64_t>(1, 2)));
91   EXPECT_TRUE(bag_assign.Remove(CheckedRange<uint64_t>(5, 6)));
92   EXPECT_EQ(bag_assign.GetCount(), 0u);
93   EXPECT_EQ(bag.GetCount(), 2u);
94 }
95 
96 // Running out of space shouldn't crash.
TEST(SimpleAddressRangeBag,OutOfSpace)97 TEST(SimpleAddressRangeBag, OutOfSpace) {
98   TSimpleAddressRangeBag<2> bag;
99   EXPECT_TRUE(bag.Insert(CheckedRange<uint64_t>(1, 2)));
100   EXPECT_TRUE(bag.Insert(CheckedRange<uint64_t>(3, 4)));
101   EXPECT_FALSE(bag.Insert(CheckedRange<uint64_t>(5, 6)));
102   EXPECT_EQ(bag.GetCount(), 2u);
103   EXPECT_FALSE(bag.Remove(CheckedRange<uint64_t>(5, 6)));
104 }
105 
106 }  // namespace
107 }  // namespace test
108 }  // namespace crashpad
109