From d58714a1d64a22f6710e704a98d85001ffc5c666 Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Tue, 5 Jun 2018 09:25:23 +0200 Subject: common_test: Remove EDoc documentation in public modules --- lib/common_test/src/ct.erl | 932 +------------------------------ lib/common_test/src/ct_cover.erl | 42 +- lib/common_test/src/ct_ftp.erl | 135 +---- lib/common_test/src/ct_hooks.erl | 12 +- lib/common_test/src/ct_master.erl | 112 +--- lib/common_test/src/ct_property_test.erl | 63 +-- lib/common_test/src/ct_rpc.erl | 112 +--- lib/common_test/src/ct_run.erl | 57 +- lib/common_test/src/ct_slave.erl | 190 +------ lib/common_test/src/ct_snmp.erl | 289 +--------- lib/common_test/src/ct_ssh.erl | 616 +------------------- lib/common_test/src/ct_telnet.erl | 409 +------------- lib/common_test/src/ct_testspec.erl | 6 +- lib/common_test/src/unix_telnet.erl | 62 +- 14 files changed, 49 insertions(+), 2988 deletions(-) (limited to 'lib') diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl index 14a9ec07cf..778ea2e9e2 100644 --- a/lib/common_test/src/ct.erl +++ b/lib/common_test/src/ct.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-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. @@ -18,38 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Main user interface for the Common Test framework. -%%% -%%%

This module implements the command line interface for running -%%% tests and some basic functions for common test case issues -%%% such as configuration and logging.

-%%% -%%%

Test Suite Support Macros

-%%% -%%%

The config macro is defined in ct.hrl. This -%%% macro should be used to retrieve information from the -%%% Config variable sent to all test cases. It is used with two -%%% arguments, where the first is the name of the configuration -%%% variable you wish to retrieve, and the second is the Config -%%% variable supplied to the test case.

-%%% -%%%

Possible configuration variables include:

-%%% - -%%% @type var_name() = atom(). A variable name which is specified when -%%% ct:require/2 is called, -%%% e.g. ct:require(mynodename,{node,[telnet]}) -%%% -%%% @type target_name() = var_name(). The name of a target. -%%% -%%% @type handle() = ct_gen_conn:handle() | term(). The identity of a -%%% specific connection. - -module(ct). -include("ct.hrl"). @@ -121,209 +89,34 @@ %%---------------------------------------------------------------------- - -%%%----------------------------------------------------------------- -%%% @spec install(Opts) -> ok | {error,Reason} -%%% Opts = [Opt] -%%% Opt = {config,ConfigFiles} | {event_handler,Modules} | -%%% {decrypt,KeyOrFile} -%%% ConfigFiles = [ConfigFile] -%%% ConfigFile = string() -%%% Modules = [atom()] -%%% KeyOrFile = {key,Key} | {file,KeyFile} -%%% Key = string() -%%% KeyFile = string() -%%% @doc Install config files and event handlers. -%%% -%%%

Run this function once before first test.

-%%% -%%%

Example:
-%%% install([{config,["config_node.ctc","config_user.ctc"]}]).

-%%% -%%%

Note that this function is automatically run by the -%%% ct_run program.

install(Opts) -> ct_run:install(Opts). -%%%----------------------------------------------------------------- -%%% @spec run(TestDir,Suite,Cases) -> Result -%%% TestDir = string() -%%% Suite = atom() -%%% Cases = atom() | [atom()] -%%% Result = [TestResult] | {error,Reason} -%%% -%%% @doc Run the given test case(s). -%%% -%%%

Requires that ct:install/1 has been run first.

-%%% -%%%

Suites (*_SUITE.erl) files must be stored in -%%% TestDir or TestDir/test. All suites -%%% will be compiled when test is run.

run(TestDir,Suite,Cases) -> ct_run:run(TestDir,Suite,Cases). -%%%----------------------------------------------------------------- -%%% @spec run(TestDir,Suite) -> Result -%%% -%%% @doc Run all test cases in the given suite. -%%% @see run/3. run(TestDir,Suite) -> ct_run:run(TestDir,Suite). -%%%----------------------------------------------------------------- -%%% @spec run(TestDirs) -> Result -%%% TestDirs = TestDir | [TestDir] -%%% -%%% @doc Run all test cases in all suites in the given directories. -%%% @see run/3. run(TestDirs) -> ct_run:run(TestDirs). -%%%----------------------------------------------------------------- -%%% @spec run_test(Opts) -> Result -%%% Opts = [OptTuples] -%%% OptTuples = {dir,TestDirs} | {suite,Suites} | {group,Groups} | -%%% {testcase,Cases} | {spec,TestSpecs} | {join_specs,Bool} | -%%% {label,Label} | {config,CfgFiles} | {userconfig, UserConfig} | -%%% {allow_user_terms,Bool} | {logdir,LogDir} | -%%% {silent_connections,Conns} | {stylesheet,CSSFile} | -%%% {cover,CoverSpecFile} | {cover_stop,Bool} | {step,StepOpts} | -%%% {event_handler,EventHandlers} | {include,InclDirs} | -%%% {auto_compile,Bool} | {abort_if_missing_suites,Bool} | -%%% {create_priv_dir,CreatePrivDir} | -%%% {multiply_timetraps,M} | {scale_timetraps,Bool} | -%%% {repeat,N} | {duration,DurTime} | {until,StopTime} | -%%% {force_stop,ForceStop} | {decrypt,DecryptKeyOrFile} | -%%% {refresh_logs,LogDir} | {logopts,LogOpts} | -%%% {verbosity,VLevels} | {basic_html,Bool} | -%%% {esc_chars,Bool} | {ct_hooks, CTHs} | -%%% {enable_builtin_hooks,Bool} | {release_shell,Bool} -%%% TestDirs = [string()] | string() -%%% Suites = [string()] | [atom()] | string() | atom() -%%% Cases = [atom()] | atom() -%%% Groups = GroupNameOrPath | [GroupNameOrPath] -%%% GroupNameOrPath = [atom()] | atom() | all -%%% TestSpecs = [string()] | string() -%%% Label = string() | atom() -%%% CfgFiles = [string()] | string() -%%% UserConfig = [{CallbackMod,CfgStrings}] | {CallbackMod,CfgStrings} -%%% CallbackMod = atom() -%%% CfgStrings = [string()] | string() -%%% LogDir = string() -%%% Conns = all | [atom()] -%%% CSSFile = string() -%%% CoverSpecFile = string() -%%% StepOpts = [StepOpt] | [] -%%% StepOpt = config | keep_inactive -%%% EventHandlers = EH | [EH] -%%% EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs} -%%% InitArgs = [term()] -%%% InclDirs = [string()] | string() -%%% CreatePrivDir = auto_per_run | auto_per_tc | manual_per_tc -%%% M = integer() -%%% N = integer() -%%% DurTime = string(HHMMSS) -%%% StopTime = string(YYMoMoDDHHMMSS) | string(HHMMSS) -%%% ForceStop = skip_rest | Bool -%%% DecryptKeyOrFile = {key,DecryptKey} | {file,DecryptFile} -%%% DecryptKey = string() -%%% DecryptFile = string() -%%% LogOpts = [LogOpt] -%%% LogOpt = no_nl | no_src -%%% VLevels = VLevel | [{Category,VLevel}] -%%% VLevel = integer() -%%% Category = atom() -%%% CTHs = [CTHModule | {CTHModule, CTHInitArgs}] -%%% CTHModule = atom() -%%% CTHInitArgs = term() -%%% Result = {Ok,Failed,{UserSkipped,AutoSkipped}} | TestRunnerPid | {error,Reason} -%%% Ok = integer() -%%% Failed = integer() -%%% UserSkipped = integer() -%%% AutoSkipped = integer() -%%% TestRunnerPid = pid() -%%% Reason = term() -%%% @doc

Run tests as specified by the combination of options in Opts. -%%% The options are the same as those used with the -%%% ct_run program. -%%% Note that here a TestDir can be used to point out the path to -%%% a Suite. Note also that the option testcase -%%% corresponds to the -case option in the ct_run -%%% program. Configuration files specified in Opts will be -%%% installed automatically at startup.

-%%%

TestRunnerPid is returned if release_shell == true -%%% (see break/1 for details).

-%%%

Reason indicates what type of error has been encountered.

run_test(Opts) -> ct_run:run_test(Opts). -%%%----------------------------------------------------------------- -%%% @spec run_testspec(TestSpec) -> Result -%%% TestSpec = [term()] -%%% Result = {Ok,Failed,{UserSkipped,AutoSkipped}} | {error,Reason} -%%% Ok = integer() -%%% Failed = integer() -%%% UserSkipped = integer() -%%% AutoSkipped = integer() -%%% Reason = term() -%%% @doc Run test specified by TestSpec. The terms are -%%% the same as those used in test specification files. -%%%

Reason indicates what type of error has been encountered.

run_testspec(TestSpec) -> ct_run:run_testspec(TestSpec). -%%%----------------------------------------------------------------- -%%% @spec step(TestDir,Suite,Case) -> Result -%%% Case = atom() -%%% -%%% @doc Step through a test case with the debugger. -%%% @see run/3 step(TestDir,Suite,Case) -> ct_run:step(TestDir,Suite,Case). -%%%----------------------------------------------------------------- -%%% @spec step(TestDir,Suite,Case,Opts) -> Result -%%% Case = atom() -%%% Opts = [Opt] | [] -%%% Opt = config | keep_inactive -%%% -%%% @doc Step through a test case with the debugger. If the -%%% config option has been given, breakpoints will -%%% be set also on the configuration functions in Suite. -%%% @see run/3 step(TestDir,Suite,Case,Opts) -> ct_run:step(TestDir,Suite,Case,Opts). -%%%----------------------------------------------------------------- -%%% @spec start_interactive() -> ok -%%% -%%% @doc Start CT in interactive mode. -%%% -%%%

From this mode all test case support functions can be executed -%%% directly from the erlang shell. The interactive mode can also be -%%% started from the OS command line with ct_run -shell -%%% [-config File...].

-%%% -%%%

If any functions using "required config data" (e.g. telnet or -%%% ftp functions) are to be called from the erlang shell, config data -%%% must first be required with ct:require/2.

-%%% -%%%

Example:
-%%% > ct:require(unix_telnet, unix).
-%%% ok
-%%% > ct_telnet:open(unix_telnet).
-%%% {ok,<0.105.0>}
-%%% > ct_telnet:cmd(unix_telnet, "ls .").
-%%% {ok,["ls","file1 ...",...]}

start_interactive() -> _ = ct_util:start(interactive), ok. -%%%----------------------------------------------------------------- -%%% @spec stop_interactive() -> ok -%%% -%%% @doc Exit the interactive mode. -%%% @see start_interactive/0 stop_interactive() -> ct_util:stop(normal), ok. @@ -332,181 +125,24 @@ stop_interactive() -> %%% MISC INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%----------------------------------------------------------------- -%%% @spec require(Required) -> ok | {error,Reason} -%%% Required = Key | {Key,SubKeys} | {Key,SubKey,SubKeys} -%%% Key = atom() -%%% SubKeys = SubKey | [SubKey] -%%% SubKey = atom() -%%% -%%% @doc Check if the required configuration is available. It is possible -%%% to specify arbitrarily deep tuples as Required. Note that it is -%%% only the last element of the tuple which can be a list of SubKeys. -%%% -%%%

Example 1: require the variable myvar:

-%%%
ok = ct:require(myvar).
-%%% -%%%

In this case the config file must at least contain:

-%%%
{myvar,Value}.
-%%% -%%%

Example 2: require the key myvar with -%%% subkeys sub1 and sub2:

-%%%
ok = ct:require({myvar,[sub1,sub2]}).
-%%% -%%%

In this case the config file must at least contain:

-%%%
{myvar,[{sub1,Value},{sub2,Value}]}.
-%%% -%%%

Example 3: require the key myvar with -%%% subkey sub1 with subsub1:

-%%%
ok = ct:require({myvar,sub1,sub2}).
-%%% -%%%

In this case the config file must at least contain:

-%%%
{myvar,[{sub1,[{sub2,Value}]}]}.
-%%% -%%% @see require/2 -%%% @see get_config/1 -%%% @see get_config/2 -%%% @see get_config/3 require(Required) -> ct_config:require(Required). -%%%----------------------------------------------------------------- -%%% @spec require(Name,Required) -> ok | {error,Reason} -%%% Name = atom() -%%% Required = Key | {Key,SubKey} | {Key,SubKey,SubKey} -%%% SubKey = Key -%%% Key = atom() -%%% -%%% @doc Check if the required configuration is available, and give it -%%% a name. The semantics for Required is the same as in -%%% required/1 except that it is not possible to specify a list -%%% of SubKeys. -%%% -%%%

If the requested data is available, the sub entry will be -%%% associated with Name so that the value of the element -%%% can be read with get_config/1,2 provided -%%% Name instead of the whole Required term.

-%%% -%%%

Example: Require one node with a telnet connection and an -%%% ftp connection. Name the node a: -%%%

ok = ct:require(a,{machine,node}).
-%%% All references to this node may then use the node name. -%%% E.g. you can fetch a file over ftp like this:

-%%%
ok = ct:ftp_get(a,RemoteFile,LocalFile).
-%%% -%%%

For this to work, the config file must at least contain:

-%%%
{machine,[{node,[{telnet,IpAddr},{ftp,IpAddr}]}]}.
-%%% -%%%

The behaviour of this function changed radically in common_test -%%% 1.6.2. In order too keep some backwards compatability it is still possible -%%% to do:
ct:require(a,{node,[telnet,ftp]}).
-%%% This will associate the name a with the top level node entry. -%%% For this to work, the config file must at least contain:
-%%% {node,[{telnet,IpAddr},{ftp,IpAddr}]}.

-%%% -%%% @see require/1 -%%% @see get_config/1 -%%% @see get_config/2 -%%% @see get_config/3 require(Name,Required) -> ct_config:require(Name,Required). -%%%----------------------------------------------------------------- -%%% @spec get_config(Required) -> Value -%%% @equiv get_config(Required,undefined,[]) get_config(Required) -> ct_config:get_config(Required,undefined,[]). -%%%----------------------------------------------------------------- -%%% @spec get_config(Required,Default) -> Value -%%% @equiv get_config(Required,Default,[]) get_config(Required,Default) -> ct_config:get_config(Required,Default,[]). -%%%----------------------------------------------------------------- -%%% @spec get_config(Required,Default,Opts) -> ValueOrElement -%%% Required = KeyOrName | {KeyOrName,SubKey} | {KeyOrName,SubKey,SubKey} -%%% KeyOrName = atom() -%%% SubKey = atom() -%%% Default = term() -%%% Opts = [Opt] | [] -%%% Opt = element | all -%%% ValueOrElement = term() | Default -%%% -%%% @doc Read config data values. -%%% -%%%

This function returns the matching value(s) or config element(s), -%%% given a config variable key or its associated name -%%% (if one has been specified with require/2 or a -%%% require statement).

-%%% -%%%

Example, given the following config file:

-%%%
-%%% {unix,[{telnet,IpAddr},
-%%%        {user,[{username,Username},
-%%%               {password,Password}]}]}.
-%%%

ct:get_config(unix,Default) -> -%%% [{telnet,IpAddr}, -%%% {user, [{username,Username}, -%%% {password,Password}]}]
-%%% ct:get_config({unix,telnet},Default) -> IpAddr
-%%% ct:get_config({unix,user,username},Default) -> Username
-%%% ct:get_config({unix,ftp},Default) -> Default
-%%% ct:get_config(unknownkey,Default) -> Default

-%%% -%%%

If a config variable key has been associated with a name (by -%%% means of require/2 or a require statement), the name -%%% may be used instead of the key to read the value:

-%%% -%%%

ct:require(myuser,{unix,user}) -> ok.
-%%% ct:get_config(myuser,Default) -> -%%% [{username,Username}, -%%% {password,Password}]

-%%% -%%%

If a config variable is defined in multiple files and you want to -%%% access all possible values, use the all option. The -%%% values will be returned in a list and the order of the elements -%%% corresponds to the order that the config files were specified at -%%% startup.

-%%% -%%%

If you want config elements (key-value tuples) returned as result -%%% instead of values, use the element option. -%%% The returned elements will then be on the form {Required,Value}

-%%% -%%% @see get_config/1 -%%% @see get_config/2 -%%% @see require/1 -%%% @see require/2 get_config(Required,Default,Opts) -> ct_config:get_config(Required,Default,Opts). -%%%----------------------------------------------------------------- -%%% @spec reload_config(Required) -> ValueOrElement -%%% Required = KeyOrName | {KeyOrName,SubKey} | {KeyOrName,SubKey,SubKey} -%%% KeyOrName = atom() -%%% SubKey = atom() -%%% ValueOrElement = term() -%%% -%%% @doc Reload config file which contains specified configuration key. -%%% -%%%

This function performs updating of the configuration data from which the -%%% given configuration variable was read, and returns the (possibly) new -%%% value of this variable.

-%%%

Note that if some variables were present in the configuration but are not loaded -%%% using this function, they will be removed from the configuration table together -%%% with their aliases.

-%%% reload_config(Required)-> ct_config:reload_config(Required). -%%%----------------------------------------------------------------- -%%% @spec get_testspec_terms() -> TestSpecTerms | undefined -%%% TestSpecTerms = [{Tag,Value}] -%%% Value = [term()] -%%% -%%% @doc Get a list of all test specification terms used to -%%% configure and run this test. -%%% get_testspec_terms() -> case ct_util:get_testdata(testspec) of undefined -> @@ -515,25 +151,6 @@ get_testspec_terms() -> ct_testspec:testspec_rec2list(CurrSpecRec) end. -%%%----------------------------------------------------------------- -%%% @spec get_testspec_terms(Tags) -> TestSpecTerms | undefined -%%% Tags = [Tag] | Tag -%%% Tag = atom() -%%% TestSpecTerms = [{Tag,Value}] | {Tag,Value} -%%% Value = [{Node,term()}] | [term()] -%%% Node = atom() -%%% -%%% @doc Read one or more terms from the test specification used -%%% to configure and run this test. Tag is any valid test specification -%%% tag, such as e.g. label, config, logdir. -%%% User specific terms are also available to read if the -%%% allow_user_terms option has been set. Note that all value tuples -%%% returned, except user terms, will have the node name as first element. -%%% Note also that in order to read test terms, use Tag = tests -%%% (rather than suites, groups or cases). Value is -%%% then the list of *all* tests on the form: -%%% [{Node,Dir,[{TestSpec,GroupsAndCases1},...]},...], where -%%% GroupsAndCases = [{Group,[Case]}] | [Case]. get_testspec_terms(Tags) -> case ct_util:get_testdata(testspec) of undefined -> @@ -542,24 +159,9 @@ get_testspec_terms(Tags) -> ct_testspec:testspec_rec2list(Tags, CurrSpecRec) end. - -%%%----------------------------------------------------------------- -%%% @spec escape_chars(IoList1) -> IoList2 | {error,Reason} -%%% IoList1 = iolist() -%%% IoList2 = iolist() -%%% -%%% @doc Escape special characters to be printed in html log -%%% escape_chars(IoList) -> ct_logs:escape_chars(IoList). -%%%----------------------------------------------------------------- -%%% @spec escape_chars(Format, Args) -> IoList | {error,Reason} -%%% Format = string() -%%% Args = list() -%%% -%%% @doc Escape special characters to be printed in html log -%%% escape_chars(Format, Args) -> try io_lib:format(Format, Args) of IoList -> @@ -569,17 +171,9 @@ escape_chars(Format, Args) -> {error,Reason} end. -%%%----------------------------------------------------------------- -%%% @spec log(Format) -> ok -%%% @equiv log(default,50,Format,[],[]) log(Format) -> log(default,?STD_IMPORTANCE,Format,[],[]). -%%%----------------------------------------------------------------- -%%% @spec log(X1,X2) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Format | Args -%%% @equiv log(Category,Importance,Format,Args,[]) log(X1,X2) -> {Category,Importance,Format,Args} = if is_atom(X1) -> {X1,?STD_IMPORTANCE,X2,[]}; @@ -588,12 +182,6 @@ log(X1,X2) -> end, log(Category,Importance,Format,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec log(X1,X2,X3) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Importance | Format | Args -%%% X3 = Format | Args | Opts -%%% @equiv log(Category,Importance,Format,Args,Opts) log(X1,X2,X3) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[],[]}; @@ -603,13 +191,6 @@ log(X1,X2,X3) -> end, log(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec log(X1,X2,X3,X4) -> ok -%%% X1 = Category | Importance -%%% X2 = Importance | Format -%%% X3 = Format | Args -%%% X4 = Args | Opts -%%% @equiv log(Category,Importance,Format,Args,Opts) log(X1,X2,X3,X4) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,X4,[]}; @@ -618,40 +199,12 @@ log(X1,X2,X3,X4) -> end, log(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec log(Category,Importance,Format,Args,Opts) -> ok -%%% Category = atom() -%%% Importance = integer() -%%% Format = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {heading,string()} | esc_chars | no_css -%%% -%%% @doc Printout from a test case to the log file. -%%% -%%%

This function is meant for printing a string directly from a -%%% test case to the test case log file.

-%%% -%%%

Default Category is default, -%%% default Importance is ?STD_IMPORTANCE, -%%% and default value for Args is [].

-%%%

Please see the User's Guide for details on Category -%%% and Importance.

log(Category,Importance,Format,Args,Opts) -> ct_logs:tc_log(Category,Importance,Format,Args,Opts). - -%%%----------------------------------------------------------------- -%%% @spec print(Format) -> ok -%%% @equiv print(default,50,Format,[],[]) print(Format) -> print(default,?STD_IMPORTANCE,Format,[],[]). -%%%----------------------------------------------------------------- -%%% @spec print(X1,X2) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Format | Args -%%% @equiv print(Category,Importance,Format,Args,[]) print(X1,X2) -> {Category,Importance,Format,Args} = if is_atom(X1) -> {X1,?STD_IMPORTANCE,X2,[]}; @@ -660,12 +213,6 @@ print(X1,X2) -> end, print(Category,Importance,Format,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec print(X1,X2,X3) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Importance | Format | Args -%%% X3 = Format | Args | Opts -%%% @equiv print(Category,Importance,Format,Args,Opts) print(X1,X2,X3) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[],[]}; @@ -675,13 +222,6 @@ print(X1,X2,X3) -> end, print(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec print(X1,X2,X3,X4) -> ok -%%% X1 = Category | Importance -%%% X2 = Importance | Format -%%% X3 = Format | Args -%%% X4 = Args | Opts -%%% @equiv print(Category,Importance,Format,Args,Opts) print(X1,X2,X3,X4) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,X4,[]}; @@ -690,40 +230,12 @@ print(X1,X2,X3,X4) -> end, print(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec print(Category,Importance,Format,Args,Opts) -> ok -%%% Category = atom() -%%% Importance = integer() -%%% Format = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {heading,string()} -%%% -%%% @doc Printout from a test case to the console. -%%% -%%%

This function is meant for printing a string from a test case -%%% to the console.

-%%% -%%%

Default Category is default, -%%% default Importance is ?STD_IMPORTANCE, -%%% and default value for Args is [].

-%%%

Please see the User's Guide for details on Category -%%% and Importance.

print(Category,Importance,Format,Args,Opts) -> ct_logs:tc_print(Category,Importance,Format,Args,Opts). - -%%%----------------------------------------------------------------- -%%% @spec pal(Format) -> ok -%%% @equiv pal(default,50,Format,[],[]) pal(Format) -> pal(default,?STD_IMPORTANCE,Format,[]). -%%%----------------------------------------------------------------- -%%% @spec pal(X1,X2) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Format | Args -%%% @equiv pal(Category,Importance,Format,Args,[]) pal(X1,X2) -> {Category,Importance,Format,Args} = if is_atom(X1) -> {X1,?STD_IMPORTANCE,X2,[]}; @@ -732,12 +244,6 @@ pal(X1,X2) -> end, pal(Category,Importance,Format,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec pal(X1,X2,X3) -> ok -%%% X1 = Category | Importance | Format -%%% X2 = Importance | Format | Args -%%% X3 = Format | Args | Opts -%%% @equiv pal(Category,Importance,Format,Args,Opts) pal(X1,X2,X3) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[],[]}; @@ -747,13 +253,6 @@ pal(X1,X2,X3) -> end, pal(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec pal(X1,X2,X3,X4) -> ok -%%% X1 = Category | Importance -%%% X2 = Importance | Format -%%% X3 = Format | Args -%%% X4 = Args | Opts -%%% @equiv pal(Category,Importance,Format,Args,Opts) pal(X1,X2,X3,X4) -> {Category,Importance,Format,Args,Opts} = if is_atom(X1), is_integer(X2) -> {X1,X2,X3,X4,[]}; @@ -762,91 +261,25 @@ pal(X1,X2,X3,X4) -> end, pal(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec pal(Category,Importance,Format,Args,Opts) -> ok -%%% Category = atom() -%%% Importance = integer() -%%% Format = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {heading,string()} | no_css -%%% -%%% @doc Print and log from a test case. -%%% -%%%

This function is meant for printing a string from a test case, -%%% both to the test case log file and to the console.

-%%% -%%%

Default Category is default, -%%% default Importance is ?STD_IMPORTANCE, -%%% and default value for Args is [].

-%%%

Please see the User's Guide for details on Category -%%% and Importance.

pal(Category,Importance,Format,Args,Opts) -> ct_logs:tc_pal(Category,Importance,Format,Args,Opts). -%%%----------------------------------------------------------------- -%%% @spec set_verbosity(Category, Level) -> ok -%%% Category = default | atom() -%%% Level = integer() -%%% -%%% @doc Set the verbosity level for a category set_verbosity(Category, Level) -> ct_util:set_verbosity({Category,Level}). -%%%----------------------------------------------------------------- -%%% @spec get_verbosity(Category) -> Level | undefined -%%% Category = default | atom() -%%% Level = integer() -%%% -%%% @doc Read the verbosity level for a category get_verbosity(Category) -> ct_util:get_verbosity(Category). -%%%----------------------------------------------------------------- -%%% @spec capture_start() -> ok -%%% -%%% @doc Start capturing all text strings printed to stdout during -%%% execution of the test case. -%%% -%%% @see capture_stop/0 -%%% @see capture_get/1 capture_start() -> test_server:capture_start(). -%%%----------------------------------------------------------------- -%%% @spec capture_stop() -> ok -%%% -%%% @doc Stop capturing text strings (a session started with -%%% capture_start/0). -%%% -%%% @see capture_start/0 -%%% @see capture_get/1 capture_stop() -> test_server:capture_stop(). -%%%----------------------------------------------------------------- -%%% @spec capture_get() -> ListOfStrings -%%% ListOfStrings = [string()] -%%% -%%% @equiv capture_get([default]) capture_get() -> %% remove default log printouts (e.g. ct:log/2 printouts) capture_get([default]). -%%%----------------------------------------------------------------- -%%% @spec capture_get(ExclCategories) -> ListOfStrings -%%% ExclCategories = [atom()] -%%% ListOfStrings = [string()] -%%% -%%% @doc Return and purge the list of text strings buffered -%%% during the latest session of capturing printouts to stdout. -%%% With ExclCategories it's possible to specify -%%% log categories that should be ignored in ListOfStrings. -%%% If ExclCategories = [], no filtering takes place. -%%% -%%% @see capture_start/0 -%%% @see capture_stop/0 -%%% @see log/3 capture_get([ExclCat | ExclCategories]) -> Strs = test_server:capture_get(), CatsStr = [atom_to_list(ExclCat) | @@ -863,12 +296,6 @@ capture_get([ExclCat | ExclCategories]) -> capture_get([]) -> test_server:capture_get(). -%%%----------------------------------------------------------------- -%%% @spec fail(Reason) -> ok -%%% Reason = term() -%%% -%%% @doc Terminate a test case with the given error -%%% Reason. fail(Reason) -> try exit({test_case_failed,Reason}) @@ -881,14 +308,6 @@ fail(Reason) -> erlang:raise(Class, R, Stk) end. -%%%----------------------------------------------------------------- -%%% @spec fail(Format, Args) -> ok -%%% Format = string() -%%% Args = list() -%%% -%%% @doc Terminate a test case with an error message specified -%%% by a format string and a list of values (used as arguments to -%%% io_lib:format/2). fail(Format, Args) -> try io_lib:format(Format, Args) of Str -> @@ -907,16 +326,6 @@ fail(Format, Args) -> exit({BadArgs,{?MODULE,fail,[Format,Args]}}) end. -%%%----------------------------------------------------------------- -%%% @spec comment(Comment) -> ok -%%% Comment = term() -%%% -%%% @doc Print the given Comment in the comment field in -%%% the table on the test suite result page. -%%% -%%%

If called several times, only the last comment is printed. -%%% The test case return value {comment,Comment} -%%% overwrites the string set by this function.

comment(Comment) when is_list(Comment) -> Formatted = case (catch io_lib:format("~ts",[Comment])) of @@ -930,19 +339,6 @@ comment(Comment) -> Formatted = io_lib:format("~tp",[Comment]), send_html_comment(lists:flatten(Formatted)). -%%%----------------------------------------------------------------- -%%% @spec comment(Format, Args) -> ok -%%% Format = string() -%%% Args = list() -%%% -%%% @doc Print the formatted string in the comment field in -%%% the table on the test suite result page. -%%% -%%%

The Format and Args arguments are -%%% used in call to io_lib:format/2 in order to create -%%% the comment string. The behaviour of comment/2 is -%%% otherwise the same as the comment/1 function (see -%%% above for details).

comment(Format, Args) when is_list(Format), is_list(Args) -> Formatted = case (catch io_lib:format(Format, Args)) of @@ -958,28 +354,12 @@ send_html_comment(Comment) -> ct_util:set_testdata({{comment,group_leader()},Html}), test_server:comment(Html). -%%%----------------------------------------------------------------- -%%% @spec make_priv_dir() -> ok | {error,Reason} -%%% Reason = term() -%%% @doc If the test has been started with the create_priv_dir -%%% option set to manual_per_tc, in order for the test case to use -%%% the private directory, it must first create it by calling -%%% this function. make_priv_dir() -> test_server:make_priv_dir(). -%%%----------------------------------------------------------------- -%%% @spec get_target_name(Handle) -> {ok,TargetName} | {error,Reason} -%%% Handle = handle() -%%% TargetName = target_name() -%%% @doc Return the name of the target that the given connection -%%% belongs to. get_target_name(Handle) -> ct_util:get_target_name(Handle). -%%%----------------------------------------------------------------- -%%% @doc Return the command used to start (this) erlang - -spec get_progname() -> string(). get_progname() -> @@ -990,44 +370,12 @@ get_progname() -> "no_prog_name" end. -%%%----------------------------------------------------------------- -%%% @spec parse_table(Data) -> {Heading,Table} -%%% Data = [string()] -%%% Heading = tuple() -%%% Table = [tuple()] -%%% -%%% @doc Parse the printout from an SQL table and return a list of tuples. -%%% -%%%

The printout to parse would typically be the result of a -%%% select command in SQL. The returned -%%% Table is a list of tuples, where each tuple is a row -%%% in the table.

-%%% -%%%

Heading is a tuple of strings representing the -%%% headings of each column in the table.

parse_table(Data) -> ct_util:parse_table(Data). -%%%----------------------------------------------------------------- -%%% @spec listenv(Telnet) -> [Env] -%%% Telnet = term() -%%% Env = {Key,Value} -%%% Key = string() -%%% Value = string() -%%% -%%% @doc Performs the listenv command on the given telnet connection -%%% and returns the result as a list of Key-Value pairs. listenv(Telnet) -> ct_util:listenv(Telnet). -%%%----------------------------------------------------------------- -%%% @spec testcases(TestDir, Suite) -> Testcases | {error,Reason} -%%% TestDir = string() -%%% Suite = atom() -%%% Testcases = list() -%%% Reason = term() -%%% -%%% @doc Returns all test cases in the specified suite. testcases(TestDir, Suite) -> case make_and_load(TestDir, Suite) of E = {error,_} -> @@ -1067,15 +415,6 @@ make_and_load(Dir, Suite) -> end end. -%%%----------------------------------------------------------------- -%%% @spec userdata(TestDir, Suite) -> SuiteUserData | {error,Reason} -%%% TestDir = string() -%%% Suite = atom() -%%% SuiteUserData = [term()] -%%% Reason = term() -%%% -%%% @doc Returns any data specified with the tag userdata -%%% in the list of tuples returned from Suite:suite/0. userdata(TestDir, Suite) -> case make_and_load(TestDir, Suite) of E = {error,_} -> @@ -1101,18 +440,6 @@ get_userdata(List, _) when is_list(List) -> get_userdata(_BadTerm, Spec) -> {error,list_to_atom(Spec ++ " must return a list")}. -%%%----------------------------------------------------------------- -%%% @spec userdata(TestDir, Suite, GroupOrCase) -> TCUserData | {error,Reason} -%%% TestDir = string() -%%% Suite = atom() -%%% GroupOrCase = {group,GroupName} | atom() -%%% GroupName = atom() -%%% TCUserData = [term()] -%%% Reason = term() -%%% -%%% @doc Returns any data specified with the tag userdata -%%% in the list of tuples returned from Suite:group(GroupName) -%%% or Suite:Case(). userdata(TestDir, Suite, {group,GroupName}) -> case make_and_load(TestDir, Suite) of E = {error,_} -> @@ -1131,27 +458,6 @@ userdata(TestDir, Suite, Case) when is_atom(Case) -> get_userdata(Info, atom_to_list(Case)++"/0") end. - -%%%----------------------------------------------------------------- -%%% @spec get_status() -> TestStatus | {error,Reason} | no_tests_running -%%% TestStatus = [StatusElem] -%%% StatusElem = {current,TestCaseInfo} | {successful,Successful} | -%%% {failed,Failed} | {skipped,Skipped} | {total,Total} -%%% TestCaseInfo = {Suite,TestCase} | [{Suite,TestCase}] -%%% Suite = atom() -%%% TestCase = atom() -%%% Successful = integer() -%%% Failed = integer() -%%% Skipped = {UserSkipped,AutoSkipped} -%%% UserSkipped = integer() -%%% AutoSkipped = integer() -%%% Total = integer() -%%% Reason = term() -%%% -%%% @doc Returns status of ongoing test. The returned list contains info about -%%% which test case is currently executing (a list of cases when a -%%% parallel test case group is executing), as well as counters for -%%% successful, failed, skipped, and total test cases so far. get_status() -> case get_testdata(curr_tc) of {ok,TestCase} -> @@ -1183,176 +489,37 @@ get_testdata(Key) -> {ok,Data} end. -%%%----------------------------------------------------------------- -%%% @spec abort_current_testcase(Reason) -> ok | {error,ErrorReason} -%%% Reason = term() -%%% ErrorReason = no_testcase_running | parallel_group -%%% -%%% @doc

When calling this function, the currently executing test case will be aborted. -%%% It is the user's responsibility to know for sure which test case is currently -%%% executing. The function is therefore only safe to call from a function which -%%% has been called (or synchronously invoked) by the test case.

-%%% -%%%

Reason, the reason for aborting the test case, is printed -%%% in the test case log.

abort_current_testcase(Reason) -> test_server_ctrl:abort_current_testcase(Reason). -%%%----------------------------------------------------------------- -%%% @spec get_event_mgr_ref() -> EvMgrRef -%%% EvMgrRef = atom() -%%% -%%% @doc

Call this function in order to get a reference to the -%%% CT event manager. The reference can be used to e.g. add -%%% a user specific event handler while tests are running. -%%% Example: -%%% gen_event:add_handler(ct:get_event_mgr_ref(), my_ev_h, [])

get_event_mgr_ref() -> ?CT_EVMGR_REF. -%%%----------------------------------------------------------------- -%%% @spec encrypt_config_file(SrcFileName, EncryptFileName) -> -%%% ok | {error,Reason} -%%% SrcFileName = string() -%%% EncryptFileName = string() -%%% Reason = term() -%%% -%%% @doc

This function encrypts the source config file with DES3 and -%%% saves the result in file EncryptFileName. The key, -%%% a string, must be available in a text file named -%%% .ct_config.crypt in the current directory, or the -%%% home directory of the user (it is searched for in that order).

-%%%

See the Common Test User's Guide for information about using -%%% encrypted config files when running tests.

-%%%

See the crypto application for details on DES3 -%%% encryption/decryption.

encrypt_config_file(SrcFileName, EncryptFileName) -> ct_config:encrypt_config_file(SrcFileName, EncryptFileName). -%%%----------------------------------------------------------------- -%%% @spec encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) -> -%%% ok | {error,Reason} -%%% SrcFileName = string() -%%% EncryptFileName = string() -%%% KeyOrFile = {key,string()} | {file,string()} -%%% Reason = term() -%%% -%%% @doc

This function encrypts the source config file with DES3 and -%%% saves the result in the target file EncryptFileName. -%%% The encryption key to use is either the value in -%%% {key,Key} or the value stored in the file specified -%%% by {file,File}.

-%%%

See the Common Test User's Guide for information about using -%%% encrypted config files when running tests.

-%%%

See the crypto application for details on DES3 -%%% encryption/decryption.

encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) -> ct_config:encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile). -%%%----------------------------------------------------------------- -%%% @spec decrypt_config_file(EncryptFileName, TargetFileName) -> -%%% ok | {error,Reason} -%%% EncryptFileName = string() -%%% TargetFileName = string() -%%% Reason = term() -%%% -%%% @doc

This function decrypts EncryptFileName, previously -%%% generated with encrypt_config_file/2/3. The original -%%% file contents is saved in the target file. The encryption key, a -%%% string, must be available in a text file named -%%% .ct_config.crypt in the current directory, or the -%%% home directory of the user (it is searched for in that order).

decrypt_config_file(EncryptFileName, TargetFileName) -> ct_config:decrypt_config_file(EncryptFileName, TargetFileName). -%%%----------------------------------------------------------------- -%%% @spec decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) -> -%%% ok | {error,Reason} -%%% EncryptFileName = string() -%%% TargetFileName = string() -%%% KeyOrFile = {key,string()} | {file,string()} -%%% Reason = term() -%%% -%%% @doc

This function decrypts EncryptFileName, previously -%%% generated with encrypt_config_file/2/3. The original -%%% file contents is saved in the target file. The key must have the -%%% the same value as that used for encryption.

decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) -> ct_config:decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile). - -%%%----------------------------------------------------------------- -%%% @spec add_config(Callback, Config) -> ok | {error, Reason} -%%% Callback = atom() -%%% Config = string() -%%% Reason = term() -%%% -%%% @doc

This function loads configuration variables using the -%%% given callback module and configuration string. Callback module -%%% should be either loaded or present in the code part. Loaded -%%% configuration variables can later be removed using -%%% remove_config/2 function.

add_config(Callback, Config)-> ct_config:add_config(Callback, Config). -%%%----------------------------------------------------------------- -%%% @spec remove_config(Callback, Config) -> ok -%%% Callback = atom() -%%% Config = string() -%%% Reason = term() -%%% -%%% @doc

This function removes configuration variables (together with -%%% their aliases) which were loaded with specified callback module and -%%% configuration string.

remove_config(Callback, Config) -> ct_config:remove_config(Callback, Config). -%%%----------------------------------------------------------------- -%%% @spec timetrap(Time) -> ok -%%% Time = {hours,Hours} | {minutes,Mins} | {seconds,Secs} | Millisecs | infinity | Func -%%% Hours = integer() -%%% Mins = integer() -%%% Secs = integer() -%%% Millisecs = integer() | float() -%%% Func = {M,F,A} | fun() -%%% M = atom() -%%% F = atom() -%%% A = list() -%%% -%%% @doc

Use this function to set a new timetrap for the running test case. -%%% If the argument is Func, the timetrap will be triggered -%%% when this function returns. Func may also return a new -%%% Time value, which in that case will be the value for the -%%% new timetrap.

timetrap(Time) -> test_server:timetrap_cancel(), test_server:timetrap(Time). -%%%----------------------------------------------------------------- -%%% @spec get_timetrap_info() -> {Time,Scale} -%%% Time = integer() | infinity -%%% Scale = true | false -%%% -%%% @doc

Read info about the timetrap set for the current test case. -%%% Scale indicates if Common Test will attempt to automatically -%%% compensate timetraps for runtime delays introduced by e.g. tools like -%%% cover.

get_timetrap_info() -> test_server:get_timetrap_info(). -%%%----------------------------------------------------------------- -%%% @spec sleep(Time) -> ok -%%% Time = {hours,Hours} | {minutes,Mins} | {seconds,Secs} | Millisecs | infinity -%%% Hours = integer() -%%% Mins = integer() -%%% Secs = integer() -%%% Millisecs = integer() | float() -%%% -%%% @doc

This function, similar to timer:sleep/1, suspends the test -%%% case for specified time. However, this function also multiplies -%%% Time with the 'multiply_timetraps' value (if set) and under -%%% certain circumstances also scales up the time automatically -%%% if 'scale_timetraps' is set to true (default is false).

sleep({hours,Hs}) -> sleep(trunc(Hs * 1000 * 60 * 60)); sleep({minutes,Ms}) -> @@ -1362,52 +529,12 @@ sleep({seconds,Ss}) -> sleep(Time) -> test_server:adjusted_sleep(Time). -%%%----------------------------------------------------------------- -%%% @spec notify(Name,Data) -> ok -%%% Name = atom() -%%% Data = term() -%%% -%%% @doc

Sends a asynchronous notification of type Name with -%%% Datato the common_test event manager. This can later be -%%% caught by any installed event manager.

-%%% @see //stdlib/gen_event notify(Name,Data) -> ct_event:notify(Name, Data). -%%%----------------------------------------------------------------- -%%% @spec sync_notify(Name,Data) -> ok -%%% Name = atom() -%%% Data = term() -%%% -%%% @doc

Sends a synchronous notification of type Name with -%%% Datato the common_test event manager. This can later be -%%% caught by any installed event manager.

-%%% @see //stdlib/gen_event sync_notify(Name,Data) -> ct_event:sync_notify(Name, Data). -%%%----------------------------------------------------------------- -%%% @spec break(Comment) -> ok | {error,Reason} -%%% Comment = string() -%%% Reason = {multiple_cases_running,TestCases} | -%%% 'enable break with release_shell option' -%%% TestCases = [atom()] -%%% -%%% @doc

This function will cancel any active timetrap and pause the -%%% execution of the current test case until the user calls the -%%% continue/0 function. It gives the user the opportunity -%%% to interact with the erlang node running the tests, e.g. for -%%% debugging purposes or for manually executing a part of the -%%% test case. If a parallel group is executing, break/2 -%%% should be called instead.

-%%%

A cancelled timetrap will not be automatically -%%% reactivated after the break, but must be started exlicitly with -%%% ct:timetrap/1

-%%%

In order for the break/continue functionality to work, -%%% Common Test must release the shell process controlling stdin. -%%% This is done by setting the release_shell start option -%%% to true. See the User's Guide for more information.

- break(Comment) -> case {ct_util:get_testdata(starter), ct_util:get_testdata(release_shell)} of @@ -1430,19 +557,6 @@ break(Comment) -> end end. -%%%----------------------------------------------------------------- -%%% @spec break(TestCase, Comment) -> ok | {error,Reason} -%%% TestCase = atom() -%%% Comment = string() -%%% Reason = 'test case not running' | -%%% 'enable break with release_shell option' -%%% -%%% @doc

This function works the same way as break/1, -%%% only the TestCase argument makes it possible to -%%% pause a test case executing in a parallel group. The -%%% continue/1 function should be used to resume -%%% execution of TestCase.

-%%%

See break/1 for more details.

break(TestCase, Comment) -> case {ct_util:get_testdata(starter), ct_util:get_testdata(release_shell)} of @@ -1469,56 +583,12 @@ break(TestCase, Comment) -> end end. -%%%----------------------------------------------------------------- -%%% @spec continue() -> ok -%%% -%%% @doc

This function must be called in order to continue after a -%%% test case (not executing in a parallel group) has called -%%% break/1.

continue() -> test_server:continue(). -%%%----------------------------------------------------------------- -%%% @spec continue(TestCase) -> ok -%%% TestCase = atom() -%%% -%%% @doc

This function must be called in order to continue after a -%%% test case has called break/2. If the paused test case, -%%% TestCase, executes in a parallel group, this -%%% function - rather than continue/0 - must be used -%%% in order to let the test case proceed.

continue(TestCase) -> test_server:continue(TestCase). -%%%----------------------------------------------------------------- -%%% @spec remaining_test_procs() -> {TestProcs,SharedGL,OtherGLs} -%%% TestProcs = [{pid(),GL}] -%%% GL = SharedGL = pid() -%%% OtherGLs = [pid()] -%%% -%%% @doc

This function will return the identity of test- and group -%%% leader processes that are still running at the time of this call. -%%% TestProcs are processes in the system that have a Common Test IO -%%% process as group leader. SharedGL is the central Common Test -%%% IO process, responsible for printing to log files for configuration -%%% functions and sequentially executing test cases. OtherGLs are -%%% Common Test IO processes that print to log files for test cases -%%% in parallel test case groups.

-%%%

The process information returned by this function may be -%%% used to locate and terminate remaining processes after tests have -%%% finished executing. The function would typically by called from -%%% Common Test Hook functions.

-%%%

Note that processes that execute configuration functions or -%%% test cases are never included in TestProcs. It is therefore safe -%%% to use post configuration hook functions (such as post_end_per_suite, -%%% post_end_per_group, post_end_per_testcase) to terminate all processes -%%% in TestProcs that have the current group leader process as its group -%%% leader.

-%%%

Note also that the shared group leader (SharedGL) must never be -%%% terminated by the user, only by Common Test. Group leader processes -%%% for parallel test case groups (OtherGLs) may however be terminated -%%% in post_end_per_group hook functions.

-%%% remaining_test_procs() -> ct_util:remaining_test_procs(). diff --git a/lib/common_test/src/ct_cover.erl b/lib/common_test/src/ct_cover.erl index c258516915..d286f20a4d 100644 --- a/lib/common_test/src/ct_cover.erl +++ b/lib/common_test/src/ct_cover.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2016. All Rights Reserved. +%% Copyright Ericsson AB 2006-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. @@ -18,11 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework code coverage support module. -%%% -%%%

This module exports help functions for performing code -%%% coverage analysis.

- -module(ct_cover). -export([get_spec/1, add_nodes/1, remove_nodes/1, cross_cover_analyse/2]). @@ -31,16 +26,6 @@ -include_lib("kernel/include/file.hrl"). -%%%----------------------------------------------------------------- -%%% @spec add_nodes(Nodes) -> {ok,StartedNodes} | {error,Reason} -%%% Nodes = [atom()] -%%% StartedNodes = [atom()] -%%% Reason = cover_not_running | not_main_node -%%% -%%% @doc Add nodes to current cover test (only works if cover support -%%% is active!). To have effect, this function should be called -%%% from init_per_suite/1 before any actual tests are performed. -%%% add_nodes([]) -> {ok,[]}; add_nodes(Nodes) -> @@ -67,17 +52,6 @@ add_nodes(Nodes) -> end end. - -%%%----------------------------------------------------------------- -%%% @spec remove_nodes(Nodes) -> ok | {error,Reason} -%%% Nodes = [atom()] -%%% Reason = cover_not_running | not_main_node -%%% -%%% @doc Remove nodes from current cover test. Call this function -%%% to stop cover test on nodes previously added with add_nodes/1. -%%% Results on the remote node are transferred to the Common Test -%%% node. -%%% remove_nodes([]) -> ok; remove_nodes(Nodes) -> @@ -103,25 +77,11 @@ remove_nodes(Nodes) -> end end. - -%%%----------------------------------------------------------------- -%%% @spec cross_cover_analyse(Level,Tests) -> ok -%%% Level = overview | details -%%% Tests = [{Tag,Dir}] -%%% Tag = atom() -%%% Dir = string() -%%% -%%% @doc Accumulate cover results over multiple tests. -%%% See the chapter about cross cover -%%% analysis in the users's guide. -%%% cross_cover_analyse(Level,Tests) -> test_server_ctrl:cross_cover_analyse(Level,Tests). %%%----------------------------------------------------------------- -%%% @hidden %% Read cover specification file and return the parsed info. %% -> CoverSpec: {CoverFile,Nodes,Import,Export,AppCoverInfo} diff --git a/lib/common_test/src/ct_ftp.erl b/lib/common_test/src/ct_ftp.erl index 8b02ae3a0f..93d1f88041 100644 --- a/lib/common_test/src/ct_ftp.erl +++ b/lib/common_test/src/ct_ftp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-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. @@ -18,12 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc FTP client module (based on the FTP application). -%%% -%%% @type connection() = handle() | ct:target_name() -%%% @type handle() = ct_gen_conn:handle(). Handle for a specific -%%% ftp connection. - -module(ct_ftp). %% API @@ -42,76 +36,14 @@ %%%================================================================= %%% API -%%%----------------------------------------------------------------- -%%% @spec put(KeyOrName,LocalFile,RemoteFile) -> ok | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% LocalFile = string() -%%% RemoteFile = string() -%%% -%%% @doc Open a ftp connection and send a file to the remote host. -%%% -%%%

LocalFile and RemoteFile must be -%%% absolute paths.

-%%% -%%%

If the target host is a "special" node, the ftp address must be -%%% specified in the config file like this:

-%%%
-%%% {node,[{ftp,IpAddr}]}.
-%%% -%%%

If the target host is something else, e.g. a unix host, the -%%% config file must also include the username and password (both -%%% strings):

-%%%
-%%% {unix,[{ftp,IpAddr},
-%%%        {username,Username},
-%%%        {password,Password}]}.
-%%% @see ct:require/2 put(KeyOrName,LocalFile,RemoteFile) -> Fun = fun(Ftp) -> send(Ftp,LocalFile,RemoteFile) end, open_and_do(KeyOrName,Fun). -%%%----------------------------------------------------------------- -%%% @spec get(KeyOrName,RemoteFile,LocalFile) -> ok | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% RemoteFile = string() -%%% LocalFile = string() -%%% -%%% @doc Open a ftp connection and fetch a file from the remote host. -%%% -%%%

RemoteFile and LocalFile must be -%%% absolute paths.

-%%% -%%%

The config file must be as for put/3.

-%%% @see put/3 -%%% @see ct:require/2 get(KeyOrName,RemoteFile,LocalFile) -> Fun = fun(Ftp) -> recv(Ftp,RemoteFile,LocalFile) end, open_and_do(KeyOrName,Fun). - -%%%----------------------------------------------------------------- -%%% @spec open(KeyOrName) -> {ok,Handle} | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% Handle = handle() -%%% -%%% @doc Open an FTP connection to the specified node. -%%%

You can open one connection for a particular Name and -%%% use the same name as reference for all subsequent operations. If you -%%% want the connection to be associated with Handle instead -%%% (in case you need to open multiple connections to a host for example), -%%% simply use Key, the configuration variable name, to -%%% specify the target. Note that a connection that has no associated target -%%% name can only be closed with the handle value.

-%%% -%%%

See ct:require/2 for how to create a new Name

-%%% -%%% @see ct:require/2 open(KeyOrName) -> case ct_util:get_key_from_name(KeyOrName) of {ok,node} -> @@ -152,25 +84,9 @@ open(KeyOrName,Username,Password) -> ct_gen_conn:start(KeyOrName,full_addr(Addr),{Username,Password},?MODULE) end. - -%%%----------------------------------------------------------------- -%%% @spec send(Connection,LocalFile) -> ok | {error,Reason} -%%% -%%% @doc Send a file over FTP. -%%%

The file will get the same name on the remote host.

-%%% @see send/3 send(Connection,LocalFile) -> send(Connection,LocalFile,filename:basename(LocalFile)). -%%%----------------------------------------------------------------- -%%% @spec send(Connection,LocalFile,RemoteFile) -> ok | {error,Reason} -%%% Connection = connection() -%%% LocalFile = string() -%%% RemoteFile = string() -%%% -%%% @doc Send a file over FTP. -%%% -%%%

The file will be named RemoteFile on the remote host.

send(Connection,LocalFile,RemoteFile) -> case get_handle(Connection) of {ok,Pid} -> @@ -179,24 +95,9 @@ send(Connection,LocalFile,RemoteFile) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec recv(Connection,RemoteFile) -> ok | {error,Reason} -%%% -%%% @doc Fetch a file over FTP. -%%%

The file will get the same name on the local host.

-%%% @see recv/3 recv(Connection,RemoteFile) -> recv(Connection,RemoteFile,filename:basename(RemoteFile)). -%%%----------------------------------------------------------------- -%%% @spec recv(Connection,RemoteFile,LocalFile) -> ok | {error,Reason} -%%% Connection = connection() -%%% RemoteFile = string() -%%% LocalFile = string() -%%% -%%% @doc Fetch a file over FTP. -%%% -%%%

The file will be named LocalFile on the local host.

recv(Connection,RemoteFile,LocalFile) -> case get_handle(Connection) of {ok,Pid} -> @@ -205,12 +106,6 @@ recv(Connection,RemoteFile,LocalFile) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec cd(Connection,Dir) -> ok | {error,Reason} -%%% Connection = connection() -%%% Dir = string() -%%% -%%% @doc Change directory on remote host. cd(Connection,Dir) -> case get_handle(Connection) of {ok,Pid} -> @@ -219,13 +114,6 @@ cd(Connection,Dir) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec ls(Connection,Dir) -> {ok,Listing} | {error,Reason} -%%% Connection = connection() -%%% Dir = string() -%%% Listing = string() -%%% -%%% @doc List the directory Dir. ls(Connection,Dir) -> case get_handle(Connection) of {ok,Pid} -> @@ -234,12 +122,6 @@ ls(Connection,Dir) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec type(Connection,Type) -> ok | {error,Reason} -%%% Connection = connection() -%%% Type = ascii | binary -%%% -%%% @doc Change file transfer type type(Connection,Type) -> case get_handle(Connection) of {ok,Pid} -> @@ -248,12 +130,6 @@ type(Connection,Type) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec delete(Connection,File) -> ok | {error,Reason} -%%% Connection = connection() -%%% File = string() -%%% -%%% @doc Delete a file on remote host delete(Connection,File) -> case get_handle(Connection) of {ok,Pid} -> @@ -262,11 +138,6 @@ delete(Connection,File) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec close(Connection) -> ok | {error,Reason} -%%% Connection = connection() -%%% -%%% @doc Close the FTP connection. close(Connection) -> case get_handle(Connection) of {ok,Pid} -> @@ -279,7 +150,6 @@ close(Connection) -> %%%================================================================= %%% Callback functions -%% @hidden init(KeyOrName,{IP,Port},{Username,Password}) -> case ftp_connect(IP,Port,Username,Password) of {ok,FtpPid} -> @@ -305,7 +175,6 @@ ftp_connect(IP,Port,Username,Password) -> {error,{open,Reason}} end. -%% @hidden handle_msg({send,LocalFile,RemoteFile},State) -> log(heading(send,State#state.target_name), "LocalFile: ~tp\nRemoteFile: ~tp\n",[LocalFile,RemoteFile]), @@ -333,11 +202,9 @@ handle_msg({delete,File},State) -> Result = ftp:delete(State#state.ftp_pid,File), {Result,State}. -%% @hidden reconnect(_Addr,_State) -> {error,no_reconnection_of_ftp}. -%% @hidden terminate(FtpPid,State) -> log(heading(terminate,State#state.target_name), "Closing FTP connection.\nHandle: ~p\n",[FtpPid]), diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl index bb33f0243b..49587b3edd 100644 --- a/lib/common_test/src/ct_hooks.erl +++ b/lib/common_test/src/ct_hooks.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%% Copyright Ericsson AB 2004-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. @@ -18,10 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework test execution control module. -%%% -%%%

This module is a proxy for calling and handling common test hooks.

- -module(ct_hooks). %% API Exports @@ -47,14 +43,12 @@ %% API Functions %% ------------------------------------------------------------------------- -%% @doc Called before any suites are started -spec init(State :: term()) -> ok | {fail, Reason :: term()}. init(Opts) -> call(get_builtin_hooks(Opts) ++ get_new_hooks(Opts, undefined), ok, init, []). -%% @doc Called after all suites are done. -spec terminate(Hooks :: term()) -> ok. terminate(Hooks) -> @@ -63,8 +57,6 @@ terminate(Hooks) -> ct_hooks_terminate_dummy, terminate, Hooks), ok. -%% @doc Called as each test case is started. This includes all configuration -%% tests. -spec init_tc(Mod :: atom(), FuncSpec :: atom() | {ConfigFunc :: init_per_testcase | end_per_testcase, @@ -104,8 +96,6 @@ init_tc(Mod, {end_per_testcase,TC}, Config) -> init_tc(Mod, TC = error_in_suite, Config) -> call(fun call_generic_fallback/3, Config, [pre_init_per_testcase, Mod, TC]). -%% @doc Called as each test case is completed. This includes all configuration -%% tests. -spec end_tc(Mod :: atom(), FuncSpec :: atom() | {ConfigFunc :: init_per_testcase | end_per_testcase, diff --git a/lib/common_test/src/ct_master.erl b/lib/common_test/src/ct_master.erl index e2ea525cdd..fd33ee2280 100644 --- a/lib/common_test/src/ct_master.erl +++ b/lib/common_test/src/ct_master.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2017. All Rights Reserved. +%% Copyright Ericsson AB 2006-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. @@ -18,9 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Distributed test execution control for Common Test. -%%%

This module exports functions for running Common Test nodes -%%% on multiple hosts in parallel.

-module(ct_master). -export([run/1,run/3,run/4]). @@ -45,50 +42,14 @@ blocked=[] }). -%%%----------------------------------------------------------------- -%%% @spec run_test(Node,Opts) -> ok -%%% Node = atom() -%%% Opts = [OptTuples] -%%% OptTuples = {config,CfgFiles} | {dir,TestDirs} | {suite,Suites} | -%%% {testcase,Cases} | {spec,TestSpecs} | {allow_user_terms,Bool} | -%%% {logdir,LogDir} | {event_handler,EventHandlers} | -%%% {silent_connections,Conns} | {cover,CoverSpecFile} | -%%% {cover_stop,Bool} | {userconfig, UserCfgFiles} -%%% CfgFiles = string() | [string()] -%%% TestDirs = string() | [string()] -%%% Suites = atom() | [atom()] -%%% Cases = atom() | [atom()] -%%% TestSpecs = string() | [string()] -%%% LogDir = string() -%%% EventHandlers = EH | [EH] -%%% EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs} -%%% InitArgs = [term()] -%%% Conns = all | [atom()] -%%% -%%% @doc Tests are spawned on Node using ct:run_test/1. run_test(Node,Opts) -> run_test([{Node,Opts}]). -%%% @hidden run_test({Node,Opts}) -> run_test([{Node,Opts}]); run_test(NodeOptsList) when is_list(NodeOptsList) -> start_master(NodeOptsList). -%%%----------------------------------------------------------------- -%%% @spec run(TestSpecs,AllowUserTerms,InclNodes,ExclNodes) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% SeparateOrMerged = string() | [string()] -%%% AllowUserTerms = bool() -%%% InclNodes = [atom()] -%%% ExclNodes = [atom()] -%%% -%%% @doc Tests are spawned on the nodes as specified in TestSpecs. -%%% Each specification in TestSpec will be handled separately. It is however -%%% possible to also specify a list of specifications that should be merged -%%% into one before the tests are executed. Any test without a particular node -%%% specification will also be executed on the nodes in InclNodes. -%%% Nodes in the ExclNodes list will be excluded from the test. run([TS|TestSpecs],AllowUserTerms,InclNodes,ExclNodes) when is_list(TS), is_list(InclNodes), is_list(ExclNodes) -> @@ -128,22 +89,9 @@ run(TS,AllowUserTerms,InclNodes,ExclNodes) when is_list(InclNodes), is_list(ExclNodes) -> run([TS],AllowUserTerms,InclNodes,ExclNodes). -%%%----------------------------------------------------------------- -%%% @spec run(TestSpecs,InclNodes,ExclNodes) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% SeparateOrMerged = string() | [string()] -%%% InclNodes = [atom()] -%%% ExclNodes = [atom()] -%%% -%%% @equiv run(TestSpecs,false,InclNodes,ExclNodes) run(TestSpecs,InclNodes,ExclNodes) -> run(TestSpecs,false,InclNodes,ExclNodes). -%%%----------------------------------------------------------------- -%%% @spec run(TestSpecs) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% -%%% @equiv run(TestSpecs,false,[],[]) run(TestSpecs=[TS|_]) when is_list(TS) -> run(TestSpecs,false,[],[]); run(TS) -> @@ -156,15 +104,6 @@ exclude_nodes([],RunSkipPerNode) -> RunSkipPerNode. -%%%----------------------------------------------------------------- -%%% @spec run_on_node(TestSpecs,AllowUserTerms,Node) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% SeparateOrMerged = string() | [string()] -%%% AllowUserTerms = bool() -%%% Node = atom() -%%% -%%% @doc Tests are spawned on Node according to -%%% TestSpecs. run_on_node([TS|TestSpecs],AllowUserTerms,Node) when is_list(TS),is_atom(Node) -> case catch ct_testspec:collect_tests_from_file([TS],[Node], AllowUserTerms) of @@ -194,13 +133,6 @@ run_on_node([],_,_) -> run_on_node(TS,AllowUserTerms,Node) when is_atom(Node) -> run_on_node([TS],AllowUserTerms,Node). -%%%----------------------------------------------------------------- -%%% @spec run_on_node(TestSpecs,Node) -> ok -%%% TestSpecs = string() | [SeparateOrMerged] -%%% SeparateOrMerged = string() | [string()] -%%% Node = atom() -%%% -%%% @equiv run_on_node(TestSpecs,false,Node) run_on_node(TestSpecs,Node) -> run_on_node(TestSpecs,false,Node). @@ -264,64 +196,25 @@ run_all([],AllLogDirs,_,AllEvHs,_AllIncludes, ok. -%%%----------------------------------------------------------------- -%%% @spec abort() -> ok -%%% -%%% @doc Stops all running tests. abort() -> call(abort). -%%%----------------------------------------------------------------- -%%% @spec abort(Nodes) -> ok -%%% Nodes = atom() | [atom()] -%%% -%%% @doc Stops tests on specified nodes. abort(Nodes) when is_list(Nodes) -> call({abort,Nodes}); abort(Node) when is_atom(Node) -> abort([Node]). -%%%----------------------------------------------------------------- -%%% @spec progress() -> [{Node,Status}] -%%% Node = atom() -%%% Status = finished_ok | ongoing | aborted | {error,Reason} -%%% Reason = term() -%%% -%%% @doc Returns test progress. If Status is ongoing, -%%% tests are running on the node and have not yet finished. progress() -> call(progress). -%%%----------------------------------------------------------------- -%%% @spec get_event_mgr_ref() -> MasterEvMgrRef -%%% MasterEvMgrRef = atom() -%%% -%%% @doc

Call this function in order to get a reference to the -%%% CT master event manager. The reference can be used to e.g. -%%% add a user specific event handler while tests are running. -%%% Example: -%%% gen_event:add_handler(ct_master:get_event_mgr_ref(), my_ev_h, [])

get_event_mgr_ref() -> ?CT_MEVMGR_REF. -%%%----------------------------------------------------------------- -%%% @spec basic_html(Bool) -> ok -%%% Bool = true | false -%%% -%%% @doc If set to true, the ct_master logs will be written on a -%%% primitive html format, not using the Common Test CSS style -%%% sheet. basic_html(Bool) -> application:set_env(common_test_master, basic_html, Bool), ok. -%%%----------------------------------------------------------------- -%%% @spec esc_chars(Bool) -> ok -%%% Bool = true | false -%%% -%%% @doc If set to false, the ct_master logs will be written without -%%% special characters being escaped in the HTML logs. esc_chars(Bool) -> application:set_env(common_test_master, esc_chars, Bool), ok. @@ -340,7 +233,6 @@ start_master(NodeOptsList,EvHandlers,MasterLogDir,LogDirs,InitOptions,Specs) -> {Master,Result} -> Result end. -%%% @hidden init_master(Parent,NodeOptsList,EvHandlers,MasterLogDir,LogDirs, InitOptions,Specs) -> case whereis(ct_master) of @@ -687,7 +579,6 @@ refresh_logs([],Refreshed) -> %%%----------------------------------------------------------------- %%% NODE CONTROLLER, runs and controls tests on a test node. %%%----------------------------------------------------------------- -%%% @hidden init_node_ctrl(MasterPid,Cookie,Opts) -> %% make sure tests proceed even if connection to master is lost process_flag(trap_exit, true), @@ -742,7 +633,6 @@ start_ct_event() -> %%%----------------------------------------------------------------- %%% Event handling %%%----------------------------------------------------------------- -%%% @hidden status(MasterPid,Event=#event{name=start_make}) -> call(MasterPid,Event); status(MasterPid,Event=#event{name=finished_make}) -> diff --git a/lib/common_test/src/ct_property_test.erl b/lib/common_test/src/ct_property_test.erl index 94ccb59af9..f51f454d08 100644 --- a/lib/common_test/src/ct_property_test.erl +++ b/lib/common_test/src/ct_property_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-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. @@ -28,46 +28,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% @doc EXPERIMENTAL support in common-test for calling property based tests. -%%% -%%%

This module is a first step towards running Property Based testing in the -%%% Common Test framework. A property testing tool like QuickCheck or PropEr is -%%% assumed to be installed.

-%%% -%%%

The idea is to have a common_test testsuite calling a property testing -%%% tool with special property test suites as defined by that tool. In this manual -%%% we assume the usual Erlang Application directory structure. The tests are -%%% collected in the application's test directory. The test directory -%%% has a sub-directory called property_test where everything needed for -%%% the property tests are collected.

-%%% -%%%

A typical ct test suite using ct_property_test is organized as follows: -%%%

-%%% ``` -%%% -include_lib("common_test/include/ct.hrl"). -%%% -%%% all() -> [prop_ftp_case]. -%%% -%%% init_per_suite(Config) -> -%%% ct_property_test:init_per_suite(Config). -%%% -%%% %%%---- test case -%%% prop_ftp_case(Config) -> -%%% ct_property_test:quickcheck( -%%% ftp_simple_client_server:prop_ftp(Config), -%%% Config -%%% ). -%%% ''' -%%% -%%% -%%%

-%%% This is experimental code which may be changed or removed -%%% anytime without any warning. -%%%

-%%%
-%%% -%%% @end - -module(ct_property_test). %% API @@ -76,19 +36,6 @@ -include_lib("common_test/include/ct.hrl"). -%%%----------------------------------------------------------------- -%%% @spec init_per_suite(Config) -> Config | {skip,Reason} -%%% -%%% @doc Initializes Config for property testing. -%%% -%%%

The function investigates if support is available for either Quickcheck, PropEr, -%%% or Triq. -%%% The options {property_dir,AbsPath} and -%%% {property_test_tool,Tool} is set in the Config returned.

-%%%

The function is intended to be called in the init_per_suite in the test suite.

-%%%

The property tests are assumed to be in the subdirectory property_test.

-%%% @end - init_per_suite(Config) -> case which_module_exists([eqc,proper,triq]) of {ok,ToolModule} -> @@ -108,14 +55,6 @@ init_per_suite(Config) -> {skip, "No property testing tool found"} end. -%%%----------------------------------------------------------------- -%%% @spec quickcheck(Property, Config) -> true | {fail,Reason} -%%% -%%% @doc Call quickcheck and return the result in a form suitable for common_test. -%%% -%%%

The function is intended to be called in the test cases in the test suite.

-%%% @end - quickcheck(Property, Config) -> Tool = proplists:get_value(property_test_tool,Config), F = function_name(quickcheck, Tool), diff --git a/lib/common_test/src/ct_rpc.erl b/lib/common_test/src/ct_rpc.erl index b4a0bc9d74..cef5ad14e5 100644 --- a/lib/common_test/src/ct_rpc.erl +++ b/lib/common_test/src/ct_rpc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-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. @@ -18,8 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test specific layer on Erlang/OTP rpc. - -module(ct_rpc). %%% API @@ -29,49 +27,12 @@ %%%========================================================================= %%% API %%%========================================================================= -%%% @spec app_node(App, Candidates) -> NodeName -%%% -%%% App = atom() -%%% Candidates = [NodeName] -%%% NodeName = atom() -%%% -%%% @doc From a set of candidate nodes determines which of them is -%%% running the application App. If none of the candidate nodes -%%% is running the application the function will make the test case -%%% calling this function fail. This function is the same as calling -%%% app_node(App, Candidates, true). -%%% app_node(App, Candidates) -> app_node(App, Candidates, true, []). -%%% @spec app_node(App, Candidates, FailOnBadRPC) -> NodeName -%%% -%%% App = atom() -%%% Candidates = [NodeName] -%%% NodeName = atom() -%%% FailOnBadRPC = true | false -%%% -%%% @doc Same as app_node/2 only the FailOnBadRPC -%%% argument will determine if the search for a candidate node should -%%% stop or not if badrpc is received at some point. -%%% app_node(App, Candidates, FailOnBadRPC) -> app_node(App, Candidates, FailOnBadRPC, []). -%%% @spec app_node(App, Candidates, FailOnBadRPC, Cookie) -> NodeName -%%% -%%% App = atom() -%%% Candidates = [NodeName] -%%% NodeName = atom() -%%% FailOnBadRPC = true | false -%%% Cookie = atom() -%%% -%%% @doc Same as app_node/2 only the FailOnBadRPC -%%% argument will determine if the search for a candidate node should -%%% stop or not if badrpc is received at some point. -%%% The cookie on the client node will be set to Cookie -%%% for this rpc operation (use to match the server node cookie). -%%% app_node(App, [], _, _) -> ct:fail({application_not_running, App}); @@ -96,49 +57,12 @@ app_node(App, _Candidates = [CandidateNode | Nodes], FailOnBadRPC, Cookie) -> end end. -%%% @spec call(Node, Module, Function, Args) -> term() | {badrpc, Reason} -%%% -%%% @doc Same as call(Node, Module, Function, Args, infinity) -%%% call(Node, Module, Function, Args) -> call(Node, Module, Function, Args, infinity, []). -%%% @spec call(Node, Module, Function, Args, TimeOut) -> -%%% term() | {badrpc, Reason} -%%% Node = NodeName | {Fun, FunArgs} -%%% Fun = fun() -%%% FunArgs = term() -%%% NodeName = atom() -%%% Module = atom() -%%% Function = atom() -%%% Args = [term()] -%%% Reason = timeout | term() -%%% -%%% @doc Evaluates apply(Module, Function, Args) on the node Node. -%%% Returns whatever Function returns or {badrpc, Reason} if the -%%% remote procedure call fails. If Node is {Fun, FunArgs} applying -%%% Fun to FunArgs should return a node name. call(Node, Module, Function, Args, TimeOut) -> call(Node, Module, Function, Args, TimeOut, []). -%%% @spec call(Node, Module, Function, Args, TimeOut, Cookie) -> -%%% term() | {badrpc, Reason} -%%% Node = NodeName | {Fun, FunArgs} -%%% Fun = fun() -%%% FunArgs = term() -%%% NodeName = atom() -%%% Module = atom() -%%% Function = atom() -%%% Args = [term()] -%%% Reason = timeout | term() -%%% Cookie = atom() -%%% -%%% @doc Evaluates apply(Module, Function, Args) on the node Node. -%%% Returns whatever Function returns or {badrpc, Reason} if the -%%% remote procedure call fails. If Node is {Fun, FunArgs} applying -%%% Fun to FunArgs should return a node name. -%%% The cookie on the client node will be set to Cookie -%%% for this rpc operation (use to match the server node cookie). call({Fun, FunArgs}, Module, Function, Args, TimeOut, Cookie) -> Node = Fun(FunArgs), call(Node, Module, Function, Args, TimeOut, Cookie); @@ -148,42 +72,9 @@ call(Node, Module, Function, Args, TimeOut, Cookie) when is_atom(Node) -> _ = set_the_cookie(Cookie0), Result. -%%% @spec cast(Node, Module, Function, Args) -> ok -%%% Node = NodeName | {Fun, FunArgs} -%%% Fun = fun() -%%% FunArgs = term() -%%% NodeName = atom() -%%% Module = atom() -%%% Function = atom() -%%% Args = [term()] -%%% Reason = timeout | term() -%%% -%%% @doc Evaluates apply(Module, Function, Args) on the node Node. -%%% No response is delivered and the process which makes the call is -%%% not suspended until the evaluation is compleated as in the case of -%%% call/[3,4]. If Node is {Fun, FunArgs} applying -%%% Fun to FunArgs should return a node name. cast(Node, Module, Function, Args) -> cast(Node, Module, Function, Args, []). -%%% @spec cast(Node, Module, Function, Args, Cookie) -> ok -%%% Node = NodeName | {Fun, FunArgs} -%%% Fun = fun() -%%% FunArgs = term() -%%% NodeName = atom() -%%% Module = atom() -%%% Function = atom() -%%% Args = [term()] -%%% Reason = timeout | term() -%%% Cookie = atom() -%%% -%%% @doc Evaluates apply(Module, Function, Args) on the node Node. -%%% No response is delivered and the process which makes the call is -%%% not suspended until the evaluation is compleated as in the case of -%%% call/[3,4]. If Node is {Fun, FunArgs} applying -%%% Fun to FunArgs should return a node name. -%%% The cookie on the client node will be set to Cookie -%%% for this rpc operation (use to match the server node cookie). cast({Fun, FunArgs}, Module, Function, Args, Cookie) -> Node = Fun(FunArgs), cast(Node, Module, Function, Args, Cookie); @@ -196,7 +87,6 @@ cast(Node, Module, Function, Args, Cookie) when is_atom(Node) -> %%%---------- Internal ----------- -%%% @hidden set_the_cookie([]) -> []; set_the_cookie(Cookie) -> diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index afc5fee4f7..223aa06e64 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%% Copyright Ericsson AB 2004-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. @@ -18,11 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework test execution control module. -%%% -%%%

This module exports functions for installing and running tests -%%% withing the Common Test Framework.

- -module(ct_run). %% Script interface @@ -84,17 +79,6 @@ tests, starter}). -%%%----------------------------------------------------------------- -%%% @spec script_start() -> term() -%%% -%%% @doc Start tests via the ct_run program or script. -%%% -%%%

Example:
./ct_run -config config.ctc -dir -%%% $TEST_DIR

-%%% -%%%

Example:
./ct_run -config config.ctc -suite -%%% $SUITE_PATH/$SUITE_NAME [-case $CASE_NAME]

-%%% script_start() -> process_flag(trap_exit, true), Init = init:get_arguments(), @@ -799,9 +783,6 @@ script_start4(#opts{shell = true, cover = Cover}, _) -> script_start4(Opts = #opts{tests = Tests}, Args) -> do_run(Tests, [], Opts, Args). -%%%----------------------------------------------------------------- -%%% @spec script_usage() -> ok -%%% @doc Print usage information for ct_run. script_usage() -> io:format("\nUsage:\n\n"), io:format("Run tests from command line:\n\n" @@ -885,9 +866,6 @@ script_usage() -> "\n\t [-basic_html]" "\n\t [-no_esc_chars]\n\n"). -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:install/1 install(Opts) -> install(Opts, "."). @@ -931,15 +909,6 @@ install(Opts, LogDir) -> variables_file_name(Dir) -> filename:join(Dir, "variables-"++atom_to_list(node())). -%%%----------------------------------------------------------------- -%%% @spec run_test(Opts) -> Result -%%% Opts = [tuple()] -%%% Result = [TestResult] | {error,Reason} -%%% -%%% @doc Start tests from the erlang shell or from an erlang program. -%%% @equiv ct:run_test/1 -%%%----------------------------------------------------------------- - run_test(StartOpt) when is_tuple(StartOpt) -> run_test([StartOpt]); @@ -1427,14 +1396,6 @@ run_dir(Opts = #opts{logdir = LogDir, exit({error,{incorrect_start_options,{Dir,Suite,GsAndCs}}}) end. -%%%----------------------------------------------------------------- -%%% @spec run_testspec(TestSpec) -> Result -%%% TestSpec = [term()] -%%% -%%% @doc Run test specified by TestSpec. The terms are -%%% the same as those used in test specification files. -%%% @equiv ct:run_testspec/1 -%%%----------------------------------------------------------------- run_testspec(TestSpec) -> CTPid = spawn(run_testspec1_fun(TestSpec)), Ref = monitor(process, CTPid), @@ -1634,9 +1595,6 @@ delistify([E]) -> E; delistify(E) -> E. -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:run/3 run(TestDir, Suite, Cases) -> case install([]) of ok -> @@ -1645,9 +1603,6 @@ run(TestDir, Suite, Cases) -> Error end. -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:run/2 run(TestDir, Suite) when is_list(TestDir), is_integer(hd(TestDir)) -> case install([]) of ok -> @@ -1656,9 +1611,6 @@ run(TestDir, Suite) when is_list(TestDir), is_integer(hd(TestDir)) -> Error end. -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:run/1 run(TestDirs) -> case install([]) of ok -> @@ -2068,16 +2020,9 @@ get_bad_suites([], BadSuites) -> BadSuites. - -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:step/3 step(TestDir, Suite, Case) -> step(TestDir, Suite, Case, []). -%%%----------------------------------------------------------------- -%%% @hidden -%%% @equiv ct:step/4 step(TestDir, Suite, Case, Opts) when is_list(TestDir), is_atom(Suite), is_atom(Case), Suite =/= all, Case =/= all -> diff --git a/lib/common_test/src/ct_slave.erl b/lib/common_test/src/ct_slave.erl index 0c16ad5980..dde33440be 100644 --- a/lib/common_test/src/ct_slave.erl +++ b/lib/common_test/src/ct_slave.erl @@ -1,7 +1,7 @@ %%-------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-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. @@ -17,13 +17,6 @@ %% %% %CopyrightEnd% -%%% @doc Common Test Framework functions for starting and stopping nodes for -%%% Large Scale Testing. -%%% -%%%

This module exports functions which are used by the Common Test Master -%%% to start and stop "slave" nodes. It is the default callback module for the -%%% {init, node_start} term of the Test Specification.

- %%---------------------------------------------------------------------- %% File : ct_slave.erl %% Description : CT module for starting nodes for large-scale testing. @@ -41,42 +34,9 @@ kill_if_fail, erl_flags, env, ssh_port, ssh_opts, stop_timeout}). -%%%----------------------------------------------------------------- -%%% @spec start(Node) -> Result -%%% Node = atom() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = already_started | -%%% started_not_connected | -%%% boot_timeout | -%%% init_timeout | -%%% startup_timeout | -%%% not_alive -%%% NodeName = atom() -%%% @doc Starts an Erlang node with name Node on the local host. -%%% @see start/3 start(Node) -> start(gethostname(), Node). -%%%----------------------------------------------------------------- -%%% @spec start(HostOrNode, NodeOrOpts) -> Result -%%% HostOrNode = atom() -%%% NodeOrOpts = atom() | list() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = already_started | -%%% started_not_connected | -%%% boot_timeout | -%%% init_timeout | -%%% startup_timeout | -%%% not_alive -%%% NodeName = atom() -%%% @doc Starts an Erlang node with default options on a specified -%%% host, or on the local host with specified options. That is, -%%% the call is interpreted as start(Host, Node) when the -%%% second argument is atom-valued and start(Node, Opts) -%%% when it's list-valued. -%%% @see start/3 start(_HostOrNode = Node, _NodeOrOpts = Opts) %% match to satiate edoc when is_list(Opts) -> start(gethostname(), Node, Opts); @@ -84,104 +44,6 @@ start(_HostOrNode = Node, _NodeOrOpts = Opts) %% match to satiate edoc start(Host, Node) -> start(Host, Node, []). -%%%----------------------------------------------------------------- -%%% @spec start(Host, Node, Opts) -> Result -%%% Node = atom() -%%% Host = atom() -%%% Opts = [OptTuples] -%%% OptTuples = {username, Username} | -%%% {password, Password} | -%%% {boot_timeout, BootTimeout} | {init_timeout, InitTimeout} | -%%% {startup_timeout, StartupTimeout} | -%%% {startup_functions, StartupFunctions} | -%%% {monitor_master, Monitor} | -%%% {kill_if_fail, KillIfFail} | -%%% {erl_flags, ErlangFlags} | -%%% {env, [{EnvVar,Value}]} -%%% Username = string() -%%% Password = string() -%%% BootTimeout = integer() -%%% InitTimeout = integer() -%%% StartupTimeout = integer() -%%% StartupFunctions = [StartupFunctionSpec] -%%% StartupFunctionSpec = {Module, Function, Arguments} -%%% Module = atom() -%%% Function = atom() -%%% Arguments = [term] -%%% Monitor = bool() -%%% KillIfFail = bool() -%%% ErlangFlags = string() -%%% EnvVar = string() -%%% Value = string() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = already_started | -%%% started_not_connected | -%%% boot_timeout | -%%% init_timeout | -%%% startup_timeout | -%%% not_alive -%%% NodeName = atom() -%%% @doc Starts an Erlang node with name Node on host -%%% Host as specified by the combination of options in -%%% Opts. -%%% -%%%

Options Username and Password will be used -%%% to log in onto the remote host Host. -%%% Username, if omitted, defaults to the current user name, -%%% and password is empty by default.

-%%% -%%%

A list of functions specified in the Startup option will be -%%% executed after startup of the node. Note that all used modules should be -%%% present in the code path on the Host.

-%%% -%%%

The timeouts are applied as follows:

-%%% -%%% -%%% BootTimeout - time to start the Erlang node, in seconds. -%%% Defaults to 3 seconds. If node does not become pingable within this time, -%%% the result {error, boot_timeout, NodeName} is returned; -%%% -%%% -%%% InitTimeout - time to wait for the node until it calls the -%%% internal callback function informing master about successfull startup. -%%% Defaults to one second. -%%% In case of timed out message the result -%%% {error, init_timeout, NodeName} is returned; -%%% -%%% -%%% StartupTimeout - time to wait intil the node finishes to run -%%% the StartupFunctions. Defaults to one second. -%%% If this timeout occurs, the result -%%% {error, startup_timeout, NodeName} is returned. -%%% -%%% -%%% -%%%

Option monitor_master specifies, if the slave node should be -%%% stopped in case of master node stop. Defaults to false.

-%%% -%%%

Option kill_if_fail specifies, if the slave node should be -%%% killed in case of a timeout during initialization or startup. -%%% Defaults to true. Note that node also may be still alive it the boot -%%% timeout occurred, but it will not be killed in this case.

-%%% -%%%

Option erlang_flags specifies, which flags will be added -%%% to the parameters of the erl executable.

-%%% -%%%

Option env specifies a list of environment variables -%%% that will extended the environment.

-%%% -%%%

Special return values are:

-%%% -%%% {error, already_started, NodeName} - if the node with -%%% the given name is already started on a given host; -%%% {error, started_not_connected, NodeName} - if node is -%%% started, but not connected to the master node. -%%% {error, not_alive, NodeName} - if node on which the -%%% ct_slave:start/3 is called, is not alive. Note that -%%% NodeName is the name of current node in this case. -%%% -%%% start(Host, Node, Opts) -> ENode = enodename(Host, Node), case erlang:is_alive() of @@ -199,36 +61,9 @@ start(Host, Node, Opts) -> end end. -%%%----------------------------------------------------------------- -%%% @spec stop(Node) -> Result -%%% Node = atom() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = not_started | -%%% not_connected | -%%% stop_timeout -%%% NodeName = atom() -%%% @doc Stops the running Erlang node with name Node on -%%% the localhost. stop(Node) -> stop(gethostname(), Node). -%%%----------------------------------------------------------------- -%%% @spec stop(HostOrNode, NodeOrOpts) -> Result -%%% HostOrNode = atom() -%%% NodeOrOpts = atom() | list() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = not_started | -%%% not_connected | -%%% stop_timeout -%%% NodeName = atom() -%%% @doc Stops the running Erlang node with default options on a specified -%%% host, or on the local host with specified options. That is, -%%% the call is interpreted as stop(Host, Node) when the -%%% second argument is atom-valued and stop(Node, Opts) -%%% when it's list-valued. -%%% @see stop/3 stop(_HostOrNode = Node, _NodeOrOpts = Opts) %% match to satiate edoc when is_list(Opts) -> stop(gethostname(), Node, Opts); @@ -236,26 +71,6 @@ stop(_HostOrNode = Node, _NodeOrOpts = Opts) %% match to satiate edoc stop(Host, Node) -> stop(Host, Node, []). -%%% @spec stop(Host, Node, Opts) -> Result -%%% Host = atom() -%%% Node = atom() -%%% Opts = [OptTuples] -%%% OptTuples = {stop_timeout, StopTimeout} -%%% StopTimeout = integer() -%%% Result = {ok, NodeName} | -%%% {error, Reason, NodeName} -%%% Reason = not_started | -%%% not_connected | -%%% stop_timeout -%%% NodeName = atom() -%%% @doc Stops the running Erlang node with name Node on -%%% host Host as specified by options Opts. -%%% -%%%

Option stop_timeout specifies, in seconds, -%%% the time to wait until the node is disconnected. -%%% Defaults to 5 seconds. If this timeout occurs, -%%% the result {error, stop_timeout, NodeName} is returned. -%%% stop(Host, Node, Opts) -> ENode = enodename(Host, Node), case is_started(ENode) of @@ -300,19 +115,16 @@ fetch_options(Options) -> stop_timeout=StopTimeout}. % send a message when slave node is started -% @hidden slave_started(ENode, MasterPid) -> MasterPid ! {node_started, ENode}, ok. % send a message when slave node has finished startup -% @hidden slave_ready(ENode, MasterPid) -> MasterPid ! {node_ready, ENode}, ok. % start monitoring of the master node -% @hidden monitor_master(MasterNode) -> spawn(fun() -> monitor_master_int(MasterNode) end). diff --git a/lib/common_test/src/ct_snmp.erl b/lib/common_test/src/ct_snmp.erl index 5844909d17..27b74dd04e 100644 --- a/lib/common_test/src/ct_snmp.erl +++ b/lib/common_test/src/ct_snmp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-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. @@ -18,139 +18,8 @@ %% %CopyrightEnd% %% -%%% @doc Common Test user interface module for the OTP snmp application -%%% -%%%

The purpose of this module is to make snmp configuration easier for -%%% the test case writer. Many test cases can use default values for common -%%% operations and then no snmp configuration files need to be supplied. When -%%% it is necessary to change particular configuration parameters, a subset -%%% of the relevant snmp configuration files may be passed to ct_snmp -%%% by means of Common Test configuration files. -%%% For more specialized configuration parameters, it is possible to place a -%%% "simple snmp configuration file" in the test suite data directory. -%%% To simplify the test suite, Common Test keeps track -%%% of some of the snmp manager information. This way the test suite doesn't -%%% have to handle as many input parameters as it would if it had to interface the -%%% OTP snmp manager directly.

-%%% -%%%

The following snmp manager and agent parameters are configurable:

-%%% -%%%
-%%% {snmp,
-%%%        %%% Manager config
-%%%        [{start_manager, boolean()}    % Optional - default is true
-%%%        {users, [{user_name(), [call_back_module(), user_data()]}]}, %% Optional 
-%%%        {usm_users, [{usm_user_name(), [usm_config()]}]},%% Optional - snmp v3 only
-%%%        % managed_agents is optional 
-%%%        {managed_agents,[{agent_name(), [user_name(), agent_ip(), agent_port(), [agent_config()]]}]},   
-%%%        {max_msg_size, integer()},     % Optional - default is 484
-%%%        {mgr_port, integer()},         % Optional - default is 5000
-%%%        {engine _id, string()},        % Optional - default is "mgrEngine"
-%%%
-%%%        %%% Agent config 
-%%%        {start_agent, boolean()},      % Optional - default is false
-%%%        {agent_sysname, string()},     % Optional - default is "ct_test"
-%%%        {agent_manager_ip, manager_ip()}, % Optional - default is localhost
-%%%        {agent_vsns, list()},          % Optional - default is [v2]
-%%%        {agent_trap_udp, integer()},   % Optional - default is 5000
-%%%        {agent_udp, integer()},        % Optional - default is 4000
-%%%        {agent_notify_type, atom()},   % Optional - default is trap
-%%%        {agent_sec_type, sec_type()},  % Optional - default is none
-%%%        {agent_passwd, string()},      % Optional - default is ""
-%%%        {agent_engine_id, string()},   % Optional - default is "agentEngine"
-%%%        {agent_max_msg_size, string()},% Optional - default is 484
-%%%
-%%%        %% The following parameters represents the snmp configuration files
-%%%        %% context.conf, standard.conf, community.conf, vacm.conf,  
-%%%        %% usm.conf, notify.conf, target_addr.conf and target_params.conf.
-%%%        %% Note all values in agent.conf can be altered by the parametes 
-%%%        %% above. All these configuration files have default values set   
-%%%        %% up by the snmp application. These values can be overridden by
-%%%        %% suppling a list of valid configuration values or a file located
-%%%        %% in the test suites data dir that can produce a list 
-%%%        %% of valid configuration values if you apply file:consult/1 to the 
-%%%        %% file. 
-%%%        {agent_contexts, [term()] | {data_dir_file, rel_path()}}, % Optional
-%%%        {agent_community, [term()] | {data_dir_file, rel_path()}},% Optional
-%%%        {agent_sysinfo,  [term()] | {data_dir_file, rel_path()}}, % Optional
-%%%        {agent_vacm, [term()] | {data_dir_file, rel_path()}},     % Optional
-%%%        {agent_usm, [term()] | {data_dir_file, rel_path()}},      % Optional 
-%%%        {agent_notify_def, [term()] | {data_dir_file, rel_path()}},% Optional
-%%%        {agent_target_address_def, [term()] | {data_dir_file, rel_path()}},% Optional
-%%%        {agent_target_param_def, [term()] | {data_dir_file, rel_path()}},% Optional
-%%%       ]}.
-%%% 
-%%% -%%%

The MgrAgentConfName parameter in the functions -%%% should be a name you allocate in your test suite using a -%%% require statement. -%%% Example (where MgrAgentConfName = snmp_mgr_agent):

-%%%
 suite() -> [{require, snmp_mgr_agent, snmp}].
-%%%

or

-%%%
  ct:require(snmp_mgr_agent, snmp).
-%%% -%%%

Note that Usm users are needed for snmp v3 configuration and are -%%% not to be confused with users.

-%%% -%%%

Snmp traps, inform and report messages are handled by the -%%% user callback module. For more information about this see -%%% the snmp application.

-%%%

Note: It is recommended to use the .hrl-files created by the -%%% Erlang/OTP mib-compiler to define the oids. -%%% Example for the getting the erlang node name from the erlNodeTable -%%% in the OTP-MIB:

-%%%
Oid = ?erlNodeEntry ++ [?erlNodeName, 1] 
-%%% -%%%

It is also possible to set values for snmp application configuration -%%% parameters, such as config, server, -%%% net_if, etc (see the "Configuring the application" chapter in -%%% the OTP snmp User's Guide for a list of valid parameters and types). This is -%%% done by defining a configuration data variable on the following form:

-%%%
-%%% {snmp_app, [{manager, [snmp_app_manager_params()]},
-%%%             {agent, [snmp_app_agent_params()]}]}.
-%%% -%%%

A name for the data needs to be allocated in the suite using -%%% require (see example above), and this name passed as -%%% the SnmpAppConfName argument to start/3. -%%% ct_snmp specifies default values for some snmp application -%%% configuration parameters (such as {verbosity,trace} for the -%%% config parameter). This set of defaults will be -%%% merged with the parameters specified by the user, and user values -%%% override ct_snmp defaults.

- -module(ct_snmp). -%%% Common Types -%%% @type agent_ip() = ip() -%%% @type manager_ip() = ip() -%%% @type agent_name() = atom() -%%% @type ip() = string() | {integer(), integer(), -%%% integer(), integer()} -%%% @type agent_port() = integer() -%%% @type agent_config() = {Item, Value} -%%% @type user_name() = atom() -%%% @type usm_user_name() = string() -%%% @type usm_config() = {Item, Value} -%%% @type call_back_module() = atom() -%%% @type user_data() = term() -%%% @type oids() = [oid()] -%%% @type oid() = [byte()] -%%% @type snmpreply() = {error_status(), error_index(), varbinds()} -%%% @type error_status() = noError | atom() -%%% @type error_index() = integer() -%%% @type varbinds() = [varbind()] -%%% @type varbind() = term() -%%% @type value_type() = o ('OBJECT IDENTIFIER') | i ('INTEGER') | -%%% u ('Unsigned32') | g ('Unsigned32') | s ('OCTET STRING') -%%% @type varsandvals() = [var_and_val()] -%%% @type var_and_val() = {oid(), value_type(), value()} -%%% @type sec_type() = none | minimum | semi -%%% @type rel_path() = string() -%%% @type snmp_app_manager_params() = term() -%%% @type snmp_app_agent_params() = term() - - -include("snmp_types.hrl"). -include("inet.hrl"). -include("ct.hrl"). @@ -181,31 +50,9 @@ %%% API %%%========================================================================= -%%%----------------------------------------------------------------- -%%% @spec start(Config, MgrAgentConfName) -> ok -%%% @equiv start(Config, MgrAgentConfName, undefined) start(Config, MgrAgentConfName) -> start(Config, MgrAgentConfName, undefined). -%%% @spec start(Config, MgrAgentConfName, SnmpAppConfName) -> ok -%%% Config = [{Key, Value}] -%%% Key = atom() -%%% Value = term() -%%% MgrAgentConfName = atom() -%%% SnmpConfName = atom() -%%% -%%% @doc Starts an snmp manager and/or agent. In the manager case, -%%% registrations of users and agents as specified by the configuration -%%% MgrAgentConfName will be performed. When using snmp -%%% v3 also so called usm users will be registered. Note that users, -%%% usm_users and managed agents may also be registered at a later time -%%% using ct_snmp:register_users/2, ct_snmp:register_agents/2, and -%%% ct_snmp:register_usm_users/2. The agent started will be -%%% called snmp_master_agent. Use ct_snmp:load_mibs/1 to load -%%% mibs into the agent. With SnmpAppConfName it's possible -%%% to configure the snmp application with parameters such as config, -%%% mibs, net_if, etc. The values will be merged -%%% with (and possibly override) default values set by ct_snmp. start(Config, MgrAgentConfName, SnmpAppConfName) -> StartManager= ct:get_config({MgrAgentConfName, start_manager}, true), StartAgent = ct:get_config({MgrAgentConfName, start_agent}, false), @@ -233,12 +80,6 @@ start_application(App) -> Else end. -%%% @spec stop(Config) -> ok -%%% Config = [{Key, Value}] -%%% Key = atom() -%%% Value = term() -%%% -%%% @doc Stops the snmp manager and/or agent removes all files created. stop(Config) -> PrivDir = ?config(priv_dir, Config), ok = application:stop(snmp), @@ -251,41 +92,16 @@ stop(Config) -> catch del_dir(DbDir). -%%% @spec get_values(Agent, Oids, MgrAgentConfName) -> SnmpReply -%%% -%%% Agent = agent_name() -%%% Oids = oids() -%%% MgrAgentConfName = atom() -%%% SnmpReply = snmpreply() -%%% -%%% @doc Issues a synchronous snmp get request. get_values(Agent, Oids, MgrAgentConfName) -> [Uid | _] = agent_conf(Agent, MgrAgentConfName), {ok, SnmpReply, _} = snmpm:sync_get2(Uid, target_name(Agent), Oids), SnmpReply. -%%% @spec get_next_values(Agent, Oids, MgrAgentConfName) -> SnmpReply -%%% -%%% Agent = agent_name() -%%% Oids = oids() -%%% MgrAgentConfName = atom() -%%% SnmpReply = snmpreply() -%%% -%%% @doc Issues a synchronous snmp get next request. get_next_values(Agent, Oids, MgrAgentConfName) -> [Uid | _] = agent_conf(Agent, MgrAgentConfName), {ok, SnmpReply, _} = snmpm:sync_get_next2(Uid, target_name(Agent), Oids), SnmpReply. -%%% @spec set_values(Agent, VarsAndVals, MgrAgentConfName, Config) -> SnmpReply -%%% -%%% Agent = agent_name() -%%% Oids = oids() -%%% MgrAgentConfName = atom() -%%% Config = [{Key, Value}] -%%% SnmpReply = snmpreply() -%%% -%%% @doc Issues a synchronous snmp set request. set_values(Agent, VarsAndVals, MgrAgentConfName, Config) -> PrivDir = ?config(priv_dir, Config), [Uid | _] = agent_conf(Agent, MgrAgentConfName), @@ -301,19 +117,6 @@ set_values(Agent, VarsAndVals, MgrAgentConfName, Config) -> end, SnmpSetReply. -%%% @spec set_info(Config) -> [{Agent, OldVarsAndVals, NewVarsAndVals}] -%%% -%%% Config = [{Key, Value}] -%%% Agent = agent_name() -%%% OldVarsAndVals = varsandvals() -%%% NewVarsAndVals = varsandvals() -%%% -%%% @doc Returns a list of all successful set requests performed in -%%% the test case in reverse order. The list contains the involved -%%% user and agent, the value prior to the set and the new value. This -%%% is intended to facilitate the clean up in the end_per_testcase -%%% function i.e. the undoing of the set requests and its possible -%%% side-effects. set_info(Config) -> PrivDir = ?config(priv_dir, Config), SetLogFile = filename:join(PrivDir, ?CT_SNMP_LOG_FILE), @@ -325,18 +128,6 @@ set_info(Config) -> [] end. -%%% @spec register_users(MgrAgentConfName, Users) -> ok | {error, Reason} -%%% -%%% MgrAgentConfName = atom() -%%% Users = [user()] -%%% Reason = term() -%%% -%%% @doc Register the manager entity (=user) responsible for specific agent(s). -%%% Corresponds to making an entry in users.conf. -%%% -%%%

This function will try to register the given users, without -%%% checking if any of them already exist. In order to change an -%%% already registered user, the user must first be unregistered.

register_users(MgrAgentConfName, Users) -> case setup_users(Users) of ok -> @@ -350,19 +141,6 @@ register_users(MgrAgentConfName, Users) -> Error end. -%%% @spec register_agents(MgrAgentConfName, ManagedAgents) -> ok | {error, Reason} -%%% -%%% MgrAgentConfName = atom() -%%% ManagedAgents = [agent()] -%%% Reason = term() -%%% -%%% @doc Explicitly instruct the manager to handle this agent. -%%% Corresponds to making an entry in agents.conf -%%% -%%%

This function will try to register the given managed agents, -%%% without checking if any of them already exist. In order to change -%%% an already registered managed agent, the agent must first be -%%% unregistered.

register_agents(MgrAgentConfName, ManagedAgents) -> case setup_managed_agents(MgrAgentConfName,ManagedAgents) of ok -> @@ -377,18 +155,6 @@ register_agents(MgrAgentConfName, ManagedAgents) -> Error end. -%%% @spec register_usm_users(MgrAgentConfName, UsmUsers) -> ok | {error, Reason} -%%% -%%% MgrAgentConfName = atom() -%%% UsmUsers = [usm_user()] -%%% Reason = term() -%%% -%%% @doc Explicitly instruct the manager to handle this USM user. -%%% Corresponds to making an entry in usm.conf -%%% -%%%

This function will try to register the given users, without -%%% checking if any of them already exist. In order to change an -%%% already registered user, the user must first be unregistered.

register_usm_users(MgrAgentConfName, UsmUsers) -> EngineID = ct:get_config({MgrAgentConfName, engine_id}, ?ENGINE_ID), case setup_usm_users(UsmUsers, EngineID) of @@ -403,23 +169,10 @@ register_usm_users(MgrAgentConfName, UsmUsers) -> Error end. -%%% @spec unregister_users(MgrAgentConfName) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% Reason = term() -%%% -%%% @doc Unregister all users. unregister_users(MgrAgentConfName) -> Users = [Id || {Id,_} <- ct:get_config({MgrAgentConfName, users},[])], unregister_users(MgrAgentConfName,Users). -%%% @spec unregister_users(MgrAgentConfName,Users) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% Users = [user_name()] -%%% Reason = term() -%%% -%%% @doc Unregister the given users. unregister_users(MgrAgentConfName,Users) -> takedown_users(Users), SnmpVals = ct:get_config(MgrAgentConfName), @@ -432,25 +185,12 @@ unregister_users(MgrAgentConfName,Users) -> ct_config:update_config(MgrAgentConfName, NewSnmpVals), ok. -%%% @spec unregister_agents(MgrAgentConfName) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% Reason = term() -%%% -%%% @doc Unregister all managed agents. unregister_agents(MgrAgentConfName) -> ManagedAgents = [AgentName || {AgentName, _} <- ct:get_config({MgrAgentConfName,managed_agents},[])], unregister_agents(MgrAgentConfName,ManagedAgents). -%%% @spec unregister_agents(MgrAgentConfName,ManagedAgents) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% ManagedAgents = [agent_name()] -%%% Reason = term() -%%% -%%% @doc Unregister the given managed agents. unregister_agents(MgrAgentConfName,ManagedAgents) -> takedown_managed_agents(MgrAgentConfName, ManagedAgents), SnmpVals = ct:get_config(MgrAgentConfName), @@ -464,23 +204,10 @@ unregister_agents(MgrAgentConfName,ManagedAgents) -> ct_config:update_config(MgrAgentConfName, NewSnmpVals), ok. -%%% @spec unregister_usm_users(MgrAgentConfName) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% Reason = term() -%%% -%%% @doc Unregister all usm users. unregister_usm_users(MgrAgentConfName) -> UsmUsers = [Id || {Id,_} <- ct:get_config({MgrAgentConfName, usm_users},[])], unregister_usm_users(MgrAgentConfName,UsmUsers). -%%% @spec unregister_usm_users(MgrAgentConfName,UsmUsers) -> ok -%%% -%%% MgrAgentConfName = atom() -%%% UsmUsers = [usm_user_name()] -%%% Reason = term() -%%% -%%% @doc Unregister the given usm users. unregister_usm_users(MgrAgentConfName,UsmUsers) -> EngineID = ct:get_config({MgrAgentConfName, engine_id}, ?ENGINE_ID), takedown_usm_users(UsmUsers,EngineID), @@ -495,23 +222,9 @@ unregister_usm_users(MgrAgentConfName,UsmUsers) -> ct_config:update_config(MgrAgentConfName, NewSnmpVals), ok. -%%% @spec load_mibs(Mibs) -> ok | {error, Reason} -%%% -%%% Mibs = [MibName] -%%% MibName = string() -%%% Reason = term() -%%% -%%% @doc Load the mibs into the agent 'snmp_master_agent'. load_mibs(Mibs) -> snmpa:load_mibs(snmp_master_agent, Mibs). -%%% @spec unload_mibs(Mibs) -> ok | {error, Reason} -%%% -%%% Mibs = [MibName] -%%% MibName = string() -%%% Reason = term() -%%% -%%% @doc Unload the mibs from the agent 'snmp_master_agent'. unload_mibs(Mibs) -> snmpa:unload_mibs(snmp_master_agent, Mibs). diff --git a/lib/common_test/src/ct_ssh.erl b/lib/common_test/src/ct_ssh.erl index 491d56dfc1..79ab122452 100644 --- a/lib/common_test/src/ct_ssh.erl +++ b/lib/common_test/src/ct_ssh.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2017. All Rights Reserved. +%% Copyright Ericsson AB 2009-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. @@ -18,44 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc SSH/SFTP client module. -%%% -%%%

ct_ssh uses the OTP ssh application and more detailed information -%%% about e.g. functions, types and options can be found in the -%%% documentation for this application.

-%%% -%%%

The Server argument in the SFTP functions should -%%% only be used for SFTP sessions that have been started on existing -%%% SSH connections (i.e. when the original connection type is -%%% ssh). Whenever the connection type is -%%% sftp, use the SSH connection reference only.

-%%% -%%%

The following options are valid for specifying an SSH/SFTP -%%% connection (i.e. may be used as config elements):

-%%% -%%%
-%%%
-%%%  [{ConnType, Addr},
-%%%   {port, Port},
-%%%   {user, UserName}
-%%%   {password, Pwd}
-%%%   {user_dir, String}
-%%%   {public_key_alg, PubKeyAlg}
-%%%   {connect_timeout, Timeout}
-%%%   {key_cb, KeyCallbackMod}]
-%%% 
-%%% -%%%

ConnType = ssh | sftp.

-%%%

Please see ssh(3) for other types.

-%%% -%%%

All timeout parameters in ct_ssh functions are values in -%%% milliseconds.

-%%% -%%% @type connection() = handle() | ct:target_name() -%%% @type handle() = ct_gen_conn:handle(). Handle for a specific -%%% SSH/SFTP connection. -%%% @type ssh_sftp_return() = term(). A return value from an ssh_sftp function. - -module(ct_ssh). %% SSH Functions @@ -100,64 +62,15 @@ %%%----------------------------------------------------------------- %%%------------------------ SSH COMMANDS --------------------------- -%%%----------------------------------------------------------------- -%%% @spec connect(KeyOrName) -> {ok,Handle} | {error,Reason} -%%% @equiv connect(KeyOrName,host,[]) connect(KeyOrName) -> connect(KeyOrName, host). -%%%----------------------------------------------------------------- -%%% @spec connect(KeyOrName,ConnType) -> {ok,Handle} | {error,Reason} -%%% @equiv connect(KeyOrName,ConnType,[]) connect(KeyOrName, ConnType) when is_atom(ConnType) -> connect(KeyOrName, ConnType, []); -%%%----------------------------------------------------------------- -%%% @spec connect(KeyOrName,ExtraOpts) -> {ok,Handle} | {error,Reason} -%%% @equiv connect(KeyOrName,host,ExtraOpts) connect(KeyOrName, ExtraOpts) when is_list(ExtraOpts) -> connect(KeyOrName, host, ExtraOpts). -%%%----------------------------------------------------------------- -%%% @spec connect(KeyOrName,ConnType,ExtraOpts) -> -%%% {ok,Handle} | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% ConnType = ssh | sftp | host -%%% ExtraOpts = ssh_connect_options() -%%% Handle = handle() -%%% Reason = term() -%%% -%%% @doc Open an SSH or SFTP connection using the information -%%% associated with KeyOrName. -%%% -%%%

If Name (an alias name for Key), -%%% is used to identify the connection, this name may -%%% be used as connection reference for subsequent calls. -%%% It's only possible to have one open connection at a time -%%% associated with Name. If Key is -%%% used, the returned handle must be used for subsequent calls -%%% (multiple connections may be opened using the config -%%% data specified by Key). See ct:require/2 -%%% for how to create a new Name

-%%% -%%%

ConnType will always override the type -%%% specified in the address tuple in the configuration data (and -%%% in ExtraOpts). So it is possible to for example -%%% open an sftp connection directly using data originally -%%% specifying an ssh connection. The value host -%%% means the connection type specified by the host option -%%% (either in the configuration data or in ExtraOpts) -%%% will be used.

-%%% -%%%

ExtraOpts (optional) are extra SSH options -%%% to be added to the config data for KeyOrName. -%%% The extra options will override any existing options with the -%%% same key in the config data. For details on valid SSH -%%% options, see the documentation for the OTP ssh application.

-%%% -%%% @see ct:require/2 connect(KeyOrName, ConnType, ExtraOpts) -> case ct:get_config(KeyOrName) of undefined -> @@ -232,12 +145,6 @@ connect(KeyOrName, ConnType, ExtraOpts) -> end end. -%%%----------------------------------------------------------------- -%%% @spec disconnect(SSH) -> ok | {error,Reason} -%%% SSH = connection() -%%% Reason = term() -%%% -%%% @doc Close an SSH/SFTP connection. disconnect(SSH) -> case get_handle(SSH) of {ok,Pid} -> @@ -252,242 +159,78 @@ disconnect(SSH) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec session_open(SSH) -> {ok,ChannelId} | {error, Reason} -%%% @equiv session_open(SSH,DefaultTimeout) session_open(SSH) -> call(SSH, {session_open,?DEFAULT_TIMEOUT}). -%%%----------------------------------------------------------------- -%%% @spec session_open(SSH,Timeout) -> {ok,ChannelId} | {error, Reason} -%%% SSH = connection() -%%% Timeout = integer() -%%% ChannelId = integer() -%%% Reason = term() -%%% -%%% @doc Opens a channel for an SSH session. session_open(SSH, Timeout) -> call(SSH, {session_open,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec session_close(SSH,ChannelId) -> ok | {error, Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Reason = term() -%%% -%%% @doc Closes an SSH session channel. session_close(SSH, ChannelId) -> call(SSH, {session_close,ChannelId}). -%%%----------------------------------------------------------------- -%%% @spec exec(SSH,Command) -> {ok,Data} | {error,Reason} -%%% @equiv exec(SSH,Command,DefaultTimeout) exec(SSH, Command) -> exec(SSH, undefined, Command, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec exec(SSH,Command,Timeout) -> {ok,Data} | {error,Reason} -%%% SSH = connection() -%%% Command = string() -%%% Timeout = integer() -%%% Data = list() -%%% Reason = term() -%%% -%%% @doc Requests server to perform Command. A session -%%% channel is opened automatically for the request. -%%% Data is received from the server as a result -%%% of the command. exec(SSH, Command, Timeout) when is_list(Command) -> exec(SSH, undefined, Command, Timeout); -%%%----------------------------------------------------------------- -%%% @spec exec(SSH,ChannelId,Command) -> {ok,Data} | {error,Reason} -%%% @equiv exec(SSH,ChannelId,Command,DefaultTimeout) exec(SSH, ChannelId, Command) when is_integer(ChannelId) -> exec(SSH, ChannelId, Command, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec exec(SSH,ChannelId,Command,Timeout) -> {ok,Data} | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Command = string() -%%% Timeout = integer() -%%% Data = list() -%%% Reason = term() -%%% -%%% @doc Requests server to perform Command. A previously -%%% opened session channel is used for the request. -%%% Data is received from the server as a result -%%% of the command. exec(SSH, ChannelId, Command, Timeout) -> call(SSH, {exec,ChannelId,Command,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec receive_response(SSH,ChannelId) -> {ok,Data} | {error,Reason} -%%% @equiv receive_response(SSH,ChannelId,close) receive_response(SSH, ChannelId) -> receive_response(SSH, ChannelId, close, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec receive_response(SSH,ChannelId,End) -> {ok,Data} | {error,Reason} -%%% @equiv receive_response(SSH,ChannelId,End,DefaultTimeout) receive_response(SSH, ChannelId, End) when is_function(End) -> receive_response(SSH, ChannelId, End, ?DEFAULT_TIMEOUT); -%%%----------------------------------------------------------------- -%%% @spec receive_response(SSH,ChannelId,Timeout) -> {ok,Data} | {error,Reason} -%%% @equiv receive_response(SSH,ChannelId,close,Timeout) receive_response(SSH, ChannelId, Timeout) when is_integer(Timeout) -> receive_response(SSH, ChannelId, close, Timeout). -%%%----------------------------------------------------------------- -%%% @spec receive_response(SSH,ChannelId,End,Timeout) -> -%%% {ok,Data} | {timeout,Data} | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% End = Fun | close | timeout -%%% Timeout = integer() -%%% Data = list() -%%% Reason = term() -%%% -%%% @doc Receives expected data from server on the specified -%%% session channel. -%%% -%%%

If End == close, data is returned -%%% to the caller when the channel is closed by the -%%% server. If a timeout occurs before this happens, -%%% the function returns {timeout,Data} -%%% (where Data is the data received so far). -%%% If End == timeout, a timeout is expected -%%% and {ok,Data} is returned both in the case -%%% of a timeout and when the channel is closed. If -%%% End is a fun, this fun will be -%%% called with one argument - the data value in a received -%%% ssh_cm message (see ssh_connection(3)). The -%%% fun should return true to end the receiving -%%% operation (and have the so far collected data returned), or -%%% false to wait for more data from the server. -%%% (Note that even if a fun is supplied, the function returns -%%% immediately if the server closes the channel).

receive_response(SSH, ChannelId, End, Timeout) -> call(SSH, {receive_response,ChannelId,End,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec send(SSH,ChannelId,Data) -> ok | {error,Reason} -%%% @equiv send(SSH,ChannelId,0,Data,DefaultTimeout) send(SSH, ChannelId, Data) -> send(SSH, ChannelId, 0, Data, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send(SSH,ChannelId,Data,Timeout) -> ok | {error,Reason} -%%% @equiv send(SSH,ChannelId,0,Data,Timeout) send(SSH, ChannelId, Data, Timeout) when is_integer(Timeout) -> send(SSH, ChannelId, 0, Data, Timeout); -%%%----------------------------------------------------------------- -%%% @spec send(SSH,ChannelId,Type,Data) -> ok | {error,Reason} -%%% @equiv send(SSH,ChannelId,Type,Data,DefaultTimeout) send(SSH, ChannelId, Type, Data) when is_integer(Type) -> send(SSH, ChannelId, Type, Data, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send(SSH,ChannelId,Type,Data,Timeout) -> ok | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Type = integer() -%%% Data = list() -%%% Timeout = integer() -%%% Reason = term() -%%% -%%% @doc Send data to server on specified session channel. send(SSH, ChannelId, Type, Data, Timeout) -> call(SSH, {send,ChannelId,Type,Data,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Data) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,Data,close) send_and_receive(SSH, ChannelId, Data) -> send_and_receive(SSH, ChannelId, 0, Data, close, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Data,End) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,0,Data,End,DefaultTimeout) send_and_receive(SSH, ChannelId, Data, End) when is_function(End) -> send_and_receive(SSH, ChannelId, 0, Data, End, ?DEFAULT_TIMEOUT); -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Data,Timeout) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,0,Data,close,Timeout) send_and_receive(SSH, ChannelId, Data, Timeout) when is_integer(Timeout) -> send_and_receive(SSH, ChannelId, 0, Data, close, Timeout); -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Type,Data) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,Type,Data,close,DefaultTimeout) send_and_receive(SSH, ChannelId, Type, Data) when is_integer(Type) -> send_and_receive(SSH, ChannelId, Type, Data, close, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Data,End,Timeout) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,0,Data,End,Timeout) send_and_receive(SSH, ChannelId, Data, End, Timeout) when is_integer(Timeout) -> send_and_receive(SSH, ChannelId, 0, Data, End, Timeout); -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Type,Data,Timeout) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,Type,Data,close,Timeout) send_and_receive(SSH, ChannelId, Type, Data, Timeout) when is_integer(Type) -> send_and_receive(SSH, ChannelId, Type, Data, close, Timeout); -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Type,Data,End) -> -%%% {ok,Data} | {error,Reason} -%%% @equiv send_and_receive(SSH,ChannelId,Type,Data,End,DefaultTimeout) send_and_receive(SSH, ChannelId, Type, Data, End) when is_function(End) -> send_and_receive(SSH, ChannelId, Type, Data, End, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec send_and_receive(SSH,ChannelId,Type,Data,End,Timeout) -> -%%% {ok,Data} | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Type = integer() -%%% Data = list() -%%% End = Fun | close | timeout -%%% Timeout = integer() -%%% Reason = term() -%%% -%%% @doc Send data to server on specified session channel and wait -%%% to receive the server response. -%%% -%%%

See receive_response/4 for details on the -%%% End argument.

send_and_receive(SSH, ChannelId, Type, Data, End, Timeout) -> call(SSH, {send_and_receive,ChannelId,Type,Data,End,Timeout}). -%%%----------------------------------------------------------------- -%%% @spec subsystem(SSH,ChannelId,Subsystem) -> Status | {error,Reason} -%%% @equiv subsystem(SSH,ChannelId,Subsystem,DefaultTimeout) subsystem(SSH, ChannelId, Subsystem) -> subsystem(SSH, ChannelId, Subsystem, ?DEFAULT_TIMEOUT). -%%%----------------------------------------------------------------- -%%% @spec subsystem(SSH,ChannelId,Subsystem,Timeout) -> -%%% Status | {error,Reason} -%%% SSH = connection() -%%% ChannelId = integer() -%%% Subsystem = string() -%%% Timeout = integer() -%%% Status = success | failure -%%% Reason = term() -%%% -%%% @doc Sends a request to execute a predefined subsystem. subsystem(SSH, ChannelId, Subsystem, Timeout) -> call(SSH, {subsystem,ChannelId,Subsystem,Timeout}). @@ -511,439 +254,157 @@ shell(SSH, ChannelId, Timeout) -> %%%----------------------------------------------------------------- %%%------------------------ SFTP COMMANDS -------------------------- -%%%----------------------------------------------------------------- -%%% @spec sftp_connect(SSH) -> {ok,Server} | {error,Reason} -%%% SSH = connection() -%%% Server = pid() -%%% Reason = term() -%%% @doc Starts an SFTP session on an already existing SSH connection. -%%% Server identifies the new session and must be -%%% specified whenever SFTP requests are to be sent. sftp_connect(SSH) -> call(SSH, sftp_connect). -%%%----------------------------------------------------------------- -%%% @spec read_file(SSH, File) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read_file(SSH, File) -> call(SSH, {read_file,sftp,File}). -%%%----------------------------------------------------------------- -%%% @spec read_file(SSH, Server, File) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read_file(SSH, Server, File) -> call(SSH, {read_file,Server,File}). -%%%----------------------------------------------------------------- -%%% @spec write_file(SSH, File, Iolist) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). write_file(SSH, File, Iolist) -> call(SSH, {write_file,sftp,File,Iolist}). -%%%----------------------------------------------------------------- -%%% @spec write_file(SSH, Server, File, Iolist) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + write_file(SSH, Server, File, Iolist) -> call(SSH, {write_file,Server,File,Iolist}). -%%%----------------------------------------------------------------- -%%% @spec list_dir(SSH, Path) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). list_dir(SSH, Path) -> call(SSH, {list_dir,sftp,Path}). -%%%----------------------------------------------------------------- -%%% @spec list_dir(SSH, Server, Path) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + list_dir(SSH, Server, Path) -> call(SSH, {list_dir,Server,Path}). -%%%----------------------------------------------------------------- -%%% @spec open(SSH, File, Mode) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). open(SSH, File, Mode) -> call(SSH, {open,sftp,File,Mode}). -%%%----------------------------------------------------------------- -%%% @spec open(SSH, Server, File, Mode) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + open(SSH, Server, File, Mode) -> call(SSH, {open,Server,File,Mode}). -%%%----------------------------------------------------------------- -%%% @spec opendir(SSH, Path) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). opendir(SSH, Path) -> call(SSH, {opendir,sftp,Path}). -%%%----------------------------------------------------------------- -%%% @spec opendir(SSH, Server, Path) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + opendir(SSH, Server, Path) -> call(SSH, {opendir,Server,Path}). -%%%----------------------------------------------------------------- -%%% @spec close(SSH, Handle) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). close(SSH, Handle) -> call(SSH, {close,sftp,Handle}). -%%%----------------------------------------------------------------- -%%% @spec close(SSH, Server, Handle) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + close(SSH, Server, Handle) -> call(SSH, {close,Server,Handle}). -%%%----------------------------------------------------------------- -%%% @spec read(SSH, Handle, Len) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read(SSH, Handle, Len) -> call(SSH, {read,sftp,Handle,Len}). -%%%----------------------------------------------------------------- -%%% @spec read(SSH, Server, Handle, Len) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read(SSH, Server, Handle, Len) -> call(SSH, {read,Server,Handle,Len}). -%%%----------------------------------------------------------------- -%%% @spec pread(SSH, Handle, Position, Length) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). pread(SSH, Handle, Position, Length) -> call(SSH, {pread,sftp,Handle,Position,Length}). -%%%----------------------------------------------------------------- -%%% @spec pread(SSH, Server, Handle, Position, Length) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + pread(SSH, Server, Handle, Position, Length) -> call(SSH, {pread,Server,Handle,Position,Length}). -%%%----------------------------------------------------------------- -%%% @spec aread(SSH, Handle, Len) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). aread(SSH, Handle, Len) -> call(SSH, {aread,sftp,Handle,Len}). -%%%----------------------------------------------------------------- -%%% @spec aread(SSH, Server, Handle, Len) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + aread(SSH, Server, Handle, Len) -> call(SSH, {aread,Server,Handle,Len}). -%%%----------------------------------------------------------------- -%%% @spec apread(SSH, Handle, Position, Length) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). apread(SSH, Handle, Position, Length) -> call(SSH, {apread,sftp,Handle,Position,Length}). -%%%----------------------------------------------------------------- -%%% @spec apread(SSH, Server, Handle, Position, Length) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + apread(SSH, Server, Handle, Position, Length) -> call(SSH, {apread,Server,Handle,Position,Length}). -%%%----------------------------------------------------------------- -%%% @spec write(SSH, Handle, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). write(SSH, Handle, Data) -> call(SSH, {write,sftp,Handle,Data}). -%%%----------------------------------------------------------------- -%%% @spec write(SSH, Server, Handle, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + write(SSH, Server, Handle, Data) -> call(SSH, {write,Server,Handle,Data}). -%%%----------------------------------------------------------------- -%%% @spec pwrite(SSH, Handle, Position, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). pwrite(SSH, Handle, Position, Data) -> call(SSH, {pwrite,sftp,Handle,Position,Data}). -%%%----------------------------------------------------------------- -%%% @spec pwrite(SSH, Server, Handle, Position, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + pwrite(SSH, Server, Handle, Position, Data) -> call(SSH, {pwrite,Server,Handle,Position,Data}). -%%%----------------------------------------------------------------- -%%% @spec awrite(SSH, Handle, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). awrite(SSH, Handle, Data) -> call(SSH, {awrite,sftp,Handle, Data}). -%%%----------------------------------------------------------------- -%%% @spec awrite(SSH, Server, Handle, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + awrite(SSH, Server, Handle, Data) -> call(SSH, {awrite,Server,Handle, Data}). -%%%----------------------------------------------------------------- -%%% @spec apwrite(SSH, Handle, Position, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). apwrite(SSH, Handle, Position, Data) -> call(SSH, {apwrite,sftp,Handle,Position,Data}). -%%%----------------------------------------------------------------- -%%% @spec apwrite(SSH, Server, Handle, Position, Data) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + apwrite(SSH, Server, Handle, Position, Data) -> call(SSH, {apwrite,Server,Handle,Position,Data}). -%%%----------------------------------------------------------------- -%%% @spec position(SSH, Handle, Location) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). position(SSH, Handle, Location) -> call(SSH, {position,sftp,Handle,Location}). -%%%----------------------------------------------------------------- -%%% @spec position(SSH, Server, Handle, Location) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + position(SSH, Server, Handle, Location) -> call(SSH, {position,Server,Handle,Location}). -%%%----------------------------------------------------------------- -%%% @spec read_file_info(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read_file_info(SSH, Name) -> call(SSH, {read_file_info,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec read_file_info(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read_file_info(SSH, Server, Name) -> call(SSH, {read_file_info,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec get_file_info(SSH, Handle) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). get_file_info(SSH, Handle) -> call(SSH, {get_file_info,sftp,Handle}). -%%%----------------------------------------------------------------- -%%% @spec get_file_info(SSH, Server, Handle) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + get_file_info(SSH, Server, Handle) -> call(SSH, {get_file_info,Server,Handle}). -%%%----------------------------------------------------------------- -%%% @spec read_link_info(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read_link_info(SSH, Name) -> call(SSH, {read_link_info,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec read_link_info(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read_link_info(SSH, Server, Name) -> call(SSH, {read_link_info,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec write_file_info(SSH, Name, Info) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). write_file_info(SSH, Name, Info) -> call(SSH, {write_file_info,sftp,Name,Info}). -%%%----------------------------------------------------------------- -%%% @spec write_file_info(SSH, Server, Name, Info) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + write_file_info(SSH, Server, Name, Info) -> call(SSH, {write_file_info,Server,Name,Info}). -%%%----------------------------------------------------------------- -%%% @spec read_link(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). read_link(SSH, Name) -> call(SSH, {read_link,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec read_link(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + read_link(SSH, Server, Name) -> call(SSH, {read_link,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec make_symlink(SSH, Name, Target) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). make_symlink(SSH, Name, Target) -> call(SSH, {make_symlink,sftp,Name,Target}). -%%%----------------------------------------------------------------- -%%% @spec make_symlink(SSH, Server, Name, Target) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + make_symlink(SSH, Server, Name, Target) -> call(SSH, {make_symlink,Server,Name,Target}). -%%%----------------------------------------------------------------- -%%% @spec rename(SSH, OldName, NewName) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). rename(SSH, OldName, NewName) -> call(SSH, {rename,sftp,OldName,NewName}). -%%%----------------------------------------------------------------- -%%% @spec rename(SSH, Server, OldName, NewName) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + rename(SSH, Server, OldName, NewName) -> call(SSH, {rename,Server,OldName,NewName}). -%%%----------------------------------------------------------------- -%%% @spec delete(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + delete(SSH, Name) -> call(SSH, {delete,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec delete(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + delete(SSH, Server, Name) -> call(SSH, {delete,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec make_dir(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). make_dir(SSH, Name) -> call(SSH, {make_dir,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec make_dir(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + make_dir(SSH, Server, Name) -> call(SSH, {make_dir,Server,Name}). -%%%----------------------------------------------------------------- -%%% @spec del_dir(SSH, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). del_dir(SSH, Name) -> call(SSH, {del_dir,sftp,Name}). -%%%----------------------------------------------------------------- -%%% @spec del_dir(SSH, Server, Name) -> Result -%%% SSH = connection() -%%% Result = ssh_sftp_return() | {error,Reason} -%%% Reason = term() -%%% @doc For info and other types, see ssh_sftp(3). + del_dir(SSH, Server, Name) -> call(SSH, {del_dir,Server,Name}). @@ -952,7 +413,6 @@ del_dir(SSH, Server, Name) -> %%% Callback functions %%%================================================================= -%% @hidden init(KeyOrName, {ConnType,Addr,Port}, AllOpts) -> User = proplists:get_value(user, AllOpts), Password = case proplists:get_value(password, AllOpts) of @@ -1002,7 +462,6 @@ init(KeyOrName, {ConnType,Addr,Port}, AllOpts) -> target=KeyOrName}} end. -%% @hidden handle_msg(sftp_connect, State) -> #state{ssh_ref=SSHRef, target=Target} = State, try_log(heading(sftp_connect,Target), "SSH Ref: ~p", [SSHRef]), @@ -1246,15 +705,12 @@ handle_msg({del_dir,Srv,Name}=Cmd, S=#state{ssh_ref=SSHRef}) -> [SSHRef,ref(Srv,SSHRef),mod(Cmd)]), {ssh_sftp:del_dir(ref(Srv,SSHRef), Name),S}. -%% @hidden reconnect(_Addr,_State) -> {error,no_reconnection_of_ssh}. -%% @hidden close(SSHRef) -> disconnect(SSHRef). -%% @hidden terminate(SSHRef, State) -> case State#state.conn_type of ssh -> @@ -1271,8 +727,6 @@ terminate(SSHRef, State) -> %%%================================================================= %%% Internal functions -%%%----------------------------------------------------------------- -%%% do_recv_response(SSH, Chn, Data, End, Timeout) -> receive {ssh_cm, SSH, {open,Chn,RemoteChn,{session}}} -> @@ -1351,8 +805,6 @@ do_recv_response(SSH, Chn, Data, End, Timeout) -> end end. -%%%----------------------------------------------------------------- -%%% get_handle(SSH) when is_pid(SSH) -> {ok,SSH}; get_handle(SSH) -> @@ -1365,8 +817,6 @@ get_handle(SSH) -> Error end. -%%%----------------------------------------------------------------- -%%% call(SSH, Msg) -> call(SSH, Msg, infinity). @@ -1378,29 +828,19 @@ call(SSH, Msg, Timeout) -> Error end. -%%%----------------------------------------------------------------- -%%% ref(sftp, SSHRef) -> SSHRef; ref(Server, _) -> Server. -%%%----------------------------------------------------------------- -%%% mod(Cmd) -> [Op,_Server|Args] = tuple_to_list(Cmd), list_to_tuple([Op|Args]). -%%%----------------------------------------------------------------- -%%% heading(Function, Ref) -> io_lib:format("ct_ssh:~tw ~tp",[Function,Ref]). -%%%----------------------------------------------------------------- -%%% log(Heading, Str, Args) -> ct_gen_conn:log(Heading, Str, Args). -%%%----------------------------------------------------------------- -%%% try_log(Heading, Str, Args) -> try_log(Heading, Str, Args, infinity). @@ -1414,8 +854,6 @@ try_log(Heading, Str, Args, Timeout) -> ok end. -%%%----------------------------------------------------------------- -%%% debug(Str) -> debug(Str, []). diff --git a/lib/common_test/src/ct_telnet.erl b/lib/common_test/src/ct_telnet.erl index b50cddd492..f9abecfd38 100644 --- a/lib/common_test/src/ct_telnet.erl +++ b/lib/common_test/src/ct_telnet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-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. @@ -18,131 +18,6 @@ %% %CopyrightEnd% %% -%% @doc Common Test specific layer on top of telnet client `ct_telnet_client.erl' -%% -%%

Use this module to set up telnet connections, send commands and -%% perform string matching on the result. -%% See the `unix_telnet' manual page for information about how to use -%% `ct_telnet', and configure connections, specifically for unix hosts.

-%%

The following default values are defined in `ct_telnet':

-%%
-%% Connection timeout = 10 sec (time to wait for connection)
-%% Command timeout = 10 sec (time to wait for a command to return)
-%% Max no of reconnection attempts = 3
-%% Reconnection interval = 5 sek (time to wait in between reconnection attempts)
-%% Keep alive = true (will send NOP to the server every 8 sec if connection is idle)
-%% Polling limit = 0 (max number of times to poll to get a remaining string terminated)
-%% Polling interval = 1 sec (sleep time between polls)
-%%

These parameters can be altered by the user with the following -%% configuration term:

-%%
-%% {telnet_settings, [{connect_timeout,Millisec},
-%%                    {command_timeout,Millisec},
-%%                    {reconnection_attempts,N},
-%%                    {reconnection_interval,Millisec},
-%%                    {keep_alive,Bool},
-%%                    {poll_limit,N},
-%%                    {poll_interval,Millisec},
-%%                    {tcp_nodelay,Bool}]}.
-%%

Millisec = integer(), N = integer()

-%%

Enter the telnet_settings term in a configuration -%% file included in the test and ct_telnet will retrieve the information -%% automatically. Note that `keep_alive' may be specified per connection if -%% required. See `unix_telnet' for details.

-%% -%% == Logging == -%% -%% The default logging behaviour of `ct_telnet' is to print information -%% to the test case HTML log about performed operations and commands -%% and their corresponding results. What won't be printed to the HTML log -%% are text strings sent from the telnet server that are not explicitly -%% received by means of a `ct_telnet' function such as `expect/3'. -%% `ct_telnet' may however be configured to use a special purpose event handler, -%% implemented in `ct_conn_log_h', for logging all telnet traffic. -%% To use this handler, you need to install a Common Test hook named -%% `cth_conn_log'. Example (using the test suite info function): -%% -%% ``` -%% suite() -> -%% [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}]. -%% ''' -%% -%% `conn_mod()' is the name of the common_test module implementing -%% the connection protocol, i.e. `ct_telnet'. -%% -%% The `cth_conn_log' hook performs unformatted logging of telnet data to -%% a separate text file. All telnet communication is captured and printed, -%% including arbitrary data sent from the server. The link to this text file -%% can be found on the top of the test case HTML log. -%% -%% By default, data for all telnet connections is logged in one common -%% file (named `default'), which might get messy e.g. if multiple telnet -%% sessions are running in parallel. It is therefore possible to create a -%% separate log file for each connection. To configure this, use the hook -%% option `hosts' and list the names of the servers/connections that will be -%% used in the suite. Note that the connections must be named for this to work -%% (see the `open' function below). -%% -%% The hook option named `log_type' may be used to change the `cth_conn_log' -%% behaviour. The default value of this option is `raw', which results in the -%% behaviour described above. If the value is set to `html', all telnet -%% communication is printed to the test case HTML log instead. -%% -%% All `cth_conn_log' hook options described above can also be specified in -%% a configuration file with the configuration variable `ct_conn_log'. Example: -%% -%% ``` -%% {ct_conn_log, [{ct_telnet,[{log_type,raw}, -%% {hosts,[key_or_name()]}]}]} -%% ''' -%% -%% Note that hook options specified in a configuration file -%% will overwrite any hardcoded hook options in the test suite! -%% -%% === Logging example === -%% -%% The following `ct_hooks' statement will cause printing of telnet traffic -%% to separate logs for the connections named `server1' and `server2'. -%% Traffic for any other connections will be logged in the default telnet log. -%% -%% ``` -%% suite() -> -%% [{ct_hooks, -%% [{cth_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}]}]. -%%''' -%% -%% As previously explained, the above specification could also be provided -%% by means of an entry like this in a configuration file: -%% -%% ``` -%% {ct_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}. -%% ''' -%% -%% in which case the `ct_hooks' statement in the test suite may simply look -%% like this: -%% -%% ``` -%% suite() -> -%% [{ct_hooks, [{cth_conn_log, []}]}]. -%% ''' -%% -%% @end - -%% @type connection_type() = telnet | ts1 | ts2 - -%% @type connection() = handle() | -%% {ct:target_name(),connection_type()} | ct:target_name() - -%% @type handle() = ct_gen_conn:handle(). Handle for a -%% specific telnet connection. - -%% @type prompt_regexp() = string(). A regular expression which -%% matches all possible prompts for a specific type of target. The -%% regexp must not have any groups i.e. when matching, re:run/3 shall -%% return a list with one single element. -%% -%% @see unix_telnet - -module(ct_telnet). -export([open/1, open/2, open/3, open/4, close/1]). @@ -186,20 +61,9 @@ reconn_int=?RECONN_TIMEOUT, tcp_nodelay=false}). -%%%----------------------------------------------------------------- -%%% @spec open(Name) -> {ok,Handle} | {error,Reason} -%%% @equiv open(Name,telnet) open(Name) -> open(Name,telnet). -%%%----------------------------------------------------------------- -%%% @spec open(Name,ConnType) -> {ok,Handle} | {error,Reason} -%%% Name = target_name() -%%% ConnType = ct_telnet:connection_type() -%%% Handle = ct_telnet:handle() -%%% Reason = term() -%%% -%%% @doc Open a telnet connection to the specified target host. open(Name,ConnType) -> case ct_util:get_key_from_name(Name) of {ok, unix} -> % unix host @@ -210,44 +74,9 @@ open(Name,ConnType) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec open(KeyOrName,ConnType,TargetMod) -> -%%% {ok,Handle} | {error,Reason} -%%% @equiv open(KeyOrName,ConnType,TargetMod,[]) open(KeyOrName,ConnType,TargetMod) -> open(KeyOrName,ConnType,TargetMod,KeyOrName). -%%%----------------------------------------------------------------- -%%% @spec open(KeyOrName,ConnType,TargetMod,Extra) -> -%%% {ok,Handle} | {error,Reason} -%%% KeyOrName = Key | Name -%%% Key = atom() -%%% Name = ct:target_name() -%%% ConnType = connection_type() -%%% TargetMod = atom() -%%% Extra = term() -%%% Handle = handle() -%%% Reason = term() -%%% -%%% @doc Open a telnet connection to the specified target host. -%%% -%%%

The target data must exist in a configuration file. The connection -%%% may be associated with either Name and/or the returned -%%% Handle. To allocate a name for the target, -%%% use ct:require/2 in a test case, or use a -%%% require statement in the suite info function -%%% (suite/0), or in a test case info function. -%%% If you want the connection to be associated with Handle only -%%% (in case you need to open multiple connections to a host for example), -%%% simply use Key, the configuration variable name, to -%%% specify the target. Note that a connection that has no associated target -%%% name can only be closed with the handle value.

-%%% -%%%

TargetMod is a module which exports the functions -%%% connect(Ip,Port,KeepAlive,Extra) and get_prompt_regexp() -%%% for the given TargetType (e.g. unix_telnet).

-%%% -%%% @see ct:require/2 open(KeyOrName,ConnType,TargetMod,Extra) -> case ct:get_config({KeyOrName,ConnType}) of undefined -> @@ -287,17 +116,6 @@ open(KeyOrName,ConnType,TargetMod,Extra) -> {old,true}]) end. -%%%----------------------------------------------------------------- -%%% @spec close(Connection) -> ok | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Reason = term() -%%% -%%% @doc Close the telnet connection and stop the process managing it. -%%% -%%%

A connection may be associated with a target name and/or a handle. -%%% If Connection has no associated target name, it may only -%%% be closed with the handle value (see the open/4 -%%% function).

close(Connection) -> case get_handle(Connection) of {ok,Pid} -> @@ -315,30 +133,10 @@ close(Connection) -> %%%================================================================= %%% Test suite interface %%%----------------------------------------------------------------- -%%% @spec cmd(Connection,Cmd) -> {ok,Data} | {error,Reason} -%%% @equiv cmd(Connection,Cmd,[]) + cmd(Connection,Cmd) -> cmd(Connection,Cmd,[]). -%%%----------------------------------------------------------------- -%%% @spec cmd(Connection,Cmd,Opts) -> {ok,Data} | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Cmd = string() -%%% Opts = [Opt] -%%% Opt = {timeout,timeout()} | {newline,boolean()} -%%% Data = [string()] -%%% Reason = term() -%%% @doc Send a command via telnet and wait for prompt. -%%% -%%%

This function will by default add a newline to the end of the -%%% given command. If this is not desired, the option -%%% `{newline,false}' can be used. This is necessary, for example, -%%% when sending telnet command sequences (prefixed with the -%%% Interprete As Command, IAC, character).

-%%% -%%%

The option `timeout' specifies how long the client shall wait for -%%% prompt. If the time expires, the function returns -%%% `{error,timeout}'. See the module description for information -%%% about the default value for the command timeout.

+ cmd(Connection,Cmd,Opts) when is_list(Opts) -> case check_cmd_opts(Opts) of ok -> @@ -363,42 +161,13 @@ check_cmd_opts([]) -> check_cmd_opts(Opts) -> check_send_opts(Opts). -%%%----------------------------------------------------------------- -%%% @spec cmdf(Connection,CmdFormat,Args) -> {ok,Data} | {error,Reason} -%%% @equiv cmdf(Connection,CmdFormat,Args,[]) cmdf(Connection,CmdFormat,Args) -> cmdf(Connection,CmdFormat,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec cmdf(Connection,CmdFormat,Args,Opts) -> {ok,Data} | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% CmdFormat = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {timeout,timeout()} | {newline,boolean()} -%%% Data = [string()] -%%% Reason = term() -%%% @doc Send a telnet command and wait for prompt -%%% (uses a format string and list of arguments to build the command). -%%% -%%%

See {@link cmd/3} further description.

+ cmdf(Connection,CmdFormat,Args,Opts) when is_list(Args) -> Cmd = lists:flatten(io_lib:format(CmdFormat,Args)), cmd(Connection,Cmd,Opts). -%%%----------------------------------------------------------------- -%%% @spec get_data(Connection) -> {ok,Data} | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Data = [string()] -%%% Reason = term() -%%% @doc Get all data that has been received by the telnet client -%%% since the last command was sent. Note that only newline terminated -%%% strings are returned. If the last string received has not yet -%%% been terminated, the connection may be polled automatically until -%%% the string is complete. The polling feature is controlled -%%% by the `poll_limit' and `poll_interval' config values and is -%%% by default disabled (meaning the function will immediately -%%% return all complete strings received and save a remaining -%%% non-terminated string for a later `get_data' call). get_data(Connection) -> case get_handle(Connection) of {ok,Pid} -> @@ -407,29 +176,9 @@ get_data(Connection) -> Error end. -%%%----------------------------------------------------------------- -%%% @spec send(Connection,Cmd) -> ok | {error,Reason} -%%% @equiv send(Connection,Cmd,[]) send(Connection,Cmd) -> send(Connection,Cmd,[]). -%%%----------------------------------------------------------------- -%%% @spec send(Connection,Cmd,Opts) -> ok | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Cmd = string() -%%% Opts = [Opt] -%%% Opt = {newline,boolean()} -%%% Reason = term() -%%% @doc Send a telnet command and return immediately. -%%% -%%% This function will by default add a newline to the end of the -%%% given command. If this is not desired, the option -%%% `{newline,false}' can be used. This is necessary, for example, -%%% when sending telnet command sequences (prefixed with the -%%% Interprete As Command, IAC, character). -%%% -%%%

The resulting output from the command can be read with -%%% get_data/1 or expect/2/3.

send(Connection,Cmd,Opts) -> case check_send_opts(Opts) of ok -> @@ -450,142 +199,16 @@ check_send_opts([Invalid|_]) -> check_send_opts([]) -> ok. - -%%%----------------------------------------------------------------- -%%% @spec sendf(Connection,CmdFormat,Args) -> ok | {error,Reason} -%%% @equiv sendf(Connection,CmdFormat,Args,[]) sendf(Connection,CmdFormat,Args) when is_list(Args) -> sendf(Connection,CmdFormat,Args,[]). -%%%----------------------------------------------------------------- -%%% @spec sendf(Connection,CmdFormat,Args,Opts) -> ok | {error,Reason} -%%% Connection = ct_telnet:connection() -%%% CmdFormat = string() -%%% Args = list() -%%% Opts = [Opt] -%%% Opt = {newline,boolean()} -%%% Reason = term() -%%% @doc Send a telnet command and return immediately (uses a format -%%% string and a list of arguments to build the command). sendf(Connection,CmdFormat,Args,Opts) when is_list(Args) -> Cmd = lists:flatten(io_lib:format(CmdFormat,Args)), send(Connection,Cmd,Opts). -%%%----------------------------------------------------------------- -%%% @spec expect(Connection,Patterns) -> term() -%%% @equiv expect(Connections,Patterns,[]) expect(Connection,Patterns) -> expect(Connection,Patterns,[]). -%%%----------------------------------------------------------------- -%%% @spec expect(Connection,Patterns,Opts) -> {ok,Match} | -%%% {ok,MatchList,HaltReason} | -%%% {error,Reason} -%%% Connection = ct_telnet:connection() -%%% Patterns = Pattern | [Pattern] -%%% Pattern = string() | {Tag,string()} | prompt | {prompt,Prompt} -%%% Prompt = string() -%%% Tag = term() -%%% Opts = [Opt] -%%% Opt = {idle_timeout,IdleTimeout} | {total_timeout,TotalTimeout} | -%%% repeat | {repeat,N} | sequence | {halt,HaltPatterns} | -%%% ignore_prompt | no_prompt_check | wait_for_prompt | -%%% {wait_for_prompt,Prompt} -%%% IdleTimeout = infinity | integer() -%%% TotalTimeout = infinity | integer() -%%% N = integer() -%%% HaltPatterns = Patterns -%%% MatchList = [Match] -%%% Match = RxMatch | {Tag,RxMatch} | {prompt,Prompt} -%%% RxMatch = [string()] -%%% HaltReason = done | Match -%%% Reason = timeout | {prompt,Prompt} -%%% -%%% @doc Get data from telnet and wait for the expected pattern. -%%% -%%%

Pattern can be a POSIX regular expression. The function -%%% returns as soon as a pattern has been successfully matched (at least one, -%%% in the case of multiple patterns).

-%%% -%%%

RxMatch is a list of matched strings. It looks -%%% like this: [FullMatch, SubMatch1, SubMatch2, ...] -%%% where FullMatch is the string matched by the whole -%%% regular expression and SubMatchN is the string that -%%% matched subexpression no N. Subexpressions are -%%% denoted with '(' ')' in the regular expression

-%%% -%%%

If a Tag is given, the returned Match -%%% will also include the matched Tag. Else, only -%%% RxMatch is returned.

-%%% -%%%

The idle_timeout option indicates that the function -%%% shall return if the telnet client is idle (i.e. if no data is -%%% received) for more than IdleTimeout milliseconds. Default -%%% timeout is 10 seconds.

-%%% -%%%

The total_timeout option sets a time limit for -%%% the complete expect operation. After TotalTimeout -%%% milliseconds, {error,timeout} is returned. The default -%%% value is infinity (i.e. no time limit).

-%%% -%%%

The function will return when a prompt is received, even if no -%%% pattern has yet been matched. In this event, -%%% {error,{prompt,Prompt}} is returned. -%%% However, this behaviour may be modified with the -%%% ignore_prompt or no_prompt_check option, which -%%% tells expect to return only when a match is found or after a -%%% timeout.

-%%% -%%%

If the ignore_prompt option is used, -%%% ct_telnet will ignore any prompt found. This option -%%% is useful if data sent by the server could include a pattern that -%%% would match the prompt regexp (as returned by -%%% TargedMod:get_prompt_regexp/0), but which should not -%%% cause the function to return.

-%%% -%%%

If the no_prompt_check option is used, -%%% ct_telnet will not search for a prompt at all. This -%%% is useful if, for instance, the Pattern itself -%%% matches the prompt.

-%%% -%%%

The wait_for_prompt option forces ct_telnet -%%% to wait until the prompt string has been received before returning -%%% (even if a pattern has already been matched). This is equal to calling: -%%% expect(Conn, Patterns++[{prompt,Prompt}], [sequence|Opts]). -%%% Note that idle_timeout and total_timeout -%%% may abort the operation of waiting for prompt.

-%%% -%%%

The repeat option indicates that the pattern(s) -%%% shall be matched multiple times. If N is given, the -%%% pattern(s) will be matched N times, and the function -%%% will return with HaltReason = done.

-%%% -%%%

The sequence option indicates that all patterns -%%% shall be matched in a sequence. A match will not be concluded -%%% untill all patterns are matched.

-%%% -%%%

Both repeat and sequence can be -%%% interrupted by one or more HaltPatterns. When -%%% sequence or repeat is used, there will -%%% always be a MatchList returned, i.e. a list of -%%% Match instead of only one Match. There -%%% will also be a HaltReason returned.

-%%% -%%%

Examples:
-%%% expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}], -%%% [sequence,{halt,[{nnn,"NNN"}]}]).
will try to match -%%% "ABC" first and then "XYZ", but if "NNN" appears the function will -%%% return {error,{nnn,["NNN"]}}. If both "ABC" and "XYZ" -%%% are matched, the function will return -%%% {ok,[AbcMatch,XyzMatch]}.

-%%% -%%%

expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}], -%%% [{repeat,2},{halt,[{nnn,"NNN"}]}]).
will try to match -%%% "ABC" or "XYZ" twice. If "NNN" appears the function will return -%%% with HaltReason = {nnn,["NNN"]}.

-%%% -%%%

The repeat and sequence options can be -%%% combined in order to match a sequence multiple times.

expect(Connection,Patterns,Opts) -> case get_handle(Connection) of {ok,Pid} -> @@ -596,7 +219,7 @@ expect(Connection,Patterns,Opts) -> %%%================================================================= %%% Callback functions -%% @hidden + init(Name,{Ip,Port,Type},{TargetMod,KeepAlive,Extra}) -> S0 = case ct:get_config(telnet_settings) of undefined -> @@ -677,7 +300,6 @@ set_telnet_defaults([Unknown|Ss],S) -> set_telnet_defaults([],S) -> S. -%% @hidden handle_msg({cmd,Cmd,Opts},State) -> start_gen_log(heading(cmd,State#state.name)), log(State,cmd,"Cmd: ~tp",[Cmd]), @@ -803,7 +425,6 @@ handle_msg({expect,Pattern,Opts},State) -> {Return1,State#state{buffer=NewBuffer,prompt=Prompt}}. -%% @hidden reconnect({Ip,Port,_Type},State) -> reconnect(Ip,Port,State#state.reconns,State). reconnect(Ip,Port,N,State=#state{name=Name, @@ -834,7 +455,6 @@ reconnect(Ip,Port,N,State=#state{name=Name, end. -%% @hidden terminate(TelnPid,State) -> Result = ct_telnet_client:close(TelnPid), log(State,close,"Telnet connection for ~w closed.",[TelnPid]), @@ -902,7 +522,6 @@ force_log(State,Action,String,Args) -> log(State,Action,String,Args,true). %%%----------------------------------------------------------------- -%%% @hidden log(State,Action,String,Args) when is_record(State, state) -> log(State,Action,String,Args,false); log(Name,Action,String,Args) when is_atom(Name) -> @@ -911,7 +530,6 @@ log(TelnPid,Action,String,Args) when is_pid(TelnPid) -> log(#state{teln_pid=TelnPid},Action,String,Args,false). %%%----------------------------------------------------------------- -%%% @hidden log(undefined,String,Args) -> log(#state{},undefined,String,Args,false); log(Name,String,Args) when is_atom(Name) -> @@ -920,7 +538,6 @@ log(TelnPid,String,Args) when is_pid(TelnPid) -> log(#state{teln_pid=TelnPid},undefined,String,Args). %%%----------------------------------------------------------------- -%%% @hidden log(#state{name=Name,teln_pid=TelnPid,host=Host,port=Port}, Action,String,Args,ForcePrint) -> Name1 = if Name == undefined -> get({ct_telnet_pid2name,TelnPid}); @@ -971,7 +588,6 @@ log(#state{name=Name,teln_pid=TelnPid,host=Host,port=Port}, end. %%%----------------------------------------------------------------- -%%% @hidden start_gen_log(Heading) -> %% check if output is suppressed case ct_util:is_silenced(telnet) of @@ -980,7 +596,6 @@ start_gen_log(Heading) -> end. %%%----------------------------------------------------------------- -%%% @hidden end_gen_log() -> %% check if output is suppressed case ct_util:is_silenced(telnet) of @@ -988,7 +603,6 @@ end_gen_log() -> false -> ct_gen_conn:end_log() end. -%%% @hidden %% Debug printouts. debug_cont_gen_log(Str,Args) -> Old = put(silent,true), @@ -1038,8 +652,7 @@ teln_get_all_data(State=#state{teln_pid=Pid,prx=Prx},Data,Acc,LastLine,Polls) -> found_prompt=false, prompt_check=true}). -%% @hidden -%% @doc Externally the silent_teln_expect function shall only be used +%% Externally the silent_teln_expect function shall only be used %% by the TargetModule, i.e. the target specific module which %% implements connect/2 and get_prompt_regexp/0. silent_teln_expect(Name,Pid,Data,Pattern,Prx,Opts) -> @@ -1057,9 +670,9 @@ silent_teln_expect(Name,Pid,Data,Pattern,Prx,Opts) -> %% 2) Sequence: Several patterns are given, and they are matched in %% the order they appear in the pattern list. %% 3a) Repeat (single): 1) is repeated either N times or until a halt -%% condition is fullfilled. +%% condition is fulfilled. %% 3b) Repeat (sequence): 2) is repeated either N times or until a -%% halt condition is fullfilled. +%% halt condition is fulfilled. teln_expect(Name,Pid,Data,Pattern0,Prx,Opts) -> HaltPatterns = case get_ignore_prompt(Opts) of @@ -1203,7 +816,7 @@ wait_for_prompt2(Prompt, Pattern, Opts) -> {true,Pattern1,Opts1}. %% Repeat either single or sequence. All match results are accumulated -%% and returned when a halt condition is fulllfilled. +%% and returned when a halt condition is fulfilled. repeat_expect(_Name,_Pid,Rest,_Pattern,Acc,#eo{repeat=0}) -> {ok,lists:reverse(Acc),done,Rest}; repeat_expect(Name,Pid,Data,Pattern,Acc,EO) -> @@ -1342,7 +955,7 @@ one_expect1(Name,Pid,Data,Pattern,Rest,EO) -> %% 2) Sequence. %% First the whole data chunk is searched for a prompt (to avoid doing %% a regexp match for the prompt at each line). -%% If we are searching for anyting else, the datachunk is split into +%% If we are searching for anything else, the datachunk is split into %% lines and each line is matched against the first pattern in the list. %% When a match is found, the match result is accumulated, and we keep %% searching for the next pattern in the list. @@ -1530,8 +1143,6 @@ add_tabs([],[$\n|Acc],LastLine) -> add_tabs([],[],LastLine) -> {[],lists:reverse(LastLine)}. - -%%% @hidden teln_receive_until_prompt(Pid,Prx,Timeout) -> Fun = fun() -> teln_receive_until_prompt(Pid,Prx,[],[]) end, ct_gen_conn:do_within_time(Fun, Timeout). diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl index bd3755722f..2c18caf18f 100644 --- a/lib/common_test/src/ct_testspec.erl +++ b/lib/common_test/src/ct_testspec.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2017. All Rights Reserved. +%% Copyright Ericsson AB 2006-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. @@ -18,10 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Common Test Framework functions handling test specifications. -%%% -%%%

This module exports functions that are used within CT to -%%% scan and parse test specifikations.

-module(ct_testspec). -export([prepare_tests/1, prepare_tests/2, diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl index 5992f26e6d..7a210237a8 100644 --- a/lib/common_test/src/unix_telnet.erl +++ b/lib/common_test/src/unix_telnet.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%% Copyright Ericsson AB 2004-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. @@ -18,39 +18,6 @@ %% %CopyrightEnd% %% -%%% @doc Callback module for ct_telnet, for connecting to a telnet -%%% server on a unix host. -%%% -%%%

It requires the following entry in the config file:

-%%%
-%%% {unix,[{telnet,HostNameOrIpAddress},
-%%%        {port,PortNum},                 % optional
-%%%        {username,UserName},
-%%%        {password,Password},
-%%%        {keep_alive,Bool},              % optional
-%%%        {tcp_nodely,Bool}]}             % optional
-%%% -%%%

To communicate via telnet to the host specified by -%%% HostNameOrIpAddress, use the interface functions in -%%% ct_telnet, e.g. open(Name), cmd(Name,Cmd), ....

-%%% -%%%

Name is the name you allocated to the unix host in -%%% your require statement. E.g.

-%%%
   suite() -> [{require,Name,{unix,[telnet]}}].
-%%%

or

-%%%
   ct:require(Name,{unix,[telnet]}).
-%%% -%%%

The "keep alive" activity (i.e. that Common Test sends NOP to the server -%%% every 10 seconds if the connection is idle) may be enabled or disabled for one -%%% particular connection as described here. It may be disabled for all connections -%%% using telnet_settings (see ct_telnet).

-%%% -%%%

Note that the {port,PortNum} tuple is optional and if -%%% omitted, default telnet port 23 will be used. Also the keep_alive tuple -%%% is optional, and the value defauls to true (enabled).

-%%% -%%% @see ct -%%% @see ct_telnet -module(unix_telnet). %% Callbacks for ct_telnet.erl @@ -61,36 +28,9 @@ -define(password,"Password: "). -define(prx,"login: |Password: |\\\$ |> "). -%%%----------------------------------------------------------------- -%%% @spec get_prompt_regexp() -> PromptRegexp -%%% PromptRegexp = ct_telnet:prompt_regexp() -%%% -%%% @doc Callback for ct_telnet.erl. -%%% -%%%

Return a suitable regexp string that will match common -%%% prompts for users on unix hosts.

get_prompt_regexp() -> ?prx. - -%%%----------------------------------------------------------------- -%%% @spec connect(ConnName,Ip,Port,Timeout,KeepAlive,Extra) -> -%%% {ok,Handle} | {error,Reason} -%%% ConnName = ct:target_name() -%%% Ip = string() | {integer(),integer(),integer(),integer()} -%%% Port = integer() -%%% Timeout = integer() -%%% KeepAlive = bool() -%%% TCPNoDelay = bool() -%%% Extra = ct:target_name() | {Username,Password} -%%% Username = string() -%%% Password = string() -%%% Handle = ct_telnet:handle() -%%% Reason = term() -%%% -%%% @doc Callback for ct_telnet.erl. -%%% -%%%

Setup telnet connection to a unix host.

connect(ConnName,Ip,Port,Timeout,KeepAlive,TCPNoDelay,Extra) -> case Extra of {Username,Password} -> -- cgit v1.2.3