From 13f299b2c98cce0ede3a8a37dd11832fdb3827bb Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Sat, 16 Jan 2021 14:54:27 -0500 Subject: build: test-driver.scm: Make output redirection optional. This makes it easier (and less surprising) for users to experiment with the custom Scheme test driver directly. The behavior is unchanged from Automake's point of view. * build-aux/test-driver.scm (main): Make the --log-file and --trs-file arguments optional and update doc. Only open, redirect and close a port to a log file when the --log-file option is provided. Only open and close a port to a trs file when the --trs-file option is provided. (test-runner-gnu): Set OUT-PORT parameter default value to the current output port. Set the TRS-PORT parameter default value to a void port. Update doc. --- build-aux/test-driver.scm | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'build-aux/test-driver.scm') diff --git a/build-aux/test-driver.scm b/build-aux/test-driver.scm index 52af1e9be7..eee3f1e08c 100644 --- a/build-aux/test-driver.scm +++ b/build-aux/test-driver.scm @@ -1,8 +1,9 @@ ;;;; test-driver.scm - Guile test driver for Automake testsuite harness -(define script-version "2017-03-22.13") ;UTC +(define script-version "2021-01-26.20") ;UTC ;;; Copyright © 2015, 2016 Mathieu Lirzin +;;; Copyright © 2021 Maxim Cournoyer ;;; ;;; This program is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by @@ -35,7 +36,7 @@ [--expect-failure={yes|no}] [--color-tests={yes|no}] [--enable-hard-errors={yes|no}] [--brief={yes|no}}] [--] TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] -The '--test-name', '--log-file' and '--trs-file' options are mandatory.\n")) +The '--test-name' option is mandatory.\n")) (define %options '((test-name (value #t)) @@ -75,11 +76,14 @@ The '--test-name', '--log-file' and '--trs-file' options are mandatory.\n")) "") ;no color result))) -(define* (test-runner-gnu test-name #:key color? brief? out-port trs-port) +(define* (test-runner-gnu test-name #:key color? brief? + (out-port (current-output-port)) + (trs-port (%make-void-port "w"))) "Return an custom SRFI-64 test runner. TEST-NAME is a string specifying the file name of the current the test. COLOR? specifies whether to use colors, -and BRIEF?, well, you know. OUT-PORT and TRS-PORT must be output ports. The -current output port is supposed to be redirected to a '.log' file." +and BRIEF?, well, you know. OUT-PORT and TRS-PORT must be output ports. +OUT-PORT defaults to the current output port, while TRS-PORT defaults to a +void port, which means no TRS output is logged." (define (test-on-test-begin-gnu runner) ;; Procedure called at the start of an individual test case, before the @@ -156,20 +160,22 @@ current output port is supposed to be redirected to a '.log' file." ((option 'help #f) (show-help)) ((option 'version #f) (format #t "test-driver.scm ~A" script-version)) (else - (let ((log (open-file (option 'log-file "") "w0")) - (trs (open-file (option 'trs-file "") "wl")) - (out (duplicate-port (current-output-port) "wl"))) - (redirect-port log (current-output-port)) - (redirect-port log (current-warning-port)) - (redirect-port log (current-error-port)) + (let ((log (and=> (option 'log-file #f) (cut open-file <> "w0"))) + (trs (and=> (option 'trs-file #f) (cut open-file <> "wl"))) + (out (duplicate-port (current-output-port) "wl")) + (test-name (option 'test-name #f))) + (when log + (redirect-port log (current-output-port)) + (redirect-port log (current-warning-port)) + (redirect-port log (current-error-port))) (test-with-runner - (test-runner-gnu (option 'test-name #f) + (test-runner-gnu test-name #:color? (option->boolean opts 'color-tests) #:brief? (option->boolean opts 'brief) #:out-port out #:trs-port trs) - (load-from-path (option 'test-name #f))) - (close-port log) - (close-port trs) + (load-from-path test-name)) + (and=> log close-port) + (and=> trs close-port) (close-port out)))) (exit 0))) -- cgit v1.2.3 From 346210b1b2130112dd5f894c1d40afb37c1c51a5 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Sat, 16 Jan 2021 22:32:20 -0500 Subject: build: test-driver.scm: Enable colored test results by default. The Automake parallel test harness does its own smart detection of the terminal color capability and always provides the --color-tests argument to the driver. This change defaults the --color-tests argument to true when the test driver is run on its own (not via Automake). * build-aux/test-driver.scm (main): Set the default value of the --color-tests argument to true when it's not explicitly provided. --- build-aux/test-driver.scm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'build-aux/test-driver.scm') diff --git a/build-aux/test-driver.scm b/build-aux/test-driver.scm index eee3f1e08c..fe7e9c8807 100644 --- a/build-aux/test-driver.scm +++ b/build-aux/test-driver.scm @@ -163,14 +163,17 @@ void port, which means no TRS output is logged." (let ((log (and=> (option 'log-file #f) (cut open-file <> "w0"))) (trs (and=> (option 'trs-file #f) (cut open-file <> "wl"))) (out (duplicate-port (current-output-port) "wl")) - (test-name (option 'test-name #f))) + (test-name (option 'test-name #f)) + (color-tests (if (assoc 'color-tests opts) + (option->boolean opts 'color-tests) + #t))) (when log (redirect-port log (current-output-port)) (redirect-port log (current-warning-port)) (redirect-port log (current-error-port))) (test-with-runner (test-runner-gnu test-name - #:color? (option->boolean opts 'color-tests) + #:color? color-tests #:brief? (option->boolean opts 'brief) #:out-port out #:trs-port trs) (load-from-path test-name)) -- cgit v1.2.3 From a1ea2acb376c8a74f41ce0e683680417207b365a Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Sun, 17 Jan 2021 09:03:07 -0500 Subject: build: test-driver.scm: Add test cases filtering options. * build-aux/test-driver.scm (show-help): Add help text for the new --select and --exclude options. (%options): Add the new select and exclude options. (test-runner-gnu): Pass them to the test runner. Update doc. (test-match-name*, test-match-name*/negated, %test-match-all): New variables. (main): Compute the test specifier based on the values of the new options and apply it to the current test runner when running the test file. * doc/guix.texi (Running the Test Suite): Document the new options. --- build-aux/test-driver.scm | 74 ++++++++++++++++++++++++++++++++++++++++------- doc/guix.texi | 12 ++++++++ 2 files changed, 75 insertions(+), 11 deletions(-) (limited to 'build-aux/test-driver.scm') diff --git a/build-aux/test-driver.scm b/build-aux/test-driver.scm index fe7e9c8807..2a5362a9fb 100644 --- a/build-aux/test-driver.scm +++ b/build-aux/test-driver.scm @@ -27,6 +27,8 @@ (use-modules (ice-9 getopt-long) (ice-9 pretty-print) + (ice-9 regex) + (srfi srfi-1) (srfi srfi-26) (srfi srfi-64)) @@ -34,14 +36,19 @@ (display "Usage: test-driver --test-name=NAME --log-file=PATH --trs-file=PATH [--expect-failure={yes|no}] [--color-tests={yes|no}] + [--select=REGEXP] [--exclude=REGEXP] [--enable-hard-errors={yes|no}] [--brief={yes|no}}] [--] TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] -The '--test-name' option is mandatory.\n")) +The '--test-name' option is mandatory. The '--select' and '--exclude' options +allow selecting or excluding individual test cases via a regexp, +respectively.\n")) (define %options '((test-name (value #t)) (log-file (value #t)) (trs-file (value #t)) + (select (value #t)) + (exclude (value #t)) (color-tests (value #t)) (expect-failure (value #t)) ;XXX: not implemented yet (enable-hard-errors (value #t)) ;not implemented in SRFI-64 @@ -76,14 +83,22 @@ The '--test-name' option is mandatory.\n")) "") ;no color result))) + +;;; +;;; SRFI 64 custom test runner. +;;; + (define* (test-runner-gnu test-name #:key color? brief? (out-port (current-output-port)) - (trs-port (%make-void-port "w"))) + (trs-port (%make-void-port "w")) + select exclude) "Return an custom SRFI-64 test runner. TEST-NAME is a string specifying the file name of the current the test. COLOR? specifies whether to use colors, and BRIEF?, well, you know. OUT-PORT and TRS-PORT must be output ports. OUT-PORT defaults to the current output port, while TRS-PORT defaults to a -void port, which means no TRS output is logged." +void port, which means no TRS output is logged. SELECT and EXCLUDE may take a +regular expression to select or exclude individual test cases based on their +names." (define (test-on-test-begin-gnu runner) ;; Procedure called at the start of an individual test case, before the @@ -148,6 +163,34 @@ void port, which means no TRS output is logged." (test-runner-on-bad-end-name! runner test-on-bad-end-name-simple) runner)) + +;;; +;;; SRFI 64 test specifiers. +;;; +(define (test-match-name* regexp) + "Return a test specifier that matches a test name against REGEXP." + (lambda (runner) + (string-match regexp (test-runner-test-name runner)))) + +(define (test-match-name*/negated regexp) + "Return a negated test specifier version of test-match-name*." + (lambda (runner) + (not (string-match regexp (test-runner-test-name runner))))) + +;;; XXX: test-match-all is a syntax, which isn't convenient to use with a list +;;; of test specifiers computed at run time. Copy this SRFI 64 internal +;;; definition here, which is the procedural equivalent of 'test-match-all'. +(define (%test-match-all . pred-list) + (lambda (runner) + (let ((result #t)) + (let loop ((l pred-list)) + (if (null? l) + result + (begin + (if (not ((car l) runner)) + (set! result #f)) + (loop (cdr l)))))))) + ;;; ;;; Entry point. @@ -160,13 +203,20 @@ void port, which means no TRS output is logged." ((option 'help #f) (show-help)) ((option 'version #f) (format #t "test-driver.scm ~A" script-version)) (else - (let ((log (and=> (option 'log-file #f) (cut open-file <> "w0"))) - (trs (and=> (option 'trs-file #f) (cut open-file <> "wl"))) - (out (duplicate-port (current-output-port) "wl")) - (test-name (option 'test-name #f)) - (color-tests (if (assoc 'color-tests opts) - (option->boolean opts 'color-tests) - #t))) + (let* ((log (and=> (option 'log-file #f) (cut open-file <> "w0"))) + (trs (and=> (option 'trs-file #f) (cut open-file <> "wl"))) + (out (duplicate-port (current-output-port) "wl")) + (test-name (option 'test-name #f)) + (select (option 'select #f)) + (exclude (option 'exclude #f)) + (test-specifiers (filter-map + identity + (list (and=> select test-match-name*) + (and=> exclude test-match-name*/negated)))) + (test-specifier (apply %test-match-all test-specifiers)) + (color-tests (if (assoc 'color-tests opts) + (option->boolean opts 'color-tests) + #t))) (when log (redirect-port log (current-output-port)) (redirect-port log (current-warning-port)) @@ -176,7 +226,9 @@ void port, which means no TRS output is logged." #:color? color-tests #:brief? (option->boolean opts 'brief) #:out-port out #:trs-port trs) - (load-from-path test-name)) + (test-apply test-specifier + (lambda _ + (load-from-path test-name)))) (and=> log close-port) (and=> trs close-port) (close-port out)))) diff --git a/doc/guix.texi b/doc/guix.texi index aca4657d6a..b58fdad282 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -921,6 +921,18 @@ the @code{SCM_LOG_DRIVER_FLAGS} makefile variable as in this example: make check TESTS="tests/base64.scm" SCM_LOG_DRIVER_FLAGS="--brief=no" @end example +The underlying SRFI 64 custom Automake test driver used for the 'check' +test suite (located at @file{build-aux/test-driver.scm}) also allows +selecting which test cases to run at a finer level, via its +@option{--select} and @option{--exclude} options. Here's an example, to +run all the test cases from the @file{tests/packages.scm} test file +whose names start with ``transaction-upgrade-entry'': + +@example +export SCM_LOG_DRIVER_FLAGS="--select=^transaction-upgrade-entry" +make check TESTS="tests/packages.scm" +@end example + Upon failure, please email @email{bug-guix@@gnu.org} and attach the @file{test-suite.log} file. Please specify the Guix version being used as well as version numbers of the dependencies (@pxref{Requirements}) in -- cgit v1.2.3 From 93a628c4e4f4a7f6665190f3c52a417daebaf28a Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Mon, 18 Jan 2021 00:19:06 -0500 Subject: build: test-driver.scm: Add a new '--errors-only' option. * build-aux/test-driver.scm (show-help): Add the help text for the new '--errors-only' option. (%options): Add the errors-only option. (test-runner-gnu): Add the errors-only? parameter and update doc. Move the logging of the test data after the test has completed, so a choice can be made whether to keep it or discard it based on the value of the test result. (main): Pass the errors-only? option to the driver. * doc/guix.texi (Running the Test Suite): Document the new option. --- build-aux/test-driver.scm | 75 +++++++++++++++++++++++++++-------------------- doc/guix.texi | 12 ++++++++ 2 files changed, 55 insertions(+), 32 deletions(-) (limited to 'build-aux/test-driver.scm') diff --git a/build-aux/test-driver.scm b/build-aux/test-driver.scm index 2a5362a9fb..763ba457d8 100644 --- a/build-aux/test-driver.scm +++ b/build-aux/test-driver.scm @@ -36,12 +36,15 @@ (display "Usage: test-driver --test-name=NAME --log-file=PATH --trs-file=PATH [--expect-failure={yes|no}] [--color-tests={yes|no}] - [--select=REGEXP] [--exclude=REGEXP] + [--select=REGEXP] [--exclude=REGEXP] [--errors-only={yes|no}] [--enable-hard-errors={yes|no}] [--brief={yes|no}}] [--] TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] The '--test-name' option is mandatory. The '--select' and '--exclude' options -allow selecting or excluding individual test cases via a regexp, -respectively.\n")) +allow selecting or excluding individual test cases via a regexp, respectively. +The '--errors-only' option can be set to \"yes\" to limit the logged test case +metadata to only those test cases that failed. When set to \"yes\", the +'--brief' option disables printing the individual test case result to the +console.\n")) (define %options '((test-name (value #t)) @@ -49,6 +52,7 @@ respectively.\n")) (trs-file (value #t)) (select (value #t)) (exclude (value #t)) + (errors-only (value #t)) (color-tests (value #t)) (expect-failure (value #t)) ;XXX: not implemented yet (enable-hard-errors (value #t)) ;not implemented in SRFI-64 @@ -88,27 +92,26 @@ respectively.\n")) ;;; SRFI 64 custom test runner. ;;; -(define* (test-runner-gnu test-name #:key color? brief? +(define* (test-runner-gnu test-name #:key color? brief? errors-only? (out-port (current-output-port)) (trs-port (%make-void-port "w")) select exclude) "Return an custom SRFI-64 test runner. TEST-NAME is a string specifying the -file name of the current the test. COLOR? specifies whether to use colors, -and BRIEF?, well, you know. OUT-PORT and TRS-PORT must be output ports. -OUT-PORT defaults to the current output port, while TRS-PORT defaults to a -void port, which means no TRS output is logged. SELECT and EXCLUDE may take a -regular expression to select or exclude individual test cases based on their -names." - - (define (test-on-test-begin-gnu runner) - ;; Procedure called at the start of an individual test case, before the - ;; test expression (and expected value) are evaluated. - (let ((result (cute assq-ref (test-result-alist runner) <>))) - (format #t "test-name: ~A~%" (result 'test-name)) - (format #t "location: ~A~%" - (string-append (result 'source-file) ":" - (number->string (result 'source-line)))) - (test-display "source" (result 'source-form) #:pretty? #t))) +file name of the current the test. COLOR? specifies whether to use colors. +When BRIEF? is true, the individual test cases results are masked and only the +summary is shown. ERRORS-ONLY? reduces the amount of test case metadata +logged to only that of the failed test cases. OUT-PORT and TRS-PORT must be +output ports. OUT-PORT defaults to the current output port, while TRS-PORT +defaults to a void port, which means no TRS output is logged. SELECT and +EXCLUDE may take a regular expression to select or exclude individual test +cases based on their names." + + (define (test-skipped? runner) + (eq? 'skip (test-result-kind runner))) + + (define (test-failed? runner) + (not (or (test-passed? runner) + (test-skipped? runner)))) (define (test-on-test-end-gnu runner) ;; Procedure called at the end of an individual test case, when the result @@ -116,21 +119,29 @@ names." (let* ((results (test-result-alist runner)) (result? (cut assq <> results)) (result (cut assq-ref results <>))) - (unless brief? + (unless (or brief? (and errors-only? (test-skipped? runner))) ;; Display the result of each test case on the console. (format out-port "~A: ~A - ~A~%" (result->string (test-result-kind runner) #:colorize? color?) test-name (test-runner-test-name runner))) - (when (result? 'expected-value) - (test-display "expected-value" (result 'expected-value))) - (when (result? 'expected-error) - (test-display "expected-error" (result 'expected-error) #:pretty? #t)) - (when (result? 'actual-value) - (test-display "actual-value" (result 'actual-value))) - (when (result? 'actual-error) - (test-display "actual-error" (result 'actual-error) #:pretty? #t)) - (format #t "result: ~a~%" (result->string (result 'result-kind))) - (newline) + + (unless (and errors-only? (not (test-failed? runner))) + (format #t "test-name: ~A~%" (result 'test-name)) + (format #t "location: ~A~%" + (string-append (result 'source-file) ":" + (number->string (result 'source-line)))) + (test-display "source" (result 'source-form) #:pretty? #t) + (when (result? 'expected-value) + (test-display "expected-value" (result 'expected-value))) + (when (result? 'expected-error) + (test-display "expected-error" (result 'expected-error) #:pretty? #t)) + (when (result? 'actual-value) + (test-display "actual-value" (result 'actual-value))) + (when (result? 'actual-error) + (test-display "actual-error" (result 'actual-error) #:pretty? #t)) + (format #t "result: ~a~%" (result->string (result 'result-kind))) + (newline)) + (format trs-port ":test-result: ~A ~A~%" (result->string (test-result-kind runner)) (test-runner-test-name runner)))) @@ -157,7 +168,6 @@ names." #f)) (let ((runner (test-runner-null))) - (test-runner-on-test-begin! runner test-on-test-begin-gnu) (test-runner-on-test-end! runner test-on-test-end-gnu) (test-runner-on-group-end! runner test-on-group-end-gnu) (test-runner-on-bad-end-name! runner test-on-bad-end-name-simple) @@ -225,6 +235,7 @@ names." (test-runner-gnu test-name #:color? color-tests #:brief? (option->boolean opts 'brief) + #:errors-only? (option->boolean opts 'errors-only) #:out-port out #:trs-port trs) (test-apply test-specifier (lambda _ diff --git a/doc/guix.texi b/doc/guix.texi index b58fdad282..7393cc8ecd 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -933,6 +933,18 @@ export SCM_LOG_DRIVER_FLAGS="--select=^transaction-upgrade-entry" make check TESTS="tests/packages.scm" @end example +Those wishing to inspect the results of failed tests directly from the +command line can add the @option{--errors-only=yes} option to the +@code{SCM_LOG_DRIVER_FLAGS} makefile variable and set the @code{VERBOSE} +Automake makefile variable, as in: + +@example +make check SCM_LOG_DRIVER_FLAGS="--brief=no --errors-only=yes" VERBOSE=1 +@end example + +@xref{Parallel Test Harness,,,automake,GNU Automake} for more +information about the Automake Parallel Test Harness. + Upon failure, please email @email{bug-guix@@gnu.org} and attach the @file{test-suite.log} file. Please specify the Guix version being used as well as version numbers of the dependencies (@pxref{Requirements}) in -- cgit v1.2.3 From 26a66d0feaab7626c4053071d5557394931fe14b Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Sat, 16 Jan 2021 22:30:33 -0500 Subject: build: test-driver.scm: Allow running as a standalone script. * build-aux/test-driver.scm: Add an exec-based shebang and set the script executable bit. (main): Insert a newline after the version string is printed with --version. --- build-aux/test-driver.scm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) mode change 100644 => 100755 build-aux/test-driver.scm (limited to 'build-aux/test-driver.scm') diff --git a/build-aux/test-driver.scm b/build-aux/test-driver.scm old mode 100644 new mode 100755 index 763ba457d8..ac21783d41 --- a/build-aux/test-driver.scm +++ b/build-aux/test-driver.scm @@ -1,3 +1,6 @@ +#!/bin/sh +exec guile --no-auto-compile -e main -s "$0" "$@" +!# ;;;; test-driver.scm - Guile test driver for Automake testsuite harness (define script-version "2021-01-26.20") ;UTC @@ -211,7 +214,7 @@ cases based on their names." (option (cut option-ref opts <> <>))) (cond ((option 'help #f) (show-help)) - ((option 'version #f) (format #t "test-driver.scm ~A" script-version)) + ((option 'version #f) (format #t "test-driver.scm ~A~%" script-version)) (else (let* ((log (and=> (option 'log-file #f) (cut open-file <> "w0"))) (trs (and=> (option 'trs-file #f) (cut open-file <> "wl"))) -- cgit v1.2.3 From 5e652e94a9203e0cfa27e93a89878439b7900001 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 2 Feb 2021 00:28:49 -0500 Subject: build: Add a --show-duration option to the SCM test-driver. * build-aux/test-driver.scm (script-version): Update. (show-help): Document it. (%options): Add the 'show-duration' option. (test-runner-gnu): Pass as a new argument. [test-cases-start-time]: New inner variable. [test-on-test-begin-gnu]: New hook, used to record the start time. [test-on-test-end-gnu]: Conditionally print elapsed time. Record it as the optional metadata in the test result file (.trs). * doc/guix.texi (Running the Test Suite): Document it. --- build-aux/test-driver.scm | 43 ++++++++++++++++++++++++++++++++++--------- doc/guix.texi | 10 +++++++++- 2 files changed, 43 insertions(+), 10 deletions(-) (limited to 'build-aux/test-driver.scm') diff --git a/build-aux/test-driver.scm b/build-aux/test-driver.scm index ac21783d41..1cdd4ff8f7 100755 --- a/build-aux/test-driver.scm +++ b/build-aux/test-driver.scm @@ -3,7 +3,7 @@ exec guile --no-auto-compile -e main -s "$0" "$@" !# ;;;; test-driver.scm - Guile test driver for Automake testsuite harness -(define script-version "2021-01-26.20") ;UTC +(define script-version "2021-02-02.05") ;UTC ;;; Copyright © 2015, 2016 Mathieu Lirzin ;;; Copyright © 2021 Maxim Cournoyer @@ -28,10 +28,12 @@ exec guile --no-auto-compile -e main -s "$0" "$@" ;;; ;;;; Code: -(use-modules (ice-9 getopt-long) +(use-modules (ice-9 format) + (ice-9 getopt-long) (ice-9 pretty-print) (ice-9 regex) (srfi srfi-1) + (srfi srfi-19) (srfi srfi-26) (srfi srfi-64)) @@ -40,14 +42,16 @@ exec guile --no-auto-compile -e main -s "$0" "$@" test-driver --test-name=NAME --log-file=PATH --trs-file=PATH [--expect-failure={yes|no}] [--color-tests={yes|no}] [--select=REGEXP] [--exclude=REGEXP] [--errors-only={yes|no}] - [--enable-hard-errors={yes|no}] [--brief={yes|no}}] [--] + [--enable-hard-errors={yes|no}] [--brief={yes|no}}] + [--show-duration={yes|no}] [--] TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] The '--test-name' option is mandatory. The '--select' and '--exclude' options allow selecting or excluding individual test cases via a regexp, respectively. The '--errors-only' option can be set to \"yes\" to limit the logged test case metadata to only those test cases that failed. When set to \"yes\", the '--brief' option disables printing the individual test case result to the -console.\n")) +console. When '--show-duration' is set to \"yes\", the time elapsed per test +case is shown.\n")) (define %options '((test-name (value #t)) @@ -60,6 +64,7 @@ console.\n")) (expect-failure (value #t)) ;XXX: not implemented yet (enable-hard-errors (value #t)) ;not implemented in SRFI-64 (brief (value #t)) + (show-duration (value #t)) (help (single-char #\h) (value #f)) (version (single-char #\V) (value #f)))) @@ -96,6 +101,7 @@ console.\n")) ;;; (define* (test-runner-gnu test-name #:key color? brief? errors-only? + show-duration? (out-port (current-output-port)) (trs-port (%make-void-port "w")) select exclude) @@ -109,6 +115,15 @@ defaults to a void port, which means no TRS output is logged. SELECT and EXCLUDE may take a regular expression to select or exclude individual test cases based on their names." + (define test-cases-start-time (make-hash-table)) + + (define (test-on-test-begin-gnu runner) + ;; Procedure called at the start of an individual test case, before the + ;; test expression (and expected value) are evaluated. + (let ((test-case-name (test-runner-test-name runner)) + (start-time (current-time time-monotonic))) + (hash-set! test-cases-start-time test-case-name start-time))) + (define (test-skipped? runner) (eq? 'skip (test-result-kind runner))) @@ -121,12 +136,19 @@ cases based on their names." ;; of the test is available. (let* ((results (test-result-alist runner)) (result? (cut assq <> results)) - (result (cut assq-ref results <>))) + (result (cut assq-ref results <>)) + (test-case-name (test-runner-test-name runner)) + (start (hash-ref test-cases-start-time test-case-name)) + (end (current-time time-monotonic)) + (time-elapsed (time-difference end start)) + (time-elapsed-seconds (+ (time-second time-elapsed) + (* 1e-9 (time-nanosecond time-elapsed))))) (unless (or brief? (and errors-only? (test-skipped? runner))) ;; Display the result of each test case on the console. - (format out-port "~A: ~A - ~A~%" + (format out-port "~a: ~a - ~a ~@[[~,3fs]~]~%" (result->string (test-result-kind runner) #:colorize? color?) - test-name (test-runner-test-name runner))) + test-name test-case-name + (and show-duration? time-elapsed-seconds))) (unless (and errors-only? (not (test-failed? runner))) (format #t "test-name: ~A~%" (result 'test-name)) @@ -145,9 +167,9 @@ cases based on their names." (format #t "result: ~a~%" (result->string (result 'result-kind))) (newline)) - (format trs-port ":test-result: ~A ~A~%" + (format trs-port ":test-result: ~A ~A [~,3fs]~%" (result->string (test-result-kind runner)) - (test-runner-test-name runner)))) + (test-runner-test-name runner) time-elapsed-seconds))) (define (test-on-group-end-gnu runner) ;; Procedure called by a 'test-end', including at the end of a test-group. @@ -171,6 +193,7 @@ cases based on their names." #f)) (let ((runner (test-runner-null))) + (test-runner-on-test-begin! runner test-on-test-begin-gnu) (test-runner-on-test-end! runner test-on-test-end-gnu) (test-runner-on-group-end! runner test-on-group-end-gnu) (test-runner-on-bad-end-name! runner test-on-bad-end-name-simple) @@ -239,6 +262,8 @@ cases based on their names." #:color? color-tests #:brief? (option->boolean opts 'brief) #:errors-only? (option->boolean opts 'errors-only) + #:show-duration? (option->boolean + opts 'show-duration) #:out-port out #:trs-port trs) (test-apply test-specifier (lambda _ diff --git a/doc/guix.texi b/doc/guix.texi index beff276f9d..598d3d6773 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -48,7 +48,7 @@ Copyright @copyright{} 2017 humanitiesNerd@* Copyright @copyright{} 2017 Christopher Allan Webber@* Copyright @copyright{} 2017, 2018, 2019, 2020 Marius Bakke@* Copyright @copyright{} 2017, 2019, 2020 Hartmut Goebel@* -Copyright @copyright{} 2017, 2019, 2020 Maxim Cournoyer@* +Copyright @copyright{} 2017, 2019, 2020, 2021 Maxim Cournoyer@* Copyright @copyright{} 2017, 2018, 2019, 2020 Tobias Geerinckx-Rice@* Copyright @copyright{} 2017 George Clemmer@* Copyright @copyright{} 2017 Andy Wingo@* @@ -942,6 +942,14 @@ Automake makefile variable, as in: make check SCM_LOG_DRIVER_FLAGS="--brief=no --errors-only=yes" VERBOSE=1 @end example +The @option{--show-duration=yes} option can be used to print the +duration of the individual test cases, when used in combination with +@option{--brief=no}: + +@example +make check SCM_LOG_DRIVER_FLAGS="--brief=no --show-duration=yes" +@end example + @xref{Parallel Test Harness,,,automake,GNU Automake} for more information about the Automake Parallel Test Harness. -- cgit v1.2.3