Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp213422img; Thu, 21 Mar 2019 18:12:32 -0700 (PDT) X-Google-Smtp-Source: APXvYqxjSGMvZyinPdL/eYxJEuu0D3T58GzL7ptPnbieLrA00qYYvTNpQ9z0XkpDFz00oj484553 X-Received: by 2002:a17:902:7c8f:: with SMTP id y15mr6568963pll.44.1553217152600; Thu, 21 Mar 2019 18:12:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553217152; cv=none; d=google.com; s=arc-20160816; b=oe+kVGyTNogTEqV4FC6Kegz6DsuWZpan+84I6gIKa+H5byqPvuXONIlr54ocREq5JZ qF1+TYmhLIvqpFtXUJfV3JyTqxc0Py8QLetW3GYUAR0kful7Xwq8WvHQmy8Vmv8qsicZ tfW+/W2zL1xfin5Gd/kw9UaHn4m5HxMfTk+NfdwbdDgTVIKLxVA841WhC4OhyfO+BisT z3g9PAPExcTXW9ydvDzuPF7b7wcmotAtvj0DwD/ZDJBmiMzNg2HvhzZCc4iGBO4UKtlY 4b48npQDWm50G3VXwgkUX8zYrgPQjurY86TJnBfj3ngObJ3jlfrb1LMI38Z75GSynRKH 8EwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature; bh=QgBnLuwIoaOqn1M2NY5NRuDQzGpKg4quCarl6P8ka20=; b=Nrs+Rbxajft+LkHFgQTkX9LEP55vfweU3fcAXO879plKSYdNjzjjNNNVveUM+CLO7Q IYSgyUD4Z6/Hlw0DdRKr8xNtnxYZ4BcLvLMpwG9cLzxjnDatyRNbme6McPdzjIKUcPIV yAYcXD3FM2IG2UUOynMnRuYFXrQGZRWAJw1swKWuB+mDrQXMgY1whS9R7iSyfGL2/fhb noutW9EUzPddNzOKzvZyoQ7OOfKZM1zAhR2hah6JpkdZ4NIPLTc8AU8OMK6ZMEAVuMEE 8nT0zKmRZiQipKxIHcdjp0YVYaLfPJPon0/SHhbLTNV4RX1cUrISed59yVoyRVjoGXyF YuWA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=o46QXeHb; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q1si5865675pfb.68.2019.03.21.18.12.13; Thu, 21 Mar 2019 18:12:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=o46QXeHb; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727440AbfCVBKA (ORCPT + 99 others); Thu, 21 Mar 2019 21:10:00 -0400 Received: from mail-pf1-f194.google.com ([209.85.210.194]:37622 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726460AbfCVBKA (ORCPT ); Thu, 21 Mar 2019 21:10:00 -0400 Received: by mail-pf1-f194.google.com with SMTP id 8so320640pfr.4; Thu, 21 Mar 2019 18:09:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=QgBnLuwIoaOqn1M2NY5NRuDQzGpKg4quCarl6P8ka20=; b=o46QXeHbDWNFb0zRD1LbeA8hd2BO3AJRl1uX3Gx6eJHOuSVeNBMPmhmYRlxhWNZHeF OrWurnpBRHTk7E6mK+eTzDVgQWAG1IQLEybMBwjdn+3AeizcZkdMBjM57LSkjiJ4Pfa4 kHjThjRC2JfkiD184ofJXOj8fTN7Ua+OD8lrAdM5A8eLK2GojfnB8GFBGHQJDCyM/RPu 7iTDPyQphVZCgTIunKnRuqZaAHop0Nd8MlVKVKLsfDEkQJft/OWyFkg1h6DeAcnZue3H YkVEjLz+oaFIqLOXOhJ8vFojuCfuavj3FrdPZNYYqrv8iwiVQgXzaQVKPui/2OLqbVsd LyQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=QgBnLuwIoaOqn1M2NY5NRuDQzGpKg4quCarl6P8ka20=; b=MAQ7+6hhjearO+MPBIr9xu0n7AZQjV3ek0LD6EUMcS77S9J1jf9V8prVv6KpEEuXqF 6zxH3XV4dVe4mvycwE3L3QDO5cQvInBq46EmEcG1wA+iNQCaQiRJnXWgyMCZDI+7I6Fw 90qK10UKzogSZDPs/GhxhP5e9MFVoMrpoRC3RHR9iPusT/RsZcg+yQKGv+bAKX1/uRg6 AmsZrNs585ZsI3DDitqxhD/QpPVJ66AtCB8JWIw6pGFCFrHgHP4As82r2uaKT6XbQYab aQFgZ5udhlAG6+PAYxAVyGc/a/LgmfosFKdl3S5ZOrSGwbwdkzmTsbM6623N6Biv5XRt murA== X-Gm-Message-State: APjAAAVrw1rVd0/H+h3nLWSy97jpKQHLlrUnY+2uzKk5FyjGTCtjWKfl qeucaApjQpGtvFtDqynosLM= X-Received: by 2002:a65:6299:: with SMTP id f25mr6334824pgv.376.1553216998936; Thu, 21 Mar 2019 18:09:58 -0700 (PDT) Received: from [192.168.1.70] (c-24-6-192-50.hsd1.ca.comcast.net. [24.6.192.50]) by smtp.gmail.com with ESMTPSA id p34sm10873576pgb.18.2019.03.21.18.09.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 21 Mar 2019 18:09:58 -0700 (PDT) Subject: Re: [RFC v4 08/17] kunit: test: add support for test abort To: Brendan Higgins Cc: Kees Cook , Luis Chamberlain , shuah@kernel.org, Rob Herring , Kieran Bingham , Greg KH , Joel Stanley , Michael Ellerman , Joe Perches , brakmo@fb.com, Steven Rostedt , "Bird, Timothy" , Kevin Hilman , Julia Lawall , linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, Linux Kernel Mailing List , Jeff Dike , Richard Weinberger , linux-um@lists.infradead.org, Daniel Vetter , dri-devel , Dan Williams , linux-nvdimm , Knut Omang , devicetree , Petr Mladek , Sasha Levin , Amir Goldstein , dan.carpenter@oracle.com, wfg@linux.intel.com, Frank Rowand References: <20190214213729.21702-1-brendanhiggins@google.com> <20190214213729.21702-9-brendanhiggins@google.com> <0124ed28-466c-e954-ddde-495419630a9f@gmail.com> From: Frank Rowand Message-ID: <118d89b7-d468-6d68-a48d-4d6d9cefd106@gmail.com> Date: Thu, 21 Mar 2019 18:09:55 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2/27/19 11:42 PM, Brendan Higgins wrote: > On Tue, Feb 19, 2019 at 10:44 PM Frank Rowand wrote: >> >> On 2/19/19 7:39 PM, Brendan Higgins wrote: >>> On Mon, Feb 18, 2019 at 11:52 AM Frank Rowand wrote: >>>> >>>> On 2/14/19 1:37 PM, Brendan Higgins wrote: >>>>> Add support for aborting/bailing out of test cases. Needed for >>>>> implementing assertions. >>>>> >>>>> Signed-off-by: Brendan Higgins >>>>> --- >>>>> Changes Since Last Version >>>>> - This patch is new introducing a new cross-architecture way to abort >>>>> out of a test case (needed for KUNIT_ASSERT_*, see next patch for >>>>> details). >>>>> - On a side note, this is not a complete replacement for the UML abort >>>>> mechanism, but covers the majority of necessary functionality. UML >>>>> architecture specific featurs have been dropped from the initial >>>>> patchset. >>>>> --- >>>>> include/kunit/test.h | 24 +++++ >>>>> kunit/Makefile | 3 +- >>>>> kunit/test-test.c | 127 ++++++++++++++++++++++++++ >>>>> kunit/test.c | 208 +++++++++++++++++++++++++++++++++++++++++-- >>>>> 4 files changed, 353 insertions(+), 9 deletions(-) >>>>> create mode 100644 kunit/test-test.c >>>> >>>> < snip > >>>> >>>>> diff --git a/kunit/test.c b/kunit/test.c >>>>> index d18c50d5ed671..6e5244642ab07 100644 >>>>> --- a/kunit/test.c >>>>> +++ b/kunit/test.c >>>>> @@ -6,9 +6,9 @@ >>>>> * Author: Brendan Higgins >>>>> */ >>>>> >>>>> -#include >>>>> #include >>>>> -#include >>>>> +#include >>>>> +#include >>>>> #include >>>>> >>>>> static bool kunit_get_success(struct kunit *test) >>>>> @@ -32,6 +32,27 @@ static void kunit_set_success(struct kunit *test, bool success) >>>>> spin_unlock_irqrestore(&test->lock, flags); >>>>> } >>>>> >>>>> +static bool kunit_get_death_test(struct kunit *test) >>>>> +{ >>>>> + unsigned long flags; >>>>> + bool death_test; >>>>> + >>>>> + spin_lock_irqsave(&test->lock, flags); >>>>> + death_test = test->death_test; >>>>> + spin_unlock_irqrestore(&test->lock, flags); >>>>> + >>>>> + return death_test; >>>>> +} >>>>> + >>>>> +static void kunit_set_death_test(struct kunit *test, bool death_test) >>>>> +{ >>>>> + unsigned long flags; >>>>> + >>>>> + spin_lock_irqsave(&test->lock, flags); >>>>> + test->death_test = death_test; >>>>> + spin_unlock_irqrestore(&test->lock, flags); >>>>> +} >>>>> + >>>>> static int kunit_vprintk_emit(const struct kunit *test, >>>>> int level, >>>>> const char *fmt, >>>>> @@ -70,13 +91,29 @@ static void kunit_fail(struct kunit *test, struct kunit_stream *stream) >>>>> stream->commit(stream); >>>>> } >>>>> >>>>> +static void __noreturn kunit_abort(struct kunit *test) >>>>> +{ >>>>> + kunit_set_death_test(test, true); >>>>> + >>>>> + test->try_catch.throw(&test->try_catch); >>>>> + >>>>> + /* >>>>> + * Throw could not abort from test. >>>>> + */ >>>>> + kunit_err(test, "Throw could not abort from test!"); >>>>> + show_stack(NULL, NULL); >>>>> + BUG(); >>>> >>>> kunit_abort() is what will be call as the result of an assert failure. >>> >>> Yep. Does that need clarified somewhere. >>>> >>>> BUG(), which is a panic, which is crashing the system is not acceptable >>>> in the Linux kernel. You will just annoy Linus if you submit this. >>> >>> Sorry, I thought this was an acceptable use case since, a) this should >>> never be compiled in a production kernel, b) we are in a pretty bad, >>> unpredictable state if we get here and keep going. I think you might >>> have said elsewhere that you think "a" is not valid? In any case, I >>> can replace this with a WARN, would that be acceptable? >> >> A WARN may or may not make sense, depending on the context. It may >> be sufficient to simply report a test failure (as in the old version >> of case (2) below. >> >> Answers to "a)" and "b)": >> >> a) it might be in a production kernel > > Sorry for a possibly stupid question, how might it be so? Why would > someone intentionally build unit tests into a production kernel? People do things. Just expect it. >> >> a') it is not acceptable in my development kernel either > > Fair enough. > >> >> b) No. You don't crash a developer's kernel either unless it is >> required to avoid data corruption. > > Alright, I thought that was one of those cases, but I am not going to > push the point. Also, in case it wasn't clear, the path where BUG() > gets called only happens if there is a bug in KUnit itself, not just > because a test case fails catastrophically. Still not out of the woods. Still facing Lions and Tigers and Bears, Oh my! So kunit_abort() is normally called as the result of an assert failure (as written many lines further above). kunit_abort() test->try_catch.throw(&test->try_catch) // this is really kunit_generic_throw(), yes? complete_and_exit() if (comp) // comp is test_case_completion? complete(comp) do_exit() // void __noreturn do_exit(long code) // depending on the task, either panic // or the task dies I did not read through enough of the code to understand what is going on here. Is each kunit_module executed in a newly created thread? And if kunit_abort() is called then that thread dies? Or something else? >> >> b') And you can not do replacements like: >> >> (1) in of_unittest_check_tree_linkage() >> >> ----- old ----- >> >> if (!of_root) >> return; >> >> ----- new ----- >> >> KUNIT_ASSERT_NOT_ERR_OR_NULL(test, of_root); >> >> (2) in of_unittest_property_string() >> >> ----- old ----- >> >> /* of_property_read_string_index() tests */ >> rc = of_property_read_string_index(np, "string-property", 0, strings); >> unittest(rc == 0 && !strcmp(strings[0], "foobar"), "of_property_read_string_index() failure; rc=%i\n", rc); >> >> ----- new ----- >> >> /* of_property_read_string_index() tests */ >> rc = of_property_read_string_index(np, "string-property", 0, strings); >> KUNIT_ASSERT_EQ(test, rc, 0); >> KUNIT_EXPECT_STREQ(test, strings[0], "foobar"); >> >> >> If a test fails, that is no reason to abort testing. The remainder of the unit >> tests can still run. There may be cascading failures, but that is ok. > > Sure, that's what I am trying to do. I don't see how (1) changes > anything, a failed KUNIT_ASSERT_* only bails on the current test case, > it does not quit the entire test suite let alone crash the kernel. This may be another case of whether a kunit_module is approximately a single KUNIT_EXPECT_*() or a larger number of them. I still want, for example, of_unittest_property_string() to include a large number of KUNIT_EXPECT_*() instances. In that case I still want the rest of the tests in the kunit_module to be executed even after a KUNIT_ASSERT_*() fails. The existing test code has that property. > > In case it wasn't clear above, >>>>> + test->try_catch.throw(&test->try_catch); > should never, ever return. The only time it would, would be if KUnit > was very broken. This should never actually happen, even if the > assertion that called it was violated. KUNIT_ASSERT_* just says, "this > is a prerequisite property for this test case"; if it is violated, the > test case should fail and bail because the preconditions for the test > case cannot be satisfied. Nevertheless, other tests cases will still > run. >