From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id EE7747030B; Fri, 19 Feb 2021 22:04:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org EE7747030B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1613761476; bh=/5ahp00JnmALG6JF834I5S/ZXu2kHREKF/M8PkNMQmg=; h=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=BoIFgW/UEjZs3aLqvg50SeZalO/RkSv/RfBECm/2deVPhpTe7KncV2TKJfkm+sC1T FpYAcabyilPMMig0Ian5c4D/SvuT8zyMVrMOJz/NmZ9zAafoI+BFX5umE0HFkZ738j 6B3zcZM7n27zNlE5VIX8uTDUBZsvFUzbeFECTNAY= Received: from smtpng2.m.smailru.net (smtpng2.m.smailru.net [94.100.179.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 980FD7030B for ; Fri, 19 Feb 2021 22:04:34 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 980FD7030B Received: by smtpng2.m.smailru.net with esmtpa (envelope-from ) id 1lDB4r-00082n-7y; Fri, 19 Feb 2021 22:04:33 +0300 Date: Fri, 19 Feb 2021 22:04:30 +0300 To: Sergey Kaplun Message-ID: <20210219190430.GO5448@tarantool.org> References: <6a03d693204cacc5791c75e1003efc150abb2979.1612291495.git.imun@tarantool.org> <20210214184858.GE9361@root> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20210214184858.GE9361@root> X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.10.1 (2018-07-13) X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD975C3EC174F56692254B0AABE1FB071B2BA6557555153D6A0182A05F538085040802A7024E2201992BA448BE22B50C29AC96C446B3B95F0CC340D72C62A05E6B0 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7850A3F981F25E362EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F79006375080A183704825A98638F802B75D45FF5571747095F342E8C7A0BC55FA0FE5FC6E46C3FEA7AD79AB7BAFCBB57D92D2674951F7B3FFBCA0FB389733CBF5DBD5E913377AFFFEAFD269A417C69337E82CC2CC7F00164DA146DAFE8445B8C89999729449624AB7ADAF37F6B57BC7E64490611E7FA7ABCAF51C92A417C69337E82CC2CC7F00164DA146DA6F5DAA56C3B73B23C77107234E2CFBA567F23339F89546C55F5C1EE8F4F765FCB9CEE4F2B4A90F8475ECD9A6C639B01BBD4B6F7A4D31EC0BC0CAF46E325F83A522CA9DD8327EE4930A3850AC1BE2E7355705F49E3A860CEDC4224003CC836476C0CAF46E325F83A50BF2EBBBDD9D6B0F05F538519369F3743B503F486389A921A5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A5A30802B4D13B85183DAA4A3D2A638913E240819CD8ED093BD59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA75448CF9D3A7B2C848410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34D4140D813EC137C613F7BE082084E6EE230DFDE3ECF99642579A9FF3559A31BAB429D423C2B8ED201D7E09C32AA3244CED6F46347C0020A9844913F54540CBA0D08D48398F32B4A6927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojPfquRGj73121ydo98zNYGQ== X-Mailru-Sender: 689FA8AB762F73936BC43F508A0638221D78A50EB36284E88A8648547D28419FA7C8D0F45F857DBFE9F1EFEE2F478337FB559BB5D741EB964C8C2C849690F8E70A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit 3/5] test: run LuaJIT tests via CMake X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Igor Munkin via Tarantool-patches Reply-To: Igor Munkin Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Sergey, Thanks for the patch! On 14.02.21, Sergey Kaplun wrote: > Hi, Igor! > > > CMake can't expand the generator expression used in DEPENDS section of > > Typo? s/in DEPENDS section/in the DEPENDS section/ This is the common section name, not the particular section. > > > Tarantool tests are implemented using Tarantool on-board TAP module[2], > > that is moved to LuaJIT repository with a little changes to save Lua > > Typo: s/a little changes/little changes/ No, I don't want to emphasize the amount, but rather the fact the chunks are almost untouched. > > > Side note: What kind of quotes is preferable for our code style in > LuaJIT? This is an open question for the LuaJIT style guide. I personally prefer single until I have to use double ones. > The new module is written with single quotes, but a lot of > code inside LuaJIT uses double quotes (see , for > example). Also, as far as you've already changed indentation it will be > nice do not stop there and fix quotes and change `{ }` to `{}` as usual. Fixed all new occurrences. > > Side note: (this is more like discussion question) -- do we really need > to use Tarantool's module here? I provide some > dissatisfactions, but as I say below, we can't just change this > module API because we want (if you remove this module from Tarantool > and save it only here). > If it is saved untouchable in Tarantool repo I see no reason to > avoid replacing it with another one more suitable (if we want) or > improving it. Amount of tests is really small now and it can be easily > adapted. May be we should take a look at Lua test-modules like [1] and > [2]. I'm totally for lua-TestMore. We can try to port everything to its tap, when it has been incorporated to the trunk. > > > diff --git a/etc/CMakeLists.txt b/etc/CMakeLists.txt > > index 4a4c3cd..d54fa79 100644 > > --- a/etc/CMakeLists.txt > > +++ b/etc/CMakeLists.txt > > @@ -1,6 +1,7 @@ > > # Building supplementary materials for LuaJIT. > > > > -cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) > > +# See the rationale in the root CMakeLists.txt. > > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > > Why is the minimum required version for this module/subdirectory > increased? To make it consistent project-wide, obviously. I totally don't want to check every damn shit per-CMakeLists.txt like genex support, and others, so now we can freely consider only 3.1.3 docs on cmake.org. > > > > > set(LUAJIT_PC_PREFIX ${CMAKE_INSTALL_PREFIX}) > > if(CMAKE_LIBRARY_ARCHITECTURE) > > diff --git a/test/tarantool-tests/CMakeLists.txt b/test/tarantool-tests/CMakeLists.txt > > new file mode 100644 > > index 0000000..0be4b34 > > --- /dev/null > > +++ b/test/tarantool-tests/CMakeLists.txt > > @@ -0,0 +1,92 @@ > > +# Test suite that has been moved from Tarantool repository in > > +# scope of https://github.com/tarantool/tarantool/issues/4478. > > + > > +# See the rationale in the root CMakeLists.txt. > > +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) > > + > > +find_program(PROVE prove) > > +if(NOT PROVE) > > + message(WARNING "`prove' is not found, so tarantool-tests target is not generated") > > + return() > > +endif() > > + > > +macro(BuildTestLib lib sources) > > Nit: BuildTestCLib or BuildTestLuaCLib is more verbose for me. > Feel free to ignore. Technicaly these libraries are not fully implemented via Lua C API, so I chose the first one. Diff is below: ================================================================================ diff --git a/test/tarantool-tests/CMakeLists.txt b/test/tarantool-tests/CMakeLists.txt index a7af807..c7a4ccc 100644 --- a/test/tarantool-tests/CMakeLists.txt +++ b/test/tarantool-tests/CMakeLists.txt @@ -10,7 +10,7 @@ if(NOT PROVE) return() endif() -macro(BuildTestLib lib sources) +macro(BuildTestCLib lib sources) add_library(${lib} SHARED EXCLUDE_FROM_ALL ${sources}) target_include_directories(${lib} PRIVATE ${LUAJIT_SOURCE_DIR} diff --git a/test/tarantool-tests/gh-4427-ffi-sandwich/CMakeLists.txt b/test/tarantool-tests/gh-4427-ffi-sandwich/CMakeLists.txt index 5515567..f2be549 100644 --- a/test/tarantool-tests/gh-4427-ffi-sandwich/CMakeLists.txt +++ b/test/tarantool-tests/gh-4427-ffi-sandwich/CMakeLists.txt @@ -1 +1 @@ -BuildTestLib(libsandwich libsandwich.c) +BuildTestCLib(libsandwich libsandwich.c) diff --git a/test/tarantool-tests/lj-flush-on-trace/CMakeLists.txt b/test/tarantool-tests/lj-flush-on-trace/CMakeLists.txt index 91a18a6..16f1aa8 100644 --- a/test/tarantool-tests/lj-flush-on-trace/CMakeLists.txt +++ b/test/tarantool-tests/lj-flush-on-trace/CMakeLists.txt @@ -1 +1 @@ -BuildTestLib(libflush libflush.c) +BuildTestCLib(libflush libflush.c) diff --git a/test/tarantool-tests/misclib-getmetrics-capi/CMakeLists.txt b/test/tarantool-tests/misclib-getmetrics-capi/CMakeLists.txt index cff0096..60eb5bb 100644 --- a/test/tarantool-tests/misclib-getmetrics-capi/CMakeLists.txt +++ b/test/tarantool-tests/misclib-getmetrics-capi/CMakeLists.txt @@ -1 +1 @@ -BuildTestLib(testgetmetrics testgetmetrics.c) +BuildTestCLib(testgetmetrics testgetmetrics.c) ================================================================================ > > > + # Unfortunately, CMake is a crap and there is no other way to > > + # extend the list in parent scope but join two strings with > > + # semicolon. If one finds the normal way to make it work, feel > > + # free to reach me. > > + set(TESTLIBS "${lib};${TESTLIBS}" PARENT_SCOPE) > > + # Add the directory where the lib is built to the LUA_CPATH > > + # environment variable, so interpreter can find and load it. > > Typo: s/interpreter/the interpreter/ Changed to LuaJIT. > > > +# LUA_CPATH and LD_LIBRARY_PATH variables and also TESTLIBS list > > +# with dependecies are set in scope of BuildTestLib macro. > > +add_custom_command( > > + COMMENT "Running Tarantool tests" > > + OUTPUT tests.ok > > + DEPENDS ${LUAJIT_TEST_BINARY} ${TESTLIBS} ${TEST_DEPS} > > + COMMAND > > + env > > + LUA_PATH="${LUA_PATH}\;\;" > > + LUA_CPATH="${LUA_CPATH}\;\;" > > + LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" > > + ${PROVE} ${CMAKE_CURRENT_SOURCE_DIR} > > + --exec ${LUAJIT_TEST_BINARY} > > + --ext ${LUA_TEST_SUFFIX} > > + --failures --shuffle > > See nothing bad to add `--verbose` option here. It's better to see the > name of the single test, not the test file only. No. It spoils the output too much. I propose the following change: ================================================================================ diff --git a/test/tarantool-tests/CMakeLists.txt b/test/tarantool-tests/CMakeLists.txt index c7a4ccc..9c9dabf 100644 --- a/test/tarantool-tests/CMakeLists.txt +++ b/test/tarantool-tests/CMakeLists.txt @@ -68,8 +68,13 @@ set(LUA_PATH "${CMAKE_CURRENT_SOURCE_DIR}/?.lua\;${PROJECT_SOURCE_DIR}/tools/?.lua" ) set(LUA_TEST_SUFFIX .test.lua) +set(LUA_TEST_FLAGS --failures --shuffle) file(GLOB TEST_DEPS ${CMAKE_CURRENT_SOURCE_DIR}/*${LUA_TEST_SUFFIX}) +if(CMAKE_VERBOSE_MAKEFILE) + list(APPEND LUA_TEST_FLAGS --verbose) +endif() + # LUA_CPATH and LD_LIBRARY_PATH variables and also TESTLIBS list # with dependecies are set in scope of BuildTestLib macro. add_custom_command( @@ -84,7 +89,7 @@ add_custom_command( ${PROVE} ${CMAKE_CURRENT_SOURCE_DIR} --exec ${LUAJIT_TEST_BINARY} --ext ${LUA_TEST_SUFFIX} - --failures --shuffle + ${LUA_TEST_FLAGS} && touch tests.ok WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) ================================================================================ If you're OK with it, I'll apply these changes to the branch. > > > + && touch tests.ok > > + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} > > +) > > + > > +add_custom_target(tarantool-tests DEPENDS tests.ok) > > diff --git a/test/gh-3196-incorrect-string-length.test.lua b/test/tarantool-tests/gh-3196-incorrect-string-length.test.lua > > similarity index 94% > > rename from test/gh-3196-incorrect-string-length.test.lua > > rename to test/tarantool-tests/gh-3196-incorrect-string-length.test.lua > > index f135de7..edb728f 100755 > > --- a/test/gh-3196-incorrect-string-length.test.lua > > +++ b/test/tarantool-tests/gh-3196-incorrect-string-length.test.lua > > @@ -1,4 +1,4 @@ > > -#!/usr/bin/env tarantool > > +#!/usr/bin/env luajit > > I think, that this line unnecessary, as much as an executable format of > the file. Same thoughts about all test files below. Removed all shebangs and x permissions. > > > > > -- Miscellaneous test for LuaJIT bugs > > local tap = require('tap') > > diff --git a/test/gh-4427-ffi-sandwich.test.lua b/test/tarantool-tests/gh-4427-ffi-sandwich.test.lua > > similarity index 70% > > rename from test/gh-4427-ffi-sandwich.test.lua > > rename to test/tarantool-tests/gh-4427-ffi-sandwich.test.lua > > index 9d5e50f..e9771e8 100755 > > --- a/test/gh-4427-ffi-sandwich.test.lua > > +++ b/test/tarantool-tests/gh-4427-ffi-sandwich.test.lua > > @@ -1,22 +1,30 @@ > > -#!/usr/bin/env tarantool > > +#!/usr/bin/env luajit > > > > if #arg == 0 then > > - require('utils').selfrun(arg, { > > + > > + local utils = require('utils') > > + > > + -- Disabled on *BSD due to #4819. > > + utils.skipcond(jit.os == 'BSD', 'Disabled due to #4819') > > + > > + utils.selfrun(arg, { > > { > > - arg = { > > + arg = { > > This alignment is beauty, but unnecessary, please drop these changes. > Same remarks for the changes below. Removed. > > > 1, -- hotloop (arg[1]) > > Side note: this may be not arg[1] or so on for Tarantool or pure LuaJIT > with additional flags. But good for now, so whatever. > > > 1, -- trigger (arg[2]) > > }, > > - res = tostring(3), -- hotloop + trigger + 1 > > - msg = 'Trace is aborted', > > + test = 'is', > > + res = tostring(3), -- hotloop + trigger + 1 > > + msg = 'Trace is aborted', > > }, > > { > > - arg = { > > + arg = { > > 1, -- hotloop (arg[1]) > > 2, -- trigger (arg[2]) > > }, > > - res = 'Lua VM re-entrancy is detected while executing the trace', > > - msg = 'Trace is recorded', > > + test = 'like', > > What does it mean? The type of test used for verification: either pattern matching ('like') or exact match ('is'). > > > + res = 'Lua VM re%-entrancy is detected while executing the trace', > > This % is redundant. Any proof for it? > > > + msg = 'Trace is recorded', > > }, > > }) > > end > > diff --git a/test/misclib-getmetrics-lapi.test.lua b/test/tarantool-tests/misclib-getmetrics-lapi.test.lua > > similarity index 98% > > rename from test/misclib-getmetrics-lapi.test.lua > > rename to test/tarantool-tests/misclib-getmetrics-lapi.test.lua > > index 3b3d1f8..959293d 100755 > > --- a/test/misclib-getmetrics-lapi.test.lua > > +++ b/test/tarantool-tests/misclib-getmetrics-lapi.test.lua > > @@ -49,7 +52,10 @@ test:test("gc-allocated-freed", function(subtest) > > subtest:plan(1) > > > > -- Force up garbage collect all dead objects. > > Please, add comments about testing as a third party for the Tarantool > and GC finalizers to describe this change. Well, isn't everything described above? We are forcing GC to collect *all* dead objects. In other words until collectgarbage("count") return value changes. > > > - collectgarbage("collect") > > + repeat > > + local count = collectgarbage("count") > > + collectgarbage("collect") > > + until collectgarbage("count") == count > > > > -- Bump getmetrics table and string keys allocation. > > local old_metrics = misc.getmetrics() > > diff --git a/test/tarantool-tests/tap.lua b/test/tarantool-tests/tap.lua > > Side note: firstly I thought that will be clashing with tap > inside other suites, but these conflicts will be easily resolved by > LUA_PATH. > > > new file mode 100644 > > index 0000000..fd03132 > > --- /dev/null > > +++ b/test/tarantool-tests/tap.lua > > Feel free to stop me from refactoring anytime, but I try to dump all my > thoughts about this module now to be referred later. > > Side note: It's a pity that there is no such module as Perl's Test::Deep [3] > in Lua (or at least I haven't seen one). > > > @@ -0,0 +1,306 @@ > > +--- tap.lua internal file. > > +--- > > +--- The Test Anything Protocol vesion 13 producer. > > +--- > > + > > +-- Initializer FFI for check. > > This comment is misleading a bit, NULL usage is important too. Removed. > > > +local ffi = require('ffi') > > +local NULL = ffi.new('void *') > > Nit: What if LuaJIT is built without FFI? Lol, these tests do not respect such configuration. I have the following change to support testing with FFI disabled, but most of the tests are simply skipped. ================================================================================ diff --git a/test/tarantool-tests/gh-4427-ffi-sandwich.test.lua b/test/tarantool-tests/gh-4427-ffi-sandwich.test.lua index 149bd9a..17b4852 100644 --- a/test/tarantool-tests/gh-4427-ffi-sandwich.test.lua +++ b/test/tarantool-tests/gh-4427-ffi-sandwich.test.lua @@ -5,6 +5,9 @@ if #arg == 0 then -- Disabled on *BSD due to #4819. utils.skipcond(jit.os == 'BSD', 'Disabled due to #4819') + utils.skipcond(not pcall(require, 'ffi'), + 'Disabled due to the lack of FFI support') + utils.selfrun(arg, { { arg = { diff --git a/test/tarantool-tests/lj-494-table-chain-infinite-loop.test.lua b/test/tarantool-tests/lj-494-table-chain-infinite-loop.test.lua index 9c04ef6..f478516 100644 --- a/test/tarantool-tests/lj-494-table-chain-infinite-loop.test.lua +++ b/test/tarantool-tests/lj-494-table-chain-infinite-loop.test.lua @@ -1,5 +1,8 @@ #!/usr/bin/env luajit +require('utils').skipcond(not pcall(require, 'ffi'), + 'Disabled due to the lack of FFI support') + local tap = require('tap') local test = tap.test("lj-494-table-chain-infinite-loop") diff --git a/test/tarantool-tests/lj-524-fold-conv-respect-src-irt.test.lua b/test/tarantool-tests/lj-524-fold-conv-respect-src-irt.test.lua index cd0f0f0..adce712 100644 --- a/test/tarantool-tests/lj-524-fold-conv-respect-src-irt.test.lua +++ b/test/tarantool-tests/lj-524-fold-conv-respect-src-irt.test.lua @@ -1,3 +1,5 @@ +require('utils').skipcond(not pcall(require, 'ffi'), + 'Disabled due to the lack of FFI support') local tap = require('tap') local ffi = require('ffi') diff --git a/test/tarantool-tests/lj-flush-on-trace.test.lua b/test/tarantool-tests/lj-flush-on-trace.test.lua index 46fee53..4c665f2 100644 --- a/test/tarantool-tests/lj-flush-on-trace.test.lua +++ b/test/tarantool-tests/lj-flush-on-trace.test.lua @@ -5,6 +5,9 @@ if #arg == 0 then -- Disabled on *BSD due to #4819. utils.skipcond(jit.os == 'BSD', 'Disabled due to #4819') + utils.skipcond(not pcall(require, 'ffi'), + 'Disabled due to the lack of FFI support') + utils.selfrun(arg, { { arg = { diff --git a/test/tarantool-tests/misclib-getmetrics-capi.test.lua b/test/tarantool-tests/misclib-getmetrics-capi.test.lua index ef93597..785b2c6 100644 --- a/test/tarantool-tests/misclib-getmetrics-capi.test.lua +++ b/test/tarantool-tests/misclib-getmetrics-capi.test.lua @@ -23,45 +23,49 @@ test:ok(testgetmetrics.base()) test:ok(testgetmetrics.gc_allocated_freed()) test:ok(testgetmetrics.gc_steps()) -test:ok(testgetmetrics.objcount(function(iterations) - local ffi = require("ffi") - - jit.opt.start(0) - - local placeholder = { - str = {}, - tab = {}, - udata = {}, - cdata = {}, - } - - -- Separate objects creations to separate jit traces. - for _ = 1, iterations do - table.insert(placeholder.str, tostring(_)) - end - - for _ = 1, iterations do - table.insert(placeholder.tab, {_}) - end - - for _ = 1, iterations do - table.insert(placeholder.udata, newproxy()) - end - - for _ = 1, iterations do - -- Check counting of VLA/VLS/aligned cdata. - table.insert(placeholder.cdata, ffi.new("char[?]", 4)) - end - - for _ = 1, iterations do - -- Check counting of non-VLA/VLS/aligned cdata. - table.insert(placeholder.cdata, ffi.new("uint64_t", _)) - end - - placeholder = nil -- luacheck: no unused - -- Restore default jit settings. - jit.opt.start(unpack(jit_opt_default)) -end)) +if pcall(require, "ffi") then + test:ok(testgetmetrics.objcount(function(iterations) + local ffi = require("ffi") + + jit.opt.start(0) + + local placeholder = { + str = {}, + tab = {}, + udata = {}, + cdata = {}, + } + + -- Separate objects creations to separate jit traces. + for _ = 1, iterations do + table.insert(placeholder.str, tostring(_)) + end + + for _ = 1, iterations do + table.insert(placeholder.tab, {_}) + end + + for _ = 1, iterations do + table.insert(placeholder.udata, newproxy()) + end + + for _ = 1, iterations do + -- Check counting of VLA/VLS/aligned cdata. + table.insert(placeholder.cdata, ffi.new("char[?]", 4)) + end + + for _ = 1, iterations do + -- Check counting of non-VLA/VLS/aligned cdata. + table.insert(placeholder.cdata, ffi.new("uint64_t", _)) + end + + placeholder = nil -- luacheck: no unused + -- Restore default jit settings. + jit.opt.start(unpack(jit_opt_default)) + end)) +else + test:skip('Disabled due to the lack of FFI support') +end -- Compiled loop with a direct exit to the interpreter. test:ok(testgetmetrics.snap_restores(function() diff --git a/test/tarantool-tests/misclib-getmetrics-lapi.test.lua b/test/tarantool-tests/misclib-getmetrics-lapi.test.lua index a005781..faffe5c 100644 --- a/test/tarantool-tests/misclib-getmetrics-lapi.test.lua +++ b/test/tarantool-tests/misclib-getmetrics-lapi.test.lua @@ -175,69 +175,73 @@ test:test("gc-steps", function(subtest) subtest:is(newm.gc_steps_finalize, 0) end) -test:test("objcount", function(subtest) - subtest:plan(4) - local ffi = require("ffi") +if pcall(require, "ffi") then + test:test("objcount", function(subtest) + subtest:plan(4) + local ffi = require("ffi") - jit.opt.start(0) + jit.opt.start(0) - -- Remove all dead objects. - collectgarbage("collect") - - local old_metrics = misc.getmetrics() - - local placeholder = { - str = {}, - tab = {}, - udata = {}, - cdata = {}, - } + -- Remove all dead objects. + collectgarbage("collect") - -- Separate objects creations to separate jit traces. - for _ = 1, 1000 do - table.insert(placeholder.str, tostring(_)) - end + local old_metrics = misc.getmetrics() - for _ = 1, 1000 do - table.insert(placeholder.tab, {_}) - end + local placeholder = { + str = {}, + tab = {}, + udata = {}, + cdata = {}, + } - for _ = 1, 1000 do - table.insert(placeholder.udata, newproxy()) - end + -- Separate objects creations to separate jit traces. + for _ = 1, 1000 do + table.insert(placeholder.str, tostring(_)) + end - for _ = 1, 1000 do - -- Check counting of VLA/VLS/aligned cdata. - table.insert(placeholder.cdata, ffi.new("char[?]", 4)) - end + for _ = 1, 1000 do + table.insert(placeholder.tab, {_}) + end - for _ = 1, 1000 do - -- Check counting of non-VLA/VLS/aligned cdata. - table.insert(placeholder.cdata, ffi.new("uint64_t", _)) - end + for _ = 1, 1000 do + table.insert(placeholder.udata, newproxy()) + end - placeholder = nil -- luacheck: no unused - collectgarbage("collect") - local new_metrics = misc.getmetrics() + for _ = 1, 1000 do + -- Check counting of VLA/VLS/aligned cdata. + table.insert(placeholder.cdata, ffi.new("char[?]", 4)) + end - -- Check that amount of objects not increased. - subtest:is(new_metrics.gc_strnum, old_metrics.gc_strnum, - "strnum don't change") - -- When we call getmetrics, we create table for metrics first. - -- So, when we save old_metrics there are x + 1 tables, - -- when we save new_metrics there are x + 2 tables, because - -- old table hasn't been collected yet (it is still - -- reachable). - subtest:is(new_metrics.gc_tabnum - old_metrics.gc_tabnum, 1, - "tabnum don't change") - subtest:is(new_metrics.gc_udatanum, old_metrics.gc_udatanum, - "udatanum don't change") - subtest:is(new_metrics.gc_cdatanum, old_metrics.gc_cdatanum, - "cdatanum don't change") + for _ = 1, 1000 do + -- Check counting of non-VLA/VLS/aligned cdata. + table.insert(placeholder.cdata, ffi.new("uint64_t", _)) + end - -- Restore default jit settings. - jit.opt.start(unpack(jit_opt_default)) -end) + placeholder = nil -- luacheck: no unused + collectgarbage("collect") + local new_metrics = misc.getmetrics() + + -- Check that amount of objects not increased. + subtest:is(new_metrics.gc_strnum, old_metrics.gc_strnum, + "strnum don't change") + -- When we call getmetrics, we create table for metrics first. + -- So, when we save old_metrics there are x + 1 tables, + -- when we save new_metrics there are x + 2 tables, because + -- old table hasn't been collected yet (it is still + -- reachable). + subtest:is(new_metrics.gc_tabnum - old_metrics.gc_tabnum, 1, + "tabnum don't change") + subtest:is(new_metrics.gc_udatanum, old_metrics.gc_udatanum, + "udatanum don't change") + subtest:is(new_metrics.gc_cdatanum, old_metrics.gc_cdatanum, + "cdatanum don't change") + + -- Restore default jit settings. + jit.opt.start(unpack(jit_opt_default)) + end) +else + test:skip('Disabled due to the lack of FFI support') +end test:test("snap-restores-direct-loop", function(subtest) -- Compiled loop with a direct exit to the interpreter. diff --git a/test/tarantool-tests/misclib-memprof-lapi.test.lua b/test/tarantool-tests/misclib-memprof-lapi.test.lua index 7bfcb4d..f05d7e6 100644 --- a/test/tarantool-tests/misclib-memprof-lapi.test.lua +++ b/test/tarantool-tests/misclib-memprof-lapi.test.lua @@ -1,3 +1,8 @@ +-- XXX: utils.bufread unconditionally loads FFI, so the test can't +-- proceed if FFI support is not enabled. +require('utils').skipcond(not pcall(require, 'ffi'), + 'Disabled due to the lack of FFI support') + local tap = require("tap") local test = tap.test("misc-memprof-lapi") diff --git a/test/tarantool-tests/or-232-unsink-64-kptr.test.lua b/test/tarantool-tests/or-232-unsink-64-kptr.test.lua index fc8acaa..b4e0778 100644 --- a/test/tarantool-tests/or-232-unsink-64-kptr.test.lua +++ b/test/tarantool-tests/or-232-unsink-64-kptr.test.lua @@ -1,3 +1,6 @@ +require('utils').skipcond(not pcall(require, 'ffi'), + 'Disabled due to the lack of FFI support') + local tap = require('tap') local test = tap.test("or-232-unsink-64-kptr") diff --git a/test/tarantool-tests/tap.lua b/test/tarantool-tests/tap.lua index f0730c0..46e3bd1 100644 --- a/test/tarantool-tests/tap.lua +++ b/test/tarantool-tests/tap.lua @@ -4,8 +4,8 @@ --- -- Initializer FFI for check. -local ffi = require('ffi') -local NULL = ffi.new('void *') +local hasffi, ffi = pcall(require, 'ffi') +local NULL = hasffi and ffi.new('void *') local function indent(chars) return (' '):rep(chars) @@ -204,6 +204,9 @@ end local function iscdata(test, v, ctype, message, extra) extra = extra or {} + if not hasffi then + return fail(test, message, extra) + end extra.expected = ffi.typeof(ctype) if type(v) ~= 'cdata' then extra.got = type(v) ================================================================================ BTW, nothing works also if LuaJIT is build with JIT support disabled. Furthermore, I believe LuaJIT suite also doesn't fit to this particular configuration. I propose to adjust the tests in scope of another issue, if you want. > > > > + level = level or 3 > > Why 3? Please add the comment about this here. > Also, please mention about LuaJIT behaviour here (traceback not > reporting tail call) -- that's why traceback is one and the same for > `ok()` and `fail()` functions. Added the following comment: ================================================================================ diff --git a/test/tarantool-tests/tap.lua b/test/tarantool-tests/tap.lua index 29af3b9..41e918c 100644 --- a/test/tarantool-tests/tap.lua +++ b/test/tarantool-tests/tap.lua @@ -15,6 +15,14 @@ end local function traceback(level) local trace = {} + -- The default level is 3 since at this point you have the + -- following frame layout + -- frame #0: (its call is below) + -- frame #1: (this function) + -- frame #2: (the "dominator" function for all assertions) + -- XXX: all exported assertions call function using tail + -- call (i.e. "return ok(...)"), so frame #3 contains the + -- assertion function used in the test chunk. level = level or 3 while true do local info = debug.getinfo(level, "nSl") ================================================================================ > > > + table.insert(trace, { > > + source = info.source, > > + src = info.short_src, > > + line = info.linedefined or 0, > > + what = info.what, > > + name = info.name, > > + namewhat = info.namewhat, > > + filename = info.source:sub(1, 1) == '@' and info.source:sub(2) or 'eval', > > What does 'eval' mean? AFAICS, the code executed via -e flag: in that case source is the line passed via this flag. > > > +local function ok(test, cond, message, extra) > > + test.total = test.total + 1 > > + if cond then > > + io.write(indent(4 * test.level), ('ok - %s\n'):format(message)) > > + return true > > + end > > + > > + test.failed = test.failed + 1 > > + io.write(indent(4 * test.level), ('not ok - %s\n'):format(message)) > > Nit: 4 * test.level repeated several times. May be encapsulated inside > `local cur_level` variable. > Feel free to ignore. I reimplemented function a bit. The changes are below: ================================================================================ diff --git a/test/tarantool-tests/tap.lua b/test/tarantool-tests/tap.lua index 3fe6910..41e918c 100644 --- a/test/tarantool-tests/tap.lua +++ b/test/tarantool-tests/tap.lua @@ -7,8 +7,10 @@ local ffi = require("ffi") local NULL = ffi.new("void *") -local function indent(chars) - return (" "):rep(chars) +local function indent(level, size) + -- Use the default indent size if none is specified. + size = tonumber(size) or 4 + return (" "):rep(level * size) end local function traceback(level) @@ -42,22 +44,23 @@ local function traceback(level) end local function diag(test, fmt, ...) - io.write(indent(4 * test.level), ("# %s\n"):format(fmt:format(...))) + io.write(indent(test.level), ("# %s\n"):format(fmt:format(...))) end local function ok(test, cond, message, extra) test.total = test.total + 1 if cond then - io.write(indent(4 * test.level), ("ok - %s\n"):format(message)) + io.write(indent(test.level), ("ok - %s\n"):format(message)) return true end test.failed = test.failed + 1 - io.write(indent(4 * test.level), ("not ok - %s\n"):format(message)) + io.write(indent(test.level), ("not ok - %s\n"):format(message)) -- Dump extra contents added in outer space. for key, value in pairs(extra or {}) do - io.write(indent(2 + 4 * test.level), ("%s:\t%s\n"):format(key, value)) + -- XXX: Use "half indent" to dump fields. + io.write(indent(test.level + 0.5), ("%s:\t%s\n"):format(key, value)) end if not test.trace then @@ -65,12 +68,13 @@ local function ok(test, cond, message, extra) end local trace = traceback() - local tindent = indent(4 + 4 * test.level) + local tindent = indent(test.level + 1) io.write(tindent, ("filename:\t%s\n"):format(trace[#trace].filename)) io.write(tindent, ("line:\t%s\n"):format(trace[#trace].line)) for frameno, frame in ipairs(trace) do io.write(tindent, ("frame #%d\n"):format(frameno)) - local findent = indent(2) .. tindent + -- XXX: Use "half indent" to dump fiels. + local findent = indent(0.5) .. tindent for key, value in pairs(frame) do io.write(findent, ("%s:\t%s\n"):format(key, value)) end @@ -257,7 +261,7 @@ end local function plan(test, planned) test.planned = planned - io.write(indent(4 * test.level), ("1..%d\n"):format(planned)) + io.write(indent(test.level), ("1..%d\n"):format(planned)) end local function check(test) ================================================================================ > > > > + return false > > + end > > + > > + local trace = traceback() > > Nit: Looks like this chunk can be separated inside one function > `dump_traceback()` back or whatever. > Feel free to ignore. Don't get this nit. > > > + local tindent = indent(4 + 4 * test.level) > > + io.write(tindent, ('filename:\t%s\n'):format(trace[#trace].filename)) > > + io.write(tindent, ('line:\t%s\n'):format(trace[#trace].line)) > > + for frameno, frame in ipairs(trace) do > > + io.write(tindent, ('frame #%d\n'):format(frameno)) > > Nit: Looks inconsistent with other output. > > | io.write(tindent, ('frameno: #%d\n'):format(frameno)) > > hits better, in my opinion. > > Looks like it will be good to add the function that does something like: You missed there is a space instead of the tab in the output above. This is done intentionally. > > | io.write(indent, ('%s:\t%s\n'):format(key, value)) > > Feel free to ignore. Ignoring. > > > + local findent = indent(2) .. tindent > > Nit: s/ .. /../ > Here and below. We have already discussed it: this is a binary op, so it should be wrapped with the spaces like other binary ops. You argument "this is how it is used in LuaJIT sources" doesn't work here, since concat is wrapped with spaces in almost all test files (except ones introduced by you). Ignoring. > > > > +local function cmpdeeply(got, expected, extra) > > + if type(expected) == 'number' or type(got) == 'number' then > > + extra.got = got > > + extra.expected = expected > > + -- Handle NaN. > > + if got ~= got and expected ~= expected then > > + return true > > + end > > + return got == expected > > + end > > + > > + if ffi.istype('bool', got) then got = (got == 1) end > > + if ffi.istype('bool', expected) then expected = (expected == 1) end > > + > > + if extra.strict and type(got) ~= type(expected) then > > + extra.got = type(got) > > + extra.expected = type(expected) > > + return false > > + end > > + > > + if type(got) ~= 'table' or type(expected) ~= 'table' then > > + extra.got = got > > + extra.expected = expected > > + return got == expected > > + end > > + > > + local path = extra.path or '/' > > This `path` in `extra` field looks unusable, please drop it. Why do you think so? It allows to distinguish the path with missing keys or invalid values. Anyway, I've reimplemented it a bit. ================================================================================ diff --git a/test/tarantool-tests/tap.lua b/test/tarantool-tests/tap.lua index ce563fb..a5ac31a 100644 --- a/test/tarantool-tests/tap.lua +++ b/test/tarantool-tests/tap.lua @@ -159,12 +159,12 @@ local function is_deeply(test, got, expected, message, extra) end seen[got] = true - local path = extra.path or "/" + local path = extra.path or "obj" local has = {} for k, v in pairs(got) do has[k] = true - extra.path = path .. "/" .. k + extra.path = path .. "." .. k if not cmpdeeply(v, expected[k], extra) then return false end @@ -173,6 +173,7 @@ local function is_deeply(test, got, expected, message, extra) -- Check if expected contains more keys then got. for k, v in pairs(expected) do if has[k] ~= true and (extra.strict or v ~= NULL) then + extra.path = path .. "." .. k extra.expected = "key " .. tostring(k) extra.got = "nil" return false ================================================================================ > > > + visited_keys[i] = true I believe this doesn't handle your case. This variable is introduced for checking whether there are extra keys in table. > > This is not good enough, visited keys should be cashed better: > > | tarantool> local test = tap.test("") local t1 = {1, 2, 3} t1[4] = {t1} local t2 = {1, 2, 3} t2[4] = {t2} return test:is_deeply(t1, t2), t1, t2 > | TAP version 13 > | --- > | - error: stack overflow Anyway, nice catch, thanks! Fixed this, diff is below: ================================================================================ diff --git a/test/tarantool-tests/tap.lua b/test/tarantool-tests/tap.lua index f13e1b7..44e731f 100644 --- a/test/tarantool-tests/tap.lua +++ b/test/tarantool-tests/tap.lua @@ -88,58 +88,6 @@ local function skip(test, message, extra) ok(test, true, message .. " # skip", extra) end -local function cmpdeeply(got, expected, extra) - if type(expected) == "number" or type(got) == "number" then - extra.got = got - extra.expected = expected - -- Handle NaN. - if got ~= got and expected ~= expected then - return true - end - return got == expected - end - - if ffi.istype("bool", got) then got = (got == 1) end - if ffi.istype("bool", expected) then expected = (expected == 1) end - - if extra.strict and type(got) ~= type(expected) then - extra.got = type(got) - extra.expected = type(expected) - return false - end - - if type(got) ~= "table" or type(expected) ~= "table" then - extra.got = got - extra.expected = expected - return got == expected - end - - local path = extra.path or "obj" - local visited_keys = {} - - for i, v in pairs(got) do - visited_keys[i] = true - extra.path = path .. "." .. i - if not cmpdeeply(v, expected[i], extra) then - return false - end - end - - -- Check if expected contains more keys then got. - for i, v in pairs(expected) do - if visited_keys[i] ~= true and (extra.strict or v ~= NULL) then - extra.path = path .. "." .. i - extra.expected = "key " .. tostring(i) - extra.got = "nil" - return false - end - end - - extra.path = path - - return true -end - local function like(test, got, pattern, message, extra) extra = extra or {} extra.got = got @@ -177,6 +125,66 @@ local function is_deeply(test, got, expected, message, extra) extra.got = got extra.expected = expected extra.strict = test.strict + + local seen = {} + local function cmpdeeply(got, expected, extra) --luacheck: ignore + if type(expected) == "number" or type(got) == "number" then + extra.got = got + extra.expected = expected + -- Handle NaN. + if got ~= got and expected ~= expected then + return true + end + return got == expected + end + + if ffi.istype("bool", got) then got = (got == 1) end + if ffi.istype("bool", expected) then expected = (expected == 1) end + + if extra.strict and type(got) ~= type(expected) then + extra.got = type(got) + extra.expected = type(expected) + return false + end + + if type(got) ~= "table" or type(expected) ~= "table" then + extra.got = got + extra.expected = expected + return got == expected + end + + -- Stop if tables are equal or has been already seen. + if got == expected or seen[got] then + return true + end + seen[got] = true + + local path = extra.path or "obj" + local has = {} + + for k, v in pairs(got) do + has[k] = true + extra.path = path .. "." .. k + if not cmpdeeply(v, expected[k], extra) then + return false + end + end + + -- Check if expected contains more keys then got. + for k, v in pairs(expected) do + if has[k] ~= true and (extra.strict or v ~= NULL) then + extra.path = path .. "." .. k + extra.expected = "key " .. tostring(k) + extra.got = "nil" + return false + end + end + + extra.path = path + + return true + end + return ok(test, cmpdeeply(got, expected, extra), message, extra) end ================================================================================ > > > + extra.path = path .. '/' .. i > > + if not cmpdeeply(v, expected[i], extra) then > > + return false > > + end > > + end > > + > > + -- Check if expected contains more keys then got. > > + for i, v in pairs(expected) do > > +local function is(test, got, expected, message, extra) > > + extra = extra or { } > > + extra.got = got > > + extra.expected = expected > > + local rc = (test.strict == false or type(got) == type(expected)) > > Nit: It is nice to leave the comment here to provide description why > just `==` is not enough. Also, I don't like this behaviour -- it > disrespects `eq` metamethod, and there is not mentioned in the doc [4]. In what sense this "disrespects" eq metamethod? Unfortunately, these docs are quite bad... > > > + and got == expected > > + return ok(test, rc, message, extra) > > +end > > + > > +local function isnt(test, got, unexpected, message, extra) > > + extra = extra or { } > > + extra.got = got > > + extra.unexpected = unexpected > > + local rc = (test.strict == true and type(got) ~= type(unexpected)) > > Ditto. > > > + or got ~= unexpected > > + return ok(test, rc, message, extra) > > +end > > + > > +local function is_deeply(test, got, expected, message, extra) > > + extra = extra or { } > > + extra.got = got > > + extra.expected = expected > > + extra.strict = test.strict > > + return ok(test, cmpdeeply(got, expected, extra), message, extra) > > +end > > + > > +local function isnil(test, v, message, extra) > > + return is(test, not v and v == nil and 'nil' or v, 'nil', message, extra) > > Looks like type(v) 'nil' is enough. Or please add a comment why it is > necessary. You're right, these are just artefacts. Fixed, squashed, force-pushed to the branch. Diff is below: ================================================================================ diff --git a/test/tarantool-tests/tap.lua b/test/tarantool-tests/tap.lua index 9aa823f..44e731f 100644 --- a/test/tarantool-tests/tap.lua +++ b/test/tarantool-tests/tap.lua @@ -189,7 +189,7 @@ local function is_deeply(test, got, expected, message, extra) end local function isnil(test, v, message, extra) - return is(test, not v and v == nil and "nil" or v, "nil", message, extra) + return is(test, type(v), "nil", message, extra) end local function isnumber(test, v, message, extra) ================================================================================ > > > +end > > + > > +local function isnumber(test, v, message, extra) > > + return is(test, type(v), 'number', message, extra) > > +end > > + > > +local function isstring(test, v, message, extra) > > + return is(test, type(v), 'string', message, extra) > > +end > > + > > +local function istable(test, v, message, extra) > > + return is(test, type(v), 'table', message, extra) > > +end > > + > > +local function isboolean(test, v, message, extra) > > + return is(test, type(v), 'boolean', message, extra) > > +end > > + > > +local function isfunction(test, v, message, extra) > > + return is(test, type(v), 'function', message, extra) > > +end > > + > > +local function isudata(test, v, utype, message, extra) > > Side note: Looks like it does not test type(v) equals "udata", that's Em, what?.. > inconsistent with other checkers. But changing it equals to break > backward compatibility. With what? BTW, it is already broken after the changes in . > > > + extra = extra or { } > > + extra.expected = ('userdata<%s>'):format(utype) > > + if type(v) ~= 'userdata' then ... Here it is. > > + extra.got = type(v) > > + return fail(test, message, extra) > > + end > > + extra.got = ('userdata<%s>'):format(getmetatable(v)) > > + return ok(test, getmetatable(v) == utype, message, extra) > > Does it assume that compared udata-s should have the same metatable? Otherwise there is nothing else to compare. BTW, I strongly doubt this is rather useful. > > > +end > > + > > +local function iscdata(test, v, ctype, message, extra) > > Ditto about inconsistency. Still don't get what inconsistency you're talking about. > > > + extra = extra or { } > > + extra.expected = ffi.typeof(ctype) > > + if type(v) ~= 'cdata' then > > + extra.got = type(v) > > + return fail(test, message, extra) > > + end > > + extra.got = ffi.typeof(v) > > + return ok(test, ffi.istype(ctype, v), message, extra) > > +end > > + > > +local test_mt > > Nit: Why is it declared here, not inside the `new()` function? It is used in new function as an upvalue and is filled with the methods later. If I declared it inside the function it would be either global or not visible outside of the function. > > > + > > +local function new(parent, name, fun, ...) > > Side note: Why so serious :}? > > > + local level = parent ~= nil and parent.level + 1 or 0 > > + local test = setmetatable({ > > + parent = parent, > > + name = name, > > + level = level, > > + total = 0, > > + failed = 0, > > + planned = 0, > > + trace = parent == nil and true or parent.trace, > > + strict = false, > > What does strict mean and how it can be changed? Em, in a quite simple way? | test.strict = true > I see nothing bad to copy some rationale from documentation [5] here > as comments for each field. I found no rationale there, could you please specify the places you want to clarify in a more accurate way? > > > + }, test_mt) > > + if fun == nil then > > + return test > > + end > > + test:diag('%s', test.name) > > + fun(test, ...) > > + test:diag('%s: end', test.name) > > + return test:check() > > +end > > +local function check(test) > > + if test.checked then > > + error('check called twice') > > Nit: eror_level = 2 is better here in my opinion. > Feel free to ignore. Unfortunately, nothing's changed: ================================================================================ $ luajit t.lua luajit: ./tap.lua:261: check called twice stack traceback: [C]: in function 'error' ./tap.lua:261: in function 'check' t.lua:9: in main chunk [C]: at 0x5563639c4eb0 TAP version 13 1..1 ok - nil $ git stash pop $ git diff diff --git a/test/tarantool-tests/tap.lua b/test/tarantool-tests/tap.lua index e2149a7..575e7bd 100644 --- a/test/tarantool-tests/tap.lua +++ b/test/tarantool-tests/tap.lua @@ -258,7 +258,7 @@ end local function check(test) if test.checked then - error('check called twice') + error('check called twice', 2) end test.checked = true if test.planned ~= test.total then $ luajit t.lua luajit: t.lua:9: check called twice stack traceback: [C]: in function 'error' ./tap.lua:261: in function 'check' t.lua:9: in main chunk [C]: at 0x55cea3cfceb0 TAP version 13 1..1 ok - nil ================================================================================ Please correct me if I've done something wrong. Ignoring for now. > > > + end > > + test.checked = true > > + if test.planned ~= test.total then > > + if test.parent ~= nil then > > + ok(test.parent, false, 'bad plan', { > > + planned = test.planned, > > + run = test.total, > > + }) > > + else > > + diag(test, ('bad plan: planned %d run %d') > > + :format(test.planned, test.total)) > > + end > > + elseif test.failed > 0 then > > + if test.parent ~= nil then > > + ok(test.parent, false, 'failed subtests', { > > + failed = test.failed, > > + planned = test.planned, > > + }) > > + else > > + diag(test, 'failed subtest: %d', test.failed) > > + end > > + else > > + if test.parent ~= nil then > > + ok(test.parent, true, test.name) > > + end > > + end > > Nit: looks like `if test.parent ~= nil` can be taken out for branches. > Feel free to ignore. It can, but such change doesn't worth it. Ignoring. > > > + return test.planned == test.total and test.failed == 0 > > +end > > + > > +test_mt = { > > + __index = { > > + test = new, > > + plan = plan, > > + check = check, > > + diag = diag, > > + ok = ok, > > + fail = fail, > > + skip = skip, > > + is = is, > > + isnt = isnt, > > + isnil = isnil, > > + isnumber = isnumber, > > + isstring = isstring, > > + istable = istable, > > + isboolean = isboolean, > > + isfunction = isfunction, > > + isudata = isudata, > > + iscdata = iscdata, > > + is_deeply = is_deeply, > > + like = like, > > + unlike = unlike, > > + } > > +} > > + > > +return { > > + test = function(...) > > + io.write('TAP version 13\n') > > + return new(nil, ...) > > + end > > +} > > diff --git a/test/tarantool-tests/utils.lua b/test/tarantool-tests/utils.lua > > new file mode 100644 > > index 0000000..197b138 > > --- /dev/null > > +++ b/test/tarantool-tests/utils.lua > > @@ -0,0 +1,43 @@ > > +local M = { } > > + > > +local tap = require('tap') > > + > > +function M.selfrun(arg, checks) > > + local test = tap.test(arg[0]:match('/?(.+)%.test%.lua')) > > + > > + test:plan(#checks) > > + > > + local vars = { > > + LUABIN = arg[-1], > > + SCRIPT = arg[0], > > + PATH = arg[0]:gsub('%.test%.lua', ''), > > + SUFFIX = package.cpath:match('?.(%a+);'), > > + } > > + > > + local cmd = string.gsub('LUA_PATH="/?.lua;$LUA_PATH" ' .. > > Why do you use that way instead configuration? To make the tests using to be executed as a standalone script. > > > + 'LUA_CPATH="/?.;$LUA_CPATH" ' .. > > + 'LD_LIBRARY_PATH=:$LD_LIBRARY_PATH ' .. > > + ' 2>&1