1
# Copyright (C) 2009, 2010 Canonical Ltd
3
# This program is free software: you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License version 3 as
5
# published by the Free Software Foundation.
7
# This program is distributed in the hope that it will be useful, but
8
# WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
# General Public License for more details.
12
# You should have received a copy of the GNU General Public License
13
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
"""Pyrex extension for tracking loaded objects"""
24
class TestMemObjectCollection(tests.TestCase):
26
def test__init__(self):
27
moc = _loader.MemObjectCollection()
28
self.assertEqual(0, moc._active)
29
self.assertEqual(0, moc._filled)
30
self.assertEqual(1023, moc._table_mask)
32
def test__lookup_direct(self):
33
moc = _loader.MemObjectCollection()
34
self.assertEqual(1023, moc._table_mask)
35
self.assertEqual(0, moc._test_lookup(0))
36
self.assertEqual(0, moc._test_lookup(1024))
37
self.assertEqual(255, moc._test_lookup(255))
38
self.assertEqual(933, moc._test_lookup(933))
39
self.assertEqual(933, moc._test_lookup(933+1024))
40
self.assertEqual(933, moc._test_lookup(933L+1024L))
41
self.assertEqual(933, moc._test_lookup(933L+2**32-1))
43
def test__len__(self):
44
moc = _loader.MemObjectCollection()
45
self.assertEqual(0, len(moc))
46
moc.add(0, 'foo', 100)
47
self.assertEqual(1, len(moc))
48
moc.add(1024, 'foo', 100)
49
self.assertEqual(2, len(moc))
51
self.assertEqual(1, len(moc))
53
self.assertEqual(0, len(moc))
55
def test__lookup_collide(self):
56
moc = _loader.MemObjectCollection()
57
self.assertEqual(1023, moc._table_mask)
58
self.assertEqual(0, moc._test_lookup(0))
59
self.assertEqual(0, moc._test_lookup(1024))
60
moc.add(0, 'foo', 100)
61
self.assertEqual(0, moc._test_lookup(0))
62
self.assertEqual(1, moc._test_lookup(1024))
63
moc.add(1024, 'bar', 200)
64
self.assertEqual(0, moc._test_lookup(0))
65
self.assertEqual(1, moc._test_lookup(1024))
67
def test__contains__(self):
68
moc = _loader.MemObjectCollection()
69
self.assertEqual(0, moc._test_lookup(0))
70
self.assertEqual(0, moc._test_lookup(1024))
71
self.assertFalse(0 in moc)
72
self.assertFalse(1024 in moc)
73
moc.add(0, 'foo', 100)
74
self.assertTrue(0 in moc)
75
self.assertFalse(1024 in moc)
76
moc.add(1024, 'bar', 200)
77
self.assertTrue(0 in moc)
78
self.assertTrue(1024 in moc)
80
def test__getitem__(self):
81
moc = _loader.MemObjectCollection()
84
self.assertRaises(KeyError, get, 0)
85
self.assertRaises(KeyError, get, 1024)
86
moc.add(0, 'foo', 100)
88
self.assertTrue(isinstance(mop, _loader._MemObjectProxy))
89
self.assertEqual('foo', mop.type_str)
90
self.assertEqual(100, mop.size)
91
self.assertRaises(KeyError, get, 1024)
92
self.assertTrue(mop is moc[mop])
95
moc = _loader.MemObjectCollection()
96
self.assertEqual(None, moc.get(0, None))
97
moc.add(0, 'foo', 100)
98
self.assertEqual(100, moc.get(0, None).size)
100
def test__delitem__(self):
101
moc = _loader.MemObjectCollection()
106
self.assertRaises(KeyError, delete, 0)
107
self.assertRaises(KeyError, delete, 1024)
108
moc.add(0, 'foo', 100)
109
self.assertTrue(0 in moc)
110
self.assertFalse(1024 in moc)
111
self.assertRaises(KeyError, delete, 1024)
112
moc.add(1024, 'bar', 200)
114
self.assertFalse(0 in moc)
115
self.assertRaises(KeyError, get, 0)
118
self.assertRaises(KeyError, get, 1024)
120
def test_add_until_resize(self):
121
moc = _loader.MemObjectCollection()
122
for i in xrange(1025):
123
moc.add(i, 'foo', 100+i)
124
self.assertEqual(1025, moc._filled)
125
self.assertEqual(1025, moc._active)
126
self.assertEqual(2047, moc._table_mask)
128
self.assertEqual(1024, mop.address)
129
self.assertEqual(1124, mop.size)
131
def test_itervalues_to_tip(self):
132
moc = _loader.MemObjectCollection()
133
moc.add(0, 'bar', 100)
134
moc.add(1024, 'baz', 102)
135
moc.add(512, 'bing', 104)
136
self.assertEqual([0, 1024, 512],
137
[x.address for x in moc.itervalues()])
139
self.assertEqual([1024, 512],
140
[x.address for x in moc.itervalues()])
141
moc.add(1023, 'booze', 103)
142
self.assertEqual([1024, 512, 1023],
143
[x.address for x in moc.itervalues()])
145
self.assertEqual([1024, 512],
146
[x.address for x in moc.itervalues()])
148
def test_items(self):
149
moc = _loader.MemObjectCollection()
150
moc.add(0, 'bar', 100)
151
moc.add(1024, 'baz', 102)
152
moc.add(512, 'bing', 103)
154
self.assertTrue(isinstance(items, list))
155
self.assertEqual([(0, 0), (1024, 1024), (512, 512)],
156
[(k, v.address) for k,v in items])
158
self.assertEqual([(1024, 1024), (512, 512)],
159
[(k, v.address) for k,v in moc.items()])
161
def test_iteritems(self):
162
moc = _loader.MemObjectCollection()
163
moc.add(0, 'bar', 100)
164
moc.add(1024, 'baz', 102)
165
moc.add(512, 'bing', 103)
166
self.assertEqual([(0, 0), (1024, 1024), (512, 512)],
167
[(k, v.address) for k,v in moc.iteritems()])
169
self.assertEqual([(1024, 1024), (512, 512)],
170
[(k, v.address) for k,v in moc.iteritems()])
173
moc = _loader.MemObjectCollection()
174
moc.add(0, 'bar', 100)
175
moc.add(1024, 'baz', 102)
176
moc.add(512, 'bing', 103)
178
self.assertTrue(isinstance(keys, list))
179
self.assertEqual([0, 1024, 512], keys)
181
self.assertEqual([1024, 512], moc.keys())
183
def test__iter__(self):
184
moc = _loader.MemObjectCollection()
185
moc.add(0, 'bar', 100)
186
moc.add(1024, 'baz', 102)
187
moc.add(512, 'bing', 103)
188
self.assertEqual([0, 1024, 512], list(moc))
189
self.assertEqual([0, 1024, 512], list(moc.iterkeys()))
191
self.assertEqual([1024, 512], list(moc))
192
self.assertEqual([1024, 512], list(moc.iterkeys()))
195
class Test_MemObjectProxy(tests.TestCase):
198
super(Test_MemObjectProxy, self).setUp()
199
self.moc = _loader.MemObjectCollection()
200
self.moc.add(1024, 'bar', 200)
201
self.moc.add(0, 'foo', 100)
202
self.moc.add(255, 'baz', 300)
205
def test_basic_proxy(self):
207
self.assertEqual(0, mop.address)
208
self.assertEqual('foo', mop.type_str)
209
self.assertEqual(100, mop.size)
211
self.assertEqual(1024, mop.size)
212
self.assertEqual(1024, self.moc[0].size)
213
self.assertEqual(0, len(mop))
215
def test_deleted_proxy(self):
218
self.assertEqual('foo', mop.type_str)
219
self.assertEqual(100, mop.size)
220
self.assertEqual(0, len(mop))
222
def test_value(self):
223
mop = self.moc.add(1234, 'type', 256, value='testval')
224
self.assertEqual('testval', mop.value)
226
self.assertEqual(None, mop.value)
228
self.assertEqual('a str', mop.value)
230
self.assertEqual('a str', mop.value)
232
def test_type_str(self):
233
mop = self.moc.add(1234, 'type', 256, value='testval')
234
self.assertEqual('type', mop.type_str)
235
mop.type_str = 'difftype'
236
self.assertEqual('difftype', mop.type_str)
239
mop = self.moc.add(1234, 'type', 256, name='the name')
240
# 'name' entries get mapped as value
241
self.assertEqual('the name', mop.value)
243
def test__intern_from_cache(self):
246
mop = self.moc.add(addr, 'my ' + ' type', 256)
247
mop._intern_from_cache(cache)
248
self.assertTrue(addr in cache)
249
self.assertTrue(mop.address is addr)
250
self.assertTrue(cache[addr] is addr)
252
self.assertTrue(mop.type_str is t)
254
mop = self.moc.add(1234566+1, 'my ' + ' ty' + 'pe', 256)
256
cache[addr876543] = addr876543
258
cache[addr654321] = addr654321
259
mop.children = [876542+1, 654320+1]
260
mop.parents = [876542+1, 654320+1]
261
self.assertFalse(mop.address is addr)
262
self.assertFalse(mop.type_str is t)
264
self.assertFalse(rl[0] is addr876543)
265
self.assertFalse(rl[1] is addr654321)
267
self.assertFalse(rl[0] is addr876543)
268
self.assertFalse(rl[1] is addr654321)
269
mop._intern_from_cache(cache)
270
self.assertTrue(mop.address is addr)
271
self.assertTrue(mop.type_str is t)
273
self.assertTrue(rl[0] is addr876543)
274
self.assertTrue(rl[1] is addr654321)
276
self.assertTrue(rfrs[0] is addr876543)
277
self.assertTrue(rfrs[1] is addr654321)
279
def test_children(self):
280
mop = self.moc.add(1234567, 'type', 256, children=[1, 2, 3])
281
self.assertEqual(3, len(mop))
282
self.assertEqual([1, 2, 3], mop.children)
283
mop.children = [87654321, 23456]
284
self.assertEqual([87654321, 23456], mop.children)
285
self.assertEqual(2, len(mop))
288
mop = self.moc.add(1234567, 'type', 256, children=[0, 255])
290
self.assertEqual([], mop0.c)
292
self.assertEqual(2, len(c))
293
self.assertEqual(0, c[0].address)
294
self.assertEqual(255, c[1].address)
296
def test_ref_list(self):
299
def log_warn(msg, klass, stacklevel=None):
300
logged.append((msg, klass, stacklevel))
301
old_func = warn.trap_warnings(log_warn)
303
mop = self.moc.add(1234567, 'type', 256, children=[1, 2, 3])
304
self.assertEqual(3, len(mop))
305
self.assertEqual(3, mop.num_refs)
306
self.assertEqual([('Attribute .num_refs deprecated.'
307
' Use len() instead.', DeprecationWarning, 3),
310
self.assertEqual([1, 2, 3], mop.ref_list)
311
self.assertEqual([('Attribute .ref_list deprecated.'
312
' Use .children instead.',
313
DeprecationWarning, 3),
315
mop.ref_list = [87654321, 23456]
316
self.assertEqual([('Attribute .ref_list deprecated.'
317
' Use .children instead.',
318
DeprecationWarning, 3),
320
self.assertEqual([87654321, 23456], mop.children)
321
self.assertEqual(2, len(mop))
323
warn.trap_warnings(old_func)
325
def test__getitem__(self):
326
mop = self.moc.add(1234567, 'type', 256, children=[0, 255])
327
self.assertEqual(2, len(mop))
328
self.assertEqual(2, len(list(mop)))
331
self.assertEqual([mop0, mop255], list(mop))
332
self.assertEqual(0, mop0.address)
333
self.assertEqual('foo', mop0.type_str)
334
self.assertEqual(255, mop255.address)
335
self.assertEqual('baz', mop255.type_str)
337
def test_total_size(self):
339
self.assertEqual(0, mop.total_size)
340
mop.total_size = 10245678
341
self.assertEqual(10245678, mop.total_size)
342
mop.total_size = (2**31+1)
343
self.assertEqual(2**31+1, mop.total_size)
345
def test_parents(self):
346
mop = self.moc.add(1234567, 'type', 256, children=[0, 255])
348
self.assertEqual((), mop0.parents)
349
self.assertEqual(0, mop0.num_parents)
350
mop255 = self.moc[255]
351
self.assertEqual((), mop255.parents)
352
self.assertEqual(0, mop255.num_parents)
353
mop0.parents = [1234567]
354
self.assertEqual(1, mop0.num_parents)
355
self.assertEqual([1234567], mop0.parents)
356
mop255.parents = [1234567]
357
self.assertEqual(1, mop255.num_parents)
358
self.assertEqual([1234567], mop255.parents)
361
mop = self.moc.add(1234567, 'type', 256, children=[0, 255])
363
self.assertEqual([], mop0.p)
364
mop0.parents = [1234567]
366
self.assertEqual(1, len(p))
367
self.assertEqual(mop, p[0])
369
def test_referrers(self):
370
mop = self.moc.add(1234567, 'type', 256, children=[0, 255])
371
# Referrers is deprecated
373
def log_warn(msg, klass, stacklevel=None):
374
logged.append((msg, klass, stacklevel))
375
old_func = warn.trap_warnings(log_warn)
378
self.assertEqual((), mop0.referrers)
379
self.assertEqual([('Attribute .referrers deprecated.'
380
' Use .parents instead.',
381
DeprecationWarning, 3)
383
mop0.referrers = [1234567]
384
self.assertEqual([('Attribute .referrers deprecated.'
385
' Use .parents instead.',
386
DeprecationWarning, 3)
388
self.assertEqual([1234567], mop0.parents)
390
self.assertEqual(1, mop0.num_referrers)
391
self.assertEqual([('Attribute .num_referrers deprecated.'
392
' Use .num_parents instead.',
393
DeprecationWarning, 3)
396
warn.trap_warnings(old_func)
398
def test_parents(self):
399
mop = self.moc.add(1234567, 'type', 256, children=[0, 255])
401
self.assertEqual((), mop0.parents)
402
self.assertEqual(0, mop0.num_parents)
403
mop255 = self.moc[255]
404
self.assertEqual((), mop255.parents)
405
self.assertEqual(0, mop255.num_parents)
406
mop0.parents = [1234567]
407
self.assertEqual(1, mop0.num_parents)
408
self.assertEqual([1234567], mop0.parents)
409
mop255.parents = [1234567]
410
self.assertEqual(1, mop255.num_parents)
411
self.assertEqual([1234567], mop255.parents)
413
def test__repr__(self):
414
mop = self.moc.add(1234, 'str', 24)
415
self.assertEqual('str(1234 24B)', repr(mop))
416
mop = self.moc.add(1235, 'tuple', 12, [4567, 8900])
417
self.assertEqual('tuple(1235 12B 2refs)', repr(mop))
418
mop = self.moc.add(1236, 'module', 12, [4568, 8900], name='named')
419
# TODO: Will we show the refs? If so, we will want to truncate
420
self.assertEqual("module(1236 12B 2refs 'named')", repr(mop))
421
mop = self.moc.add(1237, 'module', 12, range(20), name='named')
422
self.assertEqual("module(1237 12B 20refs 'named')", repr(mop))
423
mop = self.moc.add(1238, 'foo', 12, [10], parent_list=[20, 30])
424
self.assertEqual("foo(1238 12B 1refs 2par)", repr(mop))
425
mop = self.moc.add(1239, 'str', 24, value='teststr')
426
self.assertEqual("str(1239 24B 'teststr')", repr(mop))
427
# TODO: Will we want to truncate value?
428
mop.value = 'averylongstringwithmorestuff'
429
self.assertEqual("str(1239 24B 'averylongstringwithmorestuff')",
431
mop = self.moc.add(1240, 'int', 12, value=12345)
432
self.assertEqual('int(1240 12B 12345)', repr(mop))
434
self.assertEqual('int(1240 12B 12345 12.0Btot)', repr(mop))
435
mop.total_size = 1024
436
self.assertEqual('int(1240 12B 12345 1.0Ktot)', repr(mop))
437
mop.total_size = int(1024*1024*10.5)
438
self.assertEqual('int(1240 12B 12345 10.5Mtot)', repr(mop))
440
def test_expand_refs_as_dict(self):
441
self.moc.add(1, 'str', 25, value='a')
442
self.moc.add(2, 'int', 12, value=1)
443
mop = self.moc.add(3, 'dict', 140, children=[1, 2])
444
as_dict = mop.refs_as_dict()
445
self.assertEqual({'a': 1}, mop.refs_as_dict())
446
# It should even work if there is a 'trailing' entry, as after
447
# collapse, instances have the dict inline, and end with the reference
449
mop = self.moc.add(4, 'MyClass', 156, children=[2, 1, 8])
450
self.assertEqual({1: 'a'}, mop.refs_as_dict())