Chromium Code Reviews| Index: gm/rebaseline_server/results.py |
| =================================================================== |
| --- gm/rebaseline_server/results.py (revision 11711) |
| +++ gm/rebaseline_server/results.py (working copy) |
| @@ -32,26 +32,36 @@ |
| CATEGORIES_TO_SUMMARIZE = [ |
| 'builder', 'test', 'config', 'resultType', |
| ] |
| +RESULTS_ALL = 'all' |
| +RESULTS_FAILURES = 'failures' |
| class Results(object): |
| """ Loads actual and expected results from all builders, supplying combined |
| - reports as requested. """ |
| + reports as requested. |
| + Once this object has been constructed, the results are immutable. If you |
| + want to update the results based on updated JSON file contents, you will |
| + need to create a new Results object.""" |
| + |
| def __init__(self, actuals_root, expected_root): |
| """ |
| Args: |
| actuals_root: root directory containing all actual-results.json files |
| expected_root: root directory containing all expected-results.json files |
| """ |
| - self._actual_builder_dicts = Results._GetDictsFromRoot(actuals_root) |
| - self._expected_builder_dicts = Results._GetDictsFromRoot(expected_root) |
| - self._all_results = Results._Combine( |
| - actual_builder_dicts=self._actual_builder_dicts, |
| - expected_builder_dicts=self._expected_builder_dicts) |
| + self._actual_builder_dicts = Results._get_dicts_from_root(actuals_root) |
| + self._expected_builder_dicts = Results._get_dicts_from_root(expected_root) |
| + self._combine_actual_and_expected() |
| - def GetAll(self): |
| - """Return results of all tests, as a dictionary in this form: |
| + def get_results_of_type(self, type): |
| + """Return results of some/all tests (depending on 'type' parameter). |
| + Args: |
| + type: string describing which types of results to include; must be one |
| + of the RESULTS_* constants |
| + |
| + Results are returned as a dictionary in this form: |
| + |
| { |
| 'categories': # dictionary of categories listed in |
| # CATEGORIES_TO_SUMMARIZE, with the number of times |
| @@ -76,7 +86,6 @@ |
| 'testData': # list of test results, with a dictionary for each |
| [ |
| { |
| - 'index': 0, # index of this result within testData list |
|
epoger
2013/10/10 19:16:08
We generate the "index" entries on the client side
|
| 'builder': 'Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug', |
| 'test': 'bigmatrix', |
| 'config': '8888', |
| @@ -90,10 +99,10 @@ |
| ], # end of 'testData' list |
| } |
| """ |
| - return self._all_results |
| + return self._results[type] |
| @staticmethod |
| - def _GetDictsFromRoot(root, pattern='*.json'): |
|
epoger
2013/10/10 19:16:08
Updated function/method names as per http://google
|
| + def _get_dicts_from_root(root, pattern='*.json'): |
| """Read all JSON dictionaries within a directory tree. |
| Args: |
| @@ -114,37 +123,32 @@ |
| meta_dict[builder] = gm_json.LoadFromFile(fullpath) |
| return meta_dict |
| - @staticmethod |
| - def _Combine(actual_builder_dicts, expected_builder_dicts): |
| + def _combine_actual_and_expected(self): |
| """Gathers the results of all tests, across all builders (based on the |
| - contents of actual_builder_dicts and expected_builder_dicts). |
| - |
| - This is a static method, because once we start refreshing results |
| - asynchronously, we need to make sure we are not corrupting the object's |
| - member variables. |
| - |
| - Args: |
| - actual_builder_dicts: a meta-dictionary of all actual JSON results, |
| - as returned by _GetDictsFromRoot(). |
| - actual_builder_dicts: a meta-dictionary of all expected JSON results, |
| - as returned by _GetDictsFromRoot(). |
| - |
| - Returns: |
| - A list of all the results of all tests, in the same form returned by |
| - self.GetAll(). |
| + contents of self._actual_builder_dicts and self._expected_builder_dicts), |
| + and stores them in self._results. |
| """ |
| - test_data = [] |
| - category_dict = {} |
| - Results._EnsureIncludedInCategoryDict(category_dict, 'resultType', [ |
| + categories_all = {} |
| + categories_failures = {} |
| + Results._ensure_included_in_category_dict(categories_all, |
| + 'resultType', [ |
| gm_json.JSONKEY_ACTUALRESULTS_FAILED, |
| gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED, |
| gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON, |
| gm_json.JSONKEY_ACTUALRESULTS_SUCCEEDED, |
| ]) |
| + Results._ensure_included_in_category_dict(categories_failures, |
| + 'resultType', [ |
| + gm_json.JSONKEY_ACTUALRESULTS_FAILED, |
| + gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED, |
| + gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON, |
| + ]) |
| - for builder in sorted(actual_builder_dicts.keys()): |
| + data_all = [] |
| + data_failures = [] |
| + for builder in sorted(self._actual_builder_dicts.keys()): |
| actual_results_for_this_builder = ( |
| - actual_builder_dicts[builder][gm_json.JSONKEY_ACTUALRESULTS]) |
| + self._actual_builder_dicts[builder][gm_json.JSONKEY_ACTUALRESULTS]) |
| for result_type in sorted(actual_results_for_this_builder.keys()): |
| results_of_this_type = actual_results_for_this_builder[result_type] |
| if not results_of_this_type: |
| @@ -154,7 +158,7 @@ |
| try: |
| # TODO(epoger): assumes a single allowed digest per test |
| expected_image = ( |
| - expected_builder_dicts |
| + self._expected_builder_dicts |
| [builder][gm_json.JSONKEY_EXPECTEDRESULTS] |
| [image_name][gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGESTS] |
| [0]) |
| @@ -213,7 +217,6 @@ |
| (test, config) = IMAGE_FILENAME_RE.match(image_name).groups() |
| results_for_this_test = { |
| - 'index': len(test_data), |
| 'builder': builder, |
| 'test': test, |
| 'config': config, |
| @@ -223,12 +226,22 @@ |
| 'expectedHashType': expected_image[0], |
| 'expectedHashDigest': str(expected_image[1]), |
| } |
| - Results._AddToCategoryDict(category_dict, results_for_this_test) |
| - test_data.append(results_for_this_test) |
| - return {'categories': category_dict, 'testData': test_data} |
| + Results._add_to_category_dict(categories_all, results_for_this_test) |
| + data_all.append(results_for_this_test) |
| + if updated_result_type != gm_json.JSONKEY_ACTUALRESULTS_SUCCEEDED: |
| + Results._add_to_category_dict(categories_failures, |
| + results_for_this_test) |
| + data_failures.append(results_for_this_test) |
| + self._results = { |
| + RESULTS_ALL: |
| + {'categories': categories_all, 'testData': data_all}, |
| + RESULTS_FAILURES: |
| + {'categories': categories_failures, 'testData': data_failures}, |
| + } |
| + |
| @staticmethod |
| - def _AddToCategoryDict(category_dict, test_results): |
| + def _add_to_category_dict(category_dict, test_results): |
| """Add test_results to the category dictionary we are building. |
| (See documentation of self.GetAll() for the format of this dictionary.) |
| @@ -252,8 +265,8 @@ |
| category_dict[category][category_value] += 1 |
| @staticmethod |
| - def _EnsureIncludedInCategoryDict(category_dict, |
| - category_name, category_values): |
| + def _ensure_included_in_category_dict(category_dict, |
| + category_name, category_values): |
| """Ensure that the category name/value pairs are included in category_dict, |
| even if there aren't any results with that name/value pair. |
| (See documentation of self.GetAll() for the format of this dictionary.) |