<HTML><BODY><div>Hi!</div><div>Thanks for the patch!</div><div>Please consider my comments below.</div><div> </div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div> <blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_16788968931016309467_BODY">This patch rewrites the aforementioned test with usage libtest recently</div></div></div></div></blockquote><div>Typo: s/with usage libtest/with the usage of libtest,/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>introduced. Since we still stand in need of a Lua helper script for<br>generation of traces, the original test file is reworked as a standalone<br>script, which returns the table with helper functions. Each helper<br>function is named the same as the test where it will be used. Now single<br>quotes are used according our Lua code style.</div></div></div></div></blockquote><div>Typo: s/according our/according to our/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div><br>In C part all asserts from glibc are replaced with the corresponding<br>assert_{cond} from the libtest. Now tests return `TEST_EXIT_SUCCESS` at<br>the finish. Also, stack check for the amount of return results from</div></div></div></div></blockquote><div>Typo s:/stack check/the stack check/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>helper function is slightly changed, since there is one more stack slot</div></div></div></div></blockquote><div>Typo: s/helper/the helper/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>in use (table with these functions). `snap_restores()` C function<br>duplicates 4 times for each subtest. Common helper<br>`check_snap_restores()` is used for each of them. Each error throwing is<br>replaced with `bail_out()` call.<br><br>NB: `lua_pop()` to clear the Lua stack after call should be done before</div></div></div></div></blockquote><div>Typo: s/after call/after a call/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>any possible assertion, which exit from test leaving the stack</div></div></div></div></blockquote><div>Typo: s/which exit from test/which would exit from the test/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>uncleaned.<br><br>All skipconds use macros defined in <lj_arch.h>, so it is included in<br>the test. As far as this test initializes LuaJIT VM manually, there is</div></div></div></div></blockquote><div>Typo: s/LuaJIT/the LuaJIT</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>no need to check `jit.status()` result; check `LJ_HASJIT` is enough.</div></div></div></div></blockquote><div>Typo: s/check/checking/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>Now, only JIT-related tests are skipped, when compiled without JIT.<br>Nevertheless, all tests are skipped for *BSD arches.<br><br>Also, this patch sets the new CMake variable named `LUAJIT_LIBRARY`<br>equals to `LUAJIT_LIB` in `PARENT_SCOPE` to be used in tarantool-c-tests</div></div></div></div></blockquote><div>Typo: s/equals/equal/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>linking.<br><br>Also, .c_test suffix is added to the <.gitignore>.<br><br>Part of tarantool/tarantool#7900<br>---<br> .gitignore | 1 +<br> src/CMakeLists.txt | 2 +<br> test/tarantool-c-tests/CMakeLists.txt | 32 +-<br> .../misclib-getmetrics-capi-script.lua} | 82 ++---<br> .../misclib-getmetrics-capi.test.c | 341 ++++++++++++++++++<br> test/tarantool-tests/CMakeLists.txt | 1 -<br> .../misclib-getmetrics-capi/CMakeLists.txt | 1 -<br> .../misclib-getmetrics-capi/testgetmetrics.c | 270 --------------<br> 8 files changed, 409 insertions(+), 321 deletions(-)<br> rename test/{tarantool-tests/misclib-getmetrics-capi.test.lua => tarantool-c-tests/misclib-getmetrics-capi-script.lua} (68%)<br> create mode 100644 test/tarantool-c-tests/misclib-getmetrics-capi.test.c<br> delete mode 100644 test/tarantool-tests/misclib-getmetrics-capi/CMakeLists.txt<br> delete mode 100644 test/tarantool-tests/misclib-getmetrics-capi/testgetmetrics.c<br><br>diff --git a/.gitignore b/.gitignore<br>index b7908aee..dc5ea5fc 100644<br>--- a/.gitignore<br>+++ b/.gitignore<br>@@ -24,3 +24,4 @@ install_manifest.txt<br> luajit-parse-memprof<br> luajit-parse-sysprof<br> luajit.pc<br>+*.c_test<br>diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt<br>index dffc0a4d..58d83330 100644<br>--- a/src/CMakeLists.txt<br>+++ b/src/CMakeLists.txt<br>@@ -325,6 +325,8 @@ if(NOT BUILDMODE STREQUAL "dynamic")<br>   set(LUAJIT_BIN luajit_static)<br>   set(LUAJIT_LIB libluajit_static)<br> endif()<br>+# Need for test linking, so PARENT_SCOPE option is used.</div></div></div></div></blockquote><div>Typo: s/Need for test/Needed for the test/<br>Typo: s/so PARENT_SCOPE/so the PARENT_SCOPE/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>+set(LUAJIT_LIBRARY ${LUAJIT_LIB} PARENT_SCOPE)<br> set(LIBLUAJIT_DEPS ${LIBLUAJIT_STATIC_DEPS} ${LIBLUAJIT_SHARED_DEPS})<br> <br> add_executable(${LUAJIT_BIN} EXCLUDE_FROM_ALL ${CLI_SOURCES})<br>diff --git a/test/tarantool-c-tests/CMakeLists.txt b/test/tarantool-c-tests/CMakeLists.txt<br>index 5ebea441..96beef1a 100644<br>--- a/test/tarantool-c-tests/CMakeLists.txt<br>+++ b/test/tarantool-c-tests/CMakeLists.txt<br>@@ -22,13 +22,37 @@ set_target_properties(libtest PROPERTIES<br>   LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"<br> )<br> <br>-# XXX: For now, just build libtest. The tests to be depended on<br>-# will be added at the next commit.<br>+# TARGET_C_FLAGS is required here to be sure that headers like<br>+# lj_arch.h in compiled test is consistent with the LuaJIT library</div></div></div></div></blockquote><div>Typo: s/is consistent/are consistent/</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>+# to link.<br>+AppendFlags(TESTS_C_FLAGS ${TARGET_C_FLAGS})<br>+<br>+set(CTEST_SRC_SUFFIX ".test.c")<br>+file(GLOB tests "${CMAKE_CURRENT_SOURCE_DIR}/*${CTEST_SRC_SUFFIX}")<br>+foreach(test_source ${tests})<br>+ string(REGEX REPLACE ".+/([^/]+)${CTEST_SRC_SUFFIX}" "\\1" exe ${test_source})<br>+ add_executable(${exe} EXCLUDE_FROM_ALL ${test_source})<br>+ target_include_directories(${exe} PRIVATE<br>+ ${CMAKE_CURRENT_SOURCE_DIR}<br>+ ${LUAJIT_SOURCE_DIR}<br>+ )<br>+ set_target_properties(${exe} PROPERTIES<br>+ # `__FILE__` macro may not represnt absolute path to the<br>+ # source file, depening on cmake version or<br>+ # -fmacro-prefix-map flag value.<br>+ # Use custom macro.<br>+ COMPILE_FLAGS "${TESTS_C_FLAGS} -D__ABS_FILENAME__='\"${test_source}\"'"<br>+ OUTPUT_NAME "${exe}${C_TEST_SUFFIX}"<br>+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"<br>+ )<br>+ target_link_libraries(${exe} libtest ${LUAJIT_LIBRARY})<br>+ LIST(APPEND TESTS_COMPILED ${exe})<br>+endforeach()<br>+<br> add_custom_target(tarantool-c-tests<br>- DEPENDS libluajit libtest<br>+ DEPENDS libluajit libtest ${TESTS_COMPILED}<br> )<br> <br>-# XXX: For now, run 0 tests. Just verify that libtest was build.<br> add_custom_command(TARGET tarantool-c-tests<br>   COMMENT "Running Tarantool C tests"<br>   COMMAND<br>diff --git a/test/tarantool-tests/misclib-getmetrics-capi.test.lua b/test/tarantool-c-tests/misclib-getmetrics-capi-script.lua<br>similarity index 68%<br>rename from test/tarantool-tests/misclib-getmetrics-capi.test.lua<br>rename to test/tarantool-c-tests/misclib-getmetrics-capi-script.lua<br>index 654e5545..8fab485a 100644<br>--- a/test/tarantool-tests/misclib-getmetrics-capi.test.lua<br>+++ b/test/tarantool-c-tests/misclib-getmetrics-capi-script.lua<br>@@ -1,32 +1,25 @@<br>-local tap = require('tap')<br>-local test = tap.test("clib-misc-getmetrics"):skipcond({<br>- ['Test requires JIT enabled'] = not jit.status(),<br>- ['Disabled on *BSD due to #4819'] = jit.os == 'BSD',<br>-})<br>+local ffi = require('ffi')<br> <br>-test:plan(11)<br>+-- Auxiliary script to provide Lua functions to be used in tests<br>+-- for `getmetrics()` C API inside the test<br>+-- <misclib-getmetrics-capi.test.c>.<br>+local M = {}<br> <br>-local path = arg[0]:gsub('%.test%.lua', '')<br>-local suffix = package.cpath:match('?.(%a+);')<br>-package.cpath = ('%s/?.%s;'):format(path, suffix)..package.cpath<br>+-- XXX: Max nins is limited by max IRRef, that equals to<br>+-- REF_DROP - REF_BIAS. Unfortunately, these constants are not<br>+-- provided to Lua space, so we ought to make some math:</div></div></div></div></blockquote><div>Maybe, it’s better to say `exposed` instead of `provided`. Feel free to ignore.</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>+-- * REF_DROP = 0xffff<br>+-- * REF_BIAS = 0x8000</div></div></div></div></blockquote><div>Path to file with their definition would be useful.</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>+local MAXNINS = 0xffff - 0x8000<br> <br>-local MAXNINS = require('utils').const.maxnins<br> local jit_opt_default = {<br>     3, -- level<br>- "hotloop=56",<br>- "hotexit=10",<br>- "minstitch=0",<br>+ 'hotloop=56',<br>+ 'hotexit=10',<br>+ 'minstitch=0',<br> }<br> <br>-local testgetmetrics = require("testgetmetrics")<br>-<br>-test:ok(testgetmetrics.base())<br>-test:ok(testgetmetrics.gc_allocated_freed())<br>-test:ok(testgetmetrics.gc_steps())<br>-<br>-test:ok(testgetmetrics.objcount(function(iterations)<br>- local ffi = require("ffi")<br>-<br>+M.objcount = function(iterations)<br>     jit.opt.start(0)<br> <br>     local placeholder = {<br>@@ -51,35 +44,34 @@ test:ok(testgetmetrics.objcount(function(iterations)<br> <br>     for _ = 1, iterations do<br>         -- Check counting of VLA/VLS/aligned cdata.<br>- table.insert(placeholder.cdata, ffi.new("char[?]", 4))<br>+ table.insert(placeholder.cdata, ffi.new('char[?]', 4))<br>     end<br> <br>     for _ = 1, iterations do<br>         -- Check counting of non-VLA/VLS/aligned cdata.<br>- table.insert(placeholder.cdata, ffi.new("uint64_t", _))<br>+ table.insert(placeholder.cdata, ffi.new('uint64_t', _))<br>     end<br> <br>     placeholder = nil -- luacheck: no unused<br>     -- Restore default jit settings.<br>     jit.opt.start(unpack(jit_opt_default))<br>-end))<br>+end<br> <br>-test:ok(testgetmetrics.objcount_cdata_decrement(function()<br>+M.objcount_cdata_decrement = function()<br>     -- gc_cdatanum decrement test.<br>     -- See <a href="https://github.com/tarantool/tarantool/issues/5820" target="_blank">https://github.com/tarantool/tarantool/issues/5820</a>.<br>- local ffi = require("ffi")<br>     local function nop() end<br>- ffi.gc(ffi.cast("void *", 0), nop)<br>+ ffi.gc(ffi.cast('void *', 0), nop)<br>     -- Does not collect the cdata, but resurrects the object and<br>     -- removes LJ_GC_CDATA_FIN flag.<br>     collectgarbage()<br>     -- Collects the cdata.<br>     collectgarbage()<br>-end))<br>+end<br> <br> -- Compiled loop with a direct exit to the interpreter.<br>-test:ok(testgetmetrics.snap_restores(function()<br>- jit.opt.start(0, "hotloop=1")<br>+M.snap_restores_direct_exit = function()<br>+ jit.opt.start(0, 'hotloop=1')<br> <br>     local sum = 0<br>     for i = 1, 20 do<br>@@ -91,11 +83,11 @@ test:ok(testgetmetrics.snap_restores(function()<br> <br>     -- A single snapshot restoration happened on loop finish.<br>     return 1<br>-end))<br>+end<br> <br> -- Compiled loop with a side exit which does not get compiled.<br>-test:ok(testgetmetrics.snap_restores(function()<br>- jit.opt.start(0, "hotloop=1", "hotexit=2", ("minstitch=%d"):format(MAXNINS))<br>+M.snap_restores_side_exit_not_compiled = function()<br>+ jit.opt.start(0, 'hotloop=1', 'hotexit=2', ('minstitch=%d'):format(MAXNINS))<br> <br>     local function foo(i)<br>         -- math.fmod is not yet compiled!<br>@@ -112,13 +104,13 @@ test:ok(testgetmetrics.snap_restores(function()<br> <br>     -- Side exits from the root trace could not get compiled.<br>     return 5<br>-end))<br>+end<br> <br> -- Compiled loop with a side exit which gets compiled.<br>-test:ok(testgetmetrics.snap_restores(function()<br>+M.snap_restores_side_exit_compiled = function()<br>     -- Optimization level is important here as `loop` optimization<br>     -- may unroll the loop body and insert +1 side exit.<br>- jit.opt.start(0, "hotloop=1", "hotexit=5")<br>+ jit.opt.start(0, 'hotloop=1', 'hotexit=5')<br> <br>     local function foo(i)<br>         return i <= 10 and i or tostring(i)<br>@@ -136,13 +128,13 @@ test:ok(testgetmetrics.snap_restores(function()<br>     -- and compiled<br>     -- 1 side exit on loop end<br>     return 6<br>-end))<br>+end<br> <br> -- Compiled scalar trace with a direct exit to the interpreter.<br>-test:ok(testgetmetrics.snap_restores(function()<br>+M.snap_restores_direct_exit_scalar = function()<br>     -- For calls it will be 2 * hotloop (see lj_dispatch.{c,h}<br>     -- and hotcall@vm_*.dasc).<br>- jit.opt.start(3, "hotloop=2", "hotexit=3")<br>+ jit.opt.start(3, 'hotloop=2', 'hotexit=3')<br> <br>     local function foo(i)<br>         return i <= 15 and i or tostring(i)<br>@@ -167,15 +159,15 @@ test:ok(testgetmetrics.snap_restores(function()<br>     jit.opt.start(unpack(jit_opt_default))<br> <br>     return 2<br>-end))<br>+end<br> <br>-test:ok(testgetmetrics.strhash())<br>-<br>-test:ok(testgetmetrics.tracenum_base(function()<br>+M.tracenum_base = function()<br>     local sum = 0<br>     for i = 1, 200 do<br>         sum = sum + i<br>     end<br>     -- Compiled only 1 loop as new trace.<br>     return 1<br>-end))<br>+end<br>+<br>+return M<br>diff --git a/test/tarantool-c-tests/misclib-getmetrics-capi.test.c b/test/tarantool-c-tests/misclib-getmetrics-capi.test.c<br>new file mode 100644<br>index 00000000..a1bafbe6<br>--- /dev/null<br>+++ b/test/tarantool-c-tests/misclib-getmetrics-capi.test.c<br>@@ -0,0 +1,341 @@<br>+#include "lua.h"<br>+#include "luajit.h"<br>+#include "lauxlib.h"<br>+#include "lmisclib.h"<br>+<br>+#include "test.h"<br>+#include "utils.h"<br>+<br>+/* Need for skipcond for BSD and JIT. */<br>+#include "lj_arch.h"</div></div></div></div></blockquote><div>Still don’t like the fact that we need to do that.</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>+<br>+static int base(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ struct luam_Metrics metrics;<br>+ luaM_metrics(L, &metrics);<br>+<br>+ /*<br>+ * Just check structure format, not values that fields<br>+ * contain.<br>+ */<br>+ (void)metrics.strhash_hit;<br>+ (void)metrics.strhash_miss;<br>+<br>+ (void)metrics.gc_strnum;<br>+ (void)metrics.gc_tabnum;<br>+ (void)metrics.gc_udatanum;<br>+ (void)metrics.gc_cdatanum;<br>+<br>+ (void)metrics.gc_total;<br>+ (void)metrics.gc_freed;<br>+ (void)metrics.gc_allocated;<br>+<br>+ (void)metrics.gc_steps_pause;<br>+ (void)metrics.gc_steps_propagate;<br>+ (void)metrics.gc_steps_atomic;<br>+ (void)metrics.gc_steps_sweepstring;<br>+ (void)metrics.gc_steps_sweep;<br>+ (void)metrics.gc_steps_finalize;<br>+<br>+ (void)metrics.jit_snap_restore;<br>+ (void)metrics.jit_trace_abort;<br>+ (void)metrics.jit_mcode_size;<br>+ (void)metrics.jit_trace_num;<br>+<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+static int gc_allocated_freed(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ struct luam_Metrics oldm, newm;<br>+ /* Force up garbage collect all dead objects. */<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+<br>+ luaM_metrics(L, &oldm);<br>+ /* Simple garbage generation. */<br>+ if (luaL_dostring(L, "local i = 0 for j = 1, 10 do i = i + j end"))<br>+ bail_out("failed to translate Lua code snippet");</div></div></div></div></blockquote><div>Why `bail_out` and not an assertion? Here and below.</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+ luaM_metrics(L, &newm);<br>+ assert_true(newm.gc_allocated - oldm.gc_allocated > 0);<br>+ assert_true(newm.gc_freed - oldm.gc_freed > 0);<br>+<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+static int gc_steps(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ struct luam_Metrics oldm, newm;<br>+ /*<br>+ * Some garbage has already happened before the next line,<br>+ * i.e. during frontend processing Lua test chunk.<br>+ * Let's put a full garbage collection cycle on top<br>+ * of that, and confirm that non-null values are reported<br>+ * (we are not yet interested in actual numbers):<br>+ */<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+<br>+ luaM_metrics(L, &oldm);<br>+ assert_true(oldm.gc_steps_pause > 0);<br>+ assert_true(oldm.gc_steps_propagate > 0);<br>+ assert_true(oldm.gc_steps_atomic > 0);<br>+ assert_true(oldm.gc_steps_sweepstring > 0);<br>+ assert_true(oldm.gc_steps_sweep > 0);<br>+ /* Nothing to finalize, skipped. */<br>+ assert_true(oldm.gc_steps_finalize == 0);<br>+<br>+ /*<br>+ * As long as we don't create new Lua objects<br>+ * consequent call should return the same values:<br>+ */<br>+ luaM_metrics(L, &newm);<br>+ assert_sizet_equal(newm.gc_steps_pause, oldm.gc_steps_pause);<br>+ assert_sizet_equal(newm.gc_steps_propagate, oldm.gc_steps_propagate);<br>+ assert_sizet_equal(newm.gc_steps_atomic, oldm.gc_steps_atomic);<br>+ assert_sizet_equal(newm.gc_steps_sweepstring,<br>+ oldm.gc_steps_sweepstring);<br>+ assert_sizet_equal(newm.gc_steps_sweep, oldm.gc_steps_sweep);<br>+ /* Nothing to finalize, skipped. */<br>+ assert_true(newm.gc_steps_finalize == 0);<br>+ oldm = newm;<br>+<br>+ /*<br>+ * Now the last phase: run full GC once and make sure that<br>+ * everything is being reported as expected:<br>+ */<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+ luaM_metrics(L, &newm);<br>+ assert_true(newm.gc_steps_pause - oldm.gc_steps_pause == 1);<br>+ assert_true(newm.gc_steps_propagate - oldm.gc_steps_propagate >= 1);<br>+ assert_true(newm.gc_steps_atomic - oldm.gc_steps_atomic == 1);<br>+ assert_true(newm.gc_steps_sweepstring - oldm.gc_steps_sweepstring >= 1);<br>+ assert_true(newm.gc_steps_sweep - oldm.gc_steps_sweep >= 1);<br>+ /* Nothing to finalize, skipped. */<br>+ assert_true(newm.gc_steps_finalize == 0);<br>+ oldm = newm;<br>+<br>+ /*<br>+ * Now let's run three GC cycles to ensure that<br>+ * increment was not a lucky coincidence.<br>+ */<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+ luaM_metrics(L, &newm);<br>+ assert_true(newm.gc_steps_pause - oldm.gc_steps_pause == 3);<br>+ assert_true(newm.gc_steps_propagate - oldm.gc_steps_propagate >= 3);<br>+ assert_true(newm.gc_steps_atomic - oldm.gc_steps_atomic == 3);<br>+ assert_true(newm.gc_steps_sweepstring - oldm.gc_steps_sweepstring >= 3);<br>+ assert_true(newm.gc_steps_sweep - oldm.gc_steps_sweep >= 3);<br>+ /* Nothing to finalize, skipped. */<br>+ assert_true(newm.gc_steps_finalize == 0);<br>+<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+static int objcount(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ struct luam_Metrics oldm, newm;<br>+ if (!LJ_HASJIT)<br>+ skip("Test requires JIT enabled");<br>+<br>+ utils_get_aux_lfunc(L);<br>+<br>+ /* Force up garbage collect all dead objects. */<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+<br>+ luaM_metrics(L, &oldm);<br>+ /* Generate garbage. Argument is iterations amount. */<br>+ lua_pushnumber(L, 1000);<br>+ lua_call(L, 1, 0);<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+ luaM_metrics(L, &newm);<br>+ assert_sizet_equal(newm.gc_strnum, oldm.gc_strnum);<br>+ assert_sizet_equal(newm.gc_tabnum, oldm.gc_tabnum);<br>+ assert_sizet_equal(newm.gc_udatanum, oldm.gc_udatanum);<br>+ assert_sizet_equal(newm.gc_cdatanum, oldm.gc_cdatanum);<br>+<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+static int objcount_cdata_decrement(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ /*<br>+ * cdata decrement test.<br>+ * See <a href="https://github.com/tarantool/tarantool/issues/5820" target="_blank">https://github.com/tarantool/tarantool/issues/5820</a>.<br>+ */<br>+ struct luam_Metrics oldm, newm;<br>+ utils_get_aux_lfunc(L);<br>+<br>+ /* Force up garbage collect all dead objects. */<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+<br>+ luaM_metrics(L, &oldm);<br>+ /*<br>+ * The function generates and collects cdata with<br>+ * LJ_GC_CDATA_FIN flag.<br>+ */<br>+ lua_call(L, 0, 0);<br>+ luaM_metrics(L, &newm);<br>+ assert_sizet_equal(newm.gc_cdatanum, oldm.gc_cdatanum);<br>+<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+/*<br>+ * Get function to call to generate the corresponding snapshot<br>+ * restores on top of the Lua stack. Function returns the amount<br>+ * of snapshot restorations expected.<br>+ * Clear stack after call.<br>+ */<br>+static void check_snap_restores(lua_State *L)<br>+{<br>+ struct luam_Metrics oldm, newm;<br>+ luaM_metrics(L, &oldm);<br>+ /* Generate snapshots. */<br>+ lua_call(L, 0, 1);<br>+ int n = lua_gettop(L);<br>+ /*<br>+ * The first value is the table with functions,<br>+ * the second is number of snapshot restores.<br>+ */<br>+ if (n != 2 || !lua_isnumber(L, -1))<br>+ bail_out("incorrect return value: 1 number is required");<br>+ size_t snap_restores = lua_tonumber(L, -1);<br>+ luaM_metrics(L, &newm);<br>+ /*<br>+ * Remove `snap_restores` from stack.<br>+ * Must be done before potiential assert and exit from<br>+ * the test.<br>+ */<br>+ lua_pop(L, 1);<br>+ assert_true(newm.jit_snap_restore - oldm.jit_snap_restore<br>+ == snap_restores);<br>+}<br>+<br>+static int snap_restores_direct_exit(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ if (!LJ_HASJIT)<br>+ skip("Test requires JIT enabled");<br>+ utils_get_aux_lfunc(L);<br>+ check_snap_restores(L);<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+static int snap_restores_direct_exit_scalar(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ if (!LJ_HASJIT)<br>+ skip("Test requires JIT enabled");<br>+ utils_get_aux_lfunc(L);<br>+ check_snap_restores(L);<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+static int snap_restores_side_exit_compiled(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ if (!LJ_HASJIT)<br>+ skip("Test requires JIT enabled");<br>+ utils_get_aux_lfunc(L);<br>+ check_snap_restores(L);<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+static int snap_restores_side_exit_not_compiled(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ if (!LJ_HASJIT)<br>+ skip("Test requires JIT enabled");<br>+ utils_get_aux_lfunc(L);<br>+ check_snap_restores(L);<br>+ return TEST_EXIT_SUCCESS;<br>+}</div></div></div></div></blockquote><div>Maybe we should extend the testing utility, so it is possible to join test sets like</div><div>those into a single group and skip them all at once?</div><div>It would be much easier to maintain them for sure.</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>+<br>+static int strhash(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ struct luam_Metrics oldm, newm;<br>+ lua_pushstring(L, "strhash_hit");<br>+ luaM_metrics(L, &oldm);<br>+ lua_pushstring(L, "strhash_hit");<br>+ lua_pushstring(L, "new_str");<br>+ luaM_metrics(L, &newm);<br>+ /* Remove pushed strings. */<br>+ lua_pop(L, 3);<br>+ assert_true(newm.strhash_hit - oldm.strhash_hit == 1);<br>+ assert_true(newm.strhash_miss - oldm.strhash_miss == 1);<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+static int tracenum_base(void *test_state)<br>+{<br>+ lua_State *L = test_state;<br>+ if (!LJ_HASJIT)<br>+ skip("Test requires JIT enabled");<br>+ struct luam_Metrics metrics;<br>+ utils_get_aux_lfunc(L);<br>+<br>+ luaJIT_setmode(L, 0, LUAJIT_MODE_FLUSH);<br>+ /* Force up garbage collect all dead objects. */<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+<br>+ luaM_metrics(L, &metrics);<br>+ assert_true(metrics.jit_trace_num == 0);<br>+<br>+ /* Generate traces. */<br>+ lua_call(L, 0, 1);<br>+ int n = lua_gettop(L);<br>+ /*<br>+ * The first value is the table with functions,<br>+ * the second is the amount of traces.<br>+ */<br>+ if (n != 2 || !lua_isnumber(L, -1))<br>+ bail_out("incorrect return value: 1 number is required");<br>+ size_t jit_trace_num = lua_tonumber(L, -1);<br>+ luaM_metrics(L, &metrics);<br>+ /* Remove `jit_trace_num` from Lua stack. */<br>+ lua_pop(L, 1);<br>+<br>+ assert_sizet_equal(metrics.jit_trace_num, jit_trace_num);<br>+<br>+ luaJIT_setmode(L, 0, LUAJIT_MODE_FLUSH);<br>+ /* Force up garbage collect all dead objects. */<br>+ lua_gc(L, LUA_GCCOLLECT, 0);<br>+ luaM_metrics(L, &metrics);<br>+ assert_true(metrics.jit_trace_num == 0);<br>+<br>+ return TEST_EXIT_SUCCESS;<br>+}<br>+<br>+int main(void)<br>+{<br>+ if (LUAJIT_OS == LUAJIT_OS_BSD)<br>+ skip_all("Disabled on *BSD due to #4819");</div></div></div></div></blockquote><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>+<br>+ lua_State *L = utils_lua_init();<br>+<br>+ utils_load_aux_script(L);<br>+ const struct test_unit tgroup[] = {<br>+ test_unit_new(base),<br>+ test_unit_new(gc_allocated_freed),<br>+ test_unit_new(gc_steps),<br>+ test_unit_new(objcount),<br>+ test_unit_new(objcount_cdata_decrement),<br>+ test_unit_new(snap_restores_direct_exit),<br>+ test_unit_new(snap_restores_direct_exit_scalar),<br>+ test_unit_new(snap_restores_side_exit_compiled),<br>+ test_unit_new(snap_restores_side_exit_not_compiled),<br>+ test_unit_new(strhash),<br>+ test_unit_new(tracenum_base)</div></div></div></div></blockquote><div>I think that we need to make an effort and try move all skipconds into</div><div>one place. The main functions seems like a good place for them. It</div><div>would greatly increase readabilty and maintainability.</div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;"><div><div class="js-helper js-readmsg-msg"><div><div>+ };<br>+ const int test_result = test_run_group(tgroup, L);<br>+ utils_lua_close(L);<br>+ return test_result;<br>+}<br>diff --git a/test/tarantool-tests/CMakeLists.txt b/test/tarantool-tests/CMakeLists.txt<br>index 38d6ae49..b4ce39d3 100644<br>--- a/test/tarantool-tests/CMakeLists.txt<br>+++ b/test/tarantool-tests/CMakeLists.txt<br>@@ -66,7 +66,6 @@ add_subdirectory(lj-416-xor-before-jcc)<br><snipped><br>diff --git a/test/tarantool-tests/misclib-getmetrics-capi/CMakeLists.txt b/test/tarantool-tests/misclib-getmetrics-capi/CMakeLists.txt<br>deleted file mode 100644<br>index 60eb5bbb..00000000<br>--- a/test/tarantool-tests/misclib-getmetrics-capi/CMakeLists.txt<br>+++ /dev/null<br>@@ -1 +0,0 @@<br>-BuildTestCLib(testgetmetrics testgetmetrics.c)<br>diff --git a/test/tarantool-tests/misclib-getmetrics-capi/testgetmetrics.c b/test/tarantool-tests/misclib-getmetrics-capi/testgetmetrics.c<br>deleted file mode 100644<br>index 67776338..00000000<br>--- a/test/tarantool-tests/misclib-getmetrics-capi/testgetmetrics.c<br>+++ /dev/null<br>@@ -1,270 +0,0 @@<br><snipped><br>--<br>2.34.1</div></div></div></div></blockquote><div><div>--<br>Best regards,</div><div>Maxim Kokryashkin</div></div><div> </div></div></blockquote></BODY></HTML>