test: fix nil pointer panic in testMutexLock

Refer to: https://github.com/etcd-io/etcd/actions/runs/3671847902/jobs/6207463700

```
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0xedc388]

goroutine 5253 [running]:
go.etcd.io/etcd/client/v3/concurrency.(*Session).Client(...)
	/home/runner/work/etcd/etcd/client/v3/concurrency/session.go:76
go.etcd.io/etcd/client/v3/concurrency.(*Mutex).tryAcquire(0xc000133140, {0x18a8668, 0xc000050158})
	/home/runner/work/etcd/etcd/client/v3/concurrency/mutex.go:111 +0x88
go.etcd.io/etcd/client/v3/concurrency.(*Mutex).Lock(0xc000133140, {0x18a8668, 0xc000050158})
	/home/runner/work/etcd/etcd/client/v3/concurrency/mutex.go:74 +0x68
go.etcd.io/etcd/tests/v3/integration/clientv3/experimental/recipes_test.testMutexLock.func1()
	/home/runner/work/etcd/etcd/tests/integration/clientv3/experimental/recipes/v3_lock_test.go:65 +0x285
created by go.etcd.io/etcd/tests/v3/integration/clientv3/experimental/recipes_test.testMutexLock
	/home/runner/work/etcd/etcd/tests/integration/clientv3/experimental/recipes/v3_lock_test.go:59 +0xda
FAIL	go.etcd.io/etcd/tests/v3/integration/clientv3/experimental/recipes	7.070s
FAIL
```

Signed-off-by: Benjamin Wang <wachao@vmware.com>
This commit is contained in:
Benjamin Wang 2022-12-12 10:18:19 +08:00
parent 64599b4072
commit 3c51c42417

View File

@ -16,7 +16,9 @@ package recipes_test
import ( import (
"context" "context"
"fmt"
"math/rand" "math/rand"
"sync"
"testing" "testing"
"time" "time"
@ -51,26 +53,27 @@ func TestMutexLockMultiNode(t *testing.T) {
func testMutexLock(t *testing.T, waiters int, chooseClient func() *clientv3.Client) { func testMutexLock(t *testing.T, waiters int, chooseClient func() *clientv3.Client) {
// stream lock acquisitions // stream lock acquisitions
lockedC := make(chan *concurrency.Mutex) lockedC := make(chan *concurrency.Mutex, waiters)
stopC := make(chan struct{}) errC := make(chan error, waiters)
defer close(stopC)
var wg sync.WaitGroup
wg.Add(waiters)
for i := 0; i < waiters; i++ { for i := 0; i < waiters; i++ {
go func() { go func(i int) {
defer wg.Done()
session, err := concurrency.NewSession(chooseClient()) session, err := concurrency.NewSession(chooseClient())
if err != nil { if err != nil {
t.Error(err) errC <- fmt.Errorf("#%d: failed to create new session: %w", i, err)
return
} }
m := concurrency.NewMutex(session, "test-mutex") m := concurrency.NewMutex(session, "test-mutex")
if err := m.Lock(context.TODO()); err != nil { if err := m.Lock(context.TODO()); err != nil {
t.Errorf("could not wait on lock (%v)", err) errC <- fmt.Errorf("#%d: failed to wait on lock: %w", i, err)
return
} }
select { lockedC <- m
case lockedC <- m: }(i)
case <-stopC:
}
}()
} }
// unlock locked mutexes // unlock locked mutexes
timerC := time.After(time.Duration(waiters) * time.Second) timerC := time.After(time.Duration(waiters) * time.Second)
@ -78,6 +81,8 @@ func testMutexLock(t *testing.T, waiters int, chooseClient func() *clientv3.Clie
select { select {
case <-timerC: case <-timerC:
t.Fatalf("timed out waiting for lock %d", i) t.Fatalf("timed out waiting for lock %d", i)
case err := <-errC:
t.Fatalf("Unexpected error: %v", err)
case m := <-lockedC: case m := <-lockedC:
// lock acquired with m // lock acquired with m
select { select {
@ -90,6 +95,7 @@ func testMutexLock(t *testing.T, waiters int, chooseClient func() *clientv3.Clie
} }
} }
} }
wg.Wait()
} }
func TestMutexTryLockSingleNode(t *testing.T) { func TestMutexTryLockSingleNode(t *testing.T) {