l

2011年6月21日 星期二

我期待...

June 21 21:55~23:01

開發軟體,常常需要安裝一些測試環境,例如在一台新的電腦上面安裝 JDK,MySQL Server,SVN client,ANT,等等等等等.....。這些剛剛裝好的測試環境(尚未安裝待測程式),在此稱之為『乾淨的環境』。如果久久才需要製作一次乾淨的環境也就算了,但是如果需要經常安裝,這些安裝軟體的工作就變得很無聊而且浪費時間。如果測試環境可以用 VM 來取代,那也就還好,只要安裝好之後把 VM 備份,然後把待測程式安裝到這個 VM 裡面,用完之後再用剛剛備份的那個 VM 覆蓋掉這個『髒掉』的 VM,這樣每次測試的時候就都有一個全新乾淨的環境。當然鄉民們也可以用 VM 的快照功能來將 VM 回復到初始(尚未安裝待測程式)的狀態。

有時候因為某種原因,每次都一定要在『實體機器』上面重裝一份新的 OS,然後在這個新的 OS 上面安裝一些測試需要用到的軟體,最後在安裝待測程式。在這種狀況下鄉民們可以用 ghost 或是 Clonezilla 將整個實體機器硬碟中的資料全部備份成一個影像檔,安裝過測試程式之後再用這個影像檔來復原到最初的狀態便可。

假設因為某種神秘不可告人的原因,鄉民們需要不斷的在剛裝好的 OS  裡面安裝一些軟體,如果需要手動去安裝的話,那就很麻煩了。今天 Teddy 介紹一個在 Linux 下面的小工具,叫做 Expect,可以在『文字模式』下用來幫助鄉民們安裝軟體。

Expect 的間單說明鄉民們可以在 Wikipedia 看到,它是一個 Unix/Linux 下面 automation and testing 的工具,其工作原理非常簡單:
  • Expect 幫我們執行某個程式。
  • Expect 一直等待(一直期待),直到該程式在文字畫面上顯示某些字串。
  • 當 Expect 讀到它所期待的文字之後,代替『人』送出某些訊息給該程式。例如,送出 enter + 換行字元,或是送出  Y + 換行字元。
  • 該程式繼續動作。
  •  Expect 繼續等待(期待),直到該程式在文字畫面上顯示某些字串。
  • ... (以此類推)
舉個實際的例子,假設鄉民們想要寫一隻程式自動連到 ftp.ntut.edu.tw ,然後把登入目錄中的所有檔案全部都抓回來,如果是用『人』來執行這些工作的話,那麼大概會長這樣子:

root@Ubuntu:~# ftp ftp.ntut.edu.tw
Connected to ftp.cc.ntut.edu.tw.
220 (vsFTPd 2.0.5)
Name (ftp.ntut.edu.tw:root): guest
331 Please specify the password.
Password:
(以下省略)

如果用 Expect 的話,可以寫一個 script 來做這件事:

  spawn ftp ftp.ntut.edu.tw
  expect "Name"
  send "teddy\r"
  expect "Password:"
  send "xxx123\r"
  expect "ftp>"
  send "bin\r"
  expect "ftp>"
  send "prompt\r"
  expect "ftp>"
  send "mget *\r"
  expect "ftp>"
  send "bye\r"
  expect eof

第一行的 spawn 這個指令是用來啟動一隻程式,而第二行的 expect "Name" 這個指令是告訴 Expect 去等待剛剛啟動的那隻程式透過 stand output 所輸出的字串中,是否有出現 Name 這個字串,如果沒有,就一直等待,一直到 Name 這個字串出現為止。在此先插花補充說明一下,由於使用 spawn 指令所啟動的那隻程式,算是 Expect 的『子行程(sub-process)』,所以 Expect 是可以讀到該 sub-process 輸出到 stand output 上面的字串(原本這些字串會直接出現在 console 上)。

當 Expect 等到畫面上出現 Name 這個字的時候,就是 ftp 軟體要鄉民們輸入登入的使用者名稱的時候。此時執行到第三行的 send "teddy\r",Expect 會幫鄉民們透過 stand input 輸出登入使用者名稱給 ftp 程式。用下面的圖來解釋應該比較容易理解:

                    stand out
Expect  <-------------------  被啟動的程式
                    [expect xxx]



                  stand in
Expect  --------------------> 被啟動的程式
                  [send yyy]



所以這隻被 Expect 所啟動的程式,其實是不知道倒底是有一個『真正的人類』在和它互動,還是由另外一隻程式在和它互動。寫過文字模式 C 的程式的人都知道,console mode 程式就是透過 stand in 和 stand out 來輸入/輸出資料。

***
以上,和『自動安裝軟體』有何關係?當然有,因為 Expect 可以『騙』console mode 程式,假裝是『人』跟這些  console mode 程式在互動。所以如果所有需要安裝的軟體是可以透過 console mode 來安裝的話,那麼就可以寫 Expect scripts 來將這些安裝的工作自動化了。這個特性對於 automationtesting 都是非常有用滴。

不要小看 Expect,可以用它來佈署應用程式到大量(例如 1000 台)的電腦之中,或是幫 1000 人建 Linux 帳號並且改密碼,也可以幫只有 console mode 的程式建立一個 GUI 畫面,然後透過這個 GUI 畫面來控制原本 console mode 程式。還有很多,很多的應用,有興趣的鄉民們,可以參考 O'Reilly 出版的 Exploring Expect 這本書(500 多頁,還真厚)。

***
友藏內心獨白:學弟,要學起來喔。

沒有留言:

張貼留言