| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Unit tests for annotated log parsers (aka log processors) used by runtest.py. | 6 """Unit tests for annotated log processor classes used by runtest.py.""" |
| 7 | |
| 8 The classes tested here reside in process_log_utils.py. | |
| 9 | |
| 10 The script runtest.py has the option to parse test output locally and send | |
| 11 results to the master via annotator steps. This file tests those parsers. | |
| 12 """ | |
| 13 | 7 |
| 14 import json | 8 import json |
| 15 import os | 9 import os |
| 16 import unittest | 10 import unittest |
| 17 | 11 |
| 18 import test_env # pylint: disable=W0403,W0611 | 12 import test_env # pylint: disable=W0403,W0611 |
| 19 | 13 |
| 20 from slave import process_log_utils | 14 from slave import performance_log_processor |
| 21 | 15 |
| 22 # These should be the same as the constants used in process_log_utils. | 16 # These should be the same as the constants used in performance_log_processor. |
| 23 # See: http://docs.buildbot.net/current/developer/results.html | 17 # See: http://docs.buildbot.net/current/developer/results.html |
| 24 SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, RETRY = range(6) | 18 SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, RETRY = range(6) |
| 25 | 19 |
| 26 # Custom percentile numbers to use in the tests below. | 20 # Custom percentile numbers to use in the tests below. |
| 27 TEST_PERCENTILES = [.05, .3, .8] | 21 TEST_PERCENTILES = [.05, .3, .8] |
| 28 | 22 |
| 29 | 23 |
| 30 class LogProcessorTest(unittest.TestCase): | 24 class LogProcessorTest(unittest.TestCase): |
| 31 """Base class for log processor unit tests. Contains common operations.""" | 25 """Base class for log processor unit tests. Contains common operations.""" |
| 32 | 26 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 """Test case for basic functionality of GraphingLogProcessor class.""" | 128 """Test case for basic functionality of GraphingLogProcessor class.""" |
| 135 | 129 |
| 136 def testSummary(self): | 130 def testSummary(self): |
| 137 """Tests the output of "summary" files, which contain per-graph data.""" | 131 """Tests the output of "summary" files, which contain per-graph data.""" |
| 138 input_files = ['graphing_processor.log'] | 132 input_files = ['graphing_processor.log'] |
| 139 output_files = ['%s-summary.dat' % graph for graph in ('commit_charge', | 133 output_files = ['%s-summary.dat' % graph for graph in ('commit_charge', |
| 140 'ws_final_total', 'vm_final_browser', 'vm_final_total', | 134 'ws_final_total', 'vm_final_browser', 'vm_final_total', |
| 141 'ws_final_browser', 'processes', 'artificial_graph')] | 135 'ws_final_browser', 'processes', 'artificial_graph')] |
| 142 | 136 |
| 143 self._ConstructParseAndCheckJSON(input_files, output_files, None, | 137 self._ConstructParseAndCheckJSON(input_files, output_files, None, |
| 144 process_log_utils.GraphingLogProcessor) | 138 performance_log_processor.GraphingLogProcessor) |
| 145 | 139 |
| 146 def testGraphList(self): | 140 def testGraphList(self): |
| 147 """Tests the output of "graphs.dat" files, which contains a graph list.""" | 141 """Tests the output of "graphs.dat" files, which contains a graph list.""" |
| 148 input_files = ['graphing_processor.log'] | 142 input_files = ['graphing_processor.log'] |
| 149 graphfile = 'graphs.dat' | 143 graphfile = 'graphs.dat' |
| 150 output_files = [graphfile] | 144 output_files = [graphfile] |
| 151 | 145 |
| 152 logs = self._ConstructParseAndCheckLogfiles(input_files, output_files, | 146 logs = self._ConstructParseAndCheckLogfiles(input_files, output_files, |
| 153 process_log_utils.GraphingLogProcessor) | 147 performance_log_processor.GraphingLogProcessor) |
| 154 | 148 |
| 155 actual = json.loads('\n'.join(logs[graphfile])) | 149 actual = json.loads('\n'.join(logs[graphfile])) |
| 156 expected = json.load(open( | 150 expected = json.load(open( |
| 157 os.path.join(test_env.DATA_PATH, 'graphing_processor-graphs.dat'))) | 151 os.path.join(test_env.DATA_PATH, 'graphing_processor-graphs.dat'))) |
| 158 | 152 |
| 159 self.assertEqual(len(actual), len(expected)) | 153 self.assertEqual(len(actual), len(expected)) |
| 160 | 154 |
| 161 for graph in expected: | 155 for graph in expected: |
| 162 self.assertTrue(graph['name'] in actual) | 156 self.assertTrue(graph['name'] in actual) |
| 163 for element in graph: | 157 for element in graph: |
| 164 self.assertEqual(actual[graph['name']][element], graph[element]) | 158 self.assertEqual(actual[graph['name']][element], graph[element]) |
| 165 | 159 |
| 166 def testHistogramGeometricMeanAndStandardDeviation(self): | 160 def testHistogramGeometricMeanAndStandardDeviation(self): |
| 167 input_files = ['graphing_processor.log'] | 161 input_files = ['graphing_processor.log'] |
| 168 summary_file = 'hist1-summary.dat' | 162 summary_file = 'hist1-summary.dat' |
| 169 output_files = [summary_file] | 163 output_files = [summary_file] |
| 170 | 164 |
| 171 logs = self._ConstructParseAndCheckLogfiles(input_files, output_files, | 165 logs = self._ConstructParseAndCheckLogfiles(input_files, output_files, |
| 172 process_log_utils.GraphingLogProcessor) | 166 performance_log_processor.GraphingLogProcessor) |
| 173 | 167 |
| 174 actual = json.loads('\n'.join(logs[summary_file])) | 168 actual = json.loads('\n'.join(logs[summary_file])) |
| 175 expected = json.load(open( | 169 expected = json.load(open( |
| 176 os.path.join(test_env.DATA_PATH, summary_file))) | 170 os.path.join(test_env.DATA_PATH, summary_file))) |
| 177 | 171 |
| 178 self.assertEqual(actual, expected, 'Filename %s did not contain expected ' | 172 self.assertEqual(actual, expected, 'Filename %s did not contain expected ' |
| 179 'data.' % summary_file) | 173 'data.' % summary_file) |
| 180 | 174 |
| 181 def testHistogramPercentiles(self): | 175 def testHistogramPercentiles(self): |
| 182 input_files = ['graphing_processor.log'] | 176 input_files = ['graphing_processor.log'] |
| 183 summary_files = ['hist1_%s-summary.dat' % str(p) for p in TEST_PERCENTILES] | 177 summary_files = ['hist1_%s-summary.dat' % str(p) for p in TEST_PERCENTILES] |
| 184 output_files = summary_files | 178 output_files = summary_files |
| 185 | 179 |
| 186 logs = self._ConstructParseAndCheckLogfiles(input_files, output_files, | 180 logs = self._ConstructParseAndCheckLogfiles(input_files, output_files, |
| 187 process_log_utils.GraphingLogProcessor) | 181 performance_log_processor.GraphingLogProcessor) |
| 188 | 182 |
| 189 for filename in output_files: | 183 for filename in output_files: |
| 190 actual = json.loads('\n'.join(logs[filename])) | 184 actual = json.loads('\n'.join(logs[filename])) |
| 191 expected = json.load(open(os.path.join(test_env.DATA_PATH, filename))) | 185 expected = json.load(open(os.path.join(test_env.DATA_PATH, filename))) |
| 192 self.assertEqual(actual, expected, 'Filename %s did not contain expected ' | 186 self.assertEqual(actual, expected, 'Filename %s did not contain expected ' |
| 193 'data.' % filename) | 187 'data.' % filename) |
| 194 | 188 |
| 195 | 189 |
| 196 class GraphingLogProcessorPerfTest(LogProcessorTest): | 190 class GraphingLogProcessorPerfTest(LogProcessorTest): |
| 197 """Another test case for the GraphingLogProcessor class. | 191 """Another test case for the GraphingLogProcessor class. |
| 198 | 192 |
| 199 The tests in this test case compare results against the contents of a | 193 The tests in this test case compare results against the contents of a |
| 200 perf expectations file. | 194 perf expectations file. |
| 201 """ | 195 """ |
| 202 | 196 |
| 203 def _TestPerfExpectations(self, perf_expectations_file): | 197 def _TestPerfExpectations(self, perf_expectations_file): |
| 204 perf_expectations_path = os.path.join( | 198 perf_expectations_path = os.path.join( |
| 205 test_env.DATA_PATH, perf_expectations_file) | 199 test_env.DATA_PATH, perf_expectations_file) |
| 206 | 200 |
| 207 input_file = 'graphing_processor.log' | 201 input_file = 'graphing_processor.log' |
| 208 graph_file = 'graphs.dat' | 202 graph_file = 'graphs.dat' |
| 209 | 203 |
| 210 parser = self._ConstructDefaultProcessor( | 204 parser = self._ConstructDefaultProcessor( |
| 211 process_log_utils.GraphingLogProcessor, | 205 performance_log_processor.GraphingLogProcessor, |
| 212 factory_properties={'expectations': True, 'perf_id': 'tester'}, | 206 factory_properties={'expectations': True, 'perf_id': 'tester'}, |
| 213 perf_expectations_path=perf_expectations_path) | 207 perf_expectations_path=perf_expectations_path) |
| 214 | 208 |
| 215 self._ProcessLog(parser, input_file) | 209 self._ProcessLog(parser, input_file) |
| 216 | 210 |
| 217 actual = json.loads('\n'.join(parser.PerformanceLogs()[graph_file])) | 211 actual = json.loads('\n'.join(parser.PerformanceLogs()[graph_file])) |
| 218 expected = json.load(open( | 212 expected = json.load(open( |
| 219 os.path.join(test_env.DATA_PATH, 'graphing_processor-graphs.dat'))) | 213 os.path.join(test_env.DATA_PATH, 'graphing_processor-graphs.dat'))) |
| 220 | 214 |
| 221 self.assertEqual(len(actual), len(expected)) | 215 self.assertEqual(len(actual), len(expected)) |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 expected = ('PERF_IMPROVE: vm_final_browser/1t_vm_b (inf%)') | 355 expected = ('PERF_IMPROVE: vm_final_browser/1t_vm_b (inf%)') |
| 362 self.assertEqual(expected, step.PerformanceSummary()[0]) | 356 self.assertEqual(expected, step.PerformanceSummary()[0]) |
| 363 self.assertEqual(WARNINGS, step.evaluateCommand('mycommand')) | 357 self.assertEqual(WARNINGS, step.evaluateCommand('mycommand')) |
| 364 | 358 |
| 365 | 359 |
| 366 class GraphingPageCyclerLogProcessorPerfTest(LogProcessorTest): | 360 class GraphingPageCyclerLogProcessorPerfTest(LogProcessorTest): |
| 367 """Unit tests for the GraphingPageCyclerLogProcessor class.""" | 361 """Unit tests for the GraphingPageCyclerLogProcessor class.""" |
| 368 | 362 |
| 369 def testPageCycler(self): | 363 def testPageCycler(self): |
| 370 parser = self._ConstructDefaultProcessor( | 364 parser = self._ConstructDefaultProcessor( |
| 371 process_log_utils.GraphingPageCyclerLogProcessor) | 365 performance_log_processor.GraphingPageCyclerLogProcessor) |
| 372 self._ProcessLog(parser, 'page_cycler.log') | 366 self._ProcessLog(parser, 'page_cycler.log') |
| 373 | 367 |
| 374 expected = 't: 2.32k' | 368 expected = 't: 2.32k' |
| 375 self.assertEqual(expected, parser.PerformanceSummary()[0]) | 369 self.assertEqual(expected, parser.PerformanceSummary()[0]) |
| 376 | 370 |
| 377 | 371 |
| 378 if __name__ == '__main__': | 372 if __name__ == '__main__': |
| 379 unittest.main() | 373 unittest.main() |
| OLD | NEW |