From 97f0b089da0d9c4fe8aa2532b5f61d2615f6bf65 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Thu, 8 May 2014 21:15:20 +0000 Subject: rebaseline_server JSON: pass category values as values, not keys BUG=skia:1758 NOTRY=True R=borenet@google.com Author: epoger@google.com Review URL: https://codereview.chromium.org/270413002 git-svn-id: http://skia.googlecode.com/svn/trunk@14658 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gm/rebaseline_server/column.py | 25 +++-- gm/rebaseline_server/compare_to_expectations.py | 2 + gm/rebaseline_server/imagepairset.py | 3 +- gm/rebaseline_server/imagepairset_test.py | 4 +- gm/rebaseline_server/results.py | 2 +- gm/rebaseline_server/static/constants.js | 14 +-- gm/rebaseline_server/static/loader.js | 32 +++++- gm/rebaseline_server/static/view.html | 20 ++-- .../gm.json | 93 ++++++++++++----- .../compare_rendered_pictures.json | 63 ++++++++---- .../gm.json | 113 ++++++++++++++++----- 11 files changed, 263 insertions(+), 108 deletions(-) diff --git a/gm/rebaseline_server/column.py b/gm/rebaseline_server/column.py index d8d119d130..26597c37d5 100644 --- a/gm/rebaseline_server/column.py +++ b/gm/rebaseline_server/column.py @@ -11,11 +11,12 @@ ColumnHeaderFactory class (see class docstring for details) # Keys used within dictionary representation of each column header. # NOTE: Keep these in sync with static/constants.js -KEY__HEADER_TEXT = 'headerText' -KEY__HEADER_URL = 'headerUrl' -KEY__IS_FILTERABLE = 'isFilterable' -KEY__IS_SORTABLE = 'isSortable' -KEY__VALUES_AND_COUNTS = 'valuesAndCounts' +KEY__EXTRACOLUMNHEADERS = 'extraColumnHeaders' +KEY__EXTRACOLUMNHEADERS__HEADER_TEXT = 'headerText' +KEY__EXTRACOLUMNHEADERS__HEADER_URL = 'headerUrl' +KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE = 'isFilterable' +KEY__EXTRACOLUMNHEADERS__IS_SORTABLE = 'isSortable' +KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS = 'valuesAndCounts' class ColumnHeaderFactory(object): @@ -46,7 +47,8 @@ class ColumnHeaderFactory(object): """Creates the header for this column, in dictionary form. Creates the header for this column in dictionary form, as needed when - constructing the JSON representation. Uses the KEY__* constants as keys. + constructing the JSON representation. Uses the KEY__EXTRACOLUMNHEADERS__* + constants as keys. Args: values_and_counts_dict: dictionary mapping each possible column value @@ -54,12 +56,13 @@ class ColumnHeaderFactory(object): None if this information is not available. """ asdict = { - KEY__HEADER_TEXT: self._header_text, - KEY__IS_FILTERABLE: self._is_filterable, - KEY__IS_SORTABLE: self._is_sortable, + KEY__EXTRACOLUMNHEADERS__HEADER_TEXT: self._header_text, + KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE: self._is_filterable, + KEY__EXTRACOLUMNHEADERS__IS_SORTABLE: self._is_sortable, } if self._header_url: - asdict[KEY__HEADER_URL] = self._header_url + asdict[KEY__EXTRACOLUMNHEADERS__HEADER_URL] = self._header_url if self._include_values_and_counts and values_and_counts_dict: - asdict[KEY__VALUES_AND_COUNTS] = values_and_counts_dict + asdict[KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS] = sorted( + values_and_counts_dict.items()) return asdict diff --git a/gm/rebaseline_server/compare_to_expectations.py b/gm/rebaseline_server/compare_to_expectations.py index ab05f6f51b..cddca55d2a 100755 --- a/gm/rebaseline_server/compare_to_expectations.py +++ b/gm/rebaseline_server/compare_to_expectations.py @@ -316,6 +316,8 @@ class ExpectationComparisons(results.BaseComparisons): # categories recorded within the gm_actuals AT ALL, and # instead evaluate the result_type ourselves based on what # we see in expectations vs actual checksum? + # See related http://skbug.com/2514 ('rebaseline_server: apply + # ignored-tests.txt within rebaseline_server, not just on the bots') if expected_image_relative_url == actual_image_relative_url: updated_result_type = results.KEY__RESULT_TYPE__SUCCEEDED else: diff --git a/gm/rebaseline_server/imagepairset.py b/gm/rebaseline_server/imagepairset.py index 04aea90342..880987703d 100644 --- a/gm/rebaseline_server/imagepairset.py +++ b/gm/rebaseline_server/imagepairset.py @@ -17,7 +17,6 @@ import column # Keys used within dictionary representation of ImagePairSet. # NOTE: Keep these in sync with static/constants.js -KEY__EXTRACOLUMNHEADERS = 'extraColumnHeaders' KEY__IMAGEPAIRS = 'imagePairs' KEY__IMAGESETS = 'imageSets' KEY__IMAGESETS__FIELD__BASE_URL = 'baseUrl' @@ -141,7 +140,7 @@ class ImagePairSet(object): key_description = KEY__IMAGESETS__FIELD__DESCRIPTION key_base_url = KEY__IMAGESETS__FIELD__BASE_URL return { - KEY__EXTRACOLUMNHEADERS: self._column_headers_as_dict(), + column.KEY__EXTRACOLUMNHEADERS: self._column_headers_as_dict(), KEY__IMAGEPAIRS: self._image_pair_dicts, KEY__IMAGESETS: { KEY__IMAGESETS__SET__IMAGE_A: { diff --git a/gm/rebaseline_server/imagepairset_test.py b/gm/rebaseline_server/imagepairset_test.py index c046ec7c7c..d7aeb64fea 100755 --- a/gm/rebaseline_server/imagepairset_test.py +++ b/gm/rebaseline_server/imagepairset_test.py @@ -91,9 +91,7 @@ class ImagePairSetTest(unittest.TestCase): 'headerText': 'builder', 'isFilterable': True, 'isSortable': True, - 'valuesAndCounts': { - 'MyBuilder': 3 - }, + 'valuesAndCounts': [('MyBuilder', 3)], }, 'test': { 'headerText': 'which GM test', diff --git a/gm/rebaseline_server/results.py b/gm/rebaseline_server/results.py index 461e7463a6..254b0a3c84 100755 --- a/gm/rebaseline_server/results.py +++ b/gm/rebaseline_server/results.py @@ -31,7 +31,7 @@ import imagepairset # Keys used to link an image to a particular GM test. # NOTE: Keep these in sync with static/constants.js -REBASELINE_SERVER_SCHEMA_VERSION_NUMBER = 2 +REBASELINE_SERVER_SCHEMA_VERSION_NUMBER = 3 KEY__EXPECTATIONS__BUGS = gm_json.JSONKEY_EXPECTEDRESULTS_BUGS KEY__EXPECTATIONS__IGNOREFAILURE = gm_json.JSONKEY_EXPECTEDRESULTS_IGNOREFAILURE KEY__EXPECTATIONS__REVIEWED = gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED diff --git a/gm/rebaseline_server/static/constants.js b/gm/rebaseline_server/static/constants.js index 87a07752a3..55dddbf749 100644 --- a/gm/rebaseline_server/static/constants.js +++ b/gm/rebaseline_server/static/constants.js @@ -9,11 +9,12 @@ var module = angular.module( module.constant('constants', (function() { return { // NOTE: Keep these in sync with ../column.py - KEY__HEADER_TEXT: 'headerText', - KEY__HEADER_URL: 'headerUrl', - KEY__IS_FILTERABLE: 'isFilterable', - KEY__IS_SORTABLE: 'isSortable', - KEY__VALUES_AND_COUNTS: 'valuesAndCounts', + KEY__EXTRACOLUMNHEADERS: 'extraColumnHeaders', + KEY__EXTRACOLUMNHEADERS__HEADER_TEXT: 'headerText', + KEY__EXTRACOLUMNHEADERS__HEADER_URL: 'headerUrl', + KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE: 'isFilterable', + KEY__EXTRACOLUMNHEADERS__IS_SORTABLE: 'isSortable', + KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS: 'valuesAndCounts', // NOTE: Keep these in sync with ../imagediffdb.py KEY__DIFFERENCE_DATA__MAX_DIFF_PER_CHANNEL: 'maxDiffPerChannel', @@ -31,7 +32,6 @@ module.constant('constants', (function() { KEY__IS_DIFFERENT: 'isDifferent', // NOTE: Keep these in sync with ../imagepairset.py - KEY__EXTRACOLUMNHEADERS: 'extraColumnHeaders', KEY__IMAGEPAIRS: 'imagePairs', KEY__IMAGESETS: 'imageSets', KEY__IMAGESETS__FIELD__BASE_URL: 'baseUrl', @@ -42,7 +42,7 @@ module.constant('constants', (function() { KEY__IMAGESETS__SET__WHITEDIFFS: 'whiteDiffs', // NOTE: Keep these in sync with ../results.py - REBASELINE_SERVER_SCHEMA_VERSION_NUMBER: 2, + REBASELINE_SERVER_SCHEMA_VERSION_NUMBER: 3, KEY__EXPECTATIONS__BUGS: 'bugs', KEY__EXPECTATIONS__IGNOREFAILURE: 'ignore-failure', KEY__EXPECTATIONS__REVIEWED: 'reviewed-by-human', diff --git a/gm/rebaseline_server/static/loader.js b/gm/rebaseline_server/static/loader.js index dc33bd0a93..f5a4f7bf4d 100644 --- a/gm/rebaseline_server/static/loader.js +++ b/gm/rebaseline_server/static/loader.js @@ -148,13 +148,15 @@ Loader.controller( constants.KEY__RESULT_TYPE__NOCOMPARISON] = true; $scope.hiddenResultTypes[ constants.KEY__RESULT_TYPE__SUCCEEDED] = true; - $scope.allResultTypes = Object.keys( + $scope.allResultTypes = $scope.columnSliceOf2DArray( $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMN__RESULT_TYPE] - [constants.KEY__VALUES_AND_COUNTS]); + [constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS], + 0); $scope.hiddenConfigs = {}; - $scope.allConfigs = Object.keys( + $scope.allConfigs = $scope.columnSliceOf2DArray( $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMN__CONFIG] - [constants.KEY__VALUES_AND_COUNTS]); + [constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS], + 0); // Associative array of partial string matches per category. $scope.categoryValueMatch = {}; @@ -743,6 +745,28 @@ Loader.controller( // TODO(epoger): move into a separate .js file? // + /** + * Returns a single "column slice" of a 2D array. + * + * For example, if array is: + * [[A0, A1], + * [B0, B1], + * [C0, C1]] + * and index is 0, this this will return: + * [A0, B0, C0] + * + * @param array a Javascript Array + * @param column (numeric): index within each row array + */ + $scope.columnSliceOf2DArray = function(array, column) { + var slice = []; + var numRows = array.length; + for (var row = 0; row < numRows; row++) { + slice.push(array[row][column]); + } + return slice; + } + /** * Returns a human-readable (in local time zone) time string for a * particular moment in time. diff --git a/gm/rebaseline_server/static/view.html b/gm/rebaseline_server/static/view.html index bbe1f210f3..b2f3fba4f3 100644 --- a/gm/rebaseline_server/static/view.html +++ b/gm/rebaseline_server/static/view.html @@ -68,13 +68,13 @@ resultType
-