diff options
Diffstat (limited to 'gm/rebaseline_server')
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 = {}; @@ -744,6 +746,28 @@ Loader.controller( // /** + * 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 @@ <tr valign="top"> <td> resultType<br> - <label ng-repeat="(resultType, count) in extraColumnHeaders[constants.KEY__EXTRACOLUMN__RESULT_TYPE][constants.KEY__VALUES_AND_COUNTS] track by $index"> + <label ng-repeat="valueAndCount in extraColumnHeaders[constants.KEY__EXTRACOLUMN__RESULT_TYPE][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]"> <input type="checkbox" name="resultTypes" - value="{{resultType}}" - ng-checked="!isValueInSet(resultType, hiddenResultTypes)" - ng-click="toggleValueInSet(resultType, hiddenResultTypes); setUpdatesPending(true)"> - {{resultType}} ({{count}})<br> + value="{{valueAndCount[0]}}" + ng-checked="!isValueInSet(valueAndCount[0], hiddenResultTypes)" + ng-click="toggleValueInSet(valueAndCount[0], hiddenResultTypes); setUpdatesPending(true)"> + {{valueAndCount[0]}} ({{valueAndCount[1]}})<br> </label> <button ng-click="hiddenResultTypes = {}; updateResults()"> all @@ -100,13 +100,13 @@ </td> <td> config<br> - <label ng-repeat="(config, count) in extraColumnHeaders[constants.KEY__EXTRACOLUMN__CONFIG][constants.KEY__VALUES_AND_COUNTS] track by $index"> + <label ng-repeat="valueAndCount in extraColumnHeaders[constants.KEY__EXTRACOLUMN__CONFIG][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]"> <input type="checkbox" name="configs" - value="{{config}}" - ng-checked="!isValueInSet(config, hiddenConfigs)" - ng-click="toggleValueInSet(config, hiddenConfigs); setUpdatesPending(true)"> - {{config}} ({{count}})<br> + value="{{valueAndCount[0]}}" + ng-checked="!isValueInSet(valueAndCount[0], hiddenConfigs)" + ng-click="toggleValueInSet(valueAndCount[0], hiddenConfigs); setUpdatesPending(true)"> + {{valueAndCount[0]}} ({{valueAndCount[1]}})<br> </label> <button ng-click="hiddenConfigs = {}; updateResults()"> all diff --git a/gm/rebaseline_server/testdata/outputs/expected/compare_configs_test.CompareConfigsTest.test_gm/gm.json b/gm/rebaseline_server/testdata/outputs/expected/compare_configs_test.CompareConfigsTest.test_gm/gm.json index aabbdbf859..6d63113f37 100644 --- a/gm/rebaseline_server/testdata/outputs/expected/compare_configs_test.CompareConfigsTest.test_gm/gm.json +++ b/gm/rebaseline_server/testdata/outputs/expected/compare_configs_test.CompareConfigsTest.test_gm/gm.json @@ -4,51 +4,96 @@ "headerText": "builder", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "Test-Android-GalaxyNexus-SGX540-Arm7-Release": 7, - "Test-Builder-We-Have-No-Expectations-File-For": 3, - "Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug": 3 - } + "valuesAndCounts": [ + [ + "Test-Android-GalaxyNexus-SGX540-Arm7-Release", + 7 + ], + [ + "Test-Builder-We-Have-No-Expectations-File-For", + 3 + ], + [ + "Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug", + 3 + ] + ] }, "config": { "headerText": "config", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "TODO": 13 - } + "valuesAndCounts": [ + [ + "TODO", + 13 + ] + ] }, "resultType": { "headerText": "resultType", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "failed": 4, - "no-comparison": 7, - "succeeded": 2 - } + "valuesAndCounts": [ + [ + "failed", + 4 + ], + [ + "no-comparison", + 7 + ], + [ + "succeeded", + 2 + ] + ] }, "test": { "headerText": "test", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "3x3bitmaprect": 3, - "aaclip": 1, - "bigblurs": 3, - "bitmapsource": 1, - "displacement": 2, - "filterbitmap_checkerboard_192_192": 1, - "filterbitmap_checkerboard_32_2": 1, - "texdata": 1 - } + "valuesAndCounts": [ + [ + "3x3bitmaprect", + 3 + ], + [ + "aaclip", + 1 + ], + [ + "bigblurs", + 3 + ], + [ + "bitmapsource", + 1 + ], + [ + "displacement", + 2 + ], + [ + "filterbitmap_checkerboard_192_192", + 1 + ], + [ + "filterbitmap_checkerboard_32_2", + 1 + ], + [ + "texdata", + 1 + ] + ] } }, "header": { "dataHash": "-7043844904261310530", "isEditable": false, "isExported": true, - "schemaVersion": 2, + "schemaVersion": 3, "timeNextUpdateAvailable": null, "timeUpdated": 12345678, "type": "all" diff --git a/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd/compare_rendered_pictures.json b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd/compare_rendered_pictures.json index fbe48c088d..464b1d4e94 100644 --- a/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd/compare_rendered_pictures.json +++ b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd/compare_rendered_pictures.json @@ -4,45 +4,72 @@ "headerText": "builder", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "TODO": 4 - } + "valuesAndCounts": [ + [ + "TODO", + 4 + ] + ] }, "config": { "headerText": "config", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "whole-image": 4 - } + "valuesAndCounts": [ + [ + "whole-image", + 4 + ] + ] }, "resultType": { "headerText": "resultType", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "failed": 1, - "no-comparison": 2, - "succeeded": 1 - } + "valuesAndCounts": [ + [ + "failed", + 1 + ], + [ + "no-comparison", + 2 + ], + [ + "succeeded", + 1 + ] + ] }, "test": { "headerText": "test", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "changed.skp": 1, - "only-in-after.skp": 1, - "only-in-before.skp": 1, - "unchanged.skp": 1 - } + "valuesAndCounts": [ + [ + "changed.skp", + 1 + ], + [ + "only-in-after.skp", + 1 + ], + [ + "only-in-before.skp", + 1 + ], + [ + "unchanged.skp", + 1 + ] + ] } }, "header": { "dataHash": "-595743736412687673", "isEditable": false, "isExported": true, - "schemaVersion": 2, + "schemaVersion": 3, "timeNextUpdateAvailable": null, "timeUpdated": 12345678, "type": "all" diff --git a/gm/rebaseline_server/testdata/outputs/expected/compare_to_expectations_test.CompareToExpectationsTest.test_gm/gm.json b/gm/rebaseline_server/testdata/outputs/expected/compare_to_expectations_test.CompareToExpectationsTest.test_gm/gm.json index f8774689fa..4f4eef7bf8 100644 --- a/gm/rebaseline_server/testdata/outputs/expected/compare_to_expectations_test.CompareToExpectationsTest.test_gm/gm.json +++ b/gm/rebaseline_server/testdata/outputs/expected/compare_to_expectations_test.CompareToExpectationsTest.test_gm/gm.json @@ -4,55 +4,112 @@ "headerText": "builder", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "Test-Android-GalaxyNexus-SGX540-Arm7-Release": 13, - "Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug": 15 - } + "valuesAndCounts": [ + [ + "Test-Android-GalaxyNexus-SGX540-Arm7-Release", + 13 + ], + [ + "Test-Mac10.7-MacMini4.1-GeForce320M-x86_64-Debug", + 15 + ] + ] }, "config": { "headerText": "config", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "565": 9, - "8888": 9, - "gpu": 4, - "pdf-mac": 3, - "pdf-poppler": 3 - } + "valuesAndCounts": [ + [ + "565", + 9 + ], + [ + "8888", + 9 + ], + [ + "gpu", + 4 + ], + [ + "pdf-mac", + 3 + ], + [ + "pdf-poppler", + 3 + ] + ] }, "resultType": { "headerText": "resultType", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "failed": 1, - "failure-ignored": 4, - "no-comparison": 9, - "succeeded": 14 - } + "valuesAndCounts": [ + [ + "failed", + 1 + ], + [ + "failure-ignored", + 4 + ], + [ + "no-comparison", + 9 + ], + [ + "succeeded", + 14 + ] + ] }, "test": { "headerText": "test", "isFilterable": true, "isSortable": true, - "valuesAndCounts": { - "3x3bitmaprect": 7, - "aaclip": 2, - "bigblurs": 7, - "bitmapsource": 2, - "displacement": 5, - "filterbitmap_checkerboard_192_192": 2, - "filterbitmap_checkerboard_32_2": 2, - "texdata": 1 - } + "valuesAndCounts": [ + [ + "3x3bitmaprect", + 7 + ], + [ + "aaclip", + 2 + ], + [ + "bigblurs", + 7 + ], + [ + "bitmapsource", + 2 + ], + [ + "displacement", + 5 + ], + [ + "filterbitmap_checkerboard_192_192", + 2 + ], + [ + "filterbitmap_checkerboard_32_2", + 2 + ], + [ + "texdata", + 1 + ] + ] } }, "header": { "dataHash": "2775016045957284034", "isEditable": false, "isExported": true, - "schemaVersion": 2, + "schemaVersion": 3, "timeNextUpdateAvailable": null, "timeUpdated": 12345678, "type": "all" |