~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/lib/kunit/platform-test.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * KUnit test for KUnit platform driver infrastructure.
  4  */
  5 
  6 #include <linux/platform_device.h>
  7 
  8 #include <kunit/platform_device.h>
  9 #include <kunit/test.h>
 10 
 11 /*
 12  * Test that kunit_platform_device_alloc() creates a platform device.
 13  */
 14 static void kunit_platform_device_alloc_test(struct kunit *test)
 15 {
 16         KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
 17                         kunit_platform_device_alloc(test, "kunit-platform", 1));
 18 }
 19 
 20 /*
 21  * Test that kunit_platform_device_add() registers a platform device on the
 22  * platform bus with the proper name and id.
 23  */
 24 static void kunit_platform_device_add_test(struct kunit *test)
 25 {
 26         struct platform_device *pdev;
 27         const char *name = "kunit-platform-add";
 28         const int id = -1;
 29 
 30         pdev = kunit_platform_device_alloc(test, name, id);
 31         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
 32 
 33         KUNIT_EXPECT_EQ(test, 0, kunit_platform_device_add(test, pdev));
 34         KUNIT_EXPECT_TRUE(test, dev_is_platform(&pdev->dev));
 35         KUNIT_EXPECT_STREQ(test, pdev->name, name);
 36         KUNIT_EXPECT_EQ(test, pdev->id, id);
 37 }
 38 
 39 /*
 40  * Test that kunit_platform_device_add() called twice with the same device name
 41  * and id fails the second time and properly cleans up.
 42  */
 43 static void kunit_platform_device_add_twice_fails_test(struct kunit *test)
 44 {
 45         struct platform_device *pdev;
 46         const char *name = "kunit-platform-add-2";
 47         const int id = -1;
 48 
 49         pdev = kunit_platform_device_alloc(test, name, id);
 50         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
 51         KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev));
 52 
 53         pdev = kunit_platform_device_alloc(test, name, id);
 54         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
 55 
 56         KUNIT_EXPECT_NE(test, 0, kunit_platform_device_add(test, pdev));
 57 }
 58 
 59 static int kunit_platform_device_find_by_name(struct device *dev, const void *data)
 60 {
 61         return strcmp(dev_name(dev), data) == 0;
 62 }
 63 
 64 /*
 65  * Test that kunit_platform_device_add() cleans up by removing the platform
 66  * device when the test finishes. */
 67 static void kunit_platform_device_add_cleans_up(struct kunit *test)
 68 {
 69         struct platform_device *pdev;
 70         const char *name = "kunit-platform-clean";
 71         const int id = -1;
 72         struct kunit fake;
 73         struct device *dev;
 74 
 75         kunit_init_test(&fake, "kunit_platform_device_add_fake_test", NULL);
 76         KUNIT_ASSERT_EQ(test, fake.status, KUNIT_SUCCESS);
 77 
 78         pdev = kunit_platform_device_alloc(&fake, name, id);
 79         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
 80         KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(&fake, pdev));
 81         dev = bus_find_device(&platform_bus_type, NULL, name,
 82                               kunit_platform_device_find_by_name);
 83         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
 84         put_device(dev);
 85 
 86         /* Remove pdev */
 87         kunit_cleanup(&fake);
 88 
 89         /*
 90          * Failing to migrate the kunit_resource would lead to an extra
 91          * put_device() call on the platform device. The best we can do here is
 92          * make sure the device no longer exists on the bus, but if something
 93          * is wrong we'll see a refcount underflow here. We can't test for a
 94          * refcount underflow because the kref matches the lifetime of the
 95          * device which should already be freed and could be used by something
 96          * else.
 97          */
 98         dev = bus_find_device(&platform_bus_type, NULL, name,
 99                               kunit_platform_device_find_by_name);
100         KUNIT_EXPECT_PTR_EQ(test, NULL, dev);
101         put_device(dev);
102 }
103 
104 /*
105  * Test suite for struct platform_device kunit APIs
106  */
107 static struct kunit_case kunit_platform_device_test_cases[] = {
108         KUNIT_CASE(kunit_platform_device_alloc_test),
109         KUNIT_CASE(kunit_platform_device_add_test),
110         KUNIT_CASE(kunit_platform_device_add_twice_fails_test),
111         KUNIT_CASE(kunit_platform_device_add_cleans_up),
112         {}
113 };
114 
115 static struct kunit_suite kunit_platform_device_suite = {
116         .name = "kunit_platform_device",
117         .test_cases = kunit_platform_device_test_cases,
118 };
119 
120 struct kunit_platform_driver_test_context {
121         struct platform_driver pdrv;
122         const char *data;
123 };
124 
125 static const char * const test_data = "test data";
126 
127 static inline struct kunit_platform_driver_test_context *
128 to_test_context(struct platform_device *pdev)
129 {
130         return container_of(to_platform_driver(pdev->dev.driver),
131                             struct kunit_platform_driver_test_context,
132                             pdrv);
133 }
134 
135 static int kunit_platform_driver_probe(struct platform_device *pdev)
136 {
137         struct kunit_platform_driver_test_context *ctx;
138 
139         ctx = to_test_context(pdev);
140         ctx->data = test_data;
141 
142         return 0;
143 }
144 
145 /* Test that kunit_platform_driver_register() registers a driver that probes. */
146 static void kunit_platform_driver_register_test(struct kunit *test)
147 {
148         struct platform_device *pdev;
149         struct kunit_platform_driver_test_context *ctx;
150         DECLARE_COMPLETION_ONSTACK(comp);
151         const char *name = "kunit-platform-register";
152 
153         ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
154         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
155 
156         pdev = kunit_platform_device_alloc(test, name, -1);
157         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
158         KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev));
159 
160         ctx->pdrv.probe = kunit_platform_driver_probe;
161         ctx->pdrv.driver.name = name;
162         ctx->pdrv.driver.owner = THIS_MODULE;
163 
164         KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_prepare_wait_for_probe(test, pdev, &comp));
165 
166         KUNIT_EXPECT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
167         KUNIT_EXPECT_NE(test, 0, wait_for_completion_timeout(&comp, 3 * HZ));
168         KUNIT_EXPECT_STREQ(test, ctx->data, test_data);
169 }
170 
171 /*
172  * Test that kunit_platform_device_prepare_wait_for_probe() completes the completion
173  * when the device is already probed.
174  */
175 static void kunit_platform_device_prepare_wait_for_probe_completes_when_already_probed(struct kunit *test)
176 {
177         struct platform_device *pdev;
178         struct kunit_platform_driver_test_context *ctx;
179         DECLARE_COMPLETION_ONSTACK(comp);
180         const char *name = "kunit-platform-wait";
181 
182         ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
183         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
184 
185         pdev = kunit_platform_device_alloc(test, name, -1);
186         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
187         KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev));
188 
189         ctx->pdrv.probe = kunit_platform_driver_probe;
190         ctx->pdrv.driver.name = name;
191         ctx->pdrv.driver.owner = THIS_MODULE;
192 
193         /* Make sure driver has actually probed */
194         KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_prepare_wait_for_probe(test, pdev, &comp));
195         KUNIT_ASSERT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
196         KUNIT_ASSERT_NE(test, 0, wait_for_completion_timeout(&comp, 3 * HZ));
197 
198         reinit_completion(&comp);
199         KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_prepare_wait_for_probe(test, pdev, &comp));
200 
201         KUNIT_EXPECT_NE(test, 0, wait_for_completion_timeout(&comp, HZ));
202 }
203 
204 static struct kunit_case kunit_platform_driver_test_cases[] = {
205         KUNIT_CASE(kunit_platform_driver_register_test),
206         KUNIT_CASE(kunit_platform_device_prepare_wait_for_probe_completes_when_already_probed),
207         {}
208 };
209 
210 /*
211  * Test suite for struct platform_driver kunit APIs
212  */
213 static struct kunit_suite kunit_platform_driver_suite = {
214         .name = "kunit_platform_driver",
215         .test_cases = kunit_platform_driver_test_cases,
216 };
217 
218 kunit_test_suites(
219         &kunit_platform_device_suite,
220         &kunit_platform_driver_suite,
221 );
222 
223 MODULE_LICENSE("GPL");
224 MODULE_DESCRIPTION("KUnit test for KUnit platform driver infrastructure");
225 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php