Improving the reliability of interfaces is a crucial aspect regarding the quality and predictability of complex software systems. You might know that situation from your daily work pretty well. Although you have full test coverage of your interfaces, your application does not behave as expected when integrating all components to form an entire system.
This is because the client in production might use the interface in a different way than in your test implementation.
In this blog post we show how you can retrace and validate the correct usage of your interfaces, starting from the formal specification up to the invocation at runtime. In order to approach this challenge we are combining two methods respectively tools: Franca for modeling interfaces (see Part 1 of our series) and EB solys for validating the interface usage at runtime (see Part 2 of our series).
Setting up an example scenario
We demonstrate the methodology based on a simple music player application. It consists of a client which is running in a browser and a service which is implemented as a web-service.
The communication between client and server is based on websockets and the application logging is done via log4js. The entire ecosystem runs in a Linux virtual machine.
Defining the Franca Interface
First we define our service interface with Franca IDL. The interface contains simple methods for searching, playing and pausing tracks.
This allows us to generate source code that is used for both the service and the client as well as for the message passing in between: The MusicPlayerProxy is used by the client to invoke the corresponding function on the server. The MusicPlayerStub resides in the service and retrieves the request sent from the client. Both the proxy and the stub are generated in a way to use the WAMP/Websocket protocol. Incoming requests on server side are automatically logged with the log4js framework.
Capturing runtime data with EB solys
Next we configure EB solys in order to be able to monitor the runtime calls between the client and the server. The network sniffer plugin hooks into the network stream and collects websocket messages while the logging sniffer plugin reads continuously log4js traces. With that we are able to monitor the exchanged messages on protocol level as well as on application level.
Defining the Franca contract
In addition to the static elements of our interface (methods and data types) we will also define its dynamic behavior by means of a protocol state machine or contract. This allows to specify exactly what order of events is allowed on any implementation of this interface. Every sequence which is not covered by the protocol state machine is violating the contract.
Identifying and visualizing interface violations
The Franca interface (including its contract) can be loaded and utilized by EB solys. Therefore, we now have everything in place to check if the methods of the service interface are invoked in the expected order from the client or not.
The HMI of the example application is faulty on purpose, i.e. it allows all service interface calls at any time, which might break the contract, because this is what we want to identify.
We first search a track named “Let it be”, then press the play button and afterwards the pause button. So far the service is used as intended.
We are now in the state TrackSelected where we could play the track again or search for a new track. Instead we press pause again which obviously breaks the contract.
With EB solys we are able to identify that interface misuse by highlighting the corrupted state together with the message that causes the failure.
As we have seen there are obviously some rules or conventions beyond the static description of software interfaces. But these rules are usually not defined at all or they are documented alongside the interface definition, e.g. in requirement documents as plain text or as sequence diagrams. This has significant drawbacks: Plain text cannot be exploited by automatic tools at all – sequence diagrams can only represent single examples of allowed or prohibited behavior.
By experience rectifying this type of error is costly, since often, a large number of developers from different suppliers are involved in searching for the error and reproducing it. It becomes even more critical in case of safety and security relevant functions.
However Franca contracts in combination with the runtime analysis capabilities of EB solys allows you the localization of misused interfaces fast and automatically. You don’t even have the need to instrument your source code for finding the issues.
It helps you saving time and resources and makes your software more robust and predictable.