Received: by 2002:a05:6358:489b:b0:bb:da1:e618 with SMTP id x27csp3584593rwn; Sat, 10 Sep 2022 15:25:18 -0700 (PDT) X-Google-Smtp-Source: AA6agR5HjkNZ7sRRPcSKJ7WEMcN4tVAIKCLSbsyshA1oDU007CzDou+57XxdBiEfY9FnB5gmtSSa X-Received: by 2002:a17:907:968f:b0:774:d10f:a98e with SMTP id hd15-20020a170907968f00b00774d10fa98emr10504060ejc.750.1662848718609; Sat, 10 Sep 2022 15:25:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1662848718; cv=none; d=google.com; s=arc-20160816; b=BZFrL3Xqf5NQXKBN/gq3lbnIiJa55w0A1sIqV+D0PRmlopkZUf83Z93TFL1zpvxGl8 s4aRLIYKMPSDd3lDJ30P40uIdAvDuSBPOvkbu060xHRdVFQpFIHBFjpaWkZeEGkBKIKZ X3nv8TdiGkAfvCHKGgUx4MSkeMbfmfs7IySap0v5Czc9CQvnpMFI1xmUq8LOlpsS7IGr zSelK7izAdw82MKr2o/9fvpg5ujzBC60NiA8C7v4rEObkSofzlZnW4DOOlrY2qqx18+g 7GYUeH46j28trkoq0lJc2zlhOHgQWb7Ojirpw6PQPgx2Hn+0GbcnL6tJ2bvaf4NqYBJa 8Aog== 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:message-id:mime-version:date :dkim-signature; bh=AtmQOz4cqU5AlOnIxEScnXs2STqQsi71nD797NpxF7g=; b=wI7rq2s/chnphwZAw4Sf4bADiuGq11DAk1PTf3FATNQkXd+B4eFmRmCnsU5cf3L0d8 +57Wf7ltcsxQEOBwtmPXHibQkgor6LgkfG+DHfLsI08V6LpJlNuIjSinweOFKZZ559sh fwgvEYuGEIdGvj4SxrDhjt03DrD8+jcxoUoa0qMz1V5yq0fi6a6Ns8wBz5uG0p4dU3NI waOyvE6brQAT/9AG/2rVhM+BLJOZ8PP+YVxkKW8KYW5634WVHV1dYTXKv+dm40gm3dlU 0t7fb3zG1qpH8/RoA1Gem3kTbXuaqwVF/rt2a7aA/r89ffTUzLB1johB3LnyOWABGM1B HKaA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=ONMGnunK; 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 m17-20020a056402511100b0044ea701dba9si4246364edd.471.2022.09.10.15.24.53; Sat, 10 Sep 2022 15:25:18 -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=ONMGnunK; 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 S229807AbiIJVfy (ORCPT + 99 others); Sat, 10 Sep 2022 17:35:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230505AbiIJVfT (ORCPT ); Sat, 10 Sep 2022 17:35:19 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5249B1A047 for ; Sat, 10 Sep 2022 14:29:45 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id s16-20020a170902ea1000b00176cf52a348so3471908plg.3 for ; Sat, 10 Sep 2022 14:29:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date; bh=AtmQOz4cqU5AlOnIxEScnXs2STqQsi71nD797NpxF7g=; b=ONMGnunKNz4gp6pmKkYtXjmszONPlJmgdmvIFMNIH+l1kH1hr624Pikj7usUwyBpKa jdsHPH0YixHNFhP/yHhRREK/X8wkkfqH6qk8dp5aGV6QebWO+f6XMb2QvPYteCi4E4Uc T8M/1/I05+yqj5lcEBqf6Xk3mm1+GqkhSuJGBcWXiIU6f3W+6QjI9nzceAR+tOPaenBz UTSW3y14Yxlk4TNZ/Wl7n2dP7gYAOGOoyxN1CHYmrWybYD+5sZdz4CQLci8yoJ9emYSc Nctku8l/YvfTuqjQV/j26hSEz3mpU5iS7q0UtrBp4MSk+XbJ2haQ1nySY5D37C0eYdQx +vRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date; bh=AtmQOz4cqU5AlOnIxEScnXs2STqQsi71nD797NpxF7g=; b=UfbdHQZwSQ8FQkzFz3aYOp81SombHH8pWUqXvHtNKE4oREa2YvXsm984P1LjdviiwL 7BjUH1k+JrZotLrBxWqJF4ohfum6m7MPNHKfzl1jki8eFMACVKv68/5DwNtEUH3fmZv4 kj5Hfcbqt1Xd5ip7MSB7WN/VrdrRXudkaqZf1ze+ZvU4CHhwfa+pZhw7ruoKwZ7KRys3 MLZVY96fiC+fJfpNl2o+Efa39xuCKm7bG5/3V4fpUiugl7WxbUFYVmL/UTmTYEKywnoX +CzYhe0Hg4YFDnsiGSdilhIBd5jc72uqv9Vev1BRVrZb6nzY5ICjfo+j5aIH1boMUIW3 4l9A== X-Gm-Message-State: ACgBeo20AAV6qXlViPRRAHK5b8PQLSgoKuL7ypCoFnFpyK2sGsP4YkAY 9m1sJTdBfh+jG2hiYSrm7k77l076k0313A== X-Received: from slicestar.c.googlers.com ([fda3:e722:ac3:cc00:4f:4b78:c0a8:20a1]) (user=davidgow job=sendgmr) by 2002:a17:902:bd48:b0:172:bb9d:d6d5 with SMTP id b8-20020a170902bd4800b00172bb9dd6d5mr19190501plx.59.1662845297768; Sat, 10 Sep 2022 14:28:17 -0700 (PDT) Date: Sun, 11 Sep 2022 05:28:02 +0800 Mime-Version: 1.0 X-Mailer: git-send-email 2.37.2.789.g6183377224-goog Message-ID: <20220910212804.670622-1-davidgow@google.com> Subject: [RFC PATCH v2 0/2] kunit: Support redirecting function calls From: David Gow To: Brendan Higgins , Daniel Latypov , Kees Cook , Shuah Khan , Steven Rostedt , Joe Fradley Cc: Steve Muckle , kunit-dev@googlegroups.com, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, David Gow Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_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 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? 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