Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp129959ybt; Tue, 23 Jun 2020 17:18:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwLBzHK49pHxiujL6dwZ9nuHYEcjQkzfkRUCzvr/6rzkRPYiX2Lgd5Ay9ryPsXQJuJ1e7yv X-Received: by 2002:a50:f702:: with SMTP id g2mr8627359edn.348.1592957895746; Tue, 23 Jun 2020 17:18:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592957895; cv=none; d=google.com; s=arc-20160816; b=ZCB2TcCbGF0hG+eTg05WhuKC9ehxVxHI8EXakJ68wfFZnGG4UKNIJPoXKJHJCm6iWs roM6FI885ETymLZpA8ZD9R5wA4OoRoMDDgdMuq4KE78rzDGEwFrRyx5KgGGT9bT+nwd2 uBf1uKol63bFiiWjqCz9gSL4FxfWKx55rmpKCxozL9bUR8Feznj7yKqp4xf+vBWfM/gj 6xdM4zmGz2h3IO5DaPdyzt328gllBPfS4TYPkNjbE6dsdMS2H9Dg2qGSaS8JzHaSOL4X leQg+3eD3klW7plKkTlZsBs5LpYVHvdWBa0QY9BLtB3FNY9RrWJOYzvSzGRcpV9arU4/ eZSw== 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:references:cc:to:from:subject:dkim-signature; bh=sOYuOvsc9gJcUjnm82UQmjUC31ysVgRWd9G8r3SM37M=; b=WLZGJGUSjiGRquuuSEoDtlT94z+TygQOGHN6UTT8Toi41yn9FQrOVf4lNcA4e+vV0h C4Z7pkulC60edXE+qg//Y3fxtyv3dKvLiQAJKW+cusJ4I/tRORaC1c2fbgPLaoSFqqYk 1//3eIknwcSGwy0ve9N1/Jvk5wt9DXtV9rxNMDLvscdDuvhwovsEp6TS9GLBqTTGVYBJ bPX948OrRy5fojc2tBnBFzoWNQLQdhAx4/Qc8K4J4ERGsDAPAZhUDuIrgVBto9dWWl+p Subv+aHGWa8FWebq4iHMpSxNoI9IxtR+tTBxyp8VYCVVVudjMDlutghfMc2ajKoZJ2/X 3tfQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=ELby4e0p; 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=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bs16si12664790edb.197.2020.06.23.17.17.49; Tue, 23 Jun 2020 17:18:15 -0700 (PDT) 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=@gmail.com header.s=20161025 header.b=ELby4e0p; 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=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387986AbgFXAPY (ORCPT + 99 others); Tue, 23 Jun 2020 20:15:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387693AbgFXAPX (ORCPT ); Tue, 23 Jun 2020 20:15:23 -0400 Received: from mail-qk1-x742.google.com (mail-qk1-x742.google.com [IPv6:2607:f8b0:4864:20::742]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D3E8DC061573; Tue, 23 Jun 2020 17:15:22 -0700 (PDT) Received: by mail-qk1-x742.google.com with SMTP id z63so273605qkb.8; Tue, 23 Jun 2020 17:15:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:references:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=sOYuOvsc9gJcUjnm82UQmjUC31ysVgRWd9G8r3SM37M=; b=ELby4e0pwkI6pxFaGR8/dyiw09MkELZqJcL/vqcZV+ASC65Xo0ZdXhLsYXW3w1QbIb BTfkzfnBQ+V9pWJw4fVcpJNOQ88nHzRIHXzBRgLXR2jmFuGjZjpJigvkS2EFiSNX72Oe Zh5Y/o8yyQfRmltIXpRNOoPxWX6WFqq5+CPV8JmJd9CfacENGeSzjUw9ppeGqdD8pbFS eDswJzBygAOMgRRlYALqUjXDR89XG5kaaE6S5TnmLeuf7+aD5KxB5FGpsZ0uWZcsDVmF b5fZTTEOoVtw3ZkFllUqVn2MFDkJD7fzPFr6cD+Fc/uKepigZbvep/n3bhQRZbyvh+lZ zUKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=sOYuOvsc9gJcUjnm82UQmjUC31ysVgRWd9G8r3SM37M=; b=VvhXs5Rkg13gC5hFpnzsTomr/ZLy0i7dtaJthyAgJKPaAzTN9pQLscp5nDyDr59FTq 5Zq68l7PBQnOYMk5vbHyQbCDiApEsLTtBKbkXFSwab8OfQFGZ6FcZD15AKdFQoSRY4KD wekoTt76Pvzk8lASLyLXtDSQXL6c3pOxU1BxID+0U52LmQ6Jt6XFTGOCt01/k9PdcQS5 t1vSROQcWkKvs7UqLUj0QrA5bPtoLmChQPd3N11dEOly9YhKZS1BxVULa7O74pcStsyZ JW9D0Ww2Gg7c5yaFnJ1DQSrso5WqouVnj7A2lZEeIRNLe2VE+qQ4pnoCcQuZLkS2vJQl 3dGw== X-Gm-Message-State: AOAM533+gHHI9HIfS3aGEuWmXzMThC94HofpNzvbGau8SG0+HkkjTaNW ULtNQsN0F/AhnrS+HmQjWiw= X-Received: by 2002:ae9:efc7:: with SMTP id d190mr4131800qkg.212.1592957721928; Tue, 23 Jun 2020 17:15:21 -0700 (PDT) Received: from [192.168.1.46] (c-73-88-245-53.hsd1.tn.comcast.net. [73.88.245.53]) by smtp.gmail.com with ESMTPSA id p7sm1668569qki.61.2020.06.23.17.15.20 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 23 Jun 2020 17:15:21 -0700 (PDT) Subject: Re: RFC: KTAP documentation - expected messages From: Frank Rowand To: "Bird, Tim" , "shuah@kernel.org" , "linux-kselftest@vger.kernel.org" , Brendan Higgins , David Gow , Kees Cook , Paolo Bonzini Cc: "linux-kernel@vger.kernel.org" References: <5c0c1ad7-c3c6-39b9-0907-330241d40464@gmail.com> Message-ID: <9aa2b75a-d848-5a87-2e2b-07f2931bd031@gmail.com> Date: Tue, 23 Jun 2020 19:15:20 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.8.0 MIME-Version: 1.0 In-Reply-To: <5c0c1ad7-c3c6-39b9-0907-330241d40464@gmail.com> 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 2020-06-21 17:49, Frank Rowand wrote: > On 2020-06-21 17:45, Frank Rowand wrote: >> Tim Bird started a thread [1] proposing that he document the selftest result >> format used by Linux kernel tests. >> >> [1] https://lore.kernel.org/r/CY4PR13MB1175B804E31E502221BC8163FD830@CY4PR13MB1175.namprd13.prod.outlook.com >> >> The issue of messages generated by the kernel being tested (that are not >> messages directly created by the tests, but are instead triggered as a >> side effect of the test) came up. In this thread, I will call these >> messages "expected messages". Instead of sidetracking that thread with >> a proposal to handle expected messages, I am starting this new thread. >> >> I implemented an API for expected messages that are triggered by tests >> in the Devicetree unittest code, with the expectation that the specific >> details may change when the Devicetree unittest code adapts the KUnit >> API. It seems appropriate to incorporate the concept of expected >> messages in Tim's documentation instead of waiting to address the >> subject when the Devicetree unittest code adapts the KUnit API, since >> Tim's document may become the kernel selftest standard. >> >> Instead of creating a very long email containing multiple objects, >> I will reply to this email with a separate reply for each of: >> >> The "expected messages" API implemention and use can be from >> drivers/of/unittest.c in the mainline kernel. >> >> of_unittest_expect - A proof of concept perl program to filter console >> output containing expected messages output >> >> of_unittest_expect is also available by cloning >> https://github.com/frowand/dt_tools.git >> >> An example raw console output with timestamps and expect messages. >> >> An example of console output processed by filter program >> of_unittest_expect to be more human readable. The expected >> messages are not removed, but are flagged. >> >> An example of console output processed by filter program >> of_unittest_expect to be more human readable. The expected >> messages are removed instead of being flagged. >> > > reply 1/5 > > expected messages API: > > - execute EXPECT_BEGIN(), reporting the expected message, before the > point when the message will occur > > - execute EXPECT_END(), reporting the same expected message, after the > point when the message will occur > > - EXPECT_BEGIN() may occur multiple times, before the corresponding > EXPECT_END()s, when a single test action may result in multiple > expected messages > > - When multiple EXPECT_BEGIN()s are nested, the corresponding (matching) > EXPECT_END()s occur in the inverse order of the EXPECT_BEGIN()s. > > - When the expected message contain a non-constant value, a place holder > can be placed in the message. Current place holders are: > > - <> an integer > - <> a hexadecimal number > > Suggested additional place holder(s) are: > > - <> contiguous non white space characters > > I have avoided allowing regular expessions, because test frameworks > may implement their own filtering instead of relying on a generic > console output filter program. There are multiple definitions for > regular expressions in different languages, thus it could be > difficult to set rules for a subset of regular expression usable > by all languages. > > A preliminary version of an expected messages framework has been > implemented in the mainline drivers/of/unittest.c. The implementation > is trivial, as seen below. > > Note that the define of "pr_fmt()" pre-dates the implementation > of the EXPECT_BEGIN() and EXPECT_END() macros. > --------------------------------------------------------------- > > #define pr_fmt(fmt) "### dt-test ### " fmt > > > /* > * Expected message may have a message level other than KERN_INFO. > * Print the expected message only if the current loglevel will allow > * the actual message to print. > * > * Do not use EXPECT_BEGIN() or EXPECT_END() for messages generated by > * pr_debug(). > */ > #define EXPECT_BEGIN(level, fmt, ...) \ > printk(level pr_fmt("EXPECT \\ : ") fmt, ##__VA_ARGS__) > > #define EXPECT_END(level, fmt, ...) \ > printk(level pr_fmt("EXPECT / : ") fmt, ##__VA_ARGS__) > > > > Example 1 of the API use, single message: > ----------------------------------------- > > EXPECT_BEGIN(KERN_INFO, > "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle"); > > rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle", > "#phandle-cells", 0, &args); > > EXPECT_END(KERN_INFO, > "OF: /testcase-data/phandle-tests/consumer-a: could not find phandle"); > > > Example 2 of the API use, two messages, > "<>" placeholder matches any integer: > ------------------------------------------ > > /* > * messages are the result of the probes, after the > * driver is registered > */ > > EXPECT_BEGIN(KERN_INFO, > "GPIO line <> (line-B-input) hogged as input\n"); > > EXPECT_BEGIN(KERN_INFO, > "GPIO line <> (line-A-input) hogged as input\n"); > > ret = platform_driver_register(&unittest_gpio_driver); > if (unittest(ret == 0, "could not register unittest gpio driver\n")) > return; > > EXPECT_END(KERN_INFO, > "GPIO line <> (line-A-input) hogged as input\n"); > EXPECT_END(KERN_INFO, > "GPIO line <> (line-B-input) hogged as input\n"); > > Subtle flow of control issue: the two EXPECT_END() are not executed if > platform_driver_register() fails. The two expected messages will not > be printed, but the filter tool (of_unittest_expect) will not report this > as an error because of_unittest_expect does not search for the messages > until the EXPEND_END() output is encountered. > > One could argue that this is correct behavior because unittest() will print > the error that platform_driver_register() failed. The "expected" messages > are not expected if the register fails. > > One could equally well argue that the two EXPECT_END() should execute > before unittest() checks the value of ret, so the missing messages will > be reported as an error by of_unittest_expect. > > But that is a discussion that should occur in the context of whether > drivers/of/unittest.c has a coding error, not in the context of how > to implement the expected messages framework. > > > goals: > > - The console output should be human readable and easy to parse. > Have "\" in the expect begin and a matching "/" in the expect end > is intended to make it easier to visualize pairs. > > - The console output should be machine parsable. > > > Design alternate choices: > > - Expect message nesting: > 1) Nested expect messages place the "\" in the same column. > 2) For each nested expect message, indent the "\" by one more column > for each level of nesting. > > Chose 1. This keeps the EXPECT_BEGIN() and EXPECT_END() macros very > simple, at the expense of the output being less human readable in the > raw log. > > The raw log is already not very readable, and I would expect the normal > use case would be using a filter program, such as of_unittest_expect, > to handle the readability issue. > > > Issues: > > - The EXPECT_BEGIN() and EXPECT_END() macros use printk() for output. > printk() prefixes the output with the value of the pr_fmt() macro. > This means the filter program must be able to deal with different > pr_fmt() strings being incorporated in the expect messages that > are in different source files. The unittest.c pr_fmt() value is > currently hard coded in the of_unittest_expect filter program. > > - The output of the of_unittest_expect filter program prepends several > columns of data at the beginning of the resulting filtered data. The > TAP format does not expect these extra columns. > > The prepended data is very important for making the report easily > read by humans. > > 1) It will be trivial to add an of_unittest_expect "--tap-out" option > to not add the prepended data, so that normal TAP programs can use > the output from of_unittest_expect. > > 2) The "--tap-out" option could also create a TAP "test line" reporting > an "ok" for expected message detected and "not ok" if an expected > message is not detected. > > This would also require modifying the "test plan" line to change > the number of tests. > - KUnit already has a concept that uses the word "expect". A test may have expectations about what the data created or modified by the test will be. For example, if the test invokes: ret = add(3, 4) then the test might expect ret to contain the value "7". If it does not, then the test could report: ret = add(14, -7) expected ret == 7, but instead ret == -22 (Don't take this example as a valid KUnit format, I just trying to explain the concept.) The word EXPECT in this new feature should be changed to something else to avoid confusion with the other KUnit concept. Or alternately, KUnit could change the word used for its existing concept, if that is an easier change.