@@ -144,6 +144,44 @@ func TestClientContextCancelDuringRPC(t *testing.T) {
144
144
}
145
145
}
146
146
147
+ func TestClientLeakCallbacks (t * testing.T ) {
148
+ if testing .Short () {
149
+ t .Skip ("skipping during short test run" )
150
+ }
151
+
152
+ c , _ , done := testClient (t , func (_ jsonrpc.Request ) jsonrpc.Response {
153
+ // Only respond with messages that don't match an incoming request.
154
+ return jsonrpc.Response {
155
+ ID : intPtr (100 ),
156
+ Result : mustMarshalJSON (t , []string {"foo" }),
157
+ }
158
+ })
159
+ defer done ()
160
+
161
+ // Expect no callbacks registered before RPCs, and none after RPCs time out.
162
+ var want ovsdb.ClientStats
163
+ want .Callbacks .Current = 0
164
+
165
+ if diff := cmp .Diff (want , c .Stats ()); diff != "" {
166
+ t .Fatalf ("unexpected starting client stats (-want +got):\n %s" , diff )
167
+ }
168
+
169
+ for i := 0 ; i < 5 ; i ++ {
170
+ // Give enough time for an RPC to be sent so we don't immediately time out.
171
+ ctx , cancel := context .WithTimeout (context .Background (), 50 * time .Millisecond )
172
+ defer cancel ()
173
+
174
+ _ , err := c .ListDatabases (ctx )
175
+ if err != context .DeadlineExceeded {
176
+ t .Fatalf ("expected context deadline exceeded error: %v" , err )
177
+ }
178
+ }
179
+
180
+ if diff := cmp .Diff (want , c .Stats ()); diff != "" {
181
+ t .Fatalf ("unexpected ending client stats (-want +got):\n %s" , diff )
182
+ }
183
+ }
184
+
147
185
func testClient (t * testing.T , fn jsonrpc.TestFunc ) (* ovsdb.Client , chan <- * jsonrpc.Response , func ()) {
148
186
t .Helper ()
149
187
0 commit comments