Databend 是一個使用 Rust 研發、開源的、完全面向雲架構的新式數倉,致力於提供極速的彈性擴充套件能力,打造按需、按量的 Data Cloud 產品體驗。

開源地址:

https://

github。com/datafuselabs

/databend

Databend 從第一天就是開源的,測試系統也是基於開源生態所構建,比如使用了大量的 github CI(免費),已經支撐了我們半年來的快速迭代。

對於一個開源資料庫專案,做到可測試性是加速迭代的不二法寶。一個 Pull Request (通常說的 Patch) 從提交到合併到主幹分支,作為一個 Review 人員會比較關注以下幾個問題:

是否會導致功能不正常?

是否會影響分散式執行?

是否有跨平臺編譯問題?

是否會導致效能下降?

本篇就從一個 Pull Request 測試周期說起,看看它從建立再到合併入主幹分支,Databend 經過了哪些測試,針對上面四個問題做到心中有數,讓每個 Pull Request 都有質量保障。

單元測試

單元測試是最小的測試單元。

我們每寫一個函式都要做到可獨立測試,如果這個函式有其他狀態依賴,那狀態也要是可以 Mock 的。

在 Databend 中,單元測試都放在一個獨立的檔案中,比如,x_test。rs:

#[test]

fn test_y() -> Result<()> {

。。。 。。。

}

目前 Databend 有 500+ 的單元測試,並對一些狀態做了全域性 Mock,讓開發者更加容易的編寫測試用例,以從程式碼層面確保函式執行都符合預期,儘早的發現和解決問題。

Databend 的單元測試會在 Ubuntu 和 MacOS 兩個系統上執行 (Databend 研發主要使用 Mac 和 Ubuntu 兩個主力系統)。

Rust, Databend and the Cloud Warehouse(3)Databend 社群如何做測試

功能測試

當單元測試通過後,並不一定保證功能是正確的,因為功能通常來說是由多個函式邏輯性的貫穿而成。

功能測試又分為 Stateless 和 Stateful 兩種模型,其中 Stateless 測試模型不需要載入資料集, Stateful 測試模型則需要載入預值的資料集,接下來我們著重看下 Stateless 測試模型。 Databend 參考了 ClickHouse 的做法,使用表函式

numbers_mt

來便捷的做 Stateless 測試。

比如這個稍微“複雜”的SQL:

SELECT number%3 as c1, number%2 as c2 FROM numbers_mt(10000) WHERE number > 2 GROUP BY number%3, number%2 ORDER BY c1, c2;

它先根據條件過濾資料,然後再進行 GROUP BY 分組,最後做一個排序,這個 SQL 執行時,會涉及非常多的函式,所以我們必須有一套便捷的機制來保證多個函式組成的功能也是正確的。

Databend 是如何做的呢?

我們會先定義一個需要測試的 SQL 集,x。sql:

SELECT number%3 as c1, number%2 as c2 FROM numbers_mt(10000) WHERE number > 2 GROUP BY number%3, number%2 ORDER BY c1, c2;

然後再定義一個預期的結果集,x。result:

0 0

0 1

1 0

1 1

2 0

2 1

每次做功能測試的時候,Databend 會呼叫這個 x。sql 檔案,然後把得到的結果集和 x。result 檔案進行對比,如果有出入則報錯並給出提示資訊。

由於 Databend 具備分散式的 MPP 能力,所以功能測試會在單機(Standalone)和 叢集(Cluster)兩種模式下進行迴歸測試,以確保 Patch 對功能沒有影響。

Rust, Databend and the Cloud Warehouse(3)Databend 社群如何做測試

效能測試

當單元測試和功能測試都通過後,我們還會關注一個重要的指標:這個 Patch 是否導致效能下降?或者是一個性能最佳化的 Patch 提升了多少效能?

針對這個問題,Databend 使用數字來做量化,我們只需在 Pull Request 裡回覆:

/run-perf master

CI 會自動編譯當前分支然後跑相應的效能測試,再跟 master 做對比並生成一份效能對比報告:

Rust, Databend and the Cloud Warehouse(3)Databend 社群如何做測試

這樣,Review 人員就可以根據這個報告清晰的知道當前 Patch 對效能的影響,以確保每個 Patch 在效能上都是可控的。

編譯測試

Databend 目標是打造一個跨平臺的 Cloud Warehouse,所以要求每個 Patch 在以下幾個平臺都可以正常編譯和工作:

- {os: ubuntu-latest, toolchain: stable, target: x86_64-unknown-linux-gnu, cross: false}

- {os: ubuntu-latest, toolchain: stable, target: aarch64-unknown-linux-gnu, cross: true}

- {os: ubuntu-latest, toolchain: stable, target: arm-unknown-linux-gnueabi, cross: true}

- {os: ubuntu-latest, toolchain: stable, target: armv7-unknown-linux-gnueabihf, cross: true}

- {os: macos-latest, toolchain: stable, target: x86_64-apple-darwin, cross: false}

當這個 CI 跑完後,我們可以明確的知道當前 Patch 對跨版本編譯是沒有影響的。

小結

Rust, Databend and the Cloud Warehouse(3)Databend 社群如何做測試

以上所有的 CI 測試都通過後,我們的 Pull Request 才算合格,具備合併到主幹分支的條件。

如果沒有這些自動化測試 CI 做保障,每個問題都會消耗 Review 人員大量的精力去做驗證,這種模式肯定不可持久,嚴重影響產品的迭代速度,拖慢社群的節奏。

Databend 從第一天開始就在努力打造一個可測試的系統,為此我們研發了 test-infra 以及社群協作的 fusebot 機器人,以加速 Databend 產品迭代,儘快提供一個可試用的 Alpha 版本。

References

Databend: A Modern Real-Time Data Processing & Analytics DBMS with Cloud-Native Architecture

Databend Github Workflows

Databend Test Infra

Databend FuseBots

ClickHouse Testing