1 # Copyright (c) 2015 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 import json 5 import unittest 6 7 from perf_insights import function_handle 8 from perf_insights import map_single_trace 9 from perf_insights.mre import file_handle 10 from perf_insights.mre import job as job_module 11 12 13 def _Handle(filename): 14 module = function_handle.ModuleToLoad(filename=filename) 15 map_handle = function_handle.FunctionHandle( 16 modules_to_load=[module], function_name='MyMapFunction') 17 return job_module.Job(map_handle, None) 18 19 20 class MapSingleTraceTests(unittest.TestCase): 21 22 def testPassingMapScript(self): 23 events = [ 24 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'a', 'cat': 'c', 25 'ts': 0, 'dur': 10, 'args': {}}, 26 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'b', 'cat': 'c', 27 'ts': 3, 'dur': 5, 'args': {}} 28 ] 29 trace_handle = file_handle.InMemoryFileHandle( 30 '/a.json', json.dumps(events)) 31 32 with map_single_trace.TemporaryMapScript(""" 33 pi.FunctionRegistry.register( 34 function MyMapFunction(result, model) { 35 var canonicalUrl = model.canonicalUrlThatCreatedThisTrace; 36 result.addPair('result', { 37 numProcesses: model.getAllProcesses().length 38 }); 39 }); 40 """) as map_script: 41 result = map_single_trace.MapSingleTrace(trace_handle, 42 _Handle(map_script.filename)) 43 44 self.assertFalse(result.failures) 45 r = result.pairs['result'] 46 self.assertEquals(r['numProcesses'], 1) 47 48 def testTraceDidntImport(self): 49 trace_string = 'This is intentionally not a trace-formatted string.' 50 trace_handle = file_handle.InMemoryFileHandle( 51 '/a.json', trace_string) 52 53 with map_single_trace.TemporaryMapScript(""" 54 pi.FunctionRegistry.register( 55 function MyMapFunction(results, model) { 56 }); 57 """) as map_script: 58 result = map_single_trace.MapSingleTrace(trace_handle, 59 _Handle(map_script.filename)) 60 61 self.assertEquals(len(result.failures), 1) 62 self.assertEquals(len(result.pairs), 0) 63 f = result.failures[0] 64 self.assertIsInstance(f, map_single_trace.TraceImportFailure) 65 66 def testMapFunctionThatThrows(self): 67 events = [ 68 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'a', 'cat': 'c', 69 'ts': 0, 'dur': 10, 'args': {}}, 70 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'b', 'cat': 'c', 71 'ts': 3, 'dur': 5, 'args': {}} 72 ] 73 trace_handle = file_handle.InMemoryFileHandle( 74 '/a.json', json.dumps(events)) 75 76 with map_single_trace.TemporaryMapScript(""" 77 pi.FunctionRegistry.register( 78 function MyMapFunction(results, model) { 79 throw new Error('Expected error'); 80 }); 81 """) as map_script: 82 result = map_single_trace.MapSingleTrace(trace_handle, 83 _Handle(map_script.filename)) 84 85 self.assertEquals(len(result.failures), 1) 86 self.assertEquals(len(result.pairs), 0) 87 f = result.failures[0] 88 self.assertIsInstance(f, map_single_trace.MapFunctionFailure) 89 90 def testMapperWithLoadError(self): 91 events = [ 92 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'a', 'cat': 'c', 93 'ts': 0, 'dur': 10, 'args': {}}, 94 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'b', 'cat': 'c', 95 'ts': 3, 'dur': 5, 'args': {}} 96 ] 97 trace_handle = file_handle.InMemoryFileHandle( 98 '/a.json', json.dumps(events)) 99 100 with map_single_trace.TemporaryMapScript(""" 101 throw new Error('Expected load error'); 102 """) as map_script: 103 result = map_single_trace.MapSingleTrace(trace_handle, 104 _Handle(map_script.filename)) 105 106 self.assertEquals(len(result.failures), 1) 107 self.assertEquals(len(result.pairs), 0) 108 f = result.failures[0] 109 self.assertIsInstance(f, map_single_trace.FunctionLoadingFailure) 110 111 def testNoMapper(self): 112 events = [ 113 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'a', 'cat': 'c', 114 'ts': 0, 'dur': 10, 'args': {}}, 115 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'b', 'cat': 'c', 116 'ts': 3, 'dur': 5, 'args': {}} 117 ] 118 trace_handle = file_handle.InMemoryFileHandle( 119 '/a.json', json.dumps(events)) 120 121 with map_single_trace.TemporaryMapScript(""" 122 """) as map_script: 123 result = map_single_trace.MapSingleTrace(trace_handle, 124 _Handle(map_script.filename)) 125 126 self.assertEquals(len(result.failures), 1) 127 self.assertEquals(len(result.pairs), 0) 128 f = result.failures[0] 129 self.assertIsInstance(f, map_single_trace.FunctionNotDefinedFailure) 130 131 def testMapperDoesntAddValues(self): 132 events = [ 133 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'a', 'cat': 'c', 134 'ts': 0, 'dur': 10, 'args': {}}, 135 {'pid': 1, 'tid': 2, 'ph': 'X', 'name': 'b', 'cat': 'c', 136 'ts': 3, 'dur': 5, 'args': {}} 137 ] 138 trace_handle = file_handle.InMemoryFileHandle( 139 '/a.json', json.dumps(events)) 140 141 with map_single_trace.TemporaryMapScript(""" 142 pi.FunctionRegistry.register( 143 function MyMapFunction(results, model) { 144 }); 145 """) as map_script: 146 result = map_single_trace.MapSingleTrace(trace_handle, 147 _Handle(map_script.filename)) 148 149 self.assertEquals(len(result.failures), 1) 150 self.assertEquals(len(result.pairs), 0) 151 f = result.failures[0] 152 self.assertIsInstance(f, map_single_trace.NoResultsAddedFailure) 153