From e1c1a9ae367c53561cdb4f53ad8589e2bc859b0b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 20 Apr 2016 19:57:03 -0500 Subject: add unit tests for greeter --- tests/unit/CMakeLists.txt | 5 ++ tests/unit/greeter-test.cpp | 151 ++++++++++++++++++++++++++++++++++++++ tests/utils/mock-unity-greeter.py | 41 +++++++++++ 3 files changed, 197 insertions(+) create mode 100644 tests/unit/greeter-test.cpp create mode 100644 tests/utils/mock-unity-greeter.py diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index fe70461..9d8cad2 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -14,6 +14,10 @@ set(TEST_LINK_LIBRARIES ${GMOCK_LIBRARIES} ) +add_definitions( + -DGREETER_TEMPLATE="${CMAKE_SOURCE_DIR}/tests/utils/mock-unity-greeter.py" +) + function(add_test_by_name name) set(TEST_NAME ${name}) add_executable (${TEST_NAME} ${TEST_NAME}.cpp) @@ -31,4 +35,5 @@ function(add_qt_test_by_name name) set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT ${CTEST_ENVIRONMENT}) target_link_libraries(${TEST_NAME} ${SERVICE_LINK_LIBRARIES} ${QT_LINK_LIBRARIES} ${TEST_LINK_LIBRARIES} ${THREAD_LINK_LIBRARIES}) endfunction() +add_qt_test_by_name(greeter-test) add_qt_test_by_name(usb-snap-test) diff --git a/tests/unit/greeter-test.cpp b/tests/unit/greeter-test.cpp new file mode 100644 index 0000000..5d29023 --- /dev/null +++ b/tests/unit/greeter-test.cpp @@ -0,0 +1,151 @@ +/* + * Copyright 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 + */ + +#include + +#include +#include + +#include +#include +#include + +class GreeterFixture: public QtFixture +{ +private: + + using super = QtFixture; + +public: + + GreeterFixture() =default; + ~GreeterFixture() =default; + +protected: + + std::shared_ptr m_dbus_runner; + std::shared_ptr m_dbus_mock; + GDBusConnection* m_session_bus; + + void SetUp() override + { + super::SetUp(); + + // use a fresh bus for each test + + m_dbus_runner.reset(new QtDBusTest::DBusTestRunner()); + m_dbus_mock.reset(new QtDBusMock::DBusMock(*m_dbus_runner.get())); + + GError* error {}; + m_session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, &error); + g_assert_no_error(error); + g_dbus_connection_set_exit_on_close(m_session_bus, false); + } + + void TearDown() override + { + g_clear_object(&m_session_bus); + m_dbus_mock.reset(); + m_dbus_runner.reset(); + + super::TearDown(); + } + + void start_greeter_service(bool is_active) + { + // set a watcher to look for our mock to appear + bool owned {}; + QDBusServiceWatcher watcher( + DBusNames::UnityGreeter::NAME, + m_dbus_runner->sessionConnection() + ); + QObject::connect( + &watcher, + &QDBusServiceWatcher::serviceRegistered, + [&owned](const QString&){owned = true;} + ); + + // start the mock greeter + QVariantMap parameters; + parameters["IsActive"] = QVariant(is_active); + m_dbus_mock->registerTemplate( + DBusNames::UnityGreeter::NAME, + GREETER_TEMPLATE, + parameters, + QDBusConnection::SessionBus + ); + m_dbus_runner->startServices(); + + // wait for the watcher to be triggered + ASSERT_TRUE(wait_for([&owned]{return owned;})); + } +}; + +#define ASSERT_PROPERTY_EVENTUALLY(expected_in, property_in) \ + do { \ + const auto& e = expected_in; \ + const auto& p = property_in; \ + ASSERT_TRUE(wait_for([e, &p](){ return e == p.get(); })) \ + << "expected " << e << " but got " << p.get(); \ + } while(0) + +TEST_F(GreeterFixture, ActiveServiceStartsBeforeWatcher) +{ + constexpr bool expected {true}; + + start_greeter_service(expected); + + UnityGreeter greeter(m_session_bus); + + ASSERT_PROPERTY_EVENTUALLY(expected, greeter.is_active()); +} + +TEST_F(GreeterFixture, WatcherStartsBeforeActiveService) +{ + constexpr bool expected {true}; + + UnityGreeter greeter(m_session_bus); + + start_greeter_service(expected); + + ASSERT_PROPERTY_EVENTUALLY(expected, greeter.is_active()); +} + +TEST_F(GreeterFixture, InactiveServiceStartsBeforeWatcher) +{ + constexpr bool expected {false}; + + start_greeter_service(expected); + + UnityGreeter greeter(m_session_bus); + + ASSERT_PROPERTY_EVENTUALLY(expected, greeter.is_active()); +} + +TEST_F(GreeterFixture, WatcherStartsBeforeInactiveService) +{ + constexpr bool expected {false}; + + UnityGreeter greeter(m_session_bus); + + start_greeter_service(expected); + + ASSERT_PROPERTY_EVENTUALLY(expected, greeter.is_active()); +} + diff --git a/tests/utils/mock-unity-greeter.py b/tests/utils/mock-unity-greeter.py new file mode 100644 index 0000000..70fb791 --- /dev/null +++ b/tests/utils/mock-unity-greeter.py @@ -0,0 +1,41 @@ +'''unity greeter mock template + +Very basic template that just mocks the greeter is-active flag +''' + +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) any +# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text +# of the license. + +__author__ = 'Charles Kerr' +__email__ = 'charles.kerr@canonical.com' +__copyright__ = '(c) 2016 Canonical Ltd.' +__license__ = 'LGPL 3+' + +import dbus +import os + +from dbusmock import MOCK_IFACE, mockobject + +BUS_NAME = 'com.canonical.UnityGreeter' +MAIN_OBJ = '/' +MAIN_IFACE = 'com.canonical.UnityGreeter' +SYSTEM_BUS = False + + +def load(mock, parameters): + mock.AddMethods( + MAIN_IFACE, [ + ('HideGreeter', '', '', 'self.Set("com.canonical.UnityGreeter", "IsActive", False)'), + ('ShowGreeter', '', '', 'self.Set("com.canonical.UnityGreeter", "IsActive", True)') + ] + ) + mock.AddProperties( + MAIN_IFACE, + dbus.Dictionary({ + 'IsActive': parameters.get('IsActive', False), + }, signature='sv') + ) + -- cgit v1.2.3