2
3
6
7
8
9
10
12#include <so_5/experimental/testing/v1/all.hpp>
14#include <so_5/details/safe_cv_wait_for.hpp>
16#include <so_5/impl/enveloped_msg_details.hpp>
31 std::type_index msg_type,
32 mbox_id_t src_mbox_id )
55 m_completion = std::move(fn);
59 completion_function_t joined_version =
60 [old_fn = m_completion, new_fn = std::move(fn)]
61 (
const trigger_completion_context_t & ctx ) {
68 m_completion = std::move(joined_version);
77 m_activation = std::move(fn);
81 activation_function_t joined_version =
82 [old_fn = m_activation, new_fn = std::move(fn)]
83 (
const trigger_activation_context_t & ctx ) {
90 m_activation = std::move(joined_version);
98 const incident_info_t & info )
const noexcept
100 return incident_status == m_incident_status
101 && info.m_agent->so_direct_mbox()->id() == m_target_id
102 && info.m_msg_type == m_msg_type
103 && info.m_src_mbox_id == m_src_mbox_id;
110 return static_cast<
bool>(m_completion);
118 m_activation( context );
125 m_completion( context );
129
130
131
132
136 using preactivate_actions_container_t =
137 std::vector< preactivate_action_t >;
150
151
152
153
154
155
156
157
161
162
163
164
165
171
172
179
180
181
182
183
211 const scenario_in_progress_accessor_t & scenario_accessor,
212 const incident_info_t & info,
213 const message_ref_t & incoming_msg )
noexcept override
219 trigger_activation_context_t{
231 const scenario_in_progress_accessor_t & scenario_accessor,
232 token_t token )
noexcept override
237 trigger_completion_context_t{
242 --m_triggers_to_completion;
249 if( !m_triggers_to_completion &&
250 status_t::active == m_status )
257 const scenario_in_progress_accessor_t & scenario_accessor,
258 const incident_info_t & info,
259 const message_ref_t & incoming_msg )
noexcept override
263 trigger_activation_context_t{
280 preactivate_action_t action )
override
282 m_preactivate_actions.emplace_back( std::move(action) );
287 trigger_container_t triggers,
288 std::size_t triggers_to_activate )
noexcept override
292 swap( m_triggers, triggers );
293 m_triggers_to_activate = triggers_to_activate;
295 m_last_non_activated_trigger = m_triggers.size();
296 if( m_last_non_activated_trigger )
297 --m_last_non_activated_trigger;
302 constraint_container_t constraints )
noexcept override
306 swap( m_constraints, constraints );
313
314
315
316
317
318
319
328 for(
auto & act : m_preactivate_actions )
331 for(
auto & c : m_constraints )
337 for(
auto & c : m_constraints )
349
350
355 const incident_info_t & info )
const noexcept
357 for(
auto & c : m_constraints )
358 if( !c->check( incident_status, info ) )
370 const incident_info_t & info )
noexcept
383 auto end = std::begin(m_triggers) +
384 static_cast<trigger_container_t::iterator::difference_type>(
385 m_last_non_activated_trigger + 1u);
387 auto it = std::find_if(
388 std::begin(m_triggers), end,
389 [incident_status, &info]
390 ( trigger_unique_ptr_t & trigger ) {
391 return trigger->check( incident_status, info );
397 trigger_t * active_trigger = it->get();
402 if( m_last_non_activated_trigger )
405 std::swap( *it, m_triggers[ m_last_non_activated_trigger ] );
406 --m_last_non_activated_trigger;
409 ++m_triggers_activated;
412 ++m_triggers_to_completion;
414 result = token_t
{ active_trigger
};
418 if( m_triggers_activated == m_triggers_to_activate )
422 change_status( (0u != m_triggers_to_completion) ?
423 status_t::active : status_t::completed );
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
466
467
468
469
475
476
477
487
488
492
493
494
495
503
504
505 using state_name_map_t = std::map<
506 std::pair< std::string, std::string >,
511
512
513 using inspection_result_map_t = std::map<
514 std::pair< std::string, std::string >,
522
523
528
529
537
538
539
550 std::lock_guard< std::mutex > lock{ m_lock };
551 if( scenario_status_t::not_started != m_status )
553 rc_unable_to_define_new_step,
554 "new testing scenario step can be defined only when "
555 "scenario is not started yet" );
557 m_steps.emplace_back(
558 std::make_unique< real_scenario_step_t >(
559 step_name.giveout_value() ) );
561 return { m_steps.back().get() };
568 std::lock_guard< std::mutex > lock{ m_lock };
573 return { m_status, describe_current_state() };
577 run_for( std::chrono::steady_clock::duration run_time )
override
579 std::unique_lock< std::mutex > lock{ m_lock };
587 if( m_steps.empty() )
594 ::so_5::details::wait_for_big_interval(
598 [
this]{
return scenario_status_t::completed == m_status; });
608 const incident_info_t & info,
609 const message_ref_t & incoming_msg )
noexcept override
613 std::lock_guard< std::mutex > lock{ m_lock };
617 if( scenario_status_t::in_progress == m_status &&
618 m_waiting_step_index < m_steps.size() )
628 token_t token )
noexcept override
630 std::lock_guard< std::mutex > lock{ m_lock };
648 m_active_steps.erase( &step_to_check );
657 const incident_info_t & info,
658 const message_ref_t & incoming_msg )
noexcept override
660 std::lock_guard< std::mutex > lock{ m_lock };
664 if( scenario_status_t::in_progress == m_status &&
665 m_waiting_step_index < m_steps.size() )
673 const scenario_in_progress_accessor_t & ,
675 const std::string & tag,
676 const std::string & state_name )
override
678 m_stored_states[ std::make_pair(step.name(), tag) ] = state_name;
683 const scenario_in_progress_accessor_t & ,
685 const std::string & tag,
686 const std::string & inspection_result )
override
688 m_stored_inspection_results[ std::make_pair(step.name(), tag) ]
698 std::lock_guard< std::mutex > lock{ m_lock };
700 if( scenario_status_t::completed != m_status )
702 rc_scenario_must_be_completed,
703 "scenario must be completed before call to "
704 "stored_state_name()" );
706 const auto it = m_stored_states.find(
707 std::make_pair(step_name, tag) );
708 if( it == m_stored_states.end() )
710 rc_stored_state_name_not_found,
711 "unable to find stored state name for <" +
712 step_name +
"," + tag +
">" );
720 const std::string & step_name,
721 const std::string & tag )
const override
723 std::lock_guard< std::mutex > lock{ m_lock };
725 if( scenario_status_t::completed != m_status )
727 rc_scenario_must_be_completed,
728 "scenario must be completed before call to "
729 "stored_state_name()" );
731 return m_stored_states.end() != m_stored_states.find(
732 std::make_pair(step_name, tag) );
741 std::lock_guard< std::mutex > lock{ m_lock };
743 if( scenario_status_t::completed != m_status )
745 rc_scenario_must_be_completed,
746 "scenario must be completed before call to "
747 "stored_msg_inspection_result()" );
749 const auto it = m_stored_inspection_results.find(
750 std::make_pair(step_name, tag) );
751 if( it == m_stored_inspection_results.end() )
753 rc_stored_msg_inspection_result_not_found,
754 "unable to find stored msg inspection result for <" +
755 step_name +
"," + tag +
">" );
763 const std::string & step_name,
764 const std::string & tag )
const override
766 std::lock_guard< std::mutex > lock{ m_lock };
768 if( scenario_status_t::completed != m_status )
770 rc_scenario_must_be_completed,
771 "scenario must be completed before call to "
772 "has_stored_msg_inspection_result()" );
774 return m_stored_inspection_results.end() !=
775 m_stored_inspection_results.find(
776 std::make_pair(step_name, tag) );
784 m_steps[ m_waiting_step_index ]->preactivate();
790 const incident_info_t & info,
791 const message_ref_t & incoming_msg )
noexcept
796 auto & step_to_check = *(m_steps[ m_waiting_step_index ]);
797 auto step_token = step_to_check.pre_handler_hook(
802 if( step_token.valid() )
807 result = token_t{ &step_to_check, std::move(step_token) };
810 switch( step_to_check.status() )
812 case abstract_scenario_step_t::status_t::active :
814 m_active_steps.insert( &step_to_check );
815 switch_to_next_step_if_possible();
818 case abstract_scenario_step_t::status_t::completed :
820 switch_to_next_step_if_possible();
822 check_scenario_completion();
825 case abstract_scenario_step_t::status_t::passive:
break;
826 case abstract_scenario_step_t::status_t::preactivated:
break;
834 const incident_info_t & info,
835 const message_ref_t & incoming_msg )
noexcept
838 auto & step_to_check = *(m_steps[ m_waiting_step_index ]);
839 step_to_check.no_handler_hook(
845 switch( step_to_check.status() )
847 case abstract_scenario_step_t::status_t::active :
849 m_active_steps.insert( &step_to_check );
850 switch_to_next_step_if_possible();
853 case abstract_scenario_step_t::status_t::completed :
855 switch_to_next_step_if_possible();
857 check_scenario_completion();
860 case abstract_scenario_step_t::status_t::passive:
break;
861 case abstract_scenario_step_t::status_t::preactivated:
break;
868 ++m_waiting_step_index;
869 if( m_waiting_step_index < m_steps.size() )
880 if( m_active_steps.empty() &&
881 m_waiting_step_index >= m_steps.size() )
884 m_completion_cv.notify_all();
892 std::ostringstream ss;
894 if( m_waiting_step_index < m_steps.size() )
895 ss <<
"preactivated step:"
896 << m_steps[ m_waiting_step_index ]->name();
898 ss <<
"all steps handled";
902 if( !m_active_steps.empty() )
904 ss <<
" active steps:{";
905 bool need_comma =
false;
906 for(
auto * s : m_active_steps )
918 if( !m_stored_states.empty() )
920 ss <<
" stored states:{";
921 bool need_comma =
false;
922 for(
auto & p : m_stored_states )
929 ss <<
"[" << p.first.first <<
", "
930 << p.first.second <<
"]="
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
1010 class pre_handler_hook_invoker_t
final :
public handler_invoker_t
1030 invoke(
const payload_info_t & payload )
noexcept override
1033 auto token = m_owner.get()
1036 m_owner.get().m_demand_info,
1037 payload.message() );
1040 m_actual_invoker.get().invoke( payload );
1043 m_owner.get().m_scenario.get().post_handler_hook( token );
1048 class no_handler_invoker_t
final :
public handler_invoker_t
1061 invoke(
const payload_info_t & payload )
noexcept override
1063 m_owner.get().m_scenario.get().no_handler_hook(
1064 m_owner.get().m_demand_info,
1065 payload.message() );
1075 class invoker_for_message_extraction_t
final
1109 m_invoker.get().invoke( payload );
1117 auto & nested_envelope =
1151 no_handler_invoker_t invoker_no_handler_hook{
1152 outliving_mutable( *
this )
1154 invoker_for_message_extraction_t special_invoker{
1155 outliving_mutable( invoker_no_handler_hook ),
1160 special_invoker.invoke( payload_info_t{ m_message } );
1167 access_context_t context,
1169 handler_invoker_t & invoker )
noexcept override
1177 pre_handler_hook_invoker_t pre_handler_hook_invoker{
1178 outliving_mutable( *
this ),
1179 outliving_mutable( invoker )
1185 invoker_for_message_extraction_t special_invoker{
1186 outliving_mutable( pre_handler_hook_invoker ),
1191 special_invoker.invoke( payload_info_t{ m_message } );
1201 case access_context_t::transformation :
1202 invoker.invoke( payload_info_t{ m_message } );
1205 case access_context_t::inspection :
1206 invoker.invoke( payload_info_t{ m_message } );
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1268
1269
1294 std::lock_guard< std::mutex > lock{ m_lock };
1296 if( queue_mode_t::buffer == m_mode )
1297 m_buffer.push_back( std::move(demand) );
1299 m_original_queue.get().push( std::move(demand) );
1317 push_to_queue( std::move(demand) );
1322 message_ref_t new_env{
1323 std::make_unique< special_envelope_t >(
1328 demand.m_message_ref = std::move(new_env);
1332 push_to_queue( std::move(demand) );
1340 push_to_queue( std::move(demand) );
1347 push_to_queue( std::move(demand) );
1355 decltype(m_buffer) tmp;
1357 std::lock_guard< std::mutex > lock{ m_lock };
1361 for(
auto & d : m_buffer )
1362 m_original_queue.get().push( std::move(d) );
1365 swap( tmp, m_buffer );
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388class stop_guard_for_unfreezer_t
final
1390 ,
public std::enable_shared_from_this< stop_guard_for_unfreezer_t >
1408 m_unfreezer.get().unfreeze();
1412 m_env.get().remove_stop_guard( shared_from_this() );
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429class special_event_queue_hook_t
final
1444
1445
1446
1447
1448
1449
1450
1451
1466 std::lock_guard< std::mutex > lock{ m_lock };
1468 auto sq = std::make_unique< special_event_queue_t >(
1470 outliving_mutable( *original_queue ),
1473 if( queue_mode_t::buffer == m_mode )
1474 m_created_queues.push_back( sq.get() );
1476 return sq.release();
1496 decltype(m_created_queues) tmp;
1498 std::lock_guard< std::mutex > lock{ m_lock };
1503 swap( tmp, m_created_queues );
1508 for(
auto * sq : tmp )
1509 sq->switch_to_direct_mode();
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1532
1533
1534
1535
1536
1547 m_scenario.setup_unfreezer( m_special_hook );
1552 make() {
return std::make_unique<internals_t>(); }
1562 to.event_queue_hook(
1563 event_queue_hook_unique_ptr_t{
1564 std::addressof( internals.get().m_special_hook ),
1565 event_queue_hook_t::noop_deleter
1572 so_5::generic_simple_so_env_params_tuner_t env_params_tuner )
1575 env_params_tuner( result );
1586 setup_special_queue_hook( internals, params );
1590 ::msg_catcher_map_layer_t;
1592 std::make_unique< msg_catcher_map_layer_t >() );
1594 return std::move(params);
1611 return m_scenario.get().define_step( std::move(step_name) );
1617 return m_scenario.get().result();
1622 std::chrono::steady_clock::duration run_time )
1624 return m_scenario.get().run_for( run_time );
1632 return m_scenario.get().stored_state_name( step_name, tag );
1637 const std::string & step_name,
1638 const std::string & tag )
const
1640 return m_scenario.get().has_stored_state_name( step_name, tag );
1648 return m_scenario.get().stored_msg_inspection_result( step_name, tag );
1653 const std::string & step_name,
1654 const std::string & tag )
const
1656 return m_scenario.get().has_stored_msg_inspection_result( step_name, tag );
1667 so_5::generic_simple_so_env_params_tuner_t env_params_tuner )
1690 return m_sobjectizer.environment();
1696 m_sobjectizer.stop();
1702 m_sobjectizer.join();
1708 m_sobjectizer.stop_then_join();
1715 return { outliving_mutable(m_internals->m_scenario) };
1723 env.setup_stop_guard(
1724 std::make_shared< impl::stop_guard_for_unfreezer_t >(
1725 outliving_mutable(m_internals->m_special_hook),
1726 outliving_mutable(env) ) );
1732 m_internals->m_init_completed.m_completed.set_value();
1738 m_internals->m_init_completed.m_completed.get_future().wait();
static demand_handler_pfn_t get_demand_handler_on_message_ptr() noexcept
static demand_handler_pfn_t get_demand_handler_on_enveloped_msg_ptr() noexcept
An interface of envelope with some message/signal inside.
virtual void access_hook(access_context_t context, handler_invoker_t &invoker) noexcept=0
An extended version of handling_context which can be used for calling event handler.
An information about payload inside envelope.
message_ref_t & message() const noexcept
Parameters for the SObjectizer Environment initialization.
environment_params_t()
Constructor.
Interface of event_queue_hook object.
An interface of event queue for agent.
trigger_t & trigger() const noexcept
Get a reference to activated trigger.
token_t(trigger_t *trigger) noexcept
bool valid() const noexcept
An interface of testing scenario step.
virtual void post_handler_hook(const scenario_in_progress_accessor_t &scenario_accessor, token_t token) noexcept=0
Hook that should be called just after completion of event-handler.
virtual status_t status() const noexcept=0
Get the current status of the step.
abstract_scenario_step_t & activated_step() const noexcept
abstract_scenario_step_t::token_t step_token() const noexcept
bool valid() const noexcept
An interface of testing scenario.
scenario_in_progress_accessor_t make_accessor() noexcept
Helper method for creation of scenario_in_progress_accessor instance.
An interface for object that will unfreeze all registered agents when testing scenario starts.
agent_unfreezer_t(const agent_unfreezer_t &)=delete
agent_unfreezer_t & operator=(const agent_unfreezer_t &)=delete
agent_unfreezer_t()=default
virtual void unfreeze() noexcept=0
Issue a command to unfreeze all frozen agents.
agent_unfreezer_t(agent_unfreezer_t &&)=delete
agent_unfreezer_t & operator=(agent_unfreezer_t &&)=delete
virtual ~agent_unfreezer_t()=default
msg_catcher_map_layer_t()
~msg_catcher_map_layer_t() noexcept override
preactivate_actions_container_t m_preactivate_actions
All preactivation actions.
std::size_t m_triggers_activated
Count of triggers those are activated.
void no_handler_hook(const scenario_in_progress_accessor_t &scenario_accessor, const incident_info_t &info, const message_ref_t &incoming_msg) noexcept override
token_t pre_handler_hook(const scenario_in_progress_accessor_t &scenario_accessor, const incident_info_t &info, const message_ref_t &incoming_msg) noexcept override
Hook that should be called before invocation of event-handler.
bool try_pass_constraints(const incident_status_t incident_status, const incident_info_t &info) const noexcept
An attempt to check constraints for a new incident.
void setup_constraints(constraint_container_t constraints) noexcept override
Setup constraints for the step.
void preactivate() noexcept override
Perform preactivation of the step.
const std::string m_name
Name of a step.
std::size_t m_last_non_activated_trigger
Index of last trigger in the first part of trigger's container.
std::size_t m_triggers_to_activate
status_t status() const noexcept override
Get the current status of the step.
std::size_t m_triggers_to_completion
Count of activated triggers those are not completed yet.
status_t m_status
The current state of the step.
void post_handler_hook(const scenario_in_progress_accessor_t &scenario_accessor, token_t token) noexcept override
Hook that should be called just after completion of event-handler.
const std::string & name() const noexcept override
Get the name of the step.
token_t try_activate(const trigger_activation_context_t &context, const incident_status_t incident_status, const incident_info_t &info) noexcept
An attempt to activate the step when a new incident arrives.
constraint_container_t m_constraints
All constraints.
trigger_container_t m_triggers
All triggers.
real_scenario_step_t(std::string name)
void add_preactivate_action(preactivate_action_t action) override
Add another preactivation action.
void setup_triggers(trigger_container_t triggers, std::size_t triggers_to_activate) noexcept override
Setup triggers for the step.
void change_status(status_t status) noexcept
void no_handler_hook(const incident_info_t &info, const message_ref_t &incoming_msg) noexcept override
std::string stored_msg_inspection_result(const std::string &step_name, const std::string &tag) const override
Get a value of stored msg inspection result.
bool has_stored_state_name(const std::string &step_name, const std::string &tag) const override
Check presence of the stored state name.
void check_scenario_completion() noexcept
std::size_t m_waiting_step_index
Index of the current preactivated step.
void switch_to_next_step_if_possible()
std::set< abstract_scenario_step_t * > m_active_steps
Set of active step those are not completed yet.
scenario_result_t result() const noexcept override
Get the result of scenario execution.
void store_msg_inspection_result(const scenario_in_progress_accessor_t &, const abstract_scenario_step_t &step, const std::string &tag, const std::string &inspection_result) override
Store msg inspection result in the scenario.
std::string describe_current_state() const
bool has_stored_msg_inspection_result(const std::string &step_name, const std::string &tag) const override
Is there the inspection result?
std::string stored_state_name(const std::string &step_name, const std::string &tag) const override
Get the stored state name.
token_t react_on_pre_handler_hook(const incident_info_t &info, const message_ref_t &incoming_msg) noexcept
std::condition_variable m_completion_cv
Condition variable for waiting completion of the scenario.
void react_on_no_handler_hook(const incident_info_t &info, const message_ref_t &incoming_msg) noexcept
void preactivate_current_step()
void post_handler_hook(token_t token) noexcept override
Hook that should be called just after completion of event-handler.
void run_for(std::chrono::steady_clock::duration run_time) override
Run the scenario until completion or for specific amount of time.
agent_unfreezer_t * m_unfreezer
Unfreezer for registered agents.
real_scenario_t()=default
void setup_unfreezer(agent_unfreezer_t &unfreezer) noexcept
Set the unfreezer for registered agents.
inspection_result_map_t m_stored_inspection_results
Container for holding stored inspection results for messages.
void store_state_name(const scenario_in_progress_accessor_t &, const abstract_scenario_step_t &step, const std::string &tag, const std::string &state_name) override
Store a name of an agent state in the scenario.
token_t pre_handler_hook(const incident_info_t &info, const message_ref_t &incoming_msg) noexcept override
Hook that should be called before invocation of event-handler.
std::mutex m_lock
Object lock.
step_definition_proxy_t define_step(nonempty_name_t step_name) override
Create a new step and return proxy for it.
state_name_map_t m_stored_states
Container for holding stored state names.
scenario_status_t m_status
The current state of the scenario.
std::vector< step_unique_ptr_t > m_steps
Scenario's steps.
void set_completion(completion_function_t fn)
Setter for completion function.
void set_activation(activation_function_t fn)
Setter for activation function.
void activate(const trigger_activation_context_t &context) noexcept
Do activation of the trigger.
bool check(const incident_status_t incident_status, const incident_info_t &info) const noexcept
Check for activation of the trigger.
const mbox_id_t m_src_mbox_id
ID of source mbox of message/signal to activate the trigger.
trigger_t(incident_status_t incident_status, const agent_t &target, std::type_index msg_type, mbox_id_t src_mbox_id)
Initializing constructor.
const agent_t & target_agent() const noexcept
Get the reference of the target agent.
const incident_status_t m_incident_status
What should happen with initial message/signal.
bool requires_completion() const noexcept
Does this trigger require separate completion action?
void complete(const trigger_completion_context_t &context) noexcept
Do completion of a trigger.
const agent_t & m_target_agent
A reference to the target agent.
void invoke(const payload_info_t &payload) noexcept override
Call an actual handler for the enveloped message/signal.
no_handler_invoker_t(outliving_reference_t< special_envelope_t > owner)
Initializing constructor.
outliving_reference_t< special_envelope_t > m_owner
Owner of this invoker.
outliving_reference_t< handler_invoker_t > m_actual_invoker
Invoker to be used to call the actual event handler.
void invoke(const payload_info_t &payload) noexcept override
Call an actual handler for the enveloped message/signal.
pre_handler_hook_invoker_t(outliving_reference_t< special_envelope_t > owner, outliving_reference_t< handler_invoker_t > actual_invoker)
Intializing constructor.
outliving_reference_t< special_envelope_t > m_owner
Owner of this invoker.
outliving_reference_t< details::abstract_scenario_t > m_scenario
A testing scenario for that envelope.
~special_envelope_t() noexcept override
@ delivered
Message delivered to the destination agent.
@ suppressed_by_envelope
Message suppressed by a nested envelope.
@ ignored
Message ignored by the destination agent.
special_envelope_t(outliving_reference_t< details::abstract_scenario_t > scenario, const execution_demand_t &demand)
Initializing constructor.
message_ref_t m_message
Enveloped message.
details::incident_info_t m_demand_info
Information about enveloped message.
void access_hook(access_context_t context, handler_invoker_t &invoker) noexcept override
delivery_result_t m_delivery_result
Was this message handled by a receiver?
void unfreeze() noexcept override
Issue a command to unfreeze all frozen agents.
std::mutex m_lock
Lock for this object.
outliving_reference_t< details::abstract_scenario_t > m_scenario
Testing scenario for that this object is created.
void on_unbind(agent_t *, event_queue_t *queue) noexcept override
A reaction to unbinding of an agent from some event_queue.
queue_mode_t m_mode
Mode of operation for new queues.
std::vector< special_event_queue_t * > m_created_queues
List of all queues created before unfreeze was called.
special_event_queue_hook_t(outliving_reference_t< details::abstract_scenario_t > scenario)
event_queue_t * on_bind(agent_t *, event_queue_t *original_queue) noexcept override
A reaction to binding of an agent to some event_queue.
std::vector< execution_demand_t > m_buffer
Local storage for demands to be used in buffered mode.
static bool is_ordinary_demand(const execution_demand_t &demand) noexcept
special_event_queue_t(outliving_reference_t< details::abstract_scenario_t > scenario, outliving_reference_t< event_queue_t > original_queue, queue_mode_t queue_mode)
void push_to_queue(execution_demand_t demand)
void push_evt_finish(execution_demand_t demand) noexcept override
Enqueue a demand for evt_finish event.
queue_mode_t m_mode
The current mode of operation.
std::mutex m_lock
Object lock.
void push_evt_start(execution_demand_t demand) override
Enqueue a demand for evt_start event.
outliving_reference_t< event_queue_t > m_original_queue
Original event_queue.
void switch_to_direct_mode()
void push(execution_demand_t demand) override
Enqueue new event to the queue.
outliving_reference_t< details::abstract_scenario_t > m_scenario
Testing scenario for that this queue was created.
stop_guard_for_unfreezer_t(outliving_reference_t< details::agent_unfreezer_t > unfreezer, outliving_reference_t< environment_t > env)
outliving_reference_t< details::agent_unfreezer_t > m_unfreezer
outliving_reference_t< environment_t > m_env
void stop() noexcept override
Perform stop-related actions.
step_definition_proxy_t define_step(nonempty_name_t step_name)
Start definition of a new scenario's step.
std::string stored_state_name(const std::string &step_name, const std::string &tag) const
Try to get stored name of an agent's state.
std::string stored_msg_inspection_result(const std::string &step_name, const std::string &tag) const
Try to get stored msg inspection result.
bool has_stored_state_name(const std::string &step_name, const std::string &tag) const
Is there the inspection result?
bool has_stored_msg_inspection_result(const std::string &step_name, const std::string &tag) const
Is there the inspection result?
void run_for(std::chrono::steady_clock::duration run_time)
Runs the scenario for specified amount of time.
scenario_proxy_t(outliving_reference_t< details::abstract_scenario_t > scenario)
scenario_result_t result() const
Get the result of scenario execution.
The result of run of testing scenario.
scenario_result_t(scenario_status_t status)
The constructor for a case when there is only status of scenario.
A special object that should be used for definition of a step of a testing scenario.
A special testing environment that should be used for testing of agents.
void stop()
Send stop signal to environment.
environment_t & environment() const
Access to wrapped environment.
testing_env_t()
Default constructor.
testing_env_t(environment_params_t &&env_params)
void wait_init_completion()
scenario_proxy_t scenario() noexcept
Access to the associated scenario.
void join()
Wait for complete finish of environment's work.
void tune_environment_on_start(environment_t &env)
void stop_then_join()
Send stop signal and wait for complete finish of environment's work.
testing_env_t(so_5::generic_simple_so_env_params_tuner_t env_params_tuner)
A constructor that allows to tune environment's parameters.
A base class for agent messages.
friend message_kind_t message_kind(const so_5::intrusive_ptr_t< message_t > &what)
Helper method for quering kind of the message.
A class for the name which cannot be empty.
Helper class for indication of long-lived reference via its type.
An interface of stop_guard entity.
#define SO_5_THROW_EXCEPTION(error_code, desc)
Some reusable and low-level classes/functions which can be used in public header files.
envelope_t & message_to_envelope(const message_ref_t &src_msg)
A helper function for casting message instance to envelope instance.
access_context_t
Information about context on that enveloped message is handled.
incident_status_t
What happened with source of an event.
@ handled
Message or signal has been handled.
@ ignored
Message or signal has been ignored.
environment_params_t make_special_params(outliving_reference_t< testing_env_t::internals_t > internals, environment_params_t &¶ms)
void setup_special_queue_hook(outliving_reference_t< testing_env_t::internals_t > internals, environment_params_t &to)
environment_params_t make_tuned_params(so_5::generic_simple_so_env_params_tuner_t env_params_tuner)
queue_mode_t
A mode of work for special_event_queue.
@ direct
All messages should go to the original queue without buffering.
@ buffer
All messages must be stored locally.
scenario_status_t
Status of testing scenario.
@ completed
Testing scenario is successfuly completed.
Private part of message limit implementation.
@ user_type_message
Message is an user type message.
@ enveloped_msg
Message is an envelope with some other message inside.
A description of event execution demand.
demand_handler_pfn_t m_demand_handler
Demand handler.
Description of context on that an attempt to activate a trigger is performing.
Description of context on that a trigger is completed.
A helper object for synchronization between helper worker where testing environment is launched and u...
std::promise< void > m_completed
Internal data for testing environment.
impl::init_completed_data_t m_init_completed
impl::special_event_queue_hook_t m_special_hook
details::real_scenario_t m_scenario
static std::unique_ptr< internals_t > make()