tests: devicetree: test supported devices API

Add tests for the supported devices API.

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
This commit is contained in:
Jordan Yates 2021-08-20 19:30:47 +10:00 committed by Carles Cufí
commit eec7c5389b
2 changed files with 94 additions and 17 deletions

View file

@ -57,6 +57,28 @@
supply-gpios = <&test_gpiox 2 0>; supply-gpios = <&test_gpiox 2 0>;
label = "TEST_I2C_DEV_12"; label = "TEST_I2C_DEV_12";
}; };
test_dev_c: test-i2c-dev@13 {
compatible = "vnd,i2c-device";
label = "TEST_SPI_DEV_0";
reg = <13>;
status = "disabled";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
test_p0: partition@0 {
label = "partition-0";
reg = <0x000000000 0x0000C000>;
};
test_p1: partition@c000 {
label = "partition-1";
reg = <0x0000C000 0x00067000>;
};
};
};
}; };
}; };
}; };

View file

@ -14,6 +14,8 @@
#define TEST_DEVA DT_NODELABEL(test_dev_a) #define TEST_DEVA DT_NODELABEL(test_dev_a)
#define TEST_GPIOX DT_NODELABEL(test_gpiox) #define TEST_GPIOX DT_NODELABEL(test_gpiox)
#define TEST_DEVB DT_NODELABEL(test_dev_b) #define TEST_DEVB DT_NODELABEL(test_dev_b)
#define TEST_DEVC DT_NODELABEL(test_dev_c)
#define TEST_PARTITION DT_NODELABEL(test_p0)
static const struct device *devlist; static const struct device *devlist;
static const struct device *devlist_end; static const struct device *devlist_end;
@ -41,6 +43,10 @@ DEVICE_DT_DEFINE(TEST_DEVB, dev_init, NULL,
NULL, NULL, POST_KERNEL, 30, NULL); NULL, NULL, POST_KERNEL, 30, NULL);
DEVICE_DT_DEFINE(TEST_GPIOX, dev_init, NULL, DEVICE_DT_DEFINE(TEST_GPIOX, dev_init, NULL,
NULL, NULL, POST_KERNEL, 40, NULL); NULL, NULL, POST_KERNEL, 40, NULL);
DEVICE_DT_DEFINE(TEST_DEVC, dev_init, NULL,
NULL, NULL, POST_KERNEL, 50, NULL);
DEVICE_DT_DEFINE(TEST_PARTITION, dev_init, NULL,
NULL, NULL, POST_KERNEL, 60, NULL);
#define DEV_HDL(node_id) device_handle_get(DEVICE_DT_GET(node_id)) #define DEV_HDL(node_id) device_handle_get(DEVICE_DT_GET(node_id))
@ -74,15 +80,15 @@ static bool check_handle(device_handle_t hdl,
return false; return false;
} }
struct requires_context { struct visitor_context {
uint8_t ndevs; uint8_t ndevs;
const struct device *rdevs[2]; const struct device *rdevs[2];
}; };
static int requires_visitor(const struct device *dev, static int device_visitor(const struct device *dev,
void *context) void *context)
{ {
struct requires_context *ctx = context; struct visitor_context *ctx = context;
const struct device **rdp = ctx->rdevs; const struct device **rdp = ctx->rdevs;
while (rdp < (ctx->rdevs + ctx->ndevs)) { while (rdp < (ctx->rdevs + ctx->ndevs)) {
@ -102,14 +108,14 @@ static void test_requires(void)
size_t nhdls = 0; size_t nhdls = 0;
const device_handle_t *hdls; const device_handle_t *hdls;
const struct device *dev; const struct device *dev;
struct requires_context ctx = { 0 }; struct visitor_context ctx = { 0 };
/* TEST_GPIO: no req */ /* TEST_GPIO: no req */
dev = device_get_binding(DT_LABEL(TEST_GPIO)); dev = device_get_binding(DT_LABEL(TEST_GPIO));
zassert_equal(dev, DEVICE_DT_GET(TEST_GPIO), NULL); zassert_equal(dev, DEVICE_DT_GET(TEST_GPIO), NULL);
hdls = device_required_handles_get(dev, &nhdls); hdls = device_required_handles_get(dev, &nhdls);
zassert_equal(nhdls, 0, NULL); zassert_equal(nhdls, 0, NULL);
zassert_equal(0, device_required_foreach(dev, requires_visitor, &ctx), zassert_equal(0, device_required_foreach(dev, device_visitor, &ctx),
NULL); NULL);
/* TEST_I2C: no req */ /* TEST_I2C: no req */
@ -117,7 +123,7 @@ static void test_requires(void)
zassert_equal(dev, DEVICE_DT_GET(TEST_I2C), NULL); zassert_equal(dev, DEVICE_DT_GET(TEST_I2C), NULL);
hdls = device_required_handles_get(dev, &nhdls); hdls = device_required_handles_get(dev, &nhdls);
zassert_equal(nhdls, 0, NULL); zassert_equal(nhdls, 0, NULL);
zassert_equal(0, device_required_foreach(dev, requires_visitor, &ctx), zassert_equal(0, device_required_foreach(dev, device_visitor, &ctx),
NULL); NULL);
/* TEST_DEVA: TEST_I2C GPIO */ /* TEST_DEVA: TEST_I2C GPIO */
@ -129,17 +135,17 @@ static void test_requires(void)
zassert_true(check_handle(DEV_HDL(TEST_GPIO), hdls, nhdls), NULL); zassert_true(check_handle(DEV_HDL(TEST_GPIO), hdls, nhdls), NULL);
/* Visit fails if not enough space */ /* Visit fails if not enough space */
ctx = (struct requires_context){ ctx = (struct visitor_context){
.ndevs = 1, .ndevs = 1,
}; };
zassert_equal(-ENOSPC, device_required_foreach(dev, requires_visitor, &ctx), zassert_equal(-ENOSPC, device_required_foreach(dev, device_visitor, &ctx),
NULL); NULL);
/* Visit succeeds if enough space. */ /* Visit succeeds if enough space. */
ctx = (struct requires_context){ ctx = (struct visitor_context){
.ndevs = 2, .ndevs = 2,
}; };
zassert_equal(2, device_required_foreach(dev, requires_visitor, &ctx), zassert_equal(2, device_required_foreach(dev, device_visitor, &ctx),
NULL); NULL);
zassert_true((ctx.rdevs[0] == device_from_handle(DEV_HDL(TEST_I2C))) zassert_true((ctx.rdevs[0] == device_from_handle(DEV_HDL(TEST_I2C)))
|| (ctx.rdevs[1] == device_from_handle(DEV_HDL(TEST_I2C))), || (ctx.rdevs[1] == device_from_handle(DEV_HDL(TEST_I2C))),
@ -154,10 +160,10 @@ static void test_requires(void)
hdls = device_required_handles_get(dev, &nhdls); hdls = device_required_handles_get(dev, &nhdls);
zassert_equal(nhdls, 1, NULL); zassert_equal(nhdls, 1, NULL);
zassert_true(check_handle(DEV_HDL(TEST_I2C), hdls, nhdls), NULL); zassert_true(check_handle(DEV_HDL(TEST_I2C), hdls, nhdls), NULL);
ctx = (struct requires_context){ ctx = (struct visitor_context){
.ndevs = 3, .ndevs = 3,
}; };
zassert_equal(1, device_required_foreach(dev, requires_visitor, &ctx), zassert_equal(1, device_required_foreach(dev, device_visitor, &ctx),
NULL); NULL);
zassert_true(ctx.rdevs[0] == device_from_handle(DEV_HDL(TEST_I2C)), zassert_true(ctx.rdevs[0] == device_from_handle(DEV_HDL(TEST_I2C)),
NULL); NULL);
@ -171,7 +177,6 @@ static void test_requires(void)
zassert_true(check_handle(DEV_HDL(TEST_GPIOX), hdls, nhdls), NULL); zassert_true(check_handle(DEV_HDL(TEST_GPIOX), hdls, nhdls), NULL);
} }
static void test_get_or_null(void) static void test_get_or_null(void)
{ {
const struct device *dev; const struct device *dev;
@ -183,6 +188,55 @@ static void test_get_or_null(void)
zassert_equal(dev, NULL, NULL); zassert_equal(dev, NULL, NULL);
} }
static void test_supports(void)
{
size_t nhdls = 0;
const device_handle_t *hdls;
const struct device *dev;
struct visitor_context ctx = { 0 };
/* TEST_DEVB: None */
dev = DEVICE_DT_GET(TEST_DEVB);
hdls = device_supported_handles_get(dev, &nhdls);
zassert_equal(nhdls, 0, NULL);
/* TEST_GPIO: TEST_DEVA */
dev = DEVICE_DT_GET(TEST_GPIO);
hdls = device_supported_handles_get(dev, &nhdls);
zassert_equal(nhdls, 1, NULL);
zassert_true(check_handle(DEV_HDL(TEST_DEVA), hdls, nhdls), NULL);
/* Visit fails if not enough space */
ctx = (struct visitor_context){
.ndevs = 0,
};
zassert_equal(-ENOSPC, device_supported_foreach(dev, device_visitor, &ctx), NULL);
/* Visit succeeds if enough space. */
ctx = (struct visitor_context){
.ndevs = 1,
};
zassert_equal(1, device_supported_foreach(dev, device_visitor, &ctx), NULL);
zassert_true(ctx.rdevs[0] == device_from_handle(DEV_HDL(TEST_DEVA)), NULL);
/* TEST_I2C: TEST_DEVA TEST_GPIOX TEST_DEVB TEST_DEVC */
dev = DEVICE_DT_GET(TEST_I2C);
hdls = device_supported_handles_get(dev, &nhdls);
zassert_equal(nhdls, 4, NULL);
zassert_true(check_handle(DEV_HDL(TEST_DEVA), hdls, nhdls), NULL);
zassert_true(check_handle(DEV_HDL(TEST_GPIOX), hdls, nhdls), NULL);
zassert_true(check_handle(DEV_HDL(TEST_DEVB), hdls, nhdls), NULL);
zassert_true(check_handle(DEV_HDL(TEST_DEVC), hdls, nhdls), NULL);
/* Support forwarding (intermediate missing devicetree node)
* TEST_DEVC: TEST_PARTITION
*/
dev = DEVICE_DT_GET(TEST_DEVC);
hdls = device_supported_handles_get(dev, &nhdls);
zassert_equal(nhdls, 1, NULL);
zassert_true(check_handle(DEV_HDL(TEST_PARTITION), hdls, nhdls), NULL);
}
void test_main(void) void test_main(void)
{ {
size_t ndevs; size_t ndevs;
@ -193,7 +247,8 @@ void test_main(void)
ztest_test_suite(devicetree_driver, ztest_test_suite(devicetree_driver,
ztest_unit_test(test_init_order), ztest_unit_test(test_init_order),
ztest_unit_test(test_requires), ztest_unit_test(test_requires),
ztest_unit_test(test_get_or_null) ztest_unit_test(test_get_or_null),
ztest_unit_test(test_supports)
); );
ztest_run_test_suite(devicetree_driver); ztest_run_test_suite(devicetree_driver);
} }