test: add functional tests for autoping (XEP-0199)

- autoping_set_interval: verify /autoping set command
- autoping_set_zero_disables: verify disabling autoping
- autoping_timeout_set: verify /autoping timeout command
- autoping_timeout_zero_disables: verify disabling timeout
- autoping_sends_ping_after_interval: verify automatic ping IQ
- autoping_server_not_supporting_ping: verify error handling

Fast tests (command parsing) in Group 1, slow tests (timer-based) in Group 3.
This commit is contained in:
2026-02-10 17:47:26 +03:00
committed by Jabber Developer
parent 31538580fb
commit 663a959f9c
4 changed files with 140 additions and 2 deletions

View File

@@ -186,6 +186,7 @@ functionaltest_sources = \
tests/functionaltests/test_muc.c tests/functionaltests/test_muc.h \
tests/functionaltests/test_disconnect.c tests/functionaltests/test_disconnect.h \
tests/functionaltests/test_lastactivity.c tests/functionaltests/test_lastactivity.h \
tests/functionaltests/test_autoping.c tests/functionaltests/test_autoping.h \
tests/functionaltests/functionaltests.c
main_source = src/main.c

View File

@@ -15,9 +15,9 @@
* functional tests run less frequently than unit tests.
*
* Tests are organized into groups for better maintainability and parallel execution:
* Group 1: Connect, Ping, Rooms, Software
* Group 1: Connect, Ping, Autoping (fast), Rooms, Software, Last Activity
* Group 2: Message, Receipts, Roster, Chat Session
* Group 3: Presence, Disconnect
* Group 3: Presence, Disconnect, Autoping (slow)
* Group 4: MUC, Carbons
*
* Parallel execution:
@@ -53,6 +53,7 @@
#include "test_muc.h"
#include "test_disconnect.h"
#include "test_lastactivity.h"
#include "test_autoping.h"
/* Macro to wrap each test with setup/teardown functions */
#define PROF_FUNC_TEST(test) cmocka_unit_test_setup_teardown(test, init_prof_test, close_prof_test)
@@ -95,6 +96,12 @@ main(int argc, char* argv[])
PROF_FUNC_TEST(ping_jid),
PROF_FUNC_TEST(ping_jid_not_supported),
/* Autoping command tests - fast, no waiting */
PROF_FUNC_TEST(autoping_set_interval),
PROF_FUNC_TEST(autoping_set_zero_disables),
PROF_FUNC_TEST(autoping_timeout_set),
PROF_FUNC_TEST(autoping_timeout_zero_disables),
/* Room discovery - XEP-0045 */
PROF_FUNC_TEST(rooms_query),
@@ -165,6 +172,10 @@ main(int argc, char* argv[])
/* Disconnect - clean session termination */
PROF_FUNC_TEST(disconnect_ends_session),
/* Autoping slow tests - require sleep for timer triggers */
PROF_FUNC_TEST(autoping_sends_ping_after_interval),
PROF_FUNC_TEST(autoping_server_not_supporting_ping),
};
/* ============================================================

View File

@@ -0,0 +1,120 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stabber.h>
#include "proftest.h"
void
autoping_set_interval(void** state)
{
prof_connect();
prof_input("/autoping set 60");
assert_true(prof_output_exact("Autoping interval set to 60 seconds."));
}
void
autoping_set_zero_disables(void** state)
{
prof_connect();
prof_input("/autoping set 0");
assert_true(prof_output_exact("Autoping disabled."));
}
void
autoping_timeout_set(void** state)
{
prof_connect();
prof_input("/autoping timeout 30");
assert_true(prof_output_exact("Autoping timeout set to 30 seconds."));
}
void
autoping_timeout_zero_disables(void** state)
{
prof_connect();
prof_input("/autoping timeout 0");
assert_true(prof_output_exact("Autoping timeout disabled."));
}
void
autoping_sends_ping_after_interval(void** state)
{
/*
* This test verifies that autoping sends a ping IQ after the configured
* interval. We set a short interval (2 seconds) and verify the ping is sent.
*/
// Register disco#info response with ping support
stbbr_for_query("http://jabber.org/protocol/disco#info",
"<iq to='stabber@localhost/profanity' type='result' from='localhost'>"
"<query xmlns='http://jabber.org/protocol/disco#info'>"
"<identity category='server' type='im' name='Stabber'/>"
"<feature var='urn:xmpp:ping'/>"
"</query>"
"</iq>"
);
// Register ping response
stbbr_for_query("urn:xmpp:ping",
"<iq from='localhost' to='stabber@localhost/profanity' type='result'/>"
);
prof_connect();
// Wait for disco exchange
sleep(2);
// Set short autoping interval
prof_input("/autoping set 2");
assert_true(prof_output_exact("Autoping interval set to 2 seconds."));
// Wait for autoping to trigger (interval + some buffer)
sleep(4);
// Verify ping was sent (no 'to' attribute means server ping)
assert_true(stbbr_received(
"<iq id='*' type='get'>"
"<ping xmlns='urn:xmpp:ping'/>"
"</iq>"
));
}
void
autoping_server_not_supporting_ping(void** state)
{
/*
* When server doesn't support ping, autoping should show error.
*/
// Register disco#info response WITHOUT ping support
stbbr_for_query("http://jabber.org/protocol/disco#info",
"<iq to='stabber@localhost/profanity' type='result' from='localhost'>"
"<query xmlns='http://jabber.org/protocol/disco#info'>"
"<identity category='server' type='im' name='Stabber'/>"
"</query>"
"</iq>"
);
prof_connect();
// Wait for disco exchange
sleep(2);
// Set short autoping interval
prof_input("/autoping set 2");
assert_true(prof_output_exact("Autoping interval set to 2 seconds."));
// Wait for autoping to trigger
sleep(4);
// Should show error about ping not being supported
assert_true(prof_output_regex("Server ping not supported"));
}

View File

@@ -0,0 +1,6 @@
void autoping_set_interval(void** state);
void autoping_set_zero_disables(void** state);
void autoping_timeout_set(void** state);
void autoping_timeout_zero_disables(void** state);
void autoping_sends_ping_after_interval(void** state);
void autoping_server_not_supporting_ping(void** state);