.. SPDX-License-Identifier: GPL-2.0 .. include:: ../disclaimer-zh_TW.rst :Original: Documentation/dev-tools/testing-overview.rst :Translator: 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn> ============ å…§æ ¸æ¸¬è©¦æŒ‡å— ============ 有許多ä¸åŒçš„工具å¯ä»¥ç”¨æ–¼æ¸¬è©¦Linuxå…§æ ¸ï¼Œå› æ¤çžè§£ä»€éº¼æ™‚候使用它們å¯èƒ½ 很困難。本文檔粗略概述了它們之間的å€åˆ¥ï¼Œä¸¦é—¡é‡‹äº†å®ƒå€‘是怎樣糅åˆåœ¨ä¸€èµ· 的。 編寫和é‹è¡Œæ¸¬è©¦ ============== å¤§å¤šæ•¸å…§æ ¸æ¸¬è©¦éƒ½æ˜¯ç”¨kselftest或KUnit框架之一編寫的。它們都讓é‹è¡Œæ¸¬è©¦ æ›´åŠ ç°¡åŒ–ï¼Œä½µçˆ²ç·¨å¯«æ–°æ¸¬è©¦æ供幫助。 å¦‚æžœä½ æƒ³é©—è‰å…§æ ¸çš„è¡Œçˆ²â€”â€”å°¤å…¶æ˜¯å…§æ ¸çš„ç‰¹å®šéƒ¨åˆ†â€”â€”é‚£ä½ å°±è¦ä½¿ç”¨kUnit或 kselftest。 KUnitå’Œkselftestçš„å€åˆ¥ ---------------------- .. note:: 由於本文段ä¸éƒ¨åˆ†è¡“語尚無較好的å°æ‡‰ä¸æ–‡é‡‹ç¾©ï¼Œå¯èƒ½å°Žè‡´èˆ‡åŽŸæ–‡å«ç¾© å˜åœ¨äº›è¨±å·®ç•°ï¼Œå› æ¤å»ºè°è®€è€…çµåˆåŽŸæ–‡ (Documentation/dev-tools/testing-overview.rst)輔助閱讀。 如å°éƒ¨åˆ†ç¿»è¯æœ‰ç•°è°æˆ–有更好的翻è¯æ„見,æ¡è¿Žè¯ç¹«è¯è€…進行修訂。 KUnit(Documentation/dev-tools/kunit/index.rst)是用於“白箱â€æ¸¬ è©¦çš„ä¸€å€‹å®Œæ•´çš„å…§æ ¸å…§éƒ¨ç³»çµ±ï¼šå› çˆ²æ¸¬è©¦ä»£ç¢¼æ˜¯å…§æ ¸çš„ä¸€éƒ¨åˆ†ï¼Œæ‰€ä»¥å®ƒèƒ½å¤ è¨ª å•ç”¨æˆ¶ç©ºé–“ä¸èƒ½è¨ªå•åˆ°çš„內部çµæ§‹å’ŒåŠŸèƒ½ã€‚ å› æ¤ï¼ŒKUnit測試最好é‡å°å…§æ ¸ä¸è¼ƒå°çš„ã€è‡ªåŒ…å«çš„éƒ¨åˆ†ï¼Œä»¥ä¾¿èƒ½å¤ ç¨ç«‹åœ°æ¸¬ 試。“單元â€æ¸¬è©¦çš„概念亦是如æ¤ã€‚ 比如,一個KUnit測試å¯èƒ½æ¸¬è©¦ä¸€å€‹å–®ç¨çš„å…§æ ¸åŠŸèƒ½ï¼ˆç”šè‡³é€šéŽä¸€å€‹å‡½æ•¸æ¸¬è©¦ 一個單一的代碼路徑,例如一個錯誤處ç†æ¡ˆä¾‹ï¼‰ï¼Œè€Œä¸æ˜¯æ•´å€‹åœ°æ¸¬è©¦ä¸€å€‹ç‰¹æ€§ã€‚ 這也使得KUnit測試構建和é‹è¡Œéžå¸¸åœ°å¿«ï¼Œå¾žè€Œèƒ½å¤ 作爲開發æµç¨‹çš„一部分被 é »ç¹åœ°é‹è¡Œã€‚ 有關更詳細的介紹,請åƒé–±KUnitæ¸¬è©¦ä»£ç¢¼é¢¨æ ¼æŒ‡å— Documentation/dev-tools/kunit/style.rst kselftest(Documentation/dev-tools/kselftest.rst),相å°ä¾†èªªï¼Œå¤§é‡ç”¨ 於用戶空間,並且通常測試用戶空間的腳本或程åºã€‚ 這使得編寫複雜的測試,或者需è¦æ“ä½œæ›´å¤šå…¨å±€ç³»çµ±ç‹€æ…‹çš„æ¸¬è©¦æ›´åŠ å®¹æ˜“ï¼ˆè«¸ 如生æˆé€²ç¨‹ä¹‹é¡žï¼‰ã€‚然而,從kselftestç›´æŽ¥èª¿ç”¨å…§æ ¸å‡½æ•¸æ˜¯ä¸è¡Œçš„。這也就 æ„味ç€åªæœ‰é€šéŽæŸç¨®æ–¹å¼ï¼ˆå¦‚系統調用ã€é©…å‹•è¨å‚™ã€æ–‡ä»¶ç³»çµ±ç‰ï¼‰å°Žå‡ºåˆ°äº†ç”¨ æˆ¶ç©ºé–“çš„å…§æ ¸åŠŸèƒ½æ‰èƒ½ä½¿ç”¨kselftest來測試。爲æ¤ï¼Œæœ‰äº›æ¸¬è©¦åŒ…å«äº†ä¸€å€‹ä¼´ ç”Ÿçš„å…§æ ¸æ¨¡å¡Šç”¨æ–¼å°Žå‡ºæ›´å¤šçš„ä¿¡æ¯å’ŒåŠŸèƒ½ã€‚ä¸éŽï¼Œå°æ–¼åŸºæœ¬ä¸Šæˆ–è€…å®Œå…¨åœ¨å…§æ ¸ ä¸é‹è¡Œçš„測試,KUnitå¯èƒ½æ˜¯æ›´ä½³å·¥å…·ã€‚ kselftestä¹Ÿå› æ¤éžå¸¸é©åˆæ–¼å…¨éƒ¨åŠŸèƒ½çš„æ¸¬è©¦ï¼Œå› çˆ²é€™äº›åŠŸèƒ½æœƒå°‡æŽ¥å£æš´éœ²åˆ° ç”¨æˆ¶ç©ºé–“ï¼Œå¾žè€Œèƒ½å¤ è¢«æ¸¬è©¦ï¼Œè€Œä¸æ˜¯å±•ç¾å¯¦ç¾ç´°ç¯€ã€‚“systemâ€æ¸¬è©¦å’Œ “end-to-endâ€æ¸¬è©¦äº¦æ˜¯å¦‚æ¤ã€‚ 比如,一個新的系統調用應該伴隨有新的kselftest測試。 代碼覆蓋率工具 ============== 支æŒå…©ç¨®ä¸åŒä»£ç¢¼ä¹‹é–“的覆蓋率測é‡å·¥å…·ã€‚它們å¯ä»¥ç”¨ä¾†é©—è‰ä¸€é …測試執行的 ç¢ºåˆ‡å‡½æ•¸æˆ–ä»£ç¢¼è¡Œã€‚é€™æœ‰åŠ©æ–¼æ±ºå®šå…§æ ¸è¢«æ¸¬è©¦äº†å¤šå°‘ï¼Œæˆ–ç”¨ä¾†æŸ¥æ‰¾åˆé©çš„測試 ä¸æ²’有覆蓋到的極端情æ³ã€‚ Documentation/translations/zh_CN/dev-tools/gcov.rst 是GCC的覆蓋率測試 工具,能用於ç²å–å…§æ ¸çš„å…¨å±€æˆ–æ¯å€‹æ¨¡å¡Šçš„覆蓋率。與KCOVä¸åŒçš„是,這個工具 ä¸è¨˜éŒ„æ¯å€‹ä»»å‹™çš„覆蓋率。覆蓋率數據å¯ä»¥é€šéŽdebugfs讀å–,並通éŽå¸¸è¦çš„ gcov工具進行解釋。 Documentation/dev-tools/kcov.rst æ˜¯èƒ½å¤ æ§‹å»ºåœ¨å…§æ ¸ä¹‹ä¸ï¼Œç”¨æ–¼åœ¨æ¯å€‹ä»»å‹™ 的層é¢æ•æ‰è¦†è“‹çŽ‡çš„ä¸€å€‹åŠŸèƒ½ã€‚å› æ¤ï¼Œå®ƒå°æ–¼æ¨¡ç³Šæ¸¬è©¦å’Œé—œæ–¼ä»£ç¢¼åŸ·è¡ŒæœŸé–“ä¿¡ æ¯çš„其它情æ³éžå¸¸æœ‰ç”¨ï¼Œæ¯”如在一個單一系統調用è£ä½¿ç”¨å®ƒå°±å¾ˆæœ‰ç”¨ã€‚ 動態分æžå·¥å…· ============ å…§æ ¸ä¹Ÿæ”¯æŒè¨±å¤šå‹•æ…‹åˆ†æžå·¥å…·ï¼Œç”¨ä»¥æª¢æ¸¬æ£åœ¨é‹è¡Œçš„å…§æ ¸ä¸å‡ºç¾çš„多種類型的 å•é¡Œã€‚這些工具通常æ¯å€‹åŽ»å°‹æ‰¾ä¸€é¡žä¸åŒçš„缺陷,比如éžæ³•å…§å˜è¨ªå•ï¼Œæ•¸æ“šç«¶ çˆç‰ä½µç™¼å•é¡Œï¼Œæˆ–整型溢出ç‰å…¶ä»–未定義行爲。 如下所示: * kmemleak檢測å¯èƒ½çš„å…§å˜æ³„æ¼ã€‚åƒé–± Documentation/dev-tools/kmemleak.rst * KASAN檢測éžæ³•å…§å˜è¨ªå•ï¼Œå¦‚數組越界和釋放後é‡ç”¨ï¼ˆUAF)。åƒé–± Documentation/dev-tools/kasan.rst * UBSAN檢測C標準ä¸æœªå®šç¾©çš„行爲,如整型溢出。åƒé–± Documentation/dev-tools/ubsan.rst * KCSAN檢測數據競çˆã€‚åƒé–± Documentation/dev-tools/kcsan.rst * KFENCE是一個低開銷的內å˜å•é¡Œæª¢æ¸¬å™¨ï¼Œæ¯”KASAN更快且能被用於批é‡æ§‹å»ºã€‚ åƒé–± Documentation/dev-tools/kfence.rst * lockdep是一個鎖定æ£ç¢ºæ€§æª¢æ¸¬å™¨ã€‚åƒé–± Documentation/locking/lockdep-design.rst * 除æ¤ä»¥å¤–ï¼Œåœ¨å…§æ ¸ä¸é‚„有一些其它的調試工具,大多數能在 lib/Kconfig.debug ä¸æ‰¾åˆ°ã€‚ 這些工具傾å‘æ–¼å°å…§æ ¸é€²è¡Œæ•´é«”測試,並且ä¸åƒkselftestå’ŒKUnit一樣“傳éžâ€ã€‚ 它們å¯ä»¥é€šéŽåœ¨å•“用這些工具時é‹è¡Œå…§æ ¸æ¸¬è©¦ä»¥èˆ‡kselftest或KUnitçµåˆèµ·ä¾†ï¼š ä¹‹å¾Œä½ å°±èƒ½ç¢ºä¿é€™äº›éŒ¯èª¤åœ¨æ¸¬è©¦éŽç¨‹ä¸éƒ½ä¸æœƒç™¼ç”Ÿäº†ã€‚ 一些工具與KUnitå’Œkselftest集æˆï¼Œä¸¦ä¸”在檢測到å•é¡Œæ™‚會自動打斷測試。 éœæ…‹åˆ†æžå·¥å…· ============ 除了測試é‹è¡Œä¸çš„å…§æ ¸ï¼Œæˆ‘å€‘é‚„å¯ä»¥ä½¿ç”¨**éœæ…‹åˆ†æž**工具直接分æžå…§æ ¸çš„æºä»£ 碼(**在編è¯æ™‚**ï¼‰ã€‚å…§æ ¸ä¸å¸¸ç”¨çš„工具å…許人們檢查整個æºä»£ç¢¼æ¨¹æˆ–å…¶ä¸çš„特 定文件。它們使得在開發éŽç¨‹ä¸æ›´å®¹æ˜“發ç¾å’Œä¿®å¾©å•é¡Œã€‚ Sparseå¯ä»¥é€šéŽåŸ·è¡Œé¡žåž‹æª¢æŸ¥ã€éŽ–檢查ã€å€¼ç¯„åœæª¢æŸ¥ä¾†å¹«åŠ©æ¸¬è©¦å…§æ ¸ï¼Œæ¤å¤–é‚„ å¯ä»¥åœ¨æª¢æŸ¥ä»£ç¢¼æ™‚å ±å‘Šå„種錯誤和è¦å‘Šã€‚關於如何使用它的細節,請åƒé–± Documentation/translations/zh_CN/dev-tools/sparse.rst。 Smatch擴展了Sparse,並æ供了å°ç·¨ç¨‹é‚輯錯誤的é¡å¤–檢查,如開關語å¥ä¸ 缺少斷點,錯誤檢查ä¸æœªä½¿ç”¨çš„返回值,忘記在錯誤路徑的返回ä¸è¨ç½®éŒ¯èª¤ä»£ 碼ç‰ã€‚Smatch也有é‡å°æ›´åš´é‡å•é¡Œçš„測試,如整數溢出ã€ç©ºæŒ‡é‡è§£é™¤å¼•ç”¨å’Œå…§ å˜æ³„æ¼ã€‚è¦‹é …ç›®é é¢http://smatch.sourceforge.net/。 Coccinelle是我們å¯ä»¥ä½¿ç”¨çš„å¦ä¸€å€‹éœæ…‹åˆ†æžå™¨ã€‚Coccinelle經常被用來 幫助æºä»£ç¢¼çš„é‡æ§‹å’Œä¸¦è¡Œæ¼”化,但它也å¯ä»¥å¹«åŠ©é¿å…常見代碼模å¼ä¸å‡ºç¾çš„æŸ äº›éŒ¯èª¤ã€‚å¯ç”¨çš„測試類型包括API測試ã€å…§æ ¸è¿ä»£å™¨çš„æ£ç¢ºä½¿ç”¨æ¸¬è©¦ã€è‡ªç”±æ“ 作的åˆç†æ€§æª¢æŸ¥ã€éŽ–定行爲的分æžï¼Œä»¥åŠå·²çŸ¥çš„有助於ä¿æŒå…§æ ¸ä½¿ç”¨ä¸€è‡´æ€§çš„ 進一æ¥æ¸¬è©¦ã€‚詳情請見Documentation/dev-tools/coccinelle.rst。 ä¸éŽè¦æ³¨æ„的是,éœæ…‹åˆ†æžå·¥å…·å˜åœ¨**å‡é™½æ€§**çš„å•é¡Œã€‚åœ¨è©¦åœ–ä¿®å¾©éŒ¯èª¤å’Œè¦ å‘Šä¹‹å‰ï¼Œéœ€è¦ä»”細評估它們。 何時使用Sparseå’ŒSmatch ---------------------- Sparseåšé¡žåž‹æª¢æŸ¥ï¼Œä¾‹å¦‚é©—è‰è¨»é‡‹çš„變é‡ä¸æœƒå°Žè‡´ç„¡ç¬¦è™Ÿçš„錯誤,檢測 ``__user`` 指é‡ä½¿ç”¨ä¸ç•¶çš„地方,以åŠåˆ†æžç¬¦è™Ÿåˆå§‹åŒ–器的兼容性。 Smatch進行æµç¨‹åˆ†æžï¼Œå¦‚æžœå…許建立函數數據庫,它還會進行跨函數分æžã€‚ Smatch試圖回ç”一些å•é¡Œï¼Œæ¯”如這個緩è¡å€æ˜¯åœ¨å“ªè£åˆ†é…的?它有多大?這 個索引å¯ä»¥ç”±ç”¨æˆ¶æŽ§åˆ¶å—Žï¼Ÿé€™å€‹è®Šé‡æ¯”那個變é‡å¤§å—Žï¼Ÿ 一般來說,在Smatchä¸å¯«æª¢æŸ¥æ¯”在Sparseä¸å¯«æª¢æŸ¥è¦å®¹æ˜“。儘管如æ¤ï¼Œ Sparseå’ŒSmatch的檢查還是有一些é‡ç–Šçš„地方。 Smatchå’ŒCoccinelleçš„å¼·é … ------------------------ Coccinelleå¯èƒ½æ˜¯æœ€å®¹æ˜“寫檢查的。它在é 處ç†å™¨ä¹‹å‰å·¥ä½œï¼Œæ‰€ä»¥ç”¨Coccinelle 檢查å®ä¸çš„錯誤更容易。Coccinelleé‚„èƒ½çˆ²ä½ å‰µå»ºè£œä¸ï¼Œé€™æ˜¯å…¶ä»–工具無法åšåˆ°çš„。 例如,用Coccinelleä½ å¯ä»¥å¾ž ``kmalloc_array(x, size, GFP_KERNEL)`` 到 ``kmalloc_array(x, size, GFP_KERNEL)`` 進行大è¦æ¨¡è½‰æ›ï¼Œé€™çœŸçš„很 æœ‰ç”¨ã€‚å¦‚æžœä½ åªæ˜¯å‰µå»ºä¸€å€‹Smatchè¦å‘Šï¼Œä¸¦è©¦åœ–把轉æ›çš„工作推給ç¶è·è€…,他們會很 惱ç«ã€‚ä½ å°‡ä¸å¾—ä¸çˆ²æ¯å€‹è¦å‘Šçˆè«–是å¦çœŸçš„å¯ä»¥æº¢å‡ºã€‚ Coccinelleä¸å°è®Šé‡å€¼é€²è¡Œåˆ†æžï¼Œè€Œé€™æ£æ˜¯Smatchçš„å¼·é …ã€‚å¦ä¸€æ–¹é¢ï¼ŒCoccinelle å…è¨±ä½ ç”¨ç°¡å–®çš„æ–¹æ³•åšç°¡å–®çš„事情。