Add support for launching webcam software for use in recipes
* Copy ensure_webcam_is_running.py from recipes repo * Turn it into a wrapper that can launch another script (fix_python_path is copied from test_env.py as _ForcePythonInterpreter) * Support it in mb.py * Add it to video_capture_unittests No-Try: True Bug: chromium:755660 Change-Id: I376724a77e443620724add7818592e9368d02079 Reviewed-on: https://webrtc-review.googlesource.com/77320 Commit-Queue: Oleh Prypin <oprypin@webrtc.org> Reviewed-by: Patrik Höglund <phoglund@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23275}
This commit is contained in:
123
tools_webrtc/ensure_webcam_is_running.py
Executable file
123
tools_webrtc/ensure_webcam_is_running.py
Executable file
@ -0,0 +1,123 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Use of this source code is governed by a BSD-style license
|
||||||
|
# that can be found in the LICENSE file in the root of the source
|
||||||
|
# tree. An additional intellectual property rights grant can be found
|
||||||
|
# in the file PATENTS. All contributing project authors may
|
||||||
|
# be found in the AUTHORS file in the root of the source tree.
|
||||||
|
|
||||||
|
"""Checks if a virtual webcam is running and starts it if not.
|
||||||
|
|
||||||
|
Returns a non-zero return code if the webcam could not be started.
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
* The Python interpreter must have the psutil package installed.
|
||||||
|
* Windows: a scheduled task named 'ManyCam' must exist and be configured to
|
||||||
|
launch ManyCam preconfigured to auto-play the test clip.
|
||||||
|
* Mac: ManyCam must be installed in the default location and be preconfigured
|
||||||
|
to auto-play the test clip.
|
||||||
|
* Linux: The v4l2loopback kernel module must be compiled and loaded to the
|
||||||
|
kernel already and the v4l2_file_player application must be compiled and put
|
||||||
|
in the location specified below.
|
||||||
|
|
||||||
|
NOTICE: When running this script as a buildbot step, make sure to set
|
||||||
|
usePTY=False for the build step when adding it, or the subprocess will die as
|
||||||
|
soon the step has executed.
|
||||||
|
|
||||||
|
If any command line arguments are passed to the script, it is executed as a
|
||||||
|
command in a subprocess.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
# psutil is not installed on non-Linux machines by default.
|
||||||
|
import psutil # pylint: disable=F0401
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
WEBCAM_WIN = ('schtasks', '/run', '/tn', 'ManyCam')
|
||||||
|
WEBCAM_MAC = ('open', '/Applications/ManyCam/ManyCam.app')
|
||||||
|
E = os.path.expandvars
|
||||||
|
WEBCAM_LINUX = (
|
||||||
|
E('$HOME/fake-webcam-driver/linux/v4l2_file_player/v4l2_file_player'),
|
||||||
|
E('$HOME/webrtc_video_quality/reference_video.yuv'),
|
||||||
|
'640', '480', '/dev/video0',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def IsWebCamRunning():
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
process_name = 'ManyCam.exe'
|
||||||
|
elif sys.platform.startswith('darwin'):
|
||||||
|
process_name = 'ManyCam'
|
||||||
|
elif sys.platform.startswith('linux'):
|
||||||
|
process_name = 'v4l2_file_player'
|
||||||
|
else:
|
||||||
|
raise Exception('Unsupported platform: %s' % sys.platform)
|
||||||
|
for p in psutil.process_iter():
|
||||||
|
try:
|
||||||
|
if process_name == p.name:
|
||||||
|
print 'Found a running virtual webcam (%s with PID %s)' % (p.name,
|
||||||
|
p.pid)
|
||||||
|
return True
|
||||||
|
except psutil.AccessDenied:
|
||||||
|
pass # This is normal if we query sys processes, etc.
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def StartWebCam():
|
||||||
|
try:
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
subprocess.check_call(WEBCAM_WIN)
|
||||||
|
print 'Successfully launched virtual webcam.'
|
||||||
|
elif sys.platform.startswith('darwin'):
|
||||||
|
subprocess.check_call(WEBCAM_MAC)
|
||||||
|
print 'Successfully launched virtual webcam.'
|
||||||
|
elif sys.platform.startswith('linux'):
|
||||||
|
|
||||||
|
# Must redirect stdout/stderr/stdin to avoid having the subprocess
|
||||||
|
# being killed when the parent shell dies (happens on the bots).
|
||||||
|
process = subprocess.Popen(WEBCAM_LINUX, stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
stdin=subprocess.PIPE)
|
||||||
|
# If the v4l2loopback module is not loaded or incorrectly configured,
|
||||||
|
# the process will still launch but will die immediately.
|
||||||
|
# Wait for a second and then check for aliveness to catch such errors.
|
||||||
|
time.sleep(1)
|
||||||
|
if process.poll() is None:
|
||||||
|
print 'Successfully launched virtual webcam with PID %s' % process.pid
|
||||||
|
else:
|
||||||
|
print 'Failed to launch virtual webcam.'
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print 'Failed to launch virtual webcam: %s' % e
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _ForcePythonInterpreter(cmd):
|
||||||
|
"""Returns the fixed command line to call the right python executable."""
|
||||||
|
out = cmd[:]
|
||||||
|
if out[0] == 'python':
|
||||||
|
out[0] = sys.executable
|
||||||
|
elif out[0].endswith('.py'):
|
||||||
|
out.insert(0, sys.executable)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def Main(argv):
|
||||||
|
if IsWebCamRunning():
|
||||||
|
return 0
|
||||||
|
if not StartWebCam():
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if argv:
|
||||||
|
return subprocess.call(_ForcePythonInterpreter(argv))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(Main(sys.argv[1:]))
|
@ -121,6 +121,7 @@
|
|||||||
"video_capture_tests": {
|
"video_capture_tests": {
|
||||||
"label": "//modules/video_capture:video_capture_tests",
|
"label": "//modules/video_capture:video_capture_tests",
|
||||||
"type": "console_test_launcher",
|
"type": "console_test_launcher",
|
||||||
|
"use_webcam": True,
|
||||||
},
|
},
|
||||||
"video_engine_tests": {
|
"video_engine_tests": {
|
||||||
"label": "//:video_engine_tests",
|
"label": "//:video_engine_tests",
|
||||||
|
@ -844,18 +844,20 @@ class MetaBuildWrapper(object):
|
|||||||
else:
|
else:
|
||||||
extra_files = ['../../testing/test_env.py']
|
extra_files = ['../../testing/test_env.py']
|
||||||
|
|
||||||
|
if isolate_map[target].get('use_webcam', False):
|
||||||
|
cmdline.append('../../tools_webrtc/ensure_webcam_is_running.py')
|
||||||
|
extra_files.append('../../tools_webrtc/ensure_webcam_is_running.py')
|
||||||
|
|
||||||
# This needs to mirror the settings in //build/config/ui.gni:
|
# This needs to mirror the settings in //build/config/ui.gni:
|
||||||
# use_x11 = is_linux && !use_ozone.
|
# use_x11 = is_linux && !use_ozone.
|
||||||
use_x11 = is_linux and not 'use_ozone=true' in vals['gn_args']
|
use_x11 = is_linux and not 'use_ozone=true' in vals['gn_args']
|
||||||
|
|
||||||
xvfb = use_x11 and test_type == 'windowed_test_launcher'
|
xvfb = use_x11 and test_type == 'windowed_test_launcher'
|
||||||
if xvfb:
|
if xvfb:
|
||||||
extra_files += [
|
cmdline.append('../../testing/xvfb.py')
|
||||||
'../../testing/xvfb.py',
|
extra_files.append('../../testing/xvfb.py')
|
||||||
]
|
else:
|
||||||
|
cmdline.append('../../testing/test_env.py')
|
||||||
cmdline = (['../../testing/xvfb.py'] if xvfb else
|
|
||||||
['../../testing/test_env.py'])
|
|
||||||
|
|
||||||
# Memcheck is only supported for linux. Ignore in other platforms.
|
# Memcheck is only supported for linux. Ignore in other platforms.
|
||||||
if is_linux and 'rtc_use_memcheck=true' in vals['gn_args']:
|
if is_linux and 'rtc_use_memcheck=true' in vals['gn_args']:
|
||||||
|
@ -711,6 +711,57 @@ class UnitTest(unittest.TestCase):
|
|||||||
'--tsan=0',
|
'--tsan=0',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_isolate_test_launcher_with_webcam(self):
|
||||||
|
test_files = {
|
||||||
|
'/tmp/swarming_targets': 'base_unittests\n',
|
||||||
|
'/fake_src/testing/buildbot/gn_isolate_map.pyl': (
|
||||||
|
"{'base_unittests': {"
|
||||||
|
" 'label': '//base:base_unittests',"
|
||||||
|
" 'type': 'console_test_launcher',"
|
||||||
|
" 'use_webcam': True,"
|
||||||
|
"}}\n"
|
||||||
|
),
|
||||||
|
'/fake_src/out/Default/base_unittests.runtime_deps': (
|
||||||
|
"base_unittests\n"
|
||||||
|
"some_resource_file\n"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
mbw = self.check(['gen', '-c', 'debug_goma', '//out/Default',
|
||||||
|
'--swarming-targets-file', '/tmp/swarming_targets',
|
||||||
|
'--isolate-map-file',
|
||||||
|
'/fake_src/testing/buildbot/gn_isolate_map.pyl'],
|
||||||
|
files=test_files, ret=0)
|
||||||
|
|
||||||
|
isolate_file = mbw.files['/fake_src/out/Default/base_unittests.isolate']
|
||||||
|
isolate_file_contents = ast.literal_eval(isolate_file)
|
||||||
|
files = isolate_file_contents['variables']['files']
|
||||||
|
command = isolate_file_contents['variables']['command']
|
||||||
|
|
||||||
|
self.assertEqual(files, [
|
||||||
|
'../../testing/test_env.py',
|
||||||
|
'../../third_party/gtest-parallel/gtest-parallel',
|
||||||
|
'../../third_party/gtest-parallel/gtest_parallel.py',
|
||||||
|
'../../tools_webrtc/ensure_webcam_is_running.py',
|
||||||
|
'../../tools_webrtc/gtest-parallel-wrapper.py',
|
||||||
|
'base_unittests',
|
||||||
|
'some_resource_file',
|
||||||
|
])
|
||||||
|
self.assertEqual(command, [
|
||||||
|
'../../tools_webrtc/ensure_webcam_is_running.py',
|
||||||
|
'../../testing/test_env.py',
|
||||||
|
'../../tools_webrtc/gtest-parallel-wrapper.py',
|
||||||
|
'--output_dir=${ISOLATED_OUTDIR}/test_logs',
|
||||||
|
'--gtest_color=no',
|
||||||
|
'--timeout=900',
|
||||||
|
'--retry_failed=3',
|
||||||
|
'./base_unittests',
|
||||||
|
'--',
|
||||||
|
'--asan=0',
|
||||||
|
'--lsan=0',
|
||||||
|
'--msan=0',
|
||||||
|
'--tsan=0',
|
||||||
|
])
|
||||||
|
|
||||||
def test_isolate(self):
|
def test_isolate(self):
|
||||||
files = {
|
files = {
|
||||||
'/fake_src/out/Default/toolchain.ninja': "",
|
'/fake_src/out/Default/toolchain.ninja': "",
|
||||||
|
Reference in New Issue
Block a user