Exemplo n.º 1
0
// Invoke calls the mojom service based on the suffix and converts the mojom
// results (a struct) to Vanadium results (a slice of *vom.RawBytes).
// Note: The argptrs from Prepare are reused here. The vom bytes should have
// been decoded into these argptrs, so there are actual values inside now.
func (fs fakeService) Invoke(ctx *context.T, call rpc.StreamServerCall, method string, argptrs []interface{}) (results []interface{}, _ error) {
	// fs.suffix consists of the mojo url and the application/interface name.
	// The last part should be the name; everything else is the url.
	parts := strings.Split(fs.suffix, "/")
	mojourl := strings.Join(parts[:len(parts)-1], "/") // e.g., mojo:go_remote_echo_server. May be defined in a BUILD.gn file.
	mojoname := parts[len(parts)-1]                    // e.g., mojo::examples::RemoteEcho. Defined from the interface + module.

	// Create the generic message pipe. r is a bindings.InterfaceRequest, and
	// p is a bindings.InterfacePointer.
	r, p := bindings.CreateMessagePipeForMojoInterface()
	v := v23ServiceRequest{
		request: r,
		name:    mojoname,
	} // v is an application.ServiceRequest with mojoname

	// Connect to the mojourl.
	fs.appctx.ConnectToApplication(mojourl).ConnectToService(&v)

	// Then assign a new router the FakeService.
	// This will never conflict because each FakeService is only invoked once.
	fs.router = bindings.NewRouter(p.PassMessagePipe(), bindings.GetAsyncWaiter())
	defer fs.Close_Proxy()

	ctx.Infof("Fake Service Invoke (Remote Signature: %q -- %q)", mojourl, mojoname)

	// Vanadium relies on type information, so we will retrieve that first.
	mojomInterface, desc, err := fs.callRemoteSignature(mojourl, mojoname)
	if err != nil {
		return nil, err
	}

	ctx.Infof("Fake Service Invoke Signature %v", mojomInterface)
	ctx.Infof("Fake Service Invoke (Remote Method: %v)", method)

	// With the type information, we can make the method call to the remote interface.
	methodResults, err := fs.callRemoteMethod(ctx, method, mojomInterface, desc, argptrs)
	if err != nil {
		ctx.Errorf("Method called failed: %v", err)
		return nil, err
	}

	ctx.Infof("Fake Service Invoke Results %v", methodResults)

	// Convert methodResult to results.
	results = make([]interface{}, len(methodResults))
	for i := range methodResults {
		results[i] = &methodResults[i]
	}
	return results, nil
}
Exemplo n.º 2
0
func TestAccept(t *testing.T) {
	r, h0, h1 := core.CreateMessagePipe(nil)
	defer h1.Close()
	if r != system.MOJO_RESULT_OK {
		t.Fatalf("can't create a message pipe: %v", r)
	}
	router := bindings.NewRouter(h0, bindings.GetAsyncWaiter())
	header := bindings.MessageHeader{0, 0, 0}
	if err := router.Accept(encodeMessage(header, &header)); err != nil {
		t.Fatal(err)
	}
	header = bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, 1}
	err := router.Accept(encodeMessage(header, &header))
	expectError(t, "message header should have a zero request ID", err)
	router.Close()
}
Exemplo n.º 3
0
func TestAcceptWithResponseMultiple(t *testing.T) {
	r, h0, h1 := core.CreateMessagePipe(nil)
	defer h1.Close()
	if r != system.MOJO_RESULT_OK {
		t.Fatalf("can't create a message pipe: %v", r)
	}
	router := bindings.NewRouter(h0, bindings.GetAsyncWaiter())
	var wg sync.WaitGroup
	wg.Add(numberOfRequests + 1)
	// Serve requests.
	go func() {
		for i := 0; i < numberOfRequests; i++ {
			c := make(chan bindings.WaitResponse, 1)
			bindings.GetAsyncWaiter().AsyncWait(h1, system.MOJO_HANDLE_SIGNAL_READABLE, c)
			r, bytes, handles := h1.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE)
			if r != system.MOJO_RESULT_OK {
				t.Fatalf("can't read from a message pipe: %v", r)
			}
			r = h1.WriteMessage(bytes, handles, system.MOJO_WRITE_MESSAGE_FLAG_NONE)
			if r != system.MOJO_RESULT_OK {
				t.Fatalf("can't write to a message pipe: %v", r)
			}
		}
		wg.Done()
	}()
	// Send concurrent requests.
	for i := 0; i < numberOfRequests; i++ {
		go func(i int) {
			header := bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, uint64(i + 1)}
			err := (<-router.AcceptWithResponse(encodeMessage(header, &header))).Error
			if err != nil {
				panic(err)
			}
			wg.Done()
		}(i)
	}
	wg.Wait()
	router.Close()
}
Exemplo n.º 4
0
func TestClose(t *testing.T) {
	r, h0, h1 := core.CreateMessagePipe(nil)
	defer h1.Close()
	if r != system.MOJO_RESULT_OK {
		t.Fatalf("can't create a message pipe: %v", r)
	}
	router := bindings.NewRouter(h0, bindings.GetAsyncWaiter())
	var wg sync.WaitGroup
	wg.Add(numberOfRequests*2 + 1)

	// Send requests from the same go routine.
	for i := 0; i < numberOfRequests; i++ {
		header := bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, uint64(i + 1)}
		c := router.AcceptWithResponse(encodeMessage(header, &header))
		go func() {
			if err := (<-c).Error; err == nil {
				panic("unexpected nil error")
			}
			wg.Done()
		}()
	}
	// Send requests from different go routines.
	for i := 0; i < numberOfRequests; i++ {
		go func(i int) {
			header := bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, uint64(i + 1)}
			err := (<-router.AcceptWithResponse(encodeMessage(header, &header))).Error
			if err == nil {
				panic("unexpected nil error")
			}
			wg.Done()
		}(i + numberOfRequests)
	}
	go func() {
		router.Close()
		wg.Done()
	}()
	wg.Wait()
}