aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/alloc_SUITE.erl9
-rw-r--r--erts/emulator/test/bif_SUITE.erl28
-rw-r--r--erts/emulator/test/binary_SUITE.erl128
-rw-r--r--erts/emulator/test/decode_packet_SUITE.erl12
-rw-r--r--erts/emulator/test/distribution_SUITE.erl237
-rw-r--r--erts/emulator/test/driver_SUITE.erl6
-rw-r--r--erts/emulator/test/erl_link_SUITE.erl13
-rw-r--r--erts/emulator/test/node_container_SUITE.erl2
-rw-r--r--erts/emulator/test/num_bif_SUITE.erl2
-rw-r--r--erts/emulator/test/port_SUITE.erl15
-rw-r--r--erts/emulator/test/process_SUITE.erl13
-rw-r--r--erts/emulator/test/receive_SUITE.erl62
-rw-r--r--erts/emulator/test/scheduler_SUITE.erl6
-rw-r--r--erts/emulator/test/system_info_SUITE.erl6
14 files changed, 361 insertions, 178 deletions
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index f0871ead7d..5e5cd6f578 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -89,10 +89,11 @@ mmsc_flags() ->
mmsc_flags(Env) ->
case os:getenv(Env) of
false -> false;
- V -> case string:str(V, "+MMsc") of
- 0 -> false;
- P -> Env ++ "=" ++ string:substr(V, P)
- end
+ V ->
+ case string:find(V, "+MMsc") of
+ nomatch -> false;
+ SubStr -> Env ++ "=" ++ SubStr
+ end
end.
erts_mmap_do(Config, SCO, SCRPM, SCRFSD) ->
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index 04b7f2de15..e1b42e5d85 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -731,10 +731,12 @@ erlang_halt(Config) when is_list(Config) ->
[broken_halt, "Validate correct crash dump"]),
{ok,_} = wait_until_stable_size(CrashDump,-1),
{ok, Bin} = file:read_file(CrashDump),
- case {string:str(binary_to_list(Bin),"\n=end\n"),
- string:str(binary_to_list(Bin),"\r\n=end\r\n")} of
- {0,0} -> ct:fail("Could not find end marker in crash dump");
- _ -> ok
+ case {string:find(Bin, <<"\n=end\n">>),
+ string:find(Bin, <<"\r\n=end\r\n">>)} of
+ {nomatch,nomatch} ->
+ ct:fail("Could not find end marker in crash dump");
+ {_,_} ->
+ ok
end.
wait_until_stable_size(_File,-10) ->
@@ -779,14 +781,20 @@ is_builtin(_Config) ->
{F,A} <- M:module_info(exports)],
Exp = ordsets:from_list(Exp0),
- %% erlang:apply/3 is considered to be built-in, but is not
- %% implemented as other BIFs.
+ %% Built-ins implemented as special instructions.
+ Instructions = [{erlang,apply,2},{erlang,apply,3},{erlang,yield,0}],
- Builtins0 = [{erlang,apply,3}|erlang:system_info(snifs)],
+ Builtins0 = Instructions ++ erlang:system_info(snifs),
Builtins = ordsets:from_list(Builtins0),
- NotBuiltin = ordsets:subtract(Exp, Builtins),
- _ = [true = erlang:is_builtin(M, F, A) || {M,F,A} <- Builtins],
- _ = [false = erlang:is_builtin(M, F, A) || {M,F,A} <- NotBuiltin],
+
+ Fakes = [{M,F,42} || {M,F,_} <- Instructions],
+ All = ordsets:from_list(Fakes ++ Exp),
+ NotBuiltin = ordsets:subtract(All, Builtins),
+
+ _ = [{true,_} = {erlang:is_builtin(M, F, A),MFA} ||
+ {M,F,A}=MFA <- Builtins],
+ _ = [{false,_} = {erlang:is_builtin(M, F, A),MFA} ||
+ {M,F,A}=MFA <- NotBuiltin],
ok.
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 61536bacd7..b59c22f125 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -48,6 +48,7 @@
bad_list_to_binary/1, bad_binary_to_list/1,
t_split_binary/1, bad_split/1,
terms/1, terms_float/1, float_middle_endian/1,
+ b2t_used_big/1,
external_size/1, t_iolist_size/1,
t_hash/1,
bad_size/1,
@@ -57,7 +58,9 @@
otp_5484/1,otp_5933/1,
ordering/1,unaligned_order/1,gc_test/1,
bit_sized_binary_sizes/1,
- otp_6817/1,deep/1,obsolete_funs/1,robustness/1,otp_8117/1,
+ otp_6817/1,deep/1,
+ term2bin_tuple_fallbacks/1,
+ robustness/1,otp_8117/1,
otp_8180/1, trapping/1, large/1,
error_after_yield/1, cmp_old_impl/1]).
@@ -72,12 +75,14 @@ all() ->
t_split_binary, bad_split,
bad_list_to_binary, bad_binary_to_list, terms,
terms_float, float_middle_endian, external_size, t_iolist_size,
+ b2t_used_big,
bad_binary_to_term_2, safe_binary_to_term2,
bad_binary_to_term, bad_terms, t_hash, bad_size,
bad_term_to_binary, more_bad_terms, otp_5484, otp_5933,
ordering, unaligned_order, gc_test,
bit_sized_binary_sizes, otp_6817, otp_8117, deep,
- obsolete_funs, robustness, otp_8180, trapping, large,
+ term2bin_tuple_fallbacks,
+ robustness, otp_8180, trapping, large,
error_after_yield, cmp_old_impl].
groups() ->
@@ -425,40 +430,77 @@ bad_term_to_binary(Config) when is_list(Config) ->
terms(Config) when is_list(Config) ->
TestFun = fun(Term) ->
- try
- S = io_lib:format("~p", [Term]),
- io:put_chars(S)
- catch
- error:badarg ->
- io:put_chars("bit sized binary")
- end,
+ S = io_lib:format("~p", [Term]),
+ io:put_chars(S),
Bin = term_to_binary(Term),
case erlang:external_size(Bin) of
Sz when is_integer(Sz), size(Bin) =< Sz ->
ok
end,
- Bin1 = term_to_binary(Term, [{minor_version, 1}]),
- case erlang:external_size(Bin1, [{minor_version, 1}]) of
- Sz1 when is_integer(Sz1), size(Bin1) =< Sz1 ->
- ok
- end,
+ Bin1 = term_to_binary(Term, [{minor_version, 1}]),
+ case erlang:external_size(Bin1, [{minor_version, 1}]) of
+ Sz1 when is_integer(Sz1), size(Bin1) =< Sz1 ->
+ ok
+ end,
Term = binary_to_term_stress(Bin),
Term = binary_to_term_stress(Bin, [safe]),
- Unaligned = make_unaligned_sub_binary(Bin),
- Term = binary_to_term_stress(Unaligned),
- Term = binary_to_term_stress(Unaligned, []),
- Term = binary_to_term_stress(Bin, [safe]),
+ Bin_sz = byte_size(Bin),
+ {Term,Bin_sz} = binary_to_term_stress(Bin, [used]),
+
+ BinE = <<Bin/binary, 1, 2, 3>>,
+ {Term,Bin_sz} = binary_to_term_stress(BinE, [used]),
+
+ BinU = make_unaligned_sub_binary(Bin),
+ Term = binary_to_term_stress(BinU),
+ Term = binary_to_term_stress(BinU, []),
+ Term = binary_to_term_stress(BinU, [safe]),
+ {Term,Bin_sz} = binary_to_term_stress(BinU, [used]),
+
+ BinUE = make_unaligned_sub_binary(BinE),
+ {Term,Bin_sz} = binary_to_term_stress(BinUE, [used]),
+
BinC = erlang:term_to_binary(Term, [compressed]),
+ BinC_sz = byte_size(BinC),
+ true = BinC_sz =< size(Bin),
Term = binary_to_term_stress(BinC),
- true = size(BinC) =< size(Bin),
+ {Term, BinC_sz} = binary_to_term_stress(BinC, [used]),
+
Bin = term_to_binary(Term, [{compressed,0}]),
terms_compression_levels(Term, size(Bin), 1),
- UnalignedC = make_unaligned_sub_binary(BinC),
- Term = binary_to_term_stress(UnalignedC)
+
+ BinUC = make_unaligned_sub_binary(BinC),
+ Term = binary_to_term_stress(BinUC),
+ {Term,BinC_sz} = binary_to_term_stress(BinUC, [used]),
+
+ BinCE = <<BinC/binary, 1, 2, 3>>,
+ {Term,BinC_sz} = binary_to_term_stress(BinCE, [used]),
+
+ BinUCE = make_unaligned_sub_binary(BinCE),
+ Term = binary_to_term_stress(BinUCE),
+ {Term,BinC_sz} = binary_to_term_stress(BinUCE, [used])
end,
test_terms(TestFun),
ok.
+%% Test binary_to_term(_, [used]) returning a big Used integer.
+b2t_used_big(_Config) ->
+ case erlang:system_info(wordsize) of
+ 8 ->
+ {skipped, "This is not a 32-bit machine"};
+ 4 ->
+ %% Use a long utf8 atom for large external format but compact on heap.
+ BigAtom = binary_to_atom(<< <<16#F0908D88:32>> || _ <- lists:seq(1,255) >>,
+ utf8),
+ Atoms = (1 bsl 17) + (1 bsl 9),
+ BigAtomList = lists:duplicate(Atoms, BigAtom),
+ BigBin = term_to_binary(BigAtomList),
+ {BigAtomList, Used} = binary_to_term(BigBin, [used]),
+ 2 = erts_debug:size(Used),
+ Used = byte_size(BigBin),
+ Used = 1 + 1 + 4 + Atoms*(1+2+4*255) + 1,
+ ok
+ end.
+
terms_compression_levels(Term, UncompressedSz, Level) when Level < 10 ->
BinC = erlang:term_to_binary(Term, [{compressed,Level}]),
Term = binary_to_term_stress(BinC),
@@ -1261,40 +1303,28 @@ deep_roundtrip(T) ->
B = term_to_binary(T),
T = binary_to_term(B).
-obsolete_funs(Config) when is_list(Config) ->
+term2bin_tuple_fallbacks(Config) when is_list(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
- X = id({1,2,3}),
- Y = id([a,b,c,d]),
- Z = id({x,y,z}),
- obsolete_fun(fun() -> ok end),
- obsolete_fun(fun() -> X end),
- obsolete_fun(fun(A) -> {A,X} end),
- obsolete_fun(fun() -> {X,Y} end),
- obsolete_fun(fun() -> {X,Y,Z} end),
-
- obsolete_fun(fun ?MODULE:all/1),
+ term2bin_tf(fun ?MODULE:all/1),
+ term2bin_tf(<<1:1>>),
+ term2bin_tf(<<90,80:7>>),
erts_debug:set_internal_state(available_internal_state, false),
ok.
-obsolete_fun(Fun) ->
- Tuple = case erlang:fun_info(Fun, type) of
- {type,external} ->
- {module,M} = erlang:fun_info(Fun, module),
- {name,F} = erlang:fun_info(Fun, name),
- {M,F};
- {type,local} ->
- {module,M} = erlang:fun_info(Fun, module),
- {index,I} = erlang:fun_info(Fun, index),
- {uniq,U} = erlang:fun_info(Fun, uniq),
- {env,E} = erlang:fun_info(Fun, env),
- {'fun',M,I,U,list_to_tuple(E)}
- end,
- Tuple = no_fun_roundtrip(Fun).
-
-no_fun_roundtrip(Term) ->
- binary_to_term_stress(erts_debug:get_internal_state({term_to_binary_no_funs,Term})).
+term2bin_tf(Term) ->
+ Tuple = case Term of
+ Fun when is_function(Fun) ->
+ {type, external} = erlang:fun_info(Fun, type),
+ {module,M} = erlang:fun_info(Fun, module),
+ {name,F} = erlang:fun_info(Fun, name),
+ {M,F};
+ BS when bit_size(BS) rem 8 =/= 0 ->
+ Bits = bit_size(BS) rem 8,
+ {<<BS/bitstring, 0:(8-Bits)>>, Bits}
+ end,
+ Tuple = binary_to_term_stress(erts_debug:get_internal_state({term_to_binary_tuple_fallbacks,Term})).
%% Test non-standard encodings never generated by term_to_binary/1
%% but recognized by binary_to_term/1.
diff --git a/erts/emulator/test/decode_packet_SUITE.erl b/erts/emulator/test/decode_packet_SUITE.erl
index 54ee4d5567..0ccdbd7ee8 100644
--- a/erts/emulator/test/decode_packet_SUITE.erl
+++ b/erts/emulator/test/decode_packet_SUITE.erl
@@ -239,7 +239,7 @@ packet_size(Config) when is_list(Config) ->
%% Test OTP-9389, long HTTP header lines.
Opts = [{packet_size, 128}],
Pkt = list_to_binary(["GET / HTTP/1.1\r\nHost: localhost\r\nLink: /",
- string:chars($Y, 64), "\r\n\r\n"]),
+ lists:duplicate(64, $Y), "\r\n\r\n"]),
<<Pkt1:50/binary, Pkt2/binary>> = Pkt,
{ok, {http_request,'GET',{abs_path,"/"},{1,1}}, Rest1} =
erlang:decode_packet(http, Pkt1, Opts),
@@ -250,7 +250,7 @@ packet_size(Config) when is_list(Config) ->
erlang:decode_packet(httph, list_to_binary([Rest2, Pkt2]), Opts),
Pkt3 = list_to_binary(["GET / HTTP/1.1\r\nHost: localhost\r\nLink: /",
- string:chars($Y, 129), "\r\n\r\n"]),
+ lists:duplicate(129, $Y), "\r\n\r\n"]),
{ok, {http_request,'GET',{abs_path,"/"},{1,1}}, Rest3} =
erlang:decode_packet(http, Pkt3, Opts),
{ok, {http_header,_,'Host',_,"localhost"}, Rest4} =
@@ -509,9 +509,9 @@ decode_line(Bin,MaxLen) ->
end.
find_in_binary(Byte, Bin) ->
- case string:chr(binary_to_list(Bin),Byte) of
- 0 -> notfound;
- P -> P
+ case string:find(Bin, [Byte]) of
+ nomatch -> notfound;
+ Suffix -> byte_size(Bin) - byte_size(Suffix) + 1
end.
ssl(Config) when is_list(Config) ->
@@ -562,7 +562,7 @@ decode_pkt(Type,Bin,Opts) ->
otp_9389(Config) when is_list(Config) ->
Opts = [{packet_size, 16384}, {line_length, 3000}],
Pkt = list_to_binary(["GET / HTTP/1.1\r\nHost: localhost\r\nLink: /",
- string:chars($X, 8192),
+ lists:duplicate(8192, $X),
"\r\nContent-Length: 0\r\n\r\n"]),
<<Pkt1:5000/binary, Pkt2/binary>> = Pkt,
{ok, {http_request,'GET',{abs_path,"/"},{1,1}}, Rest1} =
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index 17cd1d1a3b..f1831b7c45 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -35,13 +35,18 @@
-include_lib("common_test/include/ct.hrl").
+%-define(Line, erlang:display({line,?LINE}),).
+-define(Line,).
+
-export([all/0, suite/0, groups/0,
ping/1, bulk_send_small/1,
+ group_leader/1,
+ optimistic_dflags/1,
bulk_send_big/1, bulk_send_bigbig/1,
local_send_small/1, local_send_big/1,
local_send_legal/1, link_to_busy/1, exit_to_busy/1,
lost_exit/1, link_to_dead/1, link_to_dead_new_node/1,
- applied_monitor_node/1, ref_port_roundtrip/1, nil_roundtrip/1,
+ ref_port_roundtrip/1, nil_roundtrip/1,
trap_bif_1/1, trap_bif_2/1, trap_bif_3/1,
stop_dist/1,
dist_auto_connect_never/1, dist_auto_connect_once/1,
@@ -61,6 +66,8 @@
%% Internal exports.
-export([sender/3, receiver2/2, dummy_waiter/0, dead_process/0,
+ group_leader_1/1,
+ optimistic_dflags_echo/0, optimistic_dflags_sender/1,
roundtrip/1, bounce/1, do_dist_auto_connect/1, inet_rpc_server/1,
dist_parallel_sender/3, dist_parallel_receiver/0,
dist_evil_parallel_receiver/0]).
@@ -74,8 +81,10 @@ suite() ->
all() ->
[ping, {group, bulk_send}, {group, local_send},
+ group_leader,
+ optimistic_dflags,
link_to_busy, exit_to_busy, lost_exit, link_to_dead,
- link_to_dead_new_node, applied_monitor_node,
+ link_to_dead_new_node,
ref_port_roundtrip, nil_roundtrip, stop_dist,
{group, trap_bif}, {group, dist_auto_connect},
dist_parallel_send, atom_roundtrip, unicode_atom_roundtrip,
@@ -124,6 +133,96 @@ ping(Config) when is_list(Config) ->
ok.
+%% Test erlang:group_leader(_, ExternalPid), i.e. DOP_GROUP_LEADER
+group_leader(Config) when is_list(Config) ->
+ ?Line Sock = start_relay_node(group_leader_1, []),
+ ?Line Sock2 = start_relay_node(group_leader_2, []),
+ try
+ ?Line Node2 = inet_rpc_nodename(Sock2),
+ ?Line {ok, ok} = do_inet_rpc(Sock, ?MODULE, group_leader_1, [Node2])
+ after
+ ?Line stop_relay_node(Sock),
+ ?Line stop_relay_node(Sock2)
+ end,
+ ok.
+
+group_leader_1(Node2) ->
+ ?Line ExtPid = spawn(Node2, fun F() ->
+ receive {From, group_leader} ->
+ From ! {self(), group_leader, group_leader()}
+ end,
+ F()
+ end),
+ ?Line GL1 = self(),
+ ?Line group_leader(GL1, ExtPid),
+ ?Line ExtPid ! {self(), group_leader},
+ ?Line {ExtPid, group_leader, GL1} = receive_one(),
+
+ %% Kill connection and repeat test when group_leader/2 triggers auto-connect
+ ?Line net_kernel:monitor_nodes(true),
+ ?Line net_kernel:disconnect(Node2),
+ ?Line {nodedown, Node2} = receive_one(),
+ ?Line GL2 = spawn(fun() -> dummy end),
+ ?Line group_leader(GL2, ExtPid),
+ ?Line {nodeup, Node2} = receive_one(),
+ ?Line ExtPid ! {self(), group_leader},
+ ?Line {ExtPid, group_leader, GL2} = receive_one(),
+ ok.
+
+%% Test optimistic distribution flags toward pending connections (DFLAG_DIST_HOPEFULLY)
+optimistic_dflags(Config) when is_list(Config) ->
+ ?Line Sender = start_relay_node(optimistic_dflags_sender, []),
+ ?Line Echo = start_relay_node(optimistic_dflags_echo, []),
+ try
+ ?Line {ok, ok} = do_inet_rpc(Echo, ?MODULE, optimistic_dflags_echo, []),
+
+ ?Line EchoNode = inet_rpc_nodename(Echo),
+ ?Line {ok, ok} = do_inet_rpc(Sender, ?MODULE, optimistic_dflags_sender, [EchoNode])
+ after
+ ?Line stop_relay_node(Sender),
+ ?Line stop_relay_node(Echo)
+ end,
+ ok.
+
+optimistic_dflags_echo() ->
+ P = spawn(fun F() ->
+ receive {From, Term} ->
+ From ! {self(), Term}
+ end,
+ F()
+ end),
+ register(optimistic_dflags_echo, P),
+ optimistic_dflags_echo ! {self(), hello},
+ {P, hello} = receive_one(),
+ ok.
+
+optimistic_dflags_sender(EchoNode) ->
+ ?Line net_kernel:monitor_nodes(true),
+
+ optimistic_dflags_do(EchoNode, <<1:1>>),
+ optimistic_dflags_do(EchoNode, fun lists:map/2),
+ ok.
+
+optimistic_dflags_do(EchoNode, Term) ->
+ ?Line {optimistic_dflags_echo, EchoNode} ! {self(), Term},
+ ?Line {nodeup, EchoNode} = receive_one(),
+ ?Line {EchoPid, Term} = receive_one(),
+ %% repeat with pid destination
+ ?Line net_kernel:disconnect(EchoNode),
+ ?Line {nodedown, EchoNode} = receive_one(),
+ ?Line EchoPid ! {self(), Term},
+ ?Line {nodeup, EchoNode} = receive_one(),
+ ?Line {EchoPid, Term} = receive_one(),
+
+ ?Line net_kernel:disconnect(EchoNode),
+ ?Line {nodedown, EchoNode} = receive_one(),
+ ok.
+
+
+receive_one() ->
+ receive M -> M after 1000 -> timeout end.
+
+
bulk_send_small(Config) when is_list(Config) ->
bulk_send(64, 32).
@@ -639,26 +738,6 @@ link_to_dead_new_node(Config) when is_list(Config) ->
end,
ok.
-%% Test that monitor_node/2 works when applied.
-applied_monitor_node(Config) when is_list(Config) ->
- NonExisting = list_to_atom("__non_existing__@" ++ hostname()),
-
- %% Tail-recursive call to apply (since the node is non-existing,
- %% there will be a trap).
-
- true = tail_apply(erlang, monitor_node, [NonExisting, true]),
- [{nodedown, NonExisting}] = test_server:messages_get(),
-
- %% Ordinary call (with trap).
-
- true = apply(erlang, monitor_node, [NonExisting, true]),
- [{nodedown, NonExisting}] = test_server:messages_get(),
-
- ok.
-
-tail_apply(M, F, A) ->
- apply(M, F, A).
-
%% Test that sending a port or reference to another node and back again
%% doesn't correct them in any way.
ref_port_roundtrip(Config) when is_list(Config) ->
@@ -786,8 +865,8 @@ dist_auto_connect_once(Config) when is_list(Config) ->
{ok, pong} = do_inet_rpc(Sock2,net_adm,ping,[NN]),
{ok,[NN2]} = do_inet_rpc(Sock,erlang,nodes,[]),
{ok,[NN]} = do_inet_rpc(Sock2,erlang,nodes,[]),
- [_,HostPartPeer] = string:tokens(atom_to_list(NN),"@"),
- [_,MyHostPart] = string:tokens(atom_to_list(node()),"@"),
+ [_,HostPartPeer] = string:lexemes(atom_to_list(NN),"@"),
+ [_,MyHostPart] = string:lexemes(atom_to_list(node()),"@"),
% Give net_kernel a chance to change the state of the node to up to.
receive after 1000 -> ok end,
case HostPartPeer of
@@ -1158,8 +1237,6 @@ contended_atom_cache_entry_test(Config, Type) ->
spawn_link(
SNode,
fun () ->
- erts_debug:set_internal_state(available_internal_state,
- true),
Master = self(),
CIX = get_cix(),
TestAtoms = case Type of
@@ -1244,7 +1321,7 @@ get_cix(CIX) when is_integer(CIX), CIX < 0 ->
get_cix(CIX) when is_integer(CIX) ->
get_cix(CIX,
unwanted_cixs(),
- erts_debug:get_internal_state(max_atom_out_cache_index)).
+ get_internal_state(max_atom_out_cache_index)).
get_cix(CIX, Unwanted, MaxCIX) when CIX > MaxCIX ->
get_cix(0, Unwanted, MaxCIX);
@@ -1256,8 +1333,8 @@ get_cix(CIX, Unwanted, MaxCIX) ->
unwanted_cixs() ->
lists:map(fun (Node) ->
- erts_debug:get_internal_state({atom_out_cache_index,
- Node})
+ get_internal_state({atom_out_cache_index,
+ Node})
end,
nodes()).
@@ -1266,7 +1343,7 @@ get_conflicting_atoms(_CIX, 0) ->
[];
get_conflicting_atoms(CIX, N) ->
Atom = list_to_atom("atom" ++ integer_to_list(erlang:unique_integer([positive]))),
- case erts_debug:get_internal_state({atom_out_cache_index, Atom}) of
+ case get_internal_state({atom_out_cache_index, Atom}) of
CIX ->
[Atom|get_conflicting_atoms(CIX, N-1)];
_ ->
@@ -1277,7 +1354,7 @@ get_conflicting_unicode_atoms(_CIX, 0) ->
[];
get_conflicting_unicode_atoms(CIX, N) ->
Atom = string_to_atom([16#1f608] ++ "atom" ++ integer_to_list(erlang:unique_integer([positive]))),
- case erts_debug:get_internal_state({atom_out_cache_index, Atom}) of
+ case get_internal_state({atom_out_cache_index, Atom}) of
CIX ->
[Atom|get_conflicting_unicode_atoms(CIX, N-1)];
_ ->
@@ -1365,81 +1442,59 @@ bad_dist_structure(Config) when is_list(Config) ->
start_monitor(Offender,P),
P ! one,
send_bad_structure(Offender, P,{?DOP_MONITOR_P_EXIT,'replace',P,normal},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_monitor(Offender,P),
send_bad_structure(Offender, P,{?DOP_MONITOR_P_EXIT,'replace',P,normal,normal},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_link(Offender,P),
send_bad_structure(Offender, P,{?DOP_LINK},0),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_link(Offender,P),
send_bad_structure(Offender, P,{?DOP_UNLINK,'replace'},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_link(Offender,P),
send_bad_structure(Offender, P,{?DOP_UNLINK,'replace',make_ref()},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_link(Offender,P),
send_bad_structure(Offender, P,{?DOP_UNLINK,make_ref(),P},0),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_link(Offender,P),
send_bad_structure(Offender, P,{?DOP_UNLINK,normal,normal},0),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_monitor(Offender,P),
send_bad_structure(Offender, P,{?DOP_MONITOR_P,'replace',P},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_monitor(Offender,P),
send_bad_structure(Offender, P,{?DOP_MONITOR_P,'replace',P,normal},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_monitor(Offender,P),
send_bad_structure(Offender, P,{?DOP_DEMONITOR_P,'replace',P},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
start_monitor(Offender,P),
send_bad_structure(Offender, P,{?DOP_DEMONITOR_P,'replace',P,normal},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
+
send_bad_structure(Offender, P,{?DOP_EXIT,'replace',P},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_EXIT,make_ref(),normal,normal},0),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_EXIT_TT,'replace',token,P},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_EXIT_TT,make_ref(),token,normal,normal},0),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_EXIT2,'replace',P},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_EXIT2,make_ref(),normal,normal},0),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_EXIT2_TT,'replace',token,P},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_EXIT2_TT,make_ref(),token,normal,normal},0),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_GROUP_LEADER,'replace'},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_GROUP_LEADER,'replace','atomic'},2),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_GROUP_LEADER,'replace',P},0),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_REG_SEND_TT,'replace','',name},2,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_REG_SEND_TT,'replace','',name,token},0,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace',''},2,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace','',P},0,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace','',name},0,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace','',name,{token}},2,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_SEND_TT,'',P},0,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_SEND_TT,'',name,token},0,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_SEND,''},0,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_SEND,'',name},0,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
send_bad_structure(Offender, P,{?DOP_SEND,'',P,{token}},0,{message}),
- pong = rpc:call(Victim, net_adm, ping, [Offender]),
P ! two,
P ! check_msgs,
receive
@@ -1685,13 +1740,16 @@ bad_dist_ext_size(Config) when is_list(Config) ->
start_node_monitors([Offender,Victim]),
Parent = self(),
- P = spawn_link(Victim,
+ P = spawn_opt(Victim,
fun () ->
Parent ! {self(), started},
receive check_msgs -> ok end, %% DID CRASH HERE
bad_dist_ext_check_msgs([one]),
Parent ! {self(), messages_checked}
- end),
+ end,
+ [link,
+ %% on_heap to force total_heap_size to inspect msg queue
+ {message_queue_data, on_heap}]),
receive {P, started} -> ok end,
P ! one,
@@ -1714,6 +1772,7 @@ bad_dist_ext_size(Config) when is_list(Config) ->
verify_still_up(Offender, Victim),
+ %% Let process_info(P, total_heap_size) find bad msg and disconnect
rpc:call(Victim, erlang, process_info, [P, total_heap_size]),
verify_down(Offender, connection_closed, Victim, killed),
@@ -1795,10 +1854,11 @@ send_bad_structure(Offender,Victim,Bad,WhereToPutSelf) ->
send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,PayLoad) ->
Parent = self(),
Done = make_ref(),
- spawn(Offender,
+ spawn_link(Offender,
fun () ->
Node = node(Victim),
pong = net_adm:ping(Node),
+ erlang:monitor_node(Node, true),
DCtrl = dctrl(Node),
Bad1 = case WhereToPutSelf of
0 ->
@@ -1812,7 +1872,16 @@ send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,PayLoad) ->
[] -> [];
_Other -> [dmsg_ext(PayLoad)]
end,
+
+ receive {nodedown, Node} -> exit("premature nodedown")
+ after 10 -> ok
+ end,
+
dctrl_send(DCtrl, DData),
+
+ receive {nodedown, Node} -> ok
+ after 5000 -> exit("missing nodedown")
+ end,
Parent ! {DData,Done}
end),
receive
@@ -1893,11 +1962,26 @@ send_bad_dhdr(BadNode, ToNode) when is_atom(BadNode), is_atom(ToNode) ->
receive Done -> ok end.
dctrl(Node) when is_atom(Node) ->
- case catch erts_debug:get_internal_state(available_internal_state) of
- true -> true;
- _ -> erts_debug:set_internal_state(available_internal_state, true)
- end,
- erts_debug:get_internal_state({dist_ctrl, Node}).
+ get_internal_state({dist_ctrl, Node}).
+
+get_internal_state(Op) ->
+ try erts_debug:get_internal_state(Op) of
+ R -> R
+ catch
+ error:undef ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ erts_debug:get_internal_state(Op)
+ end.
+
+set_internal_state(Op, Val) ->
+ try erts_debug:set_internal_state(Op, Val) of
+ R -> R
+ catch
+ error:undef ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ erts_debug:set_internal_state(Op, Val)
+ end.
+
dmsg_hdr() ->
[131, % Version Magic
@@ -2040,11 +2124,9 @@ freeze_node(Node, MS) ->
Freezer = self(),
spawn_link(Node,
fun () ->
- erts_debug:set_internal_state(available_internal_state,
- true),
dctrl_dop_send(Freezer, DoingIt),
receive after Own -> ok end,
- erts_debug:set_internal_state(block, MS+Own)
+ set_internal_state(block, MS+Own)
end),
receive DoingIt -> ok end,
receive after Own -> ok end.
@@ -2094,7 +2176,7 @@ start_relay_node(Node, Args) ->
[{args, Args ++
" -setcookie "++Cookie++" -pa "++Pa++" "++
RunArg}]),
- [N,H] = string:tokens(atom_to_list(NN),"@"),
+ [N,H] = string:lexemes(atom_to_list(NN),"@"),
{ok, Sock} = gen_tcp:accept(LSock),
pang = net_adm:ping(NN),
{N,H,Sock}.
@@ -2248,8 +2330,7 @@ forever(Fun) ->
forever(Fun).
abort(Why) ->
- erts_debug:set_internal_state(available_internal_state, true),
- erts_debug:set_internal_state(abort, Why).
+ set_internal_state(abort, Why).
start_busy_dist_port_tracer() ->
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index 33d0b708cf..475e03087a 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -1192,9 +1192,9 @@ check_driver_system_info_result(Result) ->
io:format("All names: ~p~n", [?EXPECTED_SYSTEM_INFO_NAMES]),
io:format("Result: ~p~n", [Result]),
{[], Ns, DDVSN} = chk_sis(lists:map(fun (Str) ->
- string:tokens(Str, "=")
+ string:lexemes(Str, "=")
end,
- string:tokens(Result, " ")),
+ string:lexemes(Result, " ")),
?EXPECTED_SYSTEM_INFO_NAMES),
case {DDVSN,
drv_vsn_str2tup(erlang:system_info(driver_version))} of
@@ -2438,7 +2438,7 @@ wait_until(Fun) ->
end.
drv_vsn_str2tup(Str) ->
- [Major, Minor] = string:tokens(Str, "."),
+ [Major, Minor] = string:lexemes(Str, "."),
{list_to_integer(Major), list_to_integer(Minor)}.
%% Build port data from a template.
diff --git a/erts/emulator/test/erl_link_SUITE.erl b/erts/emulator/test/erl_link_SUITE.erl
index d8c5b663e3..a66ca7a57d 100644
--- a/erts/emulator/test/erl_link_SUITE.erl
+++ b/erts/emulator/test/erl_link_SUITE.erl
@@ -200,13 +200,16 @@ monitor_nodes(Config) when is_list(Config) ->
monitor_node(A, true),
check_monitor_node(self(), A, 1),
check_monitor_node(self(), B, 3),
+ ok = receive {nodedown, C} -> ok after 1000 -> timeout end,
+ %%OTP-21: monitor_node(_,false) does not trigger auto-connect anymore
+ %% and therefore no nodedown if it fails.
+ %%ok = receive {nodedown, C} -> ok after 1000 -> timeout end,
+ ok = receive {nodedown, C} -> ok after 1000 -> timeout end,
+ ok = receive {nodedown, D} -> ok after 1000 -> timeout end,
+ ok = receive {nodedown, D} -> ok after 1000 -> timeout end,
check_monitor_node(self(), C, 0),
check_monitor_node(self(), D, 0),
- receive {nodedown, C} -> ok end,
- receive {nodedown, C} -> ok end,
- receive {nodedown, C} -> ok end,
- receive {nodedown, D} -> ok end,
- receive {nodedown, D} -> ok end,
+
stop_node(A),
receive {nodedown, A} -> ok end,
check_monitor_node(self(), A, 0),
diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl
index be90f929df..7df001fec5 100644
--- a/erts/emulator/test/node_container_SUITE.erl
+++ b/erts/emulator/test/node_container_SUITE.erl
@@ -966,6 +966,8 @@ check_refc(ThisNodeName,ThisCreation,Table,EntryList) when is_list(EntryList) ->
{case Referrer of
{system,delayed_delete_timer} ->
true;
+ {system,thread_progress_delete_timer} ->
+ true;
_ ->
DDT
end,
diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl
index 1c76eb8019..17555d63c6 100644
--- a/erts/emulator/test/num_bif_SUITE.erl
+++ b/erts/emulator/test/num_bif_SUITE.erl
@@ -145,7 +145,7 @@ t_float_to_string(Config) when is_list(Config) ->
123456789012345678.0, [{decimals, 237}])),
{'EXIT', {badarg, _}} = (catch float_to_binary(
123456789012345678.0, [{decimals, 237}])),
- test_fts("1." ++ string:copies("0", 249) ++ "e+00",
+ test_fts("1." ++ lists:duplicate(249, $0) ++ "e+00",
1.0, [{scientific, 249}, compact]),
X1 = float_to_list(1.0),
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index 730a17d7e8..e46665a881 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -1035,6 +1035,9 @@ huge_env(Config) when is_list(Config) ->
try erlang:open_port({spawn,Cmd},[exit_status, {env, Env}]) of
P ->
receive
+ {P, {exit_status,N}} = M when N > 127->
+ %% If exit status is > 127 something went very wrong
+ ct:fail("Open port failed got ~p",[M]);
{P, {exit_status,N}} = M ->
%% We test that the exit status is an integer, this means
%% that the child program has started. If we get an atom
@@ -1662,13 +1665,7 @@ spawn_executable(Config) when is_list(Config) ->
[ExactFile2,"hello world","dlrow olleh"] =
run_echo_args_2(unicode:characters_to_binary("\""++ExactFile2++"\" "++"\"hello world\" \"dlrow olleh\"")),
- ExeExt =
- case string:to_lower(lists:last(string:tokens(ExactFile2,"."))) of
- "exe" ->
- ".exe";
- _ ->
- ""
- end,
+ ExeExt = filename:extension(ExactFile2),
Executable2 = "spoky name"++ExeExt,
file:copy(ExactFile1,filename:join([SpaceDir,Executable2])),
ExactFile3 = filename:nativename(filename:join([SpaceDir,Executable2])),
@@ -1836,7 +1833,7 @@ collect_data(Port) ->
end.
parse_echo_args_output(Data) ->
- [lists:last(string:tokens(S,"|")) || S <- string:tokens(Data,"\r\n")].
+ [lists:last(string:lexemes(S,"|")) || S <- string:lexemes(Data,["\r\n",$\n])].
%% Test that the emulator does not mix up ports when the port table wraps
mix_up_ports(Config) when is_list(Config) ->
@@ -1962,7 +1959,7 @@ max_ports() ->
erlang:system_info(port_limit).
port_ix(Port) when is_port(Port) ->
- ["#Port",_,PortIxStr] = string:tokens(erlang:port_to_list(Port),
+ ["#Port",_,PortIxStr] = string:lexemes(erlang:port_to_list(Port),
"<.>"),
list_to_integer(PortIxStr).
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index a9f20f9928..a8bcfac84d 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -2532,8 +2532,13 @@ system_task_on_suspended(Config) when is_list(Config) ->
end.
gc_request_when_gc_disabled(Config) when is_list(Config) ->
- Master = self(),
AIS = erts_debug:set_internal_state(available_internal_state, true),
+ gc_request_when_gc_disabled_do(ref),
+ gc_request_when_gc_disabled_do(immed),
+ erts_debug:set_internal_state(available_internal_state, AIS).
+
+gc_request_when_gc_disabled_do(ReqIdType) ->
+ Master = self(),
{P, M} = spawn_opt(fun () ->
true = erts_debug:set_internal_state(gc_state,
false),
@@ -2545,7 +2550,10 @@ gc_request_when_gc_disabled(Config) when is_list(Config) ->
receive after 100 -> ok end
end, [monitor, link]),
receive {P, gc_state, false} -> ok end,
- ReqId = make_ref(),
+ ReqId = case ReqIdType of
+ ref -> make_ref();
+ immed -> immed
+ end,
async = garbage_collect(P, [{async, ReqId}]),
receive
{garbage_collect, ReqId, Result} ->
@@ -2554,7 +2562,6 @@ gc_request_when_gc_disabled(Config) when is_list(Config) ->
ok
end,
receive {garbage_collect, ReqId, true} -> ok end,
- erts_debug:set_internal_state(available_internal_state, AIS),
receive {'DOWN', M, process, P, _Reason} -> ok end,
ok.
diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl
index a12019ec83..1fe11428b4 100644
--- a/erts/emulator/test/receive_SUITE.erl
+++ b/erts/emulator/test/receive_SUITE.erl
@@ -25,14 +25,16 @@
-include_lib("common_test/include/ct.hrl").
-export([all/0, suite/0,
- call_with_huge_message_queue/1,receive_in_between/1]).
+ call_with_huge_message_queue/1,receive_in_between/1,
+ receive_opt_exception/1,receive_opt_recursion/1]).
suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap, {minutes, 3}}].
-all() ->
- [call_with_huge_message_queue, receive_in_between].
+all() ->
+ [call_with_huge_message_queue, receive_in_between,
+ receive_opt_exception, receive_opt_recursion].
call_with_huge_message_queue(Config) when is_list(Config) ->
Pid = spawn_link(fun echo_loop/0),
@@ -113,6 +115,60 @@ receive_one() ->
dummy -> ok
end.
+receive_opt_exception(_Config) ->
+ Recurse = fun() ->
+ %% Overwrite with the same mark,
+ %% and never consume it.
+ ThrowFun = fun() -> throw(aborted) end,
+ aborted = (catch do_receive_opt_exception(ThrowFun)),
+ ok
+ end,
+ do_receive_opt_exception(Recurse),
+
+ %% Eat the second message.
+ receive
+ Ref when is_reference(Ref) -> ok
+ end.
+
+do_receive_opt_exception(Disturber) ->
+ %% Create a receive mark.
+ Ref = make_ref(),
+ self() ! Ref,
+ Disturber(),
+ receive
+ Ref ->
+ ok
+ after 0 ->
+ error(the_expected_message_was_not_there)
+ end.
+
+receive_opt_recursion(_Config) ->
+ Recurse = fun() ->
+ %% Overwrite with the same mark,
+ %% and never consume it.
+ NoOp = fun() -> ok end,
+ BlackHole = spawn(NoOp),
+ expected = do_receive_opt_recursion(BlackHole, NoOp, true),
+ ok
+ end,
+ do_receive_opt_recursion(self(), Recurse, false),
+ ok.
+
+do_receive_opt_recursion(Recipient, Disturber, IsInner) ->
+ Ref = make_ref(),
+ Recipient ! Ref,
+ Disturber(),
+ receive
+ Ref -> ok
+ after 0 ->
+ case IsInner of
+ true ->
+ expected;
+ false ->
+ error(the_expected_message_was_not_there)
+ end
+ end.
+
%%%
%%% Common helpers.
%%%
diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl
index 7afb82a1b8..7eebbe8b19 100644
--- a/erts/emulator/test/scheduler_SUITE.erl
+++ b/erts/emulator/test/scheduler_SUITE.erl
@@ -894,11 +894,9 @@ adjust_schedulers_online() ->
read_affinity(Data) ->
Exp = "pid " ++ os:getpid() ++ "'s current affinity mask",
- case string:tokens(Data, ":") of
+ case string:lexemes(Data, ":") of
[Exp, DirtyAffinityStr] ->
- AffinityStr = string:strip(string:strip(DirtyAffinityStr,
- both, $ ),
- both, $\n),
+ AffinityStr = string:trim(DirtyAffinityStr),
case catch erlang:list_to_integer(AffinityStr, 16) of
Affinity when is_integer(Affinity) ->
Affinity;
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index 56522039da..fdf4aab24d 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -308,9 +308,9 @@ memory_test(_Config) ->
mem_workers_call(MWs,
fun () ->
- list_to_atom("an ugly atom "++integer_to_list(erlang:system_info(scheduler_id))),
- list_to_atom("another ugly atom "++integer_to_list(erlang:system_info(scheduler_id))),
- list_to_atom("yet another ugly atom "++integer_to_list(erlang:system_info(scheduler_id)))
+ _ = list_to_atom("an ugly atom "++integer_to_list(erlang:system_info(scheduler_id))),
+ _ = list_to_atom("another ugly atom "++integer_to_list(erlang:system_info(scheduler_id))),
+ _ = list_to_atom("yet another ugly atom "++integer_to_list(erlang:system_info(scheduler_id)))
end, []),
cmp_memory(MWs, "new atoms"),