diff options
Diffstat (limited to 'lib/erl_interface/test')
-rw-r--r-- | lib/erl_interface/test/Makefile | 4 | ||||
-rw-r--r-- | lib/erl_interface/test/all_SUITE_data/ei_runner.c | 2 | ||||
-rw-r--r-- | lib/erl_interface/test/all_SUITE_data/ei_runner.h | 3 | ||||
-rw-r--r-- | lib/erl_interface/test/all_SUITE_data/reclaim.h | 152 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_accept_SUITE.erl | 246 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c | 21 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c | 4 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c | 2 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_connect_SUITE_data/einode.c | 2 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_decode_SUITE.erl | 4 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_encode_SUITE.erl | 2 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c | 2 | ||||
-rw-r--r-- | lib/erl_interface/test/ei_tmo_SUITE.erl | 277 | ||||
-rw-r--r-- | lib/erl_interface/test/runner.erl | 17 |
14 files changed, 430 insertions, 308 deletions
diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile index bdfedecc66..11c60953ca 100644 --- a/lib/erl_interface/test/Makefile +++ b/lib/erl_interface/test/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2020. All Rights Reserved. +# Copyright Ericsson AB 1997-2022. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -58,7 +58,7 @@ RELSYSDIR = $(RELEASE_PATH)/erl_interface_test # Targets # ---------------------------------------------------- -tests debug opt: +tests $(TYPES): clean: diff --git a/lib/erl_interface/test/all_SUITE_data/ei_runner.c b/lib/erl_interface/test/all_SUITE_data/ei_runner.c index b1a4f1a2c1..3732cb9f5b 100644 --- a/lib/erl_interface/test/all_SUITE_data/ei_runner.c +++ b/lib/erl_interface/test/all_SUITE_data/ei_runner.c @@ -274,7 +274,7 @@ void do_fail(const char* file, int line, const char* reason, ...) /* * This function sends a message to the Erlang side. * The message will be written to the test servers log file, - * but will otherwise be completly ignored. + * but will otherwise be completely ignored. */ void message(char* format, ...) diff --git a/lib/erl_interface/test/all_SUITE_data/ei_runner.h b/lib/erl_interface/test/all_SUITE_data/ei_runner.h index 6d6e0717e8..3073d1b60f 100644 --- a/lib/erl_interface/test/all_SUITE_data/ei_runner.h +++ b/lib/erl_interface/test/all_SUITE_data/ei_runner.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2020. All Rights Reserved. + * Copyright Ericsson AB 2001-2022. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,7 @@ void free_packet(char*); #define fail(reason) do_fail(__FILE__, __LINE__, reason) #define fail1(reason, a1) do_fail(__FILE__, __LINE__, reason, a1) #define fail2(reason, a1, a2) do_fail(__FILE__, __LINE__, reason, a1, a2) +#define fail3(reason, a1, a2, a3) do_fail(__FILE__, __LINE__, reason, a1, a2, a3) #define report(ok) do_report(__FILE__, __LINE__, ok) void do_report(char* file, int line, int ok); diff --git a/lib/erl_interface/test/all_SUITE_data/reclaim.h b/lib/erl_interface/test/all_SUITE_data/reclaim.h deleted file mode 100644 index fe99bb0afc..0000000000 --- a/lib/erl_interface/test/all_SUITE_data/reclaim.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2001-2016. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * %CopyrightEnd% - * - - */ -#ifndef _RECLAIM_H -#define _RECLAIM_H - - -/* The Erlang release for VxWorks includes a simple mechanism for - "resource reclamation" at task exit - it allows replacement of the - functions that open/close "files" and malloc/free memory with versions - that keep track, to be able to "reclaim" file descriptors and memory - when a task exits (regardless of *how* it exits). - - The interface to this mechanism is made available via this file, - with the following caveats: - - - The interface may change (or perhaps even be removed, though that - isn't likely until VxWorks itself provides similar functionality) - in future releases - i.e. you must always use the version of this - file that comes with the Erlang release you are using. - - - Disaster is guaranteed if you use the mechanism incorrectly (see - below for the correct way), e.g. allocate memory with the "tracking" - version of malloc() and free it with the "standard" version of free(). - - - The mechanism (of course) incurs some performance penalty - thus - for a simple program you may be better off with careful programming, - making sure that you do whatever close()/free()/etc calls that are - appropriate at all exit points (though if you need to guard against - taskDelete() etc, things get messy...). - - To use the mechanism, simply program your application normally, i.e. - use open()/close()/malloc()/free() etc as usual, but #include this - file before any usage of the relevant functions. NOTE: To avoid the - "disaster" mentioned above, you *must* #include it in *all* (or none) - of the files that manipulate a particular file descriptor, allocated - memory area, etc. - - Before any task that uses this utility is loaded (which includes the - erlang emulator), the reclaim.o object file has to be loaded and - the function reclaim_init() has to be called. reclaim_init should be called - only _ONCE_ in a systems lifetime and has only a primitive guard - against multiple calls (i.e. a global variable is checked). Therefore - the initialization should occur either in the start script of the system - or (even better) in the usrInit() part of system initialization. The - object file itself should be loaded only once, so linking it with the - kernel is a good idea, linking with each application is an extremely bad - dito. Make really sure that it's loaded _before_ any application that - uses it if You want to load it in the startup script. - - If You dont want to have #define's for the posix/stdio names - of the file/memory operations (i.e. no #define malloc save_malloc etc), - #define RECLAIM_NO_ALIAS in Your source before reclaim.h is included. -*/ - -#include <vxWorks.h> /* STATUS, size_t */ -#include <sockLib.h> /* struct sockaddr */ -#include <stdio.h> /* FILE */ - -#if defined(__STDC__) -#define _RECLAIM_DECL_FUN(RetType, FunName, ParamList) \ -extern RetType FunName##ParamList -#define _RECLAIM_VOID_PTR void * -#define _RECLAIM_VOID_PARAM void -#define _RECLAIM_VOID_RETURN void -#elif defined(__cplusplus) -#define _RECLAIM_DECL_FUN(RetType, FunName, ParamList) \ -extern "C" RetType FunName##ParamList -#define _RECLAIM_VOID_PTR void * -#define _RECLAIM_VOID_PARAM -#define _RECLAIM_VOID_RETURN void -#else -#define _RECLAIM_DECL_FUN(RetType, FunName, Ignore) extern RetType FunName() -#define DECLARE_FUNCTION_TYPE(RetType, Type, PList) typedef RetType (* Type)() -#define _RECLAIM_VOID_PTR char * -#define _RECLAIM_VOID_PARAM -#define _RECLAIM_VOID_RETURN -#endif /* __STDC__ / __cplusplus */ - -/* Initialize the facility, on a per system basis. */ -_RECLAIM_DECL_FUN(STATUS, reclaim_init, (_RECLAIM_VOID_PARAM)); - -/* File descriptor operations */ -_RECLAIM_DECL_FUN(int,save_open,(char *, int, ...)); -_RECLAIM_DECL_FUN(int,save_creat,(char *, int)); -_RECLAIM_DECL_FUN(int,save_socket,(int, int, int)); -_RECLAIM_DECL_FUN(int,save_accept,(int, struct sockaddr *, int *)); -_RECLAIM_DECL_FUN(int,save_close,(int)); -/* Interface to add an fd to what's reclaimed even though it's not open with - one of the above functions */ -_RECLAIM_DECL_FUN(_RECLAIM_VOID_RETURN, save_fd, (int fd)); -#ifndef RECLAIM_NO_ALIAS -#define open save_open -#define creat save_creat -#define socket save_socket -#define accept save_accept -#define close save_close -#endif -/* Stdio file operations */ -_RECLAIM_DECL_FUN(FILE *, save_fopen, (char *, char *)); -_RECLAIM_DECL_FUN(FILE *, save_fdopen, (int, char *)); -_RECLAIM_DECL_FUN(FILE *, save_freopen, (char *, char *, FILE *)); -_RECLAIM_DECL_FUN(int, save_fclose, (FILE *)); -/* XXX Should do opendir/closedir too... */ -#ifndef RECLAIM_NO_ALIAS -#define fopen save_fopen -#define fdopen save_fdopen -#define freopen save_freopen -#define fclose save_fclose -#endif -/* Memory allocation */ -_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, save_malloc, (size_t)); -_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, save_calloc, (size_t, size_t)); -_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, save_realloc, - (_RECLAIM_VOID_PTR, size_t)); -_RECLAIM_DECL_FUN(void, save_free, (_RECLAIM_VOID_PTR)); -_RECLAIM_DECL_FUN(void, save_cfree, (_RECLAIM_VOID_PTR)); -#ifndef RECLAIM_NO_ALIAS -#define malloc save_malloc -#define calloc save_calloc -#define realloc save_realloc -#define free save_free -#define cfree save_cfree -#endif -/* Generic interfaces to malloc etc... */ -_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, plain_malloc, (size_t)); -_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, plain_realloc, - (_RECLAIM_VOID_PTR, size_t)); -_RECLAIM_DECL_FUN(void, plain_free, (_RECLAIM_VOID_PTR)); -#endif /* _RECLAIM_H */ - - - - diff --git a/lib/erl_interface/test/ei_accept_SUITE.erl b/lib/erl_interface/test/ei_accept_SUITE.erl index 612d6e1b81..f563feaa72 100644 --- a/lib/erl_interface/test/ei_accept_SUITE.erl +++ b/lib/erl_interface/test/ei_accept_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2020. All Rights Reserved. +%% Copyright Ericsson AB 2001-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -26,70 +26,270 @@ -export([all/0, suite/0, init_per_testcase/2, - ei_accept/1, ei_threaded_accept/1, + ei_accept/1, + hopeful_random/1, + ei_threaded_accept/1, monitor_ei_process/1]). +%% Internals +-export([id/1]). + -import(runner, [get_term/1,send_term/2]). + +-define(ERL_ONHEAP_BIN_LIMIT, 64). + suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap, {seconds, 30}}]. all() -> - [ei_accept, ei_threaded_accept, + [ei_accept, + hopeful_random, + ei_threaded_accept, monitor_ei_process]. init_per_testcase(Case, Config) -> + rand:uniform(), % Make sure rand is initialized and seeded. + %%rand:seed({exsss, [61781477086241372|88832360391433009]}), + io:format("** rand seed = ~p\n", [rand:export_seed()]), runner:init_per_testcase(?MODULE, Case, Config). ei_accept(Config) when is_list(Config) -> - [ei_accept_do(Config, CR, SI) - || CR <- [0,21], - SI <- [default, ussi]], + _ = [ei_accept_do(Config, SI) || SI <- [default, ussi]], ok. -ei_accept_do(Config, CompatRel, SockImpl) -> - io:format("CompatRel=~p, SockImpl=~p\n", [CompatRel, SockImpl]), +ei_accept_do(Config, SockImpl) -> + io:format("SockImpl=~p\n", [SockImpl]), P = runner:start(Config, ?interpret), - 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, CompatRel, SockImpl), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, 0, SockImpl), Myname = hd(tl(string:tokens(atom_to_list(node()), "@"))), io:format("Myname ~p ~n", [Myname]), EINode = list_to_atom("c42@"++Myname), io:format("EINode ~p ~n", [EINode]), - %% We take this opportunity to also test export-funs and bit-strings - %% with (ugly) tuple fallbacks in OTP 21 and older. + %% We take this opportunity to also test export-funs and bit-strings. %% Test both toward pending connection and established connection. - RealTerms = [<<1:1>>, fun lists:map/2], - EncTerms = case CompatRel of - 0 -> RealTerms; - 21 -> [{<<128>>,1}, {lists,map}] - end, + %% OTP-25: This is a bit obsolete now as we no longer support + %% tuple fallbacks for export-funs and bit-strings. + RealTerms = + [<<1:1>>, + fun lists:map/2, + fun_with_env(<<1:1>>), + fun_with_env(fun lists:map/2)], Self = self(), Funny = fun() -> hello end, - TermToSend = {call, Self, "Test", Funny, RealTerms}, - TermToGet = {call, Self, "Test", Funny, EncTerms}, + Terms = {call, Self, "Test", Funny, RealTerms}, Port = 6543, {ok, ListenFd} = ei_publish(P, Port), - {any, EINode} ! TermToSend, + {any, EINode} ! Terms, {ok, Fd, Node} = ei_accept(P, ListenFd), Node = node(), Got1 = ei_receive(P, Fd), %% Send again, now without auto-connect - {any, EINode} ! TermToSend, + {any, EINode} ! Terms, Got2 = ei_receive(P, Fd), - io:format("Sent ~p~nExp. ~p~nGot1 ~p~nGot2 ~p~n", [TermToSend, TermToGet, Got1, Got2]), - TermToGet = Got1, - TermToGet = Got2, + io:format("Sent ~p~nExp. ~p~nGot1 ~p~nGot2 ~p~n", [Terms, Terms, Got1, Got2]), + Terms = Got1, + Terms = Got2, runner:finish(P), ok. +fun_with_env(Term) -> + Env = ?MODULE:id(Term), + fun() -> Env end. + +id(X) -> X. + + +%% Send random encoded terms from emulator to c-node +%% and verify correct encoding. +hopeful_random(Config) when is_list(Config) -> + [hopeful_random_do(Config, SI) + || SI <- [default, ussi]], + ok. + + +hopeful_random_do(Config, SockImpl) -> + io:format("SockImpl=~p\n", [SockImpl]), + P = runner:start(Config, ?interpret), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, 0, SockImpl), + + Myname = hd(tl(string:tokens(atom_to_list(node()), "@"))), + io:format("Myname ~p ~n", [Myname]), + EINode = list_to_atom("c42@"++Myname), + io:format("EINode ~p ~n", [EINode]), + + Port = 6543, + {ok, ListenFd} = ei_publish(P, Port), + + Terms = [random_term(20) || _ <- lists:seq(1,10)], + + %% lists:foldl(fun(T,N) -> + %% io:format("Term #~p = ~p\n", [N, printable(T)]), + %% N+1 + %% end, + %% 1, + %% Terms), + + %% Send on pending connection (hopeful encoding) + [{any, EINode} ! T || T <- Terms], + {ok, Fd, Node} = ei_accept(P, ListenFd), + Node = node(), + [match(T, ei_receive(P, Fd)) || T <- Terms], + + %% Send again on established connection + [{any, EINode} ! T || T <- Terms], + [match(T, ei_receive(P, Fd)) || T <- Terms], + + runner:finish(P), + ok. + + +match(A, A) -> ok; +match(A, B) -> + io:format("match failed\nA = ~p\nB = ~p\n", [printable(A), printable(B)]), + ct:fail("match failed"). + +random_term(MaxSize) -> + rand_term(rand:uniform(MaxSize)). + +rand_term(Arity) when Arity > 0 -> + List = rand_list(Arity, []), + case rand:uniform(6) of + 1 -> List; + 2 -> list_to_improper_list(List); + 3 -> list_to_tuple(List); + 4 -> list_to_flatmap(List); + 5 -> list_to_hashmap(List); + 6 -> list_to_fun(List) + end; +rand_term(0) -> + rand_leaf(). + +rand_list(0, Acc) -> + %% Shuffle result list to not favor tail heavy lists. + {_, MixedList} = lists:unzip(lists:sort(Acc)), + MixedList; +rand_list(Budget, Acc) -> + Depth = rand:uniform(Budget), + SortIx = rand:uniform(1 bsl 26), + rand_list(Budget-Depth, [{SortIx, rand_term(Depth-1)} | Acc]). + +rand_leaf() -> + case rand:uniform(19) of + 1 -> rand_integer(); + 2 -> rand_float(); + 3 -> rand_heapbin(); + 4 -> rand_procbin(); + 5 -> rand_subbin(rand_heapbin()); + 6 -> rand_subbin(rand_procbin()); + 7 -> atom; + 8 -> []; + 9 -> {}; + 10 -> #{}; + 11 -> fun lists:sort/1; + 12 -> fun() -> ok end; + 13 -> self(); + 14 -> lists:last(erlang:ports()); + 15 -> make_ref(); + 16 -> atomics:new(10,[]); % Magic ref + 17 -> mk_ext_pid({a@b, 17}, 17, 42); + 18 -> mk_ext_port({a@b, 21}, 13); + 19 -> mk_ext_ref({a@b, 42}, [42, 19, 11]) + end. + +rand_integer() -> + Bits = rand:uniform(150), + Uint = rand:uniform(1 bsl Bits), + case rand:uniform(2) of + 1 -> Uint; + 2 -> -Uint + end. + +rand_float() -> + rand:uniform(). + +rand_heapbin() -> + HeapBinSz = rand:uniform(?ERL_ONHEAP_BIN_LIMIT + 1) - 1, + HeapBig = rand:uniform(1 bsl (HeapBinSz*8)), + <<HeapBig:HeapBinSz/unit:8>>. + +rand_procbin() -> + ProcBinSz = ?ERL_ONHEAP_BIN_LIMIT + rand:uniform(?ERL_ONHEAP_BIN_LIMIT), + ProcBig = rand:uniform(1 bsl (ProcBinSz*8)), + <<ProcBig:ProcBinSz/unit:8>>. + +rand_subbin(Bin) -> + TotSz = bit_size(Bin), + Offs = rand:uniform(TotSz + 1) - 1, + Bits = rand:uniform(TotSz - Offs + 1) - 1, + <<_:Offs, BitStr:Bits/bits, _/bits>> = Bin, + BitStr. + +list_to_improper_list([A,B|T]) -> + T ++ [A|B]; +list_to_improper_list([H]) -> + [[]|H]. + +list_to_flatmap(List) -> + list_to_map(List, #{}). + +list_to_hashmap(List) -> + HashMap = #{1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9,10=>0, + 11=>1,12=>2,13=>3,14=>4,15=>5,16=>6,17=>7,18=>8,19=>9,20=>0, + 21=>1,22=>2,23=>3,24=>4,25=>5,26=>6,27=>7,28=>8,29=>9,30=>0, + 31=>1,32=>2,33=>3}, + list_to_map(List, HashMap). + +list_to_map([], Map) -> + Map; +list_to_map([K], Map) -> + Map#{K => K}; +list_to_map([K,V|T], Map) -> + list_to_map(T, Map#{K => V}). + +list_to_fun([X]) -> + fun(A) -> A + X end; +list_to_fun([X, Y]) -> + fun(A) -> A + X + Y end; +list_to_fun([X, Y | T]) -> + fun(A) -> [A+X+Y | T] end. + +mk_ext_pid({NodeName, Creation}, Number, Serial) -> + erts_test_utils:mk_ext_pid({NodeName, Creation}, Number, Serial). + +mk_ext_port({NodeName, Creation}, Number) -> + erts_test_utils:mk_ext_port({NodeName, Creation}, Number). + +mk_ext_ref({NodeName, Creation}, Numbers) -> + erts_test_utils:mk_ext_ref({NodeName, Creation}, Numbers). + +%% Convert local funs to maps to show fun environment +printable(Fun) when is_function(Fun) -> + case erlang:fun_info(Fun, type) of + {type,local} -> + {env, Env} = erlang:fun_info(Fun, env), + #{'fun' => [printable(T) || T <- Env]}; + {type,external} -> + Fun + end; +printable([H|T]) -> + [printable(H)|printable(T)]; +printable(Tuple) when is_tuple(Tuple) -> + list_to_tuple(printable(tuple_to_list(Tuple))); +printable(Map) when is_map(Map) -> + maps:from_list(printable(maps:to_list(Map))); +printable(Leaf) -> + Leaf. + + ei_threaded_accept(Config) when is_list(Config) -> Einode = filename:join(proplists:get_value(data_dir, Config), "eiaccnode"), ei_threaded_accept_do(Einode, default), diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c index 7cfc0c9da0..97c8721bde 100644 --- a/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c +++ b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2020. All Rights Reserved. + * Copyright Ericsson AB 2001-2022. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -198,10 +198,13 @@ static void cmd_ei_accept(char* buf, int len) static void cmd_ei_receive(char* buf, int len) { + static int call_cnt = 0; ei_x_buff x; erlang_msg msg; long l; int fd, index = 0; + + call_cnt++; if (ei_decode_long(buf, &index, &l) < 0) fail("expected int (fd)"); @@ -215,6 +218,22 @@ static void cmd_ei_receive(char* buf, int len) fail1("ei_xreceive_msg, got==%d", got); break; } + + { + int index = 0; + int skip_ret; + + if (ei_decode_version(x.buff, &index, NULL) != 0) + fail("ei_decode_version failed"); + + skip_ret = ei_skip_term(x.buff, &index); + if (skip_ret != 0) + fail1("ei_skip_term returned %d", skip_ret); + if (index != x.index ) + fail3("ei_skip_term length mismatch %d != %d (call_cnt=%d)\n", + index, x.index, call_cnt); + } + index = 1; send_bin_term(&x); ei_x_free(&x); diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c b/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c index ef1ab96d41..7dc9696611 100644 --- a/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c +++ b/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2020. All Rights Reserved. + * Copyright Ericsson AB 2001-2021. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -145,7 +145,7 @@ static void* ei_x_free(&x); ei_x_free(&xs); } else { - fprintf(file, "coudn't connect fd %d r %d\n", fd, r); fflush(file); + fprintf(file, "couldn't connect fd %d r %d\n", fd, r); fflush(file); } ei_close_connection(listen); fprintf(file, "done thread %d\n", n); diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c index 379c3bb4ba..f713637438 100644 --- a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c +++ b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c @@ -72,7 +72,7 @@ static struct { /* - * Sends a list contaning all data types to the Erlang side. + * Sends a list containing all data types to the Erlang side. */ TESTCASE(interpret) diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c index 54bd0ecd8b..1739245ab8 100644 --- a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c +++ b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c @@ -89,7 +89,7 @@ static void* shutdown(fd, SD_SEND); closesocket(fd); } else { - printf("coudn't connect fd %d r %d\n", fd, r); // DebugBreak(); + printf("couldn't connect fd %d r %d\n", fd, r); // DebugBreak(); } printf("done thread %d\n", n); return 0; diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl index a51078f7e7..3703e85777 100644 --- a/lib/erl_interface/test/ei_decode_SUITE.erl +++ b/lib/erl_interface/test/ei_decode_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2020. All Rights Reserved. +%% Copyright Ericsson AB 2004-2021. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ init_per_testcase(Case, Config) -> %% --------------------------------------------------------------------------- -% NOTE: for historical reasons we don't pach as tight as we can, +% NOTE: for historical reasons we don't patch as tight as we can, % we only fill 27 bits in 32 bit INTEGER_EXT diff --git a/lib/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl index d6e026379f..8327398527 100644 --- a/lib/erl_interface/test/ei_encode_SUITE.erl +++ b/lib/erl_interface/test/ei_encode_SUITE.erl @@ -52,7 +52,7 @@ init_per_testcase(Case, Config) -> %% --------------------------------------------------------------------------- -% NOTE: for historical reasons we don't pach as tight as we can, +% NOTE: for historical reasons we don't patch as tight as we can, % we only fill 27 bits in 32 bit INTEGER_EXT diff --git a/lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c b/lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c index c018ff625a..5150b78e6d 100644 --- a/lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c +++ b/lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c @@ -59,7 +59,7 @@ static struct { /* - * Sends a list contaning all data types to the Erlang side. + * Sends a list containing all data types to the Erlang side. */ TESTCASE(interpret) diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl index 2e3789a3d9..a6964e3ec0 100644 --- a/lib/erl_interface/test/ei_tmo_SUITE.erl +++ b/lib/erl_interface/test/ei_tmo_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2021. All Rights Reserved. +%% Copyright Ericsson AB 2003-2023. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -31,7 +31,8 @@ ei_send_tmo/1, ei_send_failure_tmo/1, ei_connect_unreachable_tmo/0, ei_connect_unreachable_tmo/1, - ei_recv_tmo/1]). + ei_recv_tmo/1, + ei_dflags/1]). suite() -> [{ct_hooks,[ts_install_cth]}, @@ -48,7 +49,8 @@ groups() -> Members = [ei_recv_tmo, ei_accept_tmo, ei_connect_tmo, - ei_send_tmo], + ei_send_tmo, + ei_dflags], [{default, [], Members}, {ussi, [], Members}]. @@ -61,6 +63,41 @@ init_per_testcase(Case, Config) -> end_per_testcase(_Case, _Config) -> ok. +-define(DFLAG_PUBLISHED, 16#01). +-define(DFLAG_ATOM_CACHE, 16#02). +-define(DFLAG_EXTENDED_REFERENCES, 16#04). +-define(DFLAG_DIST_MONITOR, 16#08). +-define(DFLAG_FUN_TAGS, 16#10). +-define(DFLAG_NEW_FUN_TAGS, 16#80). +-define(DFLAG_EXTENDED_PIDS_PORTS, 16#100). +-define(DFLAG_EXPORT_PTR_TAG, 16#200). +-define(DFLAG_BIT_BINARIES, 16#400). +-define(DFLAG_NEW_FLOATS, 16#800). +-define(DFLAG_UTF8_ATOMS, 16#10000). +-define(DFLAG_MAP_TAG, 16#20000). +-define(DFLAG_BIG_CREATION, 16#40000). +-define(DFLAG_HANDSHAKE_23, 16#1000000). +-define(DFLAG_MANDATORY_25_DIGEST, 16#4000000). + +%% From OTP R9 extended references are compulsory. +%% From OTP R10 extended pids and ports are compulsory. +%% From OTP 20 UTF8 atoms are compulsory. +%% From OTP 21 NEW_FUN_TAGS is compulsory (no more tuple fallback {fun, ...}). +%% From OTP 23 BIG_CREATION is compulsory. +%% From OTP 25 NEW_FLOATS, MAP_TAG, EXPORT_PTR_TAG, and BIT_BINARIES are compulsory. +-define(COMPULSORY_DFLAGS, + (?DFLAG_EXTENDED_REFERENCES bor + ?DFLAG_FUN_TAGS bor + ?DFLAG_EXTENDED_PIDS_PORTS bor + ?DFLAG_UTF8_ATOMS bor + ?DFLAG_NEW_FUN_TAGS bor + ?DFLAG_BIG_CREATION bor + ?DFLAG_NEW_FLOATS bor + ?DFLAG_MAP_TAG bor + ?DFLAG_EXPORT_PTR_TAG bor + ?DFLAG_BIT_BINARIES bor + ?DFLAG_HANDSHAKE_23)). + %% Check the framework. framework_check(Config) when is_list(Config) -> %%dbg:tracer(), @@ -106,9 +143,13 @@ do_one_recv_failure(Config,CNode) -> true = (Ret < 0), runner:recv_eot(P1). --define(EI_DIST_LOW, 5). +-define(EI_DIST_LOW, 6). -define(EI_DIST_HIGH, 6). +%% An OTP-23 or 24 node may connect assuming 5 or higher. +-define(EI_DIST_LOWEST_ASSUMED, 5). + + %% Check send with timeouts. ei_send_tmo(Config) when is_list(Config) -> register(ei_send_tmo_1,self()), @@ -140,15 +181,11 @@ do_one_send(Config,From,CNode) -> ei_send_failure_tmo(Config) when is_list(Config) -> register(ei_send_tmo_1,self()), - [begin - io:format("Test dist version ~p\n", [Ver]), - do_one_send_failure(Config,self(),cccc1,c_nod_send_tmo_3, Ver), - do_one_send_failure(Config,ei_send_tmo_1,cccc2,c_nod_send_tmo_4, Ver) - end - || Ver <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH)], + do_one_send_failure(Config,self(),cccc1,c_nod_send_tmo_3), + do_one_send_failure(Config,ei_send_tmo_1,cccc2,c_nod_send_tmo_4), ok. -do_one_send_failure(Config,From,FakeName,CName, OurVer) -> +do_one_send_failure(Config,From,FakeName,CName) -> {_,Host} = split(node()), OurName = join(FakeName,Host), Node = join(CName,Host), @@ -158,7 +195,7 @@ do_one_send_failure(Config,From,FakeName,CName, OurVer) -> Else -> exit(Else) end, - EpmdSocket = epmd_register(OurName, LSocket, OurVer), + EpmdSocket = epmd_register(OurName, LSocket), P3 = runner:start(Config, ?send_tmo), Cookie = kaksmula_som_ingen_bryr_sig_om, runner:send_term(P3,{CName, @@ -171,10 +208,10 @@ do_one_send_failure(Config,From,FakeName,CName, OurVer) -> Else2 -> exit(Else2) end, - {hidden,Node} = recv_name(SocketB, OurVer), % See 1) + {hidden,Node} = recv_name(SocketB), % See 1) send_status(SocketB, ok), MyChallengeB = gen_challenge(), - send_challenge(SocketB, OurName, MyChallengeB, OurVer), + send_challenge(SocketB, OurName, MyChallengeB), HisChallengeB = recv_challenge_reply(SocketB, MyChallengeB, Cookie), @@ -220,15 +257,8 @@ ei_connect_unreachable_tmo(Config) when is_list(Config) -> ok. ei_connect_tmo(Config) when is_list(Config) -> - [begin - io:format("Test dist version ~p published as ~p\n", [OurVer,OurEpmdVer]), - do_ei_connect_tmo(Config, OurVer, OurEpmdVer) - end - || OurVer <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH), - OurEpmdVer <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH), - OurVer >= OurEpmdVer]. + Flags = ?COMPULSORY_DFLAGS bor ?DFLAG_MANDATORY_25_DIGEST, -do_ei_connect_tmo(Config, OurVer, OurEpmdVer) -> P2 = runner:start(Config, ?connect_tmo), runner:send_term(P2,{c_nod_connect_tmo_2, erlang:get_cookie(), @@ -237,6 +267,7 @@ do_ei_connect_tmo(Config, OurVer, OurEpmdVer) -> {term, X} = runner:get_term(P2, 10000), runner:recv_eot(P2), true = is_integer(X), + %% Aborted handshake test... {_,Host} = split(node()), OurName = join(cccc,Host), @@ -247,7 +278,7 @@ do_ei_connect_tmo(Config, OurVer, OurEpmdVer) -> Else -> exit(Else) end, - EpmdSocket = epmd_register(OurName, LSocket, OurEpmdVer), + EpmdSocket = epmd_register(OurName, LSocket), P3 = runner:start(Config, ?connect_tmo), Cookie = kaksmula_som_ingen_bryr_sig_om, runner:send_term(P3,{c_nod_connect_tmo_3, @@ -260,11 +291,10 @@ do_ei_connect_tmo(Config, OurVer, OurEpmdVer) -> Else2 -> exit(Else2) end, - {hidden,Node} = recv_name(SocketB, OurEpmdVer), % See 1) + {hidden,Node} = recv_name(SocketB), % See 1) send_status(SocketB, ok), MyChallengeB = gen_challenge(), - send_challenge(SocketB, OurName, MyChallengeB, OurVer), - recv_complement(SocketB, OurVer, OurEpmdVer), + send_challenge(SocketB, OurName, MyChallengeB, Flags), _HisChallengeB = recv_challenge_reply(SocketB, MyChallengeB, Cookie), @@ -278,22 +308,23 @@ do_ei_connect_tmo(Config, OurVer, OurEpmdVer) -> %% Check accept with timeouts. ei_accept_tmo(Config) when is_list(Config) -> [begin - io:format("Test our dist ver=~p and assumed ver=~p\n", - [OurVer, AssumedVer]), - do_ei_accept_tmo(Config, OurVer, AssumedVer) + io:format("Test assumed ver=~p\n", + [AssumedVer]), + do_ei_accept_tmo(Config, AssumedVer) end - || OurVer <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH), - AssumedVer <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH), - OurVer >= AssumedVer], + || AssumedVer <- lists:seq(?EI_DIST_LOWEST_ASSUMED, ?EI_DIST_HIGH)], ok. -do_ei_accept_tmo(Config, OurVer, AssumedVer) -> +do_ei_accept_tmo(Config, AssumedVer) -> + Flags = ?COMPULSORY_DFLAGS bor ?DFLAG_MANDATORY_25_DIGEST, + P = runner:start(Config, ?accept_tmo), runner:send_term(P,{c_nod_som_ingen_kontaktar_1, kaksmula_som_ingen_bryr_sig_om, get_group(Config)}), {term,{-1,ETimedout,ETimedout}} = runner:get_term(P, 10000), runner:recv_eot(P), + P2 = runner:start(Config, ?accept_tmo), runner:send_term(P2,{c_nod_som_vi_kontaktar_1, erlang:get_cookie(), @@ -304,8 +335,14 @@ do_ei_accept_tmo(Config, OurVer, AssumedVer) -> {term, X} = runner:get_term(P2, 10000), runner:recv_eot(P2), true = is_integer(X), - P3 = runner:start(Config, ?accept_tmo), - runner:send_term(P3,{c_nod_som_vi_kontaktar_2, + + normal_accept(Config, AssumedVer, Flags), + + ok. + +normal_accept(Config, AssumedVer, Flags) -> + P = runner:start(Config, ?accept_tmo), + runner:send_term(P,{c_nod_som_vi_kontaktar_2, erlang:get_cookie(), get_group(Config)}), receive after 1000 -> ok end, @@ -317,17 +354,47 @@ do_ei_accept_tmo(Config, OurVer, AssumedVer) -> {ok, SocketA} = gen_tcp:connect(atom_to_list(NB),PortNo, [{active,false}, {packet,2}]), - send_name(SocketA,OurName,OurVer,AssumedVer), + send_name(SocketA, OurName, AssumedVer, Flags), ok = recv_status(SocketA), - {hidden,_Node,HisChallengeA} = recv_challenge(SocketA,OurVer), % See 1) + {hidden,_Node,HisChallengeA} = recv_challenge(SocketA), % See 1) _OurChallengeA = gen_challenge(), _OurDigestA = gen_digest(HisChallengeA, erlang:get_cookie()), %% Dont do the last two steps of the connection setup... %% send_challenge_reply(SocketA, OurChallengeA, OurDigestA), %% ok = recv_challenge_ack(SocketA, OurChallengeA, erlang:get_cookie()), - {term, {-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000), - runner:recv_eot(P3), - gen_tcp:close(SocketA), + {term, {-1,ETimedout,ETimedout}} = runner:get_term(P, 10000), + runner:recv_eot(P), + gen_tcp:close(SocketA). + +normal_connect(Config, Flags) -> + {_,Host} = split(node()), + OurName = join(cccc,Host), + Node = join(c_nod_connect_tmo_3,Host), + LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of + {ok, Socket} -> + Socket; + Else -> + exit(Else) + end, + EpmdSocket = epmd_register(OurName, LSocket), + P3 = runner:start(Config, ?connect_tmo), + Cookie = kaksmula_som_ingen_bryr_sig_om, + runner:send_term(P3, {c_nod_connect_tmo_3, + Cookie, + OurName, + get_group(Config)}), + SocketB = case gen_tcp:accept(LSocket) of + {ok, Socket1} -> + Socket1; + Else2 -> + exit(Else2) + end, + {hidden,Node} = recv_name(SocketB), + send_status(SocketB, ok), + MyChallengeB = gen_challenge(), + send_challenge(SocketB, OurName, MyChallengeB, Flags), + gen_tcp:close(SocketB), + gen_tcp:close(EpmdSocket), ok. make_node(X) -> @@ -345,6 +412,23 @@ make_and_check_dummy() -> list_to_atom("dummy@"++HostNotReachable). +%% Test that erl_interface sets the appropriate distributions flags. +ei_dflags(Config) -> + AssumedVer = 5, + OurVer = 6, + + %% Test compatibility with OTP 24 and earlier. + normal_connect(Config, ?COMPULSORY_DFLAGS), + normal_accept(Config, AssumedVer, ?COMPULSORY_DFLAGS), + normal_accept(Config, OurVer, ?COMPULSORY_DFLAGS), + + %% Test compatibility with future versions. + normal_connect(Config, ?DFLAG_MANDATORY_25_DIGEST), + normal_accept(Config, AssumedVer, ?DFLAG_MANDATORY_25_DIGEST), + normal_accept(Config, OurVer, ?DFLAG_MANDATORY_25_DIGEST), + + ok. + %% %% Stolen from the erl_distribution_wb_test in kernel %% To be able to do partial handshakes... @@ -359,18 +443,6 @@ make_and_check_dummy() -> R end). --define(DFLAG_PUBLISHED,1). --define(DFLAG_ATOM_CACHE,2). --define(DFLAG_EXTENDED_REFERENCES,4). --define(DFLAG_EXTENDED_PIDS_PORTS,16#100). --define(DFLAG_NEW_FLOATS,16#800). --define(DFLAG_DIST_MONITOR,8). --define(DFLAG_HANDSHAKE_23,16#1000000). - -%% From R9 and forward extended references is compulsory -%% From 14 and forward new float is compulsory --define(COMPULSORY_DFLAGS, (?DFLAG_EXTENDED_REFERENCES bor ?DFLAG_EXTENDED_PIDS_PORTS bor ?DFLAG_NEW_FLOATS)). - -define(shutdown(X), exit(X)). -define(int16(X), [((X) bsr 8) band 16#ff, (X) band 16#ff]). @@ -411,7 +483,7 @@ gen_digest(Challenge, Cookie) when is_integer(Challenge), is_atom(Cookie) -> %% -%% The differrent stages of the MD5 handshake +%% The different stages of the MD5 handshake %% send_status(Socket, Stat) -> @@ -429,40 +501,27 @@ recv_status(Socket) -> exit(Bad) end. -send_challenge(Socket, Node, Challenge, OurVer) -> - send_challenge(Socket, Node, Challenge, OurVer, ?COMPULSORY_DFLAGS). - -send_challenge(Socket, Node, Challenge, OurVer, Flags) -> - if OurVer =:= 5 -> - ?to_port(Socket, [$n, ?int16(OurVer), ?int32(Flags), - ?int32(Challenge), atom_to_list(Node)]); - OurVer >= 6 -> - NodeName = atom_to_binary(Node, latin1), - NameLen = byte_size(NodeName), - Creation = erts_internal:get_creation(), - ?to_port(Socket, [$N, - <<(Flags bor ?DFLAG_HANDSHAKE_23):64, - Challenge:32, - Creation:32, - NameLen:16>>, - NodeName]) - end. - -recv_challenge(Socket, OurVer) -> +send_challenge(Socket, Node, Challenge) -> + DefaultFlags = ?COMPULSORY_DFLAGS bor ?DFLAG_MANDATORY_25_DIGEST, + send_challenge(Socket, Node, Challenge, DefaultFlags). + +send_challenge(Socket, Node, Challenge, Flags) -> + NodeName = atom_to_binary(Node, latin1), + NameLen = byte_size(NodeName), + Creation = erts_internal:get_creation(), + ?to_port(Socket, [$N, + << Flags:64, + Challenge:32, + Creation:32, + NameLen:16>>, + NodeName]). + +recv_challenge(Socket) -> case gen_tcp:recv(Socket, 0) of - {ok,[$n,V1,V0,Fl1,Fl2,Fl3,Fl4,CA3,CA2,CA1,CA0 | Ns]} -> - 5 = OurVer, - Flags = ?u32(Fl1,Fl2,Fl3,Fl4), - Type = flags_to_type(Flags), - Node =list_to_atom(Ns), - OurVer = ?u16(V1,V0), % echoed back - Challenge = ?u32(CA3,CA2,CA1,CA0), - {Type,Node,Challenge}; - {ok,[$N, F7,F6,F5,F4,F3,F2,F1,F0, CA3,CA2,CA1,CA0, _Cr3,_Cr2,_Cr1,_Cr0, NL1,NL0 | Rest]} -> - true = (OurVer >= 6), <<Flags:64>> = <<F7,F6,F5,F4,F3,F2,F1,F0>>, + verify_flags(Flags), Type = flags_to_type(Flags), NameLen = ?u16(NL1,NL0), {NodeName,_} = lists:split(NameLen, Rest), @@ -517,17 +576,11 @@ send_challenge_ack(Socket, Digest) -> % ?shutdown(bad_challenge_ack) % end. -send_name(Socket, MyNode, OurVer, AssumedVer) -> - Flags = ?COMPULSORY_DFLAGS bor (case OurVer of - 5 -> 0; - 6 -> ?DFLAG_HANDSHAKE_23 - end), - send_name(Socket, MyNode, OurVer, AssumedVer, Flags). - -send_name(Socket, MyNode, OurVer, AssumedVer, Flags) -> +send_name(Socket, MyNode, AssumedVer, Flags0) -> + Flags = Flags0 bor?DFLAG_HANDSHAKE_23, NodeName = atom_to_binary(MyNode, latin1), if AssumedVer =:= 5 -> - ?to_port(Socket, [$n,?int16(OurVer),?int32(Flags),NodeName]); + ?to_port(Socket, [$n,?int16(?EI_DIST_HIGH),?int32(Flags),NodeName]); AssumedVer >= 6 -> Creation = erts_internal:get_creation(), ?to_port(Socket, [$N, @@ -537,34 +590,18 @@ send_name(Socket, MyNode, OurVer, AssumedVer, Flags) -> NodeName]) end. -recv_name(Socket, OurEpmdVer) -> +recv_name(Socket) -> case gen_tcp:recv(Socket, 0) of - {ok,[$n, V1,V0, F3,F2,F1,F0 | OtherNode]} -> - 5 = OurEpmdVer, - 5 = ?u16(V1,V0), - Type = flags_to_type(?u32(F3,F2,F1,F0)), - {Type, list_to_atom(OtherNode)}; {ok,[$N, F7,F6,F5,F4,F3,F2,F1,F0, _Cr3,_Cr2,_Cr1,_Cr0, NL1, NL0 | Rest]} -> - true = (OurEpmdVer >= 6), {OtherNode, _Residue} = lists:split(?u16(NL1,NL0), Rest), <<Flags:64>> = <<F7,F6,F5,F4,F3,F2,F1,F0>>, + verify_flags(Flags), Type = flags_to_type(Flags), {Type, list_to_atom(OtherNode)}; Res -> ?shutdown({no_node,Res}) end. -recv_complement(Socket, OurVer, 5) when OurVer > 5 -> - case gen_tcp:recv(Socket, 0) of - {ok,[$c, _F7,_F6,_F5,_F4, _Cr3,_Cr2,_Cr1,_Cr0]} -> - ok; - Res -> - ?shutdown({no_node,Res}) - end; -recv_complement(_, _OurVer, _OurEpmdVer) -> - ok. - - %% %% tell_name is for old handshake %% @@ -576,7 +613,7 @@ recv_complement(_, _OurVer, _OurEpmdVer) -> %% %% The communication with EPMD follows %% -do_register_node(NodeName, TcpPort, VLow, VHigh) -> +do_register_node(NodeName, TcpPort) -> case gen_tcp:connect({127,0,0,1}, get_epmd_port(), []) of {ok, Socket} -> {N0,_} = split(NodeName), @@ -588,8 +625,8 @@ do_register_node(NodeName, TcpPort, VLow, VHigh) -> ?int16(TcpPort), $M, 0, - ?int16(VHigh), - ?int16(VLow), + ?int16(?EI_DIST_HIGH), + ?int16(?EI_DIST_LOW), ?int16(length(Name)), Name, ?int16(Elen), @@ -625,15 +662,25 @@ wait_for_reg_reply(Socket, SoFar) -> end. -epmd_register(NodeName, ListenSocket, OurVer) -> +epmd_register(NodeName, ListenSocket) -> {ok,{_,TcpPort}} = inet:sockname(ListenSocket), - case do_register_node(NodeName, TcpPort, ?EI_DIST_LOW, OurVer) of + case do_register_node(NodeName, TcpPort) of {alive, Socket, _Creation} -> Socket; Other -> exit(Other) end. +verify_flags(Flags) -> + RequiredFlags = ?COMPULSORY_DFLAGS bor ?DFLAG_MANDATORY_25_DIGEST, + if + Flags band RequiredFlags =:= RequiredFlags -> + ok; + true -> + io:format("Given flags: ~.16.0B\n", [Flags]), + io:format("Required flags: ~.16.0B\n", [RequiredFlags]), + ct:fail(missing_dflags) + end. %% %% Utilities diff --git a/lib/erl_interface/test/runner.erl b/lib/erl_interface/test/runner.erl index 484890006e..0ebaf0f1d9 100644 --- a/lib/erl_interface/test/runner.erl +++ b/lib/erl_interface/test/runner.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2018. All Rights Reserved. +%% Copyright Ericsson AB 1997-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ -export([test/2, test/3, init_per_testcase/3, - start/2, send_term/2, finish/1, send_eot/1, recv_eot/1, + start/2, start/3, send_term/2, finish/1, send_eot/1, recv_eot/1, get_term/1, get_term/2]). -define(default_timeout, 5000). @@ -55,14 +55,21 @@ test(Config, Tc, Timeout) -> %% %% Returns: {ok, Port} -start(Config, {Prog, Tc}) when is_list(Prog), is_integer(Tc) -> - Port = open_port({spawn, prog_cmd(Config, Prog)}, +start(Config, ProgTc) -> + start(Config, ProgTc, []). + +start(Config, {Prog, Tc}, Opt) when is_list(Prog), is_integer(Tc) -> + Port = open_port({spawn, prog_cmd(Config, Prog, Opt)}, [{packet, 4}, exit_status]), Command = [Tc div 256, Tc rem 256], Port ! {self(), {command, Command}}, Port. -prog_cmd(Config, Prog) -> +prog_cmd(Config, Prog0, Opt) -> + Prog = case Opt of + rr -> "rr " ++ Prog0; + [] -> Prog0 + end, case proplists:get_value(valgrind_cmd_fun, Config) of undefined -> Prog; |