|
| 1 | +local yaml = require('yaml') |
| 2 | +local t = require('luatest') |
| 3 | +local cbuilder = require('luatest.cbuilder') |
| 4 | +local treegen = require('luatest.treegen') |
| 5 | +local justrun = require('luatest.justrun') |
| 6 | +local cluster = require('test.config-luatest.cluster') |
| 7 | +local it = require('test.interactive_tarantool') |
| 8 | + |
| 9 | +local g = t.group() |
| 10 | + |
| 11 | +g.before_all(cluster.init) |
| 12 | +g.after_each(cluster.drop) |
| 13 | +g.after_all(cluster.clean) |
| 14 | + |
| 15 | +g.after_each(function(g) |
| 16 | + if g.it ~= nil then |
| 17 | + g.it:close() |
| 18 | + end |
| 19 | +end) |
| 20 | + |
| 21 | +-- Verify that an instance can't start in the isolated mode if |
| 22 | +-- there is no local snapshot. |
| 23 | +g.test_startup_no_snap = function() |
| 24 | + local config = cbuilder:new() |
| 25 | + :set_replicaset_option('replication.failover', 'manual') |
| 26 | + :set_replicaset_option('leader', 'i-001') |
| 27 | + :add_instance('i-001', {}) |
| 28 | + :add_instance('i-002', {}) |
| 29 | + :add_instance('i-003', {isolated = true}) |
| 30 | + :config() |
| 31 | + |
| 32 | + -- Write config to a temporary directory. |
| 33 | + local dir = treegen.prepare_directory({}, {}) |
| 34 | + local config_file = treegen.write_file(dir, 'config.yaml', |
| 35 | + yaml.encode(config)) |
| 36 | + |
| 37 | + -- Run tarantool instance that is expected to exit |
| 38 | + -- immediately. |
| 39 | + local env = {} |
| 40 | + local args = {'--name', 'i-003', '--config', config_file} |
| 41 | + local opts = {nojson = true, stderr = true} |
| 42 | + local res = justrun.tarantool(dir, env, args, opts) |
| 43 | + |
| 44 | + -- Verify the exit code and the error reported to stderr. |
| 45 | + local exp_err = 'Startup failure.\n' .. |
| 46 | + 'The isolated mode is enabled and the instance "i-003" has no local ' .. |
| 47 | + 'snapshot. An attempt to bootstrap the instance would lead to the ' .. |
| 48 | + 'split-brain situation.' |
| 49 | + t.assert_covers(res, { |
| 50 | + exit_code = 1, |
| 51 | + stderr = ('LuajitError: %s\nfatal error, exiting the event loop') |
| 52 | + :format(exp_err), |
| 53 | + }) |
| 54 | +end |
| 55 | + |
| 56 | +-- The opposite to the previous test case: verify that an instance |
| 57 | +-- can start in the isolated mode if there is a local snapshot. |
| 58 | +g.test_startup_with_snap = function(g) |
| 59 | + local config = cbuilder:new() |
| 60 | + :set_replicaset_option('replication.failover', 'manual') |
| 61 | + :set_replicaset_option('leader', 'i-001') |
| 62 | + :add_instance('i-001', {}) |
| 63 | + :add_instance('i-002', {}) |
| 64 | + :add_instance('i-003', {}) |
| 65 | + :config() |
| 66 | + |
| 67 | + local cluster = cluster.new(g, config) |
| 68 | + cluster:start() |
| 69 | + |
| 70 | + -- Stop i-003. It leaves a local snapshot. |
| 71 | + cluster['i-003']:stop() |
| 72 | + |
| 73 | + -- Mark i-003 as isolated in the configuration, write it to |
| 74 | + -- the file. |
| 75 | + local config_2 = cbuilder:new(config) |
| 76 | + :set_instance_option('i-003', 'isolated', true) |
| 77 | + :config() |
| 78 | + cluster:sync(config_2) |
| 79 | + |
| 80 | + -- Start the instance again from the local snapshot in the |
| 81 | + -- isolated mode. |
| 82 | + cluster['i-003']:start() |
| 83 | + |
| 84 | + -- Use the console connection, because an instance in the |
| 85 | + -- isolated mode doesn't accept iproto requests. |
| 86 | + g.it = it.connect(cluster['i-003']) |
| 87 | + |
| 88 | + -- Verify that the instance is started in the isolated mode. |
| 89 | + g.it:roundtrip("require('config'):get('isolated')", true) |
| 90 | + |
| 91 | + -- Verify that the instance loaded the database. |
| 92 | + g.it:roundtrip("box.space._schema:get({'replicaset_name'})[2]", |
| 93 | + 'replicaset-001') |
| 94 | +end |
0 commit comments