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/utils/mock-unity-greeter.py | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tests/utils/mock-unity-greeter.py (limited to 'tests/utils') 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 From ce5234162fa0c534ff9abf3fce3d03f4b01e893e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 22 Apr 2016 09:43:44 -0500 Subject: don't prompt when the greeter's not running yet: change greeter's payload from an 'is_active' bool to a three-value state of active, inactive, and unavailable --- src/greeter.cpp | 18 +++++++++--------- src/greeter.h | 6 ++++-- src/usb-manager.cpp | 14 ++++++++++---- tests/integration/usb-manager-test.cpp | 4 ++-- tests/unit/greeter-test.cpp | 29 +++++++++++++++++------------ tests/utils/gtest-print-helpers.h | 18 ++++++++++++++++++ tests/utils/mock-greeter.h | 4 ++-- 7 files changed, 62 insertions(+), 31 deletions(-) create mode 100644 tests/utils/gtest-print-helpers.h (limited to 'tests/utils') diff --git a/src/greeter.cpp b/src/greeter.cpp index d41160f..317a829 100644 --- a/src/greeter.cpp +++ b/src/greeter.cpp @@ -41,9 +41,9 @@ public: ~Impl() =default; - core::Property& is_active() + core::Property& state() { - return m_is_active; + return m_state; } private: @@ -130,7 +130,7 @@ private: auto self = static_cast(gself); self->m_owner.clear(); - self->m_is_active.set(false); + self->m_state.set(State::UNAVAILABLE); } static void on_get_is_active_ready( @@ -147,7 +147,7 @@ private: } else { GVariant* is_active {}; g_variant_get_child(v, 0, "v", &is_active); - static_cast(gself)->m_is_active.set(g_variant_get_boolean(is_active)); + static_cast(gself)->m_state.set(g_variant_get_boolean(is_active) ? State::ACTIVE : State::INACTIVE); g_clear_pointer(&is_active, g_variant_unref); } g_clear_pointer(&v, g_variant_unref); @@ -175,12 +175,12 @@ private: if (g_variant_lookup(v, "IsActive", "b", &is_active)) { g_debug("%s is_active changed to %d", G_STRLOC, int(is_active)); - self->m_is_active.set(is_active); + self->m_state.set(is_active ? State::ACTIVE : State::INACTIVE); } g_clear_pointer(&v, g_variant_unref); } - core::Property m_is_active {false}; + core::Property m_state {State::UNAVAILABLE}; std::shared_ptr m_cancellable; std::shared_ptr m_bus; std::string m_owner; @@ -201,8 +201,8 @@ UnityGreeter::UnityGreeter(): UnityGreeter::~UnityGreeter() =default; -core::Property& -UnityGreeter::is_active() +core::Property& +UnityGreeter::state() { - return impl->is_active(); + return impl->state(); } diff --git a/src/greeter.h b/src/greeter.h index e084d25..cde1429 100644 --- a/src/greeter.h +++ b/src/greeter.h @@ -29,7 +29,9 @@ class Greeter public: Greeter(); virtual ~Greeter(); - virtual core::Property& is_active() =0; + + enum class State { UNAVAILABLE, INACTIVE, ACTIVE }; + virtual core::Property& state() =0; }; @@ -38,7 +40,7 @@ class UnityGreeter: public Greeter public: UnityGreeter(); virtual ~UnityGreeter(); - core::Property& is_active() override; + core::Property& state() override; protected: class Impl; diff --git a/src/usb-manager.cpp b/src/usb-manager.cpp index 4d750c0..80b274b 100644 --- a/src/usb-manager.cpp +++ b/src/usb-manager.cpp @@ -49,7 +49,7 @@ public: restart(); }); - m_greeter->is_active().changed().connect([this](bool /*is_active*/) { + m_greeter->state().changed().connect([this](Greeter::State /*state*/) { maybe_snap(); }); @@ -92,9 +92,15 @@ private: void maybe_snap() { - // don't prompt in the greeter! - if (!m_req.public_key.empty() && !m_greeter->is_active().get()) - snap(); + // only prompt if there's something to prompt about + if (m_req.public_key.empty()) + return; + + // only prompt in an unlocked session + if (m_greeter->state().get() != Greeter::State::INACTIVE) + return; + + snap(); } void snap() diff --git a/tests/integration/usb-manager-test.cpp b/tests/integration/usb-manager-test.cpp index d62756f..7320640 100644 --- a/tests/integration/usb-manager-test.cpp +++ b/tests/integration/usb-manager-test.cpp @@ -206,7 +206,7 @@ TEST_F(UsbManagerFixture, Greeter) auto adbd_server = std::make_shared(*socket_path, std::vector{"PK"+public_key}); // set up a UsbManager to process the request - m_greeter->m_is_active.set(true); + m_greeter->m_state.set(Greeter::State::ACTIVE); auto usb_manager = std::make_shared(*socket_path, *public_keys_path, m_usb_monitor, m_greeter); // add a signal spy to listen to the notification daemon @@ -219,7 +219,7 @@ TEST_F(UsbManagerFixture, Greeter) EXPECT_FALSE(notificationsSpy.wait(2000)); // disable the greeter, the notification should appear - m_greeter->m_is_active.set(false); + m_greeter->m_state.set(Greeter::State::INACTIVE); wait_for_signals(notificationsSpy, 1); EXPECT_EQ("Notify", notificationsSpy.at(0).at(0)); notificationsSpy.clear(); diff --git a/tests/unit/greeter-test.cpp b/tests/unit/greeter-test.cpp index 72df3bc..bfa88e8 100644 --- a/tests/unit/greeter-test.cpp +++ b/tests/unit/greeter-test.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -110,45 +111,49 @@ protected: TEST_F(GreeterFixture, ActiveServiceStartsBeforeWatcher) { - constexpr bool expected {true}; + constexpr bool is_active {true}; + constexpr Greeter::State expected {Greeter::State::ACTIVE}; - start_greeter_service(expected); + start_greeter_service(is_active); UnityGreeter greeter; - ASSERT_PROPERTY_EQ_EVENTUALLY(expected, greeter.is_active()); + ASSERT_PROPERTY_EQ_EVENTUALLY(expected, greeter.state()); } TEST_F(GreeterFixture, WatcherStartsBeforeActiveService) { - constexpr bool expected {true}; + constexpr bool is_active {true}; + constexpr Greeter::State expected {Greeter::State::ACTIVE}; UnityGreeter greeter; - start_greeter_service(expected); + start_greeter_service(is_active); - ASSERT_PROPERTY_EQ_EVENTUALLY(expected, greeter.is_active()); + ASSERT_PROPERTY_EQ_EVENTUALLY(expected, greeter.state()); } TEST_F(GreeterFixture, InactiveServiceStartsBeforeWatcher) { - constexpr bool expected {false}; + constexpr bool is_active {false}; + constexpr Greeter::State expected {Greeter::State::INACTIVE}; - start_greeter_service(expected); + start_greeter_service(is_active); UnityGreeter greeter; - ASSERT_PROPERTY_EQ_EVENTUALLY(expected, greeter.is_active()); + ASSERT_PROPERTY_EQ_EVENTUALLY(expected, greeter.state()); } TEST_F(GreeterFixture, WatcherStartsBeforeInactiveService) { - constexpr bool expected {false}; + constexpr bool is_active {false}; + constexpr Greeter::State expected {Greeter::State::INACTIVE}; UnityGreeter greeter; - start_greeter_service(expected); + start_greeter_service(is_active); - ASSERT_PROPERTY_EQ_EVENTUALLY(expected, greeter.is_active()); + ASSERT_PROPERTY_EQ_EVENTUALLY(expected, greeter.state()); } diff --git a/tests/utils/gtest-print-helpers.h b/tests/utils/gtest-print-helpers.h new file mode 100644 index 0000000..75ee13b --- /dev/null +++ b/tests/utils/gtest-print-helpers.h @@ -0,0 +1,18 @@ + +#pragma once + +#include + +inline void PrintTo(const Greeter::State& state, std::ostream* os) { + switch(state) { + case Greeter::State::ACTIVE: *os << "Active"; break; + case Greeter::State::INACTIVE: *os << "Inactive"; break; + default: *os << "Unavailable"; break; + } +} + +std::ostream& operator<<(std::ostream& os, const Greeter::State& state) { + PrintTo(state, &os); + return os; +} + diff --git a/tests/utils/mock-greeter.h b/tests/utils/mock-greeter.h index 5ac85a0..5015087 100644 --- a/tests/utils/mock-greeter.h +++ b/tests/utils/mock-greeter.h @@ -26,7 +26,7 @@ class MockGreeter: public Greeter public: MockGreeter() =default; virtual ~MockGreeter() =default; - core::Property& is_active() override {return m_is_active;} - core::Property m_is_active {false}; + core::Property& state() override {return m_state;} + core::Property m_state {State::INACTIVE}; }; -- cgit v1.2.3 From 0f5534d22903f73e2d33ea2e29efb2307463bfa4 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 23 Apr 2016 12:29:45 +0200 Subject: in tests/utils/adbd-server.h, fix a timing bug in the test scaffolding by creating the adb socket in AdbdServer's ctor instead of in its worker thread. --- tests/utils/adbd-server.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'tests/utils') diff --git a/tests/utils/adbd-server.h b/tests/utils/adbd-server.h index b574622..585380f 100644 --- a/tests/utils/adbd-server.h +++ b/tests/utils/adbd-server.h @@ -38,7 +38,7 @@ public: GAdbdServer(const std::string& socket_path, const std::vector& requests): m_requests{requests}, - m_socket_path{socket_path}, + m_server_socket{create_server_socket(socket_path)}, m_cancellable{g_cancellable_new()}, m_worker_thread{&GAdbdServer::worker_func, this} { @@ -50,6 +50,7 @@ public: g_cancellable_cancel(m_cancellable); m_worker_thread.join(); g_clear_object(&m_cancellable); + g_clear_object(&m_server_socket); } const std::vector m_requests; @@ -59,18 +60,14 @@ private: void worker_func() // runs in worker thread { - auto server_socket = create_server_socket(m_socket_path); auto requests = m_requests; - GError* error {}; - g_socket_listen (server_socket, &error); - g_assert_no_error (error); - while (!g_cancellable_is_cancelled(m_cancellable) && !requests.empty()) { // wait for a client connection g_message("GAdbdServer::Impl::worker_func() calling g_socket_accept()"); - auto client_socket = g_socket_accept(server_socket, m_cancellable, &error); + GError* error {}; + auto client_socket = g_socket_accept(m_server_socket, m_cancellable, &error); if (error != nullptr) { if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_message("GAdbdServer: Error accepting socket connection: %s", error->message); @@ -121,8 +118,6 @@ private: // cleanup g_clear_object(&client_socket); } - - g_clear_object(&server_socket); } // bind to a local domain socket @@ -139,11 +134,14 @@ private: g_assert_no_error (error); g_clear_object (&address); + g_socket_listen (socket, &error); + g_assert_no_error (error); + return socket; } - const std::string m_socket_path; - GCancellable* m_cancellable = nullptr; + GSocket* m_server_socket {}; + GCancellable* m_cancellable {}; std::thread m_worker_thread; }; -- cgit v1.2.3 From 2e88906dc5ced1c5f601cef2514d8e559246e0d5 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 27 Apr 2016 10:16:39 +0200 Subject: silence clang warning in PrintTo gtest helper --- tests/utils/gtest-print-helpers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tests/utils') diff --git a/tests/utils/gtest-print-helpers.h b/tests/utils/gtest-print-helpers.h index 75ee13b..6dc1217 100644 --- a/tests/utils/gtest-print-helpers.h +++ b/tests/utils/gtest-print-helpers.h @@ -5,9 +5,9 @@ inline void PrintTo(const Greeter::State& state, std::ostream* os) { switch(state) { - case Greeter::State::ACTIVE: *os << "Active"; break; - case Greeter::State::INACTIVE: *os << "Inactive"; break; - default: *os << "Unavailable"; break; + case Greeter::State::ACTIVE: *os << "Active"; break; + case Greeter::State::INACTIVE: *os << "Inactive"; break; + case Greeter::State::UNAVAILABLE: *os << "Unavailable"; break; } } -- cgit v1.2.3 From fcf75a545e25baa8777a310c648846537590fa2b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 27 Apr 2016 10:33:05 +0200 Subject: silence 'no previous prototype' warning from clang --- tests/utils/gtest-print-helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/utils') diff --git a/tests/utils/gtest-print-helpers.h b/tests/utils/gtest-print-helpers.h index 6dc1217..60f42b4 100644 --- a/tests/utils/gtest-print-helpers.h +++ b/tests/utils/gtest-print-helpers.h @@ -11,7 +11,7 @@ inline void PrintTo(const Greeter::State& state, std::ostream* os) { } } -std::ostream& operator<<(std::ostream& os, const Greeter::State& state) { +inline std::ostream& operator<<(std::ostream& os, const Greeter::State& state) { PrintTo(state, &os); return os; } -- cgit v1.2.3