/* * Copyright 2013 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 #include "glib-fixture.h" #include #include /*** **** ***/ struct TimedatedFixture: public GlibFixture { private: using super = GlibFixture; protected: GDBusConnection* m_bus {}; GTestDBus* m_test_bus {}; virtual void SetUp() override { super::SetUp(); // use a fake bus m_test_bus = g_test_dbus_new(G_TEST_DBUS_NONE); g_test_dbus_up(m_test_bus); const char * address = g_test_dbus_get_bus_address(m_test_bus); g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, true); g_setenv("DBUS_SESSION_BUS_ADDRESS", address, true); g_debug("test_dbus's address is %s", address); // get the bus m_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr); g_dbus_connection_set_exit_on_close(m_bus, FALSE); g_object_add_weak_pointer(G_OBJECT(m_bus), (gpointer*)&m_bus); } virtual void TearDown() override { g_clear_object(&m_bus); g_clear_object(&m_test_bus); super::TearDown(); } void start_timedate1(const std::string& tzid) { // start dbusmock with the timedated template auto json_parameters = g_strdup_printf("{\"Timezone\": \"%s\"}", tzid.c_str()); const gchar* child_argv[] = { "python3", "-m", "dbusmock", "--template", "timedated", "--parameters", json_parameters, nullptr }; GError* error = nullptr; g_spawn_async(nullptr, (gchar**)child_argv, nullptr, G_SPAWN_SEARCH_PATH, nullptr, nullptr, nullptr, &error); g_assert_no_error(error); g_free(json_parameters); // wait for it to appear on the bus wait_for_name_owned(m_bus, Bus::Timedate1::BUSNAME); } bool wait_for_tzid(const std::string& tzid, ayatana::indicator::datetime::Timezone& tz) { return wait_for([&tzid, &tz](){return tzid == tz.timezone.get();}); } void set_timedate1_timezone(const std::string& tzid) { GError* error {}; auto v = g_dbus_connection_call_sync( m_bus, Bus::Timedate1::BUSNAME, Bus::Timedate1::ADDR, Bus::Timedate1::IFACE, Bus::Timedate1::Methods::SET_TIMEZONE, g_variant_new("(sb)", tzid.c_str(), FALSE), nullptr, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error); g_assert_no_error(error); g_clear_pointer(&v, g_variant_unref); } std::string get_timedate1_timezone() { GError* error {}; auto v = g_dbus_connection_call_sync( m_bus, Bus::Timedate1::BUSNAME, Bus::Timedate1::ADDR, Bus::Properties::IFACE, Bus::Properties::Methods::GET, g_variant_new("(ss)", Bus::Timedate1::IFACE, Bus::Timedate1::Properties::TIMEZONE), G_VARIANT_TYPE("(v)"), G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error); g_assert_no_error(error); GVariant* tzv {}; g_variant_get(v, "(v)", &tzv); std::string tzid; const char* tz = g_variant_get_string(tzv, nullptr); if (tz != nullptr) tzid = tz; g_clear_pointer(&tzv, g_variant_unref); g_clear_pointer(&v, g_variant_unref); return tzid; } }; #define EXPECT_TZID(expected_tzid, tmp) \ EXPECT_TRUE(wait_for_tzid(expected_tzid, tmp)) \ << "expected " << expected_tzid \ << " got " << tmp.timezone.get();