aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib/test')
-rw-r--r--lib/stdlib/test/epp_SUITE.erl171
-rw-r--r--lib/stdlib/test/ets_SUITE.erl71
-rw-r--r--lib/stdlib/test/io_SUITE.erl24
-rw-r--r--lib/stdlib/test/qlc_SUITE.erl6
-rw-r--r--lib/stdlib/test/shell_SUITE.erl6
-rw-r--r--lib/stdlib/test/string_SUITE.erl24
6 files changed, 257 insertions, 45 deletions
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index 9123bf2f28..a3e294ffea 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -28,7 +28,8 @@
otp_8130/1, overload_mac/1, otp_8388/1, otp_8470/1,
otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1,
otp_11728/1, encoding/1, extends/1, function_macro/1,
- test_error/1, test_warning/1, otp_14285/1]).
+ test_error/1, test_warning/1, otp_14285/1,
+ test_if/1]).
-export([epp_parse_erl_form/2]).
@@ -69,7 +70,7 @@ all() ->
overload_mac, otp_8388, otp_8470, otp_8562,
otp_8665, otp_8911, otp_10302, otp_10820, otp_11728,
encoding, extends, function_macro, test_error, test_warning,
- otp_14285].
+ otp_14285, test_if].
groups() ->
[{upcase_mac, [], [upcase_mac_1, upcase_mac_2]},
@@ -799,7 +800,8 @@ otp_8130(Config) when is_list(Config) ->
PreDefMacs = macs(Epp),
['BASE_MODULE','BASE_MODULE_STRING','BEAM','FILE',
'FUNCTION_ARITY','FUNCTION_NAME',
- 'LINE','MACHINE','MODULE','MODULE_STRING'] = PreDefMacs,
+ 'LINE','MACHINE','MODULE','MODULE_STRING',
+ 'OTP_RELEASE'] = PreDefMacs,
{ok,[{'-',_},{atom,_,file}|_]} = epp:scan_erl_form(Epp),
{ok,[{'-',_},{atom,_,module}|_]} = epp:scan_erl_form(Epp),
{ok,[{atom,_,t}|_]} = epp:scan_erl_form(Epp),
@@ -952,27 +954,7 @@ ifdef(Config) ->
{define_c5,
<<"-\ndefine a.\n">>,
- {errors,[{{2,1},epp,{bad,define}}],[]}},
-
- {define_c6,
- <<"\n-if.\n"
- "-endif.\n">>,
- {errors,[{{2,2},epp,{'NYI','if'}}],[]}},
-
- {define_c7,
- <<"-ifndef(a).\n"
- "-elif.\n"
- "-endif.\n">>,
- {errors,[{{2,2},epp,{'NYI',elif}}],[]}},
-
- {define_c7,
- <<"-ifndef(a).\n"
- "-if.\n"
- "-elif.\n"
- "-endif.\n"
- "-endif.\n"
- "t() -> a.\n">>,
- {errors,[{{2,2},epp,{'NYI','if'}}],[]}}
+ {errors,[{{2,1},epp,{bad,define}}],[]}}
],
[] = compile(Config, Cs),
@@ -1117,6 +1099,147 @@ test_warning(Config) ->
[] = compile(Config, Cs),
ok.
+%% OTP-12847: Test the -if and -elif directives and the built-in
+%% function defined(Symbol).
+test_if(Config) ->
+ Cs = [{if_1c,
+ <<"-if.\n"
+ "-endif.\n"
+ "-if no_parentheses.\n"
+ "-endif.\n"
+ "-if(syntax error.\n"
+ "-endif.\n"
+ "-if(true).\n"
+ "-if(a+3).\n"
+ "syntax error not triggered here.\n"
+ "-endif.\n">>,
+ {errors,[{1,epp,{bad,'if'}},
+ {3,epp,{bad,'if'}},
+ {5,erl_parse,["syntax error before: ","error"]},
+ {11,epp,{illegal,"unterminated",'if'}}],
+ []}},
+
+ {if_2c, %Bad guard expressions.
+ <<"-if(is_list(integer_to_list(42))).\n" %Not guard BIF.
+ "-endif.\n"
+ "-if(begin true end).\n"
+ "-endif.\n">>,
+ {errors,[{1,epp,{bad,'if'}},
+ {3,epp,{bad,'if'}}],
+ []}},
+
+ {if_3c, %Invalid use of defined/1.
+ <<"-if defined(42).\n"
+ "-endif.\n">>,
+ {errors,[{1,epp,{bad,'if'}}],[]}},
+
+ {if_4c,
+ <<"-elif OTP_RELEASE > 18.\n">>,
+ {errors,[{1,epp,{illegal,"unbalanced",'elif'}}],[]}},
+
+ {if_5c,
+ <<"-ifdef(not_defined_today).\n"
+ "-else.\n"
+ "-elif OTP_RELEASE > 18.\n"
+ "-endif.\n">>,
+ {errors,[{3,epp,{illegal,"unbalanced",'elif'}}],[]}},
+
+ {if_6c,
+ <<"-if(defined(OTP_RELEASE)).\n"
+ "-else.\n"
+ "-elif(true).\n"
+ "-endif.\n">>,
+ {errors,[{3,epp,elif_after_else}],[]}},
+
+ {if_7c,
+ <<"-if(begin true end).\n" %Not a guard expression.
+ "-endif.\n">>,
+ {errors,[{1,epp,{bad,'if'}}],[]}}
+
+ ],
+ [] = compile(Config, Cs),
+
+ Ts = [{if_1,
+ <<"-if(?OTP_RELEASE > 18).\n"
+ "t() -> ok.\n"
+ "-else.\n"
+ "a bug.\n"
+ "-endif.\n">>,
+ ok},
+
+ {if_2,
+ <<"-if(false).\n"
+ "a bug.\n"
+ "-elif(?OTP_RELEASE > 18).\n"
+ "t() -> ok.\n"
+ "-else.\n"
+ "a bug.\n"
+ "-endif.\n">>,
+ ok},
+
+ {if_3,
+ <<"-if(true).\n"
+ "t() -> ok.\n"
+ "-elif(?OTP_RELEASE > 18).\n"
+ "a bug.\n"
+ "-else.\n"
+ "a bug.\n"
+ "-endif.\n">>,
+ ok},
+
+ {if_4,
+ <<"-define(a, 1).\n"
+ "-if(defined(a) andalso defined(OTP_RELEASE)).\n"
+ "t() -> ok.\n"
+ "-else.\n"
+ "a bug.\n"
+ "-endif.\n">>,
+ ok},
+
+ {if_5,
+ <<"-if(defined(a)).\n"
+ "a bug.\n"
+ "-else.\n"
+ "t() -> ok.\n"
+ "-endif.\n">>,
+ ok},
+
+ {if_6,
+ <<"-if(defined(not_defined_today)).\n"
+ " -if(true).\n"
+ " bug1.\n"
+ " -elif(true).\n"
+ " bug2.\n"
+ " -elif(true).\n"
+ " bug3.\n"
+ " -else.\n"
+ " bug4.\n"
+ " -endif.\n"
+ "-else.\n"
+ "t() -> ok.\n"
+ "-endif.\n">>,
+ ok},
+
+ {if_7,
+ <<"-if(not_builtin()).\n"
+ "a bug.\n"
+ "-else.\n"
+ "t() -> ok.\n"
+ "-endif.\n">>,
+ ok},
+
+ {if_8,
+ <<"-if(42).\n" %Not boolean.
+ "a bug.\n"
+ "-else.\n"
+ "t() -> ok.\n"
+ "-endif.\n">>,
+ ok}
+ ],
+ [] = run(Config, Ts),
+
+ ok.
+
%% Advanced test on overloading macros.
overload_mac(Config) when is_list(Config) ->
Cs = [
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 02211fa8df..a97fe4a5d9 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -87,6 +87,7 @@
-export([t_select_reverse/1]).
+-include_lib("stdlib/include/ms_transform.hrl"). % ets:fun2ms
-include_lib("common_test/include/ct.hrl").
-define(m(A,B), assert_eq(A,B)).
@@ -173,10 +174,12 @@ groups() ->
init_per_suite(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
+ erts_debug:set_internal_state(ets_force_trap, true),
Config.
end_per_suite(_Config) ->
stop_spawn_logger(),
+ erts_debug:set_internal_state(ets_force_trap, false),
catch erts_debug:set_internal_state(available_internal_state, false),
ok.
@@ -812,7 +815,60 @@ t_delete_all_objects_do(Opts) ->
4000 = ets:info(T,size),
true = ets:delete_all_objects(T),
0 = ets:info(T,size),
- ets:delete(T).
+ ets:delete(T),
+
+ %% Test delete_all_objects is atomic
+ T2 = ets:new(t_delete_all_objects, [public | Opts]),
+ Self = self(),
+ Inserters = [spawn_link(fun() -> inserter(T2, 100*1000, 1, Self) end) || _ <- [1,2,3,4]],
+ [receive {Ipid, running} -> ok end || Ipid <- Inserters],
+
+ ets:delete_all_objects(T2),
+ erlang:yield(),
+ [Ipid ! stop || Ipid <- Inserters],
+ Result = [receive {Ipid, stopped, Highest} -> {Ipid,Highest} end || Ipid <- Inserters],
+
+ %% Verify unbroken sequences of objects inserted _after_ ets:delete_all_objects.
+ Sum = lists:foldl(fun({Ipid, Highest}, AccSum) ->
+ %% ets:fun2ms(fun({{K,Ipid}}) when K =< Highest -> true end),
+ AliveMS = [{{{'$1',Ipid}},[{'=<','$1',{const,Highest}}],[true]}],
+ Alive = ets:select_count(T2, AliveMS),
+ Lowest = Highest - (Alive-1),
+
+ %% ets:fun2ms(fun({{K,Ipid}}) when K < Lowest -> true end)
+ DeletedMS = [{{{'$1',Ipid}},[{'<','$1',{const,Lowest}}],[true]}],
+ 0 = ets:select_count(T2, DeletedMS),
+ AccSum + Alive
+ end,
+ 0,
+ Result),
+ ok = case ets:info(T2, size) of
+ Sum -> ok;
+ Size ->
+ io:format("Sum = ~p\nSize = ~p\n", [Sum, Size]),
+ {Sum,Size}
+ end,
+
+ ets:delete(T2).
+
+inserter(_, 0, _, _) ->
+ ok;
+inserter(T, N, Next, Papa) ->
+ case Next of
+ 10*1000 ->
+ Papa ! {self(), running};
+ _ ->
+ ok
+ end,
+
+ ets:insert(T, {{Next, self()}}),
+ receive
+ stop ->
+ Papa ! {self(), stopped, Next},
+ ok
+ after 0 ->
+ inserter(T, N-1, Next+1, Papa)
+ end.
%% Test ets:delete_object/2.
@@ -6153,20 +6209,23 @@ spawn_logger(Procs) ->
ok;
(Proc) ->
Mon = erlang:monitor(process, Proc),
- receive
+ ok = receive
{'DOWN', Mon, _, _, _} ->
ok
after 0 ->
case Kill of
true -> exit(Proc, kill);
- _ ->
- erlang:display({"Waiting for 'DOWN' from", Proc,
- process_info(Proc),
- pid_status(Proc)})
+ _ -> ok
end,
receive
{'DOWN', Mon, _, _, _} ->
ok
+ after 5000 ->
+ io:format("Waiting for 'DOWN' from ~w, status=~w\n"
+ "info = ~p\n", [Proc,
+ pid_status(Proc),
+ process_info(Proc)]),
+ timeout
end
end
end, Procs),
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 9f48fbf5e3..91fe1133f6 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -31,7 +31,7 @@
otp_10836/1, io_lib_width_too_small/1,
io_with_huge_message_queue/1, format_string/1,
maps/1, coverage/1, otp_14178_unicode_atoms/1, otp_14175/1,
- otp_14285/1, limit_term/1, otp_14983/1]).
+ otp_14285/1, limit_term/1, otp_14983/1, otp_15103/1]).
-export([pretty/2, trf/3]).
@@ -63,7 +63,7 @@ all() ->
io_lib_print_binary_depth_one, otp_10302, otp_10755, otp_10836,
io_lib_width_too_small, io_with_huge_message_queue,
format_string, maps, coverage, otp_14178_unicode_atoms, otp_14175,
- otp_14285, limit_term, otp_14983].
+ otp_14285, limit_term, otp_14983, otp_15103].
%% Error cases for output.
error_1(Config) when is_list(Config) ->
@@ -1808,7 +1808,7 @@ rpc_call_max(Node, M, F, Args) ->
%% Make sure that a bad specification for a printable range is rejected.
bad_printable_range(Config) when is_list(Config) ->
- Cmd = lists:concat([lib:progname()," +pcunnnnnicode -run erlang halt"]),
+ Cmd = ct:get_progname() ++ " +pcunnnnnicode -run erlang halt",
P = open_port({spawn, Cmd}, [stderr_to_stdout, {line, 200}]),
ok = receive
{P, {data, {eol , "bad range of printable characters" ++ _}}} ->
@@ -2615,3 +2615,21 @@ trf(Format, Args, T) ->
trf(Format, Args, T, Opts) ->
lists:flatten(io_lib:format(Format, Args, [{chars_limit, T}|Opts])).
+
+otp_15103(_Config) ->
+ T = lists:duplicate(5, {a,b,c}),
+
+ S1 = io_lib:format("~0p", [T]),
+ "[{a,b,c},{a,b,c},{a,b,c},{a,b,c},{a,b,c}]" = lists:flatten(S1),
+ S2 = io_lib:format("~-0p", [T]),
+ "[{a,b,c},{a,b,c},{a,b,c},{a,b,c},{a,b,c}]" = lists:flatten(S2),
+ S3 = io_lib:format("~1p", [T]),
+ "[{a,\n b,\n c},\n {a,\n b,\n c},\n {a,\n b,\n c},\n {a,\n b,\n"
+ " c},\n {a,\n b,\n c}]" = lists:flatten(S3),
+
+ S4 = io_lib:format("~0P", [T, 5]),
+ "[{a,b,c},{a,b,...},{a,...},{...}|...]" = lists:flatten(S4),
+ S5 = io_lib:format("~1P", [T, 5]),
+ "[{a,\n b,\n c},\n {a,\n b,...},\n {a,...},\n {...}|...]" =
+ lists:flatten(S5),
+ ok.
diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl
index 8f8a0f6e73..5c189a6c73 100644
--- a/lib/stdlib/test/qlc_SUITE.erl
+++ b/lib/stdlib/test/qlc_SUITE.erl
@@ -7468,7 +7468,7 @@ strip_qlc_call(H) ->
strip_qlc_call2(H) ->
S = qlc:info(H, {flat, false}),
{ok, Tokens, _EndLine} = erl_scan:string(S++".", 1, [text]),
- {ok, [Expr], Bs} = lib:extended_parse_exprs(Tokens),
+ {ok, [Expr], Bs} = erl_eval:extended_parse_exprs(Tokens),
{case Expr of
{call,_,{remote,_,{atom,_,qlc},{atom,_,q}},[LC]} ->
{qlc, lists:flatten([erl_pp:expr(LC), "."]), []};
@@ -7489,7 +7489,7 @@ strip_qlc_call2(H) ->
join_info_count(H) ->
S = qlc:info(H, {flat, false}),
{ok, Tokens, _EndLine} = erl_scan:string(S++".", 1, [text]),
- {ok, [Expr], _Bs} = lib:extended_parse_exprs(Tokens),
+ {ok, [Expr], _Bs} = erl_eval:extended_parse_exprs(Tokens),
#ji{nmerge = Nmerge, nlookup = Nlookup,
nkeysort = NKeysort, nnested_loop = Nnested_loop} =
ji(Expr, #ji{}),
@@ -7533,7 +7533,7 @@ lookup_keys({generate,_,Q}, L) ->
lookup_keys(Q, L);
lookup_keys({table,Chars}, L) when is_list(Chars) ->
{ok, Tokens, _} = erl_scan:string(lists:flatten(Chars++"."), 1, [text]),
- {ok, [Expr], _Bs} = lib:extended_parse_exprs(Tokens),
+ {ok, [Expr], _Bs} = erl_eval:extended_parse_exprs(Tokens),
case Expr of
{call,_,_,[_fun,AKs]} ->
case erl_parse:normalise(AKs) of
diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl
index ca85314775..22136d687c 100644
--- a/lib/stdlib/test/shell_SUITE.erl
+++ b/lib/stdlib/test/shell_SUITE.erl
@@ -2780,7 +2780,7 @@ otp_10302(Config) when is_list(Config) ->
rpc:call(Node,shell, prompt_func, [default]),
_ = shell:prompt_func(default),
- %% Test lib:format_exception() (cf. OTP-6554)
+ %% Test erl_error:format_exception() (cf. OTP-6554)
Test6 =
<<"begin
A = <<\"\\xaa\">>,
@@ -2967,10 +2967,10 @@ otp_14296(Config) when is_list(Config) ->
R = t(S)
end(),
- %% Test lib:extended_parse_term/1
+ %% Test erl_eval:extended_parse_term/1
TF = fun(S) ->
{ok, Ts, _} = erl_scan:string(S++".", 1, [text]),
- case lib:extended_parse_term(Ts) of
+ case erl_eval:extended_parse_term(Ts) of
{ok, Term} -> Term;
{error, _}=Error -> Error
end
diff --git a/lib/stdlib/test/string_SUITE.erl b/lib/stdlib/test/string_SUITE.erl
index fdff2d24b8..ab412dcc70 100644
--- a/lib/stdlib/test/string_SUITE.erl
+++ b/lib/stdlib/test/string_SUITE.erl
@@ -409,8 +409,8 @@ uppercase(_) ->
?TEST("abc", [], "ABC"),
?TEST("ABC", [], "ABC"),
?TEST("abcdefghiljklmnopqrstvxyzåäö",[], "ABCDEFGHILJKLMNOPQRSTVXYZÅÄÖ"),
- ?TEST("åäö", [], "ÅÄÖ"),
- ?TEST("ÅÄÖ", [], "ÅÄÖ"),
+ ?TEST("åäö ", [], "ÅÄÖ "),
+ ?TEST("ÅÄÖ ", [], "ÅÄÖ "),
?TEST("Michał", [], "MICHAŁ"),
?TEST(["Mic",<<"hał"/utf8>>], [], "MICHAŁ"),
?TEST("ljLJ", [], "LJLJ"),
@@ -423,8 +423,8 @@ lowercase(_) ->
?TEST("123", [], "123"),
?TEST("abc", [], "abc"),
?TEST("ABC", [], "abc"),
- ?TEST("åäö", [], "åäö"),
- ?TEST("ÅÄÖ", [], "åäö"),
+ ?TEST("åäö ", [], "åäö "),
+ ?TEST("ÅÄÖ ", [], "åäö "),
?TEST("MICHAŁ", [], "michał"),
?TEST(["Mic",<<"HAŁ"/utf8>>], [], "michał"),
?TEST("ß SHARP S", [], "ß sharp s"),
@@ -449,8 +449,8 @@ casefold(_) ->
?TEST("123", [], "123"),
?TEST("abc", [], "abc"),
?TEST("ABC", [], "abc"),
- ?TEST("åäö", [], "åäö"),
- ?TEST("ÅÄÖ", [], "åäö"),
+ ?TEST("åäö ", [], "åäö "),
+ ?TEST("ÅÄÖ ", [], "åäö "),
?TEST("MICHAŁ", [], "michał"),
?TEST(["Mic",<<"HAŁ"/utf8>>], [], "michał"),
?TEST("ß SHARP S", [], "ss sharp s"),
@@ -810,6 +810,18 @@ do_measure(DataDir) ->
Do2(slice, repeat(fun() -> string:slice(S0, 20, 15) end), list),
Do2(slice, repeat(fun() -> string:slice(S0B, 20, 15) end), binary),
+ LCase = "areaa reare rerar earea reare reare",
+ LCaseB = unicode:characters_to_binary(LCase),
+ UCase = string:uppercase(LCase),
+ UCaseB = unicode:characters_to_binary(UCase),
+
+ Do2(to_upper_0, repeat(fun() -> string:to_upper(UCase) end), list),
+ Do2(uppercase_0, repeat(fun() -> string:uppercase(UCase) end), list),
+ Do2(uppercase_0, repeat(fun() -> string:uppercase(UCaseB) end), binary),
+ Do2(to_upper_a, repeat(fun() -> string:to_upper(LCase) end), list),
+ Do2(uppercase_a, repeat(fun() -> string:uppercase(LCase) end), list),
+ Do2(uppercase_a, repeat(fun() -> string:uppercase(LCaseB) end), binary),
+
io:format("--~n",[]),
NthTokens = {nth_lexemes, fun(Str) -> string:nth_lexeme(Str, 18000, [$\n,$\r]) end},
[Do(Name,Fun,Mode) || {Name,Fun} <- [NthTokens], Mode <- [list, binary]],