discovery: fix flaky test
Since stopping is done asynchronously, advertisement can be stopped
after scanning in test. Wait a bit after stopping to fix the flaky test.
Change-Id: I200e75d474aa3b5d6cde7167d217fb67467b0788
diff --git a/runtime/internal/discovery/discovery_test.go b/runtime/internal/discovery/discovery_test.go
index 6a4b248..1032778 100644
--- a/runtime/internal/discovery/discovery_test.go
+++ b/runtime/internal/discovery/discovery_test.go
@@ -5,7 +5,9 @@
package discovery_test
import (
+ "fmt"
"reflect"
+ "runtime"
"testing"
"time"
@@ -34,64 +36,37 @@
for _, service := range services {
stop, err := advertise(ds, service)
if err != nil {
- t.Fatalf("Advertise failed: %v\n", err)
+ t.Fatal(err)
}
stops = append(stops, stop)
}
- updates, err := scan(ds, "v.io/v23/a")
- if err != nil {
- t.Fatalf("Scan failed: %v\n", err)
+ if err := scanAndMatch(ds, "v.io/v23/a", services[0]); err != nil {
+ t.Error(err)
}
- if !match(updates, services[0]) {
- t.Errorf("Scan failed; got %v, but wanted %v\n", updates, services[0])
+ if err := scanAndMatch(ds, "v.io/v23/b", services[1]); err != nil {
+ t.Error(err)
}
- updates, err = scan(ds, "v.io/v23/b")
- if err != nil {
- t.Fatalf("Scan failed: %v\n", err)
+ if err := scanAndMatch(ds, "", services...); err != nil {
+ t.Error(err)
}
- if !match(updates, services[1]) {
- t.Errorf("Scan failed; got %v, but wanted %v\n", updates, services[1])
- }
- updates, err = scan(ds, "")
- if err != nil {
- t.Fatalf("Scan failed: %v\n", err)
- }
- if !match(updates, services...) {
- t.Errorf("Scan failed; got %v, but wanted %v\n", updates, services)
- }
- updates, err = scan(ds, "v.io/v23/c")
- if err != nil {
- t.Fatalf("Scan failed: %v\n", err)
- }
- if !match(updates) {
- t.Errorf("Scan failed; got %v, but wanted %v\n", updates, nil)
+ if err := scanAndMatch(ds, "v.io/v23/c"); err != nil {
+ t.Error(err)
}
// Stop advertising the first service. Shouldn't affect the other.
stops[0]()
- updates, err = scan(ds, "v.io/v23/a")
- if err != nil {
- t.Fatalf("Scan failed: %v\n", err)
+ if err := scanAndMatch(ds, "v.io/v23/a"); err != nil {
+ t.Error(err)
}
- if !match(updates) {
- t.Errorf("Scan failed; got %v, but wanted %v\n", updates, nil)
+ if err := scanAndMatch(ds, "v.io/v23/b", services[1]); err != nil {
+ t.Error(err)
}
- updates, err = scan(ds, "v.io/v23/b")
- if err != nil {
- t.Fatalf("Scan failed: %v\n", err)
- }
- if !match(updates, services[1]) {
- t.Errorf("Scan failed; got %v, but wanted %v\n", updates, services[1])
- }
+
// Stop advertising the other. Now shouldn't discover any service.
stops[1]()
- updates, err = scan(ds, "")
- if err != nil {
- t.Fatalf("Scan failed: %v\n", err)
- }
- if !match(updates) {
- t.Errorf("Scan failed; got %v, but wanted %v\n", updates, nil)
+ if err := scanAndMatch(ds, ""); err != nil {
+ t.Error(err)
}
}
@@ -99,25 +74,24 @@
ctx, cancel := context.RootContext()
for _, service := range services {
if err := ds.Advertise(ctx, service, nil); err != nil {
- return nil, err
+ return nil, fmt.Errorf("Advertise failed: %v", err)
}
}
return cancel, nil
}
func scan(ds discovery.Scanner, query string) ([]discovery.Update, error) {
- ctx, cancel := context.RootContext()
- defer cancel()
+ ctx, _ := context.RootContext()
updateCh, err := ds.Scan(ctx, query)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("Scan failed: %v", err)
}
var updates []discovery.Update
for {
select {
case update := <-updateCh:
updates = append(updates, update)
- case <-time.After(10 * time.Millisecond):
+ case <-time.After(5 * time.Millisecond):
return updates, nil
}
}
@@ -143,3 +117,22 @@
}
return len(updates) == 0
}
+
+func scanAndMatch(ds discovery.Scanner, query string, wants ...discovery.Service) error {
+ const timeout = 3 * time.Second
+
+ var updates []discovery.Update
+ for now := time.Now(); time.Since(now) < timeout; {
+ runtime.Gosched()
+
+ var err error
+ updates, err = scan(ds, query)
+ if err != nil {
+ return err
+ }
+ if match(updates, wants...) {
+ return nil
+ }
+ }
+ return fmt.Errorf("Match failed; got %v, but wanted %v", updates, wants)
+}