diff options
-rw-r--r-- | lib/common_test/doc/src/common_test_app.xml | 776 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct.xml | 1386 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_cover.xml | 106 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_ftp.xml | 277 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_hooks.xml | 805 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_master.xml | 220 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_netconfc.xml | 1037 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_property_test.xml | 116 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_rpc.xml | 220 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_run.xml | 299 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_slave.xml | 221 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_snmp.xml | 524 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_ssh.xml | 1150 | ||||
-rw-r--r-- | lib/common_test/doc/src/ct_telnet.xml | 601 | ||||
-rw-r--r-- | lib/common_test/doc/src/ref_man.xml | 38 | ||||
-rw-r--r-- | lib/common_test/doc/src/unix_telnet.xml | 134 |
16 files changed, 6929 insertions, 981 deletions
diff --git a/lib/common_test/doc/src/common_test_app.xml b/lib/common_test/doc/src/common_test_app.xml index cc554eb84e..10c93e2ed1 100644 --- a/lib/common_test/doc/src/common_test_app.xml +++ b/lib/common_test/doc/src/common_test_app.xml @@ -33,89 +33,84 @@ <file>common_test_app.sgml</file> </header> <module>common_test</module> - <modulesummary>A framework for automated testing of arbitrary target nodes</modulesummary> + <modulesummary>A framework for automated testing of any target nodes.</modulesummary> <description> - <p>The <em>Common Test</em> framework is an environment for + <p>The <c>Common Test</c> framework is an environment for implementing and performing automatic and semi-automatic execution of - test cases. + test cases.</p> - Common Test uses the OTP Test Server as engine for test case - execution and logging.</p> - - <p>In brief, Common Test supports:</p> + <p>In brief, <c>Common Test</c> supports:</p> <list> - <item>Automated execution of test suites (sets of test cases).</item> - <item>Logging of the events during execution.</item> - <item>HTML presentation of test suite results.</item> - <item>HTML presentation of test suite code.</item> - <item>Support functions for test suite authors.</item> - <item>Step by step execution of test cases.</item> + <item>Automated execution of test suites (sets of test cases)</item> + <item>Logging of events during execution</item> + <item>HTML presentation of test suite results</item> + <item>HTML presentation of test suite code</item> + <item>Support functions for test suite authors</item> + <item>Step-by-step execution of test cases</item> </list> - - <p>The following sections describe the mandatory and optional test suite - functions Common Test will call during test execution. For more details - see <seealso marker="write_test_chapter">Common Test User's - Guide.</seealso> </p> - + + <p>The following section describes the mandatory and optional test suite + functions that <c>Common Test</c> calls during test execution. + For more details, see section + <seealso marker="write_test_chapter">Writing Test Suites</seealso> + in the User's Guide.</p> + </description> <section> - <title>TEST CASE CALLBACK FUNCTIONS</title> + <title>Test Case Callback Functions</title> <p>The following functions define the callback interface for a test suite.</p> </section> - + <funcs> <func> <name>Module:all() -> Tests | {skip,Reason} </name> <fsummary>Returns the list of all test case groups and test cases in the module.</fsummary> <type> - <v>Tests = [TestCase | {group,GroupName} | - {group,GroupName,Properties} | - {group,GroupName,Properties,SubGroups}]</v> + <v>Tests = [TestCase | {group,GroupName} | {group,GroupName,Properties} | {group,GroupName,Properties,SubGroups}]</v> <v>TestCase = atom()</v> <v>GroupName = atom()</v> - <v>Properties = [parallel | sequence | Shuffle | {RepeatType,N}] | - default</v> - <v>SubGroups = [{GroupName,Properties} | - {GroupName,Properties,SubGroups}]</v> + <v>Properties = [parallel | sequence | Shuffle | {RepeatType,N}] | default</v> + <v>SubGroups = [{GroupName,Properties} | {GroupName,Properties,SubGroups}]</v> <v>Shuffle = shuffle | {shuffle,Seed}</v> <v>Seed = {integer(),integer(),integer()}</v> - <v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | - repeat_until_any_ok | repeat_until_any_fail</v> + <v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | repeat_until_any_ok | repeat_until_any_fail</v> <v>N = integer() | forever</v> <v>Reason = term()</v> </type> - + <desc> - <p> MANDATORY </p> - - <p>This function must return the list of all test cases and test - case groups in the test suite module that are to be executed. - This list also specifies the order the cases and groups will - be executed by Common Test. A test case is represented by an atom, + <p>MANDATORY</p> + + <p>Returns the list of all test cases and test case groups in the + test suite module to be executed. This list also specifies the + order the cases and groups are executed by <c>Common Test</c>. + A test case is represented by an atom, the name of the test case function. A test case group is represented by a <c>group</c> tuple, where <c>GroupName</c>, - an atom, is the name of the group (defined in <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). - Execution properties for groups may also be specified, both - for a top level group and for any of its sub-groups. - Group execution properties specified here, will override - properties in the group definition (see <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). + an atom, is the name of the group (defined in + <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). + Execution properties for groups can also be specified, both + for a top-level group and for any of its subgroups. + Group execution properties specified here override + properties in the group definition (see + <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). (With value <c>default</c>, the group definition properties - will be used).</p> - - <p> If <c>{skip,Reason}</c> is returned, all test cases - in the module will be skipped, and the <c>Reason</c> will - be printed on the HTML result page.</p> - - <p>For details on groups, see - <seealso marker="write_test_chapter#test_case_groups">Test case - groups</seealso> in the User's Guide.</p> - + are used).</p> + + <p>If <c>{skip,Reason}</c> is returned, all test cases + in the module are skipped and <c>Reason</c> + is printed on the HTML result page.</p> + + <p>For details on groups, see section + <seealso marker="write_test_chapter#test_case_groups">Test Case + Groups</seealso> in the User's Guide.</p> + </desc> </func> @@ -123,25 +118,24 @@ <name>Module:groups() -> GroupDefs</name> <fsummary>Returns a list of test case group definitions.</fsummary> <type> - <v>GroupDefs = [Group]</v> - <v>Group = {GroupName,Properties,GroupsAndTestCases}</v> - <v>GroupName = atom()</v> - <v>Properties = [parallel | sequence | Shuffle | {RepeatType,N}]</v> - <v>GroupsAndTestCases = [Group | {group,GroupName} | TestCase]</v> - <v>TestCase = atom()</v> - <v>Shuffle = shuffle | {shuffle,Seed}</v> - <v>Seed = {integer(),integer(),integer()}</v> - <v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | - repeat_until_any_ok | repeat_until_any_fail</v> - <v>N = integer() | forever</v> + <v>GroupDefs = [Group]</v> + <v>Group = {GroupName,Properties,GroupsAndTestCases}</v> + <v>GroupName = atom()</v> + <v>Properties = [parallel | sequence | Shuffle | {RepeatType,N}]</v> + <v>GroupsAndTestCases = [Group | {group,GroupName} | TestCase]</v> + <v>TestCase = atom()</v> + <v>Shuffle = shuffle | {shuffle,Seed}</v> + <v>Seed = {integer(),integer(),integer()}</v> + <v>RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail | repeat_until_any_ok | repeat_until_any_fail</v> + <v>N = integer() | forever</v> </type> - + <desc> - <p> OPTIONAL </p> - - <p>Function for defining test case groups. Please see - <seealso marker="write_test_chapter#test_case_groups">Test case - groups</seealso> in the User's Guide for details.</p> + <p>OPTIONAL</p> + + <p>Defines test case groups. For details, see section + <seealso marker="write_test_chapter#test_case_groups">Test Case + Groups</seealso> in the User's Guide.</p> </desc> </func> @@ -150,75 +144,71 @@ <fsummary>Test suite info function (providing default data for the suite).</fsummary> <type> - <v> Info = {timetrap,Time} | {require,Required} | - {require,Name,Required} | {userdata,UserData} | - {silent_connections,Conns} | {stylesheet,CSSFile} | - {ct_hooks, CTHs}</v> - <v> Time = TimeVal | TimeFunc</v> - <v> TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} | - {hours,integer()}</v> - <v> TimeFunc = {Mod,Func,Args} | Fun</v> - <v> MilliSec = integer()</v> - <v> Mod = atom()</v> - <v> Func = atom()</v> - <v> Args = list()</v> - <v> Fun = fun()</v> - <v> Required = Key | {Key,SubKeys} | {Key,SubKey} | {Key,SubKey,SubKeys}</v> - <v> Key = atom()</v> - <v> SubKeys = SubKey | [SubKey]</v> - <v> SubKey = atom()</v> - <v> Name = atom()</v> - <v> UserData = term()</v> - <v> Conns = [atom()]</v> - <v> CSSFile = string()</v> - <v> CTHs = [CTHModule |</v> - <v> {CTHModule, CTHInitArgs} |</v> - <v> {CTHModule, CTHInitArgs, CTHPriority}]</v> - <v> CTHModule = atom()</v> - <v> CTHInitArgs = term()</v> + <v>Info = {timetrap,Time} | {require,Required} | {require,Name,Required} | {userdata,UserData} | {silent_connections,Conns} | {stylesheet,CSSFile} | {ct_hooks, CTHs}</v> + <v>Time = TimeVal | TimeFunc</v> + <v>TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} | {hours,integer()}</v> + <v>TimeFunc = {Mod,Func,Args} | Fun</v> + <v>MilliSec = integer()</v> + <v>Mod = atom()</v> + <v>Func = atom()</v> + <v>Args = list()</v> + <v>Fun = fun()</v> + <v>Required = Key | {Key,SubKeys} | {Key,SubKey} | {Key,SubKey,SubKeys}</v> + <v>Key = atom()</v> + <v>SubKeys = SubKey | [SubKey]</v> + <v>SubKey = atom()</v> + <v>Name = atom()</v> + <v>UserData = term()</v> + <v>Conns = [atom()]</v> + <v>CSSFile = string()</v> + <v>CTHs = [CTHModule |</v> + <v> {CTHModule, CTHInitArgs} |</v> + <v> {CTHModule, CTHInitArgs, CTHPriority}]</v> + <v>CTHModule = atom()</v> + <v>CTHInitArgs = term()</v> </type> <desc> - - <p> OPTIONAL </p> - - <p>This is the test suite info function. It is supposed to - return a list of tagged tuples that specify various properties - related to the execution of this test suite (common for all - test cases in the suite).</p> - - <p>The <c>timetrap</c> tag sets the maximum time each - test case is allowed to execute (including <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> - and <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>). If the timetrap time is - exceeded, the test case fails with reason + + <p>OPTIONAL</p> + + <p>The test suite information function. Returns a list of tagged + tuples specifying various properties related to the execution of + this test suite (common for all test cases in the suite).</p> + + <p>Tag <c>timetrap</c> sets the maximum time that each + test case is allowed to execute (including + <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> + and + <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>). + If the timetrap time is exceeded, the test case fails with reason <c>timetrap_timeout</c>. A <c>TimeFunc</c> function can be used to - set a new timetrap by returning a <c>TimeVal</c>. It may also be - used to trigger a timetrap timeout by, at some point, returning a - value other than a <c>TimeVal</c>. (See the - <seealso marker="write_test_chapter#timetraps">User's Guide</seealso> - for details). - </p> - - <p>The <c>require</c> tag specifies configuration variables - that are required by test cases (and/or configuration functions) + set a new timetrap by returning a <c>TimeVal</c>. It can also be + used to trigger a timetrap time-out by, at some point, returning a + value other than a <c>TimeVal</c>. For details, see section + <seealso marker="write_test_chapter#timetraps">Timetrap Time-Outs</seealso> + in the User's Guide.</p> + + <p>Tag <c>require</c> specifies configuration variables + required by test cases (or configuration functions) in the suite. If the required configuration variables are not found - in any of the configuration files, all test cases are skipped. For more - information about the 'require' functionality, see the - reference manual for the function - <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p> + in any of the configuration files, all test cases are skipped. + For details about the <c>require</c> functionality, see funtion + <seealso marker="ct#require-1"><c>ct:require/1,2</c></seealso>.</p> - <p>With <c>userdata</c>, it is possible for the user to - specify arbitrary test suite related information which can be - read by calling <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p> + <p>With <c>userdata</c>, the user can + specify any test suite-related information, which can be + read by calling + <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p> - <p>The <c>ct_hooks</c> tag specifies which + <p>Tag <c>ct_hooks</c> specifies the <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso> - are to be run together with this suite.</p> - - <p>Other tuples than the ones defined will simply be ignored.</p> + to be run with this suite.</p> - <p>For more information about the test suite info function, - see <seealso marker="write_test_chapter#suite">Test - suite info function</seealso> in the User's Guide.</p> + <p>Other tuples than the ones defined are ignored.</p> + + <p>For details about the test suite information function, see section + <seealso marker="write_test_chapter#suite">Test + Suite Information Function</seealso> in the User's Guide.</p> </desc> </func> @@ -227,129 +217,133 @@ {skip_and_save,Reason,SaveConfig}</name> <fsummary>Test suite initializations.</fsummary> <type> - <v> Config = NewConfig = SaveConfig = [{Key,Value}]</v> - <v> Key = atom()</v> - <v> Value = term()</v> - <v> Reason = term()</v> + <v>Config = NewConfig = SaveConfig = [{Key,Value}]</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> <desc> - - <p> OPTIONAL </p> - + + <p>OPTIONAL</p> + <p>This configuration function is called as the first function in the - suite. It typically contains initializations which are common for - all test cases in the suite, and which shall only be done - once. The <c>Config</c> parameter is the configuration data - which can be modified here. Whatever is returned from this - function is given as <c>Config</c> to all configuration functions - and test cases in the suite. If <c>{skip,Reason}</c> - is returned, all test cases in the suite will be skipped - and <c>Reason</c> printed in the overview log for the suite.</p> - <p>For information on <c>save_config</c> and <c>skip_and_save</c>, - please see - <seealso marker="dependencies_chapter#save_config">Dependencies - between Test Cases and Suites</seealso> in the User's Guide.</p> - </desc> + suite. It typically contains initializations that are common for + all test cases in the suite, and that must only be done + once. Parameter <c>Config</c> is the configuration data + that can be modified. Whatever is returned from this + function is specified as <c>Config</c> to all configuration functions + and test cases in the suite.</p> + + <p>If <c>{skip,Reason}</c> + is returned, all test cases in the suite are skipped + and <c>Reason</c> is printed in the overview log for the suite.</p> + + <p>For information on <c>save_config</c> and <c>skip_and_save</c>, + see section + <seealso marker="dependencies_chapter#save_config">Saving + Configuration Data</seealso> in the User's Guide.</p> + </desc> </func> - + <func> <name>Module:end_per_suite(Config) -> term() | {save_config,SaveConfig}</name> - <fsummary>Test suite finalization. </fsummary> + <fsummary>Test suite finalization.</fsummary> <type> - <v> Config = SaveConfig = [{Key,Value}]</v> - <v> Key = atom()</v> - <v> Value = term()</v> + <v>Config = SaveConfig = [{Key,Value}]</v> + <v>Key = atom()</v> + <v>Value = term()</v> </type> - + <desc> - <p> OPTIONAL </p> + <p>OPTIONAL</p> <p>This function is called as the last test case in the suite. It is meant to be used for cleaning up after - <seealso marker="#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso>. - For information on <c>save_config</c>, please see - <seealso marker="dependencies_chapter#save_config">Dependencies - between Test Cases and Suites</seealso> in the User's Guide.</p> + <seealso marker="#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso>.</p> + <p>For information on <c>save_config</c>, see section + <seealso marker="dependencies_chapter#save_config">Saving + Configuration Data</seealso> in the User's Guide.</p> </desc> </func> <func> <name>Module:group(GroupName) -> [Info] </name> - <fsummary>Test case group info function (providing default data - for a test case group, i.e. its test cases and sub-groups).</fsummary> + <fsummary>Test case group information function (providing default data + for a test case group, that is, its test cases and + subgroups).</fsummary> <type> - <v> Info = {timetrap,Time} | {require,Required} | - {require,Name,Required} | {userdata,UserData} | - {silent_connections,Conns} | {stylesheet,CSSFile} | - {ct_hooks, CTHs}</v> - <v> Time = TimeVal | TimeFunc</v> - <v> TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} | - {hours,integer()}</v> - <v> TimeFunc = {Mod,Func,Args} | Fun</v> - <v> MilliSec = integer()</v> - <v> Mod = atom()</v> - <v> Func = atom()</v> - <v> Args = list()</v> - <v> Fun = fun()</v> - <v> Required = Key | {Key,SubKeys} | {Key,Subkey} | {Key,Subkey,SubKeys}</v> - <v> Key = atom()</v> - <v> SubKeys = SubKey | [SubKey]</v> - <v> SubKey = atom()</v> - <v> Name = atom()</v> - <v> UserData = term()</v> - <v> Conns = [atom()]</v> - <v> CSSFile = string()</v> - <v> CTHs = [CTHModule |</v> - <v> {CTHModule, CTHInitArgs} |</v> - <v> {CTHModule, CTHInitArgs, CTHPriority}]</v> - <v> CTHModule = atom()</v> - <v> CTHInitArgs = term()</v> - </type> - <desc> - - <p> OPTIONAL </p> - - <p>This is the test case group info function. It is supposed to + <v>Info = {timetrap,Time} | {require,Required} | {require,Name,Required} | {userdata,UserData} | {silent_connections,Conns} | {stylesheet,CSSFile} | {ct_hooks, CTHs}</v> + <v>Time = TimeVal | TimeFunc</v> + <v>TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} | {hours,integer()}</v> + <v>TimeFunc = {Mod,Func,Args} | Fun</v> + <v>MilliSec = integer()</v> + <v>Mod = atom()</v> + <v>Func = atom()</v> + <v>Args = list()</v> + <v>Fun = fun()</v> + <v>Required = Key | {Key,SubKeys} | {Key,Subkey} | {Key,Subkey,SubKeys}</v> + <v>Key = atom()</v> + <v>SubKeys = SubKey | [SubKey]</v> + <v>SubKey = atom()</v> + <v>Name = atom()</v> + <v>UserData = term()</v> + <v>Conns = [atom()]</v> + <v>CSSFile = string()</v> + <v>CTHs = [CTHModule |</v> + <v> {CTHModule, CTHInitArgs} |</v> + <v> {CTHModule, CTHInitArgs, CTHPriority}]</v> + <v>CTHModule = atom()</v> + <v>CTHInitArgs = term()</v> + </type> + <desc> + + <p>OPTIONAL</p> + + <p>The test case group information function. It is supposed to return a list of tagged tuples that specify various properties - related to the execution of a test case group (i.e. its test cases - and sub-groups). Properties set by + related to the execution of a test case group (that is, its test + cases and subgroups). Properties set by <seealso marker="#Module:group-1"><c>group/1</c></seealso> override - properties with the same key that have been previously set by + properties with the same key that have been set previously by <seealso marker="#Module:suite-0"><c>suite/0</c></seealso>.</p> - <p>The <c>timetrap</c> tag sets the maximum time each - test case is allowed to execute (including <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> - and <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>). If the timetrap time is + <p>Tag <c>timetrap</c> sets the maximum time that each + test case is allowed to execute (including + <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> + and + <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso>). + If the timetrap time is exceeded, the test case fails with reason <c>timetrap_timeout</c>. A <c>TimeFunc</c> function can be used to - set a new timetrap by returning a <c>TimeVal</c>. It may also be - used to trigger a timetrap timeout by, at some point, returning a - value other than a <c>TimeVal</c>. (See the - <seealso marker="write_test_chapter#timetraps">User's Guide</seealso> - for details).</p> + set a new timetrap by returning a <c>TimeVal</c>. It can also be + used to trigger a timetrap time-out by, at some point, returning a + value other than a <c>TimeVal</c>. For details, see section + <seealso marker="write_test_chapter#timetraps">Timetrap + Time-Outs</seealso> in the User's Guide.</p> - <p>The <c>require</c> tag specifies configuration variables - that are required by test cases (and/or configuration functions) + <p>Tag <c>require</c> specifies configuration variables + required by test cases (or configuration functions) in the suite. If the required configuration variables are not found - in any of the configuration files, all test cases in this group are skipped. - For more information about the 'require' functionality, see the - reference manual for the function - <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p> + in any of the configuration files, all test cases in this group are + skipped. For details about the <c>require</c> functionality, see + function + <seealso marker="ct#require-1"><c>ct:require/1,2</c></seealso>.</p> - <p>With <c>userdata</c>, it is possible for the user to - specify arbitrary test case group related information which can be - read by calling <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p> + <p>With <c>userdata</c>, the user can + specify any test case group related information that can be + read by calling + <seealso marker="ct#userdata-2"><c>ct:userdata/2</c></seealso>.</p> - <p>The <c>ct_hooks</c> tag specifies which + <p>Tag <c>ct_hooks</c> specifies the <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso> - are to be run together with this suite.</p> - - <p>Other tuples than the ones defined will simply be ignored.</p> + to be run with this suite.</p> - <p>For more information about the test case group info function, - see <seealso marker="write_test_chapter#suite">Test - case group info function</seealso> in the User's Guide.</p> + <p>Other tuples than the ones defined are ignored.</p> + + <p>For details about the test case group information function, + see section <seealso marker="write_test_chapter#group_info">Group + Information Function</seealso> in the User's Guide.</p> </desc> </func> @@ -358,59 +352,66 @@ {skip,Reason}</name> <fsummary>Test case group initializations.</fsummary> <type> - <v> GroupName = atom()</v> - <v> Config = NewConfig = [{Key,Value}]</v> - <v> Key = atom()</v> - <v> Value = term()</v> - <v> Reason = term()</v> + <v>GroupName = atom()</v> + <v>Config = NewConfig = [{Key,Value}]</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> <desc> - - <p> OPTIONAL </p> - + + <p>OPTIONAL</p> + <p>This configuration function is called before execution of a - test case group. It typically contains initializations which are - common for all test cases and sub-groups in the group, and which - shall only be performed once. <c>GroupName</c> is the name of the - group, as specified in the group definition (see <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). The - <c>Config</c> parameter is the configuration data which can be modified - here. The return value of this function is given as <c>Config</c> - to all test cases and sub-groups in the group. If <c>{skip,Reason}</c> - is returned, all test cases in the group will be skipped and - <c>Reason</c> printed in the overview log for the group.</p> - - <p>For information about test case groups, please see - <seealso marker="write_test_chapter#test_case_groups">Test case - groups</seealso> chapter in the User's Guide.</p> + test case group. It typically contains initializations that are + common for all test cases and subgroups in the group, and that + must only be performed once. <c>GroupName</c> is the name of the + group, as specified in the group definition (see + <seealso marker="#Module:groups-0"><c>groups/0</c></seealso>). + Parameter <c>Config</c> is the configuration data that can be + modified. + The return value of this function is given as <c>Config</c> + to all test cases and subgroups in the group.</p> + + <p>If <c>{skip,Reason}</c> + is returned, all test cases in the group are skipped and + <c>Reason</c> is printed in the overview log for the group.</p> + + <p>For information about test case groups, see section + <seealso marker="write_test_chapter#test_case_groups">Test Case + Groups</seealso> in the User's Guide.</p> </desc> </func> - + <func> <name>Module:end_per_group(GroupName, Config) -> term() | {return_group_result,Status}</name> <fsummary>Test case group finalization.</fsummary> <type> - <v> GroupName = atom()</v> - <v> Config = [{Key,Value}]</v> - <v> Key = atom()</v> - <v> Value = term()</v> - <v> Status = ok | skipped | failed</v> + <v>GroupName = atom()</v> + <v>Config = [{Key,Value}]</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Status = ok | skipped | failed</v> </type> - + <desc> - <p> OPTIONAL </p> - - <p>This function is called after the execution of a test case group is finished. - It is meant to be used for cleaning up after <seealso marker="#Module:init_per_group-2"><c>init_per_group/2</c></seealso>. - By means of <c>{return_group_result,Status}</c>, it is possible to return a - status value for a nested sub-group. The status can be retrieved in - <seealso marker="#Module:end_per_group-2"><c>end_per_group/2</c></seealso> for the group on the level above. The status will also - be used by Common Test for deciding if execution of a group should proceed in - case the property <c>sequence</c> or <c>repeat_until_*</c> is set.</p> - - <p>For more information about test case groups, please see - <seealso marker="write_test_chapter#test_case_groups">Test case - groups</seealso> chapter in the User's Guide.</p> + <p>OPTIONAL</p> + + <p>This function is called after the execution of a test case group + is finished. It is meant to be used for cleaning up after + <seealso marker="#Module:init_per_group-2"><c>init_per_group/2</c></seealso>. + A status value for a nested subgroup can be returned with + <c>{return_group_result,Status}</c>. The status can be retrieved in + <seealso marker="#Module:end_per_group-2"><c>end_per_group/2</c></seealso> + for the group on the level above. The status is also used by + <c>Common Test</c> for deciding if execution of a group is to + proceed if property <c>sequence</c> or <c>repeat_until_*</c> + is set.</p> + + <p>For details about test case groups, see section + <seealso marker="write_test_chapter#test_case_groups">Test Case + Groups</seealso> in the User's Guide.</p> </desc> </func> @@ -424,168 +425,173 @@ <v> Value = term()</v> <v> Reason = term()</v> </type> - <desc> - + <desc> + <p>OPTIONAL</p> - - <p>This function is called before each test case. The - <c>TestCase</c> argument is the name of the test case, and + + <p>This function is called before each test case. Argument + <c>TestCase</c> is the test case name, and <c>Config</c> (list of key-value tuples) is the configuration - data that can be modified here. The <c>NewConfig</c> list returned + data that can be modified. The <c>NewConfig</c> list returned from this function is given as <c>Config</c> to the test case. If <c>{fail,Reason}</c> is returned, the test case is - marked as failed without being executed. If <c>{skip,Reason}</c> is - returned, the test case will be skipped and <c>Reason</c> printed - in the overview log for the suite.</p> + marked as failed without being executed.</p> + + <p>If <c>{skip,Reason}</c> is returned, the test case is skipped + and <c>Reason</c> is printed in the overview log for the suite.</p> </desc> </func> - + <func> <name>Module:end_per_testcase(TestCase, Config) -> term() | {fail,Reason} | {save_config,SaveConfig}</name> <fsummary>Test case finalization.</fsummary> <type> - <v> TestCase = atom()</v> - <v> Config = SaveConfig = [{Key,Value}]</v> - <v> Key = atom()</v> - <v> Value = term()</v> - <v> Reason = term()</v> + <v>TestCase = atom()</v> + <v>Config = SaveConfig = [{Key,Value}]</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> <desc> - - <p> OPTIONAL </p> - - <p> This function is called after each test case, and can be used - to clean up after <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> and the test case. - Any return value (besides <c>{fail,Reason}</c> and <c>{save_config,SaveConfig}</c>) - is ignored. By returning <c>{fail,Reason}</c>, <c>TestCase</c> will be marked as - failed (even though it was actually successful in the sense that it returned - a value instead of terminating). For information on <c>save_config</c>, please see - <seealso marker="dependencies_chapter#save_config">Dependencies between - Test Cases and Suites</seealso> in the User's Guide</p> + + <p>OPTIONAL</p> + + <p>This function is called after each test case, and can be used + to clean up after + <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> + and the test case. Any return value (besides <c>{fail,Reason}</c> + and <c>{save_config,SaveConfig}</c>) is ignored. By returning + <c>{fail,Reason}</c>, <c>TestCase</c> is marked as faulty (even + though it was successful in the sense that it returned + a value instead of terminating).</p> + + <p>For information on <c>save_config</c>, see section + <seealso marker="dependencies_chapter#save_config">Saving + Configuration Data</seealso> in the User's Guide.</p> </desc> </func> - + <func> <name>Module:Testcase() -> [Info] </name> - <fsummary>Test case info function. </fsummary> + <fsummary>Test case information function.</fsummary> <type> - <v> Info = {timetrap,Time} | {require,Required} | - {require,Name,Required} | {userdata,UserData} | - {silent_connections,Conns}</v> - <v> Time = TimeVal | TimeFunc</v> - <v> TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} | - {hours,integer()}</v> - <v> TimeFunc = {Mod,Func,Args} | Fun</v> - <v> MilliSec = integer()</v> - <v> Mod = atom()</v> - <v> Func = atom()</v> - <v> Args = list()</v> - <v> Fun = fun()</v> - <v> Required = Key | {Key,SubKeys} | {Key,Subkey} | {Key,Subkey,SubKeys}</v> - <v> Key = atom()</v> - <v> SubKeys = SubKey | [SubKey]</v> - <v> SubKey = atom()</v> - <v> Name = atom()</v> - <v> UserData = term()</v> - <v> Conns = [atom()]</v> + <v>Info = {timetrap,Time} | {require,Required} | {require,Name,Required} | {userdata,UserData} | {silent_connections,Conns}</v> + <v>Time = TimeVal | TimeFunc</v> + <v>TimeVal = MilliSec | {seconds,integer()} | {minutes,integer()} | {hours,integer()}</v> + <v>TimeFunc = {Mod,Func,Args} | Fun</v> + <v>MilliSec = integer()</v> + <v>Mod = atom()</v> + <v>Func = atom()</v> + <v>Args = list()</v> + <v>Fun = fun()</v> + <v>Required = Key | {Key,SubKeys} | {Key,Subkey} | {Key,Subkey,SubKeys}</v> + <v>Key = atom()</v> + <v>SubKeys = SubKey | [SubKey]</v> + <v>SubKey = atom()</v> + <v>Name = atom()</v> + <v>UserData = term()</v> + <v>Conns = [atom()]</v> </type> - - <desc> + + <desc> <p>OPTIONAL</p> - - <p>This is the test case info function. It is supposed to + + <p>The test case information function. It is supposed to return a list of tagged tuples that specify various properties related to the execution of this particular test case. - Properties set by <seealso marker="#Module:Testcase-0"><c>Testcase/0</c></seealso> override - properties that have been previously set for the test case - by <seealso marker="#Module:group-1"><c>group/1</c></seealso> or <seealso marker="#Module:suite-0"><c>suite/0</c></seealso>.</p> - - <p>The <c>timetrap</c> tag sets the maximum time the + Properties set by + <seealso marker="#Module:Testcase-0"><c>Testcase/0</c></seealso> + override properties set previously for the test case by + <seealso marker="#Module:group-1"><c>group/1</c></seealso> or + <seealso marker="#Module:suite-0"><c>suite/0</c></seealso>.</p> + + <p>Tag <c>timetrap</c> sets the maximum time that the test case is allowed to execute. If the timetrap time is - exceeded, the test case fails with reason - <c>timetrap_timeout</c>. <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> - and <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso> are included in the - timetrap time. A <c>TimeFunc</c> function can be used to - set a new timetrap by returning a <c>TimeVal</c>. It may also be - used to trigger a timetrap timeout by, at some point, returning a - value other than a <c>TimeVal</c>. (See the - <seealso marker="write_test_chapter#timetraps">User's Guide</seealso> - for details).</p> + exceeded, the test case fails with reason <c>timetrap_timeout</c>. + <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> + and + <seealso marker="#Module:end_per_testcase-2"><c>end_per_testcase/2</c></seealso> + are included in the timetrap time. + A <c>TimeFunc</c> function can be used to + set a new timetrap by returning a <c>TimeVal</c>. It can also be + used to trigger a timetrap time-out by, at some point, returning a + value other than a <c>TimeVal</c>. For details, see section + <seealso marker="write_test_chapter#timetraps">Timetrap + Time-Outs</seealso> in the User's Guide.</p> - <p>The <c>require</c> tag specifies configuration variables - that are required by the test case (and/or <c>init/end_per_testcase/2</c>). + <p>Tag <c>require</c> specifies configuration variables + that are required by the test case (or <c>init_per_testcase/2</c> + or <c>end_per_testcase/2</c>). If the required configuration variables are not found in any of the - configuration files, the test case is skipped. For more - information about the 'require' functionality, see the - reference manual for the function - <seealso marker="ct#require-1"><c>ct:require/1/2</c></seealso>.</p> - - <p>If <c>timetrap</c> and/or <c>require</c> is not set, the - default values specified by <seealso marker="#Module:suite-0"><c>suite/0</c></seealso> (or - <seealso marker="#Module:group-1"><c>group/1</c></seealso>) will be used.</p> - - <p>With <c>userdata</c>, it is possible for the user to - specify arbitrary test case related information which can be - read by calling <seealso marker="ct#userdata-3"><c>ct:userdata/3</c></seealso>.</p> - - <p>Other tuples than the ones defined will simply be ignored.</p> + configuration files, the test case is skipped. For details about + the <c>require</c> functionality, see function + <seealso marker="ct#require-1"><c>ct:require/1,2</c></seealso>.</p> + + <p>If <c>timetrap</c> or <c>require</c> is not set, the + default values specified by + <seealso marker="#Module:suite-0"><c>suite/0</c></seealso> (or + <seealso marker="#Module:group-1"><c>group/1</c></seealso>) are used.</p> + + <p>With <c>userdata</c>, the user can specify any test case-related + information that can be read by calling + <seealso marker="ct#userdata-3"><c>ct:userdata/3</c></seealso>.</p> + + <p>Other tuples than the ones defined are ignored.</p> - <p>For more information about the test case info function, - see <seealso marker="write_test_chapter#info_function">Test - case info function</seealso> in the User's Guide.</p> + <p>For details about the test case information function, see section + <seealso marker="write_test_chapter#info_function">Test + Case Information Function</seealso> in the User's Guide.</p> </desc> </func> - - + <func> <name>Module:Testcase(Config) -> term() | {skip,Reason} | {comment,Comment} | {save_config,SaveConfig} | {skip_and_save,Reason,SaveConfig} | exit() </name> - <fsummary>A test case</fsummary> + <fsummary>A test case.</fsummary> <type> - <v> Config = SaveConfig = [{Key,Value}]</v> - <v> Key = atom()</v> - <v> Value = term()</v> - <v> Reason = term()</v> - <v> Comment = string()</v> + <v>Config = SaveConfig = [{Key,Value}]</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> + <v>Comment = string()</v> </type> - + <desc> - <p> MANDATORY </p> - - <p>This is the implementation of a test case. Here you must - call the functions you want to test, and do whatever you - need to check the result. If something fails, make sure the - function causes a runtime error, or call <seealso marker="ct#fail-1"><c>ct:fail/1/2</c></seealso> + <p>MANDATORY</p> + + <p>The implementation of a test case. Call the functions to test and + check the result. If something fails, ensure the + function causes a runtime error or call + <seealso marker="ct#fail-1"><c>ct:fail/1,2</c></seealso> (which also causes the test case process to terminate).</p> - - <p>Elements from the <c>Config</c> list can e.g. be read - with <c>proplists:get_value/2</c> (or the macro <c>?config</c> - defined in <c>ct.hrl</c>).</p> - <p>You can return <c>{skip,Reason}</c> if you decide not to - run the test case after all. <c>Reason</c> will then be - printed in 'Comment' field on the HTML result page.</p> - - <p>You can return <c>{comment,Comment}</c> if you wish to - print some information in the 'Comment' field on the HTML - result page.</p> - - <p>If the function returns anything else, the test case is - considered successful. (The return value always gets printed - in the test case log file).</p> + <p>Elements from the <c>Config</c> list can, for example, be read + with <c>proplists:get_value/2</c> in <c>STDLIB</c> + (or the macro <c>?config</c> defined in <c>ct.hrl</c>).</p> + + <p>If you decide not to run the test case after all, return + <c>{skip,Reason}</c>. <c>Reason</c> is then + printed in field <c>Comment</c> on the HTML result page.</p> + + <p>To print some information in field <c>Comment</c> on the HTML + result page, return <c>{comment,Comment}</c>.</p> - <p>For more information about test case implementation, please - see <seealso marker="write_test_chapter#test_cases">Test - cases</seealso> in the User's Guide.</p> + <p>If the function returns anything else, the test case is + considered successful. The return value always gets printed + in the test case log file.</p> - <p>For information on <c>save_config</c> and <c>skip_and_save</c>, please see - <seealso marker="dependencies_chapter#save_config">Dependencies between - Test Cases and Suites</seealso> in the User's Guide.</p> + <p>For details about test case implementation, see section + <seealso marker="write_test_chapter#test_cases">Test Cases</seealso> + in the User's Guide.</p> + + <p>For information on <c>save_config</c> and <c>skip_and_save</c>, + see section + <seealso marker="dependencies_chapter#save_config">Saving + Configuration Data</seealso> in the User's Guide.</p> </desc> </func> - + </funcs> </erlref> - diff --git a/lib/common_test/doc/src/ct.xml b/lib/common_test/doc/src/ct.xml new file mode 100644 index 0000000000..ed3d76061a --- /dev/null +++ b/lib/common_test/doc/src/ct.xml @@ -0,0 +1,1386 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct.xml</file> + </header> + <module>ct</module> + <modulesummary>Main user interface for the Common Test framework.</modulesummary> + + <description> + + <p>Main user interface for the <c>Common Test</c> framework.</p> + + <p>This module implements the command-line interface for running + tests and basic functions for <c>Common Test</c> case issues, such as + configuration and logging.</p> + + <p><em>Test Suite Support Macros</em></p> + + <p>The <c>config</c> macro is defined in <c>ct.hrl</c>. This macro is + to be used to retrieve information from the <c>Config</c> variable sent + to all test cases. It is used with two arguments; the first is the name + of the configuration variable to retrieve, the second is the + <c>Config</c> variable supplied to the test case.</p> + + <p>Possible configuration variables include:</p> + + <list type="bulleted"> + <item><p><c>data_dir</c> - Data file directory</p></item> + <item><p><c>priv_dir</c> - Scratch file directory</p></item> + <item><p>Whatever added by + <seealso marker="#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso> + or + <seealso marker="#Module:init_per_testcase-2"><c>init_per_testcase/2</c></seealso> + in the test suite.</p></item> + </list> + + </description> + + <section> + <title>Data Types</title> + <marker id="types"/> + <taglist> + + <tag><c>handle() = pid()</c></tag> + <item><marker id="type-handle"/> + <p>The identity (handle) of a connection.</p></item> + + <tag><c>target_name() = atom()</c></tag> + <item><marker id="type-target_name"/> + <p>A name and association to configuration data introduced + through a require statement, or a call to + <seealso marker="#require-2"><c>ct:require/2</c></seealso>, + for example, + <c>ct:require(mynodename,{node,[telnet]})</c>.</p></item> + + </taglist> + </section> + + <funcs> + <func> + <name>abort_current_testcase(Reason) -> ok | {error, ErrorReason}</name> + <fsummary>Aborts the currently executing test case.</fsummary> + <type> + <v>Reason = term()</v> + <v>ErrorReason = no_testcase_running | parallel_group</v> + </type> + <desc><marker id="abort_current_testcase-1"/> + <p>Aborts the currently executing test case. The user must know with + certainty which test case is currently executing. The function is + therefore only safe to call from a function that has been called + (or synchronously invoked) by the test case.</p> + + <p><c>Reason</c>, the reason for aborting the test case, is printed + in the test case log.</p> + </desc> + </func> + + <func> + <name>add_config(Callback, Config) -> ok | {error, Reason}</name> + <fsummary>Loads configuration variables using the specified callback + module and configuration string.</fsummary> + <type> + <v>Callback = atom()</v> + <v>Config = string()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="add_config-2"/> + <p>Loads configuration variables using the specified callback module and + configuration string. The callback module is to be either loaded or + present in the code part. Loaded configuration variables can later + be removed using function + <seealso marker="#remove_config-2"><c>ct:remove_config/2</c></seealso>. + </p> + </desc> + </func> + + <func> + <name>break(Comment) -> ok | {error, Reason}</name> + <fsummary>Cancels any active timetrap and pause the execution of the + current test case until the user calls function continue/0.</fsummary> + <type> + <v>Comment = string()</v> + <v>Reason = {multiple_cases_running, TestCases} | 'enable break with release_shell option'</v> + <v>TestCases = [atom()]</v> + </type> + <desc><marker id="break-1"/> + <p>Cancels any active timetrap and pauses the execution of the + current test case until the user calls function <c>continue/0</c>. + The user can then interact with the Erlang node running the tests, + for example, for debugging purposes or for manually executing a + part of the test case. If a parallel group is executing, + <seealso marker="#break-2"><c>ct:break/2</c></seealso> is to be + called instead.</p> + <p>A cancelled timetrap is not automatically reactivated after the + break, but must be started exlicitly with + <seealso marker="#timetrap-1"><c>ct:timetrap/1</c></seealso>.</p> + <p>In order for the break/continue functionality to work, <c>Common + Test</c> must release the shell process controlling <c>stdin</c>. + This is done by setting start option <c>release_shell</c> + to <c>true</c>. For details, see section + <seealso marker="run_test_chapter#erlang_shell_or_program">Running + Tests from the Erlang Shell or from an Erlang Program</seealso> + in the User's Guide.</p> + </desc> + </func> + + <func> + <name>break(TestCase, Comment) -> ok | {error, Reason}</name> + <fsummary>Works the same way as break/1, only argument TestCase makes it + possible to pause a test case executing in a parallel group.</fsummary> + <type> + <v>TestCase = atom()</v> + <v>Comment = string()</v> + <v>Reason = 'test case not running' | 'enable break with release_shell option'</v> + </type> + <desc><marker id="break-2"/> + <p>Works the same way as + <seealso marker="#break-1"><c>ct:break/1</c></seealso>, only + argument <c>TestCase</c> makes it possible to pause a test case + executing in a parallel group. Function + <seealso marker="#continue-1"><c>ct:continue/1</c></seealso> is to + be used to resume execution of <c>TestCase</c>.</p> + + <p>For details, see + <seealso marker="#break/1"><c>ct:break/1</c></seealso>.</p> + </desc> + </func> + + <func> + <name>capture_get() -> ListOfStrings</name> + <fsummary>Equivalent to capture_get([default]).</fsummary> + <type> + <v>ListOfStrings = [string()]</v> + </type> + <desc><marker id="capture_get-0"/> + <p>Equivalent to + <seealso marker="#capture_get-1">ct:capture_get([default])</seealso>.</p> + </desc> + </func> + + <func> + <name>capture_get(ExclCategories) -> ListOfStrings</name> + <fsummary>Returns and purges the list of text strings buffered during + the latest session of capturing printouts to stdout.</fsummary> + <type> + <v>ExclCategories = [atom()]</v> + <v>ListOfStrings = [string()]</v> + </type> + <desc><marker id="capture_get-1"/> + <p>Returns and purges the list of text strings buffered during the + latest session of capturing printouts to <c>stdout</c>. Log + categories that are to be ignored in <c>ListOfStrings</c> can be + specified with <c>ExclCategories</c>. + If <c>ExclCategories = []</c>, no filtering takes place.</p> + + <p>See also + <seealso marker="#capture_start-0"><c>ct:capture_start/0</c></seealso>, + <seealso marker="#capture_stop-0"><c>ct:capture_stop/0</c></seealso>, + <seealso marker="#log-3"><c>ct:log/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>capture_start() -> ok</name> + <fsummary>Starts capturing all text strings printed to stdout + during execution of the test case.</fsummary> + <desc><marker id="capture_start-0"/> + <p>Starts capturing all text strings printed to <c>stdout</c> + during execution of the test case.</p> + + <p>See also + <seealso marker="#capture_get-1"><c>ct:capture_get/1</c></seealso>, + <seealso marker="#capture_stop-0"><c>ct:capture_stop/0</c></seealso>.</p> + </desc> + </func> + + <func> + <name>capture_stop() -> ok</name> + <fsummary>Stops capturing text strings (a session started with + capture_start/0).</fsummary> + <desc><marker id="capture_stop-0"/> + <p>Stops capturing text strings (a session started with + <c>capture_start/0</c>).</p> + + <p>See also + <seealso marker="#capture_get-1"><c>ct:capture_get/1</c></seealso>, + <seealso marker="#capture_start-0"><c>ct:capture_start/0</c></seealso>.</p> + </desc> + </func> + + <func> + <name>comment(Comment) -> ok</name> + <fsummary>Prints the specified Comment in the comment field in the + table on the test suite result page.</fsummary> + <type> + <v>Comment = term()</v> + </type> + <desc><marker id="comment-1"/> + <p>Prints the specified <c>Comment</c> in the comment field in the + table on the test suite result page.</p> + + <p>If called several times, only the last comment is printed. The + test case return value <c>{comment,Comment}</c> overwrites the + string set by this function.</p> + </desc> + </func> + + <func> + <name>comment(Format, Args) -> ok</name> + <fsummary>Prints the formatted string in the comment field in the + table on the test suite result page.</fsummary> + <type> + <v>Format = string()</v> + <v>Args = list()</v> + </type> + <desc><marker id="comment-2"/> + <p>Prints the formatted string in the comment field in the table + on the test suite result page.</p> + + <p>Arguments <c>Format</c> and <c>Args</c> are used in a call to + <c>io_lib:format/2</c> to create the comment string. The behavior + of <c>comment/2</c> is otherwise the same as function + <seealso marker="#comment-1"><c>ct:comment/1</c></seealso>.</p> + </desc> + </func> + + <func> + <name>continue() -> ok</name> + <fsummary>This function must be called to continue after a test + case (not executing in a parallel group) has called break/1.</fsummary> + <desc><marker id="continue-0"/> + <p>This function must be called to continue after a test case + (not executing in a parallel group) has called function + <seealso marker="#break-1"><c>ct:break/1</c></seealso>.</p> + </desc> + </func> + + <func> + <name>continue(TestCase) -> ok</name> + <fsummary>This function must be called to continue after a test case + has called break/2.</fsummary> + <type> + <v>TestCase = atom()</v> + </type> + <desc><marker id="continue-1"/> + <p>This function must be called to continue after a test case has + called <seealso marker="#break-2"><c>ct:break/2</c></seealso>. + If the paused test case, <c>TestCase</c>, executes in a parallel + group, this function, rather than <c>continue/0</c>, must be used + to let the test case proceed.</p> + </desc> + </func> + + <func> + <name>decrypt_config_file(EncryptFileName, TargetFileName) -> ok | {error, Reason}</name> + <fsummary>Decrypts EncryptFileName, previously generated with + encrypt_config_file/2,3.</fsummary> + <type> + <v>EncryptFileName = string()</v> + <v>TargetFileName = string()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="decrypt_config_file-2"/> + <p>Decrypts <c>EncryptFileName</c>, previously generated with + <seealso marker="#encrypt_config_file-2"><c>ct:encrypt_config_file/2,3</c></seealso>. + The original file contents is saved in the target file. The + encryption key, a string, must be available in a text file named + <c>.ct_config.crypt</c>, either in the current directory, or the + home directory of the user (it is searched for in that order).</p> + </desc> + </func> + + <func> + <name>decrypt_config_file(EncryptFileName, TargetFileName, KeyOrFile) -> ok | {error, Reason}</name> + <fsummary>Decrypts EncryptFileName, previously generated with + encrypt_config_file/2,3.</fsummary> + <type> + <v>EncryptFileName = string()</v> + <v>TargetFileName = string()</v> + <v>KeyOrFile = {key, string()} | {file, string()}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="decrypt_config_file-3"/> + <p>Decrypts <c>EncryptFileName</c>, previously generated with + <seealso marker="#encrypt_config_file-2"><c>ct:encrypt_config_file/2,3</c></seealso>. + The original file contents is saved in the target file. The key + must have the same value as that used for encryption.</p> + </desc> + </func> + + <func> + <name>encrypt_config_file(SrcFileName, EncryptFileName) -> ok | {error, Reason}</name> + <fsummary>Encrypts the source configuration file with DES3 and saves the + result in file EncryptFileName.</fsummary> + <type> + <v>SrcFileName = string()</v> + <v>EncryptFileName = string()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="encrypt_config_file-2"/> + <p>Encrypts the source configuration file with DES3 and saves the result + in file <c>EncryptFileName</c>. The key, a string, must be + available in a text file named <c>.ct_config.crypt</c>, either + in the current directory, or the home directory of the user (it + is searched for in that order).</p> + + <p>For information about using encrypted configuration files when + running tests, see section + <seealso marker="config_file_chapter#encrypted_config_files">Encrypted + Configuration Files</seealso> in the User's Guide.</p> + + <p>For details on DES3 encryption/decryption, see application + <seealso marker="crypto"><c>Crypto</c></seealso>.</p> + </desc> + </func> + + <func> + <name>encrypt_config_file(SrcFileName, EncryptFileName, KeyOrFile) -> ok | {error, Reason}</name> + <fsummary>Encrypts the source configuration file with DES3 and saves the + result in the target file EncryptFileName.</fsummary> + <type> + <v>SrcFileName = string()</v> + <v>EncryptFileName = string()</v> + <v>KeyOrFile = {key, string()} | {file, string()}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="encrypt_config_file-3"/> + <p>Encrypts the source configuration file with DES3 and saves the result + in the target file <c>EncryptFileName</c>. The encryption key + to use is either the value in <c>{key,Key}</c> or the value + stored in the file specified by <c>{file,File}</c>.</p> + + <p>For information about using encrypted configuration files when + running tests, see section + <seealso marker="config_file_chapter#encrypted_config_files">Encrypted + Configuration Files</seealso> in the User's Guide.</p> + + <p>For details on DES3 encryption/decryption, see application + <seealso marker="crypto"><c>Crypto</c></seealso>.</p> + </desc> + </func> + + <func> + <name>fail(Reason) -> ok</name> + <fsummary>Terminates a test case with the specified error + Reason.</fsummary> + <type> + <v>Reason = term()</v> + </type> + <desc><marker id="fail-1"/> + <p>Terminates a test case with the specified error <c>Reason</c>.</p> + </desc> + </func> + + <func> + <name>fail(Format, Args) -> ok</name> + <fsummary>Terminates 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).</fsummary> + <type> + <v>Format = string()</v> + <v>Args = list()</v> + </type> + <desc><marker id="fail-2"/> + <p>Terminates a test case with an error message specified by a + format string and a list of values (used as arguments to + <c>io_lib:format/2</c>).</p> + </desc> + </func> + + <func> + <name>get_config(Required) -> Value</name> + <fsummary>Equivalent to get_config(Required, undefined, []).</fsummary> + <desc><marker id="get_config-1"/> + <p>Equivalent to <seealso marker="#get_config-3"><c>ct:get_config(Required, + undefined, [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get_config(Required, Default) -> Value</name> + <fsummary>Equivalent to get_config(Required, Default, []).</fsummary> + <desc><marker id="get_config-2"/> + <p>Equivalent to <seealso marker="#get_config-3"><c>ct:get_config(Required, + Default, [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get_config(Required, Default, Opts) -> ValueOrElement</name> + <fsummary>Reads configuration data values.</fsummary> + <type> + <v>Required = KeyOrName | {KeyOrName, SubKey} | {KeyOrName, SubKey, SubKey}</v> + <v>KeyOrName = atom()</v> + <v>SubKey = atom()</v> + <v>Default = term()</v> + <v>Opts = [Opt] | []</v> + <v>Opt = element | all</v> + <v>ValueOrElement = term() | Default</v> + </type> + <desc><marker id="get_config-3"/> + <p>Reads configuration data values.</p> + + <p>Returns the matching values or configuration elements, given a + configuration variable key or its associated name (if one has been + specified with + <seealso marker="#require-2"><c>ct:require/2</c></seealso> + or a <c>require</c> statement).</p> + + <p><em>Example:</em></p> + + <p>Given the following configuration file:</p> + + <pre> + {unix,[{telnet,IpAddr}, + {user,[{username,Username}, + {password,Password}]}]}.</pre> + + <p>Then:</p> + + <pre> + 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</pre> + + <p>If a configuration variable key has been associated with a name (by + <seealso marker="#require-2"><c>ct:require/2</c></seealso> + or a <c>require</c> statement), the name can be used instead + of the key to read the value:</p> + + <pre> + ct:require(myuser,{unix,user}) -> ok. + ct:get_config(myuser,Default) -> [{username,Username}, {password,Password}]</pre> + + <p>If a configuration variable is defined in multiple files, use option + <c>all</c> to access all possible values. The values are returned + in a list. The order of the elements corresponds to the order + that the configuration files were specified at startup.</p> + + <p>If configuration elements (key-value tuples) are to be returned as + result instead of values, use option <c>element</c>. The + returned elements are then on the form <c>{Required,Value}</c>.</p> + + <p>See also + <seealso marker="#get_config-1"><c>ct:get_config/1</c></seealso>, + <seealso marker="#get_config-2"><c>ct:get_config/2</c></seealso>, + <seealso marker="#require-1"><c>ct:require/1</c></seealso>, + <seealso marker="#require-2"><c>ct:require/2</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get_event_mgr_ref() -> EvMgrRef</name> + <fsummary>Gets a reference to the <c>Common Test</c> event manager.</fsummary> + <type> + <v>EvMgrRef = atom()</v> + </type> + <desc><marker id="get_event_mgr_ref-0"/> + <p>Gets a reference to the <c>Common Test</c> event manager. + The reference can be used to, for example, add a user-specific + event handler while tests are running.</p> + + <p><em>Example:</em></p> + + <pre> + gen_event:add_handler(ct:get_event_mgr_ref(), my_ev_h, [])</pre> + </desc> + </func> + + <func> + <name>get_status() -> TestStatus | {error, Reason} | no_tests_running</name> + <fsummary>Returns status of ongoing test.</fsummary> + <type> + <v>TestStatus = [StatusElem]</v> + <v>StatusElem = {current, TestCaseInfo} | {successful, Successful} | {failed, Failed} | {skipped, Skipped} | {total, Total}</v> + <v>TestCaseInfo = {Suite, TestCase} | [{Suite, TestCase}]</v> + <v>Suite = atom()</v> + <v>TestCase = atom()</v> + <v>Successful = integer()</v> + <v>Failed = integer()</v> + <v>Skipped = {UserSkipped, AutoSkipped}</v> + <v>UserSkipped = integer()</v> + <v>AutoSkipped = integer()</v> + <v>Total = integer()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="get_status-0"/> + <p>Returns status of ongoing test. The returned list contains + information about which test case is 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.</p> + </desc> + </func> + + <func> + <name>get_target_name(Handle) -> {ok, TargetName} | {error, Reason}</name> + <fsummary>Returns the name of the target that the specified connection + belongs to.</fsummary> + <type> + <v>Handle = handle()</v> + <v>TargetName = target_name()</v> + </type> + <desc><marker id="get_target_name-1"/> + <p>Returns the name of the target that the specified connection + belongs to.</p> + </desc> + </func> + + <func> + <name>get_testspec_terms() -> TestSpecTerms | undefined</name> + <fsummary>Gets a list of all test specification terms used to + configure and run this test.</fsummary> + <type> + <v>TestSpecTerms = [{Tag, Value}]</v> + <v>Value = [term()]</v> + </type> + <desc><marker id="get_testspec_terms-0"/> + <p>Gets a list of all test specification terms used to configure + and run this test.</p> + </desc> + </func> + + <func> + <name>get_testspec_terms(Tags) -> TestSpecTerms | undefined</name> + <fsummary>Reads one or more terms from the test specification used to + configure and run this test.</fsummary> + <type> + <v>Tags = [Tag] | Tag</v> + <v>Tag = atom()</v> + <v>TestSpecTerms = [{Tag, Value}] | {Tag, Value}</v> + <v>Value = [{Node, term()}] | [term()]</v> + <v>Node = atom()</v> + </type> + <desc><marker id="get_testspec_terms-1"/> + <p>Reads one or more terms from the test specification used to + configure and run this test. <c>Tag</c> is any valid test + specification tag, for example, <c>label</c>, <c>config</c>, or + <c>logdir</c>. User-specific terms are also available to read if + option <c>allow_user_terms</c> is set.</p> + <p>All value tuples returned, except user terms, have the node + name as first element.</p> + <p>To read test terms, use <c>Tag = tests</c> (rather than + <c>suites</c>, <c>groups</c>, or <c>cases</c>). <c>Value</c> is + then the list of <em>all</em> tests on the form + <c>[{Node,Dir,[{TestSpec,GroupsAndCases1},...]},...]</c>, where + <c>GroupsAndCases = [{Group,[Case]}] | [Case]</c>.</p> + </desc> + </func> + + <func> + <name>get_timetrap_info() -> {Time, Scale}</name> + <fsummary>Reads information about the timetrap set for the current + test case.</fsummary> + <type> + <v>Time = integer() | infinity</v> + <v>Scale = true | false</v> + </type> + <desc><marker id="get_timetrap_info-0"/> + <p>Reads information about the timetrap set for the current test + case. <c>Scale</c> indicates if <c>Common Test</c> will attempt + to compensate timetraps automatically for runtime delays + introduced by, for example, tools like cover.</p> + </desc> + </func> + + <func> + <name>install(Opts) -> ok | {error, Reason}</name> + <fsummary>Installs configuration files and event handlers.</fsummary> + <type> + <v>Opts = [Opt]</v> + <v>Opt = {config, ConfigFiles} | {event_handler, Modules} | {decrypt, KeyOrFile}</v> + <v>ConfigFiles = [ConfigFile]</v> + <v>ConfigFile = string()</v> + <v>Modules = [atom()]</v> + <v>KeyOrFile = {key, Key} | {file, KeyFile}</v> + <v>Key = string()</v> + <v>KeyFile = string()</v> + </type> + <desc><marker id="install-1"/> + <p>Installs configuration files and event handlers.</p> + + <p>Run this function once before the first test.</p> + + <p><em>Example:</em></p> + + <pre> + install([{config,["config_node.ctc","config_user.ctc"]}])</pre> + + <p>This function is automatically run by program <c>ct_run</c>.</p> + </desc> + </func> + + <func> + <name>listenv(Telnet) -> [Env]</name> + <fsummary>Performs command listenv on the specified Telnet connection + and returns the result as a list of key-value pairs.</fsummary> + <type> + <v>Telnet = term()</v> + <v>Env = {Key, Value}</v> + <v>Key = string()</v> + <v>Value = string()</v> + </type> + <desc><marker id="listenv-1"/> + <p>Performs command <c>listenv</c> on the specified Telnet connection + and returns the result as a list of key-value pairs.</p> + </desc> + </func> + + <func> + <name>log(Format) -> ok</name> + <fsummary>Equivalent to log(default, 50, Format, []).</fsummary> + <desc><marker id="log-1"/> + <p>Equivalent to + <seealso marker="#log-4"><c>ct:log(default, 50, Format, [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>log(X1, X2) -> ok</name> + <fsummary>Equivalent to log(Category, Importance, Format, + Args).</fsummary> + <type> + <v>X1 = Category | Importance | Format</v> + <v>X2 = Format | Args</v> + </type> + <desc><marker id="log-2"/> + <p>Equivalent to <seealso marker="#log-4"><c>ct:log(Category, + Importance, Format, Args)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>log(X1, X2, X3) -> ok</name> + <fsummary>Equivalent to log(Category, Importance, Format, + Args).</fsummary> + <type> + <v>X1 = Category | Importance</v> + <v>X2 = Importance | Format</v> + <v>X3 = Format | Args</v> + </type> + <desc><marker id="log-3"/> + <p>Equivalent to <seealso marker="#log-4"><c>ct:log(Category, + Importance, Format, Args)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>log(Category, Importance, Format, Args) -> ok</name> + <fsummary>Prints from a test case to the log file.</fsummary> + <type> + <v>Category = atom()</v> + <v>Importance = integer()</v> + <v>Format = string()</v> + <v>Args = list()</v> + </type> + <desc><marker id="log-4"/> + <p>Prints from a test case to the log file.</p> + + <p>This function is meant for printing a string directly from a + test case to the test case log file.</p> + + <p>Default <c>Category</c> is <c>default</c>, + default <c>Importance</c> is <c>?STD_IMPORTANCE</c>, + and default value for <c>Args</c> is <c>[]</c>.</p> + + <p>For details on <c>Category</c> and <c>Importance</c>, see section + <seealso marker="write_test_chapter#logging">Logging - Categories + and Verbosity Levels</seealso> in the User's Guide.</p> + </desc> + </func> + + <func> + <name>make_priv_dir() -> ok | {error, Reason}</name> + <fsummary>If the test has been started with option create_priv_dir + 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.</fsummary> + <type> + <v>Reason = term()</v> + </type> + <desc><marker id="make_priv_dir-0"/> + <p>If the test is started with option <c>create_priv_dir</c> + set to <c>manual_per_tc</c>, in order for the test case to use + the private directory, it must first create it by calling this + function.</p> + </desc> + </func> + + <func> + <name>notify(Name, Data) -> ok</name> + <fsummary>Sends an asynchronous notification of type Name with Data + to the <c>Common Test</c> event manager.</fsummary> + <type> + <v>Name = atom()</v> + <v>Data = term()</v> + </type> + <desc><marker id="notify-2"/> + <p>Sends an asynchronous notification of type <c>Name</c> with + <c>Data</c>to the Common Test event manager. This can later be + caught by any installed event manager.</p> + + <p>See also + <seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>pal(Format) -> ok</name> + <fsummary>Equivalent to pal(default, 50, Format, []).</fsummary> + <desc><marker id="pal-1"/> + <p>Equivalent to + <seealso marker="#pal-4"><c>ct:pal(default, 50, Format, + [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>pal(X1, X2) -> ok</name> + <fsummary>Equivalent to pal(Category, Importance, Format, + Args).</fsummary> + <type> + <v>X1 = Category | Importance | Format</v> + <v>X2 = Format | Args</v> + </type> + <desc><marker id="pal-2"/> + <p>Equivalent to <seealso marker="#pal-4"><c>ct:pal(Category, + Importance, Format, Args)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>pal(X1, X2, X3) -> ok</name> + <fsummary>Equivalent to pal(Category, Importance, Format, + Args).</fsummary> + <type> + <v>X1 = Category | Importance</v> + <v>X2 = Importance | Format</v> + <v>X3 = Format | Args</v> + </type> + <desc><marker id="pal-3"/> + <p>Equivalent to <seealso marker="#pal-4"><c>ct:pal(Category, + Importance, Format, Args)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>pal(Category, Importance, Format, Args) -> ok</name> + <fsummary>Prints and logs from a test case.</fsummary> + <type> + <v>Category = atom()</v> + <v>Importance = integer()</v> + <v>Format = string()</v> + <v>Args = list()</v> + </type> + <desc><marker id="pal-4"/> + <p>Prints and logs from a test case.</p> + + <p>This function is meant for printing a string from a test case, + both to the test case log file and to the console.</p> + + <p>Default <c>Category</c> is <c>default</c>, + default <c>Importance</c> is <c>?STD_IMPORTANCE</c>, + and default value for <c>Args</c> is <c>[]</c>.</p> + + <p>For details on <c>Category</c> and <c>Importance</c>, see section + <seealso marker="write_test_chapter#logging">Logging - Categories + and Verbosity Levels</seealso> in the User's Guide.</p> + </desc> + </func> + + <func> + <name>parse_table(Data) -> {Heading, Table}</name> + <fsummary>Parses the printout from an SQL table and returns a list of + tuples.</fsummary> + <type> + <v>Data = [string()]</v> + <v>Heading = tuple()</v> + <v>Table = [tuple()]</v> + </type> + <desc><marker id="parse_table-1"/> + <p>Parses the printout from an SQL table and returns a list of + tuples.</p> + + <p>The printout to parse is typically the result of a <c>select</c> + command in SQL. The returned <c>Table</c> is a list of tuples, + where each tuple is a row in the table.</p> + + <p><c>Heading</c> is a tuple of strings representing the headings + of each column in the table.</p> + </desc> + </func> + + <func> + <name>print(Format) -> ok</name> + <fsummary>Equivalent to print(default, 50, Format, []).</fsummary> + <desc><marker id="print-1"/> + <p>Equivalent to <seealso marker="#print-4"><c>ct:print(default, + 50, Format, [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>print(X1, X2) -> ok</name> + <fsummary>Equivalent to print(Category, Importance, Format, + Args).</fsummary> + <type> + <v>X1 = Category | Importance | Format</v> + <v>X2 = Format | Args</v> + </type> + <desc><marker id="print-2"/> + <p>Equivalent to <seealso marker="#print-4"><c>ct:print(Category, + Importance, Format, Args)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>print(X1, X2, X3) -> ok</name> + <fsummary>Equivalent to print(Category, Importance, Format, + Args).</fsummary> + <type> + <v>X1 = Category | Importance</v> + <v>X2 = Importance | Format</v> + <v>X3 = Format | Args</v> + </type> + <desc><marker id="print-3"/> + <p>Equivalent to <seealso marker="#print-4"><c>ct:print(Category, + Importance, Format, Args)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>print(Category, Importance, Format, Args) -> ok</name> + <fsummary>Prints from a test case to the console.</fsummary> + <type> + <v>Category = atom()</v> + <v>Importance = integer()</v> + <v>Format = string()</v> + <v>Args = list()</v> + </type> + <desc><marker id="print-4"/> + <p>Prints from a test case to the console.</p> + + <p>This function is meant for printing a string from a test case to + the console.</p> + + <p>Default <c>Category</c> is <c>default</c>, + default <c>Importance</c> is <c>?STD_IMPORTANCE</c>, + and default value for <c>Args</c> is <c>[]</c>.</p> + + <p>For details on <c>Category</c> and <c>Importance</c>, see section + <seealso marker="write_test_chapter#logging">Logging - Categories + and Verbosity Levels</seealso> in the User's Guide.</p> + </desc> + </func> + + <func> + <name>reload_config(Required) -> ValueOrElement</name> + <fsummary>Reloads configuration file containing specified configuration + key.</fsummary> + <type> + <v>Required = KeyOrName | {KeyOrName, SubKey} | {KeyOrName, SubKey, SubKey}</v> + <v>KeyOrName = atom()</v> + <v>SubKey = atom()</v> + <v>ValueOrElement = term()</v> + </type> + <desc><marker id="reload_config-1"/> + <p>Reloads configuration file containing specified configuration key.</p> + + <p>This function updates the configuration data from which the + specified configuration variable was read, and returns the (possibly) + new value of this variable.</p> + + <p>If some variables were present in the configuration, but are + not loaded using this function, they are removed from the + configuration table together with their aliases.</p> + </desc> + </func> + + <func> + <name>remove_config(Callback, Config) -> ok</name> + <fsummary>Removes configuration variables (together with + their aliases) that were loaded with specified callback module and + configuration string.</fsummary> + <type> + <v>Callback = atom()</v> + <v>Config = string()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="remove_config-2"/> + <p>Removes configuration variables (together wih their aliases) + that were loaded with specified callback module and configuration + string.</p> + </desc> + </func> + + <func> + <name>require(Required) -> ok | {error, Reason}</name> + <fsummary>Checks if the required configuration is available.</fsummary> + <type> + <v>Required = Key | {Key, SubKeys} | {Key, SubKey, SubKeys}</v> + <v>Key = atom()</v> + <v>SubKeys = SubKey | [SubKey]</v> + <v>SubKey = atom()</v> + </type> + <desc><marker id="require-1"/> + <p>Checks if the required configuration is available. Arbitrarily + deep tuples can be specified as <c>Required</c>. Only the last + element of the tuple can be a list of <c>SubKey</c>s.</p> + + <p><em>Example 1.</em> Require the variable <c>myvar</c>:</p> + + <pre> + ok = ct:require(myvar).</pre> + + <p>In this case the configuration file must at least contain:</p> + + <pre> + {myvar,Value}.</pre> + + <p><em>Example 2.</em> Require key <c>myvar</c> with subkeys + <c>sub1</c> and <c>sub2</c>:</p> + + <pre> + ok = ct:require({myvar,[sub1,sub2]}).</pre> + + <p>In this case the configuration file must at least contain:</p> + + <pre> + {myvar,[{sub1,Value},{sub2,Value}]}.</pre> + + <p><em>Example 3.</em> Require key <c>myvar</c> with subkey + <c>sub1</c> with <c>subsub1</c>:</p> + + <pre> + ok = ct:require({myvar,sub1,sub2}).</pre> + + <p>In this case the configuration file must at least contain:</p> + + <pre> + {myvar,[{sub1,[{sub2,Value}]}]}.</pre> + + <p>See also + <seealso marker="#get_config-1"><c>ct:get_config/1</c></seealso>, + <seealso marker="#get_config-2"><c>ct:get_config/2</c></seealso>, + <seealso marker="#get_config-3"><c>ct:get_config/3</c></seealso>, + <seealso marker="#require-2"><c>ct:require/2</c></seealso>.</p> + </desc> + </func> + + <func> + <name>require(Name, Required) -> ok | {error, Reason}</name> + <fsummary>Checks if the required configuration is available and gives + it a name.</fsummary> + <type> + <v>Name = atom()</v> + <v>Required = Key | {Key, SubKey} | {Key, SubKey, SubKey}</v> + <v>SubKey = Key</v> + <v>Key = atom()</v> + </type> + <desc><marker id="require-2"/> + <p>Checks if the required configuration is available and gives it a + name. The semantics for <c>Required</c> is the same as in + <seealso marker="#require-1"><c>ct:require/1</c></seealso> except + that a list of <c>SubKey</c>s cannot be specified.</p> + + <p>If the requested data is available, the subentry is associated + with <c>Name</c> so that the value of the element can be read with + <seealso marker="#get_config-1"><c>ct:get_config/1,2</c></seealso> + provided <c>Name</c> is used instead of the whole <c>Required</c> + term.</p> + + <p><em>Example:</em></p> + + <p>Require one node with a Telnet connection and an FTP connection. + Name the node <c>a</c>:</p> + + <pre> + ok = ct:require(a,{machine,node}).</pre> + + <p>All references to this node can then use the node name. For + example, a file over FTP is fetched like follows:</p> + + <pre> + ok = ct:ftp_get(a,RemoteFile,LocalFile).</pre> + + <p>For this to work, the configuration file must at least contain:</p> + + <pre> + {machine,[{node,[{telnet,IpAddr},{ftp,IpAddr}]}]}.</pre> + + <note><p>The behavior of this function changed radically in + <c>Common Test</c> 1.6.2. To keep some backwards compatability, + it is still possible to do:<br/> + <c>ct:require(a,{node,[telnet,ftp]}).</c><br/> + This associates the name <c>a</c> with the top-level <c>node</c> + entry. For this to work, the configuration file must at least + contain:<br/> + <c>{node,[{telnet,IpAddr},{ftp,IpAddr}]}.</c></p> + </note> + + <p>See also + <seealso marker="#get_config-1"><c>ct:get_config/1</c></seealso>, + <seealso marker="#get_config-2"><c>ct:get_config/2</c></seealso>, + <seealso marker="#get_config-3"><c>ct:get_config/3</c></seealso>, + <seealso marker="#require-1"><c>ct:require/1</c></seealso>.</p> + </desc> + </func> + + <func> + <name>run(TestDirs) -> Result</name> + <fsummary>Runs all test cases in all suites in the specified + directories.</fsummary> + <type> + <v>TestDirs = TestDir | [TestDir]</v> + </type> + <desc><marker id="run-1"/> + <p>Runs all test cases in all suites in the specified directories.</p> + + <p>See also <seealso marker="#run-3"><c>ct:run/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>run(TestDir, Suite) -> Result</name> + <fsummary>Runs all test cases in the specified suite.</fsummary> + <desc><marker id="run-2"/> + <p>Runs all test cases in the specified suite.</p> + + <p>See also <seealso marker="#run-3"><c>ct:run/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>run(TestDir, Suite, Cases) -> Result</name> + <fsummary>Runs the specified test cases.</fsummary> + <type> + <v>TestDir = string()</v> + <v>Suite = atom()</v> + <v>Cases = atom() | [atom()]</v> + <v>Result = [TestResult] | {error, Reason}</v> + </type> + <desc><marker id="run-3"/> + <p>Runs the specified test cases.</p> + + <p>Requires that + <seealso marker="#install-1"><c>ct:install/1</c></seealso> has been + run first.</p> + + <p>Suites (<c>*_SUITE.erl</c>) files must be stored in <c>TestDir</c> + or <c>TestDir/test</c>. All suites are compiled when the test is + run.</p> + </desc> + </func> + + <func> + <name>run_test(Opts) -> Result</name> + <fsummary>Runs tests as specified by the combination of options in + Opts.</fsummary> + <type> + <v>Opts = [OptTuples]</v> + <v>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} | {ct_hooks, CTHs} | {enable_builtin_hooks, Bool} | {release_shell, Bool}</v> + <v>TestDirs = [string()] | string()</v> + <v>Suites = [string()] | [atom()] | string() | atom()</v> + <v>Cases = [atom()] | atom()</v> + <v>Groups = GroupNameOrPath | [GroupNameOrPath]</v> + <v>GroupNameOrPath = [atom()] | atom() | all</v> + <v>TestSpecs = [string()] | string()</v> + <v>Label = string() | atom()</v> + <v>CfgFiles = [string()] | string()</v> + <v>UserConfig = [{CallbackMod, CfgStrings}] | {CallbackMod, CfgStrings}</v> + <v>CallbackMod = atom()</v> + <v>CfgStrings = [string()] | string()</v> + <v>LogDir = string()</v> + <v>Conns = all | [atom()]</v> + <v>CSSFile = string()</v> + <v>CoverSpecFile = string()</v> + <v>StepOpts = [StepOpt] | []</v> + <v>StepOpt = config | keep_inactive</v> + <v>EventHandlers = EH | [EH]</v> + <v>EH = atom() | {atom(), InitArgs} | {[atom()], InitArgs}</v> + <v>InitArgs = [term()]</v> + <v>InclDirs = [string()] | string()</v> + <v>CreatePrivDir = auto_per_run | auto_per_tc | manual_per_tc</v> + <v>M = integer()</v> + <v>N = integer()</v> + <v>DurTime = string(HHMMSS)</v> + <v>StopTime = string(YYMoMoDDHHMMSS) | string(HHMMSS)</v> + <v>ForceStop = skip_rest | Bool</v> + <v>DecryptKeyOrFile = {key, DecryptKey} | {file, DecryptFile}</v> + <v>DecryptKey = string()</v> + <v>DecryptFile = string()</v> + <v>LogOpts = [LogOpt]</v> + <v>LogOpt = no_nl | no_src</v> + <v>VLevels = VLevel | [{Category, VLevel}]</v> + <v>VLevel = integer()</v> + <v>Category = atom()</v> + <v>CTHs = [CTHModule | {CTHModule, CTHInitArgs}]</v> + <v>CTHModule = atom()</v> + <v>CTHInitArgs = term()</v> + <v>Result = {Ok, Failed, {UserSkipped, AutoSkipped}} | TestRunnerPid | {error, Reason}</v> + <v>Ok = integer()</v> + <v>Failed = integer()</v> + <v>UserSkipped = integer()</v> + <v>AutoSkipped = integer()</v> + <v>TestRunnerPid = pid()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="run_test-1"/> + <p>Runs tests as specified by the combination of options in + <c>Opts</c>. The options are the same as those used with program + <c>ct_run</c>, see <seealso marker="ct_run#ct_run">Run Tests from + Command Line</seealso> in the <c>ct_run</c> manual page.</p> + <p>Here a <c>TestDir</c> can be used to point out the path to a + <c>Suite</c>. Option <c>testcase</c> corresponds to option + <c>-case</c> in program <c>ct_run</c>. Configuration files + specified in <c>Opts</c> are installed automatically at startup.</p> + + <p><c>TestRunnerPid</c> is returned if <c>release_shell == true</c>. + For details, see + <seealso marker="#break-1"><c>ct:break/1</c></seealso>.</p> + + <p><c>Reason</c> indicates the type of error encountered.</p> + </desc> + </func> + + <func> + <name>run_testspec(TestSpec) -> Result</name> + <fsummary>Runs a test specified by TestSpec.</fsummary> + <type> + <v>TestSpec = [term()]</v> + <v>Result = {Ok, Failed, {UserSkipped, AutoSkipped}} | {error, Reason}</v> + <v>Ok = integer()</v> + <v>Failed = integer()</v> + <v>UserSkipped = integer()</v> + <v>AutoSkipped = integer()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="run_testspec-1"/> + <p>Runs a test specified by <c>TestSpec</c>. The same terms are used + as in test specification files.</p> + + <p><c>Reason</c> indicates the type of error encountered.</p> + </desc> + </func> + + <func> + <name>sleep(Time) -> ok</name> + <fsummary>This function, similar to timer:sleep/1, suspends the + test case for a specified time.</fsummary> + <type> + <v>Time = {hours, Hours} | {minutes, Mins} | {seconds, Secs} | Millisecs | infinity</v> + <v>Hours = integer()</v> + <v>Mins = integer()</v> + <v>Secs = integer()</v> + <v>Millisecs = integer() | float()</v> + </type> + <desc><marker id="sleep-1"/> + <p>This function, similar to <c>timer:sleep/1</c> in <c>STDLIB</c>, + suspends the test case for a specified time. + However, this function also multiplies <c>Time</c> with the + <c>multiply_timetraps</c> value (if set) and under certain + circumstances also scales up the time automatically if + <c>scale_timetraps</c> is set to <c>true</c> (default is + <c>false</c>).</p> + </desc> + </func> + + <func> + <name>start_interactive() -> ok</name> + <fsummary>Starts <c>Common Test</c> in interactive mode.</fsummary> + <desc><marker id="start_interactive-0"/> + <p>Starts <c>Common Test</c> in interactive mode.</p> + + <p>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 <c>ct_run -shell + [-config File...]</c>.</p> + + <p>If any functions (for example, Telnet or FTP) using + "required configuration data" are to be called from the Erlang shell, + configuration data must first be required with + <seealso marker="#require-2"><c>ct:require/2</c></seealso>.</p> + + <p><em>Example:</em></p> + + <pre> + > ct:require(unix_telnet, unix). + ok + > ct_telnet:open(unix_telnet). + {ok,<0.105.0>} + > ct_telnet:cmd(unix_telnet, "ls ."). + {ok,["ls","file1 ...",...]}</pre> + </desc> + </func> + + <func> + <name>step(TestDir, Suite, Case) -> Result</name> + <fsummary>Steps through a test case with the debugger.</fsummary> + <type> + <v>Case = atom()</v> + </type> + <desc><marker id="step-3"/> + <p>Steps through a test case with the debugger.</p> + + <p>See also <seealso marker="#run-3"><c>ct:run/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>step(TestDir, Suite, Case, Opts) -> Result</name> + <fsummary>Steps through a test case with the debugger.</fsummary> + <type> + <v>Case = atom()</v> + <v>Opts = [Opt] | []</v> + <v>Opt = config | keep_inactive</v> + </type> + <desc><marker id="step-4"/> + <p>Steps through a test case with the debugger. If option + <c>config</c> has been specifed, breakpoints are also set on + the configuration functions in <c>Suite</c>.</p> + + <p>See also <seealso marker="#run-3"><c>ct:run/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>stop_interactive() -> ok</name> + <fsummary>Exits the interactive mode.</fsummary> + <desc><marker id="stop_interactive-0"/> + <p>Exits the interactive mode.</p> + + <p>See also + <seealso marker="#start_interactive-0"><c>ct:start_interactive/0</c></seealso>. + </p> + </desc> + </func> + + <func> + <name>sync_notify(Name, Data) -> ok</name> + <fsummary>Sends a synchronous notification of type Name with Data to + the <c>Common Test</c> event manager.</fsummary> + <type> + <v>Name = atom()</v> + <v>Data = term()</v> + </type> + <desc><marker id="sync_notify-2"/> + <p>Sends a synchronous notification of type <c>Name</c> with + <c>Data</c> to the <c>Common Test</c> event manager. This can later be + caught by any installed event manager.</p> + + <p>See also + <seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>. + </p> + </desc> + </func> + + <func> + <name>testcases(TestDir, Suite) -> Testcases | {error, Reason}</name> + <fsummary>Returns all test cases in the specified suite.</fsummary> + <type> + <v>TestDir = string()</v> + <v>Suite = atom()</v> + <v>Testcases = list()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="testcases-2"/> + <p>Returns all test cases in the specified suite.</p> + </desc> + </func> + + <func> + <name>timetrap(Time) -> ok</name> + <fsummary>Sets a new timetrap for the running test case.</fsummary> + <type> + <v>Time = {hours, Hours} | {minutes, Mins} | {seconds, Secs} | Millisecs | infinity | Func</v> + <v>Hours = integer()</v> + <v>Mins = integer()</v> + <v>Secs = integer()</v> + <v>Millisecs = integer() | float()</v> + <v>Func = {M, F, A} | function()</v> + <v>M = atom()</v> + <v>F = atom()</v> + <v>A = list()</v> + </type> + <desc><marker id="timetrap-1"/> + <p>Sets a new timetrap for the running test case.</p> + + <p>If the argument is <c>Func</c>, the timetrap is triggered when + this function returns. <c>Func</c> can also return a new + <c>Time</c> value, which in that case is the value for the new + timetrap.</p> + </desc> + </func> + + <func> + <name>userdata(TestDir, Suite) -> SuiteUserData | {error, Reason}</name> + <fsummary>Returns any data specified with tag userdata in the list of + tuples returned from Suite:suite/0.</fsummary> + <type> + <v>TestDir = string()</v> + <v>Suite = atom()</v> + <v>SuiteUserData = [term()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="userdata-2"/> + <p>Returns any data specified with tag <c>userdata</c> in the list + of tuples returned from + <seealso marker="#Module:suite-0"><c>suite/0</c></seealso>.</p> + </desc> + </func> + + <func> + <name>userdata(TestDir, Suite, Case::GroupOrCase) -> TCUserData | {error, Reason}</name> + <fsummary>Returns any data specified with tag userdata in the list of + tuples returned from Suite:group(GroupName) or Suite:Case().</fsummary> + <type> + <v>TestDir = string()</v> + <v>Suite = atom()</v> + <v>GroupOrCase = {group, GroupName} | atom()</v> + <v>GroupName = atom()</v> + <v>TCUserData = [term()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="userdata-3"/> + <p>Returns any data specified with tag <c>userdata</c> in the list + of tuples returned from <c>Suite:group(GroupName)</c> or + <c>Suite:Case()</c>.</p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_cover.xml b/lib/common_test/doc/src/ct_cover.xml new file mode 100644 index 0000000000..be09c08a68 --- /dev/null +++ b/lib/common_test/doc/src/ct_cover.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_cover</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_cover.xml</file> + </header> + <module>ct_cover</module> + <modulesummary>Common Test framework code coverage support module. + </modulesummary> + +<description> + + <p><c>Common Test</c> framework code coverage support module.</p> + + <p>This module exports help functions for performing code coverage + analysis.</p> + +</description> + + <funcs> + <func> + <name>add_nodes(Nodes) -> {ok, StartedNodes} | {error, Reason}</name> + <fsummary>Adds nodes to current cover test (only works if cover support + is active).</fsummary> + <type> + <v>Nodes = [atom()]</v> + <v>StartedNodes = [atom()]</v> + <v>Reason = cover_not_running | not_main_node</v> + </type> + <desc><marker id="add_nodes-1"/> + <p>Adds nodes to current cover test. Notice that this only works if + cover support is active.</p> + + <p>To have effect, this function is to be called from + <c>init_per_suite/1</c> (see + <seealso marker="common_test"><c>common_test</c></seealso>) + before any tests are performed.</p> + </desc> + </func> + + <func> + <name>cross_cover_analyse(Level, Tests) -> ok</name> + <fsummary>Accumulates cover results over multiple tests.</fsummary> + <type> + <v>Level = overview | details</v> + <v>Tests = [{Tag, Dir}]</v> + <v>Tag = atom()</v> + <v>Dir = string()</v> + </type> + <desc><marker id="cross_cover_analyse-2"/> + <p>Accumulates cover results over multiple tests. See section + <seealso marker="cover_chapter#cross_cover">Cross Cover + Analysis</seealso> in the Users's Guide.</p> + </desc> + </func> + + <func> + <name>remove_nodes(Nodes) -> ok | {error, Reason}</name> + <fsummary>Removes nodes from the current cover test.</fsummary> + <type> + <v>Nodes = [atom()]</v> + <v>Reason = cover_not_running | not_main_node</v> + </type> + <desc><marker id="remove_nodes-1"/> + <p>Removes nodes from the current cover test.</p> + + <p>Call this function to stop cover test on nodes previously + added with + <seealso marker="#add_nodes-1"><c>ct_cover:add_nodes/1</c></seealso>. + Results on the remote node are transferred to the <c>Common Test</c> + node.</p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_ftp.xml b/lib/common_test/doc/src/ct_ftp.xml new file mode 100644 index 0000000000..0598dcbe3e --- /dev/null +++ b/lib/common_test/doc/src/ct_ftp.xml @@ -0,0 +1,277 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_ftp</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_ftp.xml</file> + </header> + <module>ct_ftp</module> + <modulesummary>FTP client module (based on the FTP support of the Inets + application).</modulesummary> + + <description> + + <p>FTP client module (based on the FTP support of the <c>Inets</c> + application).</p> + + </description> + + <section> + <title>Data Types</title> + <marker id="types"/> + <taglist> + <tag><c>connection() = handle() | target_name()</c></tag> + <item><marker id="type-connection"/> + <p>For <c>target_name</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p></item> + + <tag><c>handle() = handle()</c></tag> + <item><marker id="type-handle"/> + <p>Handle for a specific FTP connection, see module + <seealso marker="ct"><c>ct</c></seealso>.</p></item> + </taglist> + </section> + + <funcs> + <func> + <name>cd(Connection, Dir) -> ok | {error, Reason}</name> + <fsummary>Changes directory on remote host.</fsummary> + <type> + <v>Connection = connection()</v> + <v>Dir = string()</v> + </type> + <desc><marker id="cd-2"/> + <p>Changes directory on remote host.</p> + </desc> + </func> + + <func> + <name>close(Connection) -> ok | {error, Reason}</name> + <fsummary>Closes the FTP connection.</fsummary> + <type> + <v>Connection = connection()</v> + </type> + <desc><marker id="close-1"/> + <p>Closes the FTP connection.</p> + </desc> + </func> + + <func> + <name>delete(Connection, File) -> ok | {error, Reason}</name> + <fsummary>Deletes a file on remote host.</fsummary> + <type> + <v>Connection = connection()</v> + <v>File = string()</v> + </type> + <desc><marker id="delete-2"/> + <p>Deletes a file on remote host.</p> + </desc> + </func> + + <func> + <name>get(KeyOrName, RemoteFile, LocalFile) -> ok | {error, Reason}</name> + <fsummary>Opens an FTP connection and fetches a file from the remote + host.</fsummary> + <type> + <v>KeyOrName = Key | Name</v> + <v>Key = atom()</v> + <v>Name = target_name()</v> + <v>RemoteFile = string()</v> + <v>LocalFile = string()</v> + </type> + <desc><marker id="get-3"/> + <p>Opens an FTP connection and fetches a file from the remote + host.</p> + + <p><c>RemoteFile</c> and <c>LocalFile</c> must be absolute paths.</p> + + <p>The configuration file must be as for + <seealso marker="#put-3"><c>ct_ftp:put/3</c></seealso>.</p> + + <p>For <c>target_name</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p> + + <p>See also + <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p> + </desc> + </func> + + <func> + <name>ls(Connection, Dir) -> {ok, Listing} | {error, Reason}</name> + <fsummary>Lists directory Dir.</fsummary> + <type> + <v>Connection = connection()</v> + <v>Dir = string()</v> + <v>Listing = string()</v> + </type> + <desc><marker id="ls-2"/> + <p>Lists directory <c>Dir</c>.</p> + </desc> + </func> + + <func> + <name>open(KeyOrName) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Opens an FTP connection to the specified node.</fsummary> + <type> + <v>KeyOrName = Key | Name</v> + <v>Key = atom()</v> + <v>Name = target_name()</v> + <v>Handle = handle()</v> + </type> + <desc><marker id="open-1"/> + <p>Opens an FTP connection to the specified node.</p> + + <p>You can open a connection for a particular <c>Name</c> and use the + same name as reference for all following subsequent operations. + If you want + the connection to be associated with <c>Handle</c> instead (if you, + for example, need to open multiple connections to a host), use + <c>Key</c>, the configuration variable name, to specify the target. + A connection without an associated target name can only be closed + with the handle value.</p> + + <p>For information on how to create a new <c>Name</c>, see + <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p> + + <p>For <c>target_name</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p> + </desc> + </func> + + <func> + <name>put(KeyOrName, LocalFile, RemoteFile) -> ok | {error, Reason}</name> + <fsummary>Opens an FTP connection and sends a file to the remote + host.</fsummary> + <type> + <v>KeyOrName = Key | Name</v> + <v>Key = atom()</v> + <v>Name = target_name()</v> + <v>LocalFile = string()</v> + <v>RemoteFile = string()</v> + </type> + <desc><marker id="put-3"/> + <p>Opens an FTP connection and sends a file to the remote host.</p> + + <p><c>LocalFile</c> and <c>RemoteFile</c> must be absolute paths.</p> + + <p>For <c>target_name</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p> + + <p>If the target host is a "special" node, the FTP address must be + specified in the configuration file as follows:</p> + + <pre> + {node,[{ftp,IpAddr}]}.</pre> + + <p>If the target host is something else, for example, a UNIX host, + the configuration file must also include the username and password + (both strings):</p> + + <pre> + {unix,[{ftp,IpAddr}, + {username,Username}, + {password,Password}]}.</pre> + + <p>See also + <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p> + </desc> + </func> + + <func> + <name>recv(Connection, RemoteFile) -> ok | {error, Reason}</name> + <fsummary>Fetches a file over FTP.</fsummary> + <desc><marker id="recv-2"/> + <p>Fetches a file over FTP.</p> + + <p>The file gets the same name on the local host.</p> + + <p>See also <seealso marker="#recv-3"><c>ct_ftp:recv/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>recv(Connection, RemoteFile, LocalFile) -> ok | {error, Reason}</name> + <fsummary>Fetches a file over FTP.</fsummary> + <type> + <v>Connection = connection()</v> + <v>RemoteFile = string()</v> + <v>LocalFile = string()</v> + </type> + <desc><marker id="recv-3"/> + <p>Fetches a file over FTP.</p> + + <p>The file is named <c>LocalFile</c> on the local host.</p> + </desc> + </func> + + <func> + <name>send(Connection, LocalFile) -> ok | {error, Reason}</name> + <fsummary>Sends a file over FTP.</fsummary> + <desc><marker id="send-2"/> + <p>Sends a file over FTP.</p> + + <p>The file gets the same name on the remote host.</p> + + <p>See also + <seealso marker="#send-3"><c>ct_ftp:send/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send(Connection, LocalFile, RemoteFile) -> ok | {error, Reason}</name> + <fsummary>Sends a file over FTP.</fsummary> + <type> + <v>Connection = connection()</v> + <v>LocalFile = string()</v> + <v>RemoteFile = string()</v> + </type> + <desc><marker id="send-3"/> + <p>Sends a file over FTP.</p> + + <p>The file is named <c>RemoteFile</c> on the remote host.</p> + </desc> + </func> + + <func> + <name>type(Connection, Type) -> ok | {error, Reason}</name> + <fsummary>Changes the file transfer type.</fsummary> + <type> + <v>Connection = connection()</v> + <v>Type = ascii | binary</v> + </type> + <desc><marker id="type-2"/> + <p>Changes the file transfer type.</p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_hooks.xml b/lib/common_test/doc/src/ct_hooks.xml index a9f9450dd7..9c959945d2 100644 --- a/lib/common_test/doc/src/ct_hooks.xml +++ b/lib/common_test/doc/src/ct_hooks.xml @@ -1,5 +1,4 @@ <?xml version="1.0" encoding="UTF-8" ?> - <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -12,7 +11,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software @@ -34,539 +33,515 @@ <file>ct_hooks.sgml</file> </header> <module>ct_hooks</module> - <modulesummary>A callback interface on top of Common Test</modulesummary> + <modulesummary>A callback interface on top of Common Test.</modulesummary> <description> - <p>The <em>Common Test Hook</em> (henceforth called CTH) framework allows - extensions of the default behaviour of Common Test by means of callbacks - before and after all test suite calls. It is meant for advanced users of - Common Test which want to abstract out behaviour which is common to - multiple test suites. </p> + <p>The <em>Common Test Hook (CTH)</em> framework allows extensions of the + default behavior of <c>Common Test</c> by callbacks before and after all + test suite calls. It is intended for advanced users of <c>Common Test</c> + who want to abstract out behavior that is common to multiple test suites. + </p> - <p>In brief, Common Test Hooks allows you to:</p> + <p>In brief, CTH allows you to:</p> - <list> - <item>Manipulate the runtime config before each suite - configuration call</item> - <item>Manipulate the return of all suite configuration calls and in - extension the result of the test themselves.</item> + <list type="bulleted"> + <item><p>Manipulate the runtime configuration before each suite + configuration call.</p></item> + <item><p>Manipulate the return of all suite configuration calls and by + extension the result of the test themselves.</p></item> </list> <p>The following sections describe the mandatory and optional CTH - functions Common Test will call during test execution. For more details - see <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso> in - the User's Guide.</p> + functions that <c>Common Test</c> calls during test execution. + For more details, see section + <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso> in the + User's Guide.</p> - <p>For information about how to add a CTH to your suite see - <seealso marker="ct_hooks_chapter#installing">Installing a CTH - </seealso> in the User's Guide.</p> + <p>For information about how to add a CTH to your suite, see section + <seealso marker="ct_hooks_chapter#installing">Installing a CTH</seealso> + in the User's Guide.</p> + + <note><p>For a minimal example of a CTH, see section + <seealso marker="ct_hooks_chapter#example">Example CTH</seealso> + in the User's Guide.</p></note> - <note><p>See the - <seealso marker="ct_hooks_chapter#example">Example CTH</seealso> - in the User's Guide for a minimal example of a CTH. </p></note> - </description> <section> - <title>CALLBACK FUNCTIONS</title> - <p>The following functions define the callback interface - for a Common Test Hook.</p> + <title>Callback Functions</title> + <p>The following functions define the callback interface for a CTH.</p> </section> <funcs> <func> - <name>Module:init(Id, Opts) -> {ok, State} | - {ok, State, Priority}</name> - <fsummary>Initiates the Common Test Hook</fsummary> + <name>Module:init(Id, Opts) -> {ok, State} | {ok, State, Priority}</name> + <fsummary>Initiates the Common Test Hook.</fsummary> <type> - <v>Id = reference() | term()</v> - <v>Opts = term()</v> - <v>State = term()</v> - <v>Priority = integer()</v> + <v>Id = reference() | term()</v> + <v>Opts = term()</v> + <v>State = term()</v> + <v>Priority = integer()</v> </type> - <desc> - <p> MANDATORY </p> - - <p>Always called before any other callback function. - Use this to initiate any common state. - It should return a state for this CTH.</p> - - <p><c>Id</c> is the return value of - <seealso marker="#Module:id-1">id/1</seealso>, or a <c>reference</c> - (created using - <seealso marker="erts:erlang#make_ref-0">make_ref/0</seealso>) - if <seealso marker="#Module:id-1">id/1</seealso> is not implemented. - </p> - - <p><c>Priority</c> is the relative priority of this hook. Hooks with a - lower priority will be executed first. If no priority is given, - it will be set to 0. </p> - - <p>For details about when init is called see - <seealso marker="ct_hooks_chapter#scope">scope</seealso> - in the User's Guide.</p> - + <p>MANDATORY</p> + + <p>This function is always called before any other callback function. + Use it to initiate any common state. It is to return a state for + this CTH.</p> + + <p><c>Id</c> is either the return value of + <seealso marker="#Module:id-1"><c>ct_hooks:id/1</c></seealso>, + or a <c>reference</c> (created using + <seealso marker="erts:erlang#make_ref-0">erlang:make_ref/0</seealso> + in <c>ERTS</c>) if + <seealso marker="#Module:id-1"><c>ct_hooks:id/1</c></seealso> + is not implemented.</p> + + <p><c>Priority</c> is the relative priority of this hook. Hooks with a + lower priority are executed first. If no priority is specified, it + is set to <c>0</c>.</p> + + <p>For details about when <c>init</c> is called, see section + <seealso marker="ct_hooks_chapter#scope">CTH Scope</seealso> + in the User's Guide.</p> </desc> </func> <func> - <name>Module:pre_init_per_suite(SuiteName, InitData, CTHState) -> - Result</name> - <fsummary>Called before init_per_suite</fsummary> + <name>Module:pre_init_per_suite(SuiteName, InitData, CTHState) -> Result</name> + <fsummary>Called before init_per_suite.</fsummary> <type> - <v>SuiteName = atom()</v> - <v>InitData = Config | SkipOrFail</v> - <v>Config = NewConfig = [{Key,Value}]</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {Return, NewCTHState}</v> - <v>Return = NewConfig | SkipOrFail</v> - <v>SkipOrFail = {fail, Reason} | {skip, Reason}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>SuiteName = atom()</v> + <v>InitData = Config | SkipOrFail</v> + <v>Config = NewConfig = [{Key,Value}]</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {Return, NewCTHState}</v> + <v>Return = NewConfig | SkipOrFail</v> + <v>SkipOrFail = {fail, Reason} | {skip, Reason}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called before - <seealso marker="common_test#Module:init_per_suite-1"> - init_per_suite</seealso> if it exists. - It typically contains initialization/logging which needs to be done - before init_per_suite is called. - If <c>{skip,Reason}</c> or <c>{fail,Reason}</c> is returned, - init_per_suite and all test cases of the suite will be skipped and - Reason printed in the overview log of the suite.</p> - - <p><c>SuiteName</c> is the name of the suite to be run.</p> - - <p><c>InitData</c> is the original config list of the test suite, or - a <c>SkipOrFail</c> tuple if a previous CTH has returned this.</p> - - <p><c>CTHState</c> is the current internal state of the CTH.</p> - - <p><c>Return</c> is the result of the init_per_suite function. - If it is <c>{skip,Reason}</c> or <c>{fail,Reason}</c> - <seealso marker="common_test#Module:init_per_suite-1">init_per_suite - </seealso> will never be called, instead the initiation is considered - to be skipped/failed respectively. If a <c>NewConfig</c> list - is returned, <seealso marker="common_test#Module:init_per_suite-1"> - init_per_suite</seealso> will be called with that <c>NewConfig</c> list. - See <seealso marker="ct_hooks_chapter#pre"> - Pre Hooks</seealso> in the User's Guide for more details.</p> - - - <p>Note that this function is only called if the CTH has been added - before init_per_suite is run, see - <seealso marker="ct_hooks_chapter#scope">CTH Scoping</seealso> - in the User's Guide for details.</p> + <p>OPTIONAL</p> + + <p>This function is called before + <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso> + if it exists. It typically contains initialization/logging that must + be done before <c>init_per_suite</c> is called. If + <c>{skip,Reason}</c> or <c>{fail,Reason}</c> is returned, + <c>init_per_suite</c> and all test cases of the suite are skipped + and <c>Reason</c> printed in the overview log of the suite.</p> + + <p><c>SuiteName</c> is the name of the suite to be run.</p> + + <p><c>InitData</c> is the original configuration list of the test + suite, or a <c>SkipOrFail</c> tuple if a previous CTH has returned + this.</p> + + <p><c>CTHState</c> is the current internal state of the CTH.</p> + + <p><c>Return</c> is the result of the <c>init_per_suite</c> function. + If it is <c>{skip,Reason}</c> or <c>{fail,Reason}</c>, + <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso> + is never called, instead the initiation is considered to be + skipped or failed, respectively. If a <c>NewConfig</c> list is + returned, + <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso> + is called with that <c>NewConfig</c> list. For more details, see + section <seealso marker="ct_hooks_chapter#pre">Pre Hooks</seealso> + in the User's Guide.</p> + + <p>This function is called only if the CTH is added before + <c>init_per_suite is run</c>. For details, see section + <seealso marker="ct_hooks_chapter#scope">CTH Scope</seealso> + in the User's Guide.</p> </desc> </func> - + <func> - <name>Module:post_init_per_suite(SuiteName, Config, Return, CTHState) -> - Result</name> - <fsummary>Called after init_per_suite</fsummary> + <name>Module:post_init_per_suite(SuiteName, Config, Return, CTHState) -> Result</name> + <fsummary>Called after init_per_suite.</fsummary> <type> - <v>SuiteName = atom()</v> - <v>Config = [{Key,Value}]</v> - <v>Return = NewReturn = Config | SkipOrFail | term()</v> - <v>SkipOrFail = {fail, Reason} | {skip, Reason} | term()</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {NewReturn, NewCTHState}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>SuiteName = atom()</v> + <v>Config = [{Key,Value}]</v> + <v>Return = NewReturn = Config | SkipOrFail | term()</v> + <v>SkipOrFail = {fail, Reason} | {skip, Reason} | term()</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {NewReturn, NewCTHState}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called after - <seealso marker="common_test#Module:init_per_suite-1"> - init_per_suite</seealso> if it exists. It typically contains extra - checks to make sure that all the correct dependencies have - been started correctly.</p> - - <p><c>Return</c> is what - <seealso marker="common_test#Module:init_per_suite-1">init_per_suite - </seealso> returned, i.e. {fail,Reason}, {skip,Reason}, a <c>Config</c> - list or a term describing how - <seealso marker="common_test#Module:init_per_suite-1">init_per_suite - </seealso> failed.</p> - - <p><c>NewReturn</c> is the possibly modified return value of - <seealso marker="common_test#Module:init_per_suite-1">init_per_suite - </seealso>. It is here possible to recover from a failure in - <seealso marker="common_test#Module:init_per_suite-1">init_per_suite - </seealso> by returning the <c>ConfigList</c> with the <c>tc_status</c> - element removed. See <seealso marker="ct_hooks_chapter#post"> - Post Hooks</seealso> in the User's Guide for more details.</p> - - <p><c>CTHState</c> is the current internal state of the CTH.</p> - - <p>Note that this function is only called if the CTH has been added - before or in init_per_suite, see - <seealso marker="ct_hooks_chapter#scope">CTH Scoping</seealso> - in the User's Guide for details.</p> + <p>OPTIONAL</p> + + <p>This function is called after + <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso> + if it exists. It typically contains extra checks to ensure that all + the correct dependencies are started correctly.</p> + + <p><c>Return</c> is what + <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso> + returned, that is, <c>{fail,Reason}</c>, <c>{skip,Reason}</c>, a + <c>Config</c> list, or a term describing how + <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso> + failed.</p> + + <p><c>NewReturn</c> is the possibly modified return value of + <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>. + To recover from a failure in + <seealso marker="common_test#Module:init_per_suite-1"><c>init_per_suite</c></seealso>, + return <c>ConfigList</c> with the <c>tc_status</c> element removed. + For more details, see + <seealso marker="ct_hooks_chapter#post"> Post Hooks</seealso> in + section "Manipulating Tests" in the User's Guide.</p> + + <p><c>CTHState</c> is the current internal state of the CTH.</p> + + <p>This function is called only if the CTH is added before or in + <c>init_per_suite</c>. For details, see section + <seealso marker="ct_hooks_chapter#scope">CTH Scope</seealso> + in the User's Guide.</p> </desc> </func> - + <func> - <name>Module:pre_init_per_group(GroupName, InitData, CTHState) -> - Result</name> - <fsummary>Called before init_per_group</fsummary> + <name>Module:pre_init_per_group(GroupName, InitData, CTHState) -> Result</name> + <fsummary>Called before init_per_group.</fsummary> <type> - <v>GroupName = atom()</v> - <v>InitData = Config | SkipOrFail</v> - <v>Config = NewConfig = [{Key,Value}]</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v> - <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>GroupName = atom()</v> + <v>InitData = Config | SkipOrFail</v> + <v>Config = NewConfig = [{Key,Value}]</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v> + <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called before - <seealso marker="common_test#Module:init_per_group-2"> - init_per_group</seealso> if it exists. It behaves the same way as - <seealso marker="ct_hooks#Module:pre_init_per_suite-3"> - pre_init_per_suite</seealso>, but for the - <seealso marker="common_test#Module:init_per_group-2"> - init_per_group</seealso> instead.</p> + <p>OPTIONAL</p> + + <p>This function is called before + <seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso> + if it exists. It behaves the same way as + <seealso marker="ct_hooks#Module:pre_init_per_suite-3"><c>pre_init_per_suite</c></seealso>, + but for function + <seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso> + instead.</p> </desc> </func> - + <func> - <name>Module:post_init_per_group(GroupName, Config, Return, CTHState) -> - Result</name> - <fsummary>Called after init_per_group</fsummary> + <name>Module:post_init_per_group(GroupName, Config, Return, CTHState) -> Result</name> + <fsummary>Called after init_per_group.</fsummary> <type> - <v>GroupName = atom()</v> - <v>Config = [{Key,Value}]</v> - <v>Return = NewReturn = Config | SkipOrFail | term()</v> - <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {NewReturn, NewCTHState}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>GroupName = atom()</v> + <v>Config = [{Key,Value}]</v> + <v>Return = NewReturn = Config | SkipOrFail | term()</v> + <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {NewReturn, NewCTHState}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called after - <seealso marker="common_test#Module:init_per_group-2"> - init_per_group</seealso> if it exists. It behaves the same way as - <seealso marker="ct_hooks#Module:post_init_per_suite-4"> - post_init_per_suite</seealso>, but for the - <seealso marker="common_test#Module:init_per_group-2"> - init_per_group</seealso> instead.</p> + <p>OPTIONAL</p> + + <p>This function is called after + <seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso> + if it exists. It behaves the same way as + <seealso marker="ct_hooks#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>, + but for function + <seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso> + instead.</p> </desc> </func> <func> - <name>Module:pre_init_per_testcase(TestcaseName, InitData, CTHState) -> - Result</name> - <fsummary>Called before init_per_testcase</fsummary> + <name>Module:pre_init_per_testcase(TestcaseName, InitData, CTHState) -> Result</name> + <fsummary>Called before init_per_testcase.</fsummary> <type> - <v>TestcaseName = atom()</v> - <v>InitData = Config | SkipOrFail</v> - <v>Config = NewConfig = [{Key,Value}]</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v> - <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>TestcaseName = atom()</v> + <v>InitData = Config | SkipOrFail</v> + <v>Config = NewConfig = [{Key,Value}]</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v> + <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called before - <seealso marker="common_test#Module:init_per_testcase-2"> - init_per_testcase</seealso> if it exists. It behaves the same way as - <seealso marker="ct_hooks#Module:pre_init_per_suite-3"> - pre_init_per_suite</seealso>, but for the - <seealso marker="common_test#Module:init_per_testcase-2"> - init_per_testcase</seealso> function instead.</p> - - <p>Note that it is not possible to add CTH's here right now, - that feature might be added later, - but it would right now break backwards compatibility.</p> + <p>OPTIONAL</p> + + <p>This function is called before + <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso> + if it exists. It behaves the same way as + <seealso marker="ct_hooks#Module:pre_init_per_suite-3"><c>pre_init_per_suite</c></seealso>, + but for function + <seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso> + instead.</p> + + <p>CTHs cannot be added here right now. That feature may be added in + a later release, but it would right now break backwards + compatibility.</p> </desc> </func> <func> - <name>Module:post_end_per_testcase(TestcaseName, Config, Return, CTHState) - -> Result</name> - <fsummary>Called after end_per_testcase</fsummary> + <name>Module:post_end_per_testcase(TestcaseName, Config, Return, CTHState) -> Result</name> + <fsummary>Called after end_per_testcase.</fsummary> <type> - <v>TestcaseName = atom()</v> - <v>Config = [{Key,Value}]</v> - <v>Return = NewReturn = Config | SkipOrFail | term()</v> - <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {NewReturn, NewCTHState}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>TestcaseName = atom()</v> + <v>Config = [{Key,Value}]</v> + <v>Return = NewReturn = Config | SkipOrFail | term()</v> + <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {NewReturn, NewCTHState}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called after - <seealso marker="common_test#Module:end_per_testcase-2"> - end_per_testcase</seealso> if it exists. It behaves the same way as - <seealso marker="ct_hooks#Module:post_init_per_suite-4"> - post_init_per_suite</seealso>, but for the - <seealso marker="common_test#Module:end_per_testcase-2"> - end_per_testcase</seealso> function instead.</p> + <p>OPTIONAL</p> + + <p>This function is called after + <seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso> + if it exists. It behaves the same way as + <seealso marker="ct_hooks#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>, + but for function + <seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso> + instead.</p> </desc> </func> <func> - <name>Module:pre_end_per_group(GroupName, EndData, CTHState) -> - Result</name> - <fsummary>Called before end_per_group</fsummary> + <name>Module:pre_end_per_group(GroupName, EndData, CTHState) -> Result</name> + <fsummary>Called before end_per_group.</fsummary> <type> - <v>GroupName = atom()</v> - <v>EndData = Config | SkipOrFail</v> - <v>Config = NewConfig = [{Key,Value}]</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v> - <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>GroupName = atom()</v> + <v>EndData = Config | SkipOrFail</v> + <v>Config = NewConfig = [{Key,Value}]</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v> + <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called before - <seealso marker="common_test#Module:end_per_group-2"> - end_per_group</seealso> if it exists. It behaves the same way as - <seealso marker="ct_hooks#Module:pre_init_per_suite-3"> - pre_init_per_suite</seealso>, but for the - <seealso marker="common_test#Module:end_per_group-2"> - end_per_group</seealso> function instead.</p> + <p>OPTIONAL</p> + + <p>This function is called before + <seealso marker="common_test#Module:end_per_group-2"><c>end_per_group</c></seealso> + if it exists. It behaves the same way as + <seealso marker="ct_hooks#Module:pre_init_per_suite-3"><c>pre_init_per_suite</c></seealso>, + but for function + <seealso marker="common_test#Module:end_per_group-2"><c>end_per_group</c></seealso> + instead.</p> </desc> </func> <func> - <name>Module:post_end_per_group(GroupName, Config, Return, CTHState) -> - Result</name> - <fsummary>Called after end_per_group</fsummary> + <name>Module:post_end_per_group(GroupName, Config, Return, CTHState) -> Result</name> + <fsummary>Called after end_per_group.</fsummary> <type> - <v>GroupName = atom()</v> - <v>Config = [{Key,Value}]</v> - <v>Return = NewReturn = Config | SkipOrFail | term()</v> - <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {NewReturn, NewCTHState}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>GroupName = atom()</v> + <v>Config = [{Key,Value}]</v> + <v>Return = NewReturn = Config | SkipOrFail | term()</v> + <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {NewReturn, NewCTHState}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called after - <seealso marker="common_test#Module:end_per_group-2"> - end_per_group</seealso> if it exists. It behaves the same way as - <seealso marker="ct_hooks#Module:post_init_per_suite-4"> - post_init_per_suite</seealso>, but for the - <seealso marker="common_test#Module:end_per_group-2"> - end_per_group</seealso> function instead.</p> + <p>OPTIONAL</p> + + <p>This function is called after + <seealso marker="common_test#Module:end_per_group-2"><c>end_per_group</c></seealso> + if it exists. It behaves the same way as + <seealso marker="ct_hooks#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>, + but for function + <seealso marker="common_test#Module:end_per_group-2">end_per_group</seealso> + instead.</p> </desc> </func> <func> - <name>Module:pre_end_per_suite(SuiteName, EndData, CTHState) -> - Result</name> - <fsummary>Called before end_per_suite</fsummary> + <name>Module:pre_end_per_suite(SuiteName, EndData, CTHState) -> Result</name> + <fsummary>Called before end_per_suite.</fsummary> <type> - <v>SuiteName = atom()</v> - <v>EndData = Config | SkipOrFail</v> - <v>Config = NewConfig = [{Key,Value}]</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v> - <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>SuiteName = atom()</v> + <v>EndData = Config | SkipOrFail</v> + <v>Config = NewConfig = [{Key,Value}]</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v> + <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called before - <seealso marker="common_test#Module:end_per_suite-1"> - end_per_suite</seealso> if it exists. It behaves the same way as - <seealso marker="ct_hooks#Module:pre_init_per_suite-3"> - pre_init_per_suite</seealso>, but for the - <seealso marker="common_test#Module:end_per_suite-1"> - end_per_suite</seealso> function instead.</p> + <p>OPTIONAL</p> + + <p>This function is called before + <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso> + if it exists. It behaves the same way as + <seealso marker="ct_hooks#Module:pre_init_per_suite-3"><c>pre_init_per_suite</c></seealso>, + but for function + <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso> + instead.</p> </desc> </func> <func> - <name>Module:post_end_per_suite(SuiteName, Config, Return, CTHState) -> - Result</name> - <fsummary>Called after end_per_suite</fsummary> + <name>Module:post_end_per_suite(SuiteName, Config, Return, CTHState) -> Result</name> + <fsummary>Called after end_per_suite.</fsummary> <type> - <v>SuiteName = atom()</v> - <v>Config = [{Key,Value}]</v> - <v>Return = NewReturn = Config | SkipOrFail | term()</v> - <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> - <v>CTHState = NewCTHState = term()</v> - <v>Result = {NewReturn, NewCTHState}</v> - <v>Key = atom()</v> - <v>Value = term()</v> - <v>Reason = term()</v> + <v>SuiteName = atom()</v> + <v>Config = [{Key,Value}]</v> + <v>Return = NewReturn = Config | SkipOrFail | term()</v> + <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v> + <v>CTHState = NewCTHState = term()</v> + <v>Result = {NewReturn, NewCTHState}</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>Reason = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called after - <seealso marker="common_test#Module:end_per_suite-1"> - end_per_suite</seealso> if it exists. It behaves the same way as - <seealso marker="ct_hooks#Module:post_init_per_suite-4"> - post_init_per_suite</seealso>, but for the - <seealso marker="common_test#Module:end_per_suite-1"> - end_per_suite</seealso> function instead.</p> + <p>OPTIONAL</p> + + <p>This function is called after + <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso> + if it exists. It behaves the same way as + <seealso marker="ct_hooks#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>, + but for function + <seealso marker="common_test#Module:end_per_suite-1"><c>end_per_suite</c></seealso> + instead.</p> </desc> </func> <func> - <name>Module:on_tc_fail(TestName, Reason, CTHState) -> - NewCTHState</name> - <fsummary>Called after the CTH scope ends</fsummary> + <name>Module:on_tc_fail(TestName, Reason, CTHState) -> NewCTHState</name> + <fsummary>Called after the CTH scope ends.</fsummary> <type> - <v>TestName = init_per_suite | end_per_suite | - {init_per_group,GroupName} | {end_per_group,GroupName} | - {FuncName,GroupName} | FuncName</v> - <v>FuncName = atom()</v> - <v>GroupName = atom()</v> - <v>Reason = term()</v> - <v>CTHState = NewCTHState = term()</v> + <v>TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName</v> + <v>FuncName = atom()</v> + <v>GroupName = atom()</v> + <v>Reason = term()</v> + <v>CTHState = NewCTHState = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called whenever a test case (or config function) - fails. It is called after the post function has been called for - the failed test case. I.e. if init_per_suite fails, this function - is called after - <seealso marker="#Module:post_init_per_suite-4"> - post_init_per_suite</seealso>, and if a test case fails, it is called - after <seealso marker="#Module:post_end_per_testcase-4"> - post_end_per_testcase</seealso>. If the failed test case belongs - to a test case group, the first argument is a tuple - <c>{FuncName,GroupName}</c>, otherwise simply the function name.</p> - - <p>The data which comes with the Reason follows the same format as the - <seealso marker="event_handler_chapter#failreason">FailReason - </seealso> in the <seealso marker="event_handler_chapter#tc_done">tc_done</seealso> event. - See <seealso marker="event_handler_chapter#events">Event Handling - </seealso> in the User's Guide for details.</p> + <p>OPTIONAL</p> + + <p>This function is called whenever a test case (or configuration + function) fails. It is called after the post function is called + for the failed test case, that is:</p> + + <list type="bulleted"> + <item><p>If <c>init_per_suite</c> fails, this function is called after + <seealso marker="#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>.</p></item> + <item><p>If a test case fails, this funcion is called after + <seealso marker="#Module:post_end_per_testcase-4"><c>post_end_per_testcase</c></seealso>.</p></item> + </list> + + <p>If the failed test case belongs to a test case group, the first + argument is a tuple <c>{FuncName,GroupName}</c>, otherwise only + the function name.</p> + + <p>The data that comes with <c>Reason</c> follows the same format as + <seealso marker="event_handler_chapter#failreason"><c>FailReason</c></seealso> + in event + <seealso marker="event_handler_chapter#tc_done"><c>tc_done</c></seealso>. + For details, see section + <seealso marker="event_handler_chapter#events">Event Handling</seealso> + in the User's Guide.</p> </desc> </func> <func> - <name>Module:on_tc_skip(TestName, Reason, CTHState) -> - NewCTHState</name> - <fsummary>Called after the CTH scope ends</fsummary> + <name>Module:on_tc_skip(TestName, Reason, CTHState) -> NewCTHState</name> + <fsummary>Called after the CTH scope ends.</fsummary> <type> - <v>TestName = init_per_suite | end_per_suite | - {init_per_group,GroupName} | {end_per_group,GroupName} | - {FuncName,GroupName} | FuncName</v> - <v>FuncName = atom()</v> - <v>GroupName = atom()</v> - <v>Reason = {tc_auto_skip | tc_user_skip, term()}</v> - <v>CTHState = NewCTHState = term()</v> + <v>TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName</v> + <v>FuncName = atom()</v> + <v>GroupName = atom()</v> + <v>Reason = {tc_auto_skip | tc_user_skip, term()}</v> + <v>CTHState = NewCTHState = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>This function is called whenever a test case (or config function) - is skipped. It is called after the post function has been called - for the skipped test case. I.e. if init_per_group is skipped, this - function is called after - <seealso marker="#Module:post_init_per_group-4"> - post_init_per_group</seealso>, and if a test case is skipped, - it is called after - <seealso marker="#Module:post_end_per_testcase-4"> - post_end_per_testcase</seealso>. If the skipped test case belongs to a - test case group, the first argument is a tuple <c>{FuncName,GroupName}</c>, - otherwise simply the function name.</p> - - <p>The data which comes with the Reason follows the same format as - <seealso marker="event_handler_chapter#tc_auto_skip">tc_auto_skip - </seealso> and <seealso marker="event_handler_chapter#tc_user_skip"> - tc_user_skip</seealso> events. - See <seealso marker="event_handler_chapter#events">Event Handling - </seealso> in the User's Guide for details.</p> + <p>OPTIONAL</p> + + <p>This function is called whenever a test case (or configuration + function) is skipped. It is called after the post function is called + for the skipped test case, that is:</p> + + <list type="bulleted"> + <item><p>If <c>init_per_group</c> is skipped, this function is + called after + <seealso marker="#Module:post_init_per_group-4"><c>post_init_per_group</c></seealso>.</p></item> + <item><p>If a test case is skipped, this function is called after + <seealso marker="#Module:post_end_per_testcase-4"><c>post_end_per_testcase</c></seealso>.</p></item> + </list> + + <p>If the skipped test case belongs to a test case group, the first + argument is a tuple <c>{FuncName,GroupName}</c>, otherwise only + the function name.</p> + + <p>The data that comes with <c>Reason</c> follows the same format as + events + <seealso marker="event_handler_chapter#tc_auto_skip"><c>tc_auto_skip</c></seealso> + and + <seealso marker="event_handler_chapter#tc_user_skip"><c>tc_user_skip</c></seealso> + For details, see section + <seealso marker="event_handler_chapter#events">Event Handling</seealso> + in the User's Guide.</p> </desc> </func> <func> <name>Module:terminate(CTHState)</name> - <fsummary>Called after the CTH scope ends</fsummary> + <fsummary>Called after the CTH scope ends.</fsummary> <type> - <v>CTHState = term()</v> + <v>CTHState = term()</v> </type> - <desc> - <p> OPTIONAL </p> + <p>OPTIONAL</p> - <p>This function is called at the end of a CTH's - <seealso marker="ct_hooks_chapter#scope">scope</seealso>. - </p> + <p>This function is called at the end of a CTH + <seealso marker="ct_hooks_chapter#scope">scope</seealso>.</p> </desc> </func> <func> <name>Module:id(Opts) -> Id</name> - <fsummary>Called before the init function of a CTH</fsummary> + <fsummary>Called before the init function of a CTH.</fsummary> <type> - <v>Opts = term()</v> - <v>Id = term()</v> + <v>Opts = term()</v> + <v>Id = term()</v> </type> - <desc> - <p> OPTIONAL </p> - - <p>The <c>Id</c> is used to uniquely identify a CTH instance, - if two CTH's return the same <c>Id</c> the second CTH is ignored - and subsequent calls to the CTH will only be made to the first - instance. For more information see - <seealso marker="ct_hooks_chapter#installing">Installing a CTH - </seealso> in the User's Guide. - </p> - - <p>This function should NOT have any side effects as it might - be called multiple times by Common Test.</p> + <p>OPTIONAL</p> - <p>If not implemented the CTH will act as if this function returned a - call to <c>make_ref/0</c>.</p> - </desc> + <p>The <c>Id</c> identifies a CTH instance uniquely. If two CTHs return + the same <c>Id</c>, the second CTH is ignored and subsequent calls to + the CTH are only made to the first instance. For details, see section + <seealso marker="ct_hooks_chapter#installing">Installing a CTH</seealso> + in the User's Guide.</p> + + <p>This function is <em>not</em> to have any side effects, as it can + be called multiple times by <c>Common Test</c>.</p> + + <p>If not implemented, the CTH acts as if this function returned a call + to <c>make_ref/0</c>.</p> + </desc> </func> - </funcs> </erlref> diff --git a/lib/common_test/doc/src/ct_master.xml b/lib/common_test/doc/src/ct_master.xml new file mode 100644 index 0000000000..06f9b04f1b --- /dev/null +++ b/lib/common_test/doc/src/ct_master.xml @@ -0,0 +1,220 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_master</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_master.xml</file> + </header> + <module>ct_master</module> + <modulesummary>Distributed test execution control for Common Test.</modulesummary> + +<description> + + <p>Distributed test execution control for <c>Common Test</c>.</p> + + <p>This module exports functions for running <c>Common Test</c> nodes on + multiple hosts in parallel.</p> + +</description> + + <funcs> + <func> + <name>abort() -> ok</name> + <fsummary>Stops all running tests.</fsummary> + <desc><marker id="abort-0"/> + <p>Stops all running tests.</p> + </desc> + </func> + + <func> + <name>abort(Nodes) -> ok</name> + <fsummary>Stops tests on specified nodes.</fsummary> + <type> + <v>Nodes = atom() | [atom()]</v> + </type> + <desc><marker id="abort-1"/> + <p>Stops tests on specified nodes.</p> + </desc> + </func> + + <func> + <name>basic_html(Bool) -> ok</name> + <fsummary>If set to true, the ct_master logs are written on a primitive + HTML format, not using the <c>Common Test</c> CSS style sheet.</fsummary> + <type> + <v>Bool = true | false</v> + </type> + <desc><marker id="basic_html-1"/> + <p>If set to <c>true</c>, the <c>ct_master logs</c> are written on a + primitive HTML format, not using the <c>Common Test</c> CSS style + sheet.</p> + </desc> + </func> + + <func> + <name>get_event_mgr_ref() -> MasterEvMgrRef</name> + <fsummary>Gets a reference to the <c>Common Test</c> master event + manager.</fsummary> + <type> + <v>MasterEvMgrRef = atom()</v> + </type> + <desc><marker id="get_event_mgr_ref-0"/> + <p>Gets a reference to the <c>Common Test</c> master event manager. + The reference can be used to, for example, add a user-specific + event handler while tests are running.</p> + + <p><em>Example:</em></p> + + <pre> + gen_event:add_handler(ct_master:get_event_mgr_ref(), my_ev_h, [])</pre> + </desc> + </func> + + <func> + <name>progress() -> [{Node, Status}]</name> + <fsummary>Returns test progress.</fsummary> + <type> + <v>Node = atom()</v> + <v>Status = finished_ok | ongoing | aborted | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="progress-0"/> + <p>Returns test progress. If <c>Status</c> is <c>ongoing</c>, tests + are running on the node and are not yet finished.</p> + </desc> + </func> + + <func> + <name>run(TestSpecs) -> ok</name> + <fsummary>Equivalent to run(TestSpecs, false, [], []).</fsummary> + <type> + <v>TestSpecs = string() | [SeparateOrMerged]</v> + </type> + <desc><marker id="run-1"/> + <p>Equivalent to <seealso marker="#run-4"><c>ct_master:run(TestSpecs, + false, [], [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>run(TestSpecs, InclNodes, ExclNodes) -> ok</name> + <fsummary>Equivalent to run(TestSpecs, false, InclNodes, ExclNodes). + </fsummary> + <type> + <v>TestSpecs = string() | [SeparateOrMerged]</v> + <v>SeparateOrMerged = string() | [string()]</v> + <v>InclNodes = [atom()]</v> + <v>ExclNodes = [atom()]</v> + </type> + <desc><marker id="run-3"/> + <p>Equivalent to <seealso marker="#run-4"><c>ct_master:run(TestSpecs, + false, InclNodes, ExclNodes)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>run(TestSpecs, AllowUserTerms, InclNodes, ExclNodes) -> ok</name> + <fsummary>Tests are spawned on the nodes as specified in TestSpecs. + </fsummary> + <type> + <v>TestSpecs = string() | [SeparateOrMerged]</v> + <v>SeparateOrMerged = string() | [string()]</v> + <v>AllowUserTerms = bool()</v> + <v>InclNodes = [atom()]</v> + <v>ExclNodes = [atom()]</v> + </type> + <desc><marker id="run-4"/> + <p>Tests are spawned on the nodes as specified in <c>TestSpecs</c>. + Each specification in <c>TestSpec</c> is handled separately. + However, it is also possible to specify a list of specifications to + be merged into one specification before the tests are executed. Any + test without a particular node specification is also executed on + the nodes in <c>InclNodes</c>. Nodes in the <c>ExclNodes</c> list + are excluded from the test.</p> + </desc> + </func> + + <func> + <name>run_on_node(TestSpecs, Node) -> ok</name> + <fsummary>Equivalent to run_on_node(TestSpecs, false, Node).</fsummary> + <type> + <v>TestSpecs = string() | [SeparateOrMerged]</v> + <v>SeparateOrMerged = string() | [string()]</v> + <v>Node = atom()</v> + </type> + <desc><marker id="run_on_node-2"/> + <p>Equivalent to + <seealso marker="#run_on_node-3"><c>ct_master:run_on_node(TestSpecs, + false, Node)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>run_on_node(TestSpecs, AllowUserTerms, Node) -> ok</name> + <fsummary>Tests are spawned on Node according to TestSpecs.</fsummary> + <type> + <v>TestSpecs = string() | [SeparateOrMerged]</v> + <v>SeparateOrMerged = string() | [string()]</v> + <v>AllowUserTerms = bool()</v> + <v>Node = atom()</v> + </type> + <desc><marker id="run_on_node-3"/> + <p>Tests are spawned on <c>Node</c> according to <c>TestSpecs</c>.</p> + </desc> + </func> + + <func> + <name>run_test(Node, Opts) -> ok</name> + <fsummary>Tests are spawned on Node using ct:run_test/1.</fsummary> + <type> + <v>Node = atom()</v> + <v>Opts = [OptTuples]</v> + <v>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}</v> + <v>CfgFiles = string() | [string()]</v> + <v>TestDirs = string() | [string()]</v> + <v>Suites = atom() | [atom()]</v> + <v>Cases = atom() | [atom()]</v> + <v>TestSpecs = string() | [string()]</v> + <v>LogDir = string()</v> + <v>EventHandlers = EH | [EH]</v> + <v>EH = atom() | {atom(), InitArgs} | {[atom()], InitArgs}</v> + <v>InitArgs = [term()]</v> + <v>Conns = all | [atom()]</v> + </type> + <desc><marker id="run_test-2"/> + <p>Tests are spawned on <c>Node</c> using + <seealso marker="ct:run_test-1"><c>ct:run_test/1</c></seealso></p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_netconfc.xml b/lib/common_test/doc/src/ct_netconfc.xml new file mode 100644 index 0000000000..8139d8afdb --- /dev/null +++ b/lib/common_test/doc/src/ct_netconfc.xml @@ -0,0 +1,1037 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_netconfc</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_netconfc.xml</file> + </header> + <module>ct_netconfc</module> + <modulesummary>NETCONF client module.</modulesummary> + +<description> + + <p>NETCONF client module.</p> + + <p>The NETCONF client is compliant with RFC 4741 NETCONF Configuration + Protocol and RFC 4742 Using the NETCONF Configuration Protocol over + Secure SHell (SSH)..</p> + + <p>For each server to test against, the following entry can be added to a + configuration file:</p> + + <pre> + {server_id(),options()}.</pre> + + <p>The <c>server_id()</c> or an associated <c>target_name()</c> (see + module <seealso marker="ct"><c>ct</c></seealso>) must then be used + in calls to + <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>.</p> + + <p>If no configuration exists for a server, a session can still be + opened by calling + <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso> with + all necessary options specified in the call. The first argument to + <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso> can + then be any atom.</p> + + </description> + + <section> + <marker id="Logging"/> + <title>Logging</title> + <p>The NETCONF server uses <c>error_logger</c> for logging of NETCONF + traffic. A special purpose error handler is implemented in + <c>ct_conn_log_h</c>. To use this error handler, add the + <c>cth_conn_log</c> hook in the test suite, for example:</p> + + <pre> + suite() -> + [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].</pre> + + <p><c>conn_mod()</c> is the name of the <c>Common Test</c> module + implementing the connection protocol, for example, <c>ct_netconfc</c>.</p> + + <p>Hook option <c>log_type</c> specifies the type of logging:</p> + + <taglist> + <tag><c>raw</c></tag> + <item><p>The sent and received NETCONF data is logged to a separate + text file "as is" without any formatting. A link to the file is + added to the test case HTML log.</p>.</item> + + <tag><c>pretty</c></tag> + <item><p>The sent and received NETCONF data is logged to a separate + text file with XML data nicely indented. A link to the file is + added to the test case HTML log.</p></item> + + <tag><c>html (default)</c></tag> + <item><p>The sent and received NETCONF traffic is pretty printed + directly in the test case HTML log.</p></item> + + <tag><c>silent</c></tag> + <item><p>NETCONF traffic is not logged.</p></item> + </taglist> + + <p>By default, all NETCONF traffic is logged in one single log file. + However, different connections can be logged in separate files. + To do this, use hook option <c>hosts</c> and list the names of the + servers/connections to be used in the suite. The connections + must be named for this to work, that is, they must be opened with + <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>.</p> + + <p>Option <c>hosts</c> has no effect if <c>log_type</c> is set to + <c>html</c> or <c>silent</c>.</p> + + <p>The hook options can also be specified in a configuration file with + configuration variable <c>ct_conn_log</c>:</p> + + <pre> + {ct_conn_log,[{conn_mod(),hook_options()}]}.</pre> + + <p>For example:</p> + + <pre> + {ct_conn_log,[{ct_netconfc,[{log_type,pretty}, + {hosts,[key_or_name()]}]}]}</pre> + + <note> + <p>Hook options specified in a configuration file overwrite the + hard-coded hook options in the test suite.</p> + </note> + + <p><em>Logging Example 1:</em></p> + <marker id="Logging_example_1"/> + + <p>The following <c>ct_hooks</c> statement causes pretty printing of + NETCONF traffic to separate logs for the connections named + <c>nc_server1</c> and <c>nc_server2</c>. Any other connections are + logged to default NETCONF log.</p> + + <pre> + suite() -> + [{ct_hooks, [{cth_conn_log, [{ct_netconfc,[{log_type,pretty}}, + {hosts,[nc_server1,nc_server2]}]} + ]}]}].</pre> + + <p>Connections must be opened as follows:</p> + + <pre> + open(nc_server1,[...]), + open(nc_server2,[...]).</pre> + + <p><em>Logging Example 2:</em></p> + <marker id="Logging_example_2"/> + + <p>The following configuration file causes raw logging of all NETCONF + traffic in to one single text file:</p> + + <pre> + {ct_conn_log,[{ct_netconfc,[{log_type,raw}]}]}.</pre> + + <p>The <c>ct_hooks</c> statement must look as follows:</p> + + <pre> + suite() -> + [{ct_hooks, [{cth_conn_log, []}]}].</pre> + + <p>The same <c>ct_hooks</c> statement without the configuration file + would cause HTML logging of all NETCONF connections in to the test + case HTML log.</p> + </section> + + <section> + <marker id="Notifications"/> + <title>Notifications</title> + + <p>The NETCONF client is also compliant with RFC 5277 NETCONF Event + Notifications, which defines a mechanism for an asynchronous message + notification delivery service for the NETCONF protocol.</p> + + <p>Specific functions to support this are + <seealso marker="#create_subscription-6"><c>ct_netconfc:create_subscription/6</c></seealso> + and + <seealso marker="#get_event_streams-3"><c>ct_netconfc:get_event_streams/3</c></seealso>. + (The functions also exist with other arities.)</p> + </section> + + <section> + <title>Data Types</title> + <marker id="types"/> + <taglist> + <tag><c>client() = handle() | key_or_name()</c></tag> + <item><marker id="type-client"/> + <p>For <c>handle()</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p></item> + + <tag><c>error_reason() = term()</c></tag> + <item><marker id="type-error_reason"/> </item> + <tag><c>event_time() = {eventTime, xml_attributes(), [xs_datetime()]}</c></tag> + <item><marker id="type-event_time"/> </item> + + <tag><c>handle() = term()</c></tag> + <item><marker id="type-handle"/> + <p>Opaque reference for a connection (NETCONF session). For more + information, see module <seealso marker="ct"><c>ct</c></seealso>.</p> + </item> + + <tag><c>host() = hostname() | ip_address()</c></tag> + <item><marker id="type-host"/> + <p>For <c>hostname()</c> and <c>ip_address()</c>, see module + <seealso marker="kernel:inet"><c>kernel:inet</c></seealso></p></item> + + <tag><c>key_or_name() = server_id() | target_name()</c></tag> + <item><marker id="type-key_or_name"/> + <p>For <c>target_name</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p></item> + + <tag><c>netconf_db() = running | startup | candidate</c></tag> + <item><marker id="type-netconf_db"/> </item> + + <tag><c>notification() = {notification, xml_attributes(), notification_content()}</c></tag> + <item><marker id="type-notification"/> </item> + + <tag><c>notification_content() = [event_time() | simple_xml()]</c></tag> + <item><marker id="type-notification_content"/> </item> + + <tag><c>option() = {ssh, host()} | {port, port_number()} | {user, string()} | {password, string()} | {user_dir, string()} | {timeout, timeout()}</c></tag> + <item><marker id="type-option"/> + <p>For <c>port_number()</c>, see module + <seealso marker="kernel:inet"><c>kernel:inet</c></seealso></p></item> + + <tag><c>options() = [option()]</c></tag> + <item><marker id="type-options"/> + <p>Options used for setting up an SSH connection to a NETCONF + server.</p></item> + + <tag><c>server_id() = atom()</c></tag> + <item><marker id="type-server_id"/> + <p>The identity of a server, specified in a configuration + file.</p></item> + + <tag><c>simple_xml() = {xml_tag(), xml_attributes(), xml_content()} | {xml_tag(), xml_content()} | xml_tag()</c></tag> + <item><marker id="type-simple_xml"/> + <p>This type is further described in application + <seealso marker="xmerl"><c>xmerl</c></seealso>.</p></item> + + <tag><c>stream_data() = {description, string()} | {replaySupport, string()} | {replayLogCreationTime, string()} | {replayLogAgedTime, string()}</c></tag> + <item><marker id="type-stream_data"/> + <p>For details about the data format for the string values, see + "XML Schema for Event Notifications" in RFC 5277.</p></item> + + <tag><c>stream_name() = string()</c></tag> + <item><marker id="type-stream_name"/> </item> + + <tag><c>streams() = [{stream_name(), [stream_data()]}]</c></tag> + <item><marker id="type-streams"/> </item> + + <tag><c>xml_attribute_tag() = atom()</c></tag> + <item><marker id="type-xml_attribute_tag"/> </item> + + <tag><c>xml_attribute_value() = string()</c></tag> + <item><marker id="type-xml_attribute_value"/> </item> + + <tag><c>xml_attributes() = [{xml_attribute_tag(), xml_attribute_value()}]</c></tag> + <item><marker id="type-xml_attributes"/> </item> + + <tag><c>xml_content() = [simple_xml() | iolist()]</c></tag> + <item><marker id="type-xml_content"/> </item> + + <tag><c>xml_tag() = atom()</c></tag> + <item><marker id="type-xml_tag"/> </item> + + <tag><c>xpath() = {xpath, string()}</c></tag> + <item><marker id="type-xpath"/> </item> + + <tag><c>xs_datetime() = string()</c></tag> + <item><marker id="type-xs_datetime"/> + <p>This date and time identifier has the same format as the XML type + <c>dateTime</c> and is compliant with RFC 3339 Date and Time on + the Internet Timestamps. The format is as follows:</p> + <pre> + [-]CCYY-MM-DDThh:mm:ss[.s][Z|(+|-)hh:mm]</pre> + </item> + </taglist> + </section> + + <funcs> + <func> + <name>action(Client, Action) -> Result</name> + <fsummary>Equivalent to action(Client, Action, infinity).</fsummary> + <desc><marker id="action-2"/> + <p>Equivalent to + <seealso marker="#action-3"><c>ct_netconfc:action(Client, Action, + infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>action(Client, Action, Timeout) -> Result</name> + <fsummary>Executes an action.</fsummary> + <type> + <v>Client = client()</v> + <v>Action = simple_xml()</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {ok, [simple_xml()]} | {error, error_reason()}</v> + </type> + <desc><marker id="action-3"/> + <p>Executes an action. If the return type is void, <c>ok</c> is + returned instead of <c>{ok,[simple_xml()]}</c>.</p> + </desc> + </func> + + <func> + <name>close_session(Client) -> Result</name> + <fsummary>Equivalent to close_session(Client, infinity).</fsummary> + <desc><marker id="close_session-1"/> + <p>Equivalent to + <seealso marker="#close_session-2"><c>ct_netconfc:close_session(Client, + infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>close_session(Client, Timeout) -> Result</name> + <fsummary>Requests graceful termination of the session associated with + the client.</fsummary> + <type> + <v>Client = client()</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="close_session-2"/> + <p>Requests graceful termination of the session associated with the + client.</p> + + <p>When a NETCONF server receives a <c>close-session</c> request, it + gracefully closes the session. The server releases any locks and + resources associated with the session and gracefully closes any + associated connections. Any NETCONF requests received after a + <c>close-session</c> request are ignored.</p> + </desc> + </func> + + <func> + <name>copy_config(Client, Source, Target) -> Result</name> + <fsummary>Equivalent to copy_config(Client, Source, Target, + infinity).</fsummary> + <desc><marker id="copy_config-3"/> + <p>Equivalent to + <seealso marker="#copy_config-4"><c>ct_netconfc:copy_config(Client, + Source, Target, infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>copy_config(Client, Target, Source, Timeout) -> Result</name> + <fsummary>Copies configuration data.</fsummary> + <type> + <v>Client = client()</v> + <v>Target = netconf_db()</v> + <v>Source = netconf_db()</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="copy_config-4"/> + <p>Copies configuration data.</p> + + <p>Which source and target options that can be issued depends on the + capabilities supported by the server. That is, <c>:candidate</c> + and/or <c>:startup</c> are required.</p> + </desc> + </func> + + <func> + <name>create_subscription(Client) -> term()</name> + <fsummary>Creates a subscription for event notifications.</fsummary> + <desc><marker id="create_subscription-1"/></desc> + </func> + + <func> + <name>create_subscription(Client, Timeout) -> term()</name> + <fsummary>Creates a subscription for event notifications.</fsummary> + <desc><marker id="create_subscription-2"/></desc> + </func> + + <func> + <name>create_subscription(Client, Stream, Timeout) -> term()</name> + <fsummary>Creates a subscription for event notifications.</fsummary> + <desc><marker id="create_subscription-3"/></desc> + </func> + + <func> + <name>create_subscription(Client, StartTime, StopTime, Timeout) -> term()</name> + <fsummary>Creates a subscription for event notifications.</fsummary> + <desc><marker id="create_subscription-4"/></desc> + </func> + + <func> + <name>create_subscription(Client, Stream, StartTime, StopTime, Timeout) -> term()</name> + <fsummary>Creates a subscription for event notifications.</fsummary> + <desc><marker id="create_subscription-5"/></desc> + </func> + + <func> + <name>create_subscription(Client, Stream, Filter, StartTime, StopTime, Timeout) -> Result</name> + <fsummary>Creates a subscription for event notifications.</fsummary> + <type> + <v>Client = client()</v> + <v>Stream = stream_name()</v> + <v>Filter = simple_xml() | [simple_xml()]</v> + <v>StartTime = xs_datetime()</v> + <v>StopTime = xs_datetime()</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="create_subscription-6"/> + <p>Creates a subscription for event notifications.</p> + + <p>This function sets up a subscription for NETCONF event + notifications of the specified stream type, matching the specified + filter. The calling process receives notifications as messages of + type <c>notification()</c>.</p> + + <taglist> + <tag><c>Stream</c></tag> + <item><p>Optional parameter that indicates which stream of event + is of interest. If not present, events in the default NETCONF + stream are sent.</p></item> + <tag><c>Filter</c></tag> + <item><p>Optional parameter that indicates which subset of all + possible events is of interest. The parameter format is the + same as that of the filter parameter in the NETCONF protocol + operations. If not present, all events not precluded by other + parameters are sent.</p></item> + <tag><c>StartTime</c></tag> + <item><p>Optional parameter used to trigger the replay feature and + indicate that the replay is to start at the time specified. + If <c>StartTime</c> is not present, this is not a replay + subscription.</p> + <p>It is not valid to specify start times that are later than + the current time. If <c>StartTime</c> is specified earlier + than the log can support, the replay begins with the earliest + available notification.</p> + <p>This parameter is of type <c>dateTime</c> and compliant to + RFC 3339. Implementations must support time zones.</p></item> + <tag><c>StopTime</c></tag> + <item><p>Optional parameter used with the optional replay feature + to indicate the newest notifications of interest. If + <c>StopTime</c> is not present, the notifications continues + until the subscription is terminated.</p> + <p>Must be used with and be later than <c>StartTime</c>. Values + of <c>StopTime</c> in the future are valid. This parameter is + of type <c>dateTime</c> and compliant to RFC 3339. + Implementations must support time zones.</p></item> + </taglist> + + <p>For more details about the event notification mechanism, see + RFC 5277.</p> + </desc> + </func> + + <func> + <name>delete_config(Client, Target) -> Result</name> + <fsummary>Equivalent to delete_config(Client, Target, + infinity).</fsummary> + <desc><marker id="delete_config-2"/> + <p>Equivalent to + <seealso marker="#delete_config-3"><c>ct_netconfc:delete_config(Client, Target, infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>delete_config(Client, Target, Timeout) -> Result</name> + <fsummary>Deletes configuration data.</fsummary> + <type> + <v>Client = client()</v> + <v>Target = startup | candidate</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="delete_config-3"/> + <p>Deletes configuration data.</p> + + <p>The running configuration cannot be deleted and <c>:candidate</c> + or <c>:startup</c> must be advertised by the server.</p> + </desc> + </func> + + <func> + <name>edit_config(Client, Target, Config) -> Result</name> + <fsummary>Equivalent to edit_config(Client, Target, Config, [], + infinity).</fsummary> + <desc><marker id="edit_config-3"/> + <p>Equivalent to + <seealso marker="#edit_config-5"><c>ct_netconfc:edit_config(Client, + Target, Config, [], infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>edit_config(Client, Target, Config, OptParamsOrTimeout) -> Result</name> + <fsummary>If OptParamsOrTimeout is a time-out value, this function is + equivalent to ct_netconfc:edit_config(Client, Target, Config, [], + Timeout).</fsummary> + <type> + <v>Client = client()</v> + <v>Target = netconf_db()</v> + <v>Config = simple_xml()</v> + <v>OptParamsOrTimeout = [simple_xml()] | timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="edit_config-4"/> + <p>If <c>OptParamsOrTimeout</c> is a time-out value, this function is + equivalent to + <seealso marker="#edit_config-5"><c>ct_netconfc:edit_config(Client, + Target, Config, [], Timeout)</c></seealso>.</p> + + <p>If <c>OptParamsOrTimeout</c> is a list of simple XML, this + function is equivalent to + <seealso marker="#edit_config-5"><c>ct_netconfc:edit_config(Client, + Target, Config, OptParams, infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>edit_config(Client, Target, Config, OptParams, Timeout) -> Result</name> + <fsummary>Edits configuration data.</fsummary> + <type> + <v>Client = client()</v> + <v>Target = netconf_db()</v> + <v>Config = simple_xml()</v> + <v>OptParams = [simple_xml()]</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="edit_config-5"/> + <p>Edits configuration data.</p> + + <p>By default only the running target is available, unless the server + includes <c>:candidate</c> or <c>:startup</c> in its list of + capabilities.</p> + + <p><c>OptParams</c> can be used for specifying optional parameters + (<c>default-operation</c>, <c>test-option</c>, or + <c>error-option</c>) to be added to the <c>edit-config</c> + request. The value must be a list containing valid simple XML, + for example:</p> + + <pre> + [{'default-operation', ["none"]}, + {'error-option', ["rollback-on-error"]}]</pre> + </desc> + </func> + + <func> + <name>get(Client, Filter) -> Result</name> + <fsummary>Equivalent to get(Client, Filter, infinity).</fsummary> + <desc><marker id="get-2"/> + <p>Equivalent to + <seealso marker="#get-3"><c>ct_netconfc:get(Client, Filter, + infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get(Client, Filter, Timeout) -> Result</name> + <fsummary>Gets data.</fsummary> + <type> + <v>Client = client()</v> + <v>Filter = simple_xml() | xpath()</v> + <v>Timeout = timeout()</v> + <v>Result = {ok, [simple_xml()]} | {error, error_reason()}</v> + </type> + <desc><marker id="get-3"/> + <p>Gets data.</p> + + <p>This operation returns both configuration and state data from the + server.</p> + + <p>Filter type <c>xpath</c> can be used only if the server supports + <c>:xpath</c>.</p> + </desc> + </func> + + <func> + <name>get_capabilities(Client) -> Result</name> + <fsummary>Equivalent to get_capabilities(Client, infinity).</fsummary> + <desc><marker id="get_capabilities-1"/> + <p>Equivalent to + <seealso marker="#get_capabilities-2"><c>ct_netconfc:get_capabilities(Client, + infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get_capabilities(Client, Timeout) -> Result</name> + <fsummary>Returns the server side capabilities.</fsummary> + <type> + <v>Client = client()</v> + <v>Timeout = timeout()</v> + <v>Result = [string()] | {error, error_reason()}</v> + </type> + <desc><marker id="get_capabilities-2"/> + <p>Returns the server side capabilities.</p> + + <p>The following capability identifiers, defined in RFC 4741 NETCONF + Configuration Protocol, can be returned:</p> + + <list> + <item><p><c>"urn:ietf:params:netconf:base:1.0"</c></p></item> + <item><p><c>"urn:ietf:params:netconf:capability:writable-running:1.0"</c></p></item> + <item><p><c>"urn:ietf:params:netconf:capability:candidate:1.0"</c></p></item> + <item><p><c>"urn:ietf:params:netconf:capability:confirmed-commit:1.0"</c></p></item> + <item><p><c>"urn:ietf:params:netconf:capability:rollback-on-error:1.0"</c></p></item> + <item><p><c>"urn:ietf:params:netconf:capability:startup:1.0"</c></p></item> + <item><p><c>"urn:ietf:params:netconf:capability:url:1.0"</c></p></item> + <item><p><c>"urn:ietf:params:netconf:capability:xpath:1.0"</c></p></item> + </list> + + <p>More identifiers can exist, for example, server-side namespace.</p> + </desc> + </func> + + <func> + <name>get_config(Client, Source, Filter) -> Result</name> + <fsummary>Equivalent to get_config(Client, Source, Filter, + infinity).</fsummary> + <desc><marker id="get_config-3"/> + <p>Equivalent to + <seealso marker="#get_config-4"><c>ct_netconfc:get_config(Client, Source, Filter, infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get_config(Client, Source, Filter, Timeout) -> Result</name> + <fsummary>Gets configuration data.</fsummary> + <type> + <v>Client = client()</v> + <v>Source = netconf_db()</v> + <v>Filter = simple_xml() | xpath()</v> + <v>Timeout = timeout()</v> + <v>Result = {ok, [simple_xml()]} | {error, error_reason()}</v> + </type> + <desc><marker id="get_config-4"/> + <p>Gets configuration data.</p> + + <p>To be able to access another source than <c>running</c>, the + server must advertise <c>:candidate</c> and/or <c>:startup</c>.</p> + + <p>Filter type <c>xpath</c> can be used only if the server supports + <c>:xpath</c>.</p> + </desc> + </func> + + <func> + <name>get_event_streams(Client, Timeout) -> Result</name> + <fsummary>Equivalent to get_event_streams(Client, [], Timeout).</fsummary> + <desc><marker id="get_event_streams-2"/> + <p>Equivalent to + <seealso marker="#get_event_streams-3"><c>ct_netconfc:get_event_streams(Client, + [], Timeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get_event_streams(Client, Streams, Timeout) -> Result</name> + <fsummary>Sends a request to get the specified event streams.</fsummary> + <type> + <v>Client = client()</v> + <v>Streams = [stream_name()]</v> + <v>Timeout = timeout()</v> + <v>Result = {ok, streams()} | {error, error_reason()}</v> + </type> + <desc><marker id="get_event_streams-3"/> + <p>Sends a request to get the specified event streams.</p> + + <p><c>Streams</c> is a list of stream names. The following filter is + sent to the NETCONF server in a <c>get</c> request:</p> + + <pre> + <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification"> + <streams> + <stream> + <name>StreamName1</name> + </stream> + <stream> + <name>StreamName2</name> + </stream> + ... + </streams> + </netconf></pre> + + <p>If <c>Streams</c> is an empty list, <em>all</em> streams are + requested by sending the following filter:</p> + + <pre> + <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification"> + <streams/> + </netconf></pre> + + <p>If more complex filtering is needed, use + <seealso marker="#get-2"><c>ct_netconfc:get/2</c></seealso> or + <seealso marker="#get-3"><c>ct_netconfc:get/3</c></seealso> and + specify the exact filter according to "XML Schema for Event + Notifications" in RFC 5277.</p> + </desc> + </func> + + <func> + <name>get_session_id(Client) -> Result</name> + <fsummary>Equivalent to get_session_id(Client, infinity).</fsummary> + <desc><marker id="get_session_id-1"/> + <p>Equivalent to + <seealso marker="#get_session_id-2"><c>ct_netconfc:get_session_id(Client, + infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get_session_id(Client, Timeout) -> Result</name> + <fsummary>Returns the session Id associated with the specified + client.</fsummary> + <type> + <v>Client = client()</v> + <v>Timeout = timeout()</v> + <v>Result = pos_integer() | {error, error_reason()}</v> + </type> + <desc><marker id="get_session_id-2"/> + <p>Returns the session Id associated with the specified client.</p> + </desc> + </func> + + <func> + <name>hello(Client) -> Result</name> + <fsummary>Equivalent to hello(Client, [], infinity).</fsummary> + <desc><marker id="hello-1"/> + <p>Equivalent to + <seealso marker="#hello-3"><c>ct_netconfc:hello(Client, [], + infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>hello(Client, Timeout) -> Result</name> + <fsummary>Equivalent to hello(Client, [], Timeout).</fsummary> + <desc><marker id="hello-2"/> + <p>Equivalent to + <seealso marker="#hello-3"><c>ct_netconfc:hello(Client, [], + Timeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>hello(Client, Options, Timeout) -> Result</name> + <fsummary>Exchanges hello messages with the server.</fsummary> + <type> + <v>Client = handle()</v> + <v>Options = [{capability, [string()]}]</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="hello-3"/> + <p>Exchanges <c>hello</c> messages with the server.</p> + + <p>Adds optional capabilities and sends a <c>hello</c> message to the + server and waits for the return.</p> + </desc> + </func> + + <func> + <name>kill_session(Client, SessionId) -> Result</name> + <fsummary>Equivalent to kill_session(Client, SessionId, + infinity).</fsummary> + <desc><marker id="kill_session-2"/> + <p>Equivalent to + <seealso marker="#kill_session-3"><c>ct_netconfc:kill_session(Client, +SessionId, infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>kill_session(Client, SessionId, Timeout) -> Result</name> + <fsummary>Forces termination of the session associated with the supplied + session Id.</fsummary> + <type> + <v>Client = client()</v> + <v>SessionId = pos_integer()</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="kill_session-3"/> + <p>Forces termination of the session associated with the supplied + session Id.</p> + + <p>The server side must abort any ongoing operations, release any + locks and resources associated with the session, and close any + associated connections.</p> + + <p>Only if the server is in the confirmed commit phase, the + configuration is restored to its state before entering the confirmed + commit phase. Otherwise, no configuration rollback is performed.</p> + + <p>If the specified <c>SessionId</c> is equal to the current session + Id, an error is returned.</p> + </desc> + </func> + + <func> + <name>lock(Client, Target) -> Result</name> + <fsummary>Equivalent to lock(Client, Target, infinity).</fsummary> + <desc><marker id="lock-2"/> + <p>Equivalent to + <seealso marker="#lock-3"><c>ct_netconfc:lock(Client, Target, + infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>lock(Client, Target, Timeout) -> Result</name> + <fsummary>Unlocks the configuration target.</fsummary> + <type> + <v>Client = client()</v> + <v>Target = netconf_db()</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="lock-3"/> + <p>Unlocks the configuration target.</p> + + <p>Which target parameters that can be used depends on if + <c>:candidate</c> and/or <c>:startup</c> are supported by the + server. If successfull, the configuration system of the device is + unavailable to other clients (NETCONF, CORBA, SNMP, and so on). + Locks are intended to be short-lived.</p> + + <p>Operation + <seealso marker="#kill_session-2"><c>ct_netconfc:kill_session/2</c></seealso> + or + <seealso marker="#kill_session-3"><c>ct_netconfc:kill_session/3</c></seealso> + can be used to force the release of a lock owned by another NETCONF + session. How this is achieved by the server side is + implementation-specific.</p> + </desc> + </func> + + <func> + <name>only_open(Options) -> Result</name> + <fsummary>Opens a NETCONF session, but does not send hello.</fsummary> + <type> + <v>Options = options()</v> + <v>Result = {ok, handle()} | {error, error_reason()}</v> + </type> + <desc><marker id="only_open-1"/> + <p>Opens a NETCONF session, but does not send <c>hello</c>.</p> + + <p>As <seealso marker="#open-1"><c>ct_netconfc:open/1</c></seealso>, + but does not send a <c>hello</c> message.</p> + </desc> + </func> + + <func> + <name>only_open(KeyOrName, ExtraOptions) -> Result</name> + <fsummary>Opens a name NETCONF session, but does not send + hello.</fsummary> + <type> + <v>KeyOrName = key_or_name()</v> + <v>ExtraOptions = options()</v> + <v>Result = {ok, handle()} | {error, error_reason()}</v> + </type> + <desc><marker id="only_open-2"/> + <p>Opens a name NETCONF session, but does not send <c>hello</c>.</p> + + <p>As <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>, + but does not send a <c>hello</c> message.</p> + </desc> + </func> + + <func> + <name>open(Options) -> Result</name> + <fsummary>Opens a NETCONF session and exchanges hello messages.</fsummary> + <type> + <v>Options = options()</v> + <v>Result = {ok, handle()} | {error, error_reason()}</v> + </type> + <desc><marker id="open-1"/> + <p>Opens a NETCONF session and exchanges <c>hello</c> messages.</p> + + <p>If the server options are specified in a configuration file, + or if a named client is needed for logging purposes (see section + <seealso marker="#Logging">Logging</seealso> in this module), use + <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso> + instead.</p> + + <p>The opaque <c>handler()</c> reference returned from this + function is required as client identifier when calling any other + function in this module.</p> + + <p>Option <c>timeout</c> (milliseconds) is used when setting up the + SSH connection and when waiting for the <c>hello</c> message from + the server. It is not used for any other purposes during the + lifetime of the connection.</p> + </desc> + </func> + + <func> + <name>open(KeyOrName, ExtraOptions) -> Result</name> + <fsummary>Opens a named NETCONF session and exchanges hello + messages.</fsummary> + <type> + <v>KeyOrName = key_or_name()</v> + <v>ExtraOptions = options()</v> + <v>Result = {ok, handle()} | {error, error_reason()}</v> + </type> + <desc><marker id="open-2"/> + <p>Opens a named NETCONF session and exchanges <c>hello</c> + messages.</p> + + <p>If <c>KeyOrName</c> is a configured <c>server_id()</c> or a + <c>target_name()</c> associated with such an Id, then the options + for this server are fetched from the configuration file.</p> + + <p>Argument <c>ExtraOptions</c> is added to the options found in the + configuration file. If the same options are specified, the values + from the configuration file overwrite <c>ExtraOptions</c>.</p> + + <p>If the server is not specified in a configuration file, use + <seealso marker="#open-1"><c>ct_netconfc:open/1</c></seealso> + instead.</p> + + <p>The opaque <c>handle()</c> reference returned from this + function can be used as client identifier when calling any other + function in this module. However, if <c>KeyOrName</c> is a + <c>target_name()</c>, that is, if the server is named through a + call to <seealso marker="ct#require-2"><c>ct:require/2</c></seealso> + or a <c>require</c> statement in the test suite, then this name can + be used instead of <c>handle()</c>.</p> + + <p>Option <c>timeout</c> (milliseconds) is used when setting up the + SSH connection and when waiting for the <c>hello</c> message from + the server. It is not used for any other purposes during the + lifetime of the connection.</p> + + <p>See also + <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send(Client, SimpleXml) -> Result</name> + <fsummary>Equivalent to send(Client, SimpleXml, infinity).</fsummary> + <desc><marker id="send-2"/> + <p>Equivalent to + <seealso marker="#send-3"><c>ct_netconfc:send(Client, SimpleXml, + infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send(Client, SimpleXml, Timeout) -> Result</name> + <fsummary>Sends an XML document to the server.</fsummary> + <type> + <v>Client = client()</v> + <v>SimpleXml = simple_xml()</v> + <v>Timeout = timeout()</v> + <v>Result = simple_xml() | {error, error_reason()}</v> + </type> + <desc><marker id="send-3"/> + <p>Sends an XML document to the server.</p> + + <p>The specified XML document is sent "as is" to the server. This + function can be used for sending XML documents that cannot be + expressed by other interface functions in this module.</p> + </desc> + </func> + + <func> + <name>send_rpc(Client, SimpleXml) -> Result</name> + <fsummary>Equivalent to send_rpc(Client, SimpleXml, infinity).</fsummary> + <desc><marker id="send_rpc-2"/> + <p>Equivalent to + <seealso marker="#send_rpc-3"><c>ct_netconfc:send_rpc(Client, + SimpleXml, infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send_rpc(Client, SimpleXml, Timeout) -> Result</name> + <fsummary>Sends a NETCONF rpc request to the server.</fsummary> + <type> + <v>Client = client()</v> + <v>SimpleXml = simple_xml()</v> + <v>Timeout = timeout()</v> + <v>Result = [simple_xml()] | {error, error_reason()}</v> + </type> + <desc><marker id="send_rpc-3"/> + <p>Sends a NETCONF <c>rpc</c> request to the server.</p> + + <p>The specified XML document is wrapped in a valid NETCONF <c>rpc</c> + request and sent to the server. The <c>message-id</c> and namespace + attributes are added to element <c>rpc</c>.</p> + + <p>This function can be used for sending <c>rpc</c> requests that + cannot be expressed by other interface functions in this module.</p> + </desc> + </func> + + <func> + <name>unlock(Client, Target) -> Result</name> + <fsummary>Equivalent to unlock(Client, Target, infinity).</fsummary> + <desc><marker id="unlock-2"/> + <p>Equivalent to + <seealso marker="#unlock-3"><c>ct_netconfc:unlock(Client, Target, + infinity)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>unlock(Client, Target, Timeout) -> Result</name> + <fsummary>Unlocks the configuration target.</fsummary> + <type> + <v>Client = client()</v> + <v>Target = netconf_db()</v> + <v>Timeout = timeout()</v> + <v>Result = ok | {error, error_reason()}</v> + </type> + <desc><marker id="unlock-3"/> + <p>Unlocks the configuration target.</p> + + <p>If the client earlier has acquired a lock through + <seealso marker="#lock-2"><c>ct_netconfc:lock/2</c></seealso> or + <seealso marker="#lock-3"><c>ct_netconfc:lock/3</c></seealso>, this + operation releases the associated lock. To access another target + than <c>running</c>, the server must support <c>:candidate</c> + and/or <c>:startup</c>.</p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_property_test.xml b/lib/common_test/doc/src/ct_property_test.xml new file mode 100644 index 0000000000..2e9bd1969c --- /dev/null +++ b/lib/common_test/doc/src/ct_property_test.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_property_test</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_property_test.xml</file> + </header> + <module>ct_property_test</module> + <modulesummary>EXPERIMENTAL support in Common Test for calling + property-based tests.</modulesummary> + + <description> + + <p>EXPERIMENTAL support in <c>Common Test</c> for calling property-based + tests.</p> + + <p>This module is a first step to run property-based tests in the + <c>Common Test</c> framework. A property testing tool like QuickCheck + or PropEr is assumed to be installed.</p> + + <p>The idea is to have a <c>Common Test</c> test suite calling a property + testing tool with special property test suites as defined by that tool. + The usual Erlang application directory structure is assumed. The tests + are collected in the <c>test</c> directory of the application. The + <c>test</c> directory has a subdirectory <c>property_test</c>, where + everything needed for the property tests is collected.</p> + + <p>A typical <c>Common Test</c> test suite using <c>ct_property_test</c> + is organized as follows:</p> + + <pre> + -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 + ).</pre> + + <warning> + <p>This is experimental code that can be changed or removed anytime + without any warning.</p> + </warning> + + </description> + + <funcs> + <func> + <name>init_per_suite(Config) -> Config | {skip, Reason}</name> + <fsummary>Initializes Config for property testing.</fsummary> + <desc><marker id="init_per_suite-1"/> + <p>Initializes <c>Config</c> for property testing.</p> + + <p>This function investigates if support is available for either + Quickcheck, PropEr, or Triq. The options + <c>{property_dir,AbsPath}</c> and <c>{property_test_tool,Tool}</c> + are set in the <c>Config</c> returned.</p> + + <p>The function is intended to be called in function + <c>init_per_suite</c> in the test suite.</p> + + <p>The property tests are assumed to be in subdirectory + <c>property_test</c>.</p> + </desc> + </func> + + <func> + <name>quickcheck(Property, Config) -> true | {fail, Reason}</name> + <fsummary>Calls quickcheck and returns the result in a form suitable for + Common Test.</fsummary> + <desc><marker id="quickcheck-2"/> + <p>Calls quickcheck and returns the result in a form suitable for + <c>Common Test</c>.</p> + + <p>This function is intended to be called in the test cases in the + test suite.</p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_rpc.xml b/lib/common_test/doc/src/ct_rpc.xml new file mode 100644 index 0000000000..132d04545d --- /dev/null +++ b/lib/common_test/doc/src/ct_rpc.xml @@ -0,0 +1,220 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_rpc</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_rpc.xml</file> + </header> + <module>ct_rpc</module> + <modulesummary>Common Test specific layer on Erlang/OTP rpc.</modulesummary> + + <description> + + <p><c>Common Test</c> specific layer on Erlang/OTP <c>rpc</c>.</p> + + </description> + + <funcs> + <func> + <name>app_node(App, Candidates) -> NodeName</name> + <fsummary>From a set of candidate nodes determines which of them is + running the application App.</fsummary> + <type> + <v>App = atom()</v> + <v>Candidates = [NodeName]</v> + <v>NodeName = atom()</v> + </type> + <desc><marker id="app_node-2"/> + <p>From a set of candidate nodes determines which of them is running + the application <c>App</c>. If none of the candidate nodes is + running <c>App</c>, the function makes the test case calling + this function to fail. This function is the same as calling + <c>app_node(App, Candidates, true)</c>.</p> + </desc> + </func> + + <func> + <name>app_node(App, Candidates, FailOnBadRPC) -> NodeName</name> + <fsummary>Same as app_node/2, except that argument FailOnBadRPC + determines if the search for a candidate node is to stop if + badrpc is received at some point.</fsummary> + <type> + <v>App = atom()</v> + <v>Candidates = [NodeName]</v> + <v>NodeName = atom()</v> + <v>FailOnBadRPC = true | false</v> + </type> + <desc><marker id="app_node-3"/> + <p>Same as + <seealso marker="app_node-2"><c>ct_rpc:app_node/2</c></seealso>, + except that argument <c>FailOnBadRPC</c> determines if the search + for a candidate node is to stop if <c>badrpc</c> is received at + some point.</p> + </desc> + </func> + + <func> + <name>app_node(App, Candidates, FailOnBadRPC, Cookie) -> NodeName</name> + <fsummary>Same as app_node/2, except that argument FailOnBadRPC + determines if the search for a candidate node is to stop if badrpc is + received at some point.</fsummary> + <type> + <v>App = atom()</v> + <v>Candidates = [NodeName]</v> + <v>NodeName = atom()</v> + <v>FailOnBadRPC = true | false</v> + <v>Cookie = atom()</v> + </type> + <desc><marker id="app_node-4"/> + <p>Same as + <seealso marker="app_node-2"><c>ct_rpc:app_node/2</c></seealso>, + except that argument <c>FailOnBadRPC</c> determines if the search + for a candidate node is to stop if <c>badrpc</c> is received at + some point.</p> + + <p>The cookie on the client node is set to <c>Cookie</c> for this + <c>rpc</c> operation (used to match the server node cookie).</p> + </desc> + </func> + + <func> + <name>call(Node, Module, Function, Args) -> term() | {badrpc, Reason}</name> + <fsummary>Same as call(Node, Module, Function, Args, infinity).</fsummary> + <desc><marker id="call-4"/> + <p>Same as <c>call(Node, Module, Function, Args, infinity)</c>.</p> + </desc> + </func> + + <func> + <name>call(Node, Module, Function, Args, TimeOut) -> term() | {badrpc, Reason}</name> + <fsummary>Evaluates apply(Module, Function, Args) on the node + Node.</fsummary> + <type> + <v>Node = NodeName | {Fun, FunArgs}</v> + <v>Fun = function()</v> + <v>FunArgs = term()</v> + <v>NodeName = atom()</v> + <v>Module = atom()</v> + <v>Function = atom()</v> + <v>Args = [term()]</v> + <v>Reason = timeout | term()</v> + </type> + <desc><marker id="call-5"/> + <p>Evaluates <c>apply(Module, Function, Args)</c> on the node + <c>Node</c>. Returns either whatever <c>Function</c> returns, or + <c>{badrpc, Reason}</c> if the remote procedure call fails. If + <c>Node</c> is <c>{Fun, FunArgs}</c>, applying <c>Fun</c> to + <c>FunArgs</c> is to return a node name.</p> + </desc> + </func> + + <func> + <name>call(Node, Module, Function, Args, TimeOut, Cookie) -> term() | {badrpc, Reason}</name> + <fsummary>Evaluates apply(Module, Function, Args) on the node + Node.</fsummary> + <type> + <v>Node = NodeName | {Fun, FunArgs}</v> + <v>Fun = function()</v> + <v>FunArgs = term()</v> + <v>NodeName = atom()</v> + <v>Module = atom()</v> + <v>Function = atom()</v> + <v>Args = [term()]</v> + <v>Reason = timeout | term()</v> + <v>Cookie = atom()</v> + </type> + <desc><marker id="call-6"/> + <p>Evaluates <c>apply(Module, Function, Args)</c> on the node + <c>Node</c>. Returns either whatever <c>Function</c> returns, or + <c>{badrpc, Reason}</c> if the remote procedure call fails. If + <c>Node</c> is <c>{Fun, FunArgs}</c>, applying <c>Fun</c> to + <c>FunArgs</c> is to return a node name.</p> + + <p>The cookie on the client node is set to <c>Cookie</c> for this + <c>rpc</c> operation (used to match the server node cookie).</p> + </desc> + </func> + + <func> + <name>cast(Node, Module, Function, Args) -> ok</name> + <fsummary>Evaluates apply(Module, Function, Args) on the node + Node.</fsummary> + <type> + <v>Node = NodeName | {Fun, FunArgs}</v> + <v>Fun = function()</v> + <v>FunArgs = term()</v> + <v>NodeName = atom()</v> + <v>Module = atom()</v> + <v>Function = atom()</v> + <v>Args = [term()]</v> + <v>Reason = timeout | term()</v> + </type> + <desc><marker id="cast-4"/> + <p>Evaluates <c>apply(Module, Function, Args)</c> on the node + <c>Node</c>. No response is delivered and the process that makes + the call is not suspended until the evaluation is completed as in + the case of <c>call/3,4</c>. If <c>Node</c> is + <c>{Fun, FunArgs}</c>, applying <c>Fun</c> to <c>FunArgs</c> is to + return a node name.</p> + </desc> + </func> + + <func> + <name>cast(Node, Module, Function, Args, Cookie) -> ok</name> + <fsummary>Evaluates apply(Module, Function, Args) on the node + Node.</fsummary> + <type> + <v>Node = NodeName | {Fun, FunArgs}</v> + <v>Fun = function()</v> + <v>FunArgs = term()</v> + <v>NodeName = atom()</v> + <v>Module = atom()</v> + <v>Function = atom()</v> + <v>Args = [term()]</v> + <v>Reason = timeout | term()</v> + <v>Cookie = atom()</v> + </type> + <desc><marker id="cast-5"/> + <p>Evaluates <c>apply(Module, Function, Args)</c> on the node + <c>Node</c>. No response is delivered and the process that makes + the call is not suspended until the evaluation is completed as in + the case of <c>call/3,4</c>. If <c>Node</c> is + <c>{Fun, FunArgs}</c>, applying <c>Fun</c> to <c>FunArgs</c> is to + return a node name.</p> + + <p>The cookie on the client node is set to <c>Cookie</c> for this + <c>rpc</c> operation (used to match the server node cookie).</p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_run.xml b/lib/common_test/doc/src/ct_run.xml index 5518bb039b..a1ad060366 100644 --- a/lib/common_test/doc/src/ct_run.xml +++ b/lib/common_test/doc/src/ct_run.xml @@ -33,179 +33,190 @@ <file>ct_run.xml</file> </header> <com>ct_run</com> - <comsummary>Program used for starting Common Test from the - OS command line. - </comsummary> + <comsummary>Program used for starting <c>Common Test</c> from the + OS command line.</comsummary> <description> <p>The <c>ct_run</c> program is automatically installed with Erlang/OTP - and Common Test (please see the Installation chapter in the Common - Test User's Guide for more information). The program accepts a number - of different start flags. Some flags trigger <c>ct_run</c> - to start the Common Test application and pass on data to it. Some - flags start an Erlang node prepared for running Common Test in a - particular mode.</p> - - <p>There is an interface function that corresponds to this program, - called <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, for starting Common Test from the Erlang - shell (or an Erlang program). Please see the <c>ct</c> man page for - details.</p> + and the <c>Common Test</c> application (for more information, see + section <seealso marker="install_chapter">Installation</seealso> + in the User's Guide). The program accepts different start flags. + Some flags trigger <c>ct_run</c> to start <c>Common Test</c> and + pass on data to it. Some flags start an Erlang node prepared for + running <c>Common Test</c> in a particular mode.</p> + + <p>The interface function + <seealso marker="ct#run_test-1"><c>ct:run_test/1</c></seealso>, + corresponding to the <c>ct_run</c> program, is used for starting + <c>Common Test</c> from the Erlang shell (or an Erlang program). + For details, see the <seealso marker="ct"><c>ct</c></seealso> + manual page.</p> <p><c>ct_run</c> also accepts Erlang emulator flags. These are used - when <c>ct_run</c> calls <c>erl</c> to start the Erlang node - (making it possible to e.g. add directories to the code server path, - change the cookie on the node, start additional applications, etc).</p> - - <p>With the optional flag:</p> - <pre>-erl_args</pre> - <p>it's possible to divide the options on the <c>ct_run</c> command line into - two groups, one that Common Test should process (those preceding <c>-erl_args</c>), - and one it should completely ignore and pass on directly to the emulator - (those following <c>-erl_args</c>). Options preceding <c>-erl_args</c> that Common Test - doesn't recognize, also get passed on to the emulator untouched. - By means of <c>-erl_args</c> the user may specify flags with the same name, but + when <c>ct_run</c> calls <c>erl</c> to start the Erlang node (this + makes it possible to add directories to the code server path, + change the cookie on the node, start more applications, and so on).</p> + + <p>With the optional flag <c>-erl_args</c>, options on the <c>ct_run</c> + command line can be divided into two groups:</p> + + <list type="bulleted"> + <item>One group that <c>Common Test</c> is to process (those + preceding <c>-erl_args</c>).</item> + <item>One group that <c>Common Test</c> is to ignore and pass on + directly to the emulator (those following <c>-erl_args</c>).</item> + </list> + + <p>Options preceding <c>-erl_args</c> that <c>Common Test</c> + does not recognize are also passed on to the emulator untouched. + By <c>-erl_args</c> the user can specify flags with the same name, but with different destinations, on the <c>ct_run</c> command line.</p> - <p>If <c>-pa</c> or <c>-pz</c> flags are specified in the Common Test group of options - (preceding <c>-erl_args</c>), relative directories will be converted to - absolute and re-inserted into the code path by Common Test (to avoid - problems loading user modules when Common Test changes working directory - during test runs). Common Test will however ignore <c>-pa</c> and <c>-pz</c> flags - following <c>-erl_args</c> on the command line. These directories are added - to the code path normally (i.e. on specified form)</p> - - <p>Exit status is set before the program ends. Value <c>0</c> indicates a successful - test result, <c>1</c> indicates one or more failed or auto-skipped test cases, and - <c>2</c> indicates test execution failure.</p> - - <p>If <c>ct_run</c> is called with option:</p> - <pre>-help</pre> - <p>it prints all valid start flags to stdout.</p> - </description> + <p>If flags <c>-pa</c> or <c>-pz</c> are specified in the + <c>Common Test</c> group of options (preceding <c>-erl_args</c>), + relative directories are converted to absolute and reinserted into + the code path by <c>Common Test</c>. This is to avoid problems + loading user modules when <c>Common Test</c> changes working directory + during test runs. However, <c>Common Test</c> ignores flags <c>-pa</c> + and <c>-pz</c> following <c>-erl_args</c> on the command line. These + directories are added to the code path normally (that is, on specified + form).</p> + + <p>Exit status is set before the program ends. Value <c>0</c> indicates + a successful test result, <c>1</c> indicates one or more failed or + auto-skipped test cases, and <c>2</c> indicates test execution failure.</p> + + <p>If <c>ct_run</c> is called with option <c>-help</c>, it prints all + valid start flags to <c>stdout</c>.</p> + </description> <section> <marker id="ct_run"></marker> - <title>Run tests from command line</title> + <title>Run Tests from Command Line</title> <pre> - ct_run -dir TestDir1 TestDir2 .. TestDirN | - [-dir TestDir] -suite Suite1 Suite2 .. SuiteN - [-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN] - [-step [config | keep_inactive]] - [-config ConfigFile1 ConfigFile2 .. ConfigFileN] - [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 - ConfigString2 and .. CallbackModuleN ConfigStringN] - [-decrypt_key Key] | [-decrypt_file KeyFile] - [-label Label] - [-logdir LogDir] - [-logopts LogOpts] - [-verbosity GenVLevel | [Category1 VLevel1 and - Category2 VLevel2 and .. CategoryN VLevelN]] - [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] - [-stylesheet CSSFile] - [-cover CoverCfgFile] - [-cover_stop Bool] - [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | - [-event_handler_init EvHandler1 InitArg1 and - EvHandler2 InitArg2 and .. EvHandlerN InitArgN] - [-include InclDir1 InclDir2 .. InclDirN] - [-no_auto_compile] - [-abort_if_missing_suites] - [-muliply_timetraps Multiplier] - [-scale_timetraps] - [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] - [-repeat N] | - [-duration HHMMSS [-force_stop [skip_rest]]] | - [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]] - [-basic_html] - [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and .. - CTHModuleN CTHOptsN] - [-exit_status ignore_config] - [-help] - </pre> + ct_run -dir TestDir1 TestDir2 .. TestDirN | + [-dir TestDir] -suite Suite1 Suite2 .. SuiteN + [-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN] + [-step [config | keep_inactive]] + [-config ConfigFile1 ConfigFile2 .. ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. CallbackModuleN ConfigStringN] + [-decrypt_key Key] | [-decrypt_file KeyFile] + [-label Label] + [-logdir LogDir] + [-logopts LogOpts] + [-verbosity GenVLevel | [Category1 VLevel1 and + Category2 VLevel2 and .. CategoryN VLevelN]] + [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] + [-stylesheet CSSFile] + [-cover CoverCfgFile] + [-cover_stop Bool] + [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | + [-event_handler_init EvHandler1 InitArg1 and + EvHandler2 InitArg2 and .. EvHandlerN InitArgN] + [-include InclDir1 InclDir2 .. InclDirN] + [-no_auto_compile] + [-abort_if_missing_suites] + [-muliply_timetraps Multiplier] + [-scale_timetraps] + [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] + [-repeat N] | + [-duration HHMMSS [-force_stop [skip_rest]]] | + [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]] + [-basic_html] + [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and .. + CTHModuleN CTHOptsN] + [-exit_status ignore_config] + [-help]</pre> </section> + <section> - <title>Run tests using test specification</title> + <title>Run Tests using Test Specification</title> <pre> - ct_run -spec TestSpec1 TestSpec2 .. TestSpecN - [-join_specs] - [-config ConfigFile1 ConfigFile2 .. ConfigFileN] - [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 - ConfigString2 and .. and CallbackModuleN ConfigStringN] - [-decrypt_key Key] | [-decrypt_file KeyFile] - [-label Label] - [-logdir LogDir] - [-logopts LogOpts] - [-verbosity GenVLevel | [Category1 VLevel1 and - Category2 VLevel2 and .. CategoryN VLevelN]] - [-allow_user_terms] - [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] - [-stylesheet CSSFile] - [-cover CoverCfgFile] - [-cover_stop Bool] - [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | - [-event_handler_init EvHandler1 InitArg1 and - EvHandler2 InitArg2 and .. EvHandlerN InitArgN] - [-include InclDir1 InclDir2 .. InclDirN] - [-no_auto_compile] - [-abort_if_missing_suites] - [-muliply_timetraps Multiplier] - [-scale_timetraps] - [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] - [-repeat N] | - [-duration HHMMSS [-force_stop [skip_rest]]] | - [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]] - [-basic_html] - [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and .. - CTHModuleN CTHOptsN] - [-exit_status ignore_config] - </pre> + ct_run -spec TestSpec1 TestSpec2 .. TestSpecN + [-join_specs] + [-config ConfigFile1 ConfigFile2 .. ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] + [-decrypt_key Key] | [-decrypt_file KeyFile] + [-label Label] + [-logdir LogDir] + [-logopts LogOpts] + [-verbosity GenVLevel | [Category1 VLevel1 and + Category2 VLevel2 and .. CategoryN VLevelN]] + [-allow_user_terms] + [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] + [-stylesheet CSSFile] + [-cover CoverCfgFile] + [-cover_stop Bool] + [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | + [-event_handler_init EvHandler1 InitArg1 and + EvHandler2 InitArg2 and .. EvHandlerN InitArgN] + [-include InclDir1 InclDir2 .. InclDirN] + [-no_auto_compile] + [-abort_if_missing_suites] + [-muliply_timetraps Multiplier] + [-scale_timetraps] + [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] + [-repeat N] | + [-duration HHMMSS [-force_stop [skip_rest]]] | + [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]] + [-basic_html] + [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and .. + CTHModuleN CTHOptsN] + [-exit_status ignore_config]</pre> </section> + <section> - <title>Run tests in web based GUI</title> + <title>Run Tests in Web-Based GUI</title> <pre> - ct_run -vts [-browser Browser] - [-dir TestDir1 TestDir2 .. TestDirN] | - [[dir TestDir] -suite Suite [[-group Group] [-case Case]]] - [-config ConfigFile1 ConfigFile2 .. ConfigFileN] - [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 - ConfigString2 and .. and CallbackModuleN ConfigStringN] - [-logopts LogOpts] - [-verbosity GenVLevel | [Category1 VLevel1 and - Category2 VLevel2 and .. CategoryN VLevelN]] - [-decrypt_key Key] | [-decrypt_file KeyFile] - [-include InclDir1 InclDir2 .. InclDirN] - [-no_auto_compile] - [-abort_if_missing_suites] - [-muliply_timetraps Multiplier] - [-scale_timetraps] - [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] - [-basic_html]</pre> + ct_run -vts [-browser Browser] + [-dir TestDir1 TestDir2 .. TestDirN] | + [[dir TestDir] -suite Suite [[-group Group] [-case Case]]] + [-config ConfigFile1 ConfigFile2 .. ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] + [-logopts LogOpts] + [-verbosity GenVLevel | [Category1 VLevel1 and + Category2 VLevel2 and .. CategoryN VLevelN]] + [-decrypt_key Key] | [-decrypt_file KeyFile] + [-include InclDir1 InclDir2 .. InclDirN] + [-no_auto_compile] + [-abort_if_missing_suites] + [-muliply_timetraps Multiplier] + [-scale_timetraps] + [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] + [-basic_html]</pre> </section> + <section> - <title>Refresh the HTML index files</title> + <title>Refresh HTML Index Files</title> <pre> - ct_run -refresh_logs [-logdir LogDir] [-basic_html]</pre> + ct_run -refresh_logs [-logdir LogDir] [-basic_html]</pre> </section> + <section> - <title>Run CT in interactive mode</title> + <title>Run Common Test in Interactive Mode</title> <pre> - ct_run -shell - [-config ConfigFile1 ConfigFile2 ... ConfigFileN] - [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 - ConfigString2 and .. and CallbackModuleN ConfigStringN] - [-decrypt_key Key] | [-decrypt_file KeyFile]</pre> + ct_run -shell + [-config ConfigFile1 ConfigFile2 ... ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] + [-decrypt_key Key] | [-decrypt_file KeyFile]</pre> </section> + <section> - <title>Start a Common Test Master node</title> + <title>Start a Common Test Master Node</title> <pre> - ct_run -ctmaster</pre> + ct_run -ctmaster</pre> </section> <section> - <title>See also</title> - <p>Please read the <seealso marker="run_test_chapter">Running Test Suites</seealso> - chapter in the Common Test User's Guide for information about the meaning of the - different start flags.</p> + <title>See Also</title> + <p>For information about the start flags, see section + <seealso marker="run_test_chapter">Running Tests and Analyzing + Results</seealso> in the User's Guide.</p> </section> </comref> + diff --git a/lib/common_test/doc/src/ct_slave.xml b/lib/common_test/doc/src/ct_slave.xml new file mode 100644 index 0000000000..44a7b7873f --- /dev/null +++ b/lib/common_test/doc/src/ct_slave.xml @@ -0,0 +1,221 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_slave</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_slave.xml</file> + </header> + <module>ct_slave</module> + <modulesummary>Common Test framework functions for starting and stopping + nodes for Large-Scale Testing.</modulesummary> + + <description> + + <p><c>Common Test</c> framework functions for starting and stopping nodes + for Large-Scale Testing.</p> + + <p>This module exports functions used by the <c>Common Test</c> + Master to start and stop "slave" nodes. It is the default callback + module for the <c>{init, node_start}</c> term in the Test + Specification.</p> + + </description> + + <funcs> + <func> + <name>start(Node) -> Result</name> + <fsummary>Starts an Erlang node with name Node on the local + host.</fsummary> + <type> + <v>Node = atom()</v> + <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v> + <v>Reason = already_started | started_not_connected | boot_timeout | init_timeout | startup_timeout | not_alive</v> + <v>NodeName = atom()</v> + </type> + <desc><marker id="start-1"/> + <p>Starts an Erlang node with name <c>Node</c> on the local host.</p> + + <p>See also + <seealso marker="#start-3"><c>ct_slave:start/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>start(HostOrNode, NodeOrOpts) -> Result</name> + <fsummary>Starts an Erlang node with default options on a specified + host, or on the local host with specified options.</fsummary> + <type> + <v>HostOrNode = atom()</v> + <v>NodeOrOpts = atom() | list()</v> + <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v> + <v>Reason = already_started | started_not_connected | boot_timeout | init_timeout | startup_timeout | not_alive</v> + <v>NodeName = atom()</v> + </type> + <desc><marker id="start-2"/> + <p>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 <c>start(Host, Node)</c> when the second argument is + atom-valued and <c>start(Node, Opts)</c> when it is list-valued.</p> + + <p>See also + <seealso marker="#start-3"><c>ct_slave:start/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>start(Host, Node, Opts) -> Result</name> + <fsummary>Starts an Erlang node with name Node on host Host as + specified by the combination of options in Opts.</fsummary> + <type> + <v>Node = atom()</v> + <v>Host = atom()</v> + <v>Opts = [OptTuples]</v> + <v>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}]}</v> + <v>Username = string()</v> + <v>Password = string()</v> + <v>BootTimeout = integer()</v> + <v>InitTimeout = integer()</v> + <v>StartupTimeout = integer()</v> + <v>StartupFunctions = [StartupFunctionSpec]</v> + <v>StartupFunctionSpec = {Module, Function, Arguments}</v> + <v>Module = atom()</v> + <v>Function = atom()</v> + <v>Arguments = [term]</v> + <v>Monitor = bool()</v> + <v>KillIfFail = bool()</v> + <v>ErlangFlags = string()</v> + <v>EnvVar = string()</v> + <v>Value = string()</v> + <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v> + <v>Reason = already_started | started_not_connected | boot_timeout | init_timeout | startup_timeout | not_alive</v> + <v>NodeName = atom()</v> + </type> + <desc><marker id="start-3"/> + <p>Starts an Erlang node with name <c>Node</c> on host <c>Host</c> as + specified by the combination of options in <c>Opts</c>.</p> + + <p>Options <c>Username</c> and <c>Password</c> are used to log on to the + remote host <c>Host</c>. <c>Username</c>, if omitted, defaults to + the current username. <c>Password</c> is empty by default.</p> + + <p>A list of functions specified in option <c>Startup</c> are + executed after startup of the node. Notice that all used modules + are to be present in the code path on <c>Host</c>.</p> + + <p>The time-outs are applied as follows:</p> + + <taglist> + <tag><c>BootTimeout</c></tag> + <item><p>The time to start the Erlang node, in seconds. Defaults to + 3 seconds. If the node is not pingable within this time, the result + <c>{error, boot_timeout, NodeName}</c> is returned.</p></item> + <tag><c>InitTimeout</c></tag> + <item><p>The time to wait for the node until it calls the internal + callback function informing master about a successful startup. + Defaults to 1 second. In case of a timed out message, the result + <c>{error, init_timeout, NodeName}</c> is returned.</p></item> + <tag><c>StartupTimeout</c></tag> + <item><p>The time to wait until the node stops to run + <c>StartupFunctions</c>. Defaults to 1 second. If this time-out + occurs, the result <c>{error, startup_timeout, NodeName}</c> is + returned.</p></item> + </taglist> + + <p><em>Options:</em></p> + + <taglist> + <tag><c>monitor_master</c></tag> + <item><p>Specifies if the slave node is to be stopped if the + master node stops. Defaults to <c>false</c>.</p></item> + <tag><c>kill_if_fail</c></tag> + <item><p>Specifies if the slave node is to be killed if a time-out + occurs during initialization or startup. Defaults to <c>true</c>. + Notice that the node can also be still alive it the boot time-out + occurred, but it is not killed in this case.</p></item> + <tag><c>erlang_flags</c></tag> + <item><p>Specifies which flags are added to the parameters of the + executable <c>erl</c>.</p></item> + <tag><c>env</c></tag> + <item><p>Specifies a list of environment variables that will extend + the environment.</p></item> + </taglist> + + <p><em>Special return values:</em></p> + + <list type="bulleted"> + <item><p><c>{error, already_started, NodeName}</c> if the node + with the specified name is already started on a specified + host.</p></item> + <item><p><c>{error, started_not_connected, NodeName}</c> if the + node is started, but not connected to the master node.</p></item> + <item><p><c>{error, not_alive, NodeName}</c> if the node on which + <seealso marker="#start-3"><c>ct_slave:start/3</c></seealso> is + called, is not alive. Notice that <c>NodeName</c> is the name of + the current node in this case.</p></item> + </list> + </desc> + </func> + + <func> + <name>stop(Node) -> Result</name> + <fsummary>Stops the running Erlang node with name Node on the local + host.</fsummary> + <type> + <v>Node = atom()</v> + <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v> + <v>Reason = not_started | not_connected | stop_timeout</v> + </type> + <desc><marker id="stop-1"/> + <p>Stops the running Erlang node with name <c>Node</c> on the local + host.</p> + </desc> + </func> + + <func> + <name>stop(Host, Node) -> Result</name> + <fsummary>Stops the running Erlang node with name Node on host + Host.</fsummary> + <type> + <v>Host = atom()</v> + <v>Node = atom()</v> + <v>Result = {ok, NodeName} | {error, Reason, NodeName}</v> + <v>Reason = not_started | not_connected | stop_timeout</v> + <v>NodeName = atom()</v> + </type> + <desc><marker id="stop-2"/> + <p>Stops the running Erlang node with name <c>Node</c> on host + <c>Host</c>.</p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_snmp.xml b/lib/common_test/doc/src/ct_snmp.xml new file mode 100644 index 0000000000..60f1d600e0 --- /dev/null +++ b/lib/common_test/doc/src/ct_snmp.xml @@ -0,0 +1,524 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_snmp</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_snmp.xml</file> + </header> + <module>ct_snmp</module> + <modulesummary>Common Test user interface module for the SNMP application.</modulesummary> + + <description> + + <p><c>Common Test</c> user interface module for the <c>SNMP</c> + application.</p> + + <p>The purpose of this module is to simplify SNMP configuration 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 can be passed to + <c>ct_snmp</c> by <c>Common Test</c> configuration files. For more + specialized configuration parameters, a simple SNMP configuration file + can be placed in the test suite data directory. To simplify the test + suite, <c>Common Test</c> keeps track of some of the SNMP manager + information. This way the test suite does not have to handle as many + input parameters as if it had to interface wthe OTP SNMP manager + directly.</p> + + <p><em>Configurable SNMP Manager and Agent Parameters:</em></p> + + <p>Manager configuration:</p> + + <taglist> + <tag><c>[{start_manager, boolean()}</c></tag> + <item><p>Optional. Default is <c>true</c>.</p></item> + <tag><c>{users, [{user_name(), [call_back_module(), user_data()]}]}</c></tag> + <item><p>Optional.</p></item> + <tag><c>{usm_users, [{usm_user_name(), [usm_config()]}]}</c></tag> + <item><p>Optional. SNMPv3 only.</p></item> + <tag><c>{managed_agents,[{agent_name(), [user_name(), agent_ip(), agent_port(), [agent_config()]]}]}</c></tag> + <item><p><c>managed_agents</c> is optional.</p></item> + <tag><c>{max_msg_size, integer()}</c></tag> + <item><p>Optional. Default is <c>484</c>.</p></item> + <tag><c>{mgr_port, integer()}</c></tag> + <item><p>Optional. Default is <c>5000</c>.</p></item> + <tag><c>{engine _id, string()}</c></tag> + <item><p>Optional. Default is <c>"mgrEngine"</c>.</p></item> + </taglist> + + <p>Agent configuration:</p> + + <taglist> + <tag><c>{start_agent, boolean()}</c></tag> + <item><p>Optional. Default is <c>false</c>.</p></item> + <tag><c>{agent_sysname, string()}</c></tag> + <item><p>Optional. Default is <c>"ct_test"</c>.</p></item> + <tag><c>{agent_manager_ip, manager_ip()}</c></tag> + <item><p>Optional. Default is <c>localhost</c>.</p></item> + <tag><c>{agent_vsns, list()}</c></tag> + <item><p>Optional. Default is <c>[v2]</c>.</p></item> + <tag><c>{agent_trap_udp, integer()}</c></tag> + <item><p>Optional. Default is <c>5000</c>.</p></item> + <tag><c>{agent_udp, integer()}</c></tag> + <item><p>Optional. Default is <c>4000</c>.</p></item> + <tag><c>{agent_notify_type, atom()}</c></tag> + <item><p>Optional. Default is <c>trap</c>.</p></item> + <tag><c>{agent_sec_type, sec_type()}</c></tag> + <item><p>Optional. Default is <c>none</c>.</p></item> + <tag><c>{agent_passwd, string()}</c></tag> + <item><p>Optional. Default is <c>""</c>.</p></item> + <tag><c>{agent_engine_id, string()}</c></tag> + <item><p>Optional. Default is <c>"agentEngine"</c>.</p></item> + <tag><c>{agent_max_msg_size, string()}</c></tag> + <item><p>Optional. Default is <c>484</c>.</p></item> + </taglist> + + <p>The following parameters represents the SNMP configuration files + <c>context.conf</c>, <c>standard.conf</c>, <c>community.conf</c>, + <c>vacm.conf</c>, <c>usm.conf</c>, <c>notify.conf</c>, + <c>target_addr.conf</c>, and <c>target_params.conf</c>. Notice that + all values in <c>agent.conf</c> can be modified by the parameters + listed above. All these configuration files have default values set by + the <c>SNMP</c> application. These values can be overridden by suppling + a list of valid configuration values or a file located in the test + suites data directory, which can produce a list of valid configuration + values if you apply function <c>file:consult/1</c> to the file.</p> + + <taglist> + <tag><c>{agent_contexts, [term()] | {data_dir_file, rel_path()}}</c></tag> + <item><p>Optional.</p></item> + <tag><c>{agent_community, [term()] | {data_dir_file, rel_path()}}</c></tag> + <item><p>Optional.</p></item> + <tag><c>{agent_sysinfo, [term()] | {data_dir_file, rel_path()}}</c></tag> + <item><p>Optional.</p></item> + <tag><c>{agent_vacm, [term()] | {data_dir_file, rel_path()}}</c></tag> + <item><p>Optional.</p></item> + <tag><c>{agent_usm, [term()] | {data_dir_file, rel_path()}}</c></tag> + <item><p>Optional.</p></item> + <tag><c>{agent_notify_def, [term()] | {data_dir_file, rel_path()}}</c></tag> + <item><p>Optional.</p></item> + <tag><c>{agent_target_address_def, [term()] | {data_dir_file, rel_path()}}</c></tag> + <item><p>Optional.</p></item> + <tag><c>{agent_target_param_def, [term()] | {data_dir_file, rel_path()}}</c></tag> + <item><p>Optional.</p></item> + </taglist> + + <p>Parameter <c>MgrAgentConfName</c> in the functions is to be a name + you allocate in your test suite using a <c>require</c> statement. + Example (where <c>MgrAgentConfName = snmp_mgr_agent</c>):</p> + + <pre> + suite() -> [{require, snmp_mgr_agent, snmp}].</pre> + + <p>or</p> + + <pre> + ct:require(snmp_mgr_agent, snmp).</pre> + + <p>Notice that USM users are needed for SNMPv3 configuration and are + not to be confused with users.</p> + + <p>SNMP traps, inform, and report messages are handled by the user + callback module. For details, see the + <seealso marker="snmp"><c>SNMP</c></seealso> application.</p> + + <p>It is recommended to use the <c>.hrl</c> files created by the + Erlang/OTP MIB compiler to define the Object Identifiers (OIDs). + For example, to get the Erlang node name from <c>erlNodeTable</c> + in the OTP-MIB:</p> + + <pre> + Oid = ?erlNodeEntry ++ [?erlNodeName, 1]</pre> + + <p>Furthermore, values can be set for <c>SNMP</c> application configuration + parameters, <c>config</c>, <c>server</c>, <c>net_if</c>, and so on (for + a list of valid parameters and types, see the User's Guide for + the <seealso marker="snmp"><c>SNMP</c></seealso> application). This is + done by defining a configuration data variable on the following form:</p> + + <pre> + {snmp_app, [{manager, [snmp_app_manager_params()]}, + {agent, [snmp_app_agent_params()]}]}.</pre> + + <p>A name for the data must be allocated in the suite using + <c>require</c> (see the example above). Pass this name as argument + <c>SnmpAppConfName</c> to + <seealso marker="#start-3"><c>ct_snmp:start/3</c></seealso>. + <c>ct_snmp</c> specifies default values for some <c>SNMP</c> application + configuration parameters (such as <c>{verbosity,trace}</c> for parameter + <c>config</c>). This set of defaults is merged with the parameters + specified by the user. The user values override <c>ct_snmp</c> + defaults.</p> + + </description> + + <section> + <title>Data Types</title> + <marker id="types"/> + <taglist> + <tag><c>agent_config() = {Item, Value}</c></tag> + <item><marker id="type-agent_config"/> </item> + <tag><c>agent_ip() = ip()</c></tag> + <item><marker id="type-agent_ip"/> </item> + <tag><c>agent_name() = atom()</c></tag> + <item><marker id="type-agent_name"/> </item> + <tag><c>agent_port() = integer()</c></tag> + <item><marker id="type-agent_port"/> </item> + <tag><c>call_back_module() = atom()</c></tag> + <item><marker id="type-call_back_module"/> </item> + <tag><c>error_index() = integer()</c></tag> + <item><marker id="type-error_index"/> </item> + <tag><c>error_status() = noError | atom()</c></tag> + <item><marker id="type-error_status"/> </item> + <tag><c>ip() = string() | {integer(), integer(), integer(), integer()}</c></tag> + <item><marker id="type-ip"/> </item> + <tag><c>manager_ip() = ip()</c></tag> + <item><marker id="type-manager_ip"/> </item> + <tag><c>oid() = [byte()]</c></tag> + <item><marker id="type-oid"/> </item> + <tag><c>oids() = [oid()]</c></tag> + <item><marker id="type-oids"/> </item> + <tag><c>rel_path() = string()</c></tag> + <item><marker id="type-rel_path"/> </item> + <tag><c>sec_type() = none | minimum | semi</c></tag> + <item><marker id="type-sec_type"/> </item> + <tag><c>snmp_app_agent_params() = term()</c></tag> + <item><marker id="type-snmp_app_agent_params"/> </item> + <tag><c>snmp_app_manager_params() = term()</c></tag> + <item><marker id="type-snmp_app_manager_params"/> </item> + <tag><c>snmpreply() = {error_status(), error_index(), varbinds()}</c></tag> + <item><marker id="type-snmpreply"/> </item> + <tag><c>user_data() = term()</c></tag> + <item><marker id="type-user_data"/> </item> + <tag><c>user_name() = atom()</c></tag> + <item><marker id="type-user_name"/> </item> + <tag><c>usm_config() = {Item, Value}</c></tag> + <item><marker id="type-usm_config"/> </item> + <tag><c>usm_user_name() = string()</c></tag> + <item><marker id="type-usm_user_name"/> </item> + <tag><c>value_type() = o('OBJECT IDENTIFIER') | i('INTEGER') | u('Unsigned32') | g('Unsigned32') | s('OCTET STRING')</c></tag> + <item><marker id="type-value_type"/> </item> + <tag><c>var_and_val() = {oid(), value_type(), value()}</c></tag> + <item><marker id="type-var_and_val"/> </item> + <tag><c>varbind() = term()</c></tag> + <item><marker id="type-varbind"/> </item> + <tag><c>varbinds() = [varbind()]</c></tag> + <item><marker id="type-varbinds"/> </item> + <tag><c>varsandvals() = [var_and_val()]</c></tag> + <item><marker id="type-varsandvals"/> </item> + </taglist> + <p>These data types are described in the documentation for + the <seealso marker="snmp"><c>SNMP</c></seealso> application.</p> + </section> + + <funcs> + <func> + <name>get_next_values(Agent, Oids, MgrAgentConfName) -> SnmpReply</name> + <fsummary>Issues a synchronous SNMP get next request.</fsummary> + <type> + <v>Agent = agent_name()</v> + <v>Oids = oids()</v> + <v>MgrAgentConfName = atom()</v> + <v>SnmpReply = snmpreply()</v> + </type> + <desc><marker id="get_next_values-3"/> + <p>Issues a synchronous SNMP <c>get next</c> request.</p> + </desc> + </func> + + <func> + <name>get_values(Agent, Oids, MgrAgentConfName) -> SnmpReply</name> + <fsummary>Issues a synchronous SNMP get request.</fsummary> + <type> + <v>Agent = agent_name()</v> + <v>Oids = oids()</v> + <v>MgrAgentConfName = atom()</v> + <v>SnmpReply = snmpreply()</v> + </type> + <desc><marker id="get_values-3"/> + <p>Issues a synchronous SNMP <c>get</c> request.</p> + </desc> + </func> + + <func> + <name>load_mibs(Mibs) -> ok | {error, Reason}</name> + <fsummary>Loads the MIBs into agent snmp_master_agent.</fsummary> + <type> + <v>Mibs = [MibName]</v> + <v>MibName = string()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="load_mibs-1"/> + <p>Loads the MIBs into agent <c>snmp_master_agent</c>.</p> + </desc> + </func> + + <func> + <name>register_agents(MgrAgentConfName, ManagedAgents) -> ok | {error, Reason}</name> + <fsummary>Explicitly instructs the manager to handle this + agent.</fsummary> + <type> + <v>MgrAgentConfName = atom()</v> + <v>ManagedAgents = [agent()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="register_agents-2"/> + <p>Explicitly instructs the manager to handle this agent. Corresponds + to making an entry in <c>agents.conf</c>.</p> + + <p>This function tries to register the specified managed agents, without + checking if any of them exist. To change a registered managed agent, + the agent must first be unregistered.</p> + </desc> + </func> + + <func> + <name>register_users(MgrAgentConfName, Users) -> ok | {error, Reason}</name> + <fsummary>Registers the manager entity (=user) responsible for specific + agent(s).</fsummary> + <type> + <v>MgrAgentConfName = atom()</v> + <v>Users = [user()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="register_users-2"/> + <p>Registers the manager entity (=user) responsible for specific + agent(s). Corresponds to making an entry in <c>users.conf</c>.</p> + + <p>This function tries to register the specified users, without checking + if any of them exist. To change a registered user, the user must + first be unregistered.</p> + </desc> + </func> + + <func> + <name>register_usm_users(MgrAgentConfName, UsmUsers) -> ok | {error, Reason}</name> + <fsummary>Explicitly instructs the manager to handle this USM user.</fsummary> + <type> + <v>MgrAgentConfName = atom()</v> + <v>UsmUsers = [usm_user()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="register_usm_users-2"/> + <p>Explicitly instructs the manager to handle this USM user. + Corresponds to making an entry in <c>usm.conf</c>.</p> + + <p>This function tries to register the specified users, without checking + if any of them exist. To change a registered user, the user must + first be unregistered.</p> + </desc> + </func> + + <func> + <name>set_info(Config) -> [{Agent, OldVarsAndVals, NewVarsAndVals}]</name> + <fsummary>Returns a list of all successful set requests performed in the + test case in reverse order.</fsummary> + <type> + <v>Config = [{Key, Value}]</v> + <v>Agent = agent_name()</v> + <v>OldVarsAndVals = varsandvals()</v> + <v>NewVarsAndVals = varsandvals()</v> + </type> + <desc><marker id="set_info-1"/> + <p>Returns a list of all successful <c>set</c> requests performed in + the test case in reverse order. The list contains the involved user + and agent, the value before <c>set</c>, and the new value. This is + intended to simplify the cleanup in function <c>end_per_testcase</c>, + that is, the undoing of the <c>set</c> requests and their possible + side-effects.</p> + </desc> + </func> + + <func> + <name>set_values(Agent, VarsAndVals, MgrAgentConfName, Config) -> SnmpReply</name> + <fsummary>Issues a synchronous SNMP set request.</fsummary> + <type> + <v>Agent = agent_name()</v> + <v>Oids = oids()</v> + <v>MgrAgentConfName = atom()</v> + <v>Config = [{Key, Value}]</v> + <v>SnmpReply = snmpreply()</v> + </type> + <desc><marker id="set_values-4"/> + <p>Issues a synchronous SNMP <c>set</c> request.</p> + </desc> + </func> + + <func> + <name>start(Config, MgrAgentConfName) -> ok</name> + <fsummary>Equivalent to start(Config, MgrAgentConfName, + undefined).</fsummary> + <desc><marker id="start-2"/> + <p>Equivalent to + <seealso marker="#start-3"><c>ct_snmp:start(Config, MgrAgentConfName, + undefined)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>start(Config, MgrAgentConfName, SnmpAppConfName) -> ok</name> + <fsummary>Starts an SNMP manager and/or agent.</fsummary> + <type> + <v>Config = [{Key, Value}]</v> + <v>Key = atom()</v> + <v>Value = term()</v> + <v>MgrAgentConfName = atom()</v> + <v>SnmpConfName = atom()</v> + </type> + <desc><marker id="start-3"/> + <p>Starts an SNMP manager and/or agent. In the manager case, + registrations of users and agents, as specified by the configuration + <c>MgrAgentConfName</c>, are performed. When using SNMPv3, called + USM users are also registered. Users, <c>usm_users</c>, and + managed agents can also be registered later using + <seealso marker="#register_users-2"><c>ct_snmp:register_users/2</c></seealso>, + <seealso marker="#register_agents-2"><c>ct_snmp:register_agents/2</c></seealso>, + and + <seealso marker="#register_usm_users-2"><c>ct_snmp:register_usm_users/2</c></seealso>.</p> + + <p>The agent started is called <c>snmp_master_agent</c>. Use + <seealso marker="#load_mibs-1"><c>ct_snmp:load_mibs/1</c></seealso> + to load MIBs into the agent.</p> + + <p>With <c>SnmpAppConfName</c> SNMP applications can be configured + with parameters <c>config</c>, <c>mibs</c>, <c>net_if</c>, and so on. + The values are merged with (and possibly override) default values + set by <c>ct_snmp</c>.</p> + </desc> + </func> + + <func> + <name>stop(Config) -> ok</name> + <fsummary>Stops the SNMP manager and/or agent, and removes all files + created.</fsummary> + <type> + <v>Config = [{Key, Value}]</v> + <v>Key = atom()</v> + <v>Value = term()</v> + </type> + <desc><marker id="stop-1"/> + <p>Stops the SNMP manager and/or agent, and removes all files + created.</p> + </desc> + </func> + + <func> + <name>unload_mibs(Mibs) -> ok | {error, Reason}</name> + <fsummary>Unloads the MIBs from agent snmp_master_agent.</fsummary> + <type> + <v>Mibs = [MibName]</v> + <v>MibName = string()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="unload_mibs-1"/> + <p>Unloads the MIBs from agent <c>snmp_master_agent</c>.</p> + </desc> + </func> + + <func> + <name>unregister_agents(MgrAgentConfName) -> ok</name> + <fsummary>Unregisters all managed agents.</fsummary> + <type> + <v>MgrAgentConfName = atom()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="unregister_agents-1"/> + <p>Unregisters all managed agents.</p> + </desc> + </func> + + <func> + <name>unregister_agents(MgrAgentConfName, ManagedAgents) -> ok</name> + <fsummary>Unregisters the specified managed agents.</fsummary> + <type> + <v>MgrAgentConfName = atom()</v> + <v>ManagedAgents = [agent_name()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="unregister_agents-2"/> + <p>Unregisters the specified managed agents.</p> + </desc> + </func> + + <func> + <name>unregister_users(MgrAgentConfName) -> ok</name> + <fsummary>Unregisters all users.</fsummary> + <type> + <v>MgrAgentConfName = atom()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="unregister_users-1"/> + <p>Unregisters all users.</p> + </desc> + </func> + + <func> + <name>unregister_users(MgrAgentConfName, Users) -> ok</name> + <fsummary>Unregisters the specified users.</fsummary> + <type> + <v>MgrAgentConfName = atom()</v> + <v>Users = [user_name()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="unregister_users-2"/> + <p>Unregisters the specified users.</p> + </desc> + </func> + + <func> + <name>unregister_usm_users(MgrAgentConfName) -> ok</name> + <fsummary>Unregisters all USM users.</fsummary> + <type> + <v>MgrAgentConfName = atom()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="unregister_usm_users-1"/> + <p>Unregisters all USM users.</p> + </desc> + </func> + + <func> + <name>unregister_usm_users(MgrAgentConfName, UsmUsers) -> ok</name> + <fsummary>Unregisters the specified USM users.</fsummary> + <type> + <v>MgrAgentConfName = atom()</v> + <v>UsmUsers = [usm_user_name()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="unregister_usm_users-2"/> + <p>Unregisters the specified USM users.</p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_ssh.xml b/lib/common_test/doc/src/ct_ssh.xml new file mode 100644 index 0000000000..897fd509d3 --- /dev/null +++ b/lib/common_test/doc/src/ct_ssh.xml @@ -0,0 +1,1150 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_ssh</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_ssh.xml</file> + </header> + <module>ct_ssh</module> + <modulesummary>SSH/SFTP client module.</modulesummary> + +<description> + + <p>SSH/SFTP client module.</p> + + <p>This module uses application <c>SSH</c>, which provides detailed + information about, for example, functions, types, and options.</p> + + <p>Argument <c>Server</c> in the SFTP functions is only to be used for + SFTP sessions that have been started on existing SSH connections + (that is, when the original connection type is <c>ssh</c>). Whenever + the connection type is <c>sftp</c>, use the SSH connection reference + only.</p> + + <p>The following options are valid for specifying an SSH/SFTP + connection (that is, can be used as configuration elements):</p> + + <pre> + [{ConnType, Addr}, + {port, Port}, + {user, UserName} + {password, Pwd} + {user_dir, String} + {public_key_alg, PubKeyAlg} + {connect_timeout, Timeout} + {key_cb, KeyCallbackMod}]</pre> + + <p><c>ConnType = ssh | sftp</c>.</p> + + <p>For other types, see + <seealso marker="ssh:ssh"><c>ssh:ssh(3)</c></seealso>.</p> + + <p>All time-out parameters in <c>ct_ssh</c> functions are values in + milliseconds.</p> + + </description> + + <section> + <title>Data Types</title> + <marker id="types"/> + <taglist> + <tag><c>connection() = handle() | target_name()</c></tag> + <item><marker id="type-connection"/> + <p>For <c>target_name</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p></item> + + <tag><c>handle() = handle()</c></tag> + <item><marker id="type-handle"/> + <p>Handle for a specific SSH/SFTP connection, see module + <seealso marker="ct"><c>ct</c></seealso>.</p></item> + + <tag><c>ssh_sftp_return() = term()</c></tag> + <item><marker id="type-ssh_sftp_return"/> + <p>Return value from an + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp</c></seealso> + function.</p></item> + </taglist> + </section> + + <funcs> + <func> + <name>apread(SSH, Handle, Position, Length) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="apread-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>apread(SSH, Server, Handle, Position, Length) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="apread-5"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>apwrite(SSH, Handle, Position, Data) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="apwrite-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>apwrite(SSH, Server, Handle, Position, Data) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="apwrite-5"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>aread(SSH, Handle, Len) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="aread-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>aread(SSH, Server, Handle, Len) -> Result</name> + <fsummary>For inforamtion and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="aread-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>awrite(SSH, Handle, Data) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="awrite-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>awrite(SSH, Server, Handle, Data) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="awrite-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>close(SSH, Handle) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="close-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>close(SSH, Server, Handle) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="close-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>connect(KeyOrName) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Equivalent to connect(KeyOrName, host, []).</fsummary> + <desc><marker id="connect-1"/> + <p>Equivalent to + <seealso marker="#connect-3"><c>ct_ssh:connect(KeyOrName, host, + [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>connect(KeyOrName, ConnType) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Equivalent to connect(KeyOrName, ConnType, []).</fsummary> + <desc><marker id="connect-2"/> + <p>Equivalent to + <seealso marker="#connect-3"><c>ct_ssh:connect(KeyOrName, ConnType, + [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>connect(KeyOrName, ConnType, ExtraOpts) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Opens an SSH or SFTP connection using the information + associated with KeyOrName.</fsummary> + <type> + <v>KeyOrName = Key | Name</v> + <v>Key = atom()</v> + <v>Name = target_name()</v> + <v>ConnType = ssh | sftp | host</v> + <v>ExtraOpts = ssh_connect_options()</v> + <v>Handle = handle()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="connect-3"/> + <p>Opens an SSH or SFTP connection using the information associated + with <c>KeyOrName</c>.</p> + + <p>If <c>Name</c> (an alias name for <c>Key</c>) is used to identify + the connection, this name can be used as connection reference for + subsequent calls. Only one open connection at a time associated + with <c>Name</c> is possible. If <c>Key</c> is used, the returned + handle must be used for subsequent calls (multiple connections can + be opened using the configuration data specified by <c>Key</c>).</p> + + <p>For information on how to create a new <c>Name</c>, see + <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p> + + <p>For <c>target_name</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p> + + <p><c>ConnType</c> always overrides the type specified in the + address tuple in the configuration data (and in <c>ExtraOpts</c>). + So it is possible to, for example, open an SFTP connection + directly using data originally specifying an SSH connection. Value + <c>host</c> means that the connection type specified by the host + option (either in the configuration data or in <c>ExtraOpts</c>) + is used.</p> + + <p><c>ExtraOpts</c> (optional) are extra SSH options to be added to + the configuration data for <c>KeyOrName</c>. The extra options + override any existing options with the same key in the + configuration data. For details on valid SSH options, see + application <seealso marker="ssh"><c>SSH</c></seealso>.</p> + </desc> + </func> + + <func> + <name>del_dir(SSH, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="del_dir-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>del_dir(SSH, Server, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="del_dir-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>delete(SSH, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="delete-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>delete(SSH, Server, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="delete-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>disconnect(SSH) -> ok | {error, Reason}</name> + <fsummary>Closes an SSH/SFTP connection.</fsummary> + <type> + <v>SSH = connection()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="disconnect-1"/> + <p>Closes an SSH/SFTP connection.</p> + </desc> + </func> + + <func> + <name>exec(SSH, Command) -> {ok, Data} | {error, Reason}</name> + <fsummary>Equivalent to exec(SSH, Command, DefaultTimeout).</fsummary> + <desc><marker id="exec-2"/> + <p>Equivalent to + <seealso marker="#exec-3"><c>ct_ssh:exec(SSH, Command, + DefaultTimeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>exec(SSH, Command, Timeout) -> {ok, Data} | {error, Reason}</name> + <fsummary>Requests server to perform Command.</fsummary> + <type> + <v>SSH = connection()</v> + <v>Command = string()</v> + <v>Timeout = integer()</v> + <v>Data = list()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="exec-3"/> + <p>Requests server to perform <c>Command</c>. A session channel is + opened automatically for the request. <c>Data</c> is received from + the server as a result of the command.</p> + </desc> + </func> + + <func> + <name>exec(SSH, ChannelId, Command, Timeout) -> {ok, Data} | {error, Reason}</name> + <fsummary>Requests server to perform Command.</fsummary> + <type> + <v>SSH = connection()</v> + <v>ChannelId = integer()</v> + <v>Command = string()</v> + <v>Timeout = integer()</v> + <v>Data = list()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="exec-4"/> + <p>Requests server to perform <c>Command</c>. A previously opened + session channel is used for the request. <c>Data</c> is received + from the server as a result of the command.</p> + </desc> + </func> + + <func> + <name>get_file_info(SSH, Handle) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="get_file_info-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get_file_info(SSH, Server, Handle) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="get_file_info-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>list_dir(SSH, Path) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="list_dir-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>list_dir(SSH, Server, Path) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="list_dir-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>make_dir(SSH, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="make_dir-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>make_dir(SSH, Server, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="make_dir-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>make_symlink(SSH, Name, Target) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="make_symlink-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>make_symlink(SSH, Server, Name, Target) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="make_symlink-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>open(SSH, File, Mode) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="open-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>open(SSH, Server, File, Mode) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="open-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>opendir(SSH, Path) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="opendir-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>opendir(SSH, Server, Path) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="opendir-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>position(SSH, Handle, Location) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="position-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>position(SSH, Server, Handle, Location) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="position-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>pread(SSH, Handle, Position, Length) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="pread-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>pread(SSH, Server, Handle, Position, Length) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="pread-5"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>pwrite(SSH, Handle, Position, Data) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="pwrite-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>pwrite(SSH, Server, Handle, Position, Data) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="pwrite-5"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read(SSH, Handle, Len) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read(SSH, Server, Handle, Len) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read_file(SSH, File) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read_file-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read_file(SSH, Server, File) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read_file-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read_file_info(SSH, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read_file_info-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read_file_info(SSH, Server, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read_file_info-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read_link(SSH, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read_link-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read_link(SSH, Server, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read_link-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read_link_info(SSH, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read_link_info-2"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>read_link_info(SSH, Server, Name) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="read_link_info-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>receive_response(SSH, ChannelId) -> {ok, Data} | {error, Reason}</name> + <fsummary>Equivalent to receive_response(SSH, ChannelId, + close).</fsummary> + <desc><marker id="receive_response-2"/> + <p>Equivalent to + <seealso marker="#receive_response-3"><c>ct_ssh:receive_response(SSH, +ChannelId, close)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>receive_response(SSH, ChannelId, End) -> {ok, Data} | {error, Reason}</name> + <fsummary>Equivalent to receive_response(SSH, ChannelId, End, + DefaultTimeout).</fsummary> + <desc><marker id="receive_response-3"/> + <p>Equivalent to + <seealso marker="#receive_response-4"><c>ct_ssh:receive_response(SSH, +ChannelId, End, DefaultTimeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>receive_response(SSH, ChannelId, End, Timeout) -> {ok, Data} | {timeout, Data} | {error, Reason}</name> + <fsummary>Receives expected data from server on the specified session + channel.</fsummary> + <type> + <v>SSH = connection()</v> + <v>ChannelId = integer()</v> + <v>End = Fun | close | timeout</v> + <v>Timeout = integer()</v> + <v>Data = list()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="receive_response-4"/> + <p>Receives expected data from server on the specified session + channel.</p> + + <p>If <c>End == close</c>, data is returned to the caller when the + channel is closed by the server. If a time-out occurs before this + happens, the function returns <c>{timeout,Data}</c> (where + <c>Data</c> is the data received so far).</p> + <p>If <c>End == timeout</c>, a time-out is expected and + <c>{ok,Data}</c> is returned both in the case of a time-out and + when the channel is closed.</p> + + <p>If <c>End</c> is a fun, this fun is called with one argument, the + data value in a received <c>ssh_cm</c> message (see + <seealso marker="ssh:ssh_connection"><c>ssh:ssh_connection(3)</c></seealso>. + The fun is to return either <c>true</c> to end the receiving + operation (and have the so far collected data returned) or + <c>false</c> to wait for more data from the server. Even if a fun + is supplied, the function returns immediately if the server closes + the channel).</p> + </desc> + </func> + + <func> + <name>rename(SSH, OldName, NewName) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="rename-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>rename(SSH, Server, OldName, NewName) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="rename-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send(SSH, ChannelId, Data) -> ok | {error, Reason}</name> + <fsummary>Equivalent to send(SSH, ChannelId, 0, Data, + DefaultTimeout).</fsummary> + <desc><marker id="send-3"/> + <p>Equivalent to <seealso marker="#send-5"><c>ct_ssh:send(SSH, + ChannelId, 0, Data, DefaultTimeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send(SSH, ChannelId, Data, Timeout) -> ok | {error, Reason}</name> + <fsummary>Equivalent to send(SSH, ChannelId, 0, Data, Timeout).</fsummary> + <desc><marker id="send-4"/> + <p>Equivalent to <seealso marker="#send-5"><c>ct_ssh:send(SSH, + ChannelId, 0, Data, Timeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send(SSH, ChannelId, Type, Data, Timeout) -> ok | {error, Reason}</name> + <fsummary>Sends data to server on specified session channel.</fsummary> + <type> + <v>SSH = connection()</v> + <v>ChannelId = integer()</v> + <v>Type = integer()</v> + <v>Data = list()</v> + <v>Timeout = integer()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="send-5"/> + <p>Sends data to server on specified session channel.</p> + </desc> + </func> + + <func> + <name>send_and_receive(SSH, ChannelId, Data) -> {ok, Data} | {error, Reason}</name> + <fsummary>Equivalent to send_and_receive(SSH, ChannelId, Data, + close).</fsummary> + <desc><marker id="send_and_receive-3"/> + <p>Equivalent to + <seealso marker="#send_and_receive-4"><c>ct_ssh:send_and_receive(SSH, + ChannelId, Data, close)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send_and_receive(SSH, ChannelId, Data, End) -> {ok, Data} | {error, Reason}</name> + <fsummary>Equivalent to send_and_receive(SSH, ChannelId, 0, Data, End, + DefaultTimeout).</fsummary> + <desc><marker id="send_and_receive-4"/> + <p>Equivalent to + <seealso marker="#send_and_receive-6"><c>ct_ssh;send_and_receive(SSH, +ChannelId, 0, Data, End, DefaultTimeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send_and_receive(SSH, ChannelId, Data, End, Timeout) -> {ok, Data} | {error, Reason}</name> + <fsummary>Equivalent to send_and_receive(SSH, ChannelId, 0, Data, End, + Timeout).</fsummary> + <desc><marker id="send_and_receive-5"/> + <p>Equivalent to + <seealso marker="#send_and_receive-6"><c>ct_ssh:send_and_receive(SSH, +ChannelId, 0, Data, End, Timeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send_and_receive(SSH, ChannelId, Type, Data, End, Timeout) -> {ok, Data} | {error, Reason}</name> + <fsummary>Sends data to server on specified session channel and waits + to receive the server response.</fsummary> + <type> + <v>SSH = connection()</v> + <v>ChannelId = integer()</v> + <v>Type = integer()</v> + <v>Data = list()</v> + <v>End = Fun | close | timeout</v> + <v>Timeout = integer()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="send_and_receive-6"/> + <p>Sends data to server on specified session channel and waits to + receive the server response.</p> + + <p>For details on argument <c>End</c>, see + <seealso marker="receive_response-4"><c>ct_ssh:receive_response/4</c></seealso>.</p> + </desc> + </func> + + <func> + <name>session_close(SSH, ChannelId) -> ok | {error, Reason}</name> + <fsummary>Closes an SSH session channel.</fsummary> + <type> + <v>SSH = connection()</v> + <v>ChannelId = integer()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="session_close-2"/> + <p>Closes an SSH session channel.</p> + </desc> + </func> + + <func> + <name>session_open(SSH) -> {ok, ChannelId} | {error, Reason}</name> + <fsummary>Equivalent to session_open(SSH, DefaultTimeout).</fsummary> + <desc><marker id="session_open-1"/> + <p>Equivalent to + <seealso marker="#session_open-2"><c>ct_ssh:session_open(SSH, + DefaultTimeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>session_open(SSH, Timeout) -> {ok, ChannelId} | {error, Reason}</name> + <fsummary>Opens a channel for an SSH session.</fsummary> + <type> + <v>SSH = connection()</v> + <v>Timeout = integer()</v> + <v>ChannelId = integer()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="session_open-2"/> + <p>Opens a channel for an SSH session.</p> + </desc> + </func> + + <func> + <name>sftp_connect(SSH) -> {ok, Server} | {error, Reason}</name> + <fsummary>Starts an SFTP session on an already existing SSH + connection.</fsummary> + <type> + <v>SSH = connection()</v> + <v>Server = pid()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="sftp_connect-1"/> + <p>Starts an SFTP session on an already existing SSH connection. + <c>Server</c> identifies the new session and must be specified + whenever SFTP requests are to be sent.</p> + </desc> + </func> + + <func> + <name>subsystem(SSH, ChannelId, Subsystem) -> Status | {error, Reason}</name> + <fsummary>Equivalent to subsystem(SSH, ChannelId, Subsystem, + DefaultTimeout).</fsummary> + <desc><marker id="subsystem-3"/> + <p>Equivalent to + <seealso marker="#subsystem-4"><c>ct_ssh:subsystem(SSH, ChannelId, + Subsystem, DefaultTimeout)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>subsystem(SSH, ChannelId, Subsystem, Timeout) -> Status | {error, Reason}</name> + <fsummary>Sends a request to execute a predefined subsystem.</fsummary> + <type> + <v>SSH = connection()</v> + <v>ChannelId = integer()</v> + <v>Subsystem = string()</v> + <v>Timeout = integer()</v> + <v>Status = success | failure</v> + <v>Reason = term()</v> + </type> + <desc><marker id="subsystem-4"/> + <p>Sends a request to execute a predefined subsystem.</p> + </desc> + </func> + + <func> + <name>write(SSH, Handle, Data) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="write-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>write(SSH, Server, Handle, Data) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="write-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>write_file(SSH, File, Iolist) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="write_file-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>write_file(SSH, Server, File, Iolist) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="write_file-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>write_file_info(SSH, Name, Info) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="write_file_info-3"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>write_file_info(SSH, Server, Name, Info) -> Result</name> + <fsummary>For information and other types, see ssh_sftp(3).</fsummary> + <type> + <v>SSH = connection()</v> + <v>Result = ssh_sftp_return() | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="write_file_info-4"/> + <p>For information and other types, see + <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p> + </desc> + </func> + </funcs> + +</erlref> + + diff --git a/lib/common_test/doc/src/ct_telnet.xml b/lib/common_test/doc/src/ct_telnet.xml new file mode 100644 index 0000000000..6f7fc13055 --- /dev/null +++ b/lib/common_test/doc/src/ct_telnet.xml @@ -0,0 +1,601 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>ct_telnet</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>ct_telnet.xml</file> + </header> + <module>ct_telnet</module> + <modulesummary>Common Test specific layer on top of Telnet client ct_telnet_client.erl</modulesummary> + + <description> + + <p><c>Common Test</c> specific layer on top of Telnet client + <c>ct_telnet_client.erl</c>.</p> + + <p>Use this module to set up Telnet connections, send commands, and + perform string matching on the result. For information about how to use + <c>ct_telnet</c> and configure connections, specifically for UNIX hosts, + see the + <seealso marker="unix_telnet"><c>unix_telnet</c></seealso> manual page. + </p> + + <p>Default values defined in <c>ct_telnet</c>:</p> + <marker id="Default_values"/> + + <list type="bulleted"> + <item><p>Connection timeout (time to wait for connection) = 10 + seconds</p></item> + <item><p>Command timeout (time to wait for a command to return) = + 10 seconds</p></item> + <item><p>Max number of reconnection attempts = 3</p></item> + <item><p>Reconnection interval (time to wait in between + reconnection attempts) = 5 seconds</p></item> + <item><p>Keep alive (sends NOP to the server every 8 sec if + connection is idle) = <c>true</c></p></item> + <item><p>Polling limit (max number of times to poll to get a + remaining string terminated) = 0</p></item> + <item><p>Polling interval (sleep time between polls) = 1 second</p> + </item> + </list> + + <p>These parameters can be modified by the user with the following + configuration term:</p> + + <pre> + {telnet_settings, [{connect_timeout,Millisec}, + {command_timeout,Millisec}, + {reconnection_attempts,N}, + {reconnection_interval,Millisec}, + {keep_alive,Bool}, + {poll_limit,N}, + {poll_interval,Millisec}]}.</pre> + + <p><c>Millisec = integer(), N = integer()</c></p> + + <p>Enter the <c>telnet_settings</c> term in a configuration file included + in the test and <c>ct_telnet</c> retrieves the information + automatically.</p> + + <p><c>keep_alive</c> can be specified per connection, if necessary. For + details, see + <seealso marker="unix_telnet"><c>unix_telnet</c></seealso>.</p> + + </description> + + <section> + <title>Logging</title> + <marker id="Logging"/> + + <p>The default logging behavior of <c>ct_telnet</c> is to print information + about performed operations, commands, and their corresponding results to + the test case HTML log. The following is not printed to the HTML + log: text strings sent from the Telnet server that are not explicitly + received by a <c>ct_telnet</c> function, such as <c>expect/3</c>. + However, <c>ct_telnet</c> can be configured to use a special purpose + event handler, implemented in <c>ct_conn_log_h</c>, for logging + <em>all</em> Telnet traffic. To use this handler, install a <c>Common + Test</c> hook named <c>cth_conn_log</c>. Example (using the test suite + information function):</p> + + <pre> + suite() -> + [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].</pre> + + <p><c>conn_mod()</c> is the name of the <c>Common Test</c> module + implementing the connection protocol, that is, <c>ct_telnet</c>.</p> + + <p>The <c>cth_conn_log</c> hook performs unformatted logging of Telnet + data to a separate text file. All Telnet communication is captured and + printed, including any data sent from the server. The link to + this text file is located at the top of the test case HTML log.</p> + + <p>By default, data for all Telnet connections is logged in one common + file (named <c>default</c>), which can get messy, for example, if + multiple Telnet sessions are running in parallel. Therefore a separate + log file can be created for each connection. To configure this, use hook + option <c>hosts</c> and list the names of the servers/connections + to be used in the suite. The connections must be named for this to + work (see + <seealso marker="#open-1"><c>ct_telnet:open/1,2,3,4</c></seealso>.</p> + + <p>Hook option <c>log_type</c> can be used to change the + <c>cth_conn_log</c> behavior. The default value of this option is + <c>raw</c>, which results in the behavior described above. If the value + is set to <c>html</c>, all Telnet communication is printed to the test + case HTML log instead.</p> + + <p>All <c>cth_conn_log</c> hook options described can also be + specified in a configuration file with configuration variable + <c>ct_conn_log</c>.</p> + + <p><em>Example:</em></p> + + <pre> + {ct_conn_log, [{ct_telnet,[{log_type,raw}, + {hosts,[key_or_name()]}]}]}</pre> + + <note> + <p>Hook options specified in a configuration file overwrite any + hard-coded hook options in the test suite.</p> + </note> + + <marker id="Logging_example"/> + <p><em>Logging Example:</em></p> + + <p>The following <c>ct_hooks</c> statement causes printing of Telnet + traffic to separate logs for the connections <c>server1</c> and + <c>server2</c>. Traffic for any other connections is logged in the + default Telnet log.</p> + + <pre> + suite() -> + [{ct_hooks, + [{cth_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}]}].</pre> + + <p>As previously explained, this specification can also be provided by an + entry like the following in a configuration file:</p> + + <pre> + {ct_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}.</pre> + + <p>In this case the <c>ct_hooks</c> statement in the test suite can look + as follows:</p> + + <pre> + suite() -> + [{ct_hooks, [{cth_conn_log, []}]}].</pre> + </section> + + <section> + <title>Data Types</title> + <marker id="types"/> + <taglist> + <tag><c>connection() = handle() | {target_name(), connection_type()} | target_name()</c></tag> + <item><marker id="type-connection"/> + <p>For <c>target_name()</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p></item> + + <tag><c>connection_type() = telnet | ts1 | ts2</c></tag> + <item><marker id="type-connection_type"/> </item> + + <tag><c>handle() = handle()</c></tag> + <item><marker id="type-handle"/> + <p>Handle for a specific Telnet connection, see module + <seealso marker="ct"><c>ct</c></seealso>.</p></item> + + <tag><c>prompt_regexp() = string()</c></tag> + <item><marker id="type-prompt_regexp"/> + <p>Regular expression matching all possible prompts for a specific + target type. <c>regexp</c> must not have any groups, that is, when + matching, <c>re:run/3</c> (in <c>STDLIB</c>) must return a list with + one single element.</p></item> + </taglist> + </section> + + <funcs> + <func> + <name>close(Connection) -> ok | {error, Reason}</name> + <fsummary>Closes the Telnet connection and stops the process managing + it.</fsummary> + <type> + <v>Connection = connection()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="close-1"/> + <p>Closes the Telnet connection and stops the process managing it.</p> + + <p>A connection can be associated with a target name and/or a handle. + If <c>Connection</c> has no associated target name, it can only + be closed with the handle value (see + <seealso marker="#open-4"><c>ct_telnet:open/4</c></seealso>.</p> + </desc> + </func> + + <func> + <name>cmd(Connection, Cmd) -> {ok, Data} | {error, Reason}</name> + <fsummary>Equivalent to cmd(Connection, Cmd, []).</fsummary> + <desc><marker id="cmd-2"/> + <p>Equivalent to + <seealso marker="#cmd-3"><c>ct_telnet:cmd(Connection, Cmd, + [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>cmd(Connection, Cmd, Opts) -> {ok, Data} | {error, Reason}</name> + <fsummary>Sends a command through Telnet and waits for prompt.</fsummary> + <type> + <v>Connection = connection()</v> + <v>Cmd = string()</v> + <v>Opts = [Opt]</v> + <v>Opt = {timeout, timeout()} | {newline, boolean()}</v> + <v>Data = [string()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="cmd-3"/> + <p>Sends a command through Telnet and waits for prompt.</p> + + <p>By default, this function adds a new line to the end of the + specified command. If this is not desired, use option + <c>{newline,false}</c>. This is necessary, for example, when + sending Telnet command sequences prefixed with character + Interprete As Command (IAC).</p> + + <p>Option <c>timeout</c> specifies how long the client must wait + for prompt. If the time expires, the function returns + <c>{error,timeout}</c>. For information about the default value + for the command timeout, see the + <seealso marker="#Default_values">list of default values</seealso> + in the beginning of this module.</p> + </desc> + </func> + + <func> + <name>cmdf(Connection, CmdFormat, Args) -> {ok, Data} | {error, Reason}</name> + <fsummary>Equivalent to cmdf(Connection, CmdFormat, Args, []).</fsummary> + <desc><marker id="cmdf-3"/> + <p>Equivalent to + <seealso marker="#cmdf-4"><c>ct_telnet:cmdf(Connection, CmdFormat, + Args, [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>cmdf(Connection, CmdFormat, Args, Opts) -> {ok, Data} | {error, Reason}</name> + <fsummary>Sends a Telnet command and waits for prompt (uses a format + string and a list of arguments to build the command).</fsummary> + <type> + <v>Connection = connection()</v> + <v>CmdFormat = string()</v> + <v>Args = list()</v> + <v>Opts = [Opt]</v> + <v>Opt = {timeout, timeout()} | {newline, boolean()}</v> + <v>Data = [string()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="cmdf-4"/> + <p>Sends a Telnet command and waits for prompt (uses a format string + and a list of arguments to build the command).</p> + + <p>For details, see + <seealso marker="#cmd-3"><c>ct_telnet:cmd/3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>expect(Connection, Patterns) -> term()</name> + <fsummary>Equivalent to expect(Connections, Patterns, []).</fsummary> + <desc><marker id="expect-2"/> + <p>Equivalent to + <seealso marker="#expect-3"><c>ct_telnet:expect(Connections, + Patterns, [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>expect(Connection, Patterns, Opts) -> {ok, Match} | {ok, MatchList, HaltReason} | {error, Reason}</name> + <fsummary>Gets data from Telnet and waits for the expected + pattern.</fsummary> + <type> + <v>Connection = connection()</v> + <v>Patterns = Pattern | [Pattern]</v> + <v>Pattern = string() | {Tag, string()} | prompt | {prompt, Prompt}</v> + <v>Prompt = string()</v> + <v>Tag = term()</v> + <v>Opts = [Opt]</v> + <v>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}</v> + <v>IdleTimeout = infinity | integer()</v> + <v>TotalTimeout = infinity | integer()</v> + <v>N = integer()</v> + <v>HaltPatterns = Patterns</v> + <v>MatchList = [Match]</v> + <v>Match = RxMatch | {Tag, RxMatch} | {prompt, Prompt}</v> + <v>RxMatch = [string()]</v> + <v>HaltReason = done | Match</v> + <v>Reason = timeout | {prompt, Prompt}</v> + </type> + <desc><marker id="expect-3"/> + <p>Gets data from Telnet and waits for the expected pattern.</p> + + <p><c>Pattern</c> can be a POSIX regular expression. The function + returns when a pattern is successfully matched (at least one, in + the case of multiple patterns).</p> + + <p><c>RxMatch</c> is a list of matched strings. It looks as + follows <c>[FullMatch, SubMatch1, SubMatch2, ...]</c>, where + <c>FullMatch</c> is the string matched by the whole regular + expression, and <c>SubMatchN</c> is the string that matched + subexpression number <c>N</c>. Subexpressions are denoted with + <c>(' ')</c> in the regular expression.</p> + + <p>If a <c>Tag</c> is speciifed, the returned <c>Match</c> also + includes the matched <c>Tag</c>. Otherwise, only <c>RxMatch</c> + is returned.</p> + + <p><em>Options:</em></p> + + <taglist> + <tag><c>idle_timeout</c></tag> + <item><p>Indicates that the function must return if the Telnet + client is idle (that is, if no data is received) for more than + <c>IdleTimeout</c> milliseconds. Default time-out is 10 + seconds.</p></item> + <tag><c>total_timeout</c></tag> + <item><p>Sets a time limit for the complete <c>expect</c> operation. + After <c>TotalTimeout</c> milliseconds, <c>{error,timeout}</c> + is returned. Default is <c>infinity</c> (that is, no time + limit).</p></item> + <tag><c>ignore_prompt | no_prompt_check</c></tag> + <item><p>>The function returns when a prompt is received, even if + no pattern has yet been matched, and + <c>{error,{prompt,Prompt}}</c> is returned. However, this + behavior can be modified with option <c>ignore_prompt</c> or + option <c>no_prompt_check</c>, which tells <c>expect</c> to + return only when a match is found or after a time-out.</p></item> + <tag><c>ignore_prompt</c></tag> + <item><p><c>ct_telnet</c> ignores any prompt found. This option is + useful if data sent by the server can include a pattern + matching prompt <c>regexp</c> (as returned by + <c>TargedMod:get_prompt_regexp/0</c>), but is not to not cause + the function to return.</p></item> + <tag><c>no_prompt_check</c></tag> + <item><p><c>ct_telnet</c> does not search for a prompt at all. This + is useful if, for example, <c>Pattern</c> itself matches the + prompt.</p></item> + <tag><c>wait_for_prompt</c></tag> + <item><p>Forces <c>ct_telnet</c> to wait until the prompt string + is received before returning (even if a pattern has already been + matched). This is equal to calling + <c>expect(Conn, Patterns++[{prompt,Prompt}], [sequence|Opts])</c>. + Notice that option <c>idle_timeout</c> and <c>total_timeout</c> + can abort the operation of waiting for prompt.</p></item> + <tag><c>repeat | repeat, N</c></tag> + <item><p>The pattern(s) must be matched multiple times. If <c>N</c> + is speciified, the pattern(s) are matched <c>N</c> times, and + the function returns <c>HaltReason = done</c>. This option can be + interrupted by one or more <c>HaltPatterns</c>. <c>MatchList</c> + is always returned, that is, a list of <c>Match</c> instead of + only one <c>Match</c>. Also <c>HaltReason</c> is returned.</p> + </item> + <tag><c>sequence</c></tag> + <item><p>All patterns must be matched in a sequence. A match is not + concluded until all patterns are matched. This option can be + interrupted by one or more <c>HaltPatterns</c>. <c>MatchList</c> + is always returned, that is, a list of <c>Match</c> instead of + only one <c>Match</c>. Also <c>HaltReason</c> is returned.</p> + </item> + </taglist> + + <p><em>Example 1:</em></p> + + <pre> + expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[sequence,{halt,[{nnn,"NNN"}]}])</pre> + + <p>First this tries to match <c>"ABC"</c>, and then <c>"XYZ"</c>, but + if <c>"NNN"</c> appears, the function returns + <c>{error,{nnn,["NNN"]}}</c>. If both <c>"ABC"</c> and <c>"XYZ"</c> + are matched, the function returns <c>{ok,[AbcMatch,XyzMatch]}</c>.</p> + + <p><em>Example 2:</em></p> + + <pre> + expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[{repeat,2},{halt,[{nnn,"NNN"}]}])</pre> + + <p>This tries to match <c>"ABC"</c> or <c>"XYZ"</c> twice. If + <c>"NNN"</c> appears, the function returns + <c>HaltReason = {nnn,["NNN"]}</c>.</p> + + <p>Options <c>repeat</c> and <c>sequence</c> can be combined to + match a sequence multiple times.</p> + </desc> + </func> + + <func> + <name>get_data(Connection) -> {ok, Data} | {error, Reason}</name> + <fsummary>Gets all data received by the Telnet client since the last + command was sent.</fsummary> + <type> + <v>Connection = connection()</v> + <v>Data = [string()]</v> + <v>Reason = term()</v> + </type> + <desc><marker id="get_data-1"/> + <p>Gets all data received by the Telnet client since the last + command was sent. Only newline-terminated strings are returned. + If the last received string has not yet been terminated, the + connection can be polled automatically until the string is + complete.</p> + + <p>The polling feature is controlled by the configuration values + <c>poll_limit</c> and <c>poll_interval</c> and is by default + disabled. This means that the function immediately returns all + complete strings received and saves a remaining non-terminated + string for a later <c>get_data</c> call.</p> + </desc> + </func> + + <func> + <name>open(Name) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Equivalent to open(Name, telnet).</fsummary> + <desc><marker id="open-1"/> + <p>Equivalent to + <seealso marker="#open-2"><c>ct_telnet:open(Name, + telnet)</c></seealso>.</p> + </desc> + </func> + + <func> + <name>open(Name, ConnType) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Opens a Telnet connection to the specified target + host.</fsummary> + <type> + <v>Name = target_name()</v> + <v>ConnType = connection_type()</v> + <v>Handle = handle()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="open-2"/> + <p>Opens a Telnet connection to the specified target host.</p> + </desc> + </func> + + <func> + <name>open(KeyOrName, ConnType, TargetMod) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Equivalent to open(KeyOrName, ConnType, TargetMod, []).</fsummary> + <desc><marker id="open-3"/> + <p>Equivalent to + <seealso marker="#open-4"><c>ct_telnet:ct_telnet:open(KeyOrName, + ConnType, TargetMod, [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>open(KeyOrName, ConnType, TargetMod, Extra) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Opens a Telnet connection to the specified target + host.</fsummary> + <type> + <v>KeyOrName = Key | Name</v> + <v>Key = atom()</v> + <v>Name = target_name()</v> + <v>ConnType = connection_type()</v> + <v>TargetMod = atom()</v> + <v>Extra = term()</v> + <v>Handle = handle()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="open-4"/> + <p>Opens a Telnet connection to the specified target host.</p> + + <p>The target data must exist in a configuration file. The connection + can be associated with <c>Name</c> and/or the returned <c>Handle</c>. + To allocate a name for the target, use one of the following + alternatives:</p> + + <list type="bulleted"> + <item><p><seealso marker="ct#require-2"><c>ct:require/2</c></seealso> + in a test case</p></item> + <item><p>A <c>require</c> statement in the suite information + function (<c>suite/0</c>)</p></item> + <item><p>A <c>require</c> statement in a test case information + function</p></item> + </list> + + <p>If you want the connection to be associated with <c>Handle</c> only + (if you, for example, need to open multiple connections to a host), + use <c>Key</c>, the configuration variable name, to specify the + target. Notice that a connection without an associated target name + can only be closed with the <c>Handle</c> value.</p> + + <p><c>TargetMod</c> is a module that exports the functions + <c>connect(Ip, Port, KeepAlive, Extra)</c> and + <c>get_prompt_regexp()</c> for the specified <c>TargetType</c> + (for example, <c>unix_telnet</c>).</p> + + <p>For <c>target_name()</c>, see module + <seealso marker="ct"><c>ct</c></seealso>.</p> + + <p>See also + <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send(Connection, Cmd) -> ok | {error, Reason}</name> + <fsummary>Equivalent to send(Connection, Cmd, []).</fsummary> + <desc><marker id="send-2"/> + <p>Equivalent to + <seealso marker="#send-3"><c>ct_telnet:send(Connection, Cmd, + [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>send(Connection, Cmd, Opts) -> ok | {error, Reason}</name> + <fsummary>Sends a Telnet command and returns immediately.</fsummary> + <type> + <v>Connection = connection()</v> + <v>Cmd = string()</v> + <v>Opts = [Opt]</v> + <v>Opt = {newline, boolean()}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="send-3"/> + <p>Sends a Telnet command and returns immediately.</p> + + <p>By default, this function adds a newline to the end of the + specified command. If this is not desired, option + <c>{newline,false}</c> can be used. This is necessary, for example, + when sending Telnet command sequences prefixed with character + Interprete As Command (IAC).</p> + + <p>The resulting output from the command can be read with + <seealso marker="#get_data-1"><c>ct_telnet:get_data/2</c></seealso> or + <seealso marker="#expect-2"><c>ct_telnet:expect/2,3</c></seealso>.</p> + </desc> + </func> + + <func> + <name>sendf(Connection, CmdFormat, Args) -> ok | {error, Reason}</name> + <fsummary>Equivalent to sendf(Connection, CmdFormat, Args, []).</fsummary> + <desc><marker id="sendf-3"/> + <p>Equivalent to + <seealso marker="#sendf-4"><c>ct_telnet:sendf(Connection, CmdFormat, + Args, [])</c></seealso>.</p> + </desc> + </func> + + <func> + <name>sendf(Connection, CmdFormat, Args, Opts) -> ok | {error, Reason}</name> + <fsummary>Sends a Telnet command and returns immediately (uses a format + string and a list of arguments to build the command).</fsummary> + <type> + <v>Connection = connection()</v> + <v>CmdFormat = string()</v> + <v>Args = list()</v> + <v>Opts = [Opt]</v> + <v>Opt = {newline, boolean()}</v> + <v>Reason = term()</v> + </type> + <desc><marker id="sendf-4"/> + <p>Sends a Telnet command and returns immediately (uses a format + string and a list of arguments to build the command).</p> + </desc> + </func> + </funcs> + + <section> + <title>See Also</title> + <p><seealso marker="unix_telnet"><c>unix_telnet</c></seealso></p> + </section> + +</erlref> + + diff --git a/lib/common_test/doc/src/ref_man.xml b/lib/common_test/doc/src/ref_man.xml index f98e2475a9..19960bfea7 100644 --- a/lib/common_test/doc/src/ref_man.xml +++ b/lib/common_test/doc/src/ref_man.xml @@ -30,43 +30,10 @@ <file>ref_man.xml</file> </header> <description> - <p><em>Common Test</em> is a portable application for automated - testing. It is suitable for black-box testing of target - systems of any type (i.e. not necessarily implemented in Erlang), - as well as for white-box testing of Erlang/OTP programs. - Black-box testing is performed via standard O&M - interfaces (such as SNMP, HTTP, Corba, Telnet, etc) and, - if required, via user specific interfaces (often called test - ports). White-box testing of Erlang/OTP programs is easily - accomplished by calling the target API functions directly - from the test case functions. Common Test also integrates - usage of the OTP cover tool for code coverage analysis of - Erlang/OTP programs.</p> - - <p>Common Test executes test suite programs automatically, - without operator interaction. Test progress and results is - printed to logs on HTML format, easily browsed with a standard - web browser. Common Test also sends notifications about progress - and results via an OTP event manager to event handlers plugged - in to the system. This way users can integrate their own - programs for e.g. logging, database storing or supervision with - Common Test.</p> - - <p>Common Test provides libraries that contain useful support - functions to fill various testing needs and requirements. - There is for example support for flexible test declarations - by means of so called test specifications. There is also support - for central configuration and control of multiple - independent test sessions (towards different target systems) - running in parallel.</p> - - <p>Common Test is implemented as a framework based on the OTP Test - Server application.</p> </description> + <xi:include href="common_test_app.xml"/> <xi:include href="ct_run.xml"/> - <!-- If you make modifications in the module list below, - you also need to update CT_MODULES in Makefile. --> <xi:include href="ct.xml"/> <xi:include href="ct_master.xml"/> <xi:include href="ct_cover.xml"/> @@ -83,6 +50,3 @@ </application> - - - diff --git a/lib/common_test/doc/src/unix_telnet.xml b/lib/common_test/doc/src/unix_telnet.xml new file mode 100644 index 0000000000..189379c39a --- /dev/null +++ b/lib/common_test/doc/src/unix_telnet.xml @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2010</year><year>2012</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>unix_telnet</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev>A</rev> + <file>unix_telnet.xml</file> + </header> + <module>unix_telnet</module> + <modulesummary>Callback module for ct_telnet, for connecting to a Telnet + server on a UNIX host.</modulesummary> + + <description> + + <p>Callback module for + <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>, + for connecting to a Telnet server on a UNIX host.</p> + + <p>It requires the following entry in the configuration file:</p> + + <pre> + {unix,[{telnet,HostNameOrIpAddress}, + {port,PortNum}, % optional + {username,UserName}, + {password,Password}, + {keep_alive,Bool}]}. % optional</pre> + + <p>To communicate through Telnet to the host specified by + <c>HostNameOrIpAddress</c>, use the interface functions in + <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>, for example, + <c>open(Name)</c> and <c>cmd(Name,Cmd)</c>.</p> + + <p><c>Name</c> is the name you allocated to the Unix host in your + <c>require</c> statement, for example:</p> + + <pre> + suite() -> [{require,Name,{unix,[telnet]}}].</pre> + + <p>or</p> + + <pre> + ct:require(Name,{unix,[telnet]}).</pre> + + <p>The "keep alive" activity (that is, that <c>Common Test</c> sends NOP + to the server every 10 seconds if the connection is idle) can be + enabled or disabled for one particular connection as described here. + It can be disabled for all connections using <c>telnet_settings</c> + (see <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>).</p> + + <p>The <c>{port,PortNum}</c> tuple is optional and if omitted, default + Telnet port 23 is used. Also the <c>keep_alive</c> tuple is optional, + and the value defauls to <c>true</c> (enabled).</p> + </description> + + <funcs> + <func> + <name>connect(ConnName, Ip, Port, Timeout, KeepAlive, Extra) -> {ok, Handle} | {error, Reason}</name> + <fsummary>Callback for ct_telnet.erl.</fsummary> + <type> + <v>ConnName = target_name()</v> + <v>Ip = string() | {integer(), integer(), integer(), integer()}</v> + <v>Port = integer()</v> + <v>Timeout = integer()</v> + <v>KeepAlive = bool()</v> + <v>Extra = target_name() | {Username, Password}</v> + <v>Username = string()</v> + <v>Password = string()</v> + <v>Handle = handle()</v> + <v>Reason = term()</v> + </type> + <desc><marker id="connect-6"/> + <p>Callback for <c>ct_telnet.erl</c>.</p> + + <p>Setup Telnet connection to a Unix host.</p> + + <p>For <c>target_name()</c>, see + <seealso marker="ct"><c>ct</c></seealso>. For <c>handle()</c>, see + <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>.</p> + </desc> + </func> + + <func> + <name>get_prompt_regexp() -> PromptRegexp</name> + <fsummary>Callback for ct_telnet.erl.</fsummary> + <type> + <v>PromptRegexp = prompt_regexp()</v> + </type> + <desc><marker id="get_prompt_regexp-0"/> + <p>Callback for <c>ct_telnet.erl</c>.</p> + + <p>Returns a suitable <c>regexp</c> string matching common prompts + for users on Unix hosts.</p> + + <p>For <c>prompt_regexp()</c>, see + <seealso marker="ct_telnet"><c>ct_telnet</c></seealso>.</p> + </desc> + </func> + </funcs> + + <section> + <title>See Also</title> + <p><seealso marker="ct"><c>ct</c></seealso>, + <seealso marker="ct_telnet"><c>ct_telnet</c></seealso></p> + </section> + +</erlref> + + |