| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 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 from slave import recipe_api | 5 from slave import recipe_api |
| 6 from slave.recipe_modules.webrtc import builders | 6 from slave.recipe_modules.webrtc import builders |
| 7 | 7 |
| 8 | 8 |
| 9 class WebRTCApi(recipe_api.RecipeApi): | 9 class WebRTCApi(recipe_api.RecipeApi): |
| 10 def __init__(self, **kwargs): | 10 def __init__(self, **kwargs): |
| 11 super(WebRTCApi, self).__init__(**kwargs) | 11 super(WebRTCApi, self).__init__(**kwargs) |
| 12 self._env = {} | 12 self._env = {} |
| 13 | 13 |
| 14 BUILDERS = builders.BUILDERS | 14 BUILDERS = builders.BUILDERS |
| 15 RECIPE_CONFIGS = builders.RECIPE_CONFIGS | 15 RECIPE_CONFIGS = builders.RECIPE_CONFIGS |
| 16 | 16 |
| 17 COMMON_TESTS = [ | 17 COMMON_TESTS = [ |
| 18 'audio_decoder_unittests', | 18 'audio_decoder_unittests', |
| 19 'common_audio_unittests', | 19 'common_audio_unittests', |
| 20 'common_video_unittests', | 20 'common_video_unittests', |
| 21 'modules_tests', | 21 'modules_tests', |
| 22 'modules_unittests', | 22 'modules_unittests', |
| 23 'system_wrappers_unittests', | 23 'system_wrappers_unittests', |
| 24 'test_support_unittests', | 24 'test_support_unittests', |
| 25 'tools_unittests', | 25 'tools_unittests', |
| 26 'video_engine_core_unittests', | 26 'video_engine_core_unittests', |
| 27 'video_engine_tests', | 27 'video_engine_tests', |
| 28 'voice_engine_unittests', | 28 'voice_engine_unittests', |
| 29 ] | 29 ] |
| 30 | 30 |
| 31 ANDROID_APK_TESTS = COMMON_TESTS + [ | 31 # Android APK tests. Mapping between test name and isolate file location. |
| 32 'video_capture_tests', | 32 ANDROID_APK_TESTS = { |
| 33 'webrtc_perf_tests', | 33 'audio_decoder_unittests': 'webrtc/modules/audio_coding/neteq', |
| 34 ] | 34 'common_audio_unittests': 'webrtc/common_audio', |
| 35 'common_video_unittests': 'webrtc/common_video', |
| 36 'modules_tests': 'webrtc/modules', |
| 37 'modules_unittests': 'webrtc/modules', |
| 38 'system_wrappers_unittests': 'webrtc/system_wrappers/source', |
| 39 'test_support_unittests': 'webrtc/test', |
| 40 'tools_unittests': 'webrtc/tools', |
| 41 'video_capture_tests': 'webrtc/modules/video_capture', |
| 42 'video_engine_tests': 'webrtc', |
| 43 'video_engine_core_unittests': 'webrtc/video_engine', |
| 44 'voice_engine_unittests': 'webrtc/voice_engine', |
| 45 'webrtc_perf_tests': 'webrtc', |
| 46 } |
| 35 | 47 |
| 36 NORMAL_TESTS = sorted(COMMON_TESTS + [ | 48 NORMAL_TESTS = sorted(COMMON_TESTS + [ |
| 37 'libjingle_media_unittest', | 49 'libjingle_media_unittest', |
| 38 'libjingle_p2p_unittest', | 50 'libjingle_p2p_unittest', |
| 39 'libjingle_peerconnection_unittest', | 51 'libjingle_peerconnection_unittest', |
| 40 'libjingle_sound_unittest', | 52 'libjingle_sound_unittest', |
| 41 'libjingle_unittest', | 53 'libjingle_unittest', |
| 42 ]) | 54 ]) |
| 43 | 55 |
| 44 # Map of GS archive names to urls. | 56 # Map of GS archive names to urls. |
| 45 # TODO(kjellander): Convert to use the auto-generated URLs once we've setup a | 57 # TODO(kjellander): Convert to use the auto-generated URLs once we've setup a |
| 46 # separate bucket per master. | 58 # separate bucket per master. |
| 47 GS_ARCHIVES = { | 59 GS_ARCHIVES = { |
| 48 'android_dbg_archive': 'gs://chromium-webrtc/android_chromium_dbg', | 60 'android_dbg_archive': 'gs://chromium-webrtc/android_chromium_dbg', |
| 49 'android_dbg_archive_fyi': ('gs://chromium-webrtc/' | 61 'android_dbg_archive_fyi': ('gs://chromium-webrtc/' |
| 50 'android_chromium_trunk_dbg'), | 62 'android_chromium_trunk_dbg'), |
| 51 'android_apk_dbg_archive': 'gs://chromium-webrtc/android_dbg', | 63 'android_apk_dbg_archive': 'gs://chromium-webrtc/android_dbg', |
| 52 'android_apk_rel_archive': 'gs://chromium-webrtc/android_rel', | 64 'android_apk_rel_archive': 'gs://chromium-webrtc/android_rel', |
| 53 'win_rel_archive': 'gs://chromium-webrtc/Win Builder', | 65 'win_rel_archive': 'gs://chromium-webrtc/Win Builder', |
| 54 'win_rel_archive_fyi': 'gs://chromium-webrtc/win_rel-fyi', | 66 'win_rel_archive_fyi': 'gs://chromium-webrtc/win_rel-fyi', |
| 55 'mac_rel_archive': 'gs://chromium-webrtc/Mac Builder', | 67 'mac_rel_archive': 'gs://chromium-webrtc/Mac Builder', |
| 56 'linux_rel_archive': 'gs://chromium-webrtc/Linux Builder', | 68 'linux_rel_archive': 'gs://chromium-webrtc/Linux Builder', |
| 57 } | 69 } |
| 58 | 70 |
| 59 DASHBOARD_UPLOAD_URL = 'https://chromeperf.appspot.com' | 71 DASHBOARD_UPLOAD_URL = 'https://chromeperf.appspot.com' |
| 60 | 72 |
| 61 def runtests(self, test_suite=None, revision=None): | 73 def runtests(self, test_suite=None, revision=None): |
| 62 """Generate a list of tests to run. | 74 """Add a suite of test steps. |
| 63 | 75 |
| 64 Args: | 76 Args: |
| 65 test_suite: The name of the test suite. | 77 test_suite: The name of the test suite. |
| 66 revision: Revision for the build. Mandatory for perf measuring tests. | 78 revision: Revision for the build. Mandatory for perf measuring tests. |
| 67 """ | 79 """ |
| 68 steps = [] | |
| 69 if test_suite == 'webrtc': | 80 if test_suite == 'webrtc': |
| 70 for test in self.NORMAL_TESTS: | 81 for test in self.NORMAL_TESTS: |
| 71 steps.append(self.add_test(test)) | 82 self.add_test(test) |
| 72 | 83 |
| 73 if self.m.platform.is_mac and self.m.chromium.c.TARGET_BITS == 64: | 84 if self.m.platform.is_mac and self.m.chromium.c.TARGET_BITS == 64: |
| 74 test = self.m.path.join('libjingle_peerconnection_objc_test.app', | 85 test = self.m.path.join('libjingle_peerconnection_objc_test.app', |
| 75 'Contents', 'MacOS', | 86 'Contents', 'MacOS', |
| 76 'libjingle_peerconnection_objc_test') | 87 'libjingle_peerconnection_objc_test') |
| 77 steps.append(self.add_test(test, | 88 self.add_test(test, name='libjingle_peerconnection_objc_test') |
| 78 name='libjingle_peerconnection_objc_test')) | |
| 79 elif test_suite == 'webrtc_baremetal': | 89 elif test_suite == 'webrtc_baremetal': |
| 80 # Add baremetal tests, which are different depending on the platform. | 90 # Add baremetal tests, which are different depending on the platform. |
| 81 if self.m.platform.is_win or self.m.platform.is_mac: | 91 if self.m.platform.is_win or self.m.platform.is_mac: |
| 82 steps.append(self.add_test('audio_device_tests')) | 92 self.add_test('audio_device_tests') |
| 83 elif self.m.platform.is_linux: | 93 elif self.m.platform.is_linux: |
| 84 f = self.m.path['checkout'].join | 94 f = self.m.path['checkout'].join |
| 85 steps.append(self.add_test( | 95 self.add_test( |
| 86 'audioproc', | 96 'audioproc', |
| 87 args=['-aecm', '-ns', '-agc', '--fixed_digital', '--perf', '-pb', | 97 args=['-aecm', '-ns', '-agc', '--fixed_digital', '--perf', '-pb', |
| 88 f('resources', 'audioproc.aecdump')], | 98 f('resources', 'audioproc.aecdump')], |
| 89 revision=revision, | 99 revision=revision, |
| 90 perf_test=True)) | 100 perf_test=True) |
| 91 steps.append(self.add_test( | 101 self.add_test( |
| 92 'iSACFixtest', | 102 'iSACFixtest', |
| 93 args=['32000', f('resources', 'speech_and_misc_wb.pcm'), | 103 args=['32000', f('resources', 'speech_and_misc_wb.pcm'), |
| 94 'isac_speech_and_misc_wb.pcm'], | 104 'isac_speech_and_misc_wb.pcm'], |
| 95 revision=revision, | 105 revision=revision, |
| 96 perf_test=True)) | 106 perf_test=True) |
| 97 steps.append(self.virtual_webcam_check()) | 107 self.virtual_webcam_check() |
| 98 steps.append(self.add_test( | 108 self.add_test( |
| 99 'libjingle_peerconnection_java_unittest', | 109 'libjingle_peerconnection_java_unittest', |
| 100 env={'LD_PRELOAD': '/usr/lib/x86_64-linux-gnu/libpulse.so.0'})) | 110 env={'LD_PRELOAD': '/usr/lib/x86_64-linux-gnu/libpulse.so.0'}) |
| 101 | 111 |
| 102 steps.append(self.virtual_webcam_check()) | 112 self.virtual_webcam_check() |
| 103 steps.append(self.add_test( | 113 self.add_test( |
| 104 'vie_auto_test', | 114 'vie_auto_test', |
| 105 args=['--automated', | 115 args=['--automated', |
| 106 '--capture_test_ensure_resolution_alignment_in_capture_device=' | 116 '--capture_test_ensure_resolution_alignment_in_capture_device=' |
| 107 'false'], | 117 'false'], |
| 108 revision=revision, | 118 revision=revision, |
| 109 perf_test=True)) | 119 perf_test=True) |
| 110 steps.append(self.add_test('voe_auto_test', args=['--automated'])) | 120 self.add_test('voe_auto_test', args=['--automated']) |
| 111 steps.append(self.virtual_webcam_check()) | 121 self.virtual_webcam_check() |
| 112 steps.append(self.add_test('video_capture_tests')) | 122 self.add_test('video_capture_tests') |
| 113 steps.append(self.add_test('webrtc_perf_tests', revision=revision, | 123 self.add_test('webrtc_perf_tests', revision=revision, perf_test=True) |
| 114 perf_test=True)) | |
| 115 elif test_suite == 'chromium': | 124 elif test_suite == 'chromium': |
| 116 # Many of these tests run in the Chromium WebRTC waterfalls are not run in | 125 # Many of these tests run in the Chromium WebRTC waterfalls are not run in |
| 117 # the main Chromium waterfalls as they are marked as MANUAL_. This is | 126 # the main Chromium waterfalls as they are marked as MANUAL_. This is |
| 118 # because they rely on physical audio and video devices, which are only | 127 # because they rely on physical audio and video devices, which are only |
| 119 # available at bare-metal machines. | 128 # available at bare-metal machines. |
| 120 steps.append(self.add_test( | 129 self.add_test( |
| 121 'content_browsertests', | 130 'content_browsertests', |
| 122 args=['--gtest_filter=WebRtc*', '--run-manual', | 131 args=['--gtest_filter=WebRtc*', '--run-manual', |
| 123 '--test-launcher-print-test-stdio=always', | 132 '--test-launcher-print-test-stdio=always', |
| 124 '--test-launcher-bot-mode'], | 133 '--test-launcher-bot-mode'], |
| 125 revision=revision, | 134 revision=revision, |
| 126 perf_test=True)) | 135 perf_test=True) |
| 127 steps.append(self.add_test( | 136 self.add_test( |
| 128 'browser_tests', | 137 'browser_tests', |
| 129 # These tests needs --test-launcher-jobs=1 since some of them are | 138 # These tests needs --test-launcher-jobs=1 since some of them are |
| 130 # not able to run in parallel (due to the usage of the | 139 # not able to run in parallel (due to the usage of the |
| 131 # peerconnection server). | 140 # peerconnection server). |
| 132 args = ['--gtest_filter=WebRtc*:TabCapture*', | 141 args = ['--gtest_filter=WebRtc*:TabCapture*', |
| 133 '--run-manual', '--ui-test-action-max-timeout=300000', | 142 '--run-manual', '--ui-test-action-max-timeout=300000', |
| 134 '--test-launcher-jobs=1', | 143 '--test-launcher-jobs=1', |
| 135 '--test-launcher-bot-mode', | 144 '--test-launcher-bot-mode', |
| 136 '--test-launcher-print-test-stdio=always'], | 145 '--test-launcher-print-test-stdio=always'], |
| 137 revision=revision, | 146 revision=revision, |
| 138 perf_test=True)) | 147 perf_test=True) |
| 139 steps.append(self.add_test( | 148 self.add_test( |
| 140 'content_unittests', | 149 'content_unittests', |
| 141 args=['--gtest_filter=WebRtc*:WebRTC*:RTC*:MediaStream*'])) | 150 args=['--gtest_filter=WebRtc*:WebRTC*:RTC*:MediaStream*']) |
| 151 elif test_suite == 'android': |
| 152 self.m.chromium_android.common_tests_setup_steps() |
| 142 | 153 |
| 143 return steps | 154 for test in sorted(self.ANDROID_APK_TESTS.keys()): |
| 155 # Add the filename of the test.isolate files to the path. |
| 156 isolate_file = self.m.path.join(self.ANDROID_APK_TESTS[test], |
| 157 '%s.isolate' % test) |
| 158 self.test_runner(test, isolate_file) |
| 159 |
| 160 self.m.chromium_android.common_tests_final_steps() |
| 144 | 161 |
| 145 def add_test(self, test, name=None, args=None, revision=None, env=None, | 162 def add_test(self, test, name=None, args=None, revision=None, env=None, |
| 146 perf_test=False, perf_dashboard_id=None): | 163 perf_test=False, perf_dashboard_id=None): |
| 147 """Helper function to invoke chromium.runtest(). | 164 """Helper function to invoke chromium.runtest(). |
| 148 | 165 |
| 149 Notice that the name parameter should be the same as the test executable in | 166 Notice that the name parameter should be the same as the test executable in |
| 150 order to get the stdio links in the perf dashboard to become correct. | 167 order to get the stdio links in the perf dashboard to become correct. |
| 151 """ | 168 """ |
| 152 name = name or test | 169 name = name or test |
| 153 args = args or [] | 170 args = args or [] |
| 154 env = env or {} | 171 env = env or {} |
| 155 if self.c.PERF_ID and perf_test: | 172 if self.c.PERF_ID and perf_test: |
| 156 perf_dashboard_id = perf_dashboard_id or test | 173 perf_dashboard_id = perf_dashboard_id or test |
| 157 assert revision, ('Revision must be specified for perf tests as they ' | 174 assert revision, ('Revision must be specified for perf tests as they ' |
| 158 'upload data to the perf dashboard.') | 175 'upload data to the perf dashboard.') |
| 159 self.m.chromium.runtest( | 176 self.m.chromium.runtest( |
| 160 test=test, args=args, name=name, | 177 test=test, args=args, name=name, |
| 161 results_url=self.DASHBOARD_UPLOAD_URL, annotate='graphing', | 178 results_url=self.DASHBOARD_UPLOAD_URL, annotate='graphing', |
| 162 xvfb=True, perf_dashboard_id=perf_dashboard_id, test_type=test, | 179 xvfb=True, perf_dashboard_id=perf_dashboard_id, test_type=test, |
| 163 env=env, revision=revision, perf_id=self.c.PERF_ID, | 180 env=env, revision=revision, perf_id=self.c.PERF_ID, |
| 164 perf_config=self.c.PERF_CONFIG) | 181 perf_config=self.c.PERF_CONFIG) |
| 165 else: | 182 else: |
| 166 self.m.chromium.runtest( | 183 self.m.chromium.runtest( |
| 167 test=test, args=args, name=name, annotate='gtest', xvfb=True, | 184 test=test, args=args, name=name, annotate='gtest', xvfb=True, |
| 168 test_type=test, env=env) | 185 test_type=test, env=env) |
| 169 | 186 |
| 187 def test_runner(self, test, isolate_path): |
| 188 """Adds a test to run on Android devices. |
| 189 |
| 190 This is a minimal version for WebRTC, similar to the methods in the |
| 191 chromium_android recipe module. It's needed since we need to alter the |
| 192 environment. |
| 193 """ |
| 194 script = self.m.path['checkout'].join('build', 'android', 'test_runner.py') |
| 195 args = ['gtest', '-s', test, '--verbose', '--isolate-file-path', |
| 196 isolate_path] |
| 197 if self.m.chromium.c.BUILD_CONFIG == 'Release': |
| 198 args.append('--release') |
| 199 env = {'CHECKOUT_SOURCE_ROOT': self.m.path['checkout']} |
| 200 self.m.python(test, script, args, env=env) |
| 201 |
| 170 def sizes(self, revision): | 202 def sizes(self, revision): |
| 171 # TODO(kjellander): Move this into a function of the chromium recipe | 203 # TODO(kjellander): Move this into a function of the chromium recipe |
| 172 # module instead. | 204 # module instead. |
| 173 assert self.c.PERF_ID, ('You must specify PERF_ID for the builder that ' | 205 assert self.c.PERF_ID, ('You must specify PERF_ID for the builder that ' |
| 174 'runs the sizes step.') | 206 'runs the sizes step.') |
| 175 sizes_script = self.m.path['build'].join('scripts', 'slave', 'chromium', | 207 sizes_script = self.m.path['build'].join('scripts', 'slave', 'chromium', |
| 176 'sizes.py') | 208 'sizes.py') |
| 177 args = ['--target', self.m.chromium.c.BUILD_CONFIG, | 209 args = ['--target', self.m.chromium.c.BUILD_CONFIG, |
| 178 '--platform', self.m.chromium.c.TARGET_PLATFORM] | 210 '--platform', self.m.chromium.c.TARGET_PLATFORM] |
| 179 test_name = 'sizes' | 211 test_name = 'sizes' |
| 180 self.add_test( | 212 self.add_test( |
| 181 test=sizes_script, | 213 test=sizes_script, |
| 182 name=test_name, | 214 name=test_name, |
| 183 perf_dashboard_id=test_name, | 215 perf_dashboard_id=test_name, |
| 184 args=args, | 216 args=args, |
| 185 revision=revision, | 217 revision=revision, |
| 186 perf_test=True) | 218 perf_test=True) |
| 187 | 219 |
| 188 def package_build(self, gs_url, revision): | 220 def package_build(self, gs_url, revision): |
| 189 self.m.archive.zip_and_upload_build( | 221 self.m.archive.zip_and_upload_build( |
| 190 'package build', | 222 'package build', |
| 191 self.m.chromium.c.build_config_fs, | 223 self.m.chromium.c.build_config_fs, |
| 192 gs_url, | 224 gs_url, |
| 193 build_revision=revision) | 225 build_revision=revision) |
| 194 | 226 |
| 195 def extract_build(self, gs_url, revision): | 227 def extract_build(self, gs_url, revision): |
| 228 # Ensure old build directory is not used is by removing it. |
| 229 self.m.path.rmtree( |
| 230 'build directory', |
| 231 self.m.chromium.c.build_dir.join(self.m.chromium.c.build_config_fs)) |
| 232 |
| 196 self.m.archive.download_and_unzip_build( | 233 self.m.archive.download_and_unzip_build( |
| 197 'extract build', | 234 'extract build', |
| 198 self.m.chromium.c.build_config_fs, | 235 self.m.chromium.c.build_config_fs, |
| 199 gs_url, | 236 gs_url, |
| 200 build_revision=revision) | 237 build_revision=revision) |
| 201 | 238 |
| 239 if not self.m.properties.get('parent_got_revision'): |
| 240 raise self.m.step.StepFailure( |
| 241 'Testers cannot be forced without providing revision information.' |
| 242 'Please select a previous build and click [Rebuild] or force a build' |
| 243 'for a Builder instead (will trigger new runs for the testers).') |
| 244 |
| 202 def cleanup(self): | 245 def cleanup(self): |
| 203 if self.m.chromium.c.TARGET_PLATFORM == 'android': | 246 if self.m.chromium.c.TARGET_PLATFORM == 'android': |
| 204 self.m.chromium_android.clean_local_files() | 247 self.m.chromium_android.clean_local_files() |
| 205 else: | 248 else: |
| 206 self.m.chromium.cleanup_temp() | 249 self.m.chromium.cleanup_temp() |
| 207 | 250 |
| 208 def apply_svn_patch(self): | |
| 209 """Patch step for applying WebRTC patches to Chromium checkouts. | |
| 210 | |
| 211 This step should only be used when patches are to be applied to WebRTC as a | |
| 212 part of a Chromium checkout. It is not supported on Windows. | |
| 213 """ | |
| 214 assert self.m.chromium.c.TARGET_PLATFORM != "win", ( | |
| 215 'This step is not supported on the Windows platform.') | |
| 216 script = self.m.path['build'].join('scripts', 'slave', 'apply_svn_patch.py') | |
| 217 args = ['-p', self.m.properties['patch_url'], | |
| 218 '-r', self.c.patch_root_dir] | |
| 219 | |
| 220 # Allow manipulating patches for try jobs. | |
| 221 if self.c.patch_filter_script and self.c.patch_path_filter: | |
| 222 args += ['--filter-script', self.c.patch_filter_script, | |
| 223 '--strip-level', self.c.patch_strip_level, | |
| 224 '--', '--path-filter', self.c.patch_path_filter] | |
| 225 self.m.python('apply_patch', script, args) | |
| 226 | |
| 227 def virtual_webcam_check(self): | 251 def virtual_webcam_check(self): |
| 228 self.m.python( | 252 self.m.python( |
| 229 'webcam_check', | 253 'webcam_check', |
| 230 self.m.path['build'].join('scripts', 'slave', 'webrtc', | 254 self.m.path['build'].join('scripts', 'slave', 'webrtc', |
| 231 'ensure_webcam_is_running.py')) | 255 'ensure_webcam_is_running.py')) |
| OLD | NEW |