Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Commit

Permalink
Fix bug 554241 - cfx should have a --logfile option
Browse files Browse the repository at this point in the history
# vim: se ft=diff :
Fix bug 554241 -  cfx should have a --logfile option

Fix bug 554241 -  cfx should have a --logfile option
  • Loading branch information
Atul Varma committed Mar 23, 2010
1 parent 1979b57 commit 155382d
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 28 deletions.
9 changes: 3 additions & 6 deletions packages/test-harness/lib/run-tests.js
Expand Up @@ -39,7 +39,7 @@ const THUNDERBIRD_ID = "{3550f703-e582-4d05-9a08-453d09bdfdc6}";

var obsvc = require("observer-service");

function runTests(iterations, verbose, rootPaths, quit) {
function runTests(iterations, verbose, rootPaths, quit, print) {
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Ci.nsIWindowWatcher);

Expand All @@ -48,10 +48,6 @@ function runTests(iterations, verbose, rootPaths, quit) {

var harness = require("harness");

function print() {
dump.apply(undefined, arguments);
};

function onDone(tests) {
window.close();
if (tests.passed > 0 && tests.failed == 0)
Expand All @@ -70,7 +66,8 @@ function runTests(iterations, verbose, rootPaths, quit) {
exports.main = function main(options, callbacks) {
function doRunTests() {
runTests(options.iterations, options.verbose,
options.rootPaths, callbacks.quit);
options.rootPaths, callbacks.quit,
callbacks.print);
}

// TODO: This is optional code that might be put in by
Expand Down
7 changes: 6 additions & 1 deletion python-lib/cuddlefish/__init__.py
Expand Up @@ -81,6 +81,10 @@
"firefox, or thunderbird"),
metavar=None,
default="xulrunner"),
("-f", "--logfile",): dict(dest="logfile",
help="log console output to file",
metavar=None,
default=None),
("", "--use-server",): dict(dest="use_server",
help="use task queue server",
action="store_true",
Expand Down Expand Up @@ -429,6 +433,7 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
profiledir=options.profiledir,
verbose=options.verbose,
no_quit=options.no_quit,
timeout=timeout)
timeout=timeout,
logfile=options.logfile)

sys.exit(retval)
28 changes: 25 additions & 3 deletions python-lib/cuddlefish/app-extension/components/harness.js
Expand Up @@ -137,6 +137,7 @@ function buildHarnessService(rootFileSpec, dump, logError,
Cu.import(options.loader, jsm);
var packaging = new Packaging();
var loader = new jsm.Loader({rootPaths: options.rootPaths.slice(),
print: dump,
globals: { packaging: packaging }
});
packaging.__setLoader(loader);
Expand Down Expand Up @@ -239,7 +240,7 @@ function buildHarnessService(rootFileSpec, dump, logError,
if (options.main) {
try {
var program = this.loader.require(options.main);
program.main(options, {quit: quit});
program.main(options, {quit: quit, print: dump});
} catch (e) {
this.loader.console.exception(e);
quit("FAIL");
Expand Down Expand Up @@ -426,14 +427,35 @@ function getDefaults(rootFileSpec) {
if ('resultFile' in options)
onQuit = buildDevQuit(options);

return {options: options, onQuit: onQuit};
var logFile;
var logStream;

if ('logFile' in options) {
logFile = Cc["@mozilla.org/file/local;1"]
.createInstance(Ci.nsILocalFile);
logFile.initWithPath(options.logFile);

logStream = Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
logStream.init(logFile, -1, -1, 0);
}

function print(msg) {
dump(msg);
if (logStream && typeof(msg) == "string") {
logStream.write(msg, msg.length);
logStream.flush();
}
}

return {options: options, onQuit: onQuit, dump: print};
}

function NSGetModule(compMgr, fileSpec) {
var rootFileSpec = fileSpec.parent.parent;
var defaults = getDefaults(rootFileSpec);
var HarnessService = buildHarnessService(rootFileSpec,
dump,
defaults.dump,
defaultLogError,
defaults.onQuit,
defaults.options);
Expand Down
88 changes: 71 additions & 17 deletions python-lib/cuddlefish/runner.py
Expand Up @@ -2,12 +2,12 @@
import sys
import time
import tempfile
import subprocess
import atexit
import shutil

import simplejson as json
import mozrunner
from mozrunner import killableprocess
from cuddlefish.prefs import DEFAULT_FIREFOX_PREFS
from cuddlefish.prefs import DEFAULT_THUNDERBIRD_PREFS

Expand Down Expand Up @@ -38,9 +38,47 @@ def cleanup_installed_xpts():
for path in installed_xpts:
os.remove(path)

def follow_file(filename):
"""
Generator that yields the latest unread content from the given
file, or None if no new content is available.
For example:
>>> f = open('temp.txt', 'w')
>>> f.write('hello')
>>> f.flush()
>>> tail = follow_file('temp.txt')
>>> tail.next()
'hello'
>>> tail.next() is None
True
>>> f.write('there')
>>> f.flush()
>>> tail.next()
'there'
>>> f.close()
>>> os.remove('temp.txt')
"""

last_pos = 0
last_size = 0
while True:
newstuff = None
if os.path.exists(filename):
size = os.stat(filename).st_size
if size > last_size:
last_size = size
f = open(filename, 'r')
f.seek(last_pos)
newstuff = f.read()
last_pos = f.tell()
f.close()
yield newstuff

def run_app(harness_root_dir, harness_options, xpts,
app_type, binary=None, profiledir=None, verbose=False,
no_quit=False, timeout=None):
no_quit=False, timeout=None, logfile=None):
if binary:
binary = os.path.expanduser(binary)
if app_type == "xulrunner":
Expand All @@ -65,6 +103,25 @@ def run_app(harness_root_dir, harness_options, xpts,
os.remove(resultfile)
harness_options['resultFile'] = resultfile

def maybe_remove_logfile():
if os.path.exists(logfile):
os.remove(logfile)

logfile_tail = None

if sys.platform in ['win32', 'cygwin']:
if not logfile:
# If we're on Windows, we need to keep a logfile simply
# to print console output to stdout.
logfile = os.path.join(tempfile.gettempdir(), 'harness_log')
logfile_tail = follow_file(logfile)
atexit.register(maybe_remove_logfile)

if logfile:
logfile = os.path.abspath(os.path.expanduser(logfile))
maybe_remove_logfile()
harness_options['logFile'] = logfile

install_xpts(harness_root_dir, xpts)

env = {}
Expand Down Expand Up @@ -97,18 +154,15 @@ def remove_xulrunner_profile():
cmdline = [binary,
'-app',
os.path.join(harness_root_dir, 'application.ini'),
'-profile', xulrunner_profile,
# This ensures that dump() calls are visible
# in Windows.
'-console']
'-profile', xulrunner_profile]

if "xulrunner-bin" in binary:
cmdline.remove("-app")

if sys.platform == 'linux2' and not env.get('LD_LIBRARY_PATH'):
env['LD_LIBRARY_PATH'] = os.path.dirname(binary)

popen = subprocess.Popen(cmdline, env=env, **popen_kwargs)
popen = killableprocess.Popen(cmdline, env=env, **popen_kwargs)
else:
plugins = [harness_root_dir]
create_new = profiledir is None
Expand All @@ -118,7 +172,6 @@ def remove_xulrunner_profile():
preferences=preferences)
runner = runner_class(profile=profile,
binary=binary,
cmdargs=['-console'],
env=env,
kp_kwargs=popen_kwargs)
runner.start()
Expand All @@ -128,21 +181,22 @@ def remove_xulrunner_profile():
output = None
while not done:
time.sleep(0.05)
if popen.poll() is not None:
# Sometimes the child process will spawn yet another
# child and terminate the parent, so look for the
# result file.
if popen.returncode != 0:
if logfile_tail:
new_chars = logfile_tail.next()
if new_chars:
sys.stdout.write(new_chars)
sys.stdout.flush()
if os.path.exists(resultfile):
output = open(resultfile).read()
if output in ['OK', 'FAIL']:
done = True
elif os.path.exists(resultfile):
output = open(resultfile).read()
if output in ['OK', 'FAIL']:
done = True
if timeout and (time.time() - starttime > timeout):
# TODO: Kill the child process.
raise Exception("Wait timeout exceeded (%ds)" %
timeout)

popen.wait(10)

print "Total time: %f seconds" % (time.time() - starttime)

if profile:
Expand Down
2 changes: 1 addition & 1 deletion python-lib/cuddlefish/server.py
Expand Up @@ -362,7 +362,7 @@ def generate_static_docs(env_root, tgz_filename):

def run_app(harness_root_dir, harness_options, xpts,
app_type, binary=None, profiledir=None, verbose=False,
no_quit=False, timeout=None,
no_quit=False, timeout=None, logfile=None,
host=DEFAULT_HOST,
port=DEFAULT_PORT):
payload = json.dumps(harness_options)
Expand Down

0 comments on commit 155382d

Please sign in to comment.