From nobody Wed Apr 8 04:56:55 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 280C6FA373D for ; Sun, 23 Oct 2022 12:55:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230329AbiJWMz1 (ORCPT ); Sun, 23 Oct 2022 08:55:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59790 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229973AbiJWMzW (ORCPT ); Sun, 23 Oct 2022 08:55:22 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D00D72656D; Sun, 23 Oct 2022 05:55:20 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id t10-20020a17090a4e4a00b0020af4bcae10so6990185pjl.3; Sun, 23 Oct 2022 05:55:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Ixa9Q2USMZVhIzGh4MBP10w3G2Xm+tYD7e/S5JSlY6c=; b=YZub1opvBM/rm6EqBO8wWMRkXO0TGkK8l3eH2nAwSo85z0HdbKN71E4SYDEIyXbrlE ODmYJ0TA3mad6Mc1FkbGFLcTUH8nOiCi4+gjBG+Tm4cD8kQV+UOUPsATsDzD7E3d6Ace f2vRe3EKwaii8riit++oU1/kl6XgruIGEZjHeaklyBktySa2CF+v4ikF2s/Wi5swTJi2 phYRb8pWH3ka2AV+c61igG077f3KIlPfZBPbJ/TkI5cvxolGfvPhU09fuMNdW2TNJGSm V085xLxEY9sJOgCIfaFed+GORrJROv0/PCSuTlzYQzFn4E5X9U96th+7AvRqUF+eIijA NdUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ixa9Q2USMZVhIzGh4MBP10w3G2Xm+tYD7e/S5JSlY6c=; b=qKjYLKBTfz7YJKflnBkapZbVKPpAWJ/CpU10i2DqOm2fZj/AJ1dG5JSxNPj8nCJ/28 2Dp/bhokX6hDWIaHftEvy652F9tJSCTvKuHjLSQrgvKcBbdmZ5HPDkQVJ0CUn6tnbKP3 K8jZ6rxbWGvPtY4bJfzJN72jGFkX631saiXlDYXXuZNWdRxtaCqBTF+WFmOHkdfgeBOn vsgyFmrI9bzD5lQsxSJ4DAu2KRxI6rlIcZuV4VeIValHxZnLg4kd+TFz6xHuOLW4XQhv uhU/2utqOIW21eu+FUEJ5rylrNUy9B1Q6Nke0O6t/TcfbyrExWX5xjjoZuk6zWyW114T F+yg== X-Gm-Message-State: ACrzQf1v6yrWCxfHhbxNPME1WG5vjn+Gla+wDbvE0reyh+p8U5oQsIG/ cE+Q9NJs5NE6+zEO4prpqtgRhGX71/N0Ew== X-Google-Smtp-Source: AMsMyM7L0BQT9FIqmjZfswd+mcRO/+OClgxBzUaBq79YZsJrik0fd7hKcvwkRrQPmjxilmdAyb93aA== X-Received: by 2002:a17:903:18b:b0:185:43e6:20df with SMTP id z11-20020a170903018b00b0018543e620dfmr27969785plg.4.1666529720134; Sun, 23 Oct 2022 05:55:20 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id om10-20020a17090b3a8a00b00212daa68b7csm2670639pjb.44.2022.10.23.05.55.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 05:55:19 -0700 (PDT) From: Bagas Sanjaya To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com Cc: Jonathan Corbet , Brendan Higgins , David Gow , Lukas Bulwahn , Khalid Masum , Sadiya Kazi , Bagas Sanjaya Subject: [PATCH 1/7] Documentation: kunit: rewrite "Writing Your First Test" section Date: Sun, 23 Oct 2022 19:54:08 +0700 Message-Id: <20221023125414.60961-2-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023125414.60961-1-bagasdotme@gmail.com> References: <20221023125414.60961-1-bagasdotme@gmail.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3749; i=bagasdotme@gmail.com; h=from:subject; bh=g91P+iZ/B5WmHtrZ4ClqKE+RwGXIgqSSfN3JfN7FHdA=; b=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhljmeKW8/XWvk3//0R7jbIUUDdU8W3Yb1EwOalNd/2R98 qmN5RykLgxgHg6yYIsukRL6m07uMRC60r3WEmcPKBDKEgYtTACZyxZqR4Wa54K8HPI6unk3RCt4OEe 6lcsVr53wK/b8+PMRgbW/9MUaGs94H796Mu16y4EjEu0VTt9n9vel6geFYr8yTJbq5G98t4gcA X-Developer-Key: i=bagasdotme@gmail.com; a=openpgp; fpr=701B806FDCA5D3A58FFB8F7D7C276C64A5E44A1D Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The "Writing Your First Test" section in "Getting Started" documentation have wordings that need to be tweaked for clarity and reducing redundancy. Rewrite the section. Signed-off-by: Bagas Sanjaya --- Documentation/dev-tools/kunit/start.rst | 34 +++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-to= ols/kunit/start.rst index f4f504f1fb154f..590e25166efb0d 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -179,15 +179,19 @@ are built-in. Otherwise the module will need to be lo= aded. =20 Writing Your First Test =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -In your kernel repository, let's add some code that we can test. +In this tutorial, you will learn how to write and test a simple driver +which performs addition of two integers. =20 -1. Create a file ``drivers/misc/example.h``, which includes: +1. First, write the driver implementation. Follow the below steps. + + a. Create a new header file ``drivers/misc/example.h`` and add the + prototype for ``misc_example_add()``: =20 .. code-block:: c =20 int misc_example_add(int left, int right); =20 -2. Create a file ``drivers/misc/example.c``, which includes: + b. Write the function implementation in ``drivers/misc/example.c``: =20 .. code-block:: c =20 @@ -200,22 +204,25 @@ In your kernel repository, let's add some code that w= e can test. return left + right; } =20 -3. Add the following lines to ``drivers/misc/Kconfig``: + c. In order for the driver to be selected, add configuration entry to + ``drivers/misc/Kconfig``: =20 .. code-block:: kconfig =20 config MISC_EXAMPLE bool "My example" =20 -4. Add the following lines to ``drivers/misc/Makefile``: + d. Last but not least, append the make goal to ``drivers/misc/Makefile`` + so that the driver can be built: =20 .. code-block:: make =20 obj-$(CONFIG_MISC_EXAMPLE) +=3D example.o =20 -Now we are ready to write the test cases. +2. Write the test suite that covers the driver functionality. Follow the + steps below: =20 -1. Add the below test case in ``drivers/misc/example_test.c``: + a. Write the test in ``drivers/misc/example_test.c``: =20 .. code-block:: c =20 @@ -250,7 +257,7 @@ Now we are ready to write the test cases. }; kunit_test_suite(misc_example_test_suite); =20 -2. Add the following lines to ``drivers/misc/Kconfig``: + b. Add configuration entry for the test suite to ``drivers/misc/Kconfig= ``: =20 .. code-block:: kconfig =20 @@ -259,26 +266,27 @@ Now we are ready to write the test cases. depends on MISC_EXAMPLE && KUNIT=3Dy default KUNIT_ALL_TESTS =20 -3. Add the following lines to ``drivers/misc/Makefile``: + c. Append make goal for the configuration to ``drivers/misc/Makefile``:=20 =20 .. code-block:: make =20 obj-$(CONFIG_MISC_EXAMPLE_TEST) +=3D example_test.o =20 -4. Add the following lines to ``.kunit/.kunitconfig``: +3. In order to enable the driver and its test suite, append configuration + fragment to ``.kunit/.kunitconfig``: =20 .. code-block:: none =20 CONFIG_MISC_EXAMPLE=3Dy CONFIG_MISC_EXAMPLE_TEST=3Dy =20 -5. Run the test: +4. Run the test: =20 .. code-block:: bash =20 ./tools/testing/kunit/kunit.py run =20 -You should see the following failure: +You should see the following output: =20 .. code-block:: none =20 @@ -289,7 +297,7 @@ You should see the following failure: [16:08:57] This test never passes. ... =20 -Congrats! You just wrote your first KUnit test. +Congrats! You have just written your first KUnit test. =20 Next Steps =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --=20 An old man doll... just what I always wanted! - Clara From nobody Wed Apr 8 04:56:55 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36F0FC433FE for ; Sun, 23 Oct 2022 12:55:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230350AbiJWMza (ORCPT ); Sun, 23 Oct 2022 08:55:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230320AbiJWMz0 (ORCPT ); Sun, 23 Oct 2022 08:55:26 -0400 Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F3943B9B1; Sun, 23 Oct 2022 05:55:24 -0700 (PDT) Received: by mail-pg1-x530.google.com with SMTP id q71so6532610pgq.8; Sun, 23 Oct 2022 05:55:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LXi6pfUX/CUtGab0f5TwpdJc904ss1/0JV1i/36x4zc=; b=eE4khKnss0xZCgP20SAc/gED9JtWoZ4VnwcjyhoggmhqySRKeqVKw4N+xLTth2rW+3 7F/XA17KwWsPXjYaX8aT+EbIAlSyEF6x/HwqU2qdCIeDm+7if3m6TfM9XKJq9N1cF7QI D3mWbmQIn7fG2dHuuQ1jwk10lVOTFllFO/ew2ySKMAybSiHMnXuZ+CSpHx9QOhHZ6PEd 0hCpJRzgqdBMpQpTfG3Yc7CLVTLy+eSkzrBD+otIKcfR4b+xMOhA/MvBglrO2C/gjmsH GGuWrd5jEcvYpcA+aSYa81Yu8a/s9sniPZXVwh5SlJbZBVCNqt9IAZ2mzWnpz+DsbJhA 6KfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LXi6pfUX/CUtGab0f5TwpdJc904ss1/0JV1i/36x4zc=; b=GUVVaR5hbhHvX95TJa8DdQUwxjIaPrXY/sFQL5M8peljx+vWnC9DDM3exwbdjizjMQ 6IkLRTKGuVJHSbDnlMuHyn9ydDYIhBjQEgdNn7Wojh61NdhwhLotJYNfZOl88bIq2MbF XTz/oBNdYQWA5X8qIKwzfDaoAv5Vv9VyDT9vNqLvtfktjpkTMZV/iVEPY/jjXu670ZR3 NbDNirOV3AK6Q+KLQCJ5xQLBTeNPEMOKPDmZ8jp54ZcUhc45tx5JBMnAC9DW7/d8zLlA HnycfFyQWoO1RdqOE3LHESP3BNywlOYGt/AqO0erqh+0U9q76FewqhltjJjQ4rPR9A5d B/NA== X-Gm-Message-State: ACrzQf1nIKG+mWncLSnQmZaJrFna8e4JrjFKR19zPIkaoClKSl9yT87E cIXSp6HfovZUQbl7LjuOMfWjM9PXHVaM+A== X-Google-Smtp-Source: AMsMyM4yr/1OgjoHaYEBexf5UGscUnJLo/TXzks+p/OYKBAHfYJsrncB5RKX520c32PsMSpyhBr5WQ== X-Received: by 2002:a05:6a02:199:b0:469:d0e6:dab8 with SMTP id bj25-20020a056a02019900b00469d0e6dab8mr24696794pgb.97.1666529723789; Sun, 23 Oct 2022 05:55:23 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id om10-20020a17090b3a8a00b00212daa68b7csm2670639pjb.44.2022.10.23.05.55.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 05:55:23 -0700 (PDT) From: Bagas Sanjaya To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com Cc: Jonathan Corbet , Brendan Higgins , David Gow , Lukas Bulwahn , Khalid Masum , Sadiya Kazi , Bagas Sanjaya Subject: [PATCH 2/7] Documentation: kunit: align instruction code blocks Date: Sun, 23 Oct 2022 19:54:09 +0700 Message-Id: <20221023125414.60961-3-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023125414.60961-1-bagasdotme@gmail.com> References: <20221023125414.60961-1-bagasdotme@gmail.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2933; i=bagasdotme@gmail.com; h=from:subject; bh=1SnUiB0gzIYxvwi4z2UvKjSn6I+UTeuPVzieo1f/vRU=; b=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhlrm37PdVmj9UfpLkoZGzPm7lzFOvL0rV/Pt7+ZmZWvoa u/UTO0pZGMQ4GGTFFFkmJfI1nd5lJHKhfa0jzBxWJpAhDFycAjCRIm2GvyKxty4UMOhuteOeVmdxg6 16tuJq68dikxZmxzHkyzBOT2ZkmKmhelSN6aL5/7k695/dOTVRPIdR6Fo0l52c4nHVYxcvcwMA X-Developer-Key: i=bagasdotme@gmail.com; a=openpgp; fpr=701B806FDCA5D3A58FFB8F7D7C276C64A5E44A1D Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Align code blocks in "Writing Your First Test" instructions list so that these blocks will be rendered at the same level as surrounding paragraphs in the list. Signed-off-by: Bagas Sanjaya --- Documentation/dev-tools/kunit/start.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-to= ols/kunit/start.rst index 590e25166efb0d..cdf043b6550e66 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -187,13 +187,13 @@ which performs addition of two integers. a. Create a new header file ``drivers/misc/example.h`` and add the prototype for ``misc_example_add()``: =20 -.. code-block:: c + .. code-block:: c =20 int misc_example_add(int left, int right); =20 b. Write the function implementation in ``drivers/misc/example.c``: =20 -.. code-block:: c + .. code-block:: c =20 #include =20 @@ -207,7 +207,7 @@ which performs addition of two integers. c. In order for the driver to be selected, add configuration entry to ``drivers/misc/Kconfig``: =20 -.. code-block:: kconfig + .. code-block:: kconfig =20 config MISC_EXAMPLE bool "My example" @@ -215,7 +215,7 @@ which performs addition of two integers. d. Last but not least, append the make goal to ``drivers/misc/Makefile`` so that the driver can be built: =20 -.. code-block:: make + .. code-block:: make =20 obj-$(CONFIG_MISC_EXAMPLE) +=3D example.o =20 @@ -224,7 +224,7 @@ which performs addition of two integers. =20 a. Write the test in ``drivers/misc/example_test.c``: =20 -.. code-block:: c + .. code-block:: c =20 #include #include "example.h" @@ -259,7 +259,7 @@ which performs addition of two integers. =20 b. Add configuration entry for the test suite to ``drivers/misc/Kconfig= ``: =20 -.. code-block:: kconfig + .. code-block:: kconfig =20 config MISC_EXAMPLE_TEST tristate "Test for my example" if !KUNIT_ALL_TESTS @@ -268,27 +268,27 @@ which performs addition of two integers. =20 c. Append make goal for the configuration to ``drivers/misc/Makefile``:=20 =20 -.. code-block:: make + .. code-block:: make =20 obj-$(CONFIG_MISC_EXAMPLE_TEST) +=3D example_test.o =20 3. In order to enable the driver and its test suite, append configuration fragment to ``.kunit/.kunitconfig``: =20 -.. code-block:: none + .. code-block:: none =20 CONFIG_MISC_EXAMPLE=3Dy CONFIG_MISC_EXAMPLE_TEST=3Dy =20 4. Run the test: =20 -.. code-block:: bash + .. code-block:: bash =20 ./tools/testing/kunit/kunit.py run =20 You should see the following output: =20 -.. code-block:: none + .. code-block:: none =20 ... [16:08:57] [PASSED] misc-example:misc_example_add_test_basic --=20 An old man doll... just what I always wanted! - Clara From nobody Wed Apr 8 04:56:55 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F1A1ECAAA1 for ; Sun, 23 Oct 2022 12:55:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230319AbiJWMzn (ORCPT ); Sun, 23 Oct 2022 08:55:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230344AbiJWMze (ORCPT ); Sun, 23 Oct 2022 08:55:34 -0400 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A379E3CBC7; Sun, 23 Oct 2022 05:55:28 -0700 (PDT) Received: by mail-pl1-x62a.google.com with SMTP id p6so6324572plr.7; Sun, 23 Oct 2022 05:55:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1vJjSOBwWKd48xSylazpwkm6EPjFpvkm4tEsXJ6mBNY=; b=jVHAMQ6IPr776EXcAbglzAk3REPjDZ0mAoD32lAvbaeb/JRfU8uDxIWZF7BgY7FGOp vFCaYr9++1945kze+SloI1EvtCSyo0a0WzmNmlY32ERgOAapR9KwEfx33WnkBoOsm3m3 v5gUh3xMbPny4akHTfry9/tPMfw+cnu2okLI/eX2oyPvUNcazj3+s6FpubdNpaVybQEg 3Jg+6WFYskEjogi1JWyuxcF8haA83LZQhgGx+ydWbbGa2lbQdG1WO+kkO58TKMTKQ00j typp/eE7h5sBjVmfYD7dq5AcuQbtx1OrzxqDGLx1H6b3OpzPfyJz+f7JLAkdQZgQGfi6 MG5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1vJjSOBwWKd48xSylazpwkm6EPjFpvkm4tEsXJ6mBNY=; b=gmSkUGRvtFP8kdzCveDtFG9D2IQ+i56iBdiGZEI6+Jzn92ecZSfdoK9L/jN4/CLzSD gB+ZAEoOKE6heoe9XDmztnv+Qic4gCEM/g6rOAK5CrWb2j1xSJwE2ViIISXdkX8qfgIz QQufdMafasRceQMyfxE2Q7RS617Xo/IscJrShJqrmp2MUSCo1nzXWgGFAaWX6QeM5dVh MYhtx4n/V3LvP5LTpS6yjGcxzVTL0ePAgY7QG07gzxyW5386QaKn4WuKk7p5f/ssgobr 5WX8gC9eesi3opyuQfE56QmIW/dK7Lv6KO8xFqOSDl5EcMevB8UzomLktmwJcKjels/B 8rMw== X-Gm-Message-State: ACrzQf2dv8CmnCRPiKQ6/iF/aDfhDyzcOkMZvbXRbPWMy/orb0gPmsnp 4b3eHEorCHtgHMapMRu6da3NQBQqydLACg== X-Google-Smtp-Source: AMsMyM7qCEJQheASrbJFNHrK70GdCXmGhAJeIhJygbihHikvQbgGGRIT2FhPG+kh0Mig0yQrxZpnbQ== X-Received: by 2002:a17:902:f643:b0:185:3e6d:6171 with SMTP id m3-20020a170902f64300b001853e6d6171mr28118809plg.123.1666529727463; Sun, 23 Oct 2022 05:55:27 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id om10-20020a17090b3a8a00b00212daa68b7csm2670639pjb.44.2022.10.23.05.55.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 05:55:27 -0700 (PDT) From: Bagas Sanjaya To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com Cc: Jonathan Corbet , Brendan Higgins , David Gow , Lukas Bulwahn , Khalid Masum , Sadiya Kazi , Bagas Sanjaya Subject: [PATCH 3/7] Documentation: kunit: rewrite the rest of "Getting Started" documentation Date: Sun, 23 Oct 2022 19:54:10 +0700 Message-Id: <20221023125414.60961-4-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023125414.60961-1-bagasdotme@gmail.com> References: <20221023125414.60961-1-bagasdotme@gmail.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=14213; i=bagasdotme@gmail.com; h=from:subject; bh=KHKCvMsVjuqrd8vApmXHIpqnqVrG7j8/yR7ng37u1b8=; b=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhlrkTys4W7O+7z5XW0Z792KGntjj2ghvTLOaUyZfnPHmT apXdUcrCIMbBICumyDIpka/p9C4jkQvtax1h5rAygQxh4OIUgIl8LGD4H6AU7nPMNPN3hL0Q0/ut78 +ZqxeYPSz2VVr59/80u/0etxgZrosKd9zKFt7v41p2Se7e/6VHtZVjyhWeHT15WpJtY58jFwA= X-Developer-Key: i=bagasdotme@gmail.com; a=openpgp; fpr=701B806FDCA5D3A58FFB8F7D7C276C64A5E44A1D Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Rewrite the rest of "Getting Started" documentation for clarity. Major points: * link to "Build directory for the kernel" section of kernel README for the caveats. * To change kernel configurations in .kunitconfig, use configuration interfaces just like configuring normal kernel. * Remove "Next steps" section as it will be placed on the introduction page. Signed-off-by: Bagas Sanjaya --- Documentation/admin-guide/README.rst | 2 + Documentation/dev-tools/kunit/start.rst | 210 ++++++++++-------------- 2 files changed, 93 insertions(+), 119 deletions(-) diff --git a/Documentation/admin-guide/README.rst b/Documentation/admin-gui= de/README.rst index 9a969c0157f1e5..f3cdc8496da03f 100644 --- a/Documentation/admin-guide/README.rst +++ b/Documentation/admin-guide/README.rst @@ -123,6 +123,8 @@ Software requirements you can just update packages when obvious problems arise during build or operation. =20 +.. _kernel-build-directory: + Build directory for the kernel ------------------------------ =20 diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-to= ols/kunit/start.rst index cdf043b6550e66..1195d5de53343e 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -4,178 +4,164 @@ Getting Started =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -This page contains an overview of the kunit_tool and KUnit framework, -teaching how to run existing tests and then how to write a simple test cas= e, -and covers common problems users face when using KUnit for the first time. +This guide is an overview of KUnit framework. It teaches how to run tests +with kunit_tool as well as writing a simple test case. =20 -Installing Dependencies -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -KUnit has the same dependencies as the Linux kernel. As long as you can -build the kernel, you can run KUnit. +Prerequisites +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +No extra dependencies are required in order to use KUnit. See +:doc:`/process/changes` for details. =20 Running tests with kunit_tool =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D -kunit_tool is a Python script, which configures and builds a kernel, runs -tests, and formats the test results. From the kernel repository, you -can run kunit_tool: +kunit_tool is a wrapper script written in Python. It configures and builds +the kernel, runs tests, and formats the results. To run the script: =20 .. code-block:: bash =20 ./tools/testing/kunit/kunit.py run =20 .. note :: - You may see the following error: - "The source tree is not clean, please run 'make ARCH=3Dum mrproper'" + You may see the following error:: =20 - This happens because internally kunit.py specifies ``.kunit`` - (default option) as the build directory in the command ``make O=3Doutput/= dir`` - through the argument ``--build_dir``. Hence, before starting an - out-of-tree build, the source tree must be clean. + The source tree is not clean, please run 'make ARCH=3Dum mrproper' =20 - There is also the same caveat mentioned in the "Build directory for - the kernel" section of the :doc:`admin-guide `, - that is, its use, it must be used for all invocations of ``make``. - The good news is that it can indeed be solved by running - ``make ARCH=3Dum mrproper``, just be aware that this will delete the - current configuration and all generated files. + This happens because internally kunit_tool passes the default build + directory ``.kunit`` as environment variable to make (which is inv= oked + as ``make O=3D.kunit``). A different build directory can be specif= ied by + passing ``--build_dir`` option. Hence, before starting the build, + the source tree must be clean. =20 -If everything worked correctly, you should see the following: + The caveat from the :ref:`kernel-build-directory` + also applies to running kunit_tool. =20 -.. code-block:: +If everything worked correctly, you should see the following output:: =20 Configuring KUnit Kernel ... Building KUnit Kernel ... Starting KUnit Kernel ... =20 -The tests will pass or fail. +.. note :: + Depending on configurations enabled in the kernel, the build proce= ss + may take a while. + +See Documentation/dev-tools/kunit/run_wrapper.rst for details. + +Selecting tests +--------------- + +By default, kunit_tool runs all tests using default configuration (defconf= ig). +The following subsections allow you to customize the configuration as well= as +filtering the test that will be run. =20 .. note :: - Because it is building a lot of sources for the first time, - the ``Building KUnit Kernel`` step may take a while. + KUnit by default runs tests for UML architecture (``ARCH=3Dum``). = If you + need to run test on other architectures see :ref:`kunit-on-qemu`. =20 -For detailed information on this wrapper, see: -Documentation/dev-tools/kunit/run_wrapper.rst. - -Selecting which tests to run ----------------------------- - -By default, kunit_tool runs all tests reachable with minimal configuration, -that is, using default values for most of the kconfig options. However, -you can select which tests to run by: - -- `Customizing Kconfig`_ used to compile the kernel, or -- `Filtering tests by name`_ to select specifically which compiled tests t= o run. - -Customizing Kconfig -~~~~~~~~~~~~~~~~~~~ -A good starting point for the ``.kunitconfig`` is the KUnit default config. -If you didn't run ``kunit.py run`` yet, you can generate it by running: +Kernel configuration +~~~~~~~~~~~~~~~~~~~~ +A good starting point for the ``.kunitconfig`` is the KUnit default config, +which can be generated by: =20 .. code-block:: bash =20 - cd $PATH_TO_LINUX_REPO - tools/testing/kunit/kunit.py config - cat .kunit/.kunitconfig + ./tools/testing/kunit/kunit.py config =20 .. note :: - ``.kunitconfig`` lives in the ``--build_dir`` used by kunit.py, which is - ``.kunit`` by default. + ``.kunitconfig`` is located in the directory specified by ``--build_dir= `` + argument. The default build directory is ``.kunit``. =20 -Before running the tests, kunit_tool ensures that all config options -set in ``.kunitconfig`` are set in the kernel ``.config``. It will warn -you if you have not included dependencies for the options used. +Before running the tests, kunit_tool ensures that all options set in +``.kunitconfig`` are set in the ``.config`` used for kernel build process.= It +will errored if you have not enabled option dependencies for all selected +options. =20 There are many ways to customize the configurations: =20 -a. Edit ``.kunit/.kunitconfig``. The file should contain the list of kconf= ig +a. Edit the configuration. ``.kunitconfig`` should contains configuration options required to run the desired tests, including their dependencies. - You may want to remove CONFIG_KUNIT_ALL_TESTS from the ``.kunitconfig``= as - it will enable a number of additional tests that you may not want. - If you need to run on an architecture other than UML see :ref:`kunit-on= -qemu`. - -b. Enable additional kconfig options on top of ``.kunit/.kunitconfig``. - For example, to include the kernel's linked-list test you can run:: + As with other kernel configurations, it is recommended to use :doc:`one= of + configuration interfaces `, passing + ``KCONFIG_CONFIG=3D.kunit/.kunitconfig`` target variable to make. You m= ay + want to disable ``CONFIG_KUNIT_ALL_TESTS`` as it will enable a number of + additional tests that you may not want to be run. + =20 +b. Add options with ``--kconfig_add``. For example, to include the + linked-list test you can run:: =20 ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_LIST_KUNIT_TEST=3Dy =20 -c. Provide the path of one or more .kunitconfig files from the tree. - For example, to run only ``FAT_FS`` and ``EXT4`` tests you can run:: +c. Pass the path to one or more .kunitconfig files from the tree. + For example, to run only ``FAT_FS`` and ``EXT4`` tests:: =20 ./tools/testing/kunit/kunit.py run \ --kunitconfig ./fs/fat/.kunitconfig \ --kunitconfig ./fs/ext4/.kunitconfig =20 -d. If you change the ``.kunitconfig``, kunit.py will trigger a rebuild of = the - ``.config`` file. But you can edit the ``.config`` file directly or with - tools like ``make menuconfig O=3D.kunit``. As long as its a superset of - ``.kunitconfig``, kunit.py won't overwrite your changes. - - .. note :: =20 - To save a .kunitconfig after finding a satisfactory configuration:: - - make savedefconfig O=3D.kunit - cp .kunit/defconfig .kunit/.kunitconfig + If you change the ``.kunitconfig``, kunit_tool will resynchronize + ``.config``, which can be edited. As long as it is a superset of + ``.kunitconfig``, kunit.py won't overwrite your changes in ``.conf= ig`` =20 Filtering tests by name ~~~~~~~~~~~~~~~~~~~~~~~ -If you want to be more specific than Kconfig can provide, it is also possi= ble -to select which tests to execute at boot-time by passing a glob filter -(read instructions regarding the pattern in the manpage :manpage:`glob(7)`= ). -If there is a ``"."`` (period) in the filter, it will be interpreted as a -separator between the name of the test suite and the test case, -otherwise, it will be interpreted as the name of the test suite. -For example, let's assume we are using the default config: +It is also possible to select which tests to execute at boot-time by passi= ng +a glob filter (see :manpage:`glob(7)` for details). +If there is a period (``.``) in the filter, it will be interpreted as a +separator between the name of the test suite and the test case; otherwise = it +will be interpreted as the name of the test suite. =20 -a. inform the name of a test suite, like ``"kunit_executor_test"``, - to run every test case it contains:: +The complete ways to specify the tests are: + +a. Pass the test suite name to run every case in that test:: =20 ./tools/testing/kunit/kunit.py run "kunit_executor_test" =20 -b. inform the name of a test case prefixed by its test suite, - like ``"example.example_simple_test"``, to run specifically that test c= ase:: +b. Pass the fully qualified name of test case to run the specific case:: =20 ./tools/testing/kunit/kunit.py run "example.example_simple_test" =20 -c. use wildcard characters (``*?[``) to run any test case that matches the= pattern, - like ``"*.*64*"`` to run test cases containing ``"64"`` in the name ins= ide - any test suite:: +c. Use wildcard characters (``*?[``) to run any test case that matches the + pattern. For example, ``"*.*64*"`` matches test case names that contain + "64" across any test suite:: =20 ./tools/testing/kunit/kunit.py run "*.*64*" =20 -Running Tests without the KUnit Wrapper -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -If you do not want to use the KUnit Wrapper (for example: you want code -under test to integrate with other systems, or use a different/ +Running tests without kunit_tool +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D +If you do not want to use kunit_tool (e.g. you want the tested code +to be integrated with other systems, or use different/ unsupported architecture or configuration), KUnit can be included in -any kernel, and the results are read out and parsed manually. +any kernel code. The results can then be read out and parsed manually. =20 .. note :: ``CONFIG_KUNIT`` should not be enabled in a production environment. Enabling KUnit disables Kernel Address-Space Layout Randomization - (KASLR), and tests may affect the state of the kernel in ways not - suitable for production. + (KASLR) and tests may affect the state of the kernel in ways not + suitable for production (like performance issues). =20 -Configuring the Kernel +Configuring the kernel ---------------------- -To enable KUnit itself, you need to enable the ``CONFIG_KUNIT`` Kconfig -option (under Kernel Hacking/Kernel Testing and Coverage in -``menuconfig``). From there, you can enable any KUnit tests. They -usually have config options ending in ``_KUNIT_TEST``. +To enable KUnit itself, you need to enable the ``CONFIG_KUNIT`` +option (the entry is under +:menuselection:`Kernel Hacking -> Kernel Testing and Coverage`). +You can enable any tests that you want to be run. These +configuration usually have ``_KUNIT_TEST`` suffix. =20 -KUnit and KUnit tests can be compiled as modules. The tests in a module -will run when the module is loaded. +Just like any other configuration options, KUnit and KUnit tests can be +built as modules. The tests in the module will be run when the module is +loaded. =20 -Running Tests (without KUnit Wrapper) -------------------------------------- -Build and run your kernel. In the kernel log, the test output is printed -out in the TAP format. This will only happen by default if KUnit/tests -are built-in. Otherwise the module will need to be loaded. +Running tests +------------- +Build and run your kernel as usual. If KUnit and the tests are built as +modules, these need to be loaded first. The test results are logged (print= ed +out) in the TAP format. =20 .. note :: - Some lines and/or data may get interspersed in the TAP output. + Some lines and/or data may get interspersed in the output. =20 Writing Your First Test =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D @@ -298,17 +284,3 @@ You should see the following output: ... =20 Congrats! You have just written your first KUnit test. - -Next Steps -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -* Documentation/dev-tools/kunit/architecture.rst - KUnit architecture. -* Documentation/dev-tools/kunit/run_wrapper.rst - run kunit_tool. -* Documentation/dev-tools/kunit/run_manual.rst - run tests without kunit= _tool. -* Documentation/dev-tools/kunit/usage.rst - write tests. -* Documentation/dev-tools/kunit/tips.rst - best practices with - examples. -* Documentation/dev-tools/kunit/api/index.rst - KUnit APIs - used for testing. -* Documentation/dev-tools/kunit/faq.rst - KUnit common questions and - answers. --=20 An old man doll... just what I always wanted! - Clara From nobody Wed Apr 8 04:56:55 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3626EFA373D for ; Sun, 23 Oct 2022 12:57:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229520AbiJWM5q (ORCPT ); Sun, 23 Oct 2022 08:57:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230373AbiJWM5Z (ORCPT ); Sun, 23 Oct 2022 08:57:25 -0400 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 997AA62AAB; Sun, 23 Oct 2022 05:56:59 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id m14-20020a17090a3f8e00b00212dab39bcdso4244751pjc.0; Sun, 23 Oct 2022 05:56:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gmR/gqIxQhBNs+360mgXWEdqP4BqSnl2UZtgUNKM0Tw=; b=CZSBuCjJVa0mOW3xN6xHk+V/mMN8hDZJfgbiVp8nU7K3kjfJciKEhPPUPUirXLzXoc zxLtv9fUTOLtlAS/zzJ0vqwLupRpbRw2WEpe7qj3sCgGo8E/skqvGMaxi3Y8NR9A+tFo PHNOvgBZHcbPX1/4PsJ5TFnhFoBiAiO1kx9IbQHUL1WLfq0uA8jMrKiBbHU0Achjc2rm WkcZ9ovsHn0j9tuZU5MyASQ1G+e9oR8GLKZpmR8sCIeaZMrEUMkqRVTRZOji8lwq1Qis zRnpO4FppWAIT+yxnIKLCmIBRI2UQW/6w36fGI5kvKaKIImJR0j71j5KYdIpDuLAxxBi hprw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gmR/gqIxQhBNs+360mgXWEdqP4BqSnl2UZtgUNKM0Tw=; b=bbrUe+HJIxCsDGjh84DbARV84IER0kfrEdMA2ro/zPzZYEifcoZG8TM76Hqhkec8U7 jmHvYd20agUMhXw4N229FgbjFCP/RfhBdS6fJpZvvQpo/mkZQxYr0lTR7vO1J2Z+IioW qmcCRZMqSs6vX+oHn/idu8XrxrUTSUT3VzpcAdJbqRCEi7G/SoZkd09+PZGN9WDKulYP eZAj95H9/6tFFdLLrONxUCGHsfJJT6IN4cUWI0aubKUP3bZFnhIc1DamP0fcvb6LEQSI 9Diet89Ni1a7et64kVLDQiluzjeti5gA/UF+hJaMuUH8ds9YYCfXG/3B6ywm6q0Omie1 FChQ== X-Gm-Message-State: ACrzQf25n4ShQJDQtAONYegfs0WTKzdOtUMnj8hXALAOMd5UK9jfFWSv 9HIJ0AQ1gM/Y+DDKFWsIp+G4V1TOuL4tSg== X-Google-Smtp-Source: AMsMyM4udHaviZWGrxBvutPkMlA7bwzb1895/q/cEBXMaD2LCvJlRqxFMwSMB3eLF4M4VfQ2VmrCmA== X-Received: by 2002:a17:902:b218:b0:184:710c:8c52 with SMTP id t24-20020a170902b21800b00184710c8c52mr28721026plr.95.1666529731291; Sun, 23 Oct 2022 05:55:31 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id om10-20020a17090b3a8a00b00212daa68b7csm2670639pjb.44.2022.10.23.05.55.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 05:55:31 -0700 (PDT) From: Bagas Sanjaya To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com Cc: Jonathan Corbet , Brendan Higgins , David Gow , Lukas Bulwahn , Khalid Masum , Sadiya Kazi , Bagas Sanjaya Subject: [PATCH 4/7] Documentation: kunit: move introduction to its own document Date: Sun, 23 Oct 2022 19:54:11 +0700 Message-Id: <20221023125414.60961-5-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023125414.60961-1-bagasdotme@gmail.com> References: <20221023125414.60961-1-bagasdotme@gmail.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7356; i=bagasdotme@gmail.com; h=from:subject; bh=OEQrwbZin8rzzpBGXarDh6toHlpYYd/ADdl9XFMdDz8=; b=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhlrk/Uj5Oil0vEb98cUnVwdDz8f8qHzYsET/3KnMju/uj As+DHaUsDGIcDLJiiiyTEvmaTu8yErnQvtYRZg4rE8gQBi5OAZgIy22G/17/RTnvNVuWJRdfVTnh97 3ZzNPj9p575TsjjbNOJSgzODD8DypKEjH8vr7j/SHtNY4fH1763CHx5ae8ov9D+cmP6xaoMQAA X-Developer-Key: i=bagasdotme@gmail.com; a=openpgp; fpr=701B806FDCA5D3A58FFB8F7D7C276C64A5E44A1D Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Move KUnit introduction from table of contents index to its own page. While at it, rewrite the intro. Signed-off-by: Bagas Sanjaya --- Documentation/dev-tools/kunit/index.rst | 93 +------------------------ Documentation/dev-tools/kunit/intro.rst | 61 ++++++++++++++++ 2 files changed, 62 insertions(+), 92 deletions(-) create mode 100644 Documentation/dev-tools/kunit/intro.rst diff --git a/Documentation/dev-tools/kunit/index.rst b/Documentation/dev-to= ols/kunit/index.rst index f5d13f1d37be1d..ad972602d91ad8 100644 --- a/Documentation/dev-tools/kunit/index.rst +++ b/Documentation/dev-tools/kunit/index.rst @@ -8,6 +8,7 @@ KUnit - Linux Kernel Unit Testing :maxdepth: 2 :caption: Contents: =20 + intro start architecture run_wrapper @@ -19,95 +20,3 @@ KUnit - Linux Kernel Unit Testing tips running_tips =20 -This section details the kernel unit testing framework. - -Introduction -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -KUnit (Kernel unit testing framework) provides a common framework for -unit tests within the Linux kernel. Using KUnit, you can define groups -of test cases called test suites. The tests either run on kernel boot -if built-in, or load as a module. KUnit automatically flags and reports -failed test cases in the kernel log. The test results appear in -:doc:`KTAP (Kernel - Test Anything Protocol) format`. -It is inspired by JUnit, Python=E2=80=99s unittest.mock, and GoogleTest/Go= ogleMock -(C++ unit testing framework). - -KUnit tests are part of the kernel, written in the C (programming) -language, and test parts of the Kernel implementation (example: a C -language function). Excluding build time, from invocation to -completion, KUnit can run around 100 tests in less than 10 seconds. -KUnit can test any kernel component, for example: file system, system -calls, memory management, device drivers and so on. - -KUnit follows the white-box testing approach. The test has access to -internal system functionality. KUnit runs in kernel space and is not -restricted to things exposed to user-space. - -In addition, KUnit has kunit_tool, a script (``tools/testing/kunit/kunit.p= y``) -that configures the Linux kernel, runs KUnit tests under QEMU or UML -(:doc:`User Mode Linux `), -parses the test results and -displays them in a user friendly manner. - -Features --------- - -- Provides a framework for writing unit tests. -- Runs tests on any kernel architecture. -- Runs a test in milliseconds. - -Prerequisites -------------- - -- Any Linux kernel compatible hardware. -- For Kernel under test, Linux kernel version 5.5 or greater. - -Unit Testing -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -A unit test tests a single unit of code in isolation. A unit test is the f= inest -granularity of testing and allows all possible code paths to be tested in = the -code under test. This is possible if the code under test is small and does= not -have any external dependencies outside of the test's control like hardware. - - -Write Unit Tests ----------------- - -To write good unit tests, there is a simple but powerful pattern: -Arrange-Act-Assert. This is a great way to structure test cases and -defines an order of operations. - -- Arrange inputs and targets: At the start of the test, arrange the data - that allows a function to work. Example: initialize a statement or - object. -- Act on the target behavior: Call your function/code under test. -- Assert expected outcome: Verify that the result (or resulting state) is = as - expected. - -Unit Testing Advantages ------------------------ - -- Increases testing speed and development in the long run. -- Detects bugs at initial stage and therefore decreases bug fix cost - compared to acceptance testing. -- Improves code quality. -- Encourages writing testable code. - -Read also :ref:`kinds-of-tests`. - -How do I use it? -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -* Documentation/dev-tools/kunit/start.rst - for KUnit new users. -* Documentation/dev-tools/kunit/architecture.rst - KUnit architecture. -* Documentation/dev-tools/kunit/run_wrapper.rst - run kunit_tool. -* Documentation/dev-tools/kunit/run_manual.rst - run tests without kunit= _tool. -* Documentation/dev-tools/kunit/usage.rst - write tests. -* Documentation/dev-tools/kunit/tips.rst - best practices with - examples. -* Documentation/dev-tools/kunit/api/index.rst - KUnit APIs - used for testing. -* Documentation/dev-tools/kunit/faq.rst - KUnit common questions and - answers. diff --git a/Documentation/dev-tools/kunit/intro.rst b/Documentation/dev-to= ols/kunit/intro.rst new file mode 100644 index 00000000000000..6061aaa0e905ab --- /dev/null +++ b/Documentation/dev-tools/kunit/intro.rst @@ -0,0 +1,61 @@ +Introduction to KUnit +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +KUnit (Kernel unit testing framework) provides a common framework for +unit tests within the Linux kernel. Using KUnit, you can write test +suites for your kernel code. As with other kernel features, the +tests can be either built into the kernel image or as loadable modules. +It automatically flags and reports +failed test cases in the kernel log. The test results appear in +:doc:`KTAP (Kernel - Test Anything Protocol) format`. +It is inspired by JUnit, Python=E2=80=99s unittest.mock, and GoogleTest/Go= ogleMock +(C++ unit testing framework). + +KUnit tests are kernel code, written in the C, that tests particular kernel +functionality. KUnit can run around +100 tests in less than 10 seconds. +KUnit can test any kernel component, such as file system, system +calls, memory management, device drivers and so on. + +KUnit follows the white-box testing approach. The test has access to +kernel internal. It runs in kernel space and thus not restricted to things +exposed to user-space. + +In addition, KUnit has a script (``tools/testing/kunit/kunit.py``) +that configures the kernel, runs the tests under QEMU or UML +(:doc:`User Mode Linux `), +parses the test results and displays them in a user friendly manner. +The rest of KUnit documentation will refer to this script as kunit_tool. + +Features +-------- + +- Provides a framework for writing unit tests. +- Runs tests on any kernel architecture. +- Runs a test in milliseconds. + +Prerequisites +------------- + +- Linux kernel 5.5 or later is required to test using KUnit. + +Unit testing +------------ + +A unit test tests a particular code in isolation. It is the finest +granularity of testing and allows all possible code paths to be tested in = the +code under test. This is possible if the code under test is small and does= not +depend on external factors (like hardware). + +Next steps +---------- + +If you haven't write the test before, see +Documentation/dev-tools/kunit/start.rst for tutorial on writing your first +test. An in-depth explanation of writing test is described in +Documentation/dev-tools/kunit/usage.rst. For information on running tests, +see Documentation/dev-tools/kunit/run_wrapper.rst and +Documentation/dev-tools/kunit/run_manual.rst. + +The KUnit infrastructure is explained in +Documentation/dev-tools/kunit/architecture.rst. --=20 An old man doll... just what I always wanted! - Clara From nobody Wed Apr 8 04:56:55 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F6C3ECAAA1 for ; Sun, 23 Oct 2022 12:56:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230422AbiJWM4E (ORCPT ); Sun, 23 Oct 2022 08:56:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230304AbiJWMzp (ORCPT ); Sun, 23 Oct 2022 08:55:45 -0400 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE2EB53009; Sun, 23 Oct 2022 05:55:36 -0700 (PDT) Received: by mail-pf1-x436.google.com with SMTP id w189so5413827pfw.4; Sun, 23 Oct 2022 05:55:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vpG+SRQgjbwGLK3JR4AvWZbDBzEcpzsUq8C95pBLv3g=; b=VXG6ib9kVkqnXksm+4BptaUjV1+QQsQeViQ+alkXZpQQZ1EMIsMS15+2qaKTEG46Lr wi2Lslm7KPLXxHZDidOwJ9OCp8Mkg3AnmQeQKJLCPKC4pU2MSY5NQ5pCoHjeBRAkgdAd a9GTCcO4bjoTT17Q/sO7EDjk1k31QyfjCR5Q5eLT5Wp8lrlt7/FpnKI6TJVnOe5LkLo8 mcCPO5RLSzNxb/ltjYLFSXHQVX/U6CuGeuhvq6AghuWTR1syoRL6bIplaC4rXDpwasmx 8zgJHxEfO7wN+gITeX/AvJmPE6qh2EQknQDHmrFREPNodrXfk5PG3X9PGp3A+fF78ELU x2rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vpG+SRQgjbwGLK3JR4AvWZbDBzEcpzsUq8C95pBLv3g=; b=ikCdfiplrBrQ/910JJWDjtQOsy8ekwMxEG1u0Mc1yTsQgfXeplt3e9z1ksx6lwdc8v BF+hEUwo+Kun780r6CJTk8iFVQ7v1IkgIkYOd2lrTLCwa9eWFbrsLAGIsoEsbrqiDtzX Qln1Lwr23jMoOUX2U8kpN1SF8c1UoC/ZvrDWKTvN6Vje9VmzM+SZRFOfpsrSWUmTlokZ 1tVODSAsPslpZ8yJGneqnYW+DVxNQ9Dr1NlgNq4d2NQ4OO4MTqMOONmj1zO5cuKOCYsF 3C5eKbd++6L4V1UJCbH1+Vh6xXVGTnYO+EjYgmOP5U8DYMxRCLEOdK7jCNrxfsWo1gwu BEbg== X-Gm-Message-State: ACrzQf1+EFgEBs6F5xfAtxA7SAcflu94gkBJzaTxUcnMhj9uaCVOu4hd vsROBa25FXw+BUJl/o+lv5h//y/27RsPiA== X-Google-Smtp-Source: AMsMyM5KcL3RazCpFInBPWLF0AMXiSN8Zf9aVwuUd9VnHhFkmD+9hEQskagYOEkkvSgIhOkurRka7Q== X-Received: by 2002:a63:ea48:0:b0:43c:69c4:68d4 with SMTP id l8-20020a63ea48000000b0043c69c468d4mr24389797pgk.416.1666529735247; Sun, 23 Oct 2022 05:55:35 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id om10-20020a17090b3a8a00b00212daa68b7csm2670639pjb.44.2022.10.23.05.55.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 05:55:34 -0700 (PDT) From: Bagas Sanjaya To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com Cc: Jonathan Corbet , Brendan Higgins , David Gow , Lukas Bulwahn , Khalid Masum , Sadiya Kazi , Bagas Sanjaya Subject: [PATCH 5/7] Documentation: kunit: rewrite "Running tests with kunit_tool" Date: Sun, 23 Oct 2022 19:54:12 +0700 Message-Id: <20221023125414.60961-6-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023125414.60961-1-bagasdotme@gmail.com> References: <20221023125414.60961-1-bagasdotme@gmail.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=18063; i=bagasdotme@gmail.com; h=from:subject; bh=rxjOwzmgDzh9fnwudOgKLwsz0s/nduKdCjKl6wBh20A=; b=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhlnltWY9MFB+sOqGWmeqjENsXPjvje9f02h9rd+15tqb9 x/OwjlIWBjEOBlkxRZZJiXxNp3cZiVxoX+sIM4eVCWQIAxenAEzk0lmG/47ut//XVsjN2nTg30JneY NX9ip27zLqw4V/J3+tcutolWVkWCjkZL/zXXl/8r61nyqt605NCeq50da0TDPl7POG0vUMrAA= X-Developer-Key: i=bagasdotme@gmail.com; a=openpgp; fpr=701B806FDCA5D3A58FFB8F7D7C276C64A5E44A1D Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Rewrite the documentation for clarity. Major points: * Switch from first-person to second-person point of view * The configuration step is now within "Kernel configuration" section * Replace description of common options with pointer to running --help for commands of the wrapper script Signed-off-by: Bagas Sanjaya --- Documentation/dev-tools/kunit/run_wrapper.rst | 302 ++++++------------ 1 file changed, 97 insertions(+), 205 deletions(-) diff --git a/Documentation/dev-tools/kunit/run_wrapper.rst b/Documentation/= dev-tools/kunit/run_wrapper.rst index dafe8eb28d3015..d683580b21d2db 100644 --- a/Documentation/dev-tools/kunit/run_wrapper.rst +++ b/Documentation/dev-tools/kunit/run_wrapper.rst @@ -4,21 +4,20 @@ Running tests with kunit_tool =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D =20 -We can either run KUnit tests using kunit_tool or can run tests -manually, and then use kunit_tool to parse the results. To run tests -manually, see: Documentation/dev-tools/kunit/run_manual.rst. -As long as we can build the kernel, we can run KUnit. +This documentation describes running tests with kunit_tool script. +If you'd like to manually run tests, see +Documentation/dev-tools/kunit/run_manual.rst. =20 kunit_tool is a Python script which configures and builds a kernel, runs tests, and formats the test results. =20 -Run command: +To run the tests: =20 .. code-block:: =20 ./tools/testing/kunit/kunit.py run =20 -We should see the following: +You should see the following output: =20 .. code-block:: =20 @@ -26,124 +25,112 @@ We should see the following: Building KUnit kernel... Starting KUnit kernel... =20 -We may want to use the following options: +You can also specify options to the script when running the tests. For +example, to run tests utilizing all available CPUs within 30 seconds +time limit: =20 .. code-block:: =20 ./tools/testing/kunit/kunit.py run --timeout=3D30 --jobs=3D`nproc --all` =20 -- ``--timeout`` sets a maximum amount of time for tests to run. -- ``--jobs`` sets the number of threads to build the kernel. +For list of all options, see:: =20 -kunit_tool will generate a ``.kunitconfig`` with a default -configuration, if no other ``.kunitconfig`` file exists -(in the build directory). In addition, it verifies that the -generated ``.config`` file contains the ``CONFIG`` options in the -``.kunitconfig``. -It is also possible to pass a separate ``.kunitconfig`` fragment to -kunit_tool. This is useful if we have several different groups of -tests we want to run independently, or if we want to use pre-defined -test configs for certain subsystems. + ./tools/testing/kunit/kunit.py run --help + +Kernel configuration +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +kunit_tool will generate kernel configuration named ``.kunitconfig`` +if it doesn't exist in the build directory. For list of selected options by +default, see ``tools/testing/kunit/configs/default.config`` file. + +In addition, it verifies that the synchronized ``.config`` file +contains options enabled in ``.kunitconfig``. It will errored out if +you have not enabled option dependencies required by all selected options. + +It is also possible to specify different ``.kunitconfig`` to +kunit_tool. This is useful if you have several different groups of +tests that you want to run independently, or if you want to use pre-defined +configurations for certain subsystems. =20 To use a different ``.kunitconfig`` file (such as one -provided to test a particular subsystem), pass it as an option: +provided to test a particular subsystem), specify ``--kunitconfig`` option. +For example, to run ext4 tests: =20 .. code-block:: =20 ./tools/testing/kunit/kunit.py run --kunitconfig=3Dfs/ext4/.kunitconfig =20 -To view kunit_tool flags (optional command-line arguments), run: +Customizing configuration +------------------------- =20 -.. code-block:: +A ``.kunitconfig`` is a configuration file generated by +``make savedefconfig``, used for running enabled set of tests. This file +contains configuration options with specific enabled tests. The file also +contains any other coptions required by the tests, for example +dependencies for features under tests, arch-specific configs and so on. =20 - ./tools/testing/kunit/kunit.py run --help - -Creating a ``.kunitconfig`` file -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D - -If we want to run a specific set of tests (rather than those listed -in the KUnit ``defconfig``), we can provide Kconfig options in the -``.kunitconfig`` file. For default .kunitconfig, see: -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/to= ols/testing/kunit/configs/default.config. -A ``.kunitconfig`` is a ``minconfig`` (a .config -generated by running ``make savedefconfig``), used for running a -specific set of tests. This file contains the regular Kernel configs -with specific test targets. The ``.kunitconfig`` also -contains any other config options required by the tests (For example: -dependencies for features under tests, configs that enable/disable -certain code blocks, arch configs and so on). - -To create a ``.kunitconfig``, using the KUnit ``defconfig``: +To generate default ``.kunitconfig``: =20 .. code-block:: =20 cd $PATH_TO_LINUX_REPO cp tools/testing/kunit/configs/default.config .kunit/.kunitconfig =20 -We can then add any other Kconfig options. For example: +You can then customize the configuration. As with configuring regular kern= els +for production deployment, it is recommended to use +:doc:`one of configuration interfaces `. For example, +to configure through menuconfig:: =20 -.. code-block:: + make O=3D.kunit KCONFIG_CONFIG=3D.kunit/.kunitconfig menuconfig =20 - CONFIG_LIST_KUNIT_TEST=3Dy +.. note:: + ``.config`` will only be resynchronized if it is the superset of + ``.kunitconfig``. Removing any options from the latter will not + resynchronize the former. In that case, you need to manually + update the former by:: =20 -kunit_tool ensures that all config options in ``.kunitconfig`` are -set in the kernel ``.config`` before running the tests. It warns if we -have not included the options dependencies. + cp .kunitconfig .config =20 -.. note:: Removing something from the ``.kunitconfig`` will - not rebuild the ``.config file``. The configuration is only - updated if the ``.kunitconfig`` is not a subset of ``.config``. - This means that we can use other tools - (For example: ``make menuconfig``) to adjust other config options. - The build dir needs to be set for ``make menuconfig`` to - work, therefore by default use ``make O=3D.kunit menuconfig``. +Step-by-step run +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -Configuring, building, and running tests -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +It is possible to sequentially run testing steps for finer-grained control. =20 -If we want to make manual changes to the KUnit build process, we -can run part of the KUnit build process independently. -When running kunit_tool, from a ``.kunitconfig``, we can generate a -``.config`` by using the ``config`` argument: +First, synchronize ``.config`` from ``.kunitconfig`` that have been +configured before: =20 .. code-block:: =20 ./tools/testing/kunit/kunit.py config =20 -To build a KUnit kernel from the current ``.config``, we can use the -``build`` argument: +Before the tests can be run, the kernel needs to be built first: =20 .. code-block:: =20 ./tools/testing/kunit/kunit.py build =20 -If we already have built UML kernel with built-in KUnit tests, we -can run the kernel, and display the test results with the ``exec`` -argument: +The whole tests can now be executed: =20 .. code-block:: =20 ./tools/testing/kunit/kunit.py exec =20 -The ``run`` command discussed in section: **Running tests with kunit_tool*= *, -is equivalent to running the above three commands in sequence. - Parsing test results =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -KUnit tests output displays results in TAP (Test Anything Protocol) -format. When running tests, kunit_tool parses this output and prints -a summary. To see the raw test results in TAP format, we can pass the -``--raw_output`` argument: +KUnit generates test results in TAP (Test Anything Protocol) format. When +the tests are running, kunit_tool parses the result and prints +the summary. To see the results in raw TAP format, you can pass +``--raw_output`` option: =20 .. code-block:: =20 ./tools/testing/kunit/kunit.py run --raw_output =20 -If we have KUnit results in the raw TAP format, we can parse them and -print the human-readable summary with the ``parse`` command for -kunit_tool. This accepts a filename for an argument, or will read from -standard input. +Now you can parse the output and print the human-readable summary with the +``parse`` command. It accepts the filename argument. If none is given, it +will read from standard input. =20 .. code-block:: bash =20 @@ -155,74 +142,63 @@ standard input. Filtering tests =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -By passing a bash style glob filter to the ``exec`` or ``run`` -commands, we can run a subset of the tests built into a kernel . For -example: if we only want to run KUnit resource tests, use: +You can also specify tests using :manpage:`glob(7)` pattern. For example, +to run resource tests (which are prefixed by ``kunit-resource``): =20 .. code-block:: =20 ./tools/testing/kunit/kunit.py run 'kunit-resource*' =20 -This uses the standard glob format with wildcard characters. - .. _kunit-on-qemu: =20 Running tests on QEMU =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -kunit_tool supports running tests on qemu as well as -via UML. To run tests on qemu, by default it requires two flags: +Besides running tests with UML kernel, kunit_wrapper also supports +running tests on QEMU. Two options are required for this to work: =20 -- ``--arch``: Selects a configs collection (Kconfig, qemu config options - and so on), that allow KUnit tests to be run on the specified - architecture in a minimal way. The architecture argument is same as - the option name passed to the ``ARCH`` variable used by Kbuild. - Not all architectures currently support this flag, but we can use - ``--qemu_config`` to handle it. If ``um`` is passed (or this flag - is ignored), the tests will run via UML. Non-UML architectures, - for example: i386, x86_64, arm and so on; run on qemu. +- ``--arch``: Run tests for the specified architecture. The value will be + passed to make as ``ARCH`` environment variable.=20 + Not all architectures currently support this flag. For such architecture= s, + use ``--qemu_config`` instead (discussed later). If ``um`` is specifed (= or + if this option is not given), the tests will run in UML kernel. Otherwis= e, + the tests run on QEMU. =20 -- ``--cross_compile``: Specifies the Kbuild toolchain. It passes the - same argument as passed to the ``CROSS_COMPILE`` variable used by - Kbuild. As a reminder, this will be the prefix for the toolchain - binaries such as GCC. For example: +- ``--cross_compile``: Specifies the cross-compiler toolchain prefix. + The value will be used for ``CROSS_COMPILE`` environment variable when + building the kernel.=20 =20 - - ``sparc64-linux-gnu`` if we have the sparc toolchain installed on - our system. +Examples: =20 - - ``$HOME/toolchains/microblaze/gcc-9.2.0-nolibc/microblaze-linux/bin/mi= croblaze-linux`` - if we have downloaded the microblaze toolchain from the 0-day - website to a directory in our home directory called toolchains. + - To run tests for native x86_64 architecture: =20 -This means that for most architectures, running under qemu is as simple as: - -.. code-block:: bash + .. code-block:: bash =20 ./tools/testing/kunit/kunit.py run --arch=3Dx86_64 =20 -When cross-compiling, we'll likely need to specify a different toolchain, = for -example: + - To cross-compile and test for s390: =20 -.. code-block:: bash + .. code-block:: bash =20 ./tools/testing/kunit/kunit.py run \ --arch=3Ds390 \ --cross_compile=3Ds390x-linux-gnu- =20 -If we want to run KUnit tests on an architecture not supported by -the ``--arch`` flag, or want to run KUnit tests on qemu using a -non-default configuration; then we can write our own``QemuConfig``. -These ``QemuConfigs`` are written in Python. They have an import line -``from..qemu_config import QemuArchParams`` at the top of the file. -The file must contain a variable called ``QEMU_ARCH`` that has an -instance of ``QemuArchParams`` assigned to it. See example in: -``tools/testing/kunit/qemu_configs/x86_64.py``. +Custom QEMU configuration +------------------------- +If you want to test on an architecture unsupported by the ``--arch`` optio= n, +or to customize QEMU invocation, you can write ``QemuConfig`` configuratio= n, +which is written in Python. The file begins with +:code:`from..qemu_config import QemuArchParams` as import directive. +The file must contain an object called ``QEMU_ARCH`` which is +built from ``QemuArchParams`` class. =20 -Once we have a ``QemuConfig``, we can pass it into kunit_tool, -using the ``--qemu_config`` flag. When used, this flag replaces the -``--arch`` flag. For example: using -``tools/testing/kunit/qemu_configs/x86_64.py``, the invocation appear -as +Once ``QemuConfig`` have been configured, you can specify the file to +kunit_tool using the ``--qemu_config`` option. This overrides ``--arch`` +option.=20 + +For example, to specify QEMU configuration for native x86_64 architecture +with 12 build jobs and 60 seconds timeout: =20 .. code-block:: bash =20 @@ -231,93 +207,9 @@ as --jobs=3D12 \ --qemu_config=3D./tools/testing/kunit/qemu_configs/x86_64.py =20 -Running command-line arguments -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D +Command options +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -kunit_tool has a number of other command-line arguments which can -be useful for our test environment. Below are the most commonly used -command line arguments: +To see a list of options for a particular command (along with usage), see:: =20 -- ``--help``: Lists all available options. To list common options, - place ``--help`` before the command. To list options specific to that - command, place ``--help`` after the command. - - .. note:: Different commands (``config``, ``build``, ``run``, etc) - have different supported options. -- ``--build_dir``: Specifies kunit_tool build directory. It includes - the ``.kunitconfig``, ``.config`` files and compiled kernel. - -- ``--make_options``: Specifies additional options to pass to make, when - compiling a kernel (using ``build`` or ``run`` commands). For example: - to enable compiler warnings, we can pass ``--make_options W=3D1``. - -- ``--alltests``: Enable a predefined set of options in order to build - as many tests as possible. - - .. note:: The list of enabled options can be found in - ``tools/testing/kunit/configs/all_tests.config``. - - If you only want to enable all tests with otherwise satisfied - dependencies, instead add ``CONFIG_KUNIT_ALL_TESTS=3Dy`` to yo= ur - ``.kunitconfig``. - -- ``--kunitconfig``: Specifies the path or the directory of the ``.kunitco= nfig`` - file. For example: - - - ``lib/kunit/.kunitconfig`` can be the path of the file. - - - ``lib/kunit`` can be the directory in which the file is located. - - This file is used to build and run with a predefined set of tests - and their dependencies. For example, to run tests for a given subsystem. - -- ``--kconfig_add``: Specifies additional configuration options to be - appended to the ``.kunitconfig`` file. For example: - - .. code-block:: - - ./tools/testing/kunit/kunit.py run --kconfig_add CONFIG_KASAN=3Dy - -- ``--arch``: Runs tests on the specified architecture. The architecture - argument is same as the Kbuild ARCH environment variable. - For example, i386, x86_64, arm, um, etc. Non-UML architectures run on qe= mu. - Default is `um`. - -- ``--cross_compile``: Specifies the Kbuild toolchain. It passes the - same argument as passed to the ``CROSS_COMPILE`` variable used by - Kbuild. This will be the prefix for the toolchain - binaries such as GCC. For example: - - - ``sparc64-linux-gnu-`` if we have the sparc toolchain installed on - our system. - - - ``$HOME/toolchains/microblaze/gcc-9.2.0-nolibc/microblaze-linux/bin/mi= croblaze-linux`` - if we have downloaded the microblaze toolchain from the 0-day - website to a specified path in our home directory called toolchains. - -- ``--qemu_config``: Specifies the path to a file containing a - custom qemu architecture definition. This should be a python file - containing a `QemuArchParams` object. - -- ``--qemu_args``: Specifies additional qemu arguments, for example, ``-sm= p 8``. - -- ``--jobs``: Specifies the number of jobs (commands) to run simultaneousl= y. - By default, this is set to the number of cores on your system. - -- ``--timeout``: Specifies the maximum number of seconds allowed for all t= ests to run. - This does not include the time taken to build the tests. - -- ``--kernel_args``: Specifies additional kernel command-line arguments. M= ay be repeated. - -- ``--run_isolated``: If set, boots the kernel for each individual suite/t= est. - This is useful for debugging a non-hermetic test, one that - might pass/fail based on what ran before it. - -- ``--raw_output``: If set, generates unformatted output from kernel. Poss= ible options are: - - - ``all``: To view the full kernel output, use ``--raw_output=3Dall``. - - - ``kunit``: This is the default option and filters to KUnit output. Us= e ``--raw_output`` or ``--raw_output=3Dkunit``. - -- ``--json``: If set, stores the test results in a JSON format and prints = to `stdout` or - saves to a file if a filename is specified. + ./tools/testing/kunit/kunit.py --help --=20 An old man doll... just what I always wanted! - Clara From nobody Wed Apr 8 04:56:55 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10D49ECAAA1 for ; Sun, 23 Oct 2022 12:56:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230452AbiJWM4X (ORCPT ); Sun, 23 Oct 2022 08:56:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34040 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230373AbiJWMzr (ORCPT ); Sun, 23 Oct 2022 08:55:47 -0400 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E85EF5804B; Sun, 23 Oct 2022 05:55:40 -0700 (PDT) Received: by mail-pl1-x629.google.com with SMTP id g24so1333508plq.3; Sun, 23 Oct 2022 05:55:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bF5znLGuPVLtnOoJ3II0Xy0V4uHOebw2aO2RcdQSGFY=; b=ks1jhW+ps8LDUsSZc3bogZI3OEsFtcXV2uJ0bQlv8Eaykv+dAaYTPM/nazEakBgD05 qn74xxSXj//sm3PhG+X0f7fmDlnKsJ2BkfQjNdZDx/8FTwgCWr6CvkXbQ43VFur1g50m 9yRsWU/qFuEsCrr8DVkIjOdlukp6sdtb1jD4cHMlAol4k9SA9/i1FKcBcm1qhGahpnJG la0Se4z0dY3HNr+dUkveuWgxvytcHDJ5TBcFDB91A/NW3iQW8a6wv3KhF45wZVrz8G8H sEqKnIYhPjOhaGlu4qLYFA1g72jF/g5IvBMfet5r1Y8+P3t2zR9ElcpatoB8OWnJFbZm nXlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bF5znLGuPVLtnOoJ3II0Xy0V4uHOebw2aO2RcdQSGFY=; b=HgZs7WTfhHkrzTbj/CXs3FJaCUI2tZPWZdElV5+ne/r/NhtnKiMJYfmvX/M+cKEuNd e1g7GMyLvLoK5ZzigssRNAVMqQPbvj7dRQ6YEdQ7WUoUpbtWf47MX39YDKrhGmvFk5cf oh76xh/s80uuoiWD6Gxc/t18EncnwJdGEOd78siU/C5e2nyuXlS2MXyLqj4LcyW5J1bT zr5+DAUBoX5X9KHV+PKbQmIDbIjSrXhLj+dfh0cbS7I2zAkBXKLahH70nwyJLJ3/MWNV gw0NMJMJy3tm02t94Swydit6ujNpprtKOKJ93uAW9dJQ6zB62lCugg1yub60OJ6NlQCp TBjQ== X-Gm-Message-State: ACrzQf1Kl/uh7GCcilP7y2xARnQTQTYcVNdpVG3q2To8dSWJpGAdkkpo 19nLouAiPxSa/s2fKiDHdwX3Z9mIVlcSHA== X-Google-Smtp-Source: AMsMyM4kvWHErfgMi2MPdjUmL/xMTrw3ObzJqiXAhaJQm3NxkN2Js5gMZQIhv7bAlid4Hy3btFnjAA== X-Received: by 2002:a17:90b:17cf:b0:20d:72eb:fd0c with SMTP id me15-20020a17090b17cf00b0020d72ebfd0cmr32651625pjb.217.1666529738933; Sun, 23 Oct 2022 05:55:38 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id om10-20020a17090b3a8a00b00212daa68b7csm2670639pjb.44.2022.10.23.05.55.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 05:55:38 -0700 (PDT) From: Bagas Sanjaya To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com Cc: Jonathan Corbet , Brendan Higgins , David Gow , Lukas Bulwahn , Khalid Masum , Sadiya Kazi , Bagas Sanjaya Subject: [PATCH 6/7] Documentation: kunit: rewrite "Run Tests without kunit_tool" Date: Sun, 23 Oct 2022 19:54:13 +0700 Message-Id: <20221023125414.60961-7-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023125414.60961-1-bagasdotme@gmail.com> References: <20221023125414.60961-1-bagasdotme@gmail.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4241; i=bagasdotme@gmail.com; h=from:subject; bh=Q3fuweCLfHmnxI0IOEYUUbA5DoSMaj2RueyhbXjdlto=; b=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhlnmTJmUvVTm1hcvniLalkZ/q/ZqdOzgkFlZHGF4+YPm7 cHNGRykLgxgHg6yYIsukRL6m07uMRC60r3WEmcPKBDKEgYtTACZyjIvhn6FHi8nvH+YL9xzOzW7dte mf4qISx5VMvLq9H9tC3vgwHmVkmMValn57ZeXkqX8X/Ogt59Rdw/mhaUncV8Mvb3/u0d9swg8A X-Developer-Key: i=bagasdotme@gmail.com; a=openpgp; fpr=701B806FDCA5D3A58FFB8F7D7C276C64A5E44A1D Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Rewrite the documentation for clarity. Major points: * Use second-person point of view * Align and format the first note like other note blocks * Remove unnecessary lists and trivial modprobe code block (every developer should have known how to load modules) Signed-off-by: Bagas Sanjaya --- Documentation/dev-tools/kunit/run_manual.rst | 68 ++++++++------------ 1 file changed, 27 insertions(+), 41 deletions(-) diff --git a/Documentation/dev-tools/kunit/run_manual.rst b/Documentation/d= ev-tools/kunit/run_manual.rst index e7b46421f247e1..28c6a1caa0fed0 100644 --- a/Documentation/dev-tools/kunit/run_manual.rst +++ b/Documentation/dev-tools/kunit/run_manual.rst @@ -4,54 +4,40 @@ Run Tests without kunit_tool =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D =20 -If we do not want to use kunit_tool (For example: we want to integrate -with other systems, or run tests on real hardware), we can -include KUnit in any kernel, read out results, and parse manually. +If you do not want to use kunit_tool (e.g. integrating +with other testing framework or running tests on real hardware), you +can run KUnit-enabled kernel manually. The test results can be parsed with +your existing tools. =20 -.. note:: KUnit is not designed for use in a production system. It is - possible that tests may reduce the stability or security of - the system. +.. note:: =20 -Configure the Kernel + Using KUnit is not recommended in production system, since + stability and security issues may occur if it is enabled. + +Kernel configuration =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -KUnit tests can run without kunit_tool. This can be useful, if: +To enable KUnit, configure the kernel with ``CONFIG_KUNIT`` enabled. +Individual tests can then be selected. KUnit tests usually (but don't alwa= ys) +have configuration name suffixed with ``_KUNIT_TEST``. As with other kernel +configurations, most tests can be enabled either builtin or as module. =20 -- We have an existing kernel configuration to test. -- Need to run on real hardware (or using an emulator/VM kunit_tool - does not support). -- Wish to integrate with some existing testing systems. +.. note:: =20 -KUnit is configured with the ``CONFIG_KUNIT`` option, and individual -tests can also be built by enabling their config options in our -``.config``. KUnit tests usually (but don't always) have config options -ending in ``_KUNIT_TEST``. Most tests can either be built as a module, -or be built into the kernel. + You can enable ``KUNIT_ALL_TESTS``, which automatically enable all + tests for which their dependencies can be satisfied. This is a good + way of quickly testing everything applicable to the current + configuration. =20 -.. note :: +Once the kernel have been built and installed, it is simple to run +the tests just by booting the kernel. If these are builtin, they will run +automatically. If these are built as modules, they will need to be loaded +first in order to run them. =20 - We can enable the ``KUNIT_ALL_TESTS`` config option to - automatically enable all tests with satisfied dependencies. This is - a good way of quickly testing everything applicable to the current - config. +The test results will be logged in TAP format in ``dmesg``. =20 -Once we have built our kernel (and/or modules), it is simple to run -the tests. If the tests are built-in, they will run automatically on the -kernel boot. The results will be written to the kernel log (``dmesg``) -in TAP format. +.. note:: =20 -If the tests are built as modules, they will run when the module is -loaded. - -.. code-block :: bash - - # modprobe example-test - -The results will appear in TAP format in ``dmesg``. - -.. note :: - - If ``CONFIG_KUNIT_DEBUGFS`` is enabled, KUnit test results will - be accessible from the ``debugfs`` filesystem (if mounted). - They will be in ``/sys/kernel/debug/kunit//results``, in - TAP format. + If ``CONFIG_KUNIT_DEBUGFS`` is enabled, the test results can + be accessed from debugfs (if mounted). Results for each test suite + will be in ``/sys/kernel/debug/kunit//results``. --=20 An old man doll... just what I always wanted! - Clara From nobody Wed Apr 8 04:56:55 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39AE4ECAAA1 for ; Sun, 23 Oct 2022 12:56:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230406AbiJWM4b (ORCPT ); Sun, 23 Oct 2022 08:56:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230408AbiJWMz5 (ORCPT ); Sun, 23 Oct 2022 08:55:57 -0400 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7538F5A831; Sun, 23 Oct 2022 05:55:47 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id io19so1378098plb.8; Sun, 23 Oct 2022 05:55:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=y6vwtBgk1QR+Bc4S86nB20t7mIV4s/vDKmFGd1CmmDU=; b=SydiUkHhHoFeJCGoiPL1fizZPohFw5Ahd2lb/ZMpjCSptBRRIfuz4jFScNI5VzzDTE PgJ3NaqXphcLhVsYIX55+6KOQ/66PsNPBaAIJwYqhhws7YuXL+u7KqAMMLvsPqMwqlO4 IJBSzrmCJSQ5maMvwSFs30u9d9AaJR1ykp4wx3V7mzQirJdakkBXshbDaHHxMPbcFjub AjhLICoYWaTHr0QAc2xbCpbXMFLg/ZL1JQ28QS7lXsknIql8qDBu0QNZYis0GwYgrAxK kGfUBqBVOKbgHDsHwSXx6C+M2cPVnUCIQ5V9Z58RZZukTMlMIfJzsYNkuCuJY8VVsPDW Iy3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=y6vwtBgk1QR+Bc4S86nB20t7mIV4s/vDKmFGd1CmmDU=; b=NFRxbKf5DvJXRFKPylooXsQIhahl1aJoOfCA6f0sQyt+ZrdFL7mXLJ7YY7px+uIqQv zTNsGMvIS0NchrZOnoGkK4GRJsIgR0q3OJMBXBcXif2SLRKBxGTpD+1nzHSW/sqet0r0 peIaDI8RwnhfyTyS6sygqKrp4+e9Q1Qve5JZwXqC+TxYnnaAMFnrNDLbaEJSZF/E0KqH FVuCBOkQOYJSYuqFvOwKagMDKFKSZjl0Zm7/q0GP7tpTgwsDLfe3o08Ptf0HNZOaN5ko Zbf8I4EeYbTk3Bn7MjPrqTNCjhyX+7X3ElnrcxLHXXmf1yJIot7uj1891f1XNeTqTcrO 26Ew== X-Gm-Message-State: ACrzQf1KMs6fQFX61voIzGb2kh7lR4boz4k9e7AWtgJ8bn0XAXidVTsF py31ba32KQNmSbHIKoR/v/dqrTUKE42OXQ== X-Google-Smtp-Source: AMsMyM6Cr7hlp7akFl0nHZQPIDrRnI/PW0nOT68JuQwZPXjKHQ6SIsObFx9HEv/NdwtIBoYYDK85Pw== X-Received: by 2002:a17:903:230b:b0:186:6041:51bf with SMTP id d11-20020a170903230b00b00186604151bfmr18220217plh.24.1666529746308; Sun, 23 Oct 2022 05:55:46 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id om10-20020a17090b3a8a00b00212daa68b7csm2670639pjb.44.2022.10.23.05.55.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 05:55:46 -0700 (PDT) From: Bagas Sanjaya To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com Cc: Jonathan Corbet , Brendan Higgins , David Gow , Lukas Bulwahn , Khalid Masum , Sadiya Kazi , Bagas Sanjaya Subject: [PATCH 7/7] Documentation: kunit: rewrite "Writing tests" Date: Sun, 23 Oct 2022 19:54:15 +0700 Message-Id: <20221023125414.60961-9-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023125414.60961-1-bagasdotme@gmail.com> References: <20221023125414.60961-1-bagasdotme@gmail.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=27186; i=bagasdotme@gmail.com; h=from:subject; bh=ZBMrD2zTAwPNW4BI+VkpvBw6PlGVuQCho52Kn8PDVZU=; b=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhlnmpLdsljxmL9txp0t56pNzr6KrbAutl3TLtv64X02Xg r+DoKGVhEONgkBVTZJmUyNd0epeRyIX2tY4wc1iZQIYwcHEKwERSVjMyfL8ttmO904MHKSraTN5Rz+ aYiQovTvNK+nfyUE3e6mup3xgZjrf+slY5Y2x+7PFdH3b7S5u8hDd3lk/66f70zWnv1cv5mAA= X-Developer-Key: i=bagasdotme@gmail.com; a=openpgp; fpr=701B806FDCA5D3A58FFB8F7D7C276C64A5E44A1D Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Rewrite the documentation for clarity. Major points: * Switch to third person point of view * Briefly describe code examples before giving them out * Use "base" and "derived" terminology on class inheritance Signed-off-by: Bagas Sanjaya --- Documentation/dev-tools/kunit/usage.rst | 322 +++++++++++++----------- 1 file changed, 173 insertions(+), 149 deletions(-) diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-to= ols/kunit/usage.rst index 2737863ef36532..e529da3fd1d32b 100644 --- a/Documentation/dev-tools/kunit/usage.rst +++ b/Documentation/dev-tools/kunit/usage.rst @@ -6,9 +6,11 @@ Writing Tests Test Cases ---------- =20 -The fundamental unit in KUnit is the test case. A test case is a function = with -the signature ``void (*)(struct kunit *test)``. It calls the function unde= r test -and then sets *expectations* for what should happen. For example: +The fundamental unit in KUnit is the test case. A test case in KUnit is a +function with the signature ``void (*)(struct kunit *test)``. It calls the +function under test and then sets *expectations* for what should happen. + +Below are the simplest examples: =20 .. code-block:: c =20 @@ -22,18 +24,17 @@ and then sets *expectations* for what should happen. Fo= r example: } =20 In the above example, ``example_test_success`` always passes because it do= es -nothing; no expectations are set, and therefore all expectations pass. On = the -other hand ``example_test_failure`` always fails because it calls ``KUNIT_= FAIL``, -which is a special expectation that logs a message and causes the test cas= e to -fail. +nothing (there are no expectations set). On the +other hand ``example_test_failure`` always fails because it calls +``KUNIT_FAIL``, which is a special function that logs the message string a= nd +signal the test as failed. =20 Expectations ~~~~~~~~~~~~ -An *expectation* specifies that we expect a piece of code to do something = in a -test. An expectation is called like a function. A test is made by setting -expectations about the behavior of a piece of code under test. When one or= more -expectations fail, the test case fails and information about the failure is -logged. For example: +An *expectation* specifies the expected behavior of tested function. It is +written as regular function call. A test is made by asserting one or more +expectations in the test case. When any of these is not satisfied, the test +case fails and information about the failure is logged. For example: =20 .. code-block:: c =20 @@ -43,18 +44,16 @@ logged. For example: KUNIT_EXPECT_EQ(test, 2, add(1, 1)); } =20 -In the above example, ``add_test_basic`` makes a number of assertions abou= t the -behavior of a function called ``add``. The first parameter is always of ty= pe +In the above example, ``add_test_basic`` tests a function called ``add()``. +The first parameter to ``KUNIT_EXPECT_EQ`` is always of type ``struct kunit *``, which contains information about the current test cont= ext. -The second parameter, in this case, is what the value is expected to be. T= he -last value is what the value actually is. If ``add`` passes all of these -expectations, the test case, ``add_test_basic`` will pass; if any one of t= hese -expectations fails, the test case will fail. +The second parameter is what the value is expected to be returned by the +function. The last is value returned by calling the tested function. =20 -A test case *fails* when any expectation is violated; however, the test wi= ll -continue to run, and try other expectations until the test case ends or is -otherwise terminated. This is as opposed to *assertions* which are discuss= ed -later. +Even though a single expectation is not satisfied, the test will +continue to run and try asserting the following expectations until either +the test case ends or is terminated. This is as opposed to *assertions* wh= ich +are discussed later. =20 To learn about more KUnit expectations, see Documentation/dev-tools/kunit/= api/test.rst. =20 @@ -62,9 +61,8 @@ To learn about more KUnit expectations, see Documentation= /dev-tools/kunit/api/te A single test case should be short, easy to understand, and focused on a single behavior. =20 -For example, if we want to rigorously test the ``add`` function above, cre= ate -additional tests cases which would test each property that an ``add`` func= tion -should have as shown below: +The example below extends ``add()`` tests with cases for negative values +and edge cases involving ``INT_MIN`` and ``INT_MAX`` constants: =20 .. code-block:: c =20 @@ -93,8 +91,10 @@ should have as shown below: Assertions ~~~~~~~~~~ =20 -An assertion is like an expectation, except that the assertion immediately -terminates the test case if the condition is not satisfied. For example: +An assertion is like an expectation, except that it immediately +terminates the test case if the condition is false. + +The following example demonstrate testing ``sort()`` function: =20 .. code-block:: c =20 @@ -112,21 +112,22 @@ terminates the test case if the condition is not sati= sfied. For example: KUNIT_EXPECT_LE(test, a[i], a[i + 1]); } =20 -In this example, the method under test should return pointer to a value. I= f the -pointer returns null or an errno, we want to stop the test since the follo= wing -expectation could crash the test case. `ASSERT_NOT_ERR_OR_NULL(...)` allow= s us -to bail out of the test case if the appropriate conditions are not satisfi= ed to -complete the test. +In this example, the method under test should return pointer to a value. If +it instead returns null pointer or errno, the test case should be bailed o= ut +with ``KUNIT_ASSERT_NOT_ERR_OR_NULL()`` since the following expectation th= at +asserts the array order could crash it. =20 Test Suites ~~~~~~~~~~~ =20 -We need many test cases covering all the unit's behaviors. It is common to= have -many similar tests. In order to reduce duplication in these closely related -tests, most unit testing frameworks (including KUnit) provide the concept = of a -*test suite*. A test suite is a collection of test cases for a unit of code -with optional setup and teardown functions that run before/after the whole -suite and/or every test case. For example: +It is common to have many similar tests cases in order to test the code +behavior. In order to reduce duplication in these closely related +tests, most unit testing frameworks (including KUnit) provide the *test su= ite* +concept. A test suite is a collection of test cases for a particularcode +with optional setup and cleanup functions that run before/after the whole +suite and/or every test case. + +Below is an example of writing a test suite: =20 .. code-block:: c =20 @@ -147,21 +148,21 @@ suite and/or every test case. For example: }; kunit_test_suite(example_test_suite); =20 -In the above example, the test suite ``example_test_suite`` would first run -``example_suite_init``, then run the test cases ``example_test_foo``, -``example_test_bar``, and ``example_test_baz``. Each would have -``example_test_init`` called immediately before it and ``example_test_exit= `` -called immediately after it. Finally, ``example_suite_exit`` would be call= ed -after everything else. ``kunit_test_suite(example_test_suite)`` registers = the -test suite with the KUnit test framework. +In the above example, running ``example_test_suite`` will initialize the +suite with ``example_suite_init``, then run three cases ``example_test_foo= ``, +``example_test_bar``, and ``example_test_baz``. Each case will be initiali= zed +with ``example_test_init`` and ``example_test_exit`` will take care of +case-specific cleanup after the case have been finished. Finally, +``example_suite_exit`` will do suite-wide cleanup, then finish the suite. +``kunit_test_suite(example_test_suite)`` registers the test suite with KUn= it. =20 .. note:: A test case will only run if it is associated with a test suite. =20 -``kunit_test_suite(...)`` is a macro which tells the linker to put the -specified test suite in a special linker section so that it can be run by = KUnit -either after ``late_init``, or when the test module is loaded (if the test= was -built as a module). +``kunit_test_suite()`` is a macro which tells the linker to put the specif= ied +test suite in a special linker section so that it can be run either after +``late_init``, or when the test module is loaded (if the test was built as +module). =20 For more information, see Documentation/dev-tools/kunit/api/test.rst. =20 @@ -170,25 +171,23 @@ For more information, see Documentation/dev-tools/kun= it/api/test.rst. Writing Tests For Other Architectures ------------------------------------- =20 -It is better to write tests that run on UML to tests that only run under a -particular architecture. It is better to write tests that run under QEMU or -another easy to obtain (and monetarily free) software environment to a spe= cific -piece of hardware. +In many cases, it is better to write tests that can be run on UML or QEMU +without requiring any specific architecture or hardware, since these can +be practically run by any machine that is capable of cross-compiling. =20 -Nevertheless, there are still valid reasons to write a test that is archit= ecture -or hardware specific. For example, we might want to test code that really -belongs in ``arch/some-arch/*``. Even so, try to write the test so that it= does -not depend on physical hardware. Some of our test cases may not need hardw= are, -only few tests actually require the hardware to test it. When hardware is = not -available, instead of disabling tests, we can skip them. +Nevertheless, there are still valid reasons to write architecture-specific +or hardware-specific tests. For example, you might want to test codes that +are in ``arch/some-arch/*``. Even so, try to write tests so that it does +not require specific hardware to run them. A test suite may contain +hardware-specific cases. These can be skipped if the hardware is not +available. =20 -Now that we have narrowed down exactly what bits are hardware specific, the -actual procedure for writing and running the tests is same as writing norm= al -KUnit tests. +Writing architecture-specific and hardware-specific tests is the same as +writing any other tests. =20 .. important:: - We may have to reset hardware state. If this is not possible, we may on= ly - be able to run one test case per invocation. + In some cases you need to reset hardware state after each test case, + otherwise only one case can be run per test suite. =20 .. TODO(brendanhiggins@google.com): Add an actual example of an architectu= re- dependent KUnit test. @@ -200,38 +199,41 @@ Isolating Behavior ------------------ =20 Unit testing limits the amount of code under test to a single unit. It con= trols -what code gets run when the unit under test calls a function. Where a func= tion -is exposed as part of an API such that the definition of that function can= be +what code gets run when the unit under test calls a function. When a funct= ion +is exposed as part of an API, the function definition can be changed without affecting the rest of the code base. In the kernel, this c= omes from two constructs: classes, which are structs that contain function poin= ters -provided by the implementer, and architecture-specific functions, which ha= ve -definitions selected at compile time. +provided by the implementer; and architecture-specific functions, which ha= ve +definitions determined at compile time. =20 Classes ~~~~~~~ =20 -Classes are not a construct that is built into the C programming language; -however, it is an easily derived concept. Accordingly, in most cases, every -project that does not use a standardized object oriented library (like GNO= ME's -GObject) has their own slightly different way of doing object oriented -programming; the Linux kernel is no exception. +The C programming language does not have the formal notion of class-based +object-oriented programming, hovewer the paradigm can be applied within +procedural framework. Accordingly, every project has their own slightly +different way of doing object oriented programming (such as GNOME's GObjec= t); +the Linux kernel is no exception. =20 The central concept in kernel object oriented programming is the class. In= the kernel, a *class* is a struct that contains function pointers. This create= s a contract between *implementers* and *users* since it forces them to use the -same function signature without having to call the function directly. To b= e a -class, the function pointers must specify that a pointer to the class, kno= wn as -a *class handle*, be one of the parameters. Thus the member functions (also -known as *methods*) have access to member variables (also known as *fields= *) -allowing the same implementation to have multiple *instances*. +same function signature without having to call the function directly. In o= rder +to be a class, the function pointers must specify that a pointer to the cl= ass +(known as a *class handle*) be one of the parameters; thus the member func= tions +(also known as *methods*) have access to member variables (also known as +*fields*), allowing the same implementation to have multiple *instances*. =20 -A class can be *overridden* by *child classes* by embedding the *parent cl= ass* -in the child class. Then when the child class *method* is called, the child -implementation knows that the pointer passed to it is of a parent contained -within the child. Thus, the child can compute the pointer to itself becaus= e the -pointer to the parent is always a fixed offset from the pointer to the chi= ld. -This offset is the offset of the parent contained in the child struct. For -example: +A class can be *overridden* by *derived classes* by embedding the *base cl= ass* +in the derived class. Then when the dervied class *method* is called, the +derived class implementation knows that the pointer passed to it is of a b= ase +class contained within the derived class. Thus, the child can compute the +pointer to itself because the pointer to the base class is always a fixed +offset from the pointer to the derived class. This offset is the offset of= the +base class contained in the struct of derived class. + +The example below defines a base class ``shape`` and derived class +``rectangle`` along with class implementations: =20 .. code-block:: c =20 @@ -259,8 +261,8 @@ example: self->width =3D width; } =20 -In this example, computing the pointer to the child from the pointer to the -parent is done by ``container_of``. +In this example, computing the pointer to ``rectangle`` from the pointer to +the ``shape`` is taken care of by ``container_of`` method. =20 Faking Classes ~~~~~~~~~~~~~~ @@ -269,11 +271,13 @@ In order to unit test a piece of code that calls a me= thod in a class, the behavior of the method must be controllable, otherwise the test ceases to = be a unit test and becomes an integration test. =20 -A fake class implements a piece of code that is different than what runs i= n a -production instance, but behaves identical from the standpoint of the call= ers. -This is done to replace a dependency that is hard to deal with, or is slow= . For -example, implementing a fake EEPROM that stores the "contents" in an -internal buffer. Assume we have a class that represents an EEPROM: +A fake class implements a piece of code that interfaces to actual code +used in production. This is done to replace code dependencies that is hard= to +deal with (expensive or impossible to duplicate), or is slow. + +The examples below shows how to test fake EEPROM implementation that stores +its contents in an internal buffer. Assume that there is ``eeprom`` class, +which is defined as: =20 .. code-block:: c =20 @@ -282,7 +286,8 @@ internal buffer. Assume we have a class that represents= an EEPROM: ssize_t (*write)(struct eeprom *this, size_t offset, const char *buffer,= size_t count); }; =20 -And we want to test code that buffers writes to the EEPROM: +Supposes that you want to test ``eeprom_buffer`` class, which writes the +contents to actual EEPROM: =20 .. code-block:: c =20 @@ -295,7 +300,8 @@ And we want to test code that buffers writes to the EEP= ROM: struct eeprom_buffer *new_eeprom_buffer(struct eeprom *eeprom); void destroy_eeprom_buffer(struct eeprom *eeprom); =20 -We can test this code by *faking out* the underlying EEPROM: +In order to test ``eeprom_buffer``, you need *faking out* the underlying +EEPROM with ``fake_eeprom``, which is derived from ``eeprom``: =20 .. code-block:: c =20 @@ -331,7 +337,7 @@ We can test this code by *faking out* the underlying EE= PROM: memset(this->contents, 0, FAKE_EEPROM_CONTENTS_SIZE); } =20 -We can now use it to test ``struct eeprom_buffer``: +You can now use it to test ``eeprom_buffer``: =20 .. code-block:: c =20 @@ -425,11 +431,12 @@ We can now use it to test ``struct eeprom_buffer``: Testing Against Multiple Inputs ------------------------------- =20 -Testing just a few inputs is not enough to ensure that the code works corr= ectly, -for example: testing a hash function. +Sometimes in order to correctly test the code, many inputs are required. In +such cases, you can write a helper macro or function. The helper can be +called for each test input. =20 -We can write a helper macro or function. The function is called for each i= nput. -For example, to test ``sha1sum(1)``, we can write: +The following example defines ``TEST_SHA1`` helper macro for testing +:manpage:`sha1sum(1)`. The macro is called on 2 test cases: =20 .. code-block:: c =20 @@ -444,12 +451,15 @@ For example, to test ``sha1sum(1)``, we can write: Note the use of the ``_MSG`` version of ``KUNIT_EXPECT_STREQ`` to print a = more detailed error and make the assertions clearer within the helper macros. =20 -The ``_MSG`` variants are useful when the same expectation is called multi= ple -times (in a loop or helper function) and thus the line number is not enoug= h to -identify what failed, as shown below. +The ``_MSG`` variants are useful when the same expectation is asserted +multiple times (in a loop or helper function), since the line number alone= is +not enough to identify the failure, as shown below. =20 -In complicated cases, we recommend using a *table-driven test* compared to= the -helper macro variation, for example: +In complicated cases, it is recommended to use *table-driven test* pattern +instead. + +The following example does the same test as above, but the test cases are +defined in an array of struct: =20 .. code-block:: c =20 @@ -478,18 +488,14 @@ helper macro variation, for example: } =20 =20 -There is more boilerplate code involved, but it can: +There are advantages of *table-driven tests*: =20 -* be more readable when there are multiple inputs/outputs (due to field na= mes). - - * For example, see ``fs/ext4/inode-test.c``. - -* reduce duplication if test cases are shared across multiple tests. - - * For example: if we want to test ``sha256sum``, we could add a ``sha256= `` - field and reuse ``cases``. - -* be converted to a "parameterized test". +* The test is more readable when there are many inputs and expected output= s. + See ``fs/ext4/inode-test.c`` for example. +* It can reduce duplication if test cases are shared across multiple tests. + For example, if you want to also test :manpage:`sha256sum(1)`, you can + simply add ``sha256`` field to ``cases``. +* The test can be turned into "parameterized test", see below subsection. =20 Parameterized Testing ~~~~~~~~~~~~~~~~~~~~~ @@ -497,8 +503,8 @@ Parameterized Testing The table-driven testing pattern is common enough that KUnit has special support for it. =20 -By reusing the same ``cases`` array from above, we can write the test as a -"parameterized test" with the following. +The following example does the same :manpage:`sha1sum(1)` test as above, +but is written using parameterized testing facilities: =20 .. code-block:: c =20 @@ -526,7 +532,7 @@ By reusing the same ``cases`` array from above, we can = write the test as a // Creates `sha1_gen_params()` to iterate over `cases`. KUNIT_ARRAY_PARAM(sha1, cases, case_to_desc); =20 - // Looks no different from a normal test. + // Looks no different from other tests. static void sha1_test(struct kunit *test) { // This function can just contain the body of the for-loop. @@ -539,7 +545,7 @@ By reusing the same ``cases`` array from above, we can = write the test as a "sha1sum(%s)", test_param->str); } =20 - // Instead of KUNIT_CASE, we use KUNIT_CASE_PARAM and pass in the + // Instead of KUNIT_CASE, use KUNIT_CASE_PARAM and pass in the // function declared by KUNIT_ARRAY_PARAM. static struct kunit_case sha1_test_cases[] =3D { KUNIT_CASE_PARAM(sha1_test, sha1_gen_params), @@ -549,9 +555,13 @@ By reusing the same ``cases`` array from above, we can= write the test as a Exiting Early on Failed Expectations ------------------------------------ =20 -We can use ``KUNIT_EXPECT_EQ`` to mark the test as failed and continue -execution. In some cases, it is unsafe to continue. We can use the -``KUNIT_ASSERT`` variant to exit on failure. +All the tests until now uses ``KUNIT_EXPECT`` macros to assert expectation= s. +In case of any of these are failed, the test continues. However, in some +cases, continuing tests is not possible or is unsafe. For these cases, +you can use ``KUNIT_ASSERT`` variant to exit early on failure. + +The example below tests allocating objects then play with them. Only if +the allocation succeed, these objects can be played with: =20 .. code-block:: c =20 @@ -567,12 +577,15 @@ execution. In some cases, it is unsafe to continue. = We can use the Allocating Memory ----------------- =20 -Where you might use ``kzalloc``, you can instead use ``kunit_kzalloc`` as = KUnit -will then ensure that the memory is freed once the test completes. +When ``kzalloc`` may be used to allocate memory, you can instead use +``kunit_kzalloc`` as KUnit will then ensure that the memory is freed once +the test completes. =20 -This is useful because it lets us use the ``KUNIT_ASSERT_EQ`` macros to ex= it -early from a test without having to worry about remembering to call ``kfre= e``. -For example: +This is useful because it lets you to use ``KUNIT_ASSERT_EQ`` macros to ex= it +early from a test without having to worry about remembering to freeing +memory with ``kfree``. + +The following example tests allocating buffer memory: =20 .. code-block:: c =20 @@ -589,9 +602,11 @@ For example: Testing Static Functions ------------------------ =20 -If we do not want to expose functions or variables for testing, one option= is to -conditionally ``#include`` the test file at the end of your .c file. For -example: +If you do not want to expose testing functions or variables unconditionall= y, +you can ``#include`` the test file inside ``#ifdef`` guard. + +In the example below, the test code in ``my_kunit_test.c`` is included and +compiled only if ``CONFIG_MY_KUNIT_TEST`` is enabled: =20 .. code-block:: c =20 @@ -606,7 +621,11 @@ example: Injecting Test-Only Code ------------------------ =20 -Similar to as shown above, we can add test-specific logic. For example: +You can also add test-only logic inside the guard. + +In the following example, prototype of ``test_only_hook()`` is defined with +``CONFIG_MY_KUNIT_TEST`` both enabled and disabled. In case the configurat= ion +is disabled, the hook is defined as empty function: =20 .. code-block:: c =20 @@ -619,19 +638,21 @@ Similar to as shown above, we can add test-specific l= ogic. For example: void test_only_hook(void) { } #endif =20 -This test-only code can be made more useful by accessing the current ``kun= it_test`` -as shown in next section: *Accessing The Current Test*. +This can be made more useful by accessing the current ``kunit_test`` +as shown in next section below. =20 Accessing The Current Test -------------------------- =20 -In some cases, we need to call test-only code from outside the test file. -For example, see example in section *Injecting Test-Only Code* or if -we are providing a fake implementation of an ops struct. Using -``kunit_test`` field in ``task_struct``, we can access it via -``current->kunit_test``. +In some cases, it is desired to call test-only code from outside the test +file. See example from previous section for how this can be done by +including the test file. =20 -The example below includes how to implement "mocking": +Another way is to provide the fake implementation of an ops struct. For +example, given ``kunit_test`` field in ``task_struct``, the field can be +accessed via ``current->kunit_test``. + +The example below shows how to implement "mocking" pattern: =20 .. code-block:: c =20 @@ -665,25 +686,28 @@ The example below includes how to implement "mocking": KUNIT_EXPECT_EQ(test, fake_foo(1), 42); } =20 -In this example, we are using the ``priv`` member of ``struct kunit`` as a= way +In this example, ``kunit->priv`` is used as a way of passing data to the test from the init function. In general ``priv`` is pointer that can be used for any user data. This is preferred over static variables, as it avoids concurrency issues. =20 -Had we wanted something more flexible, we could have used a named ``kunit_= resource``. -Each test can have multiple resources which have string names providing th= e same -flexibility as a ``priv`` member, but also, for example, allowing helper +In cases where you want something more flexible, ``kunit_resource`` can be +used instead. Each test can have multiple resources which have names provi= ding +the same flexibility as ``priv``, but also, for example, allowing helper functions to create resources without conflicting with each other. It is a= lso -possible to define a clean up function for each resource, making it easy to -avoid resource leaks. For more information, see Documentation/dev-tools/ku= nit/api/test.rst. +possible to define clean up routines for each resource, making it easy to +avoid leaking. For more information, see +Documentation/dev-tools/kunit/api/test.rst. =20 Failing The Current Test ------------------------ =20 -If we want to fail the current test, we can use ``kunit_fail_current_test(= fmt, args...)`` -which is defined in ```` and does not require pulling in= ````. -For example, we have an option to enable some extra debug checks on some d= ata -structures as shown below: +If you want to fail the current test with a meaningful reason, you can use +``kunit_fail_current_test()``, which is defined in ````. +It does not require pulling in ````. + +The following example have the extra validation over ``data`` struct, which +is only done when ``CONFIG_EXTRA_DEBUG_CHECKS`` is enabled: =20 .. code-block:: c =20 --=20 An old man doll... just what I always wanted! - Clara From nobody Wed Apr 8 04:56:55 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 137BAECAAA1 for ; Sun, 23 Oct 2022 12:56:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230403AbiJWM41 (ORCPT ); Sun, 23 Oct 2022 08:56:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230395AbiJWMzz (ORCPT ); Sun, 23 Oct 2022 08:55:55 -0400 Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 024C35926A; Sun, 23 Oct 2022 05:55:43 -0700 (PDT) Received: by mail-pg1-x52d.google.com with SMTP id q71so6532998pgq.8; Sun, 23 Oct 2022 05:55:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=y6vwtBgk1QR+Bc4S86nB20t7mIV4s/vDKmFGd1CmmDU=; b=kHn1W714Xzr/vtBCCFUq0WBZxVmrVcf4dPWQJoxAMiC04ZGcMieo2FrC5rfZOrVYz4 oanp3gIJQeVsH3axIiiGlzOUnceFabBpBjfmA+RPU2eCJW3nz/W9glyDka4JMU0YqcTW BmBW1pm0HzmifRvyxhqUXVn6LuXSQs05gw5iwNPeOj9e32LyKgW8NUNggrlwIFV8UAxL L6nWKALz/aRHyNS7DDgRRj7E5P90cdLPshnAspHmm9tBB6+p6AJoHOOjRw+MLvk5oDKW NfLqxQlOU21RSpP6VBUumjg+xr+pe3dAB+a+uQ8Y+s5qIlOWZ4PX9wW5/ZuGPdNSfyZV mhoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=y6vwtBgk1QR+Bc4S86nB20t7mIV4s/vDKmFGd1CmmDU=; b=TuDV7WMtp1g4F7eUFKMEiVH3fOIiQLGjh7I8C0r9x2A8944yfOFhq+2ilQ6j7Y56y7 MkXApvTr66O/uLZfQfCKFpsJtZiC/HuNnbaX7U9tpcfnYB6zAYPI0bSCgy5FPp6zfv/C xm9mFlewtSK/MfgT+sMOB+xMrhiVuwgK7KeXfnlq5GyuaaV6bLq1o3Qd7osmhJC5/Ghj qyem7Gxvp4V7HLecAwpoeNOES3T3jvbxri5kFGQFS/ZuBkfwFGdUsogyoynptbpcMI8O 5OpkOGL8wK1C0UcLrXXcgg514hxXIbego10dMbAG/xlsrao95FGx0L+VhcbdESlj5TUD /UAg== X-Gm-Message-State: ACrzQf1zKRWgZpmaWi1joYSFuu8Qz9ErvVFkPjfNIMk4xPK8kn6WrOno Dp61L80lAEXM9mr0MAiegeUO4SV3sDZdQQ== X-Google-Smtp-Source: AMsMyM4uO0IdVXYOy1WLfEvKbk+bybxbD0GLAXz3vo0E5dv8HZ9RfQ4b/6hqKpyEVahjHjqgvaybXg== X-Received: by 2002:a63:6cc3:0:b0:43c:7585:1ec with SMTP id h186-20020a636cc3000000b0043c758501ecmr24240336pgc.571.1666529742597; Sun, 23 Oct 2022 05:55:42 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id om10-20020a17090b3a8a00b00212daa68b7csm2670639pjb.44.2022.10.23.05.55.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 05:55:42 -0700 (PDT) From: Bagas Sanjaya To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com Cc: Jonathan Corbet , Brendan Higgins , David Gow , Lukas Bulwahn , Khalid Masum , Sadiya Kazi , Bagas Sanjaya Subject: [PATCH 7/7] Documentation: kunit: rewrite usage Date: Sun, 23 Oct 2022 19:54:14 +0700 Message-Id: <20221023125414.60961-8-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023125414.60961-1-bagasdotme@gmail.com> References: <20221023125414.60961-1-bagasdotme@gmail.com> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=27186; i=bagasdotme@gmail.com; h=from:subject; bh=ZBMrD2zTAwPNW4BI+VkpvBw6PlGVuQCho52Kn8PDVZU=; b=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhlnkV9WX7db9m2RybzTZFwerLznrOovlmV6/xyq+7s3Ol itvKjlIWBjEOBlkxRZZJiXxNp3cZiVxoX+sIM4eVCWQIAxenAEyEuZKRoUdq1XzhjzenTdNZe12J6/ FUs/Wsk3V3Ze/Mzdy+m2VTkyojw+6YE6nvBSenuV+/K3La1EnUdt+ONxobFns+sNqisf7yFA4A X-Developer-Key: i=bagasdotme@gmail.com; a=openpgp; fpr=701B806FDCA5D3A58FFB8F7D7C276C64A5E44A1D Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Rewrite the documentation for clarity. Major points: * Switch to third person point of view * Briefly describe code examples before giving them out * Use "base" and "derived" terminology on class inheritance Signed-off-by: Bagas Sanjaya --- Documentation/dev-tools/kunit/usage.rst | 322 +++++++++++++----------- 1 file changed, 173 insertions(+), 149 deletions(-) diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-to= ols/kunit/usage.rst index 2737863ef36532..e529da3fd1d32b 100644 --- a/Documentation/dev-tools/kunit/usage.rst +++ b/Documentation/dev-tools/kunit/usage.rst @@ -6,9 +6,11 @@ Writing Tests Test Cases ---------- =20 -The fundamental unit in KUnit is the test case. A test case is a function = with -the signature ``void (*)(struct kunit *test)``. It calls the function unde= r test -and then sets *expectations* for what should happen. For example: +The fundamental unit in KUnit is the test case. A test case in KUnit is a +function with the signature ``void (*)(struct kunit *test)``. It calls the +function under test and then sets *expectations* for what should happen. + +Below are the simplest examples: =20 .. code-block:: c =20 @@ -22,18 +24,17 @@ and then sets *expectations* for what should happen. Fo= r example: } =20 In the above example, ``example_test_success`` always passes because it do= es -nothing; no expectations are set, and therefore all expectations pass. On = the -other hand ``example_test_failure`` always fails because it calls ``KUNIT_= FAIL``, -which is a special expectation that logs a message and causes the test cas= e to -fail. +nothing (there are no expectations set). On the +other hand ``example_test_failure`` always fails because it calls +``KUNIT_FAIL``, which is a special function that logs the message string a= nd +signal the test as failed. =20 Expectations ~~~~~~~~~~~~ -An *expectation* specifies that we expect a piece of code to do something = in a -test. An expectation is called like a function. A test is made by setting -expectations about the behavior of a piece of code under test. When one or= more -expectations fail, the test case fails and information about the failure is -logged. For example: +An *expectation* specifies the expected behavior of tested function. It is +written as regular function call. A test is made by asserting one or more +expectations in the test case. When any of these is not satisfied, the test +case fails and information about the failure is logged. For example: =20 .. code-block:: c =20 @@ -43,18 +44,16 @@ logged. For example: KUNIT_EXPECT_EQ(test, 2, add(1, 1)); } =20 -In the above example, ``add_test_basic`` makes a number of assertions abou= t the -behavior of a function called ``add``. The first parameter is always of ty= pe +In the above example, ``add_test_basic`` tests a function called ``add()``. +The first parameter to ``KUNIT_EXPECT_EQ`` is always of type ``struct kunit *``, which contains information about the current test cont= ext. -The second parameter, in this case, is what the value is expected to be. T= he -last value is what the value actually is. If ``add`` passes all of these -expectations, the test case, ``add_test_basic`` will pass; if any one of t= hese -expectations fails, the test case will fail. +The second parameter is what the value is expected to be returned by the +function. The last is value returned by calling the tested function. =20 -A test case *fails* when any expectation is violated; however, the test wi= ll -continue to run, and try other expectations until the test case ends or is -otherwise terminated. This is as opposed to *assertions* which are discuss= ed -later. +Even though a single expectation is not satisfied, the test will +continue to run and try asserting the following expectations until either +the test case ends or is terminated. This is as opposed to *assertions* wh= ich +are discussed later. =20 To learn about more KUnit expectations, see Documentation/dev-tools/kunit/= api/test.rst. =20 @@ -62,9 +61,8 @@ To learn about more KUnit expectations, see Documentation= /dev-tools/kunit/api/te A single test case should be short, easy to understand, and focused on a single behavior. =20 -For example, if we want to rigorously test the ``add`` function above, cre= ate -additional tests cases which would test each property that an ``add`` func= tion -should have as shown below: +The example below extends ``add()`` tests with cases for negative values +and edge cases involving ``INT_MIN`` and ``INT_MAX`` constants: =20 .. code-block:: c =20 @@ -93,8 +91,10 @@ should have as shown below: Assertions ~~~~~~~~~~ =20 -An assertion is like an expectation, except that the assertion immediately -terminates the test case if the condition is not satisfied. For example: +An assertion is like an expectation, except that it immediately +terminates the test case if the condition is false. + +The following example demonstrate testing ``sort()`` function: =20 .. code-block:: c =20 @@ -112,21 +112,22 @@ terminates the test case if the condition is not sati= sfied. For example: KUNIT_EXPECT_LE(test, a[i], a[i + 1]); } =20 -In this example, the method under test should return pointer to a value. I= f the -pointer returns null or an errno, we want to stop the test since the follo= wing -expectation could crash the test case. `ASSERT_NOT_ERR_OR_NULL(...)` allow= s us -to bail out of the test case if the appropriate conditions are not satisfi= ed to -complete the test. +In this example, the method under test should return pointer to a value. If +it instead returns null pointer or errno, the test case should be bailed o= ut +with ``KUNIT_ASSERT_NOT_ERR_OR_NULL()`` since the following expectation th= at +asserts the array order could crash it. =20 Test Suites ~~~~~~~~~~~ =20 -We need many test cases covering all the unit's behaviors. It is common to= have -many similar tests. In order to reduce duplication in these closely related -tests, most unit testing frameworks (including KUnit) provide the concept = of a -*test suite*. A test suite is a collection of test cases for a unit of code -with optional setup and teardown functions that run before/after the whole -suite and/or every test case. For example: +It is common to have many similar tests cases in order to test the code +behavior. In order to reduce duplication in these closely related +tests, most unit testing frameworks (including KUnit) provide the *test su= ite* +concept. A test suite is a collection of test cases for a particularcode +with optional setup and cleanup functions that run before/after the whole +suite and/or every test case. + +Below is an example of writing a test suite: =20 .. code-block:: c =20 @@ -147,21 +148,21 @@ suite and/or every test case. For example: }; kunit_test_suite(example_test_suite); =20 -In the above example, the test suite ``example_test_suite`` would first run -``example_suite_init``, then run the test cases ``example_test_foo``, -``example_test_bar``, and ``example_test_baz``. Each would have -``example_test_init`` called immediately before it and ``example_test_exit= `` -called immediately after it. Finally, ``example_suite_exit`` would be call= ed -after everything else. ``kunit_test_suite(example_test_suite)`` registers = the -test suite with the KUnit test framework. +In the above example, running ``example_test_suite`` will initialize the +suite with ``example_suite_init``, then run three cases ``example_test_foo= ``, +``example_test_bar``, and ``example_test_baz``. Each case will be initiali= zed +with ``example_test_init`` and ``example_test_exit`` will take care of +case-specific cleanup after the case have been finished. Finally, +``example_suite_exit`` will do suite-wide cleanup, then finish the suite. +``kunit_test_suite(example_test_suite)`` registers the test suite with KUn= it. =20 .. note:: A test case will only run if it is associated with a test suite. =20 -``kunit_test_suite(...)`` is a macro which tells the linker to put the -specified test suite in a special linker section so that it can be run by = KUnit -either after ``late_init``, or when the test module is loaded (if the test= was -built as a module). +``kunit_test_suite()`` is a macro which tells the linker to put the specif= ied +test suite in a special linker section so that it can be run either after +``late_init``, or when the test module is loaded (if the test was built as +module). =20 For more information, see Documentation/dev-tools/kunit/api/test.rst. =20 @@ -170,25 +171,23 @@ For more information, see Documentation/dev-tools/kun= it/api/test.rst. Writing Tests For Other Architectures ------------------------------------- =20 -It is better to write tests that run on UML to tests that only run under a -particular architecture. It is better to write tests that run under QEMU or -another easy to obtain (and monetarily free) software environment to a spe= cific -piece of hardware. +In many cases, it is better to write tests that can be run on UML or QEMU +without requiring any specific architecture or hardware, since these can +be practically run by any machine that is capable of cross-compiling. =20 -Nevertheless, there are still valid reasons to write a test that is archit= ecture -or hardware specific. For example, we might want to test code that really -belongs in ``arch/some-arch/*``. Even so, try to write the test so that it= does -not depend on physical hardware. Some of our test cases may not need hardw= are, -only few tests actually require the hardware to test it. When hardware is = not -available, instead of disabling tests, we can skip them. +Nevertheless, there are still valid reasons to write architecture-specific +or hardware-specific tests. For example, you might want to test codes that +are in ``arch/some-arch/*``. Even so, try to write tests so that it does +not require specific hardware to run them. A test suite may contain +hardware-specific cases. These can be skipped if the hardware is not +available. =20 -Now that we have narrowed down exactly what bits are hardware specific, the -actual procedure for writing and running the tests is same as writing norm= al -KUnit tests. +Writing architecture-specific and hardware-specific tests is the same as +writing any other tests. =20 .. important:: - We may have to reset hardware state. If this is not possible, we may on= ly - be able to run one test case per invocation. + In some cases you need to reset hardware state after each test case, + otherwise only one case can be run per test suite. =20 .. TODO(brendanhiggins@google.com): Add an actual example of an architectu= re- dependent KUnit test. @@ -200,38 +199,41 @@ Isolating Behavior ------------------ =20 Unit testing limits the amount of code under test to a single unit. It con= trols -what code gets run when the unit under test calls a function. Where a func= tion -is exposed as part of an API such that the definition of that function can= be +what code gets run when the unit under test calls a function. When a funct= ion +is exposed as part of an API, the function definition can be changed without affecting the rest of the code base. In the kernel, this c= omes from two constructs: classes, which are structs that contain function poin= ters -provided by the implementer, and architecture-specific functions, which ha= ve -definitions selected at compile time. +provided by the implementer; and architecture-specific functions, which ha= ve +definitions determined at compile time. =20 Classes ~~~~~~~ =20 -Classes are not a construct that is built into the C programming language; -however, it is an easily derived concept. Accordingly, in most cases, every -project that does not use a standardized object oriented library (like GNO= ME's -GObject) has their own slightly different way of doing object oriented -programming; the Linux kernel is no exception. +The C programming language does not have the formal notion of class-based +object-oriented programming, hovewer the paradigm can be applied within +procedural framework. Accordingly, every project has their own slightly +different way of doing object oriented programming (such as GNOME's GObjec= t); +the Linux kernel is no exception. =20 The central concept in kernel object oriented programming is the class. In= the kernel, a *class* is a struct that contains function pointers. This create= s a contract between *implementers* and *users* since it forces them to use the -same function signature without having to call the function directly. To b= e a -class, the function pointers must specify that a pointer to the class, kno= wn as -a *class handle*, be one of the parameters. Thus the member functions (also -known as *methods*) have access to member variables (also known as *fields= *) -allowing the same implementation to have multiple *instances*. +same function signature without having to call the function directly. In o= rder +to be a class, the function pointers must specify that a pointer to the cl= ass +(known as a *class handle*) be one of the parameters; thus the member func= tions +(also known as *methods*) have access to member variables (also known as +*fields*), allowing the same implementation to have multiple *instances*. =20 -A class can be *overridden* by *child classes* by embedding the *parent cl= ass* -in the child class. Then when the child class *method* is called, the child -implementation knows that the pointer passed to it is of a parent contained -within the child. Thus, the child can compute the pointer to itself becaus= e the -pointer to the parent is always a fixed offset from the pointer to the chi= ld. -This offset is the offset of the parent contained in the child struct. For -example: +A class can be *overridden* by *derived classes* by embedding the *base cl= ass* +in the derived class. Then when the dervied class *method* is called, the +derived class implementation knows that the pointer passed to it is of a b= ase +class contained within the derived class. Thus, the child can compute the +pointer to itself because the pointer to the base class is always a fixed +offset from the pointer to the derived class. This offset is the offset of= the +base class contained in the struct of derived class. + +The example below defines a base class ``shape`` and derived class +``rectangle`` along with class implementations: =20 .. code-block:: c =20 @@ -259,8 +261,8 @@ example: self->width =3D width; } =20 -In this example, computing the pointer to the child from the pointer to the -parent is done by ``container_of``. +In this example, computing the pointer to ``rectangle`` from the pointer to +the ``shape`` is taken care of by ``container_of`` method. =20 Faking Classes ~~~~~~~~~~~~~~ @@ -269,11 +271,13 @@ In order to unit test a piece of code that calls a me= thod in a class, the behavior of the method must be controllable, otherwise the test ceases to = be a unit test and becomes an integration test. =20 -A fake class implements a piece of code that is different than what runs i= n a -production instance, but behaves identical from the standpoint of the call= ers. -This is done to replace a dependency that is hard to deal with, or is slow= . For -example, implementing a fake EEPROM that stores the "contents" in an -internal buffer. Assume we have a class that represents an EEPROM: +A fake class implements a piece of code that interfaces to actual code +used in production. This is done to replace code dependencies that is hard= to +deal with (expensive or impossible to duplicate), or is slow. + +The examples below shows how to test fake EEPROM implementation that stores +its contents in an internal buffer. Assume that there is ``eeprom`` class, +which is defined as: =20 .. code-block:: c =20 @@ -282,7 +286,8 @@ internal buffer. Assume we have a class that represents= an EEPROM: ssize_t (*write)(struct eeprom *this, size_t offset, const char *buffer,= size_t count); }; =20 -And we want to test code that buffers writes to the EEPROM: +Supposes that you want to test ``eeprom_buffer`` class, which writes the +contents to actual EEPROM: =20 .. code-block:: c =20 @@ -295,7 +300,8 @@ And we want to test code that buffers writes to the EEP= ROM: struct eeprom_buffer *new_eeprom_buffer(struct eeprom *eeprom); void destroy_eeprom_buffer(struct eeprom *eeprom); =20 -We can test this code by *faking out* the underlying EEPROM: +In order to test ``eeprom_buffer``, you need *faking out* the underlying +EEPROM with ``fake_eeprom``, which is derived from ``eeprom``: =20 .. code-block:: c =20 @@ -331,7 +337,7 @@ We can test this code by *faking out* the underlying EE= PROM: memset(this->contents, 0, FAKE_EEPROM_CONTENTS_SIZE); } =20 -We can now use it to test ``struct eeprom_buffer``: +You can now use it to test ``eeprom_buffer``: =20 .. code-block:: c =20 @@ -425,11 +431,12 @@ We can now use it to test ``struct eeprom_buffer``: Testing Against Multiple Inputs ------------------------------- =20 -Testing just a few inputs is not enough to ensure that the code works corr= ectly, -for example: testing a hash function. +Sometimes in order to correctly test the code, many inputs are required. In +such cases, you can write a helper macro or function. The helper can be +called for each test input. =20 -We can write a helper macro or function. The function is called for each i= nput. -For example, to test ``sha1sum(1)``, we can write: +The following example defines ``TEST_SHA1`` helper macro for testing +:manpage:`sha1sum(1)`. The macro is called on 2 test cases: =20 .. code-block:: c =20 @@ -444,12 +451,15 @@ For example, to test ``sha1sum(1)``, we can write: Note the use of the ``_MSG`` version of ``KUNIT_EXPECT_STREQ`` to print a = more detailed error and make the assertions clearer within the helper macros. =20 -The ``_MSG`` variants are useful when the same expectation is called multi= ple -times (in a loop or helper function) and thus the line number is not enoug= h to -identify what failed, as shown below. +The ``_MSG`` variants are useful when the same expectation is asserted +multiple times (in a loop or helper function), since the line number alone= is +not enough to identify the failure, as shown below. =20 -In complicated cases, we recommend using a *table-driven test* compared to= the -helper macro variation, for example: +In complicated cases, it is recommended to use *table-driven test* pattern +instead. + +The following example does the same test as above, but the test cases are +defined in an array of struct: =20 .. code-block:: c =20 @@ -478,18 +488,14 @@ helper macro variation, for example: } =20 =20 -There is more boilerplate code involved, but it can: +There are advantages of *table-driven tests*: =20 -* be more readable when there are multiple inputs/outputs (due to field na= mes). - - * For example, see ``fs/ext4/inode-test.c``. - -* reduce duplication if test cases are shared across multiple tests. - - * For example: if we want to test ``sha256sum``, we could add a ``sha256= `` - field and reuse ``cases``. - -* be converted to a "parameterized test". +* The test is more readable when there are many inputs and expected output= s. + See ``fs/ext4/inode-test.c`` for example. +* It can reduce duplication if test cases are shared across multiple tests. + For example, if you want to also test :manpage:`sha256sum(1)`, you can + simply add ``sha256`` field to ``cases``. +* The test can be turned into "parameterized test", see below subsection. =20 Parameterized Testing ~~~~~~~~~~~~~~~~~~~~~ @@ -497,8 +503,8 @@ Parameterized Testing The table-driven testing pattern is common enough that KUnit has special support for it. =20 -By reusing the same ``cases`` array from above, we can write the test as a -"parameterized test" with the following. +The following example does the same :manpage:`sha1sum(1)` test as above, +but is written using parameterized testing facilities: =20 .. code-block:: c =20 @@ -526,7 +532,7 @@ By reusing the same ``cases`` array from above, we can = write the test as a // Creates `sha1_gen_params()` to iterate over `cases`. KUNIT_ARRAY_PARAM(sha1, cases, case_to_desc); =20 - // Looks no different from a normal test. + // Looks no different from other tests. static void sha1_test(struct kunit *test) { // This function can just contain the body of the for-loop. @@ -539,7 +545,7 @@ By reusing the same ``cases`` array from above, we can = write the test as a "sha1sum(%s)", test_param->str); } =20 - // Instead of KUNIT_CASE, we use KUNIT_CASE_PARAM and pass in the + // Instead of KUNIT_CASE, use KUNIT_CASE_PARAM and pass in the // function declared by KUNIT_ARRAY_PARAM. static struct kunit_case sha1_test_cases[] =3D { KUNIT_CASE_PARAM(sha1_test, sha1_gen_params), @@ -549,9 +555,13 @@ By reusing the same ``cases`` array from above, we can= write the test as a Exiting Early on Failed Expectations ------------------------------------ =20 -We can use ``KUNIT_EXPECT_EQ`` to mark the test as failed and continue -execution. In some cases, it is unsafe to continue. We can use the -``KUNIT_ASSERT`` variant to exit on failure. +All the tests until now uses ``KUNIT_EXPECT`` macros to assert expectation= s. +In case of any of these are failed, the test continues. However, in some +cases, continuing tests is not possible or is unsafe. For these cases, +you can use ``KUNIT_ASSERT`` variant to exit early on failure. + +The example below tests allocating objects then play with them. Only if +the allocation succeed, these objects can be played with: =20 .. code-block:: c =20 @@ -567,12 +577,15 @@ execution. In some cases, it is unsafe to continue. = We can use the Allocating Memory ----------------- =20 -Where you might use ``kzalloc``, you can instead use ``kunit_kzalloc`` as = KUnit -will then ensure that the memory is freed once the test completes. +When ``kzalloc`` may be used to allocate memory, you can instead use +``kunit_kzalloc`` as KUnit will then ensure that the memory is freed once +the test completes. =20 -This is useful because it lets us use the ``KUNIT_ASSERT_EQ`` macros to ex= it -early from a test without having to worry about remembering to call ``kfre= e``. -For example: +This is useful because it lets you to use ``KUNIT_ASSERT_EQ`` macros to ex= it +early from a test without having to worry about remembering to freeing +memory with ``kfree``. + +The following example tests allocating buffer memory: =20 .. code-block:: c =20 @@ -589,9 +602,11 @@ For example: Testing Static Functions ------------------------ =20 -If we do not want to expose functions or variables for testing, one option= is to -conditionally ``#include`` the test file at the end of your .c file. For -example: +If you do not want to expose testing functions or variables unconditionall= y, +you can ``#include`` the test file inside ``#ifdef`` guard. + +In the example below, the test code in ``my_kunit_test.c`` is included and +compiled only if ``CONFIG_MY_KUNIT_TEST`` is enabled: =20 .. code-block:: c =20 @@ -606,7 +621,11 @@ example: Injecting Test-Only Code ------------------------ =20 -Similar to as shown above, we can add test-specific logic. For example: +You can also add test-only logic inside the guard. + +In the following example, prototype of ``test_only_hook()`` is defined with +``CONFIG_MY_KUNIT_TEST`` both enabled and disabled. In case the configurat= ion +is disabled, the hook is defined as empty function: =20 .. code-block:: c =20 @@ -619,19 +638,21 @@ Similar to as shown above, we can add test-specific l= ogic. For example: void test_only_hook(void) { } #endif =20 -This test-only code can be made more useful by accessing the current ``kun= it_test`` -as shown in next section: *Accessing The Current Test*. +This can be made more useful by accessing the current ``kunit_test`` +as shown in next section below. =20 Accessing The Current Test -------------------------- =20 -In some cases, we need to call test-only code from outside the test file. -For example, see example in section *Injecting Test-Only Code* or if -we are providing a fake implementation of an ops struct. Using -``kunit_test`` field in ``task_struct``, we can access it via -``current->kunit_test``. +In some cases, it is desired to call test-only code from outside the test +file. See example from previous section for how this can be done by +including the test file. =20 -The example below includes how to implement "mocking": +Another way is to provide the fake implementation of an ops struct. For +example, given ``kunit_test`` field in ``task_struct``, the field can be +accessed via ``current->kunit_test``. + +The example below shows how to implement "mocking" pattern: =20 .. code-block:: c =20 @@ -665,25 +686,28 @@ The example below includes how to implement "mocking": KUNIT_EXPECT_EQ(test, fake_foo(1), 42); } =20 -In this example, we are using the ``priv`` member of ``struct kunit`` as a= way +In this example, ``kunit->priv`` is used as a way of passing data to the test from the init function. In general ``priv`` is pointer that can be used for any user data. This is preferred over static variables, as it avoids concurrency issues. =20 -Had we wanted something more flexible, we could have used a named ``kunit_= resource``. -Each test can have multiple resources which have string names providing th= e same -flexibility as a ``priv`` member, but also, for example, allowing helper +In cases where you want something more flexible, ``kunit_resource`` can be +used instead. Each test can have multiple resources which have names provi= ding +the same flexibility as ``priv``, but also, for example, allowing helper functions to create resources without conflicting with each other. It is a= lso -possible to define a clean up function for each resource, making it easy to -avoid resource leaks. For more information, see Documentation/dev-tools/ku= nit/api/test.rst. +possible to define clean up routines for each resource, making it easy to +avoid leaking. For more information, see +Documentation/dev-tools/kunit/api/test.rst. =20 Failing The Current Test ------------------------ =20 -If we want to fail the current test, we can use ``kunit_fail_current_test(= fmt, args...)`` -which is defined in ```` and does not require pulling in= ````. -For example, we have an option to enable some extra debug checks on some d= ata -structures as shown below: +If you want to fail the current test with a meaningful reason, you can use +``kunit_fail_current_test()``, which is defined in ````. +It does not require pulling in ````. + +The following example have the extra validation over ``data`` struct, which +is only done when ``CONFIG_EXTRA_DEBUG_CHECKS`` is enabled: =20 .. code-block:: c =20 --=20 An old man doll... just what I always wanted! - Clara