| // Copyright 2018 The Fuchsia 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 fidl_test |
| |
| import ( |
| "fmt" |
| "reflect" |
| "strings" |
| "syscall/zx" |
| "syscall/zx/fidl" |
| "syscall/zx/fidl/internal/bindingstest" |
| "testing" |
| ) |
| |
| var testCtx fidl.MarshalerContext |
| |
| type example struct { |
| name string |
| input fidl.Message |
| expectSize int |
| } |
| |
| // general provides test cases used to verify correctness, and |
| // benchmark against. |
| // |
| // Keep these as a slice to preserve consistent ordering when running. |
| func general() []example { |
| h0, h1, err := zx.NewChannel(0) |
| if err != nil { |
| panic(fmt.Sprintf("failed to create channel: %s", err)) |
| } |
| defer func() { |
| if err := h0.Close(); err != nil { |
| panic(fmt.Sprintf("failed to close channel: %s", err)) |
| } |
| if err := h1.Close(); err != nil { |
| panic(fmt.Sprintf("failed to close channel: %s", err)) |
| } |
| }() |
| |
| return []example{ |
| // TODO(https://fxbug.dev/7832): Here we're checking the special logic adapting channels to |
| // `request<P>` or `P` representations. This is not supported by GIDL yet. |
| {"interface1", &bindingstest.TestInterface1{ |
| A: bindingstest.Test1WithCtxInterface(fidl.ChannelProxy{Channel: h0}), |
| B: bindingstest.Test1WithCtxInterface(fidl.ChannelProxy{Channel: zx.Channel(zx.HandleInvalid)}), |
| C: bindingstest.Test1WithCtxInterfaceRequest(fidl.InterfaceRequest{Channel: h1}), |
| D: bindingstest.Test1WithCtxInterfaceRequest(fidl.InterfaceRequest{ |
| Channel: zx.Channel(zx.HandleInvalid), |
| }), |
| }, 16}, |
| } |
| } |
| |
| func check(t *testing.T, input fidl.Message, expectSize int) { |
| t.Helper() |
| var respb [zx.ChannelMaxMessageBytes]byte |
| var resphd [zx.ChannelMaxMessageHandles]zx.HandleDisposition |
| nb, nh, err := fidl.Marshal(testCtx, input, respb[:], resphd[:]) |
| if err != nil { |
| t.Fatalf("marshal: failed: %s", err) |
| } |
| if nb != expectSize { |
| t.Fatalf("marshal: expected size %d but got %d: %s", expectSize, nb, respb[:nb]) |
| } |
| var resphi [zx.ChannelMaxMessageHandles]zx.HandleInfo |
| for i := 0; i < nh; i++ { |
| resphi[i] = zx.HandleInfo{ |
| Handle: resphd[i].Handle, |
| Type: resphd[i].Type, |
| Rights: resphd[i].Rights, |
| } |
| } |
| output := makeDefault(reflect.TypeOf(input)) |
| err = fidl.Unmarshal(testCtx, respb[:nb], resphi[:nh], output) |
| if err != nil { |
| t.Fatalf("unmarshal: failed: %s", err) |
| } |
| if !reflect.DeepEqual(input, output) { |
| t.Fatalf("unmarshal: expected: %#v, got: %#v", input, output) |
| } |
| } |
| |
| func TestCorrectness(t *testing.T) { |
| for _, ex := range general() { |
| t.Run(ex.name, func(t *testing.T) { |
| check(t, ex.input, ex.expectSize) |
| }) |
| } |
| } |
| |
| // This is a specific test checking that the marshaler construction properly |
| // fails with a clear error message if fed incorrect generated code. Hence, |
| // this has to stay a hand written test. |
| func TestFailureNullableTable(t *testing.T) { |
| type TestNullableTable struct { |
| _ struct{} `fidl:"s"` |
| A *bindingstest.SimpleTable `fidl:"0" fidl_offset_v2:"0"` |
| } |
| _, err := fidl.CreateMarshaler(TestNullableTable{}) |
| if err == nil { |
| t.Fatalf("expected error creating marshaler for nullable table") |
| } |
| if !strings.Contains(err.Error(), "optional field marshaler") { |
| t.Fatalf("unexpected error: %s", err.Error()) |
| } |
| } |
| |
| // TODO(https://fxbug.dev/62647): Move to GIDL once we support protocol handles. |
| func TestConformanceClientEnd(t *testing.T) { |
| successCase{ |
| name: "handles-clientend", |
| context: testCtx, |
| input: &bindingstest.HasClientEnd{ |
| ClientEnd: bindingstest.ExampleProtocolWithCtxInterface(fidl.ChannelProxy{ |
| Channel: zx.Channel(0x44332211), |
| }), |
| }, |
| bytes: []byte{ |
| 0xff, 0xff, 0xff, 0xff, // handle present |
| 0x00, 0x00, 0x00, 0x00, // padding |
| }, |
| handleInfos: []zx.HandleInfo{ |
| { |
| Handle: zx.Handle(0x44332211), |
| Rights: fidl.ProtocolRights, |
| Type: zx.ObjTypeChannel, |
| }, |
| }, |
| checkRights: true, |
| }.check(t) |
| } |
| |
| // TODO(https://fxbug.dev/62647): Move to GIDL once we support protocol handles. |
| func TestConformanceServerEnd(t *testing.T) { |
| successCase{ |
| name: "handles-serverend", |
| context: testCtx, |
| input: &bindingstest.HasServerEnd{ |
| ServerEnd: bindingstest.ExampleProtocolWithCtxInterfaceRequest(fidl.InterfaceRequest{ |
| Channel: zx.Channel(0x44332211), |
| }), |
| }, |
| bytes: []byte{ |
| 0xff, 0xff, 0xff, 0xff, // handle present |
| 0x00, 0x00, 0x00, 0x00, // padding |
| }, |
| handleInfos: []zx.HandleInfo{ |
| { |
| Handle: zx.Handle(0x44332211), |
| Rights: fidl.ProtocolRights, |
| Type: zx.ObjTypeChannel, |
| }, |
| }, |
| checkRights: true, |
| }.check(t) |
| } |