Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: scripts/slave/recipe_modules/chromium_tests/steps.py

Issue 1424693002: Add swarming support for IsolatedScriptTest. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@master
Patch Set: Add idempotent TODO Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import re 5 import re
6 import string 6 import string
7 7
8 8
9 class Test(object): 9 class Test(object):
10 """ 10 """
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 isolate_file_path = (api.path['checkout'].join(self._android_isolate_path) 868 isolate_file_path = (api.path['checkout'].join(self._android_isolate_path)
869 if self._android_isolate_path else None) 869 if self._android_isolate_path else None)
870 return AndroidInstrumentationTest( 870 return AndroidInstrumentationTest(
871 name=self.name, 871 name=self.name,
872 compile_target=self._compile_target, 872 compile_target=self._compile_target,
873 apk_under_test=self._apk_under_test, 873 apk_under_test=self._apk_under_test,
874 test_apk=self.name, 874 test_apk=self.name,
875 isolate_file_path=isolate_file_path).run(api, suffix) 875 isolate_file_path=isolate_file_path).run(api, suffix)
876 876
877 877
878 class IsolatedScriptTest(Test): 878 class LocalIsolatedScriptTest(Test):
879 def __init__(self, name, args=None, target_name=None, **runtest_kwargs): 879 def __init__(self, name, args=None, target_name=None, **runtest_kwargs):
880 """Constructs an instance of IsolatedScriptTest. 880 """Constructs an instance of LocalIsolatedScriptTest.
881 881
882 An IsolatedScriptTest knows how to invoke an isolate which obeys a certain 882 An LocalIsolatedScriptTest knows how to invoke an isolate which obeys a cert ain
883 contract. The isolate's main target must be a wrapper script which must 883 contract. The isolate's main target must be a wrapper script which must
884 interpret certain command line arguments as follows: 884 interpret certain command line arguments as follows:
885 885
886 --isolated-script-test-output [FILENAME] 886 --isolated-script-test-output [FILENAME]
887 887
888 The wrapper script must write the simplified json output that the recipes 888 The wrapper script must write the simplified json output that the recipes
889 consume (similar to GTestTest and ScriptTest) into |FILENAME|. 889 consume (similar to GTestTest and ScriptTest) into |FILENAME|.
890 890
891 The contract may be expanded later to support functionality like sharding 891 The contract may be expanded later to support functionality like sharding
892 and retries of specific failed tests. Currently the examples of such wrapper 892 and retries of specific failed tests. Currently the examples of such wrapper
893 scripts live in src/testing/scripts/ in the Chromium workspace. 893 scripts live in src/testing/scripts/ in the Chromium workspace.
894 894
895 Args: 895 Args:
896 name: Displayed name of the test. May be modified by suffixes. 896 name: Displayed name of the test. May be modified by suffixes.
897 args: Arguments to be passed to the test. 897 args: Arguments to be passed to the test.
898 target_name: Actual name of the test. Defaults to name. 898 target_name: Actual name of the test. Defaults to name.
899 runtest_kwargs: Additional keyword args forwarded to the runtest. 899 runtest_kwargs: Additional keyword args forwarded to the runtest.
900 """ 900 """
901 super(IsolatedScriptTest, self).__init__() 901 super(LocalIsolatedScriptTest, self).__init__()
902 self._name = name 902 self._name = name
903 self._args = args or [] 903 self._args = args or []
904 self._target_name = target_name 904 self._target_name = target_name
905 self._runtest_kwargs = runtest_kwargs 905 self._runtest_kwargs = runtest_kwargs
906 906
907 @property 907 @property
908 def name(self): 908 def name(self):
909 return self._name 909 return self._name
910 910
911 @property 911 @property
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 self.failures(api, suffix) 962 self.failures(api, suffix)
963 963
964 return self._test_runs[suffix].json.output['valid'] 964 return self._test_runs[suffix].json.output['valid']
965 except Exception: # pragma: no cover 965 except Exception: # pragma: no cover
966 return False 966 return False
967 967
968 def failures(self, api, suffix): 968 def failures(self, api, suffix):
969 return self._test_runs[suffix].json.output['failures'] 969 return self._test_runs[suffix].json.output['failures']
970 970
971 971
972 class SwarmingIsolatedScriptTest(SwarmingTest):
973 def __init__(self, name, args=None, target_name=None, shards=1,
974 dimensions=None, tags=None, extra_suffix=None,
975 upload_test_results=True):
976 super(SwarmingIsolatedScriptTest, self).__init__(
977 name, dimensions, tags, target_name, extra_suffix)
978 self._args = args or []
979 self._shards = shards
980 self._upload_test_results = upload_test_results
981
982 @property
983 def target_name(self):
984 return self._target_name or self._name
985
986 def compile_targets(self, _):
987 return [self.target_name]
988
989 @property
990 def uses_swarming(self):
991 return True
992
993 def create_task(self, api, suffix, isolated_hash):
994 # For local tests args are added inside api.chromium.run_telemetry_test.
995 browser_config = api.chromium.c.build_config_fs.lower()
996 args = self._args[:]
997
998 # TODO(nednguyen): only rerun the tests that failed.
999 if suffix == 'without patch': # pragma: no cover
Paweł Hajdan Jr. 2015/10/26 17:00:40 Whoa, retrying everything would be much better tha
nednguyen 2015/10/27 00:54:29 But not doing anything here mean we gonna rerun al
Paweł Hajdan Jr. 2015/10/27 11:12:52 Oh, I realized it's "pass" and not "return". Sorry
nednguyen 2015/10/27 16:36:48 Done.
1000 pass
1001
1002 # For the time being, we assume all isolated_script_test are not idempotent
1003 # TODO(nednguyen): make this configurable in isolated_scripts's spec.
1004 return api.swarming.isolated_script_task(
1005 title=self._step_name(suffix), isolated_hash=isolated_hash,
1006 idempotent=None, extra_args=args)
Paweł Hajdan Jr. 2015/10/26 17:00:41 Why None as opposed to e.g. False?
nednguyen 2015/10/27 00:54:29 Done.
1007
1008 def validate_task_results(self, api, step_result):
1009 results = getattr(step_result, 'isolated_script_results', None) or {}
1010
1011 try:
1012 failures = results['failures']
1013 if not failures and step_result.retcode != 0:
1014 failures = ['%s (entire test suite)' % self.name]
Paweł Hajdan Jr. 2015/10/26 17:00:40 I think this means valid=False. Otherwise, if e.g
Ken Russell (switch to Gerrit) 2015/10/26 18:55:43 I'm not sure about that. Please see https://codere
Paweł Hajdan Jr. 2015/10/27 11:12:52 Yup, returning no failures where there are in fact
Ken Russell (switch to Gerrit) 2015/10/27 12:55:55 Looking again at https://codereview.chromium.org/1
nednguyen 2015/10/27 16:36:48 Set "valid=False" here.
1015 valid = results['valid']
1016 except (ValueError, KeyError) as e:
1017 step_result.presentation.logs['invalid_results_exc'] = [str(e)]
1018 valid = False
1019 failures = None
1020 if valid:
1021 step_result.presentation.step_text += api.test_utils.format_step_text([
1022 ['failures:', failures]
1023 ])
1024 return valid, failures
1025
1026
1027 class IsolatedScriptTest(Test):
Paweł Hajdan Jr. 2015/10/26 17:00:41 What's the reason for introducing another indirect
Ken Russell (switch to Gerrit) 2015/10/26 18:55:43 It'd be fine IMO to remove this indirection, FWIW.
nednguyen 2015/10/27 00:54:29 Done.
1028 def __init__(self, name, args=None, target_name=None, enable_swarming=False,
1029 swarming_shards=1, swarming_dimensions=None, swarming_tags=None,
1030 swarming_extra_suffix=None, **runtest_kwargs):
1031 super(IsolatedScriptTest, self).__init__()
1032 if enable_swarming:
1033 self._test = SwarmingIsolatedScriptTest(
1034 name, args, target_name, swarming_shards, swarming_dimensions,
1035 swarming_tags, swarming_extra_suffix)
1036 else:
1037 self._test = LocalIsolatedScriptTest(name, args, target_name,
1038 **runtest_kwargs)
1039
1040 @property
1041 def name(self):
1042 return self._test.name
1043
1044 @property
1045 def uses_local_devices(self):
1046 return True # pragma: no cover
1047
1048 @property
1049 def isolate_target(self):
1050 return self._test.isolate_target
1051
1052 def compile_targets(self, api):
1053 return self._test.compile_targets(api)
1054
1055 def pre_run(self, api, suffix):
1056 return self._test.pre_run(api, suffix)
1057
1058 def run(self, api, suffix):
1059 return self._test.run(api, suffix)
1060
1061 def post_run(self, api, suffix):
1062 return self._test.post_run(api, suffix)
1063
1064 def has_valid_results(self, api, suffix):
1065 return self._test.has_valid_results(api, suffix) # pragma: no cover
1066
1067 def failures(self, api, suffix):
1068 return self._test.failures(api, suffix) # pragma: no cover
1069
1070 @property
1071 def uses_swarming(self):
1072 return self._test.uses_swarming
1073
1074
972 def generate_isolated_script(api, mastername, buildername, test_spec, 1075 def generate_isolated_script(api, mastername, buildername, test_spec,
973 enable_swarming=False, 1076 enable_swarming=False,
974 scripts_compile_targets=None): 1077 scripts_compile_targets=None):
975 for spec in test_spec.get(buildername, {}).get( 1078 for spec in test_spec.get(buildername, {}).get('isolated_scripts', []):
976 'isolated_scripts', []): 1079 use_swarming = False
1080 swarming_shards = 1
1081 if enable_swarming:
1082 swarming_spec = spec.get('swarming', {})
1083 if swarming_spec.get('can_use_on_swarming_builders'):
1084 use_swarming = True
1085 swarming_shards = swarming_spec.get('shards', 1)
1086
977 yield IsolatedScriptTest( 1087 yield IsolatedScriptTest(
978 str(spec['name']), 1088 str(spec['name']),
979 args=spec.get('args', []), 1089 args=spec.get('args', []),
980 target_name=spec['isolate_name']) 1090 target_name=spec['isolate_name'],
1091 enable_swarming=use_swarming,
1092 swarming_shards=swarming_shards)
981 1093
982 1094
983 class GTestTest(Test): 1095 class GTestTest(Test):
984 def __init__(self, name, args=None, target_name=None, enable_swarming=False, 1096 def __init__(self, name, args=None, target_name=None, enable_swarming=False,
985 swarming_shards=1, swarming_dimensions=None, swarming_tags=None, 1097 swarming_shards=1, swarming_dimensions=None, swarming_tags=None,
986 swarming_extra_suffix=None, **runtest_kwargs): 1098 swarming_extra_suffix=None, **runtest_kwargs):
987 super(GTestTest, self).__init__() 1099 super(GTestTest, self).__init__()
988 if enable_swarming: 1100 if enable_swarming:
989 self._test = SwarmingGTestTest( 1101 self._test = SwarmingGTestTest(
990 name, args, target_name, swarming_shards, swarming_dimensions, 1102 name, args, target_name, swarming_shards, swarming_dimensions,
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 def run(self, api, suffix): 1809 def run(self, api, suffix):
1698 api.chromium_android.coverage_report(upload=False) 1810 api.chromium_android.coverage_report(upload=False)
1699 api.chromium_android.get_changed_lines_for_revision() 1811 api.chromium_android.get_changed_lines_for_revision()
1700 api.chromium_android.incremental_coverage_report() 1812 api.chromium_android.incremental_coverage_report()
1701 1813
1702 1814
1703 GOMA_TESTS = [ 1815 GOMA_TESTS = [
1704 GTestTest('base_unittests'), 1816 GTestTest('base_unittests'),
1705 GTestTest('content_unittests'), 1817 GTestTest('content_unittests'),
1706 ] 1818 ]
OLDNEW
« no previous file with comments | « no previous file | scripts/slave/recipe_modules/swarming/api.py » ('j') | scripts/slave/recipe_modules/swarming/api.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698