View
@@ -1,18 +1,13 @@
#!/usr/bin/env bash
#
# Usage:
# ./spec-file.sh <function name>
# test/spec.sh <function name>
set -o nounset
set -o pipefail
set -o errexit
# Duplicate definition since we can't source test/common.sh without clobbering
# OSH!
die() {
echo "$@" 1>&2
exit 1
}
source test/common.sh
# For now, fall back to the shell in $PATH.
shell-path() {
@@ -43,20 +38,15 @@ fi
readonly OSH_CPYTHON='bin/osh'
readonly OSH_OVM=${OSH_OVM:-_bin/osh}
readonly OSH_LIST=${OSH_LIST:-} # A space-separated list.
OSH_LIST=${OSH_LIST:-} # A space-separated list.
# TODO: Would be nicer to use ${OSH[@]} everywhere.
OSH=''
if test -n "$OSH_LIST"; then
OSH="$OSH_LIST"
else
if test -z "$OSH_LIST"; then
if test -e $OSH_OVM; then
# TODO: Does it make sense to copy the binary to an unrelated to directory,
# like /tmp? /tmp/{oil.ovm,osh}.
OSH="$OSH_CPYTHON $OSH_OVM"
OSH_LIST="$OSH_CPYTHON $OSH_OVM"
else
OSH="$OSH_CPYTHON"
OSH_LIST="$OSH_CPYTHON"
fi
fi
@@ -82,7 +72,7 @@ install-shells() {
# TODO: Maybe do this before running all tests.
check-shells() {
for sh in "${REF_SHELLS[@]}" $ZSH $OSH; do
for sh in "${REF_SHELLS[@]}" $ZSH $OSH_LIST; do
test -e $sh || { echo "ERROR: $sh does not exist"; break; }
test -x $sh || { echo "ERROR: $sh isn't executable"; break; }
done
@@ -98,19 +88,9 @@ maybe-show() {
}
version-text() {
date
echo
if test -d .git; then
local branch=$(git rev-parse --abbrev-ref HEAD)
local hash=$(git rev-parse $branch)
echo "oil repo: $hash on branch $branch"
else
echo "(not running from git repository)"
fi
echo
date-and-git-info
for bin in $OSH; do
for bin in $OSH_LIST; do
echo ---
echo "\$ $bin --version"
$bin --version
@@ -224,190 +204,190 @@ all() {
#
smoke() {
sh-spec spec/smoke.test.sh ${REF_SHELLS[@]} $OSH "$@"
sh-spec spec/smoke.test.sh ${REF_SHELLS[@]} $OSH_LIST "$@"
}
osh-only() {
sh-spec spec/osh-only.test.sh $OSH "$@"
sh-spec spec/osh-only.test.sh $OSH_LIST "$@"
}
# Regress bugs
bugs() {
sh-spec spec/bugs.test.sh ${REF_SHELLS[@]} $OSH "$@"
sh-spec spec/bugs.test.sh ${REF_SHELLS[@]} $OSH_LIST "$@"
}
blog1() {
sh-spec spec/blog1.test.sh \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
blog2() {
sh-spec spec/blog2.test.sh \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
blog-other1() {
sh-spec spec/blog-other1.test.sh \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
alias() {
sh-spec spec/alias.test.sh --osh-failures-allowed 10 \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
comments() {
sh-spec spec/comments.test.sh ${REF_SHELLS[@]} $OSH "$@"
sh-spec spec/comments.test.sh ${REF_SHELLS[@]} $OSH_LIST "$@"
}
word-split() {
sh-spec spec/word-split.test.sh --osh-failures-allowed 2 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
word-eval() {
sh-spec spec/word-eval.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
# 'do' -- detected statically as syntax error? hm.
assign() {
sh-spec spec/assign.test.sh --osh-failures-allowed 3 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
background() {
sh-spec spec/background.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
subshell() {
sh-spec spec/subshell.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
quote() {
sh-spec spec/quote.test.sh \
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH "$@"
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH_LIST "$@"
}
loop() {
sh-spec spec/loop.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
case_() {
sh-spec spec/case_.test.sh --osh-failures-allowed 2 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
if_() {
sh-spec spec/if_.test.sh --osh-failures-allowed 1 \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
builtins() {
sh-spec spec/builtins.test.sh --osh-failures-allowed 1 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
builtin-eval-source() {
sh-spec spec/builtin-eval-source.test.sh \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
builtin-io() {
sh-spec spec/builtin-io.test.sh \
${REF_SHELLS[@]} $ZSH $BUSYBOX_ASH $OSH "$@"
${REF_SHELLS[@]} $ZSH $BUSYBOX_ASH $OSH_LIST "$@"
}
builtins2() {
sh-spec spec/builtins2.test.sh ${REF_SHELLS[@]} $ZSH $OSH "$@"
sh-spec spec/builtins2.test.sh ${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
# dash and mksh don't implement 'dirs'
builtin-dirs() {
sh-spec spec/builtin-dirs.test.sh $BASH $ZSH $OSH "$@"
sh-spec spec/builtin-dirs.test.sh $BASH $ZSH $OSH_LIST "$@"
}
builtin-vars() {
sh-spec spec/builtin-vars.test.sh --osh-failures-allowed 2 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
builtin-getopts() {
sh-spec spec/builtin-getopts.test.sh --osh-failures-allowed 1 \
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH "$@"
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH_LIST "$@"
}
builtin-test() {
sh-spec spec/builtin-test.test.sh --osh-failures-allowed 1 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
builtin-trap() {
sh-spec spec/builtin-trap.test.sh --osh-failures-allowed 3 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
# Bash implements type -t, but no other shell does. For Nix.
# zsh/mksh/dash don't have the 'help' builtin.
builtin-bash() {
sh-spec spec/builtin-bash.test.sh \
$BASH $OSH "$@"
$BASH $OSH_LIST "$@"
}
builtins-special() {
sh-spec spec/builtins-special.test.sh --osh-failures-allowed 3 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
command-parsing() {
sh-spec spec/command-parsing.test.sh ${REF_SHELLS[@]} $OSH "$@"
sh-spec spec/command-parsing.test.sh ${REF_SHELLS[@]} $OSH_LIST "$@"
}
func-parsing() {
sh-spec spec/func-parsing.test.sh ${REF_SHELLS[@]} $OSH "$@"
sh-spec spec/func-parsing.test.sh ${REF_SHELLS[@]} $OSH_LIST "$@"
}
func() {
sh-spec spec/func.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
glob() {
sh-spec spec/glob.test.sh --osh-failures-allowed 4 \
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH "$@"
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH_LIST "$@"
}
arith() {
sh-spec spec/arith.test.sh --osh-failures-allowed 2 \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
command-sub() {
sh-spec spec/command-sub.test.sh --osh-failures-allowed 2 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
command_() {
sh-spec spec/command_.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
pipeline() {
sh-spec spec/pipeline.test.sh --osh-failures-allowed 3 \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
explore-parsing() {
sh-spec spec/explore-parsing.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
parse-errors() {
sh-spec spec/parse-errors.test.sh --osh-failures-allowed 5 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
here-doc() {
@@ -418,90 +398,90 @@ here-doc() {
# Is this due to Python 3.2 vs 3.4? Either way osh doesn't implement the
# functionality, so it's probably best to just implement it.
sh-spec spec/here-doc.test.sh --range 0-30 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
redirect() {
sh-spec spec/redirect.test.sh --osh-failures-allowed 5 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
posix() {
sh-spec spec/posix.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
special-vars() {
sh-spec spec/special-vars.test.sh --osh-failures-allowed 4 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
# dash/mksh don't implement this.
introspect() {
sh-spec spec/introspect.test.sh --osh-failures-allowed 3 \
$BASH $OSH "$@"
$BASH $OSH_LIST "$@"
}
# DONE -- pysh is the most conformant!
tilde() {
sh-spec spec/tilde.test.sh ${REF_SHELLS[@]} $OSH "$@"
sh-spec spec/tilde.test.sh ${REF_SHELLS[@]} $OSH_LIST "$@"
}
var-op-test() {
sh-spec spec/var-op-test.test.sh --osh-failures-allowed 5 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
var-op-other() {
sh-spec spec/var-op-other.test.sh \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
var-op-strip() {
sh-spec spec/var-op-strip.test.sh --osh-failures-allowed 1 \
${REF_SHELLS[@]} $ZSH $OSH "$@"
${REF_SHELLS[@]} $ZSH $OSH_LIST "$@"
}
var-sub() {
# NOTE: ZSH has interesting behavior, like echo hi > "$@" can write to TWO
# FILES! But ultimately we don't really care, so I disabled it.
sh-spec spec/var-sub.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
var-num() {
sh-spec spec/var-num.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
var-sub-quote() {
sh-spec spec/var-sub-quote.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
sh-options() {
sh-spec spec/sh-options.test.sh --osh-failures-allowed 3 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
xtrace() {
sh-spec spec/xtrace.test.sh --osh-failures-allowed 5 \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
strict-options() {
sh-spec spec/strict-options.test.sh \
${REF_SHELLS[@]} $OSH "$@"
${REF_SHELLS[@]} $OSH_LIST "$@"
}
errexit() {
sh-spec spec/errexit.test.sh \
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH "$@"
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH_LIST "$@"
}
errexit-strict() {
sh-spec spec/errexit-strict.test.sh \
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH "$@"
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH_LIST "$@"
}
#
@@ -511,17 +491,17 @@ errexit-strict() {
# There as many non-POSIX arithmetic contexts.
arith-context() {
sh-spec spec/arith-context.test.sh --osh-failures-allowed 3 \
$BASH $MKSH $ZSH $OSH "$@"
$BASH $MKSH $ZSH $OSH_LIST "$@"
}
array() {
sh-spec spec/array.test.sh --osh-failures-allowed 8 \
$BASH $MKSH $OSH "$@"
$BASH $MKSH $OSH_LIST "$@"
}
array-compat() {
sh-spec spec/array-compat.test.sh --osh-failures-allowed 6 \
$BASH $MKSH $OSH "$@"
$BASH $MKSH $OSH_LIST "$@"
}
type-compat() {
@@ -531,7 +511,7 @@ type-compat() {
# += is not POSIX and not in dash.
append() {
sh-spec spec/append.test.sh --osh-failures-allowed 4 \
$BASH $MKSH $OSH "$@"
$BASH $MKSH $OSH_LIST "$@"
}
# associative array -- mksh implements different associative arrays.
@@ -548,30 +528,30 @@ assoc-zsh() {
# I guess.
dbracket() {
sh-spec spec/dbracket.test.sh --osh-failures-allowed 2 \
$BASH $MKSH $OSH "$@"
#sh-spec spec/dbracket.test.sh $BASH $MKSH $OSH $ZSH "$@"
$BASH $MKSH $OSH_LIST "$@"
#sh-spec spec/dbracket.test.sh $BASH $MKSH $OSH_LIST $ZSH "$@"
}
dparen() {
sh-spec spec/dparen.test.sh \
$BASH $MKSH $ZSH $OSH "$@"
$BASH $MKSH $ZSH $OSH_LIST "$@"
}
brace-expansion() {
# TODO for osh: implement num ranges, mark char ranges unimplemented?
sh-spec spec/brace-expansion.test.sh --osh-failures-allowed 12 \
$BASH $MKSH $ZSH $OSH "$@"
$BASH $MKSH $ZSH $OSH_LIST "$@"
}
regex() {
sh-spec spec/regex.test.sh --osh-failures-allowed 3 \
$BASH $ZSH $OSH "$@"
$BASH $ZSH $OSH_LIST "$@"
}
process-sub() {
# mksh and dash don't support it
sh-spec spec/process-sub.test.sh \
$BASH $ZSH $OSH "$@"
$BASH $ZSH $OSH_LIST "$@"
}
extended-glob() {
@@ -582,7 +562,7 @@ extended-glob() {
# ${!var} syntax -- oil should replace this with associative arrays.
var-ref() {
sh-spec spec/var-ref.test.sh --osh-failures-allowed 5 \
$BASH $MKSH $OSH "$@"
$BASH $MKSH $OSH_LIST "$@"
}
let() {
@@ -591,11 +571,11 @@ let() {
for-expr() {
sh-spec spec/for-expr.test.sh \
$BASH $ZSH $OSH "$@"
$BASH $ZSH $OSH_LIST "$@"
}
empty-bodies() {
sh-spec spec/empty-bodies.test.sh "${REF_SHELLS[@]}" $ZSH $OSH "$@"
sh-spec spec/empty-bodies.test.sh "${REF_SHELLS[@]}" $ZSH $OSH_LIST "$@"
}
# TODO: This is for the ANTLR grammars, in the oil-sketch repo.
@@ -605,7 +585,7 @@ shell-grammar() {
}
compgen() {
sh-spec spec/compgen.test.sh $BASH $OSH "$@"
sh-spec spec/compgen.test.sh $BASH $OSH_LIST "$@"
}
"$@"
View
@@ -87,15 +87,25 @@ _link() {
ln -s -f -v "$@"
}
version-text() {
date-and-git-info
echo "\$ $OSH --version"
$OSH --version
}
make-report() {
cat $MANIFEST | wild-report summarize-dirs
local in_dir=_tmp/wild/raw
local out_dir=_tmp/wild/www
# TODO: This could also go in 'raw', and then be processed by Python?
version-text > $out_dir/version-info.txt
cat $MANIFEST | wild-report summarize-dirs $in_dir $out_dir
# This has to go inside the www dir because of the way that relative links
# are calculated.
_link \
$PWD/web/osh-to-oil.{html,js} \
_tmp/wild/www
# TODO: Isn't this redundant?
_link $PWD/web/osh-to-oil.{html,js} $out_dir
_link $PWD/web _tmp
}
View
@@ -5,6 +5,7 @@
"""
import json
import optparse
import os
import sys
@@ -89,6 +90,20 @@ def MakeHtmlGroup(title_str, body_str):
PAGE_TEMPLATES = {}
# <a href="{base_url}osh-to-oil.html#{rel_path|htmltag}/{name|htmltag}">view</a>
PAGE_TEMPLATES['FAILED'] = MakeHtmlGroup(
'{task}_failed',
"""\
<h1>{failures|size} {task} failures</h1>
{.repeated section failures}
<a href="{base_url}osh-to-oil.html#{rel_path|htmltag}">{rel_path|html}</a>
<pre>
{stderr}
</pre>
{.end}
""")
# One is used for sort order. One is used for alignment.
# type="string"
# should we use the column css class as the sort order? Why not?
@@ -117,6 +132,10 @@ def MakeHtmlGroup(title_str, body_str):
Failed to parse <b>{parse_failed|commas}</b> scripts, leaving
<b>{lines_parsed|commas}</b> lines parsed in <b>{parse_proc_secs}</b> seconds
(<b>{lines_per_sec}</b> lines/sec).
{.if test top_level_links}
(<a href="parse-failed.html">all failures</a>,
<a href="parse-failed.txt">text</a>)
{.end}
</li>
{.or}
<li>
@@ -127,13 +146,20 @@ def MakeHtmlGroup(title_str, body_str):
</li>
{.end}
<li><b>{osh2oil_failed|commas}</b> OSH-to-Oil translations failed.</li>
<li>
<b>{osh2oil_failed|commas}</b> OSH-to-Oil translations failed.
{.if test top_level_links}
(<a href="osh2oil-failed.html">all failures</a>,
<a href="osh2oil-failed.txt">text</a>)
{.end}
</li>
</ul>
</div>
<p></p>
{.end}
{.section dirs}
<table id="dirs">
<colgroup> <!-- for table-sort.js -->
@@ -277,6 +303,10 @@ def MakeHtmlGroup(title_str, body_str):
</table>
{.end}
{.if test top_level_links}
<a href="version-info.txt">Date and OSH version<a>
{.end}
<!-- page globals -->
<script type="text/javascript">
var gUrlHash = new UrlHash(location.hash);
@@ -371,6 +401,8 @@ def UpdateNodes(node, path_parts, file_stats):
UpdateNodes(child, rest, file_stats)
else:
# TODO: Put these in different sections? Or least one below the other?
# Include stderr if non-empty, or if FAILED
parse_stderr = file_stats.pop('parse_stderr')
if parse_stderr or file_stats['parse_failed']:
@@ -505,6 +537,9 @@ def WriteHtmlFiles(node, out_dir, rel_path='', base_url=''):
'stderr': node.stderr,
'nav': _MakeNav(rel_path),
}
# Hack to add links for top level page:
if rel_path == '':
data['top_level_links'] = True
group = PAGE_TEMPLATES['LISTING']
body = BODY_STYLE.expand(data, group=group)
@@ -520,74 +555,171 @@ def WriteHtmlFiles(node, out_dir, rel_path='', base_url=''):
WriteHtmlFiles(child, child_out, rel_path=child_rel, base_url=child_base)
def main(argv):
action = argv[1]
def _ReadTaskFile(path):
"""
Parses the a file that looks like '0 0.11', for the status code and timing.
This is output by test/common.sh run-task-with-status.
"""
try:
with open(path) as f:
parts = f.read().split()
status, secs = parts
except ValueError as e:
log('ERROR reading %s: %s', path, e)
raise
# Turn it into pass/fail
num_failed = 1 if int(status) >= 1 else 0
return num_failed, float(secs)
if action == 'summarize-dirs':
# lines and size, oops
# TODO: Need read the manifest instead, and then go by dirname() I guess
# I guess it is a BFS so you can just assume?
# os.path.dirname() on the full path?
# Or maybe you need the output files?
def _ReadLinesToSet(path):
result = set()
if not path:
return result
with open(path) as f:
for line in f:
result.add(line.strip())
return result
root_node = DirNode()
# Collect work into dirs
for line in sys.stdin:
#d = line.strip()
rel_path, abs_path = line.split()
#print proj, '-', abs_path, '-', rel_path
def SumStats(stdin, in_dir, root_node, failures):
"""Reads pairs of paths from stdin, and updates root_node."""
# Collect work into dirs
for line in stdin:
# TODO: Add a column for wild_-not-shell.txt wild-not-osh. I guess it
# can just be an attribute on st, and then you can test for it.
# If it's not shell, omit it from the totals. If it's not OSH, append it
# to a common page, like www/not-shell.html and www/not-osh.html.
def _ReadTaskFile(path):
try:
with open(path) as f:
parts = f.read().split()
status, secs = parts
except ValueError as e:
log('ERROR reading %s: %s', path, e)
raise
# Turn it into pass/fail
num_failed = 1 if int(status) >= 1 else 0
return num_failed, float(secs)
rel_path, abs_path = line.split()
#print proj, '-', abs_path, '-', rel_path
raw_base = os.path.join('_tmp/wild/raw', rel_path)
st = {}
raw_base = os.path.join(in_dir, rel_path)
st = {}
# TODO:
# - Open stderr to get internal time
parse_task_path = raw_base + '__parse.task.txt'
parse_failed, st['parse_proc_secs'] = _ReadTaskFile(
parse_task_path)
st['parse_failed'] = parse_failed
parse_task_path = raw_base + '__parse.task.txt'
st['parse_failed'], st['parse_proc_secs'] = _ReadTaskFile(
parse_task_path)
with open(raw_base + '__parse.stderr.txt') as f:
st['parse_stderr'] = f.read()
with open(raw_base + '__parse.stderr.txt') as f:
st['parse_stderr'] = f.read()
if parse_failed:
failures.parse_failed.append(
{'rel_path': rel_path, 'stderr': st['parse_stderr']}
)
osh2oil_task_path = raw_base + '__osh2oil.task.txt'
st['osh2oil_failed'], st['osh2oil_proc_secs'] = _ReadTaskFile(
osh2oil_task_path)
osh2oil_task_path = raw_base + '__osh2oil.task.txt'
osh2oil_failed, st['osh2oil_proc_secs'] = _ReadTaskFile(
osh2oil_task_path)
with open(raw_base + '__osh2oil.stderr.txt') as f:
st['osh2oil_stderr'] = f.read()
# Only count translation failures if the parse suceeded!
st['osh2oil_failed'] = osh2oil_failed if not parse_failed else 0
wc_path = raw_base + '__wc.txt'
with open(wc_path) as f:
st['num_lines'] = int(f.read().split()[0])
# For lines per second calculation
st['lines_parsed'] = 0 if st['parse_failed'] else st['num_lines']
with open(raw_base + '__osh2oil.stderr.txt') as f:
st['osh2oil_stderr'] = f.read()
st['num_files'] = 1
if st['osh2oil_failed']:
failures.osh2oil_failed.append(
{'rel_path': rel_path, 'stderr': st['osh2oil_stderr']}
)
wc_path = raw_base + '__wc.txt'
with open(wc_path) as f:
st['num_lines'] = int(f.read().split()[0])
# For lines per second calculation
st['lines_parsed'] = 0 if st['parse_failed'] else st['num_lines']
st['num_files'] = 1
path_parts = rel_path.split('/')
#print path_parts
UpdateNodes(root_node, path_parts, st)
class Failures(object):
"""Simple object that gets transformed to HTML and text."""
def __init__(self):
self.parse_failed = []
self.osh2oil_failed = []
def Write(self, out_dir):
with open(os.path.join(out_dir, 'parse-failed.txt'), 'w') as f:
for failure in self.parse_failed:
print(failure['rel_path'], file=f)
with open(os.path.join(out_dir, 'osh2oil-failed.txt'), 'w') as f:
for failure in self.osh2oil_failed:
print(failure['rel_path'], file=f)
base_url = ''
with open(os.path.join(out_dir, 'parse-failed.html'), 'w') as f:
data = {
'task': 'parse', 'failures': self.parse_failed, 'base_url': base_url
}
body = BODY_STYLE.expand(data, group=PAGE_TEMPLATES['FAILED'])
f.write(body)
with open(os.path.join(out_dir, 'osh2oil-failed.html'), 'w') as f:
data = {
'task': 'osh2oil', 'failures': self.osh2oil_failed,
'base_url': base_url
}
body = BODY_STYLE.expand(data, group=PAGE_TEMPLATES['FAILED'])
f.write(body)
def Options():
"""Returns an option parser instance."""
p = optparse.OptionParser('wild_report.py [options] ACTION...')
p.add_option(
'-v', '--verbose', dest='verbose', action='store_true', default=False,
help='Show details about test execution')
p.add_option(
'--not-shell', default=None,
help="A file that contains a list of files that are known to be invalid "
"shell")
p.add_option(
'--not-osh', default=None,
help="A file that contains a list of files that are known to be invalid "
"under the OSH language.")
return p
def main(argv):
o = Options()
(opts, argv) = o.parse_args(argv)
action = argv[1]
if action == 'summarize-dirs':
in_dir = argv[2]
out_dir = argv[3]
not_shell = _ReadLinesToSet(opts.not_shell)
not_osh = _ReadLinesToSet(opts.not_osh)
# lines and size, oops
# TODO: Need read the manifest instead, and then go by dirname() I guess
# I guess it is a BFS so you can just assume?
# os.path.dirname() on the full path?
# Or maybe you need the output files?
root_node = DirNode()
failures = Failures()
SumStats(sys.stdin, in_dir, root_node, failures)
path_parts = rel_path.split('/')
#print path_parts
UpdateNodes(root_node, path_parts, st)
failures.Write(out_dir)
# Debug print
#DebugPrint(root_node)
#WriteJsonFiles(root_node, '_tmp/wild/www')
#WriteJsonFiles(root_node, out_dir)
WriteHtmlFiles(root_node, '_tmp/wild/www')
WriteHtmlFiles(root_node, out_dir)
else:
raise RuntimeError('Invalid action %r' % action)
View
@@ -0,0 +1,29 @@
#!/usr/bin/python -S
"""
wild_report_test.py: Tests for wild_report.py
"""
import unittest
import wild_report # module under test
class FooTest(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def testTemplate(self):
BODY_STYLE = wild_report.BODY_STYLE
PAGE_TEMPLATES = wild_report.PAGE_TEMPLATES
data = {'base_url': '', 'paths': [], 'task': 'osh2oil'}
body = BODY_STYLE.expand(data, group=PAGE_TEMPLATES['FAILED'])
print(body)
if __name__ == '__main__':
unittest.main()