Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp3943262rwb; Fri, 30 Sep 2022 10:21:36 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7ruMW0YqV4QUypWW77ag6pWTzRp0x7uYwnm3ZoPvoyT4Dw7q7Tzh3mLfU6PTqQ6w9LOl7K X-Received: by 2002:a17:902:8e84:b0:178:71f2:113c with SMTP id bg4-20020a1709028e8400b0017871f2113cmr9818984plb.79.1664558496073; Fri, 30 Sep 2022 10:21:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664558496; cv=none; d=google.com; s=arc-20160816; b=GXJNuZiRAqaZBg7rrUOeLgNvVGx40ON3yo4IDHpKKPUY+ueBLqDi/oFY45vwEU6QaT I+2TilGE4iSqntthTgwbO0iRVKroG3Repw/lweVZmsNSsdsZF19OUsrx+aIjnLn6K3Nh kJzHq99zPoajQETDg+jYwfL+qUgV9RaLOMusGmpWZg0SU9z3tmKae5dWqihDNyCutaMU cexT5WbOBhNBv9TwMU0Ocg12UW4qP/W4O60cdyH9CpkMEjr9b7XWdYcfr27WNdp229HZ k2eOFogcSDQYTDmm/HYi4aXEl8WSX0/Dck1dZt+w9d11lbqsJBw5F01f+mcAMp/jEETw 2JmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=NK6zfHFnMf5a+HdLSDIx93EDC/e6X/0+F6ZlZy78SrM=; b=H+T4mQ2eTX8YfiZhjyPKW8zcC9/cMbeSmWtDeoraKyFKhlsTBmbQcxghllT6lbMFwe bLyqcfskWiw7AhHwohYqW/pa6I2H7IVfwpWPG3FGiZmnvev3MmzpwFolCdvBCZ6fRwBP N8Seg+jIhysQLGgixlYXTO8w3TGO+Wpc3LKY/1lbwvArZpqZFh31cdI/DTTydLAms2fp ++YlyD0uKsdzIkW/9BksMOulZs9CuHJ7cgi09uQCN1QWQ2yccuuMhAOAaCNDivJ2JCag ikB4GE1vRTEAlUgHZrUjboSGx+OpQQc8InPMwZ9PIu3nUnQvoHFZ+mbD9ZIAPS1bmuU+ q+DA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=oI44i8ct; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id mu18-20020a17090b389200b001fbc6ba91besi10521206pjb.96.2022.09.30.10.21.23; Fri, 30 Sep 2022 10:21:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=oI44i8ct; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S230198AbiI3QAO (ORCPT + 99 others); Fri, 30 Sep 2022 12:00:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60194 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231821AbiI3P7x (ORCPT ); Fri, 30 Sep 2022 11:59:53 -0400 Received: from mail-qt1-x833.google.com (mail-qt1-x833.google.com [IPv6:2607:f8b0:4864:20::833]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39C1C10561 for ; Fri, 30 Sep 2022 08:59:39 -0700 (PDT) Received: by mail-qt1-x833.google.com with SMTP id y2so2915211qtv.5 for ; Fri, 30 Sep 2022 08:59:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date; bh=NK6zfHFnMf5a+HdLSDIx93EDC/e6X/0+F6ZlZy78SrM=; b=oI44i8ct1miKHvC15nqHdpFZsiQN/a6fBOW+ZYxIuHgcgrSgEMiy1UDyFqNCnVQflK e8RynzGvVbPEIr334P0F2XEgZVy/hznfl/4rSmPKGh5lulb5qPi4/9UgvgyQ6BOQk1l4 VcV/Qev9ROuqB14ytynnwQv7acnIJh1lOteutIjv3x5mhvIoMKy6EXeBNoP1jxeeCFqm rgGpdpCOCSPhxtiRqotxIJq5HVLIO9GGne2Ht8GTXS7malqIMoa4MBWLmLtcFNGWecH5 S0RtWkjqiVOwRAlsCYJk1MlNUBEk/EUoNLZAUWO78kJR4ZdUbb3P0QIwnWYLsFEBUFeC vrCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date; bh=NK6zfHFnMf5a+HdLSDIx93EDC/e6X/0+F6ZlZy78SrM=; b=qgcyvJJUuS/jBMDDjX77ralGiERkZ8Pc9xpOCJj9zBnSMgQZMKhOIz/EEKu0I8CW4f Ml+2VDU4EtNqAX7TE0t9JfuzUEr0et4qb9d7pTBodXuOUc8n1M2VsUiCrmwCzuOs6XWj 9n1DzXRPR12PhktSAp5ahCNrH/wyTIoevzhxmD12Gqvoww9uTmBx7NOdgCeKhQm9F6Z0 NwhqsKt7BVthxtl9GaTqF3/pCKFy4wv5b8IZpf8qJkgfIYVG/AbZhc7Ie/GEIf8tlH4j jICGeqmoRFLciLBISF8NiHCLPzfEtwa6CvVtaRWy9Os65J8e/qS4VuOKNq2bN3MxjPsX t3sg== X-Gm-Message-State: ACrzQf3KB8z8UkvgnqBBLx0kYYOw/A/7wbCBA8GJouM7cEIxO++IR21h 76byfMlFLhi9rTO+n/oSHVkdZ7uDXuuMUBXttael X-Received: by 2002:ac8:5e51:0:b0:35c:e40f:d898 with SMTP id i17-20020ac85e51000000b0035ce40fd898mr7287109qtx.685.1664553578206; Fri, 30 Sep 2022 08:59:38 -0700 (PDT) MIME-Version: 1.0 References: <20220910212804.670622-1-davidgow@google.com> In-Reply-To: <20220910212804.670622-1-davidgow@google.com> From: Joe Fradley Date: Fri, 30 Sep 2022 08:59:26 -0700 Message-ID: Subject: Re: [RFC PATCH v2 0/2] kunit: Support redirecting function calls To: David Gow Cc: Brendan Higgins , Daniel Latypov , Kees Cook , Shuah Khan , Steven Rostedt , Steve Muckle , kunit-dev@googlegroups.com, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-17.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Sep 10, 2022 at 2:28 PM David Gow wrote: > > When writing tests, it'd often be very useful to be able to intercept > calls to a function in the code being tested and replace it with a > test-specific stub. This has always been an obviously missing piece of > KUnit, and the solutions always involve some tradeoffs with cleanliness, > performance, or impact on non-test code. See the folowing document for > some of the challenges: > https://kunit.dev/mocking.html > > This series consists of two prototype patches which add support for this > sort of redirection to KUnit tests: > > 1: static_stub: Any function which might want to be intercepted adds a > call to a macro which checks if a test has redirected calls to it, and > calls the corresponding replacement. > > 2: ftrace_stub: Functions are intercepted using ftrace. > This doesn't require adding a new prologue to each function being > replaced, but does have more dependencies (which restricts it to a small > number of architectures, not including UML), and doesn't work well with > inline functions. > > The API for both implementations is very similar, so it should be easy > to migrate from one to the other if necessary. Both of these > implementations restrict the redirection to the test context: it is > automatically undone after the KUnit test completes, and does not affect > calls in other threads. If CONFIG_KUNIT is not enabled, there should be > no overhead in either implementation. > > Does either (or both) of these features sound useful, and is this > sort-of API the right model? (Personally, I think there's a reasonable > scope for both.) Is anything obviously missing or wrong? Do the names, > descriptions etc. make any sense? David, This will be a great addition to the KUnit framework and another tool in the toolbox for test writers. Both approaches have their merits. If all things were equal the ftrace option would be preffered in my opinion. The ability to add tests without having to touch the source of what you're testing is superior. However, all things aren't equal as you've detailed. There are a number of open items for the ftrace approach that will limit its scope of use. Given that a solid amount of test developers already develop on what they're testing, the static stub option sounds like the one to go with for now, if you had to choose one. Regarding the implementation, could there be more granualitary in the activation of these stubs? Considering there's a small amount overhead for these stubs when CONFIG_KUNIT is enabled, a developer's environment could be adversely affected when they're testing a completely different area that doesn't require mocks. Maybe only activate these with CONFIG_KUNIT_FTRACE_STUBS and CONFIG_KUNIT_STATIC_STUBS respectively? Joe > > Note that these patches are definitely still at the "prototype" level, > and things like error-handling, documentation, and testing are still > pretty sparse. There is also quite a bit of room for optimisation. > These'll all be improved for v1 if the concept seems good. > > We're going to be talking about this again at LPC, so it's worth having > another look before then if you're interested and/or will be attending: > https://lpc.events/event/16/contributions/1308/ > > Cheers, > -- David > > --- > > Changes since RFC v1: > https://lore.kernel.org/lkml/20220318021314.3225240-1-davidgow@google.com/ > - Fix some typos (thanks Daniel) > - Use typecheck_fn() to fix typechecking in some cases (thanks Brendan) > - Use ftrace_instruction_pointer_set() in place of kernel livepatch, > which seems to have disappeared: > https://lore.kernel.org/lkml/0a76550d-008d-0364-8244-4dae2981ea05@csgroup.eu/T/ > - Fix a copy-paste name error in the resource finding function. > - Rebase on top of torvalds/master, as it wasn't applying cleanly. > > Note that the Kernel Livepatch -> ftrace change seems to allow more > architectures to work, but while they compile, there still seems to be > issues. So, this will compile on (e.g.) arm64, but fails: > $ ./tools/testing/kunit/kunit.py run 'example*' --kunitconfig lib/kunit/stubs_example.kunitconfig --arch arm64 --make_options LLVM=1 > [05:00:13] # example_ftrace_stub_test: initializing > [05:00:13] # example_ftrace_stub_test: EXPECTATION FAILED at lib/kunit/kunit-example-test.c:179 > [05:00:13] Expected add_one(1) == 0, but > [05:00:13] add_one(1) == 2 > [05:00:13] not ok 6 - example_ftrace_stub_test > [05:00:13] [FAILED] example_ftrace_stub_test > > > > Daniel Latypov (1): > kunit: expose ftrace-based API for stubbing out functions during tests > > David Gow (1): > kunit: Expose 'static stub' API to redirect functions > > include/kunit/ftrace_stub.h | 84 +++++++++++++++++ > include/kunit/static_stub.h | 106 +++++++++++++++++++++ > lib/kunit/Kconfig | 11 +++ > lib/kunit/Makefile | 5 + > lib/kunit/ftrace_stub.c | 137 ++++++++++++++++++++++++++++ > lib/kunit/kunit-example-test.c | 63 +++++++++++++ > lib/kunit/static_stub.c | 125 +++++++++++++++++++++++++ > lib/kunit/stubs_example.kunitconfig | 10 ++ > 8 files changed, 541 insertions(+) > create mode 100644 include/kunit/ftrace_stub.h > create mode 100644 include/kunit/static_stub.h > create mode 100644 lib/kunit/ftrace_stub.c > create mode 100644 lib/kunit/static_stub.c > create mode 100644 lib/kunit/stubs_example.kunitconfig > > -- > 2.37.2.789.g6183377224-goog >