openSUSE:WebYaST Testing/D-Bus

Jump to: navigation, search

Writing tests involving D-Bus

Following the Don't access the system conventions, here's how to simulate D-Bus calls when writing WebYaST tests.

[ Reference: Riding the D-Bus with Ruby ]

A short reminder of D-Bus 'speak'

Terms you need to know: Bus, Service, Object, Interface, Proxy

At its core, D-Bus offers 'remote procedure calls' in an object-oriented way.

A Service has Objects implementing Interfaces (set of functions).

Services are identified by dotted notation, i.e. "org.freedesktop.Hal"

Interfaces also have dotted notation, i.e. "org.freedesktop.Hal.Device.Storage.Removable"

Objects are identified by slashed notation, i.e. "/org/freedesktop/Hal/devices/storage_model_DVDRW_LH_20A1S"

Services are available globally (through the System bus) or locally (Session bus)

Since objects live 'on the other side' of D-Bus, you need to transfer a function call through D-Bus to the remote object.

This is greatly simplified by Proxy objects. A proxy is an object living on 'your' side of the D-Bus pretending to be the real thing. Internally, it is sending all function calls via D-Bus to the remote object and receives results back.

Mocking D-Bus

Most of the mocking details are available in the DBusStub Ruby class, part of the webyast-base-ws package

Your Ruby test case should have this line to import the DBusStub class

 require File.expand_path( File.join("test","dbus_stub"), RailsParent.parent )

Now create a DBusStub instance with

  dbus = DBusStub.new :system, "dbus.service.spec"

The first parameter can be :system for a service on the D-Bus System bus or :session for the Session bus

Next we create a proxy. The proxy is a local instance of a remote (D-Bus) object, pretending to be the real thing.

  proxy = dbus.proxy "/path/to/service"

Service functions are offered through an interface, created by

  interface = dbus.interface proxy, "dbus.service.spec.iface"

Since proxy and interface creation usually comes together, the above two calls can be combined in one as:

  proxy,interface = dbus.proxy "/path/to/service", "dbus.service.spec.iface"

Now you can use normal Mocha calls to mock the interface functions, i.e.

  interface.stubs(:Function).returns(true)