diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a22462e952139ac3d484484cbaef350a2eaa4ef6..954af8a95406d3e307a9445de4e9f45ac34d5513 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -42,9 +42,10 @@ installation:
artifacts:
paths:
- output.log
+ - test/tests-*.xml
- test/eXist-db-*/webapp/WEB-INF/logs/expath-repo.log
reports:
- junit: tests-*.xml
+ junit: test/tests-*.xml
upload:
only:
diff --git a/README.md b/README.md
index ed9ebbd704000a1dc76c7d2c910ea9e8262919ce..3e0a9c4d1aeb4a8c4b1289174d4fa2070a619f5a 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 bb19300387423a23ddc9614631a236cd00be7c9f..98cb02365126d4762262f18e84b3eb33de916afe 100644
--- a/post-install.xq
+++ b/post-install.xq
@@ -7,6 +7,80 @@ declare namespace xconf="http://exist-db.org/collection-config/1.0";
(: the target collection into which the app is deployed :)
declare variable $target external;
+(:~
+ : 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 $functions := 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()
+ let $failures := $allFailures - $failsTriggered
+ let $errors := $tests//testsuite/@errors => sum()
+ let $pending := $tests//testsuite/@pending => sum()
+
+ let $testsDone := $tests//testsuite/@tests => sum()
+
+ let $testCoverage := ($testsDone - sum( ($failures, $errors, $pending) )) div $testsDone
+ return
+ local:format-test-rate-output($coverage)
+};
+
+
+
let $project-name := tokenize($target, "/")[last()]
let $log := util:log-system-out("installing " || $project-name)
@@ -55,24 +129,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[38;2;0;0;0m " ||
"This is JOB #" || string($jobId) || "." || " [0m" )
return
-(
- if ($jobId gt 0)
- then
- (
- let $tests := util:eval(xs:anyURI('test.xq'))
- let $print := util:log-system-out( $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(
TEI Publishing powered by TextGrid
made with