blob: 50ab773b82bd4680972353c291324ce2470a89bf [file] [log] [blame]
// Copyright 2015 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 (
"io"
"reflect"
"sort"
"testing"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/naming"
"v.io/v23/rpc"
"v.io/x/ref/lib/stats"
irpc "v.io/x/ref/runtime/internal/rpc"
"v.io/x/ref/services/debug/debuglib"
"v.io/x/ref/test"
"v.io/x/ref/test/testutil"
)
func TestDebugServer(t *testing.T) {
ctx, shutdown := test.V23InitWithMounttable()
defer shutdown()
// Setup the client and server principals, with the client willing to share its
// blessing with the server.
var (
pclient = testutil.NewPrincipal()
cctx, _ = v23.WithPrincipal(ctx, pclient)
)
idp := testutil.IDProviderFromPrincipal(v23.GetPrincipal(ctx))
if err := idp.Bless(pclient, "client"); err != nil {
t.Fatal(err)
}
name := "testserver"
debugDisp := debuglib.NewDispatcher(nil)
_, _, err := v23.WithNewServer(ctx, name, &testObject{}, nil,
irpc.ReservedNameDispatcher{debugDisp})
if err != nil {
t.Fatal(err)
}
// Call the Foo method on ""
{
var value string
if err := v23.GetClient(cctx).Call(cctx, name, "Foo", nil, []interface{}{&value}); err != nil {
t.Fatalf("client.Call failed: %v", err)
}
if want := "BAR"; value != want {
t.Errorf("unexpected value: Got %v, want %v", value, want)
}
}
// Call Value on __debug/stats/testing/foo
{
foo := stats.NewString("testing/foo")
foo.Set("The quick brown fox jumps over the lazy dog")
fullname := naming.Join(name, "__debug/stats/testing/foo")
var value string
if err := v23.GetClient(cctx).Call(cctx, fullname, "Value", nil, []interface{}{&value}); err != nil {
t.Fatalf("client.Call failed: %v", err)
}
if want := foo.Value(); value != want {
t.Errorf("unexpected result: Got %v, want %v", value, want)
}
}
// Call Glob
testcases := []struct {
name, pattern string
expected []string
}{
{"", "*", []string{}},
{"", "__*", []string{"__debug"}},
{"", "__*/*", []string{"__debug/logs", "__debug/pprof", "__debug/stats", "__debug/vtrace"}},
{"__debug", "*", []string{"logs", "pprof", "stats", "vtrace"}},
}
for _, tc := range testcases {
fullname := naming.Join(name, tc.name)
call, err := v23.GetClient(ctx).StartCall(cctx, fullname, rpc.GlobMethod, []interface{}{tc.pattern})
if err != nil {
t.Fatalf("client.StartCall failed for %q: %v", tc.name, err)
}
results := []string{}
for {
var gr naming.GlobReply
if err := call.Recv(&gr); err != nil {
if err != io.EOF {
t.Fatalf("Recv failed for %q: %v. Results received thus far: %q", tc.name, err, results)
}
break
}
switch v := gr.(type) {
case naming.GlobReplyEntry:
results = append(results, v.Value.Name)
}
}
if err := call.Finish(); err != nil {
t.Fatalf("call.Finish failed for %q: %v", tc.name, err)
}
sort.Strings(results)
if !reflect.DeepEqual(tc.expected, results) {
t.Errorf("unexpected results for %q. Got %v, want %v", tc.name, results, tc.expected)
}
}
}
type testObject struct {
}
func (o testObject) Foo(*context.T, rpc.ServerCall) (string, error) {
return "BAR", nil
}