blob: 4257409a089a0aa6318c36afbb1868a7c0c878c0 [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 xproxyd_test
import (
"bufio"
"strings"
"testing"
_ "v.io/x/ref/runtime/factories/generic"
"v.io/x/ref/services/xproxyd"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/flow"
"v.io/v23/naming"
"v.io/v23/rpc"
"v.io/v23/security"
)
func TestProxiedConnection(t *testing.T) {
pctx, shutdown := v23.Init()
defer shutdown()
actx, am, err := v23.ExperimentalWithNewFlowManager(pctx)
if err != nil {
t.Fatal(err)
}
dctx, dm, err := v23.ExperimentalWithNewFlowManager(pctx)
if err != nil {
t.Fatal(err)
}
pep := startProxy(t, pctx, address{"tcp", "127.0.0.1:0"})
if err := am.Listen(actx, "v23", pep.String()); err != nil {
t.Fatal(err)
}
testEndToEndConnections(t, dctx, actx, dm, am)
}
func TestMultipleProxies(t *testing.T) {
pctx, shutdown := v23.Init()
defer shutdown()
p2ctx, _, err := v23.ExperimentalWithNewFlowManager(pctx)
if err != nil {
t.Fatal(err)
}
p3ctx, _, err := v23.ExperimentalWithNewFlowManager(pctx)
if err != nil {
t.Fatal(err)
}
actx, am, err := v23.ExperimentalWithNewFlowManager(pctx)
if err != nil {
t.Fatal(err)
}
dctx, dm, err := v23.ExperimentalWithNewFlowManager(pctx)
if err != nil {
t.Fatal(err)
}
pep := startProxy(t, pctx, address{"tcp", "127.0.0.1:0"})
p2ep := startProxy(t, p2ctx, address{"v23", pep.String()}, address{"tcp", "127.0.0.1:0"})
p3ep := startProxy(t, p3ctx, address{"v23", p2ep.String()}, address{"tcp", "127.0.0.1:0"})
if err := am.Listen(actx, "v23", p3ep.String()); err != nil {
t.Fatal(err)
}
testEndToEndConnections(t, dctx, actx, dm, am)
}
func testEndToEndConnections(t *testing.T, dctx, actx *context.T, dm, am flow.Manager) {
aeps := am.ListeningEndpoints()
if len(aeps) == 0 {
t.Fatal("acceptor not listening on any endpoints")
}
for _, aep := range aeps {
testEndToEndConnection(t, dctx, actx, dm, am, aep)
}
}
func testEndToEndConnection(t *testing.T, dctx, actx *context.T, dm, am flow.Manager, aep naming.Endpoint) {
// The dialing flow.Manager dials a flow to the accepting flow.Manager.
want := "Do you read me?"
df, err := dm.Dial(dctx, aep, bfp)
if err != nil {
t.Fatal(err)
}
// We write before accepting to ensure that the openFlow message is sent.
writeLine(df, want)
af, err := am.Accept(actx)
if err != nil {
t.Fatal(err)
}
got, err := readLine(af)
if err != nil {
t.Fatal(err)
}
if got != want {
t.Errorf("got %v, want %v", got, want)
}
// Writes in the opposite direction should work as well.
want = "I read you loud and clear."
writeLine(af, want)
got, err = readLine(df)
if err != nil {
t.Fatal(err)
}
if got != want {
t.Errorf("got %v, want %v", got, want)
}
}
// TODO(suharshs): Add test for bidirectional RPC.
func readLine(f flow.Flow) (string, error) {
s, err := bufio.NewReader(f).ReadString('\n')
return strings.TrimRight(s, "\n"), err
}
func writeLine(f flow.Flow, data string) error {
data += "\n"
_, err := f.Write([]byte(data))
return err
}
func bfp(
ctx *context.T,
localEndpoint, remoteEndpoint naming.Endpoint,
remoteBlessings security.Blessings,
remoteDischarges map[string]security.Discharge,
) (security.Blessings, map[string]security.Discharge, error) {
return v23.GetPrincipal(ctx).BlessingStore().Default(), nil, nil
}
type address struct {
Protocol, Address string
}
func startProxy(t *testing.T, ctx *context.T, addrs ...address) naming.Endpoint {
var ls rpc.ListenSpec
for _, addr := range addrs {
ls.Addrs = append(ls.Addrs, addr)
}
ctx = v23.WithListenSpec(ctx, ls)
proxy, err := xproxyd.New(ctx)
if err != nil {
t.Fatal(err)
}
peps := proxy.ListeningEndpoints()
for _, pep := range peps {
if pep.Addr().Network() == "tcp" {
return pep
}
}
t.Fatal("Proxy not listening on network address.")
return nil
}