Lumiera
0.pre.03
»edit your freedom«
|
Go to the source code of this file.
Function(integration) test of command dispatch into session thread.
This is a test combining several components to operate similar as in the real application, while still relying upon an unit-test like setup. The goal is to cover how session commands are issued from an access point (CoreService) in the UI backbone, passed on through an abstraction interface (the SessionCommand facade), handed over to the SteamDispatcher, which, running within a dedicated thread (the »session loop thread«), enqueues all these commands and dispatches them one by one.
This test setup defines a specifically rigged test command, which does not actually operate on the session. Instead, it performs some time calculations and adds the resulting time offset to a global variable, which can be observed from the test methods. The generated values are controlled by the command arguments and thus predictable, which allows to verify the expected number of invocations happened, using the right arguments.
The last test case performs a massively multithreaded torture test to scrutinise the sanity of locking and state management. It creates several threads, each of which produces several instances of the common test command used in this test, and binds each instance with different execution arguments. All these operations are sent as command messages, interspersed with short random pauses, which causes them to arrive in arbitrary order within the dispatcher queue. Moreover, while the "command producer threads" are running, the main thread temporarily disables command dispatch, which causes the command queue to build up. After re-enabling dispatch, the main thread spins to wait for the queue to become empty. The important point to note is that the test command function itself contains no locking. But since all command operations are triggered in a single dedicated thread, albeit in arbitrary order, at the end the checksum must add up to the expected value.
It is possible to change the actual setup with the following positional commandline arguments
This test case can fail when, by bad coincidence, the command queue is temporarily emptied, while some producer threads are still alive – because in this case the main thread might verify the checksum before all command instances have been triggered. To avoid this situation, make sure the delay between actions in the threads is not too long and start a sufficiently high number of producer threads.
Definition in file session-command-function-test.cpp.
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "common/interfaceregistry.h"
#include "steam/control/steam-dispatcher.hpp"
#include "steam/control/command-def.hpp"
#include "include/session-command-facade.h"
#include "lib/typed-counter.hpp"
#include "lib/format-string.hpp"
#include "lib/sync-barrier.hpp"
#include "lib/thread.hpp"
#include "lib/symbol.hpp"
#include "lib/util.hpp"
#include <boost/lexical_cast.hpp>
#include <chrono>
#include <string>
#include <vector>
#include <deque>
Classes | |
class | SessionCommandFunction_test |
Macros | |
#define | __DELAY__ sleep_for (20ms); |
Functions | |
Time | capture (Duration, Offset, int) |
LAUNCHER (SessionCommandFunction_test, "function controller") | |
Register this test class... More... | |
void | maybeOverride (uint &configSetting, Arg cmdline, uint paramNr) |
void | operate (Duration dur, Offset offset, int factor) |
void | undoIt (Duration, Offset, int, Time oldState) |
Variables | |
const Symbol | COMMAND_I1 {"test.dispatch.function.command.instance-1"} |
const Symbol | COMMAND_I2 {"test.dispatch.function.command.instance-2"} |
const Symbol | COMMAND_ID {"test.dispatch.function.command"} |
uint | MAX_RAND_DELAY_us = 50 |
uint | NUM_INVOC_PER_THRED = 10 |
uint | NUM_THREADS_DEFAULT = 50 |
TimeVar | testCommandState = randTime() |
Namespaces | |
steam | |
Steam-Layer implementation namespace root. | |
steam::control | |
Steam-Layer dispatcher, controller and administrative facilities. | |
steam::control::test::LAUNCHER | ( | SessionCommandFunction_test | , |
"function controller" | |||
) |
Register this test class...