Files
tomato-testing/auto_tests/scenarios/framework/README.md
Green Sky 565efa4f39 Squashed 'external/toxcore/c-toxcore/' changes from 1828c5356..c9cdae001
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
2026-01-11 14:42:31 +01:00

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 ToxNode instances.
  • 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:

  1. Runner: Orchestrates the scenario in "Ticks" (default 10ms).
  2. Nodes: Run concurrently in their own threads but synchronize at every tick.
  3. Yielding: When a script calls WAIT_UNTIL, WAIT_FOR_EVENT, or tox_scenario_yield, it yields control back to the runner.
  4. Time Advancement: The runner advances the virtual clock and signals all nodes to proceed only after all active nodes have yielded.
  5. 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.