From 828f79bb4ac478adc9cc05cd476be7549d814229 Mon Sep 17 00:00:00 2001 From: knevcher Date: Mon, 11 Oct 2010 16:59:16 +0400 Subject: [PATCH 1/2] -- added bamboo runner --- bamboo/bamboo.sh | 37 ++++ bamboo/common.inc.php | 9 + bamboo/runner.php | 181 +++++++++++++++++ .../tests_runner/BambooTestReporter.class.php | 65 ++++++ .../tests_runner/BambooTestRunner.class.php | 24 +++ .../BambooTestXmlGenerator.class.php | 186 ++++++++++++++++++ 6 files changed, 502 insertions(+) create mode 100755 bamboo/bamboo.sh create mode 100644 bamboo/common.inc.php create mode 100644 bamboo/runner.php create mode 100644 bamboo/tests_runner/BambooTestReporter.class.php create mode 100644 bamboo/tests_runner/BambooTestRunner.class.php create mode 100644 bamboo/tests_runner/BambooTestXmlGenerator.class.php diff --git a/bamboo/bamboo.sh b/bamboo/bamboo.sh new file mode 100755 index 0000000..57173a9 --- /dev/null +++ b/bamboo/bamboo.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +CUR_DIR=$(cd $(dirname $0) && pwd); +#PROJECT_PATH=`readlink -f "$CUR_DIR/../.."` + +LIMB_DIR=$1 + +if [ ! -d $LIMB_DIR ]; then + echo 'Please pass a full path to limb repo as argument to this script' + exit 1; +fi + +PROJECT_PATH=`readlink -f "$LIMB_DIR"/../` + +#LIMB_DIR=`readlink -f "$CUR_DIR/.."` +#LIMB_DIR=$PROJECT_PATH + +LIMB_DIR_NAME=`basename "$LIMB_DIR"` + +echo $LIMB_DIR_NAME + +rm -rf $CUR_DIR/var/* + +if [ "$LIMB_DIR_NAME" != "limb" ]; then + mv $PROJECT_PATH/$LIMB_DIR_NAME $PROJECT_PATH/limb +fi + +rm -rf $PROJECT_PATH/limb/bamboo + +mkdir -p $PROJECT_PATH/limb/bamboo +cp -r $CUR_DIR/../bamboo_runner/* $PROJECT_PATH/limb/bamboo + +php $PROJECT_PATH/limb/bamboo/runner.php + +if [ "$LIMB_DIR_NAME" != "limb" ]; then + mv $PROJECT_PATH/limb $PROJECT_PATH/$LIMB_DIR_NAME +fi diff --git a/bamboo/common.inc.php b/bamboo/common.inc.php new file mode 100644 index 0000000..257c4e9 --- /dev/null +++ b/bamboo/common.inc.php @@ -0,0 +1,9 @@ +\s*(.*)$~', $line, $m)) + { + if(file_exists($m[1])) + $php_ini = "-c " . $m[1]; + } + } + return $php_bin . " " . $php_ini; +} + +$defines = array(); + +process_argv($argv, $defines); + +if(sizeof($argv) > 1) + $tests = array_splice($argv, 1); + +if(!$tests) + $tests = glob("*", GLOB_ONLYDIR); + + +$tests = array_diff($tests, $skipped); + +if($fork) +{ + $php_bin = get_php_bin(); + out("=========== Forking processes for each test path(PHP cmdline '$php_bin') ===========\n"); +} + +$res = true; +foreach($tests as $test) +{ + if(file_exists($test) || is_dir($test)) + { + $result_xml_path = LIMB_PATH . '/bamboo/var/' . $test . '_result.xml'; + if($fork) + { + $response = system($php_bin . " " . __FILE__ . " -q --no-fork " . implode(" ", $defines) . " $test", $ret); + if($ret != 0) + $res = false; + + if(!file_exists($result_xml_path)) + { + $error_result_string = " + + + + + +"; + + lmbFs :: safeWrite($result_xml_path, $error_result_string); + } + } + else + { + $runner = new BambooTestRunner(); + $runner->setReporter($reporter = new BambooTestReporter()); + + if($runner->run(new lmbTestTreeFilePathNode($test))) + { + $generator = new BambooTestXmlGenerator($reporter); + lmbFs :: safeWrite($result_xml_path, $generator->generate()); + } + else + $res = false; + } + } + else + out("=========== Test path '$test' is not valid, skipping ==========\n"); +} + +if(!$res) + out("=========== TESTS HAD ERRORS(see above) ===========\n"); +else + out("=========== ALL TESTS PASSED ===========\n"); + +exit($res ? 0 : 1); diff --git a/bamboo/tests_runner/BambooTestReporter.class.php b/bamboo/tests_runner/BambooTestReporter.class.php new file mode 100644 index 0000000..cf326b9 --- /dev/null +++ b/bamboo/tests_runner/BambooTestReporter.class.php @@ -0,0 +1,65 @@ +_skipped++; + parent :: paintSkip($message); + $this->_generateElement($message, 'Skipped'); + } + + function getSkippedCount() + { + return $this->_skipped; + } + + function _generateElement($message, $status) + { + $breadcrumb = $this->getTestList(); + array_shift($breadcrumb); + + $result = array( + 'test_class' => $breadcrumb[count($breadcrumb) - 2], + 'test_method' => $breadcrumb[count($breadcrumb) - 1], + 'time' => time(), + 'message' => $message, + 'status' => $status, + ); + + $this->_results[] = $result; + } + + function paintPass($message) + { + parent::paintPass($message); + $this->_generateElement($message, 'Passed'); + } + + function paintFail($message) + { + parent::paintFail($message); + $this->_generateElement($message, 'Failed'); + } + + function paintError($message) + { + parent::paintError($message); + $this->_generateElement($message, 'Error'); + } + + function paintException($message) + { + parent::paintException($message); + $this->_generateElement($message, 'Exception'); + } + + function getResults() + { + return $this->_results; + } +} \ No newline at end of file diff --git a/bamboo/tests_runner/BambooTestRunner.class.php b/bamboo/tests_runner/BambooTestRunner.class.php new file mode 100644 index 0000000..dd86ae7 --- /dev/null +++ b/bamboo/tests_runner/BambooTestRunner.class.php @@ -0,0 +1,24 @@ +reporter) + { + require_once('limb/test_runner/src/lmbTestShellReporter.class.php'); + SimpleTest :: prefer(new lmbTestShellReporter()); + + $this->reporter = clone(SimpleTest :: preferred(array('SimpleReporter', 'SimpleReporterDecorator'))); + } + + return $this->reporter; + } +} \ No newline at end of file diff --git a/bamboo/tests_runner/BambooTestXmlGenerator.class.php b/bamboo/tests_runner/BambooTestXmlGenerator.class.php new file mode 100644 index 0000000..5486ff9 --- /dev/null +++ b/bamboo/tests_runner/BambooTestXmlGenerator.class.php @@ -0,0 +1,186 @@ +_recorder = $recorder; + $this->_dom = new DOMDocument('1.0', 'utf-8'); + $this->_dom->formatOutput = true; + $this->_dom->preserveWhiteSpace = false; + + $this->_prepareResultDataset(); + } + + protected function _prepareResultDataset() + { + $this->_result_dataset = array(); + + if(!$this->_recorder->getResults()) + return; + + foreach($this->_recorder->getResults() as $result) + { + if(!isset($this->_result_dataset[$result['test_class']][$result['test_method']])) + $this->_result_dataset[$result['test_class']][$result['test_method']] = array(); + + $this->_result_dataset[$result['test_class']][$result['test_method']][] = $result; + } + } + + function generate() + { + $this->_generateRootElement(); + $this->_generateTestSuites(); + + return $this->_dom->saveXML(); + } + + protected function _generateRootElement() + { + $root = $this->_dom->createElement('testsuites'); + $this->_dom->appendChild($root); + + $this->_createAttribute('name', 'ATS Run tests results', $root); + + $this->_root = $root; + } + + protected function _generateTestSuites() + { + foreach($this->_result_dataset as $testsuite_name => $dataset) + $this->_createTestSuite($testsuite_name, $dataset); + } + + protected function _createTestSuite($testsuite_name, $dataset) + { + $testsuite = $this->_dom->createElement('testsuite'); + $this->_createAttribute('name', $testsuite_name, $testsuite); + + $this->_root->appendChild($testsuite); + + $this->_generateTestCasesAndCountResults($testsuite, $testsuite_name, $dataset); + } + + protected function _generateTestCasesAndCountResults($testsuite, $testsuite_name, $dataset) + { + $testsuite_assertions = 0; + $testsuite_failures = 0; + $testsuite_errors = 0; + $testsuite_skipped = 0; + + foreach($dataset as $testcase_name => $testcase_dataset) + { + $results = $this->_createTestCase($testsuite, $testsuite_name, $testcase_name, $testcase_dataset); + + $testsuite_assertions += $results['assertions']; + $testsuite_failures += $results['failures']; + $testsuite_errors += $results['errors']; + $testsuite_skipped += $results['skipped']; + } + + $this->_createAttribute('assertions', $testsuite_assertions, $testsuite); + $this->_createAttribute('failures', $testsuite_failures, $testsuite); + $this->_createAttribute('errors', $testsuite_errors, $testsuite); + $this->_createAttribute('skipped', $testsuite_skipped, $testsuite); + } + + protected function _createTestCase($testsuite, $testsuite_name, $testcase_name, $testcase_dataset) + { + $testcase = $this->_dom->createElement('testcase'); + + $this->_createAttribute('name', $testcase_name, $testcase); + $this->_createAttribute('class', $testsuite_name, $testcase); + + $testsuite->appendChild($testcase); + + $testcase_assertions = 0; + $testcase_failures = 0; + $testcase_errors = 0; + $testcase_exceptions = 0; + $testcase_skipped = 0; + + foreach($testcase_dataset as $result) + { + if($result['status'] == 'Passed') + $testcase_assertions++; + elseif($result['status'] == 'Failed') + { + $testcase_failures++; + $this->_createFailureOrErrorElement($testcase, $result); + } + elseif($result['status'] == 'Error') + { + $testcase_errors++; + $this->_createFailureOrErrorElement($testcase, $result); + } + elseif($result['status'] == 'Exception') + { + $testcase_exceptions++; + $this->_createFailureOrExceptionElement($testcase, $result); + } + elseif($result['status'] == 'Skipped') + { + $testcase_assertions++; /// - for bamboo while it can't handle skipped tests + $testcase_skipped++; + // $this->_createSkippedElement($testcase, $result); -- bamboo can't parse tag + $this->_createAttribute('name', 'SKIPPED TESTS!'. $testcase_name, $testcase); + } + } + + $this->_createAttribute('assertions', $testcase_assertions, $testcase); + $this->_createAttribute('errors', $testcase_errors, $testcase); + $this->_createAttribute('failures', $testcase_failures, $testcase); + $this->_createAttribute('exceptions', $testcase_exceptions, $testcase); + $this->_createAttribute('skipped', $testcase_skipped, $testcase); + + return array( + 'assertions' => $testcase_assertions, + 'failures' => $testcase_failures, + 'errors' => $testcase_errors, + 'skipped' => $testcase_skipped, + ); + } + + protected function _createAttribute($name, $value, $append_to) + { + $attribute = $this->_dom->createAttribute($name); + $attribute->value = $value; + + $append_to->appendChild($attribute); + } + + protected function _createFailureOrErrorElement($testcase, $result) + { + $tag_name = ($result['status'] == 'Failed' ? 'failure' : 'error'); + $element = $this->_dom->createElement($tag_name); + $message = $this->_dom->createTextNode($result['message']); + + $element->appendChild($message); + $testcase->appendChild($element); + } + + protected function _createFailureOrExceptionElement($testcase, $result) + { + $element = $this->_dom->createElement('error'); + $message = $this->_dom->createTextNode($result['message']); + + $element->appendChild($message); + $testcase->appendChild($element); + } + + protected function _createSkippedElement($testcase, $result) + { + $element = $this->_dom->createElement('message'); + $message = $this->_dom->createTextNode($result['message']); + + $element->appendChild($message); + $testcase->appendChild($element); + } +} From 85b3418019fc8e8781296dc7f56c513c38d1f879 Mon Sep 17 00:00:00 2001 From: knevcher Date: Mon, 11 Oct 2010 17:01:57 +0400 Subject: [PATCH 2/2] -- minor fix in bamboo runner --- bamboo/bamboo.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bamboo/bamboo.sh b/bamboo/bamboo.sh index 57173a9..7f00915 100755 --- a/bamboo/bamboo.sh +++ b/bamboo/bamboo.sh @@ -28,7 +28,7 @@ fi rm -rf $PROJECT_PATH/limb/bamboo mkdir -p $PROJECT_PATH/limb/bamboo -cp -r $CUR_DIR/../bamboo_runner/* $PROJECT_PATH/limb/bamboo +cp -r $CUR_DIR/* $PROJECT_PATH/limb/bamboo php $PROJECT_PATH/limb/bamboo/runner.php