Testing the Midi Kit

Most of the Haiku source code has unit tests in the current/src/tests directory. I looked into building CppUnit tests for the midi2 kit, but decided that it doesn’t really make much sense. Unit tests work best if you can test something in isolation, but in the case of the midi2 kit this is very hard to achieve. Because the classes from libmidi2.so always need to talk to the midi_server, the tests depend on too many external factors. The available endpoints, for example, will differ from system to system. The spray and hook functions are difficult to test this way, too.

So instead of a CppUnit test suite, here is a list of manual tests that I performed when developing the midi2 kit:

======================================================================

Registering the application

*Required:* Client app that calls BMidiRoster::MidiRoster()

======================================================================

Creating endpoints

*Required:* Client app that creates a new BMidiLocalProducer and/or BMidiLocalConsumer

======================================================================

Deleting endpoints

*Required:* client app that creates one or more endpoints and Release()’s them

======================================================================

Changing attributes

*Required:* Client app that creates an endpoint and calls Register(), Unregister(), SetName(), and SetLatency()

======================================================================

Consulting the roster

*Required:* Client app that creates several endpoints, and registers some of them (not all), and uses the BMidiRoster::FindEndpoint() etc functions to examine the roster.

Verify that FindEndpoint() returns a valid BMidiEndpoint object if you pass it:

======================================================================

Making/breaking connections

*Required:* Client app that creates a producer and consumer endpoint, optionally registers them, consults the roster for remote endpoints, and makes various kinds of connections.

======================================================================

Watching

*Required:* Client app that creates local consumer and producer endpoints, and calls Register(), Unregister(), SetName(), SetLatency(), and SetProperties(). It should also make and break connections.

======================================================================

Event tests

*Required:* Several client apps that create and register consumer endpoints that override the various MIDI event hook functions, as well as producer endpoints that spray MIDI events. Also useful is a tool that lets you make connections between all these endpoints (PatchBay), and a tool that lets you monitor the MIDI events (MidiMonitor).

======================================================================

Other tests

*Required:* Client app that creates a new endpoint and registers it. In the app’s destructor, it unregisters and releases the endpoint.

*How to reproduce:* Run the app from two different Terminals. Ctrl-C app1. Start app1 again. From the Deskbar quit both apps at the same time (that is possible because app1 and app2 both have the same signature). When it tries to send the Unregister() request to the midi_server, app2 gives the error “Cannot send msg to server”. The error code is “Bad Port ID”, which means that the reply port is dead. The Mdel message from Release() is sent without any problems, however, because that expects no reply back. This is not the only way to reproduce the problem, but it seems to be the most reliable one.

The reason this happens is because you kill app1. When app2 sends a synchronous request to the midi_server, the server re-used that same message to notify the other apps. (Because it already contained all the necessary fields.) But app1 is dead, the notification fails, and this (probably) wipes out the reply address in the message. I changed the midi_server to create new BMessages for the notifications, and was no longer able to reproduce the problem.