Source file
src/database/sql/closemu_test.go
1
2
3
4
5 package sql
6
7 import (
8 "testing"
9 "testing/synctest"
10 )
11
12 func TestClosingMutex(t *testing.T) {
13 start := func(t *testing.T, f func()) func() bool {
14 done := false
15 go func() {
16 f()
17 done = true
18 }()
19 return func() bool {
20 synctest.Wait()
21 return done
22 }
23 }
24
25 synctest.Test(t, func(t *testing.T) {
26 var m closingMutex
27
28
29 m.RLock()
30 m.RLock()
31 m.RUnlock()
32 m.RUnlock()
33
34
35 m.RLock()
36 lock1Done := start(t, m.Lock)
37 if lock1Done() {
38 t.Fatalf("m.Lock(): succeeded on RLocked mutex")
39 }
40 m.RLock()
41 m.RUnlock()
42 if lock1Done() {
43 t.Fatalf("m.Lock(): succeeded after one RUnlock, one RLock remains")
44 }
45 m.RUnlock()
46 if !lock1Done() {
47 t.Fatalf("m.Lock(): still blocking after all RUnlocks")
48 }
49 m.Unlock()
50
51
52 m.Lock()
53 rlock1Done := start(t, m.RLock)
54 rlock2Done := start(t, m.RLock)
55 if rlock1Done() || rlock2Done() {
56 t.Fatalf("m.RLock(): succeeded on Locked mutex")
57 }
58 m.Unlock()
59 if !rlock1Done() || !rlock2Done() {
60 t.Fatalf("m.RLock(): succeeded on Locked mutex")
61 }
62 m.RUnlock()
63 m.RUnlock()
64
65
66 m.Lock()
67 lock2Done := start(t, m.Lock)
68 if lock2Done() {
69 t.Fatalf("m.Lock(): succeeded on Locked mutex")
70 }
71 m.Unlock()
72 if !lock2Done() {
73 t.Fatalf("m.Lock(): still blocking after Unlock")
74 }
75 m.Unlock()
76
77
78 m.RLock()
79 lock3Done := start(t, m.Lock)
80 if lock3Done() {
81 t.Fatalf("m.Lock(): succeeded on RLocked mutex")
82 }
83 m.RLock()
84 m.RUnlock()
85 m.RUnlock()
86 if !lock3Done() {
87 t.Fatalf("m.Lock(): still blocking after RUnlock")
88 }
89 m.Unlock()
90
91 })
92 }
93
94 func TestClosingMutexPanics(t *testing.T) {
95 for _, test := range []struct {
96 name string
97 f func()
98 }{{
99 name: "double RUnlock",
100 f: func() {
101 var m closingMutex
102 m.RLock()
103 m.RUnlock()
104 m.RUnlock()
105 },
106 }, {
107 name: "double Unlock",
108 f: func() {
109 var m closingMutex
110 m.Lock()
111 m.Unlock()
112 m.Unlock()
113 },
114 }} {
115 var got any
116 func() {
117 defer func() {
118 got = recover()
119 }()
120 test.f()
121 }()
122 if got == nil {
123 t.Errorf("no panic, want one")
124 }
125 }
126 }
127
View as plain text