func TestRelease(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	p, q := pipetransport.New()
	if *logMessages {
		p = logtransport.New(nil, p)
	}
	c := rpc.NewConn(p)
	hf := new(HandleFactory)
	d := rpc.NewConn(q, rpc.MainInterface(testcapnp.HandleFactory_ServerToClient(hf).Client))
	defer d.Wait()
	defer c.Close()
	client := testcapnp.HandleFactory{Client: c.Bootstrap(ctx)}
	r, err := client.NewHandle(ctx, nil).Struct()
	if err != nil {
		t.Fatal("NewHandle:", err)
	}
	handle := r.Handle()
	if n := hf.numHandles(); n != 1 {
		t.Fatalf("numHandles = %d; want 1", n)
	}

	if err := handle.Client.Close(); err != nil {
		t.Error("handle.Client.Close():", err)
	}
	flushConn(ctx, c)

	if n := hf.numHandles(); n != 0 {
		t.Errorf("numHandles = %d; want 0", n)
	}
}
Beispiel #2
0
func TestCancel(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	p, q := pipetransport.New()
	if *logMessages {
		p = logtransport.New(nil, p)
	}
	c := rpc.NewConn(p)
	notify := make(chan struct{})
	hanger := testcapnp.Hanger_ServerToClient(Hanger{notify: notify})
	d := rpc.NewConn(q, rpc.MainInterface(hanger.Client))
	defer d.Wait()
	defer c.Close()
	client := testcapnp.Hanger{Client: c.Bootstrap(ctx)}

	subctx, subcancel := context.WithCancel(ctx)
	promise := client.Hang(subctx, func(r testcapnp.Hanger_hang_Params) error { return nil })
	<-notify
	subcancel()
	_, err := promise.Struct()
	<-notify // test will deadlock if cancel not delivered

	if err != context.Canceled {
		t.Errorf("promise.Get() error: %v; want %v", err, context.Canceled)
	}
}
Beispiel #3
0
func TestIssue3(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	p, q := pipetransport.New()
	if *logMessages {
		p = logtransport.New(nil, p)
	}
	log := testLogger{t}
	c := rpc.NewConn(p, rpc.ConnLog(log))
	echoSrv := testcapnp.Echoer_ServerToClient(new(SideEffectEchoer))
	d := rpc.NewConn(q, rpc.MainInterface(echoSrv.Client), rpc.ConnLog(log))
	defer d.Wait()
	defer c.Close()
	client := testcapnp.Echoer{Client: c.Bootstrap(ctx)}
	localCap := testcapnp.CallOrder_ServerToClient(new(CallOrder))
	echo := client.Echo(ctx, func(p testcapnp.Echoer_echo_Params) error {
		return p.SetCap(localCap)
	})

	// This should not deadlock.
	_, err := echo.Struct()
	if err != nil {
		t.Error("Echo error:", err)
	}
}
func TestPromisedCapability(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	p, q := pipetransport.New()
	if *logMessages {
		p = logtransport.New(nil, p)
	}
	c := rpc.NewConn(p)
	delay := make(chan struct{})
	echoSrv := testcapnp.Echoer_ServerToClient(&DelayEchoer{delay: delay})
	d := rpc.NewConn(q, rpc.MainInterface(echoSrv.Client))
	defer d.Wait()
	defer c.Close()
	client := testcapnp.Echoer{Client: c.Bootstrap(ctx)}

	echo := client.Echo(ctx, func(p testcapnp.Echoer_echo_Params) error {
		return p.SetCap(testcapnp.CallOrder{Client: client.Client})
	})
	pipeline := echo.Cap()
	call0 := callseq(ctx, pipeline.Client, 0)
	call1 := callseq(ctx, pipeline.Client, 1)
	close(delay)

	check := func(promise testcapnp.CallOrder_getCallSequence_Results_Promise, n uint32) {
		r, err := promise.Struct()
		if err != nil {
			t.Errorf("call%d error: %v", n, err)
		}
		if r.N() != n {
			t.Errorf("call%d = %d; want %d", n, r.N(), n)
		}
	}
	check(call0, 0)
	check(call1, 1)
}
Beispiel #5
0
func BenchmarkPingPong(b *testing.B) {
	p, q := pipetransport.New()
	if *logMessages {
		p = logtransport.New(nil, p)
	}
	log := testLogger{b}
	c := rpc.NewConn(p, rpc.ConnLog(log))
	d := rpc.NewConn(q, rpc.ConnLog(log), rpc.BootstrapFunc(bootstrapPingPong))
	defer d.Wait()
	defer c.Close()

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	client := testcapnp.PingPong{Client: c.Bootstrap(ctx)}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		promise := client.EchoNum(ctx, func(p testcapnp.PingPong_echoNum_Params) error {
			p.SetN(42)
			return nil
		})
		result, err := promise.Struct()
		if err != nil {
			b.Errorf("EchoNum(42) failed on iteration %d: %v", i, err)
			break
		}
		if result.N() != 42 {
			b.Errorf("EchoNum(42) = %d; want 42", result.N())
			break
		}
	}
}
Beispiel #6
0
func newTestConn(t *testing.T, options ...rpc.ConnOption) (*rpc.Conn, rpc.Transport) {
	p, q := pipetransport.New()
	if *logMessages {
		p = logtransport.New(nil, p)
	}
	c := rpc.NewConn(p, options...)
	return c, q
}
Beispiel #7
0
func newUnpairedConn(t *testing.T, options ...rpc.ConnOption) (*rpc.Conn, rpc.Transport) {
	p, q := pipetransport.New()
	if *logMessages {
		p = logtransport.New(nil, p)
	}
	newopts := make([]rpc.ConnOption, len(options), len(options)+1)
	copy(newopts, options)
	newopts = append(newopts, rpc.ConnLog(testLogger{t}))
	c := rpc.NewConn(p, newopts...)
	return c, q
}
func TestEmbargo(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	p, q := pipetransport.New()
	if *logMessages {
		p = logtransport.New(nil, p)
	}
	log := testLogger{t}
	c := rpc.NewConn(p, rpc.ConnLog(log))
	echoSrv := testcapnp.Echoer_ServerToClient(new(Echoer))
	d := rpc.NewConn(q, rpc.MainInterface(echoSrv.Client), rpc.ConnLog(log))
	defer d.Wait()
	defer c.Close()
	client := testcapnp.Echoer{Client: c.Bootstrap(ctx)}
	localCap := testcapnp.CallOrder_ServerToClient(new(CallOrder))

	earlyCall := callseq(ctx, client.Client, 0)
	echo := client.Echo(ctx, func(p testcapnp.Echoer_echo_Params) error {
		return p.SetCap(localCap)
	})
	pipeline := echo.Cap()
	call0 := callseq(ctx, pipeline.Client, 0)
	call1 := callseq(ctx, pipeline.Client, 1)
	_, err := earlyCall.Struct()
	if err != nil {
		t.Errorf("earlyCall error: %v", err)
	}
	call2 := callseq(ctx, pipeline.Client, 2)
	_, err = echo.Struct()
	if err != nil {
		t.Errorf("echo.Get() error: %v", err)
	}
	call3 := callseq(ctx, pipeline.Client, 3)
	call4 := callseq(ctx, pipeline.Client, 4)
	call5 := callseq(ctx, pipeline.Client, 5)

	check := func(promise testcapnp.CallOrder_getCallSequence_Results_Promise, n uint32) {
		r, err := promise.Struct()
		if err != nil {
			t.Errorf("call%d error: %v", n, err)
		}
		if r.N() != n {
			t.Errorf("call%d = %d; want %d", n, r.N(), n)
		}
	}
	check(call0, 0)
	check(call1, 1)
	check(call2, 2)
	check(call3, 3)
	check(call4, 4)
	check(call5, 5)
}
Beispiel #9
0
func TestReleaseAlias(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	p, q := pipetransport.New()
	if *logMessages {
		p = logtransport.New(nil, p)
	}
	c := rpc.NewConn(p)
	hf := singletonHandleFactory()
	d := rpc.NewConn(q, rpc.MainInterface(testcapnp.HandleFactory_ServerToClient(hf).Client))
	defer d.Wait()
	defer c.Close()
	client := testcapnp.HandleFactory{Client: c.Bootstrap(ctx)}
	r1, err := client.NewHandle(ctx, func(r testcapnp.HandleFactory_newHandle_Params) error { return nil }).Struct()
	if err != nil {
		t.Fatal("NewHandle #1:", err)
	}
	handle1 := r1.Handle()
	r2, err := client.NewHandle(ctx, func(r testcapnp.HandleFactory_newHandle_Params) error { return nil }).Struct()
	if err != nil {
		t.Fatal("NewHandle #2:", err)
	}
	handle2 := r2.Handle()
	if n := hf.numHandles(); n != 1 {
		t.Fatalf("after creation, numHandles = %d; want 1", n)
	}

	if err := handle1.Client.Close(); err != nil {
		t.Error("handle1.Client.Close():", err)
	}
	flushConn(ctx, c)
	if n := hf.numHandles(); n != 1 {
		t.Errorf("after handle1.Client.Close(), numHandles = %d; want 1", n)
	}
	if err := handle2.Client.Close(); err != nil {
		t.Error("handle2.Client.Close():", err)
	}
	flushConn(ctx, c)
	if n := hf.numHandles(); n != 0 {
		t.Errorf("after handle1.Close() and handle2.Close(), numHandles = %d; want 0", n)
	}
}