1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 /** Unit tests for OwnedPointerMap. */
32 
33 #include "mongo/base/owned_pointer_map.h"
34 
35 #include <string>
36 #include <vector>
37 
38 #include "mongo/unittest/unittest.h"
39 
40 namespace mongo {
41 namespace {
42 
43 using std::make_pair;
44 using std::string;
45 
46 /** Helper class that logs its constructor argument to a static vector on destruction. */
47 class DestructionLogger {
48 public:
DestructionLogger(const string & name)49     DestructionLogger(const string& name) : _name(name) {}
~DestructionLogger()50     ~DestructionLogger() {
51         _destroyedNames.push_back(_name);
52     }
53 
destroyedNames()54     static std::vector<string>& destroyedNames() {
55         return _destroyedNames;
56     }
57 
getName()58     string getName() {
59         return _name;
60     }
61 
62 private:
63     string _name;
64     static std::vector<string> _destroyedNames;
65 };
66 
67 std::vector<string> DestructionLogger::_destroyedNames;
68 
TEST(OwnedPointerMapTest,OwnedPointerDestroyed)69 TEST(OwnedPointerMapTest, OwnedPointerDestroyed) {
70     DestructionLogger::destroyedNames().clear();
71     {
72         OwnedPointerMap<int, DestructionLogger> owned;
73         owned.mutableMap().insert(make_pair(0, new DestructionLogger("foo")));
74         // owned destroyed
75     }
76     ASSERT_EQUALS(1U, DestructionLogger::destroyedNames().size());
77     ASSERT_EQUALS("foo", DestructionLogger::destroyedNames()[0]);
78 }
79 
TEST(OwnedPointerMapTest,OwnedConstPointerDestroyed)80 TEST(OwnedPointerMapTest, OwnedConstPointerDestroyed) {
81     DestructionLogger::destroyedNames().clear();
82     {
83         OwnedPointerMap<int, const DestructionLogger> owned;
84         owned.mutableMap().insert(make_pair(0, new DestructionLogger("foo")));
85         // owned destroyed
86     }
87     ASSERT_EQUALS(1U, DestructionLogger::destroyedNames().size());
88     ASSERT_EQUALS("foo", DestructionLogger::destroyedNames()[0]);
89 }
90 
TEST(OwnedPointerMapTest,OwnedPointersDestroyedInOrder)91 TEST(OwnedPointerMapTest, OwnedPointersDestroyedInOrder) {
92     DestructionLogger::destroyedNames().clear();
93     {
94         OwnedPointerMap<int, DestructionLogger> owned;
95         owned.mutableMap().insert(make_pair(0, new DestructionLogger("first")));
96         owned.mutableMap().insert(make_pair(1, new DestructionLogger("second")));
97         // owned destroyed
98     }
99     ASSERT_EQUALS(2U, DestructionLogger::destroyedNames().size());
100     ASSERT_EQUALS("first", DestructionLogger::destroyedNames()[0]);
101     ASSERT_EQUALS("second", DestructionLogger::destroyedNames()[1]);
102 }
103 
TEST(OwnedPointerMapTest,OwnedPointersWithCompare)104 TEST(OwnedPointerMapTest, OwnedPointersWithCompare) {
105     DestructionLogger::destroyedNames().clear();
106     {
107         OwnedPointerMap<int, DestructionLogger, std::greater<int>> owned;
108         owned.mutableMap().insert(make_pair(0, new DestructionLogger("0")));
109         owned.mutableMap().insert(make_pair(1, new DestructionLogger("1")));
110 
111         // use std::greater<int> rather than the default std::less<int>
112         std::map<int, DestructionLogger*, std::greater<int>>::iterator it =
113             owned.mutableMap().begin();
114 
115         ASSERT(owned.mutableMap().end() != it);
116         // "1" should be sorted to be the first item.
117         ASSERT_EQUALS("1", it->second->getName());
118 
119         it++;
120         ASSERT(owned.mutableMap().end() != it);
121         ASSERT_EQUALS("0", it->second->getName());
122 
123         // owned destroyed
124     }
125     // destroyed in descending order
126     ASSERT_EQUALS(2U, DestructionLogger::destroyedNames().size());
127     ASSERT_EQUALS("1", DestructionLogger::destroyedNames()[0]);
128     ASSERT_EQUALS("0", DestructionLogger::destroyedNames()[1]);
129 }
130 
131 
132 }  // namespace
133 }  // namespace mongo
134