diff options
author | Björn Gustavsson <[email protected]> | 2013-03-14 14:54:07 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2013-03-14 14:54:07 +0100 |
commit | 2251b9344c2e5d0ba5d43f89a1ad896c1e67cb0c (patch) | |
tree | 169caa76a1c314684b699a0eb2cdf7581ce76dc4 /lib | |
parent | 59ab7fcb61da503f7a25d6d85fa555b4d9be5f8f (diff) | |
parent | 5f764a80aab1af1bbae170f8819fe3c3393b0cb6 (diff) | |
download | otp-2251b9344c2e5d0ba5d43f89a1ad896c1e67cb0c.tar.gz otp-2251b9344c2e5d0ba5d43f89a1ad896c1e67cb0c.tar.bz2 otp-2251b9344c2e5d0ba5d43f89a1ad896c1e67cb0c.zip |
Merge branch 'maint'
* maint:
[sasl] Fix tests that compare execution time
Prepare release
PER: Ensure that the complete encoding is at least one byte
PER/UPER: Correct decoding of ENUMERATEDs with a single value
[jinterface] Kill process between tests to avoid consequential error
[observer] Extend timer to allow trace msgs to arrive over tcp/ip
[observer] Kill slave node between tests in etop_SUITE
[observer] Accept current function for a process to be 'undefined' on hipe
[observer] Improve measurement of CPU utilization in etop
[observer] Fix non tail-recusive loop when measuring scheduler utilization
[jinterface] Make tests handle space in path on windows
[common_test] Extend timers for slave nodes in ct_cover_SUITE
[test_server] Clean up unused code in test_server_SUITE
[reltool] Increase timetrap timeout for reltool_server_SUTIE to 10 minutes
[test_server] Fix encoding of HTML file references to work on windows
[test_server] Use simpler tc name in unicode test to make it work on windows
Diffstat (limited to 'lib')
24 files changed, 295 insertions, 124 deletions
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml index 4d4600b3ab..e619408591 100644 --- a/lib/asn1/doc/src/notes.xml +++ b/lib/asn1/doc/src/notes.xml @@ -31,6 +31,27 @@ <p>This document describes the changes made to the asn1 application.</p> +<section><title>Asn1 2.0.1.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>The generated decoder for the 'per' and 'uper' + backends did not correctly decode ENUMERATEDs with a + single value.</p> + <p>The generated encoder for the 'per' and 'uper' + backends generated an empty binary for a top-level type + that did not need to be encoded (such as an ENUMERATED + with a single value). The correct result should be a + binary containing a 0 byte.</p> + <p> + Own Id: OTP-10916 Aux Id: seq12270 </p> + </item> + </list> + </section> + +</section> + <section><title>Asn1 2.0.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl index 869bda5d52..4b2c3b1b65 100644 --- a/lib/asn1/src/asn1ct_imm.erl +++ b/lib/asn1/src/asn1ct_imm.erl @@ -61,6 +61,8 @@ optimize_alignment(Imm, Al) -> per_dec_boolean() -> {map,{get_bits,1,[1]},[{0,false},{1,true}]}. +per_dec_enumerated([{V,_}], _Aligned) -> + {value,V}; per_dec_enumerated(NamedList0, Aligned) -> Ub = length(NamedList0) - 1, Constraint = [{'ValueRange',{0,Ub}}], @@ -375,6 +377,8 @@ opt_al({call,Fun,E0}, A0) -> opt_al({convert,Op,E0}, A0) -> {E,A} = opt_al(E0, A0), {{convert,Op,E},A}; +opt_al({value,V}=Term, A) when is_integer(V); is_atom(V) -> + {Term,A}; opt_al({value,E0}, A0) -> {E,A} = opt_al(E0, A0), {{value,E},A}; @@ -391,8 +395,6 @@ opt_al({'case',Cs0}, A0) -> opt_al({map,E0,Cs}, A0) -> {E,A} = opt_al(E0, A0), {{map,E,Cs},A}; -opt_al('NULL'=Null, A) -> - {Null,A}; opt_al(I, A) when is_integer(I) -> {I,A}. @@ -480,8 +482,8 @@ flatten({map,E0,Cs0}, Buf0, St0) -> {Dst,St2} = new_var("Int", St1), Cs = flatten_map_cs(Cs0, E), {{Dst,DstBuf},Pre++[{'map',E,Cs,{Dst,DstBuf}}],St2}; -flatten({value,'NULL'}, Buf0, St0) -> - {{"'NULL'",Buf0},[],St0}; +flatten({value,V}, Buf0, St0) when is_atom(V) -> + {{"'"++atom_to_list(V)++"'",Buf0},[],St0}; flatten({value,V0}, Buf0, St0) when is_integer(V0) -> {{V0,Buf0},[],St0}; flatten({value,V0}, Buf0, St0) -> diff --git a/lib/asn1/src/asn1rtt_per.erl b/lib/asn1/src/asn1rtt_per.erl index 84ff809912..aa6cf4da0a 100644 --- a/lib/asn1/src/asn1rtt_per.erl +++ b/lib/asn1/src/asn1rtt_per.erl @@ -963,7 +963,10 @@ encode_relative_oid(Val) when is_list(Val) -> %% complete(L) -> - asn1rt_nif:encode_per_complete(L). + case asn1rt_nif:encode_per_complete(L) of + <<>> -> <<0>>; + Bin -> Bin + end. octets_to_complete(Len,Val) when Len < 256 -> [20,Len,Val]; diff --git a/lib/asn1/src/asn1rtt_uper.erl b/lib/asn1/src/asn1rtt_uper.erl index ad0678f3c3..8efe9a7b0f 100644 --- a/lib/asn1/src/asn1rtt_uper.erl +++ b/lib/asn1/src/asn1rtt_uper.erl @@ -1016,8 +1016,11 @@ complete(InList) when is_list(InList) -> Bits -> <<Res/bitstring,0:(8-Bits)>> end end; -complete(InList) when is_binary(InList) -> - InList; +complete(Bin) when is_binary(Bin) -> + case Bin of + <<>> -> <<0>>; + _ -> Bin + end; complete(InList) when is_bitstring(InList) -> PadLen = 8 - (bit_size(InList) band 7), <<InList/bitstring,0:PadLen>>. diff --git a/lib/asn1/test/asn1_SUITE_data/Prim.asn1 b/lib/asn1/test/asn1_SUITE_data/Prim.asn1 index 17a5d3490a..c3d54dbbb3 100644 --- a/lib/asn1/test/asn1_SUITE_data/Prim.asn1 +++ b/lib/asn1/test/asn1_SUITE_data/Prim.asn1 @@ -22,6 +22,8 @@ BEGIN Enum ::= ENUMERATED {monday(1),tuesday(2),wednesday(3),thursday(4), friday(5),saturday(6),sunday(7)} + SingleEnumVal ::= ENUMERATED {true} + SingleEnumValExt ::= ENUMERATED {true, ...} ObjId ::= OBJECT IDENTIFIER @@ -35,4 +37,15 @@ BEGIN base (2), exponent (-125..128) } ) + Seq ::= SEQUENCE { + n Null, + i1 INTEGER (0..63), + e1 SingleEnumVal, + i2 INTEGER (0..63), + e2 SingleEnumVal, + i3 INTEGER (0..63), + b Bool, + i4 INTEGER (0..63) + } + END diff --git a/lib/asn1/test/testPrim.erl b/lib/asn1/test/testPrim.erl index 0d4427ba69..91fb9fffca 100644 --- a/lib/asn1/test/testPrim.erl +++ b/lib/asn1/test/testPrim.erl @@ -513,6 +513,14 @@ enum(Rules) -> case catch asn1_wrapper:encode('Prim','Enum',4) of Enum -> Enum end, ok end, + + case Rules of + Per when Per =:= per; Per =:= uper -> + {ok,<<0>>} = 'Prim':encode('SingleEnumVal', true), + {ok,<<0>>} = 'Prim':encode('SingleEnumValExt', true); + ber -> + ok + end, ok. diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk index aaa060c806..3c4f3ff122 100644 --- a/lib/asn1/vsn.mk +++ b/lib/asn1/vsn.mk @@ -1,2 +1,2 @@ #next version number to use is 2.0 -ASN1_VSN = 2.0.1 +ASN1_VSN = 2.0.1.1 diff --git a/lib/common_test/test/ct_cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE.erl index cb49dc423f..ec2680f664 100644 --- a/lib/common_test/test/ct_cover_SUITE.erl +++ b/lib/common_test/test/ct_cover_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012. All Rights Reserved. +%% Copyright Ericsson AB 2012-2013. 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 @@ -59,10 +59,8 @@ init_per_testcase(TestCase, Config) -> ct_test_support:init_per_testcase(TestCase, Config). end_per_testcase(TestCase, Config) -> - Node = fullname(existing_node), - case lists:member(Node,nodes()) of - true -> rpc:call(Node,erlang,halt,[]); - false -> ok + try apply(?MODULE,TestCase,[cleanup,Config]) + catch error:undef -> ok end, ct_test_support:end_per_testcase(TestCase, Config). @@ -125,33 +123,35 @@ slave_start_slave(Config) -> %% spec file. %% Check that cover is collected from test node and slave node. cover_node_option(Config) -> - {ok, HostStr}=inet:gethostname(), - Host = list_to_atom(HostStr), DataDir = ?config(data_dir,Config), - {ok,Node} = ct_slave:start(Host,existing_node, - [{erl_flags,"-pa " ++ DataDir}]), + {ok,Node} = start_slave(existing_node_1, "-pa " ++ DataDir), false = check_cover(Node), CoverSpec = default_cover_file_content() ++ [{nodes,[Node]}], CoverFile = create_cover_file(cover_node_option,CoverSpec,Config), {ok,Events} = run_test(cover_node_option,cover_node_option, [{cover,CoverFile}],Config), check_calls(Events,2), - {ok,Node} = ct_slave:stop(existing_node), + {ok,Node} = ct_slave:stop(existing_node_1), + ok. + +cover_node_option(cleanup,_Config) -> + _ = ct_slave:stop(existing_node_1), ok. %% Test ct_cover:add_nodes/1 and ct_cover:remove_nodes/1 %% Check that cover is collected from added node ct_cover_add_remove_nodes(Config) -> - {ok, HostStr}=inet:gethostname(), - Host = list_to_atom(HostStr), DataDir = ?config(data_dir,Config), - {ok,Node} = ct_slave:start(Host,existing_node, - [{erl_flags,"-pa " ++ DataDir}]), + {ok,Node} = start_slave(existing_node_2, "-pa " ++ DataDir), false = check_cover(Node), {ok,Events} = run_test(ct_cover_add_remove_nodes,ct_cover_add_remove_nodes, [],Config), check_calls(Events,2), - {ok,Node} = ct_slave:stop(existing_node), + {ok,Node} = ct_slave:stop(existing_node_2), + ok. + +ct_cover_add_remove_nodes(cleanup,_Config) -> + _ = ct_slave:stop(existing_node_2), ok. %% Test that the test suite itself can be cover compiled and that @@ -310,3 +310,12 @@ create_cover_file(Filename,Terms,Config) -> end,Terms), ok = file:close(Fd), File. + +start_slave(Name,Args) -> + {ok, HostStr}=inet:gethostname(), + Host = list_to_atom(HostStr), + ct_slave:start(Host,Name, + [{erl_flags,Args}, + {boot_timeout,10}, % extending some timers for slow test hosts + {init_timeout,10}, + {startup_timeout,10}]). diff --git a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl index fdc3323f0a..d967590c72 100644 --- a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl +++ b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012. All Rights Reserved. +%% Copyright Ericsson AB 2012-2013. 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 @@ -76,7 +76,7 @@ slave(Config) -> cover_compiled = code:which(cover_test_mod), cover_test_mod:foo(), N1 = nodename(slave,1), - {ok,Node} = ct_slave:start(N1), + {ok,Node} = start_slave(N1), cover_compiled = rpc:call(Node,code,which,[cover_test_mod]), rpc:call(Node,cover_test_mod,foo,[]), {ok,Node} = ct_slave:stop(N1), @@ -87,7 +87,7 @@ slave_start_slave(Config) -> cover_test_mod:foo(), N1 = nodename(slave_start_slave,1), N2 = nodename(slave_start_slave,2), - {ok,Node} = ct_slave:start(N1), + {ok,Node} = start_slave(N1), cover_compiled = rpc:call(Node,code,which,[cover_test_mod]), rpc:call(Node,cover_test_mod,foo,[]), {ok,Node2} = rpc:call(Node,ct_slave,start,[N2]), @@ -99,7 +99,7 @@ slave_start_slave(Config) -> cover_node_option(Config) -> cover_compiled = code:which(cover_test_mod), cover_test_mod:foo(), - Node = fullname(existing_node), + Node = fullname(existing_node_1), cover_compiled = rpc:call(Node,code,which,[cover_test_mod]), rpc:call(Node,cover_test_mod,foo,[]), ok. @@ -107,7 +107,7 @@ cover_node_option(Config) -> ct_cover_add_remove_nodes(Config) -> cover_compiled = code:which(cover_test_mod), cover_test_mod:foo(), - Node = fullname(existing_node), + Node = fullname(existing_node_2), Beam = rpc:call(Node,code,which,[cover_test_mod]), false = (Beam == cover_compiled), @@ -154,3 +154,11 @@ kill_slaves(Case, [Node|Nodes]) -> kill_slaves(Case,Nodes); kill_slaves(_,[]) -> ok. + +start_slave(Name) -> + {ok, HostStr}=inet:gethostname(), + Host = list_to_atom(HostStr), + ct_slave:start(Host,Name, + [{boot_timeout,10}, % extending some timers for slow test hosts + {init_timeout,10}, + {startup_timeout,10}]). diff --git a/lib/jinterface/test/jinterface_SUITE.erl b/lib/jinterface/test/jinterface_SUITE.erl index 82bc878112..b438da12d0 100644 --- a/lib/jinterface/test/jinterface_SUITE.erl +++ b/lib/jinterface/test/jinterface_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2013. 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 @@ -184,6 +184,10 @@ init_per_testcase(_Case,Config) -> [{watch_dog,Dog}|Config]. end_per_testcase(_Case,Config) -> + case whereis(erl_link_server) of + undefined -> ok; + Pid -> exit(Pid,kill) + end, ?t:timetrap_cancel(?config(watch_dog,Config)), ok. diff --git a/lib/jinterface/test/jitu.erl b/lib/jinterface/test/jitu.erl index 571a2dc9c7..0e1af0ff22 100644 --- a/lib/jinterface/test/jitu.erl +++ b/lib/jinterface/test/jitu.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2012. All Rights Reserved. +%% Copyright Ericsson AB 2004-2013. 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 @@ -48,7 +48,7 @@ java(Java, Dir, Class, Args, Props) -> -init_all(Config) when list(Config) -> +init_all(Config) when is_list(Config) -> case find_executable(["java"]) of false -> {skip,"Found no Java VM"}; Path -> [{java,Path}|Config] @@ -69,13 +69,13 @@ find_executable([E|T]) -> Path -> Path end. -to_string([H|T]) when integer(H) -> +to_string([H|T]) when is_integer(H) -> integer_to_list(H)++" "++to_string(T); -to_string([H|T]) when atom(H) -> +to_string([H|T]) when is_atom(H) -> atom_to_list(H)++" "++to_string(T); -to_string([H|T]) when pid(H) -> +to_string([H|T]) when is_pid(H) -> pid_to_list(H)++" "++to_string(T); -to_string([H|T]) when list(H) -> +to_string([H|T]) when is_list(H) -> lists:flatten(H)++" "++to_string(T); to_string([]) -> []. @@ -84,35 +84,37 @@ to_string([]) -> []. % filename:join(Dir, File)). classpath(Dir) -> - PS = + {PS,Quote,EscSpace} = case os:type() of - {win32, _} -> ";"; - _ -> ":" + {win32, _} -> {";","\"",""}; + _ -> {":","","\\"} end, es(Dir++PS++ filename:join([code:lib_dir(jinterface),"priv","OtpErlang.jar"])++PS++ case os:getenv("CLASSPATH") of false -> ""; Classpath -> Classpath - end). + end, + Quote, + EscSpace). -es(L) -> - lists:flatmap(fun($ ) -> - "\\ "; - (C) -> - [C] - end,lists:flatten(L)). +es(L,Quote,EscSpace) -> + Quote++lists:flatmap(fun($ ) -> + EscSpace++" "; + (C) -> + [C] + end,lists:flatten(L)) ++ Quote. cmd(Cmd) -> PortOpts = [{line,80},eof,exit_status,stderr_to_stdout], io:format("cmd: ~s~n", [Cmd]), case catch open_port({spawn,Cmd}, PortOpts) of - Port when port(Port) -> + Port when is_port(Port) -> Result = cmd_loop(Port, []), io:format("cmd res: ~w~n", [Result]), case Result of 0 -> ok; - ExitCode when integer(ExitCode) -> {error,ExitCode}; + ExitCode when is_integer(ExitCode) -> {error,ExitCode}; Error -> Error end; {'EXIT',Reason} -> diff --git a/lib/observer/src/etop.erl b/lib/observer/src/etop.erl index 428757e5ce..2610060eae 100644 --- a/lib/observer/src/etop.erl +++ b/lib/observer/src/etop.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2012. All Rights Reserved. +%% Copyright Ericsson AB 2002-2013. 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 @@ -325,13 +325,40 @@ loadinfo(SysI) -> #etop_info{n_procs = Procs, run_queue = RQ, now = Now, - wall_clock = {_, WC}, - runtime = {_, RT}} = SysI, - Cpu = round(100*RT/WC), + wall_clock = WC, + runtime = RT} = SysI, + Cpu = calculate_cpu_utilization(WC,RT), Clock = io_lib:format("~2.2.0w:~2.2.0w:~2.2.0w", tuple_to_list(element(2,calendar:now_to_datetime(Now)))), {Cpu,Procs,RQ,Clock}. +calculate_cpu_utilization({_,WC},{_,RT}) -> + %% Old version of observer_backend, using statistics(wall_clock) + %% and statistics(runtime) + case {WC,RT} of + {0,0} -> + 0; + {0,_} -> + 100; + _ -> + round(100*RT/WC) + end; +calculate_cpu_utilization(_,undefined) -> + %% First time collecting - no cpu utilization has been measured + %% since scheduler_wall_time flag is not yet on + 0; +calculate_cpu_utilization(_,RTInfo) -> + %% New version of observer_backend, using statistics(scheduler_wall_time) + Sum = lists:foldl(fun({_,A,T},{AAcc,TAcc}) -> {A+AAcc,T+TAcc} end, + {0,0}, + RTInfo), + case Sum of + {0,0} -> + 0; + {Active,Total} -> + round(100*Active/Total) + end. + meminfo(MemI, [Tag|Tags]) -> [round(get_mem(Tag, MemI)/1024)|meminfo(MemI, Tags)]; meminfo(_MemI, []) -> []. diff --git a/lib/observer/src/etop_gui.erl b/lib/observer/src/etop_gui.erl index f5cc0deb38..3971646abc 100644 --- a/lib/observer/src/etop_gui.erl +++ b/lib/observer/src/etop_gui.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2012. All Rights Reserved. +%% Copyright Ericsson AB 2002-2013. 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 @@ -276,7 +276,12 @@ clear_lines(From, To, Grid) -> end. formatmfa({M, F, A}) -> - io_lib:format("~w:~w/~w",[M, F, A]). + io_lib:format("~w:~w/~w",[M, F, A]); +formatmfa(Other) -> + %% E.g. when running hipe - the current_function for some + %% processes will be 'undefined' + io_lib:format("~w",[Other]). + makegridlines([#etop_proc_info{pid=Pid, mem=Mem, diff --git a/lib/observer/test/etop_SUITE.erl b/lib/observer/test/etop_SUITE.erl index 06577f82cc..6ce3ea59cf 100644 --- a/lib/observer/test/etop_SUITE.erl +++ b/lib/observer/test/etop_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2012. All Rights Reserved. +%% Copyright Ericsson AB 2002-2013. 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 @@ -21,7 +21,8 @@ %% Test functions -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2,text/1,text_tracing_off/1]). + init_per_group/2,end_per_group/2]). +-export([text/1,text/2,text_tracing_off/1,text_tracing_off/2]). -export([init_per_testcase/2, end_per_testcase/2]). -include_lib("test_server/include/test_server.hrl"). @@ -31,7 +32,10 @@ init_per_testcase(_Case, Config) -> ?line Dog=test_server:timetrap(?default_timeout), [{watchdog, Dog}|Config]. -end_per_testcase(_Case, Config) -> +end_per_testcase(Case, Config) -> + try apply(?MODULE,Case,[cleanup,Config]) + catch error:undef -> ok + end, Dog=?config(watchdog, Config), ?t:timetrap_cancel(Dog), ok. @@ -82,9 +86,12 @@ text() -> ?line timer:sleep(3000), ?line etop:config(sort,msg_q), ?line timer:sleep(3000), - ?line etop:stop(), - ?line ?t:stop_node(Node), ok. +text(cleanup,_Config) -> + etop:stop(), + {ok,Host} = inet:gethostname(), + Node = list_to_atom("node2@"++Host), + ?t:stop_node(Node). text_tracing_off(suite) -> []; @@ -111,7 +118,10 @@ text_tracing_off(Config) when is_list(Config) -> ?line timer:sleep(3000), ?line etop:config(sort,runtime), % this should not crash, but has no effect ?line timer:sleep(3000), - ?line etop:stop(), - ?line ?t:stop_node(Node), ok. +text_tracing_off(cleanup,_Config) -> + etop:stop(), + {ok,Host} = inet:gethostname(), + Node = list_to_atom("node2@"++Host), + ?t:stop_node(Node). diff --git a/lib/observer/test/ttb_SUITE.erl b/lib/observer/test/ttb_SUITE.erl index 695d41b48a..f3fcd9f283 100644 --- a/lib/observer/test/ttb_SUITE.erl +++ b/lib/observer/test/ttb_SUITE.erl @@ -1,7 +1,8 @@ +%% %% %CopyrightBegin% %% %% -%% Copyright Ericsson AB 2002-2010. All Rights Reserved. +%% Copyright Ericsson AB 2002-2013. 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 @@ -57,7 +58,7 @@ init_per_testcase(Case, Config) -> catch error:undef -> ok end, [{watchdog, Dog}|Config]. -end_per_testcase(Case, Config) -> +end_per_testcase(_Case, Config) -> %% try apply(?MODULE,Case,[cleanup,Config]) %% catch error:undef -> ok %% end, diff --git a/lib/observer/test/ttb_helper.erl b/lib/observer/test/ttb_helper.erl index 76b06cd3ce..05f6d73aef 100644 --- a/lib/observer/test/ttb_helper.erl +++ b/lib/observer/test/ttb_helper.erl @@ -70,7 +70,7 @@ msgs(N) -> msgs_ip(N) -> [c(client, put, [test_msg]) || _ <- lists:seq(1, N)], s(server, received, [a,b]), - timer:sleep(200). %% allow trace messages to arrive over tcp/ip + timer:sleep(500). %% allow trace messages to arrive over tcp/ip run() -> ttb({local, "A"}), diff --git a/lib/reltool/test/reltool_test_lib.erl b/lib/reltool/test/reltool_test_lib.erl index 61f783190c..3485365ed9 100644 --- a/lib/reltool/test/reltool_test_lib.erl +++ b/lib/reltool/test/reltool_test_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. 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 @@ -25,7 +25,7 @@ init_per_suite(Config) when is_list(Config)-> global:register_name(reltool_global_logger, group_leader()), - incr_timetrap(Config, 5). + incr_timetrap(Config, 10). end_per_suite(Config) when is_list(Config)-> global:unregister_name(reltool_global_logger), @@ -51,7 +51,7 @@ set_kill_timer(Config) -> Time = case lookup_config(tc_timeout, Config) of [] -> - timer:minutes(5); + timer:minutes(10); ConfigTime when is_integer(ConfigTime) -> ConfigTime end, diff --git a/lib/runtime_tools/include/observer_backend.hrl b/lib/runtime_tools/include/observer_backend.hrl index 4be9baca5b..91647a4468 100644 --- a/lib/runtime_tools/include/observer_backend.hrl +++ b/lib/runtime_tools/include/observer_backend.hrl @@ -1,26 +1,27 @@ -%% ``The contents of this file are subject to the Erlang Public License, +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-2013. 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 %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% +%% retrieved online at http://www.erlang.org/. +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights 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$ +%% +%% %CopyrightEnd% %% -record(etop_info, {now = {0, 0, 0}, n_procs = 0, - wall_clock = {0, 0}, - runtime = {0, 0}, + wall_clock, + runtime, run_queue = 0, alloc_areas = [], memi = [{total, 0}, diff --git a/lib/runtime_tools/src/observer_backend.erl b/lib/runtime_tools/src/observer_backend.erl index 9498412505..d1d291d5cb 100644 --- a/lib/runtime_tools/src/observer_backend.erl +++ b/lib/runtime_tools/src/observer_backend.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2012. All Rights Reserved. +%% Copyright Ericsson AB 2002-2013. 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 @@ -199,34 +199,57 @@ get_table_list(mnesia, Opts) -> lists:foldl(Info, [], mnesia:system_info(tables)). fetch_stats(Parent, Time) -> - erlang:system_flag(scheduler_wall_time, true), process_flag(trap_exit, true), - fetch_stats_loop(Parent, Time), - erlang:system_flag(scheduler_wall_time, false). + fetch_stats_loop(Parent, Time). fetch_stats_loop(Parent, Time) -> + erlang:system_flag(scheduler_wall_time, true), receive - _Msg -> normal + _Msg -> erlang:system_flag(scheduler_wall_time, false) after Time -> _M = Parent ! {stats, 1, erlang:statistics(scheduler_wall_time), erlang:statistics(io), erlang:memory()}, - fetch_stats(Parent, Time) + fetch_stats_loop(Parent, Time) end. %% %% etop backend %% etop_collect(Collector) -> + %% If this is the first time and the scheduler_wall_time flag is + %% false, SchedulerWallTime will be 'undefined' (and show 0 cpu + %% utilization in etop). Next time the flag will be true and then + %% there will be a measurement. + SchedulerWallTime = erlang:statistics(scheduler_wall_time), + + %% Turn off the flag while collecting data per process etc. + case erlang:system_flag(scheduler_wall_time,false) of + false -> + %% First time and the flag was false - start a monitoring + %% process to set the flag back to false when etop is stopped. + spawn(fun() -> flag_holder_proc(Collector) end); + _ -> + ok + end, + ProcInfo = etop_collect(processes(), []), + Collector ! {self(),#etop_info{now = now(), n_procs = length(ProcInfo), run_queue = erlang:statistics(run_queue), - wall_clock = erlang:statistics(wall_clock), - runtime = erlang:statistics(runtime), + runtime = SchedulerWallTime, memi = etop_memi(), procinfo = ProcInfo - }}. + }}, + erlang:system_flag(scheduler_wall_time,true). + +flag_holder_proc(Collector) -> + Ref = erlang:monitor(process,Collector), + receive + {'DOWN',Ref,_,_,_} -> + erlang:system_flag(scheduler_wall_time,false) + end. etop_memi() -> try diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl index 82b7a738bb..97ba70c9bd 100644 --- a/lib/sasl/test/release_handler_SUITE.erl +++ b/lib/sasl/test/release_handler_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2012. All Rights Reserved. +%% Copyright Ericsson AB 2011-2013. 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 @@ -1094,9 +1094,11 @@ otp_9395_update_many_mods(Conf) when is_list(Conf) -> [RelVsn2, filename:join(Rel2Dir, "sys.config")]), %% First, install release directly and check how much time it takes + rpc:call(Node,erlang,system_flag,[scheduler_wall_time,true]), {TInst0,{ok, _, []}} = timer:tc(rpc,call,[Node, release_handler, install_release, [RelVsn2]]), - ct:log("install_release: ~.2f",[TInst0/1000000]), + SWT0 = rpc:call(Node,erlang,statistics,[scheduler_wall_time]), +% ct:log("install_release: ~.2f",[TInst0/1000000]), %% Restore to old release, spawn processes again and load to get old code {_,RelVsn1} = init:script_id(), @@ -1113,15 +1115,32 @@ otp_9395_update_many_mods(Conf) when is_list(Conf) -> {TCheck,{ok, _RelVsn1, []}} = timer:tc(rpc,call,[Node, release_handler, check_install_release, [RelVsn2,[purge]]]), - ct:log("check_install_release with purge: ~.2f",[TCheck/1000000]), +% ct:log("check_install_release with purge: ~.2f",[TCheck/1000000]), %% Finally install release after check and purge, and check that %% this install was faster than the first. + rpc:call(Node,erlang,system_flag,[scheduler_wall_time,false]), + rpc:call(Node,erlang,system_flag,[scheduler_wall_time,true]), {TInst2,{ok, _RelVsn1, []}} = timer:tc(rpc,call,[Node, release_handler, install_release, [RelVsn2]]), - ct:log("install_release: ~.2f",[TInst2/1000000]), - - true = (TInst2 < TInst0), + SWT2 = rpc:call(Node,erlang,statistics,[scheduler_wall_time]), +% ct:log("install_release: ~.2f",[TInst2/1000000]), + + %% Calculate and print real time and CPU utilization + SumFun = fun({_,A,T},{AAcc,TAcc}) -> {A+AAcc,T+TAcc} end, + {SumA0,SumT0} = lists:foldl(SumFun,{0,0},SWT0), + {SumA2,SumT2} = lists:foldl(SumFun,{0,0},SWT2), + TI0=TInst0/1000000, + TI2=TInst2/1000000, + CPU0=SumA0/SumT0, + CPU2=SumA2/SumT2, + X0 = TI0*CPU0, + X2 = TI2*CPU2, + ct:log("First run: T=~.2fsec, CPU=~.2f, T*CPU=~.2f~n" + "Second run: T=~.2fsec, CPU=~.2f, T*CPU=~.2f~n", + [TI0, CPU0, X0, TI2, CPU2, X2]), + + true = (X2 =< X0), % disregarding wait time for file access etc. ok. @@ -1172,9 +1191,11 @@ otp_9395_rm_many_mods(Conf) when is_list(Conf) -> [RelVsn2, filename:join(Rel2Dir, "sys.config")]), %% First, install release directly and check how much time it takes + rpc:call(Node,erlang,system_flag,[scheduler_wall_time,true]), {TInst0,{ok, _, []}} = timer:tc(rpc,call,[Node, release_handler, install_release, [RelVsn2]]), - ct:log("install_release: ~.2f",[TInst0/1000000]), + SWT0 = rpc:call(Node,erlang,statistics,[scheduler_wall_time]), +% ct:log("install_release: ~.2f",[TInst0/1000000]), %% Restore to old release, spawn processes again and load to get old code {_,RelVsn1} = init:script_id(), @@ -1191,15 +1212,32 @@ otp_9395_rm_many_mods(Conf) when is_list(Conf) -> {TCheck,{ok, _RelVsn1, []}} = timer:tc(rpc,call,[Node, release_handler, check_install_release, [RelVsn2,[purge]]]), - ct:log("check_install_release with purge: ~.2f",[TCheck/1000000]), +% ct:log("check_install_release with purge: ~.2f",[TCheck/1000000]), %% Finally install release after check and purge, and check that %% this install was faster than the first. + rpc:call(Node,erlang,system_flag,[scheduler_wall_time,false]), + rpc:call(Node,erlang,system_flag,[scheduler_wall_time,true]), {TInst2,{ok, _RelVsn1, []}} = timer:tc(rpc,call,[Node, release_handler, install_release, [RelVsn2]]), - ct:log("install_release: ~.2f",[TInst2/1000000]), - - true = (TInst2 =< TInst0), + SWT2 = rpc:call(Node,erlang,statistics,[scheduler_wall_time]), +% ct:log("install_release: ~.2f",[TInst2/1000000]), + + %% Calculate and print real time and CPU utilization + SumFun = fun({_,A,T},{AAcc,TAcc}) -> {A+AAcc,T+TAcc} end, + {SumA0,SumT0} = lists:foldl(SumFun,{0,0},SWT0), + {SumA2,SumT2} = lists:foldl(SumFun,{0,0},SWT2), + TI0=TInst0/1000000, + TI2=TInst2/1000000, + CPU0=SumA0/SumT0, + CPU2=SumA2/SumT2, + X0 = TI0*CPU0, + X2 = TI2*CPU2, + ct:log("First run: T=~.2fsec, CPU=~.2f, T*CPU=~.2f~n" + "Second run: T=~.2fsec, CPU=~.2f, T*CPU=~.2f~n", + [TI0, CPU0, X0, TI2, CPU2, X2]), + + true = (X2 =< X0), % disregarding wait time for file access etc. ok. diff --git a/lib/test_server/src/erl2html2.erl b/lib/test_server/src/erl2html2.erl index 9c0ca64173..5584c1e50c 100644 --- a/lib/test_server/src/erl2html2.erl +++ b/lib/test_server/src/erl2html2.erl @@ -126,7 +126,7 @@ build_html(SFd,DFd,Encoding,Functions) -> build_html(SFd,DFd,Encoding,file:read_line(SFd),1,Functions,false). build_html(SFd,DFd,Encoding,{ok,Str},L,[{F,A,L}|Functions],_IsFuncDef) -> - FALink = http_uri:encode(F++"-"++integer_to_list(A)), + FALink = test_server_ctrl:uri_encode(F++"-"++integer_to_list(A),utf8), file:write(DFd,["<a name=\"",to_raw_list(FALink,Encoding),"\"/>"]), build_html(SFd,DFd,Encoding,{ok,Str},L,Functions,true); build_html(SFd,DFd,Encoding,{ok,Str},L,[{clause,L}|Functions],_IsFuncDef) -> diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index a5216571c7..21c10adccb 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -5326,31 +5326,28 @@ uri_encode(File,Encoding) -> Components = filename:split(File), filename:join([uri_encode_comp(C,Encoding) || C <- Components]). -uri_encode_comp("/",_) -> - "/"; -uri_encode_comp(Chars,utf8) -> - http_uri:encode(Chars); -uri_encode_comp(Chars,latin1) -> - do_uri_encode(Chars). - -%% Encode a file reference to a latin1 filename so it can be inserted -%% in a utf8 encoded HTML file. -%% This does the same as http_uri:encode/1, except it also encodes all -%% characters >127 - i.e. latin1 but not ASCII. -do_uri_encode([Char|Chars]) -> - case Char>127 orelse sets:is_element(Char, reserved()) of +%% Encode the reference to a "filename of the given encoding" so it +%% can be inserted in a utf8 encoded HTML file. +%% This does almost the same as http_uri:encode/1, except +%% 1. it does not convert @, : and / (in order to preserve nodename and c:/) +%% 2. if the file name is in latin1, it also encodes all +%% characters >127 - i.e. latin1 but not ASCII. +uri_encode_comp([Char|Chars],Encoding) -> + Reserved = sets:is_element(Char, reserved()), + case (Char>127 andalso Encoding==latin1) orelse Reserved of true -> - [ $% | http_util:integer_to_hexlist(Char)] ++ do_uri_encode(Chars); + [ $% | http_util:integer_to_hexlist(Char)] ++ + uri_encode_comp(Chars,Encoding); false -> - [Char | do_uri_encode(Chars)] + [Char | uri_encode_comp(Chars,Encoding)] end; -do_uri_encode([]) -> +uri_encode_comp([],_) -> []. %% Copied from http_uri.erl, but slightly modified -%% (not converting @ and :) +%% (not converting @, : and /) reserved() -> - sets:from_list([$;, $&, $=, $+, $,, $/, $?, + sets:from_list([$;, $&, $=, $+, $,, $?, $#, $[, $], $<, $>, $\", ${, $}, $|, $\\, $', $^, $%, $ ]). diff --git a/lib/test_server/test/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE.erl index bea2c0dc49..1a2fc632da 100644 --- a/lib/test_server/test/test_server_SUITE.erl +++ b/lib/test_server/test/test_server_SUITE.erl @@ -323,11 +323,7 @@ generate_and_run_unicode_test(Config0,Encoding) -> Config1 = lists:keydelete(node,1,Config0), Config2 = lists:keydelete(work_dir,1,Config1), NodeName = list_to_atom("test_server_tester_" ++ atom_to_list(Encoding)), - ErtsSwitch = case Encoding of - latin1 -> "+fnl"; - utf8 -> "+fnu" - end, - Config = start_node(Config2,NodeName,ErtsSwitch), + Config = start_node(Config2,NodeName,erts_switch(Encoding)), %% Compile the suite Node = proplists:get_value(node,Config), diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl index 662adedd4c..284b51babe 100644 --- a/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl +++ b/lib/test_server/test/test_server_SUITE_data/test_server_unicode_SUITE.erl @@ -21,14 +21,14 @@ -export([all/1, init_per_suite/1, end_per_suite/1]). -export([init_per_testcase/2, end_per_testcase/2]). --export([':#"|@\\ difficult_case_name_äöå'/1, +-export(['#=@: difficult_case_name_äöå'/1, print_and_log_unicode/1, print_and_log_latin1/1]). -include_lib("test_server/include/test_server.hrl"). all(suite) -> - [':#"|@\\ difficult_case_name_äöå', + ['#=@: difficult_case_name_äöå', print_and_log_unicode, print_and_log_latin1]. @@ -57,7 +57,7 @@ cancel_timetrap(Config) -> %%%----------------------------------------------------------------- %%% Test cases -':#"|@\\ difficult_case_name_äöå'(Config) when is_list(Config) -> +'#=@: difficult_case_name_äöå'(Config) when is_list(Config) -> ok. print_and_log_unicode(Config) when is_list(Config) -> |