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