Files
feedbackd/tests/test-lfb-integration.c
T
Evangelos Ribeiro Tzaras 72c7d3ba25 tests/integration: Test that "feedback-ended" is propagated through LfbEvent
When no feedbacks are available (either because the requested event does
not exist in the theme or because the system does not have required
capabilities, e.g. no vibration motor or LED) feedbackd will emit a
"feedback-ended" signal (with reason LFB_EVENT_STATE_REASON_NOT_FOUND)
on DBus _before_ completing the event triggering DBus call.

Since the DBus call was not completed yet, LfbEvent will not have
learned it's ID yet and therefore not emit it's own "feedback-ended"
GObject signal.

In this case the test will timeout since the main loop is never quit.
2022-11-09 11:54:44 +01:00

370 lines
11 KiB
C

/*
* Copyright (C) 2020 Purism SPC
* SPDX-License-Identifier: GPL-3.0+
* Author: Guido Günther <agx@sigxcpu.org>
*/
#include "libfeedback.h"
#include <gio/gio.h>
typedef struct {
GTestDBus *dbus;
} TestFixture;
GMainLoop *mainloop;
static void
fixture_setup (TestFixture *fixture, gconstpointer unused)
{
g_autoptr (GError) err = NULL;
gchar *relative, *servicesdir;
gint success;
fixture->dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
relative = g_test_build_filename (G_TEST_BUILT, "services", NULL);
servicesdir = g_canonicalize_filename (relative, NULL);
g_free (relative);
g_test_dbus_add_service_dir (fixture->dbus, servicesdir);
g_free (servicesdir);
g_setenv ("FEEDBACK_THEME", TEST_DATA_DIR "/test.json", TRUE);
g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
g_test_dbus_up (fixture->dbus);
g_assert_null (mainloop);
mainloop = g_main_loop_new (NULL, FALSE);
success = lfb_init (TEST_APP_ID, &err);
g_assert_no_error (err);
g_assert_true (success);
}
static void
fixture_teardown (TestFixture *fixture, gconstpointer unused)
{
g_clear_pointer (&mainloop, g_main_loop_unref);
lfb_uninit ();
g_test_dbus_down (fixture->dbus);
g_object_unref (fixture->dbus);
}
static void
on_feedback_ended (LfbEvent *event, LfbEvent **cmp)
{
g_assert_true (LFB_IS_EVENT (event));
g_assert_null (*cmp);
g_debug ("Feedback ended for %s: %d",
lfb_event_get_event (event),
lfb_event_get_end_reason (event));
g_assert_cmpint (lfb_event_get_state (event), ==, LFB_EVENT_STATE_ENDED);
/* "Return" event */
*cmp = event;
}
static void
test_lfb_integration_event_sync (void)
{
g_autoptr(LfbEvent) event0 = NULL;
g_autoptr(LfbEvent) event10 = NULL;
g_autoptr (GError) err = NULL;
LfbEvent *cmp = NULL;
gboolean success;
event0 = lfb_event_new ("test-dummy-0");
success = lfb_event_trigger_feedback (event0, &err);
g_assert_no_error (err);
g_assert_true (success);
event10 = lfb_event_new ("test-dummy-10");
g_signal_connect (event10, "feedback-ended", (GCallback)on_feedback_ended, &cmp);
g_signal_connect_swapped (event10, "feedback-ended", (GCallback)g_main_loop_quit, mainloop);
success = lfb_event_trigger_feedback (event10, &err);
g_assert_no_error (err);
g_assert_true (success);
success = lfb_event_end_feedback (event10, &err);
g_assert_no_error (err);
g_assert_true (success);
g_main_loop_run (mainloop);
/* If the signal fired cmp will match event */
g_assert_true (event10 == cmp);
g_assert_cmpint (lfb_event_get_state (event10), ==, LFB_EVENT_STATE_ENDED);
g_assert_cmpint (lfb_event_get_end_reason (event10), ==, LFB_EVENT_END_REASON_EXPLICIT);
}
static void
test_lfb_integration_event_not_found (void)
{
g_autoptr(LfbEvent) event0 = NULL;
g_autoptr (GError) err = NULL;
LfbEvent *cmp = NULL;
gboolean success;
event0 = lfb_event_new ("test-does-not-exist");
g_signal_connect (event0, "feedback-ended", (GCallback)on_feedback_ended, &cmp);
g_signal_connect_swapped (event0, "feedback-ended", (GCallback)g_main_loop_quit, mainloop);
success = lfb_event_trigger_feedback (event0, &err);
g_assert_no_error (err);
g_assert_true (success);
g_main_loop_run (mainloop);
/* If the signal fired cmp will match event */
g_assert_true (event0 == cmp);
g_assert_cmpint (lfb_event_get_state (event0), ==, LFB_EVENT_STATE_ENDED);
g_assert_cmpint (lfb_event_get_end_reason (event0), ==, LFB_EVENT_END_REASON_NOT_FOUND);
}
static void
on_event_triggered (LfbEvent *event,
GAsyncResult *res,
LfbEvent **cmp)
{
g_autoptr (GError) err = NULL;
gboolean success;
g_assert_true (LFB_IS_EVENT (event));
g_assert_null (*cmp);
g_debug ("%s: %p, %s", __func__, event, lfb_event_get_event (event));
success = lfb_event_trigger_feedback_finish (event, res, &err);
g_assert_no_error (err);
g_assert_true (success);
g_assert_cmpint (lfb_event_get_state (event), ==, LFB_EVENT_STATE_RUNNING);
/* "Return" event */
*cmp = event;
}
static void
on_event_triggered_quit (LfbEvent *event,
GAsyncResult *res,
LfbEvent **cmp)
{
g_autoptr (GError) err = NULL;
gboolean success;
g_assert_true (LFB_IS_EVENT (event));
g_assert_null (*cmp);
g_debug ("%s: %p, %s", __func__, event, lfb_event_get_event (event));
success = lfb_event_trigger_feedback_finish (event, res, &err);
g_assert_no_error (err);
g_assert_true (success);
g_assert_cmpint (lfb_event_get_state (event), ==, LFB_EVENT_STATE_RUNNING);
/* "Return" event */
*cmp = event;
g_main_loop_quit (mainloop);
}
static void
on_event_end_finished (LfbEvent *event,
GAsyncResult *res,
LfbEvent **cmp)
{
g_autoptr (GError) err = NULL;
gboolean success;
g_debug ("%s: %p, %s", __func__, event, lfb_event_get_event (event));
g_assert_true (LFB_IS_EVENT (event));
g_assert_null (*cmp);
success = lfb_event_end_feedback_finish (event, res, &err);
g_assert_no_error (err);
g_assert_true (success);
/* This is not guaranteed for all types of feedback, see `feedback-ended` */
g_assert_cmpint (lfb_event_get_state (event), ==, LFB_EVENT_STATE_ENDED);
/* "Return" event */
*cmp = event;
g_main_loop_quit (mainloop);
}
static void
test_lfb_integration_event_not_found_async (void)
{
g_autoptr(LfbEvent) event0 = NULL;
LfbEvent *cmp = NULL;
LfbEvent *cmp2 = NULL;
event0 = lfb_event_new ("test-does-not-exist");
g_signal_connect (event0, "feedback-ended", (GCallback)on_feedback_ended, &cmp2);
/* The main loop will only quit if the "feedback-ended" signal actually gets emitted */
g_signal_connect_swapped (event0, "feedback-ended", (GCallback)g_main_loop_quit, mainloop);
lfb_event_trigger_feedback_async (event0,
NULL,
(GAsyncReadyCallback)on_event_triggered,
&cmp);
g_main_loop_run (mainloop);
/* If the signal fired cmp will match event */
g_assert_true (event0 == cmp);
g_assert_true (event0 == cmp2);
g_assert_cmpint (lfb_event_get_state (event0), ==, LFB_EVENT_STATE_ENDED);
g_assert_cmpint (lfb_event_get_end_reason (event0), ==, LFB_EVENT_END_REASON_NOT_FOUND);
}
static void
test_lfb_integration_event_async (void)
{
g_autoptr(LfbEvent) event0 = NULL;
g_autoptr(LfbEvent) event10 = NULL;
LfbEvent *cmp1 = NULL, *cmp2 = NULL, *cmp3 = NULL;
event0 = lfb_event_new ("test-dummy-0");
lfb_event_trigger_feedback_async (event0,
NULL,
(GAsyncReadyCallback)on_event_triggered_quit,
&cmp1);
g_main_loop_run (mainloop);
/* The async finish callback saw the right event */
g_assert_true (event0 == cmp1);
cmp1 = NULL;
event10 = lfb_event_new ("test-dummy-10");
lfb_event_set_timeout (event10, 1);
g_assert_cmpint (lfb_event_get_timeout (event10), ==, 1);
lfb_event_set_feedback_profile (event10, "quiet");
g_signal_connect (event10, "feedback-ended", (GCallback)on_feedback_ended, &cmp1);
/* The async callback ends the main loop */
lfb_event_trigger_feedback_async (event10,
NULL,
(GAsyncReadyCallback)on_event_triggered_quit,
&cmp2);
g_main_loop_run (mainloop);
/* The async callback ends the main loop */
lfb_event_end_feedback_async (event10,
NULL,
(GAsyncReadyCallback)on_event_end_finished,
&cmp3);
g_main_loop_run (mainloop);
/* Check if callbacks saw the right event */
g_assert_true (event10 == cmp1);
g_assert_true (event10 == cmp2);
g_assert_true (event10 == cmp3);
g_assert_cmpint (lfb_event_get_state (event10), ==, LFB_EVENT_STATE_ENDED);
g_assert_cmpint (lfb_event_get_end_reason (event10), ==, LFB_EVENT_END_REASON_EXPLICIT);
}
static void
on_event_with_error_triggered (LfbEvent *event,
GAsyncResult *res,
LfbEvent **cmp)
{
g_autoptr (GError) err = NULL;
gboolean success;
g_debug ("%s: %p, %s", __func__, event, lfb_event_get_event (event));
g_assert_true (LFB_IS_EVENT (event));
g_assert_null (*cmp);
success = lfb_event_end_feedback_finish (event, res, &err);
g_assert_false (success);
g_assert_error (err, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS);
/* "Return" event */
*cmp = event;
g_main_loop_quit (mainloop);
}
static void
test_lfb_integration_event_async_error (void)
{
g_autoptr(LfbEvent) event0 = NULL;
LfbEvent *cmp1 = NULL;
/* Empty event names are invalid */
event0 = lfb_event_new ("");
lfb_event_trigger_feedback_async (event0,
NULL,
(GAsyncReadyCallback)on_event_with_error_triggered,
&cmp1);
g_main_loop_run (mainloop);
/* The async finish callback saw the right event */
g_assert_true (event0 == cmp1);
}
static void
on_profile_changed (LfbGdbusFeedback *proxy, GParamSpec *psepc, const gchar **profile)
{
g_assert_null (*profile);
*profile = lfb_get_feedback_profile();
g_debug("Set feedback profile to: '%s'", *profile);
g_main_loop_quit (mainloop);
}
static void
test_lfb_integration_profile (void)
{
LfbGdbusFeedback *proxy;
gchar *cmp = NULL;
g_assert_cmpstr (lfb_get_feedback_profile (), ==, "full");
proxy = lfb_get_proxy ();
g_assert_nonnull (proxy);
lfb_set_feedback_profile ("quiet");
g_signal_connect (proxy, "notify::profile", (GCallback)on_profile_changed, &cmp);
g_main_loop_run (mainloop);
g_assert_cmpstr (lfb_get_feedback_profile (), ==, "quiet");
g_assert_cmpstr (cmp, ==, "quiet");
}
gint
main (gint argc, gchar *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add("/feedbackd/lfb-integration/event_sync", TestFixture, NULL,
(gpointer)fixture_setup,
(gpointer)test_lfb_integration_event_sync,
(gpointer)fixture_teardown);
g_test_add("/feedbackd/lfb-integration/event_async/success", TestFixture, NULL,
(gpointer)fixture_setup,
(gpointer)test_lfb_integration_event_async,
(gpointer)fixture_teardown);
g_test_add("/feedbackd/lfb-integration/event_async/error", TestFixture, NULL,
(gpointer)fixture_setup,
(gpointer)test_lfb_integration_event_async_error,
(gpointer)fixture_teardown);
g_test_add("/feedbackd/lfb-integration/event_not_found", TestFixture, NULL,
(gpointer)fixture_setup,
(gpointer)test_lfb_integration_event_not_found,
(gpointer)fixture_teardown);
g_test_add("/feedbackd/lfb-integration/event_not_found_async", TestFixture, NULL,
(gpointer)fixture_setup,
(gpointer)test_lfb_integration_event_not_found_async,
(gpointer)fixture_teardown);
g_test_add("/feedbackd/lfb-integration/profile", TestFixture, NULL,
(gpointer)fixture_setup,
(gpointer)test_lfb_integration_profile,
(gpointer)fixture_teardown);
return g_test_run();
}