1 #include "client_state_fixture.hpp"
2 #include <iostream>
3
4 //
5 // Test a successful XA transaction lifecycle
6 //
BOOST_FIXTURE_TEST_CASE(transaction_xa,replicating_client_fixture_sync_rm)7 BOOST_FIXTURE_TEST_CASE(transaction_xa,
8 replicating_client_fixture_sync_rm)
9 {
10 wsrep::xid xid(1, 9, 0, "test xid");
11
12 BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
13 cc.assign_xid(xid);
14
15 BOOST_REQUIRE(tc.active());
16 BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
17 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
18
19 BOOST_REQUIRE(cc.before_prepare() == 0);
20 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_preparing);
21 BOOST_REQUIRE(tc.ordered() == false);
22 // certified() only after the last fragment
23 BOOST_REQUIRE(tc.certified() == false);
24 BOOST_REQUIRE(cc.after_prepare() == 0);
25 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_prepared);
26 BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
27 // XA START + PREPARE fragment
28 BOOST_REQUIRE(sc.provider().start_fragments() == 1);
29 BOOST_REQUIRE(sc.provider().fragments() == 1);
30
31 BOOST_REQUIRE(cc.before_commit() == 0);
32 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committing);
33 BOOST_REQUIRE(cc.ordered_commit() == 0);
34 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_ordered_commit);
35 BOOST_REQUIRE(tc.ordered());
36 BOOST_REQUIRE(tc.certified());
37 BOOST_REQUIRE(cc.after_commit() == 0);
38 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
39 // XA PREPARE and XA COMMIT fragments
40 BOOST_REQUIRE(sc.provider().fragments() == 2);
41 BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
42
43 BOOST_REQUIRE(cc.after_statement() == 0);
44 BOOST_REQUIRE(tc.active() == false);
45 BOOST_REQUIRE(tc.ordered() == false);
46 BOOST_REQUIRE(tc.certified() == false);
47 BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
48 }
49
50
51 //
52 // Test detaching of XA transactions
53 //
BOOST_FIXTURE_TEST_CASE(transaction_xa_detach_commit_by_xid,replicating_two_clients_fixture_sync_rm)54 BOOST_FIXTURE_TEST_CASE(transaction_xa_detach_commit_by_xid,
55 replicating_two_clients_fixture_sync_rm)
56 {
57 wsrep::xid xid(1, 1, 1, "id");
58
59 cc1.start_transaction(wsrep::transaction_id(1));
60 cc1.assign_xid(xid);
61 cc1.before_prepare();
62 cc1.after_prepare();
63 BOOST_REQUIRE(sc.provider().fragments() == 1);
64 BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
65
66 cc1.xa_detach();
67
68 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
69 BOOST_REQUIRE(cc1.after_statement() == 0);
70
71 cc2.start_transaction(wsrep::transaction_id(2));
72 cc2.assign_xid(xid);
73 BOOST_REQUIRE(cc2.client_state::commit_by_xid(xid) == 0);
74 BOOST_REQUIRE(cc2.after_statement() == 0);
75 BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
76
77 // xa_detach() creates a streaming applier, clean it up
78 wsrep::mock_high_priority_service* hps(
79 static_cast<wsrep::mock_high_priority_service*>(
80 sc.find_streaming_applier(xid)));
81 BOOST_REQUIRE(hps);
82 hps->rollback(wsrep::ws_handle(), wsrep::ws_meta());
83 hps->after_apply();
84 sc.stop_streaming_applier(sc.id(), wsrep::transaction_id(1));
85 server_service.release_high_priority_service(hps);
86 }
87
BOOST_FIXTURE_TEST_CASE(transaction_xa_detach_rollback_by_xid,replicating_two_clients_fixture_sync_rm)88 BOOST_FIXTURE_TEST_CASE(transaction_xa_detach_rollback_by_xid,
89 replicating_two_clients_fixture_sync_rm)
90 {
91 wsrep::xid xid(1, 1, 1, "id");
92
93 cc1.start_transaction(wsrep::transaction_id(1));
94 cc1.assign_xid(xid);
95 cc1.before_prepare();
96 cc1.after_prepare();
97 BOOST_REQUIRE(sc.provider().fragments() == 1);
98 BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
99
100 cc1.xa_detach();
101
102 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
103 BOOST_REQUIRE(cc1.after_statement() == 0);
104
105 cc2.start_transaction(wsrep::transaction_id(2));
106 cc2.assign_xid(xid);
107 BOOST_REQUIRE(cc2.rollback_by_xid(xid) == 0);
108 BOOST_REQUIRE(cc2.after_statement() == 0);
109 BOOST_REQUIRE(sc.provider().rollback_fragments() == 1);
110
111 // xa_detach() creates a streaming applier, clean it up
112 wsrep::mock_high_priority_service* hps(
113 static_cast<wsrep::mock_high_priority_service*>(
114 sc.find_streaming_applier(xid)));
115 BOOST_REQUIRE(hps);
116 hps->rollback(wsrep::ws_handle(), wsrep::ws_meta());
117 hps->after_apply();
118 sc.stop_streaming_applier(sc.id(), wsrep::transaction_id(1));
119 server_service.release_high_priority_service(hps);
120 }
121
122
123 //
124 // Test XA replay
125 //
BOOST_FIXTURE_TEST_CASE(transaction_xa_replay,replicating_client_fixture_sync_rm)126 BOOST_FIXTURE_TEST_CASE(transaction_xa_replay,
127 replicating_client_fixture_sync_rm)
128 {
129 wsrep::xid xid(1, 1, 1, "id");
130
131 cc.start_transaction(wsrep::transaction_id(1));
132 cc.assign_xid(xid);
133 cc.before_prepare();
134 cc.after_prepare();
135 cc.after_command_before_result();
136 cc.after_command_after_result();
137 BOOST_REQUIRE(cc.state() == wsrep::client_state::s_idle);
138 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_prepared);
139 wsrep_test::bf_abort_unordered(cc);
140 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
141
142 // this is normally done by rollbacker
143 cc.xa_replay();
144 cc.sync_rollback_complete();
145
146 BOOST_REQUIRE(cc.unordered_replays() == 1);
147
148 // xa_replay() creates a streaming applier, clean it up
149 wsrep::mock_high_priority_service* hps(
150 static_cast<wsrep::mock_high_priority_service*>(
151 sc.find_streaming_applier(sc.id(), wsrep::transaction_id(1))));
152 BOOST_REQUIRE(hps);
153 hps->rollback(wsrep::ws_handle(), wsrep::ws_meta());
154 hps->after_apply();
155 sc.stop_streaming_applier(sc.id(), wsrep::transaction_id(1));
156 server_service.release_high_priority_service(hps);
157 }
158
BOOST_FIXTURE_TEST_CASE(transaction_xa_replay_after_command_before_result,replicating_client_fixture_sync_rm)159 BOOST_FIXTURE_TEST_CASE(transaction_xa_replay_after_command_before_result,
160 replicating_client_fixture_sync_rm)
161 {
162 wsrep::xid xid(1, 1, 1, "id");
163
164 cc.start_transaction(wsrep::transaction_id(1));
165 cc.assign_xid(xid);
166 cc.before_prepare();
167 cc.after_prepare();
168 BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
169 wsrep_test::bf_abort_unordered(cc);
170 cc.after_command_before_result();
171 cc.after_command_after_result();
172
173 BOOST_REQUIRE(cc.unordered_replays() == 1);
174
175 // xa_replay() creates a streaming applier, clean it up
176 wsrep::mock_high_priority_service* hps(
177 static_cast<wsrep::mock_high_priority_service*>(
178 sc.find_streaming_applier(sc.id(), wsrep::transaction_id(1))));
179 BOOST_REQUIRE(hps);
180 hps->rollback(wsrep::ws_handle(), wsrep::ws_meta());
181 hps->after_apply();
182 sc.stop_streaming_applier(sc.id(), wsrep::transaction_id(1));
183 server_service.release_high_priority_service(hps);
184 }
185
BOOST_FIXTURE_TEST_CASE(transaction_xa_replay_after_command_after_result,replicating_client_fixture_sync_rm)186 BOOST_FIXTURE_TEST_CASE(transaction_xa_replay_after_command_after_result,
187 replicating_client_fixture_sync_rm)
188 {
189 wsrep::xid xid(1, 1, 1, "id");
190
191 cc.start_transaction(wsrep::transaction_id(1));
192 cc.assign_xid(xid);
193 cc.before_prepare();
194 cc.after_prepare();
195 cc.after_command_before_result();
196 BOOST_REQUIRE(cc.state() == wsrep::client_state::s_result);
197 wsrep_test::bf_abort_unordered(cc);
198
199 cc.after_command_after_result();
200
201 BOOST_REQUIRE(cc.unordered_replays() == 1);
202
203 // xa_replay() creates a a streaming applier, clean it up
204 wsrep::mock_high_priority_service* hps(
205 static_cast<wsrep::mock_high_priority_service*>(
206 sc.find_streaming_applier(sc.id(), wsrep::transaction_id(1))));
207 BOOST_REQUIRE(hps);
208 hps->rollback(wsrep::ws_handle(), wsrep::ws_meta());
209 hps->after_apply();
210 sc.stop_streaming_applier(sc.id(), wsrep::transaction_id(1));
211 server_service.release_high_priority_service(hps);
212 }
213
214 //
215 // Test a successful XA transaction lifecycle (applying side)
216 //
BOOST_FIXTURE_TEST_CASE(transaction_xa_applying,applying_client_fixture)217 BOOST_FIXTURE_TEST_CASE(transaction_xa_applying,
218 applying_client_fixture)
219 {
220 wsrep::xid xid(1, 9, 0, "test xid");
221
222 start_transaction(wsrep::transaction_id(1), wsrep::seqno(1));
223 cc.assign_xid(xid);
224
225 BOOST_REQUIRE(cc.before_prepare() == 0);
226 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_preparing);
227 BOOST_REQUIRE(tc.ordered());
228 BOOST_REQUIRE(tc.certified());
229 BOOST_REQUIRE(tc.ws_meta().gtid().is_undefined() == false);
230 BOOST_REQUIRE(cc.after_prepare() == 0);
231 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_prepared);
232
233 BOOST_REQUIRE(cc.before_commit() == 0);
234 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committing);
235 BOOST_REQUIRE(cc.ordered_commit() == 0);
236 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_ordered_commit);
237 BOOST_REQUIRE(cc.after_commit() == 0);
238 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
239 cc.after_applying();
240 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
241 BOOST_REQUIRE(tc.active() == false);
242 BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
243 }
244
245 ///////////////////////////////////////////////////////////////////////////////
246 // STREAMING REPLICATION //
247 ///////////////////////////////////////////////////////////////////////////////
248
249 //
250 // Test a successful XA transaction lifecycle
251 //
BOOST_FIXTURE_TEST_CASE(transaction_xa_sr,streaming_client_fixture_byte)252 BOOST_FIXTURE_TEST_CASE(transaction_xa_sr,
253 streaming_client_fixture_byte)
254 {
255 wsrep::xid xid(1, 9, 0, "test xid");
256
257 BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
258 cc.assign_xid(xid);
259
260 cc.bytes_generated_ = 1;
261 BOOST_REQUIRE(cc.after_row() == 0);
262 BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
263 // XA START fragment with data
264 BOOST_REQUIRE(sc.provider().fragments() == 1);
265 BOOST_REQUIRE(sc.provider().start_fragments() == 1);
266
267 BOOST_REQUIRE(tc.active());
268 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
269
270 BOOST_REQUIRE(cc.before_prepare() == 0);
271 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_preparing);
272 BOOST_REQUIRE(tc.ordered() == false);
273 BOOST_REQUIRE(tc.certified() == false);
274 BOOST_REQUIRE(cc.after_prepare() == 0);
275 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_prepared);
276 // XA PREPARE fragment
277 BOOST_REQUIRE(sc.provider().fragments() == 2);
278
279 BOOST_REQUIRE(cc.before_commit() == 0);
280 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committing);
281 BOOST_REQUIRE(cc.ordered_commit() == 0);
282 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_ordered_commit);
283 BOOST_REQUIRE(tc.ordered());
284 BOOST_REQUIRE(tc.certified());
285 BOOST_REQUIRE(cc.after_commit() == 0);
286 BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
287 BOOST_REQUIRE(cc.after_statement() == 0);
288 BOOST_REQUIRE(tc.active() == false);
289 BOOST_REQUIRE(tc.ordered() == false);
290 BOOST_REQUIRE(tc.certified() == false);
291 BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
292 // XA START fragment (with data), XA PREPARE fragment and XA COMMIT fragment
293 BOOST_REQUIRE(sc.provider().fragments() == 3);
294 BOOST_REQUIRE(sc.provider().start_fragments() == 1);
295 BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
296 }
297