forked from Green-Sky/tomato
c9cdae001 fix(toxav): remove extra copy of video frame on encode 4f6d4546b test: Improve the fake network library. a2581e700 refactor(toxcore): generate `Friend_Request` and `Dht_Nodes_Response` 2aaa11770 refactor(toxcore): use Tox_Memory in generated events 5c367452b test(toxcore): fix incorrect mutex in tox_scenario_get_time 8f92e710f perf: Add a timed limit of number of cookie requests. 695b6417a test: Add some more simulated network support. 815ae9ce9 test(toxcore): fix thread-safety in scenario framework 6d85c754e test(toxcore): add unit tests for net_crypto 9c22e79cc test(support): add SimulatedEnvironment for deterministic testing f34fcb195 chore: Update windows Dockerfile to debian stable (trixie). ece0e8980 fix(group_moderation): allow validating unsorted sanction list signatures a4fa754d7 refactor: rename struct Packet to struct Net_Packet d6f330f85 cleanup: Fix some warnings from coverity. e206bffa2 fix(group_chats): fix sync packets reverting topics 0e4715598 test: Add new scenario testing framework. 668291f44 refactor(toxcore): decouple Network_Funcs from sockaddr via IP_Port fc4396cef fix: potential division by zero in toxav and unsafe hex parsing 8e8b352ab refactor: Add nullable annotations to struct members. 7740bb421 refactor: decouple net_crypto from DHT 1936d4296 test: add benchmark for toxav audio and video 46bfdc2df fix: correct printf format specifiers for unsigned integers REVERT: 1828c5356 fix(toxav): remove extra copy of video frame on encode git-subtree-dir: external/toxcore/c-toxcore git-subtree-split: c9cdae001341e701fca980c9bb9febfeb95d2902
2.9 KiB
2.9 KiB
Tox Scenario Framework
Tests should read like protocol specifications. Instead of managing manual loops and shared global state, each "node" in a test is assigned a script (sequence of tasks) that it executes concurrently with other nodes in a simulated environment.
1. ToxScenario
The container for a single test case.
- Manages a collection of
ToxNodeinstances. - Owns the Virtual Clock. All nodes in a scenario share the same timeline, making timeouts and delays deterministic.
- Handles the orchestration of the event loop (
tox_iterate).
2. ToxNode
A wrapper around a Tox instance and its associated state.
- Each node has its own
Tox_Dispatch. - Nodes are identified by a simple index or a string alias (e.g., "Alice", "Bob").
- Encapsulates the node's progress through its assigned Script.
3. tox_node_script_cb
A C function that defines what a node does. Because it runs in its own thread, you can use standard C control flow, local variables, and loops.
Example Usage
void alice_script(ToxNode *self, void *ctx) {
// Step 1: Wait for DHT connection
WAIT_UNTIL(tox_node_is_self_connected(self));
// Step 2: Send a message to Bob (friend 0)
uint8_t msg[] = "Hello Bob";
tox_friend_send_message(tox_node_get_tox(self), 0, TOX_MESSAGE_TYPE_NORMAL, msg, sizeof(msg), NULL);
// Step 3: Wait for a specific response event
WAIT_FOR_EVENT(TOX_EVENT_FRIEND_MESSAGE);
}
void test_simple_interaction() {
ToxScenario *s = tox_scenario_new(argc, argv, 10000); // 10s virtual timeout
ToxNode *alice = tox_scenario_add_node(s, "Alice", alice_script, NULL);
ToxNode *bob = tox_scenario_add_node(s, "Bob", bob_script, NULL);
tox_node_bootstrap(bob, alice);
tox_node_friend_add(alice, bob);
tox_node_friend_add(bob, alice);
ToxScenarioStatus res = tox_scenario_run(s);
ck_assert(res == TOX_SCENARIO_DONE);
tox_scenario_free(s);
}
Execution Model: Cooperative Multi-threading
The scenario framework uses pthread to provide a natural programming model
while maintaining a deterministic virtual clock:
- Runner: Orchestrates the scenario in "Ticks" (default 10ms).
- Nodes: Run concurrently in their own threads but synchronize at every tick.
- Yielding: When a script calls
WAIT_UNTIL,WAIT_FOR_EVENT, ortox_scenario_yield, it yields control back to the runner. - Time Advancement: The runner advances the virtual clock and signals all nodes to proceed only after all active nodes have yielded.
- Barriers: Nodes can synchronize their progress using
tox_scenario_barrier_wait(self). This function blocks the calling node until all other active nodes have also reached the barrier. This is useful for ensuring setup steps (like group creation or connection establishment) are complete across all nodes before proceeding to the next phase of the test.