all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#62406: “! failing-command” pattern in shell tests is wrong
@ 2023-03-23 16:00 Ludovic Courtès
  2023-03-23 18:53 ` Eric Bavier
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Ludovic Courtès @ 2023-03-23 16:00 UTC (permalink / raw)
  To: 62406; +Cc: Eric Bavier

In <https://issues.guix.gnu.org/43616> (commit
d8934360d2453a403b5433e71d09188e4ed23b57), we changed:

  if command that should fail; then false; else true; fi

to:

  ! command that should fail

I had reservations back then, and now I know why: :-)

--8<---------------cut here---------------start------------->8---
$ bash -xe -c '! true; true'
+ true
+ true
$ echo $?
0
$ bash -xe -c '! false; true'
+ false
+ true
$ echo $?
0
--8<---------------cut here---------------end--------------->8---

Whether or not the command following the exclamation mark succeeds, the
statement succeeds.  Bummer.

The Bash manual (info "(bash) Pipelines") reads:

  If the reserved word '!' precedes the pipeline, the exit status is the
  logical negation of the exit status as described above.  The shell
  waits for all commands in the pipeline to terminate before returning a
  value.

To me, that means it should work as we thought, but it’s a fact that it
doesn’t.

Thoughts?

Ludo’.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#62406: “! failing-command” pattern in shell tests is wrong
  2023-03-23 16:00 bug#62406: “! failing-command” pattern in shell tests is wrong Ludovic Courtès
@ 2023-03-23 18:53 ` Eric Bavier
  2023-03-28 16:21   ` Ludovic Courtès
  2023-03-26 18:16 ` Martin Castillo
  2023-03-26 18:21 ` Martin Castillo
  2 siblings, 1 reply; 6+ messages in thread
From: Eric Bavier @ 2023-03-23 18:53 UTC (permalink / raw)
  To: Ludovic Courtès, 62406

[-- Attachment #1: Type: text/plain, Size: 1663 bytes --]

On Thu, 2023-03-23 at 17:00 +0100, Ludovic Courtès wrote:
> In <https://issues.guix.gnu.org/43616> (commit
> d8934360d2453a403b5433e71d09188e4ed23b57), we changed:
> 
>   if command that should fail; then false; else true; fi
> 
> to:
> 
>   ! command that should fail
> 
> I had reservations back then, and now I know why: :-)
> 
> --8<---------------cut here---------------start------------->8---
> $ bash -xe -c '! true; true'
> + true
> + true
> $ echo $?
> 0
> $ bash -xe -c '! false; true'
> + false
> + true
> $ echo $?
> 0
> --8<---------------cut here---------------end--------------->8---
> 
> Whether or not the command following the exclamation mark succeeds, the
> statement succeeds.  Bummer.

I think it's maybe not that the statement succeeds regardless.  But that 'set
-e' doesn't consider it a "failure".  From "The Set Builtin":

    '-e'
          Exit immediately if a pipeline (*note Pipelines::)... returns a
          non-zero status.  The shell does not exit if the command that
          fails is ..., or if the command's return status is being
          inverted with '!'.

So in each of your examples, execution continues to the second 'true'
statement and the overall exit status is 0.  This is not the behavior we want
in our tests.

The purpose of d89343 was to ease visual parsing of the tests.  I mentioned
having used the '!' syntax in my own shell tests, but I realize now that I
was not relying on `set -e` like guix is.

I'll consider a few options.  Do we have a known issue where this is causing
a test to not to catch a failure?

Thanks for bringing this up,
`~Eric




[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 858 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#62406: “! failing-command” pattern in shell tests is wrong
  2023-03-23 16:00 bug#62406: “! failing-command” pattern in shell tests is wrong Ludovic Courtès
  2023-03-23 18:53 ` Eric Bavier
@ 2023-03-26 18:16 ` Martin Castillo
  2023-03-26 18:21 ` Martin Castillo
  2 siblings, 0 replies; 6+ messages in thread
From: Martin Castillo @ 2023-03-26 18:16 UTC (permalink / raw)
  To: Ludovic Courtès, 62406; +Cc: Eric Bavier

Hi,

Am 23.03.23 um 17:00 schrieb Ludovic Courtès:> In 
<https://issues.guix.gnu.org/43616> (commit
 > d8934360d2453a403b5433e71d09188e4ed23b57), we changed:
 >
 >    if command that should fail; then false; else true; fi
 >
 > to:
 >
 >    ! command that should fail
 >
 > I had reservations back then, and now I know why: :-)
 >
 > --8<---------------cut here---------------start------------->8---
 > $ bash -xe -c '! true; true'
 > + true
 > + true
 > $ echo $?
 > 0
 > $ bash -xe -c '! false; true'
 > + false
 > + true
 > $ echo $?
 > 0
 > --8<---------------cut here---------------end--------------->8---
 >
 > Whether or not the command following the exclamation mark succeeds, the
 > statement succeeds.  Bummer.
 >
 > The Bash manual (info "(bash) Pipelines") reads:
 >
 >    If the reserved word '!' precedes the pipeline, the exit status is the
 >    logical negation of the exit status as described above.  The shell
 >    waits for all commands in the pipeline to terminate before returning a
 >    value.
 >
 > To me, that means it should work as we thought, but it’s a fact that it
 > doesn’t.
the documentation on `-e` says:

-e      Exit  immediately  if a pipeline (which may consist of a
         single simple command), a list, or  a  compound  command
         (see SHELL GRAMMAR above), exits with a non-zero status.
         The shell does not exit [...] if the
         command's return value is being inverted with !.

I have no idea what might be the rationale for that.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#62406: “! failing-command” pattern in shell tests is wrong
  2023-03-23 16:00 bug#62406: “! failing-command” pattern in shell tests is wrong Ludovic Courtès
  2023-03-23 18:53 ` Eric Bavier
  2023-03-26 18:16 ` Martin Castillo
@ 2023-03-26 18:21 ` Martin Castillo
  2 siblings, 0 replies; 6+ messages in thread
From: Martin Castillo @ 2023-03-26 18:21 UTC (permalink / raw)
  To: Ludovic Courtès, 62406; +Cc: Eric Bavier

Sorry for my answer. I overlooked that Eric already answered.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#62406: “! failing-command” pattern in shell tests is wrong
  2023-03-23 18:53 ` Eric Bavier
@ 2023-03-28 16:21   ` Ludovic Courtès
  2023-04-20  5:48     ` Eric Bavier
  0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2023-03-28 16:21 UTC (permalink / raw)
  To: Eric Bavier; +Cc: 62406

Hi Eric,

Eric Bavier <bavier@posteo.net> skribis:

> The purpose of d89343 was to ease visual parsing of the tests.  I mentioned
> having used the '!' syntax in my own shell tests, but I realize now that I
> was not relying on `set -e` like guix is.
>
> I'll consider a few options.

Neat.  I guess we could have a ‘lib.sh’ with an ‘expect_fail’ function
or something.

> Do we have a known issue where this is causing a test to not to catch
> a failure?

No; I noticed it while writing a new test that I expected to fail.

Thanks for your feedback!  Shell semantics are definitely weird.  :-)

Ludo’.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#62406: “! failing-command” pattern in shell tests is wrong
  2023-03-28 16:21   ` Ludovic Courtès
@ 2023-04-20  5:48     ` Eric Bavier
  0 siblings, 0 replies; 6+ messages in thread
From: Eric Bavier @ 2023-04-20  5:48 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 62406

[-- Attachment #1: Type: text/plain, Size: 1757 bytes --]

On Tue, 2023-03-28 at 18:21 +0200, Ludovic Courtès wrote:
> Hi Eric,
> 
> Eric Bavier <bavier@posteo.net> skribis:
> 
> > The purpose of d89343 was to ease visual parsing of the tests.  I mentioned
> > having used the '!' syntax in my own shell tests, but I realize now that I
> > was not relying on `set -e` like guix is.
> > 
> > I'll consider a few options.
> 
> Neat.  I guess we could have a ‘lib.sh’ with an ‘expect_fail’ function
> or something.
> 

Instead of a shared 'lib.sh', the attached patch uses 'cmd && false', which
has the desired semantics under 'set -e' and is no more verbose than a
wrapping function call.

If 'cmd' fails, the return status is ignored by 'set -e', which considers
only the return status of a command following the final '&&' or '||'.  And
because 'cmd' failed the statement short-circuits without executing the
'false.  Otherwise, if 'cmd' succeeds, the 'false' is executed and the shell
exits immediately.

In other places the '! test ...' pattern is replaced with 'test ! ...'.

There was some small amount of fall-out.  I fixed a couple issues where I
could:

  - tests/guix-archive.sh: added '--export' to command

  - tests/guix-style.sh: added an escape to a sed pattern

But a couple others have failures I'm not as confident in fixing myself:

  - tests/guix-refresh.sh: 'guix refresh' seems to not exit with a failure
status if a warning is issued, but the tests seem to think it should.

  - tests/guix-git-authenticate.sh: A general failure to authenticate a
particular commit.  This could be an issue with my test environment.

This patch should probably not be applied until those tests are fixed.  I
would appreciate any help with that.

`~Eric
> 

[-- Attachment #2: 0001-tests-Fix-checks-for-expected-failures.patch --]
[-- Type: text/x-patch, Size: 34490 bytes --]

From 625ec5da4179f0ea791d6cda2d452617cd1b96d8 Mon Sep 17 00:00:00 2001
From: Eric Bavier <bavier@posteo.net>
Date: Thu, 20 Apr 2023 00:11:27 -0500
Subject: [PATCH] tests: Fix checks for expected failures.

Addresses <https://issues.guix.gnu.org/62406>.

With 'set -e', a return status inverted with '!' does not cause the shell to
exit immediately.  Instead use '&& false' to indicate an expected failure.

* tests/guix-archive.sh, tests/guix-build-branch.sh, tests/guix-build.sh,
tests/guix-daemon.sh, tests/guix-download.sh,
tests/guix-environment-container.sh, tests/guix-environment.sh,
tests/guix-gc.sh, tests/guix-git-authenticate.sh, tests/guix-graph.sh,
tests/guix-hash.sh, tests/guix-home.sh, tests/guix-pack-relocatable.sh,
tests/guix-pack.sh, tests/guix-package-aliases.sh, tests/guix-package-net.sh,
tests/guix-package.sh, tests/guix-refresh.sh, tests/guix-shell.sh,
tests/guix-style.sh, tests/guix-system.sh: Replace uses of '! ...' with
'... && false' or `test ! ...` as appropriate.
---
 tests/guix-archive.sh               |  8 +++--
 tests/guix-build-branch.sh          |  4 ++-
 tests/guix-build.sh                 | 22 +++++++-------
 tests/guix-daemon.sh                |  2 +-
 tests/guix-download.sh              | 10 ++++---
 tests/guix-environment-container.sh |  7 ++---
 tests/guix-environment.sh           |  6 ++--
 tests/guix-gc.sh                    | 18 +++++------
 tests/guix-git-authenticate.sh      |  8 ++---
 tests/guix-graph.sh                 |  6 ++--
 tests/guix-hash.sh                  | 11 +++----
 tests/guix-home.sh                  | 14 ++++-----
 tests/guix-pack-relocatable.sh      |  2 +-
 tests/guix-pack.sh                  |  4 +--
 tests/guix-package-aliases.sh       | 12 ++++----
 tests/guix-package-net.sh           | 22 +++++++-------
 tests/guix-package.sh               | 46 ++++++++++++++---------------
 tests/guix-refresh.sh               |  6 ++--
 tests/guix-shell.sh                 | 10 +++----
 tests/guix-style.sh                 |  6 ++--
 tests/guix-system.sh                |  2 +-
 21 files changed, 117 insertions(+), 109 deletions(-)

diff --git a/tests/guix-archive.sh b/tests/guix-archive.sh
index 00b87ff0ac..0866b5a4d8 100644
--- a/tests/guix-archive.sh
+++ b/tests/guix-archive.sh
@@ -44,7 +44,7 @@ cmp "$archive" "$archive_alt"
 # Check the exit value upon import.
 guix archive --import < "$archive"
 
-! guix archive something-that-does-not-exist
+guix archive --export something-that-does-not-exist && false
 
 # This one must not be listed as missing.
 guix build guile-bootstrap > "$archive"
@@ -61,7 +61,7 @@ cmp "$archive" "$archive_alt"
 
 # This is not a valid store file name, so an error.
 echo something invalid > "$archive"
-! guix archive --missing < "$archive"
+guix archive --missing < "$archive" && false
 
 # Check '--extract'.
 guile -c "(use-modules (guix serialization))
@@ -77,4 +77,6 @@ guix archive -t < "$archive" | grep "^D /share/guile"
 guix archive -t < "$archive" | grep "^x /bin/guile"
 guix archive -t < "$archive" | grep "^r /share/guile.*/boot-9\.scm"
 
-! echo foo | guix archive --authorize
+echo foo | guix archive --authorize && false
+
+exit 0
diff --git a/tests/guix-build-branch.sh b/tests/guix-build-branch.sh
index 7bf6a318ca..2d3b115e78 100644
--- a/tests/guix-build-branch.sh
+++ b/tests/guix-build-branch.sh
@@ -58,4 +58,6 @@ guix gc -R "$v0_1_0_drv" | grep guile-gcrypt-9e3eacd
 test "$v0_1_0_drv" != "$latest_drv"
 test "$v0_1_0_drv" != "$orig_drv"
 
-! guix build guix --with-commit=guile-gcrypt=000 -d
+guix build guix --with-commit=guile-gcrypt=000 -d && false
+
+exit 0
diff --git a/tests/guix-build.sh b/tests/guix-build.sh
index 9cbf8fe26d..2c59177c86 100644
--- a/tests/guix-build.sh
+++ b/tests/guix-build.sh
@@ -25,7 +25,7 @@
 guix build --version
 
 # Should fail.
-! guix build -e +
+guix build -e + && false
 
 # Source-less packages are accepted; they just return nothing.
 guix build -e '(@ (gnu packages bootstrap) %bootstrap-glibc)' -S
@@ -92,7 +92,7 @@ cat > "$module_dir/foo.scm" <<EOF
 (use-modules (guix))
 ) ;extra closing paren
 EOF
-! guix build -f "$module_dir/foo.scm" 2> "$module_dir/stderr"
+guix build -f "$module_dir/foo.scm" 2> "$module_dir/stderr" && false
 grep "read error" "$module_dir/stderr"
 rm "$module_dir/stderr" "$module_dir/foo.scm"
 
@@ -199,7 +199,7 @@ cat > "$module_dir/foo.scm" <<EOF
     (inputs (quasiquote (("sed" ,sed))))))  ;unbound variable
 EOF
 
-! guix build package-with-something-wrong -n
+guix build package-with-something-wrong -n && false
 guix build package-with-something-wrong -n 2> "$module_dir/err" || true
 grep "unbound" "$module_dir/err"		     # actual error
 grep "forget.*(gnu packages base)" "$module_dir/err" # hint
@@ -240,7 +240,7 @@ cat > "$module_dir/cc-user.scm" <<EOF
 (define-module (cc-user))
 (make-thing 42)
 EOF
-! guix build -f "$module_dir/cc-user.scm" -n 2> "$module_dir/err"
+guix build -f "$module_dir/cc-user.scm" -n 2> "$module_dir/err" && false
 cat "$module_dir/err"
 grep "make-thing.*unbound" "$module_dir/err"		 # actual error
 grep "forget.*(bb-public)" "$module_dir/err"		 # hint
@@ -270,7 +270,7 @@ test "`guix build --log-file guile-bootstrap`" = "$log"
 test "`guix build --log-file $out`" = "$log"
 
 # Should fail because the name/version combination could not be found.
-! guix build hello-0.0.1 -n
+guix build hello-0.0.1 -n && false
 
 # Keep a symlink to the result, registered as a root.
 result="t-result-$$"
@@ -279,7 +279,7 @@ guix build -r "$result"					\
 test -x "$result/bin/guile"
 
 # Should fail, because $result already exists.
-! guix build -r "$result" -e '(@@ (gnu packages bootstrap) %bootstrap-guile)'
+guix build -r "$result" -e '(@@ (gnu packages bootstrap) %bootstrap-guile)' && false
 
 rm -f "$result"
 
@@ -323,7 +323,7 @@ drv2=`guix build hello -d --with-input=gcc=gcc-toolchain`
 test "$drv1" != "$drv2"
 guix gc -R "$drv2" | grep `guix build -d gcc-toolchain`
 
-! guix build guile --with-input=libunistring=something-really-silly
+guix build guile --with-input=libunistring=something-really-silly && false
 
 # Deprecated/superseded packages.
 test "`guix build superseded -d`" = "`guix build bar -d`"
@@ -331,8 +331,8 @@ test "`guix build superseded -d`" = "`guix build bar -d`"
 # Parsing package names and versions.
 guix build -n time		# PASS
 guix build -n time@1.9		# PASS, version found
-! guix build -n time@3.2	# FAIL, version not found
-! guix build -n something-that-will-never-exist # FAIL
+guix build -n time@3.2 && false	# FAIL, version not found
+guix build -n something-that-will-never-exist && false	# FAIL
 
 # Invoking a monadic procedure.
 guix build -e "(begin
@@ -404,4 +404,6 @@ export GUIX_BUILD_OPTIONS
 guix build emacs
 
 GUIX_BUILD_OPTIONS="--something-completely-crazy"
-! guix build emacs
+guix build emacs && false
+
+exit 0
diff --git a/tests/guix-daemon.sh b/tests/guix-daemon.sh
index 4b09c8c162..d85727c955 100644
--- a/tests/guix-daemon.sh
+++ b/tests/guix-daemon.sh
@@ -224,7 +224,7 @@ daemon_pid=$!
 GUIX_DAEMON_SOCKET="guix://$tcp_socket"
 export GUIX_DAEMON_SOCKET
 
-! guix gc
+guix gc && false
 
 unset GUIX_DAEMON_SOCKET
 kill "$daemon_pid"
diff --git a/tests/guix-download.sh b/tests/guix-download.sh
index 5475d43e60..f4cb335eef 100644
--- a/tests/guix-download.sh
+++ b/tests/guix-download.sh
@@ -23,11 +23,11 @@
 guix download --version
 
 # Make sure it fails here.
-! guix download http://does.not/exist
+guix download http://does.not/exist && false
 
-! guix download unknown://some/where;
+guix download unknown://some/where && false
 
-! guix download /does-not-exist
+guix download /does-not-exist && false
 
 # This one should succeed.
 guix download "file://$abs_top_srcdir/README"
@@ -43,4 +43,6 @@ GUIX_DAEMON_SOCKET="/nowhere" guix download -o "$output" \
 cmp "$output" "$abs_top_srcdir/README"
 
 # This one should fail.
-! guix download "file:///does-not-exist" "file://$abs_top_srcdir/README"
+guix download "file:///does-not-exist" "file://$abs_top_srcdir/README" && false
+
+exit 0
diff --git a/tests/guix-environment-container.sh b/tests/guix-environment-container.sh
index a30d6b7fb2..a3bc1ab572 100644
--- a/tests/guix-environment-container.sh
+++ b/tests/guix-environment-container.sh
@@ -260,16 +260,15 @@ guix shell --bootstrap guile-bootstrap --container \
      /usr/bin/guile --version
 
 # A dangling symlink causes the command to fail.
-! guix shell --bootstrap -CS /usr/bin/python=bin/python guile-bootstrap -- exit
+guix shell --bootstrap -CS /usr/bin/python=bin/python guile-bootstrap -- exit && false
 
 # An invalid symlink spec causes the command to fail.
-! guix shell --bootstrap -CS bin/guile=/usr/bin/guile guile-bootstrap -- exit
+guix shell --bootstrap -CS bin/guile=/usr/bin/guile guile-bootstrap -- exit && false
 
 # Check whether '--nesting' works.
 guix build hello -d
 env="$(type -P pre-inst-env)"
-if guix shell -C -D guix -- "$env" guix build hello -d # cannot work
-then false; else true; fi
+guix shell -C -D guix -- "$env" guix build hello -d && false # cannot work
 hello_drv="$(guix build hello -d)"
 hello_drv_nested="$(cd "$(dirname env)" && guix shell --bootstrap -CW -D guix -- "$env" guix build hello -d)"
 test "$hello_drv" = "$hello_drv_nested"
diff --git a/tests/guix-environment.sh b/tests/guix-environment.sh
index 95fe95b437..1424ea9a88 100644
--- a/tests/guix-environment.sh
+++ b/tests/guix-environment.sh
@@ -60,7 +60,7 @@ guix environment --bootstrap --ad-hoc guile-bootstrap --pure	\
 grep '^PATH=' "$tmpdir/a"
 grep '^GUIX_TEST_ABC=' "$tmpdir/a"
 grep '^GUIX_TEST_DEF=' "$tmpdir/a"
-! grep '^GUIX_TEST_XYZ=' "$tmpdir/a"
+grep '^GUIX_TEST_XYZ=' "$tmpdir/a" && false
 
 # Make sure the exit value is preserved.
 if guix environment --bootstrap --ad-hoc guile-bootstrap --pure \
@@ -207,7 +207,7 @@ then
     done
 
     # 'make-boot0' itself must not be listed.
-    ! guix gc --references "$profile" | grep make-boot0
+    guix gc --references "$profile" | grep make-boot0 && false
 
     # Make sure that the shell spawned with '--exec' sees the same environment
     # as returned by '--search-paths'.
@@ -224,7 +224,7 @@ then
     test "x$make_boot0_debug" != "x"
 
     # Make sure the "debug" output is not listed.
-    ! guix gc --references "$profile" | grep "$make_boot0_debug"
+    guix gc --references "$profile" | grep "$make_boot0_debug" && false
 
     # Compute the build environment for the initial GNU Make, but add in the
     # bootstrap Guile as an ad-hoc addition.
diff --git a/tests/guix-gc.sh b/tests/guix-gc.sh
index f40619876d..675a13115d 100644
--- a/tests/guix-gc.sh
+++ b/tests/guix-gc.sh
@@ -36,11 +36,11 @@ unset out
 # For some operations, passing extra arguments is an error.
 for option in "" "-C 500M" "--verify" "--optimize" "--list-roots"
 do
-    ! guix gc $option whatever
+    guix gc $option whatever && false
 done
 
 # This should fail.
-! guix gc --verify=foo
+guix gc --verify=foo && false
 
 # Check the references of a .drv.
 drv="`guix build guile-bootstrap -d`"
@@ -51,7 +51,7 @@ guix gc --references "$drv" | grep -e -bash
 guix gc --references "$out"
 guix gc --references "$out/bin/guile"
 
-! guix gc --references /dev/null;
+guix gc --references /dev/null && false
 
 # Check derivers.
 guix gc --derivers "$out" | grep "$drv"
@@ -62,7 +62,7 @@ test -f "$drv"
 
 guix gc --list-dead | grep "$drv"
 guix gc --delete "$drv"
-! test -f "$drv"
+test ! -f "$drv"
 
 # Add a .drv, register it as a root.
 drv="`guix build --root=guix-gc-root lsh -d`"
@@ -71,18 +71,18 @@ test -f "$drv" && test -L guix-gc-root
 guix gc --list-roots | grep "$PWD/guix-gc-root"
 
 guix gc --list-live | grep "$drv"
-! guix gc --delete "$drv";
+guix gc --delete "$drv" && false
 
 rm guix-gc-root
 guix gc --list-dead | grep "$drv"
 guix gc --delete "$drv"
-! test -f "$drv"
+test ! -f "$drv"
 
 # Try a random collection.
 guix gc -C 1KiB
 
 # Check trivial error cases.
-! guix gc --delete /dev/null;
+guix gc --delete /dev/null && false
 
 # Bug #19757
 out="`guix build guile-bootstrap`"
@@ -90,14 +90,14 @@ test -d "$out"
 
 guix gc --delete "$out"
 
-! test -d "$out"
+test ! -d "$out"
 
 out="`guix build guile-bootstrap`"
 test -d "$out"
 
 guix gc --delete "$out/"
 
-! test -d "$out"
+test ! -d "$out"
 
 out="`guix build guile-bootstrap`"
 test -d "$out"
diff --git a/tests/guix-git-authenticate.sh b/tests/guix-git-authenticate.sh
index 2b90d8a4af..ec89f941e6 100644
--- a/tests/guix-git-authenticate.sh
+++ b/tests/guix-git-authenticate.sh
@@ -35,9 +35,9 @@ intro_signer="BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA"
 cache_key="test-$$"
 
 # This must fail because the end commit is not a descendant of $intro_commit.
-! guix git authenticate "$intro_commit" "$intro_signer"	\
+guix git authenticate "$intro_commit" "$intro_signer"	\
      --cache-key="$cache_key" --stats			\
-     --end=9549f0283a78fe36f2d4ff2a04ef8ad6b0c02604
+     --end=9549f0283a78fe36f2d4ff2a04ef8ad6b0c02604 && false
 
 # The v1.2.0 commit is a descendant of $intro_commit and it satisfies the
 # authorization invariant.
@@ -59,8 +59,8 @@ guix git authenticate "$intro_commit" "$intro_signer"	\
      --end="$v1_0_0_commit"
 
 # This should fail because these commits lack '.guix-authorizations'.
-! guix git authenticate "$v1_0_0_commit" "$v1_0_0_signer" \
-       --cache-key="$cache_key" --end="$v1_0_1_commit"
+guix git authenticate "$v1_0_0_commit" "$v1_0_0_signer" \
+       --cache-key="$cache_key" --end="$v1_0_1_commit" && false
 
 # This should work thanks to '--historical-authorizations'.
 guix git authenticate "$v1_0_0_commit" "$v1_0_0_signer" 	\
diff --git a/tests/guix-graph.sh b/tests/guix-graph.sh
index e813e01c31..9824c6a65a 100644
--- a/tests/guix-graph.sh
+++ b/tests/guix-graph.sh
@@ -59,7 +59,7 @@ guix graph -t references guile-bootstrap | grep guile-bootstrap
 guix graph -e '(@ (gnu packages bootstrap) %bootstrap-guile)' \
     | grep guile-bootstrap
 
-! guix graph -e +
+guix graph -e + && false
 
 # Try passing store file names.
 
@@ -76,13 +76,13 @@ cmp "$tmpfile1" "$tmpfile2"
 # Try package transformation options.
 guix graph git | grep 'label = "openssl'
 guix graph git --with-input=openssl=libressl | grep 'label = "libressl'
-! guix graph git --with-input=openssl=libressl | grep 'label = "openssl'
+guix graph git --with-input=openssl=libressl | grep 'label = "openssl' && false
 
 # Try --load-path
 guix graph -L $module_dir dummy | grep 'label = "dummy'
 
 # Displaying shortest paths (or lack thereof).
-! guix graph --path emacs vim
+guix graph --path emacs vim && false
 
 path="\
 emacs
diff --git a/tests/guix-hash.sh b/tests/guix-hash.sh
index 8b03c7985d..e260396fd8 100644
--- a/tests/guix-hash.sh
+++ b/tests/guix-hash.sh
@@ -38,12 +38,12 @@ test `guix hash -H sha1 -f base64 /dev/null` = "2jmj7l5rSw0yVb/vlWAYkK/YBwk="
 test "`guix hash /dev/null "$abs_top_srcdir/README"`" = "`guix hash /dev/null ; guix hash "$abs_top_srcdir/README"`"
 
 # Zero files.
-! guix hash
+guix hash && false
 
 # idem as `cat /dev/null | git hash-object --stdin`
 test `guix hash -S git -H sha1 -f hex  /dev/null` = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
 
-! guix hash -H abcd1234 /dev/null
+guix hash -H abcd1234 /dev/null && false
 
 mkdir "$tmpdir"
 echo -n executable > "$tmpdir/exe"
@@ -61,11 +61,11 @@ test `guix hash -r "$tmpdir" 2>/dev/null` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslin
 test `guix hash -r "$tmpdir" -H sha512 2>/dev/null` = 301ra58c2vahczzxiyfin41mpyb0ljh4dh9zn3ijvwviaw1j40sfzw5skh9x945da88n3785ggifzig7acd6k72h0mpsc20m1f66m9n
 
 # Without '-r', this should fail.
-! guix hash "$tmpdir"
+guix hash "$tmpdir" && false
 
 # This should fail because /dev/null is a character device, which
 # the archive format doesn't support.
-! guix hash -S nar /dev/null
+guix hash -S nar /dev/null && false
 
 # Adding a .git directory
 mkdir "$tmpdir/.git"
@@ -80,5 +80,6 @@ test `guix hash -S nar $tmpdir -x` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppi
 test `guix hash -S git $tmpdir -x` = 1m9yxz99g7askm88h6hzyv4g2bfv57rp5wvwp3iq5ypsplq1xkkk
 
 # Without '-r', this should fail.
-! guix hash "$tmpdir"
+guix hash "$tmpdir" && false
 
+exit 0
diff --git a/tests/guix-home.sh b/tests/guix-home.sh
index 11b068ca43..e9ef76c862 100644
--- a/tests/guix-home.sh
+++ b/tests/guix-home.sh
@@ -109,7 +109,7 @@ EOF
     guix home extension-graph "home.scm" | grep 'label = "home"'
 
     # There are no Shepherd services so the one below must fail.
-    ! guix home shepherd-graph "home.scm"
+    guix home shepherd-graph "home.scm" && false
 
     if container_supported
     then
@@ -118,17 +118,17 @@ EOF
         # TODO: Make container independent from external environment variables.
         SHELL=bash
 	guix home container home.scm -- true
-	! guix home container home.scm -- false
+	guix home container home.scm -- false && false
 	test "$(guix home container home.scm -- echo '$HOME')" = "$HOME"
 	guix home container home.scm -- cat '~/.config/test.conf' | \
 	    grep "the content of"
 	guix home container home.scm -- test -h '~/.bashrc'
 	test "$(guix home container home.scm -- id -u)" = 1000
-	! guix home container home.scm -- test -f '$HOME/sample/home.scm'
+	guix home container home.scm -- test -f '$HOME/sample/home.scm' && false
 	guix home container home.scm --expose="$PWD=$HOME/sample" -- \
 	     test -f '$HOME/sample/home.scm'
-	! guix home container home.scm --expose="$PWD=$HOME/sample" -- \
-	     rm -v '$HOME/sample/home.scm'
+	guix home container home.scm --expose="$PWD=$HOME/sample" -- \
+	     rm -v '$HOME/sample/home.scm' && false
     else
 	echo "'guix home container' test SKIPPED" >&2
     fi
@@ -206,8 +206,8 @@ EOF
 # the NEW content of bashrc-test-config.sh"
 
     # This file must have been removed and not backed up.
-    ! test -e "$HOME/.config/test.conf"
-    ! test -e "$HOME"/*guix-home*backup/.config/test.conf
+    test ! -e "$HOME/.config/test.conf"
+    test ! -e "$HOME"/*guix-home*backup/.config/test.conf
 
     test "$(cat "$(configuration_file)")" == "$(cat home.scm)"
     test "$(canonical_file_name)" == "$(readlink "${HOME}/.guix-home")"
diff --git a/tests/guix-pack-relocatable.sh b/tests/guix-pack-relocatable.sh
index 46120c9ee6..2fc9fde0bd 100644
--- a/tests/guix-pack-relocatable.sh
+++ b/tests/guix-pack-relocatable.sh
@@ -92,7 +92,7 @@ then
     grep 'GNU sed' "$test_directory/output"
 
     # Check whether the exit code is preserved.
-    ! run_without_store "$test_directory/Bin/sed" --does-not-exist
+    run_without_store "$test_directory/Bin/sed" --does-not-exist && false
 
     chmod -Rf +w "$test_directory"; rm -rf "$test_directory"/*
 else
diff --git a/tests/guix-pack.sh b/tests/guix-pack.sh
index a13e0ededf..4042e54aeb 100644
--- a/tests/guix-pack.sh
+++ b/tests/guix-pack.sh
@@ -37,7 +37,7 @@ test_directory="`mktemp -d`"
 trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT
 
 # Reject unsuppoted packages.
-! guix pack intelmetool -s armhf-linux -n
+guix pack intelmetool -s armhf-linux -n && false
 
 # Compute the derivation of a pack.
 drv="`guix pack coreutils -d --no-grafts`"
@@ -48,7 +48,7 @@ guix gc -R "$drv" | grep "`guix build coreutils -d --no-grafts`"
 drv="`guix pack idutils -d --no-grafts --target=arm-linux-gnueabihf`"
 guix gc -R "$drv" | \
     grep "`guix build idutils --target=arm-linux-gnueabihf -d --no-grafts`"
-! guix gc -R "$drv" | grep "`guix build idutils -d --no-grafts`"
+guix gc -R "$drv" | grep "`guix build idutils -d --no-grafts`" && false
 
 # Build a tarball with no compression.
 guix pack --compression=none --bootstrap guile-bootstrap
diff --git a/tests/guix-package-aliases.sh b/tests/guix-package-aliases.sh
index 311838b768..f68d24b9a7 100644
--- a/tests/guix-package-aliases.sh
+++ b/tests/guix-package-aliases.sh
@@ -36,7 +36,7 @@ guix install --bootstrap guile-bootstrap -p "$profile"
 test -x "$profile/bin/guile"
 
 # Make sure '-r' isn't passed as-is to 'guix package'.
-! guix install -r guile-bootstrap -p "$profile" --bootstrap
+guix install -r guile-bootstrap -p "$profile" --bootstrap && false
 test -x "$profile/bin/guile"
 
 # Use a package transformation option and make sure it's recorded.
@@ -48,16 +48,16 @@ grep "libreoffice=inkscape" "$profile/manifest"
 guix upgrade --version
 guix upgrade -n
 guix upgrade gui.e -n
-! guix upgrade foo bar -n;
+guix upgrade foo bar -n && false
 
 guix remove --version
 guix remove --bootstrap guile-bootstrap -p "$profile"
-! test -x "$profile/bin/guile"
+test ! -x "$profile/bin/guile"
 test `guix package -p "$profile" -I | wc -l` -eq 0
 
-! guix remove -p "$profile" this-is-not-installed --bootstrap
+guix remove -p "$profile" this-is-not-installed --bootstrap && false
 
-! guix remove -i guile-bootstrap -p "$profile" --bootstrap
+guix remove -i guile-bootstrap -p "$profile" --bootstrap && false
 
 guix search '\<board\>' game | grep '^name: gnubg'
 
@@ -66,7 +66,7 @@ guix show guile
 guix show python@3 | grep "^name: python"
 
 # "python@2" exists but is deprecated; make sure it doesn't show up.
-! guix show python@2
+guix show python@2 && false
 
 # Specifying multiple packages.
 output="`guix show sed grep | grep ^name:`"
diff --git a/tests/guix-package-net.sh b/tests/guix-package-net.sh
index 1cdeff773a..62e17815bf 100644
--- a/tests/guix-package-net.sh
+++ b/tests/guix-package-net.sh
@@ -58,7 +58,7 @@ trap 'rm -f "$profile" "$profile_alt" "$profile.lock" "$profile_alt.lock" "$prof
 
 guix package --bootstrap -p "$profile" -i guile-bootstrap
 test -L "$profile" && test -L "$profile-1-link"
-! test -f "$profile-2-link"
+test ! -f "$profile-2-link"
 test -f "$profile/bin/guile"
 
 boot_make="(@ (guix tests) gnu-make-for-tests)"
@@ -98,13 +98,13 @@ test "`guix package -p "$profile" -l | cut -f1 | grep guile | head -n1`" \
      = "  guile-bootstrap"
 
 # Exit with 1 when a generation does not exist.
-! guix package -p "$profile" --list-generations=42
-! guix package -p "$profile" --switch-generation=99
+guix package -p "$profile" --list-generations=42 && false
+guix package -p "$profile" --switch-generation=99 && false
 
 # Remove a package.
 guix package --bootstrap -p "$profile" -r "guile-bootstrap"
 test -L "$profile-3-link"
-test -f "$profile/bin/make" && ! test -f "$profile/bin/guile"
+test -f "$profile/bin/make" && test ! -f "$profile/bin/guile"
 
 # Roll back.
 guix package --roll-back -p "$profile"
@@ -112,7 +112,7 @@ test "`readlink_base "$profile"`" = "$profile-2-link"
 test -x "$profile/bin/guile" && test -x "$profile/bin/make"
 guix package --roll-back -p "$profile"
 test "`readlink_base "$profile"`" = "$profile-1-link"
-test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
+test -x "$profile/bin/guile" && test ! -x "$profile/bin/make"
 
 # Switch to the rolled generation and switch back.
 guix package -p "$profile" --switch-generation=2
@@ -124,8 +124,8 @@ test "`readlink_base "$profile"`" = "$profile-1-link"
 for i in `seq 1 3`
 do
     guix package --bootstrap --roll-back -p "$profile"
-    ! test -f "$profile/bin"
-    ! test -f "$profile/lib"
+    test ! -f "$profile/bin"
+    test ! -f "$profile/lib"
     test "`readlink_base "$profile"`" = "$profile-0-link"
 done
 
@@ -135,7 +135,7 @@ test -z "`guix package -p "$profile" -l 0`"
 # Reinstall after roll-back to the empty profile.
 guix package --bootstrap -p "$profile" -e "$boot_make"
 test "`readlink_base "$profile"`" = "$profile-1-link"
-test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
+test -x "$profile/bin/guile" && test ! -x "$profile/bin/make"
 
 # Check that the first generation is the current one.
 test "`guix package -p "$profile" -l 1 | cut -f3 | head -n1`" = "(current)"
@@ -143,7 +143,7 @@ test "`guix package -p "$profile" -l 1 | cut -f3 | head -n1`" = "(current)"
 # Roll-back to generation 0, and install---all at once.
 guix package --bootstrap -p "$profile" --roll-back -i guile-bootstrap
 test "`readlink_base "$profile"`" = "$profile-1-link"
-test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
+test -x "$profile/bin/guile" && test ! -x "$profile/bin/make"
 
 # Install Make.
 guix package --bootstrap -p "$profile" -e "$boot_make"
@@ -175,7 +175,7 @@ test -z "`guix package -p "$profile" -l 3`"
 rm "$profile"
 guix package --bootstrap -p "$profile" -i guile-bootstrap
 guix package --bootstrap -p "$profile_alt" -i gcc-bootstrap
-! guix package -p "$profile" --search-paths | grep LIBRARY_PATH
+guix package -p "$profile" --search-paths | grep LIBRARY_PATH && false
 guix package -p "$profile" -p "$profile_alt" --search-paths \
      | grep "LIBRARY_PATH.*$profile/lib.$profile_alt/lib"
 
@@ -234,4 +234,4 @@ guix package --bootstrap -e "$boot_make"
 test -f "$HOME/.guix-profile/bin/make"
 
 guix package --bootstrap --roll-back
-! test -f "$HOME/.guix-profile/bin/make"
+test ! -f "$HOME/.guix-profile/bin/make"
diff --git a/tests/guix-package.sh b/tests/guix-package.sh
index cc416ec6a1..945d59cdfb 100644
--- a/tests/guix-package.sh
+++ b/tests/guix-package.sh
@@ -37,7 +37,7 @@ rm -f "$profile" "$tmpfile"
 trap 'rm -f "$profile" "$profile.lock" "$profile-"[0-9]* "$tmpfile"; rm -rf "$module_dir" t-home-'"$$" EXIT
 
 # Use `-e' with a non-package expression.
-! guix package --bootstrap -e +
+guix package --bootstrap -e + && false
 
 # Install a store item and make sure the version and output in the manifest
 # are correct.
@@ -57,23 +57,23 @@ guix gc --list-live | grep "`readlink "$profile-1-link"`"
 # Installing the same package a second time does nothing.
 guix package --bootstrap -p "$profile" -i guile-bootstrap
 test -L "$profile" && test -L "$profile-1-link"
-! test -f "$profile-2-link"
+test ! -f "$profile-2-link"
 test -f "$profile/bin/guile"
 
 # Unsupported packages cannot be installed.
-! guix package -e '(begin (use-modules (guix) (gnu packages base)) (package (inherit sed) (supported-systems (list))))' -n
+guix package -e '(begin (use-modules (guix) (gnu packages base)) (package (inherit sed) (supported-systems (list))))' -n && false
 case $(uname -m) in
     x86_64|i[3456]86)
-	! guix package -i novena-eeprom -n
+	guix package -i novena-eeprom -n && false
 	break;;
     *)
-	! guix package -i intelmetool -n
+	guix package -i intelmetool -n && false
 	break;;
 esac
 
 # Collisions are properly flagged (in this case, 'g-wrap' propagates
 # guile@2.2, which conflicts with guile@2.0.)
-! guix package --bootstrap -n -p "$profile" -i g-wrap guile@2.0
+guix package --bootstrap -n -p "$profile" -i g-wrap guile@2.0 && false
 
 guix package --bootstrap -n -p "$profile" -i g-wrap guile@2.0 \
      --allow-collisions
@@ -88,7 +88,7 @@ test "`guix package -p "$profile" --search-paths | wc -l`" = 1  # $PATH
   type -P rm )
 
 # Exit with 1 when a generation does not exist.
-! guix package -p "$profile" --delete-generations=42
+guix package -p "$profile" --delete-generations=42 && false
 
 # Exit with 0 when trying to delete the zeroth generation.
 guix package -p "$profile" --delete-generations=0
@@ -101,12 +101,12 @@ guix package --bootstrap -i "glibc:debug" -p "$profile" -n
 
 # Make sure nonexistent outputs are reported.
 guix package --bootstrap -i "guile-bootstrap:out" -p "$profile" -n
-! guix package --bootstrap -i "guile-bootstrap:does-not-exist" -p "$profile" -n
-! guix package --bootstrap -i "guile-bootstrap:does-not-exist" -p "$profile"
+guix package --bootstrap -i "guile-bootstrap:does-not-exist" -p "$profile" -n && false
+guix package --bootstrap -i "guile-bootstrap:does-not-exist" -p "$profile" && false
 
 # Make sure we get an error when trying to remove something that's not
 # installed.
-! guix package --bootstrap -r something-not-installed -p "$profile"
+guix package --bootstrap -r something-not-installed -p "$profile" && false
 
 # Check whether `--list-available' returns something sensible.
 guix package -p "$profile" -A 'gui.*e' | grep guile
@@ -118,8 +118,8 @@ guix package --show=guile | grep "^name: guile"
 guix package --show=texlive
 
 # Fail for non-existent packages or package/version pairs.
-! guix package --show=does-not-exist
-! guix package --show=emacs@42
+guix package --show=does-not-exist && false
+guix package --show=emacs@42 && false
 
 # Search.
 LC_MESSAGES=C
@@ -163,19 +163,19 @@ guix package --search="" > /dev/null
 # There's no generation older than 12 months, so the following command should
 # have no effect.
 generation="`readlink_base "$profile"`"
-! guix package -p "$profile" --delete-generations=12m
+guix package -p "$profile" --delete-generations=12m && false
 test "`readlink_base "$profile"`" = "$generation"
 
 # The following command should not delete the current generation, even though
 # it matches the given pattern (see <http://bugs.gnu.org/19978>.)  And since
 # there's nothing else to delete, it should just fail.
 guix package --list-generations -p "$profile"
-! guix package --bootstrap -p "$profile" --delete-generations=1..
+guix package --bootstrap -p "$profile" --delete-generations=1.. && false
 test "`readlink_base "$profile"`" = "$generation"
 
 # Make sure $profile is a GC root at this point.
 real_profile="`readlink -f "$profile"`"
-! guix gc -d "$real_profile"
+guix gc -d "$real_profile" && false
 test -d "$real_profile"
 
 # Now, let's remove all the symlinks to $real_profile, and make sure
@@ -278,22 +278,22 @@ do
     guix gc --list-live | grep "`readlink "$profile_link"`"
 
     guix package --bootstrap --roll-back
-    ! test -f "$HOME/.guix-profile/bin"
-    ! test -f "$HOME/.guix-profile/lib"
+    test ! -f "$HOME/.guix-profile/bin"
+    test ! -f "$HOME/.guix-profile/lib"
     test "`readlink "$default_profile"`" = "`basename $default_profile-0-link`"
 done
 
 # Check whether '-p ~/.guix-profile' makes any difference.
 # See <http://bugs.gnu.org/17939>.
-! test -e "$HOME/.guix-profile-0-link"
-! test -e "$HOME/.guix-profile-1-link"
+test ! -e "$HOME/.guix-profile-0-link"
+test ! -e "$HOME/.guix-profile-1-link"
 guix package --bootstrap -p "$HOME/.guix-profile" -i guile-bootstrap
-! test -e "$HOME/.guix-profile-1-link"
+test ! -e "$HOME/.guix-profile-1-link"
 guix package --bootstrap --roll-back -p "$HOME/.guix-profile"
-! test -e "$HOME/.guix-profile-0-link"
+test ! -e "$HOME/.guix-profile-0-link"
 
 # Extraneous argument.
-! guix package install foo-bar
+guix package install foo-bar && false
 
 # Make sure the "broken pipe" doesn't yield an error.
 # Note: 'pipefail' is a Bash-specific option.
@@ -382,7 +382,7 @@ cat > "$module_dir/package.scm"<<EOF
 
 (define my-package coreutils)   ;returns *unspecified*
 EOF
-! guix package --bootstrap --install-from-file="$module_dir/package.scm"
+guix package --bootstrap --install-from-file="$module_dir/package.scm" && false
 
 rm "$module_dir/package.scm"
 
diff --git a/tests/guix-refresh.sh b/tests/guix-refresh.sh
index c5214e1d6e..1167703b74 100644
--- a/tests/guix-refresh.sh
+++ b/tests/guix-refresh.sh
@@ -37,12 +37,12 @@ GUIX_TEST_UPDATER_TARGETS='
    ("the-test-package" "" (("5.5" "file://'$PWD/$module_dir'/source"))))'
 
 # No newer version available.
-! guix refresh -t test idutils
+guix refresh -t test idutils && false
 case "$(guix refresh -t test idutils 2>&1)" in
     *"$idutils_version"*"already the latest version"*) true;;
     *) false;;
 esac
-! guix refresh -t test libreoffice
+guix refresh -t test libreoffice && false
 case "$(guix refresh -t test libreoffice 2>&1)" in
     *"greater than the latest known version"*"1.0"*) true;;
     *) false;;
@@ -100,7 +100,7 @@ grep 'version "5.5"' "$module_dir/sample.scm"
 grep "$(guix hash -H sha256 -f nix-base32 "$module_dir/source")" "$module_dir/sample.scm"
 
 # Specifying a target version.
-! guix refresh -t test guile=2.0.0
+guix refresh -t test guile=2.0.0 && false
 case "$(guix refresh -t test guile=2.0.0 2>&1)" in
     *"failed to find"*"2.0.0"*) true;;
     *) false;;
diff --git a/tests/guix-shell.sh b/tests/guix-shell.sh
index cb2b53466d..ed368515eb 100644
--- a/tests/guix-shell.sh
+++ b/tests/guix-shell.sh
@@ -33,13 +33,13 @@ export XDG_CONFIG_HOME
 guix shell --bootstrap --pure guile-bootstrap -- guile --version
 
 # '--symlink' can only be used with --container.
-! guix shell --bootstrap guile-bootstrap -S /dummy=bin/guile
+guix shell --bootstrap guile-bootstrap -S /dummy=bin/guile && false
 
 # '--ad-hoc' is a thing of the past.
-! guix shell --ad-hoc guile-bootstrap
+guix shell --ad-hoc guile-bootstrap && false
 
 # Rejecting unsupported packages.
-! guix shell -s armhf-linux intelmetool -n
+guix shell -s armhf-linux intelmetool -n && false
 
 # Test approximately that the child process does not inherit extra file
 # descriptors.  Ideally we'd check there's nothing more than 0, 1, and 2, but
@@ -55,7 +55,7 @@ test "$(echo $fd_list | wc -w)" -le "$(echo $initial_fd_list | wc -w)"
 cat > "$tmpdir/guix.scm" <<EOF
 This is a broken guix.scm file.
 EOF
-! (cd "$tmpdir"; SHELL="$(type -P true)" guix shell --bootstrap 2> "stderr")
+(cd "$tmpdir"; SHELL="$(type -P true)" guix shell --bootstrap 2> "stderr") && false
 grep "not authorized" "$tmpdir/stderr"
 rm "$tmpdir/stderr"
 
@@ -122,7 +122,7 @@ then
     done
 
     # 'make-boot0' itself must not be listed.
-    ! guix gc --references "$profile" | grep make-boot0
+    guix gc --references "$profile" | grep make-boot0 && false
 
     # Honoring the local 'guix.scm' file.
     echo '(@ (guix tests) gnu-make-for-tests)' > "$tmpdir/guix.scm"
diff --git a/tests/guix-style.sh b/tests/guix-style.sh
index 58f953a0ec..2de879d5e3 100644
--- a/tests/guix-style.sh
+++ b/tests/guix-style.sh
@@ -65,7 +65,7 @@ cp "$tmpfile" "$tmpfile.bak"
 initial_hash="$(guix hash "$tmpfile")"
 
 guix style -f "$tmpfile"
-if ! test "$initial_hash" = "$(guix hash "$tmpfile")"
+if test "$initial_hash" != "$(guix hash "$tmpfile")"
 then
     cat "$tmpfile"
     diff -u "$tmpfile.bak" "$tmpfile"
@@ -73,8 +73,8 @@ then
 fi
 
 # Introduce random changes and try again.
-sed -i "$tmpfile" -e's/ +/ /g'
-! test "$initial_hash" = "$(guix hash "$tmpfile")"
+sed -i "$tmpfile" -e's/ \+/ /g'
+test "$initial_hash" != "$(guix hash "$tmpfile")"
 
 guix style -f "$tmpfile"
 test "$initial_hash" = "$(guix hash "$tmpfile")"
diff --git a/tests/guix-system.sh b/tests/guix-system.sh
index 1dbd5a0b85..adc0c44a6f 100644
--- a/tests/guix-system.sh
+++ b/tests/guix-system.sh
@@ -318,7 +318,7 @@ cat > "$tmpdir/config.scm" <<EOF
 
 (bad-local-file "whatever.scm")
 EOF
-! guix system build "$tmpdir/config.scm" -n
+guix system build "$tmpdir/config.scm" -n && false
 guix system build "$tmpdir/config.scm" -n 2>&1 | \
     grep "config\.scm:4:2: warning:.*whatever.*relative to current directory"
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-04-20  5:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-23 16:00 bug#62406: “! failing-command” pattern in shell tests is wrong Ludovic Courtès
2023-03-23 18:53 ` Eric Bavier
2023-03-28 16:21   ` Ludovic Courtès
2023-04-20  5:48     ` Eric Bavier
2023-03-26 18:16 ` Martin Castillo
2023-03-26 18:21 ` Martin Castillo

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.