檢視原始碼 ct_telnet (common_test v1.27.5)
Common Test
特定的 Telnet 客戶端 ct_telnet_client.erl
之上的層。
使用此模組來設定 Telnet 連線、傳送指令,並對結果執行字串匹配。關於如何使用 ct_telnet
和設定連線,特別是針對 UNIX 主機,請參閱 unix_telnet
手冊頁面。
在 ct_telnet
中定義的預設值
- 連線逾時(等待連線的時間)= 10 秒
- 指令逾時(等待指令返回的時間)= 10 秒
- 最大重新連線嘗試次數 = 3
- 重新連線間隔(在重新連線嘗試之間等待的時間)= 5 秒
- 保持連線(如果連線閒置,則每 8 秒向伺服器傳送 NOP)=
true
- 輪詢限制(輪詢以取得剩餘字串終止的最大次數)= 0
- 輪詢間隔(輪詢之間的睡眠時間)= 1 秒
- 預設情況下,telnet socket 的 TCP_NODELAY 選項已停用(設定為
false
)
使用者可以使用以下配置詞彙修改這些參數
{telnet_settings, [{connect_timeout,Millisec},
{command_timeout,Millisec},
{reconnection_attempts,N},
{reconnection_interval,Millisec},
{keep_alive,Bool},
{poll_limit,N},
{poll_interval,Millisec},
{tcp_nodelay,Bool}]}.
Millisec = integer(), N = integer()
在測試中包含的組態檔案中輸入 telnet_settings
詞彙,ct_telnet
會自動擷取資訊。
如有必要,可以針對每個連線指定 keep_alive
。如需詳細資訊,請參閱 unix_telnet
。
記錄
ct_telnet
的預設記錄行為是將有關執行操作、指令及其對應結果的資訊列印到測試案例 HTML 記錄中。以下內容不會列印到 HTML 記錄中:從 Telnet 伺服器傳送的文字字串,這些字串未由 ct_telnet
函數明確接收,例如 expect/3
。但是,可以將 ct_telnet
設定為使用在 ct_conn_log_h
中實作的特殊用途事件處理常式,以記錄所有 Telnet 流量。若要使用此處理常式,請安裝名為 cth_conn_log
的 Common Test
掛鉤。範例(使用測試套件資訊函數)
suite() ->
[{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].
conn_mod()
是實作連線協定的 Common Test
模組的名稱,也就是 ct_telnet
。
cth_conn_log
掛鉤會將 Telnet 資料以未格式化的方式記錄到個別的文字檔案中。所有 Telnet 通訊都會被擷取並列印,包括從伺服器傳送的任何資料。此文字檔案的連結位於測試案例 HTML 記錄的頂端。
依預設,所有 Telnet 連線的資料都會記錄在一個通用檔案中(名為 default
),如果有多個 Telnet 工作階段平行執行,可能會變得雜亂。因此,可以為每個連線建立單獨的記錄檔案。若要設定此行為,請使用掛鉤選項 hosts
,並列出將在套件中使用的伺服器/連線名稱。必須命名連線才能使其運作(請參閱 ct_telnet:open/1,2,3,4
)。
掛鉤選項 log_type
可用於變更 cth_conn_log
的行為。此選項的預設值為 raw
,這會導致上述行為。如果該值設定為 html
,則所有 Telnet 通訊都會改為列印到測試案例 HTML 記錄中。
對於原始記錄,prefix
選項可用於調整新增至連線記錄的前置資料。此選項的預設值為 disabled
,這會導致沒有前置資料。如果該值設定為 full
,則前置詞會包含時間戳記和額外資訊。如果該值設定為 short
,則前置詞僅包含人類可讀的時間戳記。
在組態檔案中,可以使用組態變數 ct_conn_log
指定所有描述的 cth_conn_log
掛鉤選項。
範例
{ct_conn_log, [{ct_telnet,[{log_type,raw},
{hosts,[key_or_name()]}]}]}
注意
在組態檔案中指定的掛鉤選項會覆寫測試套件中的任何硬式編碼掛鉤選項。
記錄範例
以下 ct_hooks
陳述式會將 Telnet 流量列印到 server1
和 server2
連線的單獨記錄中。任何其他連線的流量都會記錄在預設的 Telnet 記錄中。
suite() ->
[{ct_hooks,
[{cth_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}]}].
如先前所述,此規格也可以由組態檔案中類似以下的項目提供
{ct_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}.
在這種情況下,測試套件中的 ct_hooks
陳述式看起來如下所示
suite() ->
[{ct_hooks, [{cth_conn_log, []}]}].
另請參閱
摘要
類型
參考已開啟的 Telnet 連線,該連線與 handle
或 target_name
相關聯。
Telnet 連線類型,有效值:'telnet' | 'ts1' | 'ts2'。
請參閱 cmd/3
以取得說明。
符合特定目標類型所有可能提示的規則運算式。regexp
不能有任何群組,也就是說,在符合時,re:run/3
(在 STDLIB 中)必須傳回包含單一元素的清單。
函數
關閉 Telnet 連線並停止管理連線的處理程序。
透過 Telnet 傳送指令並等待提示。
傳送 Telnet 指令並等待提示(使用格式字串和引數清單來建置指令)。
從 Telnet 取得資料並等待預期的模式。
取得自傳送上一個指令以來,Telnet 用戶端接收的所有資料。僅會傳回以換行符號終止的字串。如果最後接收的字串尚未終止,則可以自動輪詢連線,直到字串完成為止。
開啟與指定目標主機的 Telnet 連線。
開啟與指定目標主機的 Telnet 連線。
傳送 Telnet 指令並立即傳回。
傳送 Telnet 指令並立即傳回(使用格式字串和引數清單來建置指令)。
類型
-type connection() :: handle() | {ct:target_name(), connection_type()} | ct:target_name().
參考已開啟的 Telnet 連線,該連線與 handle
或 target_name
相關聯。
-type connection_type() :: telnet | ts1 | ts2.
Telnet 連線類型,有效值:'telnet' | 'ts1' | 'ts2'。
-type handle() :: ct:handle().
特定 Telnet 連線的控制代碼,請參閱模組 ct
。
請參閱 cmd/3
以取得說明。
-type prompt_regexp() :: string().
符合特定目標類型所有可能提示的規則運算式。regexp
不能有任何群組,也就是說,在符合時,re:run/3
(在 STDLIB 中)必須傳回包含單一元素的清單。
函數
-spec close(Connection) -> ok | {error, Reason} when Connection :: connection(), Reason :: already_closed | term().
關閉 Telnet 連線並停止管理連線的處理程序。
連線可以與目標名稱和/或控制代碼相關聯。如果 Connection
沒有相關聯的目標名稱,則只能使用控制代碼值關閉連線(請參閱 ct_telnet:open/4
)。
-spec cmd(Connection, Cmd) -> {ok, Data} | {error, Reason} when Connection :: connection(), Cmd :: iodata(), Data :: string(), Reason :: term().
-spec cmd(Connection, Cmd, Opts) -> {ok, Data} | {error, Reason} when Connection :: connection(), Cmd :: iodata(), Opts :: [{timeout, Timeout} | newline_option()] | Timeout, Timeout :: integer(), Data :: string(), Reason :: term().
透過 Telnet 傳送指令並等待提示。
依預設,此函數會將 "\n" 新增至指定的指令結尾。如果不希望這樣做,請使用選項 {newline,false}
。例如,當傳送以字元「解譯為指令 (IAC)」為首碼的 Telnet 指令序列時,這是必要的。如果需要與 "\n" 不同的行尾,也可以使用選項 {newline,string()}
,例如 {newline,"\r\n"}
,以新增歸位字元和換行字元。
選項 timeout
指定用戶端必須等待提示的時間長度。如果時間過期,函數會傳回 {error,timeout}
。如需有關指令逾時預設值的資訊,請參閱此模組開頭的預設值清單。
-spec cmdf(Connection, CmdFormat, Args) -> {ok, Data} | {error, Reason} when Connection :: connection(), CmdFormat :: io:format(), Args :: [term()], Data :: string(), Reason :: term().
-spec cmdf(Connection, CmdFormat, Args, Opts) -> {ok, Data} | {error, Reason} when Connection :: connection(), CmdFormat :: io:format(), Args :: [term()], Opts :: [{timeout, Timeout} | newline_option()] | Timeout, Timeout :: integer(), Data :: string(), Reason :: term().
傳送 Telnet 指令並等待提示(使用格式字串和引數清單來建置指令)。
如需詳細資訊,請參閱 ct_telnet:cmd/3
。
-spec expect(Connection, Patterns) -> {ok, Match} | {ok, Match, HaltReason} | {error, Reason} | no_return() when Connection :: connection(), Patterns :: Pattern | [Pattern], Pattern :: PatternString | {Tag, PatternString}, Tag :: term(), PatternString :: unicode:charlist(), Match :: MatchResult | [MatchResult], MatchResult :: [CaptureData | {Tag, CaptureData}] | [[CaptureData | {Tag, CaptureData}]], CaptureData :: string() | {error, string(), binary()} | {incomplete, string(), binary()}, HaltReason :: MatchResult, Reason :: term().
-spec expect(Connection, Patterns, Opts) -> {ok, Match} | {ok, Match, HaltReason} | {error, Reason} | no_return() when Connection :: connection(), Patterns :: Pattern | [Pattern], Pattern :: PatternString | {Tag, PatternString}, Tag :: term(), PatternString :: unicode:charlist(), Opts :: [Option], Option :: {idle_timeout, non_neg_integer()} | {total_timeout, non_neg_integer()} | ignore_prompt | no_prompt_check | wait_for_prompt | repeat | {repeat, non_neg_integer()} | sequence | {halt, Patterns}, Match :: MatchResult | [MatchResult], MatchResult :: [CaptureData | {Tag, CaptureData}] | [[CaptureData | {Tag, CaptureData}]], CaptureData :: string() | {error, string(), binary()} | {incomplete, string(), binary()}, HaltReason :: MatchResult, Reason :: term().
從 Telnet 取得資料並等待預期的模式。
Pattern
可以是 POSIX 規則運算式。當成功匹配模式時(在多個模式的情況下,至少一個)函數會傳回。
RxMatch
是已匹配字串的清單。其外觀如下 [FullMatch, SubMatch1, SubMatch2, ...]
,其中 FullMatch
是由整個規則運算式匹配的字串,而 SubMatchN
是與子運算式編號 N
匹配的字串。子運算式在規則運算式中以 '(' ')'
表示。
如果指定了 Tag
,則傳回的 Match
也包含匹配的 Tag
。否則,只會傳回 RxMatch
。
選項
idle_timeout
- 表示如果 Telnet 用戶端閒置(也就是說,如果超過IdleTimeout
毫秒沒有收到資料),則函數必須傳回。預設逾時時間為 10 秒。total_timeout
- 設定完整expect
操作的時間限制。在TotalTimeout
毫秒之後,會傳回{error,timeout}
。預設值為infinity
(也就是說,沒有時間限制)。ignore_prompt | no_prompt_check
- >當收到提示時,即使尚未匹配任何模式,函數也會傳回,並且會傳回{error,{prompt,Prompt}}
。但是,可以使用選項ignore_prompt
或選項no_prompt_check
修改此行為,這會告訴expect
僅在找到匹配項或逾時後才傳回。ignore_prompt
-ct_telnet
會忽略任何找到的提示符號。當伺服器傳送的資料可能包含符合提示符號regexp
的模式(如TargedMod:get_prompt_regexp/0
返回的),但又不想因此讓函式返回時,此選項很有用。no_prompt_check
-ct_telnet
完全不搜尋提示符號。例如,當Pattern
本身就符合提示符號時,此選項很有用。wait_for_prompt
- 強制ct_telnet
等待直到收到提示符號字串後才返回(即使已經匹配到模式)。這等同於呼叫expect(Conn, Patterns++[{prompt,Prompt}], [sequence|Opts])
。請注意,選項idle_timeout
和total_timeout
可以中止等待提示符號的操作。repeat | repeat, N
- 模式必須匹配多次。如果指定了N
,則模式會匹配N
次,且函式會返回HaltReason = done
。此選項可以被一個或多個HaltPatterns
中斷。總是會返回MatchList
,也就是Match
的列表,而不是只有一個Match
。也會返回HaltReason
。sequence
- 所有模式必須依序匹配。在所有模式都匹配之前,不會結束匹配。此選項可以被一個或多個HaltPatterns
中斷。總是會返回MatchList
,也就是Match
的列表,而不是只有一個Match
。也會返回HaltReason
。
範例 1
expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[sequence,{halt,[{nnn,"NNN"}]}])
首先,程式會嘗試匹配 "ABC"
,然後匹配 "XYZ"
,但是如果出現 "NNN"
,函式會返回 {error,{nnn,["NNN"]}}
。如果 "ABC"
和 "XYZ"
都匹配成功,函式會返回 {ok,[AbcMatch,XyzMatch]}
。
範例 2
expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[{repeat,2},{halt,[{nnn,"NNN"}]}])
程式會嘗試匹配 "ABC"
或 "XYZ"
兩次。如果出現 "NNN"
,函式會返回 HaltReason = {nnn,["NNN"]}
。
選項 repeat
和 sequence
可以組合使用,以多次匹配一個序列。
-spec get_data(Connection) -> {ok, Data} | {error, Reason} when Connection :: connection(), Data :: string(), Reason :: term().
取得自傳送上一個指令以來,Telnet 用戶端接收的所有資料。僅會傳回以換行符號終止的字串。如果最後接收的字串尚未終止,則可以自動輪詢連線,直到字串完成為止。
輪詢功能由組態值 poll_limit
和 poll_interval
控制,預設為停用。這表示函式會立即返回所有已接收的完整字串,並將剩餘的未終止字串保存起來,供稍後的 get_data
呼叫使用。
-spec open(Name) -> {ok, Handle} | {error, Reason} when Name :: atom(), Handle :: handle(), Reason :: term().
等同於 open(Name, telnet)
。
-spec open(Name, ConnType) -> {ok, Handle} | {error, Reason} when Name :: atom(), ConnType :: connection_type(), Handle :: handle(), Reason :: term().
開啟與指定目標主機的 Telnet 連線。
-spec open(KeyOrName, ConnType, TargetMod) -> {ok, Handle} | {error, Reason} when KeyOrName :: ct:key_or_name(), ConnType :: connection_type(), TargetMod :: module(), Handle :: handle(), Reason :: term().
-spec open(KeyOrName, ConnType, TargetMod, Extra) -> {ok, Handle} | {error, Reason} when KeyOrName :: ct:key_or_name(), ConnType :: connection_type(), TargetMod :: module(), Extra :: term(), Handle :: handle(), Reason :: term().
開啟與指定目標主機的 Telnet 連線。
目標資料必須存在於組態檔中。連線可以與 Name
和/或返回的 Handle
關聯。要為目標配置名稱,請使用下列其中一種方式
- 在測試案例中使用
ct:require/2
- 在套件資訊函式 (
suite/0
) 中使用require
陳述式 - 在測試案例資訊函式中使用
require
陳述式
如果您希望連線只與 Handle
關聯(例如,您需要開啟多個與主機的連線),請使用組態變數名稱 Key
來指定目標。請注意,沒有關聯目標名稱的連線只能使用 Handle
值來關閉。
TargetMod
是一個模組,針對指定的 TargetType
(例如 unix_telnet
),它匯出函式 connect(Ip, Port, KeepAlive, Extra)
和 get_prompt_regexp()
。
另請參閱 ct:require/2
。
-spec send(Connection, Cmd) -> ok | {error, Reason} when Connection :: connection(), Cmd :: iodata(), Reason :: term().
-spec send(Connection, Cmd, Opts) -> ok | {error, Reason} when Connection :: connection(), Cmd :: iodata(), Opts :: [newline_option()], Reason :: term().
傳送 Telnet 指令並立即傳回。
預設情況下,此函式會在指定的命令末尾加上 "\n"。如果不需要這樣,可以使用選項 {newline,false}
。例如,當傳送以字元 Interpret As Command (IAC) 為前綴的 Telnet 命令序列時,這會是必要的。如果需要使用 "\n" 以外的行尾符號,也可以使用選項 {newline,string()}
,例如 {newline,"\r\n"}
,以同時加上歸位字元和換行字元。
可以使用 ct_telnet:get_data/2
或 ct_telnet:expect/2,3
讀取命令的輸出結果。
-spec sendf(Connection, CmdFormat, Args) -> ok | {error, Reason} when Connection :: connection(), CmdFormat :: io:format(), Args :: [term()], Reason :: term().
-spec sendf(Connection, CmdFormat, Args, Opts) -> ok | {error, Reason} when Connection :: connection(), CmdFormat :: io:format(), Args :: [term()], Opts :: [newline_option()], Reason :: term().
傳送 Telnet 指令並立即傳回(使用格式字串和引數清單來建置指令)。
詳細資訊請參閱 ct_telnet:send/3
。