blob: dea5351e7be0bfae1dd37a46b0602e168c4a045c [file] [log] [blame]
package internal
import (
"reflect"
"testing"
"v.io/v23/discovery"
"v.io/v23/security/access"
"v.io/v23/context"
idiscovery "v.io/x/ref/lib/discovery"
vtest "v.io/x/ref/test"
_ "v.io/x/ref/runtime/factories/generic"
mojom "mojom/vanadium/discovery"
)
type mockAdv struct {
s discovery.Service
}
type discoveryMock struct {
trigger *idiscovery.Trigger
id int64
services map[int64]discovery.Service
// An item will be put in deleteCh when something has been deleted.
deleteCh chan struct{}
}
func (d *discoveryMock) Advertise(ctx *context.T,s discovery.Service, perms access.Permissions) error {
currId := d.id
d.services[currId] = s
d.id++
c := func() {
delete(d.services, currId)
d.deleteCh <- struct{}{}
}
d.trigger.Add(c, ctx.Done())
return nil
}
func (*discoveryMock) Scan(ctx *context.T, query string) (<-chan discovery.Update, error) {
return nil, nil
}
func compare(t *testing.T, vService discovery.Service, mService mojom.Service) {
if !reflect.DeepEqual(vService.Addrs, mService.Addrs) {
t.Errorf("addrs not the same: %v, %v", vService.Addrs, mService.Addrs)
}
if vService.InterfaceName != mService.InterfaceName {
t.Errorf("interface name not the same: %v, %v", vService.InterfaceName, mService.InterfaceName)
}
if !reflect.DeepEqual(map[string]string(vService.Attrs), mService.Attrs) {
t.Errorf("attributes not the same: %v, %v", vService.Attrs, mService.Attrs)
}
}
func TestAdvertising(t *testing.T) {
ctx, shutdown := vtest.V23Init()
defer shutdown()
mock := &discoveryMock{
trigger: idiscovery.NewTrigger(),
services: map[int64]discovery.Service{},
deleteCh: make(chan struct{}),
}
s := NewDiscoveryService(ctx, mock)
testService := mojom.Service {
InterfaceName: "v.io/v23/discovery.T",
Attrs: map[string]string{
"key1": "value1",
"key2": "value2",
},
Addrs: []string{ "addr1", "addr2"},
}
id, e1, e2 := s.Advertise(testService, nil)
if e1 != nil || e2 != nil {
t.Fatalf("Failed to start service: %v, %v", e1, e2)
}
if len(mock.services) != 1 {
t.Errorf("service missing in mock")
}
for _, service := range mock.services {
compare(t, service, testService)
}
testService2 := mojom.Service {
InterfaceName: "v.io/v23/naming.T",
Attrs: map[string]string{
"key1": "value1",
"key2": "value2",
},
Addrs: []string{ "addr1", "addr2"},
}
_, e1, e2 = s.Advertise(testService2, nil)
if e1 != nil || e2 != nil {
t.Fatalf("Failed to start service: %v, %v", e1, e2)
}
s.StopAdvertising(id)
// Wait for the deletion to finish.
<-mock.deleteCh
if len(mock.services) != 1 {
t.Errorf("service should have been removed")
}
for _, service := range mock.services {
compare(t, service, testService2)
}
s.Stop()
<-mock.deleteCh
if len(mock.services) != 0 {
t.Errorf("service should have been removed")
}
}