diff options
author | John Reck <jreck@google.com> | 2015-08-20 10:19:35 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2015-08-20 10:19:35 -0700 |
commit | 24e1a9362ca2bf7d5cf659231f70375b3761edba (patch) | |
tree | 122c7ae747b28060a29f66e534a6c14420a18ff1 /catapult/tracing | |
parent | a7946b36d7115dfaad5510119808a7e899bff4f1 (diff) | |
download | chromium-trace-24e1a9362ca2bf7d5cf659231f70375b3761edba.tar.gz |
Update to latest catapult
Bug: 23281041
Change-Id: I68b14f607d624d979b324b956550c4877ed8485b
Diffstat (limited to 'catapult/tracing')
18 files changed, 325 insertions, 112 deletions
diff --git a/catapult/tracing/bin/run_tests b/catapult/tracing/bin/run_tests index 6b2ff524..cf87e9c0 100755 --- a/catapult/tracing/bin/run_tests +++ b/catapult/tracing/bin/run_tests @@ -3,84 +3,23 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import argparse -import logging import os -import subprocess import sys _THIS_PATH = os.path.dirname(__file__) -_RUN_PY_TESTS_PATH = os.path.join(_THIS_PATH, 'run_py_tests') -_RUN_VINN_TESTS_PATH = os.path.join(_THIS_PATH, 'run_vinn_tests') -_RUN_DEV_SERVER_TESTS_PATH = os.path.join(_THIS_PATH, 'run_dev_server_tests') - - -class bcolors(object): - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - - -def _RunPyTests(): - command = [_RUN_PY_TESTS_PATH] - if sys.platform == 'win32': - command = ['python'] + command - return subprocess.call(command) - - -def _RunVinnTests(): - if sys.platform == 'win32': # Vinn doesn't work on Windows yet. - return 0 - return subprocess.call([_RUN_VINN_TESTS_PATH]) - - -def _RunDevServerTests(chrome_command): - command = [_RUN_DEV_SERVER_TESTS_PATH] - if chrome_command: - command += ['--chrome_path', chrome_command] - if sys.platform == 'win32': - command = ['python'] + command - return subprocess.call(command) +_TESTS = [ + {'path': os.path.join(_THIS_PATH, 'run_py_tests')}, + {'path': os.path.join(_THIS_PATH, 'run_vinn_tests'), + 'disabled': {'win32'}}, + {'path': os.path.join(_THIS_PATH, 'run_dev_server_tests'), + 'chrome_path_arg': True} +] if __name__ == '__main__': - parser = argparse.ArgumentParser( - description='Run all tests of tracing project.') - parser.add_argument('--chrome_path', type=str, - help='Path to Chrome browser binary.') - args = parser.parse_args() - run_py_tests_exit_code = _RunPyTests() - run_vinn_tests_exit_code = _RunVinnTests() - run_dev_server_exit_code = _RunDevServerTests(args.chrome_path) - - exit_code = (run_py_tests_exit_code | run_dev_server_exit_code | - run_vinn_tests_exit_code) - if exit_code: - print (bcolors.FAIL + - 'Oooops! Looks like some of your tests have failed.' + - bcolors.ENDC), u'\U0001F631'.encode('utf-8') - else: - print (bcolors.OKGREEN + - 'Woho! All the tests have passed. You are awesome!' + - bcolors.ENDC), u'\U0001F601'.encode('utf-8') - - if run_py_tests_exit_code: - sys.stderr.write( - 'run_py_tests have some failed tests. Rerun run_py_tests script ' - 'to see those.\n') - if run_vinn_tests_exit_code: - sys.stderr.write( - 'run_vinn_tests have some failed tests. Rerun run_vinn_tests script ' - 'to see those.\n') - if run_dev_server_exit_code: - sys.stderr.write( - 'run_dev_server have some failed tests. Rerun run_dev_server_test script ' - 'and open the browser to see those.\n') - - sys.exit(exit_code) + catapult_path = os.path.abspath(os.path.join(os.path.dirname(__file__), + '..', '..')) + sys.path.append(catapult_path) + from build import test_runner + sys.exit(test_runner.Main('tracing', _TESTS, sys.argv)) diff --git a/catapult/tracing/third_party/tvcm/tvcm/project.py b/catapult/tracing/third_party/tvcm/tvcm/project.py index 7f871c7e..f7f99e24 100644 --- a/catapult/tracing/third_party/tvcm/tvcm/project.py +++ b/catapult/tracing/third_party/tvcm/tvcm/project.py @@ -130,6 +130,10 @@ class Project(object): return [self.loader.LoadModule(module_filename=filename) for filename in filenames] + def LoadModule(self, module_name=None, module_filename=None): + return self.loader.LoadModule(module_name=module_name, + module_filename=module_filename) + def CalcLoadSequenceForModuleNames(self, module_names): modules = [self.loader.LoadModule(module_name=name) for name in module_names] diff --git a/catapult/tracing/tracing/base/range.html b/catapult/tracing/tracing/base/range.html index 767c8671..d7811348 100644 --- a/catapult/tracing/tracing/base/range.html +++ b/catapult/tracing/tracing/base/range.html @@ -6,6 +6,7 @@ found in the LICENSE file. --> <link rel="import" href="/tracing/base/base.html"> +<link rel="import" href="/tracing/base/iteration_helpers.html"> <script> 'use strict'; @@ -142,6 +143,50 @@ tr.exportTo('tr.b', function() { max: this.max, min: this.min }; + }, + + /** + * Returns a slice of the input array that intersects with this range. If + * the range does not have a min, it is treated as unbounded from below. + * Similarly, if max is undefined, the range is unbounded from above. + * + * @param {Array} array The array of elements to be filtered. + * @param {Funcation=} opt_keyFunc A function that extracts a numeric value, + * to be used in comparisons, from an element of the array. If not + * specified, array elements themselves will be used. + * @param {Object=} opt_this An optional this argument to be passed to + * opt_keyFunc. + */ + filterArray: function(array, opt_keyFunc, opt_this) { + if (this.isEmpty_) + return []; + // Binary search. |test| is a function that should return true when we + // need to explore the left branch and false to explore the right branch. + function binSearch(test) { + var i0 = 0; + var i1 = array.length; + while (i0 < i1 - 1) { + var i = Math.trunc((i0 + i1) / 2); + if (test(i)) + i1 = i; // Explore the left branch. + else + i0 = i; // Explore the right branch. + } + return i1; + } + + var keyFunc = opt_keyFunc || tr.b.identity; + function getValue(index) { + return keyFunc.call(opt_this, array[index]); + } + + var first = binSearch(function(i) { + return this.min_ === undefined || this.min_ <= getValue(i); + }.bind(this)); + var last = binSearch(function(i) { + return this.max_ !== undefined && this.max_ < getValue(i); + }.bind(this)); + return array.slice(first, last); } }; diff --git a/catapult/tracing/tracing/base/range_test.html b/catapult/tracing/tracing/base/range_test.html index d1bd5f43..9c179bd8 100644 --- a/catapult/tracing/tracing/base/range_test.html +++ b/catapult/tracing/tracing/base/range_test.html @@ -302,5 +302,31 @@ tr.b.unittest.testSuite(function() { assert.isTrue(r1.findIntersection(r2).isEmpty); assert.isTrue(r2.findIntersection(r1).isEmpty); }); + + test('filter_numericField', function() { + var r = Range.fromExplicitRange(2, 3); + var array = [{start: 1}, + {start: 2}, + {start: 3}, + {start: 4}]; + assert.deepEqual([{start: 2}, {start: 3}], r.filterArray( + array, function(value) {return value.start;})); + }); + + test('filter_noNumericField', function() { + var r = Range.fromExplicitRange(2, 3); + assert.deepEqual([2, 3], r.filterArray([1, 2, 3, 4])); + }); + + test('filter_empty', function() { + var r = new Range(); + assert.deepEqual([], r.filterArray([1, 2, 3, 4])); + }); + + test('filter_oneSided', function() { + var r = new Range(); + r.min = 2; + assert.deepEqual([2, 3, 4], r.filterArray([1, 2, 3, 4])); + }); }); </script> diff --git a/catapult/tracing/tracing/base/utils.html b/catapult/tracing/tracing/base/utils.html index a07fd186..1a98cab4 100644 --- a/catapult/tracing/tracing/base/utils.html +++ b/catapult/tracing/tracing/base/utils.html @@ -71,7 +71,9 @@ tr.exportTo('tr.b', function() { } var typeName; - if (e.constructor) { + if (e.name) { + typeName = e.name; + } else if (e.constructor) { if (e.constructor.name) { typeName = e.constructor.name; } else { diff --git a/catapult/tracing/tracing/base/utils_test.html b/catapult/tracing/tracing/base/utils_test.html index 20ae2fde..a08ac33b 100644 --- a/catapult/tracing/tracing/base/utils_test.html +++ b/catapult/tracing/tracing/base/utils_test.html @@ -17,5 +17,14 @@ tr.b.unittest.testSuite(function() { var w = tr.b.getUsingPath('x.w', {'x': {'y': {'z': 3}}}); assert.isUndefined(w); }); + + test('testExceptionNaming', function() { + var err = new Error('asdf'); + err.name = 'MyError'; + + var ex = tr.b.normalizeException(err); + assert.equal(ex.typeName, 'MyError'); + }); + }); </script> diff --git a/catapult/tracing/tracing/extras/importer/linux_perf/android_parser_test.html b/catapult/tracing/tracing/extras/importer/linux_perf/android_parser_test.html index d3710acf..07cb9c02 100644 --- a/catapult/tracing/tracing/extras/importer/linux_perf/android_parser_test.html +++ b/catapult/tracing/tracing/extras/importer/linux_perf/android_parser_test.html @@ -202,5 +202,29 @@ tr.b.unittest.testSuite(function() { assert.equal(Math.round((253.780659 - (255.663276 - 128)) * 1000), Math.round(thread.sliceGroup.slices[0].start)); }); + + test('androidNeedReschedImport', function() { + var lines = [ + 'RenderThread-3894 [001] ...1 253.780659: tracing_mark_write: B|3586|DrawFrame', // @suppress longLineCheck + 'RenderThread-3894 [001] ...1 253.780671: tracing_mark_write: B|3586|waitForTask', // @suppress longLineCheck + 'RenderThread-3894 [001] .N.1 253.780671: tracing_mark_write: E', // @suppress longLineCheck + 'RenderThread-3894 [001] ...1 253.780671: tracing_mark_write: B|3586|waitForTask', // @suppress longLineCheck + 'RenderThread-3894 [001] .n.1 253.780671: tracing_mark_write: E', // @suppress longLineCheck + 'RenderThread-3894 [001] ...1 253.780671: tracing_mark_write: B|3586|waitForTask', // @suppress longLineCheck + 'RenderThread-3894 [001] .p.1 253.780671: tracing_mark_write: E', // @suppress longLineCheck + 'RenderThread-3894 [001] ...1 253.780686: tracing_mark_write: E', // @suppress longLineCheck + ]; + var m = newModel(lines.join('\n')); + assert.isFalse(m.hasImportWarnings, 'hasImportWarnings'); + + var threads = m.getAllThreads(); + assert.equal(threads.length, 1); + + var thread = threads[0]; + assert.equal(thread.parent.pid, 3586); + assert.equal(thread.tid, 3894); + assert.equal(thread.name, 'RenderThread'); + assert.equal(thread.sliceGroup.length, 4); + }); }); </script> diff --git a/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer.html b/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer.html index e6c9c3de..2dbae1aa 100644 --- a/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer.html +++ b/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer.html @@ -76,7 +76,7 @@ tr.exportTo('tr.e.importer.linux_perf', function() { // what userland calls a thread ID). var lineREWithTGID = new RegExp( '^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]' + - '\\s+[dX.][N.][Hhs.][0-9a-f.]' + + '\\s+[dX.][Nnp.][Hhs.][0-9a-f.]' + '\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$'); var lineParserWithTGID = function(line) { var groups = lineREWithTGID.exec(line); @@ -104,7 +104,7 @@ tr.exportTo('tr.e.importer.linux_perf', function() { // <idle>-0 [001] d... 1.23: sched_switch var lineREWithIRQInfo = new RegExp( '^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]' + - '\\s+[dX.][N.][Hhs.][0-9a-f.]' + + '\\s+[dX.][Nnp.][Hhs.][0-9a-f.]' + '\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$'); var lineParserWithIRQInfo = function(line) { var groups = lineREWithIRQInfo.exec(line); diff --git a/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer_test.html b/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer_test.html index 6720f16a..becc14d3 100644 --- a/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer_test.html +++ b/catapult/tracing/tracing/extras/importer/linux_perf/ftrace_importer_test.html @@ -58,6 +58,29 @@ tr.b.unittest.testSuite(function() { assert.equal(x.details, 'comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); // @suppress longLineCheck }); + test('lineParserWithIRQInfoNeedResched', function() { + var p = LinuxPerfImporterTestExports.lineParserWithIRQInfo; // @suppress longLineCheck + var x = p(' systrace.sh-5441 [001] .N.. 1031.091570: ' + + 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); + assert.isNotNull(x); + assert.equal(x.threadName, 'systrace.sh'); + assert.equal(x.pid, '5441'); + assert.equal(x.cpuNumber, '001'); + assert.equal(x.timestamp, '1031.091570'); + assert.equal(x.eventName, 'sched_wakeup'); + assert.equal(x.details, 'comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); // @suppress longLineCheck + + var x = p(' systrace.sh-5441 [001] .n.. 1031.091570: ' + + 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); + assert.isNotNull(x); + assert.equal(x.threadName, 'systrace.sh'); + + var x = p(' systrace.sh-5441 [001] .p.. 1031.091570: ' + + 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); + assert.isNotNull(x); + assert.equal(x.threadName, 'systrace.sh'); + }); + test('lineParserWithTGID', function() { var p = LinuxPerfImporterTestExports.lineParserWithTGID; var x = p(' systrace.sh-5441 (54321) [001] d... 1031.091570: ' + @@ -82,6 +105,30 @@ tr.b.unittest.testSuite(function() { assert.isUndefined(x.tgid); }); + test('lineParserWithTGIDNeedResched', function() { + var p = LinuxPerfImporterTestExports.lineParserWithTGID; + var x = p(' systrace.sh-5441 (54321) [001] .N.. 1031.091570: ' + + 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); + assert.isNotNull(x); + assert.equal(x.threadName, 'systrace.sh'); + assert.equal(x.pid, '5441'); + assert.equal(x.tgid, '54321'); + assert.equal(x.cpuNumber, '001'); + assert.equal(x.timestamp, '1031.091570'); + assert.equal(x.eventName, 'sched_wakeup'); + assert.equal(x.details, 'comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); // @suppress longLineCheck + + var x = p(' systrace.sh-5441 ( 321) [001] .n.. 1031.091570: ' + + 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); + assert.isNotNull(x); + assert.equal(x.tgid, '321'); + + var x = p(' systrace.sh-5441 (-----) [001] .p.. 1031.091570: ' + + 'sched_wakeup: comm=debugd pid=4978 prio=120 success=1 target_cpu=000'); + assert.isNotNull(x); + assert.isUndefined(x.tgid); + }); + test('autodetectLineCornerCases', function() { var detectParser = LinuxPerfImporterTestExports.autoDetectLineParser; diff --git a/catapult/tracing/tracing/model/source_info/source_info.html b/catapult/tracing/tracing/model/source_info/source_info.html index 75aad32d..4164391e 100644 --- a/catapult/tracing/tracing/model/source_info/source_info.html +++ b/catapult/tracing/tracing/model/source_info/source_info.html @@ -25,6 +25,13 @@ tr.exportTo('tr.model.source_info', function() { return this.line_; }, + get domain() { + if (!this.file_) + return undefined; + var domain = this.file_.match(/(.*:\/\/[^:\/]*)/i); + return domain ? domain[1] : undefined; + }, + toString: function() { var str = ''; if (this.file_) diff --git a/catapult/tracing/tracing/model/source_info/source_info_test.html b/catapult/tracing/tracing/model/source_info/source_info_test.html new file mode 100644 index 00000000..344dba0f --- /dev/null +++ b/catapult/tracing/tracing/model/source_info/source_info_test.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<!-- +Copyright (c) 2015 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<link rel="import" href="/tracing/model/source_info/source_info.html"> + +<script> +'use strict'; + +tr.b.unittest.testSuite(function() { + test('domain', function() { + var urlDomains = { + 'http://www.google.com': 'http://www.google.com', + 'http://www.google.com/bla': 'http://www.google.com', + 'http://www.google.com:1234': 'http://www.google.com', + 'bad url': undefined + }; + for (var url in urlDomains) { + var sourceInfo = new tr.model.source_info.SourceInfo(url); + assert.equal(urlDomains[url], sourceInfo.domain); + } + }); +}); +</script> diff --git a/catapult/tracing/tracing/model/stack_frame.html b/catapult/tracing/tracing/model/stack_frame.html index af676b5e..a4b48ece 100644 --- a/catapult/tracing/tracing/model/stack_frame.html +++ b/catapult/tracing/tracing/model/stack_frame.html @@ -38,6 +38,19 @@ tr.exportTo('tr.model', function() { return this.title_; }, + /** + * Attempts to find the domain of the origin of the script either from this + * stack trace or from its ancestors. + */ + get domain() { + var result = 'unknown'; + if (this.sourceInfo_ && this.sourceInfo_.domain) + result = this.sourceInfo_.domain; + if (result === 'unknown' && this.parentFrame) + result = this.parentFrame.domain; + return result; + }, + set parentFrame(parentFrame) { if (this.parentFrame_) this.parentFrame_.removeChild(this); diff --git a/catapult/tracing/tracing/model/stack_frame_test.html b/catapult/tracing/tracing/model/stack_frame_test.html new file mode 100644 index 00000000..1b8351f0 --- /dev/null +++ b/catapult/tracing/tracing/model/stack_frame_test.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<!-- +Copyright (c) 2015 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<link rel="import" href="/tracing/model/source_info/source_info.html"> +<link rel="import" href="/tracing/model/stack_frame.html"> + +<script> +'use strict'; + +tr.b.unittest.testSuite(function() { + test('domain', function() { + var stackFrame1 = new tr.model.StackFrame(undefined, 1, '1', '1', 1); + assert.equal('unknown', stackFrame1.domain); + + var sourceInfo = new tr.model.source_info.SourceInfo( + 'http://www.google.com:1234'); + var stackFrame2 = new tr.model.StackFrame( + stackFrame1, 2, '2', '2', 2, sourceInfo); + assert.equal('http://www.google.com', stackFrame2.domain); + + var stackFrame3 = new tr.model.StackFrame(stackFrame2, 3, '3', '3', 3); + assert.equal('http://www.google.com', stackFrame3.domain); + }); +}); +</script> diff --git a/catapult/tracing/tracing/ui/analysis/related_events.html b/catapult/tracing/tracing/ui/analysis/related_events.html index deb5fbb2..701c1684 100644 --- a/catapult/tracing/tracing/ui/analysis/related_events.html +++ b/catapult/tracing/tracing/ui/analysis/related_events.html @@ -5,6 +5,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> +<link rel="import" href="/tracing/base/range.html"> <link rel="import" href="/tracing/base/task.html"> <link rel="import" href="/tracing/model/event_set.html"> <link rel="import" href="/tracing/ui/analysis/analysis_link.html"> @@ -210,43 +211,16 @@ found in the LICENSE file. }); }, - // Find the [first, last] index of the samples overlapping slice, assuming - // samples are sorted. |last| is past-the-end so returned indices can be - // used with Array.slice. - findOverlappingSampleIndices_: function(samples, slice) { - // Binary search. |test| is a function that should return true when we - // need to explore the left branch and false to explore the right branch. - function binSearch(test) { - var i0 = 0; - var i1 = samples.length; - while (i0 < i1 - 1) { - var i = Math.trunc((i0 + i1) / 2); - if (test(i)) - i1 = i; // Explore the left branch. - else - i0 = i; // Explore the right branch. - } - return i1; - } - - var first = binSearch(function(i) { - return slice.start <= samples[i].start; - }); - var sliceEnd = slice.start + slice.duration; - var last = binSearch(function(i) { - return sliceEnd < samples[i].start; - }); - return [first, last]; - }, - addOverlappingSamples_: function(eventSet) { var samples = new tr.model.EventSet; eventSet.forEach(function(slice) { if (!slice.parentContainer || !slice.parentContainer.samples) return; var candidates = slice.parentContainer.samples; - var filteredSamples = candidates.slice.apply(candidates, - this.findOverlappingSampleIndices_(candidates, slice)); + var range = tr.b.Range.fromExplicitRange( + slice.start, slice.start + slice.duration); + var filteredSamples = range.filterArray( + candidates, function(value) {return value.start;}); filteredSamples.forEach(function(sample) { samples.push(sample); }); diff --git a/catapult/tracing/tracing/ui/base/dom_helpers.html b/catapult/tracing/tracing/ui/base/dom_helpers.html index 4813fbf1..7c2f01d3 100644 --- a/catapult/tracing/tracing/ui/base/dom_helpers.html +++ b/catapult/tracing/tracing/ui/base/dom_helpers.html @@ -219,7 +219,7 @@ tr.exportTo('tr.ui.b', function() { var nextCheckboxId = 1; function createCheckBox(targetEl, targetElProperty, settingsKey, defaultValue, - label) { + label, opt_changeCb) { var buttonEl = document.createElement('input'); buttonEl.type = 'checkbox'; @@ -232,6 +232,8 @@ tr.exportTo('tr.ui.b', function() { tr.b.Settings.set(settingsKey, buttonEl.checked); if (targetEl) targetEl[targetElProperty] = buttonEl.checked; + if (opt_changeCb) + opt_changeCb.call(); } buttonEl.addEventListener('change', onChange); diff --git a/catapult/tracing/tracing/ui/units/generic_table_view.html b/catapult/tracing/tracing/ui/units/generic_table_view.html index f6bb2816..207ffb57 100644 --- a/catapult/tracing/tracing/ui/units/generic_table_view.html +++ b/catapult/tracing/tracing/ui/units/generic_table_view.html @@ -32,6 +32,7 @@ found in the LICENSE file. tr.exportTo('tr.ui.units', function() { var TEXT_COLUMN_MODE = 1; var NUMERIC_COLUMN_MODE = 2; + var ELEMENT_COLUMN_MODE = 3; function isNumeric(value) { // TODO(nduca): Also consider other units that are numeric. @@ -66,6 +67,9 @@ tr.exportTo('tr.ui.units', function() { }, cmp: function(a, b) { + if (this.columnMode_ === ELEMENT_COLUMN_MODE) + return 0; + return tr.b.comparePossiblyUndefinedValues(a, b, function(a, b) { var vA = a[this.fieldName]; var vB = b[this.fieldName]; @@ -82,10 +86,17 @@ tr.exportTo('tr.ui.units', function() { if (fieldValue === undefined || fieldValue === null) return; - if (isNumeric(fieldValue)) + if (isNumeric(fieldValue)) { this.columnMode_ = NUMERIC_COLUMN_MODE; - else - this.columnMode_ = TEXT_COLUMN_MODE; + return; + } + + if (fieldValue instanceof HTMLElement) { + this.columnMode_ = ELEMENT_COLUMN_MODE; + return; + } + + this.columnMode_ = TEXT_COLUMN_MODE; return; } @@ -99,7 +110,13 @@ tr.exportTo('tr.ui.units', function() { if (isNumeric(fieldValue)) return; - this.columnMode_ = TEXT_COLUMN_MODE; + if (fieldValue instanceof HTMLElement) { + this.columnMode_ = ELEMENT_COLUMN_MODE; + return; + } + + if (this.columnMode_ === NUMERIC_COLUMN_MODE) + this.columnMode_ = TEXT_COLUMN_MODE; }, value: function(item) { @@ -114,6 +131,9 @@ tr.exportTo('tr.ui.units', function() { if (fieldValue === undefined) return '-'; + if (fieldValue instanceof HTMLElement) + return fieldValue; + if (fieldValue instanceof Object) { var gov = document.createElement('tr-ui-a-generic-object-view'); gov.object = fieldValue; @@ -128,6 +148,7 @@ tr.exportTo('tr.ui.units', function() { Polymer('tr-ui-u-generic-table-view', { created: function() { this.items_ = undefined; + this.importantColumNames_ = []; }, get items() { @@ -145,6 +166,15 @@ tr.exportTo('tr.ui.units', function() { this.updateContents_(); }, + get importantColumNames() { + return this.importantColumNames_; + }, + + set importantColumNames(importantColumNames) { + this.importantColumNames_ = importantColumNames; + this.updateContents_(); + }, + createColumns_: function() { var columnsByName = {}; this.items_.forEach(function(item) { @@ -166,7 +196,16 @@ tr.exportTo('tr.ui.units', function() { return undefined; // Sort by name. + var isColumnNameImportant = {}; + var importantColumNames = this.importantColumNames || []; + importantColumNames.forEach(function(icn) { + isColumnNameImportant[icn] = true; + }); columns.sort(function(a, b) { + var iA = isColumnNameImportant[a.title] ? 1 : 0; + var iB = isColumnNameImportant[b.title] ? 1 : 0; + if ((iB - iA) !== 0) + return iB - iA; return a.title.localeCompare(b.title); }); diff --git a/catapult/tracing/tracing/ui/units/generic_table_view_test.html b/catapult/tracing/tracing/ui/units/generic_table_view_test.html index 41b955ed..01c7ed72 100644 --- a/catapult/tracing/tracing/ui/units/generic_table_view_test.html +++ b/catapult/tracing/tracing/ui/units/generic_table_view_test.html @@ -150,6 +150,23 @@ tr.b.unittest.testSuite(function() { this.addHTMLOutput(table); }); + test('tableWithElement', function() { + var table = document.createElement('tr-ui-u-generic-table-view'); + table.items = [ + { + a: 1 + }, + { + a: tr.ui.b.createSpan({textContent: 'ohai'}) + }, + { + b: 'c' + } + ]; + this.addHTMLOutput(table); + }); + + test('emptyTable', function() { var table = document.createElement('tr-ui-u-generic-table-view'); table.items = [{}]; diff --git a/catapult/tracing/tracing_build/__init__.py b/catapult/tracing/tracing_build/__init__.py index 528e8059..40dc4d65 100644 --- a/catapult/tracing/tracing_build/__init__.py +++ b/catapult/tracing/tracing_build/__init__.py @@ -5,5 +5,14 @@ import os import sys + +def _AddTracingProjectPath(): + tracing_path = os.path.normpath( + os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + if tracing_path not in sys.path: + sys.path.insert(0, tracing_path) + + +_AddTracingProjectPath() import tracing_project tracing_project.UpdateSysPathIfNeeded() |