From patchwork Sun Oct 23 13:08:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 617704 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 68353FA373D for ; Sun, 23 Oct 2022 13:10:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230373AbiJWNKG (ORCPT ); Sun, 23 Oct 2022 09:10:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41504 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229772AbiJWNKF (ORCPT ); Sun, 23 Oct 2022 09:10:05 -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 B27902A727; Sun, 23 Oct 2022 06:09:56 -0700 (PDT) Received: by mail-pl1-x629.google.com with SMTP id f23so6346700plr.6; Sun, 23 Oct 2022 06:09:56 -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=CtunuXO8m4PYEN57qEqqRDwHZptjPq9qkJyZNyO0ImI0F7xs3oRL7o6JoVfZ+fy2fi ki1AEm8Rw/ivSQSZ2K7M0d6s1lgcDCxCA6xojppefOqkPc5K88OT/PTSBhDy2qKMs45f JAuk6rfqbtROG9/Go++G53Bq6/8I0fL/AVhSrIeRozGktIWugy6yuv5NbvKzHh+46aSf U/JcOpRRxacw/KKzrt2aAw4TYKsoXEyzxsJaaXWSlMqorUDPq9nWlPnVPPLM4u8oO4Rr kUGDZ5R/mfbSlFwjrSozTGCe6It+TV4jY0dn74U2Yv8HVLVR0Jm7hmBnPacQJKx856ad gcuw== 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=44uZZ971rqo9eavo7vzbBoMw20TleZL08Y7naB4N59T/+t0KYidVt2Mwk8Y/vElXq5 WQvsNQIw7g640EHvLd0LVap3YgjS1sU6JTiJPGYDTjow6XDY/bcWd+RNPbggWSLwBhNv BOpInC2NQQ6nmPqp+Luax5ZylPsD6Mw9CD0HVM8zVj61CbJ6QjZ6v3wTpbIAPhSih4x9 Yep28isaFZvNRuzFpf+qJz3YtJ4Zgq0X9vtT6hx1e+cpyBo9bg2OYRaIeknzL8OWcK1U TK0FsTSUVs54YwmBFzXsAE3cruojD00U+49Z1WXrqXlhphGbz4YLMbDbfglNgErLBwB2 jLlQ== X-Gm-Message-State: ACrzQf1fD9SggdxuF2j9s6pmp81xxOCPXUhrprfhdSJJUDfwQpMHfVIv oY8m972sF82sFcuQtGonCtHHVV7u4FBCqg== X-Google-Smtp-Source: AMsMyM4e24G/F3iOwPY3YBO/bvgKOsKRM/trREKWL2GqPInbpejwJPBtZq4kBW5DGaEycyK5EhNFvA== X-Received: by 2002:a17:903:2410:b0:17a:b32:dbec with SMTP id e16-20020a170903241000b0017a0b32dbecmr28521854plo.163.1666530595958; Sun, 23 Oct 2022 06:09:55 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id d5-20020a623605000000b0056b6c7a17c6sm3411713pfa.12.2022.10.23.06.09.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 06:09:55 -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 RESEND 1/7] Documentation: kunit: rewrite "Writing Your First Test" section Date: Sun, 23 Oct 2022 20:08:41 +0700 Message-Id: <20221023130846.63296-2-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023130846.63296-1-bagasdotme@gmail.com> References: <20221023130846.63296-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=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhNrc8U95+utbIv//pj3C3Q4oG6p4sug3rJwY0Ka//sj/4 VMfyjlIWBjEOBlkxRZZJiXxNp3cZiVxoX+sIM4eVCWQIAxenAEzE4B4jQ/8UN8ZLEhNufVO272/2jw kyOex7poot5e/t9Q7mbEulFjL8lRbdV/Ou6OAynVkHv+16f3HGSm3j3bX5T/Zvnca82jR8NycA 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 13:08:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 618533 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 F070DC433FE for ; Sun, 23 Oct 2022 13:10:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230388AbiJWNKN (ORCPT ); Sun, 23 Oct 2022 09:10:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230354AbiJWNKG (ORCPT ); Sun, 23 Oct 2022 09:10:06 -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 781302D1F4; Sun, 23 Oct 2022 06:10:00 -0700 (PDT) Received: by mail-pg1-x530.google.com with SMTP id h185so6539293pgc.10; Sun, 23 Oct 2022 06:10:00 -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=CykSc9zEqnTDY8iD1nH8ko4JZcgt9k+43FS1+9u9eQtHEbFJgkAoJtjMg00t5auwyA qdgadz3VF1GMRZvx3Fzm9q+0BZhbSCxCygsM48C0z9O7LIcfdLcJie8F9jdi8oZd8eoq FZp8Qj/nUPwfNsqyHP0oL75uVpkrxB0DGTuPhrqib9I9GyL+53vdy9KLkeFH2qzrhfkT YTBIwECJJ6B0cAGSHBPC5TIMWl6qpjDgYeYHiq0b6CNL9aKaRcYUSUPQh5e6iE0bfqPg crHoqzZHTTBd8ky+hoN0x/td92TDDWDD2+F0iVolb16ETZPsPADXdfYJgmU1BThFdaRM QWtQ== 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=XqDCS7BTKrbC7Vu6Huar3gMw3IsiLtmfG/Po662cIK2yLT07D6htZLo7GMEn/t97vh 25krk2iZOzzEQnJOw+cjeDESXl6wmlDqPaMz1g2A0Lnpm+UwUzsLDS7rXmQ7vh0Jshni g32Nkp9HxDh75EAlmbHhBi0j17VSHwDdk7Js3+bKJ25pqUF3xpetL3dFH1mKOWjjmObc Q+QpePQ2caHMww8nx+9tzI/3SqGLk3FgLex0DIjxmVRg00psCqVLACPwHAwewJ/oHEMh nnB4ZDkZXVy9gTL1Njd7eW4qVxHLV8Ti4LdA2MfQl6Fbfpq52FELo3GPC5MbQ45ALUTk SIlQ== X-Gm-Message-State: ACrzQf2Uj67WahGySss7sTYcd077SvjNvC0j7WeiM5LiZ8lbRlj6SGhv v6ICb/cIMXZQ5Nzi5dZQj/wZsy1i0T9XKg== X-Google-Smtp-Source: AMsMyM47nodA314qahMPh6g8SvdC4dCQBnGB2oR2EZPU/vbjq6xM0NG7lUH4A29aZfh80xyyuM4XWQ== X-Received: by 2002:a63:c4e:0:b0:45f:795:c20a with SMTP id 14-20020a630c4e000000b0045f0795c20amr24634785pgm.559.1666530599712; Sun, 23 Oct 2022 06:09:59 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id d5-20020a623605000000b0056b6c7a17c6sm3411713pfa.12.2022.10.23.06.09.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 06:09:59 -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 RESEND 2/7] Documentation: kunit: align instruction code blocks Date: Sun, 23 Oct 2022 20:08:42 +0700 Message-Id: <20221023130846.63296-3-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023130846.63296-1-bagasdotme@gmail.com> References: <20221023130846.63296-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=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhNrdv2e+rNH+o/CTJQyNnfdzKmadeX5Sq+ff38jMztfQ1 dusndpSyMIhxMMiKKbJMSuRrOr3LSORC+1pHmDmsTCBDGLg4BWAiPy4z/OG7f7DlzsFtW/Wey5x0fC FzYPfDBAXj+9ucV0u91f6YYTOPkWHZtYSP884kLo8UUVeZ+eYmq+72PWcmLY5bMGe7Z93y+dkMAA== 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 13:08:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 617703 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 3CA55C433FE for ; Sun, 23 Oct 2022 13:10:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230414AbiJWNK2 (ORCPT ); Sun, 23 Oct 2022 09:10:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41908 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229772AbiJWNKO (ORCPT ); Sun, 23 Oct 2022 09:10:14 -0400 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8BD8A3B96F; Sun, 23 Oct 2022 06:10:04 -0700 (PDT) Received: by mail-pf1-x435.google.com with SMTP id d10so6879410pfh.6; Sun, 23 Oct 2022 06:10:04 -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=P1soqzH7T7eLdsYv5gwkYyTkQj+2rv30evQvOV1NjvgmlWhVseOSTSHC1/wU51c/uP 99pzPWYGJ1tBU5E+gTUsgomFLrlMtWYExKdSTomf6LqZJCV0/nX0RNl7i3Q8BBc5sqg2 K4Za+uqivu+v1qz/hfT+eYnxSIODTbZZzz84tBrFFEsR3WOJBs91w2OoWAXGHFXw9c3M xPaWvKjQilX8FwWo0ek4CNHwIgv9ujAMqVz3YWLriNi/6heEWLZitpWITDa2ayeELkeF m6m/HTFDoJ5KklXrRcA9jwEcBH2zsqsCmpk1aTACZoIAAVQjHg5Op1AtbQ3Vnw2bS74p EFTA== 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=mlTpWBWL5rmPshbON5Q6kvKQUcCVgwj1P4vWorHWZpjtKv6bFfTrd/dy7PmEwj5seX w0hDjxVbmVBdY6KEFu1f/Iw0pcrMh1hWVPzm9j7vT7nnRiT68y2fi/Hg+dUZJDc6gbKT riau5TCBvGi7Ysuk7KSLFqGugJB+hAYJPOwdfmUOxevAYSLIfGqpWI+BBIjcFXTh2xCu wPeG/iTPwKZRP0tEH2V3gjkdGBm9+LGHMQBGKKT0a3S+3ARc4Z+axLio3+MDi2JZMurr e7A6J+bfNuuavfe6tRC/lBdIrhBI38rKH6nDe2GcXfZf6cd9XYqMy+Fd1DDqafYTqFPI FRsA== X-Gm-Message-State: ACrzQf2fMokFLPOXtLflgiZ65KJi4uaPNyVPTc+TVpaEb+0L6fcGqvrS 76BCtYbynJXFpD6il9yzr7p4C0jQFnGYJA== X-Google-Smtp-Source: AMsMyM65f1LcqlTWVoN89y85Kui3FEyXtagCBBUCKyBtbXrxd5EXtZW5/1QLwRoihqkmG+MiLGqxKA== X-Received: by 2002:a63:82c3:0:b0:46e:c4e4:f8cb with SMTP id w186-20020a6382c3000000b0046ec4e4f8cbmr8274020pgd.155.1666530603362; Sun, 23 Oct 2022 06:10:03 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id d5-20020a623605000000b0056b6c7a17c6sm3411713pfa.12.2022.10.23.06.10.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 06:10:03 -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 RESEND 3/7] Documentation: kunit: rewrite the rest of "Getting Started" documentation Date: Sun, 23 Oct 2022 20:08:43 +0700 Message-Id: <20221023130846.63296-4-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023130846.63296-1-bagasdotme@gmail.com> References: <20221023130846.63296-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=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhNrcnlJ0t2N93nyutoz37sUNPbXHsBTemWcwpky/PefIm 1Sq7o5SFQYyDQVZMkWVSIl/T6V1GIhfa1zrCzGFlAhnCwMUpABPhvcnwz0zZ/HtgyqR9f+ZI3fbuPl d+LYG906/Gv7ktScbnTUlyESPDfO36muBevsvh8Qd19EM3hZ2JaT98aLrJnGLGw7vqJn9hAgA= 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 13:08:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 618532 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 15F53FA373D for ; Sun, 23 Oct 2022 13:10:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230379AbiJWNKb (ORCPT ); Sun, 23 Oct 2022 09:10:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41880 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230382AbiJWNK0 (ORCPT ); Sun, 23 Oct 2022 09:10:26 -0400 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D120A2B62B; Sun, 23 Oct 2022 06:10:08 -0700 (PDT) Received: by mail-pj1-x1033.google.com with SMTP id u8-20020a17090a5e4800b002106dcdd4a0so10768368pji.1; Sun, 23 Oct 2022 06:10:08 -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=V5YgVNMgjszbblHEDyqPSxsjWUu4N4smV90rArkkVXcL+IIhSEONA0CHFv8/zxwx0M VmdEwZ6G5oD3BwByNlhSoUR2UxEsuYprGs/hDQCe7J2b4e/Y/8C/xVwKpz1ss1kkCpeN NWnBqjXxdMIHsjq38Q7hatqJFp6LBLGn5D0LIXec+6YO5FvtIkSbvXUjyZHDSuIk4MSj L32xc9RopO3zi/NmDBLEtKFOd48EsYyOAvy+QaO2/9KmxtYd4WAygnSv+QkDlu458ubF Al4djohhPxKgZvbnGWG2sYLmA9WNcMSGMvEGDvkCMxM8Z3+W3GCYVTCdCTNxSvFNOywV G/yw== 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=OV/SwiAj3e8zrU/tiVuI6j3KJ08PbxkMVk1jrx63XYxUFpIkfvQ4vo6V/dkMN9OjNN NfR31APYERqC2gYFPR4oIBhZJGH8plzCrxu0wqNKJzky8xRHLRLsurETKCCOOgUTW8cw Thq8X6bUe2DU0BHa3x6SfdoAKS27lwWULxwDS5Mr9E4HPGOB/AWax0D7Zbd2JkzOFa8l VgmZ9O2SDQK+MmqvfvqvPWSxdykmlqYZCgkCcbM8rRxgTXFRtSzPUFPNEdvuq/Kj/kIi Yh2QyYHdm8lUkNzGv8yrXfZxFbActZRv/Eu7ObzIm8TS0OTzO/N5EG2aEaGMjTNtG5m5 9CIg== X-Gm-Message-State: ACrzQf1WnAodgKVpCUtpCTUfqZoBoRwse9D7aCui9bPOX0Uiscl+E81r HyF/OAFvJi8ac8K9aCOqbN0uCtyRjp4tiQ== X-Google-Smtp-Source: AMsMyM5D8JgcvYw5Kjkm8KB0mwlZwcENACiSFARJGCnMpCh9tFlekvzy5gswZHnVFBwvIAHoy4jahA== X-Received: by 2002:a17:902:7849:b0:186:68b9:e1ae with SMTP id e9-20020a170902784900b0018668b9e1aemr16679819pln.139.1666530607200; Sun, 23 Oct 2022 06:10:07 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id d5-20020a623605000000b0056b6c7a17c6sm3411713pfa.12.2022.10.23.06.10.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 06:10:06 -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 RESEND 4/7] Documentation: kunit: move introduction to its own document Date: Sun, 23 Oct 2022 20:08:44 +0700 Message-Id: <20221023130846.63296-5-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023130846.63296-1-bagasdotme@gmail.com> References: <20221023130846.63296-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=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhNrd/pHycFLteIn754pKqg6Hn4/9VPmxYIn7uVeZGdvdH BZ4HO0pZGMQ4GGTFFFkmJfI1nd5lJHKhfa0jzBxWJpAhDFycAjCRq7MZ/sdLXvxvcc/U8RMvw9V/Pj 9XG72XkpzueDFs557G+fWM/88zMqwt+yeud8zpvphYSMatQt89zQlnFZZsv7U5urpx2st5vhwA 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 13:08:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 617702 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 CE65AECAAA1 for ; Sun, 23 Oct 2022 13:10:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230465AbiJWNKy (ORCPT ); Sun, 23 Oct 2022 09:10:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230420AbiJWNKj (ORCPT ); Sun, 23 Oct 2022 09:10:39 -0400 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5D2E04D4FD; Sun, 23 Oct 2022 06:10:13 -0700 (PDT) Received: by mail-pl1-x633.google.com with SMTP id p3so5402630pld.10; Sun, 23 Oct 2022 06:10:12 -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=GSV9FNyNXc1sybIGkqg9OtSEJmUHhQPBeNhwFVmkduFFFaX8zlqKbRejIu1PG6xtTQ 6B1/nkkX7mWSqMohtGdQsOQ8nv6sx77z2EfYe8CP/nh6aewxAB/ycy5Uo8hNSD+dy8HF SvpFAyzltEa8RRNECyPbAetPY0X+/P3TET3wfKtZMzXjV5/ciz+sNEAs9+1IB+WO2NJa Z6LYY7Zt+OxZ+ZVK9T5ACc3QpS4rjuzEGYFsbXHYi29oCi2GszjiLop28r5SKU7ovSZi jj9CwSrpL9FGzy5VLLHB2fu8FsRkm/zzJPSz4bUINxECntYCAWvHrJEVvjOA8b8UfGqD DicQ== 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=EI79/FQcmQM4rbMVaGXokOTtYRlz3NMSgqmVeqCV4hHYlLR0R9olZojBChY2vSN9JL Wlnww54bgnpj/4At0pcg6DIKy65ldnFThSo0r9vF72CCA497NTxlqE7PHcn+VES0o3Sg vUub1dFfuyhVtIeCp2tz6z5jCt4dtLUucXVKaLl37dQ9qhUnfuTs0xAr2y5AEDEI8J07 Eq8ZiZfvVrIAaTyGJt62Mjchtxu0AAe6ucHxUkxXy+HM9YIuyuMO2J1T8HldY6or3k+H WIJSh02nURfv1kwG+KfweUt4xD0CJpTMhbiPJ1ffyJjy0dRMJ6VZcZEH7IHH6/grcEmL W9xw== X-Gm-Message-State: ACrzQf1o+cE9bcnJf7uq0dCsD6fWvDz8enwFwS1S0NDWA3nupOc3MUaP gwwi4ihh8q9ZUfP9zl1grk5HILOxonTPbw== X-Google-Smtp-Source: AMsMyM70gKvWxXh36FqZzSG8Wa1atZsBFaBJnJoQOQe1Y9QOcqK724LoeRh0JV85vDzjowbn14lJmg== X-Received: by 2002:a17:90a:e593:b0:212:f0e8:46ca with SMTP id g19-20020a17090ae59300b00212f0e846camr5824932pjz.144.1666530610720; Sun, 23 Oct 2022 06:10:10 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id d5-20020a623605000000b0056b6c7a17c6sm3411713pfa.12.2022.10.23.06.10.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 06:10:10 -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 RESEND 5/7] Documentation: kunit: rewrite "Running tests with kunit_tool" Date: Sun, 23 Oct 2022 20:08:45 +0700 Message-Id: <20221023130846.63296-6-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023130846.63296-1-bagasdotme@gmail.com> References: <20221023130846.63296-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=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhNnfash6ZKD5YdUItM9VHIbYvfHbG967ptT/W7trzbE37 j+dhHSUsDGIcDLJiiiyTEvmaTu8yErnQvtYRZg4rE8gQBi5OAZjI8zsM/+sVc5RFzabafKtpiYz4cm bu+dalE7ZZ7Vb4/cSL/4iPex/D97rrwb0d3XwnOBSDnM5J3PRy0W08UPHFoujD8wkThXx5AQ== 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 13:08:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 618531 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 296AEFA373D for ; Sun, 23 Oct 2022 13:10:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230436AbiJWNK4 (ORCPT ); Sun, 23 Oct 2022 09:10:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41908 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230380AbiJWNKq (ORCPT ); Sun, 23 Oct 2022 09:10:46 -0400 Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E31B94F1AF; Sun, 23 Oct 2022 06:10:15 -0700 (PDT) Received: by mail-pf1-x42f.google.com with SMTP id i3so6852375pfc.11; Sun, 23 Oct 2022 06:10:15 -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=bUfSX6OBl/3BuaM0LJu+t5ru0UDx/Jh94VdHjnH1pmGbysWZYCzwCP6lPKuK+ScpCN en9MG3COU0Vkrfr//b15bQHz8vxaLkIW0ozECoxEN26j+CzWvLg0gUrT3saq8aQKBMt2 f+00q9X0V4iKMt5ooc8w7nOG+IcEwbGv1SfLSnZ9Zdzty1TaYTYldk6u3aD/fzUSGqi2 PwHvtkkAKu/cNTb+uPw76SOuzvHF1Ll2Q6r4fw5+v3zacHkeG8pX1bIuBKahPuVmD3EU 60OL8NVjhqqe78u96Nl+mYFsmQyiY7BmOvgyHfQOPV2JWLKzayCzTDtCSgAejLDqUK7h 2svg== 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=u4mjPrpcCKCLy03Xuc+6Scl2fYifpkGs8FIGPV7VhtHjSMEdZLaJcuI2mpua8kMB7+ P2cvnyVWFSJX2Qz1dNDc8kxbPMUm8LNRGaTNBXXeMIeyQPljQhJ6S9ESqrLTvfEj49Al A6v0zpBQ4bziKDHDgioE7dsrbNbWp8h22EX0N0CearOi9IH3DDrDPVplOh1UdQjrIZDC xbIW6HjGevs0xhmDfhuE/at0GdmHg2QTYEleGuxoocPK2p15kkOUlVNzcCh0ExZmsCaj LQw5vxcB4vaYYWJDHkkte0nLxa77recMWYITlvyfr+EurBAt0D6mr35u4Za39M9RZjbw NYPg== X-Gm-Message-State: ACrzQf0QdRcDyLbyaPC+3IgdGHo0X1DTfIh3skwc0B33JX9Fv4NxqoYe mf0tZlngKZFFpDRXK8UU2cukOQ/QgDxETA== X-Google-Smtp-Source: AMsMyM4DMjZk7yCd40+OB/yUMR0quoLYWDpaauPC5ZvK5NxJ8EL2gwuO5ynBBHvWtl9hhJQk2cfmLw== X-Received: by 2002:a63:235c:0:b0:459:5fef:88ab with SMTP id u28-20020a63235c000000b004595fef88abmr24482335pgm.312.1666530614310; Sun, 23 Oct 2022 06:10:14 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id d5-20020a623605000000b0056b6c7a17c6sm3411713pfa.12.2022.10.23.06.10.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 06:10:14 -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 RESEND 6/7] Documentation: kunit: rewrite "Run Tests without kunit_tool" Date: Sun, 23 Oct 2022 20:08:46 +0700 Message-Id: <20221023130846.63296-7-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023130846.63296-1-bagasdotme@gmail.com> References: <20221023130846.63296-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=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhNncmTcpeqnJqC5fPEW1LIz/V+zU7d3BILKyOMLx8wPJ3 4eaMjlIWBjEOBlkxRZZJiXxNp3cZiVxoX+sIM4eVCWQIAxenAExEQ5Dhv0eRO0NB3rSIHa2uT61mfV 8odUg0NP/2zD0Cc8L1DdTuf2D4py0RzZZe57REy5+lu3CjGW+lh8eKfR9edi5dw1Zr2m3HCwA= 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 13:08:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bagas Sanjaya X-Patchwork-Id: 617701 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 624A3ECAAA1 for ; Sun, 23 Oct 2022 13:11:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230303AbiJWNLM (ORCPT ); Sun, 23 Oct 2022 09:11:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44688 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230457AbiJWNKx (ORCPT ); Sun, 23 Oct 2022 09:10:53 -0400 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 516B554CA0; Sun, 23 Oct 2022 06:10:20 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id u6so6325573plq.12; Sun, 23 Oct 2022 06:10:19 -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=ETvKLwIy4N3Yxy995W9XmRZYzueJOJVA9EnXQOdgXTDCOeNOpnlfYkiMBKkGYXJ80w g02UTuvMJuuwAaSXKEvBMru1/E/NbJIqwGLNS+aFOei82FgiYKfTMNDhP46DUe2KLqLD vhQPlbWtSQeAJCP09RD72kiYUxg+d77ARPhsxUEOyDga7qEDI6UMPANOpciil2sNhJ0O kHo27NMgrfomjxh8X1/4iXMIQpejwXGX+X4ATbWZbQ3XCFoxAa6iVgdwpdRM52seCT/W DMSsZ7XVhqfErTiv8VKFDko2oP/LPPoCESr9mcP2nI6VuNjQG2yilHE4e/+gYnwBQuvT 1z8Q== 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=gOSrmY0jtcLJxmIF+ntkBfDjSuA166hGI0jS7mia0B7UU9V8sjg+zB0hSk0H3WwOkx 6K6aDGhTutr0aIqW67lpDMsjC9DlixmkijLLafZFNq6dCNHXQIozn3i286vUJQ79jlhF XRo1OVzZhMWtUwfW+3B1JbjXKtMLUBB/uJ6332mdx2kCZDt8KQ8mDO4/WW2m+7/gTExN CXxvpmoVKrAfRHIRGdpCyx+Rt03QUAdDQ+DGpaUa1MuOMzKaBqJPirMdbP0ygjAOFJQk shsuN+eJK1kc1qQbyUDUm1IXtNsPEVluA/3t56uUqQ3nsUu7d0TAF7dOwVPf7Ton/8q6 tcVw== X-Gm-Message-State: ACrzQf3O6XWSTcqslqKioArRcHhK1/PphKMtFtrTFBee7jlc+lhdvjr7 aT1rvS7kzien8xR4ZLDBIRs2AemROqDfeA== X-Google-Smtp-Source: AMsMyM5Fcj2aCw3lqiw6gaHuH68OFT+QSgGv4mIWZTCw1nZnDUd3WyM4QDJr3oYKXsy8IhQXm5yxnw== X-Received: by 2002:a17:903:40d2:b0:186:6f1d:608c with SMTP id t18-20020a17090340d200b001866f1d608cmr16019240pld.52.1666530618258; Sun, 23 Oct 2022 06:10:18 -0700 (PDT) Received: from debian.. (subs02-180-214-232-1.three.co.id. [180.214.232.1]) by smtp.gmail.com with ESMTPSA id d5-20020a623605000000b0056b6c7a17c6sm3411713pfa.12.2022.10.23.06.10.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Oct 2022 06:10:17 -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 RESEND 7/7] Documentation: kunit: rewrite "Writing tests" Date: Sun, 23 Oct 2022 20:08:47 +0700 Message-Id: <20221023130846.63296-8-bagasdotme@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221023130846.63296-1-bagasdotme@gmail.com> References: <20221023130846.63296-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=owGbwMvMwCH2bWenZ2ig32LG02pJDMmhNndSW7ZLHjMW7bnTpL31SLnX0VW3BdbLumXaf10vpsvA X8HRUcrCIMbBICumyDIpka/p9C4jkQvtax1h5rAygQxh4OIUgIkc/MbIcPUkm9HcirkmXqeK+SQ78y fzLLE5fTKg/t2U6xWmRgxfJzH8lVU3X/2YyzhrdtvMtngdcamFre+XbXnJlf/z0cS+TvHpzAA= 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