介紹 Flashback,一個互聯網模擬工具
在 LinkedIn,我們經常開發需要與第三方網站交互的 Web 應用程序。我們還採用自動測試,以確保我們的軟體在發布到生產環境之前的質量。然而,測試只是在它可靠時才有用。
考慮到這一點,有外部依賴關係的測試是有很大的問題的,例如在第三方網站上。這些外部網站可能會沒有通知地發生改變、遭受停機,或者由於互聯網的不可靠性暫時無法訪問。
如果我們的一個測試依賴於能夠與第三方網站通信,那麼任何故障的原因都很難確定。失敗可能是因為 LinkedIn 的內部變更、第三方網站的維護人員進行的外部變更,或網路基礎設施的問題。你可以想像,與第三方網站的交互可能會有很多失敗的原因,因此你可能想要知道,我將如何處理這個問題?
好消息是有許多互聯網模擬工具可以幫助。其中一個是 Betamax。它通過攔截 Web 應用程序發起的 HTTP 連接,之後進行重放的方式來工作。對於測試,Betamax 可以用以前記錄的響應替換 HTTP 上的任何交互,它可以非常可靠地提供這個服務。
最初,我們選擇在 LinkedIn 的自動化測試中使用 Betamax。它工作得很好,但我們遇到了一些問題:
- 出於安全考慮,我們的測試環境沒有接入互聯網。然而,與大多數代理一樣,Betamax 需要 Internet 連接才能正常運行。
- 我們有許多需要使用身份驗證協議的情況,例如 OAuth 和 OpenId。其中一些協議需要通過 HTTP 進行複雜的交互。為了模擬它們,我們需要一個複雜的模型來捕獲和重放請求。
為了應對這些挑戰,我們決定基於 Betamax 的思路,構建我們自己的互聯網模擬工具,名為 Flashback。我們也很自豪地宣布 Flashback 現在是開源的。
什麼是 Flashback?
Flashback 用於測試目的來模擬 HTTP 和 HTTPS 資源,如 Web 服務和 REST API。它記錄 HTTP/HTTPS 請求並重放以前記錄的 HTTP 事務 - 我們稱之為「 場景 」,這樣就不需要連接到 Internet 才能完成測試。
Flashback 也可以根據請求的部分匹配重放場景。它使用的是「匹配規則」。匹配規則將傳入請求與先前記錄的請求相關聯,然後將其用於生成響應。例如,以下代碼片段實現了一個基本匹配規則,其中測試方法「匹配」此 URL的傳入請求。
HTTP 請求通常包含 URL、方法、標頭和正文。Flashback 允許為這些組件的任意組合定義匹配規則。Flashback 還允許用戶向 URL 查詢參數,標頭和正文添加白名單或黑名單標籤。
例如,在 OAuth 授權流程中,請求查詢參數可能如下所示:
oauth_consumer_key="jskdjfljsdklfjlsjdfs",
oauth_nonce="ajskldfjalksjdflkajsdlfjasldfja;lsdkj",
oauth_signature="asdfjaklsdjflasjdflkajsdklf",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318622958",
oauth_token="asdjfkasjdlfajsdklfjalsdjfalksdjflajsdlfa",
oauth_version="1.0"
這些值許多將隨著每個請求而改變,因為 OAuth 要求客戶端每次為 oauth_nonce
生成一個新值。在我們的測試中,我們需要驗證 oauth_consumer_key
、oauth_signature_method
和 oauth_version
的值,同時確保 oauth_nonce
、oauth_signature
、oauth_timestamp
和 oauth_token
存在於請求中。Flashback 使我們有能力創建我們自己的匹配規則來實現這一目標。此功能允許我們測試隨時間變化的數據、簽名、令牌等的請求,而客戶端沒有任何更改。
這種靈活的匹配和在不連接互聯網的情況下運行的功能是 Flashback 與其他模擬解決方案不同的特性。其他一些顯著特點包括:
- Flashback 是一種跨平台和跨語言解決方案,能夠測試 JVM(Java虛擬機)和非 JVM(C++、Python 等)應用程序。
- Flashback 可以隨時生成 SSL/TLS 證書,以模擬 HTTPS 請求的安全通道。
如何記錄 HTTP 事務
使用 Flashback 記錄 HTTP 事務以便稍後重放是一個比較簡單的過程。在我們深入了解流程之前,我們首先列出一些術語:
Scene
:場景存儲以前記錄的 HTTP 事務 (以 JSON 格式),它可以在以後重放。例如,這裡是一個Flashback 場景示例。Root Path
:根路徑是包含 Flashback 場景數據的目錄的文件路徑。Scene Name
:場景名稱是給定場景的名稱。Scene Mode
:場景模式是使用場景的模式, 即「錄製」或「重放」。Match Rule
:匹配規則確定傳入的客戶端請求是否與給定場景的內容匹配的規則。Flashback Proxy
:Flashback 代理是一個 HTTP 代理,共有錄製和重放兩種操作模式。Host
和Port
:代理主機和埠。
為了錄製場景,你必須向目的地址發出真實的外部請求,然後 HTTPS 請求和響應將使用你指定的匹配規則存儲在場景中。在錄製時,Flashback 的行為與典型的 MITM(中間人)代理完全相同 - 只有在重放模式下,連接流和數據流僅限於客戶端和代理之間。
要實際看下 Flashback,讓我們創建一個場景,通過執行以下操作捕獲與 example.org 的交互:
1、 取回 Flashback 的源碼:
git clone https://github.com/linkedin/flashback.git
2、 啟動 Flashback 管理伺服器:
./startAdminServer.sh -port 1234
3、 注意上面的 Flashback 將在本地埠 5555 上啟動錄製模式。匹配規則需要完全匹配(匹配 HTTP 正文、標題和 URL)。場景將存儲在 /tmp/test1
下。
4、 Flashback 現在可以記錄了,所以用它來代理對 example.org 的請求:
curl http://www.example.org -x localhost:5555 -X GET
5、 Flashback 可以(可選)在一個記錄中記錄多個請求。要完成錄製,關閉 Flashback。
6、 要驗證已記錄的內容,我們可以在輸出目錄(/tmp/test1
)中查看場景的內容。它應該包含以下內容。
如何重放 HTTP 事務
要重放先前存儲的場景,請使用與錄製時使用的相同的基本設置。唯一的區別是將「場景模式」設置為上述步驟 3 中的「播放」。
驗證響應來自場景而不是外部源的一種方法,是在你執行步驟 1 到 6 時臨時禁用 Internet 連接。另一種方法是修改場景文件,看看響應是否與文件中的相同。
這是 Java 中的一個例子。
如何記錄並重播 HTTPS 事務
使用 Flashback 記錄並重放 HTTPS 事務的過程非常類似於 HTTP 事務的過程。但是,需要特別注意用於 HTTPS SSL 組件的安全證書。為了使 Flashback 作為 MITM 代理,必須創建證書頒發機構(CA)證書。在客戶端和 Flashback 之間創建安全通道時將使用此證書,並允許 Flashback 檢查其代理的 HTTPS 請求中的數據。然後將此證書存儲為受信任的源,以便客戶端在進行調用時能夠對 Flashback 進行身份驗證。有關如何創建證書的說明,有很多類似這樣的資源是非常有幫助的。大多數公司都有自己的管理和獲取證書的內部策略 - 請務必用你們自己的方法。
這裡值得一提的是,Flashback 僅用於測試目的。你可以隨時隨地將 Flashback 與你的服務集成在一起,但需要注意的是,Flashback 的記錄功能將需要存儲所有的數據,然後在重放模式下使用它。我們建議你特別注意確保不會無意中記錄或存儲敏感成員數據。任何可能違反貴公司數據保護或隱私政策的行為都是你的責任。
一旦涉及安全證書,HTTP 和 HTTPS 之間在記錄設置方面的唯一區別是添加了一些其他參數。
RootCertificateInputStream
: 表示 CA 證書文件路徑或流。RootCertificatePassphrase
: 為 CA 證書創建的密碼。CertificateAuthority
: CA 證書的屬性
查看 Flashback 中用於記錄 HTTPS 事務的代碼,它包括上述條目。
用 Flashback 重放 HTTPS 事務的過程與錄製相同。唯一的區別是場景模式設置為「播放」。這在此代碼中演示。
支持動態修改
為了測試靈活性,Flashback 允許你動態地更改場景和匹配規則。動態更改場景允許使用不同的響應(如 success
、time_out
、rate_limit
等)測試相同的請求。場景更改僅適用於我們已經 POST 更新外部資源的場景。以下圖為例。
![Scenarios where we have POSTed data to update the external resource.](/data/attachment/album/201710/15/215603k11skaj8jee8fjf1.jpg "Scenarios where we have POSTed data to update the external resource.")
能夠動態更改匹配規則可以使我們測試複雜的場景。例如,我們有一個使用情況,要求我們測試 Twitter 的公共和私有資源的 HTTP 調用。對於公共資源,HTTP 請求是不變的,所以我們可以使用 「MatchAll」 規則。然而,對於私人資源,我們需要使用 OAuth 消費者密碼和 OAuth 訪問令牌來簽名請求。這些請求包含大量具有不可預測值的參數,因此靜態 MatchAll 規則將無法正常工作。
使用案例
在 LinkedIn,Flashback 主要用於在集成測試中模擬不同的互聯網提供商,如下圖所示。第一張圖展示了 LinkedIn 生產數據中心內的一個內部服務,通過代理層,與互聯網提供商(如 Google)進行交互。我們想在測試環境中測試這個內部服務。
![Testing this internal service in a testing environment.](/data/attachment/album/201710/15/215603h9nbfc6b6z72b1fm.jpg "Testing this internal service in a testing environment.")
第二和第三張圖表展示了我們如何在不同的環境中錄製和重放場景。記錄發生在我們的開發環境中,用戶在代理啟動的同一埠上啟動 Flashback。從內部服務到提供商的所有外部請求將通過 Flashback 而不是我們的代理層。在必要場景得到記錄後,我們可以將其部署到我們的測試環境中。
![After the necessary scenes get recorded, we can deploy them to our test environment.](/data/attachment/album/201710/15/215604yr3fwqwqbazvzgwv.jpg "After the necessary scenes get recorded, we can deploy them to our test environment.")
在測試環境(隔離並且沒有 Internet 訪問)中,Flashback 在與開發環境相同的埠上啟動。所有 HTTP 請求仍然來自內部服務,但響應將來自 Flashback 而不是 Internet 提供商。
![Responses will come from Flashback instead of the Internet providers.](/data/attachment/album/201710/15/215604d83nijiy3t3y03wt.jpg "Responses will come from Flashback instead of the Internet providers.")
未來方向
我們希望將來可以支持非 HTTP 協議(如 FTP 或 JDBC),甚至可以讓用戶使用 MITM 代理框架來自行注入自己的定製協議。我們將繼續改進 Flashback 設置 API,使其更容易支持非 Java 語言。
現在為一個開源項目
我們很幸運能夠在 GTAC 2015 上發布 Flashback。在展會上,有幾名觀眾詢問是否將 Flashback 作為開源項目發布,以便他們可以將其用於自己的測試工作。
Google TechTalks:GATC 2015 - 模擬互聯網
我們很高興地宣布,Flashback 現在以 BSD 兩句版許可證開源。要開始使用,請訪問 Flashback GitHub 倉庫。
該文原始發表在LinkedIn 工程博客上。獲得轉載許可
致謝
Flashback 由 Shangshang Feng、Yabin Kang 和 Dan Vinegrad 創建,並受到 Betamax 啟發。特別感謝 Hwansoo Lee、Eran Leshem、Kunal Kandekar、Keith Dsouza 和 Kang Wang 幫助審閱代碼。同樣感謝我們的管理層 - Byron Ma、Yaz Shimizu、Yuliya Averbukh、Christopher Hazlett 和 Brandon Duncan - 感謝他們在開發和開源 Flashback 中的支持。
作者簡介:
Shangshang Feng - Shangshang 是 LinkedIn 紐約市辦公室的高級軟體工程師。在 LinkedIn 他從事了三年半的網關平台工作。在加入 LinkedIn 之前,他曾在 Thomson Reuters 和 ViewTrade 證券的基礎設施團隊工作。
via: https://opensource.com/article/17/4/flashback-internet-mocking-tool
作者: Shangshang Feng 譯者:geekpi 校對:jasminepeng
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive