file_storage_unittest.py revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson# Copyright 2014 The Chromium Authors. All rights reserved. 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson# Use of this source code is governed by a BSD-style license that can be 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson# found in the LICENSE file. 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson"""This unittest covers both file_storage and serialization modules.""" 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport os 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport tempfile 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport time 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport unittest 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonfrom memory_inspector.core import memory_map 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonfrom memory_inspector.core import native_heap 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonfrom memory_inspector.core import stacktrace 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonfrom memory_inspector.core import symbol 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonfrom memory_inspector.data import file_storage 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonclass FileStorageTest(unittest.TestCase): 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson def setUp(self): 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage_path = tempfile.mkdtemp() 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage = file_storage.Storage(self._storage_path) 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson def tearDown(self): 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson os.removedirs(self._storage_path) 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson def testSettings(self): 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson settings_1 = { 'foo' : 1, 'bar' : 2 } 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson settings_2 = { 'foo' : 1, 'bar' : 2 } 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.StoreSettings('one', settings_1) 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.StoreSettings('two', settings_2) 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._DeepCompare(settings_1, self._storage.LoadSettings('one')) 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._DeepCompare(settings_2, self._storage.LoadSettings('two')) 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.StoreSettings('one', {}) 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.StoreSettings('two', {}) 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson def testArchives(self): 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.OpenArchive('foo', create=True) 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.OpenArchive('bar', create=True) 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.OpenArchive('baz', create=True) 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.DeleteArchive('bar') 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self.assertTrue('foo' in self._storage.ListArchives()) 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self.assertFalse('bar' in self._storage.ListArchives()) 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self.assertTrue('baz' in self._storage.ListArchives()) 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.DeleteArchive('foo') 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self._storage.DeleteArchive('baz') 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson def testSnapshots(self): 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson archive = self._storage.OpenArchive('snapshots', create=True) 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson t1 = archive.StartNewSnapshot() 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson archive.StoreMemMaps(memory_map.Map()) 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson time.sleep(0.01) # Max snapshot resolution is in the order of usecs. 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson t2 = archive.StartNewSnapshot() 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson archive.StoreMemMaps(memory_map.Map()) 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson archive.StoreNativeHeap(native_heap.NativeHeap()) 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self.assertIn(t1, archive.ListSnapshots()) 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self.assertIn(t2, archive.ListSnapshots()) 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self.assertTrue(archive.HasMemMaps(t1)) 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self.assertFalse(archive.HasNativeHeap(t1)) 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self.assertTrue(archive.HasMemMaps(t2)) 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson self.assertTrue(archive.HasNativeHeap(t2)) 62 self._storage.DeleteArchive('snapshots') 63 64 def testMmap(self): 65 archive = self._storage.OpenArchive('mmap', create=True) 66 timestamp = archive.StartNewSnapshot() 67 mmap = memory_map.Map() 68 map_entry1 = memory_map.MapEntry(4096, 8191, 'rw--', '/foo', 0) 69 map_entry2 = memory_map.MapEntry(65536, 81919, 'rw--', '/bar', 4096) 70 map_entry2.resident_pages = [5] 71 mmap.Add(map_entry1) 72 mmap.Add(map_entry2) 73 archive.StoreMemMaps(mmap) 74 mmap_deser = archive.LoadMemMaps(timestamp) 75 self._DeepCompare(mmap, mmap_deser) 76 self._storage.DeleteArchive('mmap') 77 78 def testNativeHeap(self): 79 archive = self._storage.OpenArchive('nheap', create=True) 80 timestamp = archive.StartNewSnapshot() 81 nh = native_heap.NativeHeap() 82 for i in xrange(1, 4): 83 stack_trace = stacktrace.Stacktrace() 84 frame = nh.GetStackFrame(i * 10 + 1) 85 frame.SetExecFileInfo('foo.so', 1) 86 stack_trace.Add(frame) 87 frame = nh.GetStackFrame(i * 10 + 2) 88 frame.SetExecFileInfo('bar.so', 2) 89 stack_trace.Add(frame) 90 nh.Add(native_heap.Allocation(size=i * 10, 91 stack_trace=stack_trace, 92 start=i * 20, 93 flags=i * 30)) 94 archive.StoreNativeHeap(nh) 95 nh_deser = archive.LoadNativeHeap(timestamp) 96 self._DeepCompare(nh, nh_deser) 97 self._storage.DeleteArchive('nheap') 98 99 def testSymbols(self): 100 archive = self._storage.OpenArchive('symbols', create=True) 101 symbols = symbol.Symbols() 102 # Symbol db is global per archive, no need to StartNewSnapshot. 103 symbols.Add('foo.so', 1, symbol.Symbol('sym1', 'file1.c', 11)) 104 symbols.Add('bar.so', 2, symbol.Symbol('sym2', 'file2.c', 12)) 105 sym3 = symbol.Symbol('sym3', 'file2.c', 13) 106 sym3.AddSourceLineInfo('outer_file.c', 23) 107 symbols.Add('baz.so', 3, sym3) 108 archive.StoreSymbols(symbols) 109 symbols_deser = archive.LoadSymbols() 110 self._DeepCompare(symbols, symbols_deser) 111 self._storage.DeleteArchive('symbols') 112 113 def _DeepCompare(self, a, b, prefix=''): 114 """Recursively compares two objects (original and deserialized).""" 115 116 self.assertEqual(a is None, b is None) 117 if a is None: 118 return 119 120 _BASICTYPES = (long, int, basestring, float) 121 if isinstance(a, _BASICTYPES) and isinstance(b, _BASICTYPES): 122 return self.assertEqual(a, b, prefix) 123 124 self.assertEqual(type(a), type(b), prefix + ' type (%s vs %s' % ( 125 type(a), type(b))) 126 127 if isinstance(a, list): 128 self.assertEqual(len(a), len(b), prefix + ' len (%d vs %d)' % ( 129 len(a), len(b))) 130 for i in range(len(a)): 131 self._DeepCompare(a[i], b[i], prefix + '[%d]' % i) 132 return 133 134 if isinstance(a, dict): 135 self.assertEqual(a.keys(), b.keys(), prefix + ' keys (%s vs %s)' % ( 136 str(a.keys()), str(b.keys()))) 137 for k in a.iterkeys(): 138 self._DeepCompare(a[k], b[k], prefix + '.' + str(k)) 139 return 140 141 return self._DeepCompare(a.__dict__, b.__dict__, prefix)