Commit 5050d462 authored by Anthony Berent's avatar Anthony Berent Committed by Commit Bot

Create a top level ui screenshot description

Merge the screenshot descriptions produced by the instrumentation tests
into a single description. If the tests are run locally print a link
to this description, if the are run remotely add a link to the
description to the json file produced by test_results_presentation

Change-Id: Ia9dd491460633148283bed66949cec47a410dea3
Reviewed-on: https://chromium-review.googlesource.com/952972Reviewed-by: default avatarBernhard Bauer <bauerb@chromium.org>
Reviewed-by: default avatarJohn Budorick <jbudorick@chromium.org>
Commit-Queue: Anthony Berent <aberent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543393}
parent 9d280ded
......@@ -6,7 +6,9 @@
import argparse
import collections
import contextlib
import json
import logging
import tempfile
import os
import sys
......@@ -361,6 +363,56 @@ def upload_to_google_bucket(html, bucket, dest):
authenticated_link=True)
def ui_screenshot_set(json_path):
with open(json_path) as json_file:
json_object = json.loads(json_file.read())
if not 'per_iteration_data' in json_object:
# This will be reported as an error by result_details, no need to duplicate.
return None
ui_screenshots = []
for testsuite_run in json_object['per_iteration_data']:
for _, test_runs in testsuite_run.iteritems():
for test_run in test_runs:
if 'ui screenshot' in test_run['links']:
screenshot_link = test_run['links']['ui screenshot']
if screenshot_link.startswith('file:'):
with contextlib.closing(urllib.urlopen(screenshot_link)) as f:
test_screenshots = json.load(f)
else:
# Assume anything that isn't a file link is a google storage link
screenshot_string = google_storage_helper.read_from_link(
screenshot_link)
if not screenshot_string:
logging.error('Bad screenshot link %s', screenshot_link)
continue
test_screenshots = json.loads(
screenshot_string)
ui_screenshots.extend(test_screenshots)
if ui_screenshots:
return json.dumps(ui_screenshots)
return None
def upload_screenshot_set(json_path, test_name, bucket, builder_name,
build_number):
screenshot_set = ui_screenshot_set(json_path)
if not screenshot_set:
return None
dest = google_storage_helper.unique_name(
'screenshots_%s_%s_%s' % (test_name, builder_name, build_number),
suffix='.json')
with tempfile.NamedTemporaryFile(suffix='.json') as temp_file:
temp_file.write(screenshot_set)
temp_file.flush()
return google_storage_helper.upload(
name=dest,
filepath=temp_file.name,
bucket='%s/json' % bucket,
content_type='application/json',
authenticated_link=True)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--json-file', help='Path of json file.')
......@@ -455,16 +507,28 @@ def main():
'Result details link do not match. The link returned by get_url_link'
' should be the same as that returned by upload.')
ui_screenshot_link = upload_screenshot_set(json_file, args.test_name,
args.bucket, builder_name, build_number)
if args.output_json:
with open(json_file) as original_json_file:
json_object = json.load(original_json_file)
json_object['links'] = {
'result_details (logcats, flakiness links)': result_details_link
}
if ui_screenshot_link:
json_object['links']['ui screenshots'] = ui_screenshot_link
with open(args.output_json, 'w') as f:
json.dump(json_object, f)
else:
print result_details_link
print 'Result Details: %s' % result_details_link
if ui_screenshot_link:
print 'UI Screenshots %s' % ui_screenshot_link
if __name__ == '__main__':
sys.exit(main())
......@@ -13,6 +13,7 @@ import logging
import os
import sys
import time
import urlparse
from pylib.constants import host_paths
from pylib.utils import decorators
......@@ -62,6 +63,15 @@ def upload(name, filepath, bucket, gs_args=None, command_args=None,
return get_url_link(name, bucket, authenticated_link)
@decorators.NoRaiseException(default_return_value='')
def read_from_link(link):
# Note that urlparse returns the path with an initial '/', so we only need to
# add one more after the 'gs;'
gs_path = 'gs:/%s' % urlparse.urlparse(link).path
cmd = [_GSUTIL_PATH, '-q', 'cat', gs_path]
return cmd_helper.GetCmdOutput(cmd)
@decorators.NoRaiseException(default_return_value=False)
def exists(name, bucket):
bucket = _format_bucket_name(bucket)
......
......@@ -937,6 +937,16 @@ def RunTestsInPlatformMode(args):
results_detail_file.flush()
logging.critical('TEST RESULTS: %s', results_detail_file.Link())
ui_screenshots = test_results_presentation.ui_screenshot_set(
json_file.name)
if ui_screenshots:
with out_manager.ArchivedTempfile(
'ui_screenshots.json',
'ui_capture',
output_manager.Datatype.JSON) as ui_screenshot_file:
ui_screenshot_file.write(ui_screenshots)
logging.critical('UI Screenshots: %s', ui_screenshot_file.Link())
if args.command == 'perf' and (args.steps or args.single_step):
return 0
......
......@@ -10,6 +10,7 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.annotation.SuppressLint;
import android.app.Instrumentation;
import android.content.res.Configuration;
import android.graphics.Point;
......@@ -93,6 +94,7 @@ import java.util.Map;
* }
* </pre>
*/
@SuppressLint("SetWorldReadable")
public class ScreenShooter extends TestWatcher {
private static final String SCREENSHOT_DIR =
"org.chromium.base.test.util.Screenshooter.ScreenshotDir";
......@@ -204,6 +206,9 @@ public class ScreenShooter extends TestWatcher {
File shotFile = File.createTempFile(shotName, IMAGE_SUFFIX, new File(mBaseDir));
assertTrue("Screenshot " + shotName, mDevice.takeScreenshot(shotFile));
writeImageDescription(shotFile, filters, tags, metadata);
// Set as world readable so that the test runner can read it from /data/local/tmp
// without having to run as root
shotFile.setReadable(true, false);
} catch (IOException e) {
fail("Cannot create shot files " + e.toString());
}
......@@ -231,8 +236,12 @@ public class ScreenShooter extends TestWatcher {
String jsonFileName =
shotFileName.substring(0, shotFileName.length() - IMAGE_SUFFIX.length())
+ JSON_SUFFIX;
try (FileWriter fileWriter = new FileWriter(new File(mBaseDir, jsonFileName));) {
File descriptionFile = new File(mBaseDir, jsonFileName);
try (FileWriter fileWriter = new FileWriter(descriptionFile)) {
fileWriter.write(imageDescription.toString());
}
// Set as world readable so that the test runner can read it from /data/local/tmp without
// having to run as root
descriptionFile.setReadable(true, false);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment