diff options
author | Péter Dimitrov <[email protected]> | 2018-03-07 09:19:25 +0100 |
---|---|---|
committer | Péter Dimitrov <[email protected]> | 2018-03-28 10:19:38 +0200 |
commit | 118dc092313b7eae9dd4084bb354cec644823ab2 (patch) | |
tree | 7ada2ebf5d0c7c0e1ac7151734558d487b600c4d /lib/ftp | |
parent | 4fc92e109803c69aa0ff0bba11b05ff9ce119f05 (diff) | |
download | otp-118dc092313b7eae9dd4084bb354cec644823ab2.tar.gz otp-118dc092313b7eae9dd4084bb354cec644823ab2.tar.bz2 otp-118dc092313b7eae9dd4084bb354cec644823ab2.zip |
ftp: Refactor ftp tests
- Add appup file
- Update vsftpd configuration file with stronger cipher suites
- Remove unused functions from ftp_test_lib
- Improve certificate generation
Change-Id: I941e922d7532a3f2a05662aff621a175b630d3b5
Diffstat (limited to 'lib/ftp')
-rw-r--r-- | lib/ftp/src/Makefile | 6 | ||||
-rw-r--r-- | lib/ftp/src/ftp.appup.src (renamed from lib/ftp/test/inets_test_lib.hrl) | 22 | ||||
-rw-r--r-- | lib/ftp/test/Makefile | 5 | ||||
-rw-r--r-- | lib/ftp/test/ftp_SUITE.erl | 25 | ||||
-rw-r--r-- | lib/ftp/test/ftp_SUITE_data/vsftpd.conf | 1 | ||||
-rw-r--r-- | lib/ftp/test/ftp_test_lib.erl | 126 | ||||
-rw-r--r-- | lib/ftp/test/inets_test_lib.erl | 596 |
7 files changed, 144 insertions, 637 deletions
diff --git a/lib/ftp/src/Makefile b/lib/ftp/src/Makefile index d5b197d18d..6a6df6bde4 100644 --- a/lib/ftp/src/Makefile +++ b/lib/ftp/src/Makefile @@ -60,12 +60,12 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) BEHAVIOUR_TARGET_FILES= $(BEHAVIOUR_MODULES:%=$(EBIN)/%.$(EMULATOR)) APP_FILE= ftp.app -#APPUP_FILE= ftp.appup +APPUP_FILE= ftp.appup APP_SRC= $(APP_FILE).src APP_TARGET= $(EBIN)/$(APP_FILE) -#APPUP_SRC= $(APPUP_FILE).src -#APPUP_TARGET= $(EBIN)/$(APPUP_FILE) +APPUP_SRC= $(APPUP_FILE).src +APPUP_TARGET= $(EBIN)/$(APPUP_FILE) # ---------------------------------------------------- # FLAGS diff --git a/lib/ftp/test/inets_test_lib.hrl b/lib/ftp/src/ftp.appup.src index d436395290..f5798ef976 100644 --- a/lib/ftp/test/inets_test_lib.hrl +++ b/lib/ftp/src/ftp.appup.src @@ -1,7 +1,7 @@ -%% +%% -*- erlang -*- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2016. All Rights Reserved. +%% Copyright Ericsson AB 1999-2018. 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. @@ -16,13 +16,11 @@ %% limitations under the License. %% %% %CopyrightEnd% -%% -%% -%%---------------------------------------------------------------------- -%% Purpose: Define common macros for testing -%%---------------------------------------------------------------------- -%% - Misc macros - - --define(ENSURE_STARTED(A), inets_test_lib:ensure_started(A)). - - +{"%VSN%", + [ + {<<"*">>,[{restart_application, ftp}]} + ], + [ + {<<"*">>,[{restart_application, ftp}]} + ] +}. diff --git a/lib/ftp/test/Makefile b/lib/ftp/test/Makefile index 38b85449f8..e1619e2142 100644 --- a/lib/ftp/test/Makefile +++ b/lib/ftp/test/Makefile @@ -101,14 +101,13 @@ MODULES = \ erl_make_certs \ ftp_SUITE \ ftp_format_SUITE \ - inets_test_lib + ftp_test_lib EBIN = . HRL_FILES = \ - ftp_internal.hrl \ - inets_test_lib.hrl + ftp_internal.hrl ERL_FILES = $(MODULES:%=%.erl) diff --git a/lib/ftp/test/ftp_SUITE.erl b/lib/ftp/test/ftp_SUITE.erl index c1cdd13adb..3d4331f866 100644 --- a/lib/ftp/test/ftp_SUITE.erl +++ b/lib/ftp/test/ftp_SUITE.erl @@ -18,16 +18,10 @@ %% %CopyrightEnd% %% %% - -%% -%% ct:run("../inets_test", ftp_SUITE). -%% - -module(ftp_SUITE). -include_lib("kernel/include/file.hrl"). -include_lib("common_test/include/ct.hrl"). --include("inets_test_lib.hrl"). %% Note: This directive should only be used in test suites. -compile(export_all). @@ -189,7 +183,8 @@ init_per_suite(Config) -> {ok,Data} -> TstDir = filename:join(proplists:get_value(priv_dir,Config), "test"), file:make_dir(TstDir), - make_cert_files(dsa, rsa, "server-", proplists:get_value(data_dir,Config)), + %% make_cert_files(dsa, rsa, "server-", proplists:get_value(data_dir,Config)), + ftp_test_lib:make_cert_files(proplists:get_value(data_dir,Config)), start_ftpd([{test_dir,TstDir}, {ftpd_data,Data} | Config]) @@ -930,22 +925,6 @@ error_ehost(_Config) -> %% Internal functions ----------------------------------------------- %%-------------------------------------------------------------------- -make_cert_files(Alg1, Alg2, Prefix, Dir) -> - CaInfo = {CaCert,_} = erl_make_certs:make_cert([{key,Alg1}]), - {Cert,CertKey} = erl_make_certs:make_cert([{key,Alg2},{issuer,CaInfo}]), - CaCertFile = filename:join(Dir, Prefix++"cacerts.pem"), - CertFile = filename:join(Dir, Prefix++"cert.pem"), - KeyFile = filename:join(Dir, Prefix++"key.pem"), - der_to_pem(CaCertFile, [{'Certificate', CaCert, not_encrypted}]), - der_to_pem(CertFile, [{'Certificate', Cert, not_encrypted}]), - der_to_pem(KeyFile, [CertKey]), - ok. - -der_to_pem(File, Entries) -> - PemBin = public_key:pem_encode(Entries), - file:write_file(File, PemBin). - -%%-------------------------------------------------------------------- chk_file(Path=[C|_], ExpectedContents, Config) when 0<C,C=<255 -> chk_file([Path], ExpectedContents, Config); diff --git a/lib/ftp/test/ftp_SUITE_data/vsftpd.conf b/lib/ftp/test/ftp_SUITE_data/vsftpd.conf index a5584f5916..2a177644d4 100644 --- a/lib/ftp/test/ftp_SUITE_data/vsftpd.conf +++ b/lib/ftp/test/ftp_SUITE_data/vsftpd.conf @@ -11,6 +11,7 @@ listen=YES listen_port=9999 run_as_launching_user=YES ssl_enable=YES +ssl_ciphers=RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5 allow_anon_ssl=YES background=YES diff --git a/lib/ftp/test/ftp_test_lib.erl b/lib/ftp/test/ftp_test_lib.erl new file mode 100644 index 0000000000..f5fbc39037 --- /dev/null +++ b/lib/ftp/test/ftp_test_lib.erl @@ -0,0 +1,126 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2018. 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(ftp_test_lib). + +-include_lib("public_key/include/public_key.hrl"). + +-export([make_cert_files/1]). + + +make_cert_files(Dir) -> + #{server_config := ServerConf, + client_config := _} = + public_key:pkix_test_data(#{server_chain => + #{root => [{key, hardcode_rsa_key(1)}], + intermediates => [[{key, hardcode_rsa_key(2)}]], + peer => [{key, hardcode_rsa_key(3)}]}, + client_chain => + #{root => [{key, hardcode_rsa_key(1)}], + intermediates => [[{key, hardcode_rsa_key(3)}]], + peer => [{key, hardcode_rsa_key(2)}]}}), + + CaCertFile = filename:join(Dir, "server-cacerts.pem"), + CertFile = filename:join(Dir, "server-cert.pem"), + KeyFile = filename:join(Dir, "server-key.pem"), + + CAs = proplists:get_value(cacerts, ServerConf), + Cert = proplists:get_value(cert, ServerConf), + Key = proplists:get_value(key, ServerConf), + der_to_pem(CertFile, [cert_entry(Cert)]), + der_to_pem(KeyFile, [key_entry(Key)]), + der_to_pem(CaCertFile, ca_entries(CAs)). + +cert_entry(Cert) -> + {'Certificate', Cert, not_encrypted}. + +key_entry({'RSAPrivateKey', DERKey}) -> + {'RSAPrivateKey', DERKey, not_encrypted}; +key_entry({'DSAPrivateKey', DERKey}) -> + {'DSAPrivateKey', DERKey, not_encrypted}; +key_entry({'ECPrivateKey', DERKey}) -> + {'ECPrivateKey', DERKey, not_encrypted}. + +ca_entries(CAs) -> + [{'Certificate', CACert, not_encrypted} || CACert <- CAs]. + +der_to_pem(File, Entries) -> + PemBin = public_key:pem_encode(Entries), + file:write_file(File, PemBin). + +hardcode_rsa_key(1) -> + #'RSAPrivateKey'{ + version = 'two-prime', + modulus = +23995666614853919027835084074500048897452890537492185072956789802729257783422306095699263934587064480357348855732149402060270996295002843755712064937715826848741191927820899197493902093529581182351132392364214171173881547273475904587683433713767834856230531387991145055273426806331200574039205571401702219159773947658558490957010003143162250693492642996408861265758000254664396313741422909188635443907373976005987612936763564996605457102336549804831742940035613780926178523017685712710473543251580072875247250504243621640157403744718833162626193206685233710319205099867303242759099560438381385658382486042995679707669, + publicExponent = 17, + privateExponent = +11292078406990079542510627799764728892919007311761028269626724613049062486316379339152594792746853873109340637991599718616598115903530750002688030558925094987642913848386305504703012749896273497577003478759630198199473669305165131570674557041773098755873191241407597673069847908861741446606684974777271632545629600685952292605647052193819136445675100211504432575554351515262198132231537860917084269870590492135731720141577986787033006338680118008484613510063003323516659048210893001173583018220214626635609151105287049126443102976056146630518124476470236027123782297108342869049542023328584384300970694412006494684657, +prime1 = +169371138592582642967021557955633494538845517070305333860805485424261447791289944610138334410987654265476540480228705481960508520379619587635662291973699651583489223555422528867090299996446070521801757353675026048850480903160224210802452555900007597342687137394192939372218903554801584969667104937092080815197, + prime2 = +141675062317286527042995673340952251894209529891636708844197799307963834958115010129693036021381525952081167155681637592199810112261679449166276939178032066869788822014115556349519329537177920752776047051833616197615329017439297361972726138285974555338480581117881706656603857310337984049152655480389797687577, + exponent1 = +119556097830058336212015217380447172615655659108450823901745048534772786676204666783627059584226579481512852103690850928442711896738555003036938088452023283470698275450886490965004917644550167427154181661417665446247398284583687678213495921811770068712485038160606780733330990744565824684470897602653233516609, + exponent2 = +41669135975672507953822256864985956439473391144599032012999352737636422046504414744027363535700448809435637398729893409470532385959317485048904982111185902020526124121798693043976273393287623750816484427009887116945685005129205106462566511260580751570141347387612266663707016855981760014456663376585234613993, + coefficient = +76837684977089699359024365285678488693966186052769523357232308621548155587515525857011429902602352279058920284048929101483304120686557782043616693940283344235057989514310975192908256494992960578961614059245280827077951132083993754797053182279229469590276271658395444955906108899267024101096069475145863928441, + otherPrimeInfos = asn1_NOVALUE}; + +hardcode_rsa_key(2) -> + #'RSAPrivateKey'{ + version = 'two-prime', + modulus = +21343679768589700771839799834197557895311746244621307033143551583788179817796325695589283169969489517156931770973490560582341832744966317712674900833543896521418422508485833901274928542544381247956820115082240721897193055368570146764204557110415281995205343662628196075590438954399631753508888358737971039058298703003743872818150364935790613286541190842600031570570099801682794056444451081563070538409720109449780410837763602317050353477918147758267825417201591905091231778937606362076129350476690460157227101296599527319242747999737801698427160817755293383890373574621116766934110792127739174475029121017282777887777, + publicExponent = 17, + privateExponent = +18832658619343853622211588088997845201745658451136447382185486691577805721584993260814073385267196632785528033211903435807948675951440868570007265441362261636545666919252206383477878125774454042314841278013741813438699754736973658909592256273895837054592950290554290654932740253882028017801960316533503857992358685308186680144968293076156011747178275038098868263178095174694099811498968993700538293188879611375604635940554394589807673542938082281934965292051746326331046224291377703201248790910007232374006151098976879987912446997911775904329728563222485791845480864283470332826504617837402078265424772379987120023773, + prime1 = +146807662748886761089048448970170315054939768171908279335181627815919052012991509112344782731265837727551849787333310044397991034789843793140419387740928103541736452627413492093463231242466386868459637115999163097726153692593711599245170083315894262154838974616739452594203727376460632750934355508361223110419, + prime2 = +145385325050081892763917667176962991350872697916072592966410309213561884732628046256782356731057378829876640317801978404203665761131810712267778698468684631707642938779964806354584156202882543264893826268426566901882487709510744074274965029453915224310656287149777603803201831202222853023280023478269485417083, + exponent1 = +51814469205489445090252393754177758254684624060673510353593515699736136004585238510239335081623236845018299924941168250963996835808180162284853901555621683602965806809675350150634081614988136541809283687999704622726877773856604093851236499993845033701707873394143336209718962603456693912094478414715725803677, + exponent2 = +51312467664734785681382706062457526359131540440966797517556579722433606376221663384746714140373192528191755406283051201483646739222992016094510128871300458249756331334105225772206172777487956446433115153562317730076172132768497908567634716277852432109643395464627389577600646306666889302334125933506877206029, + coefficient = +30504662229874176232343608562807118278893368758027179776313787938167236952567905398252901545019583024374163153775359371298239336609182249464886717948407152570850677549297935773605431024166978281486607154204888016179709037883348099374995148481968169438302456074511782717758301581202874062062542434218011141540, + otherPrimeInfos = asn1_NOVALUE}; + +hardcode_rsa_key(3) -> + #'RSAPrivateKey'{ + version = 'two-prime', + modulus = +25089040456112869869472694987833070928503703615633809313972554887193090845137746668197820419383804666271752525807484521370419854590682661809972833718476098189250708650325307850184923546875260207894844301992963978994451844985784504212035958130279304082438876764367292331581532569155681984449177635856426023931875082020262146075451989132180409962870105455517050416234175675478291534563995772675388370042873175344937421148321291640477650173765084699931690748536036544188863178325887393475703801759010864779559318631816411493486934507417755306337476945299570726975433250753415110141783026008347194577506976486290259135429, + publicExponent = 17, + privateExponent = +8854955455098659953931539407470495621824836570223697404931489960185796768872145882893348383311931058684147950284994536954265831032005645344696294253579799360912014817761873358888796545955974191021709753644575521998041827642041589721895044045980930852625485916835514940558187965584358347452650930302268008446431977397918214293502821599497633970075862760001650736520566952260001423171553461362588848929781360590057040212831994258783694027013289053834376791974167294527043946669963760259975273650548116897900664646809242902841107022557239712438496384819445301703021164043324282687280801738470244471443835900160721870265, + prime1 = +171641816401041100605063917111691927706183918906535463031548413586331728772311589438043965564336865070070922328258143588739626712299625805650832695450270566547004154065267940032684307994238248203186986569945677705100224518137694769557564475390859269797990555863306972197736879644001860925483629009305104925823, + prime2 +=146170909759497809922264016492088453282310383272504533061020897155289106805616042710009332510822455269704884883705830985184223718261139908416790475825625309815234508695722132706422885088219618698987115562577878897003573425367881351537506046253616435685549396767356003663417208105346307649599145759863108910523, + exponent1 = +60579464612132153154728441333538327425711971378777222246428851853999433684345266860486105493295364142377972586444050678378691780811632637288529186629507258781295583787741625893888579292084087601124818789392592131211843947578009918667375697196773859928702549128225990187436545756706539150170692591519448797349, + exponent2 = +137572620950115585809189662580789132500998007785886619351549079675566218169991569609420548245479957900898715184664311515467504676010484619686391036071176762179044243478326713135456833024206699951987873470661533079532774988581535389682358631768109586527575902839864474036157372334443583670210960715165278974609, + coefficient = +15068630434698373319269196003209754243798959461311186548759287649485250508074064775263867418602372588394608558985183294561315208336731894947137343239541687540387209051236354318837334154993136528453613256169847839789803932725339395739618592522865156272771578671216082079933457043120923342632744996962853951612, + otherPrimeInfos = asn1_NOVALUE}. diff --git a/lib/ftp/test/inets_test_lib.erl b/lib/ftp/test/inets_test_lib.erl deleted file mode 100644 index 2529cc5f9b..0000000000 --- a/lib/ftp/test/inets_test_lib.erl +++ /dev/null @@ -1,596 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2015. 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(inets_test_lib). - --include("inets_test_lib.hrl"). --include_lib("inets/src/http_lib/http_internal.hrl"). - -%% Note: This directive should only be used in test suites. --compile(export_all). - -%% -- Misc os command and stuff - -has_ipv6_support() -> - tsp("has_ipv6_support -> no ipv6_hosts config"), - {ok, Hostname} = inet:gethostname(), - case inet:getaddrs(Hostname, inet6) of - {ok, [Addr|_]} when is_tuple(Addr) andalso - (element(1, Addr) =/= 0) -> - %% We actually need to test that the addr can be used, - %% this is done by attempting to create a (tcp) - %% listen socket - tsp("has_ipv6_support -> check Addr: ~p", [Addr]), - case (catch gen_tcp:listen(0, [inet6, {ip, Addr}])) of - {ok, LSock} -> - tsp("has_ipv6_support -> we are ipv6 host"), - gen_tcp:close(LSock), - {ok, Addr}; - _ -> - undefined - end; - _ -> - undefined - end. - -has_ipv6_support(Config) -> - case lists:keysearch(ipv6_hosts, 1, Config) of - false -> - %% Do a basic check to se if - %% our own host has a working IPv6 address... - has_ipv6_support(); - - {value, {_, Hosts}} when is_list(Hosts) -> - %% Check if our host is in the list of *known* IPv6 hosts - tsp("has_ipv6_support -> Hosts: ~p", [Hosts]), - {ok, Hostname} = inet:gethostname(), - case lists:member(list_to_atom(Hostname), Hosts) of - true -> - tsp("has_ipv6_support -> we are known ipv6 host"), - {ok, [Addr|_]} = inet:getaddrs(Hostname, inet6), - {ok, Addr}; - false -> - undefined - end; - - _ -> - undefined - - end. - -oscmd(Cmd) -> - string:strip(os:cmd(Cmd), right, $\n). - - -print_system_info([]) -> - do_print_system_info("System Info"); -print_system_info(Prefix) when is_list(Prefix) -> - NewPrefix = lists:flatten(io_lib:format("~s: System Info", [Prefix])), - do_print_system_info(NewPrefix). - -do_print_system_info(Prefix) -> - tsp("~s => " - "~n" - "~n OS Type: ~p" - "~n OS version: ~p" - "~n Sys Arch: ~p" - "~n CPU Topology: ~p" - "~n Num logical procs: ~p" - "~n SMP support: ~p" - "~n Num schedulers: ~p" - "~n Scheduler bindings: ~p" - "~n Wordsize: ~p" - "~n~n", [Prefix, - os:type(), os:version(), - erlang:system_info(system_architecture), - erlang:system_info(cpu_topology), - erlang:system_info(logical_processors), - erlang:system_info(smp_support), - erlang:system_info(schedulers), - erlang:system_info(scheduler_bindings), - erlang:system_info(wordsize)]), - ok. - - -run_on_windows(Fun) -> - run_on_os(windows, Fun). - -run_on_os(windows, Fun) -> - case os:type() of - {win32, _} -> - Fun(); - _ -> - ok - end. - - -%% -- Misc node operation wrapper functions -- - -start_node(Name) -> - Pa = filename:dirname(code:which(?MODULE)), - Args = case init:get_argument('CC_TEST') of - {ok, [[]]} -> - " -pa /clearcase/otp/libraries/snmp/ebin "; - {ok, [[Path]]} -> - " -pa " ++ Path; - error -> - "" - end, - A = Args ++ " -pa " ++ Pa, - Opts = [{cleanup,false}, {args, A}], - case (catch test_server:start_node(Name, slave, Opts)) of - {ok, Node} -> - Node; - Else -> - exit({failed_starting_node, Name, Else}) - end. - -stop_node(Node) -> - rpc:cast(Node, erlang, halt, []), - await_stopped(Node, 5). - -await_stopped(_, 0) -> - ok; -await_stopped(Node, N) -> - Nodes = erlang:nodes(), - case lists:member(Node, Nodes) of - true -> - sleep(1000), - await_stopped(Node, N-1); - false -> - ok - end. - - -%% ---------------------------------------------------------------- -%% Ensure apps are started -%% This to ensure we dont attempt to run teatcases on platforms -%% where there is no working ssl app. - -ensure_started([]) -> - ok; -ensure_started([App|Apps]) -> - ensure_started(App), - ensure_started(Apps); -ensure_started(crypto = App) -> - %% We have to treat crypto in this special way because - %% only this function ensures that the NIF lib is actually - %% loaded. And only by loading that lib can we know if it - %% is even possible to run crypto. - do_ensure_started(App, fun() -> crypto:start() end); -ensure_started(App) when is_atom(App) -> - do_ensure_started(App, fun() -> application:start(App) end). - -do_ensure_started(App, Start) when is_function(Start) -> - case (catch Start()) of - ok -> - ok; - {error, {already_started, _}} -> - ok; - Error -> - throw({error, {failed_starting, App, Error}}) - end. - - -ensure_loaded(App) -> - case application:load(App) of - ok -> - ok; - {error, {already_loaded,inets}} -> - ok; - Error -> - Error - end. - - - -%% ---------------------------------------------------------------- -%% HTTPD starter functions -%% - -start_http_server(Conf) -> - start_http_server(Conf, ?HTTP_DEFAULT_SSL_KIND). - -start_http_server(Conf, essl = _SslTag) -> - tsp("start_http_server(essl) -> try start crypto"), - application:start(crypto), - tsp("start_http_server(essl) -> try start public_key"), - application:start(public_key), - do_start_http_server(Conf); -start_http_server(Conf, SslTag) -> - tsp("start_http_server(~w) -> entry", [SslTag]), - do_start_http_server(Conf). - -do_start_http_server(Conf) -> - tsp("do_start_http_server -> entry with" - "~n Conf: ~p" - "~n", [Conf]), - tsp("do_start_http_server -> load inets"), - case ensure_loaded(inets) of - ok -> - tsp("do_start_http_server -> inets loaded - now set_env for httpd"), - case application:set_env(inets, services, [{httpd, Conf}]) of - ok -> - tsp("do_start_http_server -> " - "httpd conf stored in inets app env"), - case (catch application:start(inets)) of - ok -> - tsp("do_start_http_server -> inets started"), - ok; - Error1 -> - tsp("<ERROR> Failed starting application: " - "~n Error1: ~p", [Error1]), - tsf({failed_starting_inets, Error1}) - end; - Error2 -> - tsp("<ERROR> Failed set application env: " - "~n Error: ~p", [Error2]), - tsf({failed_set_env, Error2}) - end; - {error, Reason} -> - tsp("do_start_http_server -> failed loading inets" - "~n Reason: ~p", [Reason]), - tsf({failed_loading_inets, Reason}) - end. - -start_http_server_ssl(FileName) -> - start_http_server_ssl(FileName, ?HTTP_DEFAULT_SSL_KIND). - -start_http_server_ssl(FileName, essl = _SslTag) -> - application:start(crypto), - do_start_http_server_ssl(FileName); -start_http_server_ssl(FileName, _SslTag) -> - do_start_http_server_ssl(FileName). - -do_start_http_server_ssl(FileName) -> - tsp("start (ssl) http server with " - "~n FileName: ~p" - "~n", [FileName]), - application:start(ssl), - catch do_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() -> - {ok, Name} = inet:gethostname(), - Name. - -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) -> - case file:list_dir(FromDirRoot) of - {ok, Files} -> - lists:foreach( - fun(FileOrDir) -> - %% Check if it's a directory or a file - case filelib:is_dir(filename:join(FromDirRoot, - FileOrDir)) of - true -> - FromDir = filename:join([FromDirRoot, FileOrDir]), - ToDir = filename:join([ToDirRoot, FileOrDir]), - case file:make_dir(ToDir) of - ok -> - copy_dirs(FromDir, ToDir); - {error, Reason} -> - tsp("<ERROR> Failed creating directory: " - "~n ToDir: ~p" - "~n Reason: ~p" - "~nwhen" - "~n ToDirRoot: ~p" - "~n ToDirRoot file info: ~p", - [ToDir, - Reason, - ToDirRoot, - file:read_file_info(ToDirRoot)]), - tsf({failed_copy_dir, ToDir, Reason}) - end; - false -> - copy_file(FileOrDir, FromDirRoot, ToDirRoot) - end - end, Files); - {error, Reason} -> - tsp("<ERROR> Failed get directory file list: " - "~n FromDirRoot: ~p" - "~n Reason: ~p" - "~nwhen" - "~n FromDirRoot file info: ~p", - [FromDirRoot, - Reason, - file:read_file_info(FromDirRoot)]), - tsf({failed_list_dir, FromDirRoot, Reason}) - end. - - - -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, "</html>") of - 0 -> - case string:rstr(Body, "</HTML>") of - 0 -> - tsp("Body ~p", [Body]), - tsf(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(SockType, Host, Port) -> - connect_bin(SockType, Host, Port, []). - -connect_bin(ssl, Host, Port, Opts0) -> - Opts = [binary, {packet,0} | Opts0], - connect(ssl, Host, Port, Opts); -connect_bin(essl, Host, Port, Opts0) -> - Opts = [{ssl_imp, new}, binary, {packet,0}| Opts0], - connect(ssl, Host, Port, Opts); -connect_bin(ip_comm, Host, Port, Opts0) -> - Opts = [binary, {packet, 0} | Opts0], - connect(ip_comm, Host, Port, Opts); -connect_bin(Type, Host, Port, Opts) -> - connect(Type, Host, Port, Opts). - -connect_byte(SockType, Host, Port) -> - connect_byte(SockType, Host, Port, []). - -connect_byte(ssl, Host, Port, Opts0) -> - Opts = [{packet,0} | Opts0], - connect(ssl, Host, Port, Opts); -connect_byte(essl, Host, Port, Opts0) -> - Opts = [{ssl_imp, new}, {packet,0} | Opts0], - connect(ssl, Host, Port, Opts); -connect_byte(ip_comm, Host, Port, Opts0) -> - Opts = [{packet,0} | Opts0], - connect(ip_comm, Host, Port, Opts); -connect_byte(Type, Host, Port, Opts) -> - connect(Type, Host, Port, Opts). - -connect(ip_comm, Host, Port, Opts) -> - gen_tcp:connect(Host, Port, Opts); -connect(ssl, Host, Port, Opts) -> - ssl:connect(Host, Port, Opts); -connect(openssl_port, Host, Port, Opts) -> - CaCertFile = proplists:get_value(cacertfile, Opts), - Cmd = "openssl s_client -quiet -port " ++ integer_to_list(Port) ++ " -host " ++ Host - ++ " -CAfile " ++ CaCertFile, - ct:log("openssl cmd: ~p~n", [Cmd]), - OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - read_junk(OpensslPort), - {ok, OpensslPort}. - -send(ssl, Socket, Data) -> - ssl:send(Socket, Data); -send(essl, Socket, Data) -> - ssl:send(Socket, Data); -send(ip_comm,Socket,Data) -> - gen_tcp:send(Socket,Data); -send(openssl_port, Port, Data) -> - true = port_command(Port, Data), - ok. -close(ssl,Socket) -> - catch ssl:close(Socket); -close(essl,Socket) -> - catch ssl:close(Socket); -close(ip_comm,Socket) -> - catch gen_tcp:close(Socket); -close(openssl_port, Port) -> - exit(Port, normal). - - -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}}). - -fail(Reason, File, Line) -> - String = lists:flatten(io_lib:format("Failure ~p(~p): ~p~n", - [File, Line, Reason])), - tsf(String). - - - -flush() -> - receive - Msg -> - [Msg | flush()] - after 1000 -> - [] - end. - - -tsp(F) -> - tsp(F, []). -tsp(F, A) -> - Timestamp = inets_lib:formated_timestamp(), - ct:pal("*** ~s ~p ~p " ++ F ++ "~n", - [Timestamp, node(), self() | A]). - -tsf(Reason) -> - ct:fail(Reason). - -tss(Time) -> - ct:sleep(Time). - -timestamp() -> - http_util:timestamp(). - -start_apps(Apps) -> - lists:foreach(fun(App) -> - application:stop(App), - application:start(App) - end, Apps). -stop_apps(Apps) -> - lists:foreach(fun(App) -> - application:stop(App) - end, Apps). - -inet_port(Node) -> - {Port, Socket} = do_inet_port(Node), - rpc:call(Node, gen_tcp, close, [Socket]), - Port. - -do_inet_port(Node) -> - {ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]), - {ok, Port} = rpc:call(Node, inet, port, [Socket]), - {Port, Socket}. - -read_junk(OpensslPort) -> - receive - {OpensslPort, _} -> - read_junk(OpensslPort) - after 500 -> - ok - end. |