[Tarantool-patches] [PATCH v4 13/16] box: allow calling promote on a candidate
Serge Petrenko
sergepetrenko at tarantool.org
Wed Jul 14 21:25:41 MSK 2021
Part of #6034
---
src/box/box.cc | 15 +---
.../gh-6034-election-candidate-promote.result | 84 +++++++++++++++++++
...h-6034-election-candidate-promote.test.lua | 42 ++++++++++
test/replication/suite.cfg | 1 +
4 files changed, 128 insertions(+), 14 deletions(-)
create mode 100644 test/replication/gh-6034-election-candidate-promote.result
create mode 100644 test/replication/gh-6034-election-candidate-promote.test.lua
diff --git a/src/box/box.cc b/src/box/box.cc
index 6a534952f..9130fc322 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -1717,21 +1717,8 @@ box_promote(void)
"manual elections");
return -1;
case ELECTION_MODE_MANUAL:
- if (box_raft()->state == RAFT_STATE_LEADER)
- return 0;
- run_elections = true;
- break;
case ELECTION_MODE_CANDIDATE:
- /*
- * Leader elections are enabled, and this instance is allowed to
- * promote only if it's already an elected leader. No manual
- * elections.
- */
- if (box_raft()->state != RAFT_STATE_LEADER) {
- diag_set(ClientError, ER_UNSUPPORTED, "election_mode="
- "'candidate'", "manual elections");
- return -1;
- }
+ run_elections = box_raft()->state != RAFT_STATE_LEADER;
break;
default:
unreachable();
diff --git a/test/replication/gh-6034-election-candidate-promote.result b/test/replication/gh-6034-election-candidate-promote.result
new file mode 100644
index 000000000..76a54d5a6
--- /dev/null
+++ b/test/replication/gh-6034-election-candidate-promote.result
@@ -0,0 +1,84 @@
+-- test-run result file version 2
+test_run = require('test_run').new()
+ | ---
+ | ...
+
+SERVERS = {'election_replica1', 'election_replica2', 'election_replica3'}
+ | ---
+ | ...
+test_run:create_cluster(SERVERS, 'replication')
+ | ---
+ | ...
+test_run:wait_fullmesh(SERVERS)
+ | ---
+ | ...
+is_leader_cmd = 'return box.info.election.state == \'leader\''
+ | ---
+ | ...
+
+test_run:cmd("setopt delimiter ';'")
+ | ---
+ | - true
+ | ...
+function get_leader_nr()
+ local leader_nr = 0
+ test_run:wait_cond(function()
+ for nr = 1,3 do
+ local is_leader = test_run:eval('election_replica'..nr, is_leader_cmd)[1]
+ if is_leader then
+ leader_nr = nr
+ return true
+ end
+ end
+ return false
+ end)
+ return leader_nr
+end;
+ | ---
+ | ...
+test_run:cmd("setopt delimiter ''");
+ | ---
+ | - true
+ | ...
+
+leader_nr = get_leader_nr()
+ | ---
+ | ...
+
+assert(leader_nr ~= 0)
+ | ---
+ | - true
+ | ...
+
+term = test_run:eval('election_replica'..leader_nr,\
+ 'return box.info.election.term')[1]
+ | ---
+ | ...
+
+next_nr = leader_nr % 3 + 1
+ | ---
+ | ...
+-- Someone else may become a leader, thus promote may fail. But we're testing
+-- that it takes effect at all, so that's fine.
+_ = pcall(test_run:eval('election_replica'..next_nr, 'box.ctl.promote()'))
+ | ---
+ | ...
+new_term = test_run:eval('election_replica'..next_nr,\
+ 'return box.info.election.term')[1]
+ | ---
+ | ...
+assert(new_term > term)
+ | ---
+ | - true
+ | ...
+leader_nr = get_leader_nr()
+ | ---
+ | ...
+assert(leader_nr ~= 0)
+ | ---
+ | - true
+ | ...
+
+test_run:drop_cluster(SERVERS)
+ | ---
+ | ...
diff --git a/test/replication/gh-6034-election-candidate-promote.test.lua b/test/replication/gh-6034-election-candidate-promote.test.lua
new file mode 100644
index 000000000..24c57f4cb
--- /dev/null
+++ b/test/replication/gh-6034-election-candidate-promote.test.lua
@@ -0,0 +1,42 @@
+test_run = require('test_run').new()
+
+SERVERS = {'election_replica1', 'election_replica2', 'election_replica3'}
+test_run:create_cluster(SERVERS, 'replication')
+test_run:wait_fullmesh(SERVERS)
+is_leader_cmd = 'return box.info.election.state == \'leader\''
+
+test_run:cmd("setopt delimiter ';'")
+function get_leader_nr()
+ local leader_nr = 0
+ test_run:wait_cond(function()
+ for nr = 1,3 do
+ local is_leader = test_run:eval('election_replica'..nr, is_leader_cmd)[1]
+ if is_leader then
+ leader_nr = nr
+ return true
+ end
+ end
+ return false
+ end)
+ return leader_nr
+end;
+test_run:cmd("setopt delimiter ''");
+
+leader_nr = get_leader_nr()
+
+assert(leader_nr ~= 0)
+
+term = test_run:eval('election_replica'..leader_nr,\
+ 'return box.info.election.term')[1]
+
+next_nr = leader_nr % 3 + 1
+-- Someone else may become a leader, thus promote may fail. But we're testing
+-- that it takes effect at all, so that's fine.
+_ = pcall(test_run:eval('election_replica'..next_nr, 'box.ctl.promote()'))
+new_term = test_run:eval('election_replica'..next_nr,\
+ 'return box.info.election.term')[1]
+assert(new_term > term)
+leader_nr = get_leader_nr()
+assert(leader_nr ~= 0)
+
+test_run:drop_cluster(SERVERS)
diff --git a/test/replication/suite.cfg b/test/replication/suite.cfg
index 8b2204e2a..6f42db081 100644
--- a/test/replication/suite.cfg
+++ b/test/replication/suite.cfg
@@ -53,6 +53,7 @@
"gh-6057-qsync-confirm-async-no-wal.test.lua": {},
"gh-6094-rs-uuid-mismatch.test.lua": {},
"gh-6127-election-join-new.test.lua": {},
+ "gh-6034-election-candidate-promote.test.lua": {},
"gh-6035-applier-filter.test.lua": {},
"*": {
"memtx": {"engine": "memtx"},
--
2.30.1 (Apple Git-130)
More information about the Tarantool-patches
mailing list