summaryrefslogtreecommitdiff
path: root/lib/erl_interface/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/erl_interface/test')
-rw-r--r--lib/erl_interface/test/Makefile4
-rw-r--r--lib/erl_interface/test/all_SUITE_data/ei_runner.c2
-rw-r--r--lib/erl_interface/test/all_SUITE_data/ei_runner.h3
-rw-r--r--lib/erl_interface/test/all_SUITE_data/reclaim.h152
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE.erl246
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c21
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c4
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c2
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/einode.c2
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE.erl4
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE.erl2
-rw-r--r--lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c2
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE.erl277
-rw-r--r--lib/erl_interface/test/runner.erl17
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;