Merge "Add some Bruno WV test cases"
diff --git a/Makefile b/Makefile
index e3d52a3..edb2d06 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,10 @@
test:
wvtest/wvtestrun $(MAKE) runtests
+test_with_output:
+ $(MAKE) runtests &> result.txt
+ wvtest_result_converter.py result.txt result.xml
+
#TODO(apenwarr): use a smarter allocator.
# We could enable parallelism by depending on $(addsuffix ...) instead of
# looping through them one by one. But then we end up running multiple
@@ -77,6 +81,7 @@
ip addr show eth0; \
ip addr show eth1; \
ip addr show eth2; \
+ ip addr show eth4; \
cat /proc/cpuinfo
configs/nmap.%.tmp:
diff --git a/wvtest_result_converter.py b/wvtest_result_converter.py
new file mode 100755
index 0000000..4463f7b
--- /dev/null
+++ b/wvtest_result_converter.py
@@ -0,0 +1,167 @@
+#!/usr/bin/python
+"""Convert the wvtest results into standard gunit xml output.'.
+
+^Testing ".+" in .+:$ marks starts of a test file
+^! .+$ marks a test case status
+
+Examples:
+Testing "cwmpd" in unknown:
+ ! unknown:0 running cwmpd ok
+ ! unknown:0 grep X_CATAWAMPUS-ORG_CATAWAMPUS ok
+ ! unknown:0 NOT(grep NON_EXISTENT_NAME) ok
+ make[2]: Leaving directory
+ `/usr/local/google/brucefan/bruno-git/vendor/google/test'
+ make[2]: Entering directory
+ `/usr/local/google/brucefan/bruno-git/vendor/google/test'
+ echo "Testing 002-pytest.py"
+ Testing 002-pytest.py
+ ssh -l root 192.168.1.3 \
+ 'cd /tmp/tests && python ./wvtest/wvtest.py 002-pytest.py' </dev/null
+Importing: 002-pytest
+
+Testing "TestBasicPython" in 002-pytest.py:
+ ! 002-pytest.py:14 True ok
+ ! 002-pytest.py:15 1 == 1 ok
+ ! 002-pytest.py:16 1 != 2 ok
+
+The test result will be saved to a .xml file that can be used by our dashboard
+system to stream the data into Sponge easily.
+"""
+
+__author__ = 'brucefan@google.com (Chun Fan)'
+
+
+from lxml import etree
+import os
+import re
+import sys
+
+
+class TestSuitesResult(object):
+
+ def __init__(self, name):
+ self.name = name
+ self.test_suite_results = []
+
+ def AddTestSuiteResult(self, test_suite_result):
+ self.test_suite_results.append(test_suite_result)
+
+ def ToXml(self):
+ el = etree.Element('testsuites')
+ el.set('name', self.name)
+ el.set('disabled', '0')
+ el.set('time', '0.0')
+ el.set('errors', '0')
+ for ts in self.test_suite_results:
+ el.append(ts.ToXml())
+ self.total_tests = sum(
+ [ts.total_tests for ts in self.test_suite_results])
+ self.failures = sum(
+ [ts.failures for ts in self.test_suite_results])
+ el.set('failures', str(self.failures))
+ el.set('tests', str(self.total_tests))
+ return el
+
+
+class TestSuiteResult(object):
+
+ def __init__(self, name):
+ self.name = name
+ self.test_case_results = []
+
+ def AddTestCaseResult(self, test_case_result):
+ self.test_case_results.append(test_case_result)
+
+ def ToXml(self):
+ el = etree.Element('testsuite')
+ el.set('name', self.name)
+ el.set('disabled', '0')
+ el.set('time', '0.0')
+ el.set('errors', '0')
+ for tc in self.test_case_results:
+ el.append(tc.ToXml())
+ self.total_tests = len(self.test_case_results)
+ self.failures = len([tc for tc in self.test_case_results if tc.result])
+ el.set('failures', str(self.failures))
+ el.set('tests', str(self.total_tests))
+ return el
+
+
+class TestCaseResult(object):
+
+ PASSED = 0
+ FAILED = 1
+ ERROR = 2
+
+ def __init__(self, name, class_name, result, result_msg=None):
+ self.name = name
+ self.class_name = class_name
+ self.result = result
+ self.result_msg = result_msg
+
+ def ToXml(self):
+ el = etree.Element('testcase')
+ el.set('name', self.name)
+ el.set('classname', self.class_name)
+ el.set('time', '0')
+ el.set('status', 'run')
+ if self.result:
+ print 'Test case: ', self.name, 'FAILED with result code', self.result
+ failure = etree.Element('failure')
+ failure.text = self.result_msg
+ el.append(failure)
+ else:
+ print 'Test case: ', self.name, 'PASSED with result code', self.result
+ return el
+
+
+def ParseTestResult(result_file, output_xml_file):
+ """Parse the given result file and dump out parsed data to given output."""
+ if not os.path.exists(result_file):
+ print 'Error: Given result file does not exist: ', result_file
+ return
+ test_suites = TestSuitesResult('Bruno Release Smoke')
+ current_test_suite = None
+ with open(result_file, 'r') as f:
+ for line in f:
+ m = re.search(r'^Testing \"(.+)\" in (.+):$', line)
+ if m:
+ # a new start for a test file
+ suite_name = m.group(1)
+ file_name = m.group(2)
+ print 'Processing suite', suite_name, 'in file', file_name
+ current_test_suite = TestSuiteResult(suite_name)
+ test_suites.AddTestSuiteResult(current_test_suite)
+ continue
+ if line.startswith('! '):
+ if not current_test_suite:
+ print 'WARNING: Encounter a test case before a test suite is seen.'
+ continue
+ # Found a test case result
+ parts = line.strip().split(' ')
+ test_case_name = ' '.join(parts[2:-2]).strip()
+ test_case_class_name = '%s-%s' % (
+ current_test_suite.name, test_case_name)
+ test_case_result = TestCaseResult.PASSED
+ test_case_result_msg = ''
+ if parts[-1] != 'ok':
+ test_case_result = TestCaseResult.FAILED
+ test_case_result_msg = line
+ print 'Processing test case: ', test_case_name, test_case_result
+ current_test_suite.AddTestCaseResult(
+ TestCaseResult(
+ name=test_case_name,
+ class_name=test_case_class_name,
+ result=test_case_result,
+ result_msg=test_case_result_msg))
+ # Now it is time to write the xml output
+ with open(output_xml_file, 'w') as f:
+ f.write(etree.tostring(test_suites.ToXml(), pretty_print=True))
+
+
+def main(argv):
+ ParseTestResult(sys.argv[1], sys.argv[2])
+
+
+if __name__ == '__main__':
+ main(sys.argv)