1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)# found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)"""This unittest covers both file_storage and serialization modules.""" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import os 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import tempfile 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import time 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import unittest 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from memory_inspector.core import memory_map 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from memory_inspector.core import native_heap 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from memory_inspector.core import stacktrace 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from memory_inspector.core import symbol 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from memory_inspector.data import file_storage 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class FileStorageTest(unittest.TestCase): 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def setUp(self): 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage_path = tempfile.mkdtemp() 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage = file_storage.Storage(self._storage_path) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def tearDown(self): 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) os.removedirs(self._storage_path) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def testSettings(self): 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings_1 = { 'foo' : 1, 'bar' : 2 } 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings_2 = { 'foo' : 1, 'bar' : 2 } 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.StoreSettings('one', settings_1) 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.StoreSettings('two', settings_2) 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._DeepCompare(settings_1, self._storage.LoadSettings('one')) 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._DeepCompare(settings_2, self._storage.LoadSettings('two')) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.StoreSettings('one', {}) 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.StoreSettings('two', {}) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def testArchives(self): 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.OpenArchive('foo', create=True) 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.OpenArchive('bar', create=True) 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.OpenArchive('baz', create=True) 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.DeleteArchive('bar') 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertTrue('foo' in self._storage.ListArchives()) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertFalse('bar' in self._storage.ListArchives()) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertTrue('baz' in self._storage.ListArchives()) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.DeleteArchive('foo') 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.DeleteArchive('baz') 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def testSnapshots(self): 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive = self._storage.OpenArchive('snapshots', create=True) 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) t1 = archive.StartNewSnapshot() 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive.StoreMemMaps(memory_map.Map()) 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) time.sleep(0.01) # Max snapshot resolution is in the order of usecs. 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) t2 = archive.StartNewSnapshot() 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive.StoreMemMaps(memory_map.Map()) 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive.StoreNativeHeap(native_heap.NativeHeap()) 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertIn(t1, archive.ListSnapshots()) 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertIn(t2, archive.ListSnapshots()) 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertTrue(archive.HasMemMaps(t1)) 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertFalse(archive.HasNativeHeap(t1)) 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertTrue(archive.HasMemMaps(t2)) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertTrue(archive.HasNativeHeap(t2)) 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.DeleteArchive('snapshots') 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def testMmap(self): 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive = self._storage.OpenArchive('mmap', create=True) 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) timestamp = archive.StartNewSnapshot() 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) mmap = memory_map.Map() 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) map_entry1 = memory_map.MapEntry(4096, 8191, 'rw--', '/foo', 0) 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) map_entry2 = memory_map.MapEntry(65536, 81919, 'rw--', '/bar', 4096) 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) map_entry2.resident_pages = [5] 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) mmap.Add(map_entry1) 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) mmap.Add(map_entry2) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive.StoreMemMaps(mmap) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) mmap_deser = archive.LoadMemMaps(timestamp) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._DeepCompare(mmap, mmap_deser) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.DeleteArchive('mmap') 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def testNativeHeap(self): 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive = self._storage.OpenArchive('nheap', create=True) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) timestamp = archive.StartNewSnapshot() 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) nh = native_heap.NativeHeap() 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for i in xrange(1, 4): 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stack_trace = stacktrace.Stacktrace() 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame = nh.GetStackFrame(i * 10 + 1) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame.SetExecFileInfo('foo.so', 1) 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stack_trace.Add(frame) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame = nh.GetStackFrame(i * 10 + 2) 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame.SetExecFileInfo('bar.so', 2) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stack_trace.Add(frame) 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nh.Add(native_heap.Allocation(size=i * 10, 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stack_trace=stack_trace, 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci start=i * 20, 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci flags=i * 30)) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive.StoreNativeHeap(nh) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) nh_deser = archive.LoadNativeHeap(timestamp) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._DeepCompare(nh, nh_deser) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.DeleteArchive('nheap') 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def testSymbols(self): 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive = self._storage.OpenArchive('symbols', create=True) 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) symbols = symbol.Symbols() 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # Symbol db is global per archive, no need to StartNewSnapshot. 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) symbols.Add('foo.so', 1, symbol.Symbol('sym1', 'file1.c', 11)) 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) symbols.Add('bar.so', 2, symbol.Symbol('sym2', 'file2.c', 12)) 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sym3 = symbol.Symbol('sym3', 'file2.c', 13) 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sym3.AddSourceLineInfo('outer_file.c', 23) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) symbols.Add('baz.so', 3, sym3) 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) archive.StoreSymbols(symbols) 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) symbols_deser = archive.LoadSymbols() 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._DeepCompare(symbols, symbols_deser) 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._storage.DeleteArchive('symbols') 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def _DeepCompare(self, a, b, prefix=''): 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) """Recursively compares two objects (original and deserialized).""" 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertEqual(a is None, b is None) 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if a is None: 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci _BASICTYPES = (long, int, basestring, float) 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if isinstance(a, _BASICTYPES) and isinstance(b, _BASICTYPES): 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return self.assertEqual(a, b, prefix) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertEqual(type(a), type(b), prefix + ' type (%s vs %s' % ( 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) type(a), type(b))) 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if isinstance(a, list): 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertEqual(len(a), len(b), prefix + ' len (%d vs %d)' % ( 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) len(a), len(b))) 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for i in range(len(a)): 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._DeepCompare(a[i], b[i], prefix + '[%d]' % i) 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if isinstance(a, dict): 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertEqual(a.keys(), b.keys(), prefix + ' keys (%s vs %s)' % ( 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) str(a.keys()), str(b.keys()))) 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for k in a.iterkeys(): 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._DeepCompare(a[k], b[k], prefix + '.' + str(k)) 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return self._DeepCompare(a.__dict__, b.__dict__, prefix)