1 /*
2  * A test for redirection of mutable as immutable messages.
3  */
4 
5 #include <so_5/all.hpp>
6 
7 #include <test/3rd_party/various_helpers/time_limited_execution.hpp>
8 #include <test/3rd_party/various_helpers/ensure.hpp>
9 
10 #include <test/3rd_party/utest_helper/helper.hpp>
11 
12 using namespace std;
13 
14 class sobj_message_tester final : public so_5::agent_t
15 {
16 	struct hello final : public so_5::message_t
17 	{
18 		std::string m_content;
hellosobj_message_tester::hello19 		hello( std::string content ) : m_content( std::move(content) ) {}
20 	};
21 
22 public :
sobj_message_tester(context_t ctx)23 	sobj_message_tester(context_t ctx)
24 		:	so_5::agent_t(std::move(ctx))
25 	{
26 		so_subscribe_self().event( &sobj_message_tester::on_hello_mut );
27 		so_subscribe_self().event( &sobj_message_tester::on_hello_imm );
28 	}
29 
30 	virtual void
so_evt_start()31 	so_evt_start() override
32 	{
33 		so_5::send< so_5::mutable_msg< hello > >( *this, "hello" );
34 	}
35 
36 private :
37 	const hello * m_received_ptr{ nullptr };
38 
on_hello_mut(mhood_t<so_5::mutable_msg<hello>> cmd)39 	void on_hello_mut( mhood_t< so_5::mutable_msg< hello > > cmd )
40 	{
41 		ensure(
42 				so_5::message_mutability_t::mutable_message ==
43 						message_mutability( *cmd ),
44 				"mutable message is expected" );
45 
46 		std::cout << "sobj: " << cmd->m_content << std::endl;
47 
48 		m_received_ptr = cmd.get();
49 		cmd->m_content = "bye";
50 		send( *this, to_immutable( std::move(cmd) ) );
51 	}
52 
on_hello_imm(mhood_t<hello> cmd)53 	void on_hello_imm( mhood_t< hello > cmd )
54 	{
55 		ensure(
56 				so_5::message_mutability_t::immutable_message ==
57 						message_mutability( *cmd ),
58 				"immutable message is expected" );
59 
60 		std::cout << "sobj: " << cmd->m_content << std::endl;
61 
62 		ensure( m_received_ptr == cmd.get(), "expect the same message" );
63 		ensure( "bye" == cmd->m_content, "expect 'bye' message" );
64 
65 		so_deregister_agent_coop_normally();
66 	}
67 };
68 
69 class user_message_tester final : public so_5::agent_t
70 {
71 	struct hello final
72 	{
73 		std::string m_content;
hellouser_message_tester::hello74 		hello( std::string content ) : m_content( std::move(content) ) {}
75 	};
76 
77 public :
user_message_tester(context_t ctx)78 	user_message_tester(context_t ctx)
79 		:	so_5::agent_t(std::move(ctx))
80 	{
81 		so_subscribe_self().event( &user_message_tester::on_hello_mut );
82 		so_subscribe_self().event( &user_message_tester::on_hello_imm );
83 	}
84 
85 	virtual void
so_evt_start()86 	so_evt_start() override
87 	{
88 		so_5::send< so_5::mutable_msg< hello > >( *this, "hello" );
89 	}
90 
91 private :
92 	const hello * m_received_ptr{ nullptr };
93 
on_hello_mut(mhood_t<so_5::mutable_msg<hello>> cmd)94 	void on_hello_mut( mhood_t< so_5::mutable_msg< hello > > cmd )
95 	{
96 		std::cout << "user: " << cmd->m_content << std::endl;
97 
98 		m_received_ptr = cmd.get();
99 		cmd->m_content = "bye";
100 		send( *this, to_immutable( std::move(cmd) ) );
101 	}
102 
on_hello_imm(mhood_t<hello> cmd)103 	void on_hello_imm( mhood_t< hello > cmd )
104 	{
105 		std::cout << "user: " << cmd->m_content << std::endl;
106 
107 		ensure( m_received_ptr == cmd.get(), "expect the same message" );
108 		ensure( "bye" == cmd->m_content, "expect 'bye' message" );
109 
110 		so_deregister_agent_coop_normally();
111 	}
112 };
113 
114 int
main()115 main()
116 {
117 	try
118 	{
119 		run_with_time_limit(
120 			[]() {
121 				so_5::launch(
122 					[&](so_5::environment_t & env) {
123 						env.register_agent_as_coop(
124 								env.make_agent<sobj_message_tester>());
125 
126 						env.register_agent_as_coop(
127 								env.make_agent<user_message_tester>());
128 					},
129 					[](so_5::environment_params_t & params) {
130 						(void)params;
131 #if 0
132 						params.message_delivery_tracer( so_5::msg_tracing::std_cout_tracer() );
133 #endif
134 					} );
135 			},
136 			5,
137 			"simple agent");
138 	}
139 	catch(const exception & ex)
140 	{
141 		cerr << "Error: " << ex.what() << endl;
142 		return 1;
143 	}
144 
145 	return 0;
146 }
147 
148