.. SPDX-License-Identifier: GPL-2.0 .. include:: ../disclaimer-zh_CN.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 * è¿è¡Œæ—¶ç¡®è®¤ï¼ˆRuntime Verification)支æŒæ£€æŸ¥ç»™å®šå系统的特定行为。å‚阅 Documentation/trace/rv/runtime-verification.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 å…è®¸ä½ ç”¨ç®€å•çš„方法åšç®€å•çš„事情。