Robot Framework+SSHLibrary實現自動化運維質量檢測

Robot Framework+SSHLibrary介紹

首先,介紹一下robotframework,oschina這麼介紹:html

Robot Framework 是一個關鍵詞驅動的自動測試框架。測試用例位於HTML或者TSV(以tab分隔值)文件,使用在測試庫中實現的關鍵詞來在測試中運行程序。由於 Robot Framework 是靈活和可擴展的,因此它很合適用於測試具備多種接口的複雜軟件:用戶接口,命令行,webservice,編程接口等。node

Robot FrameworkCumcumber http://www.oschina.net/p/cucumber 具備類似的能力,都屬於BDD自動化測試工具。 可是Cumcumber只能順序驗證測試步驟,好比:python

Given  我在登陸頁
When  我輸入賬號"zhangsan"
And      我輸入密碼"123456"
And      我點擊登陸按鈕
Then    我能看到個人暱稱"張三"

上述的 "我在登陸頁" 等步驟的定義,都在Cumcumber的step_definitions.rb中,用ruby語言定義。
若是對Cumcumber測試安卓手機APP感興趣,能夠參閱 使用calabash測試開源中國Android客戶端mysql

Robot Framework在語義級別就提供了FOR循環和IF判斷,自定義Keyword直接在.robot文件中,不須要寫一句Python語句。linux

而後再去官網 http://robotframework.org/ ,到TestLibraries看看都提供了什麼測試庫:nginx

在此輸入圖片描述 STANDARD庫中包含OperatingSystem,String,Collections,提供了調用本地shell命令,字符串處理,和Python集合的處理能力。git

在此輸入圖片描述 EXTERNAL庫中有手機APP測試相關的測試庫、網頁測試相關、http測試相關、數據庫相關、ssh相關。github

我最看中的就是其中SSHLibrary,它提供ssh登陸和執行遠程命令的能力,並能用sftp上傳下載文件。
SSHLibrary對python庫paramiko進行了封裝,因此他是Farbric的兄弟,Fabric經常使用於自動化運維,可是缺乏對運維結果的檢測能力。web

因此,Robot Framework+SSHLibrary天生就適合作網站的自動化運維質量檢測。sql

自動化運行質量檢測,包含那些內容?

  • mysql, mongo, nginx等工具的配置是否正確
  • mysql, mongo, nginx等工具的進程是否已崩潰
  • mysql, mongo, nginx的數據等目錄的owner是否正確
  • 網站服務器各結點的網絡配置是否正確
  • 各tomcat, jetty服務的版本是否符合預期

後面經過一個一個的小例子,來演示Robot Framework+SSHLibrary怎樣達到自動化運維質量檢測

Debian/Ubunbu下安裝Robot Framework+SSHLibrary

Python默認已安裝

pip: python環境下模塊安裝工具

sudo apt-get install python-pip

python-dev: 某些python模塊安裝須要Python.h,因此要安裝python-dev

sudo apt-get install python-dev

robotframework: http://robotframework.org

sudo pip install robotframework

若是使用默認pip源很慢,能夠指定豆瓣的pip源:

sudo pip install robotframework -i http://pypi.douban.com/simple

SSHLibrary: https://github.com/robotframework/SSHLibrary

pip install robotframework-sshlibrary

Redhat/CentOS 下安裝Robot Framework+SSHLibrary

只要把Debian對應安裝命令中的apt-get 改爲yum, dev改爲devel Python默認已安裝

pip: python環境下模塊安裝工具

sudo yum install python-pip

python-devel: 某些python模塊安裝須要Python.h,因此要安裝python-devel

sudo yum install python-devel

robotframework: http://robotframework.org

sudo pip install robotframework

SSHLibrary: https://github.com/robotframework/SSHLibrary

pip install robotframework-sshlibrary

RobotFramework+SSHLibrary遠程調用命令示例

示例來自: http://robotframework.org/SSHLibrary/

注意

  • 下面的${HOST}, ${USERNAME}, ${PASSWORD} 請使用本身遠程機器名、賬號和密碼
  • 還要確保遠程機器已經開啓了sshd服務

測試用例文件:

shen@debian:~/robotframework$ cat executing-commands.robot
*** Settings ***
Documentation          This example demonstrates executing commands on a remote machine
...                    and getting their output and the return code.
...
...                    Notice how connections are handled as part of the suite setup and
...                    teardown. This saves some time when executing several test cases.

Library                SSHLibrary
Suite Setup            Open Connection And Log In
Suite Teardown         Close All Connections

*** Variables ***
${HOST}                localhost
${USERNAME}            shen
${PASSWORD}            123456

*** Test Cases ***
Execute Command And Verify Output
    [Documentation]    Execute Command can be used to ran commands on the remote machine.
    ...                The keyword returns the standard output by default.
    ${output}=    Execute Command    echo Hello SSHLibrary!
    Should Be Equal    ${output}    Hello SSHLibrary!

Execute Command And Verify Return Code
    [Documentation]    Often getting the return code of the command is enough.
    ...                This behaviour can be adjusted as Execute Command arguments.
    ${rc}=    Execute Command    echo Success guaranteed.    return_stdout=False    return_rc=True
    Should Be Equal    ${rc}    ${0}

Executing Commands In An Interactive Session
    [Documentation]    Execute Command always executes the command in a new shell.
    ...                This means that changes to the environment are not persisted
    ...                between subsequent Execute Command keyword calls.
    ...                Write and Read Until variants can be used to operate in the same shell.
    Write    cd ..
    Write    echo Hello from the parent directory!
    ${output}=    Read Until    directory!
    Should End With     ${output}    Hello from the parent directory!

*** Keywords ***
Open Connection And Log In
   Open Connection    ${HOST}
   Login    ${USERNAME}    ${PASSWORD}

gedit打開executing-commands.robot的效果:

在此輸入圖片描述

執行結果:

shen@debian:~/robotframework$ pybot executing-commands.robot 

==============================================================================
Executing Commands :: This example demonstrates executing commands on a rem...
==============================================================================
Execute Command And Verify Output :: Execute Command can be used t... | PASS |
------------------------------------------------------------------------------
Execute Command And Verify Return Code :: Often getting the return... | PASS |
------------------------------------------------------------------------------
Executing Commands In An Interactive Session :: Execute Command al... | PASS |
------------------------------------------------------------------------------
Executing Commands :: This example demonstrates executing commands... | PASS |
3 critical tests, 3 passed, 0 failed
3 tests total, 3 passed, 0 failed
==============================================================================
Output:  /home/shen/robotframework/output.xml
Log:     /home/shen/robotframework/log.html
Report:  /home/shen/robotframework/report.html

在此輸入圖片描述

Robot Framework+SSHLibrary實現自動化運維質量檢測

example-100: 直接在命令行輸入ssh密碼

爲了能方便演示,每一個例子都有各編號如100,對應的代碼目錄~/robotframework/100 上述基本ssh例子先簡化以下:

shen@debian:~/robotframework/100$ cat example-100.robot
*** Settings ***
Documentation          ssh示例

Library                SSHLibrary
Suite Setup            Open Connection And Log In
Suite Teardown         Close All Connections

*** Variables ***
${HOST}                localhost
${USERNAME}            shen
${PASSWORD}            123456

*** Test Cases ***
遠程執行命令並檢驗輸出
    ${output}=    Execute Command    echo Hello SSHLibrary!
    Should Be Equal    ${output}    Hello SSHLibrary!

*** Keywords ***
Open Connection And Log In
   Open Connection    ${HOST}
   Login    ${USERNAME}    ${PASSWORD}

在此輸入圖片描述

說明: 上述檢驗內容是ssh到localhost,執行shell命令: echo Hello SSHLibrary!
應該看到stdout爲 Hello SSHLibrary!

下面用手工執行ssh來模擬上述檢驗:

在此輸入圖片描述

在使用if判斷變量output時,碰到了單引號和雙引號的替換規則問題,並且bash的if-else-fi真心難寫。
只有下面if中的單雙引號使用是正確的:

if [ "$output" == 'Hello SSHLibrary!' ]; then echo -e "| \033[32mPASS\033[0m |"; else echo -e "| \033[31mFAIL\033[0m |"; fi

回到正題,我想在pybot命令行直接輸入ssh密碼,能夠這樣執行:

在此輸入圖片描述

由於輸入的是錯誤密碼,因此提示: Authentication failed for user 'shen'.

規則1: pybot命令行中輸入的變量值會覆蓋robot文件中*** Variables ***中定義的變量值

example-110: 執行測試時打印調試信息

上面的example-100.robot運行時,屏幕上只打印了testcase名稱和測試結果綠色PASS或紅色FAIL。
在運行目錄下生成了3個文件:output.xml, log.html, report.html,先分別打開看看:

在此輸入圖片描述

在此輸入圖片描述

在此輸入圖片描述

我不習慣去看html文件,因此我想在運行時直接打印output變量的內容。

先去官網找到Log To Console的幫助信息: http://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Log%20To%20Console

在此輸入圖片描述

官網幫助中的robotframework測試用例格式都是表格,可是最實用的是txt格式,測試用例文件的後綴能夠是.txt或.robot

表格格式的分隔方式就是一個一個格子,txt格式對應分隔符是兩個以上空格或者一個以上Tab。

shen@debian:~/robotframework/110$ cat example-110.robot
*** Settings ***
Documentation          ssh示例

Library                SSHLibrary
Suite Setup            Open Connection And Log In
Suite Teardown         Close All Connections

*** Variables ***
${HOST}                localhost
${USERNAME}            shen
${PASSWORD}            123456

*** Test Cases ***
遠程執行命令並檢驗輸出
    ${output}=         Execute Command    echo Hello SSHLibrary!
    Log To Console     \n\${output}的內容:"\x1b[1;33m${output}\x1b[0m"
    Should Be Equal    ${output}    Hello SSHLibrary!

*** Keywords ***
Open Connection And Log In
   Open Connection    ${HOST}
   Login              ${USERNAME}    ${PASSWORD}

請注意新增行:

Log To Console     \n\${output}的內容:"\x1b[1;33m${output}\x1b[0m"

執行測試結果:

在此輸入圖片描述

說明: \x1b[1;33m${output}\x1b[0m 是以高亮黃色打印變量${output}的內容。\x1b與echo打印彩色時的\033是相同的。
可是robotframework測試用例文件的語法中不支持\0nn八進制,只支持\xnn 十六進制。 Log To Console右邊必須先輸入兩個以上空格或1個以上Tab,再輸入變量;兩個變量之間也要如此分隔。

規則2: robotframework測試用例文件中字符$要用$轉義,\xnn指定十六進制字符。

example-120: 我要把服務器的結點信息保存在外部文件中

首先看一下pybot的-h幫助: 執行命令: pybot -h,其中的-v參數能夠指定一個變量的值,-V能夠從一個文件中指定多個變量。 在此輸入圖片描述

shen@debian:~/robotframework/120$ cat node-list.py
SSH_SERVERS = ['node01', 'node02', 'node03']

NODE_IP_MAP = {
	'node01':'localhost',
	'node02':'127.0.0.1',
	'node03':'192.168.0.107',
}
shen@debian:~/robotframework/120$ cat example-120.robot 
*** Settings ***
Documentation          ssh示例

Library                Collections
Library                SSHLibrary
Suite Teardown         Close All Connections

*** Variables ***

*** Test Cases ***
遠程執行命令並檢驗輸出
    :FOR    ${node}    IN    @{SSH_SERVERS}
    \    ${node_ip}=    Get From Dictionary    ${NODE_IP_MAP}     ${node}
    \    Log To Console     \n正在登陸 ${node}(${node_ip}) ...
    \    Open Connection And Log In "${node_ip}"
    \    Log To Console     \n正在${node}(${node_ip})執行命令: echo Hello SSHLibrary!
    \    ${output}=         Execute Command    echo Hello SSHLibrary!
    \    Log To Console     \n\${output}的內容:"\x1b[1;33m${output}\x1b[0m"
    \    Should Be Equal    ${output}    Hello SSHLibrary!

*** Keywords ***
Open Connection And Log In "${node_ip}"
   Open Connection    ${node_ip}
   Login              ${USERNAME}    ${PASSWORD}

在此輸入圖片描述

請注意例子120的幾處新內容:

  • node-list.py 定義了全部結點的ip信息和ssh服務器列表,使用python的列表和字典定義
  • example-120.robot 中引入了新測試庫: Collections http://robotframework.org/robotframework/latest/libraries/Collections.html
  • 從新定義了關鍵字:Open Connection And Log In,能夠接受參數${node_ip}
  • 使用FOR循環遍歷SSH_SERVERS中的每一個結點。

example-130: 我要確保服務器結點的python版本都是2.7.3

shen@debian:~/robotframework/130$ cat node-list.py
PYTHON_SERVERS = ['node01', 'node03']

SSH_SERVERS = ['node01', 'node02', 'node03']

NODE_IP_MAP = {
	'node01':'localhost',
	'node02':'127.0.0.1',
	'node03':'192.168.0.107',
}
shen@debian:~/robotframework/130$ cat versions.py
VERSIONS = {
	'python':'2.7.3',
	'gcc':'4.7.2',
	'ssh':'OpenSSH_6.0p1',
}
shen@debian:~/robotframework/130$ cat example-130.robot 
*** Settings ***
Documentation          ssh示例

Library                Collections
Library                SSHLibrary
Suite Teardown         Close All Connections

*** Variables ***

*** Test Cases ***
遠程執行命令並檢驗輸出
    :FOR    ${node}    IN    @{SSH_SERVERS}
    \    ${node_ip}=    Get From Dictionary    ${NODE_IP_MAP}     ${node}
    \    Log To Console     \n正在登陸 ${node}(${node_ip}) ...
    \    Open Connection And Log In "${node_ip}"
    \    Log To Console     \n正在${node}(${node_ip})執行命令: echo Hello SSHLibrary!
    \    ${output}=         Execute Command    echo Hello SSHLibrary!
    \    Log To Console     \n\${output}的內容:"\x1b[1;33m${output}\x1b[0m"
    \    Should Be Equal    ${output}    Hello SSHLibrary!

檢查python版本
    :FOR    ${node}    IN    @{PYTHON_SERVERS}
    \    ${node_ip}=    Get From Dictionary    ${NODE_IP_MAP}     ${node}
    \    Open Connection And Log In "${node_ip}"
    \    Log To Console     \n正在${node}(${node_ip})執行命令: python --version 2>&1 | cut -d' ' -f 2
    \    ${output}=         Execute Command    python --version 2>&1 | cut -d' ' -f 2
    \    ${version}=    Get From Dictionary    ${VERSIONS}     python
    \    Log To Console     \npython版本${output} == 指望版本${version} ?
    \    Should Be Equal    ${output}    ${version}

*** Keywords ***
Open Connection And Log In "${node_ip}"
   Open Connection    ${node_ip}
   Login              ${USERNAME}    ${PASSWORD}

執行測試命令:

pybot -v USERNAME:shen -v PASSWORD:123456 -V node-list.py -V versions.py example-130.robot

在此輸入圖片描述

若是更改指望版本爲2.6.6:

shen@debian:~/robotframework/130$ cat versions.py
VERSIONS = {
	'python':'2.6.6',
	'gcc':'4.7.2',
	'ssh':'OpenSSH_6.0p1',
}

測試結果以下:

在此輸入圖片描述

由於測試用例「檢查python版本」中的第一個結點的python版本檢查斷言:Should Be Equal ${output} ${version}失敗,
因此robotframework直接退出本測試用例的執行,不會再去檢查第二個結點的python版本。

example-140: 檢查交互式輸出的內容

shen@debian:~/robotframework/140$ cat example-140.robot 
*** Settings ***
Documentation          交互式檢查python版本

Library                Collections
Library                SSHLibrary
Suite Teardown         Close All Connections

*** Variables ***

*** Test Cases ***
交互式檢查python版本
    :FOR    ${node}    IN    @{PYTHON_SERVERS}
    \    ${node_ip}=    Get From Dictionary    ${NODE_IP_MAP}     ${node}
    \    Open Connection And Log In "${node_ip}"
    \    Write    python
    \    ${output}=    Read Until    >>>
    \    Log To Console     \n${node}(${node_ip})執行命令python的輸出:---\n${output}\n---
    \    ${version}=    Get From Dictionary    ${VERSIONS}     python
    \    Log To Console     \n${node}(${node_ip})的python版本 == ${version} ?
    \    Should Contain     ${output}    ${version}


*** Keywords ***
Open Connection And Log In "${node_ip}"
   Open Connection    ${node_ip}
   Login              ${USERNAME}    ${PASSWORD}

執行測試結果:

在此輸入圖片描述

example-150: 關鍵字定義放在獨立文件中

shen@debian:~/robotframework/150$ cat keywords.robot 
*** Settings ***
Library                Collections
Library                SSHLibrary

*** Keywords ***
Check Python Version "${servers}" "${version}"
    :FOR    ${node}    IN    @{servers}
    \    ${node_ip}=    Get From Dictionary    ${NODE_IP_MAP}     ${node}
    \    Open Connection    ${node_ip}
    \    Login              ${USERNAME}    ${PASSWORD}    
    \    Write    python
    \    ${output}=    Read Until    >>>
    \    Log To Console     \n${node}(${node_ip})執行命令python的輸出:---\n${output}\n---
    \    Log To Console     \n${node}(${node_ip})的python版本 == ${version} ?
    \    Should Contain     ${output}    ${version}


shen@debian:~/robotframework/150$ cat example-150.robot 
*** Settings ***
Documentation          交互式檢查python版本

Resource               keywords.robot
Suite Teardown         Close All Connections

*** Variables ***

*** Test Cases ***
交互式檢查python版本
    ${version}=    Get From Dictionary    ${VERSIONS}     python
    Check Python Version "${PYTHON_SERVERS}" "${version}"

*** Keywords ***

shen@debian:~/robotframework/150$ pybot -v USERNAME:shen -v PASSWORD:123456 -V node-list.py -V versions.py example-150.robot 
==============================================================================
Example-150 :: 交互式檢查python版本                                           
==============================================================================
交互式檢查python版本                                                  .
node01(localhost)執行命令python的輸出:---
Python 2.7.3 (default, Mar 13 2014, 11:03:55) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
---

node01(localhost)的python版本 == 2.7.3 ?

node03(192.168.0.107)執行命令python的輸出:---
Python 2.7.3 (default, Mar 13 2014, 11:03:55) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
---

node03(192.168.0.107)的python版本 == 2.7.3 ?
交互式檢查python版本                                                  | PASS |
------------------------------------------------------------------------------
Example-150 :: 交互式檢查python版本                                   | PASS |
1 critical test, 1 passed, 0 failed
1 test total, 1 passed, 0 failed
==============================================================================
Output:  /home/shen/robotframework/150/output.xml
Log:     /home/shen/robotframework/150/log.html
Report:  /home/shen/robotframework/150/report.html
shen@debian:~/robotframework/150$

example-160: 執行測試的彩色打印導出到文件

複用example-150的測試用例

在此輸入圖片描述

pybot -C on -v USERNAME:shen -v PASSWORD:123456 -V node-list.py -V versions.py example-150.robot | tee ../160/color_output.txt

在此輸入圖片描述

後面還有什麼?

歡迎你們繼續提出問題,我將盡力以上述example的方式給出答案。

相關文章
相關標籤/搜索