aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/binary_SUITE.erl123
-rw-r--r--erts/emulator/test/driver_SUITE.erl94
-rw-r--r--erts/emulator/test/process_SUITE.erl40
3 files changed, 193 insertions, 64 deletions
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 7e409f053e..4e82381fba 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -23,12 +23,12 @@
%% Tests binaries and the BIFs:
%% list_to_binary/1
%% iolist_to_binary/1
-%% bitstr_to_list/1
+%% list_to_bitstring/1
%% binary_to_list/1
%% binary_to_list/3
%% binary_to_term/1
%% binary_to_term/2
-%% bitstr_to_list/1
+%% bitstring_to_list/1
%% term_to_binary/1
%% erlang:external_size/1
%% size(Binary)
@@ -275,12 +275,33 @@ bad_list_to_binary(Config) when is_list(Config) ->
?line test_bad_bin(fun(X, Y) -> X*Y end),
?line test_bad_bin([1,fun(X) -> X + 1 end,2|fun() -> 0 end]),
?line test_bad_bin([fun(X) -> X + 1 end]),
+
+ %% Test iolists that do not fit in the address space.
+ %% Unfortunately, it would be too slow to test in a 64-bit emulator.
+ case erlang:system_info(wordsize) of
+ 4 -> huge_iolists();
+ _ -> ok
+ end.
+
+huge_iolists() ->
+ FourGigs = 1 bsl 32,
+ ?line Sizes = [FourGigs+N || N <- lists:seq(0, 64)] ++
+ [1 bsl N || N <- lists:seq(33, 37)],
+ ?line Base = <<0:(1 bsl 20)/unit:8>>,
+ [begin
+ L = build_iolist(Sz, Base),
+ ?line {'EXIT',{system_limit,_}} = (catch list_to_binary([L])),
+ ?line {'EXIT',{system_limit,_}} = (catch list_to_bitstring([L])),
+ ?line {'EXIT',{system_limit,_}} = (catch binary:list_to_bin([L])),
+ ?line {'EXIT',{system_limit,_}} = (catch iolist_to_binary(L))
+ end || Sz <- Sizes],
ok.
test_bad_bin(List) ->
{'EXIT',{badarg,_}} = (catch list_to_binary(List)),
{'EXIT',{badarg,_}} = (catch iolist_to_binary(List)),
- {'EXIT',{badarg,_}} = (catch list_to_bitstring(List)).
+ {'EXIT',{badarg,_}} = (catch list_to_bitstring(List)),
+ {'EXIT',{badarg,_}} = (catch iolist_size(List)).
bad_binary_to_list(doc) -> "Tries binary_to_list/1,3 with bad arguments.";
bad_binary_to_list(Config) when is_list(Config) ->
@@ -516,18 +537,65 @@ external_size_1(Term, Size0, Limit) when Size0 < Limit ->
external_size_1(_, _, _) -> ok.
t_iolist_size(Config) when is_list(Config) ->
- %% Build a term whose external size only fits in a big num (on 32-bit CPU).
- Bin = iolist_to_binary(lists:seq(0, 254)),
- ?line ok = t_iolist_size_1(Bin, 0, 16#7FFFFFFF),
- ?line ok = t_iolist_size_1(make_unaligned_sub_binary(Bin), 0, 16#7FFFFFFF).
+ ?line Seed = now(),
+ ?line io:format("Seed: ~p", [Seed]),
+ ?line random:seed(Seed),
+ ?line Base = <<0:(1 bsl 20)/unit:8>>,
+ ?line Powers = [1 bsl N || N <- lists:seq(2, 37)],
+ ?line Sizes0 = [[N - random:uniform(N div 2),
+ lists:seq(N-2, N+2),
+ N+N div 2,
+ N + random:uniform(N div 2)] ||
+ N <- Powers],
+ %% Test sizes around 1^32 more thoroughly.
+ FourGigs = 1 bsl 32,
+ ?line Sizes1 = [FourGigs+N || N <- lists:seq(-8, 40)] ++ Sizes0,
+ ?line Sizes2 = lists:flatten(Sizes1),
+ ?line Sizes = lists:usort(Sizes2),
+ io:format("~p sizes:", [length(Sizes)]),
+ io:format("~p\n", [Sizes]),
+ ?line [Sz = iolist_size(build_iolist(Sz, Base)) || Sz <- Sizes],
+ ok.
-t_iolist_size_1(IOList, Size0, Limit) when Size0 < Limit ->
- case iolist_size(IOList) of
- Size when is_integer(Size), Size0 < Size ->
- io:format("~p", [Size]),
- t_iolist_size_1([IOList|IOList], Size, Limit)
+build_iolist(N, Base) when N < 16 ->
+ case random:uniform(3) of
+ 1 ->
+ <<Bin:N/binary,_/binary>> = Base,
+ Bin;
+ _ ->
+ lists:seq(1, N)
+ end;
+build_iolist(N, Base) when N =< byte_size(Base) ->
+ case random:uniform(3) of
+ 1 ->
+ <<Bin:N/binary,_/binary>> = Base,
+ Bin;
+ 2 ->
+ <<Bin:N/binary,_/binary>> = Base,
+ [Bin];
+ 3 ->
+ case N rem 2 of
+ 0 ->
+ L = build_iolist(N div 2, Base),
+ [L,L];
+ 1 ->
+ L = build_iolist(N div 2, Base),
+ [L,L,45]
+ end
end;
-t_iolist_size_1(_, _, _) -> ok.
+build_iolist(N0, Base) ->
+ Small = random:uniform(15),
+ Seq = lists:seq(1, Small),
+ N = N0 - Small,
+ case N rem 2 of
+ 0 ->
+ L = build_iolist(N div 2, Base),
+ [L,L|Seq];
+ 1 ->
+ L = build_iolist(N div 2, Base),
+ [47,L,L|Seq]
+ end.
+
bad_binary_to_term_2(doc) -> "OTP-4053.";
bad_binary_to_term_2(suite) -> [];
@@ -1183,34 +1251,7 @@ deep(Config) when is_list(Config) ->
deep_roundtrip(T) ->
B = term_to_binary(T),
- true = deep_eq(T, binary_to_term(B)).
-
-%%
-%% FIXME: =:= runs out of stack.
-%%
-deep_eq([H1|T1], [H2|T2]) ->
- deep_eq(H1, H2) andalso deep_eq(T1, T2);
-deep_eq(T1, T2) when tuple_size(T1) =:= tuple_size(T2) ->
- deep_eq_tup(T1, T2, tuple_size(T1));
-deep_eq(T1, T2) when is_function(T1), is_function(T2) ->
- {uniq,U1} = erlang:fun_info(T1, uniq),
- {index,I1} = erlang:fun_info(T1, index),
- {arity,A1} = erlang:fun_info(T1, arity),
- {env,E1} = erlang:fun_info(T1, env),
- {uniq,U2} = erlang:fun_info(T2, uniq),
- {index,I2} = erlang:fun_info(T2, index),
- {arity,A2} = erlang:fun_info(T2, arity),
- {env,E2} = erlang:fun_info(T2, env),
- U1 =:= U2 andalso I1 =:= I2 andalso A1 =:= A2 andalso
- deep_eq(E1, E2);
-deep_eq(T1, T2) ->
- T1 =:= T2.
-
-deep_eq_tup(_T1, _T2, 0) ->
- true;
-deep_eq_tup(T1, T2, N) ->
- deep_eq(element(N, T1), element(N, T2)) andalso
- deep_eq_tup(T1, T2, N-1).
+ T = binary_to_term(B).
obsolete_funs(Config) when is_list(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index 7600a44988..520e3e8c76 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -38,7 +38,7 @@
timer_change/1,
timer_delay/1,
queue_echo/1,
- fun_to_port/1,
+ outputv_errors/1,
driver_unloaded/1,
io_ready_exit/1,
use_fallback_pollset/1,
@@ -129,7 +129,7 @@ end_per_testcase(Case, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [fun_to_port, outputv_echo, queue_echo, {group, timer},
+ [outputv_errors, outputv_echo, queue_echo, {group, timer},
driver_unloaded, io_ready_exit, use_fallback_pollset,
bad_fd_in_pollset, driver_event, fd_change,
steal_control, otp_6602, 'driver_system_info_ver1.0',
@@ -165,37 +165,89 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-
-fun_to_port(doc) -> "Test sending a fun to port with an outputv-capable driver.";
-fun_to_port(Config) when is_list(Config) ->
+outputv_errors(doc) -> "Test sending bad types to port with an outputv-capable driver.";
+outputv_errors(Config) when is_list(Config) ->
?line Path = ?config(data_dir, Config),
?line erl_ddll:start(),
?line ok = load_driver(Path, outputv_drv),
- ?line fun_to_port_1(fun() -> 33 end),
- ?line fun_to_port_1([fun() -> 42 end]),
- ?line fun_to_port_1([1|fun() -> 42 end]),
- L = build_io_list(65536),
- ?line fun_to_port_1([L,fun() -> 42 end]),
- ?line fun_to_port_1([L|fun() -> 42 end]),
+ outputv_bad_types(fun(T) ->
+ ?line outputv_errors_1(T),
+ ?line outputv_errors_1([1|T]),
+ ?line L = [1,2,3],
+ ?line outputv_errors_1([L,T]),
+ ?line outputv_errors_1([L|T])
+ end),
+ outputv_errors_1(42),
+
+ %% Test iolists that do not fit in the address space.
+ %% Unfortunately, it would be too slow to test in a 64-bit emulator.
+ case erlang:system_info(wordsize) of
+ 4 -> outputv_huge_iolists();
+ _ -> ok
+ end.
+
+outputv_bad_types(Test) ->
+ Types = [-1,256,atom,42.0,{a,b,c},make_ref(),fun() -> 42 end,
+ [1|2],<<1:1>>,<<1:9>>,<<1:15>>],
+ _ = [Test(Type) || Type <- Types],
ok.
-fun_to_port_1(Term) ->
- Port = open_port({spawn,outputv_drv}, []),
+outputv_huge_iolists() ->
+ FourGigs = 1 bsl 32,
+ ?line Sizes = [FourGigs+N || N <- lists:seq(0, 64)] ++
+ [1 bsl N || N <- lists:seq(33, 37)],
+ ?line Base = <<0:(1 bsl 20)/unit:8>>,
+ [begin
+ ?line L = build_iolist(Sz, Base),
+ ?line outputv_errors_1(L)
+ end || Sz <- Sizes],
+ ok.
+
+outputv_errors_1(Term) ->
+ Port = open_port({spawn_driver,outputv_drv}, []),
{'EXIT',{badarg,_}} = (catch port_command(Port, Term)),
port_close(Port).
-build_io_list(0) -> [];
-build_io_list(1) -> [7];
-build_io_list(N) ->
- L = build_io_list(N div 2),
+build_iolist(N, Base) when N < 16 ->
+ case random:uniform(3) of
+ 1 ->
+ <<Bin:N/binary,_/binary>> = Base,
+ Bin;
+ _ ->
+ lists:seq(1, N)
+ end;
+build_iolist(N, Base) when N =< byte_size(Base) ->
+ case random:uniform(3) of
+ 1 ->
+ <<Bin:N/binary,_/binary>> = Base,
+ Bin;
+ 2 ->
+ <<Bin:N/binary,_/binary>> = Base,
+ [Bin];
+ 3 ->
+ case N rem 2 of
+ 0 ->
+ L = build_iolist(N div 2, Base),
+ [L,L];
+ 1 ->
+ L = build_iolist(N div 2, Base),
+ [L,L,45]
+ end
+ end;
+build_iolist(N0, Base) ->
+ Small = random:uniform(15),
+ Seq = lists:seq(1, Small),
+ N = N0 - Small,
case N rem 2 of
- 0 -> [L|L];
- 1 -> [7,L|L]
+ 0 ->
+ L = build_iolist(N div 2, Base),
+ [L,L|Seq];
+ 1 ->
+ L = build_iolist(N div 2, Base),
+ [47,L,L|Seq]
end.
-
-
outputv_echo(doc) -> ["Test echoing data with a driver that supports outputv."];
outputv_echo(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:minutes(10)),
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 36bae908aa..f68e712268 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -50,7 +50,8 @@
processes_last_call_trap/1, processes_gc_trap/1,
processes_term_proc_list/1,
otp_7738_waiting/1, otp_7738_suspended/1,
- otp_7738_resume/1]).
+ otp_7738_resume/1,
+ garb_other_running/1]).
-export([prio_server/2, prio_client/2]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -72,7 +73,7 @@ all() ->
bad_register, garbage_collect, process_info_messages,
process_flag_badarg, process_flag_heap_size,
spawn_opt_heap_size, otp_6237, {group, processes_bif},
- {group, otp_7738}].
+ {group, otp_7738}, garb_other_running].
groups() ->
[{t_exit_2, [],
@@ -2116,6 +2117,41 @@ otp_7738_test(Type) ->
end,
?line ok.
+gor(Reds, Stop) ->
+ receive
+ {From, reds} ->
+ From ! {reds, Reds, self()},
+ gor(Reds+1, Stop);
+ {From, Stop} ->
+ From ! {stopped, Stop, Reds, self()}
+ after 0 ->
+ gor(Reds+1, Stop)
+ end.
+
+garb_other_running(Config) when is_list(Config) ->
+ ?line Stop = make_ref(),
+ ?line {Pid, Mon} = spawn_monitor(fun () -> gor(0, Stop) end),
+ ?line Reds = lists:foldl(fun (_, OldReds) ->
+ ?line erlang:garbage_collect(Pid),
+ ?line receive after 1 -> ok end,
+ ?line Pid ! {self(), reds},
+ ?line receive
+ {reds, NewReds, Pid} ->
+ ?line true = (NewReds > OldReds),
+ ?line NewReds
+ end
+ end,
+ 0,
+ lists:seq(1, 10000)),
+ ?line receive after 1 -> ok end,
+ ?line Pid ! {self(), Stop},
+ ?line receive
+ {stopped, Stop, StopReds, Pid} ->
+ ?line true = (StopReds > Reds)
+ end,
+ ?line receive {'DOWN', Mon, process, Pid, normal} -> ok end,
+ ?line ok.
+
%% Internal functions
wait_until(Fun) ->