Skip to content

Commit 06ca83c

Browse files
committed
test/config: add several application script tests
The declarative config has the `app` section with following three parameters: * `app.file` -- the path to the script file * `app.module` -- the same, but the script is searched using the Lua search paths (and loaded using `require`) * `app.cfg` -- a user provided configuration (arbitrary map) This commit adds a few success/failure cases. The goal is to have simple test examples to add more ones easier in a future. Implemented several test helpers for typical scenarios that can be used outside of the application script test. Part of tarantool#8862 NO_DOC=testing improvements NO_CHANGELOG=see NO_DOC
1 parent a6054f0 commit 06ca83c

File tree

3 files changed

+346
-17
lines changed

3 files changed

+346
-17
lines changed

test/config-luatest/app_test.lua

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
local t = require('luatest')
2+
local helpers = require('test.config-luatest.helpers')
3+
4+
local g = helpers.group()
5+
6+
-- Start a script that is pointed by app.file or app.module.
7+
--
8+
-- TODO: Verify that the script has access to config:get() values.
9+
g.test_startup_success = function(g)
10+
local script = [[
11+
-- TODO: Verify that the script has access to config:get()
12+
-- values.
13+
-- local config = require('config')
14+
-- assert(config:get('app.cfg.foo') == 42)
15+
16+
_G.foo = 42
17+
]]
18+
local verify = function()
19+
local config = require('config')
20+
t.assert_equals(_G.foo, 42)
21+
t.assert_equals(config:get('app.cfg.foo'), 42)
22+
end
23+
24+
helpers.success_case(g, {
25+
script = script,
26+
options = {
27+
['app.file'] = 'main.lua',
28+
['app.cfg'] = {foo = 42},
29+
},
30+
verify = verify,
31+
})
32+
33+
helpers.success_case(g, {
34+
script = script,
35+
options = {
36+
['app.module'] = 'main',
37+
['app.cfg'] = {foo = 42},
38+
},
39+
verify = verify,
40+
})
41+
end
42+
43+
-- Start a script that is pointed by app.file or app.module.
44+
--
45+
-- Verify that an error in the script leads to a startup failure.
46+
g.test_startup_error = function(g)
47+
local err_msg = 'Application is unable to start'
48+
local script = ([[
49+
error('%s', 0)
50+
]]):format(err_msg)
51+
52+
helpers.failure_case(g, {
53+
script = script,
54+
options = {['app.file'] = 'main.lua'},
55+
exp_err = err_msg,
56+
})
57+
58+
helpers.failure_case(g, {
59+
script = script,
60+
options = {['app.module'] = 'main'},
61+
exp_err = err_msg,
62+
})
63+
end
64+
65+
-- Start a server, write a script that raises an error, reload.
66+
--
67+
-- Verify that the error is raised by config:reload() and the same
68+
-- error appears in the alerts.
69+
--
70+
-- The test case uses only app.file deliberately: if the
71+
-- application script is set as app.module, it is not re-executed
72+
-- on config:reload() due to caching in package.loaded.
73+
g.test_reload_failure = function(g)
74+
local err_msg = 'Application is unable to start'
75+
76+
helpers.reload_failure_case(g, {
77+
script = '',
78+
options = {['app.file'] = 'main.lua'},
79+
verify = function() end,
80+
script_2 = ([[
81+
error('%s', 0)
82+
]]):format(err_msg),
83+
exp_err = err_msg,
84+
})
85+
end
86+
87+
-- Start a server, write a script that raises an error, reload.
88+
--
89+
-- Verify that the error is NOT raised when the application script
90+
-- is set using app.module (due to caching in package.loaded).
91+
--
92+
-- This behavior may be changed in a future.
93+
g.test_reload_success = function(g)
94+
local err_msg = 'Application is unable to start'
95+
96+
helpers.reload_success_case(g, {
97+
script = '',
98+
options = {['app.module'] = 'main'},
99+
verify = function() end,
100+
script_2 = ([[
101+
error('%s', 0)
102+
]]):format(err_msg),
103+
verify_2 = function()
104+
local config = require('config')
105+
local info = config:info()
106+
t.assert_equals(info.status, 'ready')
107+
t.assert_equals(#info.alerts, 0)
108+
end,
109+
})
110+
end

test/config-luatest/basic_test.lua

+1-17
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,7 @@ local justrun = require('test.justrun')
77
local server = require('test.luatest_helpers.server')
88
local helpers = require('test.config-luatest.helpers')
99

10-
local g = t.group()
11-
12-
g.before_all(function(g)
13-
treegen.init(g)
14-
end)
15-
16-
g.after_all(function(g)
17-
treegen.clean(g)
18-
end)
19-
20-
g.after_each(function(g)
21-
for k, v in pairs(g) do
22-
if k == 'server' or k:match('^server_%d+$') then
23-
v:stop()
24-
end
25-
end
26-
end)
10+
local g = helpers.group()
2711

2812
local function count_lines(s)
2913
return #s:split('\n')

test/config-luatest/helpers.lua

+235
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,31 @@
11
local fun = require('fun')
2+
local yaml = require('yaml')
3+
local fio = require('fio')
4+
local cluster_config = require('internal.config.cluster_config')
25
local t = require('luatest')
6+
local treegen = require('test.treegen')
7+
local justrun = require('test.justrun')
38
local server = require('test.luatest_helpers.server')
49

10+
local function group(name, params)
11+
local g = t.group(name, params)
12+
13+
g.before_all(treegen.init)
14+
15+
g.after_each(function(g)
16+
for k, v in pairs(table.copy(g)) do
17+
if k == 'server' or k:match('^server_%d+$') then
18+
v:stop()
19+
g[k] = nil
20+
end
21+
end
22+
end)
23+
24+
g.after_all(treegen.clean)
25+
26+
return g
27+
end
28+
529
local function start_example_replicaset(g, dir, config_file, opts)
630
local credentials = {
731
user = 'client',
@@ -40,6 +64,217 @@ local function start_example_replicaset(g, dir, config_file, opts)
4064
t.assert_equals(info.cluster.name, 'group-001')
4165
end
4266

67+
-- A simple single instance configuration.
68+
local simple_config = {
69+
credentials = {
70+
users = {
71+
guest = {
72+
roles = {'super'},
73+
},
74+
},
75+
},
76+
iproto = {
77+
listen = 'unix/:./{{ instance_name }}.iproto',
78+
},
79+
groups = {
80+
['group-001'] = {
81+
replicasets = {
82+
['replicaset-001'] = {
83+
instances = {
84+
['instance-001'] = {},
85+
},
86+
},
87+
},
88+
},
89+
},
90+
}
91+
92+
local function prepare_case(g, opts)
93+
local dir = opts.dir
94+
local script = opts.script
95+
local options = opts.options
96+
97+
if dir == nil then
98+
dir = treegen.prepare_directory(g, {}, {})
99+
end
100+
101+
if script ~= nil then
102+
treegen.write_script(dir, 'main.lua', script)
103+
end
104+
105+
if options ~= nil then
106+
local config = table.deepcopy(simple_config)
107+
for path, value in pairs(options) do
108+
cluster_config:set(config, path, value)
109+
end
110+
treegen.write_script(dir, 'config.yaml', yaml.encode(config))
111+
end
112+
113+
local config_file = fio.pathjoin(dir, 'config.yaml')
114+
local server = {
115+
config_file = config_file,
116+
chdir = dir,
117+
alias = 'instance-001',
118+
}
119+
local justrun = {
120+
-- dir
121+
dir,
122+
-- env
123+
{},
124+
-- args
125+
{'--name', 'instance-001', '--config', config_file},
126+
-- opts
127+
{nojson = true, stderr = true},
128+
}
129+
return {
130+
dir = dir,
131+
server = server,
132+
justrun = justrun,
133+
}
134+
end
135+
136+
-- Start a server with the given script and the given
137+
-- configuration, run a verification function on it.
138+
--
139+
-- * opts.script
140+
--
141+
-- Code write into the main.lua file.
142+
--
143+
-- * opts.options
144+
--
145+
-- The configuration is expressed as a set of path:value pairs.
146+
-- It is merged into the simple config above.
147+
--
148+
-- * opts.verify
149+
--
150+
-- Function to run on the started server to verify some
151+
-- invariants.
152+
local function success_case(g, opts)
153+
local verify = assert(opts.verify)
154+
local prepared = prepare_case(g, opts)
155+
g.server = server:new(prepared.server)
156+
g.server:start()
157+
g.server:exec(verify)
158+
return prepared
159+
end
160+
161+
-- Start tarantool process with the given script/config and check
162+
-- the error.
163+
--
164+
-- * opts.script
165+
-- * opts.options
166+
--
167+
-- Same as in success_case().
168+
--
169+
-- * opts.exp_err
170+
--
171+
-- An error that must be written into stderr by tarantool
172+
-- process.
173+
local function failure_case(g, opts)
174+
local exp_err = assert(opts.exp_err)
175+
176+
local prepared = prepare_case(g, opts)
177+
local res = justrun.tarantool(unpack(prepared.justrun))
178+
t.assert_equals(res.exit_code, 1)
179+
t.assert_str_contains(res.stderr, exp_err)
180+
end
181+
182+
-- Start a server, write a new script/config, reload, run a
183+
-- verification function.
184+
--
185+
-- * opts.script
186+
-- * opts.options
187+
-- * opts.verify
188+
--
189+
-- Same as in success_case().
190+
--
191+
-- * opts.script_2
192+
--
193+
-- A new script to write into the main.lua file before
194+
-- config:reload().
195+
--
196+
-- * opts.verify_2
197+
--
198+
-- Verify test invariants after config:reload().
199+
local function reload_success_case(g, opts)
200+
local script_2 = assert(opts.script_2)
201+
local verify_2 = assert(opts.verify_2)
202+
203+
local prepared = success_case(g, opts)
204+
205+
prepare_case(g, {
206+
dir = prepared.dir,
207+
script = script_2,
208+
})
209+
g.server:exec(function()
210+
local config = require('config')
211+
config:reload()
212+
end)
213+
g.server:exec(verify_2)
214+
end
215+
216+
-- Start a server, write a new script/config, reload, run a
217+
-- verification function.
218+
--
219+
-- * opts.script
220+
-- * opts.options
221+
-- * opts.verify
222+
--
223+
-- Same as in success_case().
224+
--
225+
-- * opts.script_2
226+
--
227+
-- A new script to write into the main.lua file before
228+
-- config:reload().
229+
--
230+
-- * opts.exp_err
231+
--
232+
-- An error that config:reload() must raise.
233+
local function reload_failure_case(g, opts)
234+
local script_2 = assert(opts.script_2)
235+
local exp_err = assert(opts.exp_err)
236+
237+
local prepared = success_case(g, opts)
238+
239+
prepare_case(g, {
240+
dir = prepared.dir,
241+
script = script_2,
242+
})
243+
t.assert_error_msg_equals(exp_err, g.server.exec, g.server, function()
244+
local config = require('config')
245+
config:reload()
246+
end)
247+
g.server:exec(function(exp_err)
248+
local config = require('config')
249+
local info = config:info()
250+
t.assert_equals(info.status, 'check_errors')
251+
t.assert_equals(#info.alerts, 1)
252+
t.assert_equals(info.alerts[1].type, 'error')
253+
t.assert(info.alerts[1].timestamp ~= nil)
254+
t.assert_equals(info.alerts[1].message, exp_err)
255+
end, {exp_err})
256+
end
257+
43258
return {
259+
-- Setup a group of tests that are prepended/postpones with
260+
-- hooks to stop servers between tests and to remove temporary
261+
-- files after the testing.
262+
group = group,
263+
264+
-- Start a three instance replicaset with the given config
265+
-- file.
266+
--
267+
-- It assumes specific instance/replicaset/group names and
268+
-- net.box credentials.
44269
start_example_replicaset = start_example_replicaset,
270+
271+
-- Run a single instance and verify some invariants.
272+
--
273+
-- All the runs are based on the given simple config,
274+
-- but the options can be adjusted.
275+
simple_config = simple_config,
276+
success_case = success_case,
277+
failure_case = failure_case,
278+
reload_success_case = reload_success_case,
279+
reload_failure_case = reload_failure_case,
45280
}

0 commit comments

Comments
 (0)