accounts/keystore: fix flaky TestUpdatedKeyfileContents notification race

TestUpdatedKeyfileContents was intermittently failing with:

- Emptying account file failed
- wasn't notified of new accounts

Root cause: waitForAccounts required the account list match and an immediately readable ks.changes notification in the same instant, creating a timing race between cache update visibility and channel delivery.

This change keeps the same timeout window but waits until both conditions are observed, which preserves test intent while removing the flaky timing dependency.

Validation:
- go test ./accounts/keystore -run '^TestUpdatedKeyfileContents$' -count=100
This commit is contained in:
Daniel Liu 2026-03-25 11:41:29 +08:00
parent e951bcbff7
commit 0d134439d3

View file

@ -68,18 +68,27 @@ func waitWatcherStart(ks *KeyStore) bool {
func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error {
var list []accounts.Account
haveAccounts := false
haveChange := false
for t0 := time.Now(); time.Since(t0) < 5*time.Second; time.Sleep(100 * time.Millisecond) {
list = ks.Accounts()
if reflect.DeepEqual(list, wantAccounts) {
// ks should have also received change notifications
if !haveAccounts {
list = ks.Accounts()
haveAccounts = reflect.DeepEqual(list, wantAccounts)
}
if !haveChange {
select {
case <-ks.changes:
haveChange = true
default:
return errors.New("wasn't notified of new accounts")
}
}
if haveAccounts && haveChange {
return nil
}
}
if haveAccounts {
return errors.New("wasn't notified of new accounts")
}
return fmt.Errorf("\ngot %v\nwant %v", list, wantAccounts)
}