Skip to content

Commit 76e4a2f

Browse files
committed
test: fix flaky test
Helper method that performs initial assigning of master/replica roles and is widely used in ConnectionPool tests was adjusted to wait for the roles to be applied successfully. Prior to this patch it doesn't, so sometimes subsequent test code might work unexpectedly (the problem was caught with TestConnectionHandlerOpenUpdateClose) Closes #452
1 parent 20dc742 commit 76e4a2f

File tree

1 file changed

+55
-7
lines changed

1 file changed

+55
-7
lines changed

test_helpers/pool_helper.go

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package test_helpers
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"reflect"
8+
"sync"
79
"time"
810

911
"github.com/tarantool/go-tarantool/v2"
@@ -206,6 +208,45 @@ func SetInstanceRO(ctx context.Context, dialer tarantool.Dialer, connOpts tarant
206208
return err
207209
}
208210

211+
// Wait for the role to be applied.
212+
for {
213+
time.Sleep(10 * time.Millisecond)
214+
215+
var reason string
216+
217+
data, err := conn.Do(tarantool.NewCallRequest("box.info")).Get()
218+
switch {
219+
case err != nil:
220+
reason = fmt.Sprintf("failed to get box.info: %s", err)
221+
case len(data) < 1:
222+
reason = "box.info is empty"
223+
default:
224+
status, statusFound := data[0].(map[interface{}]interface{})["status"]
225+
readonly, readonlyFound := data[0].(map[interface{}]interface{})["ro"]
226+
switch {
227+
case !statusFound:
228+
reason = "box.info.status is missing"
229+
case status != "running":
230+
reason = fmt.Sprintf("box.info.status='%s' (waiting for 'running')", status)
231+
case !readonlyFound:
232+
reason = "box.info.ro is missing"
233+
case readonly != isReplica:
234+
reason = fmt.Sprintf("box.info.ro='%v' (waiting for '%v')", readonly, isReplica)
235+
}
236+
}
237+
238+
if len(reason) == 0 {
239+
break
240+
}
241+
242+
select {
243+
case <-ctx.Done():
244+
return fmt.Errorf("%w: failed to apply role, the last reason: %s", ctx.Err(), reason)
245+
default:
246+
continue
247+
}
248+
}
249+
209250
return nil
210251
}
211252

@@ -215,16 +256,23 @@ func SetClusterRO(dialers []tarantool.Dialer, connOpts tarantool.Opts,
215256
return fmt.Errorf("number of servers should be equal to number of roles")
216257
}
217258

259+
ctx, cancel := GetConnectContext()
260+
defer cancel()
261+
262+
// Apply roles in parallel.
263+
errs := make([]error, len(dialers))
264+
var wg sync.WaitGroup
218265
for i, dialer := range dialers {
219-
ctx, cancel := GetConnectContext()
220-
err := SetInstanceRO(ctx, dialer, connOpts, roles[i])
221-
cancel()
222-
if err != nil {
223-
return err
224-
}
266+
wg.Add(1)
267+
// Pass loop variables to avoid its closure.
268+
go func(i int, dialer tarantool.Dialer) {
269+
defer wg.Done()
270+
errs[i] = SetInstanceRO(ctx, dialer, connOpts, roles[i])
271+
}(i, dialer)
225272
}
273+
wg.Wait()
226274

227-
return nil
275+
return errors.Join(errs...)
228276
}
229277

230278
func StartTarantoolInstances(instsOpts []StartOpts) ([]*TarantoolInstance, error) {

0 commit comments

Comments
 (0)