Add automatic tests for Tick Processor, take two.

Now tests can be run from any directory. Location of test data is now determined using test file location provided by 'testcfg.py' script.

Tested under Linux, Mac, and Windows.

Review URL: http://codereview.chromium.org/155161


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2407 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b8eb6189
......@@ -29,10 +29,12 @@ import test
import os
from os.path import join, dirname, exists
import re
import tempfile
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
FILES_PATTERN = re.compile(r"//\s+Files:(.*)")
SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME")
class MjsunitTestCase(test.TestCase):
......@@ -42,6 +44,7 @@ class MjsunitTestCase(test.TestCase):
self.file = file
self.config = config
self.mode = mode
self.self_script = False
def GetLabel(self):
return "%s %s" % (self.mode, self.GetName())
......@@ -55,19 +58,43 @@ class MjsunitTestCase(test.TestCase):
flags_match = FLAGS_PATTERN.search(source)
if flags_match:
result += flags_match.group(1).strip().split()
files_match = FILES_PATTERN.search(source);
additional_files = []
if files_match:
additional_files += files_match.group(1).strip().split()
files_match = FILES_PATTERN.search(source);
# Accept several lines of 'Files:'
while True:
if files_match:
additional_files += files_match.group(1).strip().split()
files_match = FILES_PATTERN.search(source, files_match.end())
else:
break
for a_file in additional_files:
result.append(join(dirname(self.config.root), '..', a_file))
framework = join(dirname(self.config.root), 'mjsunit', 'mjsunit.js')
if SELF_SCRIPT_PATTERN.search(source):
result.append(self.CreateSelfScript())
result += [framework, self.file]
return result
def GetSource(self):
return open(self.file).read()
def CreateSelfScript(self):
(fd_self_script, self_script) = tempfile.mkstemp(suffix=".js")
def MakeJsConst(name, value):
return "var %(name)s=\'%(value)s\';\n" % \
{'name': name, \
'value': value.replace('\\', '\\\\').replace('\'', '\\\'') }
try:
os.write(fd_self_script, MakeJsConst('TEST_FILE_NAME', self.file))
except IOError, e:
test.PrintError("write() " + str(e))
os.close(fd_self_script)
self.self_script = self_script
return self_script
def Cleanup(self):
if self.self_script:
test.CheckedUnlink(self.self_script)
class MjsunitTestConfiguration(test.TestConfiguration):
......
Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
[Unknown]:
ticks total nonlib name
2 15.4%
[Shared libraries]:
ticks total nonlib name
2 15.4% 0.0% /lib32/libm-2.7.so
1 7.7% 0.0% ffffe000-fffff000
[JavaScript]:
ticks total nonlib name
1 7.7% 10.0% LazyCompile: exp native math.js:41
[C++]:
ticks total nonlib name
2 15.4% 20.0% v8::internal::Runtime_Math_exp(v8::internal::Arguments)
1 7.7% 10.0% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 7.7% 10.0% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
1 7.7% 10.0% fegetexcept
1 7.7% 10.0% exp
[GC]:
ticks total nonlib name
0 0.0%
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 2.0% are not shown.
ticks parent name
2 15.4% v8::internal::Runtime_Math_exp(v8::internal::Arguments)
2 100.0% LazyCompile: exp native math.js:41
2 100.0% Script: exp.js
2 15.4% /lib32/libm-2.7.so
2 100.0% LazyCompile: exp native math.js:41
2 100.0% Script: exp.js
1 7.7% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 100.0% Script: exp.js
1 7.7% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
1 100.0% Script: exp.js
1 7.7% ffffe000-fffff000
1 7.7% fegetexcept
1 100.0% LazyCompile: exp native math.js:41
1 100.0% Script: exp.js
1 7.7% exp
1 100.0% LazyCompile: exp native math.js:41
1 100.0% Script: exp.js
1 7.7% LazyCompile: exp native math.js:41
1 100.0% Script: exp.js
Statistical profiling result from v8.log, (13 ticks, 0 unaccounted, 13 excluded).
[Shared libraries]:
ticks total nonlib name
[JavaScript]:
ticks total nonlib name
[C++]:
ticks total nonlib name
[GC]:
ticks total nonlib name
0 0.0%
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 2.0% are not shown.
ticks parent name
Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
[Shared libraries]:
ticks total nonlib name
2 18.2% 0.0% /lib32/libm-2.7.so
1 9.1% 0.0% ffffe000-fffff000
[JavaScript]:
ticks total nonlib name
1 9.1% 12.5% LazyCompile: exp native math.js:41
[C++]:
ticks total nonlib name
2 18.2% 25.0% v8::internal::Runtime_Math_exp(v8::internal::Arguments)
1 9.1% 12.5% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 9.1% 12.5% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
1 9.1% 12.5% fegetexcept
1 9.1% 12.5% exp
[GC]:
ticks total nonlib name
0 0.0%
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 2.0% are not shown.
ticks parent name
2 18.2% v8::internal::Runtime_Math_exp(v8::internal::Arguments)
2 100.0% LazyCompile: exp native math.js:41
2 100.0% Script: exp.js
2 18.2% /lib32/libm-2.7.so
2 100.0% LazyCompile: exp native math.js:41
2 100.0% Script: exp.js
1 9.1% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 100.0% Script: exp.js
1 9.1% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
1 100.0% Script: exp.js
1 9.1% ffffe000-fffff000
1 9.1% fegetexcept
1 100.0% LazyCompile: exp native math.js:41
1 100.0% Script: exp.js
1 9.1% exp
1 100.0% LazyCompile: exp native math.js:41
1 100.0% Script: exp.js
1 9.1% LazyCompile: exp native math.js:41
1 100.0% Script: exp.js
shared-library,"shell",0x08048000,0x081ee000
shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000
shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000
profiler,"begin",1
code-creation,Stub,0xf540a100,474,"CEntryStub"
code-creation,Script,0xf541cd80,736,"exp.js"
code-creation,Stub,0xf541d0e0,47,"RuntimeStub_Math_exp"
code-creation,LazyCompile,0xf541d120,145,"exp native math.js:41"
code-creation,LoadIC,0xf541d280,117,"j"
code-creation,LoadIC,0xf541d360,63,"i"
tick,0x80f82d1,0xffdfe880,0,0xf541ce5c
tick,0x80f89a1,0xffdfecf0,0,0xf541ce5c
tick,0x8123b5c,0xffdff1a0,0,0xf541d1a1,0xf541ceea
tick,0x8123b65,0xffdff1a0,0,0xf541d1a1,0xf541ceea
tick,0xf541d2be,0xffdff1e4,0
tick,0xf541d320,0xffdff1dc,0
tick,0xf541d384,0xffdff1d8,0
tick,0xf7db94da,0xffdff0ec,0,0xf541d1a1,0xf541ceea
tick,0xf7db951c,0xffdff0f0,0,0xf541d1a1,0xf541ceea
tick,0xf7dbc508,0xffdff14c,0,0xf541d1a1,0xf541ceea
tick,0xf7dbff21,0xffdff198,0,0xf541d1a1,0xf541ceea
tick,0xf7edec90,0xffdff0ec,0,0xf541d1a1,0xf541ceea
tick,0xffffe402,0xffdff488,0
profiler,"end"
Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0 excluded).
[Unknown]:
ticks total nonlib name
2 15.4%
[Shared libraries]:
ticks total nonlib name
2 15.4% 0.0% /lib32/libm-2.7.so
1 7.7% 0.0% ffffe000-fffff000
[JavaScript]:
ticks total nonlib name
1 7.7% 10.0% LoadIC: j
1 7.7% 10.0% LoadIC: i
1 7.7% 10.0% LazyCompile: exp native math.js:41
[C++]:
ticks total nonlib name
2 15.4% 20.0% v8::internal::Runtime_Math_exp(v8::internal::Arguments)
1 7.7% 10.0% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 7.7% 10.0% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
1 7.7% 10.0% fegetexcept
1 7.7% 10.0% exp
[GC]:
ticks total nonlib name
0 0.0%
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 2.0% are not shown.
ticks parent name
2 15.4% v8::internal::Runtime_Math_exp(v8::internal::Arguments)
2 100.0% LazyCompile: exp native math.js:41
2 100.0% Script: exp.js
2 15.4% /lib32/libm-2.7.so
2 100.0% LazyCompile: exp native math.js:41
2 100.0% Script: exp.js
1 7.7% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
1 100.0% Script: exp.js
1 7.7% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
1 100.0% Script: exp.js
1 7.7% ffffe000-fffff000
1 7.7% fegetexcept
1 100.0% LazyCompile: exp native math.js:41
1 100.0% Script: exp.js
1 7.7% exp
1 100.0% LazyCompile: exp native math.js:41
1 100.0% Script: exp.js
1 7.7% LoadIC: j
1 7.7% LoadIC: i
1 7.7% LazyCompile: exp native math.js:41
1 100.0% Script: exp.js
This diff is collapsed.
......@@ -20,4 +20,5 @@ fi
$d8_exec $tools_path/splaytree.js $tools_path/codemap.js \
$tools_path/csvparser.js $tools_path/consarray.js \
$tools_path/profile.js $tools_path/profile_view.js \
$tools_path/logreader.js $tools_path/tickprocessor.js -- $@ 2>/dev/null
$tools_path/logreader.js $tools_path/tickprocessor.js \
$tools_path/tickprocessor-driver.js -- $@ 2>/dev/null
......@@ -356,11 +356,15 @@ class TestCase(object):
def RunCommand(self, command):
full_command = self.context.processor(command)
output = Execute(full_command, self.context, self.context.timeout)
self.Cleanup()
return TestOutput(self, full_command, output)
def Run(self):
return self.RunCommand(self.GetCommand())
def Cleanup(self):
return
class TestOutput(object):
......@@ -473,6 +477,13 @@ def PrintError(str):
sys.stderr.write('\n')
def CheckedUnlink(name):
try:
os.unlink(name)
except OSError, e:
PrintError("os.unlink() " + str(e))
def Execute(args, context, timeout=None):
(fd_out, outname) = tempfile.mkstemp()
(fd_err, errname) = tempfile.mkstemp()
......@@ -487,11 +498,6 @@ def Execute(args, context, timeout=None):
os.close(fd_err)
output = file(outname).read()
errors = file(errname).read()
def CheckedUnlink(name):
try:
os.unlink(name)
except OSError, e:
PrintError("os.unlink() " + str(e))
CheckedUnlink(outname)
CheckedUnlink(errname)
return CommandOutput(exit_code, timed_out, output, errors)
......
// Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tick Processor's code flow.
function processArguments(args) {
var processor = new ArgumentsProcessor(args);
if (processor.parse()) {
return processor.result();
} else {
processor.printUsageAndExit();
}
}
var params = processArguments(arguments);
var tickProcessor = new TickProcessor(
params.platform == 'unix' ? new UnixCppEntriesProvider(params.nm) :
new WindowsCppEntriesProvider(),
params.separateIc,
params.ignoreUnknown,
params.stateFilter);
tickProcessor.processLogFile(params.logFileName);
tickProcessor.printStatistics();
......@@ -288,7 +288,11 @@ TickProcessor.prototype.printStatistics = function() {
function padLeft(s, len) {
s = s.toString();
if (s.length < len) {
s = (new Array(len - s.length + 1).join(' ')) + s;
var padLength = len - s.length;
if (!(padLength in padLeft)) {
padLeft[padLength] = new Array(padLength + 1).join(' ');
}
s = padLeft[padLength] + s;
}
return s;
};
......@@ -511,25 +515,11 @@ WindowsCppEntriesProvider.prototype.unmangleName = function(name) {
};
function padRight(s, len) {
s = s.toString();
if (s.length < len) {
s = s + (new Array(len - s.length + 1).join(' '));
}
return s;
};
function ArgumentsProcessor(args) {
this.args_ = args;
this.result_ = ArgumentsProcessor.DEFAULTS;
function processArguments(args) {
var result = {
logFileName: 'v8.log',
platform: 'unix',
stateFilter: null,
ignoreUnknown: false,
separateIc: false,
nm: 'nm'
};
var argsDispatch = {
this.argsDispatch_ = {
'-j': ['stateFilter', TickProcessor.VmStates.JS,
'Show only ticks from JS VM state'],
'-g': ['stateFilter', TickProcessor.VmStates.GC,
......@@ -551,63 +541,82 @@ function processArguments(args) {
'--nm': ['nm', 'nm',
'Specify the \'nm\' executable to use (e.g. --nm=/my_dir/nm)']
};
argsDispatch['--js'] = argsDispatch['-j'];
argsDispatch['--gc'] = argsDispatch['-g'];
argsDispatch['--compiler'] = argsDispatch['-c'];
argsDispatch['--other'] = argsDispatch['-o'];
argsDispatch['--external'] = argsDispatch['-e'];
function printUsageAndExit() {
print('Cmdline args: [options] [log-file-name]\n' +
'Default log file name is "v8.log".\n');
print('Options:');
for (var arg in argsDispatch) {
var synonims = [arg];
var dispatch = argsDispatch[arg];
for (var synArg in argsDispatch) {
if (arg !== synArg && dispatch === argsDispatch[synArg]) {
synonims.push(synArg);
delete argsDispatch[synArg];
}
}
print(' ' + padRight(synonims.join(', '), 20) + dispatch[2]);
}
quit(2);
}
this.argsDispatch_['--js'] = this.argsDispatch_['-j'];
this.argsDispatch_['--gc'] = this.argsDispatch_['-g'];
this.argsDispatch_['--compiler'] = this.argsDispatch_['-c'];
this.argsDispatch_['--other'] = this.argsDispatch_['-o'];
this.argsDispatch_['--external'] = this.argsDispatch_['-e'];
};
while (args.length) {
var arg = args[0];
ArgumentsProcessor.DEFAULTS = {
logFileName: 'v8.log',
platform: 'unix',
stateFilter: null,
ignoreUnknown: false,
separateIc: false,
nm: 'nm'
};
ArgumentsProcessor.prototype.parse = function() {
while (this.args_.length) {
var arg = this.args_[0];
if (arg.charAt(0) != '-') {
break;
}
args.shift();
this.args_.shift();
var userValue = null;
var eqPos = arg.indexOf('=');
if (eqPos != -1) {
userValue = arg.substr(eqPos + 1);
arg = arg.substr(0, eqPos);
}
if (arg in argsDispatch) {
var dispatch = argsDispatch[arg];
result[dispatch[0]] = userValue == null ? dispatch[1] : userValue;
if (arg in this.argsDispatch_) {
var dispatch = this.argsDispatch_[arg];
this.result_[dispatch[0]] = userValue == null ? dispatch[1] : userValue;
} else {
printUsageAndExit();
return false;
}
}
if (args.length >= 1) {
result.logFileName = args.shift();
if (this.args_.length >= 1) {
this.result_.logFileName = this.args_.shift();
}
return result;
return true;
};
var params = processArguments(arguments);
var tickProcessor = new TickProcessor(
params.platform == 'unix' ? new UnixCppEntriesProvider(params.nm) :
new WindowsCppEntriesProvider(),
params.separateIc,
params.ignoreUnknown,
params.stateFilter);
tickProcessor.processLogFile(params.logFileName);
tickProcessor.printStatistics();
ArgumentsProcessor.prototype.result = function() {
return this.result_;
};
ArgumentsProcessor.prototype.printUsageAndExit = function() {
function padRight(s, len) {
s = s.toString();
if (s.length < len) {
s = s + (new Array(len - s.length + 1).join(' '));
}
return s;
}
print('Cmdline args: [options] [log-file-name]\n' +
'Default log file name is "' +
ArgumentsProcessor.DEFAULTS.logFileName + '".\n');
print('Options:');
for (var arg in this.argsDispatch_) {
var synonims = [arg];
var dispatch = this.argsDispatch_[arg];
for (var synArg in this.argsDispatch_) {
if (arg !== synArg && dispatch === this.argsDispatch_[synArg]) {
synonims.push(synArg);
delete this.argsDispatch_[synArg];
}
}
print(' ' + padRight(synonims.join(', '), 20) + dispatch[2]);
}
quit(2);
};
......@@ -2,4 +2,4 @@
SET tools_dir=%~dp0
%tools_dir%..\d8 %tools_dir%splaytree.js %tools_dir%codemap.js %tools_dir%csvparser.js %tools_dir%consarray.js %tools_dir%profile.js %tools_dir%profile_view.js %tools_dir%logreader.js %tools_dir%tickprocessor.js -- --windows %*
%tools_dir%..\d8 %tools_dir%splaytree.js %tools_dir%codemap.js %tools_dir%csvparser.js %tools_dir%consarray.js %tools_dir%profile.js %tools_dir%profile_view.js %tools_dir%logreader.js %tools_dir%tickprocessor.js %tools_dir%tickprocessor-driver.js -- --windows %*
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