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": {
|
||||
"label": "//modules/video_capture:video_capture_tests",
|
||||
"type": "console_test_launcher",
|
||||
"use_webcam": True,
|
||||
},
|
||||
"video_engine_tests": {
|
||||
"label": "//:video_engine_tests",
|
||||
|
@ -844,18 +844,20 @@ class MetaBuildWrapper(object):
|
||||
else:
|
||||
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:
|
||||
# use_x11 = is_linux && !use_ozone.
|
||||
use_x11 = is_linux and not 'use_ozone=true' in vals['gn_args']
|
||||
|
||||
xvfb = use_x11 and test_type == 'windowed_test_launcher'
|
||||
if xvfb:
|
||||
extra_files += [
|
||||
'../../testing/xvfb.py',
|
||||
]
|
||||
|
||||
cmdline = (['../../testing/xvfb.py'] if xvfb else
|
||||
['../../testing/test_env.py'])
|
||||
cmdline.append('../../testing/xvfb.py')
|
||||
extra_files.append('../../testing/xvfb.py')
|
||||
else:
|
||||
cmdline.append('../../testing/test_env.py')
|
||||
|
||||
# Memcheck is only supported for linux. Ignore in other platforms.
|
||||
if is_linux and 'rtc_use_memcheck=true' in vals['gn_args']:
|
||||
|
@ -711,6 +711,57 @@ class UnitTest(unittest.TestCase):
|
||||
'--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):
|
||||
files = {
|
||||
'/fake_src/out/Default/toolchain.ninja': "",
|
||||
|
Reference in New Issue
Block a user