28
28
*/
29
29
30
30
#include < map>
31
- #include < scoped_allocator>
32
31
#include < vector>
33
32
34
33
#include " mongo/base/string_data.h"
40
39
41
40
namespace mongo ::tracking {
42
41
43
- class AllocatorTest : public unittest ::Test {};
42
+ class AllocatorTest : public unittest ::Test {
43
+ protected:
44
+ class MockClass {
45
+ private:
46
+ int64_t u;
47
+ int64_t v;
48
+ int64_t w;
49
+ int64_t x;
50
+ int64_t y;
51
+ int64_t z;
52
+ };
53
+ };
44
54
45
55
TEST_F (AllocatorTest, STLContainerSimple) {
46
56
#if _ITERATOR_DEBUG_LEVEL >= 2
@@ -186,16 +196,6 @@ TEST_F(AllocatorTest, STLContainerNested) {
186
196
}
187
197
188
198
TEST_F (AllocatorTest, ManagedObject) {
189
- class MockClass {
190
- private:
191
- int64_t u;
192
- int64_t v;
193
- int64_t w;
194
- int64_t x;
195
- int64_t y;
196
- int64_t z;
197
- };
198
-
199
199
Context Context;
200
200
ASSERT_EQ (0 , Context.allocated ());
201
201
@@ -214,4 +214,103 @@ TEST_F(AllocatorTest, ManagedObject) {
214
214
ASSERT_EQ (0 , Context.allocated ());
215
215
}
216
216
217
+ TEST_F (AllocatorTest, TrackOwnedObjectNull) {
218
+ Context Context;
219
+ ASSERT_EQ (0 , Context.allocated ());
220
+
221
+ {
222
+ unique_ptr<MockClass> mockClass = tracking::unique_ptr<MockClass>(Context, nullptr );
223
+ ASSERT_EQ (0 , Context.allocated ());
224
+ }
225
+
226
+ ASSERT_EQ (0 , Context.allocated ());
227
+ }
228
+
229
+ TEST_F (AllocatorTest, TrackOwnedObjectMoveConstruction) {
230
+ Context Context;
231
+ ASSERT_EQ (0 , Context.allocated ());
232
+
233
+ {
234
+ unique_ptr<MockClass> mockClass1 = tracking::make_unique<MockClass>(Context);
235
+ auto allocatedMemory = Context.allocated ();
236
+ ASSERT_GTE (allocatedMemory, sizeof (MockClass));
237
+
238
+ // Allocation doesn't increase by moving.
239
+ unique_ptr<MockClass> mockClass2 (std::move (mockClass1));
240
+ ASSERT_EQ (Context.allocated (), allocatedMemory);
241
+ }
242
+
243
+ ASSERT_EQ (0 , Context.allocated ());
244
+ }
245
+
246
+ TEST_F (AllocatorTest, TrackOwnedObjectMoveAssignment) {
247
+ Context Context1;
248
+ Context Context2;
249
+ Context Context3;
250
+ ASSERT_EQ (0 , Context1.allocated ());
251
+ ASSERT_EQ (0 , Context2.allocated ());
252
+ ASSERT_EQ (0 , Context3.allocated ());
253
+
254
+ {
255
+ unique_ptr<MockClass> mockClass1 = tracking::make_unique<MockClass>(Context1);
256
+ unique_ptr<MockClass> mockClass2 = tracking::make_unique<MockClass>(Context2);
257
+ ASSERT_GTE (Context1.allocated (), sizeof (MockClass));
258
+ auto allocatedMemory2 = Context2.allocated ();
259
+ ASSERT_GTE (allocatedMemory2, sizeof (MockClass));
260
+
261
+ // mockClass1 deallocates the original object and takes over mockClass2's allocator.
262
+ mockClass1 = std::move (mockClass2);
263
+ ASSERT_EQ (0 , Context1.allocated ());
264
+ // Allocation doesn't increase by moving.
265
+ ASSERT_EQ (Context2.allocated (), allocatedMemory2);
266
+
267
+ // mockClass1 deallocates the object from mockClass2 and takes over mockClass3's allocator.
268
+ unique_ptr<MockClass> mockClass3 = tracking::make_unique<MockClass>(Context3);
269
+ auto allocatedMemory3 = Context3.allocated ();
270
+ ASSERT_GTE (allocatedMemory3, sizeof (MockClass));
271
+ mockClass1 = std::move (mockClass3);
272
+ ASSERT_EQ (0 , Context1.allocated ());
273
+ ASSERT_EQ (0 , Context2.allocated ());
274
+ // Allocation doesn't increase by moving.
275
+ ASSERT_EQ (Context3.allocated (), allocatedMemory3);
276
+ }
277
+
278
+ ASSERT_EQ (0 , Context1.allocated ());
279
+ ASSERT_EQ (0 , Context2.allocated ());
280
+ ASSERT_EQ (0 , Context3.allocated ());
281
+
282
+ {
283
+ unique_ptr<MockClass> mockClass1 = tracking::unique_ptr<MockClass>(Context1, nullptr );
284
+ unique_ptr<MockClass> mockClass2 = tracking::make_unique<MockClass>(Context2);
285
+ ASSERT_EQ (0 , Context1.allocated ());
286
+ ASSERT_GTE (Context2.allocated (), sizeof (MockClass));
287
+
288
+ // mockClass1 deallocates the original object and takes over mockClass2's allocator.
289
+ mockClass1 = std::move (mockClass2);
290
+ ASSERT_EQ (0 , Context1.allocated ());
291
+ ASSERT_GTE (Context2.allocated (), sizeof (MockClass));
292
+ }
293
+
294
+ ASSERT_EQ (0 , Context1.allocated ());
295
+ ASSERT_EQ (0 , Context2.allocated ());
296
+ ASSERT_EQ (0 , Context3.allocated ());
297
+ }
298
+
299
+ TEST_F (AllocatorTest, TrackOwnedObjectRelease) {
300
+ Context Context;
301
+ ASSERT_EQ (0 , Context.allocated ());
302
+
303
+ {
304
+ unique_ptr<MockClass> mockClass = tracking::make_unique<MockClass>(Context);
305
+ ASSERT_GTE (Context.allocated (), sizeof (MockClass));
306
+
307
+ MockClass* rawMockClass = mockClass.release ();
308
+ ASSERT_GTE (Context.allocated (), sizeof (MockClass));
309
+
310
+ delete rawMockClass;
311
+ }
312
+
313
+ // The memory is no longer tracked after the pointer is released.
314
+ ASSERT_GTE (Context.allocated (), sizeof (MockClass));
315
+ }
217
316
} // namespace mongo::tracking
0 commit comments