Skip to content

Commit 87c6df0

Browse files
Oleg Chaplashkinylobankov
Oleg Chaplashkin
authored andcommitted
Migrate cbuilder module and adapt it
The original `cbuilder` module (tarantool/test/config-luatest/cbuilder.lua) has been moved to the current project with minor changes and will be available as follows: local t = require('luatest') t.cbuilder:new(...) The helper requires Tarantool 3.0.0 and newer. Otherwise `Builder:new()` will cause an error. Closes #366
1 parent ae8e3d2 commit 87c6df0

File tree

5 files changed

+495
-0
lines changed

5 files changed

+495
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Add more logs (gh-326).
1010
- Add `justrun` helper as a tarantool runner and output catcher (gh-365).
1111
- Changed error message for too long Unix domain socket paths (gh-341).
12+
- Add `cbuilder` helper as a declarative configuration builder (gh-366).
1213

1314
## 1.0.1
1415

config.ld

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ file = {
88
'luatest/server.lua',
99
'luatest/replica_set.lua',
1010
'luatest/justrun.lua',
11+
'luatest/cbuilder.lua'
1112
}
1213
topics = {
1314
'CHANGELOG.md',

luatest/cbuilder.lua

+235
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
--- Configuration builder.
2+
--
3+
-- It allows to construct a declarative configuration for a test case using
4+
-- less boilerplace code/options, especially when a replicaset is to be
5+
-- tested, not a single instance. All the methods support chaining (return
6+
-- the builder object back).
7+
--
8+
-- @usage
9+
--
10+
-- local config = Builder:new()
11+
-- :add_instance('instance-001', {
12+
-- database = {
13+
-- mode = 'rw',
14+
-- },
15+
-- })
16+
-- :add_instance('instance-002', {})
17+
-- :add_instance('instance-003', {})
18+
-- :config()
19+
--
20+
-- By default, all instances are added to replicaset-001 in group-001,
21+
-- but it's possible to select a different replicaset and/or group:
22+
--
23+
-- local config = Builder:new()
24+
-- :use_group('group-001')
25+
-- :use_replicaset('replicaset-001')
26+
-- :add_instance(<...>)
27+
-- :add_instance(<...>)
28+
-- :add_instance(<...>)
29+
--
30+
-- :use_group('group-002')
31+
-- :use_replicaset('replicaset-002')
32+
-- :add_instance(<...>)
33+
-- :add_instance(<...>)
34+
-- :add_instance(<...>)
35+
--
36+
-- :config()
37+
--
38+
-- The default credentials and iproto options are added to
39+
-- setup replication and to allow a test to connect to the
40+
-- instances.
41+
--
42+
-- There is a few other methods:
43+
--
44+
-- * :set_replicaset_option('foo.bar', value)
45+
-- * :set_instance_option('instance-001', 'foo.bar', value)
46+
--
47+
-- @classmod luatest.cbuilder
48+
49+
local checks = require('checks')
50+
local fun = require('fun')
51+
52+
local Builder = require('luatest.class').new()
53+
54+
-- Do a post-reqiure of the `internal.config.cluster_config`,
55+
-- since it is available from version 3.0.0+. Otherwise we
56+
-- will get an error when initializing the module in `luatest.init`.
57+
local cluster_config = {}
58+
59+
local base_config = {
60+
credentials = {
61+
users = {
62+
replicator = {
63+
password = 'secret',
64+
roles = {'replication'},
65+
},
66+
client = {
67+
password = 'secret',
68+
roles = {'super'},
69+
},
70+
},
71+
},
72+
iproto = {
73+
listen = {{
74+
uri = 'unix/:./{{ instance_name }}.iproto'
75+
}},
76+
advertise = {
77+
peer = {
78+
login = 'replicator',
79+
}
80+
},
81+
},
82+
replication = {
83+
-- The default value is 1 second. It is good for a real
84+
-- usage, but often suboptimal for testing purposes.
85+
--
86+
-- If an instance can't connect to another instance (say,
87+
-- because it is not started yet), it retries the attempt
88+
-- after so called 'replication interval', which is equal
89+
-- to replication timeout.
90+
--
91+
-- One second waiting means one more second for a test
92+
-- case and, if there are many test cases with a
93+
-- replicaset construction, it affects the test timing a
94+
-- lot.
95+
--
96+
-- replication.timeout = 0.1 second reduces the timing
97+
-- by half for my test.
98+
timeout = 0.1,
99+
},
100+
}
101+
102+
function Builder:inherit(object)
103+
setmetatable(object, self)
104+
self.__index = self
105+
return object
106+
end
107+
108+
--- Build a config builder object.
109+
--
110+
-- @tab[opt] config Table with declarative configuration.
111+
function Builder:new(config)
112+
checks('table', '?table')
113+
cluster_config = require('internal.config.cluster_config')
114+
115+
config = table.deepcopy(config or base_config)
116+
self._config = config
117+
self._group = 'group-001'
118+
self._replicaset = 'replicaset-001'
119+
return self
120+
end
121+
122+
--- Select a group for following calls.
123+
--
124+
-- @string group_name Group of replicas.
125+
function Builder:use_group(group_name)
126+
checks('table', 'string')
127+
self._group = group_name
128+
return self
129+
end
130+
131+
--- Select a replicaset for following calls.
132+
--
133+
-- @string replicaset_name Replica set name.
134+
function Builder:use_replicaset(replicaset_name)
135+
checks('table', 'string')
136+
self._replicaset = replicaset_name
137+
return self
138+
end
139+
140+
--- Set option to the cluster config.
141+
--
142+
-- @string path Option path.
143+
-- @param value Option value (int, string, table).
144+
function Builder:set_global_option(path, value)
145+
checks('table', 'string', '?')
146+
cluster_config:set(self._config, path, value)
147+
return self
148+
end
149+
150+
--- Set an option for the selected group.
151+
--
152+
-- @string path Option path.
153+
-- @param value Option value (int, string, table).
154+
function Builder:set_group_option(path, value)
155+
checks('table', 'string', '?')
156+
path = fun.chain({
157+
'groups', self._group,
158+
}, path:split('.')):totable()
159+
160+
cluster_config:set(self._config, path, value)
161+
return self
162+
end
163+
164+
--- Set an option for the selected replicaset.
165+
--
166+
-- @string path Option path.
167+
-- @param value Option value (int, string, table).
168+
function Builder:set_replicaset_option(path, value)
169+
checks('table', 'string', '?')
170+
path = fun.chain({
171+
'groups', self._group,
172+
'replicasets', self._replicaset,
173+
}, path:split('.')):totable()
174+
175+
-- <schema object>:set() validation is too tight. Workaround
176+
-- it. Maybe we should reconsider this :set() behavior in a
177+
-- future.
178+
if value == nil then
179+
local cur = self._config
180+
for i = 1, #path - 1 do
181+
-- Create missed fields.
182+
local component = path[i]
183+
if cur[component] == nil then
184+
cur[component] = {}
185+
end
186+
187+
cur = cur[component]
188+
end
189+
cur[path[#path]] = value
190+
return self
191+
end
192+
193+
cluster_config:set(self._config, path, value)
194+
return self
195+
end
196+
197+
-- Set an option of a particular instance in the selected replicaset.
198+
--
199+
-- @string instance_name Instance where the option will be saved.
200+
-- @string path Option path.
201+
-- @param value Option value (int, string, table).
202+
function Builder:set_instance_option(instance_name, path, value)
203+
checks('table', 'string', 'string', '?')
204+
path = fun.chain({
205+
'groups', self._group,
206+
'replicasets', self._replicaset,
207+
'instances', instance_name,
208+
}, path:split('.')):totable()
209+
210+
cluster_config:set(self._config, path, value)
211+
return self
212+
end
213+
214+
--- Add an instance with the given options to the selected replicaset.
215+
--
216+
-- @string instance_name Instance where the config will be saved.
217+
-- @tab iconfig Declarative config for the instance.
218+
function Builder:add_instance(instance_name, iconfig)
219+
checks('table', 'string', '?')
220+
local path = {
221+
'groups', self._group,
222+
'replicasets', self._replicaset,
223+
'instances', instance_name,
224+
}
225+
cluster_config:set(self._config, path, iconfig)
226+
return self
227+
end
228+
229+
--- Return the resulting configuration.
230+
--
231+
function Builder:config()
232+
return self._config
233+
end
234+
235+
return Builder

luatest/init.lua

+5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ luatest.log = require('luatest.log')
4343
-- @see luatest.justrun
4444
luatest.justrun = require('luatest.justrun')
4545

46+
--- Declarative configuration builder helper.
47+
--
48+
-- @see luatest.cbuilder
49+
luatest.cbuilder = require('luatest.cbuilder')
50+
4651
--- Add before suite hook.
4752
--
4853
-- @function before_suite

0 commit comments

Comments
 (0)