diff --git a/build/automationutils.py b/build/automationutils.py index 0ceb9dc52d41..1dfd7a470fdb 100644 --- a/build/automationutils.py +++ b/build/automationutils.py @@ -5,6 +5,7 @@ from __future__ import with_statement import glob, logging, os, platform, shutil, subprocess, sys, tempfile, urllib2, zipfile +import base64 import re from urlparse import urlparse @@ -43,7 +44,8 @@ __all__ = [ 'KeyValueParseError', 'parseKeyValue', 'systemMemory', - 'environment' + 'environment', + 'dumpScreen', ] # Map of debugging programs to information about them, like default arguments @@ -473,3 +475,56 @@ def environment(xrePath, env=None, crashreporter=True): log.info(message) return env + + +def dumpScreen(utilityPath): + """dumps the screen to the log file as a data URI""" + + # Need to figure out what tool and whether it write to a file or stdout + if mozinfo.isUnix: + utility = [os.path.join(utilityPath, "screentopng")] + imgoutput = 'stdout' + elif mozinfo.isMac: + utility = ['/usr/sbin/screencapture', '-C', '-x', '-t', 'png'] + imgoutput = 'file' + elif mozinfo.isWin: + utility = [os.path.join(utilityPath, "screenshot.exe")] + imgoutput = 'file' + else: + log.warn("Unable to dump screen on platform '%s'", sys.platform) + + # Run the capture correctly for the type of capture + kwargs = {'stdout': subprocess.PIPE} + if imgoutput == 'file': + tmpfd, imgfilename = tempfile.mkstemp(prefix='mozilla-test-fail_') + os.close(tmpfd) + utility.append(imgfilename) + elif imgoutput == 'stdout': + kwargs.update(dict(bufsize=-1, close_fds=True)) + try: + dumper = subprocess.Popen(utility, **kwargs) + except OSError, err: + log.info("Failed to start %s for screenshot: %s", + utility[0], err.strerror) + return + + # Check whether the capture utility ran successfully + stdout, _ = dumper.communicate() + returncode = dumper.poll() + if returncode: + log.info("%s exited with code %d", utility, returncode) + return + + try: + if imgoutput == 'stdout': + image = stdout + elif imgoutput == 'file': + with open(imgfilename, 'rb') as imgfile: + image = imgfile.read() + except IOError, err: + log.info("Failed to read image from %s", imgoutput) + + encoded = base64.b64encode(image) + uri = "data:image/png;base64,%s" % encoded + log.info("SCREENSHOT: %s", uri) + return uri diff --git a/build/dumpScreen.py b/build/dumpScreen.py new file mode 100644 index 000000000000..70efe0189f8c --- /dev/null +++ b/build/dumpScreen.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +""" +test dumpScreen functionality +""" + +import automationutils +import optparse +import os +import sys + + +def main(args=sys.argv[1:]): + + # parse CLI options + usage = '%prog [options] path/to/OBJDIR/dist/bin' + parser = optparse.OptionParser(usage=usage) + options, args = parser.parse_args(args) + if len(args) != 1: + parser.error("Please provide utility path") + utilityPath = args[0] + + # dump the screen to a data: URL + uri = automationutils.dumpScreen(utilityPath) + + # print the uri + print uri + +if __name__ == '__main__': + main() diff --git a/testing/mochitest/runtests.py b/testing/mochitest/runtests.py index 9da730d0ae70..0940db70ce20 100644 --- a/testing/mochitest/runtests.py +++ b/testing/mochitest/runtests.py @@ -12,7 +12,6 @@ import sys SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__))) sys.path.insert(0, SCRIPT_DIR); -import base64 import json import mozcrash import mozinfo @@ -29,7 +28,7 @@ import time import traceback import urllib2 -from automationutils import environment, getDebuggerInfo, isURL, KeyValueParseError, parseKeyValue, processLeakLog, systemMemory +from automationutils import environment, getDebuggerInfo, isURL, KeyValueParseError, parseKeyValue, processLeakLog, systemMemory, dumpScreen from datetime import datetime from manifestparser import TestManifest from mochitest_options import MochitestOptions @@ -650,59 +649,11 @@ class Mochitest(MochitestUtilsMixin): del self.profile def dumpScreen(self, utilityPath): - # TODO: this code may be moved to automationutils.py - # see also: https://bugzilla.mozilla.org/show_bug.cgi?id=749421 - if self.haveDumpedScreen: log.info("Not taking screenshot here: see the one that was previously logged") return - self.haveDumpedScreen = True - - # Need to figure out what tool and whether it write to a file or stdout - if mozinfo.isUnix: - utility = [os.path.join(utilityPath, "screentopng")] - imgoutput = 'stdout' - elif mozinfo.isMac: - utility = ['/usr/sbin/screencapture', '-C', '-x', '-t', 'png'] - imgoutput = 'file' - elif mozinfo.isWin: - utility = [os.path.join(utilityPath, "screenshot.exe")] - imgoutput = 'file' - - # Run the capture correctly for the type of capture - if imgoutput == 'file': - tmpfd, imgfilename = tempfile.mkstemp(prefix='mozilla-test-fail_') - os.close(tmpfd) - utility.append(imgfilename) - kwargs = {} - elif imgoutput == 'stdout': - kwargs=dict(bufsize=-1, close_fds=True) - try: - dumper = mozprocess.ProcessHandler(utility, **kwargs) - dumper.run() - except OSError, err: - log.info("Failed to start %s for screenshot: %s", - utility[0], err.strerror) - return - - # Check whether the capture utility ran successfully - returncode = dumper.wait() - if returncode: - log.info("%s exited with code %d", utility, returncode) - return - - try: - if imgoutput == 'stdout': - image = '\n'.join(dumper.output) - elif imgoutput == 'file': - with open(imgfilename, 'rb') as imgfile: - image = imgfile.read() - except IOError, err: - log.info("Failed to read image from %s", imgoutput) - - encoded = base64.b64encode(image) - log.info("SCREENSHOT: data:image/png;base64,%s", encoded) + dumpScreen(utilityPath) def killAndGetStack(self, processPID, utilityPath, debuggerInfo, dump_screen=False): """