From: =?utf-8?b?T3R0byBLZWvDpGzDpGluZW4=?= <otto@debian.org>
Date: Sat, 23 Aug 2025 22:35:05 +0000
Subject: Fix TestTee panic on Spawn error seen on ppc64el

The `TestTee` function was susceptible to a panic due to a nil pointer
dereference if the `Spawn` function failed as observed on the `ppc64el`
architecture during autopkgtests:

    github.com/google/goexpect
       dh_auto_test -O--builddirectory=debian/.build/upstream -O--buildsystem=golang
    ^Icd debian/.build/upstream && go test -vet=off -v -p 16 github.com/google/goexpect
    === RUN   TestBatcher
    2025/08/22 06:57:28 at login prompt
    2025/08/22 06:57:28 at password prompt
    2025/08/22 06:57:28 Done sent
    E0822 06:57:28.425817    7480 expect_test.go:138] Accept failed: accept tcp [::]:42685: use of closed network connection
    --- PASS: TestBatcher (0.08s)
    === RUN   TestTee
    --- FAIL: TestTee (0.00s)
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    ^Ipanic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x2e6c64]

    goroutine 60 [running]:
    testing.tRunner.func1.2({0x392ec0, 0x6cd9e0})
    ^I/usr/lib/go-1.24/src/testing/testing.go:1734 +0x1d8
    testing.tRunner.func1()
    ^I/usr/lib/go-1.24/src/testing/testing.go:1737 +0x33c
    panic({0x392ec0?, 0x6cd9e0?})
    ^I/usr/lib/go-1.24/src/runtime/panic.go:792 +0x154
    github.com/google/goexpect.(*GExpect).check(0x37aa40?)
    ^I/tmp/autopkgtest-lxc.onolzjvd/downtmp/autopkgtest_tmp/debian/.build/upstream/src/github.com/google/goexpect/expect.go:690 +0x34
    github.com/google/goexpect.(*GExpect).Send(0x0, {0x4004e6, 0x7})
    ^I/tmp/autopkgtest-lxc.onolzjvd/downtmp/autopkgtest_tmp/debian/.build/upstream/src/github.com/google/goexpect/expect.go:1223 +0x4c
    github.com/google/goexpect.TestTee(0xc00034ac40)
    ^I/tmp/autopkgtest-lxc.onolzjvd/downtmp/autopkgtest_tmp/debian/.build/upstream/src/github.com/google/goexpect/expect_test.go:710 +0x178
    testing.tRunner(0xc00034ac40, 0x41a0e0)
    ^I/usr/lib/go-1.24/src/testing/testing.go:1792 +0x110
    created by testing.(*T).Run in goroutine 1
    ^I/usr/lib/go-1.24/src/testing/testing.go:1851 +0x3ec
    FAIL^Igithub.com/google/goexpect^I0.093s
    FAIL
    dh_auto_test: error: cd debian/.build/upstream && go test -vet=off -v -p 16 github.com/google/goexpect returned exit code 1
    make: *** [debian/rules:9: build] Error 25


The `Spawn` function can return an error and a nil `GExpect` object if it fails
to initialize the process. The test, however, did not check for this error and
proceeded to call methods on the potentially nil `GExpect` object, leading to a
panic.

If `Spawn` returns an error, the test will now fail gracefully with a `t.Fatalf`
message, preventing the nil pointer dereference and subsequent panic. This makes
the test more robust against transient failures or environment-specific issues
during process spawning.
---
 expect_test.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/expect_test.go b/expect_test.go
index 31c1d76..ede0ee7 100644
--- a/expect_test.go
+++ b/expect_test.go
@@ -706,6 +706,9 @@ func TestTee(t *testing.T) {
 	// Send abcdef to cat 4096 times.
 	input := "abcdef\n"
 	e, _, err := Spawn("cat", 400*time.Millisecond, Tee(f), CheckDuration(1*time.Millisecond))
+	if err != nil {
+		t.Fatalf("Spawn failed: %v", err)
+	}
 	for i := 0; i < 4096; i++ {
 		e.Send(input)
 		re := regexp.MustCompile(input)
