monotone

monotone Mtn Source Tree

Root/lua-testsuite.lua

  • Property mtn:execute set to true
1#!./tester
2
3monotone_path = nil
4no_network_tests = false
5
6function safe_mtn(...)
7 if monotone_path == nil then
8 monotone_path = os.getenv("mtn")
9 if monotone_path == nil then
10 err("'mtn' environment variable not set")
11 end
12 end
13 return {monotone_path, "--norc", "--root=" .. test.root,
14 "--confdir="..test.root, unpack(arg)}
15end
16
17function mtn_ws_opts(...)
18 -- Return a mtn command string that uses options from _MTN/options,
19 -- root from current directory - as close to a normal user command
20 -- line as possible.
21 if monotone_path == nil then
22 monotone_path = os.getenv("mtn")
23 if monotone_path == nil then
24 err("'mtn' environment variable not set")
25 end
26 end
27 return {monotone_path, "--ssh-sign=no", "--no-default-confdir", "--norc", "--rcfile", test.root .. "/test_hooks.lua", unpack(arg)}
28end
29
30function mtn_outside_ws(...)
31 -- Return a mtn command string that is executed outside a workspace,
32 -- but specifies all appropriate options.
33 if monotone_path == nil then
34 monotone_path = os.getenv("mtn")
35 if monotone_path == nil then
36 err("'mtn' environment variable not set")
37 end
38 end
39 return {monotone_path,
40 "--ssh-sign=no",
41 "--norc", "--rcfile", test.root .. "/test_hooks.lua",
42 "--confdir="..test.root,
43 "--db=" .. test.root .. "/test.db",
44 "--keydir", test.root .. "/keys",
45 "--key=tester@test.net",
46 unpack(arg)}
47end
48
49-- function preexecute(x)
50-- return {"valgrind", "--tool=memcheck", unpack(x)}
51-- end
52
53function raw_mtn(...)
54 if preexecute ~= nil then
55 return preexecute(safe_mtn(unpack(arg)))
56 else
57 return safe_mtn(unpack(arg))
58 end
59end
60
61function mtn(...)
62 return raw_mtn("--rcfile", test.root .. "/test_hooks.lua", -- "--nostd",
63 "--db=" .. test.root .. "/test.db",
64 "--keydir", test.root .. "/keys",
65 "--key=tester@test.net", unpack(arg))
66end
67
68function nodb_mtn(...)
69 return raw_mtn("--rcfile", test.root .. "/test_hooks.lua", -- "--nostd",
70 "--keydir", test.root .. "/keys",
71 "--key=tester@test.net", unpack(arg))
72end
73
74function nokey_mtn(...)
75 return raw_mtn("--rcfile", test.root .. "/test_hooks.lua", -- "--nostd",
76 "--db=" .. test.root .. "/test.db",
77 "--keydir", test.root .. "/keys", unpack(arg))
78end
79
80function minhooks_mtn(...)
81 return raw_mtn("--db=" .. test.root .. "/test.db",
82 "--keydir", test.root .. "/keys",
83 "--rcfile", test.root .. "/min_hooks.lua",
84 "--key=tester@test.net", unpack(arg))
85end
86
87function commit(branch, message, mt)
88 if branch == nil then branch = "testbranch" end
89 if message == nil then message = "blah-blah" end
90 if mt == nil then mt = mtn end
91 check(mt("commit", "--message", message, "--branch", branch), 0, false, false)
92end
93
94function sha1(what)
95 check(safe_mtn("identify", what), 0, false, false)
96 return trim(readfile("ts-stdout"))
97end
98
99function probe_node(filename, rsha, fsha)
100 remove("_MTN.old")
101 rename("_MTN", "_MTN.old")
102 remove(filename)
103 check(mtn("checkout", "--revision", rsha, "."), 0, false, true)
104 rename("_MTN.old/options", "_MTN")
105 check(base_revision() == rsha)
106 check(sha1(filename) == fsha)
107end
108
109function mtn_setup()
110 check(getstd("test_keys"))
111 check(getstd("test_hooks.lua"))
112 check(getstd("min_hooks.lua"))
113
114 check(mtn("db", "init"), 0, false, false)
115 check(mtn("read", "test_keys"), 0, false, false)
116 check(mtn("setup", "--branch=testbranch", "."), 0, false, false)
117 remove("test_keys")
118end
119
120function base_revision()
121 local workrev = readfile("_MTN/revision")
122 local extract = string.gsub(workrev, "^.*old_revision %[(%x*)%].*$", "%1")
123 if extract == workrev then
124 err("failed to extract base revision from _MTN/revision")
125 end
126 return extract
127end
128
129function base_manifest()
130 check(safe_mtn("automate", "get_manifest_of", base_revision()), 0, false)
131 check(copy("ts-stdout", "base_manifest_temp"))
132 return sha1("base_manifest_temp")
133end
134
135function certvalue(rev, name)
136 check(safe_mtn("automate", "certs", rev), 0, false)
137 local parsed = parse_basic_io(readfile("ts-stdout"))
138 local cname
139 local goodsig
140 -- note: this relies on the name and signature elements appearing
141 -- before the value element, in each stanza.
142 for _,l in pairs(parsed) do
143 if l.name == "name" then cname = l.values[1] end
144 if l.name == "signature" then goodsig = l.values[1] end
145 if cname == name and l.name == "value" then return l.values[1], goodsig end
146 end
147 return nil
148end
149
150function qgrep(what, where)
151 local ok,res = pcall(unpack(grep("-q", what, where)))
152 if not ok then err(res) end
153 return res == 0
154end
155
156function addfile(filename, contents, mt)
157 if contents ~= nil then writefile(filename, contents) end
158 if mt == nil then mt = mtn end
159 check(mt("add", filename), 0, false, false)
160end
161
162function adddir(dirname, mt)
163 if not isdir(dirname) then mkdir(dirname) end
164 if mt == nil then mt = mtn end
165 check(mt("add", dirname), 0, false, false)
166end
167
168function revert_to(rev, branch, mt)
169 if type(branch) == "function" then
170 mt = branch
171 branch = nil
172 end
173 if mt == nil then mt = mtn end
174
175 check(mt("automate", "get_manifest_of", base_revision()), 0, true, false)
176 rename("stdout", "paths-new")
177
178 remove("_MTN.old")
179 rename("_MTN", "_MTN.old")
180
181 check(mt("automate", "get_manifest_of", rev), 0, true, false)
182 rename("stdout", "paths-old")
183
184 -- remove all of the files and dirs in this
185 -- manifest to clear the way for checkout
186
187 for path in io.lines("paths-new") do
188 len = string.len(path) - 1
189
190 if (string.match(path, "^ file \"")) then
191 path = string.sub(path, 10, len)
192 elseif (string.match(path, "^dir \"")) then
193 path = string.sub(path, 6, len)
194 else
195 path = ""
196 end
197
198 if (string.len(path) > 0) then
199 remove(path)
200 end
201 end
202
203 for path in io.lines("paths-old") do
204 len = string.len(path) - 1
205
206 if (string.match(path, "^ file \"")) then
207 path = string.sub(path, 10, len)
208 elseif (string.match(path, "^dir \"")) then
209 path = string.sub(path, 6, len)
210 else
211 path = ""
212 end
213
214 if (string.len(path) > 0) then
215 remove(path)
216 end
217 end
218
219 if branch == nil then
220 check(mt("checkout", "--revision", rev, "."), 0, false, true)
221 else
222 check(mt("checkout", "--branch", branch, "--revision", rev, "."), 0, false, true)
223 end
224 check(base_revision() == rev)
225end
226
227function canonicalize(filename)
228 if ostype == "Windows" then
229 L("Canonicalizing ", filename, "\n")
230 local f = io.open(filename, "rb")
231 local indat = f:read("*a")
232 f:close()
233 local outdat = string.gsub(indat, "\r\n", "\n")
234 f = io.open(filename, "wb")
235 f:write(outdat)
236 f:close()
237 else
238 L("Canonicalization not needed (", filename, ")\n")
239 end
240end
241
242function check_same_db_contents(db1, db2)
243 check_same_stdout(mtn("--db", db1, "ls", "keys"),
244 mtn("--db", db2, "ls", "keys"))
245
246 check(mtn("--db", db1, "complete", "revision", ""), 0, true, false)
247 rename("stdout", "revs")
248 check(mtn("--db", db2, "complete", "revision", ""), 0, true, false)
249 check(samefile("stdout", "revs"))
250 for rev in io.lines("revs") do
251 rev = trim(rev)
252 check_same_stdout(mtn("--db", db1, "automate", "certs", rev),
253 mtn("--db", db2, "automate", "certs", rev))
254 check_same_stdout(mtn("--db", db1, "automate", "get_revision", rev),
255 mtn("--db", db2, "automate", "get_revision", rev))
256 check_same_stdout(mtn("--db", db1, "automate", "get_manifest_of", rev),
257 mtn("--db", db2, "automate", "get_manifest_of", rev))
258 end
259
260 check(mtn("--db", db1, "complete", "file", ""), 0, true, false)
261 rename("stdout", "files")
262 check(mtn("--db", db2, "complete", "file", ""), 0, true, false)
263 check(samefile("stdout", "files"))
264 for file in io.lines("files") do
265 file = trim(file)
266 check_same_stdout(mtn("--db", db1, "automate", "get_file", file),
267 mtn("--db", db2, "automate", "get_file", file))
268 end
269end
270
271-- maybe these should go in tester.lua?
272function do_check_same_stdout(cmd1, cmd2)
273 check(cmd1, 0, true, false)
274 rename("stdout", "stdout-first")
275 check(cmd2, 0, true, false)
276 rename("stdout", "stdout-second")
277 check(samefile("stdout-first", "stdout-second"))
278end
279function do_check_different_stdout(cmd1, cmd2)
280 check(cmd1, 0, true, false)
281 rename("stdout", "stdout-first")
282 check(cmd2, 0, true, false)
283 rename("stdout", "stdout-second")
284 check(not samefile("stdout-first", "stdout-second"))
285end
286function check_same_stdout(a, b, c)
287 if type(a) == "table" and type(b) == "table" then
288 return do_check_same_stdout(a, b)
289 elseif type(a) == "table" and type(b) == "function" and type(c) == "function" then
290 return do_check_same_stdout(b(unpack(a)), c(unpack(a)))
291 elseif type(a) == "table" and type(b) == "nil" and type(c) == "nil" then
292 return do_check_same_stdout(mtn(unpack(a)), mtn2(unpack(a)))
293 else
294 err("bad arguments ("..type(a)..", "..type(b)..", "..type(c)..") to check_same_stdout")
295 end
296end
297function check_different_stdout(a, b, c)
298 if type(a) == "table" and type(b) == "table" then
299 return do_check_different_stdout(a, b)
300 elseif type(a) == "table" and type(b) == "function" and type(c) == "function" then
301 return do_check_different_stdout(b(unpack(a)), c(unpack(a)))
302 elseif type(a) == "table" and type(b) == "nil" and type(c) == "nil" then
303 return do_check_different_stdout(mtn(unpack(a)), mtn2(unpack(a)))
304 else
305 err("bad arguments ("..type(a)..", "..type(b)..", "..type(c)..") to check_different_stdout")
306 end
307end
308
309function write_large_file(name, size)
310 local file = io.open(name, "wb")
311 for i = 1,size do
312 for j = 1,128 do -- write 1MB
313 local str8k = ""
314 for k = 1,256 do
315 -- 32
316 str8k = str8k .. string.char(math.random(255), math.random(255),
317 math.random(255), math.random(255),
318 math.random(255), math.random(255),
319 math.random(255), math.random(255),
320 math.random(255), math.random(255),
321 math.random(255), math.random(255),
322 math.random(255), math.random(255),
323 math.random(255), math.random(255),
324 math.random(255), math.random(255),
325 math.random(255), math.random(255),
326 math.random(255), math.random(255),
327 math.random(255), math.random(255),
328 math.random(255), math.random(255),
329 math.random(255), math.random(255),
330 math.random(255), math.random(255),
331 math.random(255), math.random(255))
332 end
333 file:write(str8k)
334 end
335 end
336 file:close()
337end
338
339------------------------------------------------------------------------
340--====================================================================--
341------------------------------------------------------------------------
342testdir = srcdir.."/tests"
343
344function prepare_to_run_tests (P)
345 -- We have a bunch of tests that depend on being able to create
346 -- files or directories that we cannot read or write (mostly to
347 -- test error handling behavior).
348 require_not_root()
349
350 -- Several tests require the ability to create temporary
351 -- directories outside the workspace.
352 local d = make_temp_dir()
353 if d == nil then
354 P("This test suite requires the ability to create files\n"..
355 "in the system-wide temporary directory. Please correct the\n"..
356 "access permissions on this directory and try again.\n")
357 return 1
358 end
359 unlogged_remove(d)
360
361 -- Several tests require the ability to run a network server on
362 -- the loopback interface, and connect to it from another process
363 -- on this computer. Unlike the above, we just skip those tests
364 -- (loudly) if we can't do that. Verifying that this is possible
365 -- requires a helper program.
366
367 local checknet = getpathof("check_net")
368 if os.getenv("DISABLE_NETWORK_TESTS") ~= nil then
369 P("warning: DISABLE_NETWORK_TESTS set, skipping network server tests\n")
370 no_network_tests = true
371 elseif checknet == nil then
372 P("warning: check_net helper is missing, skipping network server tests\n")
373 no_network_tests = true
374 else
375 writefile_q("in", nil)
376 prepare_redirect("in", "out", "err")
377 local status = execute(checknet)
378 local out = readfile_q("out")
379 local err = readfile_q("err")
380
381 if status == 0 and err == "" and out == "" then
382 logfile:write("check_net: Can use the loopback interface.\n")
383 else
384 logfile:write(string.format("check_net: failed with status %d\n"..
385 "stdout:\n%s\nstderr:\n%s\n",
386 status, out, err))
387 P("warning: network unavailable, skipping network server tests\n")
388 no_network_tests = true
389 end
390 end
391
392 -- Record the full version of monotone under test in the logfile.
393
394 monotone_path = getpathof("mtn")
395 if monotone_path == nil then monotone_path = "mtn" end
396 set_env("mtn", monotone_path)
397
398 writefile_q("in", nil)
399 prepare_redirect("in", "out", "err")
400
401 local status = execute(monotone_path, "version", "--full")
402 local out = readfile_q("out")
403 local err = readfile_q("err")
404
405 if status == 0 and err == "" and out ~= "" then
406 logfile:write(out)
407 else
408 P(string.format("mtn version --full: exit %d\nstdout:\n", status))
409 P(out)
410 P("stderr:\n")
411 P(err)
412
413 if status == 0 then status = 1 end
414 end
415
416 unlogged_remove("in")
417 unlogged_remove("out")
418 unlogged_remove("err")
419 return status
420end

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status