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

Unified Diff: experimental/telemetry_mini/android_go_stories.py

Issue 3002943002: [telemetry_mini] Add story runner options (Closed)
Patch Set: just --repeat Created 3 years, 4 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 | « no previous file | experimental/telemetry_mini/telemetry_mini.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: experimental/telemetry_mini/android_go_stories.py
diff --git a/experimental/telemetry_mini/android_go_stories.py b/experimental/telemetry_mini/android_go_stories.py
index 7d9c57b929c93a3c30713396c359973e7a029078..07a17ed8ebd971752e7af457226feb8f0dc1da95 100755
--- a/experimental/telemetry_mini/android_go_stories.py
+++ b/experimental/telemetry_mini/android_go_stories.py
@@ -4,6 +4,7 @@
# found in the LICENSE file.
import argparse
+import fnmatch
import logging
import os
import sys
@@ -31,81 +32,6 @@ BROWSERS = {
}
-class ProcessWatcher(object):
- def __init__(self, device):
- self.device = device
- self._process_pid = {}
-
- def StartWatching(self, process_name):
- """Register a process or android app to keep track of its PID."""
- if isinstance(process_name, telemetry_mini.AndroidApp):
- process_name = process_name.PACKAGE_NAME
-
- @telemetry_mini.RetryOn(returns_falsy=True)
- def GetPids():
- # Returns an empty list if the process name is not found.
- return self.device.ProcessStatus()[process_name]
-
- assert process_name not in self._process_pid
- pids = GetPids()
- assert pids, 'PID for %s not found' % process_name
- assert len(pids) == 1, 'Single PID for %s expected, but found: %s' % (
- process_name, pids)
- logging.info('Started watching %s (PID=%d)', process_name, pids[0])
- self._process_pid[process_name] = pids[0]
-
- def AssertAllAlive(self):
- """Check that all watched processes remain alive and were not restarted."""
- status = self.device.ProcessStatus()
- all_alive = True
- for process_name, old_pid in sorted(self._process_pid.iteritems()):
- new_pids = status[process_name]
- if not new_pids:
- all_alive = False
- logging.error('Process %s died (PID=%d).', process_name, old_pid)
- elif new_pids != [old_pid]:
- all_alive = False
- logging.error(
- 'Process %s restarted (PID=%d -> %s).', process_name,
- old_pid, new_pids)
- else:
- logging.info('Process %s still alive (PID=%d)', process_name, old_pid)
- assert all_alive, 'Some watched processes died or got restarted'
-
-
-def EnsureSingleBrowser(device, browser_name, force_install=False):
- """Ensure a single Chrome browser is installed and available on the device.
-
- Having more than one Chrome browser available may produce results which are
- confusing or unreliable (e.g. unclear which browser will respond by default
- to intents triggered by other apps).
-
- This function ensures only the selected browser is available, installing it
- if necessary, and uninstalling/disabling others.
- """
- browser = BROWSERS[browser_name](device)
- available_browsers = set(device.ListPackages('chrome', only_enabled=True))
-
- # Install or enable if needed.
- if force_install or browser.PACKAGE_NAME not in available_browsers:
- browser.Install()
-
- # Uninstall disable other browser apps.
- for other_browser in BROWSERS.itervalues():
- if (other_browser.PACKAGE_NAME != browser.PACKAGE_NAME and
- other_browser.PACKAGE_NAME in available_browsers):
- other_browser(device).Uninstall()
-
- # Finally check that only the selected browser is actually available.
- available_browsers = device.ListPackages('chrome', only_enabled=True)
- assert browser.PACKAGE_NAME in available_browsers, (
- 'Unable to make %s available' % browser.PACKAGE_NAME)
- available_browsers.remove(browser.PACKAGE_NAME)
- assert not available_browsers, (
- 'Other browsers may intefere with the test: %s' % available_browsers)
- return browser
-
-
class TwitterApp(telemetry_mini.AndroidApp):
PACKAGE_NAME = 'com.twitter.android'
@@ -115,6 +41,14 @@ class InstagramApp(telemetry_mini.AndroidApp):
class TwitterFlipkartStory(telemetry_mini.UserStory):
+ """Load Chrome Custom Tab from another application.
+
+ The flow of the story is:
+ - Start Twitter app to view the @flipkart profile.
+ - Tap on a link to open Flipkart in a Chrome Custom Tab.
+ - Return to Twitter app.
+ """
+ NAME = 'twitter_flipkart'
FLIPKART_TWITTER_LINK = [
('package', 'com.twitter.android'),
('class', 'android.widget.TextView'),
@@ -149,6 +83,16 @@ class TwitterFlipkartStory(telemetry_mini.UserStory):
class FlipkartInstagramStory(telemetry_mini.UserStory):
+ """Interaction between Chrome, PWAs and a WebView-based app.
+
+ The flow of the story is:
+ - Launch the Flipkart PWA.
+ - Go back home and launch the Instagram app.
+ - Use the app switcher to return to Flipkart.
+ - Go back home and launch Cricbuzz from a shortcut.
+ """
+ NAME = 'flipkart_instagram'
+
def __init__(self, *args, **kwargs):
super(FlipkartInstagramStory, self).__init__(*args, **kwargs)
self.watcher = ProcessWatcher(self.device)
@@ -187,6 +131,87 @@ class FlipkartInstagramStory(telemetry_mini.UserStory):
self.instagram.ForceStop()
+STORIES = (
+ TwitterFlipkartStory,
+ FlipkartInstagramStory
+)
+
+
+class ProcessWatcher(object):
+ def __init__(self, device):
+ self.device = device
+ self._process_pid = {}
+
+ def StartWatching(self, process_name):
+ """Register a process or android app to keep track of its PID."""
+ if isinstance(process_name, telemetry_mini.AndroidApp):
+ process_name = process_name.PACKAGE_NAME
+
+ @telemetry_mini.RetryOn(returns_falsy=True)
+ def GetPids():
+ # Returns an empty list if the process name is not found.
+ return self.device.ProcessStatus()[process_name]
+
+ assert process_name not in self._process_pid
+ pids = GetPids()
+ assert pids, 'PID for %s not found' % process_name
+ assert len(pids) == 1, 'Single PID for %s expected, but found: %s' % (
+ process_name, pids)
+ logging.info('Started watching %s (PID=%d)', process_name, pids[0])
+ self._process_pid[process_name] = pids[0]
+
+ def AssertAllAlive(self):
+ """Check that all watched processes remain alive and were not restarted."""
+ status = self.device.ProcessStatus()
+ all_alive = True
+ for process_name, old_pid in sorted(self._process_pid.iteritems()):
+ new_pids = status[process_name]
+ if not new_pids:
+ all_alive = False
+ logging.error('Process %s died (PID=%d).', process_name, old_pid)
+ elif new_pids != [old_pid]:
+ all_alive = False
+ logging.error(
+ 'Process %s restarted (PID=%d -> %s).', process_name,
+ old_pid, new_pids)
+ else:
+ logging.info('Process %s still alive (PID=%d)', process_name, old_pid)
+ assert all_alive, 'Some watched processes died or got restarted'
+
+
+def EnsureSingleBrowser(device, browser_name, force_install=False):
+ """Ensure a single Chrome browser is installed and available on the device.
+
+ Having more than one Chrome browser available may produce results which are
+ confusing or unreliable (e.g. unclear which browser will respond by default
+ to intents triggered by other apps).
+
+ This function ensures only the selected browser is available, installing it
+ if necessary, and uninstalling/disabling others.
+ """
+ browser = BROWSERS[browser_name](device)
+ available_browsers = set(device.ListPackages('chrome', only_enabled=True))
+
+ # Install or enable if needed.
+ if force_install or browser.PACKAGE_NAME not in available_browsers:
+ browser.Install()
+
+ # Uninstall disable other browser apps.
+ for other_browser in BROWSERS.itervalues():
+ if (other_browser.PACKAGE_NAME != browser.PACKAGE_NAME and
+ other_browser.PACKAGE_NAME in available_browsers):
+ other_browser(device).Uninstall()
+
+ # Finally check that only the selected browser is actually available.
+ available_browsers = device.ListPackages('chrome', only_enabled=True)
+ assert browser.PACKAGE_NAME in available_browsers, (
+ 'Unable to make %s available' % browser.PACKAGE_NAME)
+ available_browsers.remove(browser.PACKAGE_NAME)
+ assert not available_browsers, (
+ 'Other browsers may intefere with the test: %s' % available_browsers)
+ return browser
+
+
def main():
browser_names = sorted(BROWSERS)
default_browser = 'android-chrome'
@@ -201,6 +226,15 @@ def main():
help='one of: %s' % ', '.join(
'%s (default)' % b if b == default_browser else b
for b in browser_names))
+ parser.add_argument('--story-filter', metavar='PATTERN', default='*',
+ help='run the matching stories only (allows Unix'
+ ' shell-style wildcards)')
+ parser.add_argument('--repeat', metavar='NUM', type=int, default=1,
+ help='repeat the story set a number of times'
+ ' (default: %(default)d)')
+ parser.add_argument('--output-dir', metavar='PATH',
+ help='path to directory for placing output trace files'
+ ' (defaults to current directory)')
parser.add_argument('--force-install', action='store_true',
help='install APK even if browser is already available')
parser.add_argument('--apks-dir', metavar='PATH',
@@ -215,6 +249,17 @@ def main():
if args.verbose:
logging.getLogger().setLevel(logging.INFO)
+ stories = [s for s in STORIES if fnmatch.fnmatch(s.NAME, args.story_filter)]
+ if not stories:
+ return 'No matching stories'
+
+ if args.output_dir is None:
+ args.output_dir = os.getcwd()
+ else:
+ args.output_dir = os.path.realpath(args.output_dir)
+ if not os.path.isdir(args.output_dir):
+ return 'Output directory does not exit'
+
if args.apks_dir is None:
args.apks_dir = os.path.realpath(os.path.join(
os.path.dirname(__file__), '..', '..', '..', '..',
@@ -233,10 +278,10 @@ def main():
device.RunCommand('wait-for-device')
browser = EnsureSingleBrowser(device, args.browser, args.force_install)
+ browser.SetBrowserFlags(BROWSER_FLAGS)
+ browser.SetTraceConfig(TRACE_CONFIG)
browser.SetDevToolsLocalPort(args.port)
-
- story = FlipkartInstagramStory(browser)
- story.Run(BROWSER_FLAGS, TRACE_CONFIG, 'trace.json')
+ telemetry_mini.RunStories(browser, stories, args.repeat, args.output_dir)
if __name__ == '__main__':
« no previous file with comments | « no previous file | experimental/telemetry_mini/telemetry_mini.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698