Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp48622pxb; Mon, 2 Nov 2020 13:39:22 -0800 (PST) X-Google-Smtp-Source: ABdhPJxaeA8yPYjZnAsBBEKF/7TMmDGayJIo3RXsIs9Ny/Vz0MiyNjiSfQWXuwdOBKduNFFYHioL X-Received: by 2002:a17:906:eb57:: with SMTP id mc23mr16879221ejb.373.1604353162364; Mon, 02 Nov 2020 13:39:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604353162; cv=none; d=google.com; s=arc-20160816; b=M6irDIGz4CQXeBdpyEI5VrEOU8upSP+4/DEUQU/hkrerD3Jdyo8nIKFuFH6xR7cl9z d8a2L4fM9FpSlpVqYmw6I+OzoLACRdCn3/OGDl8ETdnLrSbjL0T86P6VWaM5393JG4df c0ltqBsfbWCb7iMBKA0vvjfrz0nZFke3XDMZcrr0tN++TmoOXip4yBCZslg9sJryZGNo WbQdJIAqz1W4OdZ4L6OqprQYpAH2GXARIvID2GlnzTGblPjbNDcUK+JDlx+YAwIVZ79n E9TGL7B1FIwuafA2zh+tAfqvc/b+T0W3gyTi/vh8jDRXeBwtwOqTQiGZt8U/h+d7kCJB fHdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:mime-version:message-id:date :sender:dkim-signature; bh=6QhI3kHimGu8AWgc0fDAH50nxnuO9Boew+8qHoNE/Eo=; b=TYioNoziIs/RN4UeLNqhKq7GfpHQxkrWOsXh6e6wrwqqER0aZ+lAsGlXj9WjWL8YAP bovEMyJ4z2xnsz7GN8m9h6WZjCSSACFCHxK8kPtijJd9BlybIDl0palV5ld4p844uy7A H6getMqryQokD0M2hmDrm2h7rd/IxQrYOMGrKAcfQSxhvENmBQdp2lA4zo1HXgUblvH7 8TKEnapa36IRCBNzGFEFIoVrovrXW6sYVad5LKU3DA+MNDX8Pn0BwWBEEjgXhZQRxExa VWzX1Otj+2IgtSfQXb7hLkG3e6r8qGTwCCZUKgnUjPJkLrPg+if3t7D3SoBLaWFxZ7U2 pT1Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=BApIjvn7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ga3si9771976ejc.703.2020.11.02.13.38.59; Mon, 02 Nov 2020 13:39:22 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=BApIjvn7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726653AbgKBVhL (ORCPT + 99 others); Mon, 2 Nov 2020 16:37:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59658 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725833AbgKBVhL (ORCPT ); Mon, 2 Nov 2020 16:37:11 -0500 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28FAEC0617A6 for ; Mon, 2 Nov 2020 13:37:11 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id a126so13220499ybb.11 for ; Mon, 02 Nov 2020 13:37:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:message-id:mime-version:subject:from:to:cc; bh=6QhI3kHimGu8AWgc0fDAH50nxnuO9Boew+8qHoNE/Eo=; b=BApIjvn7QJ3hkYCJqm1ZEr4y5XnuniIqZJW0Q7lYJLi1jVypbSF5D90TrXEnym+bOJ B1ztMqsbPnPQ4SMdybfWkdITi8ZQnCByAMmpISsEN5Md1tcnwIPHvCjlZf4nQOh8T6u0 4DkOL+GJcGN40B3SWlpoARtY0uHtr7jOW0uWxqlauUKzgwTxgifEGdFaTCPbvmXrtzm/ YlScuqb6LpbvGxxN+mDRKPb/rNhwU2HDDl2vA6udlo9NabPcbA6aXok5sWeQVWsUf2zi uZrImi3XCItHlC/2uaWfp4x1ut/4y86g/1Gvqy8WsbtfV8a+m5Z1JOrEqHCJ45WBTVMt RDUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:message-id:mime-version:subject:from :to:cc; bh=6QhI3kHimGu8AWgc0fDAH50nxnuO9Boew+8qHoNE/Eo=; b=geDBTmikKnr1QOqFjypkOhxM/fGh4UyQZsjB6YbqFiYTRpLDxRd0BZ6Yekk4Nqk7cG X/joymKuPYso5GJREH9P26msPKdPskoBH2kG3lMnDYoQCWy+viZX1kSrE7101PTdU69s Su+9gCFMa3Q/CG0vjb8RYL0PIReZVZBnJbZC2OPOe5YSUOjKlcAqi5Qb/haVwUyBbhkd n34nwgICfvDKZ67XnGrLrGqA+l2xRuJocQDBbv+3MxEjjbMN7jCap+tMcwBYZODkJoJN lsWHjA/vVJaa/oMWzv2gSSEtq7OLYAw51zFdJptnP/Ll/DP20ts9jzhJ3yysST8Zti/X Pa8w== X-Gm-Message-State: AOAM533zb+OSOVXbp4Ws8QO2i9GODbAiE13o6M6Xeu4bIGhbBK3QrwdA 1DpuDq9EKqBpAOSI1YqC9uFw6yvs8y6Qwg== Sender: "dlatypov via sendgmr" X-Received: from dlatypov.svl.corp.google.com ([2620:15c:2cd:202:a28c:fdff:fee3:28c6]) (user=dlatypov job=sendgmr) by 2002:a25:b68a:: with SMTP id s10mr22646893ybj.455.1604353030242; Mon, 02 Nov 2020 13:37:10 -0800 (PST) Date: Mon, 2 Nov 2020 13:36:56 -0800 Message-Id: <20201102213656.2700500-1-dlatypov@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.29.1.341.ge80a0c044ae-goog Subject: [PATCH] Documentation: kunit: provide guidance for testing many inputs From: Daniel Latypov To: brendanhiggins@google.com, andriy.shevchenko@linux.intel.com Cc: davidgow@google.com, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, skhan@linuxfoundation.org, Daniel Latypov Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org usage.rst goes into a detailed about faking out classes, but currently lacks wording about how one might idiomatically test a range of inputs. Give an example of how one might test a hash function via macros/helper funcs and a table-driven test and very briefly discuss pros and cons. Also highlight the KUNIT_EXPECT_*_MSG() variants (that aren't mentioned elsewhere [1]) which are particularly useful in these situations. It is also criminally underused at the moment, only appearing in 2 tests (both written by people involved in KUnit). [1] not even on https://www.kernel.org/doc/html/latest/dev-tools/kunit/api/test.html Signed-off-by: Daniel Latypov --- Documentation/dev-tools/kunit/usage.rst | 66 +++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-tools/kunit/usage.rst index 62142a47488c..317390df2b96 100644 --- a/Documentation/dev-tools/kunit/usage.rst +++ b/Documentation/dev-tools/kunit/usage.rst @@ -451,6 +451,72 @@ We can now use it to test ``struct eeprom_buffer``: destroy_eeprom_buffer(ctx->eeprom_buffer); } +Testing various inputs +---------------------- + +Testing just a few inputs might not be enough to have confidence that the code +works correctly, e.g. for a hash function. + +In such cases, it can be helpful to have a helper macro or function, e.g. this +fictitious example for ``md5sum(1)`` + +.. code-block:: c + + /* Note: the cast is to satisfy overly strict type-checking. */ + #define TEST_MD5(in, want) \ + md5sum(in, out); \ + KUNIT_EXPECT_STREQ_MSG(test, (char *)out, want, "md5sum(%s)", in); + + char out[16]; + TEST_MD5("hello world", "5eb63bbbe01eeed093cb22bb8f5acdc3"); + TEST_MD5("hello world!", "fc3ff98e8c6a0d3087d515c0473f8677"); + +Note the use of ``KUNIT_EXPECT_STREQ_MSG`` to give more context when it fails +and make it easier to track down. (Yes, in this example, ``want`` is likely +going to be unique enough on its own). + +The ``_MSG`` variants are even more useful when the same expectation is called +multiple times (in a loop or helper function) and thus the line number isn't +enough to identify what failed, like below. + +In some cases, it can be helpful to write a *table-driven test* instead, e.g. + +.. code-block:: c + + int i; + char out[16]; + + struct md5_test_case { + const char *str; + const char *md5; + }; + + struct md5_test_case cases[] = { + { + .str = "hello world", + .md5 = "5eb63bbbe01eeed093cb22bb8f5acdc3", + }, + { + .str = "hello world!", + .md5 = "fc3ff98e8c6a0d3087d515c0473f8677", + }, + }; + for (i = 0; i < ARRAY_SIZE(cases); ++i) { + md5sum(cases[i].str, out); + KUNIT_EXPECT_STREQ_MSG(test, (char *)out, cases[i].md5, + "md5sum(%s)", cases[i].str); + } + + +There's more boilerplate involved, but it can: + +* be more readable when there are multiple inputs/outputs thanks to field names, + + * E.g. see ``fs/ext4/inode-test.c`` for an example of both. +* reduce duplication if test cases can be shared across multiple tests. + + * E.g. if we had a magical ``undo_md5sum`` function, we could reuse ``cases``. + .. _kunit-on-non-uml: KUnit on non-UML architectures base-commit: 77c8473edf7f7664137f555cfcdc8c460bbd947d -- 2.29.1.341.ge80a0c044ae-goog