blob: 266af85b661f8d754cb72b1501863e4d6775e48b [file] [log] [blame] [view]
# FIDL compatibility test
The FIDL compatibility test is an integration test for compatibility of
different FIDL bindings.
## How it works
- A "host" server, written in HLCPP, starts "language servers" in each of the
languages that have FIDL bindings for.
- The host server is only implemented in HLCPP.
How `compatibility_test` does testing:
1. The host server sends a message to language server 1.
2. Language server 1 forwards that message to language server 2.
3. Language server 2 echoes the message back to language server 1.
4. Language server 1 sends the message back to the host.
In short, `compatibility_test` sends messages in the following way:
host to language server 1, then to language server 2, then back to language
server 1, and finally back to the host
The message that is sent is a huge FIDL struct that is designed to exercise
encoding and decoding of every FIDL data type. See
`compatibility_service.test.fidl` for the entry point.
By default, compatibility_test will set up every possible combination of pairs
of language servers defined.
For a test instance, there is:
- HLCPP host server
- Language server 1
- Language server 2
So, if the language list is Go, Dart, and Rust, the following combinations of
servers will be tested:
- HLCPP and Go, Go and Dart
- HLCPP and Dart, Dart and Go
- HLCPP and Go, Go and Rust
- HLCPP and Rust, Rust and Go
- HLCPP and Dart, Dart and Rust
- HLCPP and Rust, Rust and Dart
The basic logic for the test is along the lines of:
```python
servers = ['go_server', 'cc_server', ...]
for proxy_name in servers:
for server_name in servers:
proxy = <connect to proxy>
struct = <construct complicated struct>
resp = proxy.EchoStruct(struct, server_name)
assert_equal(struct, resp)
```
Servers should implement the service defined in
`compatibility_service.test.fidl` with logic along the lines of:
```python
def EchoStruct(
Struct value, string forward_to_server, EchoStructCallback callback):
if value.forward_to_server:
other_server = <start server with LaunchPad>
# set forward_to_server to "" to prevent recursion
other_server.EchoStruct(value, "", callback)
else:
callback(value)
```
The logic for `EchoStructNoRetVal()` is similar. Instead of waiting for a
response directly, the test waits to receive an `EchoEvent()`. And instead of
calling the client back directly, the server sends the `EchoEvent()`.
The code for the compatibility tests are located at
`src/tests/fidl/compatibility`. It contains FIDL definitions and the server
implementations for Dart, HLCPP, LLCPP, Rust, and Go.
The test runner and all of the test server components are in a single package,
`fuchsia-pkg://fuchsia.com/fidl-compatibility-test`.
## Running
Beacuse individual tests have timeouts the test is split across 5 different
components in the same package:
- `fuchsia-pkg://fuchsia.com/fidl-compatibility-test#meta/fidl_compatibility_test_struct.cmx`
- `fuchsia-pkg://fuchsia.com/fidl-compatibility-test#meta/fidl_compatibility_test_array.cmx`
- `fuchsia-pkg://fuchsia.com/fidl-compatibility-test#meta/fidl_compatibility_test_vector.cmx`
- `fuchsia-pkg://fuchsia.com/fidl-compatibility-test#meta/fidl_compatibility_test_table.cmx`
- `fuchsia-pkg://fuchsia.com/fidl-compatibility-test#meta/fidl_compatibility_test_union.cmx`
They all invoke the same test runner but use a `--gtest_filter` argument to filter which
tests are run.
To run all of the tests:
```sh
fx test fidl_compatibility_test
```
Or to run a specific test:
```sh
fx test "fuchsia-pkg://fuchsia.com/fidl-compatibility-test#meta/fidl_compatibility_test_struct.cmx"
```
And if you want to run a specific test case:
```sh
fx test "fuchsia-pkg://fuchsia.com/fidl-compatibility-test#meta/fidl_compatibility_test_struct.cmx" \
-- --gtest_filter=Struct.EchoStructNoRetval
```
## Debugging
There are virtually no debugging messages apart from "failed" when one of the
language bindings fails to decode a message, which means that a lot of patching
in language bindings to dump the raw wire format bytes or a tool like
`fidlcat` is required to troubleshoot. A language binding failing decoding may
be due to a bug in the decoder of the receiver or a bug in the encoder in the
sender.
To use `fidlcat`:
```
fx fidlcat --remote-name=fidl
```
Then, run `compatibility_test`. Note: `fidlcat` will block until
`compatibility_test` is launched.