From patchwork Sun Oct 23 12:54:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 13016218 X-Patchwork-Delegate: brendanhiggins@google.com 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 C05FFECAAA1 for ; Sun, 23 Oct 2022 12:55:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230060AbiJWMzZ (ORCPT ); Sun, 23 Oct 2022 08:55:25 -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 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org 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-tools/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 loaded. Writing Your First Test ======================= -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. -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()``: .. code-block:: c int misc_example_add(int left, int right); -2. Create a file ``drivers/misc/example.c``, which includes: + b. Write the function implementation in ``drivers/misc/example.c``: .. code-block:: c @@ -200,22 +204,25 @@ In your kernel repository, let's add some code that we can test. return left + right; } -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``: .. code-block:: kconfig config MISC_EXAMPLE bool "My example" -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: .. code-block:: make obj-$(CONFIG_MISC_EXAMPLE) += example.o -Now we are ready to write the test cases. +2. Write the test suite that covers the driver functionality. Follow the + steps below: -1. Add the below test case in ``drivers/misc/example_test.c``: + a. Write the test in ``drivers/misc/example_test.c``: .. code-block:: c @@ -250,7 +257,7 @@ Now we are ready to write the test cases. }; kunit_test_suite(misc_example_test_suite); -2. Add the following lines to ``drivers/misc/Kconfig``: + b. Add configuration entry for the test suite to ``drivers/misc/Kconfig``: .. code-block:: kconfig @@ -259,26 +266,27 @@ Now we are ready to write the test cases. depends on MISC_EXAMPLE && KUNIT=y default KUNIT_ALL_TESTS -3. Add the following lines to ``drivers/misc/Makefile``: + c. Append make goal for the configuration to ``drivers/misc/Makefile``: .. code-block:: make obj-$(CONFIG_MISC_EXAMPLE_TEST) += example_test.o -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``: .. code-block:: none CONFIG_MISC_EXAMPLE=y CONFIG_MISC_EXAMPLE_TEST=y -5. Run the test: +4. Run the test: .. code-block:: bash ./tools/testing/kunit/kunit.py run -You should see the following failure: +You should see the following output: .. code-block:: none @@ -289,7 +297,7 @@ You should see the following failure: [16:08:57] This test never passes. ... -Congrats! You just wrote your first KUnit test. +Congrats! You have just written your first KUnit test. Next Steps ========== From patchwork Sun Oct 23 12:54:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 13016219 X-Patchwork-Delegate: brendanhiggins@google.com 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 EB9FFC433FE for ; Sun, 23 Oct 2022 12:55:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230317AbiJWMz2 (ORCPT ); Sun, 23 Oct 2022 08:55:28 -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 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org 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-tools/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()``: -.. code-block:: c + .. code-block:: c int misc_example_add(int left, int right); b. Write the function implementation in ``drivers/misc/example.c``: -.. code-block:: c + .. code-block:: c #include @@ -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``: -.. code-block:: kconfig + .. code-block:: kconfig 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: -.. code-block:: make + .. code-block:: make obj-$(CONFIG_MISC_EXAMPLE) += example.o @@ -224,7 +224,7 @@ which performs addition of two integers. a. Write the test in ``drivers/misc/example_test.c``: -.. code-block:: c + .. code-block:: c #include #include "example.h" @@ -259,7 +259,7 @@ which performs addition of two integers. b. Add configuration entry for the test suite to ``drivers/misc/Kconfig``: -.. code-block:: kconfig + .. code-block:: kconfig config MISC_EXAMPLE_TEST tristate "Test for my example" if !KUNIT_ALL_TESTS @@ -268,27 +268,27 @@ which performs addition of two integers. c. Append make goal for the configuration to ``drivers/misc/Makefile``: -.. code-block:: make + .. code-block:: make obj-$(CONFIG_MISC_EXAMPLE_TEST) += example_test.o 3. In order to enable the driver and its test suite, append configuration fragment to ``.kunit/.kunitconfig``: -.. code-block:: none + .. code-block:: none CONFIG_MISC_EXAMPLE=y CONFIG_MISC_EXAMPLE_TEST=y 4. Run the test: -.. code-block:: bash + .. code-block:: bash ./tools/testing/kunit/kunit.py run You should see the following output: -.. code-block:: none + .. code-block:: none ... [16:08:57] [PASSED] misc-example:misc_example_add_test_basic From patchwork Sun Oct 23 12:54:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 13016220 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 AE269C433FE for ; Sun, 23 Oct 2022 12:55:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230380AbiJWMzk (ORCPT ); Sun, 23 Oct 2022 08:55:40 -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 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org 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-guide/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. +.. _kernel-build-directory: + Build directory for the kernel ------------------------------ diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/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 =============== -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 case, -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. -Installing Dependencies -======================= -KUnit has the same dependencies as the Linux kernel. As long as you can -build the kernel, you can run KUnit. +Prerequisites +============= +No extra dependencies are required in order to use KUnit. See +:doc:`/process/changes` for details. Running tests with kunit_tool ============================= -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: .. code-block:: bash ./tools/testing/kunit/kunit.py run .. note :: - You may see the following error: - "The source tree is not clean, please run 'make ARCH=um mrproper'" + You may see the following error:: - This happens because internally kunit.py specifies ``.kunit`` - (default option) as the build directory in the command ``make O=output/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=um mrproper' - 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=um 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 invoked + as ``make O=.kunit``). A different build directory can be specified by + passing ``--build_dir`` option. Hence, before starting the build, + the source tree must be clean. -If everything worked correctly, you should see the following: + The caveat from the :ref:`kernel-build-directory` + also applies to running kunit_tool. -.. code-block:: +If everything worked correctly, you should see the following output:: Configuring KUnit Kernel ... Building KUnit Kernel ... Starting KUnit Kernel ... -The tests will pass or fail. +.. note :: + Depending on configurations enabled in the kernel, the build process + 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 (defconfig). +The following subsections allow you to customize the configuration as well as +filtering the test that will be run. .. 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=um``). If you + need to run test on other architectures see :ref:`kunit-on-qemu`. -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 to 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: .. code-block:: bash - cd $PATH_TO_LINUX_REPO - tools/testing/kunit/kunit.py config - cat .kunit/.kunitconfig + ./tools/testing/kunit/kunit.py config .. 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``. -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. There are many ways to customize the configurations: -a. Edit ``.kunit/.kunitconfig``. The file should contain the list of kconfig +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=.kunit/.kunitconfig`` target variable to make. You may + want to disable ``CONFIG_KUNIT_ALL_TESTS`` as it will enable a number of + additional tests that you may not want to be run. + +b. Add options with ``--kconfig_add``. For example, to include the + linked-list test you can run:: ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_LIST_KUNIT_TEST=y -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:: ./tools/testing/kunit/kunit.py run \ --kunitconfig ./fs/fat/.kunitconfig \ --kunitconfig ./fs/ext4/.kunitconfig -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=.kunit``. As long as its a superset of - ``.kunitconfig``, kunit.py won't overwrite your changes. - - .. note :: - To save a .kunitconfig after finding a satisfactory configuration:: - - make savedefconfig O=.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 ``.config`` Filtering tests by name ~~~~~~~~~~~~~~~~~~~~~~~ -If you want to be more specific than Kconfig can provide, it is also possible -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 passing +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. -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:: ./tools/testing/kunit/kunit.py run "kunit_executor_test" -b. inform the name of a test case prefixed by its test suite, - like ``"example.example_simple_test"``, to run specifically that test case:: +b. Pass the fully qualified name of test case to run the specific case:: ./tools/testing/kunit/kunit.py run "example.example_simple_test" -c. use wildcard characters (``*?[``) to run any test case that matches the pattern, - like ``"*.*64*"`` to run test cases containing ``"64"`` in the name inside - 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:: ./tools/testing/kunit/kunit.py run "*.*64*" -Running Tests without the KUnit Wrapper -======================================= -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 +================================ +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. .. 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). -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. -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. -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 (printed +out) in the TAP format. .. note :: - Some lines and/or data may get interspersed in the TAP output. + Some lines and/or data may get interspersed in the output. Writing Your First Test ======================= @@ -298,17 +284,3 @@ You should see the following output: ... Congrats! You have just written your first KUnit test. - -Next Steps -========== - -* 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. From patchwork Sun Oct 23 12:54:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 13016225 X-Patchwork-Delegate: brendanhiggins@google.com 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 61C1CFA373D for ; Sun, 23 Oct 2022 12:57:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230401AbiJWM5o (ORCPT ); Sun, 23 Oct 2022 08:57:44 -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 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@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-tools/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: + intro start architecture run_wrapper @@ -19,95 +20,3 @@ KUnit - Linux Kernel Unit Testing tips running_tips -This section details the kernel unit testing framework. - -Introduction -============ - -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’s unittest.mock, and GoogleTest/GoogleMock -(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.py``) -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 -============ - -A unit test tests a single unit of code in isolation. A unit test 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 -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? -================ - -* 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-tools/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 +===================== + +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’s unittest.mock, and GoogleTest/GoogleMock +(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. From patchwork Sun Oct 23 12:54:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 13016221 X-Patchwork-Delegate: brendanhiggins@google.com 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 240CEECAAA1 for ; Sun, 23 Oct 2022 12:56:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230410AbiJWMz5 (ORCPT ); Sun, 23 Oct 2022 08:55:57 -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 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org 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 ============================= -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. kunit_tool is a Python script which configures and builds a kernel, runs tests, and formats the test results. -Run command: +To run the tests: .. code-block:: ./tools/testing/kunit/kunit.py run -We should see the following: +You should see the following output: .. code-block:: @@ -26,124 +25,112 @@ We should see the following: Building KUnit kernel... Starting KUnit kernel... -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: .. code-block:: ./tools/testing/kunit/kunit.py run --timeout=30 --jobs=`nproc --all` -- ``--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:: -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 +==================== + +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. 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: .. code-block:: ./tools/testing/kunit/kunit.py run --kunitconfig=fs/ext4/.kunitconfig -To view kunit_tool flags (optional command-line arguments), run: +Customizing configuration +------------------------- -.. 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. - ./tools/testing/kunit/kunit.py run --help - -Creating a ``.kunitconfig`` file -================================ - -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/tools/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``: .. code-block:: cd $PATH_TO_LINUX_REPO cp tools/testing/kunit/configs/default.config .kunit/.kunitconfig -We can then add any other Kconfig options. For example: +You can then customize the configuration. As with configuring regular kernels +for production deployment, it is recommended to use +:doc:`one of configuration interfaces `. For example, +to configure through menuconfig:: -.. code-block:: + make O=.kunit KCONFIG_CONFIG=.kunit/.kunitconfig menuconfig - CONFIG_LIST_KUNIT_TEST=y +.. 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:: -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 -.. 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=.kunit menuconfig``. +Step-by-step run +================ -Configuring, building, and running tests -======================================== +It is possible to sequentially run testing steps for finer-grained control. -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: .. code-block:: ./tools/testing/kunit/kunit.py config -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: .. code-block:: ./tools/testing/kunit/kunit.py build -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: .. code-block:: ./tools/testing/kunit/kunit.py exec -The ``run`` command discussed in section: **Running tests with kunit_tool**, -is equivalent to running the above three commands in sequence. - Parsing test results ==================== -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: .. code-block:: ./tools/testing/kunit/kunit.py run --raw_output -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. .. code-block:: bash @@ -155,74 +142,63 @@ standard input. Filtering tests =============== -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``): .. code-block:: ./tools/testing/kunit/kunit.py run 'kunit-resource*' -This uses the standard glob format with wildcard characters. - .. _kunit-on-qemu: Running tests on QEMU ===================== -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: -- ``--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. + Not all architectures currently support this flag. For such architectures, + use ``--qemu_config`` instead (discussed later). If ``um`` is specifed (or + if this option is not given), the tests will run in UML kernel. Otherwise, + the tests run on QEMU. -- ``--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. - - ``sparc64-linux-gnu`` if we have the sparc toolchain installed on - our system. +Examples: - - ``$HOME/toolchains/microblaze/gcc-9.2.0-nolibc/microblaze-linux/bin/microblaze-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: -This means that for most architectures, running under qemu is as simple as: - -.. code-block:: bash + .. code-block:: bash ./tools/testing/kunit/kunit.py run --arch=x86_64 -When cross-compiling, we'll likely need to specify a different toolchain, for -example: + - To cross-compile and test for s390: -.. code-block:: bash + .. code-block:: bash ./tools/testing/kunit/kunit.py run \ --arch=s390 \ --cross_compile=s390x-linux-gnu- -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`` option, +or to customize QEMU invocation, you can write ``QemuConfig`` configuration, +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. -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. + +For example, to specify QEMU configuration for native x86_64 architecture +with 12 build jobs and 60 seconds timeout: .. code-block:: bash @@ -231,93 +207,9 @@ as --jobs=12 \ --qemu_config=./tools/testing/kunit/qemu_configs/x86_64.py -Running command-line arguments -============================== +Command options +=============== -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:: -- ``--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=1``. - -- ``--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=y`` to your - ``.kunitconfig``. - -- ``--kunitconfig``: Specifies the path or the directory of the ``.kunitconfig`` - 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=y - -- ``--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 qemu. - 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/microblaze-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, ``-smp 8``. - -- ``--jobs``: Specifies the number of jobs (commands) to run simultaneously. - By default, this is set to the number of cores on your system. - -- ``--timeout``: Specifies the maximum number of seconds allowed for all tests to run. - This does not include the time taken to build the tests. - -- ``--kernel_args``: Specifies additional kernel command-line arguments. May be repeated. - -- ``--run_isolated``: If set, boots the kernel for each individual suite/test. - 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. Possible options are: - - - ``all``: To view the full kernel output, use ``--raw_output=all``. - - - ``kunit``: This is the default option and filters to KUnit output. Use ``--raw_output`` or ``--raw_output=kunit``. - -- ``--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 From patchwork Sun Oct 23 12:54:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 13016222 X-Patchwork-Delegate: brendanhiggins@google.com 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 DA5E5C433FE for ; Sun, 23 Oct 2022 12:56:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230431AbiJWM4S (ORCPT ); Sun, 23 Oct 2022 08:56:18 -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 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org 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/dev-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 ============================ -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. -.. 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:: -Configure the Kernel + Using KUnit is not recommended in production system, since + stability and security issues may occur if it is enabled. + +Kernel configuration ==================== -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 always) +have configuration name suffixed with ``_KUNIT_TEST``. As with other kernel +configurations, most tests can be enabled either builtin or as module. -- 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:: -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. -.. 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. - 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``. -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:: -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``. From patchwork Sun Oct 23 12:54:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 13016223 X-Patchwork-Delegate: brendanhiggins@google.com 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 306A5FA373D for ; Sun, 23 Oct 2022 12:56:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230457AbiJWM4Y (ORCPT ); Sun, 23 Oct 2022 08:56:24 -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 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org 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-tools/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 ---------- -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 under 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: .. code-block:: c @@ -22,18 +24,17 @@ and then sets *expectations* for what should happen. For example: } In the above example, ``example_test_success`` always passes because it does -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 case 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 and +signal the test as failed. 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: .. code-block:: c @@ -43,18 +44,16 @@ logged. For example: KUNIT_EXPECT_EQ(test, 2, add(1, 1)); } -In the above example, ``add_test_basic`` makes a number of assertions about the -behavior of a function called ``add``. The first parameter is always of type +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 context. -The second parameter, in this case, is what the value is expected to be. The -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 these -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. -A test case *fails* when any expectation is violated; however, the test will -continue to run, and try other expectations until the test case ends or is -otherwise terminated. This is as opposed to *assertions* which are discussed -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* which +are discussed later. To learn about more KUnit expectations, see Documentation/dev-tools/kunit/api/test.rst. @@ -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. -For example, if we want to rigorously test the ``add`` function above, create -additional tests cases which would test each property that an ``add`` function -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: .. code-block:: c @@ -93,8 +91,10 @@ should have as shown below: Assertions ~~~~~~~~~~ -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: .. code-block:: c @@ -112,21 +112,22 @@ terminates the test case if the condition is not satisfied. For example: KUNIT_EXPECT_LE(test, a[i], a[i + 1]); } -In this example, the method under test should return pointer to a value. If the -pointer returns null or an errno, we want to stop the test since the following -expectation could crash the test case. `ASSERT_NOT_ERR_OR_NULL(...)` allows us -to bail out of the test case if the appropriate conditions are not satisfied 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 out +with ``KUNIT_ASSERT_NOT_ERR_OR_NULL()`` since the following expectation that +asserts the array order could crash it. Test Suites ~~~~~~~~~~~ -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 suite* +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: .. code-block:: c @@ -147,21 +148,21 @@ suite and/or every test case. For example: }; kunit_test_suite(example_test_suite); -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 called -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 initialized +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 KUnit. .. note:: A test case will only run if it is associated with a test suite. -``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 specified +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). For more information, see Documentation/dev-tools/kunit/api/test.rst. @@ -170,25 +171,23 @@ For more information, see Documentation/dev-tools/kunit/api/test.rst. Writing Tests For Other Architectures ------------------------------------- -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 specific -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. -Nevertheless, there are still valid reasons to write a test that is architecture -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 hardware, -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. -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 normal -KUnit tests. +Writing architecture-specific and hardware-specific tests is the same as +writing any other tests. .. important:: - We may have to reset hardware state. If this is not possible, we may only - 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. .. TODO(brendanhiggins@google.com): Add an actual example of an architecture- dependent KUnit test. @@ -200,38 +199,41 @@ Isolating Behavior ------------------ Unit testing limits the amount of code under test to a single unit. It controls -what code gets run when the unit under test calls a function. Where a function -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 function +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 comes from two constructs: classes, which are structs that contain function pointers -provided by the implementer, and architecture-specific functions, which have -definitions selected at compile time. +provided by the implementer; and architecture-specific functions, which have +definitions determined at compile time. Classes ~~~~~~~ -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 GNOME'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 GObject); +the Linux kernel is no exception. The central concept in kernel object oriented programming is the class. In the kernel, a *class* is a struct that contains function pointers. This creates a contract between *implementers* and *users* since it forces them to use the -same function signature without having to call the function directly. To be a -class, the function pointers must specify that a pointer to the class, known 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 order +to be a class, the function pointers must specify that a pointer to the class +(known 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*. -A class can be *overridden* by *child classes* by embedding the *parent class* -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 because the -pointer to the parent is always a fixed offset from the pointer to the child. -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 class* +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 base +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: .. code-block:: c @@ -259,8 +261,8 @@ example: self->width = width; } -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. Faking Classes ~~~~~~~~~~~~~~ @@ -269,11 +271,13 @@ In order to unit test a piece of code that calls a method 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. -A fake class implements a piece of code that is different than what runs in a -production instance, but behaves identical from the standpoint of the callers. -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: .. code-block:: c @@ -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); }; -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: .. code-block:: c @@ -295,7 +300,8 @@ And we want to test code that buffers writes to the EEPROM: struct eeprom_buffer *new_eeprom_buffer(struct eeprom *eeprom); void destroy_eeprom_buffer(struct eeprom *eeprom); -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``: .. code-block:: c @@ -331,7 +337,7 @@ We can test this code by *faking out* the underlying EEPROM: memset(this->contents, 0, FAKE_EEPROM_CONTENTS_SIZE); } -We can now use it to test ``struct eeprom_buffer``: +You can now use it to test ``eeprom_buffer``: .. code-block:: c @@ -425,11 +431,12 @@ We can now use it to test ``struct eeprom_buffer``: Testing Against Multiple Inputs ------------------------------- -Testing just a few inputs is not enough to ensure that the code works correctly, -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. -We can write a helper macro or function. The function is called for each input. -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: .. code-block:: c @@ -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. -The ``_MSG`` variants are useful when the same expectation is called multiple -times (in a loop or helper function) and thus the line number is not enough 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. -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: .. code-block:: c @@ -478,18 +488,14 @@ helper macro variation, for example: } -There is more boilerplate code involved, but it can: +There are advantages of *table-driven tests*: -* be more readable when there are multiple inputs/outputs (due to field names). - - * 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 outputs. + 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. Parameterized Testing ~~~~~~~~~~~~~~~~~~~~~ @@ -497,8 +503,8 @@ Parameterized Testing The table-driven testing pattern is common enough that KUnit has special support for it. -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: .. code-block:: c @@ -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); - // 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); } - // 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[] = { 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 ------------------------------------ -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 expectations. +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: .. code-block:: c @@ -567,12 +577,15 @@ execution. In some cases, it is unsafe to continue. We can use the Allocating Memory ----------------- -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. -This is useful because it lets us use the ``KUNIT_ASSERT_EQ`` macros to exit -early from a test without having to worry about remembering to call ``kfree``. -For example: +This is useful because it lets you to use ``KUNIT_ASSERT_EQ`` macros to exit +early from a test without having to worry about remembering to freeing +memory with ``kfree``. + +The following example tests allocating buffer memory: .. code-block:: c @@ -589,9 +602,11 @@ For example: Testing Static Functions ------------------------ -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 unconditionally, +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: .. code-block:: c @@ -606,7 +621,11 @@ example: Injecting Test-Only Code ------------------------ -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 configuration +is disabled, the hook is defined as empty function: .. code-block:: c @@ -619,19 +638,21 @@ Similar to as shown above, we can add test-specific logic. For example: void test_only_hook(void) { } #endif -This test-only code can be made more useful by accessing the current ``kunit_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. Accessing The Current Test -------------------------- -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. -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: .. code-block:: c @@ -665,25 +686,28 @@ The example below includes how to implement "mocking": KUNIT_EXPECT_EQ(test, fake_foo(1), 42); } -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. -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 the 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 providing +the same flexibility as ``priv``, but also, for example, allowing helper functions to create resources without conflicting with each other. It is also -possible to define a clean up function for each resource, making it easy to -avoid resource leaks. For more information, see Documentation/dev-tools/kunit/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. Failing The Current Test ------------------------ -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 data -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: .. code-block:: c