From 188da7c7f85b0063d290503ba5e25e94eacaa73d Mon Sep 17 00:00:00 2001 From: mathias-goebel Date: Wed, 5 Dec 2018 21:13:47 +0100 Subject: [PATCH 1/7] print test coverage --- post-install.xq | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/post-install.xq b/post-install.xq index bb19300..14fff0e 100644 --- a/post-install.xq +++ b/post-install.xq @@ -7,6 +7,22 @@ declare namespace xconf="http://exist-db.org/collection-config/1.0"; (: the target collection into which the app is deployed :) declare variable $target external; +declare function local:test-coverage($tests as element(testsuites)*) +as xs:string { + let $testsDone := $tests//testsuite/@tests => sum() + let $failures := $tests//testsuite/@failures => sum() + let $errors := $tests//testsuite/@errors => sum() + let $pending := $tests//testsuite/@pending => sum() + + let $failsTriggered := $test//testcase[@name="FAIL"] => count() + + let $testCoverage := ($testsDone - sum( $failures, $errors, $pending, $failsTriggered )) div $testsDone + return + "test coverage: " || format-number($testCoverage, "#%") +}; + + + let $project-name := tokenize($target, "/")[last()] let $log := util:log-system-out("installing " || $project-name) @@ -61,6 +77,7 @@ return ( let $tests := util:eval(xs:anyURI('test.xq')) let $print := util:log-system-out( $tests ) + let $print := util:log-system-out( local:test-coverage($tests) ) let $file-name := system:get-exist-home()||util:system-property('file.separator')||".."||util:system-property('file.separator')||"sade_job-"||string($jobId)||".log.xml" let $file := file:serialize({ $tests }, $file-name, ()) return -- GitLab From 4f6c852c059477a05d754131f4cb0bc807f737f5 Mon Sep 17 00:00:00 2001 From: mathias-goebel Date: Wed, 5 Dec 2018 21:19:17 +0100 Subject: [PATCH 2/7] correct usage of sum() --- post-install.xq | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/post-install.xq b/post-install.xq index 14fff0e..d17c01d 100644 --- a/post-install.xq +++ b/post-install.xq @@ -16,7 +16,7 @@ as xs:string { let $failsTriggered := $test//testcase[@name="FAIL"] => count() - let $testCoverage := ($testsDone - sum( $failures, $errors, $pending, $failsTriggered )) div $testsDone + let $testCoverage := ($testsDone - sum( ($failures, $errors, $pending, $failsTriggered) )) div $testsDone return "test coverage: " || format-number($testCoverage, "#%") }; -- GitLab From 57ba41d1ff19219aba604fa6b4b306bd94e128b4 Mon Sep 17 00:00:00 2001 From: mathias-goebel Date: Wed, 5 Dec 2018 21:43:17 +0100 Subject: [PATCH 3/7] minor fixes --- post-install.xq | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/post-install.xq b/post-install.xq index d17c01d..1d1728e 100644 --- a/post-install.xq +++ b/post-install.xq @@ -9,16 +9,17 @@ declare variable $target external; declare function local:test-coverage($tests as element(testsuites)*) as xs:string { - let $testsDone := $tests//testsuite/@tests => sum() - let $failures := $tests//testsuite/@failures => sum() + let $allFailures := $tests//testsuite/@failures => sum() + let $failsTriggered := $tests//testcase[@name=("FAIL", "fail")] => count() + let $failures := $allFailures - $failsTriggered let $errors := $tests//testsuite/@errors => sum() let $pending := $tests//testsuite/@pending => sum() - let $failsTriggered := $test//testcase[@name="FAIL"] => count() + let $testsDone := $tests//testsuite/@tests => sum() - let $testCoverage := ($testsDone - sum( ($failures, $errors, $pending, $failsTriggered) )) div $testsDone + let $testCoverage := ($testsDone - sum( ($failures, $errors, $pending) )) div $testsDone * 100 return - "test coverage: " || format-number($testCoverage, "#%") + "test coverage: " || format-number($testCoverage, "###.00") || "%" }; @@ -71,25 +72,12 @@ let $jobId := try {file:read("/tmp/ci.job") => xs:int()} catch * { 0 } let $log := util:log-system-out( "[48;2;"|| "255;0;0" ||"m " || "This is JOB #" || string($jobId) || "." || " " ) return -( - if ($jobId gt 0) - then - ( - let $tests := util:eval(xs:anyURI('test.xq')) - let $print := util:log-system-out( $tests ) - let $print := util:log-system-out( local:test-coverage($tests) ) - let $file-name := system:get-exist-home()||util:system-property('file.separator')||".."||util:system-property('file.separator')||"sade_job-"||string($jobId)||".log.xml" - let $file := file:serialize({ $tests }, $file-name, ()) - return - ( util:log-system-out("Hey! I am taken captive in this Docker! Let me out!"), - util:log-system-out("They forced me to say: "||$file || " for " || $file-name), - system:shutdown(15) - ) - ) - else - util:log-system-out("CI_JOB_ID: 0 (not found)") - ), - (: send a beacon to tell the engine, that installation is nearly complete – - e.g. CI can initiate shutdown procedure afterwards. :) - util:eval("file:serialize(, $system-path || 'sade.beacon', ())") + + let $tests := util:eval(xs:anyURI('test.xq')) + let $print := util:log-system-out( $tests ) + let $print := util:log-system-out( local:test-coverage($tests) ) + let $file-name := system:get-exist-home()||util:system-property('file.separator')||".."||util:system-property('file.separator')||"tests-sade_job-"||string($jobId)||".log.xml" + let $file := file:serialize({ $tests }, $file-name, ()) + return + util:log-system-out($file-name || " saved.") ) -- GitLab From 0264e152339b0dbb7c90c56eae03da7efa1c1265 Mon Sep 17 00:00:00 2001 From: mathias-goebel Date: Wed, 5 Dec 2018 21:49:15 +0100 Subject: [PATCH 4/7] set up report as build artifact --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a22462e..e6d06dc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,7 +44,7 @@ installation: - output.log - test/eXist-db-*/webapp/WEB-INF/logs/expath-repo.log reports: - junit: tests-*.xml + junit: test/tests-*.xml upload: only: -- GitLab From 804965ed3502726fccdb537acd9418c790a7d513 Mon Sep 17 00:00:00 2001 From: mathias-goebel Date: Wed, 5 Dec 2018 21:59:30 +0100 Subject: [PATCH 5/7] and include the test result to the artifacts --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e6d06dc..954af8a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,6 +42,7 @@ installation: artifacts: paths: - output.log + - test/tests-*.xml - test/eXist-db-*/webapp/WEB-INF/logs/expath-repo.log reports: junit: test/tests-*.xml -- GitLab From 95c3ea551f93271a4158915d605d4191618743e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20G=C3=B6bel?= Date: Thu, 6 Dec 2018 16:14:43 +0100 Subject: [PATCH 6/7] using code coverage --- README.md | 21 +++++++++++++- post-install.xq | 65 +++++++++++++++++++++++++++++++++++++++++--- templates/index.html | 2 +- 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ed9ebbd..3e0a9c4 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,29 @@ immediately. ## Build `ant` -Artifacts go to `build/`. +Artifacts will be stored in `build/`. The default artifact is the xar package. +## Test +`ant test` will download the specified version of eXist and all dependencies to +a ready-to-go instance in the `test/` directory. at the first start all tests +will be executed by the `post-install.xq` script. To start the database use +```bash +bash test/eXist-db-*/bin/startup.sh +``` +Guide your favorite browser to the [dashboard](http://localhost:8080/exist/). + +### Port settings +When the port 8080 is blocked by a different service, simply set different ones +with the following command and restart the database. +```bash +sed -i 's/"8080"/"8090"/g; s/"8443"/"8444"/g' \ + test/eXist-db-4.5.0/tools/jetty/etc/jetty-http.xml \ + test/eXist-db-4.5.0/tools/jetty/etc/jetty.xml \ + test/eXist-db-4.5.0/tools/jetty/etc/jetty-ssl.xml +``` + ## Deploy We recommend using Debian packages for deployment. There built-in routines in the ant script. The [CI configuration](.gitlab-ci.yml) has a part to diff --git a/post-install.xq b/post-install.xq index 1d1728e..207bcf4 100644 --- a/post-install.xq +++ b/post-install.xq @@ -7,7 +7,64 @@ declare namespace xconf="http://exist-db.org/collection-config/1.0"; (: the target collection into which the app is deployed :) declare variable $target external; -declare function local:test-coverage($tests as element(testsuites)*) +(:~ + : Helper function to get all function names declared in the application. + : Uses externally declared variable $target. + : + : @author Mathias Göbel + : @since 3.1.0 + :) +declare function local:get-function-names() +as xs:string* { +for $modulePath in collection($target)/base-uri()[ends-with(., ".xqm")] +let $function := inspect:module-functions( xs:anyURI($modulePath) ) (: QNames :) +return + for $function in $functions + let $functionQName := function-name($function) + return + prefix-from-QName($functionQName) || ":" || local-name-from-QName($functionQName) +}; + +(:~ + : Formats the test coverage output - mainly used by GitLab test coverage parser. + : + : @author Mathias Göbel + : @since 3.1.0 + : @see https://docs.gitlab.com/ee/user/project/pipelines/settings.html#test-coverage-parsing + : :) +declare function local:format-test-rate-output($value as xs:decimal) +as xs:string { + "coverage: " || ($value * 100) => format-number("###.00") || "%" +}; + +(:~ + : Returns the relative amount of tests for all function in this package + : @param $tests – a set of unit test results in the JUnit XML format + : + : @author Mathias Göbel + : @since 3.1.0 + : @see https://www.ibm.com/support/knowledgecenter/en/SSQ2R2_14.1.0/com.ibm.rsar.analysis.codereview.cobol.doc/topics/cac_useresults_junit.html + : :) +declare function local:test-function-rate($tests as element(testsuites)*) +as xs:string { + (: is function cardinality an issue? thats why disstinct-value is used :) + let $functionNames := (local:get-function-names()) => distinct-values() => count() + let $testedFunctionNames := ($tests//testcase/string(@class)) => distinct-values() => count() + let $coverage := + if($testedFunctionNames = 0) then 0 else $testedFunctionNames div $functionNames + return + local:format-test-rate-output($coverage) +}; + +(:~ + : Returns the relative amount of successfull tests + : @param $tests – a set of unit test results in the JUnit XML format + : + : @author Mathias Göbel + : @since 3.1.0 + : @see https://www.ibm.com/support/knowledgecenter/en/SSQ2R2_14.1.0/com.ibm.rsar.analysis.codereview.cobol.doc/topics/cac_useresults_junit.html + : :) +declare function local:test-success-rate($tests as element(testsuites)*) as xs:string { let $allFailures := $tests//testsuite/@failures => sum() let $failsTriggered := $tests//testcase[@name=("FAIL", "fail")] => count() @@ -17,9 +74,9 @@ as xs:string { let $testsDone := $tests//testsuite/@tests => sum() - let $testCoverage := ($testsDone - sum( ($failures, $errors, $pending) )) div $testsDone * 100 + let $testCoverage := ($testsDone - sum( ($failures, $errors, $pending) )) div $testsDone return - "test coverage: " || format-number($testCoverage, "###.00") || "%" + local:format-test-rate-output($coverage) }; @@ -75,7 +132,7 @@ return let $tests := util:eval(xs:anyURI('test.xq')) let $print := util:log-system-out( $tests ) - let $print := util:log-system-out( local:test-coverage($tests) ) + let $print := util:log-system-out( local:test-function-rate($tests) ) let $file-name := system:get-exist-home()||util:system-property('file.separator')||".."||util:system-property('file.separator')||"tests-sade_job-"||string($jobId)||".log.xml" let $file := file:serialize({ $tests }, $file-name, ()) return diff --git a/templates/index.html b/templates/index.html index 30b3070..a4fb52e 100644 --- a/templates/index.html +++ b/templates/index.html @@ -13,7 +13,7 @@

- SADE + SADE

TEI Publishing powered by TextGrid
made with -- GitLab From 9bfb306dd196f185155eb6f326c8d5cbfc55896d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20G=C3=B6bel?= Date: Thu, 6 Dec 2018 16:45:14 +0100 Subject: [PATCH 7/7] minor --- post-install.xq | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/post-install.xq b/post-install.xq index 207bcf4..98cb023 100644 --- a/post-install.xq +++ b/post-install.xq @@ -17,7 +17,7 @@ declare variable $target external; declare function local:get-function-names() as xs:string* { for $modulePath in collection($target)/base-uri()[ends-with(., ".xqm")] -let $function := inspect:module-functions( xs:anyURI($modulePath) ) (: QNames :) +let $functions := inspect:module-functions( xs:anyURI($modulePath) ) (: QNames :) return for $function in $functions let $functionQName := function-name($function) -- GitLab