blob: 8b2422bde1d724051be9954e31d860c569bc4e1e [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package test
import (
"bytes"
"reflect"
"testing"
"v.io/v23/context"
"v.io/v23/discovery"
"v.io/v23/rpc"
"v.io/v23/security"
idiscovery "v.io/x/ref/lib/discovery"
"v.io/x/ref/lib/discovery/plugins/mock"
"v.io/x/ref/lib/discovery/testutil"
"v.io/x/ref/runtime/factories/fake"
"v.io/x/ref/test"
)
func TestDirectoryBasic(t *testing.T) {
ctx, shutdown := test.V23Init()
defer shutdown()
var dirServer idiscovery.DirectoryServerStub
mockServer := testutil.NewMockServer(testutil.ToEndpoints("addr:123"))
ctx = fake.SetServerFactory(ctx, func(_ *context.T, _ string, impl interface{}, _ security.Authorizer, _ ...rpc.ServerOpt) (*context.T, rpc.Server) {
dirServer = impl.(idiscovery.DirectoryServerStub)
return ctx, mockServer
})
df, err := idiscovery.NewFactory(ctx, mock.New())
if err != nil {
t.Fatal(err)
}
defer df.Shutdown()
ad := discovery.Advertisement{
InterfaceName: "v.io/v23/a",
Addresses: []string{"/h1:123/x"},
Attachments: discovery.Attachments{"a": []byte{1, 2, 3}},
}
d1, err := df.New(ctx)
if err != nil {
t.Fatal(err)
}
stop, err := testutil.Advertise(ctx, d1, nil, &ad)
if err != nil {
t.Fatal(err)
}
// The directory server should serve the advertisement.
fetched, err := dirServer.Lookup(ctx, nil, ad.Id)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(fetched.Ad, ad) {
t.Errorf("got %v, but wanted %v", fetched.Ad, ad)
}
attachment, err := dirServer.GetAttachment(ctx, nil, ad.Id, "a")
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(attachment, ad.Attachments["a"]) {
t.Errorf("got %v, but wanted %v", attachment, ad.Attachments["a"])
}
attachment, err = dirServer.GetAttachment(ctx, nil, ad.Id, "b")
if err != nil {
t.Fatal(err)
}
if attachment != nil {
t.Errorf("got %v, but wanted %v", attachment, nil)
}
// Stop advertising; Shouldn't be served by the directory server.
stop()
if _, err = dirServer.Lookup(ctx, nil, ad.Id); err == nil {
t.Error("expected an error, but got none")
}
if _, err = dirServer.GetAttachment(ctx, nil, ad.Id, "a"); err == nil {
t.Error("expected an error, but got none")
}
}
func TestDirectoryRoaming(t *testing.T) {
ctx, shutdown := test.V23Init()
defer shutdown()
var dirServer idiscovery.DirectoryServerStub
eps := testutil.ToEndpoints("addr:123")
mockServer := testutil.NewMockServer(eps)
ctx = fake.SetServerFactory(ctx, func(_ *context.T, _ string, impl interface{}, _ security.Authorizer, _ ...rpc.ServerOpt) (*context.T, rpc.Server) {
dirServer = impl.(idiscovery.DirectoryServerStub)
return ctx, mockServer
})
mockPlugin := mock.NewWithAdStatus(idiscovery.AdPartiallyReady)
df, err := idiscovery.NewFactory(ctx, mockPlugin)
if err != nil {
t.Fatal(err)
}
defer df.Shutdown()
ad := discovery.Advertisement{
InterfaceName: "v.io/v23/a",
Addresses: []string{"/h1:123/x"},
}
d1, err := df.New(ctx)
if err != nil {
t.Fatal(err)
}
stop, err := testutil.Advertise(ctx, d1, nil, &ad)
if err != nil {
t.Fatal(err)
}
defer stop()
d2, err := df.New(ctx)
if err != nil {
t.Fatal(err)
}
// Open a new scan channel and consume expected advertisements first.
scanCh, scanStop, err := testutil.Scan(ctx, d2, ``)
if err != nil {
t.Fatal(err)
}
defer scanStop()
update := <-scanCh
if !testutil.MatchFound(ctx, []discovery.Update{update}, ad) {
t.Errorf("unexpected scan: %v", update)
}
fetched, err := dirServer.Lookup(ctx, nil, ad.Id)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(testutil.ToEndpoints(fetched.DirAddrs...), eps) {
t.Errorf("got %v, but wanted %v", testutil.ToEndpoints(fetched.DirAddrs...), eps)
}
updateCh := make(chan *idiscovery.AdInfo)
callback := func(ad *idiscovery.AdInfo) {
select {
case updateCh <- ad:
case <-ctx.Done():
}
}
if err = mockPlugin.Scan(ctx, "", callback, func() {}); err != nil {
t.Fatal(err)
}
<-updateCh
eps = testutil.ToEndpoints("addr:456")
mockServer.UpdateNetwork(eps)
// Wait until the address change is applied
for {
adinfo := <-updateCh
if reflect.DeepEqual(testutil.ToEndpoints(adinfo.DirAddrs...), eps) {
break
}
}
// Make sure that a new advertisement is published.
update = <-scanCh
if !testutil.MatchLost(ctx, []discovery.Update{update}, ad) {
t.Errorf("unexpected scan: %v", update)
}
update = <-scanCh
if !testutil.MatchFound(ctx, []discovery.Update{update}, ad) {
t.Errorf("unexpected scan: %v", update)
}
fetched, err = dirServer.Lookup(ctx, nil, ad.Id)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(testutil.ToEndpoints(fetched.DirAddrs...), eps) {
t.Errorf("got %v, but wanted %v", testutil.ToEndpoints(fetched.DirAddrs...), eps)
}
}