1 /*
2  * Copyright (C) 2018-2019 Codership Oy <info@codership.com>
3  *
4  * This file is part of wsrep-lib.
5  *
6  * Wsrep-lib is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Wsrep-lib is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with wsrep-lib.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "wsrep/transaction.hpp"
21 #include "wsrep/provider.hpp"
22 
23 #include "test_utils.hpp"
24 #include "client_state_fixture.hpp"
25 
26 #include <boost/mpl/vector.hpp>
27 
28 namespace
29 {
30     typedef
31     boost::mpl::vector<replicating_client_fixture_sync_rm,
32                        replicating_client_fixture_async_rm>
33     replicating_fixtures;
34 }
35 
BOOST_FIXTURE_TEST_CASE(transaction_append_key_data,replicating_client_fixture_sync_rm)36 BOOST_FIXTURE_TEST_CASE(transaction_append_key_data,
37                         replicating_client_fixture_sync_rm)
38 {
39     cc.start_transaction(wsrep::transaction_id(1));
40     BOOST_REQUIRE(tc.active());
41     BOOST_REQUIRE(tc.is_empty());
42     int vals[3] = {1, 2, 3};
43     wsrep::key key(wsrep::key::exclusive);
44     for (int i(0); i < 3; ++i)
45     {
46         key.append_key_part(&vals[i], sizeof(vals[i]));
47     }
48     BOOST_REQUIRE(cc.append_key(key) == 0);
49     BOOST_REQUIRE(tc.is_empty() == false);
50     wsrep::const_buffer data(&vals[2], sizeof(vals[2]));
51     BOOST_REQUIRE(cc.append_data(data) == 0);
52     BOOST_REQUIRE(cc.before_commit() == 0);
53     BOOST_REQUIRE(cc.ordered_commit() == 0);
54     BOOST_REQUIRE(cc.after_commit() == 0);
55     cc.after_statement();
56 }
57 //
58 // Test a succesful 1PC transaction lifecycle
59 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc,T,replicating_fixtures,T)60 BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc, T,
61                                  replicating_fixtures, T)
62 {
63     wsrep::mock_client& cc(T::cc);
64     const wsrep::transaction& tc(T::tc);
65     // Start a new transaction with ID 1
66     cc.start_transaction(wsrep::transaction_id(1));
67     BOOST_REQUIRE(tc.active());
68     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
69     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
70 
71     // Establish default read view
72     BOOST_REQUIRE(0 == cc.assign_read_view(NULL));
73 
74     // Verify that the commit can be successfully executed in separate command
75     BOOST_REQUIRE(cc.after_statement() == 0);
76     cc.after_command_before_result();
77     cc.after_command_after_result();
78     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
79     BOOST_REQUIRE(cc.before_command() == 0);
80     BOOST_REQUIRE(cc.before_statement() == 0);
81     // Run before commit
82     BOOST_REQUIRE(cc.before_commit() == 0);
83     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committing);
84 
85     // Run ordered commit
86     BOOST_REQUIRE(cc.ordered_commit() == 0);
87     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_ordered_commit);
88 
89     // Run after commit
90     BOOST_REQUIRE(cc.after_commit() == 0);
91     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
92 
93     // Cleanup after statement
94     cc.after_statement();
95     BOOST_REQUIRE(tc.active() == false);
96     BOOST_REQUIRE(tc.ordered() == false);
97     BOOST_REQUIRE(tc.certified() == false);
98     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
99 }
100 
101 
102 //
103 // Test a voluntary rollback
104 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_rollback,T,replicating_fixtures,T)105 BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_rollback, T,
106                                  replicating_fixtures, T)
107 {
108     wsrep::mock_client& cc(T::cc);
109     const wsrep::transaction& tc(T::tc);
110 
111     // Start a new transaction with ID 1
112     cc.start_transaction(wsrep::transaction_id(1));
113     BOOST_REQUIRE(tc.active());
114     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
115     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
116 
117     // Run before commit
118     BOOST_REQUIRE(cc.before_rollback() == 0);
119     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
120 
121     // Run after commit
122     BOOST_REQUIRE(cc.after_rollback() == 0);
123     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
124 
125     // Cleanup after statement
126     cc.after_statement();
127     BOOST_REQUIRE(tc.active() == false);
128     BOOST_REQUIRE(tc.ordered() == false);
129     BOOST_REQUIRE(tc.certified() == false);
130     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
131 }
132 
133 //
134 // Test a 1PC transaction which gets BF aborted before before_commit
135 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_before_before_commit,T,replicating_fixtures,T)136 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
137     transaction_1pc_bf_before_before_commit, T,
138     replicating_fixtures, T)
139 {
140     wsrep::mock_client& cc(T::cc);
141     const wsrep::transaction& tc(T::tc);
142 
143     // Start a new transaction with ID 1
144     cc.start_transaction(wsrep::transaction_id(1));
145     BOOST_REQUIRE(tc.active());
146     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
147     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
148 
149     wsrep_test::bf_abort_unordered(cc);
150 
151     // Run before commit
152     BOOST_REQUIRE(cc.before_commit());
153     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
154     BOOST_REQUIRE(tc.certified() == false);
155     BOOST_REQUIRE(tc.ordered() == false);
156 
157     // Rollback sequence
158     BOOST_REQUIRE(cc.before_rollback() == 0);
159     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
160     BOOST_REQUIRE(cc.after_rollback() == 0);
161     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
162 
163     // Cleanup after statement
164     cc.after_statement();
165     BOOST_REQUIRE(tc.active() == false);
166     BOOST_REQUIRE(tc.ordered() == false);
167     BOOST_REQUIRE(tc.certified() == false);
168     BOOST_REQUIRE(cc.current_error());
169 }
170 
171 
172 
173 //
174 // Test a 1PC transaction which gets BF aborted during before_commit via
175 // provider before the write set was ordered and certified.
176 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_during_before_commit_uncertified,T,replicating_fixtures,T)177 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
178     transaction_1pc_bf_during_before_commit_uncertified, T,
179     replicating_fixtures, T)
180 {
181     wsrep::mock_server_state& sc(T::sc);
182     wsrep::mock_client& cc(T::cc);
183     const wsrep::transaction& tc(T::tc);
184 
185     // Start a new transaction with ID 1
186     cc.start_transaction(wsrep::transaction_id(1));
187     BOOST_REQUIRE(tc.active());
188     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
189     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
190 
191     wsrep_test::bf_abort_provider(sc, tc, wsrep::seqno::undefined());
192 
193     // Run before commit
194     BOOST_REQUIRE(cc.before_commit());
195     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_cert_failed);
196     BOOST_REQUIRE(tc.certified() == false);
197     BOOST_REQUIRE(tc.ordered() == false);
198 
199     // Rollback sequence
200     BOOST_REQUIRE(cc.before_rollback() == 0);
201     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
202     BOOST_REQUIRE(cc.after_rollback() == 0);
203     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
204 
205     // Cleanup after statement
206     cc.after_statement();
207     BOOST_REQUIRE(tc.active() == false);
208     BOOST_REQUIRE(tc.ordered() == false);
209     BOOST_REQUIRE(tc.certified() == false);
210     BOOST_REQUIRE(cc.current_error());
211 }
212 
213 //
214 // Test a 1PC transaction which gets BF aborted during before_commit
215 // when waiting for replayers
216 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_during_commit_wait_for_replayers,T,replicating_fixtures,T)217 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
218     transaction_1pc_bf_during_commit_wait_for_replayers, T,
219     replicating_fixtures, T)
220 {
221     wsrep::mock_client& cc(T::cc);
222     const wsrep::transaction& tc(T::tc);
223 
224     // Start a new transaction with ID 1
225     cc.start_transaction(wsrep::transaction_id(1));
226     BOOST_REQUIRE(tc.active());
227     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
228     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
229 
230     cc.bf_abort_during_wait_ = true;
231 
232     // Run before commit
233     BOOST_REQUIRE(cc.before_commit());
234     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
235     BOOST_REQUIRE(tc.certified() == false);
236     BOOST_REQUIRE(tc.ordered() == false);
237 
238     // Rollback sequence
239     BOOST_REQUIRE(cc.before_rollback() == 0);
240     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
241     BOOST_REQUIRE(cc.after_rollback() == 0);
242     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
243 
244     // Cleanup after statement
245     cc.after_statement();
246     BOOST_REQUIRE(tc.active() == false);
247     BOOST_REQUIRE(tc.ordered() == false);
248     BOOST_REQUIRE(tc.certified() == false);
249     BOOST_REQUIRE(cc.current_error());
250 }
251 
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_during_commit_order_enter,T,replicating_fixtures,T)252 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
253     transaction_1pc_bf_during_commit_order_enter, T,
254     replicating_fixtures, T)
255 {
256     wsrep::mock_client& cc(T::cc);
257     const wsrep::transaction& tc(T::tc);
258     auto& sc(T::sc);
259 
260     // Start a new transaction with ID 1
261     cc.start_transaction(wsrep::transaction_id(1));
262     BOOST_REQUIRE(tc.active());
263     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
264     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
265 
266     sc.provider().commit_order_enter_result_ = wsrep::provider::error_bf_abort;
267 
268     // Run before commit
269     BOOST_REQUIRE(cc.before_commit());
270     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
271     BOOST_REQUIRE(cc.will_replay_called() == true);
272     BOOST_REQUIRE(tc.certified() == true);
273     BOOST_REQUIRE(tc.ordered() == true);
274 
275     sc.provider().commit_order_enter_result_ = wsrep::provider::success;
276 
277     // Rollback sequence
278     BOOST_REQUIRE(cc.before_rollback() == 0);
279     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
280     BOOST_REQUIRE(cc.after_rollback() == 0);
281     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
282 
283     // Replay from after_statement()
284     cc.after_statement();
285     BOOST_REQUIRE(cc.replays() > 0);
286     BOOST_REQUIRE(tc.active() == false);
287     BOOST_REQUIRE(tc.ordered() == false);
288     BOOST_REQUIRE(tc.certified() == false);
289     BOOST_REQUIRE(not cc.current_error());
290 }
291 
292 //
293 // Test a 1PC transaction for which prepare data fails
294 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_error_during_prepare_data,T,replicating_fixtures,T)295 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
296     transaction_1pc_error_during_prepare_data, T,
297     replicating_fixtures, T)
298 {
299     wsrep::mock_client& cc(T::cc);
300     const wsrep::transaction& tc(T::tc);
301 
302     // Start a new transaction with ID 1
303     cc.start_transaction(wsrep::transaction_id(1));
304     BOOST_REQUIRE(tc.active());
305     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
306     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
307 
308     cc.error_during_prepare_data_ = true;
309 
310     // Run before commit
311     BOOST_REQUIRE(cc.before_commit());
312     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
313     BOOST_REQUIRE(cc.current_error() == wsrep::e_size_exceeded_error);
314     BOOST_REQUIRE(tc.certified() == false);
315     BOOST_REQUIRE(tc.ordered() == false);
316 
317     // Rollback sequence
318     BOOST_REQUIRE(cc.before_rollback() == 0);
319     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
320     BOOST_REQUIRE(cc.after_rollback() == 0);
321     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
322 
323     // Cleanup after statement
324     cc.after_statement();
325     BOOST_REQUIRE(tc.active() == false);
326     BOOST_REQUIRE(tc.ordered() == false);
327     BOOST_REQUIRE(tc.certified() == false);
328     BOOST_REQUIRE(cc.current_error());
329 }
330 
331 //
332 // Test a 1PC transaction which gets killed by DBMS before certification
333 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_killed_before_certify,T,replicating_fixtures,T)334 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
335     transaction_1pc_killed_before_certify, T,
336     replicating_fixtures, T)
337 {
338     wsrep::mock_client& cc(T::cc);
339     const wsrep::transaction& tc(T::tc);
340 
341     // Start a new transaction with ID 1
342     cc.start_transaction(wsrep::transaction_id(1));
343     BOOST_REQUIRE(tc.active());
344     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
345     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
346 
347     cc.killed_before_certify_ = true;
348 
349     // Run before commit
350     BOOST_REQUIRE(cc.before_commit());
351     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
352     BOOST_REQUIRE(cc.current_error() == wsrep::e_interrupted_error);
353     BOOST_REQUIRE(tc.certified() == false);
354     BOOST_REQUIRE(tc.ordered() == false);
355 
356     // Rollback sequence
357     BOOST_REQUIRE(cc.before_rollback() == 0);
358     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
359     BOOST_REQUIRE(cc.after_rollback() == 0);
360     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
361 
362     // Cleanup after statement
363     cc.after_statement();
364     BOOST_REQUIRE(tc.active() == false);
365     BOOST_REQUIRE(tc.ordered() == false);
366     BOOST_REQUIRE(tc.certified() == false);
367     BOOST_REQUIRE(cc.current_error());
368 }
369 
370 //
371 // Test a transaction which gets BF aborted inside provider before
372 // certification result is known. Replaying will be successful
373 //
BOOST_FIXTURE_TEST_CASE(transaction_bf_before_cert_result_replay_success,replicating_client_fixture_sync_rm)374 BOOST_FIXTURE_TEST_CASE(
375     transaction_bf_before_cert_result_replay_success,
376     replicating_client_fixture_sync_rm)
377 {
378     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
379     sc.provider().certify_result_ = wsrep::provider::error_bf_abort;
380     sc.provider().replay_result_ = wsrep::provider::success;
381 
382     BOOST_REQUIRE(cc.before_commit());
383     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
384     BOOST_REQUIRE(cc.will_replay_called() == true);
385     BOOST_REQUIRE(cc.after_statement() == 0);
386     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
387     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
388 }
389 
390 //
391 // Test a transaction which gets BF aborted inside provider before
392 // certification result is known. Replaying will fail because of
393 // certification failure.
394 //
BOOST_FIXTURE_TEST_CASE(transaction_bf_before_cert_result_replay_cert_fail,replicating_client_fixture_sync_rm)395 BOOST_FIXTURE_TEST_CASE(
396     transaction_bf_before_cert_result_replay_cert_fail,
397     replicating_client_fixture_sync_rm)
398 {
399     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
400     sc.provider().certify_result_ = wsrep::provider::error_bf_abort;
401     sc.provider().replay_result_ = wsrep::provider::error_certification_failed;
402 
403     BOOST_REQUIRE(cc.before_commit());
404     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
405     BOOST_REQUIRE(cc.will_replay_called() == true);
406     BOOST_REQUIRE(cc.after_statement() );
407     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
408     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
409     BOOST_REQUIRE(tc.active() == false);
410 }
411 
412 //
413 // Test a 1PC transaction which gets BF aborted during before_commit via
414 // provider after the write set was ordered and certified. This must
415 // result replaying of transaction.
416 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_during_before_commit_certified,T,replicating_fixtures,T)417 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
418     transaction_1pc_bf_during_before_commit_certified, T,
419     replicating_fixtures, T)
420 {
421     wsrep::mock_server_state& sc(T::sc);
422     wsrep::mock_client& cc(T::cc);
423     const wsrep::transaction& tc(T::tc);
424 
425     // Start a new transaction with ID 1
426     cc.start_transaction(wsrep::transaction_id(1));
427     BOOST_REQUIRE(tc.active());
428     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
429     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
430 
431     wsrep_test::bf_abort_provider(sc, tc, wsrep::seqno(1));
432 
433     // Run before commit
434     BOOST_REQUIRE(cc.before_commit());
435     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
436     BOOST_REQUIRE(cc.will_replay_called() == true);
437     BOOST_REQUIRE(tc.certified() == false);
438     BOOST_REQUIRE(tc.ordered() == true);
439 
440     // Rollback sequence
441     BOOST_REQUIRE(cc.before_rollback() == 0);
442     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
443     BOOST_REQUIRE(cc.after_rollback() == 0);
444     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
445 
446     // Cleanup after statement
447     cc.after_statement();
448     BOOST_REQUIRE(tc.active() == false);
449     BOOST_REQUIRE(tc.ordered() == false);
450     BOOST_REQUIRE(tc.certified() == false);
451     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
452     BOOST_REQUIRE(cc.replays() == 1);
453 }
454 
455 //
456 // Test a 1PC transaction which gets BF aborted simultaneously with
457 // certification failure. BF abort should not succeed as the
458 // transaction is going to roll back anyway. Certification failure
459 // should not generate seqno for write set meta.
460 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_before_unordered_cert_failure,T,replicating_fixtures,T)461 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
462     transaction_1pc_bf_before_unordered_cert_failure, T,
463     replicating_fixtures, T)
464 {
465     wsrep::mock_server_state& sc(T::sc);
466     wsrep::mock_client& cc(T::cc);
467     const wsrep::transaction& tc(T::tc);
468 
469     cc.start_transaction(wsrep::transaction_id(1));
470     BOOST_REQUIRE(tc.active());
471     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
472     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
473     cc.sync_point_enabled_ = "wsrep_before_certification";
474     cc.sync_point_action_ = wsrep::mock_client_service::spa_bf_abort_unordered;
475     sc.provider().certify_result_ = wsrep::provider::error_certification_failed;
476     BOOST_REQUIRE(cc.before_commit());
477     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_cert_failed);
478     BOOST_REQUIRE(tc.certified() == false);
479     BOOST_REQUIRE(tc.ordered() == false);
480     BOOST_REQUIRE(cc.before_rollback() == 0);
481     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
482     BOOST_REQUIRE(cc.after_rollback() == 0);
483     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
484     BOOST_REQUIRE(cc.after_statement() );
485     BOOST_REQUIRE(tc.active() == false);
486     BOOST_REQUIRE(tc.ordered() == false);
487     BOOST_REQUIRE(tc.certified() == false);
488     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
489 }
490 
491 //
492 // Test a 1PC transaction which gets "warning error" from certify call
493 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_warning_error_from_certify,T,replicating_fixtures,T)494 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
495     transaction_1pc_warning_error_from_certify, T,
496     replicating_fixtures, T)
497 {
498     wsrep::mock_server_state& sc(T::sc);
499     wsrep::mock_client& cc(T::cc);
500     const wsrep::transaction& tc(T::tc);
501 
502     // Start a new transaction with ID 1
503     cc.start_transaction(wsrep::transaction_id(1));
504     BOOST_REQUIRE(tc.active());
505     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
506     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
507 
508     sc.provider().certify_result_ = wsrep::provider::error_warning;
509 
510     // Run before commit
511     BOOST_REQUIRE(cc.before_commit());
512     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
513     BOOST_REQUIRE(tc.certified() == false);
514     BOOST_REQUIRE(tc.ordered() == false);
515 
516     sc.provider().certify_result_ = wsrep::provider::success;
517 
518     // Rollback sequence
519     BOOST_REQUIRE(cc.before_rollback() == 0);
520     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
521     BOOST_REQUIRE(cc.after_rollback() == 0);
522     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
523 
524     // Cleanup after statement
525     cc.after_statement();
526     BOOST_REQUIRE(tc.active() == false);
527     BOOST_REQUIRE(tc.ordered() == false);
528     BOOST_REQUIRE(tc.certified() == false);
529     BOOST_REQUIRE(cc.current_error() == wsrep::e_error_during_commit);
530 }
531 
532 //
533 // Test a 1PC transaction which gets transaction missing from certify call
534 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_transaction_missing_from_certify,T,replicating_fixtures,T)535 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
536     transaction_1pc_transaction_missing_from_certify, T,
537     replicating_fixtures, T)
538 {
539     wsrep::mock_server_state& sc(T::sc);
540     wsrep::mock_client& cc(T::cc);
541     const wsrep::transaction& tc(T::tc);
542 
543     // Start a new transaction with ID 1
544     cc.start_transaction(wsrep::transaction_id(1));
545     BOOST_REQUIRE(tc.active());
546     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
547     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
548 
549     sc.provider().certify_result_ = wsrep::provider::error_transaction_missing;
550 
551     // Run before commit
552     BOOST_REQUIRE(cc.before_commit());
553     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
554     BOOST_REQUIRE(tc.certified() == false);
555     BOOST_REQUIRE(tc.ordered() == false);
556 
557     sc.provider().certify_result_ = wsrep::provider::success;
558 
559     // Rollback sequence
560     BOOST_REQUIRE(cc.before_rollback() == 0);
561     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
562     BOOST_REQUIRE(cc.after_rollback() == 0);
563     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
564 
565     // Cleanup after statement
566     cc.after_statement();
567     BOOST_REQUIRE(tc.active() == false);
568     BOOST_REQUIRE(tc.ordered() == false);
569     BOOST_REQUIRE(tc.certified() == false);
570     BOOST_REQUIRE(cc.current_error() == wsrep::e_error_during_commit);
571 }
572 
573 //
574 // Test a 1PC transaction which gets size exceeded error from certify call
575 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_size_exceeded_from_certify,T,replicating_fixtures,T)576 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
577     transaction_1pc_size_exceeded_from_certify, T,
578     replicating_fixtures, T)
579 {
580     wsrep::mock_server_state& sc(T::sc);
581     wsrep::mock_client& cc(T::cc);
582     const wsrep::transaction& tc(T::tc);
583 
584     // Start a new transaction with ID 1
585     cc.start_transaction(wsrep::transaction_id(1));
586     BOOST_REQUIRE(tc.active());
587     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
588     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
589 
590     sc.provider().certify_result_ = wsrep::provider::error_size_exceeded;
591 
592     // Run before commit
593     BOOST_REQUIRE(cc.before_commit());
594     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
595     BOOST_REQUIRE(tc.certified() == false);
596     BOOST_REQUIRE(tc.ordered() == false);
597 
598     sc.provider().certify_result_ = wsrep::provider::success;
599 
600     // Rollback sequence
601     BOOST_REQUIRE(cc.before_rollback() == 0);
602     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
603     BOOST_REQUIRE(cc.after_rollback() == 0);
604     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
605 
606     // Cleanup after statement
607     cc.after_statement();
608     BOOST_REQUIRE(tc.active() == false);
609     BOOST_REQUIRE(tc.ordered() == false);
610     BOOST_REQUIRE(tc.certified() == false);
611     BOOST_REQUIRE(cc.current_error() == wsrep::e_error_during_commit);
612 }
613 
614 //
615 // Test a 1PC transaction which gets connection failed error from certify call
616 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_connection_failed_from_certify,T,replicating_fixtures,T)617 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
618     transaction_1pc_connection_failed_from_certify, T,
619     replicating_fixtures, T)
620 {
621     wsrep::mock_server_state& sc(T::sc);
622     wsrep::mock_client& cc(T::cc);
623     const wsrep::transaction& tc(T::tc);
624 
625     // Start a new transaction with ID 1
626     cc.start_transaction(wsrep::transaction_id(1));
627     BOOST_REQUIRE(tc.active());
628     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
629     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
630 
631     sc.provider().certify_result_ = wsrep::provider::error_connection_failed;
632 
633     // Run before commit
634     BOOST_REQUIRE(cc.before_commit());
635     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
636     BOOST_REQUIRE(tc.certified() == false);
637     BOOST_REQUIRE(tc.ordered() == false);
638 
639     sc.provider().certify_result_ = wsrep::provider::success;
640 
641     // Rollback sequence
642     BOOST_REQUIRE(cc.before_rollback() == 0);
643     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
644     BOOST_REQUIRE(cc.after_rollback() == 0);
645     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
646 
647     // Cleanup after statement
648     cc.after_statement();
649     BOOST_REQUIRE(tc.active() == false);
650     BOOST_REQUIRE(tc.ordered() == false);
651     BOOST_REQUIRE(tc.certified() == false);
652     BOOST_REQUIRE(cc.current_error() == wsrep::e_error_during_commit);
653 }
654 
655 //
656 // Test a 1PC transaction which gets not allowed error from certify call
657 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_no_allowed_from_certify,T,replicating_fixtures,T)658 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
659     transaction_1pc_no_allowed_from_certify, T,
660     replicating_fixtures, T)
661 {
662     wsrep::mock_server_state& sc(T::sc);
663     wsrep::mock_client& cc(T::cc);
664     const wsrep::transaction& tc(T::tc);
665 
666     // Start a new transaction with ID 1
667     cc.start_transaction(wsrep::transaction_id(1));
668     BOOST_REQUIRE(tc.active());
669     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
670     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
671 
672     sc.provider().certify_result_ = wsrep::provider::error_not_allowed;
673 
674     // Run before commit
675     BOOST_REQUIRE(cc.before_commit());
676     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
677     BOOST_REQUIRE(tc.certified() == false);
678     BOOST_REQUIRE(tc.ordered() == false);
679 
680     sc.provider().certify_result_ = wsrep::provider::success;
681 
682     // Rollback sequence
683     BOOST_REQUIRE(cc.before_rollback() == 0);
684     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
685     BOOST_REQUIRE(cc.after_rollback() == 0);
686     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
687 
688     // Cleanup after statement
689     cc.after_statement();
690     BOOST_REQUIRE(tc.active() == false);
691     BOOST_REQUIRE(tc.ordered() == false);
692     BOOST_REQUIRE(tc.certified() == false);
693     BOOST_REQUIRE(cc.current_error() == wsrep::e_error_during_commit);
694 }
695 
696 //
697 // Test a 1PC transaction which gets fatal error from certify call
698 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_fatal_from_certify,T,replicating_fixtures,T)699 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
700     transaction_1pc_fatal_from_certify, T,
701     replicating_fixtures, T)
702 {
703     wsrep::mock_server_state& sc(T::sc);
704     wsrep::mock_client& cc(T::cc);
705     const wsrep::transaction& tc(T::tc);
706 
707     // Start a new transaction with ID 1
708     cc.start_transaction(wsrep::transaction_id(1));
709     BOOST_REQUIRE(tc.active());
710     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
711     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
712 
713     sc.provider().certify_result_ = wsrep::provider::error_fatal;
714 
715     // Run before commit
716     BOOST_REQUIRE(cc.before_commit());
717     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
718     BOOST_REQUIRE(tc.certified() == false);
719     BOOST_REQUIRE(tc.ordered() == false);
720 
721     sc.provider().certify_result_ = wsrep::provider::success;
722 
723     // Rollback sequence
724     BOOST_REQUIRE(cc.before_rollback() == 0);
725     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
726     BOOST_REQUIRE(cc.after_rollback() == 0);
727     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
728 
729     // Cleanup after statement
730     cc.after_statement();
731     BOOST_REQUIRE(tc.active() == false);
732     BOOST_REQUIRE(tc.ordered() == false);
733     BOOST_REQUIRE(tc.certified() == false);
734     BOOST_REQUIRE(cc.current_error() == wsrep::e_error_during_commit);
735     BOOST_REQUIRE(cc.aborts() == 1);
736 }
737 
738 //
739 // Test a 1PC transaction which gets unknown from certify call
740 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_unknown_from_certify,T,replicating_fixtures,T)741 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
742     transaction_1pc_unknown_from_certify, T,
743     replicating_fixtures, T)
744 {
745     wsrep::mock_server_state& sc(T::sc);
746     wsrep::mock_client& cc(T::cc);
747     const wsrep::transaction& tc(T::tc);
748 
749     // Start a new transaction with ID 1
750     cc.start_transaction(wsrep::transaction_id(1));
751     BOOST_REQUIRE(tc.active());
752     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
753     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
754 
755     sc.provider().certify_result_ = wsrep::provider::error_unknown;
756 
757     // Run before commit
758     BOOST_REQUIRE(cc.before_commit());
759     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
760     BOOST_REQUIRE(tc.certified() == false);
761     BOOST_REQUIRE(tc.ordered() == false);
762 
763     sc.provider().certify_result_ = wsrep::provider::success;
764 
765     // Rollback sequence
766     BOOST_REQUIRE(cc.before_rollback() == 0);
767     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
768     BOOST_REQUIRE(cc.after_rollback() == 0);
769     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
770 
771     // Cleanup after statement
772     cc.after_statement();
773     BOOST_REQUIRE(tc.active() == false);
774     BOOST_REQUIRE(tc.ordered() == false);
775     BOOST_REQUIRE(tc.certified() == false);
776     BOOST_REQUIRE(cc.current_error() == wsrep::e_error_during_commit);
777 }
778 
779 //
780 // Test a 1PC transaction which gets BF aborted before grabbing lock
781 // after certify call
782 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_abort_before_certify_regain_lock,T,replicating_fixtures,T)783 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
784     transaction_1pc_bf_abort_before_certify_regain_lock, T,
785     replicating_fixtures, T)
786 {
787     wsrep::mock_client& cc(T::cc);
788     const wsrep::transaction& tc(T::tc);
789 
790     // Start a new transaction with ID 1
791     cc.start_transaction(wsrep::transaction_id(1));
792     BOOST_REQUIRE(tc.active());
793     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
794     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
795 
796     cc.sync_point_enabled_ = "wsrep_after_certification";
797     cc.sync_point_action_ = wsrep::mock_client_service::spa_bf_abort_ordered;
798     // Run before commit
799     BOOST_REQUIRE(cc.before_commit());
800     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
801     BOOST_REQUIRE(cc.will_replay_called() == true);
802     BOOST_REQUIRE(tc.certified() == true);
803     BOOST_REQUIRE(tc.ordered() == true);
804 
805     // Rollback sequence
806     BOOST_REQUIRE(cc.before_rollback() == 0);
807     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
808     BOOST_REQUIRE(cc.after_rollback() == 0);
809     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
810 
811     // Cleanup after statement
812     cc.after_statement();
813     BOOST_REQUIRE(cc.replays() == 1);
814     BOOST_REQUIRE(tc.active() == false);
815     BOOST_REQUIRE(tc.ordered() == false);
816     BOOST_REQUIRE(tc.certified() == false);
817     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
818 }
819 
820 //
821 // Test a transaction which gets BF aborted before before_statement.
822 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_before_before_statement,T,replicating_fixtures,T)823 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
824     transaction_1pc_bf_before_before_statement, T,
825     replicating_fixtures, T)
826 {
827     wsrep::client_state& cc(T::cc);
828     const wsrep::transaction& tc(T::tc);
829 
830     // Start a new transaction with ID 1
831     cc.start_transaction(wsrep::transaction_id(1));
832     BOOST_REQUIRE(tc.active());
833     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
834     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
835     cc.after_statement();
836     cc.after_command_before_result();
837     cc.after_command_after_result();
838     BOOST_REQUIRE(cc.before_command() == 0);
839     BOOST_REQUIRE(tc.active());
840     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
841     wsrep_test::bf_abort_unordered(cc);
842     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
843     BOOST_REQUIRE(cc.before_statement() == 1);
844     BOOST_REQUIRE(tc.active());
845     cc.after_command_before_result();
846     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
847     cc.after_command_after_result();
848     BOOST_REQUIRE(tc.active() == false);
849     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
850 }
851 
852 //
853 // Test a transaction which gets BF aborted before after_statement.
854 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_before_after_statement,T,replicating_fixtures,T)855 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
856     transaction_1pc_bf_before_after_statement, T,
857     replicating_fixtures, T)
858 {
859     wsrep::client_state& cc(T::cc);
860     const wsrep::transaction& tc(T::tc);
861 
862     // Start a new transaction with ID 1
863     cc.start_transaction(wsrep::transaction_id(1));
864     BOOST_REQUIRE(tc.active());
865     BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
866     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
867 
868     wsrep_test::bf_abort_unordered(cc);
869 
870     cc.after_statement();
871     BOOST_REQUIRE(tc.active() == false);
872     BOOST_REQUIRE(tc.ordered() == false);
873     BOOST_REQUIRE(tc.certified() == false);
874     BOOST_REQUIRE(cc.current_error());
875 }
876 
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_abort_after_after_statement,T,replicating_fixtures,T)877 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
878     transaction_1pc_bf_abort_after_after_statement, T,
879     replicating_fixtures, T)
880 {
881     wsrep::client_state& cc(T::cc);
882     const wsrep::transaction& tc(T::tc);
883 
884     cc.start_transaction(wsrep::transaction_id(1));
885     BOOST_REQUIRE(tc.active());
886     cc.after_statement();
887     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
888     wsrep_test::bf_abort_unordered(cc);
889     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
890     BOOST_REQUIRE(tc.active());
891     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
892     cc.after_command_before_result();
893     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
894     BOOST_REQUIRE(tc.active() == false);
895     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
896     cc.after_command_after_result();
897     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
898     BOOST_REQUIRE(tc.active() == false);
899     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
900 }
901 
BOOST_FIXTURE_TEST_CASE(transaction_1pc_autocommit_retry_bf_aborted,replicating_client_fixture_autocommit)902 BOOST_FIXTURE_TEST_CASE(
903     transaction_1pc_autocommit_retry_bf_aborted,
904     replicating_client_fixture_autocommit)
905 {
906 
907     cc.start_transaction(wsrep::transaction_id(1));
908     BOOST_REQUIRE(tc.active());
909     wsrep_test::bf_abort_unordered(cc);
910     BOOST_REQUIRE(cc.before_commit());
911     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
912     BOOST_REQUIRE(cc.before_rollback() == 0);
913     BOOST_REQUIRE(cc.after_rollback() == 0);
914     BOOST_REQUIRE(cc.after_statement());
915     BOOST_REQUIRE(tc.active() == false);
916     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
917     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
918 }
919 
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_1pc_bf_abort_after_after_command_before_result,T,replicating_fixtures,T)920 BOOST_FIXTURE_TEST_CASE_TEMPLATE(
921     transaction_1pc_bf_abort_after_after_command_before_result, T,
922     replicating_fixtures, T)
923 {
924     wsrep::client_state& cc(T::cc);
925     const wsrep::transaction& tc(T::tc);
926 
927     cc.start_transaction(wsrep::transaction_id(1));
928     BOOST_REQUIRE(tc.active());
929     cc.after_statement();
930     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
931     cc.after_command_before_result();
932     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_result);
933     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
934     wsrep_test::bf_abort_unordered(cc);
935     // The result is being sent to client. We need to mark transaction
936     // as must_abort but not override error yet as this might cause
937     // a race condition resulting incorrect result returned to the DBMS client.
938     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
939     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
940     // After the result has been sent to the DBMS client, the after result
941     // processing should roll back the transaction and set the error.
942     cc.after_command_after_result();
943     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_idle);
944     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
945     BOOST_REQUIRE(tc.active() == true);
946     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
947     cc.sync_rollback_complete();
948     BOOST_REQUIRE(cc.before_command() == 1);
949     BOOST_REQUIRE(tc.active() == false);
950     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
951     cc.after_command_before_result();
952     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
953     cc.after_command_after_result();
954     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
955 }
956 
BOOST_FIXTURE_TEST_CASE(transaction_1pc_bf_abort_after_after_command_after_result_sync_rm,replicating_client_fixture_sync_rm)957 BOOST_FIXTURE_TEST_CASE(
958     transaction_1pc_bf_abort_after_after_command_after_result_sync_rm,
959     replicating_client_fixture_sync_rm)
960 {
961     cc.start_transaction(wsrep::transaction_id(1));
962     BOOST_REQUIRE(tc.active());
963     cc.after_statement();
964     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
965     cc.after_command_before_result();
966     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_result);
967     cc.after_command_after_result();
968     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_idle);
969     wsrep_test::bf_abort_unordered(cc);
970     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
971     BOOST_REQUIRE(tc.active());
972     cc.sync_rollback_complete();
973     BOOST_REQUIRE(cc.before_command() == 1);
974     BOOST_REQUIRE(tc.active() == false);
975     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
976     cc.after_command_before_result();
977     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
978     cc.after_command_after_result();
979     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
980     BOOST_REQUIRE(tc.active() == false);
981 }
982 
983 // Check the case where client program calls wait_rollback_complete() to
984 // gain control before before_command().
BOOST_FIXTURE_TEST_CASE(transaction_1pc_bf_abort_after_after_command_after_result_sync_rm_wait_rollback,replicating_client_fixture_sync_rm)985 BOOST_FIXTURE_TEST_CASE(
986     transaction_1pc_bf_abort_after_after_command_after_result_sync_rm_wait_rollback,
987     replicating_client_fixture_sync_rm)
988 {
989     cc.start_transaction(wsrep::transaction_id(1));
990     BOOST_REQUIRE(tc.active());
991     cc.after_statement();
992     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
993     cc.after_command_before_result();
994     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_result);
995     cc.after_command_after_result();
996     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_idle);
997     wsrep_test::bf_abort_unordered(cc);
998     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
999     BOOST_REQUIRE(tc.active());
1000     cc.sync_rollback_complete();
1001     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_idle);
1002     cc.wait_rollback_complete_and_acquire_ownership();
1003     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
1004     // Idempotent
1005     cc.wait_rollback_complete_and_acquire_ownership();
1006     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
1007     BOOST_REQUIRE(cc.before_command() == 1);
1008     BOOST_REQUIRE(tc.active() == false);
1009     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1010     cc.after_command_before_result();
1011     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1012     cc.after_command_after_result();
1013     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1014     BOOST_REQUIRE(tc.active() == false);
1015 }
1016 
1017 // Check the case where BF abort happens between client calls to
1018 // wait_rollback_complete_and_acquire_ownership()
1019 // and before before_command().
BOOST_FIXTURE_TEST_CASE(transaction_1pc_bf_abort_after_acquire_before_before_command_sync_rm,replicating_client_fixture_sync_rm)1020 BOOST_FIXTURE_TEST_CASE(
1021     transaction_1pc_bf_abort_after_acquire_before_before_command_sync_rm,
1022     replicating_client_fixture_sync_rm)
1023 {
1024     cc.start_transaction(wsrep::transaction_id(1));
1025     BOOST_REQUIRE(tc.active());
1026     cc.after_statement();
1027     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
1028     cc.after_command_before_result();
1029     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_result);
1030     cc.after_command_after_result();
1031     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_idle);
1032     cc.wait_rollback_complete_and_acquire_ownership();
1033     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
1034     // As the control is now on client, the BF abort must just change
1035     // the state to s_must_abort.
1036     wsrep_test::bf_abort_unordered(cc);
1037     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
1038     BOOST_REQUIRE(tc.active());
1039     BOOST_REQUIRE(cc.before_command() == 1);
1040     BOOST_REQUIRE(tc.active() == false);
1041     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1042     cc.after_command_before_result();
1043     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1044     cc.after_command_after_result();
1045     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1046     BOOST_REQUIRE(tc.active() == false);
1047 }
1048 
BOOST_FIXTURE_TEST_CASE(transaction_1pc_bf_abort_after_after_command_after_result_async_rm,replicating_client_fixture_async_rm)1049 BOOST_FIXTURE_TEST_CASE(
1050     transaction_1pc_bf_abort_after_after_command_after_result_async_rm,
1051     replicating_client_fixture_async_rm)
1052 {
1053     cc.start_transaction(wsrep::transaction_id(1));
1054     BOOST_REQUIRE(tc.active());
1055     cc.after_statement();
1056     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_exec);
1057     cc.after_command_before_result();
1058     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_result);
1059     cc.after_command_after_result();
1060     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_idle);
1061     wsrep_test::bf_abort_unordered(cc);
1062     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
1063     BOOST_REQUIRE(tc.active());
1064     BOOST_REQUIRE(cc.before_command() == 1);
1065     BOOST_REQUIRE(tc.active() == false);
1066     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1067     cc.after_command_before_result();
1068     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1069     cc.after_command_after_result();
1070     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1071     BOOST_REQUIRE(tc.active() == false);
1072 }
1073 
1074 //
1075 // Test before_command() with keep_command_error param
1076 // Failure free case is not affected by keep_command_error
1077 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_keep_error,T,replicating_fixtures,T)1078 BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_keep_error, T,
1079                                  replicating_fixtures, T)
1080 {
1081     wsrep::mock_client& cc(T::cc);
1082     const wsrep::transaction& tc(T::tc);
1083 
1084     cc.start_transaction(wsrep::transaction_id(1));
1085     BOOST_REQUIRE(tc.active());
1086     cc.after_statement();
1087     cc.after_command_before_result();
1088     cc.after_command_after_result();
1089 
1090     bool keep_command_error(true);
1091     BOOST_REQUIRE(cc.before_command(keep_command_error) == 0);
1092     BOOST_REQUIRE(tc.active());
1093     cc.after_command_before_result();
1094     cc.after_command_after_result();
1095 
1096     keep_command_error = false;
1097     BOOST_REQUIRE(cc.before_command(keep_command_error) == 0);
1098     BOOST_REQUIRE(cc.before_statement() == 0);
1099     BOOST_REQUIRE(cc.before_commit() == 0);
1100     BOOST_REQUIRE(cc.ordered_commit() == 0);
1101     BOOST_REQUIRE(cc.after_commit() == 0);
1102     cc.after_statement();
1103     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1104 }
1105 
1106 //
1107 // Test before_command() with keep_command_error param
1108 // BF abort while idle
1109 //
BOOST_FIXTURE_TEST_CASE(transaction_keep_error_bf_idle_sync_rm,replicating_client_fixture_sync_rm)1110 BOOST_FIXTURE_TEST_CASE(transaction_keep_error_bf_idle_sync_rm,
1111                         replicating_client_fixture_sync_rm)
1112 {
1113     cc.start_transaction(wsrep::transaction_id(1));
1114     cc.after_statement();
1115     cc.after_command_before_result();
1116     cc.after_command_after_result();
1117 
1118     BOOST_REQUIRE(cc.state() == wsrep::client_state::s_idle);
1119     wsrep_test::bf_abort_unordered(cc);
1120     cc.sync_rollback_complete();
1121     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
1122 
1123     bool keep_command_error(true);
1124     BOOST_REQUIRE(cc.before_command(keep_command_error) == 0);
1125     BOOST_REQUIRE(tc.active());
1126     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1127     cc.after_command_before_result();
1128     cc.after_command_after_result();
1129     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1130 
1131     keep_command_error = false;
1132     BOOST_REQUIRE(cc.before_command(keep_command_error) == 1);
1133     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1134     cc.after_command_before_result();
1135     cc.after_command_after_result();
1136     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1137 }
1138 
1139 //
1140 // Test before_command() with keep_command_error param
1141 // BF abort after ownership is acquired and before before_command()
1142 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_keep_error_bf_after_ownership,T,replicating_fixtures,T)1143 BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_keep_error_bf_after_ownership, T,
1144                                  replicating_fixtures, T)
1145 {
1146     wsrep::mock_client& cc(T::cc);
1147     const wsrep::transaction& tc(T::tc);
1148 
1149     cc.start_transaction(wsrep::transaction_id(1));
1150     cc.after_statement();
1151     cc.after_command_before_result();
1152     cc.after_command_after_result();
1153 
1154     cc.wait_rollback_complete_and_acquire_ownership();
1155     wsrep_test::bf_abort_unordered(cc);
1156     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
1157 
1158     bool keep_command_error(true);
1159     BOOST_REQUIRE(cc.before_command(keep_command_error) == 0);
1160     BOOST_REQUIRE(tc.active());
1161     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1162     cc.after_command_before_result();
1163     cc.after_command_after_result();
1164     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1165 
1166     keep_command_error = false;
1167     BOOST_REQUIRE(cc.before_command(keep_command_error) == 1);
1168     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1169     cc.after_command_before_result();
1170     cc.after_command_after_result();
1171     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1172 }
1173 
1174 //
1175 // Test before_command() with keep_command_error param
1176 // BF abort right after before_command()
1177 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_keep_error_bf_after_before_command,T,replicating_fixtures,T)1178 BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_keep_error_bf_after_before_command, T,
1179                                  replicating_fixtures, T)
1180 {
1181     wsrep::mock_client& cc(T::cc);
1182     const wsrep::transaction& tc(T::tc);
1183 
1184     cc.start_transaction(wsrep::transaction_id(1));
1185     cc.after_statement();
1186     cc.after_command_before_result();
1187     cc.after_command_after_result();
1188 
1189     bool keep_command_error(true);
1190     BOOST_REQUIRE(cc.before_command(keep_command_error) == 0);
1191     BOOST_REQUIRE(tc.active());
1192 
1193     wsrep_test::bf_abort_unordered(cc);
1194     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
1195     cc.after_command_before_result();
1196     cc.after_command_after_result();
1197     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
1198     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1199 
1200     keep_command_error = false;
1201     BOOST_REQUIRE(cc.before_command(keep_command_error) == 1);
1202     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1203     cc.after_command_before_result();
1204     cc.after_command_after_result();
1205     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1206 }
1207 
1208 //
1209 // Test before_command() with keep_command_error param
1210 // BF abort right after after_command_before_result()
1211 //
BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_keep_error_bf_after_after_command_before_result,T,replicating_fixtures,T)1212 BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_keep_error_bf_after_after_command_before_result, T,
1213                                  replicating_fixtures, T)
1214 {
1215     wsrep::mock_client& cc(T::cc);
1216     const wsrep::transaction& tc(T::tc);
1217 
1218     cc.start_transaction(wsrep::transaction_id(1));
1219     cc.after_statement();
1220     cc.after_command_before_result();
1221     cc.after_command_after_result();
1222 
1223     bool keep_command_error(true);
1224     BOOST_REQUIRE(cc.before_command(keep_command_error) == 0);
1225     BOOST_REQUIRE(tc.active());
1226 
1227     cc.after_command_before_result();
1228 
1229     wsrep_test::bf_abort_unordered(cc);
1230     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
1231 
1232     cc.after_command_after_result();
1233     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
1234     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1235 
1236     keep_command_error = false;
1237     BOOST_REQUIRE(cc.before_command(keep_command_error) == 1);
1238     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1239     cc.after_command_before_result();
1240     cc.after_command_after_result();
1241     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1242 }
1243 
BOOST_FIXTURE_TEST_CASE(transaction_1pc_applying,applying_client_fixture)1244 BOOST_FIXTURE_TEST_CASE(transaction_1pc_applying,
1245                         applying_client_fixture)
1246 {
1247     start_transaction(wsrep::transaction_id(1),
1248                       wsrep::seqno(1));
1249     BOOST_REQUIRE(cc.before_commit() == 0);
1250     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committing);
1251     BOOST_REQUIRE(cc.ordered_commit() == 0);
1252     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_ordered_commit);
1253     BOOST_REQUIRE(cc.after_commit() == 0);
1254     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
1255     cc.after_applying();
1256     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
1257     BOOST_REQUIRE(tc.active() == false);
1258     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1259 }
1260 
1261 
BOOST_FIXTURE_TEST_CASE(transaction_applying_rollback,applying_client_fixture)1262 BOOST_FIXTURE_TEST_CASE(transaction_applying_rollback,
1263                         applying_client_fixture)
1264 {
1265     BOOST_REQUIRE(cc.before_rollback() == 0);
1266     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting);
1267     BOOST_REQUIRE(cc.after_rollback() == 0);
1268     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
1269     cc.after_applying();
1270     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
1271     BOOST_REQUIRE(tc.active() == false);
1272     BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
1273 }
1274 
1275 ///////////////////////////////////////////////////////////////////////////////
1276 //                       STREAMING REPLICATION                               //
1277 ///////////////////////////////////////////////////////////////////////////////
1278 
1279 //
1280 // Test 1PC with row streaming with one row
1281 //
BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_1pc_commit,streaming_client_fixture_row)1282 BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_1pc_commit,
1283                         streaming_client_fixture_row)
1284 {
1285     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1286     BOOST_REQUIRE(cc.after_row() == 0);
1287     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1288     BOOST_REQUIRE(cc.before_commit() == 0);
1289     BOOST_REQUIRE(cc.ordered_commit() == 0);
1290     BOOST_REQUIRE(cc.after_commit() == 0);
1291     BOOST_REQUIRE(cc.after_statement() == 0);
1292     BOOST_REQUIRE(sc.provider().fragments() == 2);
1293     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1294     BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
1295 }
1296 
1297 //
1298 // Test 1PC with row streaming with one row
1299 //
BOOST_FIXTURE_TEST_CASE(transaction_row_batch_streaming_1pc_commit,streaming_client_fixture_row)1300 BOOST_FIXTURE_TEST_CASE(transaction_row_batch_streaming_1pc_commit,
1301                         streaming_client_fixture_row)
1302 {
1303     BOOST_REQUIRE(cc.enable_streaming(
1304                       wsrep::streaming_context::row, 2) == 0);
1305     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1306     BOOST_REQUIRE(cc.after_row() == 0);
1307     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 0);
1308     BOOST_REQUIRE(cc.after_row() == 0);
1309     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1310     BOOST_REQUIRE(cc.before_commit() == 0);
1311     BOOST_REQUIRE(cc.ordered_commit() == 0);
1312     BOOST_REQUIRE(cc.after_commit() == 0);
1313     BOOST_REQUIRE(cc.after_statement() == 0);
1314     BOOST_REQUIRE(sc.provider().fragments() == 2);
1315     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1316     BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
1317 }
1318 
1319 //
1320 // Test 1PC row streaming with two separate statements
1321 //
BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_1pc_commit_two_statements,streaming_client_fixture_row)1322 BOOST_FIXTURE_TEST_CASE(
1323     transaction_row_streaming_1pc_commit_two_statements,
1324     streaming_client_fixture_row)
1325 {
1326     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1327     BOOST_REQUIRE(cc.after_row() == 0);
1328     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1329     BOOST_REQUIRE(cc.after_statement() == 0);
1330     BOOST_REQUIRE(cc.before_statement() == 0);
1331     BOOST_REQUIRE(cc.after_row() == 0);
1332     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 2);
1333     BOOST_REQUIRE(cc.before_commit() == 0);
1334     BOOST_REQUIRE(cc.ordered_commit() == 0);
1335     BOOST_REQUIRE(cc.after_commit() == 0);
1336     BOOST_REQUIRE(cc.after_statement() == 0);
1337     BOOST_REQUIRE(sc.provider().fragments() == 3);
1338     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1339     BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
1340 }
1341 
1342 //
1343 // Fragments are removed in before_prepare in running transaction context.
1344 // In 1pc the before_prepare() is called from before_commit().
1345 // However, the BF abort may arrive during this removal and the
1346 // client_service::remove_fragments() may roll back the transaction
1347 // internally. This will cause the transaction to leave before_prepare()
1348 // in aborted state.
1349 //
BOOST_FIXTURE_TEST_CASE(transaction_streaming_1pc_bf_abort_during_fragment_removal,streaming_client_fixture_row)1350 BOOST_FIXTURE_TEST_CASE(transaction_streaming_1pc_bf_abort_during_fragment_removal,
1351                         streaming_client_fixture_row)
1352 {
1353     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1354     BOOST_REQUIRE(cc.after_row() == 0);
1355     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1356     cc.bf_abort_during_fragment_removal_ = true;
1357     BOOST_REQUIRE(cc.before_commit());
1358     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
1359     BOOST_REQUIRE(cc.after_statement());
1360     BOOST_REQUIRE(tc.active() == false);
1361     wsrep_test::terminate_streaming_applier(sc, sc.id(),
1362                                             wsrep::transaction_id(1));
1363 }
1364 
1365 //
1366 // Test streaming rollback
1367 //
BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_rollback,streaming_client_fixture_row)1368 BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_rollback,
1369                         streaming_client_fixture_row)
1370 {
1371     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1372     BOOST_REQUIRE(cc.after_row() == 0);
1373     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1374     BOOST_REQUIRE(cc.before_rollback() == 0);
1375     BOOST_REQUIRE(cc.after_rollback() == 0);
1376     BOOST_REQUIRE(cc.after_statement() == 0);
1377     BOOST_REQUIRE(sc.provider().fragments() == 2);
1378     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1379     BOOST_REQUIRE(sc.provider().rollback_fragments() == 1);
1380 
1381     wsrep::high_priority_service* hps(
1382         sc.find_streaming_applier(
1383             sc.id(), wsrep::transaction_id(1)));
1384     BOOST_REQUIRE(hps);
1385     hps->rollback(wsrep::ws_handle(), wsrep::ws_meta());
1386     hps->after_apply();
1387     sc.stop_streaming_applier(sc.id(), wsrep::transaction_id(1));
1388     server_service.release_high_priority_service(hps);
1389 }
1390 
1391 //
1392 // Test streaming BF abort in executing state.
1393 //
BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_bf_abort_executing,streaming_client_fixture_row)1394 BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_bf_abort_executing,
1395                         streaming_client_fixture_row)
1396 {
1397     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1398     BOOST_REQUIRE(cc.after_row() == 0);
1399     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1400     wsrep_test::bf_abort_unordered(cc);
1401     BOOST_REQUIRE(tc.streaming_context().rolled_back());
1402     BOOST_REQUIRE(cc.before_rollback() == 0);
1403     BOOST_REQUIRE(cc.after_rollback() == 0);
1404     BOOST_REQUIRE(cc.after_statement());
1405     wsrep_test::terminate_streaming_applier(sc, sc.id(),
1406                                             wsrep::transaction_id(1));
1407 
1408 }
1409 //
1410 // Test streaming certification failure during fragment replication
1411 //
BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_cert_fail_non_commit,streaming_client_fixture_row)1412 BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_cert_fail_non_commit,
1413                         streaming_client_fixture_row)
1414 {
1415     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1416     BOOST_REQUIRE(cc.after_row() == 0);
1417     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1418     sc.provider().certify_result_ = wsrep::provider::error_certification_failed;
1419     BOOST_REQUIRE(cc.after_row() == 1);
1420     sc.provider().certify_result_ = wsrep::provider::success;
1421     BOOST_REQUIRE(cc.before_rollback() == 0);
1422     BOOST_REQUIRE(cc.after_rollback() == 0);
1423     BOOST_REQUIRE(cc.after_statement() == 1);
1424     BOOST_REQUIRE(sc.provider().fragments() == 2);
1425     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1426     BOOST_REQUIRE(sc.provider().rollback_fragments() == 1);
1427 
1428     wsrep::high_priority_service* hps(
1429         sc.find_streaming_applier(
1430             sc.id(), wsrep::transaction_id(1)));
1431     BOOST_REQUIRE(hps);
1432     hps->rollback(wsrep::ws_handle(), wsrep::ws_meta());
1433     hps->after_apply();
1434     sc.stop_streaming_applier(sc.id(), wsrep::transaction_id(1));
1435     server_service.release_high_priority_service(hps);
1436 }
1437 
1438 //
1439 // Test streaming certification failure during commit
1440 //
BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_cert_fail_commit,streaming_client_fixture_row)1441 BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_cert_fail_commit,
1442                         streaming_client_fixture_row)
1443 {
1444     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1445     BOOST_REQUIRE(cc.after_row() == 0);
1446     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1447     sc.provider().certify_result_ = wsrep::provider::error_certification_failed;
1448     BOOST_REQUIRE(cc.before_commit() == 1);
1449     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_cert_failed);
1450     sc.provider().certify_result_ = wsrep::provider::success;
1451     BOOST_REQUIRE(cc.before_rollback() == 0);
1452     BOOST_REQUIRE(cc.after_rollback() == 0);
1453     BOOST_REQUIRE(cc.after_statement() );
1454     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
1455     BOOST_REQUIRE(sc.provider().fragments() == 2);
1456     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1457     BOOST_REQUIRE(sc.provider().rollback_fragments() == 1);
1458 
1459     wsrep::high_priority_service* hps(
1460         sc.find_streaming_applier(
1461             sc.id(), wsrep::transaction_id(1)));
1462     BOOST_REQUIRE(hps);
1463     hps->rollback(wsrep::ws_handle(), wsrep::ws_meta());
1464     hps->after_apply();
1465     sc.stop_streaming_applier(sc.id(), wsrep::transaction_id(1));
1466     server_service.release_high_priority_service(hps);
1467 }
1468 
1469 //
1470 // Test streaming BF abort after succesful certification
1471 //
BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_bf_abort_committing,streaming_client_fixture_row)1472 BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_bf_abort_committing,
1473                         streaming_client_fixture_row)
1474 {
1475     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1476     BOOST_REQUIRE(cc.after_row() == 0);
1477     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1478     BOOST_REQUIRE(cc.before_commit() == 0);
1479     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committing);
1480     wsrep_test::bf_abort_ordered(cc);
1481     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
1482     BOOST_REQUIRE(cc.before_rollback() == 0);
1483     BOOST_REQUIRE(cc.after_rollback() == 0);
1484     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
1485     BOOST_REQUIRE(cc.will_replay_called() == true);
1486     BOOST_REQUIRE(cc.after_statement() == 0);
1487     BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
1488     BOOST_REQUIRE(sc.provider().fragments() == 2);
1489     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1490     BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
1491 }
1492 
1493 
1494 
BOOST_FIXTURE_TEST_CASE(transaction_byte_streaming_1pc_commit,streaming_client_fixture_byte)1495 BOOST_FIXTURE_TEST_CASE(transaction_byte_streaming_1pc_commit,
1496                         streaming_client_fixture_byte)
1497 {
1498     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1499     cc.bytes_generated_ = 1;
1500     BOOST_REQUIRE(cc.after_row() == 0);
1501     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1502     BOOST_REQUIRE(cc.before_commit() == 0);
1503     BOOST_REQUIRE(cc.ordered_commit() == 0);
1504     BOOST_REQUIRE(cc.after_commit() == 0);
1505     BOOST_REQUIRE(cc.after_statement() == 0);
1506     BOOST_REQUIRE(sc.provider().fragments() == 2);
1507     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1508     BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
1509 }
1510 
BOOST_FIXTURE_TEST_CASE(transaction_byte_batch_streaming_1pc_commit,streaming_client_fixture_byte)1511 BOOST_FIXTURE_TEST_CASE(transaction_byte_batch_streaming_1pc_commit,
1512                         streaming_client_fixture_byte)
1513 {
1514     BOOST_REQUIRE(
1515         cc.enable_streaming(
1516             wsrep::streaming_context::bytes, 2) == 0);
1517     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1518     BOOST_REQUIRE(cc.after_row() == 0);
1519     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 0);
1520     BOOST_REQUIRE(cc.after_row() == 0);
1521     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1522     BOOST_REQUIRE(cc.before_commit() == 0);
1523     BOOST_REQUIRE(cc.ordered_commit() == 0);
1524     BOOST_REQUIRE(cc.after_commit() == 0);
1525     BOOST_REQUIRE(cc.after_statement() == 0);
1526     BOOST_REQUIRE(sc.provider().fragments() == 2);
1527     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1528     BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
1529 }
1530 
1531 
BOOST_FIXTURE_TEST_CASE(transaction_statement_streaming_statement_with_no_effect,streaming_client_fixture_statement)1532 BOOST_FIXTURE_TEST_CASE(transaction_statement_streaming_statement_with_no_effect,
1533                         streaming_client_fixture_statement)
1534 {
1535     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1536     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 0);
1537     BOOST_REQUIRE(cc.before_statement() == 0);
1538     BOOST_REQUIRE(cc.after_statement() == 0);
1539     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 0);
1540     BOOST_REQUIRE(cc.after_row() == 0);
1541     BOOST_REQUIRE(cc.before_statement() == 0);
1542     BOOST_REQUIRE(cc.after_statement() == 0);
1543     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1544     BOOST_REQUIRE(cc.before_statement() == 0);
1545     BOOST_REQUIRE(cc.before_commit() == 0);
1546     BOOST_REQUIRE(cc.ordered_commit() == 0);
1547     BOOST_REQUIRE(cc.after_commit() == 0);
1548     BOOST_REQUIRE(cc.after_statement() == 0);
1549     BOOST_REQUIRE(sc.provider().fragments() == 2);
1550     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1551     BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
1552 }
1553 
BOOST_FIXTURE_TEST_CASE(transaction_statement_streaming_1pc_commit,streaming_client_fixture_statement)1554 BOOST_FIXTURE_TEST_CASE(transaction_statement_streaming_1pc_commit,
1555                         streaming_client_fixture_statement)
1556 {
1557     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1558     BOOST_REQUIRE(cc.after_row() == 0);
1559     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 0);
1560     BOOST_REQUIRE(cc.after_statement() == 0);
1561     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1562     BOOST_REQUIRE(cc.before_statement() == 0);
1563     BOOST_REQUIRE(cc.before_commit() == 0);
1564     BOOST_REQUIRE(cc.ordered_commit() == 0);
1565     BOOST_REQUIRE(cc.after_commit() == 0);
1566     BOOST_REQUIRE(cc.after_statement() == 0);
1567     BOOST_REQUIRE(sc.provider().fragments() == 2);
1568     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1569     BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
1570 }
1571 
BOOST_FIXTURE_TEST_CASE(transaction_statement_batch_streaming_1pc_commit,streaming_client_fixture_statement)1572 BOOST_FIXTURE_TEST_CASE(transaction_statement_batch_streaming_1pc_commit,
1573                         streaming_client_fixture_statement)
1574 {
1575     BOOST_REQUIRE(
1576         cc.enable_streaming(
1577             wsrep::streaming_context::statement, 2) == 0);
1578     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1579     BOOST_REQUIRE(cc.after_row() == 0);
1580     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 0);
1581     BOOST_REQUIRE(cc.after_statement() == 0);
1582     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 0);
1583     BOOST_REQUIRE(cc.before_statement() == 0);
1584     BOOST_REQUIRE(cc.after_row() == 0);
1585     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 0);
1586     BOOST_REQUIRE(cc.after_statement() == 0);
1587     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 1);
1588     BOOST_REQUIRE(cc.before_statement() == 0);
1589     BOOST_REQUIRE(cc.before_commit() == 0);
1590     BOOST_REQUIRE(cc.ordered_commit() == 0);
1591     BOOST_REQUIRE(cc.after_commit() == 0);
1592     BOOST_REQUIRE(cc.after_statement() == 0);
1593     BOOST_REQUIRE(sc.provider().fragments() == 2);
1594     BOOST_REQUIRE(sc.provider().start_fragments() == 1);
1595     BOOST_REQUIRE(sc.provider().commit_fragments() == 1);
1596 }
1597 
BOOST_FIXTURE_TEST_CASE(transaction_statement_streaming_cert_fail,streaming_client_fixture_statement)1598 BOOST_FIXTURE_TEST_CASE(transaction_statement_streaming_cert_fail,
1599                         streaming_client_fixture_statement)
1600 {
1601     BOOST_REQUIRE(cc.start_transaction(wsrep::transaction_id(1)) == 0);
1602     BOOST_REQUIRE(cc.after_row() == 0);
1603     BOOST_REQUIRE(tc.streaming_context().fragments_certified() == 0);
1604     sc.provider().certify_result_ = wsrep::provider::error_certification_failed;
1605     BOOST_REQUIRE(cc.after_statement());
1606     BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
1607     // Note: Due to possible limitation in wsrep-API error codes
1608     // or a bug in current Galera provider, rollback fragment may be
1609     // replicated even in case of certification failure.
1610     // If the limitation is lifted later on or the provider is fixed,
1611     // the above check should be change for fragments == 0,
1612     // rollback_fragments == 0.
1613     BOOST_REQUIRE(sc.provider().fragments() == 1);
1614     BOOST_REQUIRE(sc.provider().start_fragments() == 0);
1615     BOOST_REQUIRE(sc.provider().rollback_fragments() == 1);
1616 
1617     wsrep::high_priority_service* hps(
1618         sc.find_streaming_applier(
1619             sc.id(), wsrep::transaction_id(1)));
1620     BOOST_REQUIRE(hps);
1621     hps->rollback(wsrep::ws_handle(), wsrep::ws_meta());
1622     hps->after_apply();
1623     sc.stop_streaming_applier(sc.id(), wsrep::transaction_id(1));
1624     server_service.release_high_priority_service(hps);
1625 }
1626 
1627 ///////////////////////////////////////////////////////////////////////////////
1628 //                             misc                                          //
1629 ///////////////////////////////////////////////////////////////////////////////
1630 
BOOST_AUTO_TEST_CASE(transaction_state_strings)1631 BOOST_AUTO_TEST_CASE(transaction_state_strings)
1632 {
1633     BOOST_REQUIRE(wsrep::to_string(
1634                       wsrep::transaction::s_executing) == "executing");
1635     BOOST_REQUIRE(wsrep::to_string(
1636                       wsrep::transaction::s_preparing) == "preparing");
1637     BOOST_REQUIRE(
1638         wsrep::to_string(
1639             wsrep::transaction::s_certifying) == "certifying");
1640     BOOST_REQUIRE(
1641         wsrep::to_string(
1642             wsrep::transaction::s_committing) == "committing");
1643     BOOST_REQUIRE(
1644         wsrep::to_string(
1645             wsrep::transaction::s_ordered_commit) == "ordered_commit");
1646     BOOST_REQUIRE(
1647         wsrep::to_string(
1648             wsrep::transaction::s_committed) == "committed");
1649     BOOST_REQUIRE(
1650         wsrep::to_string(
1651             wsrep::transaction::s_cert_failed) == "cert_failed");
1652     BOOST_REQUIRE(
1653         wsrep::to_string(
1654             wsrep::transaction::s_must_abort) == "must_abort");
1655     BOOST_REQUIRE(
1656         wsrep::to_string(
1657             wsrep::transaction::s_aborting) == "aborting");
1658     BOOST_REQUIRE(
1659         wsrep::to_string(
1660             wsrep::transaction::s_aborted) == "aborted");
1661     BOOST_REQUIRE(
1662         wsrep::to_string(
1663             wsrep::transaction::s_must_replay) == "must_replay");
1664     BOOST_REQUIRE(
1665         wsrep::to_string(
1666             wsrep::transaction::s_replaying) == "replaying");
1667 }
1668