%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2001-2009. 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 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. %% %% %CopyrightEnd% %% %% -module(inets_test_lib). -include("inets_test_lib.hrl"). %% Various small utility functions -export([start_http_server/1, start_http_server_ssl/1]). -export([hostname/0]). -export([connect_bin/3, connect_byte/3, send/3, close/2]). -export([copy_file/3, copy_files/2, copy_dirs/2, del_dirs/1]). -export([info/4, log/4, debug/4, print/4]). -export([check_body/1]). -export([millis/0, millis_diff/2, hours/1, minutes/1, seconds/1, sleep/1]). -export([non_pc_tc_maybe_skip/4, os_based_skip/1]). start_http_server(Conf) -> application:load(inets), ok = application:set_env(inets, services, [{httpd, Conf}]), ok = application:start(inets). start_http_server_ssl(FileName) -> application:start(ssl), catch start_http_server(FileName). %% ---------------------------------------------------------------------- %% print functions %% info(F, A, Mod, Line) -> print("INF ", F, A, Mod, Line). log(F, A, Mod, Line) -> print("LOG ", F, A, Mod, Line). debug(F, A, Mod, Line) -> print("DBG ", F, A, Mod, Line). print(P, F, A, Mod, Line) -> io:format("~s[~p:~p:~p] : " ++ F ++ "~n", [P, self(), Mod, Line| A]). print(F, A, Mod, Line) -> print("", F, A, Mod, Line). hostname() -> from($@, atom_to_list(node())). from(H, [H | T]) -> T; from(H, [_ | T]) -> from(H, T); from(_, []) -> []. copy_file(File, From, To) -> file:copy(filename:join(From, File), filename:join(To, File)). copy_files(FromDir, ToDir) -> {ok, Files} = file:list_dir(FromDir), lists:foreach(fun(File) -> FullPath = filename:join(FromDir, File), case filelib:is_file(FullPath) of true -> file:copy(FullPath, filename:join(ToDir, File)); false -> ok end end, Files). copy_dirs(FromDirRoot, ToDirRoot) -> %% io:format("~w:copy_dirs -> entry with" %% "~n FromDirRoot: ~p" %% "~n ToDirRoot: ~p" %% "~n", [?MODULE, FromDirRoot, ToDirRoot]), {ok, Files} = file:list_dir(FromDirRoot), lists:foreach( fun(FileOrDir) -> %% Check if it's a directory or a file %% io:format("~w:copy_dirs -> check ~p" %% "~n", [?MODULE, FileOrDir]), case filelib:is_dir(filename:join(FromDirRoot, FileOrDir)) of true -> %% io:format("~w:copy_dirs -> ~p is a directory" %% "~n", [?MODULE, FileOrDir]), FromDir = filename:join([FromDirRoot, FileOrDir]), ToDir = filename:join([ToDirRoot, FileOrDir]), ok = file:make_dir(ToDir), copy_dirs(FromDir, ToDir); false -> %% io:format("~w:copy_dirs -> ~p is a file" %% "~n", [?MODULE, FileOrDir]), copy_file(FileOrDir, FromDirRoot, ToDirRoot) end end, Files). del_dirs(Dir) -> case file:list_dir(Dir) of {ok, []} -> file:del_dir(Dir); {ok, Files} -> lists:foreach(fun(File) -> FullPath = filename:join(Dir,File), case filelib:is_dir(FullPath) of true -> del_dirs(FullPath), file:del_dir(FullPath); false -> file:delete(FullPath) end end, Files); _ -> ok end. check_body(Body) -> case string:rstr(Body, "") of 0 -> case string:rstr(Body, "") of 0 -> test_server:format("Body ~p~n", [Body]), test_server:fail(did_not_receive_whole_body); _ -> ok end; _ -> ok end. %% ---------------------------------------------------------------- %% Conditional skip of testcases %% non_pc_tc_maybe_skip(Config, Condition, File, Line) when is_list(Config) andalso is_function(Condition) -> %% Check if we shall skip the skip case os:getenv("TS_OS_BASED_SKIP") of "false" -> ok; _ -> case lists:keysearch(ts, 1, Config) of {value, {ts, inets}} -> %% Always run the testcase if we are using our own %% test-server... ok; _ -> case (catch Condition()) of true -> skip(non_pc_testcase, File, Line); _ -> ok end end end. os_based_skip(any) -> true; os_based_skip(Skippable) when is_list(Skippable) -> {OsFam, OsName} = case os:type() of {_Fam, _Name} = FamAndName -> FamAndName; Fam -> {Fam, undefined} end, case lists:member(OsFam, Skippable) of true -> true; false -> case lists:keysearch(OsFam, 1, Skippable) of {value, {OsFam, OsName}} -> true; {value, {OsFam, OsNames}} when is_list(OsNames) -> lists:member(OsName, OsNames); _ -> false end end; os_based_skip(_) -> false. %% ---------------------------------------------------------------------- %% Socket functions: %% open(SocketType, Host, Port) -> {ok, Socket} | {error, Reason} %% SocketType -> ssl | ip_comm %% Host -> atom() | string() | {A, B, C, D} %% Port -> integer() connect_bin(ssl, Host, Port) -> ssl:start(), %% Does not support ipv6 in old ssl case ssl:connect(Host, Port, [binary, {packet,0}]) of {ok, Socket} -> {ok, Socket}; {error, Reason} -> {error, Reason}; Error -> Error end; connect_bin(ip_comm, Host, Port) -> Opts = [inet6, binary, {packet,0}], connect(ip_comm, Host, Port, Opts). connect(ip_comm, Host, Port, Opts) -> test_server:format("gen_tcp:connect(~p, ~p, ~p) ~n", [Host, Port, Opts]), case gen_tcp:connect(Host,Port, Opts) of {ok, Socket} -> test_server:format("connect success~n", []), {ok, Socket}; {error, nxdomain} -> test_server:format("nxdomain opts: ~p~n", [Opts]), connect(ip_comm, Host, Port, lists:delete(inet6, Opts)); {error, eafnosupport} -> test_server:format("eafnosupport opts: ~p~n", [Opts]), connect(ip_comm, Host, Port, lists:delete(inet6, Opts)); {error, {enfile,_}} -> test_server:format("Error enfile~n", []), {error, enfile}; Error -> test_server:format("Unexpected error: " "~n Error: ~p" "~nwhen" "~n Host: ~p" "~n Port: ~p" "~n Opts: ~p" "~n", [Error, Host, Port, Opts]), Error end. connect_byte(ip_comm, Host, Port) -> Opts = [inet6, {packet,0}], connect(ip_comm, Host, Port, Opts); connect_byte(ssl, Host, Port) -> ssl:start(), %% Does not support ipv6 in old ssl case ssl:connect(Host,Port,[{packet,0}]) of {ok,Socket} -> {ok,Socket}; {error,{enfile,_}} -> {error, enfile}; Error -> Error end. send(ssl, Socket, Data) -> ssl:send(Socket, Data); send(ip_comm,Socket,Data) -> gen_tcp:send(Socket,Data). close(ssl,Socket) -> catch ssl:close(Socket); close(ip_comm,Socket) -> catch gen_tcp:close(Socket). millis() -> erlang:now(). millis_diff(A,B) -> T1 = (element(1,A)*1000000) + element(2,A) + (element(3,A)/1000000), T2 = (element(1,B)*1000000) + element(2,B) + (element(3,B)/1000000), T1 - T2. hours(N) -> trunc(N * 1000 * 60 * 60). minutes(N) -> trunc(N * 1000 * 60). seconds(N) -> trunc(N * 1000). sleep(infinity) -> receive after infinity -> ok end; sleep(MSecs) -> receive after trunc(MSecs) -> ok end, ok. skip(Reason, File, Line) -> exit({skipped, {Reason, File, Line}}).