Changeset 100875 in webkit


Ignore:
Timestamp:
Nov 20, 2011 5:26:57 PM (12 years ago)
Author:
ojan@chromium.org
Message:

Change the final place where we use version 3 of the results json output
https://bugs.webkit.org/show_bug.cgi?id=72838

Reviewed by Adam Barth.

This converts the json from being a flat map of test name --> results
to being hierarchical by directory. This will make the json files
considerably smaller.

Also cleaned up some functions that were returning/checking boolean values
that were always True.

  • TestResultServer/model/jsonresults.py:
  • TestResultServer/model/jsonresults_unittest.py:
Location:
trunk/Tools
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r100873 r100875  
     12011-11-20  Ojan Vafai  <ojan@chromium.org>
     2
     3        Change the final place where we use version 3 of the results json output
     4        https://bugs.webkit.org/show_bug.cgi?id=72838
     5
     6        Reviewed by Adam Barth.
     7
     8        This converts the json from being a flat map of test name --> results
     9        to being hierarchical by directory. This will make the json files
     10        considerably smaller.
     11
     12        Also cleaned up some functions that were returning/checking boolean values
     13        that were always True.
     14
     15        * TestResultServer/model/jsonresults.py:
     16        * TestResultServer/model/jsonresults_unittest.py:
     17
    1182011-11-20  Ojan Vafai  <ojan@chromium.org>
    219
  • trunk/Tools/TestResultServer/model/jsonresults.py

    r100863 r100875  
    4545JSON_RESULTS_NO_DATA = "N"
    4646JSON_RESULTS_MIN_TIME = 1
    47 JSON_RESULTS_VERSION = 3
    4847JSON_RESULTS_HIERARCHICAL_VERSION = 4
    4948JSON_RESULTS_MAX_BUILDS = 750
    5049JSON_RESULTS_MAX_BUILDS_SMALL = 200
     50
     51
     52def _add_path_to_trie(path, value, trie):
     53    if not "/" in path:
     54        trie[path] = value
     55        return
     56
     57    directory, slash, rest = path.partition("/")
     58    if not directory in trie:
     59        trie[directory] = {}
     60    _add_path_to_trie(rest, value, trie[directory])
     61
     62
     63def _trie_json_tests(tests):
     64    """Breaks a test name into chunks by directory and puts the test time as a value in the lowest part, e.g.
     65    foo/bar/baz.html: VALUE1
     66    foo/bar/baz1.html: VALUE2
     67
     68    becomes
     69    foo: {
     70        bar: {
     71            baz.html: VALUE1,
     72            baz1.html: VALUE2
     73        }
     74    }
     75    """
     76    trie = {}
     77    for test, value in tests.iteritems():
     78        _add_path_to_trie(test, value, trie)
     79    return trie
    5180
    5281
     
    79108    @classmethod
    80109    def _merge_json(cls, aggregated_json, incremental_json, num_runs):
    81         if not cls._merge_non_test_data(aggregated_json, incremental_json, num_runs):
    82             return False
    83 
     110        cls._merge_non_test_data(aggregated_json, incremental_json, num_runs)
    84111        incremental_tests = incremental_json[JSON_RESULTS_TESTS]
    85112        if incremental_tests:
     
    87114            cls._merge_tests(aggregated_tests, incremental_tests, num_runs)
    88115
    89         return True
    90 
    91116    @classmethod
    92117    def _merge_non_test_data(cls, aggregated_json, incremental_json, num_runs):
     
    101126            # Merge this build into aggreagated results.
    102127            cls._merge_one_build(aggregated_json, incremental_json, index, num_runs)
    103 
    104         return True
    105128
    106129    @classmethod
     
    120143    @classmethod
    121144    def _merge_tests(cls, aggregated_json, incremental_json, num_runs):
    122         all_tests = set(aggregated_json.iterkeys()) | set(incremental_json.iterkeys())
     145        all_tests = set(aggregated_json.iterkeys())
     146        if incremental_json:
     147            all_tests |= set(incremental_json.iterkeys())
     148
    123149        for test_name in all_tests:
    124             if test_name in aggregated_json:
    125                 aggregated_test = aggregated_json[test_name]
    126                 if test_name in incremental_json:
    127                     incremental_test = incremental_json[test_name]
    128                     results = incremental_test[JSON_RESULTS_RESULTS]
    129                     times = incremental_test[JSON_RESULTS_TIMES]
    130                 else:
    131                     results = [[1, JSON_RESULTS_NO_DATA]]
    132                     times = [[1, 0]]
    133 
    134                 cls._insert_item_run_length_encoded(results, aggregated_test[JSON_RESULTS_RESULTS], num_runs)
    135                 cls._insert_item_run_length_encoded(times, aggregated_test[JSON_RESULTS_TIMES], num_runs)
    136                 cls._normalize_results_json(test_name, aggregated_json, num_runs)
     150            if test_name not in aggregated_json:
     151                aggregated_json[test_name] = incremental_json[test_name]
     152                continue
     153
     154            if JSON_RESULTS_RESULTS not in aggregated_json[test_name]:
     155                incremental_sub_result = incremental_json[test_name] if test_name in incremental_json else None
     156                cls._merge_tests(aggregated_json[test_name], incremental_sub_result, num_runs)
     157                continue
     158
     159            if incremental_json and test_name in incremental_json:
     160                incremental_test = incremental_json[test_name]
     161                results = incremental_test[JSON_RESULTS_RESULTS]
     162                times = incremental_test[JSON_RESULTS_TIMES]
    137163            else:
    138                 aggregated_json[test_name] = incremental_json[test_name]
     164                results = [[1, JSON_RESULTS_NO_DATA]]
     165                times = [[1, 0]]
     166
     167            aggregated_test = aggregated_json[test_name]
     168            cls._insert_item_run_length_encoded(results, aggregated_test[JSON_RESULTS_RESULTS], num_runs)
     169            cls._insert_item_run_length_encoded(times, aggregated_test[JSON_RESULTS_TIMES], num_runs)
     170            cls._normalize_results_json(test_name, aggregated_json, num_runs)
    139171
    140172    @classmethod
     
    176208
    177209    @classmethod
    178     def _flatten_json_tests(cls, json, prefix=None):
    179         """Flattens a trie directory structure of tests into a flat structure.
    180         """
    181         result = {}
    182         for name, test in json.iteritems():
    183             if prefix:
    184                 fullname = prefix + "/" + name
    185             else:
    186                 fullname = name
    187 
    188             if "results" in test:
    189                 result[fullname] = test
    190             else:
    191                 result.update(cls._flatten_json_tests(test, fullname))
    192 
    193         return result
    194 
    195     @classmethod
    196210    def _remove_gtest_modifiers(cls, builder, json):
    197211        tests = json[builder][JSON_RESULTS_TESTS]
    198212        new_tests = {}
     213        # FIXME: This is wrong. If the test exists in the incremental results as both values, then one will overwrite the other.
     214        # We should instead pick the one that doesn't have NO_DATA as its value.
     215        # Alternately we could fix this by having the JSON generation code on the buildbot only include the test
     216        # that was actually run.
    199217        for name, test in tests.iteritems():
    200218            new_name = name.replace('.FLAKY_', '.', 1)
     
    222240            return False
    223241
    224         # FIXME(aboxhall): Once the dashboard can read hierarchical JSON, both
    225         # incremental and aggregated JSON can be hierarchical, with no need to
    226         # flatten here.
    227         if version == JSON_RESULTS_HIERARCHICAL_VERSION:
    228             flattened_tests = cls._flatten_json_tests(results_for_builder[JSON_RESULTS_TESTS])
    229             json[builder][JSON_RESULTS_TESTS] = flattened_tests
    230             json[JSON_RESULTS_VERSION_KEY] = JSON_RESULTS_VERSION
     242        # FIXME: Once all the bots have cycled, we can remove this code since all the results will be heirarchical.
     243        if version < JSON_RESULTS_HIERARCHICAL_VERSION:
     244            json[builder][JSON_RESULTS_TESTS] = _trie_json_tests(results_for_builder[JSON_RESULTS_TESTS])
     245            json[JSON_RESULTS_VERSION_KEY] = JSON_RESULTS_HIERARCHICAL_VERSION
    231246
    232247        return True
     
    261276        logging.info("Merging json results...")
    262277        try:
    263             if not cls._merge_json(aggregated_json[builder], incremental_json[builder], num_runs):
    264                 return None
     278            cls._merge_json(aggregated_json[builder], incremental_json[builder], num_runs)
    265279        except Exception, err:
    266280            logging.error("Failed to merge json results: %s", str(err))
    267281            return None
    268282
    269         aggregated_json[JSON_RESULTS_VERSION_KEY] = JSON_RESULTS_VERSION
     283        aggregated_json[JSON_RESULTS_VERSION_KEY] = JSON_RESULTS_HIERARCHICAL_VERSION
    270284
    271285        return cls._generate_file_data(aggregated_json, sort_keys)
  • trunk/Tools/TestResultServer/model/jsonresults_unittest.py

    r100863 r100875  
    114114        json = json.replace("[TESTDATA_TIMES]", ",".join(times))
    115115
    116         if "version" in test_data:
    117             json = json.replace("[VERSION]", str(test_data["version"]))
    118         else:
    119             json = json.replace("[VERSION]", "3")
     116        version = str(test_data["version"]) if "version" in test_data else "4"
     117        json = json.replace("[VERSION]", version)
    120118
    121119        json_tests = []
     
    557555            # Aggregated results
    558556            {"builds": ["2", "1"],
    559              "tests": {"foo/001.html": {
     557             "tests": {"bar/003.html": {
     558                           "results": "[25,\"F\"]",
     559                           "times": "[25,0]"},
     560                       "foo/001.html": {
    560561                           "results": "[50,\"F\"]",
    561562                           "times": "[50,0]"},
    562563                       "foo/002.html": {
    563564                           "results": "[100,\"I\"]",
    564                            "times": "[100,0]"}}},
    565             # Incremental results
    566             {"builds": ["3"],
    567              "tests": {"foo": {
     565                           "times": "[100,0]"}},
     566             "version": 3},
     567            # Incremental results
     568            {"builds": ["3"],
     569             "tests": {"baz": {
     570                           "004.html": {
     571                               "results": "[1,\"I\"]",
     572                               "times": "[1,0]"}},
     573                       "foo": {
    568574                           "001.html": {
    569575                               "results": "[1,\"F\"]",
     
    575581            # Expected results
    576582            {"builds": ["3", "2", "1"],
    577              "tests": {"foo/001.html": {
    578                            "results": "[51,\"F\"]",
    579                            "times": "[51,0]"},
    580                        "foo/002.html": {
    581                            "results": "[101,\"I\"]",
    582                            "times": "[101,0]"}},
    583              "version": 3})
     583             "tests": {"bar": {
     584                           "003.html": {
     585                               "results": "[1,\"N\"],[25,\"F\"]",
     586                               "times": "[26,0]"}},
     587                       "baz": {
     588                           "004.html": {
     589                               "results": "[1,\"I\"]",
     590                               "times": "[1,0]"}},
     591                       "foo": {
     592                           "001.html": {
     593                               "results": "[51,\"F\"]",
     594                               "times": "[51,0]"},
     595                           "002.html": {
     596                               "results": "[101,\"I\"]",
     597                               "times": "[101,0]"}}},
     598             "version": 4})
    584599
    585600    # FIXME(aboxhall): Add some tests for xhtml/svg test results.
     
    613628                           "results": "[100,\"I\"]",
    614629                           "times": "[100,0]"},
    615                        }},
     630                       },
     631             "version": 3},
    616632            # Incremental results
    617633            {"builds": ["3"],
     
    649665                           "results": "[1,\"I\"]",
    650666                           "times": "[1,0]"}},
    651              "version": 3})
     667             "version": 4})
    652668
    653669if __name__ == '__main__':
Note: See TracChangeset for help on using the changeset viewer.