diff options
Diffstat (limited to 'erts/emulator/test')
130 files changed, 2970 insertions, 563 deletions
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile index 318db4b45e..de395dfb97 100644 --- a/erts/emulator/test/Makefile +++ b/erts/emulator/test/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2012. All Rights Reserved. +# Copyright Ericsson AB 1997-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -70,6 +70,7 @@ MODULES= \ hash_SUITE \ hibernate_SUITE \ list_bif_SUITE \ + lttng_SUITE \ map_SUITE \ match_spec_SUITE \ module_info_SUITE \ @@ -109,8 +110,11 @@ MODULES= \ trace_meta_SUITE \ trace_call_count_SUITE \ trace_call_time_SUITE \ + tracer_SUITE \ + tracer_test \ scheduler_SUITE \ old_scheduler_SUITE \ + port_trace_SUITE \ unique_SUITE \ z_SUITE \ old_mod \ diff --git a/erts/emulator/test/a_SUITE.erl b/erts/emulator/test/a_SUITE.erl index 5b3a213154..880c5a5821 100644 --- a/erts/emulator/test/a_SUITE.erl +++ b/erts/emulator/test/a_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2011. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/after_SUITE.erl b/erts/emulator/test/after_SUITE.erl index a72cd8deea..4f20ad3656 100644 --- a/erts/emulator/test/after_SUITE.erl +++ b/erts/emulator/test/after_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl index 1f690c5015..5fb560d1ec 100644 --- a/erts/emulator/test/alloc_SUITE.erl +++ b/erts/emulator/test/alloc_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2013. All Rights Reserved. +%% Copyright Ericsson AB 2003-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -55,21 +55,13 @@ end_per_testcase(_Case, Config) when is_list(Config) -> %% %% basic(Cfg) -> drv_case(Cfg). - coalesce(Cfg) -> drv_case(Cfg). - threads(Cfg) -> drv_case(Cfg). - realloc_copy(Cfg) -> drv_case(Cfg). - bucket_index(Cfg) -> drv_case(Cfg). - bucket_mask(Cfg) -> drv_case(Cfg). - rbtree(Cfg) -> drv_case(Cfg). - mseg_clear_cache(Cfg) -> drv_case(Cfg). - cpool(Cfg) -> drv_case(Cfg). migration(Cfg) -> @@ -81,7 +73,7 @@ migration(Cfg) -> end. erts_mmap(Config) when is_list(Config) -> - case test_server:os_type() of + case os:type() of {unix, _} -> [erts_mmap_do(Config, SCO, SCRPM, SCRFSD) || SCO <-[true,false], SCRFSD <-[1234,0], SCRPM <- [true,false]]; @@ -109,25 +101,26 @@ erts_mmap_do(Config, SCO, SCRPM, SCRFSD) -> {ok, Node} = start_node(Config, Opts), Self = self(), Ref = make_ref(), - F = fun () -> - SI = erlang:system_info({allocator,mseg_alloc}), - {erts_mmap,EM} = lists:keyfind(erts_mmap, 1, SI), - {supercarrier,SC} = lists:keyfind(supercarrier, 1, EM), - {sizes,Sizes} = lists:keyfind(sizes, 1, SC), - {free_segs,Segs} = lists:keyfind(free_segs,1,SC), - {total,Total} = lists:keyfind(total,1,Sizes), - Total = SCS*1024*1024, - - {reserved,Reserved} = lists:keyfind(reserved,1,Segs), - true = (Reserved >= SCRFSD), - - case {SCO,lists:keyfind(os,1,EM)} of - {true, false} -> ok; - {false, {os,_}} -> ok - end, - - Self ! {Ref, ok} - end, + F = fun() -> + SI = erlang:system_info({allocator,mseg_alloc}), + {erts_mmap,EM} = lists:keyfind(erts_mmap, 1, SI), + {supercarrier,SC} = lists:keyfind(supercarrier, 1, EM), + {sizes,Sizes} = lists:keyfind(sizes, 1, SC), + {free_segs,Segs} = lists:keyfind(free_segs,1,SC), + {total,Total} = lists:keyfind(total,1,Sizes), + io:format("Expecting total ~w, got ~w~n", [SCS*1024*1024,Total]), + Total = SCS*1024*1024, + + {reserved,Reserved} = lists:keyfind(reserved,1,Segs), + true = (Reserved >= SCRFSD), + + case {SCO,lists:keyfind(os,1,EM)} of + {true, false} -> ok; + {false, {os,_}} -> ok + end, + + Self ! {Ref, ok} + end, spawn_link(Node, F), Result = receive {Ref, Rslt} -> Rslt end, @@ -144,7 +137,7 @@ drv_case(Config) -> drv_case(Config, one_shot, ""). drv_case(Config, Mode, NodeOpts) when is_list(Config) -> - case test_server:os_type() of + case os:type() of {Family, _} when Family == unix; Family == win32 -> {ok, Node} = start_node(Config, NodeOpts), Self = self(), diff --git a/erts/emulator/test/alloc_SUITE_data/cpool.c b/erts/emulator/test/alloc_SUITE_data/cpool.c index 73026cc758..0c41f4d747 100644 --- a/erts/emulator/test/alloc_SUITE_data/cpool.c +++ b/erts/emulator/test/alloc_SUITE_data/cpool.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2013. All Rights Reserved. + * Copyright Ericsson AB 2013-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/alloc_SUITE_data/migration.c b/erts/emulator/test/alloc_SUITE_data/migration.c index b006360043..b9a4de03b3 100644 --- a/erts/emulator/test/alloc_SUITE_data/migration.c +++ b/erts/emulator/test/alloc_SUITE_data/migration.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2014. All Rights Reserved. + * Copyright Ericsson AB 2014-2016. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in diff --git a/erts/emulator/test/beam_SUITE.erl b/erts/emulator/test/beam_SUITE.erl index f61ab431e9..6a54fa87e0 100644 --- a/erts/emulator/test/beam_SUITE.erl +++ b/erts/emulator/test/beam_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2013. All Rights Reserved. +%% Copyright Ericsson AB 1998-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ -export([applied/2,swap_temp_applied/1]). -include_lib("common_test/include/ct.hrl"). +-include_lib("syntax_tools/include/merl.hrl"). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -93,48 +94,46 @@ applied(Starter, N) -> apply_last_bif(Config) when is_list(Config) -> apply(erlang, abs, [1]). -%% Test three high register numbers in a put_list instruction -%% (to test whether packing works properly). +%% Test whether packing works properly. packed_registers(Config) when is_list(Config) -> - PrivDir = proplists:get_value(priv_dir, Config), - Mod = packed_regs, - Name = filename:join(PrivDir, atom_to_list(Mod) ++ ".erl"), - - %% Generate a module which generates a list of tuples. - %% put_list(A) -> [{A, 600}, {A, 999}, ... {A, 0}]. - Code = gen_packed_regs(600, ["-module("++atom_to_list(Mod)++").\n", - "-export([put_list/1]).\n", - "put_list(A) ->\n["]), - ok = file:write_file(Name, Code), - - %% Compile the module. - io:format("Compiling: ~s\n", [Name]), - CompRc = compile:file(Name, [{outdir, PrivDir}, report]), - io:format("Result: ~p\n",[CompRc]), - {ok, Mod} = CompRc, - - %% Load it. - io:format("Loading...\n",[]), - LoadRc = code:load_abs(filename:join(PrivDir, atom_to_list(Mod))), - {module,_Module} = LoadRc, - - %% Call it and verify result. - Term = {a, b}, - L = Mod:put_list(Term), - verify_packed_regs(L, Term, 600), + Mod = ?FUNCTION_NAME, + + %% Generate scrambled sequence. + Seq0 = [{erlang:phash2(I),I} || I <- lists:seq(0, 260)], + Seq = [I || {_,I} <- lists:sort(Seq0)], + + %% Generate a test modules that uses get_list/3 instructions + %% with high register numbers. + S0 = [begin + VarName = list_to_atom("V"++integer_to_list(V)), + {merl:var(VarName),V} + end || V <- Seq], + Vars = [V || {V,_} <- S0], + NewVars = [begin + VarName = list_to_atom("M"++integer_to_list(V)), + merl:var(VarName) + end || V <- Seq], + S = [?Q("_@Var = id(_@Value@)") || {Var,Value} <- S0], + Code = ?Q(["-module('@Mod@').\n" + "-export([f/0]).\n" + "f() ->\n" + "_@S,\n" + "_ = id(0),\n" + "L = [_@Vars],\n" + "_ = id(1),\n" + "[_@NewVars] = L,\n" %Test get_list/3. + "_ = id(2),\n" + "id([_@Vars,_@NewVars]).\n" + "id(I) -> I.\n"]), + merl:compile_and_load(Code), + CombinedSeq = Seq ++ Seq, + CombinedSeq = Mod:f(), + + %% Clean up. + true = code:delete(Mod), + false = code:purge(Mod), ok. -gen_packed_regs(0, Acc) -> - [Acc|"{A,0}].\n"]; -gen_packed_regs(N, Acc) -> - gen_packed_regs(N-1, [Acc,"{A,",integer_to_list(N)|"},\n"]). - -verify_packed_regs([], _, -1) -> ok; -verify_packed_regs([{Term, N}| T], Term, N) -> - verify_packed_regs(T, Term, N-1); -verify_packed_regs(L, Term, N) -> - ct:fail("Expected [{~p, ~p}|T]; got\n~p\n", [Term, N, L]). - buildo_mucho(Config) when is_list(Config) -> buildo_mucho_1(), ok. diff --git a/erts/emulator/test/beam_literals_SUITE.erl b/erts/emulator/test/beam_literals_SUITE.erl index b013ff5fbb..09761263e2 100644 --- a/erts/emulator/test/beam_literals_SUITE.erl +++ b/erts/emulator/test/beam_literals_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2015. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl index 43d00e699a..26bb416bf0 100644 --- a/erts/emulator/test/bif_SUITE.erl +++ b/erts/emulator/test/bif_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2012. All Rights Reserved. +%% Copyright Ericsson AB 2005-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/big_SUITE.erl b/erts/emulator/test/big_SUITE.erl index d331083661..402751393a 100644 --- a/erts/emulator/test/big_SUITE.erl +++ b/erts/emulator/test/big_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/big_SUITE_data/literal_test.erl b/erts/emulator/test/big_SUITE_data/literal_test.erl index 1620693bfa..17c4db467a 100644 --- a/erts/emulator/test/big_SUITE_data/literal_test.erl +++ b/erts/emulator/test/big_SUITE_data/literal_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl index fcd49e43d3..1c7d278bb0 100644 --- a/erts/emulator/test/binary_SUITE.erl +++ b/erts/emulator/test/binary_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2014. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/bs_bincomp_SUITE.erl b/erts/emulator/test/bs_bincomp_SUITE.erl index 8836fe40ae..c481e93e41 100644 --- a/erts/emulator/test/bs_bincomp_SUITE.erl +++ b/erts/emulator/test/bs_bincomp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2011. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/bs_bit_binaries_SUITE.erl b/erts/emulator/test/bs_bit_binaries_SUITE.erl index dd056d10af..d393bc5b91 100644 --- a/erts/emulator/test/bs_bit_binaries_SUITE.erl +++ b/erts/emulator/test/bs_bit_binaries_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2012. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl index 8deb0c7422..941cb435f7 100644 --- a/erts/emulator/test/bs_construct_SUITE.erl +++ b/erts/emulator/test/bs_construct_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/bs_match_bin_SUITE.erl b/erts/emulator/test/bs_match_bin_SUITE.erl index 6f7abf8c4e..f5c996ae9e 100644 --- a/erts/emulator/test/bs_match_bin_SUITE.erl +++ b/erts/emulator/test/bs_match_bin_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/bs_match_int_SUITE.erl b/erts/emulator/test/bs_match_int_SUITE.erl index 42d692c1ba..a7bd4b8ac3 100644 --- a/erts/emulator/test/bs_match_int_SUITE.erl +++ b/erts/emulator/test/bs_match_int_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/bs_match_misc_SUITE.erl b/erts/emulator/test/bs_match_misc_SUITE.erl index 114d7ecb36..17759d78f3 100644 --- a/erts/emulator/test/bs_match_misc_SUITE.erl +++ b/erts/emulator/test/bs_match_misc_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2011. All Rights Reserved. +%% Copyright Ericsson AB 2000-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/bs_match_tail_SUITE.erl b/erts/emulator/test/bs_match_tail_SUITE.erl index 8392a0df47..cbebc554c7 100644 --- a/erts/emulator/test/bs_match_tail_SUITE.erl +++ b/erts/emulator/test/bs_match_tail_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/bs_utf_SUITE.erl b/erts/emulator/test/bs_utf_SUITE.erl index f1c09bfbb0..a344f5c456 100644 --- a/erts/emulator/test/bs_utf_SUITE.erl +++ b/erts/emulator/test/bs_utf_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/busy_port_SUITE.erl b/erts/emulator/test/busy_port_SUITE.erl index c582f8d77b..bb0632ae08 100644 --- a/erts/emulator/test/busy_port_SUITE.erl +++ b/erts/emulator/test/busy_port_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/busy_port_SUITE_data/Makefile.src b/erts/emulator/test/busy_port_SUITE_data/Makefile.src index 0f2842e515..ae6378a6ff 100644 --- a/erts/emulator/test/busy_port_SUITE_data/Makefile.src +++ b/erts/emulator/test/busy_port_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2013. All Rights Reserved. +# Copyright Ericsson AB 1997-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/busy_port_SUITE_data/hard_busy_drv.c b/erts/emulator/test/busy_port_SUITE_data/hard_busy_drv.c index f83fa1eeaa..c4e0f13f06 100644 --- a/erts/emulator/test/busy_port_SUITE_data/hard_busy_drv.c +++ b/erts/emulator/test/busy_port_SUITE_data/hard_busy_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2009. All Rights Reserved. + * Copyright Ericsson AB 2009-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c b/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c index be913cf56e..ffaca18e90 100644 --- a/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c +++ b/erts/emulator/test/busy_port_SUITE_data/hs_busy_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2009-2013. All Rights Reserved. + * Copyright Ericsson AB 2009-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c b/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c index 40e42b6ac2..296b3f21de 100644 --- a/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c +++ b/erts/emulator/test/busy_port_SUITE_data/scheduling_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2009-2013. All Rights Reserved. + * Copyright Ericsson AB 2009-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/busy_port_SUITE_data/soft_busy_drv.c b/erts/emulator/test/busy_port_SUITE_data/soft_busy_drv.c index 3c5bafb451..8a98f050f1 100644 --- a/erts/emulator/test/busy_port_SUITE_data/soft_busy_drv.c +++ b/erts/emulator/test/busy_port_SUITE_data/soft_busy_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2009. All Rights Reserved. + * Copyright Ericsson AB 2009-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl index 4ec18aa49e..6ba6301c7c 100644 --- a/erts/emulator/test/call_trace_SUITE.erl +++ b/erts/emulator/test/call_trace_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -84,32 +84,46 @@ process_specs(Config) when is_list(Config) -> {tracer,Tracer} = trace_info(self(), tracer), trace_func({?MODULE,worker_foo,1}, []), - %% Test the 'new' flag. - - {Work1A,Work1B} = start_and_trace(new, [1,2,3], A1B={3,2,1}), - {flags,[]} = trace_info(Work1A, flags), - {tracer,[]} = trace_info(Work1A, tracer), - {tracer,Tracer} = trace_info(Work1B, tracer), - {flags,[call]} = trace_info(Work1B, flags), - expect({trace,Work1B,call,{?MODULE,worker_foo,[A1B]}}), - unlink(Work1B), - Mref = erlang:monitor(process, Work1B), - exit(Work1B, kill), - receive - {'DOWN',Mref,_,_,_} -> ok - end, - undefined = trace_info(Work1B, flags), - {flags,[]} = trace_info(new, flags), - {tracer,[]} = trace_info(new, tracer), - - %% Test the 'existing' flag. - {Work2A,_Work2B} = start_and_trace(existing, A2A=[5,6,7], [7,6,5]), - expect({trace,Work2A,call,{?MODULE,worker_foo,[A2A]}}), - - %% Test the 'all' flag. - {Work3A,Work3B} = start_and_trace(all, A3A=[12,13], A3B=[13,12]), - expect({trace,Work3A,call,{?MODULE,worker_foo,[A3A]}}), - expect({trace,Work3B,call,{?MODULE,worker_foo,[A3B]}}), + %% Test the 'new' and 'new_processes' flags. + + New = fun(Flag) -> + {Work1A,Work1B} = start_and_trace(Flag, [1,2,3], A1B={3,2,1}), + {flags,[]} = trace_info(Work1A, flags), + {tracer,[]} = trace_info(Work1A, tracer), + {tracer,Tracer} = trace_info(Work1B, tracer), + {flags,[call]} = trace_info(Work1B, flags), + expect({trace,Work1B,call,{?MODULE,worker_foo,[A1B]}}), + unlink(Work1B), + Mref = erlang:monitor(process, Work1B), + exit(Work1B, kill), + receive + {'DOWN',Mref,_,_,_} -> ok + end, + undefined = trace_info(Work1B, flags), + {flags,[]} = trace_info(Flag, flags), + {tracer,[]} = trace_info(Flag, tracer) + end, + New(new), + New(new_processes), + + %% Test the 'existing' and 'existing_processes' flags. + Existing = + fun(Flag) -> + {Work2A,_Work2B} = start_and_trace(Flag, A2A=[5,6,7], [7,6,5]), + expect({trace,Work2A,call,{?MODULE,worker_foo,[A2A]}}) + end, + Existing(existing), + Existing(existing_processes), + + %% Test the 'all' and 'processes' flags. + All = + fun(Flag) -> + {Work3A,Work3B} = start_and_trace(Flag, A3A=[12,13], A3B=[13,12]), + expect({trace,Work3A,call,{?MODULE,worker_foo,[A3A]}}), + expect({trace,Work3B,call,{?MODULE,worker_foo,[A3B]}}) + end, + All(all), + All(processes), ok. diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl index db285a3977..29b95ef674 100644 --- a/erts/emulator/test/code_SUITE.erl +++ b/erts/emulator/test/code_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/code_SUITE_data/another_code_test.erl b/erts/emulator/test/code_SUITE_data/another_code_test.erl index f6f9e32996..5708ec682c 100644 --- a/erts/emulator/test/code_SUITE_data/another_code_test.erl +++ b/erts/emulator/test/code_SUITE_data/another_code_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2009. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/code_SUITE_data/cpbugx.erl b/erts/emulator/test/code_SUITE_data/cpbugx.erl index ea01ce411b..ae2075c867 100644 --- a/erts/emulator/test/code_SUITE_data/cpbugx.erl +++ b/erts/emulator/test/code_SUITE_data/cpbugx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/code_SUITE_data/fun_confusion.erl b/erts/emulator/test/code_SUITE_data/fun_confusion.erl index 8d42937d3c..35279f241d 100644 --- a/erts/emulator/test/code_SUITE_data/fun_confusion.erl +++ b/erts/emulator/test/code_SUITE_data/fun_confusion.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/code_SUITE_data/literals.erl b/erts/emulator/test/code_SUITE_data/literals.erl index a36bfe09dd..7c3b0ebe73 100644 --- a/erts/emulator/test/code_SUITE_data/literals.erl +++ b/erts/emulator/test/code_SUITE_data/literals.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/code_SUITE_data/many_funs.erl b/erts/emulator/test/code_SUITE_data/many_funs.erl index e832f271d0..ada570feee 100644 --- a/erts/emulator/test/code_SUITE_data/many_funs.erl +++ b/erts/emulator/test/code_SUITE_data/many_funs.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/code_SUITE_data/my_code_test.erl b/erts/emulator/test/code_SUITE_data/my_code_test.erl index 57d867a5ac..d2386157d6 100644 --- a/erts/emulator/test/code_SUITE_data/my_code_test.erl +++ b/erts/emulator/test/code_SUITE_data/my_code_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/code_SUITE_data/versions.erl b/erts/emulator/test/code_SUITE_data/versions.erl index 0e2d92c8f1..56407e877a 100644 --- a/erts/emulator/test/code_SUITE_data/versions.erl +++ b/erts/emulator/test/code_SUITE_data/versions.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/code_parallel_load_SUITE.erl b/erts/emulator/test/code_parallel_load_SUITE.erl index e9e7000434..827add71e5 100644 --- a/erts/emulator/test/code_parallel_load_SUITE.erl +++ b/erts/emulator/test/code_parallel_load_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012-2014. All Rights Reserved. +%% Copyright Ericsson AB 2012-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/crypto_SUITE.erl b/erts/emulator/test/crypto_SUITE.erl index 6212997272..afb1be7332 100644 --- a/erts/emulator/test/crypto_SUITE.erl +++ b/erts/emulator/test/crypto_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/crypto_reference.erl b/erts/emulator/test/crypto_reference.erl index 7797eacd75..950b0c1560 100644 --- a/erts/emulator/test/crypto_reference.erl +++ b/erts/emulator/test/crypto_reference.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl index 6982178827..93b6f2d956 100644 --- a/erts/emulator/test/ddll_SUITE.erl +++ b/erts/emulator/test/ddll_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/decode_packet_SUITE.erl b/erts/emulator/test/decode_packet_SUITE.erl index ad592f7147..54ee4d5567 100644 --- a/erts/emulator/test/decode_packet_SUITE.erl +++ b/erts/emulator/test/decode_packet_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/dgawd_handler.erl b/erts/emulator/test/dgawd_handler.erl index bba69ef87e..52cdd26427 100644 --- a/erts/emulator/test/dgawd_handler.erl +++ b/erts/emulator/test/dgawd_handler.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2010. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl index f116ec979b..d0096fb1bc 100644 --- a/erts/emulator/test/distribution_SUITE.erl +++ b/erts/emulator/test/distribution_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -1034,6 +1034,7 @@ atom_roundtrip(Config) when is_list(Config) -> atom_roundtrip_r15b(Config) when is_list(Config) -> case test_server:is_release_available("r15b") of true -> + ct:timetrap({minutes, 6}), AtomData = atom_data(), verify_atom_data(AtomData), {ok, Node} = start_node(Config, [], "r15b"), diff --git a/erts/emulator/test/distribution_SUITE_data/run.erl b/erts/emulator/test/distribution_SUITE_data/run.erl index d5ed139369..f574b2c02c 100644 --- a/erts/emulator/test/distribution_SUITE_data/run.erl +++ b/erts/emulator/test/distribution_SUITE_data/run.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl index c589470f5b..f134a197aa 100644 --- a/erts/emulator/test/driver_SUITE.erl +++ b/erts/emulator/test/driver_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2014. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/driver_SUITE_data/async_blast_drv.c b/erts/emulator/test/driver_SUITE_data/async_blast_drv.c index a1008afcae..1432bc42c1 100644 --- a/erts/emulator/test/driver_SUITE_data/async_blast_drv.c +++ b/erts/emulator/test/driver_SUITE_data/async_blast_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2011-2013. All Rights Reserved. + * Copyright Ericsson AB 2011-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/driver_SUITE_data/consume_timeslice_drv.c b/erts/emulator/test/driver_SUITE_data/consume_timeslice_drv.c index 192ac02d3e..142ae46247 100644 --- a/erts/emulator/test/driver_SUITE_data/consume_timeslice_drv.c +++ b/erts/emulator/test/driver_SUITE_data/consume_timeslice_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2012-2013. All Rights Reserved. + * Copyright Ericsson AB 2012-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c index e2221b9e17..d87c2bec93 100644 --- a/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c +++ b/erts/emulator/test/driver_SUITE_data/ioq_exit_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2007-2013. All Rights Reserved. + * Copyright Ericsson AB 2007-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c b/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c index fdf8e4c0ad..37cb93fb3a 100644 --- a/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c +++ b/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2011-2014. All Rights Reserved. + * Copyright Ericsson AB 2011-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/driver_SUITE_data/thr_free_drv.c b/erts/emulator/test/driver_SUITE_data/thr_free_drv.c index 54205f190e..48fe5fa435 100644 --- a/erts/emulator/test/driver_SUITE_data/thr_free_drv.c +++ b/erts/emulator/test/driver_SUITE_data/thr_free_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2011. All Rights Reserved. + * Copyright Ericsson AB 2011-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c b/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c index f7a7cc2b8e..56183c9484 100644 --- a/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c +++ b/erts/emulator/test/driver_SUITE_data/thr_msg_blast_drv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2012. All Rights Reserved. + * Copyright Ericsson AB 2012-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/efile_SUITE.erl b/erts/emulator/test/efile_SUITE.erl index cefa35a3ee..6bb8487c4e 100644 --- a/erts/emulator/test/efile_SUITE.erl +++ b/erts/emulator/test/efile_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/erl_drv_thread_SUITE.erl b/erts/emulator/test/erl_drv_thread_SUITE.erl index 41a761229c..f99c151936 100644 --- a/erts/emulator/test/erl_drv_thread_SUITE.erl +++ b/erts/emulator/test/erl_drv_thread_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -65,7 +65,7 @@ drv_case(Config, CaseName, Command, TimeTrap) when is_list(Config), is_atom(CaseName), is_list(Command), is_integer(TimeTrap) -> - case test_server:os_type() of + case os:type() of {Family, _} when Family == unix; Family == win32 -> run_drv_case(Config, CaseName, Command, TimeTrap); SkipOs -> diff --git a/erts/emulator/test/erl_link_SUITE.erl b/erts/emulator/test/erl_link_SUITE.erl index 56fdfc35c0..93d2065ba3 100644 --- a/erts/emulator/test/erl_link_SUITE.erl +++ b/erts/emulator/test/erl_link_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% Copyright Ericsson AB 2001-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/erts_debug_SUITE.erl b/erts/emulator/test/erts_debug_SUITE.erl index e757ebdb3d..23871585f7 100644 --- a/erts/emulator/test/erts_debug_SUITE.erl +++ b/erts/emulator/test/erts_debug_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2012. All Rights Reserved. +%% Copyright Ericsson AB 2005-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/estone_SUITE.erl b/erts/emulator/test/estone_SUITE.erl index 93728b299b..1180a45585 100644 --- a/erts/emulator/test/estone_SUITE.erl +++ b/erts/emulator/test/estone_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/evil_SUITE.erl b/erts/emulator/test/evil_SUITE.erl index 5f5a0ef305..9416ac7a02 100644 --- a/erts/emulator/test/evil_SUITE.erl +++ b/erts/emulator/test/evil_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2011. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl index 1cad7e7920..76e3556bc4 100644 --- a/erts/emulator/test/exception_SUITE.erl +++ b/erts/emulator/test/exception_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/float_SUITE.erl b/erts/emulator/test/float_SUITE.erl index 78dec8c725..e85addae3a 100644 --- a/erts/emulator/test/float_SUITE.erl +++ b/erts/emulator/test/float_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/float_SUITE_data/has_fpe_bug.erl b/erts/emulator/test/float_SUITE_data/has_fpe_bug.erl index 79ab74dfff..26837de274 100644 --- a/erts/emulator/test/float_SUITE_data/has_fpe_bug.erl +++ b/erts/emulator/test/float_SUITE_data/has_fpe_bug.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl index 044c6aabca..26fa955e3c 100644 --- a/erts/emulator/test/fun_SUITE.erl +++ b/erts/emulator/test/fun_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/fun_r13_SUITE.erl b/erts/emulator/test/fun_r13_SUITE.erl index d66026705b..a45ed08b9d 100644 --- a/erts/emulator/test/fun_r13_SUITE.erl +++ b/erts/emulator/test/fun_r13_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl index 8e5f0b05a1..79c229a34d 100644 --- a/erts/emulator/test/gc_SUITE.erl +++ b/erts/emulator/test/gc_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/guard_SUITE.erl b/erts/emulator/test/guard_SUITE.erl index 6ad4456e6b..e155e5f49f 100644 --- a/erts/emulator/test/guard_SUITE.erl +++ b/erts/emulator/test/guard_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/hash_SUITE.erl b/erts/emulator/test/hash_SUITE.erl index be254f5543..a39d101b0d 100644 --- a/erts/emulator/test/hash_SUITE.erl +++ b/erts/emulator/test/hash_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2013. All Rights Reserved. +%% Copyright Ericsson AB 2000-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/hibernate_SUITE.erl b/erts/emulator/test/hibernate_SUITE.erl index 45f0bdc4da..6f8ce02266 100644 --- a/erts/emulator/test/hibernate_SUITE.erl +++ b/erts/emulator/test/hibernate_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2012. All Rights Reserved. +%% Copyright Ericsson AB 2003-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/ignore_cores.erl b/erts/emulator/test/ignore_cores.erl index 7373303a39..25dce346b9 100644 --- a/erts/emulator/test/ignore_cores.erl +++ b/erts/emulator/test/ignore_cores.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -94,7 +94,7 @@ setup(Suite, Testcase, Config, SetCwd) when is_atom(Suite), end, ok = file:write_file(filename:join([IgnDir, "ignore_core_files"]), <<>>), %% cores are dumped in /cores on MacOS X - CoresDir = case {test_server:os_type(), filelib:is_dir("/cores")} of + CoresDir = case {os:type(), filelib:is_dir("/cores")} of {{unix,darwin}, true} -> filelib:fold_files("/cores", "^core.*$", diff --git a/erts/emulator/test/list_bif_SUITE.erl b/erts/emulator/test/list_bif_SUITE.erl index 1f64a6a8e5..514dd2f412 100644 --- a/erts/emulator/test/list_bif_SUITE.erl +++ b/erts/emulator/test/list_bif_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/long_timers_test.erl b/erts/emulator/test/long_timers_test.erl index 9415e1cced..7c055a31f9 100644 --- a/erts/emulator/test/long_timers_test.erl +++ b/erts/emulator/test/long_timers_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2010. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/lttng_SUITE.erl b/erts/emulator/test/lttng_SUITE.erl new file mode 100644 index 0000000000..d0f6292d5b --- /dev/null +++ b/erts/emulator/test/lttng_SUITE.erl @@ -0,0 +1,499 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2011. 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% +%% + +-module(lttng_SUITE). + +-export([all/0, suite/0]). +-export([init_per_suite/1, end_per_suite/1]). +-export([init_per_testcase/2, end_per_testcase/2]). + +-export([t_lttng_list/1, + t_carrier_pool/1, + t_memory_carrier/1, + t_async_io_pool/1, + t_driver_control_ready_async/1, + t_driver_start_stop/1, + t_driver_ready_input_output/1, + t_driver_timeout/1, + t_driver_caller/1, + t_driver_flush/1, + t_scheduler_poll/1]). + +-include_lib("common_test/include/ct.hrl"). + +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {seconds, 10}}]. + +all() -> + [t_lttng_list, + t_carrier_pool, + t_async_io_pool, + t_driver_start_stop, + t_driver_ready_input_output, + t_driver_control_ready_async, + t_driver_timeout, + t_driver_caller, + t_driver_flush, + t_scheduler_poll, + t_memory_carrier]. + + +init_per_suite(Config) -> + case erlang:system_info(dynamic_trace) of + lttng -> + ensure_lttng_stopped("--all"), + Config; + _ -> + {skip, "No LTTng configured on system."} + end. + +end_per_suite(_Config) -> + ensure_lttng_stopped("--all"), + ok. + +init_per_testcase(Case, Config) -> + Name = atom_to_list(Case), + ok = ensure_lttng_started(Name, Config), + [{session, Name}|Config]. + +end_per_testcase(Case, _Config) -> + Name = atom_to_list(Case), + ok = ensure_lttng_stopped(Name), + ok. + +%% Not tested yet +%% com_ericsson_otp:driver_process_exit +%% com_ericsson_otp:driver_event + +%% tracepoints +%% +%% com_ericsson_otp:carrier_pool_get +%% com_ericsson_otp:carrier_pool_put +%% com_ericsson_otp:carrier_destroy +%% com_ericsson_otp:carrier_create +%% com_ericsson_otp:aio_pool_add +%% com_ericsson_otp:aio_pool_get +%% com_ericsson_otp:driver_control +%% com_ericsson_otp:driver_call +%% com_ericsson_otp:driver_finish +%% com_ericsson_otp:driver_ready_async +%% com_ericsson_otp:driver_process_exit +%% com_ericsson_otp:driver_stop +%% com_ericsson_otp:driver_flush +%% com_ericsson_otp:driver_stop_select +%% com_ericsson_otp:driver_timeout +%% com_ericsson_otp:driver_event +%% com_ericsson_otp:driver_ready_output +%% com_ericsson_otp:driver_ready_input +%% com_ericsson_otp:driver_output +%% com_ericsson_otp:driver_outputv +%% com_ericsson_otp:driver_init +%% com_ericsson_otp:driver_start +%% com_ericsson_otp:scheduler_poll + +%% +%% Testcases +%% + +t_lttng_list(_Config) -> + {ok, _} = cmd("lttng list -u"), + ok. + +%% com_ericsson_otp:carrier_pool_get +%% com_ericsson_otp:carrier_pool_put +t_carrier_pool(Config) -> + case have_carriers() of + false -> + {skip, "No Memory Carriers configured on system."}; + true -> + ok = lttng_start_event("com_ericsson_otp:carrier_pool*", Config), + + ok = ets_load(), + + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:carrier_pool_get", Res), + ok = check_tracepoint("com_ericsson_otp:carrier_pool_put", Res), + ok + end. + +%% com_ericsson_otp:carrier_destroy +%% com_ericsson_otp:carrier_create +t_memory_carrier(Config) -> + case have_carriers() of + false -> + {skip, "No Memory Carriers configured on system."}; + true -> + ok = lttng_start_event("com_ericsson_otp:carrier_*", Config), + + ok = ets_load(), + + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:carrier_destroy", Res), + ok = check_tracepoint("com_ericsson_otp:carrier_create", Res), + ok + end. + +%% com_ericsson_otp:aio_pool_add +%% com_ericsson_otp:aio_pool_get +t_async_io_pool(Config) -> + case have_async_threads() of + false -> + {skip, "No Async Threads configured on system."}; + true -> + ok = lttng_start_event("com_ericsson_otp:aio_pool_*", Config), + + Path1 = proplists:get_value(priv_dir, Config), + {ok, [[Path2]]} = init:get_argument(home), + {ok, _} = file:list_dir(Path1), + {ok, _} = file:list_dir(Path2), + {ok, _} = file:list_dir(Path1), + {ok, _} = file:list_dir(Path2), + + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:aio_pool_add", Res), + ok = check_tracepoint("com_ericsson_otp:aio_pool_get", Res), + ok + end. + + +%% com_ericsson_otp:driver_start +%% com_ericsson_otp:driver_stop +t_driver_start_stop(Config) -> + ok = lttng_start_event("com_ericsson_otp:driver_*", Config), + Path = proplists:get_value(priv_dir, Config), + Name = filename:join(Path, "sometext.txt"), + Bin = txt(), + ok = file:write_file(Name, Bin), + {ok, Bin} = file:read_file(Name), + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:driver_start", Res), + ok = check_tracepoint("com_ericsson_otp:driver_stop", Res), + ok = check_tracepoint("com_ericsson_otp:driver_control", Res), + ok = check_tracepoint("com_ericsson_otp:driver_outputv", Res), + ok = check_tracepoint("com_ericsson_otp:driver_ready_async", Res), + ok. + +%% com_ericsson_otp:driver_control +%% com_ericsson_otp:driver_outputv +%% com_ericsson_otp:driver_ready_async +t_driver_control_ready_async(Config) -> + ok = lttng_start_event("com_ericsson_otp:driver_control", Config), + ok = lttng_start_event("com_ericsson_otp:driver_outputv", Config), + ok = lttng_start_event("com_ericsson_otp:driver_ready_async", Config), + Path = proplists:get_value(priv_dir, Config), + Name = filename:join(Path, "sometext.txt"), + Bin = txt(), + ok = file:write_file(Name, Bin), + {ok, Bin} = file:read_file(Name), + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:driver_control", Res), + ok = check_tracepoint("com_ericsson_otp:driver_outputv", Res), + ok = check_tracepoint("com_ericsson_otp:driver_ready_async", Res), + ok. + +%% com_ericsson_otp:driver_ready_input +%% com_ericsson_otp:driver_ready_output +t_driver_ready_input_output(Config) -> + ok = lttng_start_event("com_ericsson_otp:driver_ready_*", Config), + Me = self(), + Pid = spawn_link(fun() -> tcp_server(Me, active) end), + receive {Pid, accept} -> ok end, + Bin = txt(), + Sz = byte_size(Bin), + + {ok, Sock} = gen_tcp:connect("localhost", 5679, [binary, {packet, 2}]), + ok = gen_tcp:send(Sock, <<Sz:16, Bin/binary>>), + ok = gen_tcp:send(Sock, <<Sz:16, Bin/binary>>), + ok = gen_tcp:close(Sock), + receive {Pid, done} -> ok end, + + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:driver_ready_input", Res), + ok = check_tracepoint("com_ericsson_otp:driver_ready_output", Res), + ok. + + +%% com_ericsson_otp:driver_stop_select +%% com_ericsson_otp:driver_timeout +t_driver_timeout(Config) -> + ok = lttng_start_event("com_ericsson_otp:driver_*", Config), + Me = self(), + Pid = spawn_link(fun() -> tcp_server(Me, timeout) end), + receive {Pid, accept} -> ok end, + {ok, Sock} = gen_tcp:connect("localhost", 5679, [binary]), + ok = gen_tcp:send(Sock, <<"hej">>), + receive {Pid, done} -> ok end, + ok = gen_tcp:close(Sock), + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:driver_timeout", Res), + ok = check_tracepoint("com_ericsson_otp:driver_stop_select", Res), + ok. + +%% com_ericsson_otp:driver_call +%% com_ericsson_otp:driver_output +%% com_ericsson_otp:driver_init +%% com_ericsson_otp:driver_finish +t_driver_caller(Config) -> + ok = lttng_start_event("com_ericsson_otp:driver_*", Config), + + Drv = 'caller_drv', + os:putenv("CALLER_DRV_USE_OUTPUTV", "false"), + + ok = load_driver(proplists:get_value(data_dir, Config), Drv), + Port = open_port({spawn, Drv}, []), + true = is_port(Port), + + chk_caller(Port, start, self()), + chk_caller(Port, output, spawn_link(fun() -> + port_command(Port, "") + end)), + Port ! {self(), {command, ""}}, + chk_caller(Port, output, self()), + chk_caller(Port, control, spawn_link(fun () -> + port_control(Port, 0, "") + end)), + chk_caller(Port, call, spawn_link(fun() -> + erlang:port_call(Port, 0, "") + end)), + + true = port_close(Port), + erl_ddll:unload_driver(Drv), + + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:driver_call", Res), + ok = check_tracepoint("com_ericsson_otp:driver_output", Res), + ok = check_tracepoint("com_ericsson_otp:driver_init", Res), + ok = check_tracepoint("com_ericsson_otp:driver_finish", Res), + ok. + +%% com_ericsson_otp:scheduler_poll +t_scheduler_poll(Config) -> + ok = lttng_start_event("com_ericsson_otp:scheduler_poll", Config), + + ok = memory_load(), + + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:scheduler_poll", Res), + ok. + +%% com_ericsson_otp:driver_flush +t_driver_flush(Config) -> + ok = lttng_start_event("com_ericsson_otp:driver_flush", Config), + + Me = self(), + Pid = spawn_link(fun() -> tcp_server(Me, passive_no_read) end), + receive {Pid, accept} -> ok end, + Bin = iolist_to_binary([txt() || _ <- lists:seq(1,100)]), + Sz = byte_size(Bin), + + %% We want to create a scenario where sendings stalls and we + %% queue packets in the driver. + %% When we close the socket it has to flush the queue. + {ok, Sock} = gen_tcp:connect("localhost", 5679, [binary, {packet, 2}, + {send_timeout, 10}, + {sndbuf, 10000000}]), + Pids = [spawn_link(fun() -> + gen_tcp:send(Sock, <<Sz:16, Bin/binary>>), + Me ! {self(), ok} + end) || _ <- lists:seq(1,100)], + [receive {P, ok} -> ok end || P <- Pids], + ok = gen_tcp:close(Sock), + Pid ! die, + receive {Pid, done} -> ok end, + + Res = lttng_stop_and_view(Config), + ok = check_tracepoint("com_ericsson_otp:driver_flush", Res), + ok. + +%% +%% AUX +%% + +chk_caller(Port, Callback, ExpectedCaller) -> + receive + {caller, Port, Callback, Caller} -> + ExpectedCaller = Caller + end. + + +ets_load() -> + Tid = ets:new(ets_load, [public,set]), + N = erlang:system_info(schedulers_online), + Pids = [spawn_link(fun() -> ets_shuffle(Tid) end) || _ <- lists:seq(1,N)], + ok = ets_kill(Pids, 500), + ok. + + +ets_kill([], _) -> ok; +ets_kill([Pid|Pids], Time) -> + timer:sleep(Time), + Pid ! done, + ets_kill(Pids, Time). + +ets_shuffle(Tid) -> + Payload = lists:duplicate(100, $x), + ets_shuffle(Tid, 100, Payload). +ets_shuffle(Tid, I, Data) -> + ets_shuffle(Tid, I, I, Data, Data). + +ets_shuffle(Tid, 0, N, _, Data) -> + ets_shuffle(Tid, N, N, Data, Data); +ets_shuffle(Tid, I, N, Data, Data0) -> + receive + done -> ok + after 0 -> + Key = rand:uniform(1000), + Data1 = [I|Data], + ets:insert(Tid, {Key, Data1}), + ets_shuffle(Tid, I - 1, N, Data1, Data0) + end. + + + + +memory_load() -> + Me = self(), + Pids0 = [spawn_link(fun() -> memory_loop(Me, 20, <<42>>) end) || _ <- lists:seq(1,30)], + timer:sleep(50), + Pids1 = [spawn_link(fun() -> memory_loop(Me, 20, <<42>>) end) || _ <- lists:seq(1,30)], + [receive {Pid, done} -> ok end || Pid <- Pids0 ++ Pids1], + timer:sleep(500), + ok. + +memory_loop(Parent, N, Bin) -> + memory_loop(Parent, N, Bin, []). + +memory_loop(Parent, 0, _Bin, _) -> + Parent ! {self(), done}; +memory_loop(Parent, N, Bin0, Ls) -> + Bin = binary:copy(<<Bin0/binary, Bin0/binary>>), + memory_loop(Parent, N - 1, Bin, [a,b,c|Ls]). + +tcp_server(Pid, Type) -> + {ok, LSock} = gen_tcp:listen(5679, [binary, + {reuseaddr, true}, + {active, false}]), + Pid ! {self(), accept}, + {ok, Sock} = gen_tcp:accept(LSock), + case Type of + passive_no_read -> + receive die -> ok end; + active -> + inet:setopts(Sock, [{active, once}, {packet,2}]), + receive Msg1 -> io:format("msg1: ~p~n", [Msg1]) end, + inet:setopts(Sock, [{active, once}, {packet,2}]), + receive Msg2 -> io:format("msg2: ~p~n", [Msg2]) end, + ok = gen_tcp:close(Sock); + timeout -> + Res = gen_tcp:recv(Sock, 2000, 1000), + io:format("res ~p~n", [Res]) + end, + Pid ! {self(), done}, + ok. + +txt() -> + <<"%% tracepoints\n" + "%%\n" + "%% com_ericsson_otp:carrier_pool_get\n" + "%% com_ericsson_otp:carrier_pool_put\n" + "%% com_ericsson_otp:carrier_destroy\n" + "%% com_ericsson_otp:carrier_create\n" + "%% com_ericsson_otp:aio_pool_add\n" + "%% com_ericsson_otp:aio_pool_get\n" + "%% com_ericsson_otp:driver_control\n" + "%% com_ericsson_otp:driver_call\n" + "%% com_ericsson_otp:driver_finish\n" + "%% com_ericsson_otp:driver_ready_async\n" + "%% com_ericsson_otp:driver_process_exit\n" + "%% com_ericsson_otp:driver_stop\n" + "%% com_ericsson_otp:driver_flush\n" + "%% com_ericsson_otp:driver_stop_select\n" + "%% com_ericsson_otp:driver_timeout\n" + "%% com_ericsson_otp:driver_event\n" + "%% com_ericsson_otp:driver_ready_output\n" + "%% com_ericsson_otp:driver_ready_input\n" + "%% com_ericsson_otp:driver_output\n" + "%% com_ericsson_otp:driver_outputv\n" + "%% com_ericsson_otp:driver_init\n" + "%% com_ericsson_otp:driver_start\n" + "%% com_ericsson_otp:scheduler_poll">>. + +load_driver(Dir, Driver) -> + case erl_ddll:load_driver(Dir, Driver) of + ok -> ok; + {error, Error} = Res -> + io:format("~s\n", [erl_ddll:format_error(Error)]), + Res + end. + +%% check + +have_carriers() -> + Cap = element(3,erlang:system_info(allocator)), + case Cap -- [sys_alloc,sys_aligned_alloc] of + [] -> false; + _ -> true + end. + +have_async_threads() -> + Tps = erlang:system_info(thread_pool_size), + if Tps =:= 0 -> false; + true -> true + end. + +%% lttng +lttng_stop_and_view(Config) -> + Path = proplists:get_value(priv_dir, Config), + Name = proplists:get_value(session, Config), + {ok,_} = cmd("lttng stop " ++ Name), + {ok,Res} = cmd("lttng view " ++ Name ++ " --trace-path=" ++ Path), + Res. + +check_tracepoint(TP, Data) -> + case re:run(Data, TP, [global]) of + {match, _} -> ok; + _ -> notfound + end. + +lttng_start_event(Event, Config) -> + Name = proplists:get_value(session, Config), + {ok, _} = cmd("lttng enable-event -u " ++ Event ++ " --session=" ++ Name), + {ok, _} = cmd("lttng start " ++ Name), + ok. + +ensure_lttng_started(Name, Config) -> + Out = case proplists:get_value(priv_dir, Config) of + undefined -> []; + Path -> "--output="++Path++" " + end, + {ok,_} = cmd("lttng create " ++ Out ++ Name), + ok. + +ensure_lttng_stopped(Name) -> + {ok,_} = cmd("lttng stop"), + {ok,_} = cmd("lttng destroy " ++ Name), + ok. + +cmd(Cmd) -> + io:format("<< ~ts~n", [Cmd]), + Res = os:cmd(Cmd), + io:format(">> ~ts~n", [Res]), + {ok,Res}. diff --git a/erts/emulator/test/lttng_SUITE_data/Makefile.src b/erts/emulator/test/lttng_SUITE_data/Makefile.src new file mode 100644 index 0000000000..fe7a1b6ef3 --- /dev/null +++ b/erts/emulator/test/lttng_SUITE_data/Makefile.src @@ -0,0 +1,7 @@ + +MISC_DRVS = caller_drv@dll@ + + +all: $(MISC_DRVS) + +@SHLIB_RULES@ diff --git a/erts/emulator/test/lttng_SUITE_data/caller_drv.c b/erts/emulator/test/lttng_SUITE_data/caller_drv.c new file mode 100644 index 0000000000..86fd0a2995 --- /dev/null +++ b/erts/emulator/test/lttng_SUITE_data/caller_drv.c @@ -0,0 +1,159 @@ +/* ``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. + * + * The Initial Developer of the Original Code is Ericsson Utvecklings AB. + * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings + * AB. All Rights Reserved.'' + * + * $Id$ + */ + +#include <stdlib.h> +#include <string.h> +#include "erl_driver.h" + +static int init(); +static void stop(ErlDrvData drv_data); +static void finish(); +static void flush(ErlDrvData drv_data); +static ErlDrvData start(ErlDrvPort port, char *command); +static void output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len); +static void outputv(ErlDrvData drv_data, ErlIOVec *ev); +static ErlDrvSSizeT control(ErlDrvData drv_data, + unsigned int command, char *buf, + ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen); +static ErlDrvSSizeT call(ErlDrvData drv_data, + unsigned int command, + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen, + unsigned int *flags); + +static ErlDrvEntry caller_drv_entry = { + init, + start, + stop, + output, + NULL /* ready_input */, + NULL /* ready_output */, + "caller_drv", + finish, + NULL /* handle */, + control, + NULL /* timeout */, + outputv, + NULL /* ready_async */, + flush, + call, + NULL /* event */, + ERL_DRV_EXTENDED_MARKER, + ERL_DRV_EXTENDED_MAJOR_VERSION, + ERL_DRV_EXTENDED_MINOR_VERSION, + ERL_DRV_FLAG_USE_PORT_LOCKING, + NULL /* handle2 */, + NULL /* handle_monitor */ +}; + +DRIVER_INIT(caller_drv) +{ + char buf[10]; + size_t bufsz = sizeof(buf); + char *use_outputv; + use_outputv = (erl_drv_getenv("CALLER_DRV_USE_OUTPUTV", buf, &bufsz) == 0 + ? buf + : "false"); + if (strcmp(use_outputv, "true") != 0) + caller_drv_entry.outputv = NULL; + return &caller_drv_entry; +} + +void +send_caller(ErlDrvData drv_data, char *func) +{ + int res; + ErlDrvPort port = (ErlDrvPort) drv_data; + ErlDrvTermData msg[] = { + ERL_DRV_ATOM, driver_mk_atom("caller"), + ERL_DRV_PORT, driver_mk_port(port), + ERL_DRV_ATOM, driver_mk_atom(func), + ERL_DRV_PID, driver_caller(port), + ERL_DRV_TUPLE, (ErlDrvTermData) 4 + }; + res = erl_drv_output_term(driver_mk_port(port), msg, sizeof(msg)/sizeof(ErlDrvTermData)); + if (res <= 0) + driver_failure_atom(port, "erl_drv_output_term failed"); +} + +static int +init() { + return 0; +} + +static void +stop(ErlDrvData drv_data) +{ + +} + +static void +flush(ErlDrvData drv_data) +{ + +} + +static void +finish() +{ + +} + +static ErlDrvData +start(ErlDrvPort port, char *command) +{ + send_caller((ErlDrvData) port, "start"); + return (ErlDrvData) port; +} + +static void +output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) +{ + send_caller(drv_data, "output"); +} + +static void +outputv(ErlDrvData drv_data, ErlIOVec *ev) +{ + send_caller(drv_data, "outputv"); +} + +static ErlDrvSSizeT +control(ErlDrvData drv_data, + unsigned int command, char *buf, + ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) +{ + send_caller(drv_data, "control"); + return 0; +} + +static ErlDrvSSizeT +call(ErlDrvData drv_data, + unsigned int command, + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen, + unsigned int *flags) +{ + /* echo call */ + if (len > rlen) + *rbuf = driver_alloc(len); + memcpy((void *) *rbuf, (void *) buf, len); + send_caller(drv_data, "call"); + return len; +} diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl index baa6eb8fe0..ea973276db 100644 --- a/erts/emulator/test/match_spec_SUITE.erl +++ b/erts/emulator/test/match_spec_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2014. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ -export([all/0, suite/0, not_run/1]). -export([test_1/1, test_2/1, test_3/1, bad_match_spec_bin/1, trace_control_word/1, silent/1, silent_no_ms/1, silent_test/1, - ms_trace2/1, ms_trace3/1, boxed_and_small/1, + ms_trace2/1, ms_trace3/1, ms_trace_dead/1, boxed_and_small/1, destructive_in_test_bif/1, guard_exceptions/1, empty_list/1, unary_plus/1, unary_minus/1, moving_labels/1]). @@ -49,7 +49,7 @@ all() -> false -> [test_1, test_2, test_3, bad_match_spec_bin, trace_control_word, silent, silent_no_ms, silent_test, ms_trace2, - ms_trace3, boxed_and_small, destructive_in_test_bif, + ms_trace3, ms_trace_dead, boxed_and_small, destructive_in_test_bif, guard_exceptions, unary_plus, unary_minus, fpe, moving_labels, faulty_seq_trace, @@ -500,6 +500,8 @@ ms_trace2(Config) when is_list(Config) -> [[call,return_to],[]]}, ms_trace2}] end), + %% Silence valgrind + erlang:trace_pattern({?MODULE,fn,'_'},[],[]), ok. @@ -595,7 +597,35 @@ ms_trace3(Config) when is_list(Config) -> end), ok. - +ms_trace_dead(doc) -> + ["Test that a dead tracer is removed using ms"]; +ms_trace_dead(suite) -> []; +ms_trace_dead(Config) when is_list(Config) -> + Self = self(), + TFun = fun F() -> receive M -> Self ! M, F() end end, + {Tracer, MRef} = spawn_monitor(TFun), + MetaTracer = spawn_link(TFun), + erlang:trace_pattern({?MODULE, f1, '_'}, + [{'_',[],[{trace,[], + [call,{const,{tracer,Tracer}}]}]}], + [{meta, MetaTracer}]), + erlang:trace_pattern({?MODULE, f2, '_'}, []), + ?MODULE:f2(1,2), + ?MODULE:f1(1), + {tracer,Tracer} = erlang:trace_info(self(), tracer), + {flags,[call]} = erlang:trace_info(self(), flags), + ?MODULE:f2(2,3), + receive {trace, Self, call, {?MODULE, f2, _}} -> ok end, + exit(Tracer, stop), + receive {'DOWN',MRef,_,_,_} -> ok end, + ?MODULE:f1(2), + {tracer,[]} = erlang:trace_info(self(), tracer), + ?MODULE:f2(3,4), + TRef = erlang:trace_delivered(all), + receive {trace_delivered, _, TRef} -> ok end, + receive {trace_ts, Self, call, {?MODULE, f1, _}, _} -> ok end, + receive {trace_ts, Self, call, {?MODULE, f1, _}, _} -> ok end, + receive M -> ct:fail({unexpected, M}) after 10 -> ok end. %% Test that destructive operations in test bif does not really happen destructive_in_test_bif(Config) when is_list(Config) -> @@ -905,34 +935,40 @@ collect([]) -> collect([TM | TMs]) -> io:format( "Expecting: ~p~n", [TM]), receive - M0 -> - M = case element(1, M0) of - trace_ts -> - list_to_tuple(lists:reverse( - tl(lists:reverse(tuple_to_list(M0))))); - _ -> M0 - end, - case is_function(TM,1) of - true -> - case (catch TM(M)) of - true -> - io:format("Got: ~p~n", [M]), - collect(TMs); - _ -> - io:format("Got unexpected: ~p~n", [M]), - flush({got_unexpected,M}) - end; - - false -> - case M of - TM -> - io:format("Got: ~p~n", [M]), - collect(TMs); - _ -> - io:format("Got unexpected: ~p~n", [M]), - flush({got_unexpected,M}) - end - end + %% We only look at trace messages with the same tracee + %% as the message we are looking for. This because + %% the order of trace messages is only guaranteed from + %% within a single process. + M0 when element(2, M0) =:= element(2, TM); is_function(TM, 1) -> + M = case element(1, M0) of + trace_ts -> + list_to_tuple(lists:reverse( + tl(lists:reverse(tuple_to_list(M0))))); + _ -> M0 + end, + case is_function(TM,1) of + true -> + case (catch TM(M)) of + true -> + io:format("Got: ~p~n", [M]), + collect(TMs); + _ -> + io:format("Got unexpected: ~p~n", [M]), + flush({got_unexpected,M}) + end; + + false -> + case M of + TM -> + io:format("Got: ~p~n", [M]), + collect(TMs); + _ -> + io:format("Got unexpected: ~p~n", [M]), + flush({got_unexpected,M}) + end + end + after 15000 -> + flush(timeout) end. flush(Reason) -> diff --git a/erts/emulator/test/message_queue_data_SUITE.erl b/erts/emulator/test/message_queue_data_SUITE.erl index 12c42d24aa..6efca5b39e 100644 --- a/erts/emulator/test/message_queue_data_SUITE.erl +++ b/erts/emulator/test/message_queue_data_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2014. All Rights Reserved. +%% Copyright Ericsson AB 2014-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/module_info_SUITE.erl b/erts/emulator/test/module_info_SUITE.erl index f8208c5866..ba9b564fdc 100644 --- a/erts/emulator/test/module_info_SUITE.erl +++ b/erts/emulator/test/module_info_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2011. All Rights Reserved. +%% Copyright Ericsson AB 2005-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/monitor_SUITE.erl b/erts/emulator/test/monitor_SUITE.erl index 82e3a36c1e..8955e62df5 100644 --- a/erts/emulator/test/monitor_SUITE.erl +++ b/erts/emulator/test/monitor_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/mtx_SUITE.erl b/erts/emulator/test/mtx_SUITE.erl index a17b11f3bf..1493e52655 100644 --- a/erts/emulator/test/mtx_SUITE.erl +++ b/erts/emulator/test/mtx_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2013. All Rights Reserved. +%% Copyright Ericsson AB 2010-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/mtx_SUITE_data/Makefile.src b/erts/emulator/test/mtx_SUITE_data/Makefile.src index dc880118f1..1816dc6798 100644 --- a/erts/emulator/test/mtx_SUITE_data/Makefile.src +++ b/erts/emulator/test/mtx_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2010-2013. All Rights Reserved. +# Copyright Ericsson AB 2010-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c index 1911291448..e011aadce9 100644 --- a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c +++ b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2010-2011. All Rights Reserved. + * Copyright Ericsson AB 2010-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/multi_load_SUITE.erl b/erts/emulator/test/multi_load_SUITE.erl index 784b239116..edf3205812 100644 --- a/erts/emulator/test/multi_load_SUITE.erl +++ b/erts/emulator/test/multi_load_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,32 +19,16 @@ %% -module(multi_load_SUITE). --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - many/1,on_load/1,errors/1]). +-export([all/0, suite/0, many/1, on_load/1, errors/1]). -include_lib("common_test/include/ct.hrl"). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}]. all() -> [many,on_load,errors]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - many(_Config) -> Ms = make_modules(100, fun many_module/1), @@ -57,7 +41,6 @@ many(_Config) -> io:put_chars("Heavy load\n" "=========="), many_measure(Ms), - ok. many_module(M) -> @@ -81,9 +64,12 @@ many_measure(Ms) -> "Sequential: ~9w µs\n" "Parallel: ~9w µs\n" "Ratio: ~9w\n", - [length(Ms),Us1,Us2,round(Us1/Us2)]), + [length(Ms),Us1,Us2,divide(Us1,Us2)]), ok. +divide(A,B) when B > 0 -> A div B; +divide(_,_) -> inf. + many_load_seq(Ms) -> [erlang:finish_loading([M]) || M <- Ms], ok. @@ -135,7 +121,6 @@ on_load(_Config) -> SingleOnPrep = tl(OnPrep), {on_load,[OnLoadMod]} = erlang:finish_loading(SingleOnPrep), ok = erlang:call_on_load_function(OnLoadMod), - ok. on_load_module(M) -> diff --git a/erts/emulator/test/nested_SUITE.erl b/erts/emulator/test/nested_SUITE.erl index c13e19f857..7af2873ce2 100644 --- a/erts/emulator/test/nested_SUITE.erl +++ b/erts/emulator/test/nested_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index a185b72341..a7767132ee 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2014. All Rights Reserved. +%% Copyright Ericsson AB 2010-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -1282,9 +1282,10 @@ send3_make_blob() -> repeat(N bsr 1, fun(_) -> grow_blob(MsgEnv,other_term(),rand:uniform(1 bsl 20)) end, void), - case (N band 1) of + case (N band 3) of 0 -> {term,copy_blob(MsgEnv)}; - 1 -> {msgenv,MsgEnv} + 1 -> {copy,copy_blob(MsgEnv)}; + _ -> {msgenv,MsgEnv} end end. @@ -1297,6 +1298,9 @@ send3_send(Pid, Msg) -> send3_send_nif(Pid, {term,Blob}) -> %%io:format("~p send term nif\n",[self()]), send_term(Pid, {blob, Blob}) =:= 1; +send3_send_nif(Pid, {copy,Blob}) -> + %%io:format("~p send term nif\n",[self()]), + send_copy_term(Pid, {blob, Blob}) =:= 1; send3_send_nif(Pid, {msgenv,MsgEnv}) -> %%io:format("~p send blob nif\n",[self()]), send3_blob(MsgEnv, Pid, blob) =:= 1. @@ -1305,6 +1309,10 @@ send3_send_bang(Pid, {term,Blob}) -> %%io:format("~p send term bang\n",[self()]), Pid ! {blob, Blob}, true; +send3_send_bang(Pid, {copy,Blob}) -> + %%io:format("~p send term bang\n",[self()]), + Pid ! {blob, Blob}, + true; send3_send_bang(Pid, {msgenv,MsgEnv}) -> %%io:format("~p send blob bang\n",[self()]), Pid ! {blob, copy_blob(MsgEnv)}, @@ -2062,6 +2070,7 @@ send_blob_thread(_,_,_) -> ?nif_stub. join_send_thread(_) -> ?nif_stub. copy_blob(_) -> ?nif_stub. send_term(_,_) -> ?nif_stub. +send_copy_term(_,_) -> ?nif_stub. reverse_list(_) -> ?nif_stub. echo_int(_) -> ?nif_stub. type_sizes() -> ?nif_stub. diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c index b3c6cc5ba3..11e5dab58e 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c +++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2009-2014. All Rights Reserved. + * Copyright Ericsson AB 2009-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1466,6 +1466,18 @@ static ERL_NIF_TERM send_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ return enif_make_int(env, ret); } +static ERL_NIF_TERM send_copy_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + ErlNifEnv* menv; + ErlNifPid pid; + int ret; + if (!enif_get_local_pid(env, argv[0], &pid)) { + return enif_make_badarg(env); + } + ret = enif_send(env, &pid, NULL, argv[1]); + return enif_make_int(env, ret); +} + static ERL_NIF_TERM reverse_list(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ERL_NIF_TERM rev_list; @@ -2142,6 +2154,7 @@ static ErlNifFunc nif_funcs[] = {"join_send_thread", 1, join_send_thread}, {"copy_blob", 1, copy_blob}, {"send_term", 2, send_term}, + {"send_copy_term", 2, send_copy_term}, {"reverse_list",1, reverse_list}, {"echo_int", 1, echo_int}, {"type_sizes", 0, type_sizes}, diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.c b/erts/emulator/test/nif_SUITE_data/nif_mod.c index f7e729e2b6..fd8a0d0595 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_mod.c +++ b/erts/emulator/test/nif_SUITE_data/nif_mod.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2009-2014. All Rights Reserved. + * Copyright Ericsson AB 2009-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.erl b/erts/emulator/test/nif_SUITE_data/nif_mod.erl index b6de046388..eec1bb8858 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_mod.erl +++ b/erts/emulator/test/nif_SUITE_data/nif_mod.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2011. All Rights Reserved. +%% Copyright Ericsson AB 2005-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl index 71400142af..536c91d4ae 100644 --- a/erts/emulator/test/node_container_SUITE.erl +++ b/erts/emulator/test/node_container_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2012. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -28,8 +28,6 @@ -module(node_container_SUITE). -author('[email protected]'). -%-define(line_trace, 1). - -include_lib("common_test/include/ct.hrl"). -export([all/0, suite/0, init_per_suite/1, end_per_suite/1, @@ -56,7 +54,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {minutes, 10}}]. + {timetrap, {minutes, 12}}]. all() -> @@ -126,7 +124,13 @@ term_to_binary_to_term_eq(Config) when is_list(Config) -> LHLRef = binary_to_term(term_to_binary(LHLRef)), LSRef = binary_to_term(term_to_binary(LSRef)), % Get remote node containers - RNode = {get_nodename(), 3}, + ttbtteq_do_remote({get_nodename(), 3}), + ttbtteq_do_remote({get_nodename(), 4}), + ttbtteq_do_remote({get_nodename(), 16#adec0ded}), + nc_refc_check(node()), + ok. + +ttbtteq_do_remote(RNode) -> RPid = mk_pid(RNode, 4711, 1), RXPid = mk_pid(RNode, 32767, 8191), RPort = mk_port(RNode, 4711), @@ -142,7 +146,6 @@ term_to_binary_to_term_eq(Config) when is_list(Config) -> RLRef = binary_to_term(term_to_binary(RLRef)), RHLRef = binary_to_term(term_to_binary(RHLRef)), RSRef = binary_to_term(term_to_binary(RSRef)), - nc_refc_check(node()), ok. @@ -712,7 +715,7 @@ run_otp_4715(Config) when is_list(Config) -> pid_wrap(Config) when is_list(Config) -> pp_wrap(pid). port_wrap(Config) when is_list(Config) -> - case test_server:os_type() of + case os:type() of {unix, _} -> pp_wrap(port); _ -> @@ -807,7 +810,7 @@ bad_nc(Config) when is_list(Config) -> = (catch mk_ref(RemNode, [(1 bsl 18), 4711, 4711])), {'EXIT', {badarg, mk_ref, _}} = (catch mk_ref(RemNode, [4711, 4711, 4711, 4711, 4711, 4711, 4711])), - BadNode = {x@y, 4}, + BadNode = {x@y, bad_creation}, {'EXIT', {badarg, mk_pid, _}} = (catch mk_pid(BadNode, 4711, 17)), {'EXIT', {badarg, mk_port, _}} @@ -842,11 +845,10 @@ iter_max_procs(Config) when is_list(Config) -> Res = chk_max_proc_line(), Res = chk_max_proc_line(), done = chk_max_proc_line_until(NoMoreTests, Res), - {comment, - io_lib:format("max processes = ~p; " - "process line length = ~p", - [element(2, Res), element(1, Res)])}. - + Cmt = io_lib:format("max processes = ~p; " + "process line length = ~p", + [element(2, Res), element(1, Res)]), + {comment, lists:flatten(Cmt)}. max_proc_line(Root, Parent, N) -> Me = self(), @@ -1111,6 +1113,9 @@ get_nodename() -> -define(PORT_EXT, 102). -define(PID_EXT, 103). -define(NEW_REFERENCE_EXT, 114). +-define(NEW_PID_EXT, $X). +-define(NEW_PORT_EXT, $Y). +-define(NEWER_REFERENCE_EXT, $Z). uint32_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 32 -> [(Uint bsr 24) band 16#ff, @@ -1133,51 +1138,65 @@ uint8(Uint) -> exit({badarg, uint8, [Uint]}). +pid_tag(bad_creation) -> ?PID_EXT; +pid_tag(Creation) when Creation =< 3 -> ?PID_EXT; +pid_tag(_Creation) -> ?NEW_PID_EXT. + +enc_creation(bad_creation) -> uint8(4); +enc_creation(Creation) when Creation =< 3 -> uint8(Creation); +enc_creation(Creation) -> uint32_be(Creation). mk_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) -> mk_pid({atom_to_list(NodeName), Creation}, Number, Serial); mk_pid({NodeName, Creation}, Number, Serial) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?PID_EXT, - ?ATOM_EXT, - uint16_be(length(NodeName)), - NodeName, - uint32_be(Number), - uint32_be(Serial), - uint8(Creation)])) of - Pid when is_pid(Pid) -> - Pid; - {'EXIT', {badarg, _}} -> - exit({badarg, mk_pid, [{NodeName, Creation}, Number, Serial]}); - Other -> - exit({unexpected_binary_to_term_result, Other}) + pid_tag(Creation), + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + uint32_be(Number), + uint32_be(Serial), + enc_creation(Creation)])) of + Pid when is_pid(Pid) -> + Pid; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_pid, [{NodeName, Creation}, Number, Serial]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) end. +port_tag(bad_creation) -> ?PORT_EXT; +port_tag(Creation) when Creation =< 3 -> ?PORT_EXT; +port_tag(_Creation) -> ?NEW_PORT_EXT. + mk_port({NodeName, Creation}, Number) when is_atom(NodeName) -> mk_port({atom_to_list(NodeName), Creation}, Number); mk_port({NodeName, Creation}, Number) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?PORT_EXT, - ?ATOM_EXT, - uint16_be(length(NodeName)), - NodeName, - uint32_be(Number), - uint8(Creation)])) of - Port when is_port(Port) -> - Port; - {'EXIT', {badarg, _}} -> - exit({badarg, mk_port, [{NodeName, Creation}, Number]}); - Other -> - exit({unexpected_binary_to_term_result, Other}) + port_tag(Creation), + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + uint32_be(Number), + enc_creation(Creation)])) of + Port when is_port(Port) -> + Port; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_port, [{NodeName, Creation}, Number]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) end. +ref_tag(bad_creation) -> ?NEW_REFERENCE_EXT; +ref_tag(Creation) when Creation =< 3 -> ?NEW_REFERENCE_EXT; +ref_tag(_Creation) -> ?NEWER_REFERENCE_EXT. + mk_ref({NodeName, Creation}, Numbers) when is_atom(NodeName), - is_integer(Creation), - is_list(Numbers) -> + is_list(Numbers) -> mk_ref({atom_to_list(NodeName), Creation}, Numbers); mk_ref({NodeName, Creation}, [Number]) when is_list(NodeName), - is_integer(Creation), - is_integer(Number) -> + Creation =< 3, + is_integer(Number) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, ?REFERENCE_EXT, ?ATOM_EXT, @@ -1193,25 +1212,24 @@ mk_ref({NodeName, Creation}, [Number]) when is_list(NodeName), exit({unexpected_binary_to_term_result, Other}) end; mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName), - is_integer(Creation), - is_list(Numbers) -> + is_list(Numbers) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?NEW_REFERENCE_EXT, - uint16_be(length(Numbers)), - ?ATOM_EXT, - uint16_be(length(NodeName)), - NodeName, - uint8(Creation), - lists:map(fun (N) -> - uint32_be(N) - end, - Numbers)])) of - Ref when is_reference(Ref) -> - Ref; - {'EXIT', {badarg, _}} -> - exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]}); - Other -> - exit({unexpected_binary_to_term_result, Other}) + ref_tag(Creation), + uint16_be(length(Numbers)), + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + enc_creation(Creation), + lists:map(fun (N) -> + uint32_be(N) + end, + Numbers)])) of + Ref when is_reference(Ref) -> + Ref; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) end. exec_loop() -> diff --git a/erts/emulator/test/nofrag_SUITE.erl b/erts/emulator/test/nofrag_SUITE.erl index 9cc851f9cf..8b1519ae36 100644 --- a/erts/emulator/test/nofrag_SUITE.erl +++ b/erts/emulator/test/nofrag_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2013. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl index 04a6f9d18d..d1c9648017 100644 --- a/erts/emulator/test/num_bif_SUITE.erl +++ b/erts/emulator/test/num_bif_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2014. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/old_mod.erl b/erts/emulator/test/old_mod.erl index 0da40ec430..866aba79bb 100644 --- a/erts/emulator/test/old_mod.erl +++ b/erts/emulator/test/old_mod.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2010. All Rights Reserved. +%% Copyright Ericsson AB 2003-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/old_scheduler_SUITE.erl b/erts/emulator/test/old_scheduler_SUITE.erl index 9d40417d0a..f91d84beea 100644 --- a/erts/emulator/test/old_scheduler_SUITE.erl +++ b/erts/emulator/test/old_scheduler_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/op_SUITE.erl b/erts/emulator/test/op_SUITE.erl index 562cf1c92d..08655d32a5 100644 --- a/erts/emulator/test/op_SUITE.erl +++ b/erts/emulator/test/op_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2015. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {minutes, 3}}]. + {timetrap, {minutes, 5}}]. all() -> [bsl_bsr, logical, t_not, relop_simple, relop, @@ -39,9 +39,16 @@ all() -> %% Test the bsl and bsr operators. bsl_bsr(Config) when is_list(Config) -> Vs = [unvalue(V) || V <- [-16#8000009-2,-1,0,1,2,73,16#8000000,bad,[]]], - Cases = [{Op,X,Y} || Op <- ['bsr','bsl'], X <- Vs, Y <- Vs], - run_test_module(Cases, false), - {comment,integer_to_list(length(Cases)) ++ " cases"}. + %% Try to use less memory by splitting the cases + + Cases1 = [{Op,X,Y} || Op <- ['bsl'], X <- Vs, Y <- Vs], + N1 = length(Cases1), + run_test_module(Cases1, false), + + Cases2 = [{Op,X,Y} || Op <- ['bsr'], X <- Vs, Y <- Vs], + N2 = length(Cases2), + run_test_module(Cases2, false), + {comment,integer_to_list(N1 + N2) ++ " cases"}. %% Test the logical operators and internal BIFs. logical(Config) when is_list(Config) -> diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl index 328641f5b9..79abcbde5f 100644 --- a/erts/emulator/test/port_SUITE.erl +++ b/erts/emulator/test/port_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2014. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -87,6 +87,7 @@ name1/1, t_binary/1, parallell/1, t_exit/1, env/1, huge_env/1, bad_env/1, cd/1, exit_status/1, + bad_args/1, tps_16_bytes/1, tps_1K/1, line/1, stderr_to_stdout/1, otp_3906/1, otp_4389/1, win_massive/1, win_massive_client/1, mix_up_ports/1, otp_5112/1, otp_5119/1, otp_6224/1, @@ -115,6 +116,7 @@ all() -> {group, multiple_packets}, parallell, dying_port, port_program_with_path, open_input_file_port, open_output_file_port, name1, env, huge_env, bad_env, cd, + bad_args, exit_status, iter_max_ports, count_fds, t_exit, {group, tps}, line, stderr_to_stdout, otp_3906, otp_4389, win_massive, mix_up_ports, otp_5112, otp_5119, @@ -901,14 +903,15 @@ bad_env(Config) when is_list(Config) -> ok. try_bad_env(Env) -> - try open_port({spawn,"ls"}, [{env,Env}]) - catch - error:badarg -> ok - end. + badarg = try open_port({spawn,"ls"}, [{env,Env}]) + catch + error:badarg -> badarg + end. + %% Test that we can handle a very very large environment gracefully. huge_env(Config) when is_list(Config) -> - ct:timetrap({seconds, 30}), + ct:timetrap({minutes, 2}), Vars = case os:type() of {win32,_} -> 500; _ -> @@ -940,6 +943,24 @@ huge_env(Config) when is_list(Config) -> end. +%% Test bad 'args' options. +bad_args(Config) when is_list(Config) -> + try_bad_args({args, [self()]}), + try_bad_args({args, ["head" | "tail"]}), + try_bad_args({args, ["head", "body" | "tail"]}), + try_bad_args({args, [<<"head">>, <<"body">> | <<"tail">>]}), + try_bad_args({args, not_a_list}), + try_bad_args({args, ["string",<<"binary">>, 1472, "string"]}), + try_bad_args({args, ["string",<<"binary">>], "element #3"}), + ok. + +try_bad_args(Args) -> + badarg = try open_port({spawn_executable,"ls"}, [Args]) + catch + error:badarg -> badarg + end. + + %% 'cd' option %% (Can perhaps be made smaller by calling the other utility functions @@ -1757,7 +1778,7 @@ otp_6224_loop() -> exit_status_multi_scheduling_block(Config) when is_list(Config) -> Repeat = 3, - case test_server:os_type() of + case os:type() of {unix, _} -> ct:timetrap({minutes, 2*Repeat}), SleepSecs = 6, diff --git a/erts/emulator/test/port_SUITE_data/dead_port.c b/erts/emulator/test/port_SUITE_data/dead_port.c index c859dbc402..26f09f33c7 100644 --- a/erts/emulator/test/port_SUITE_data/dead_port.c +++ b/erts/emulator/test/port_SUITE_data/dead_port.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * Copyright Ericsson AB 2001-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/port_SUITE_data/port_test.erl b/erts/emulator/test/port_SUITE_data/port_test.erl index b07038e73d..406d376b26 100644 --- a/erts/emulator/test/port_SUITE_data/port_test.erl +++ b/erts/emulator/test/port_SUITE_data/port_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% Copyright Ericsson AB 1998-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/port_bif_SUITE.erl b/erts/emulator/test/port_bif_SUITE.erl index 9b794be415..e1e1ec9fb9 100644 --- a/erts/emulator/test/port_bif_SUITE.erl +++ b/erts/emulator/test/port_bif_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/port_trace_SUITE.erl b/erts/emulator/test/port_trace_SUITE.erl new file mode 100644 index 0000000000..41e8a316c4 --- /dev/null +++ b/erts/emulator/test/port_trace_SUITE.erl @@ -0,0 +1,600 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2012. 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% +%% + + +-module(port_trace_SUITE). + +-export([all/0, suite/0,init_per_suite/1, end_per_suite/1, + init_per_group/2,end_per_group/2, + init_per_testcase/2,end_per_testcase/2]). +-export([port_specs/1, ports/1, open_close/1, + command/1, control/1, connect/1, call/1, + output/1, output2/1, output_binary/1, + outputv/1, set_timer/1, failure_eof/1, + failure_atom/1, failure_posix/1, + failure/1, output_term/1, + driver_output_term/1, + send_term/1, driver_send_term/1]). + +-define(ECHO_DRV_NOOP, 0). +-define(ECHO_DRV_OUTPUT, 1). +-define(ECHO_DRV_OUTPUT2, 2). +-define(ECHO_DRV_OUTPUT_BINARY, 3). +-define(ECHO_DRV_OUTPUTV, 4). +-define(ECHO_DRV_SET_TIMER, 5). +-define(ECHO_DRV_FAILURE_EOF, 6). +-define(ECHO_DRV_FAILURE_ATOM, 7). +-define(ECHO_DRV_FAILURE_POSIX, 8). +-define(ECHO_DRV_FAILURE, 9). +-define(ECHO_DRV_OUTPUT_TERM, 10). +-define(ECHO_DRV_DRIVER_OUTPUT_TERM, 11). +-define(ECHO_DRV_SEND_TERM, 12). +-define(ECHO_DRV_DRIVER_SEND_TERM, 13). +-define(ECHO_DRV_SAVE_CALLER, 14). + +suite() -> [{ct_hooks,[ts_install_cth]}, + {timetrap, {seconds, 30}}]. + +all() -> + [port_specs, ports, open_close, + command, control, connect, call, + output, output2, output_binary, + outputv, set_timer, failure_eof, + failure_atom, failure_posix, + failure, output_term, + driver_output_term, + send_term, driver_send_term]. + +init_per_suite(Config) -> + Config. + +end_per_suite(_Config) -> + ok. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + + +init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> + erlang:trace(all, false, [all]), + os:unsetenv("OUTPUTV"), + reload_drv(Config), + Config. + +end_per_testcase(_Func, _Config) -> + erlang:trace(all, false, [all]), + ok. + +%% Test the first argument of trace/3 +port_specs(_Config) -> + + S = self(), + + Tracer = fun F() -> + receive + stop -> + ok; + M -> + S ! M, + F() + end + end, + + Test = fun(TraceSpec, Info1, Info2) -> + {TracerPid,Ref} = spawn_monitor(Tracer), + Prt1 = erlang:open_port({spawn, echo_drv}, [binary]), + erlang:trace(TraceSpec, true, ['receive', {tracer, TracerPid}]), + %% We disable trace messages from the testcase process + erlang:trace(self(), false, ['receive']), + Prt2 = erlang:open_port({spawn, echo_drv}, [binary]), + + InfoCheck = + fun(Info, Prt) -> + if + Info -> + {tracer, TracerPid} = erlang:trace_info(Prt, tracer), + {flags,['receive']} = erlang:trace_info(Prt, flags); + not Info -> + {tracer,[]} = erlang:trace_info(Prt, tracer), + {flags,[]} = erlang:trace_info(Prt, flags) + end + end, + InfoCheck(Info1, Prt1), + InfoCheck(Info2, Prt2), + + %% These may create trace messages + erlang:port_command(Prt1, <<?ECHO_DRV_NOOP>>), + erlang:port_command(Prt2, <<?ECHO_DRV_NOOP>>), + + %% Test what happens when the tracer dies + trace_delivered(), + TracerPid ! stop, + receive {'DOWN', Ref, process, TracerPid, normal} -> ok end, + + %% These should not generate any trace messages + erlang:port_command(Prt1, <<?ECHO_DRV_NOOP>>), + erlang:port_command(Prt2, <<?ECHO_DRV_NOOP>>), + + InfoCheck(false, Prt1), + InfoCheck(false, Prt2), + + erlang:port_close(Prt1), + erlang:port_close(Prt2), + erlang:trace(all, false, [all]), + {Prt1, Prt2} + end, + + {_Prt11, Prt12} = Test(new, false, true), + [{trace, Prt12, 'receive', {S, {command,<<?ECHO_DRV_NOOP>>}}}] + = flush(Prt12), + + {_Prt21, Prt22} = Test(new_ports, false, true), + [{trace, Prt22, 'receive', {S, {command,<<?ECHO_DRV_NOOP>>}}}] + = flush(Prt22), + + {Prt31, _Prt32} = Test(existing, true, false), + [{trace, Prt31, 'receive', {S, {command,<<?ECHO_DRV_NOOP>>}}}] + = flush(Prt31), + + {Prt41, _Prt42} = Test(existing_ports, true, false), + [{trace, Prt41, 'receive', {S, {command,<<?ECHO_DRV_NOOP>>}}}] + = flush(Prt41), + + {Prt51, Prt52} = Test(all, true, true), + [{trace, Prt51, 'receive', {S, {command,<<?ECHO_DRV_NOOP>>}}}] + = flush(Prt51), + [{trace, Prt52, 'receive', {S, {command,<<?ECHO_DRV_NOOP>>}}}] + = flush(Prt52), + + {Prt61, Prt62} = Test(ports, true, true), + [{trace, Prt61, 'receive', {S, {command,<<?ECHO_DRV_NOOP>>}}}] + = flush(Prt61), + [{trace, Prt62, 'receive', {S, {command,<<?ECHO_DRV_NOOP>>}}}] + = flush(Prt62), + + ok. + +%% Test that the 'ports' trace flag works +ports(_Config) -> + + {Prt, S} = trace_and_open([ports],[binary]), + + [{trace, Prt, open, S, echo_drv}, + {trace, Prt, getting_linked, S}] = flush(), + + register(?MODULE, Prt), + unregister(?MODULE), + register(?MODULE, Prt), + + [{trace,Prt,register,port_trace_SUITE}, + {trace,Prt,unregister,port_trace_SUITE}, + {trace,Prt,register,port_trace_SUITE}] = flush(), + + unlink(Prt), + link(Prt), + + [{trace,Prt,getting_unlinked,S}, + {trace,Prt,getting_linked,S}] = flush(), + + erlang:port_close(Prt), + + [{trace,Prt,closed,normal}, + {trace,Prt,unregister,port_trace_SUITE}, + {trace,Prt,unlink,S}] = flush(), + + ok. + +%% Test that port_close and ! close generate correct trace messages +open_close(_Config) -> + + S = trace_ports([send,'receive']), + + Prt = erlang:open_port({spawn, echo_drv}, [binary]), + erlang:port_close(Prt), + [{trace, Prt, 'receive', {S, close}}] = flush(), + + Prt2 = erlang:open_port({spawn, echo_drv}, [binary]), + Prt2 ! {S, close}, + recv({Prt2, closed}), + [{trace, Prt2, 'receive', {S, close}}, + {trace, Prt2, send, closed, S}] = flush(), + + catch erlang:port_close(Prt2), + [] = flush(), + + ok. + +%% Test that port_command and ! command generate correct trace messages +command(Config) -> + + Flags = [send,'receive'], + S = trace_ports(Flags), + Prt = erlang:open_port({spawn, echo_drv}, [binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_NOOP:8>>), + [{trace, Prt, 'receive', {S, {command, <<?ECHO_DRV_NOOP:8>>}}}] = flush(), + + erlang:port_command(Prt, [?ECHO_DRV_NOOP, <<0:8>>]), + [{trace, Prt, 'receive', {S, {command, <<?ECHO_DRV_NOOP:8,0:8>>}}}] = flush(), + + Prt ! {S, {command, <<?ECHO_DRV_NOOP:8>>}}, + [{trace, Prt, 'receive', {S, {command, <<?ECHO_DRV_NOOP:8>>}}}] = flush(), + + close(Prt, Flags), + + os:putenv("OUTPUTV","true"), + reload_drv(Config), + + Prt2 = erlang:open_port({spawn, echo_drv}, [binary]), + Msg = [<<0:8>>,<<0:(8*512)>>,<<0:(8*256)>>,<<0:8>>], + + erlang:port_command(Prt2, Msg), + [{trace, Prt2, 'receive', {S, {command, Msg}}}] = flush(), + + Prt2 ! {S, {command, Msg}}, + [{trace, Prt2, 'receive', {S, {command, Msg}}}] = flush(), + + close(Prt2, Flags), + + os:unsetenv("OUTPUTV"), + + ok. + +%% Test that port_control generate correct trace messages +control(_Config) -> + + Flags = [send,'receive'], + {Prt, S} = trace_and_open(Flags,[binary]), + + [0] = erlang:port_control(Prt, 1, <<?ECHO_DRV_NOOP:8, 0:8>>), + [{trace, Prt, 'receive', {S, {control, {1, <<?ECHO_DRV_NOOP:8, 0:8>>}}}}, + {trace, Prt, send, {Prt, {control, <<0:8>>}}, S}] = flush(), + + [0] = erlang:port_control(Prt, (1 bsl 32) - 1, <<?ECHO_DRV_NOOP:8, 0:8>>), + [{trace, Prt, 'receive', {S, {control, {(1 bsl 32) - 1, <<?ECHO_DRV_NOOP:8, 0:8>>}}}}, + {trace, Prt, send, {Prt, {control, <<0:8>>}}, S}] = flush(), + + close(Prt, Flags), + + ok. + +%% Test that port_connect and ! connect generate correct trace messages +%% This includes that the proper getting_linked messages are sent +connect(_Config) -> + + + {Prt, S} = trace_and_open([send, 'receive', ports],[binary]), + + flush(), + + {Pid,Ref} = spawn_monitor( + fun() -> + receive + go -> + Prt ! {self(), {connect, S}}, + receive {Prt, connected} -> unlink(Prt) end + end + end), + erlang:trace(Pid, true, [send, 'receive', procs]), + + erlang:port_connect(Prt, Pid), + unlink(Prt), + + [{trace,Prt,getting_linked,Pid}, + {trace,Prt,'receive',{S,{connect,Pid}}}, + {trace,Prt,send,{Prt,connected},S}, + {trace,Prt,getting_unlinked, S}] = flush(Prt), + + [{trace,Pid,getting_linked,Prt}] = flush(), + + Pid ! go, + recv({'DOWN',Ref,process,Pid,normal}), + + [{trace,Prt,'receive',{Pid,{connect,S}}}, + {trace,Prt,send,{Prt,connected},Pid}, + {trace,Prt,getting_unlinked,Pid}] = flush(Prt), + + [{trace,Pid,'receive',go}, + {trace,Pid,send,{Pid,{connect,S}}, Prt}, + {trace,Pid,'receive',{Prt,connected}}, + {trace,Pid,unlink,Prt}, + {trace,Pid,exit,normal}] = flush(), + + erlang:port_close(Prt), + [{trace, Prt, 'receive', {S, close}}, + {trace, Prt, closed, normal}] = flush(), + ok. + +%% Test that port_call generate correct trace messages +call(_Config) -> + + Flags = [send,'receive'], + {Prt, S} = trace_and_open(Flags,[binary]), + + Msg = {hello, world, make_ref()}, + BinMsg = term_to_binary(Msg), + + Msg = erlang:port_call(Prt, 0, Msg), + [{trace, Prt, 'receive', {S, {call, {0, BinMsg}}}}, + {trace, Prt, send, {Prt, {call, BinMsg}}, S}] = flush(), + + close(Prt, Flags), + + ok. + +%% Test that driver_output generate correct trace messages +output(_Config) -> + + Flags = [send], + {Prt, S} = trace_and_open(Flags,[binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_OUTPUT, 123456:32>>), + recv({Prt,{data,<<123456:32>>}}), + + [{trace, Prt, send, {Prt, {data, <<123456:32>>}}, S}] = flush(), + + close(Prt, Flags), + + ok. + +%% Test that driver_output2 generate correct trace messages +output2(_Config) -> + + Flags = [send], + {Prt, S} = trace_and_open(Flags,[binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_OUTPUT2, 123456:32>>), + recv({Prt,{data,[$a|<<123456:32>>]}}), + [{trace, Prt, send, {Prt, {data, [$a|<<123456:32>>]}}, S}] = flush(), + + close(Prt, Flags), + + ok. + +%% Test that driver_output_binary generate correct trace messages +output_binary(_Config) -> + + Flags = [send], + {Prt, S} = trace_and_open(Flags,[binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_OUTPUT_BINARY, 0, 123456:32>>), + recv({Prt,{data,[$a|<<123456:32>>]}}), + [{trace, Prt, send, {Prt, {data, [$a|<<123456:32>>]}}, S}] = flush(), + + close(Prt, Flags), + + ok. + +%% Test that driver_outputv generate correct trace messages +outputv(_Config) -> + + Flags = [send], + {Prt, S} = trace_and_open(Flags,[binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_OUTPUTV, 123456:32>>), + recv({Prt,{data,[$a|<<123456:32>>]}}), + + [{trace, Prt, send, {Prt, {data, [$a|<<123456:32>>]}}, S}] = flush(), + + erlang:port_close(Prt), + [] = flush(), + + ok. + +%% Test that driver_set_timer generate correct trace messages +set_timer(_Config) -> + + Flags = [send,'receive'], + {Prt, S} = trace_and_open(Flags,[binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_SET_TIMER>>), + timer:sleep(100), + [{trace, Prt, 'receive', {S, {command, <<?ECHO_DRV_SET_TIMER>>}}}, + {trace, Prt, 'receive', timeout}] = flush(), + + close(Prt, Flags), + + ok. + +%% Test that driver_failure* generate correct trace messages +failure_eof(_Config) -> + + Flags = [send,'receive', ports], + S = trace_ports(Flags), + + Prt = erlang:open_port({spawn, echo_drv}, [eof, binary]), + [{trace, Prt, open, S, echo_drv}, + {trace, Prt, getting_linked, S}] = flush(), + + erlang:port_command(Prt, <<?ECHO_DRV_FAILURE_EOF>>), + recv({Prt,eof}), + [{trace, Prt, 'receive', {S, {command, <<?ECHO_DRV_FAILURE_EOF>>}}}, + {trace, Prt, send, {Prt, eof}, S}] = flush(), + + close(Prt, Flags), + + %% Run same test without eof option + failure_test(<<?ECHO_DRV_FAILURE_EOF>>, normal). + +failure_atom(_Config) -> + failure_test(<<?ECHO_DRV_FAILURE_ATOM, "failure\0">>, failure). +failure_posix(_Config) -> + failure_test(<<?ECHO_DRV_FAILURE_POSIX>>, eagain). +failure(_Config) -> + failure_test(<<?ECHO_DRV_FAILURE, 1>>, 1). + +failure_test(Failure, Reason) -> + + {Prt, S} = trace_and_open([send, 'receive', ports],[binary]), + + [{trace, Prt, open, S, echo_drv}, + {trace, Prt, getting_linked, S}] = flush(), + + process_flag(trap_exit, true), + erlang:port_command(Prt, Failure), + try + recv({'EXIT',Prt,Reason}) + after + process_flag(trap_exit, false) + end, + [{trace, Prt, 'receive', {S, {command, Failure}}}, + {trace, Prt, closed, Reason}, + {trace, Prt, unlink, S}] = flush(), + + ok. + +%% Test that erl_drv_output_term generate correct trace messages +output_term(_Config) -> + + Flags = [send], + {Prt, S} = trace_and_open(Flags,[binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_OUTPUT_TERM, 123456:32>>), + recv({echo, Prt, <<123456:32>>}), + [{trace, Prt, send, {echo, Prt, <<123456:32>>}, S}] = flush(), + + close(Prt, Flags), + + ok. + +%% Test that driver_output_term generate correct trace messages +driver_output_term(_Config) -> + + Flags = [send], + {Prt, S} = trace_and_open(Flags,[binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_DRIVER_OUTPUT_TERM, 123456:32>>), + recv({echo, Prt, <<123456:32>>}), + [{trace, Prt, send, {echo, Prt, <<123456:32>>}, S}] = flush(), + + close(Prt, Flags), + + ok. + +%% Test that erl_drv_send_term generate correct trace messages +send_term(_Config) -> + + Flags = [send], + {Prt, S} = trace_and_open(Flags,[binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_SEND_TERM, 123456:32>>), + recv({echo, Prt, <<123456:32>>}), + [{trace, Prt, send, {echo, Prt, <<123456:32>>}, S}] = flush(), + + {Pid, Ref} = spawn_monitor(fun() -> erlang:port_command(Prt, <<?ECHO_DRV_SAVE_CALLER>>) end), + recv({'DOWN',Ref,process,Pid,normal}), + erlang:port_command(Prt, <<?ECHO_DRV_SEND_TERM, 123456:32>>), + [{trace, Prt, send_to_non_existing_process, {echo, Prt, <<123456:32>>}, Pid}] = flush(), + + close(Prt, Flags), + + ok. + +%% Test that driver_send_term generate correct trace messages +driver_send_term(_Config) -> + + Flags = [send], + {Prt, S} = trace_and_open(Flags,[binary]), + + erlang:port_command(Prt, <<?ECHO_DRV_DRIVER_SEND_TERM, 123456:32>>), + recv({echo, Prt, <<123456:32>>}), + [{trace, Prt, send, {echo, Prt, <<123456:32>>}, S}] = flush(), + + {Pid, Ref} = spawn_monitor(fun() -> erlang:port_command(Prt, <<?ECHO_DRV_SAVE_CALLER>>) end), + recv({'DOWN',Ref,process,Pid,normal}), + erlang:port_command(Prt, <<?ECHO_DRV_SEND_TERM, 123456:32>>), + [{trace, Prt, send_to_non_existing_process, {echo, Prt, <<123456:32>>}, Pid}] = flush(), + + close(Prt, Flags), + + ok. + +%%%%%%%%%%%%%%%%%%% +%% Helper functions +%%%%%%%%%%%%%%%%%%% + +trace_ports(TraceFlags) -> + erlang:trace(new_ports, true, TraceFlags), + self(). + +trace_and_open(TraceFlags, OpenFlags) -> + S = self(), + Ports = proplists:get_value(ports, TraceFlags), + [trace_ports(TraceFlags) || Ports], + Prt = erlang:open_port({spawn, echo_drv}, OpenFlags), + [erlang:trace(Prt, true, TraceFlags) || Ports == undefined], + {Prt, S}. + +close(Prt, Flags) -> + Recv = proplists:get_value('receive', Flags), + Ports = proplists:get_value(ports, Flags), + S = self(), + + erlang:port_close(Prt), + + if Recv, Ports -> + [{trace, Prt, 'receive', {S, close}}, + {trace, Prt, closed, normal}, + {trace, Prt, unlink, S}] = flush(); + Recv -> + [{trace, Prt, 'receive', {S, close}}] = flush(); + Ports -> + [{trace, Prt, closed, normal}, + {trace, Prt, unlink, S}] = flush(); + true -> + [] = flush() + end. + +trace_delivered() -> + Ref = erlang:trace_delivered(all), + receive {trace_delivered, all, Ref} -> ok end. + +flush() -> + flush(all). +flush(From) -> + trace_delivered(), + f(From). + +f(From) -> + receive + M when From =:= all; element(2, M) == From -> + [M | f(From)] + after 0 -> + [] + end. + +recv(Msg) -> + receive Msg -> ok after 100 -> ct:fail({did_not_get_data,Msg,flush()}) end. + +load_drv(Config) -> + Path = proplists:get_value(data_dir, Config), + case erl_ddll:load_driver(Path, echo_drv) of + ok -> ok; + {error, Error} = Res -> + io:format("~s\n", [erl_ddll:format_error(Error)]), + ct:fail(Res) + end. + +reload_drv(Config) -> + erl_ddll:unload_driver(echo_drv), + load_drv(Config). diff --git a/erts/emulator/test/port_trace_SUITE_data/Makefile.src b/erts/emulator/test/port_trace_SUITE_data/Makefile.src new file mode 100644 index 0000000000..c1bf142ccf --- /dev/null +++ b/erts/emulator/test/port_trace_SUITE_data/Makefile.src @@ -0,0 +1,3 @@ +all: echo_drv@dll@ + +@SHLIB_RULES@ diff --git a/erts/emulator/test/port_trace_SUITE_data/echo_drv.c b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c new file mode 100644 index 0000000000..b5728bc170 --- /dev/null +++ b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c @@ -0,0 +1,237 @@ +#include <stdio.h> +#include "erl_driver.h" +#include <errno.h> +#include <string.h> + + +/* ------------------------------------------------------------------------- +** Data types +**/ + + +typedef struct _erl_drv_data { + ErlDrvPort erlang_port; + ErlDrvTermData caller; +} EchoDrvData; + +#define ECHO_DRV_NOOP 0 +#define ECHO_DRV_OUTPUT 1 +#define ECHO_DRV_OUTPUT2 2 +#define ECHO_DRV_OUTPUT_BINARY 3 +#define ECHO_DRV_OUTPUTV 4 +#define ECHO_DRV_SET_TIMER 5 +#define ECHO_DRV_FAILURE_EOF 6 +#define ECHO_DRV_FAILURE_ATOM 7 +#define ECHO_DRV_FAILURE_POSIX 8 +#define ECHO_DRV_FAILURE 9 +#define ECHO_DRV_OUTPUT_TERM 10 +#define ECHO_DRV_DRIVER_OUTPUT_TERM 11 +#define ECHO_DRV_SEND_TERM 12 +#define ECHO_DRV_DRIVER_SEND_TERM 13 +#define ECHO_DRV_SAVE_CALLER 14 + + +/* ------------------------------------------------------------------------- +** Entry struct +**/ + +static EchoDrvData *echo_drv_start(ErlDrvPort port, char *command); +static void echo_drv_stop(ErlDrvData drv_data); +static void echo_drv_output(ErlDrvData drv_data, char *buf, + ErlDrvSizeT len); +static void echo_drv_outputv(ErlDrvData drv_data, ErlIOVec *iov); +static void echo_drv_finish(void); +static ErlDrvSSizeT echo_drv_control(ErlDrvData drv_data, + unsigned int command, + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen); +static void echo_drv_timeout(ErlDrvData drv_data); +static ErlDrvSSizeT echo_drv_call(ErlDrvData drv_data, + unsigned int command, + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen, + unsigned int *flags); + +static ErlDrvEntry echo_drv_entry = { + NULL, /* init */ + echo_drv_start, + echo_drv_stop, + echo_drv_output, + NULL, /* ready_input */ + NULL, /* ready_output */ + "echo_drv", + echo_drv_finish, + NULL, /* handle */ + echo_drv_control, + echo_drv_timeout, /* timeout */ + NULL, /* outputv */ + NULL, /* ready_async */ + NULL, /* flush */ + echo_drv_call, /* call */ + NULL, /* event */ + ERL_DRV_EXTENDED_MARKER, + ERL_DRV_EXTENDED_MAJOR_VERSION, + ERL_DRV_EXTENDED_MINOR_VERSION, + 0, + NULL, + NULL, + NULL +}; + +/* ------------------------------------------------------------------------- +** Entry functions +**/ + +DRIVER_INIT(echo_drv) +{ + char buff[5]; + size_t size = sizeof(buff); + + if (erl_drv_getenv("OUTPUTV", buff, &size) == -1) { + echo_drv_entry.outputv = NULL; + } else { + echo_drv_entry.outputv = echo_drv_outputv; + } + + return &echo_drv_entry; +} + +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); + return echo_drv_data_p; +} + +static void echo_drv_stop(EchoDrvData *data_p) { + driver_free(data_p); +} + +static void echo_drv_outputv(ErlDrvData drv_data, ErlIOVec *iov) +{ + return; +} + +static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) { + EchoDrvData* data_p = (EchoDrvData *) drv_data; + ErlDrvPort port = data_p->erlang_port; + + switch (buf[0]) { + case ECHO_DRV_OUTPUT: + { + driver_output(port, buf+1, len-1); + break; + } + case ECHO_DRV_OUTPUT2: + { + driver_output2(port, "a", 1, buf+1, len-1); + break; + } + case ECHO_DRV_OUTPUT_BINARY: + { + ErlDrvBinary *bin = driver_alloc_binary(len-1); + memcpy(&bin->orig_bytes, buf+1, len-1); + driver_output_binary(port, "a", 1, bin, 1, len - 2); + driver_free_binary(bin); + break; + } + case ECHO_DRV_OUTPUTV: + { + ErlIOVec iov; + ErlDrvSizeT sz; + driver_enq(port, buf + 1, len - 1); + sz = driver_peekqv(port, &iov); + driver_outputv(port, "a", 1, &iov, 0); + driver_deq(port, sz); + break; + } + case ECHO_DRV_SET_TIMER: + { + driver_set_timer(port, 10); + break; + } + case ECHO_DRV_FAILURE_EOF: + { + driver_failure_eof(port); + break; + } + case ECHO_DRV_FAILURE_ATOM: + { + driver_failure_atom(port, buf+1); + break; + } + case ECHO_DRV_FAILURE_POSIX: + { + driver_failure_posix(port, EAGAIN); + break; + } + case ECHO_DRV_FAILURE: + { + driver_failure(port, buf[1]); + break; + } + case ECHO_DRV_OUTPUT_TERM: + case ECHO_DRV_DRIVER_OUTPUT_TERM: + case ECHO_DRV_SEND_TERM: + case ECHO_DRV_DRIVER_SEND_TERM: + { + ErlDrvTermData term[] = { + ERL_DRV_ATOM, driver_mk_atom("echo"), + ERL_DRV_PORT, driver_mk_port(port), + ERL_DRV_BUF2BINARY, (ErlDrvTermData)(buf+1), + (ErlDrvTermData)(len - 1), + ERL_DRV_TUPLE, 3}; + switch (buf[0]) { + case ECHO_DRV_OUTPUT_TERM: + erl_drv_output_term(driver_mk_port(port), term, sizeof(term) / sizeof(ErlDrvTermData)); + break; + case ECHO_DRV_DRIVER_OUTPUT_TERM: + driver_output_term(port, term, sizeof(term) / sizeof(ErlDrvTermData)); + break; + case ECHO_DRV_SEND_TERM: + driver_send_term(port, data_p->caller, + term, sizeof(term) / sizeof(ErlDrvTermData)); + break; + case ECHO_DRV_DRIVER_SEND_TERM: + erl_drv_send_term(driver_mk_port(port), data_p->caller, + term, sizeof(term) / sizeof(ErlDrvTermData)); + break; + } + break; + } + case ECHO_DRV_SAVE_CALLER: + data_p->caller = driver_caller(port); + break; + default: + break; + } +} + +static void echo_drv_finish() { + +} + +static ErlDrvSSizeT echo_drv_control(ErlDrvData drv_data, + unsigned int command, + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen) +{ + memcpy(*rbuf, buf+1, len-1); + return len-1; +} + +static void echo_drv_timeout(ErlDrvData drv_data) +{ + +} + +static ErlDrvSSizeT echo_drv_call(ErlDrvData drv_data, + unsigned int command, + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen, + unsigned int *flags) +{ + memcpy(*rbuf, buf+command, len-command); + return len-command; +} diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl index 5bb216ff79..61a68f9759 100644 --- a/erts/emulator/test/process_SUITE.erl +++ b/erts/emulator/test/process_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -1003,7 +1003,7 @@ low_prio_test(Config) when is_list(Config) -> process_flag(trap_exit, true), S = spawn_link(?MODULE, prio_server, [0, 0]), PCs = spawn_prio_clients(S, erlang:system_info(schedulers_online)), - timer:sleep(2000), + ct:sleep({seconds,3}), lists:foreach(fun (P) -> exit(P, kill) end, PCs), S ! exit, receive {'EXIT', S, {A, B}} -> check_prio(A, B) end, diff --git a/erts/emulator/test/pseudoknot_SUITE.erl b/erts/emulator/test/pseudoknot_SUITE.erl index 58ef3cd563..ed4d40ac65 100644 --- a/erts/emulator/test/pseudoknot_SUITE.erl +++ b/erts/emulator/test/pseudoknot_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% Copyright Ericsson AB 2001-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/random_iolist.erl b/erts/emulator/test/random_iolist.erl index 6da7da04de..555f063e0a 100644 --- a/erts/emulator/test/random_iolist.erl +++ b/erts/emulator/test/random_iolist.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl index 6097e54219..83653a7a36 100644 --- a/erts/emulator/test/receive_SUITE.erl +++ b/erts/emulator/test/receive_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/ref_SUITE.erl b/erts/emulator/test/ref_SUITE.erl index 287a2ffb73..5f519d522e 100644 --- a/erts/emulator/test/ref_SUITE.erl +++ b/erts/emulator/test/ref_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/register_SUITE.erl b/erts/emulator/test/register_SUITE.erl index ad8a9c29f3..43ae749498 100644 --- a/erts/emulator/test/register_SUITE.erl +++ b/erts/emulator/test/register_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/save_calls_SUITE.erl b/erts/emulator/test/save_calls_SUITE.erl index 3199fe9ca1..af1a0d35d6 100644 --- a/erts/emulator/test/save_calls_SUITE.erl +++ b/erts/emulator/test/save_calls_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2013. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl index 64c280b198..6b49b68ec8 100644 --- a/erts/emulator/test/scheduler_SUITE.erl +++ b/erts/emulator/test/scheduler_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -876,7 +876,7 @@ get_affinity_mask(_Port, _Status, Affinity) -> Affinity. get_affinity_mask() -> - case test_server:os_type() of + case os:type() of {unix, linux} -> case catch open_port({spawn, "taskset -p " ++ os:getpid()}, [exit_status]) of @@ -1733,7 +1733,7 @@ sched_state([], N, DC, DI) -> {N, DC, DI} catch _ : _ -> - ?t:fail({inconsisten_scheduler_state, {N, DC, DI}}) + ct:fail({inconsisten_scheduler_state, {N, DC, DI}}) end; sched_state([{normal, _, _, _} = S | Rest], _S, DC, DI) -> sched_state(Rest, S, DC, DI); diff --git a/erts/emulator/test/send_term_SUITE.erl b/erts/emulator/test/send_term_SUITE.erl index 75161389b1..8afe4e4ac1 100644 --- a/erts/emulator/test/send_term_SUITE.erl +++ b/erts/emulator/test/send_term_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2014. All Rights Reserved. +%% Copyright Ericsson AB 2005-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/sensitive_SUITE.erl b/erts/emulator/test/sensitive_SUITE.erl index e2236774a7..b7ff4c109c 100644 --- a/erts/emulator/test/sensitive_SUITE.erl +++ b/erts/emulator/test/sensitive_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/signal_SUITE.erl b/erts/emulator/test/signal_SUITE.erl index 63397fbbb4..0b11fa13f5 100644 --- a/erts/emulator/test/signal_SUITE.erl +++ b/erts/emulator/test/signal_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2011. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/smoke_test_SUITE.erl b/erts/emulator/test/smoke_test_SUITE.erl index 900dd124c0..042c7225d5 100644 --- a/erts/emulator/test/smoke_test_SUITE.erl +++ b/erts/emulator/test/smoke_test_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2012. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/statistics_SUITE.erl b/erts/emulator/test/statistics_SUITE.erl index 7d5b07f21f..71ef003b25 100644 --- a/erts/emulator/test/statistics_SUITE.erl +++ b/erts/emulator/test/statistics_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index ffea5bc15b..f31d474c20 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2011. All Rights Reserved. +%% Copyright Ericsson AB 2005-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/system_profile_SUITE.erl b/erts/emulator/test/system_profile_SUITE.erl index 6d80d436ba..2e359b11ce 100644 --- a/erts/emulator/test/system_profile_SUITE.erl +++ b/erts/emulator/test/system_profile_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2012. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ system_profile_on_and_off/1, runnable_procs/1, runnable_ports/1, dont_profile_profiler/1, - scheduler/1]). + scheduler/1, sane_location/1]). -export([profiler_process/1, ring_loop/1, port_echo_start/0, list_load/0, run_load/2]). @@ -40,7 +40,8 @@ suite() -> all() -> [system_profile_on_and_off, runnable_procs, - runnable_ports, scheduler, dont_profile_profiler]. + runnable_ports, scheduler, dont_profile_profiler, + sane_location]. %% No specification clause needed for an init function in a conf case!!! @@ -183,6 +184,33 @@ dont_profile_profiler(Config) when is_list(Config) -> exit(Pid,kill), ok. +%% Check sane location (of exits) +sane_location(Config) when is_list(Config) -> + Check = spawn_link(fun() -> flush_sane_location() end), + erlang:system_profile(Check, [runnable_procs]), + Me = self(), + Pids = [spawn_link(fun() -> wat(Me) end) || _ <- lists:seq(1,100)], + [receive {Pid,ok} -> ok end || Pid <- Pids], + Check ! {Me, done}, + receive {Check,ok} -> ok end, + ok. + +wat(Pid) -> + Pid ! {self(), ok}. + +flush_sane_location() -> + receive + {profile,_,_,{M,F,A},_} when is_atom(M), is_atom(F), + is_integer(A) -> + flush_sane_location(); + {profile,_,_,0,_} -> + flush_sane_location(); + {Pid,done} when is_pid(Pid) -> + Pid ! {self(), ok}; + M -> + ct:fail({badness,M}) + end. + %%% Check scheduler profiling diff --git a/erts/emulator/test/time_SUITE.erl b/erts/emulator/test/time_SUITE.erl index e6da5e89fa..76d440529f 100644 --- a/erts/emulator/test/time_SUITE.erl +++ b/erts/emulator/test/time_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl index fa72700604..a5f11bd959 100644 --- a/erts/emulator/test/timer_bif_SUITE.erl +++ b/erts/emulator/test/timer_bif_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2013. All Rights Reserved. +%% Copyright Ericsson AB 1998-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl index dcd5e95434..b7f312635e 100644 --- a/erts/emulator/test/trace_SUITE.erl +++ b/erts/emulator/test/trace_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,8 +24,8 @@ %%% Tests the trace BIF. %%% --export([all/0, suite/0, - receive_trace/1, self_send/1, +-export([all/0, suite/0, link_receive_call_correlation/0, + receive_trace/1, link_receive_call_correlation/1, self_send/1, timeout_trace/1, send_trace/1, procs_trace/1, dist_procs_trace/1, suspend/1, mutual_suspend/1, suspend_exit/1, suspender_exit/1, @@ -48,7 +48,8 @@ suite() -> {timetrap, {seconds, 5}}]. all() -> - [cpu_timestamp, receive_trace, self_send, timeout_trace, + [cpu_timestamp, receive_trace, link_receive_call_correlation, + self_send, timeout_trace, send_trace, procs_trace, dist_procs_trace, suspend, mutual_suspend, suspend_exit, suspender_exit, suspend_system_limit, suspend_opts, suspend_waiting, @@ -87,10 +88,10 @@ receive_trace(Config) when is_list(Config) -> 1 = erlang:trace(Receiver, true, ['receive']), Hello = {hello, world}, Receiver ! Hello, - {trace, Receiver, 'receive', Hello} = receive_first(), + {trace, Receiver, 'receive', Hello} = receive_first_trace(), Hello2 = {hello, again, world}, Receiver ! Hello2, - {trace, Receiver, 'receive', Hello2} = receive_first(), + {trace, Receiver, 'receive', Hello2} = receive_first_trace(), receive_nothing(), %% Another process should not be able to trace Receiver. @@ -104,6 +105,112 @@ receive_trace(Config) when is_list(Config) -> receive_nothing(), ok. +%% Tests that receive of a message always happens before a call with +%% that message and that links/unlinks are ordered together with the +%% 'receive'. +link_receive_call_correlation() -> + [{timetrap, {minutes, 5}}]. +link_receive_call_correlation(Config) when is_list(Config) -> + Receiver = fun_spawn(fun F() -> + receive + stop -> ok; + M -> receive_msg(M), F() + end + end), + process_flag(trap_exit, true), + + %% Trace the process; make sure that we receive the trace messages. + 1 = erlang:trace(Receiver, true, ['receive', procs, call, timestamp, scheduler_id]), + 1 = erlang:trace_pattern({?MODULE, receive_msg, '_'}, [], [local]), + + Num = 100000, + + (fun F(0) -> []; + F(N) -> + if N rem 2 == 0 -> + link(Receiver); + true -> + unlink(Receiver) + end, + [Receiver ! N | F(N-1)] + end)(Num), + + Receiver ! stop, + MonRef = erlang:monitor(process, Receiver), + receive {'DOWN', MonRef, _, _, _} -> ok end, + Ref = erlang:trace_delivered(Receiver), + receive {trace_delivered, _, Ref} -> ok end, + + Msgs = (fun F() -> receive M -> [M | F()] after 1 -> [] end end)(), + + case check_consistent(Receiver, Num, Num, Num, Msgs) of + ok -> + ok; + {error, Reason} -> + ct:log("~p", [Msgs]), + ct:fail({error, Reason}) + end. + +-define(schedid, , _). + +check_consistent(_Pid, Recv, Call, _LU, [Msg | _]) when Recv > Call -> + {error, Msg}; +check_consistent(Pid, Recv, Call, LU, [Msg | Msgs]) -> + + case Msg of + {trace, Pid, 'receive', Recv ?schedid} -> + check_consistent(Pid,Recv - 1, Call, LU, Msgs); + {trace_ts, Pid, 'receive', Recv ?schedid, _} -> + check_consistent(Pid,Recv - 1, Call, LU, Msgs); + + {trace, Pid, call, {?MODULE, receive_msg, [Call]} ?schedid} -> + check_consistent(Pid,Recv, Call - 1, LU, Msgs); + {trace_ts, Pid, call, {?MODULE, receive_msg, [Call]} ?schedid, _} -> + check_consistent(Pid,Recv, Call - 1, LU, Msgs); + + %% We check that for each receive we have gotten a + %% getting_linked or getting_unlinked message. Also + %% if we receive a getting_linked, then the next + %% message we expect to receive is an even number + %% and odd number for getting_unlinked. + {trace, Pid, getting_linked, _Self ?schedid} + when Recv rem 2 == 0, Recv == LU -> + check_consistent(Pid, Recv, Call, LU - 1, Msgs); + {trace_ts, Pid, getting_linked, _Self ?schedid, _} + when Recv rem 2 == 0, Recv == LU -> + check_consistent(Pid, Recv, Call, LU - 1, Msgs); + + {trace, Pid, getting_unlinked, _Self ?schedid} + when Recv rem 2 == 1, Recv == LU -> + check_consistent(Pid, Recv, Call, LU - 1, Msgs); + {trace_ts, Pid, getting_unlinked, _Self ?schedid, _} + when Recv rem 2 == 1, Recv == LU -> + check_consistent(Pid, Recv, Call, LU - 1, Msgs); + + {trace,Pid,'receive',Ignore ?schedid} + when Ignore == stop; Ignore == timeout -> + check_consistent(Pid, Recv, Call, LU, Msgs); + {trace_ts,Pid,'receive',Ignore ?schedid,_} + when Ignore == stop; Ignore == timeout -> + check_consistent(Pid, Recv, Call, LU, Msgs); + + {trace, Pid, exit, normal ?schedid} -> + check_consistent(Pid, Recv, Call, LU, Msgs); + {trace_ts, Pid, exit, normal ?schedid, _} -> + check_consistent(Pid, Recv, Call, LU, Msgs); + {'EXIT', Pid, normal} -> + check_consistent(Pid, Recv, Call, LU, Msgs); + Msg -> + {error, Msg} + end; +check_consistent(_, 0, 0, 0, []) -> + ok; +check_consistent(_, Recv, Call, LU, []) -> + {error,{Recv, Call, LU}}. + +receive_msg(M) -> + M. + %% Test that traces are generated for messages sent %% and received to/from self(). self_send(Config) when is_list(Config) -> @@ -134,8 +241,8 @@ timeout_trace(Config) when is_list(Config) -> Process = fun_spawn(fun process/0), 1 = erlang:trace(Process, true, ['receive']), Process ! timeout_please, - {trace, Process, 'receive', timeout_please} = receive_first(), - {trace, Process, 'receive', timeout} = receive_first(), + {trace, Process, 'receive', timeout_please} = receive_first_trace(), + {trace, Process, 'receive', timeout} = receive_first_trace(), receive_nothing(), ok. @@ -149,13 +256,13 @@ send_trace(Config) when is_list(Config) -> %% Check that a message sent to another process is traced. 1 = erlang:trace(Sender, true, [send]), Sender ! {send_please, Receiver, to_receiver}, - {trace, Sender, send, to_receiver, Receiver} = receive_first(), + {trace, Sender, send, to_receiver, Receiver} = receive_first_trace(), receive_nothing(), %% Check that a message sent to another registered process is traced. register(?MODULE,Receiver), Sender ! {send_please, ?MODULE, to_receiver}, - {trace, Sender, send, to_receiver, ?MODULE} = receive_first(), + {trace, Sender, send, to_receiver, ?MODULE} = receive_first_trace(), receive_nothing(), unregister(?MODULE), @@ -163,14 +270,14 @@ send_trace(Config) when is_list(Config) -> Sender ! {send_please, self(), to_myself}, receive to_myself -> ok end, Self = self(), - {trace, Sender, send, to_myself, Self} = receive_first(), + {trace, Sender, send, to_myself, Self} = receive_first_trace(), receive_nothing(), %% Check that a message sent to dead process is traced. {Pid,Ref} = spawn_monitor(fun() -> ok end), receive {'DOWN',Ref,_,_,_} -> ok end, Sender ! {send_please, Pid, to_dead}, - {trace, Sender, send_to_non_existing_process, to_dead, Pid} = receive_first(), + {trace, Sender, send_to_non_existing_process, to_dead, Pid} = receive_first_trace(), receive_nothing(), %% Check that a message sent to unknown registrated process is traced. @@ -178,7 +285,7 @@ send_trace(Config) when is_list(Config) -> 1 = erlang:trace(BadargSender, true, [send]), unlink(BadargSender), BadargSender ! {send_please, not_registered, to_unknown}, - {trace, BadargSender, send, to_unknown, not_registered} = receive_first(), + {trace, BadargSender, send, to_unknown, not_registered} = receive_first_trace(), receive_nothing(), %% Another process should not be able to trace Sender. @@ -205,15 +312,17 @@ procs_trace(Config) when is_list(Config) -> Proc2 = spawn(?MODULE, process, [Self]), io:format("Proc2 = ~p ~n", [Proc2]), %% - 1 = erlang:trace(Proc1, true, [procs]), + 1 = erlang:trace(Proc1, true, [procs, set_on_first_spawn]), MFA = {?MODULE, process, [Self]}, %% %% spawn, link Proc1 ! {spawn_link_please, Self, MFA}, Proc3 = receive {spawned, Proc1, P3} -> P3 end, - {trace, Proc1, spawn, Proc3, MFA} = receive_first(), + receive {trace, Proc3, spawned, Proc1, MFA} -> ok end, + receive {trace, Proc3, getting_linked, Proc1} -> ok end, + {trace, Proc1, spawn, Proc3, MFA} = receive_first_trace(), io:format("Proc3 = ~p ~n", [Proc3]), - {trace, Proc1, link, Proc3} = receive_first(), + {trace, Proc1, link, Proc3} = receive_first_trace(), receive_nothing(), %% %% getting_unlinked by exit() @@ -221,60 +330,61 @@ procs_trace(Config) when is_list(Config) -> Reason3 = make_ref(), Proc1 ! {send_please, Proc3, {exit_please, Reason3}}, receive {Proc1, {'EXIT', Proc3, Reason3}} -> ok end, - {trace, Proc1, getting_unlinked, Proc3} = receive_first(), + receive {trace, Proc3, exit, Reason3} -> ok end, + {trace, Proc1, getting_unlinked, Proc3} = receive_first_trace(), Proc1 ! {trap_exit_please, false}, receive_nothing(), %% %% link Proc1 ! {link_please, Proc2}, - {trace, Proc1, link, Proc2} = receive_first(), + {trace, Proc1, link, Proc2} = receive_first_trace(), receive_nothing(), %% %% unlink Proc1 ! {unlink_please, Proc2}, - {trace, Proc1, unlink, Proc2} = receive_first(), + {trace, Proc1, unlink, Proc2} = receive_first_trace(), receive_nothing(), %% %% getting_linked Proc2 ! {link_please, Proc1}, - {trace, Proc1, getting_linked, Proc2} = receive_first(), + {trace, Proc1, getting_linked, Proc2} = receive_first_trace(), receive_nothing(), %% %% getting_unlinked Proc2 ! {unlink_please, Proc1}, - {trace, Proc1, getting_unlinked, Proc2} = receive_first(), + {trace, Proc1, getting_unlinked, Proc2} = receive_first_trace(), receive_nothing(), %% %% register true = register(Name, Proc1), - {trace, Proc1, register, Name} = receive_first(), + {trace, Proc1, register, Name} = receive_first_trace(), receive_nothing(), %% %% unregister true = unregister(Name), - {trace, Proc1, unregister, Name} = receive_first(), + {trace, Proc1, unregister, Name} = receive_first_trace(), receive_nothing(), %% %% exit (with registered name, due to link) Reason4 = make_ref(), Proc1 ! {spawn_link_please, Self, MFA}, Proc4 = receive {spawned, Proc1, P4} -> P4 end, - {trace, Proc1, spawn, Proc4, MFA} = receive_first(), + {trace, Proc1, spawn, Proc4, MFA} = receive_first_trace(), io:format("Proc4 = ~p ~n", [Proc4]), - {trace, Proc1, link, Proc4} = receive_first(), + {trace, Proc1, link, Proc4} = receive_first_trace(), Proc1 ! {register_please, Name, Proc1}, - {trace, Proc1, register, Name} = receive_first(), + {trace, Proc1, register, Name} = receive_first_trace(), Proc4 ! {exit_please, Reason4}, receive {'EXIT', Proc1, Reason4} -> ok end, - {trace, Proc1, exit, Reason4} = receive_first(), - {trace, Proc1, unregister, Name} = receive_first(), + {trace, Proc1, exit, Reason4} = receive_first_trace(), + {trace, Proc1, unregister, Name} = receive_first_trace(), receive_nothing(), %% %% exit (not linked to tracing process) 1 = erlang:trace(Proc2, true, [procs]), Reason2 = make_ref(), Proc2 ! {exit_please, Reason2}, - {trace, Proc2, exit, Reason2} = receive_first(), + {trace, Proc2, exit, Reason2} = receive_first_trace(), receive_nothing(), ok. @@ -299,45 +409,45 @@ dist_procs_trace(Config) when is_list(Config) -> Proc1 ! {trap_exit_please, true}, Proc3 = receive {spawned, Proc1, P3} -> P3 end, io:format("Proc3 = ~p ~n", [Proc3]), - {trace, Proc1, getting_linked, Proc3} = receive_first(), + {trace, Proc1, getting_linked, Proc3} = receive_first_trace(), Reason3 = make_ref(), Proc1 ! {send_please, Proc3, {exit_please, Reason3}}, receive {Proc1, {'EXIT', Proc3, Reason3}} -> ok end, - {trace, Proc1, getting_unlinked, Proc3} = receive_first(), + {trace, Proc1, getting_unlinked, Proc3} = receive_first_trace(), Proc1 ! {trap_exit_please, false}, receive_nothing(), %% %% link Proc1 ! {link_please, Proc2}, - {trace, Proc1, link, Proc2} = receive_first(), + {trace, Proc1, link, Proc2} = receive_first_trace(), receive_nothing(), %% %% unlink Proc1 ! {unlink_please, Proc2}, - {trace, Proc1, unlink, Proc2} = receive_first(), + {trace, Proc1, unlink, Proc2} = receive_first_trace(), receive_nothing(), %% %% getting_linked Proc2 ! {link_please, Proc1}, - {trace, Proc1, getting_linked, Proc2} = receive_first(), + {trace, Proc1, getting_linked, Proc2} = receive_first_trace(), receive_nothing(), %% %% getting_unlinked Proc2 ! {unlink_please, Proc1}, - {trace, Proc1, getting_unlinked, Proc2} = receive_first(), + {trace, Proc1, getting_unlinked, Proc2} = receive_first_trace(), receive_nothing(), %% %% exit (with registered name, due to link) Name = list_to_atom(OtherName), Reason2 = make_ref(), Proc1 ! {link_please, Proc2}, - {trace, Proc1, link, Proc2} = receive_first(), + {trace, Proc1, link, Proc2} = receive_first_trace(), Proc1 ! {register_please, Name, Proc1}, - {trace, Proc1, register, Name} = receive_first(), + {trace, Proc1, register, Name} = receive_first_trace(), Proc2 ! {exit_please, Reason2}, receive {'EXIT', Proc1, Reason2} -> ok end, - {trace, Proc1, exit, Reason2} = receive_first(), - {trace, Proc1, unregister, Name} = receive_first(), + {trace, Proc1, exit, Reason2} = receive_first_trace(), + {trace, Proc1, unregister, Name} = receive_first_trace(), receive_nothing(), %% %% Done. @@ -1247,7 +1357,8 @@ existing_clear(Config) when is_list(Config) -> [N, M]), {flags, []} = erlang:trace_info(Self, flags), {tracer, []} = erlang:trace_info(Self, tracer), - M = N + 1, % Since trace could not be enabled on the tracer. + M = N, % Used to be N + 1, but from 19.0 the tracer is also traced + ok. %% Test that an invalid flag cause badarg @@ -1317,6 +1428,13 @@ receive_first() -> Any -> Any end. +%% Waits for and returns the first message in the message queue. + +receive_first_trace() -> + receive + Any when element(1,Any) =:= trace; element(1,Any) =:= trace_ts -> Any + end. + %% Ensures that there is no message in the message queue. receive_nothing() -> @@ -1421,7 +1539,7 @@ fun_spawn(Fun, Args) -> start_node(Name) -> Pa = filename:dirname(code:which(?MODULE)), Cookie = atom_to_list(erlang:get_cookie()), - test_server:start_node(Name, slave, + test_server:start_node(Name, slave, [{args, "-setcookie " ++ Cookie ++" -pa " ++ Pa}]). stop_node(Node) -> diff --git a/erts/emulator/test/trace_bif_SUITE.erl b/erts/emulator/test/trace_bif_SUITE.erl index b774210456..8c3ffccc45 100644 --- a/erts/emulator/test/trace_bif_SUITE.erl +++ b/erts/emulator/test/trace_bif_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2014. All Rights Reserved. +%% Copyright Ericsson AB 1998-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -247,7 +247,8 @@ receive_trace_msg(Mess) -> receive_trace_msg_ts({trace_ts, Pid, call, {erlang,F,A}}, PrevTs, TsType) -> receive - {trace_ts, Pid, call, {erlang, F, A}, Ts} -> + {trace_ts, Pid, call, {erlang, F, A}, Ts} = M -> + io:format("~p (PrevTs: ~p)~n",[M, PrevTs]), check_ts(TsType, PrevTs, Ts), Ts; Other -> @@ -260,7 +261,8 @@ receive_trace_msg_ts({trace_ts, Pid, call, {erlang,F,A}}, PrevTs, TsType) -> receive_trace_msg_ts_return_from({trace_ts, Pid, return_from, {erlang,F,A}}, PrevTs, TsType) -> receive - {trace_ts, Pid, return_from, {erlang, F, A}, _Value, Ts} -> + {trace_ts, Pid, return_from, {erlang, F, A}, _Value, Ts} = M -> + io:format("~p (PrevTs: ~p)~n",[M, PrevTs]), check_ts(TsType, PrevTs, Ts), Ts; Other -> @@ -272,7 +274,8 @@ receive_trace_msg_ts_return_from({trace_ts, Pid, return_from, {erlang,F,A}}, Pre receive_trace_msg_ts_return_to({trace_ts, Pid, return_to, {M,F,A}}, PrevTs, TsType) -> receive - {trace_ts, Pid, return_to, {M, F, A}, Ts} -> + {trace_ts, Pid, return_to, {M, F, A}, Ts} = Msg -> + io:format("~p (PrevTs: ~p)~n",[Msg, PrevTs]), check_ts(TsType, PrevTs, Ts), Ts; Other -> diff --git a/erts/emulator/test/trace_call_count_SUITE.erl b/erts/emulator/test/trace_call_count_SUITE.erl index c849668e84..5f871835bc 100644 --- a/erts/emulator/test/trace_call_count_SUITE.erl +++ b/erts/emulator/test/trace_call_count_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2011. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/trace_call_time_SUITE.erl b/erts/emulator/test/trace_call_time_SUITE.erl index 38972c9c02..40c8bc4340 100644 --- a/erts/emulator/test/trace_call_time_SUITE.erl +++ b/erts/emulator/test/trace_call_time_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/trace_local_SUITE.erl b/erts/emulator/test/trace_local_SUITE.erl index 24864dcbef..74c05f24e0 100644 --- a/erts/emulator/test/trace_local_SUITE.erl +++ b/erts/emulator/test/trace_local_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2013. All Rights Reserved. +%% Copyright Ericsson AB 2000-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -1224,18 +1224,22 @@ setup(ProcFlags) -> shutdown() -> trace_off(), - {Pid,Mref} = get(slave), - try erlang:is_process_alive(Pid) of - true -> - Pid ! die, - receive - {'DOWN',Mref,process,Pid,Reason} -> - Reason + case get(slave) of + {Pid,Mref} -> + try erlang:is_process_alive(Pid) of + true -> + Pid ! die, + receive + {'DOWN',Mref,process,Pid,Reason} -> + Reason + end; + _ -> + not_alive + catch _:_ -> + undefined end; _ -> - not_alive - catch _:_ -> - undefined + undefined end. trace_off() -> diff --git a/erts/emulator/test/trace_local_SUITE_data/trace_local_dummy.erl b/erts/emulator/test/trace_local_SUITE_data/trace_local_dummy.erl index a5947de4aa..a886323302 100644 --- a/erts/emulator/test/trace_local_SUITE_data/trace_local_dummy.erl +++ b/erts/emulator/test/trace_local_SUITE_data/trace_local_dummy.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% Copyright Ericsson AB 2000-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/trace_meta_SUITE.erl b/erts/emulator/test/trace_meta_SUITE.erl index dcc2cc807b..b6a6fd5404 100644 --- a/erts/emulator/test/trace_meta_SUITE.erl +++ b/erts/emulator/test/trace_meta_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2011. All Rights Reserved. +%% Copyright Ericsson AB 2002-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/trace_nif_SUITE.erl b/erts/emulator/test/trace_nif_SUITE.erl index 49757a414d..8d5bff2a48 100644 --- a/erts/emulator/test/trace_nif_SUITE.erl +++ b/erts/emulator/test/trace_nif_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/trace_port_SUITE.erl b/erts/emulator/test/trace_port_SUITE.erl index d33f18543a..1068c1d22d 100644 --- a/erts/emulator/test/trace_port_SUITE.erl +++ b/erts/emulator/test/trace_port_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. +%% Copyright Ericsson AB 1999-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -28,10 +28,6 @@ receive_trace/1, process_events/1, schedule/1, - fake_schedule/1, - fake_schedule_after_register/1, - fake_schedule_after_getting_linked/1, - fake_schedule_after_getting_unlinked/1, gc/1, default_tracer/1, tracer_port_crash/1]). @@ -44,10 +40,7 @@ suite() -> all() -> [call_trace, return_trace, send, receive_trace, - process_events, schedule, fake_schedule, - fake_schedule_after_register, - fake_schedule_after_getting_linked, - fake_schedule_after_getting_unlinked, gc, + process_events, schedule, gc, default_tracer, tracer_port_crash]. %% Test sending call trace messages to a port. @@ -234,162 +227,6 @@ schedule(Config) when is_list(Config) -> ok. -run_fake_sched_test(Fun, Config) when is_function(Fun), is_list(Config) -> - case catch erlang:system_info(smp_support) of - true -> - {skipped, - "No need for faked schedule out/in trace messages " - "when smp support is enabled"}; - _ -> - Fun(Config) - end. - -%% Tests time compensating fake out/in scheduling. -fake_schedule(Config) when is_list(Config) -> - run_fake_sched_test(fun fake_schedule_test/1, Config). - -fake_schedule_test(Config) when is_list(Config) -> - Tracer = start_tracer(Config), - Port = get(tracer_port), - General = fun_spawn(fun general/0), - %% - trac(General, true, [send, running]), - %% - %% Test that fake out/in scheduling is not generated unless - %% both 'running' and 'timestamp' is active. - [] = erlang:port_control(Port, $h, []), - General ! nop, - expect({trace, General, in, {?MODULE, general, 0}}), - expect({trace, General, out, {?MODULE, general, 0}}), - expect(), - %% - trac(General, false, [running]), - trac(General, true, [timestamp]), - %% - Ref1 = make_ref(), - Msg1 = {Port, {data, term_to_binary(Ref1)}}, - [] = erlang:port_control(Port, $h, []), - General ! {send, Tracer, Msg1}, - expect({trace_ts, General, send, Msg1, Tracer, ts}), - expect(Ref1), - expect(), - %% - trac(General, true, [running]), - %% - %% Test that fake out/in scheduling can be generated by the driver - Ref2 = make_ref(), - Msg2 = {Port, {data, term_to_binary(Ref2)}}, - [] = erlang:port_control(Port, $h, []), - General ! {send, Tracer, Msg2}, - {_,_,_,_,Ts} = - expect({trace_ts, General, in, {?MODULE, general, 0}, ts}), - expect({trace_ts, General, out, 0, Ts}), - expect({trace_ts, General, in, 0, ts}), - expect({trace_ts, General, send, Msg2, Tracer, ts}), - expect(Ref2), - expect({trace_ts, General, out, {?MODULE, general, 0}, ts}), - expect(), - %% - %% Test that fake out/in scheduling is not generated after an - %% 'out' scheduling event - Ref3 = make_ref(), - Msg3 = {Port, {data, term_to_binary(Ref3)}}, - General ! {apply, {erlang, port_control, [Port, $h, []]}}, - expect({trace_ts, General, in, {?MODULE, general, 0}, ts}), - expect({trace_ts, General, out, {?MODULE, general, 0}, ts}), - General ! {send, Tracer, Msg3}, - expect({trace_ts, General, in, {?MODULE, general, 0}, ts}), - expect({trace_ts, General, send, Msg3, Tracer, ts}), - expect(Ref3), - expect({trace_ts, General, out, {?MODULE, general, 0}, ts}), - expect(), - %% - ok. - -%% Tests fake out/in scheduling contents. -fake_schedule_after_register(Config) when is_list(Config) -> - run_fake_sched_test(fun fake_schedule_after_register_test/1, Config). - -fake_schedule_after_register_test(Config) when is_list(Config) -> - start_tracer(Config), - Port = get(tracer_port), - G1 = fun_spawn(fun general/0), - G2 = fun_spawn(fun general/0), - %% - trac(G1, true, [running, timestamp, procs]), - trac(G2, true, [running, timestamp]), - %% - %% Test fake out/in scheduling after certain messages - erlang:yield(), - G2 ! {apply, {erlang, port_control, [Port, $h, []]}}, - G2 ! {apply, {erlang, register, [fake_schedule_after_register, G1]}}, - expect({trace_ts, G2, in, {?MODULE, general, 0}, ts}), - {_,_,_,_,Ts} = - expect({trace_ts, G1, register, fake_schedule_after_register, ts}), - expect({trace_ts, G2, out, 0, Ts}), - expect({trace_ts, G2, in, 0, ts}), - expect({trace_ts, G2, out, {?MODULE, general, 0}, ts}), - expect(), - %% - ok. - -%% Tests fake out/in scheduling contents. -fake_schedule_after_getting_linked(Config) when is_list(Config) -> - run_fake_sched_test(fun fake_schedule_after_getting_linked_test/1, - Config). - -fake_schedule_after_getting_linked_test(Config) when is_list(Config) -> - start_tracer(Config), - Port = get(tracer_port), - G1 = fun_spawn(fun general/0), - G2 = fun_spawn(fun general/0), - %% - trac(G1, true, [running, timestamp, procs]), - trac(G2, true, [running, timestamp]), - %% - %% Test fake out/in scheduling after certain messages - erlang:yield(), - G2 ! {apply, {erlang, port_control, [Port, $h, []]}}, - G2 ! {apply, {erlang, link, [G1]}}, - expect({trace_ts, G2, in, {?MODULE, general, 0}, ts}), - {_,_,_,_,Ts} = - expect({trace_ts, G1, getting_linked, G2, ts}), - expect({trace_ts, G2, out, 0, Ts}), - expect({trace_ts, G2, in, 0, ts}), - expect({trace_ts, G2, out, {?MODULE, general, 0}, ts}), - expect(), - %% - ok. - -%% Tests fake out/in scheduling contents. -fake_schedule_after_getting_unlinked(Config) when is_list(Config) -> - run_fake_sched_test(fun fake_schedule_after_getting_unlinked_test/1, - Config). - -fake_schedule_after_getting_unlinked_test(Config) when is_list(Config) -> - start_tracer(Config), - Port = get(tracer_port), - G1 = fun_spawn(fun general/0), - G2 = fun_spawn(fun general/0), - %% - trac(G1, true, [running, procs]), - trac(G2, true, [running, timestamp]), - %% - %% Test fake out/in scheduling after certain messages - erlang:yield(), - G2 ! {apply, {erlang, link, [G1]}}, - G2 ! {apply, {erlang, port_control, [Port, $h, []]}}, - G2 ! {apply, {erlang, unlink, [G1]}}, - expect({trace_ts, G2, in, {?MODULE, general, 0}, ts}), - expect({trace, G1, getting_linked, G2}), - expect({trace, G1, getting_unlinked, G2}), - expect({trace_ts, G2, out, 0, ts}), - expect({trace_ts, G2, in, 0, ts}), - expect({trace_ts, G2, out, {?MODULE, general, 0}, ts}), - expect(), - %% - ok. - %% Test sending garbage collection events to a port. gc(Config) when is_list(Config) -> start_tracer(Config), @@ -440,7 +277,7 @@ default_tracer(Config) when is_list(Config) -> {tracer, []} = erlang:trace_info(G1, tracer), G1 ! {apply,{erlang,exit,[normal]}}, io:format("~p = ~p.~n", [M, N]), - M = N, + M = N - 1, % G1 has been started, but Tracer and Port have died ok. tracer_port_crash(Config) when is_list(Config) -> diff --git a/erts/emulator/test/tracer_SUITE.erl b/erts/emulator/test/tracer_SUITE.erl new file mode 100644 index 0000000000..812e834562 --- /dev/null +++ b/erts/emulator/test/tracer_SUITE.erl @@ -0,0 +1,627 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2013. 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% +%% + +-module(tracer_SUITE). + +%%% +%%% Tests the tracer module interface +%%% + +-export([all/0, suite/0,groups/0, init_per_suite/1, end_per_suite/1, + init_per_group/2,end_per_group/2, init_per_testcase/2, + end_per_testcase/2]). +-export([load/1, unload/1, reload/1, invalid_tracers/1]). +-export([send/1, recv/1, spawn/1, exit/1, link/1, unlink/1, + getting_linked/1, getting_unlinked/1, register/1, unregister/1, + in/1, out/1, gc_start/1, gc_end/1]). + +suite() -> [{ct_hooks,[ts_install_cth]}, + {timetrap, {minutes, 1}}]. + +all() -> + [load, unload, reload, invalid_tracers, {group, basic}]. + +groups() -> + [{ basic, [], [send, recv, spawn, exit, link, unlink, getting_linked, + getting_unlinked, register, unregister, in, out, + gc_start, gc_end]}]. + +init_per_suite(Config) -> + purge(), + Config. + +end_per_suite(_Config) -> + ok. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + +init_per_testcase(TC, Config) when TC =:= load; TC =:= reload -> + + DataDir = proplists:get_value(data_dir, Config), + + Pid = erlang:spawn(fun F() -> + receive + {get, Pid} -> + Pid ! DataDir, + F() + end + end), + register(tracer_test_config, Pid), + Config; +init_per_testcase(_, Config) -> + DataDir = proplists:get_value(data_dir, Config), + case catch tracer_test:enabled(trace_status, self(), self()) of + discard -> + ok; + _ -> + tracer_test:load(DataDir) + end, + Config. + +end_per_testcase(TC, _Config) when TC =:= load; TC =:= reload -> + purge(), + exit(whereis(tracer_test_config), kill), + ok; +end_per_testcase(_, _Config) -> + purge(), + ok. + +load(_Config) -> + purge(), + 1 = erlang:trace(self(), true, [{tracer, tracer_test, []}, call]), + purge(), + 1 = erlang:trace_pattern({?MODULE, all, 0}, [], + [{meta, tracer_test, []}]), + ok. + +unload(_Config) -> + + ServerFun = fun F(0, undefined) -> + receive + {N, Pid} -> F(N, Pid) + end; + F(0, Pid) -> + Pid ! done, + F(0, undefined); + F(N, Pid) -> + ?MODULE:all(), + F(N-1, Pid) + end, + + Pid = erlang:spawn_link(fun() -> ServerFun(0, undefined) end), + + + Tc = fun(N) -> + Pid ! {N, self()}, + receive done -> ok after 1000 -> ct:fail(timeout) end, + trace_delivered(Pid) + end, + + 1 = erlang:trace(Pid, true, [{tracer, tracer_test, + {#{ call => trace}, self(), []}}, + call]), + 1 = erlang:trace_pattern({?MODULE, all, 0}, [], []), + + Tc(1), + receive _ -> ok after 0 -> ct:fail(timeout) end, + + code:purge(tracer_test), + code:delete(tracer_test), + + Tc(1), + receive M1 -> ct:fail({unexpected_message, M1}) after 0 -> ok end, + + code:purge(tracer_test), + + Tc(1), + receive M2 -> ct:fail({unexpected_message, M2}) after 0 -> ok end, + + ok. + +%% This testcase is here to make sure there are not +%% segfaults when reloading the current nifs. +reload(_Config) -> + + Tracer = spawn_opt(fun F() -> receive _M -> F() end end, + [{message_queue_data, off_heap}]), + erlang:link(Tracer), + Tracee = spawn_link(fun reload_loop/0), + + [begin + Ref = make_ref(), + State = {#{ call => trace }, Tracer, [Ref]}, + erlang:trace(Tracee, true, [{tracer, tracer_test,State}, call]), + erlang:trace_pattern({?MODULE, all, 0}, []), + + false = code:purge(tracer_test), + {module, _} = code:load_file(tracer_test), + + %% There is a race involved in between when the internal nif cache + %% is purged and when the reload_loop needs the tracer module + %% so the tracer may be removed or still there. + case erlang:trace_info(Tracee, tracer) of + {tracer, []} -> ok; + {tracer, {tracer_test, State}} -> ok + end, + + false = code:purge(tracer_test), + true = code:delete(tracer_test), + false = code:purge(tracer_test) + end || _ <- lists:seq(1,15)], + + ok. + +reload_loop() -> + ?MODULE:all(), + reload_loop(). + +invalid_tracers(_Config) -> + FailTrace = fun(A) -> + try erlang:trace(self(), true, A) of + _ -> ct:fail(A) + catch _:_ -> ok end + end, + + FailTrace([{tracer, foobar}, call]), + FailTrace([{tracer, foobar, []}, call]), + FailTrace([{tracer, make_ref(), []}, call]), + FailTrace([{tracer, lists, []}, call]), + + FailTP = fun(MS,FL) -> + try erlang:trace_pattern({?MODULE,all,0}, MS, FL) of + _ -> ct:fail({MS, FL}) + catch _:_ -> ok end + end, + + FailTP([],[{meta, foobar}]), + FailTP([],[{meta, foobar, []}]), + FailTP([],[{meta, make_ref(), []}]), + FailTP([],[{meta, lists, []}]), + + ok. + + + +send(_Config) -> + + Self = self(), + Tc = fun(Pid) -> + Pid ! fun() -> Self ! ok end, + receive ok -> ok after 100 -> ct:fail(timeout) end + end, + + Expect = fun(Pid, State, EOpts) -> + receive + Msg -> + {Pid, send, State, Pid, ok, Self, Opts} = Msg, + check_opts(EOpts, Opts) + end + end, + test(send, Tc, Expect). + + +recv(_Config) -> + + Tc = fun(Pid) -> + Pid ! ok + end, + + Expect = fun(Pid, State, EOpts) -> + receive + Msg -> + {undefined, 'receive', State, Pid, ok, undefined, Opts} = Msg, + check_opts(EOpts, Opts) + end + end, + + test('receive', Tc, Expect, false). + +spawn(_Config) -> + + Tc = fun(Pid) -> + Pid ! fun() -> erlang:spawn(lists,seq,[1,10]), ok end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {Pid, spawn, State, Pid, NewPid, + {lists,seq,[1,10]}, Opts} = Msg, + check_opts(EOpts, Opts), + true = is_pid(NewPid) andalso NewPid /= Pid + end + end, + + test(spawn, procs, Tc, Expect, true). + +exit(_Config) -> + Tc = fun(Pid) -> + Pid ! fun() -> exit end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {Pid, exit, State, Pid, normal, undefined, Opts} = Msg, + check_opts(EOpts, Opts) + end + end, + + test(exit, procs, Tc, Expect, true, true). + +link(_Config) -> + + Tc = fun(Pid) -> + Pid ! fun() -> + SPid = erlang:spawn(fun() -> receive _ -> ok end end), + erlang:link(SPid), + ok + end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {Pid, link, State, Pid, NewPid, undefined, Opts} = Msg, + check_opts(EOpts, Opts), + true = is_pid(NewPid) andalso NewPid /= Pid + end + end, + + test(link, procs, Tc, Expect, true). + +unlink(_Config) -> + + Tc = fun(Pid) -> + Pid ! fun() -> + SPid = erlang:spawn(fun() -> receive _ -> ok end end), + erlang:link(SPid), + erlang:unlink(SPid), + ok + end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {Pid, unlink, State, Pid, NewPid, undefined, Opts} = Msg, + check_opts(EOpts, Opts), + true = is_pid(NewPid) andalso NewPid /= Pid + end + end, + + test(unlink, procs, Tc, Expect, true). + +getting_linked(_Config) -> + + Tc = fun(Pid) -> + Pid ! fun() -> + Self = self(), + erlang:spawn(fun() -> erlang:link(Self) end), + ok + end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {NewPid, getting_linked, State, Pid, NewPid, undefined, Opts} = Msg, + check_opts(EOpts, Opts), + true = is_pid(NewPid) andalso NewPid /= Pid + end + end, + + test(getting_linked, procs, Tc, Expect, false). + +getting_unlinked(_Config) -> + Tc = fun(Pid) -> + Pid ! fun() -> + Self = self(), + erlang:spawn(fun() -> + erlang:link(Self), + erlang:unlink(Self) + end), + ok + end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {NewPid, getting_unlinked, State, Pid, NewPid, undefined, Opts} = Msg, + check_opts(EOpts, Opts), + true = is_pid(NewPid) andalso NewPid /= Pid + end + end, + + test(getting_unlinked, procs, Tc, Expect, false). + +register(_Config) -> + + Tc = fun(Pid) -> + Pid ! fun() -> + erlang:register(?MODULE, self()), + erlang:unregister(?MODULE), + ok + end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {Pid, register, State, Pid, ?MODULE, undefined, Opts} = Msg, + check_opts(EOpts, Opts) + end + end, + + test(register, procs, Tc, Expect, true). + +unregister(_Config) -> + + Tc = fun(Pid) -> + Pid ! fun() -> + erlang:register(?MODULE, self()), + erlang:unregister(?MODULE), + ok + end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {Pid, unregister, State, Pid, ?MODULE, undefined, Opts} = Msg, + check_opts(EOpts, Opts) + end + end, + + test(unregister, procs, Tc, Expect, true). + +in(_Config) -> + + Tc = fun(Pid) -> + Self = self(), + Pid ! fun() -> receive after 1 -> Self ! ok end end, + receive ok -> ok end + end, + + Expect = + fun(Pid, State, EOpts) -> + N = (fun F(N) -> + receive + Msg -> + {Pid, in, State, Pid, _, + undefined, Opts} = Msg, + check_opts(EOpts, Opts), + F(N+1) + after 0 -> N + end + end)(0), + true = N > 0 + end, + + test(in, running, Tc, Expect, true). + +out(_Config) -> + Tc = fun(Pid) -> + Pid ! fun() -> receive after 10 -> exit end end, + Ref = erlang:monitor(process, Pid), + receive {'DOWN', Ref, _, _, _} -> ok end + end, + + Expect = + fun(Pid, State, EOpts) -> + %% We cannot predict how many out schedules there will be + N = (fun F(N) -> + receive + Msg -> + {Pid, out, State, Pid, _, + undefined, Opts} = Msg, + check_opts(EOpts, Opts), + F(N+1) + after 0 -> N + end + end)(0), + true = N > 0 + end, + + test(out, running, Tc, Expect, true, true). + +gc_start(_Config) -> + + Tc = fun(Pid) -> + Pid ! fun() -> + erlang:garbage_collect(), + ok + end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {Pid, gc_start, State, Pid, _, undefined, Opts} = Msg, + check_opts(EOpts, Opts) + end + end, + + test(gc_start, garbage_collection, Tc, Expect, true). + +gc_end(_Config) -> + + Tc = fun(Pid) -> + Pid ! fun() -> + erlang:garbage_collect(), + ok + end + end, + + Expect = + fun(Pid, State, EOpts) -> + receive + Msg -> + {Pid, gc_end, State, Pid, _, undefined, Opts} = Msg, + check_opts(EOpts, Opts) + end + end, + + test(gc_end, garbage_collection, Tc, Expect, true). + +test(Event, Tc, Expect) -> + test(Event, Tc, Expect, true). +test(Event, Tc, Expect, Removes) -> + test(Event, Event, Tc, Expect, Removes). +test(Event, TraceFlag, Tc, Expect, Removes) -> + test(Event, TraceFlag, Tc, Expect, Removes, false). +test(Event, TraceFlag, Tc, Expect, Removes, Dies) -> + + ComplexState = {fun() -> ok end, <<0:(128*8)>>}, + Opts = #{ timestamp => undefined, + scheduler_id => undefined, + match_spec_result => true }, + + %% Test that trace works + State1 = {#{ Event => trace }, self(), ComplexState}, + Pid1 = start_tracee(), + 1 = erlang:trace(Pid1, true, [TraceFlag, {tracer, tracer_test, State1}]), + Tc(Pid1), + ok = trace_delivered(Pid1), + + Expect(Pid1, State1, Opts), + receive M11 -> ct:fail({unexpected, M11}) after 0 -> ok end, + if not Dies -> + {flags, [TraceFlag]} = erlang:trace_info(Pid1, flags), + {tracer, {tracer_test, State1}} = erlang:trace_info(Pid1, tracer), + erlang:trace(Pid1, false, [TraceFlag]); + true -> ok + end, + + %% Test that trace works with scheduler id and timestamp + Pid1T = start_tracee(), + 1 = erlang:trace(Pid1T, true, [TraceFlag, {tracer, tracer_test, State1}, + timestamp, scheduler_id]), + Tc(Pid1T), + ok = trace_delivered(Pid1T), + + Expect(Pid1T, State1, Opts#{ scheduler_id := number, + timestamp := timestamp}), + receive M11T -> ct:fail({unexpected, M11T}) after 0 -> ok end, + if not Dies -> + {flags, [scheduler_id, TraceFlag, timestamp]} + = erlang:trace_info(Pid1T, flags), + {tracer, {tracer_test, State1}} = erlang:trace_info(Pid1T, tracer), + erlang:trace(Pid1T, false, [TraceFlag]); + true -> ok + end, + + %% Test that discard works + Pid2 = start_tracee(), + State2 = {#{ Event => discard }, self(), ComplexState}, + 1 = erlang:trace(Pid2, true, [TraceFlag, {tracer, tracer_test, State2}]), + Tc(Pid2), + ok = trace_delivered(Pid2), + receive M2 -> ct:fail({unexpected, M2}) after 0 -> ok end, + if not Dies -> + {flags, [TraceFlag]} = erlang:trace_info(Pid2, flags), + {tracer, {tracer_test, State2}} = erlang:trace_info(Pid2, tracer), + erlang:trace(Pid2, false, [TraceFlag]); + true -> + ok + end, + + %% Test that remove works + Pid3 = start_tracee(), + State3 = {#{ Event => remove }, self(), ComplexState}, + 1 = erlang:trace(Pid3, true, [TraceFlag, {tracer, tracer_test, State3}]), + Tc(Pid3), + ok = trace_delivered(Pid3), + receive M3 -> ct:fail({unexpected, M3}) after 0 -> ok end, + if not Dies -> + if Removes -> + {flags, []} = erlang:trace_info(Pid3, flags), + {tracer, []} = erlang:trace_info(Pid3, tracer); + true -> + {flags, [TraceFlag]} = erlang:trace_info(Pid3, flags), + {tracer, {tracer_test, State3}} = erlang:trace_info(Pid3, tracer) + end, + erlang:trace(Pid3, false, [TraceFlag]); + true -> + ok + end, + ok. + +check_opts(#{ scheduler_id := number } = E, #{ scheduler_id := N } = O) + when is_integer(N) -> + E1 = maps:remove(scheduler_id, E), + O1 = maps:remove(scheduler_id, O), + if E1 == O1 -> ok; + true -> ct:fail({invalid_opts, E, O}) + end; +check_opts(Opts, Opts) -> + ok; +check_opts(E,O) -> + ct:fail({invalid_opts, E, O}). + +start_tracee() -> + spawn_link( + fun F() -> + receive + Action when is_function(Action) -> + case Action() of + ok -> + F(); + Err -> + Err + end; + _ -> + F() + end + end). + +trace_delivered(Pid) -> + Ref = erlang:trace_delivered(Pid), + receive + {trace_delivered, Pid, Ref} -> + ok + after 1000 -> + timeout + end. + +purge() -> + %% Make sure module is not loaded + case erlang:module_loaded(tracer_test) of + true -> + code:purge(tracer_test), + true = code:delete(tracer_test), + code:purge(tracer_test); + _ -> + ok + end. diff --git a/erts/emulator/test/tracer_SUITE_data/Makefile.src b/erts/emulator/test/tracer_SUITE_data/Makefile.src new file mode 100644 index 0000000000..154bd70ccc --- /dev/null +++ b/erts/emulator/test/tracer_SUITE_data/Makefile.src @@ -0,0 +1,8 @@ + +NIF_LIBS = tracer_test@dll@ + +all: $(NIF_LIBS) + +@SHLIB_RULES@ + +$(NIF_LIBS): tracer_test.c diff --git a/erts/emulator/test/tracer_SUITE_data/tracer_test.c b/erts/emulator/test/tracer_SUITE_data/tracer_test.c new file mode 100644 index 0000000000..8b4be1345d --- /dev/null +++ b/erts/emulator/test/tracer_SUITE_data/tracer_test.c @@ -0,0 +1,122 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2009-2014. 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% + */ + +#include "erl_nif.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <limits.h> + +/* NIF interface declarations */ +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info); +static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info); +static void unload(ErlNifEnv* env, void* priv_data); + +/* The NIFs: */ +static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); + +static ErlNifFunc nif_funcs[] = { + {"enabled", 3, enabled}, + {"trace", 6, trace} +}; + +ERL_NIF_INIT(tracer_test, nif_funcs, load, NULL, upgrade, unload) + +static ERL_NIF_TERM atom_discard; +static ERL_NIF_TERM atom_ok; + +#define ASSERT(expr) assert(expr) + +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) +{ + + atom_discard = enif_make_atom(env, "discard"); + atom_ok = enif_make_atom(env, "ok"); + + *priv_data = NULL; + + return 0; +} + +static void unload(ErlNifEnv* env, void* priv_data) +{ + +} + +static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, + ERL_NIF_TERM load_info) +{ + if (*old_priv_data != NULL) { + return -1; /* Don't know how to do that */ + } + if (*priv_data != NULL) { + return -1; /* Don't know how to do that */ + } + if (load(env, priv_data, load_info)) { + return -1; + } + return 0; +} + +static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + int state_arity; + const ERL_NIF_TERM *state_tuple; + ERL_NIF_TERM value; + ASSERT(argc == 3); + + if (!enif_get_tuple(env, argv[1], &state_arity, &state_tuple)) + return atom_discard; + + if (enif_get_map_value(env, state_tuple[0], argv[0], &value)) { + return value; + } else { + return atom_discard; + } +} + +static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + int state_arity; + ErlNifPid self, to; + ERL_NIF_TERM *tuple, msg; + const ERL_NIF_TERM *state_tuple; + ASSERT(argc == 6); + + enif_get_tuple(env, argv[1], &state_arity, &state_tuple); + + tuple = enif_alloc(sizeof(ERL_NIF_TERM)*(argc+1)); + memcpy(tuple+1,argv,sizeof(ERL_NIF_TERM)*argc); + + if (enif_self(env, &self)) { + tuple[0] = enif_make_pid(env, &self); + } else { + tuple[0] = enif_make_atom(env, "undefined"); + } + + msg = enif_make_tuple_from_array(env, tuple, argc + 1); + enif_get_local_pid(env, state_tuple[1], &to); + enif_send(env, &to, NULL, msg); + enif_free(tuple); + + return atom_ok; +} diff --git a/erts/emulator/test/tracer_test.erl b/erts/emulator/test/tracer_test.erl new file mode 100644 index 0000000000..d4778f4531 --- /dev/null +++ b/erts/emulator/test/tracer_test.erl @@ -0,0 +1,55 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2013. 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% +%% + +-module(tracer_test). + +%%% +%%% Test tracer +%%% + +-export([enabled/3, trace/6]). +-export([load/1, load/2]). +-on_load(load/0). + +enabled(_, _, _) -> + erlang:nif_error(nif_not_loaded). + +trace(_, _, _, _, _, _) -> + erlang:nif_error(nif_not_loaded). + +load() -> + case whereis(tracer_test_config) of + undefined -> + ok; + Pid -> + Pid ! {get, self()}, + receive + {Conf, Postfix} -> + load(Conf, Postfix); + Conf -> + load(Conf) + end + end. + +load(DataDir) -> + load(DataDir, ""). +load(DataDir, Postfix) -> + SoFile = atom_to_list(?MODULE) ++ Postfix, + erlang:load_nif(filename:join(DataDir, SoFile) , 0). diff --git a/erts/emulator/test/tuple_SUITE.erl b/erts/emulator/test/tuple_SUITE.erl index d59d7d12d3..79b681b4d1 100644 --- a/erts/emulator/test/tuple_SUITE.erl +++ b/erts/emulator/test/tuple_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/unique_SUITE.erl b/erts/emulator/test/unique_SUITE.erl index e8537e6152..c5aa80c7b4 100644 --- a/erts/emulator/test/unique_SUITE.erl +++ b/erts/emulator/test/unique_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2014. All Rights Reserved. +%% Copyright Ericsson AB 2014-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/erts/emulator/test/z_SUITE.erl b/erts/emulator/test/z_SUITE.erl index 93a03e8f91..d1085c1958 100644 --- a/erts/emulator/test/z_SUITE.erl +++ b/erts/emulator/test/z_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2011. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. |