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