diff options
author | Sverker Eriksson <[email protected]> | 2017-02-20 20:06:28 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2017-02-20 20:06:28 +0100 |
commit | 82d3513f95198b0a4295ba866a78ae6c137a34d5 (patch) | |
tree | b45aee60996f1054e15308defddc8e96e8ef91b8 /erts/emulator/test | |
parent | 5adbf961a3c79a6782f8be8336ec26594754e9e8 (diff) | |
parent | 32a74e6c83cd110b8e8ab714be4365c0da558fca (diff) | |
download | otp-82d3513f95198b0a4295ba866a78ae6c137a34d5.tar.gz otp-82d3513f95198b0a4295ba866a78ae6c137a34d5.tar.bz2 otp-82d3513f95198b0a4295ba866a78ae6c137a34d5.zip |
Merge branch 'master' into sverker/enif_select
Conflicts:
erts/emulator/beam/erl_binary.h
erts/emulator/beam/erl_monitors.c
erts/emulator/beam/erl_nif.c
erts/emulator/beam/global.h
erts/emulator/test/nif_SUITE_data/nif_SUITE.c
Diffstat (limited to 'erts/emulator/test')
31 files changed, 670 insertions, 222 deletions
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile index 7c9927c4f3..6f9827002a 100644 --- a/erts/emulator/test/Makefile +++ b/erts/emulator/test/Makefile @@ -86,6 +86,7 @@ MODULES= \ num_bif_SUITE \ message_queue_data_SUITE \ op_SUITE \ + os_signal_SUITE \ port_SUITE \ port_bif_SUITE \ process_SUITE \ diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl index f70fb0e501..339c827602 100644 --- a/erts/emulator/test/bif_SUITE.erl +++ b/erts/emulator/test/bif_SUITE.erl @@ -26,7 +26,7 @@ -export([all/0, suite/0, display/1, display_huge/0, erl_bif_types/1,guard_bifs_in_erl_bif_types/1, - shadow_comments/1, + shadow_comments/1,list_to_utf8_atom/1, specs/1,improper_bif_stubs/1,auto_imports/1, t_list_to_existing_atom/1,os_env/1,otp_7526/1, binary_to_atom/1,binary_to_existing_atom/1, @@ -43,7 +43,7 @@ all() -> [erl_bif_types, guard_bifs_in_erl_bif_types, shadow_comments, specs, improper_bif_stubs, auto_imports, t_list_to_existing_atom, os_env, otp_7526, - display, + display, list_to_utf8_atom, atom_to_binary, binary_to_atom, binary_to_existing_atom, erl_crash_dump_bytes, min_max, erlang_halt, is_builtin, error_stacktrace, error_stacktrace_during_call_trace]. @@ -339,6 +339,38 @@ check_stub({_,F,A}, B) -> ct:fail(invalid_body) end. +list_to_utf8_atom(Config) when is_list(Config) -> + 'hello' = atom_roundtrip("hello"), + 'こんにちは' = atom_roundtrip("こんにちは"), + + %% Test all edge cases. + _ = atom_roundtrip([16#80]), + _ = atom_roundtrip([16#7F]), + _ = atom_roundtrip([16#FF]), + _ = atom_roundtrip([16#100]), + _ = atom_roundtrip([16#7FF]), + _ = atom_roundtrip([16#800]), + _ = atom_roundtrip([16#D7FF]), + atom_badarg([16#D800]), + atom_badarg([16#DFFF]), + _ = atom_roundtrip([16#E000]), + _ = atom_roundtrip([16#FFFF]), + _ = atom_roundtrip([16#1000]), + _ = atom_roundtrip([16#10FFFF]), + atom_badarg([16#110000]), + ok. + +atom_roundtrip(String) -> + Atom = list_to_atom(String), + Atom = list_to_existing_atom(String), + String = atom_to_list(Atom), + Atom. + +atom_badarg(String) -> + {'EXIT',{badarg,_}} = (catch list_to_atom(String)), + {'EXIT',{badarg,_}} = (catch list_to_existing_atom(String)), + ok. + t_list_to_existing_atom(Config) when is_list(Config) -> all = list_to_existing_atom("all"), ?MODULE = list_to_existing_atom(?MODULE_STRING), @@ -429,6 +461,8 @@ binary_to_atom(Config) when is_list(Config) -> Long = lists:seq(0, 254), LongAtom = list_to_atom(Long), LongBin = list_to_binary(Long), + UnicodeLongAtom = list_to_atom([$é || _ <- lists:seq(0, 254)]), + UnicodeLongBin = << <<"é"/utf8>> || _ <- lists:seq(0, 254)>>, %% latin1 '' = test_binary_to_atom(<<>>, latin1), @@ -440,12 +474,17 @@ binary_to_atom(Config) when is_list(Config) -> '' = test_binary_to_atom(<<>>, utf8), HalfLongAtom = test_binary_to_atom(HalfLongBin, utf8), HalfLongAtom = test_binary_to_atom(HalfLongBin, unicode), + UnicodeLongAtom = test_binary_to_atom(UnicodeLongBin, utf8), + UnicodeLongAtom = test_binary_to_atom(UnicodeLongBin, unicode), [] = [C || C <- lists:seq(128, 255), begin list_to_atom([C]) =/= test_binary_to_atom(<<C/utf8>>, utf8) end], + <<"こんにちは"/utf8>> = + atom_to_binary(test_binary_to_atom(<<"こんにちは"/utf8>>, utf8), utf8), + %% badarg failures. fail_binary_to_atom(atom), fail_binary_to_atom(42), @@ -464,10 +503,6 @@ binary_to_atom(Config) when is_list(Config) -> ?BADARG(binary_to_atom(id(<<255>>), utf8)), ?BADARG(binary_to_atom(id(<<255,0>>), utf8)), ?BADARG(binary_to_atom(id(<<16#C0,16#80>>), utf8)), %Overlong 0. - [?BADARG(binary_to_atom(<<C/utf8>>, utf8)) || C <- lists:seq(256, 16#D7FF)], - [?BADARG(binary_to_atom(<<C/utf8>>, utf8)) || C <- lists:seq(16#E000, 16#FFFD)], - [?BADARG(binary_to_atom(<<C/utf8>>, utf8)) || C <- lists:seq(16#10000, 16#8FFFF)], - [?BADARG(binary_to_atom(<<C/utf8>>, utf8)) || C <- lists:seq(16#90000, 16#10FFFF)], %% system_limit failures. ?SYS_LIMIT(binary_to_atom(id(<<0:512/unit:8,255>>), utf8)), diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl index 1c7d278bb0..324730d562 100644 --- a/erts/emulator/test/binary_SUITE.erl +++ b/erts/emulator/test/binary_SUITE.erl @@ -19,7 +19,6 @@ %% -module(binary_SUITE). --compile({nowarn_deprecated_function, {erlang,hash,2}}). %% Tests binaries and the BIFs: %% list_to_binary/1 @@ -392,7 +391,6 @@ test_hash(List) -> Bin = list_to_binary(List), Sbin = make_sub_binary(List), Unaligned = make_unaligned_sub_binary(Sbin), - test_hash_1(Bin, Sbin, Unaligned, fun erlang:hash/2), test_hash_1(Bin, Sbin, Unaligned, fun erlang:phash/2), test_hash_1(Bin, Sbin, Unaligned, fun erlang:phash2/2). @@ -1010,7 +1008,7 @@ ordering(Config) when is_list(Config) -> ok. -%% Test that comparisions between binaries with different alignment work. +%% Test that comparison between binaries with different alignment work. unaligned_order(Config) when is_list(Config) -> L = lists:seq(0, 7), [test_unaligned_order(I, J) || I <- L, J <- L], diff --git a/erts/emulator/test/bs_match_int_SUITE.erl b/erts/emulator/test/bs_match_int_SUITE.erl index a7bd4b8ac3..32bfa2f1fa 100644 --- a/erts/emulator/test/bs_match_int_SUITE.erl +++ b/erts/emulator/test/bs_match_int_SUITE.erl @@ -247,7 +247,7 @@ match_huge_int(Config) when is_list(Config) -> 8 -> %% An attempt will be made to allocate heap space for %% the bignum (which will probably fail); only if the - %% allocation succeds will the matching fail because + %% allocation succeeds will the matching fail because %% the binary is too small. ok end, diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl index 2e303ba9a8..e74631e916 100644 --- a/erts/emulator/test/call_trace_SUITE.erl +++ b/erts/emulator/test/call_trace_SUITE.erl @@ -233,7 +233,7 @@ basic() -> trace_func({'_','_','_'}, false), [b,a] = lists:reverse([a,b]), - %% Read out the remaing trace messages. + %% Read out the remaining trace messages. ?MODULE:expect({trace,Self,call,{lists,seq,[1,10]}}), ?MODULE:expect({trace,Self,call,{erlang,list_to_integer,["777"]}}), diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl index b29520ab9f..d07166ed98 100644 --- a/erts/emulator/test/code_SUITE.erl +++ b/erts/emulator/test/code_SUITE.erl @@ -296,16 +296,16 @@ get_chunk(Config) when is_list(Config) -> {ok,my_code_test,Code} = compile:file(File, [binary]), %% Should work. - Chunk = get_chunk_ok("Atom", Code), - Chunk = get_chunk_ok("Atom", make_sub_binary(Code)), - Chunk = get_chunk_ok("Atom", make_unaligned_sub_binary(Code)), + Chunk = get_chunk_ok("AtU8", Code), + Chunk = get_chunk_ok("AtU8", make_sub_binary(Code)), + Chunk = get_chunk_ok("AtU8", make_unaligned_sub_binary(Code)), %% Should fail. - {'EXIT',{badarg,_}} = (catch code:get_chunk(bit_sized_binary(Code), "Atom")), + {'EXIT',{badarg,_}} = (catch code:get_chunk(bit_sized_binary(Code), "AtU8")), {'EXIT',{badarg,_}} = (catch code:get_chunk(Code, "bad chunk id")), %% Invalid beam code or missing chunk should return 'undefined'. - undefined = code:get_chunk(<<"not a beam module">>, "Atom"), + undefined = code:get_chunk(<<"not a beam module">>, "AtU8"), undefined = code:get_chunk(Code, "XXXX"), ok. diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl index 93b6f2d956..e7e518f82b 100644 --- a/erts/emulator/test/ddll_SUITE.erl +++ b/erts/emulator/test/ddll_SUITE.erl @@ -805,7 +805,7 @@ reference_count(Config) when is_list(Config) -> Pid1 ! {self(), die}, test_server:sleep(200), % Give time to unload. - % Verify that the driver was automaticly unloaded when the + % Verify that the driver was automatically unloaded when the % process died. {error, not_loaded}=erl_ddll:unload_driver(echo_drv), ok. diff --git a/erts/emulator/test/dirty_nif_SUITE.erl b/erts/emulator/test/dirty_nif_SUITE.erl index 991ba0acc8..5ba0d85ff3 100644 --- a/erts/emulator/test/dirty_nif_SUITE.erl +++ b/erts/emulator/test/dirty_nif_SUITE.erl @@ -214,7 +214,7 @@ dirty_call_while_terminated(Config) when is_list(Config) -> undefined = process_info(Dirty, status), false = erlang:is_process_alive(Dirty), false = lists:member(Dirty, processes()), - %% Binary still refered by Dirty process not yet cleaned up + %% Binary still referred by Dirty process not yet cleaned up %% since the dirty nif has not yet returned... {value, {BinAddr, 4711, 2}} = lists:keysearch(4711, 2, element(2, diff --git a/erts/emulator/test/estone_SUITE.erl b/erts/emulator/test/estone_SUITE.erl index 3ce849b88e..35f695ffe5 100644 --- a/erts/emulator/test/estone_SUITE.erl +++ b/erts/emulator/test/estone_SUITE.erl @@ -708,7 +708,7 @@ alloc(I) -> %% Time to call bif's %% Lot's of element stuff which reflects the record code which -%% is becomming more and more common +%% is becoming more and more common bif_dispatch(0) -> 0; bif_dispatch(I) -> diff --git a/erts/emulator/test/float_SUITE.erl b/erts/emulator/test/float_SUITE.erl index 36b1f9179f..ad33ad705b 100644 --- a/erts/emulator/test/float_SUITE.erl +++ b/erts/emulator/test/float_SUITE.erl @@ -208,7 +208,7 @@ span_cmp(Axis, Incr, Length) -> %% for both negative and positive numbers. %% %% Axis: The number around which to do the tests eg. (1 bsl 58) - 1.0 -%% Incr: How much to increment the test numbers inbetween each test. +%% Incr: How much to increment the test numbers in-between each test. %% Length: Length/2 is the number of Incr away from Axis to test on the %% negative and positive plane. %% Diff: How much the float and int should differ when comparing diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl index 26fa955e3c..e4640909aa 100644 --- a/erts/emulator/test/fun_SUITE.erl +++ b/erts/emulator/test/fun_SUITE.erl @@ -19,12 +19,11 @@ %% -module(fun_SUITE). --compile({nowarn_deprecated_function, {erlang,hash,2}}). -export([all/0, suite/0, bad_apply/1,bad_fun_call/1,badarity/1,ext_badarity/1, equality/1,ordering/1, - fun_to_port/1,t_hash/1,t_phash/1,t_phash2/1,md5/1, + fun_to_port/1,t_phash/1,t_phash2/1,md5/1, refc/1,refc_ets/1,refc_dist/1, const_propagation/1,t_arity/1,t_is_function2/1, t_fun_info/1,t_fun_info_mfa/1]). @@ -38,9 +37,9 @@ suite() -> {timetrap, {minutes, 1}}]. -all() -> +all() -> [bad_apply, bad_fun_call, badarity, ext_badarity, - equality, ordering, fun_to_port, t_hash, t_phash, + equality, ordering, fun_to_port, t_phash, t_phash2, md5, refc, refc_ets, refc_dist, const_propagation, t_arity, t_is_function2, t_fun_info, t_fun_info_mfa]. @@ -412,33 +411,6 @@ build_io_list(N) -> 1 -> [7,L|L] end. -%% Test the hash/2 BIF on funs. -t_hash(Config) when is_list(Config) -> - F1 = fun(_X) -> 1 end, - F2 = fun(_X) -> 2 end, - true = hash(F1) /= hash(F2), - - G1 = make_fun(1, 2, 3), - G2 = make_fun(1, 2, 3), - G3 = make_fun(1, 2, 4), - true = hash(G1) == hash(G2), - true = hash(G2) /= hash(G3), - - FF0 = fun erlang:abs/1, - FF1 = fun erlang:exit/1, - FF2 = fun erlang:exit/2, - FF3 = fun blurf:exit/2, - true = hash(FF0) =/= hash(FF1), - true = hash(FF0) =/= hash(FF2), - true = hash(FF0) =/= hash(FF3), - true = hash(FF1) =/= hash(FF2), - true = hash(FF1) =/= hash(FF3), - true = hash(FF2) =/= hash(FF3), - ok. - -hash(Term) -> - erlang:hash(Term, 16#7ffffff). - %% Test the phash/2 BIF on funs. t_phash(Config) when is_list(Config) -> F1 = fun(_X) -> 1 end, @@ -461,7 +433,6 @@ t_phash(Config) when is_list(Config) -> true = phash(FF1) =/= phash(FF2), true = phash(FF1) =/= phash(FF3), true = phash(FF2) =/= phash(FF3), - ok. phash(Term) -> diff --git a/erts/emulator/test/guard_SUITE.erl b/erts/emulator/test/guard_SUITE.erl index e155e5f49f..54ee710363 100644 --- a/erts/emulator/test/guard_SUITE.erl +++ b/erts/emulator/test/guard_SUITE.erl @@ -317,6 +317,7 @@ guard_bifs(Config) when is_list(Config) -> try_gbif('float/1', Big, float(id(Big))), try_gbif('trunc/1', Float, 387924.0), try_gbif('round/1', Float, 387925.0), + try_gbif('round/1', 6209607916799025.0, 6209607916799025), try_gbif('length/1', [], 0), try_gbif('length/1', [a], 1), diff --git a/erts/emulator/test/hash_SUITE.erl b/erts/emulator/test/hash_SUITE.erl index a39d101b0d..3cbb3c7d5f 100644 --- a/erts/emulator/test/hash_SUITE.erl +++ b/erts/emulator/test/hash_SUITE.erl @@ -34,7 +34,6 @@ -export([basic_test/0,cmp_test/1,range_test/0,spread_test/1, phash2_test/0, otp_5292_test/0, otp_7127_test/0]). --compile({nowarn_deprecated_function, {erlang,hash,2}}). %% %% Define to run outside of test server @@ -130,24 +129,12 @@ test_hash_zero(Config) when is_list(Config) -> %% basic_test() -> 685556714 = erlang:phash({a,b,c},16#FFFFFFFF), - 14468079 = erlang:hash({a,b,c},16#7FFFFFF), 37442646 = erlang:phash([a,b,c,{1,2,3},c:pid(0,2,3), 16#77777777777777],16#FFFFFFFF), - Comment = case erlang:hash([a,b,c,{1,2,3},c:pid(0,2,3), - 16#77777777777777],16#7FFFFFF) of - 102727602 -> - big = erlang:system_info(endian), - "Big endian machine"; - 105818829 -> - little = erlang:system_info(endian), - "Little endian machine" - end, ExternalReference = <<131,114,0,3,100,0,13,110,111,110,111,100,101,64, 110,111,104,111,115,116,0,0,0,0,122,0,0,0,0,0,0,0,0>>, 1113403635 = erlang:phash(binary_to_term(ExternalReference), 16#FFFFFFFF), - 123 = erlang:hash(binary_to_term(ExternalReference), - 16#7FFFFFF), ExternalFun = <<131,117,0,0,0,3,103,100,0,13,110,111,110,111,100,101,64, 110,111,104,111,115,116,0,0,0,38,0,0,0,0,0,100,0,8,101, 114,108,95,101,118,97,108,97,20,98,5,182,139,98,108,0,0, @@ -166,11 +153,9 @@ basic_test() -> 64,110,111,104,111,115,116,0,0,0,22,0,0,0,0,0,106>>, 170987488 = erlang:phash(binary_to_term(ExternalFun), 16#FFFFFFFF), - 124460689 = erlang:hash(binary_to_term(ExternalFun), - 16#7FFFFFF), case (catch erlang:phash(1,0)) of {'EXIT',{badarg, _}} -> - {comment, Comment}; + ok; _ -> exit(phash_accepted_zero_as_range) end. @@ -193,7 +178,6 @@ range_test() -> end, F(1,16#100000000,F). - spread_test(N) -> test_fun(N,{erlang,phash},16#50000000000,fun(X) -> @@ -419,7 +403,7 @@ phash2_test() -> {"abc"++[1009], 290369864}, {"abc"++[1009]++"de", 4134369195}, {"1234567890123456", 963649519}, - + %% tuple {{}, 221703996}, {{{}}, 2165044361}, @@ -452,30 +436,15 @@ f3(X, Y) -> -endif. otp_5292_test() -> - H = fun(E) -> [erlang:hash(E, 16#7FFFFFF), - erlang:hash(-E, 16#7FFFFFF)] - end, - S1 = md5([md5(hash_int(S, E, H)) || {Start, N, Sz} <- d(), - {S, E} <- int(Start, N, Sz)]), PH = fun(E) -> [erlang:phash(E, 1 bsl 32), erlang:phash(-E, 1 bsl 32), erlang:phash2(E, 1 bsl 32), erlang:phash2(-E, 1 bsl 32)] end, - S2 = md5([md5(hash_int(S, E, PH)) || {Start, N, Sz} <- d(), + S2 = md5([md5(hash_int(S, E, PH)) || {Start, N, Sz} <- d(), {S, E} <- int(Start, N, Sz)]), - Comment = case S1 of - <<4,248,208,156,200,131,7,1,173,13,239,173,112,81,16,174>> -> - big = erlang:system_info(endian), - "Big endian machine"; - <<180,28,33,231,239,184,71,125,76,47,227,241,78,184,176,233>> -> - little = erlang:system_info(endian), - "Little endian machine" - end, <<124,81,198,121,174,233,19,137,10,83,33,80,226,111,238,99>> = S2, - 2 = erlang:hash(1, (1 bsl 27) -1), - {'EXIT', _} = (catch erlang:hash(1, (1 bsl 27))), - {comment, Comment}. + ok. d() -> [%% Start, NumOfIntervals, SizeOfInterval @@ -496,8 +465,6 @@ md5(T) -> bit_level_binaries_do() -> [3511317,7022633,14044578,28087749,56173436,112344123,90467083|_] = - bit_level_all_different(fun erlang:hash/2), - [3511317,7022633,14044578,28087749,56173436,112344123,90467083|_] = bit_level_all_different(fun erlang:phash/2), [102233154,19716,102133857,4532024,123369135,24565730,109558721|_] = bit_level_all_different(fun erlang:phash2/2), @@ -535,9 +502,7 @@ bit_level_all_different(Hash) -> Hashes1. test_hash_phash(Bitstr, Rem) -> - Hash = erlang:hash(Bitstr, Rem), Hash = erlang:phash(Bitstr, Rem), - Hash = erlang:hash(unaligned_sub_bitstr(Bitstr), Rem), Hash = erlang:phash(unaligned_sub_bitstr(Bitstr), Rem). test_phash2(Bitstr, Rem) -> @@ -555,7 +520,6 @@ hash_zero_test() -> binary_to_term(<<131,70,128,0,0,0,0,0,0,0>>)], %% -0.0 ok = hash_zero_test(Zs,fun(T) -> erlang:phash2(T, 1 bsl 32) end), ok = hash_zero_test(Zs,fun(T) -> erlang:phash(T, 1 bsl 32) end), - ok = hash_zero_test(Zs,fun(T) -> erlang:hash(T, (1 bsl 27) - 1) end), ok. hash_zero_test([Z|Zs],F) -> diff --git a/erts/emulator/test/hibernate_SUITE.erl b/erts/emulator/test/hibernate_SUITE.erl index 6f8ce02266..90693595a7 100644 --- a/erts/emulator/test/hibernate_SUITE.erl +++ b/erts/emulator/test/hibernate_SUITE.erl @@ -349,7 +349,7 @@ clean_dict() -> lists:foreach(fun ({Key, _}) -> erase(Key) end, Dict). %% -%% Wake up and then immediatly bif trap with a lengthy computation. +%% Wake up and then immediately bif trap with a lengthy computation. %% wake_up_and_bif_trap(Config) when is_list(Config) -> diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl index 5af676c409..dfa1629112 100644 --- a/erts/emulator/test/map_SUITE.erl +++ b/erts/emulator/test/map_SUITE.erl @@ -18,7 +18,6 @@ %% -module(map_SUITE). -export([all/0, suite/0]). --compile({nowarn_deprecated_function, {erlang,hash,2}}). -export([t_build_and_match_literals/1, t_build_and_match_literals_large/1, t_update_literals/1, t_update_literals_large/1, @@ -2130,8 +2129,6 @@ t_erlang_hash(Config) when is_list(Config) -> ok = t_bif_erlang_phash2(), ok = t_bif_erlang_phash(), - ok = t_bif_erlang_hash(), - ok. t_bif_erlang_phash2() -> @@ -2174,27 +2171,6 @@ t_bif_erlang_phash() -> 2620391445 = erlang:phash(M2,Sz), % 3590546636 ok. -t_bif_erlang_hash() -> - Sz = 1 bsl 27 - 1, - 39684169 = erlang:hash(#{},Sz), % 5158 - 33673142 = erlang:hash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz), % 71555838 - 95337869 = erlang:hash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz), % 5497225 - 108959561 = erlang:hash(#{ 1 => a },Sz), % 126071654 - 59623150 = erlang:hash(#{ a => 1 },Sz), % 126426236 - - 42775386 = erlang:hash(#{{} => <<>>},Sz), % 101655720 - 71692856 = erlang:hash(#{<<>> => {}},Sz), % 101655720 - - M0 = #{ a => 1, "key" => <<"value">> }, - M1 = maps:remove("key",M0), - M2 = M1#{ "key" => <<"value">> }, - - 70254632 = erlang:hash(M0,Sz), % 38260486 - 59623150 = erlang:hash(M1,Sz), % 126426236 - 70254632 = erlang:hash(M2,Sz), % 38260486 - ok. - - t_map_encode_decode(Config) when is_list(Config) -> <<131,116,0,0,0,0>> = erlang:term_to_binary(#{}), Pairs = [ diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl index 34e956bc21..971a047309 100644 --- a/erts/emulator/test/match_spec_SUITE.erl +++ b/erts/emulator/test/match_spec_SUITE.erl @@ -646,7 +646,7 @@ destructive_in_test_bif(Config) when is_list(Config) -> ([],[{'_',[],[{message,{get_tcw}}]}],trace), ok. -%% Test that the comparision between boxed and small does not crash emulator +%% Test that the comparison between boxed and small does not crash emulator boxed_and_small(Config) when is_list(Config) -> {ok, Node} = start_node(match_spec_suite_other), ok = rpc:call(Node,?MODULE,do_boxed_and_small,[]), diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index 9932b526b9..5857ed51e4 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -63,7 +63,7 @@ -define(nif_stub,nif_stub_error(?LINE)). --define(is_resource, is_binary). % to be is_reference +-define(is_resource, is_reference). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -1112,7 +1112,7 @@ resource_hugo_do(Type) -> HugoBin = <<"Hugo Hacker">>, HugoPtr = alloc_resource(Type, HugoBin), Hugo = make_resource(HugoPtr), - <<>> = Hugo, + true = is_reference(Hugo), release_resource(HugoPtr), erlang:garbage_collect(), {HugoPtr,HugoBin} = get_resource(Type,Hugo), @@ -1146,7 +1146,7 @@ resource_otto_do(Type) -> OttoBin = <<"Otto Ordonnans">>, OttoPtr = alloc_resource(Type, OttoBin), Otto = make_resource(OttoPtr), - <<>> = Otto, + true = is_reference(Otto), %% forget resource term but keep referenced by NIF {OttoPtr, OttoBin}. @@ -1169,8 +1169,9 @@ resource_new_do2(Type) -> BinB = <<"NewB">>, ResA = make_new_resource(Type, BinA), ResB = make_new_resource(Type, BinB), - <<>> = ResA, - <<>> = ResB, + true = is_reference(ResA), + true = is_reference(ResB), + ResA /= ResB, {PtrA,BinA} = get_resource(Type, ResA), {PtrB,BinB} = get_resource(Type, ResB), true = (PtrA =/= PtrB), diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c index a9622e3b8d..d5dd379d76 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c +++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c @@ -1122,6 +1122,7 @@ struct make_term_info unsigned reuse_push; unsigned reuse_pull; ErlNifResourceType* resource_type; + void *resource; ERL_NIF_TERM other_term; ERL_NIF_TERM blob; ErlNifPid to_pid; @@ -1230,12 +1231,7 @@ static ERL_NIF_TERM make_term_list0(struct make_term_info* mti, int n) } static ERL_NIF_TERM make_term_resource(struct make_term_info* mti, int n) { - void* resource = enif_alloc_resource(mti->resource_type, 10); - ERL_NIF_TERM term; - fill(resource, 10, n); - term = enif_make_resource(mti->dst_env, resource); - enif_release_resource(resource); - return term; + return enif_make_resource(mti->dst_env, mti->resource); } static ERL_NIF_TERM make_term_new_binary(struct make_term_info* mti, int n) { @@ -1339,23 +1335,39 @@ static int make_term_n(struct make_term_info* mti, int n, ERL_NIF_TERM* res) return 0; } -static ERL_NIF_TERM make_blob(ErlNifEnv* caller_env, ErlNifEnv* dst_env, - ERL_NIF_TERM other_term) + +static void +init_make_blob(struct make_term_info *mti, + ErlNifEnv* caller_env, + ERL_NIF_TERM other_term) { PrivData* priv = (PrivData*) enif_priv_data(caller_env); + mti->caller_env = caller_env; + mti->resource_type = priv->rt_arr[0].t; + mti->resource = enif_alloc_resource(mti->resource_type, 10); + fill(mti->resource, 10, 17); + mti->other_term = other_term; +} + +static void +fini_make_blob(struct make_term_info *mti) +{ + enif_release_resource(mti->resource); +} + +static ERL_NIF_TERM make_blob(struct make_term_info *mti, + ErlNifEnv* dst_env) +{ ERL_NIF_TERM term, list; int n = 0; - struct make_term_info mti; - mti.caller_env = caller_env; - mti.dst_env = dst_env; - mti.dst_env_valid = 1; - mti.reuse_push = 0; - mti.reuse_pull = 0; - mti.resource_type = priv->rt_arr[0].t; - mti.other_term = other_term; + + mti->reuse_push = 0; + mti->reuse_pull = 0; + mti->dst_env = dst_env; + mti->dst_env_valid = 1; list = enif_make_list(dst_env, 0); - while (make_term_n(&mti, n++, &term)) { + while (make_term_n(mti, n++, &term)) { list = enif_make_list_cell(dst_env, term, list); } return list; @@ -1367,13 +1379,16 @@ static ERL_NIF_TERM send_new_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM a ERL_NIF_TERM msg, copy; ErlNifEnv* msg_env; int res; + struct make_term_info mti; if (!enif_get_local_pid(env, argv[0], &to)) { return enif_make_badarg(env); } msg_env = enif_alloc_env(); - msg = make_blob(env,msg_env, argv[1]); - copy = make_blob(env,env, argv[1]); + init_make_blob(&mti, env, argv[1]); + msg = make_blob(&mti,msg_env); + copy = make_blob(&mti,env); + fini_make_blob(&mti); res = enif_send(env, &to, msg_env, msg); enif_free_env(msg_env); return enif_make_tuple3(env, atom_ok, enif_make_int(env,res), copy); @@ -1393,6 +1408,8 @@ static ERL_NIF_TERM alloc_msgenv(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar mti->reuse_push = 0; mti->reuse_pull = 0; mti->resource_type = priv->rt_arr[0].t; + mti->resource = enif_alloc_resource(mti->resource_type, 10); + fill(mti->resource, 10, 17); mti->other_term = enif_make_list(mti->dst_env, 0); mti->blob = enif_make_list(mti->dst_env, 0); mti->mtx = enif_mutex_create("nif_SUITE:mtx"); @@ -1410,6 +1427,7 @@ static void msgenv_dtor(ErlNifEnv* env, void* obj) if (mti->dst_env != NULL) { enif_free_env(mti->dst_env); } + enif_release_resource(mti->resource); enif_mutex_destroy(mti->mtx); enif_cond_destroy(mti->cond); } diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl index af18545bff..291d3ee30d 100644 --- a/erts/emulator/test/node_container_SUITE.erl +++ b/erts/emulator/test/node_container_SUITE.erl @@ -50,7 +50,8 @@ port_wrap/1, bad_nc/1, unique_pid/1, - iter_max_procs/1]). + iter_max_procs/1, + magic_ref/1]). suite() -> [{ct_hooks,[ts_install_cth]}, @@ -62,7 +63,7 @@ all() -> node_table_gc, dist_link_refc, dist_monitor_refc, node_controller_refc, ets_refc, match_spec_refc, timer_refc, otp_4715, pid_wrap, port_wrap, bad_nc, - unique_pid, iter_max_procs]. + unique_pid, iter_max_procs, magic_ref]. init_per_suite(Config) -> Config. @@ -152,7 +153,7 @@ ttbtteq_do_remote(RNode) -> %% %% Test case: round_trip_eq %% -%% Tests that node containers that are sent beteen nodes stay equal to themselves. +%% Tests that node containers that are sent between nodes stay equal to themselves. round_trip_eq(Config) when is_list(Config) -> ThisNode = {node(), erlang:system_info(creation)}, NodeFirstName = get_nodefirstname(), @@ -889,10 +890,46 @@ chk_max_proc_line_until(NoMoreTests, Res) -> chk_max_proc_line_until(NoMoreTests, Res) end. +magic_ref(Config) when is_list(Config) -> + {MRef0, Addr0} = erts_debug:set_internal_state(make, magic_ref), + true = is_reference(MRef0), + {Addr0, 1, true} = erts_debug:get_internal_state({magic_ref,MRef0}), + MRef1 = binary_to_term(term_to_binary(MRef0)), + {Addr0, 2, true} = erts_debug:get_internal_state({magic_ref,MRef1}), + MRef0 = MRef1, + Me = self(), + {Pid, Mon} = spawn_opt(fun () -> + receive + {Me, MRef} -> + Me ! {self(), erts_debug:get_internal_state({magic_ref,MRef})} + end + end, + [link, monitor]), + Pid ! {self(), MRef0}, + receive + {Pid, Info} -> + {Addr0, 3, true} = Info + end, + receive + {'DOWN', Mon, process, Pid, _} -> + ok + end, + {Addr0, 2, true} = erts_debug:get_internal_state({magic_ref,MRef0}), + id(MRef0), + id(MRef1), + MRefExt = term_to_binary(erts_debug:set_internal_state(make, magic_ref)), + garbage_collect(), + {MRef2, _Addr2} = binary_to_term(MRefExt), + true = is_reference(MRef2), + true = erts_debug:get_internal_state({magic_ref,MRef2}), + ok. %% %% -- Internal utils --------------------------------------------------------- %% +id(X) -> + X. + -define(ND_REFS, erts_debug:get_internal_state(node_and_dist_references)). node_container_refc_check(Node) when is_atom(Node) -> diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl index 1a1ab0e5e0..f62eb0b430 100644 --- a/erts/emulator/test/num_bif_SUITE.erl +++ b/erts/emulator/test/num_bif_SUITE.erl @@ -108,7 +108,7 @@ t_float(Config) when is_list(Config) -> 4294967305.0 = float(id(4294967305)), -4294967305.0 = float(id(-4294967305)), - %% Extremly big bignums. + %% Extremely big bignums. Big = id(list_to_integer(id(lists:duplicate(2000, $1)))), {'EXIT', {badarg, _}} = (catch float(Big)), @@ -295,6 +295,9 @@ t_round(Config) when is_list(Config) -> 4294967297 = round(id(4294967296.9)), -4294967296 = -round(id(4294967296.1)), -4294967297 = -round(id(4294967296.9)), + + 6209607916799025 = round(id(6209607916799025.0)), + -6209607916799025 = round(id(-6209607916799025.0)), ok. %% Test trunc/1, floor/1, ceil/1, and round/1. diff --git a/erts/emulator/test/os_signal_SUITE.erl b/erts/emulator/test/os_signal_SUITE.erl new file mode 100644 index 0000000000..9aa49a453e --- /dev/null +++ b/erts/emulator/test/os_signal_SUITE.erl @@ -0,0 +1,354 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2017. 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% +%% + +%% +%% File: os_signal_SUITE.erl +%% Author: Björn-Egil Dahlberg +%% Created: 2017-01-13 +%% + +-module(os_signal_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-export([all/0, suite/0]). +-export([init_per_testcase/2, end_per_testcase/2]). +-export([init_per_suite/1, end_per_suite/1]). + +-export([set_alarm/1, fork/0, get_exit_code/1]). + +% Test cases +-export([set_unset/1, + t_sighup/1, + t_sigusr1/1, + t_sigusr2/1, + t_sigterm/1, + t_sigalrm/1, + t_sigchld/1, + t_sigchld_fork/1]). + +-define(signal_server, erl_signal_server). + +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {minutes, 2}}]. + +all() -> + case os:type() of + {win32, _} -> []; + _ -> [set_unset, + t_sighup, + t_sigusr1, + t_sigusr2, + t_sigterm, + t_sigalrm, + t_sigchld, + t_sigchld_fork] + end. + +init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> + Pid = erlang:whereis(?signal_server), + true = erlang:unregister(?signal_server), + [{signal_server, Pid}|Config]. + +end_per_testcase(_Func, Config) -> + case proplists:get_value(signal_server, Config) of + undefined -> ok; + Pid -> + true = erlang:register(?signal_server, Pid), + ok + end. + +init_per_suite(Config) -> + load_nif(Config), + Config. + +end_per_suite(_Config) -> + ok. + +%% tests + +set_unset(_Config) -> + Signals = [sighup, %sigint, + sigquit, %sigill, + sigabrt, + sigalrm, sigterm, + sigusr1, sigusr2, + sigchld, + sigstop, sigtstp], + F1 = fun(Sig) -> ok = os:set_signal(Sig,handle) end, + F2 = fun(Sig) -> ok = os:set_signal(Sig,default) end, + F3 = fun(Sig) -> ok = os:set_signal(Sig,ignore) end, + %% set handle + ok = lists:foreach(F1, Signals), + %% set ignore + ok = lists:foreach(F2, Signals), + %% set default + ok = lists:foreach(F3, Signals), + ok. + +t_sighup(_Config) -> + Pid1 = setup_service(), + OsPid = os:getpid(), + os:set_signal(sighup, handle), + ok = kill("HUP", OsPid), + ok = kill("HUP", OsPid), + ok = kill("HUP", OsPid), + Msgs1 = fetch_msgs(Pid1), + io:format("Msgs1: ~p~n", [Msgs1]), + [{notify,sighup}, + {notify,sighup}, + {notify,sighup}] = Msgs1, + %% no proc + ok = kill("HUP", OsPid), + ok = kill("HUP", OsPid), + ok = kill("HUP", OsPid), + %% ignore + Pid2 = setup_service(), + os:set_signal(sighup, ignore), + ok = kill("HUP", OsPid), + ok = kill("HUP", OsPid), + ok = kill("HUP", OsPid), + Msgs2 = fetch_msgs(Pid2), + io:format("Msgs2: ~p~n", [Msgs2]), + [] = Msgs2, + %% reset to handle (it's the default) + os:set_signal(sighup, handle), + ok. + +t_sigusr1(_Config) -> + Pid1 = setup_service(), + OsPid = os:getpid(), + os:set_signal(sigusr1, handle), + ok = kill("USR1", OsPid), + ok = kill("USR1", OsPid), + ok = kill("USR1", OsPid), + Msgs1 = fetch_msgs(Pid1), + io:format("Msgs1: ~p~n", [Msgs1]), + [{notify,sigusr1}, + {notify,sigusr1}, + {notify,sigusr1}] = Msgs1, + %% no proc + ok = kill("USR1", OsPid), + ok = kill("USR1", OsPid), + ok = kill("USR1", OsPid), + %% ignore + Pid2 = setup_service(), + os:set_signal(sigusr1, ignore), + ok = kill("USR1", OsPid), + ok = kill("USR1", OsPid), + ok = kill("USR1", OsPid), + Msgs2 = fetch_msgs(Pid2), + io:format("Msgs2: ~p~n", [Msgs2]), + [] = Msgs2, + %% reset to ignore (it's the default) + os:set_signal(sigusr1, handle), + ok. + +t_sigusr2(_Config) -> + Pid1 = setup_service(), + OsPid = os:getpid(), + os:set_signal(sigusr2, handle), + ok = kill("USR2", OsPid), + ok = kill("USR2", OsPid), + ok = kill("USR2", OsPid), + Msgs1 = fetch_msgs(Pid1), + io:format("Msgs1: ~p~n", [Msgs1]), + [{notify,sigusr2}, + {notify,sigusr2}, + {notify,sigusr2}] = Msgs1, + %% no proc + ok = kill("USR2", OsPid), + ok = kill("USR2", OsPid), + ok = kill("USR2", OsPid), + %% ignore + Pid2 = setup_service(), + os:set_signal(sigusr2, ignore), + ok = kill("USR2", OsPid), + ok = kill("USR2", OsPid), + ok = kill("USR2", OsPid), + Msgs2 = fetch_msgs(Pid2), + io:format("Msgs2: ~p~n", [Msgs2]), + [] = Msgs2, + %% reset to ignore (it's the default) + os:set_signal(sigusr2, ignore), + ok. + +t_sigterm(_Config) -> + Pid1 = setup_service(), + OsPid = os:getpid(), + os:set_signal(sigterm, handle), + ok = kill("TERM", OsPid), + ok = kill("TERM", OsPid), + ok = kill("TERM", OsPid), + Msgs1 = fetch_msgs(Pid1), + io:format("Msgs1: ~p~n", [Msgs1]), + [{notify,sigterm}, + {notify,sigterm}, + {notify,sigterm}] = Msgs1, + %% no proc + ok = kill("TERM", OsPid), + ok = kill("TERM", OsPid), + ok = kill("TERM", OsPid), + %% ignore + Pid2 = setup_service(), + os:set_signal(sigterm, ignore), + ok = kill("TERM", OsPid), + ok = kill("TERM", OsPid), + ok = kill("TERM", OsPid), + Msgs2 = fetch_msgs(Pid2), + io:format("Msgs2: ~p~n", [Msgs2]), + [] = Msgs2, + %% reset to handle (it's the default) + os:set_signal(sigterm, handle), + ok. + +t_sigchld(_Config) -> + Pid1 = setup_service(), + OsPid = os:getpid(), + os:set_signal(sigchld, handle), + ok = kill("CHLD", OsPid), + ok = kill("CHLD", OsPid), + ok = kill("CHLD", OsPid), + Msgs1 = fetch_msgs(Pid1), + io:format("Msgs1: ~p~n", [Msgs1]), + [{notify,sigchld}, + {notify,sigchld}, + {notify,sigchld}] = Msgs1, + %% no proc + ok = kill("CHLD", OsPid), + ok = kill("CHLD", OsPid), + ok = kill("CHLD", OsPid), + %% ignore + Pid2 = setup_service(), + os:set_signal(sigchld, ignore), + ok = kill("CHLD", OsPid), + ok = kill("CHLD", OsPid), + ok = kill("CHLD", OsPid), + Msgs2 = fetch_msgs(Pid2), + io:format("Msgs2: ~p~n", [Msgs2]), + [] = Msgs2, + %% reset to handle (it's the default) + os:set_signal(sigchld, ignore), + ok. + + +t_sigalrm(_Config) -> + Pid1 = setup_service(), + ok = os:set_signal(sigalrm, handle), + ok = os_signal_SUITE:set_alarm(1), + receive after 3000 -> ok end, + Msgs1 = fetch_msgs(Pid1), + [{notify,sigalrm}] = Msgs1, + io:format("Msgs1: ~p~n", [Msgs1]), + os:set_signal(sigalrm, ignore), + Pid2 = setup_service(), + ok = os_signal_SUITE:set_alarm(1), + receive after 3000 -> ok end, + Msgs2 = fetch_msgs(Pid2), + [] = Msgs2, + io:format("Msgs2: ~p~n", [Msgs2]), + Pid3 = setup_service(), + os:set_signal(sigalrm, handle), + ok = os_signal_SUITE:set_alarm(1), + receive after 3000 -> ok end, + Msgs3 = fetch_msgs(Pid3), + [{notify,sigalrm}] = Msgs3, + io:format("Msgs3: ~p~n", [Msgs3]), + os:set_signal(sigalrm, ignore), + ok. + +t_sigchld_fork(_Config) -> + Pid1 = setup_service(), + ok = os:set_signal(sigchld, handle), + {ok,OsPid} = os_signal_SUITE:fork(), + receive after 3000 -> ok end, + Msgs1 = fetch_msgs(Pid1), + io:format("Msgs1: ~p~n", [Msgs1]), + [{notify,sigchld}] = Msgs1, + {ok,Status} = os_signal_SUITE:get_exit_code(OsPid), + io:format("exit status from ~w : ~w~n", [OsPid,Status]), + 42 = Status, + %% reset to ignore (it's the default) + os:set_signal(sigchld, ignore), + ok. + + +%% nif stubs + +set_alarm(_Secs) -> no. +fork() -> no. +get_exit_code(_OsPid) -> no. + +%% aux + +setup_service() -> + Pid = spawn_link(fun msgs/0), + true = erlang:register(?signal_server, Pid), + Pid. + +msgs() -> + msgs([]). +msgs(Ms) -> + receive + {Pid, fetch_msgs} -> Pid ! {self(), lists:reverse(Ms)}; + Msg -> + msgs([Msg|Ms]) + end. + +fetch_msgs(Pid) -> + Pid ! {self(), fetch_msgs}, + receive {Pid, Msgs} -> Msgs end. + +kill(Signal, Pid) -> + {0,_} = run("kill", ["-s", Signal, Pid]), + receive after 200 -> ok end, + ok. + +load_nif(Config) -> + Path = proplists:get_value(data_dir, Config), + ok = erlang:load_nif(filename:join(Path,"os_signal_nif"), 0). + +run(Program0, Args) -> run(".", Program0, Args). +run(Cwd, Program0, Args) when is_list(Cwd) -> + Program = case os:find_executable(Program0) of + Path when is_list(Path) -> + Path; + false -> + exit(no) + end, + Options = [{args,Args},binary,exit_status,stderr_to_stdout, + {line,4096}, {cd, Cwd}], + try open_port({spawn_executable,Program}, Options) of + Port -> + run_loop(Port, []) + catch + error:_ -> + exit(no) + end. + +run_loop(Port, Output) -> + receive + {Port,{exit_status,Status}} -> + {Status,lists:reverse(Output)}; + {Port,{data,{eol,Bin}}} -> + run_loop(Port, [Bin|Output]); + _Msg -> + run_loop(Port, Output) + end. diff --git a/erts/emulator/test/os_signal_SUITE_data/Makefile.src b/erts/emulator/test/os_signal_SUITE_data/Makefile.src new file mode 100644 index 0000000000..a7f5cdbba5 --- /dev/null +++ b/erts/emulator/test/os_signal_SUITE_data/Makefile.src @@ -0,0 +1,6 @@ + +NIF_LIBS = os_signal_nif@dll@ + +all: $(NIF_LIBS) + +@SHLIB_RULES@ diff --git a/erts/emulator/test/os_signal_SUITE_data/os_signal_nif.c b/erts/emulator/test/os_signal_SUITE_data/os_signal_nif.c new file mode 100644 index 0000000000..78e1348383 --- /dev/null +++ b/erts/emulator/test/os_signal_SUITE_data/os_signal_nif.c @@ -0,0 +1,66 @@ +#include <sys/wait.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> + +#include <erl_nif.h> + +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) +{ + return 0; +} + +static ERL_NIF_TERM set_alarm(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + int t; + if (!enif_get_int(env, argv[0], &t)) { + return enif_make_badarg(env); + } + + alarm(t); + + return enif_make_atom(env, "ok"); +} + +static ERL_NIF_TERM fork_0(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + pid_t pid; + + pid = fork(); + + if (pid == 0) { + /* child */ + exit(42); + } + + return enif_make_tuple(env, 2, + enif_make_atom(env, "ok"), + enif_make_int(env, (int)pid)); +} + +static ERL_NIF_TERM get_exit_code(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + int x; + pid_t pid; + if (!enif_get_int(env, argv[0], &x)) { + return enif_make_badarg(env); + } + + pid = (pid_t) x; + + waitpid(pid, &x, 0); + + return enif_make_tuple(env, 2, + enif_make_atom(env, "ok"), + enif_make_int(env, WEXITSTATUS(x))); +} + + +static ErlNifFunc nif_funcs[] = +{ + {"set_alarm", 1, set_alarm}, + {"fork", 0, fork_0}, + {"get_exit_code", 1, get_exit_code} +}; + +ERL_NIF_INIT(os_signal_SUITE,nif_funcs,load,NULL,NULL,NULL) diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl index 2a13b2d2f4..c117554f90 100644 --- a/erts/emulator/test/port_SUITE.erl +++ b/erts/emulator/test/port_SUITE.erl @@ -2131,7 +2131,7 @@ ping(Config, Sizes, HSize, CmdLine, Options) -> %% Sizes = Size of packets to generated. %% HSize = Header size: 1, 2, or 4 %% CmdLine = Additional command line options. -%% Options = Addtional port options. +%% Options = Additional port options. expect_input(Config, Sizes, HSize, CmdLine, Options) -> expect_input1(Config, Sizes, {HSize, CmdLine, Options}, [], []). diff --git a/erts/emulator/test/port_SUITE_data/port_test.c b/erts/emulator/test/port_SUITE_data/port_test.c index e199a0fc13..fa97b4c9d0 100644 --- a/erts/emulator/test/port_SUITE_data/port_test.c +++ b/erts/emulator/test/port_SUITE_data/port_test.c @@ -41,7 +41,7 @@ extern int errno; typedef struct { char* progname; /* Name of this program (from argv[0]). */ int header_size; /* Number of bytes in each packet header: - * 1, 2, or 4, or 0 for a continous byte stream. */ + * 1, 2, or 4, or 0 for a continuous byte stream. */ int fd_from_erl; /* File descriptor from Erlang. */ int fd_to_erl; /* File descriptor to Erlang. */ unsigned char* io_buf; /* Buffer for file i/o. */ diff --git a/erts/emulator/test/port_bif_SUITE_data/port_test.c b/erts/emulator/test/port_bif_SUITE_data/port_test.c index 28324a56a6..923ab99ccc 100644 --- a/erts/emulator/test/port_bif_SUITE_data/port_test.c +++ b/erts/emulator/test/port_bif_SUITE_data/port_test.c @@ -39,7 +39,7 @@ extern int errno; typedef struct { char* progname; /* Name of this program (from argv[0]). */ int header_size; /* Number of bytes in each packet header: - * 1, 2, or 4, or 0 for a continous byte stream. */ + * 1, 2, or 4, or 0 for a continuous byte stream. */ int fd_from_erl; /* File descriptor from Erlang. */ int fd_to_erl; /* File descriptor to Erlang. */ unsigned char* io_buf; /* Buffer for file i/o. */ diff --git a/erts/emulator/test/port_trace_SUITE_data/echo_drv.c b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c index b545523192..20ec33a594 100644 --- a/erts/emulator/test/port_trace_SUITE_data/echo_drv.c +++ b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c @@ -2,23 +2,30 @@ #include "erl_driver.h" #include <errno.h> #include <string.h> +#include <assert.h> /* ------------------------------------------------------------------------- ** Data types **/ +struct my_thread { + struct my_thread* next; + ErlDrvTid tid; +}; typedef struct _erl_drv_data { ErlDrvPort erlang_port; ErlDrvTermData caller; + struct my_thread* threads; } EchoDrvData; struct remote_send_term { - char *buf; - int len; + struct my_thread thread; ErlDrvTermData port; ErlDrvTermData caller; + int len; + char buf[1]; /* buf[len] */ }; #define ECHO_DRV_NOOP 0 @@ -86,7 +93,7 @@ static ErlDrvEntry echo_drv_entry = { NULL }; -static void send_term_thread(void *); +static void* send_term_thread(void *); /* ------------------------------------------------------------------------- ** Entry functions @@ -111,10 +118,22 @@ static EchoDrvData *echo_drv_start(ErlDrvPort port, char *command) EchoDrvData *echo_drv_data_p = driver_alloc(sizeof(EchoDrvData)); echo_drv_data_p->erlang_port = port; echo_drv_data_p->caller = driver_caller(port); + echo_drv_data_p->threads = NULL; return echo_drv_data_p; } -static void echo_drv_stop(EchoDrvData *data_p) { +static void echo_drv_stop(EchoDrvData *data_p) +{ + struct my_thread* thr = data_p->threads; + + while (thr) { + struct my_thread* next = thr->next; + void* exit_value; + int ret = erl_drv_thread_join(thr->tid, &exit_value); + assert(ret == 0 && exit_value == NULL); + driver_free(thr); + thr = next; + } driver_free(data_p); } @@ -212,14 +231,14 @@ static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) { } case ECHO_DRV_REMOTE_SEND_TERM: { - ErlDrvTid tid; - struct remote_send_term *t = malloc(sizeof(struct remote_send_term)); + struct remote_send_term *t = driver_alloc(sizeof(struct remote_send_term) + len); t->len = len-1; - t->buf = malloc(len-1); t->port = driver_mk_port(port); t->caller = data_p->caller; memcpy(t->buf, buf+1, t->len); - erl_drv_thread_create("tmp_thread", &tid, send_term_thread, t, NULL); + erl_drv_thread_create("tmp_thread", &t->thread.tid, send_term_thread, t, NULL); + t->thread.next = data_p->threads; + data_p->threads = &t->thread; break; } case ECHO_DRV_SAVE_CALLER: @@ -262,7 +281,7 @@ static ErlDrvSSizeT echo_drv_call(ErlDrvData drv_data, return len-command; } -static void send_term_thread(void *a) +static void* send_term_thread(void *a) { struct remote_send_term *t = (struct remote_send_term*)a; ErlDrvTermData term[] = { @@ -273,5 +292,5 @@ static void send_term_thread(void *a) ERL_DRV_TUPLE, 3}; erl_drv_send_term(t->port, t->caller, term, sizeof(term) / sizeof(ErlDrvTermData)); - return; + return NULL; } diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index 6a772bf7c9..6bd1eb1e1e 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -174,7 +174,7 @@ memory(Config) when is_list(Config) -> %% erts_debug:set_internal_state(available_internal_state, true), - %% Use a large heap size on the controling process in + %% Use a large heap size on the controlling process in %% order to avoid changes in its heap size during %% comparisons. MinHeapSize = process_flag(min_heap_size, 1024*1024), diff --git a/erts/emulator/test/time_SUITE.erl b/erts/emulator/test/time_SUITE.erl index 9501569814..c13d03bcc4 100644 --- a/erts/emulator/test/time_SUITE.erl +++ b/erts/emulator/test/time_SUITE.erl @@ -132,7 +132,7 @@ local_to_univ_utc(Config) when is_list(Config) -> end. -%% Tests conversion from univeral to local time. +%% Tests conversion from universal to local time. univ_to_local(Config) when is_list(Config) -> test_univ_to_local(test_data()). diff --git a/erts/emulator/test/trace_local_SUITE.erl b/erts/emulator/test/trace_local_SUITE.erl index c297acd78b..5b65889f4a 100644 --- a/erts/emulator/test/trace_local_SUITE.erl +++ b/erts/emulator/test/trace_local_SUITE.erl @@ -19,7 +19,6 @@ %% -module(trace_local_SUITE). --compile({nowarn_deprecated_function, {erlang,hash,2}}). -export([basic_test/0, bit_syntax_test/0, return_test/0, on_and_off_test/0, stack_grow_test/0, @@ -65,7 +64,7 @@ init_per_testcase(_Case, Config) -> Config. -end_per_testcase(_Case, Config) -> +end_per_testcase(_Case, _Config) -> shutdown(), %% Reloading the module will clear all trace patterns, and @@ -78,7 +77,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap, {minutes, 2}}]. -all() -> +all() -> case test_server:is_native(trace_local_SUITE) of true -> [not_run]; false -> @@ -98,7 +97,7 @@ all() -> end. -not_run(Config) when is_list(Config) -> +not_run(Config) when is_list(Config) -> {skipped,"Native code"}. %% Tests basic local call-trace @@ -300,7 +299,7 @@ basic_test() -> NumMatches = erlang:trace_pattern({?MODULE,'_','_'},[],[local]), NumMatches = erlang:trace_pattern({?MODULE,'_','_'},[],[local]), erlang:trace_pattern({?MODULE,slave,'_'},false,[local]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported,[1]), ?CT(?MODULE,local,[1]), @@ -308,17 +307,17 @@ basic_test() -> ?CT(?MODULE,local_tail,[1]), erlang:trace_pattern({?MODULE,'_','_'},[],[]), erlang:trace_pattern({?MODULE,slave,'_'},false,[local]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported_wrap,[1]), - [1,1,1,1] = lambda_slave(fun() -> - exported_wrap(1) - end), - ?NM, + [1,1,1,997] = lambda_slave(fun() -> + exported_wrap(1) + end), + ?NM, erlang:trace_pattern({?MODULE,'_','_'},[],[local]), erlang:trace_pattern({?MODULE,slave,'_'},false,[local]), - [1,1,1,1] = lambda_slave(fun() -> - exported_wrap(1) - end), + [1,1,1,997] = lambda_slave(fun() -> + exported_wrap(1) + end), ?CT(?MODULE,_,_), %% The fun ?CT(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported,[1]), @@ -379,36 +378,36 @@ return_test() -> setup([call]), erlang:trace_pattern({?MODULE,'_','_'},[{'_',[],[{return_trace}]}], [local]), - erlang:trace_pattern({erlang,hash,'_'},[{'_',[],[{return_trace}]}], + erlang:trace_pattern({erlang,phash2,'_'},[{'_',[],[{return_trace}]}], [local]), erlang:trace_pattern({?MODULE,slave,'_'},false,[local]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), - ?CT(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), + ?CT(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported,[1]), ?CT(?MODULE,local,[1]), ?CT(?MODULE,local2,[1]), ?CT(?MODULE,local_tail,[1]), - ?CT(erlang,hash,[1,1]), - ?RF(erlang,hash,2,1), - ?RF(?MODULE,local_tail,1,[1,1]), - ?RF(?MODULE,local2,1,[1,1]), - ?RF(?MODULE,local,1,[1,1,1]), - ?RF(?MODULE,exported,1,[1,1,1,1]), - ?RF(?MODULE,exported_wrap,1,[1,1,1,1]), + ?CT(erlang,phash2,[1,1023]), + ?RF(erlang,phash2,2,997), + ?RF(?MODULE,local_tail,1,[1,997]), + ?RF(?MODULE,local2,1,[1,997]), + ?RF(?MODULE,local,1,[1,1,997]), + ?RF(?MODULE,exported,1,[1,1,1,997]), + ?RF(?MODULE,exported_wrap,1,[1,1,1,997]), shutdown(), setup([call,return_to]), erlang:trace_pattern({?MODULE,'_','_'},[], [local]), - erlang:trace_pattern({erlang,hash,'_'},[], + erlang:trace_pattern({erlang,phash2,'_'},[], [local]), erlang:trace_pattern({?MODULE,slave,'_'},false,[local]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), - ?CT(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), + ?CT(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported,[1]), ?CT(?MODULE,local,[1]), ?CT(?MODULE,local2,[1]), ?CT(?MODULE,local_tail,[1]), - ?CT(erlang,hash,[1,1]), + ?CT(erlang,phash2,[1,1023]), ?RT(?MODULE,local_tail,1), ?RT(?MODULE,local,1), ?RT(?MODULE,exported,1), @@ -417,25 +416,25 @@ return_test() -> setup([call,return_to]), erlang:trace_pattern({?MODULE,'_','_'},[{'_',[],[{return_trace}]}], [local]), - erlang:trace_pattern({erlang,hash,'_'},[{'_',[],[{return_trace}]}], + erlang:trace_pattern({erlang,phash2,'_'},[{'_',[],[{return_trace}]}], [local]), erlang:trace_pattern({?MODULE,slave,'_'},false,[local]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), - ?CT(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), + ?CT(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported,[1]), ?CT(?MODULE,local,[1]), ?CT(?MODULE,local2,[1]), ?CT(?MODULE,local_tail,[1]), - ?CT(erlang,hash,[1,1]), - ?RF(erlang,hash,2,1), + ?CT(erlang,phash2,[1,1023]), + ?RF(erlang,phash2,2,997), ?RT(?MODULE,local_tail,1), - ?RF(?MODULE,local_tail,1,[1,1]), - ?RF(?MODULE,local2,1,[1,1]), + ?RF(?MODULE,local_tail,1,[1,997]), + ?RF(?MODULE,local2,1,[1,997]), ?RT(?MODULE,local,1), - ?RF(?MODULE,local,1,[1,1,1]), + ?RF(?MODULE,local,1,[1,1,997]), ?RT(?MODULE,exported,1), - ?RF(?MODULE,exported,1,[1,1,1,1]), - ?RF(?MODULE,exported_wrap,1,[1,1,1,1]), + ?RF(?MODULE,exported,1,[1,1,1,997]), + ?RF(?MODULE,exported_wrap,1,[1,1,1,997]), ?RT(?MODULE,slave,2), shutdown(), ?NM, @@ -446,7 +445,6 @@ return_test() -> erlang:trace_pattern({'_','_','_'},[],[local]), apply_slave(erlang,trace,[Pid, false, [all]]), shutdown(), - ok. on_and_off_test() -> @@ -456,72 +454,72 @@ on_and_off_test() -> LocalTail = fun() -> local_tail(1) end, - [1,1] = lambda_slave(LocalTail), + [1,997] = lambda_slave(LocalTail), ?CT(?MODULE,local_tail,[1]), erlang:trace(Pid,true,[return_to]), - [1,1] = lambda_slave(LocalTail), + [1,997] = lambda_slave(LocalTail), ?CT(?MODULE,local_tail,[1]), ?RT(?MODULE,_,_), 0 = erlang:trace_pattern({?MODULE,local_tail,1},[],[global]), - [1,1] = lambda_slave(LocalTail), + [1,997] = lambda_slave(LocalTail), ?NM, 1 = erlang:trace_pattern({?MODULE,exported_wrap,1},[],[global]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported_wrap,[1]), 1 = erlang:trace_pattern({?MODULE,exported_wrap,1},[],[local]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported_wrap,[1]), ?RT(?MODULE,slave,2), - 1 = erlang:trace_pattern({erlang,hash,2},[],[local]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), + 1 = erlang:trace_pattern({erlang,phash2,2},[],[local]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported_wrap,[1]), - ?CT(erlang,hash,[1,1]), + ?CT(erlang,phash2,[1,1023]), ?RT(?MODULE,local_tail,1), ?RT(?MODULE,slave,2), erlang:trace(Pid,true,[timestamp]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CTT(?MODULE,exported_wrap,[1]), - ?CTT(erlang,hash,[1,1]), + ?CTT(erlang,phash2,[1,1023]), ?RTT(?MODULE,local_tail,1), ?RTT(?MODULE,slave,2), erlang:trace(Pid,false,[return_to,timestamp]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported_wrap,[1]), - ?CT(erlang,hash,[1,1]), + ?CT(erlang,phash2,[1,1023]), erlang:trace(Pid,true,[return_to]), - 1 = erlang:trace_pattern({erlang,hash,2},[],[]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), + 1 = erlang:trace_pattern({erlang,phash2,2},[],[]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported_wrap,[1]), - ?CT(erlang,hash,[1,1]), + ?CT(erlang,phash2,[1,1023]), ?RT(?MODULE,slave,2), 1 = erlang:trace_pattern({?MODULE,exported_wrap,1},[],[]), - [1,1,1,1] = apply_slave(?MODULE,exported_wrap,[1]), + [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported_wrap,[1]), - ?CT(erlang,hash,[1,1]), + ?CT(erlang,phash2,[1,1023]), shutdown(), erlang:trace_pattern({'_','_','_'},false,[local]), N = erlang:trace_pattern({erlang,'_','_'},true,[local]), case erlang:trace_pattern({erlang,'_','_'},false,[local]) of - N -> + N -> ok; Else -> exit({number_mismatch, {expected, N}, {got, Else}}) end, case erlang:trace_pattern({erlang,'_','_'},false,[local]) of - N -> + N -> ok; Else2 -> exit({number_mismatch, {expected, N}, {got, Else2}}) end, M = erlang:trace_pattern({erlang,'_','_'},true,[]), case erlang:trace_pattern({erlang,'_','_'},false,[]) of - M -> + M -> ok; Else3 -> exit({number_mismatch, {expected, N}, {got, Else3}}) end, case erlang:trace_pattern({erlang,'_','_'},false,[]) of - M -> + M -> ok; Else4 -> exit({number_mismatch, {expected, N}, {got, Else4}}) @@ -930,7 +928,7 @@ local2(Val) -> local_tail(Val). %% Tail recursive call local_tail(Val) -> - [Val , erlang:hash(1,1)]. + [Val , erlang:phash2(1,1023)]. diff --git a/erts/emulator/test/z_SUITE.erl b/erts/emulator/test/z_SUITE.erl index d663cc548c..a90701c5d2 100644 --- a/erts/emulator/test/z_SUITE.erl +++ b/erts/emulator/test/z_SUITE.erl @@ -226,7 +226,7 @@ pollset_size(Config) when is_list(Config) -> "Pollset size information not available"} end; false -> - %% Somtimes we have fewer descriptors in the + %% Sometimes we have fewer descriptors in the %% pollset at the end than when we started, but %% that is ok as long as there are at least 2 %% descriptors (dist listen socket and |