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

Unified Diff: chrome/test/vr/perf/latency/run_latency_test.py

Issue 2823883003: Make VR latency results compatible with perf dashboard, refactor into classes (Closed)
Patch Set: Address nits Created 3 years, 8 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/test/vr/perf/latency/robot_arm.py ('k') | chrome/test/vr/perf/latency/webvr_latency_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/test/vr/perf/latency/run_latency_test.py
diff --git a/chrome/test/vr/perf/latency/run_latency_test.py b/chrome/test/vr/perf/latency/run_latency_test.py
index 852b42045eb2341c4e503090d2ea004457bfe2f5..ea1d04fb65f718b2e14351205b7a2671a7aa3bc8 100644
--- a/chrome/test/vr/perf/latency/run_latency_test.py
+++ b/chrome/test/vr/perf/latency/run_latency_test.py
@@ -11,104 +11,35 @@ a set of servos, which physically moves the test device and Motopho during the
latency test.
"""
+import android_webvr_latency_test
+
import argparse
-import glob
-import httplib
import logging
import os
-import re
-import serial
-import subprocess
import sys
-import threading
-import time
-# RobotArm connection constants
-BAUD_RATE = 115200
-CONNECTION_TIMEOUT = 3.0
-NUM_TRIES = 5
-# Motopho constants
-DEFAULT_ADB_PATH = os.path.join(os.path.expanduser('~'),
- 'tools/android/android-sdk-linux',
- 'platform-tools/adb')
+# TODO(bsheedy): See about having versioned copies of the flicker app
+# instead of using personal github.
+DEFAULT_FLICKER_APP_URL = ('https://weableandbob.github.io/Motopho/'
+ 'flicker_apps/webvr/webvr-flicker-app-klaus.html?'
+ 'polyfill=0\&canvasClickPresents=1')
+DEFAULT_ADB_PATH = os.path.realpath('../../third_party/android_tools/sdk/'
+ 'platform-tools/adb')
# TODO(bsheedy): See about adding tool via DEPS instead of relying on it
# existing on the bot already
DEFAULT_MOTOPHO_PATH = os.path.join(os.path.expanduser('~'), 'motopho/Motopho')
-MOTOPHO_THREAD_TIMEOUT = 30
-
-class MotophoThread(threading.Thread):
- """Handles the running of the Motopho script and extracting results."""
- def __init__(self):
- threading.Thread.__init__(self)
- self._latency = None
- self._max_correlation = None
-
- def run(self):
- motopho_output = ""
- try:
- motopho_output = subprocess.check_output(["./motophopro_nograph"],
- stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as e:
- logging.error('Failed to run Motopho script: %s', e.output)
- raise e
-
- if "FAIL" in motopho_output:
- logging.error('Failed to get latency, logging raw output: %s',
- motopho_output)
- raise RuntimeError('Failed to get latency - correlation likely too low')
-
- self._latency = None
- self._max_correlation = None
- for line in motopho_output.split("\n"):
- if 'Motion-to-photon latency:' in line:
- self._latency = float(line.split(" ")[-2])
- if 'Max correlation is' in line:
- self._max_correlation = float(line.split(' ')[-1])
- if self._latency and self._max_correlation:
- break;
-
- @property
- def latency(self):
- return self._latency
-
- @property
- def max_correlation(self):
- return self._max_correlation
-
-
-class RobotArm():
- """Handles the serial communication with the servos/arm used for movement."""
- def __init__(self, device_name, num_tries, baud, timeout):
- self._connection = None
- connected = False
- for _ in xrange(num_tries):
- try:
- self._connection = serial.Serial('/dev/' + device_name,
- baud,
- timeout=timeout)
- except serial.SerialException as e:
- pass
- if self._connection and 'Enter parameters' in self._connection.read(1024):
- connected = True
- break
- if not connected:
- raise serial.SerialException('Failed to connect to the robot arm.')
-
- def StartMotophoMovement(self):
- if not self._connection:
- return
- self._connection.write('9\n')
-
- def StopAllMovement(self):
- if not self._connection:
- return
- self._connection.write('0\n')
+DEFAULT_NUM_SAMPLES = 10
+DEFAULT_RESULTS_FILE = 'results-chart.json'
+DEFAULT_VRCORE_VERSION_FILE = 'vrcore_version.txt'
def GetParsedArgs():
"""Parses the command line arguments passed to the script.
Fails if any unknown arguments are present.
+
+ Returns:
+ An object containing all known, parsed arguments.
"""
parser = argparse.ArgumentParser()
parser.add_argument('--adb-path',
@@ -124,9 +55,27 @@ def GetParsedArgs():
type=os.path.realpath,
help='The directory where the script\'s output files '
'will be saved')
+ parser.add_argument('--platform',
+ help='The platform the test is being run on, either '
+ '"android" or "windows"')
+ parser.add_argument('--results-file',
+ default=DEFAULT_RESULTS_FILE,
+ help='The name of the JSON file the results will be '
+ 'saved to')
+ parser.add_argument('--num-samples',
+ default=DEFAULT_NUM_SAMPLES,
+ help='The number of times to run the test before '
+ 'the results are averaged')
+ parser.add_argument('--url',
+ default=DEFAULT_FLICKER_APP_URL,
+ help='The URL of the flicker app to use')
parser.add_argument('-v', '--verbose',
dest='verbose_count', default=0, action='count',
help='Verbose level (multiple times for more)')
+ parser.add_argument('--vrcore-version-file',
+ default=DEFAULT_VRCORE_VERSION_FILE,
+ help='The name of the text file that the VrCore APK '
+ 'version number will be saved to')
(args, unknown_args) = parser.parse_known_args()
SetLogLevel(args.verbose_count)
if unknown_args:
@@ -145,139 +94,17 @@ def SetLogLevel(verbose_count):
logger.setLevel(log_level)
-def GetTtyDevices(tty_pattern, vendor_ids):
- """Find all devices connected to tty that match a pattern and device id.
-
- If a serial device is connected to the computer via USB, this function
- will check all tty devices that match tty_pattern, and return the ones
- that have vendor identification number in the list vendor_ids.
-
- Args:
- tty_pattern: The search pattern, such as r'ttyACM\d+'.
- vendor_ids: The list of 16-bit USB vendor ids, such as [0x2a03].
-
- Returns:
- A list of strings of tty devices, for example ['ttyACM0'].
- """
- product_string = 'PRODUCT='
- sys_class_dir = '/sys/class/tty/'
-
- tty_devices = glob.glob(sys_class_dir + '*')
-
- matcher = re.compile('.*' + tty_pattern)
- tty_matches = [x for x in tty_devices if matcher.search(x)]
- tty_matches = [x[len(sys_class_dir):] for x in tty_matches]
-
- found_devices = []
- for match in tty_matches:
- class_filename = sys_class_dir + match + '/device/uevent'
- with open(class_filename, 'r') as uevent_file:
- # Look for the desired product id in the uevent text.
- for line in uevent_file:
- if product_string in line:
- ids = line[len(product_string):].split('/')
- ids = [int(x, 16) for x in ids]
-
- for desired_id in vendor_ids:
- if desired_id in ids:
- found_devices.append(match)
-
- return found_devices
-
-
-def RunCommand(cmd):
- """Runs the given cmd list.
-
- Prints the command's output and exits if any error occurs.
- """
- try:
- subprocess.check_output(cmd, stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as e:
- logging.error('Failed command output: %s', e.output)
- raise e
-
-
-def SetChromeCommandLineFlags(adb_path, flags):
- """Sets the given Chrome command line flags."""
- RunCommand([adb_path,
- 'shell', "echo 'chrome " + ' '.join(flags) + "' > "
- + '/data/local/tmp/chrome-command-line'])
-
-
def main():
args = GetParsedArgs()
+ latency_test = None
+ if args.platform == 'android':
+ latency_test = android_webvr_latency_test.AndroidWebVrLatencyTest(args)
+ elif args.platform == 'win':
+ raise NotImplementedError('WebVR not currently supported on Windows')
+ else:
+ raise RuntimeError('Given platform %s not recognized' % args.platform)
+ latency_test.RunTest()
- RunCommand([args.adb_path, 'root'])
- RunCommand([args.adb_path, 'install', '-r', 'apks/ChromePublic.apk'])
- # Force WebVR support and don't have first run experience
- SetChromeCommandLineFlags(args.adb_path, ['--enable-webvr', '--disable-fre'])
-
- # Motopho scripts use relative paths, so switch to the Motopho directory
- os.chdir(args.motopho_path)
-
- # Connect to the Arduino that drives the servos
- devices = GetTtyDevices(r'ttyACM\d+', [0x2a03, 0x2341])
- if len(devices) != 1:
- logging.error('Found %d devices, expected 1', len(devices))
- return 1
- robot_arm = RobotArm(devices[0], NUM_TRIES, BAUD_RATE, CONNECTION_TIMEOUT)
-
- # Wake the device
- RunCommand([args.adb_path, 'shell', 'input', 'keyevent', 'KEYCODE_WAKEUP'])
- # Sleep a bit, otherwise WebGL can crash when Canary starts
- time.sleep(1)
-
- # Start Chrome and go to the flicker app
- # TODO(bsheedy): See about having versioned copies of the flicker app instead
- # of using personal github.
- RunCommand([args.adb_path, 'shell', 'am', 'start',
- '-a', 'android.intent.action.MAIN',
- '-n', 'org.chromium.chrome/com.google.android.apps.chrome.Main',
- 'https://weableandbob.github.io/Motopho/flicker_apps/webvr/webvr-flicker-app-klaus.html?polyfill=0\&canvasClickPresents=1'])
- time.sleep(10)
-
- # Tap the screen to start presenting
- RunCommand(
- [args.adb_path, 'shell', 'input', 'touchscreen', 'tap', '800', '800'])
- # Wait for VR to fully start up
- time.sleep(5)
-
- # Start the Motopho script
- motopho_thread = MotophoThread()
- motopho_thread.start()
- # Let the Motopho be stationary so the script can calculate its bias
- time.sleep(3)
-
- # Move so we can measure latency
- robot_arm.StartMotophoMovement()
- motopho_thread.join(MOTOPHO_THREAD_TIMEOUT)
- if motopho_thread.isAlive():
- # TODO(bsheedy): Look into ways to prevent Motopho from not sending any
- # data until unplugged and replugged into the machine after a reboot.
- logging.error('Motopho thread timeout, Motopho may need to be replugged.')
- robot_arm.StopAllMovement()
-
- logging.info('Latency: %s', motopho_thread.latency)
- logging.info('Max correlation: %s', motopho_thread.max_correlation)
-
- # TODO(bsheedy): Change this to output JSON compatible with the performance
- # dashboard.
- if args.output_dir and os.path.isdir(args.output_dir):
- with file(os.path.join(args.output_dir, 'output.txt'), 'w') as outfile:
- outfile.write('Latency: %s\nMax correlation: %s\n' %
- (motopho_thread.latency, motopho_thread.max_correlation))
-
- # Exit VR and Close Chrome
- # TODO(bsheedy): See about closing current tab before exiting so they don't
- # pile up over time.
- RunCommand([args.adb_path, 'shell', 'input', 'keyevent', 'KEYCODE_BACK'])
- RunCommand([args.adb_path, 'shell', 'am', 'force-stop',
- 'org.chromium.chrome'])
-
- # Turn off the screen
- RunCommand([args.adb_path, 'shell', 'input', 'keyevent', 'KEYCODE_POWER'])
-
- return 0
if __name__ == '__main__':
sys.exit(main())
« no previous file with comments | « chrome/test/vr/perf/latency/robot_arm.py ('k') | chrome/test/vr/perf/latency/webvr_latency_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698