Skip to content

Commit d232a3f

Browse files
ImeevMAigormunkin
authored andcommitted
test: add LuaJIT-test-cleanup test suite
This patch introduces LuaJIT-test-cleanup test suite[1] into our LuaJIT fork source tree. Considering the changes made by our team (such as a new preloaded module) and tweaks made in Tarantool runtime, several tests need to be adjusted. However to be sure, we initially use the valid suite, everything in test/LuaJIT-tests directory is moved intact. [1]: https://github.com/LuaJIT/LuaJIT-test-cleanup/tree/014708b/test Part of tarantool/tarantool#4064 Part of tarantool/tarantool#4473 Reviewed-by: Sergey Kaplun <skaplun@tarantool.org> Reviewed-by: Sergey Ostanevich <sergos@tarantool.org> Signed-off-by: Igor Munkin <imun@tarantool.org>
1 parent c8265c4 commit d232a3f

File tree

198 files changed

+13251
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

198 files changed

+13251
-0
lines changed

.luacheckrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ read_globals = { 'misc' }
88
exclude_files = {
99
'dynasm/',
1010
'src/',
11+
'test/LuaJIT-tests/',
1112
}

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ else()
4141
endif()
4242

4343
add_subdirectory(tarantool-tests)
44+
add_subdirectory(LuaJIT-tests)
4445

4546
add_custom_target(${PROJECT_NAME}-test DEPENDS
47+
LuaJIT-tests
4648
tarantool-tests
4749
)
4850

test/LuaJIT-tests/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# See the rationale in the root CMakeLists.txt
2+
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
3+
4+
add_custom_target(LuaJIT-tests DEPENDS ${LUAJIT_TEST_BINARY})
5+
6+
add_custom_command(TARGET LuaJIT-tests
7+
COMMENT "Running LuaJIT-tests"
8+
COMMAND
9+
${LUAJIT_TEST_BINARY} ${CMAKE_CURRENT_SOURCE_DIR}/test.lua
10+
+slow +ffi +bit +jit
11+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
12+
)

test/LuaJIT-tests/README.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
This directory contains the LuaJIT test suite, or at least something which
2+
will evolve into the LuaJIT test suite. Large chunks of the suite can also
3+
be run with any other Lua 5.1 or 5.2 interpreter.
4+
5+
## Running the test suite ##
6+
7+
To run the default test suite, run `test.lua` using the Lua interpreter you
8+
wish to test, for example:
9+
10+
$ ~/luajit-2.0/src/luajit test.lua
11+
12+
If the test suite passes, the final line printed to stdout will be
13+
`NNN passed`, and the exit code of the process will be zero. If any tests
14+
fail, the exit code will be non-zero. If the failures caused catastrophic
15+
termination of the entire process (such as a segmentation fault or assertion
16+
failure), the last line of output will be number and name of the test which
17+
caused the catastrophe. If the failures weren't catastrophic, the penultimate
18+
line of output will be `NNN passed, MMM failed`, and the last line will say
19+
how to re-run just the failing tests.
20+
21+
Various flags and options can be passed to `test.lua` to control which tests
22+
are run, and in which order. Run `lua test.lua --help` for details.
23+
24+
## Structure of the test suite ##
25+
26+
The test suite consists of a directory tree. Within said tree there are various
27+
`.lua` files, and within every `.lua` file there are one or more tests. Every
28+
directory in the tree contains a file called `index`, which enumerates the
29+
members of the directory which contribute to the test suite (this is done to
30+
avoid an external dependency for directory iteration, and to allow metadata to
31+
be specified at the file/directory level). Every `.lua` file is structured as:
32+
33+
<< local definitions >>
34+
<< test 1 >>
35+
...
36+
<< test N >>
37+
38+
Where `<< local definitions >>` consists of Lua code to act as a common prefix
39+
for every test in the file, and each `<< test >>` looks like:
40+
41+
do --- <<name>> <<metadata>>
42+
<< code >>
43+
end
44+
45+
Where `<<name>>` is (almost) free-form, and `<< code >>` is Lua code which
46+
performs some actions and probably calls `assert` alot. The `<<metadata>>`
47+
fragment can be used to specify the conditions under which the test should
48+
or should not run, to adjust the environment in which the test is run, and to
49+
allow key/value pairs to be specified in a standard place/format.
50+
51+
Some common pieces of metadata are:
52+
* `+luajit>=2.1` - The test requires LuaJIT 2.1 or later to run.
53+
* `+lua<5.2` - The test requires Lua 5.1 or earlier to run (all versions of
54+
LuaJIT report themselves as 5.1).
55+
* `+ffi` - The test requires the `ffi` library to be present.
56+
* `+bit` - The test requires the `bit` library to be present.
57+
* `+jit` - The test requires JIT compilation be available and turned on.
58+
* `+slow` - The test is too slow to run as part of the default suite, and
59+
thus requires `+slow` to be specified on the command line.
60+
* `!private_G` - The test modifies globals, and thus needs to be run with a
61+
private (shallow) copy of `_G`.
62+
63+
Lua code which is common across all (or some) tests in a single file can be
64+
written at the top of the file as part of `<< local definitions >>`. Code
65+
which is common across multiple files lives in the `common` directory, and
66+
is pulled into applicable tests by means of `local x = require"common.x"`.
67+
68+
It is intended that most `.lua` files in the test suite can be exercised
69+
without the test runner by just passing them to a Lua interpreter. In such
70+
cases, metadata is ignored, the tests are executed from top to bottom, and
71+
any failure results in later tests not running. Also note that the test
72+
runner converts every test into a separate function, which causes references
73+
to local definitions to become upvalue accesses rather than local variable
74+
accesses - in some cases this can cause differences in behaviour.
75+
76+
## Extending the test suite ##
77+
78+
First of all, decide where your new test(s) should live. This might be within
79+
an existing `.lua` file, or might involve creating new files and/or directories.
80+
If new files are created, remember to add them to the `index` file of the
81+
enclosing directory. If new directories are created, remember to create an
82+
`index` file in said directory, and add the new directory to the `index` file
83+
in the parent directory.
84+
85+
Once you've decided in which file the test(s) should live, you're ready to add
86+
your test(s) to said file. Each test should be wrapped in a `do`/`end` block,
87+
and given some kind of name (after the `do` keyword, as in `do --- <<name>>`).
88+
The test should call `assert` to confirm whether the thing under test is
89+
behaving, or otherwise raise an error if the thing under test is misbehaving.
90+
Your test(s) should not write to stdout or stderr, nor should they mutate
91+
global state. After your test(s) are written, you should be able to determine
92+
which features they require, and put on metadata appropriately.
93+
94+
## Completing the tidy-up of the test suite ##
95+
96+
Some files/directories in this directory need some thought:
97+
98+
* `common/ffi_util.inc` - Needs renaming and being made `require`-able.
99+
* `lib/ffi` - Tests need converting to structure described in this document.
100+
* `lib/table/misc.lua` - Tests need organising and converting to structure
101+
described in this document.
102+
* `misc` - Tests need organising and converting to structure described in
103+
this document.
104+
* `src` - C/C++ source which needs to be compiled into a dynamic library and
105+
loaded for certain tests. Need to figure out a good way of handling
106+
C/C++ source.
107+
* `sysdep` - Need to figure out a good way of handling these.
108+
* `unportable` - Need to figure out a good way of handling these.
109+
110+
After that, consult the README file by Mike in the directory above this one.

test/LuaJIT-tests/bc/constov.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
do --- float
3+
local t = { "local x\n" }
4+
for i=2,65537 do t[i] = "x="..i..".5\n" end
5+
assert(loadstring(table.concat(t)) ~= nil)
6+
t[65538] = "x=65538.5"
7+
assert(loadstring(table.concat(t)) == nil)
8+
end
9+
10+
do --- int
11+
local t = { "local x\n" }
12+
for i=2,65537 do t[i] = "x='"..i.."'\n" end
13+
assert(loadstring(table.concat(t)) ~= nil)
14+
t[65538] = "x='65538'"
15+
assert(loadstring(table.concat(t)) == nil)
16+
end

test/LuaJIT-tests/bc/index

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
constov.lua +slow
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
return function(f, msg)
2+
local ok, err = pcall(f)
3+
if ok then error("error check unexpectedly succeeded", 2) end
4+
if msg then
5+
if type(err) ~= "string" then
6+
error("error check failed with "..tostring(err), 2)
7+
end
8+
local line, err2 = string.match(err, ":(%d*): (.*)")
9+
if err2 ~= msg then
10+
if err2:gsub(" got no value", " got nil") == msg then
11+
return
12+
end
13+
error("error check failed with "..err, 2)
14+
end
15+
end
16+
end

test/LuaJIT-tests/common/ffi_util.inc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
-- This should be turned into a proper module and not use globals.
2+
-- Or combined into a generiv test utility module. With FFI
3+
-- functionality turned off, if the FFI module is not built-in.
4+
5+
local ffi = require("ffi")
6+
7+
function checkfail(t, f)
8+
f = f or ffi.typeof
9+
for i=1,1e9 do
10+
local tp = t[i]
11+
if not tp then break end
12+
assert(pcall(f, tp) == false, tp)
13+
end
14+
end
15+
16+
function checktypes(t)
17+
for i=1,1e9,3 do
18+
local tp = t[i+2]
19+
if not tp then break end
20+
local id = ffi.typeof(tp)
21+
assert(ffi.sizeof(id) == t[i], tp)
22+
assert(ffi.alignof(id) == t[i+1], tp)
23+
end
24+
end
25+
26+
function fails(f, ...)
27+
if pcall(f, ...) ~= false then error("failure expected", 2) end
28+
end
29+
30+
local incroot = os.getenv("INCROOT") or "/usr/include"
31+
local cdefs = os.getenv("CDEFS") or ""
32+
33+
function include(name)
34+
local flags = ffi.abi("32bit") and "-m32" or "-m64"
35+
if string.sub(name, 1, 1) ~= "/" then name = incroot.."/"..name end
36+
local fp = assert(io.popen("cc -E -P "..flags.." "..cdefs.." "..name))
37+
local s = fp:read("*a")
38+
fp:close()
39+
ffi.cdef(s)
40+
end
41+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
return "canary is alive"

test/LuaJIT-tests/computations.lua

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
do --- ack
2+
local function Ack(m, n)
3+
if m == 0 then return n+1 end
4+
if n == 0 then return Ack(m-1, 1) end
5+
return Ack(m-1, (Ack(m, n-1))) -- The parentheses are deliberate.
6+
end
7+
8+
assert(Ack(3,5) == 253)
9+
end
10+
11+
do --- ack notail
12+
local function Ack(m, n)
13+
if m == 0 then return n+1 end
14+
if n == 0 then return Ack(m-1, 1) end
15+
return (Ack(m-1, (Ack(m, n-1)))) -- The parentheses are deliberate.
16+
end
17+
18+
assert(Ack(3,5) == 253)
19+
end
20+
21+
do --- fac
22+
local function fac(n)
23+
local x = 1
24+
for i=2,n do
25+
x = x * i
26+
end
27+
return x
28+
end
29+
30+
assert(fac(10) == 3628800)
31+
end
32+
33+
do --- ffib
34+
local function ffib(n)
35+
if n <= 2 then return n,1 end
36+
if n % 2 == 1 then
37+
local a,b = ffib((n-1)/2)
38+
local aa = a*a
39+
return aa+a*(b+b), aa+b*b
40+
else
41+
local a,b = ffib(n/2-1)
42+
local ab = a+b
43+
return ab*ab+a*a, (ab+b)*a
44+
end
45+
end
46+
47+
local function fib(n)
48+
return (ffib(n))
49+
end
50+
51+
assert(fib(40) == 165580141)
52+
assert(fib(39) == 102334155)
53+
assert(fib(77) == 8944394323791464)
54+
end
55+
56+
do --- fib
57+
local function fib(n)
58+
if n < 2 then return 1 end
59+
return fib(n-2) + fib(n-1)
60+
end
61+
62+
assert(fib(27) == 317811)
63+
end
64+
65+
do --- nsieve
66+
local function nsieve(m)
67+
local isPrime = {}
68+
for i=2,m do isPrime[i] = true end
69+
local count = 0
70+
for i=2,m do
71+
if isPrime[i] then
72+
for k=i+i,m,i do isPrime[k] = false end
73+
count = count + 1
74+
end
75+
end
76+
return count
77+
end
78+
79+
assert(nsieve(100) == 25)
80+
assert(nsieve(12345) == 1474)
81+
end
82+
83+
do --- recsum
84+
local function sum(n)
85+
if n == 1 then return 1 end
86+
return n + sum(n-1)
87+
end
88+
89+
for i=1, 100 do
90+
assert(sum(i) == i*(i+1)/2)
91+
end
92+
end
93+
94+
do --- recsump
95+
local abs = math.abs
96+
local function sum(n)
97+
if n == 1 then return 1 end
98+
return abs(n + sum(n-1))
99+
end
100+
101+
for i=1, 100 do
102+
assert(sum(i) == i*(i+1)/2)
103+
end
104+
end
105+
106+
do --- tak
107+
local function tak(x, y, z)
108+
if y >= x then return z end
109+
return tak(tak(x-1, y, z), tak(y-1, z, x), (tak(z-1, x, y)))
110+
end
111+
112+
assert(tak(21, 14, 7) == 14)
113+
end

0 commit comments

Comments
 (0)