################################################################################
# Validate group_replication_consistency= 'AFTER' behaviour against member leaves,
# when a member leaves before any member acknowledges the prepare.
#
# Test:
# 00. The test requires three servers: M1, M2 and M3.
# 01. Create a table on the group.
# 02. Make server2 block before send its prepare message. This
#     will allow us to deterministically remove server3 before
#     any member send its acknowledge.
# 03. Make server3 block before send its prepare message. This
#     will allow us to deterministically remove it from the
#     group while others are waiting for its acknowledge.
#     The not acknowledged transaction must rollback on server3.
# 04. Execute T1 on server1.
# 05. Wait until T1 is prepared on server2.
# 06. Wait until T1 is prepared on server3.
# 07. Make server3 do not send its prepare message and remove
#     it from the group.
# 08. Make server2 resume and send its prepare message.
# 09. Wait until server3 is removed from the group. T1 will
#     commit on server 1 and 2.
# 10. Clean up.
################################################################################
--source include/big_test.inc
--source include/have_debug_sync.inc
--source include/have_group_replication_plugin.inc
--let $rpl_server_count= 3
--source include/group_replication.inc

--echo
--echo ############################################################
--echo # 01. Create a table on the group.
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY);


--echo
--echo ############################################################
--echo # 02. Make server2 block before send its prepare message. This
--echo #     will allow us to deterministically remove server3 before
--echo #     any member send its acknowledge.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
SET @@GLOBAL.DEBUG= '+d,group_replication_wait_before_message_send_after_applier_prepare';


--echo
--echo ############################################################
--echo # 03. Make server3 block before send its prepare message. This
--echo #     will allow us to deterministically remove it from the
--echo #     group while others are waiting for its acknowledge.
--echo #     The not acknowledged transaction must rollback on server3.
--let $rpl_connection_name= server3
--source include/rpl_connection.inc
SET @@GLOBAL.DEBUG= '+d,group_replication_wait_on_supress_message_send_after_applier_prepare';

SET SESSION sql_log_bin= 0;
call mtr.add_suppression("Due to a plugin error, some transactions were unable to be certified and will now rollback.");
call mtr.add_suppression("Plugin group_replication reported: 'Error on transaction '.*:5' from session '.*' while waiting for being prepared on all group members.");
call mtr.add_suppression("Run function 'before_commit' in plugin 'group_replication' failed");
call mtr.add_suppression("Slave: Error on observer while running replication hook 'before_commit'. Error_code: MY-003100");
call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Error in Xid_log_event: Commit could not be completed, 'Error on observer while running replication hook 'before_commit'.', Error_code: MY-003100");
call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': Worker 1 failed executing transaction '.*:5'; Error on observer while running replication hook 'before_commit'. Error_code: MY-003100");
call mtr.add_suppression("Slave SQL for channel 'group_replication_applier': ... The slave coordinator and worker threads are stopped.*");
call mtr.add_suppression("The applier thread execution was aborted. Unable to process more transactions, this member will now leave the group.");
call mtr.add_suppression("Fatal error during execution on the Applier process of Group Replication. The server will now leave the group.");
call mtr.add_suppression("Plugin group_replication reported: 'Skipping leave operation: concurrent attempt to leave the group is on-going.");
call mtr.add_suppression("The server was automatically set into read only mode after an error was detected.");
SET SESSION sql_log_bin= 1;


--echo
--echo ############################################################
--echo # 04. Execute T1 on server1.
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
--send INSERT INTO t1 VALUES (1)


--echo
--echo ############################################################
--echo # 05. Wait until T1 is prepared on server2.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
# Wait for the debug sync to be reached.
SET DEBUG_SYNC= "now WAIT_FOR signal.after_before_message_send_after_applier_prepare_waiting";


--echo
--echo ############################################################
--echo # 06. Wait until T1 is prepared on server3.
--let $rpl_connection_name= server3
--source include/rpl_connection.inc
# Wait for the debug sync to be reached.
SET DEBUG_SYNC= "now WAIT_FOR signal.after_supress_message_send_after_applier_prepare_waiting";


--echo
--echo ############################################################
--echo # 07. Make server3 do not send its prepare message and remove
--echo #     it from the group.
--let $rpl_connection_name= server3
--source include/rpl_connection.inc
# Signal debug sync to continue.
SET DEBUG_SYNC= 'now SIGNAL signal.after_supress_message_send_after_applier_prepare_continue';
SET @@GLOBAL.DEBUG= '-d,group_replication_wait_on_supress_message_send_after_applier_prepare';

--source include/stop_group_replication.inc

--let $assert_text= 'There are no values in table t1'
--let $assert_cond= [SELECT COUNT(*) AS count FROM t1, count, 1] = 0
--source include/assert.inc


--echo
--echo ############################################################
--echo # 08. Make server2 resume and send its prepare message.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
# Signal debug sync to continue.
SET DEBUG_SYNC= 'now SIGNAL signal.after_before_message_send_after_applier_prepare_continue';
SET @@GLOBAL.DEBUG= '-d,group_replication_wait_before_message_send_after_applier_prepare';


--echo
--echo ############################################################
--echo # 09. Wait until server3 is removed from the group. T1 will
--echo #     commit on server 1 and 2.
--let $rpl_connection_name= server_1
--source include/rpl_connection.inc
--let $group_replication_number_of_members= 2
--source include/gr_wait_for_number_of_members.inc

--let $rpl_connection_name= server1
--source include/rpl_connection.inc
--reap

--let $assert_text= 'There is 1 value in table t1'
--let $assert_cond= [SELECT COUNT(*) AS count FROM t1 WHERE c1=1, count, 1] = 1
--source include/assert.inc

--let $rpl_connection_name= server2
--source include/rpl_connection.inc
--let $assert_text= 'There is 1 value in table t1'
--let $assert_cond= [SELECT COUNT(*) AS count FROM t1 WHERE c1=1, count, 1] = 1
--source include/assert.inc

--let $diff_tables=server1:t1, server2:t1
--source include/diff_tables.inc


--echo
--echo ############################################################
--echo # 10. Clean up.
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
DROP TABLE t1;

--let $rpl_connection_name= server3
--source include/rpl_connection.inc
DROP TABLE t1;

--source include/group_replication_end.inc
