Received: by 2002:a05:6358:4e97:b0:b3:742d:4702 with SMTP id ce23csp804469rwb; Thu, 18 Aug 2022 12:32:11 -0700 (PDT) X-Google-Smtp-Source: AA6agR7mfK+Zj4sWb9Jqut4kmhQPXSe+Q6fhWK+dDDjVib670hnV/XmnDuUGbujaF4R12rCy2iu0 X-Received: by 2002:a17:906:7307:b0:73c:c9ee:8b5c with SMTP id di7-20020a170906730700b0073cc9ee8b5cmr221950ejc.310.1660851131575; Thu, 18 Aug 2022 12:32:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660851131; cv=none; d=google.com; s=arc-20160816; b=lmu3T/rcUnupuPOL3vkTefl/3GWdJ5fjlKFbsD7qLqqfUH+Mcbikq1qSTyjQgRO+/s 1qN53ZyiIi+we2DICkr/jsBrWdE9SE2pnAaZ4TbFA/3GTaVTlgf3rMTMpa9PB4meNFwK sfrZ+tRHRpXibIi+My5plj6kS+9MDatlo5aC6aDMVR0mH3eANqtp+J8+oAsSlH8P1S33 Boz4KyzCZf9Nrp68hEGEaROMO2HifFbVOiUF28pORKPdj1V+PYHP/nxYFvVOrUkTiqJ+ 2DeaeycgjvGOfUM3OmMajFBK8plTgTh+gvwc9Der2v7SawpciR2HwgQ2wnrsY0kfhzIg Vdfw== 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=8WO9HL2c2NqU95pngV5GpcHf00yCayPpvaZNx/fy4Qg=; b=Yw5Z3Y181ANOtB59TRAgG5dT/bi97XzWMtn0JrXf209ev2w0Ra5vnRREKfxbbIJGTP KsYfYYQXkINxNwQQi2rXeNIq/KYK5K7jJxa5xm/GeU5rw+PZVSmI4+R3I/Pz96BVS0+8 0Mqc9jrcigEGoeW0Aq7c/G0tPQKEQfl5YW5tadbHRpHT8XPvjyh20vz/EUJ8D06cOC7l qwK94cazgTjmiWF27dvOM0EIUIdtw2IdPySiHJwd7xODSCfeLXQeubHpxsRzj0vV46YB wacgSJmfYVEXpzjZxgHiukyg1bt7THT1M1TjLme/mA3Mp3bEK5odzVRyqW9UaZFo9SZb WULA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=UbCFQNes; 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=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q9-20020a056402518900b0043dde72da34si1967481edd.68.2022.08.18.12.31.44; Thu, 18 Aug 2022 12:32:11 -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=@gmail.com header.s=20210112 header.b=UbCFQNes; 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=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344289AbiHRSyC (ORCPT + 99 others); Thu, 18 Aug 2022 14:54:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239324AbiHRSyA (ORCPT ); Thu, 18 Aug 2022 14:54:00 -0400 Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC72F501AC; Thu, 18 Aug 2022 11:53:58 -0700 (PDT) Received: by mail-wm1-x331.google.com with SMTP id c187-20020a1c35c4000000b003a30d88fe8eso3038414wma.2; Thu, 18 Aug 2022 11:53:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc; bh=8WO9HL2c2NqU95pngV5GpcHf00yCayPpvaZNx/fy4Qg=; b=UbCFQNesxAG/TMAva+KxIhwUYfVzWv9gUtIty6rIcwZhJUeg94eD6pHJnPEjSnAaTP VLNBSxOAWoszSycCRx0G2oBgnX1GiwZdNppAZRXP3GKuMr11AV6YdUWcyeIXg7JUQe1k EdQlKsNgEB36LuBWJ8qfnjY+AEmPJKRWHxGwhTDlBn8U3+EzKP4ltNDfcNSHUAys0j1p YkeAlyJ/ZIt6Ikt+ItKqOGPLZspZziU+6TE/NfiQuv0/QBiE490/6BELVp0ln34amb0e fw6+XvKwnlej9kDMqFPFF/fnhbxR6pFWns+eUAQh+htwsab7tpELxZ/k1LRudQU3tUj+ FJ+A== 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; bh=8WO9HL2c2NqU95pngV5GpcHf00yCayPpvaZNx/fy4Qg=; b=aR/l/KgZk/oclocXZK0Az0wMf4exBDxnqKvoTUomK6zZWhp1HvpawPOLIIcPdXNUrx KmeHgS69peD2hfCEsEmsA41VaMPFz/vrsxNYpGWtT5bswpwMcfe9JoEjfGPdQfRF/Yo8 cKtOfptQVV6KTgST6+4V+M+SnJ1thAyWCECCqy64Ldfce0K0O18OOABNSOvE5gBnK+/m wux8t+O6xd3yzuUBejr+U3qb8EUCzRuCHuU6eUhWyzyguOw2MUzrFPtDK6LLoDsbLEzH EQk9k71Ritc4HLT/aNkvjMqw84+YNBgyJb8wAqI0vCr3RASNxWgyOpAISZTWIqSiqWhY hPvg== X-Gm-Message-State: ACgBeo0f1aWlZv9qxkF8RAUzduWhFL2y5iDYcQPEH3QXsY0RzP+lhHgk EI9cV4C+I9N3ukL6m/hMIwG1nULNhTKFJdOz9gc= X-Received: by 2002:a05:600c:20a:b0:3a5:a700:17d with SMTP id 10-20020a05600c020a00b003a5a700017dmr2678817wmi.148.1660848837489; Thu, 18 Aug 2022 11:53:57 -0700 (PDT) MIME-Version: 1.0 References: <443632b6-c589-ef62-2385-3e8406680343@gmail.com> In-Reply-To: <443632b6-c589-ef62-2385-3e8406680343@gmail.com> From: Ramon Fried Date: Thu, 18 Aug 2022 21:53:45 +0300 Message-ID: Subject: Re: Running kunit tests on platform devices To: CAGi-RUL46gA_0ah_TTJVpc9RRS8nvd7yoqt=OLXxvUjL6TAvyQ@mail.gmail.com Cc: David Gow , Brendan Higgins , "open list:KERNEL SELFTEST FRAMEWORK" , KUnit Development , LKML Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_BLOCKED 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 Thu, Aug 18, 2022 at 9:08 PM Tales Lelo da Aparecida wrote: > > On 17/08/2022 09:19, Ramon Fried wrote: > > On Wed, Aug 17, 2022 at 7:43 AM David Gow wrote: > >> > >> On Mon, Aug 15, 2022 at 5:16 PM Ramon Fried wrote: > >>> > >>> Hi. > >>> I implemented a test suite that checks a platform driver, that's the > >>> only way I can test interrupts behavior in the code. > >>> Because it's a platform, I can't use kunit_test_suite(), so I call > >>> __kunit_test_suites_init() as part of the platform driver probe > >>> function. > >>> > >>> This works fine but has the following problems. > >>> "TAP version 14" string is not printed and it's impossible to parse > >>> the results using the script. > >>> In addition, the suite is not displayed in /sys/kernel/debug/kunit. > >>> > >>> It would be my pleasure to provide a patch that fixes this, I just > >>> wanted to make sure that my testing strategy makes sense. > >>> > >>> Thanks, > >>> Ramon > >>> > >> Hi Ramon, > >> > >> Thanks for reaching out. Calling __kunit_test_suites_init() directly > >> is not something we'd recommend (and are trying desperately to remove > >> existing uses), so several of the issues re: the "TAP version 14" > >> string et al are side effects of calling what is supposed to be an > >> internal KUnit function manually. > >> > >> That being said, we definitely do want to make testing platform > >> drivers as convenient as possible. I'm not sure why kunit_test_suite() > >> doesn't work for you for platform drivers: are you just missing some > >> way of instantiating the device from within a test context? > >> > >> I know Brendan has experimented with some hardware faking code, for > >> which there's some example use here: > >> https://kunit-review.googlesource.com/c/linux/+/5275 > >> (Note that you'll need to look at the other patches in the 'relation > >> chain' for dependencies.) > >> > >> Equally, I've experimented a bit with testing old soundcard drivers > >> (via a platform device) here, which may be an easier way to look > >> through: > >> https://github.com/sulix/linux/commit/4e1620c86553b9edde7f032318cf417dc13e4d26 > >> > >> Note that neither of those examples are anything other than > >> experiments, so may not work as-is, or be ideal. > >> > >> Otherwise, we're always happy to accept patches, though again, if > >> there's any way of getting your tests working without a direct call to > >> __kunit_test_suites_init() --- even if that would require patches to > >> work --- that'd be preferable on our end. > >> > >> Cheers, > >> -- David > > Hi David, > > Thanks for replying. > > I looked at the examples you shared, and they all fake the actual device. > > My intention is to actually interact with the real device. - get a > > real interrupt, etc. > > Is it wrong, was the intention that the platform device be mocked ? > > Thanks, > > Ramon. > > > > Hi, Ramon, > > I particularly don't condemn writing tests that require hardware, but > they're best avoided, mostly to facilitate running those tests. > > Can you share your code? Sure. > I would be happy to take a look if its not a problem for you! > > Kind regards, > Tales // SPDX-License-Identifier: GPL-2.0 #include #include #include #include #include #include #include #include #include #define ASPEN_HW_SW_QUEUES_OFFSET 0x02300000 #define ASPEN_HW_SW_QUEUES_SIZE 0x80000 #define HW_SW_QUEUES_TEST_SINGLE_QUEUE_CFG_REG_MEMORY_MAP_SIZE (0x1000) #define HW_SW_QUEUES_TEST_QUEUES_CFG_REG_MEMORY_MAP_SIZE (0x2000) #define HW_SW_QUEUES_TEST_HW2SW_QUEUE_CFG_OFFSET (0) #define HW_SW_QUEUES_TEST_HW2SW_QUEUE_COMMON_CFG_OFFSET (0x40) #define HW_SW_QUEUES_TEST_SW2HW_QUEUE_CFG_OFFSET (0x1000) #define HW_SW_QUEUES_TEST_SW2HW_QUEUE_COMMON_CFG_OFFSET (0x1020) #define QUEUE_DEPTH_MIN_SIZE (256) #define QUEUE_DEPTH_MAX_SIZE (1024) #define QUEUE_ELEM_MIN_SIZE (8) #define QUEUE_ELEM_MAX_SIZE (64) #define HW_SW_QUEUES_TEST_SINGLE_QUEUE_DATA_REG_MEMORY_MAP_SIZE \ (QUEUE_DEPTH_MAX_SIZE * QUEUE_ELEM_MAX_SIZE) #define HW_SW_QUEUES_TEST_QUEUES_DATA_REG_MEMORY_MAP_SIZE \ (HW_SW_QUEUES_TEST_SINGLE_QUEUE_DATA_REG_MEMORY_MAP_SIZE * 2) #define HW_SW_QUEUES_TEST_HW2SW_QUEUE_DATA_OFFSET (0x2000) #define HW_SW_QUEUES_TEST_SW2HW_QUEUE_DATA_OFFSET (HW_SW_QUEUES_TEST_HW2SW_QUEUE_DATA_OFFSET + \ HW_SW_QUEUES_TEST_SINGLE_QUEUE_DATA_REG_MEMORY_MAP_SIZE) struct queue_element { u64 value1; }; struct test_context { struct nr_sw_hw_queue sw_hw_queue; struct nr_hw_sw_queue hw_sw_queue; volatile bool irq_occurred; }; struct suite_context { struct platform_device *pdev; }; static struct suite_context g_context; irqreturn_t hw_sw_queue_irq_handler(int irq, void *ctx) { struct kunit *test = ctx; struct test_context *context = test->priv; kunit_info(test, "IRQ handler\n"); nr_hw_sw_consume(&context->hw_sw_queue, 1); nr_hw_sw_queue_clear_irq(&context->hw_sw_queue, 0); context->irq_occurred = true; return IRQ_HANDLED; } static void hw_sw_queues_simple_irq_test(struct kunit *test) { struct test_context *context = test->priv; int ret; void *addr; kunit_info(test, "Executing test\n"); context->irq_occurred = false; KUNIT_EXPECT_EQ(test, nr_hw_sw_queue_init(&context->hw_sw_queue), 0); KUNIT_EXPECT_EQ(test, nr_sw_hw_queue_init(&context->sw_hw_queue), 0); nr_hw_sw_queue_unmask_irq(&context->hw_sw_queue); nr_hw_sw_queue_enable(&context->hw_sw_queue); nr_sw_hw_queue_enable(&context->sw_hw_queue); ret = request_threaded_irq(context->hw_sw_queue.irq, hw_sw_queue_irq_handler, NULL, IRQF_SHARED | IRQF_TRIGGER_HIGH, "hw_sw_irq", test); KUNIT_EXPECT_EQ(test, ret, 0); nr_sw_hw_get_next_free_entry(&context->sw_hw_queue, &addr); nr_sw_hw_produce(&context->sw_hw_queue, 1); KUNIT_EXPECT_EQ(test, ret, 0); while (!context->irq_occurred) ; } static int hw_sw_queues_test_init(struct kunit *test) { struct test_context *context; context = kzalloc(sizeof(*context), GFP_KERNEL); test->priv = context; kunit_info(test, "initializing\n"); context->hw_sw_queue.common.element_size = sizeof(struct queue_element); context->hw_sw_queue.common.queue_depth = 8; context->hw_sw_queue.common.config_base = ioremap(ASPEN_HW_SW_QUEUES_OFFSET, ASPEN_HW_SW_QUEUES_SIZE); context->hw_sw_queue.irq_threshold = 1; context->hw_sw_queue.irq = platform_get_irq(g_context.pdev, 0); if (context->hw_sw_queue.irq < 0) return -1; context->sw_hw_queue.common.element_size = sizeof(struct queue_element); context->sw_hw_queue.common.queue_depth = 8; context->sw_hw_queue.common.config_base = context->hw_sw_queue.common.config_base + HW_SW_QUEUES_TEST_SW2HW_QUEUE_CFG_OFFSET; context->hw_sw_queue.common.virtual_base = context->hw_sw_queue.common.config_base + HW_SW_QUEUES_TEST_HW2SW_QUEUE_DATA_OFFSET; context->hw_sw_queue.common.physical_base = ASPEN_HW_SW_QUEUES_OFFSET + HW_SW_QUEUES_TEST_HW2SW_QUEUE_DATA_OFFSET; context->sw_hw_queue.common.virtual_base = context->hw_sw_queue.common.config_base + HW_SW_QUEUES_TEST_SW2HW_QUEUE_DATA_OFFSET; context->sw_hw_queue.common.physical_base = ASPEN_HW_SW_QUEUES_OFFSET + HW_SW_QUEUES_TEST_SW2HW_QUEUE_DATA_OFFSET; return 0; } static void hw_sw_queues_test_exit(struct kunit *test) { struct test_context *context = test->priv; kunit_info(test, "deinitializing\n"); iounmap(context->hw_sw_queue.common.config_base); free_irq(context->hw_sw_queue.irq, test); kfree(context); } static struct kunit_case hw_sw_queues_test_cases[] = { KUNIT_CASE(hw_sw_queues_simple_irq_test), {} }; static struct kunit_suite nr_hwsw_queues_test_suite = { .name = "nr_hwsw_queues", .init = hw_sw_queues_test_init, .exit = hw_sw_queues_test_exit, .test_cases = hw_sw_queues_test_cases, }; static struct kunit_suite *nr_hwsw_queues_test_suites[] = { &nr_hwsw_queues_test_suite, NULL }; static int nr_hw_sw_queues_test_probe(struct platform_device *pdev) { g_context.pdev = pdev; pr_info("TAP version 14\n"); pr_info("1..1\n"); return __kunit_test_suites_init(nr_hwsw_queues_test_suites); } static int nr_hw_sw_queues_test_remove(struct platform_device *pdev) { __kunit_test_suites_exit(nr_hwsw_queues_test_suites); return 0; } static const struct of_device_id nr_hw_sw_queues_test_of_match[] = { {.compatible = "nr,hw_sw_queus_test",}, {}, }; MODULE_DEVICE_TABLE(of, nr_hw_sw_queues_test_of_match); static struct platform_driver nr_hw_sw_queues_test = { .driver = { .name = "nr_hw_sw_queues_test", .of_match_table = nr_hw_sw_queues_test_of_match, }, .probe = nr_hw_sw_queues_test_probe, .remove = nr_hw_sw_queues_test_remove, }; module_platform_driver(nr_hw_sw_queues_test); MODULE_LICENSE("GPL");