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 B37797F60A; Sun, 7 Feb 2021 21:13:47 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org B37797F60A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1612721627; bh=llPyrxpOtdMsOwlCBktKAfWalRhsn4bMg9AvhnDFeEo=; h=To:Cc:References:Date:In-Reply-To:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Gt257y4Y/dQmAyBsvM/mJW7ObXGJbyph2FFPmYtQw4QVUaNYQ/Tb2GCZKDmPrpH17 CnxNgGmpx/ptQhxnBuGNvJaKJYC1X1TE1vrzn41L8Y1OjnHSX/B5bq71Wr37VJDx5G P4xKbTsCSRG4UTYesSsViqTcexmto1k6nrPmF+Qk= Received: from smtp31.i.mail.ru (smtp31.i.mail.ru [94.100.177.91]) (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 AD84B645E6 for ; Sun, 7 Feb 2021 20:20:51 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org AD84B645E6 Received: by smtp31.i.mail.ru with esmtpa (envelope-from ) id 1l8njt-0000dA-4P; Sun, 07 Feb 2021 20:20:49 +0300 To: Cyrill Gorcunov , tml Cc: Mons Anderson References: <20210205185436.638894-1-gorcunov@gmail.com> <20210205185436.638894-12-gorcunov@gmail.com> Message-ID: Date: Sun, 7 Feb 2021 18:20:48 +0100 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 MIME-Version: 1.0 In-Reply-To: <20210205185436.638894-12-gorcunov@gmail.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD953AC099BC0052A9C4647521586BE7E6324520D2A088600D8182A05F538085040799C37C0DB5119DFE705C4EF3972D1AACC94B241C3631EAFBEC6122AC70ACCBF X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE79B5CC362CEDE941CEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F790063704BED458119491218638F802B75D45FF5571747095F342E8C7A0BC55FA0FE5FCA1425B1BFD02B95D438E4464A5B89062E2BB3EB6FF327114389733CBF5DBD5E913377AFFFEAFD269A417C69337E82CC2CC7F00164DA146DAFE8445B8C89999729449624AB7ADAF37F6B57BC7E64490611E7FA7ABCAF51C92A417C69337E82CC2CC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB8D32BA5DBAC0009BE9E8FC8737B5C22490B2B0B017A97A07276E601842F6C81A12EF20D2F80756B5F7E9C4E3C761E06A776E601842F6C81A127C277FBC8AE2E8BCB722411C7CFE17E3AA81AA40904B5D9DBF02ECDB25306B2B25CBF701D1BE8734AD6D5ED66289B5278DA827A17800CE745781761687023AD67F23339F89546C5A8DF7F3B2552694A6FED454B719173D6725E5C173C3A84C307FFBFDCC3B3F35035872C767BF85DA2F004C906525384306FED454B719173D6462275124DF8B9C934F12F0C005D1A85E5BFE6E7EFDEDCD789D4C264860C145E X-B7AD71C0: AC4F5C86D027EB782CDD5689AFBDA7A24A6D60772A99906F8E1CD14B953EB46D0319F0E2CC438A19355D89D7DBCDD132 X-C1DE0DAB: 0D63561A33F958A5E83388D8F5852B08778764FA86DCE8C27B6354D828F99DDBD59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA75448CF9D3A7B2C848410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D348BF433665406F390C4710404AA79874F7458B325451BC26AF163B05A21E515A5F579932F370CB9DB1D7E09C32AA3244CE368B4C36E908A976F1C52289A06900651E887DA02A9F7BFFACE5A9C96DEB163 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojMxr0zTsJFiTj9Xsi8g8XGA== X-Mailru-Sender: 504CC1E875BF3E7D9BC0E5172ADA3110E20A360582E3622A854514933E0C6D84E9D060FE5E2D3E9507784C02288277CA03E0582D3806FB6A5317862B1921BA260ED6CFD6382C13A6112434F685709FCF0DA7A0AF5A3A8387 X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH v15 11/11] test: box/cfunc -- add cmod test 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: Vladislav Shpilevoy via Tarantool-patches Reply-To: Vladislav Shpilevoy Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" On 05.02.2021 19:54, Cyrill Gorcunov via Tarantool-patches wrote: > Note that the test is disabled for a while since we > need to update test-run first like > > | diff --git a/pretest_clean.lua b/pretest_clean.lua > | index 9b5ac9d..b0280c4 100644 > | --- a/pretest_clean.lua > | +++ b/pretest_clean.lua > | @@ -272,6 +272,7 @@ local function clean() > | package = true, > | pickle = true, > | popen = true, > | + cmod = true, > | pwd = true, > | socket = true, > | strict = true, > > ie need to enable cmod module. > > Part-of #4642 > > Signed-off-by: Cyrill Gorcunov > --- > test/box/CMakeLists.txt | 2 + > test/box/cfunc1.c | 58 +++++++ > test/box/cfunc2.c | 137 ++++++++++++++++ > test/box/cmod.result | 336 ++++++++++++++++++++++++++++++++++++++++ > test/box/cmod.test.lua | 130 ++++++++++++++++ > test/box/suite.ini | 2 +- > 6 files changed, 664 insertions(+), 1 deletion(-) > create mode 100644 test/box/cfunc1.c > create mode 100644 test/box/cfunc2.c > create mode 100644 test/box/cmod.result > create mode 100644 test/box/cmod.test.lua > > diff --git a/test/box/CMakeLists.txt b/test/box/CMakeLists.txt > index 06bfbbe9d..2afbeadc3 100644 > --- a/test/box/CMakeLists.txt > +++ b/test/box/CMakeLists.txt > @@ -3,3 +3,5 @@ build_module(function1 function1.c) > build_module(reload1 reload1.c) > build_module(reload2 reload2.c) > build_module(tuple_bench tuple_bench.c) > +build_module(cfunc1 cfunc1.c) > +build_module(cfunc2 cfunc2.c) > diff --git a/test/box/cfunc1.c b/test/box/cfunc1.c > new file mode 100644 > index 000000000..8f6d3990c > --- /dev/null > +++ b/test/box/cfunc1.c > @@ -0,0 +1,58 @@ > +#include > +#include > +#include > + > +#include "module.h" > + > +/* > + * Before the reload functions are just declared > + * and simply exit with zero. > + * > + * After the module reload we should provide real > + * functionality. > + */ > + > +int > +cfunc_nop(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + (void)ctx; > + (void)args; > + (void)args_end; > + return 0; > +} > + > +int > +cfunc_fetch_evens(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + (void)ctx; > + (void)args; > + (void)args_end; > + return 0; > +} > + > +int > +cfunc_multireturn(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + (void)ctx; > + (void)args; > + (void)args_end; > + return 0; > +} > + > +int > +cfunc_args(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + (void)ctx; > + (void)args; > + (void)args_end; > + return 0; > +} > + > +int > +cfunc_sum(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + (void)ctx; > + (void)args; > + (void)args_end; > + return 0; > +} > diff --git a/test/box/cfunc2.c b/test/box/cfunc2.c > new file mode 100644 > index 000000000..a4a871359 > --- /dev/null > +++ b/test/box/cfunc2.c > @@ -0,0 +1,137 @@ > +#include > +#include > +#include > + > +#include "module.h" > + > +/* > + * Just make sure we've been called. > + */ > +int > +cfunc_nop(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + (void)ctx; > + (void)args; > + (void)args_end; > + return 0; > +} > + > +/* > + * Fetch first N even numbers (just to make sure the order of > + * arguments is not screwed). > + */ > +int > +cfunc_fetch_evens(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + int arg_count = mp_decode_array(&args); > + if (arg_count != 1) { > + return box_error_set(__FILE__, __LINE__, ER_PROC_C, "%s", > + "invalid argument count"); > + } > + int field_count = mp_decode_array(&args); > + if (field_count < 1) { > + return box_error_set(__FILE__, __LINE__, ER_PROC_C, "%s", > + "invalid array size"); > + } > + > + /* > + * We expect even numbers sequence here. The idea is > + * to test invalid data an issue an error from inside > + * of C function. > + */ > + for (int i = 1; i <= field_count; i++) { > + int val = mp_decode_uint(&args); > + int needed = 2 * i; > + if (val != needed) { > + char res[128]; > + snprintf(res, sizeof(res), "%s %d != %d", > + "invalid argument", val, needed); > + return box_error_set(__FILE__, __LINE__, > + ER_PROC_C, "%s", res); > + } > + } > + > + return 0; > +} > + > +/* > + * Return one element array twice. > + */ > +int > +cfunc_multireturn(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + char tuple_buf[512]; > + char *d = tuple_buf; > + d = mp_encode_array(d, 1); > + d = mp_encode_uint(d, 1); > + assert(d <= tuple_buf + sizeof(tuple_buf)); > + > + box_tuple_format_t *fmt = box_tuple_format_default(); > + box_tuple_t *tuple_a = box_tuple_new(fmt, tuple_buf, d); > + if (tuple_a == NULL) > + return -1; > + int rc = box_return_tuple(ctx, tuple_a); > + if (rc == 0) > + return box_return_tuple(ctx, tuple_a); > + return rc; > +} > + > +/* > + * Encode int + string pair back. > + */ > +int > +cfunc_args(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + uint32_t arg_count = mp_decode_array(&args); > + if (arg_count != 2) { > + return box_error_set(__FILE__, __LINE__, ER_PROC_C, "%s", > + "invalid argument count"); > + } > + > + if (mp_typeof(*args) != MP_UINT) { > + return box_error_set(__FILE__, __LINE__, ER_PROC_C, "%s", > + "tuple field must be uint"); > + } > + uint32_t num = mp_decode_uint(&args); > + > + if (mp_typeof(*args) != MP_STR) { > + return box_error_set(__FILE__, __LINE__, ER_PROC_C, "%s", > + "tuple field must be string"); > + } > + const char *str = args; > + uint32_t len = mp_decode_strl(&str); > + > + char tuple_buf[512]; > + char *d = tuple_buf; > + d = mp_encode_array(d, 2); > + d = mp_encode_uint(d, num); > + d = mp_encode_str(d, str, len); > + assert(d <= tuple_buf + sizeof(tuple_buf)); > + > + box_tuple_format_t *fmt = box_tuple_format_default(); > + box_tuple_t *tuple = box_tuple_new(fmt, tuple_buf, d); > + if (tuple == NULL) > + return -1; > + > + return box_return_tuple(ctx, tuple); > +} > + > +/* > + * Sum two integers. > + */ > +int > +cfunc_sum(box_function_ctx_t *ctx, const char *args, const char *args_end) > +{ > + uint32_t arg_count = mp_decode_array(&args); > + if (arg_count != 2) { > + return box_error_set(__FILE__, __LINE__, ER_PROC_C, "%s", > + "invalid argument count"); > + } > + uint64_t a = mp_decode_uint(&args); > + uint64_t b = mp_decode_uint(&args); > + > + char res[16]; > + char *end = mp_encode_uint(res, a + b); > + box_return_mp(ctx, res, end); > + return 0; > +} > diff --git a/test/box/cmod.result b/test/box/cmod.result > new file mode 100644 > index 000000000..72d2f1d7d > --- /dev/null > +++ b/test/box/cmod.result > @@ -0,0 +1,336 @@ > +-- test-run result file version 2 > +-- > +-- gh-4642: New cmod module to be able to > +-- run C stored functions on read only nodes > +-- without requirement to register them with > +-- box.schema.func help. > +-- > +build_path = os.getenv("BUILDDIR") > + | --- > + | ... > +package.cpath = build_path..'/test/box/?.so;'..build_path..'/test/box/?.dylib;'..package.cpath > + | --- > + | ... > + > +cmod = require('cmod') > + | --- > + | ... > +fio = require('fio') > + | --- > + | ... > + > +ext = (jit.os == "OSX" and "dylib" or "so") > + | --- > + | ... > + > +cfunc_path = fio.pathjoin(build_path, "test/box/cfunc.") .. ext > + | --- > + | ... > +cfunc1_path = fio.pathjoin(build_path, "test/box/cfunc1.") .. ext > + | --- > + | ... > +cfunc2_path = fio.pathjoin(build_path, "test/box/cfunc2.") .. ext > + | --- > + | ... > + > +_ = pcall(fio.unlink(cfunc_path)) > + | --- > + | ... > +fio.symlink(cfunc1_path, cfunc_path) > + | --- > + | - true > + | ... > + > +_, err = pcall(cmod.load, 'non-such-module') > + | --- > + | ... > +assert(err ~= nil) > + | --- > + | - true > + | ... > + > +-- They all are sitting in cfunc.so. The "nop" module > +-- contains functions which are simply return nothing. > +old_module = cmod.load('cfunc') > + | --- > + | ... > +old_cfunc_nop = old_module:load('cfunc_nop') > + | --- > + | ... > +old_cfunc_fetch_evens = old_module:load('cfunc_fetch_evens') > + | --- > + | ... > +old_cfunc_multireturn = old_module:load('cfunc_multireturn') > + | --- > + | ... > +old_cfunc_args = old_module:load('cfunc_args') > + | --- > + | ... > +old_cfunc_sum = old_module:load('cfunc_sum') > + | --- > + | ... > +-- Test for error on nonexisting function. > +_, err = pcall(old_module.load, old_module, 'no-such-func') > + | --- > + | ... > +assert(err ~= nil) > + | --- > + | - true > + | ... > + > +-- Make sure they all are callable. > +old_cfunc_nop() > + | --- > + | - true > + | ... > +old_cfunc_fetch_evens() > + | --- > + | - true > + | ... > +old_cfunc_multireturn() > + | --- > + | - true > + | ... > +old_cfunc_args() > + | --- > + | - true > + | ... > +old_cfunc_sum() > + | --- > + | - true > + | ... > + > +-- Unload the module but keep old functions alive, so > +-- they keep reference to NOP module internally > +-- and still callable. > +old_module:unload() > + | --- > + | - true > + | ... > +old_cfunc_nop() > + | --- > + | - true > + | ... > +old_cfunc_fetch_evens() > + | --- > + | - true > + | ... > +old_cfunc_multireturn() > + | --- > + | - true > + | ... > +old_cfunc_args() > + | --- > + | - true > + | ... > +old_cfunc_sum() > + | --- > + | - true > + | ... > + > +-- The module is unloaded I should not be able > +-- to load new shared library. > +old_module:load('cfunc') > + | --- > + | - error: Expects function = module:load('name') but not module object passed > + | ... > +-- Neither I should be able to unload module twise. > +old_module:unload() > + | --- > + | - error: The module is already unloaded > + | ... > + > +-- Clean old functions. > +old_cfunc_nop:unload() > + | --- > + | - true > + | ... > +old_cfunc_fetch_evens:unload() > + | --- > + | - true > + | ... > +old_cfunc_multireturn:unload() > + | --- > + | - true > + | ... > +old_cfunc_args:unload() > + | --- > + | - true > + | ... > +old_cfunc_sum:unload() > + | --- > + | - true > + | ... > + > +-- And reload old module again. > +old_module = cmod.load('cfunc') > + | --- > + | ... > +assert(old_module.state == "cached") > + | --- > + | - true > + | ... > +old_cfunc_nop = old_module:load('cfunc_nop') > + | --- > + | ... > + > +-- Overwrite module with new contents. > +_ = pcall(fio.unlink(cfunc_path)) > + | --- > + | ... > +fio.symlink(cfunc2_path, cfunc_path) > + | --- > + | - true > + | ... > + > +-- Now try to load a function from old module, > +-- we should get chache invalidation but all > +-- old functions should be callable. > +new_module = cmod.load('cfunc') > + | --- > + | ... > +assert(old_module.state == "orphan") > + | --- > + | - true > + | ... > + > +-- Still all functions from old module should > +-- be callable. > +old_cfunc_nop = old_module:load('cfunc_nop') > + | --- > + | ... > +old_cfunc_fetch_evens = old_module:load('cfunc_fetch_evens') > + | --- > + | ... > +old_cfunc_multireturn = old_module:load('cfunc_multireturn') > + | --- > + | ... > +old_cfunc_args = old_module:load('cfunc_args') > + | --- > + | ... > +old_cfunc_sum = old_module:load('cfunc_sum') > + | --- > + | ... > + > +-- New module is loaded, lets lookup for updated symbols. > +new_cfunc_nop = new_module:load('cfunc_nop') > + | --- > + | ... > +new_cfunc_fetch_evens = new_module:load('cfunc_fetch_evens') > + | --- > + | ... > +new_cfunc_multireturn = new_module:load('cfunc_multireturn') > + | --- > + | ... > +new_cfunc_args = new_module:load('cfunc_args') > + | --- > + | ... > +new_cfunc_sum = new_module:load('cfunc_sum') > + | --- > + | ... > + > +-- Call old functions. > +old_cfunc_nop() > + | --- > + | - true > + | ... > +old_cfunc_fetch_evens() > + | --- > + | - true > + | ... > +old_cfunc_multireturn() > + | --- > + | - true > + | ... > +old_cfunc_args() > + | --- > + | - true > + | ... > +old_cfunc_sum() > + | --- > + | - true > + | ... > + > +-- And newly loaded ones. > +new_cfunc_nop() > + | --- > + | - true > + | ... > +new_cfunc_multireturn() > + | --- > + | - true > + | ... > +new_cfunc_fetch_evens({2,4,6}) > + | --- > + | - true > + | ... > +new_cfunc_fetch_evens({1,2,3}) -- error *. Why error? The same a few lines below. > + | --- > + | - true > + | ... > +new_cfunc_args(1, "hello") > + | --- > + | - true > + | ... > +new_cfunc_sum(1) -- error > + | --- > + | - true > + | ... > +new_cfunc_sum(1,2) > + | --- > + | - true > + | ... > + > +-- Cleanup old module's functions. > +old_cfunc_nop:unload() > + | --- > + | - true > + | ... > +old_cfunc_fetch_evens:unload() > + | --- > + | - true > + | ... > +old_cfunc_multireturn:unload() > + | --- > + | - true > + | ... > +old_cfunc_args:unload() > + | --- > + | - true > + | ... > +old_cfunc_sum:unload() > + | --- > + | - true > + | ... > + > +-- Cleanup new module data. > +new_cfunc_nop:unload() > + | --- > + | - true > + | ... > +new_cfunc_multireturn:unload() > + | --- > + | - true > + | ... > +new_cfunc_fetch_evens:unload() > + | --- > + | - true > + | ... > +new_cfunc_args:unload() > + | --- > + | - true > + | ... > +new_cfunc_sum:unload() > + | --- > + | - true > + | ... > +new_module:unload() > + | --- > + | - true > + | ... > + > +-- > +-- Cleanup the generated symlink > +_ = pcall(fio.unlink(cfunc_path)) > + | --- > + | ... > diff --git a/test/box/cmod.test.lua b/test/box/cmod.test.lua > new file mode 100644 > index 000000000..4d8291651 > --- /dev/null > +++ b/test/box/cmod.test.lua > @@ -0,0 +1,130 @@ > +-- > +-- gh-4642: New cmod module to be able to > +-- run C stored functions on read only nodes > +-- without requirement to register them with > +-- box.schema.func help. > +-- > +build_path = os.getenv("BUILDDIR") > +package.cpath = build_path..'/test/box/?.so;'..build_path..'/test/box/?.dylib;'..package.cpath > + > +cmod = require('cmod') > +fio = require('fio') > + > +ext = (jit.os == "OSX" and "dylib" or "so") > + > +cfunc_path = fio.pathjoin(build_path, "test/box/cfunc.") .. ext > +cfunc1_path = fio.pathjoin(build_path, "test/box/cfunc1.") .. ext > +cfunc2_path = fio.pathjoin(build_path, "test/box/cfunc2.") .. ext > + > +_ = pcall(fio.unlink(cfunc_path)) > +fio.symlink(cfunc1_path, cfunc_path) > + > +_, err = pcall(cmod.load, 'non-such-module') > +assert(err ~= nil) > + > +-- They all are sitting in cfunc.so. The "nop" module > +-- contains functions which are simply return nothing. > +old_module = cmod.load('cfunc') > +old_cfunc_nop = old_module:load('cfunc_nop') > +old_cfunc_fetch_evens = old_module:load('cfunc_fetch_evens') > +old_cfunc_multireturn = old_module:load('cfunc_multireturn') > +old_cfunc_args = old_module:load('cfunc_args') > +old_cfunc_sum = old_module:load('cfunc_sum') > +-- Test for error on nonexisting function. > +_, err = pcall(old_module.load, old_module, 'no-such-func') > +assert(err ~= nil) > + > +-- Make sure they all are callable. > +old_cfunc_nop() > +old_cfunc_fetch_evens() > +old_cfunc_multireturn() > +old_cfunc_args() > +old_cfunc_sum() > + > +-- Unload the module but keep old functions alive, so > +-- they keep reference to NOP module internally > +-- and still callable. > +old_module:unload() > +old_cfunc_nop() > +old_cfunc_fetch_evens() > +old_cfunc_multireturn() > +old_cfunc_args() > +old_cfunc_sum() > + > +-- The module is unloaded I should not be able > +-- to load new shared library. > +old_module:load('cfunc') > +-- Neither I should be able to unload module twise. > +old_module:unload() > + > +-- Clean old functions. > +old_cfunc_nop:unload() > +old_cfunc_fetch_evens:unload() > +old_cfunc_multireturn:unload() > +old_cfunc_args:unload() > +old_cfunc_sum:unload() > + > +-- And reload old module again. > +old_module = cmod.load('cfunc') > +assert(old_module.state == "cached") > +old_cfunc_nop = old_module:load('cfunc_nop') > + > +-- Overwrite module with new contents. > +_ = pcall(fio.unlink(cfunc_path)) > +fio.symlink(cfunc2_path, cfunc_path) > + > +-- Now try to load a function from old module, > +-- we should get chache invalidation but all > +-- old functions should be callable. > +new_module = cmod.load('cfunc') > +assert(old_module.state == "orphan") > + > +-- Still all functions from old module should > +-- be callable. > +old_cfunc_nop = old_module:load('cfunc_nop') > +old_cfunc_fetch_evens = old_module:load('cfunc_fetch_evens') > +old_cfunc_multireturn = old_module:load('cfunc_multireturn') > +old_cfunc_args = old_module:load('cfunc_args') > +old_cfunc_sum = old_module:load('cfunc_sum') > + > +-- New module is loaded, lets lookup for updated symbols. > +new_cfunc_nop = new_module:load('cfunc_nop') > +new_cfunc_fetch_evens = new_module:load('cfunc_fetch_evens') > +new_cfunc_multireturn = new_module:load('cfunc_multireturn') > +new_cfunc_args = new_module:load('cfunc_args') > +new_cfunc_sum = new_module:load('cfunc_sum') > + > +-- Call old functions. > +old_cfunc_nop() > +old_cfunc_fetch_evens() > +old_cfunc_multireturn() > +old_cfunc_args() > +old_cfunc_sum() > + > +-- And newly loaded ones. > +new_cfunc_nop() > +new_cfunc_multireturn() > +new_cfunc_fetch_evens({2,4,6}) > +new_cfunc_fetch_evens({1,2,3}) -- error > +new_cfunc_args(1, "hello") > +new_cfunc_sum(1) -- error > +new_cfunc_sum(1,2) > + > +-- Cleanup old module's functions. > +old_cfunc_nop:unload() > +old_cfunc_fetch_evens:unload() > +old_cfunc_multireturn:unload() > +old_cfunc_args:unload() > +old_cfunc_sum:unload() > + > +-- Cleanup new module data. > +new_cfunc_nop:unload() > +new_cfunc_multireturn:unload() > +new_cfunc_fetch_evens:unload() > +new_cfunc_args:unload() > +new_cfunc_sum:unload() > +new_module:unload() > + > +-- > +-- Cleanup the generated symlink > +_ = pcall(fio.unlink(cfunc_path)) > diff --git a/test/box/suite.ini b/test/box/suite.ini > index e700d0b9e..fc16c5951 100644 > --- a/test/box/suite.ini > +++ b/test/box/suite.ini > @@ -2,7 +2,7 @@ > core = tarantool > description = Database tests > script = box.lua > -disabled = rtree_errinj.test.lua tuple_bench.test.lua > +disabled = rtree_errinj.test.lua tuple_bench.test.lua cmod.test.lua > long_run = huge_field_map_long.test.lua > config = engine.cfg > release_disabled = errinj.test.lua errinj_index.test.lua rtree_errinj.test.lua upsert_errinj.test.lua iproto_stress.test.lua gh-4648-func-load-unload.test.lua >