/*
* Copyright 2014-2016 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3, as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranties of
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*
* Authors:
* Charles Kerr
*/
#pragma once
#include "glib-fixture.h"
#include
/***
****
***/
class LibdbusmockFixture: public GlibFixture
{
private:
typedef GlibFixture super;
protected:
GDBusConnection * system_bus {};
GDBusConnection * session_bus {};
DbusTestService * service {};
void SetUp() override
{
super::SetUp();
service = dbus_test_service_new(nullptr);
}
void startDbusMock()
{
// start 'em up.
// make the system bus work off the mock bus too, since that's
// where the upower and screen are on the system bus...
dbus_test_service_start_tasks(service);
g_setenv("DBUS_SYSTEM_BUS_ADDRESS", g_getenv("DBUS_SESSION_BUS_ADDRESS"), TRUE);
session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
ASSERT_NE(nullptr, session_bus);
g_dbus_connection_set_exit_on_close(session_bus, false);
g_object_add_weak_pointer(G_OBJECT(session_bus), (gpointer *)&session_bus);
system_bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr);
ASSERT_NE(nullptr, system_bus);
g_dbus_connection_set_exit_on_close(system_bus, FALSE);
g_object_add_weak_pointer(G_OBJECT(system_bus), (gpointer *)&system_bus);
}
void TearDown() override
{
g_clear_object(&service);
g_object_unref(session_bus);
g_object_unref(system_bus);
// wait a little while for the scaffolding to shut down,
// but don't block on it forever...
unsigned int cleartry = 0;
while (((system_bus != nullptr) || (session_bus != nullptr)) && (cleartry < 50))
{
g_usleep(100000);
while (g_main_pending(nullptr))
g_main_iteration(nullptr, true);
cleartry++;
}
super::TearDown();
}
bool wait_for_method_call(DbusTestDbusMock* mock,
DbusTestDbusMockObject* obj,
const gchar* method,
GVariant* params=nullptr,
guint timeout_msec=100)
{
if (params != nullptr)
g_variant_ref_sink(params);
auto test_function = [mock, obj, method, params]() {
GError* error {};
const auto called = dbus_test_dbus_mock_object_check_method_call(mock,
obj,
method,
params,
&error);
if (error != nullptr) {
g_critical("Error looking for method call '%s': %s", method, error->message);
g_clear_error(&error);
}
return called;
};
const auto ret = wait_for(test_function, timeout_msec);
g_clear_pointer(¶ms, g_variant_unref);
return ret;
}
void EXPECT_METHOD_CALLED_EVENTUALLY(DbusTestDbusMock* mock,
DbusTestDbusMockObject* obj,
const gchar* method,
GVariant* params=nullptr,
guint timeout_msec=1000)
{
EXPECT_TRUE(wait_for_method_call(mock, obj, method, params, timeout_msec)) << "method: " << method;
}
void EXPECT_METHOD_NOT_CALLED_EVENTUALLY(DbusTestDbusMock* mock,
DbusTestDbusMockObject* obj,
const gchar* method,
GVariant* params=nullptr,
guint timeout_msec=1000)
{
EXPECT_FALSE(wait_for_method_call(mock, obj, method, params, timeout_msec)) << "method: " << method;
}
void ASSERT_METHOD_CALLED_EVENTUALLY(DbusTestDbusMock* mock,
DbusTestDbusMockObject* obj,
const gchar* method,
GVariant* params=nullptr,
guint timeout_msec=1000)
{
ASSERT_TRUE(wait_for_method_call(mock, obj, method, params, timeout_msec)) << "method: " << method;
}
void ASSERT_METHOD_NOT_CALLED_EVENTUALLY(DbusTestDbusMock* mock,
DbusTestDbusMockObject* obj,
const gchar* method,
GVariant* params=nullptr,
guint timeout_msec=1000)
{
ASSERT_FALSE(wait_for_method_call(mock, obj, method, params, timeout_msec)) << "method: " << method;
}
};