我在之前的文章中介紹過(guò)SQLite,這是個(gè)嵌入式數(shù)據(jù)庫(kù),也是世界上最流行的數(shù)據(jù)庫(kù)。
![]()
(詳情參見(jiàn)這篇文章:)
有一天我突發(fā)奇想:既然是嵌入式數(shù)據(jù)庫(kù),那應(yīng)該不復(fù)雜,能不能用AI寫(xiě)一個(gè)?
說(shuō)干就干,我把SQLite的架構(gòu)文檔發(fā)給了AI,讓它根據(jù)現(xiàn)有架構(gòu)來(lái)實(shí)現(xiàn)。
你別說(shuō),AI實(shí)現(xiàn)得相當(dāng)不錯(cuò),把Tokenizer,Parser,Code Generator,Bytecode Engine這些核心的概念都考慮到了,代碼寫(xiě)得也不錯(cuò),著實(shí)是讓我吃驚。
![]()
但是,當(dāng)我看到SQLite的測(cè)試的時(shí)候,我就知道,現(xiàn)在的AI,想寫(xiě)出SQLite級(jí)別的代碼,恐怕是做夢(mèng)。
因?yàn)?strong>SQLite簡(jiǎn)直不是一個(gè)軟件,而是個(gè)怪物。
截至 3.42.0 版本(2023-05-16),SQLite 庫(kù)本身大約包含15.58萬(wàn)行C代碼。
而測(cè)試代碼和測(cè)試腳本腳本加起來(lái)一共有9205萬(wàn)行,是核心代碼的 590 倍!
不是5倍,50倍,而是590倍 !
測(cè)試的目標(biāo)不但要覆蓋“功能”,還要覆蓋分支,覆蓋異常,覆蓋現(xiàn)實(shí)世界的災(zāi)難。
SQLite設(shè)立了4套“互不信任”的測(cè)試體系,避免同一思路的盲區(qū)。
0 1
“保命”測(cè)試
首先,它用TCL寫(xiě)了一套“日常保命測(cè)試”,測(cè)試腳本有1390個(gè)文件,一共23.2M,包含了51,445 個(gè)不同的測(cè)試用例,參數(shù)化執(zhí)行,會(huì)跑出數(shù)百萬(wàn)測(cè)試。
開(kāi)發(fā)者日常主要依賴(lài)一個(gè)非常快的、幾分鐘就能跑完的子集,用于每次提交前自己檢查。
0 2
“徹底”測(cè)試
SQLite有一套私有的C語(yǔ)言測(cè)試系統(tǒng)(名稱(chēng)為T(mén)H3),為 SQLite 核心庫(kù)提供 100% 分支覆蓋率。
這個(gè)數(shù)字是非常恐怖的,大家都知道覆蓋所有分支很麻煩,例如這行代碼:
}想要達(dá)到100%分支覆蓋,至少需要3個(gè)測(cè)試用例:
(1) a<=b
(2) a>b 且 c==25
(3) a>b 且 c!=25
除了分支覆蓋,SQLite還是是實(shí)現(xiàn)了100% MC/DC 覆蓋率。
MC/DC(Modified Condition/Decision Coverage)是航空、核工業(yè)級(jí)別的測(cè)試標(biāo)準(zhǔn)。也就是說(shuō)SQLite 把一個(gè)嵌入式數(shù)據(jù)庫(kù),按飛控軟件的標(biāo)準(zhǔn)來(lái)測(cè)。
TH3有個(gè)非常重要的特點(diǎn),就是不靠“后門(mén)”,只是用SQLite公開(kāi)的API接口,完全模擬用戶(hù)的行為。
TH3 包含大約 76.9MB、100萬(wàn)行C 代碼,實(shí)現(xiàn)了 50,362 個(gè)不同測(cè)試用例。
在發(fā)布之前的一個(gè)長(zhǎng)時(shí)間壓力測(cè)試中,會(huì)執(zhí)行2.485億次測(cè)試。
0 3
對(duì)標(biāo)測(cè)試
這是一個(gè)裁判性測(cè)試,它將大量 SQL 語(yǔ)句同時(shí)運(yùn)行在 SQLite 和其他4個(gè)數(shù)據(jù)庫(kù)引擎(PostgreSQL、MySQL、SQL Server、Oracle 10g )上,并比較結(jié)果是否一致。
![]()
換句話(huà)說(shuō),SQLite 不只要自洽,還要和“行業(yè)共識(shí)”對(duì)齊。
這個(gè)測(cè)試共運(yùn)行 720 萬(wàn)條查詢(xún),測(cè)試數(shù)據(jù)總量 1.12GB。
0 4
模糊測(cè)試
模糊測(cè)試通過(guò)向SQLite提供無(wú)效、意外或者隨機(jī)數(shù)據(jù)來(lái)測(cè)試它的健壯性。
例如這樣的SQL語(yǔ)言:
CAST('999999999999999999999999' AS INTEGER) < 0;它完全符合SQL語(yǔ)法,但是幾乎不可能是人寫(xiě)的,因?yàn)樗珳?zhǔn)命中了“超大內(nèi)存申請(qǐng)”,“整數(shù)溢出”,“負(fù)索引”等極端情況。
更殘酷的是,模糊測(cè)試還會(huì)破壞數(shù)據(jù)庫(kù)文件(.db),對(duì)它做隨機(jī)位翻轉(zhuǎn)、截?cái)唷⒅貜?fù)、拼接。
例如,這是原始的數(shù)據(jù)文件(簡(jiǎn)化):
[Header][Page1][Page2][Page3]
模糊測(cè)試工具把它改成:
[Header][Page1][Page1][亂碼][Page3][Page3]
然后嘗試去打開(kāi)它:
sqlite3_open("mutated.db", &db);
SQLite要做到不崩潰,不越界,不死循環(huán),要么報(bào)錯(cuò),要么優(yōu)雅失敗。
最后,模糊測(cè)試還會(huì)開(kāi)關(guān)所有的宏定義,對(duì)不同的編譯器設(shè)置不同的編譯優(yōu)化級(jí)別,讓同一條SQL在不同的情況下瘋狂運(yùn)行,瘋狂地鞭打SQLite,折磨SQLite,直到它漏出所有的破綻。
由于SQLite在嵌入式領(lǐng)域非常流行,手機(jī)、路由器、車(chē)載、工業(yè)設(shè)備等在大量使用它,所以它特別注重對(duì)異常情況的處理。
內(nèi)存不足測(cè)試
在服務(wù)器和工作站上,內(nèi)存分配malloc()幾乎不會(huì)失敗,在嵌入式設(shè)備上,OOM就太常見(jiàn)了,SQLite必須得能優(yōu)雅的處理OOM錯(cuò)誤。
SQLite的測(cè)試框架(自己寫(xiě)的)可以插入自定義的可控的malloc函數(shù),設(shè)置成在調(diào)用一定次數(shù)后內(nèi)存分配失敗,這樣就可以在循環(huán)中執(zhí)行SQLite操作,確保能處理OOM錯(cuò)誤。
I/O錯(cuò)誤測(cè)試
磁盤(pán)空間不足、磁盤(pán)硬件故障、網(wǎng)絡(luò)中斷、SQL操作過(guò)程中發(fā)生的系統(tǒng)配置或權(quán)限更改,或其他硬件或操作系統(tǒng)故障......無(wú)論原因如何,SQLite 必須能夠正確響應(yīng)這些錯(cuò)誤。
測(cè)試的方法和OOM測(cè)試類(lèi)似,都是模擬I/O錯(cuò)誤,然后檢查SQLite能否正確響應(yīng)
崩潰測(cè)試
應(yīng)用系統(tǒng)崩潰,操作系統(tǒng)崩潰,數(shù)據(jù)庫(kù)更新過(guò)程中斷電,SQLite都不能發(fā)生故障。
這也是SQLite“原子提交”能被信任的原因。
復(fù)合失效測(cè)試
先發(fā)生I/O錯(cuò)誤,然后出現(xiàn)OOM,再搞一個(gè)崩潰..... 保證程序還能正常運(yùn)行。
SQLite的這些測(cè)試,它的數(shù)量、完善程度和復(fù)雜程度,看起來(lái)真是讓人脊背發(fā)涼。
這得付出多年的努力,經(jīng)歷多少事故才能寫(xiě)出來(lái)啊!
被這樣測(cè)試保護(hù)的軟件,代碼質(zhì)量可以說(shuō)是固若金湯了。
AI能寫(xiě)出這樣高質(zhì)量的SQLite嗎?
寫(xiě)個(gè)玩具版是可以的,但是想要復(fù)刻是萬(wàn)萬(wàn)不行的。
SQLite這種“高質(zhì)量”不是體現(xiàn)在代碼本身,而是體現(xiàn)在幾十年積累的測(cè)試體系、失敗經(jīng)驗(yàn)和工程紀(jì)律上。
AI 可以幫助我們寫(xiě)實(shí)現(xiàn)、補(bǔ)測(cè)試、找 bug,但無(wú)法憑空生成那些來(lái)自真實(shí)事故、長(zhǎng)期演化出來(lái)的異常場(chǎng)景和驗(yàn)證策略。
換句話(huà)說(shuō),AI 能參與寫(xiě) SQLite,但還不能“獨(dú)立孕育”一個(gè) SQLite。
SQLite只是一個(gè)嵌入式數(shù)據(jù)庫(kù),就已經(jīng)恐怖如斯了,那些更加復(fù)雜的數(shù)據(jù)庫(kù)會(huì)怎么樣呢?
歡迎了解詳情的朋友在評(píng)論區(qū)留言!
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶(hù)上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.