[v8,3/8] test: cmd: add unit tests for part command

Message ID 20260430080627.849636-4-dario.binacchi@amarulasolutions.com
State New
Headers show
Series
  • Support metadata-driven A/B boot for STM32MP25
Related show

Commit Message

Dario Binacchi April 30, 2026, 8:06 a.m. UTC
Add unit tests for the 'part' command, specifically for the 'number',
'start', and 'size' subcommands.

These tests establish a baseline for the current partition lookup
functionality by name. This foundation will be used by subsequent
patches to extend the command, ensuring consistent behavior as new
features are introduced.

Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Reviewed-by: Simon Glass <sjg@chromium.org>

---

Changes in v8:
- Skip the test in case the CONFIG_MCC is not enabled or the mmc
  device is not found.

Changes in v6:
- Add Reviewed-by of Simon Glass to patch 3/8 "test: cmd: add unit
  tests for part command"

Changes in v4:
- Place the part command tests in the cmd suite rather than the dm
  suite.
- Order the include files according the U-Boot coding style.

Changes in v3:
- Wrap the lines exceeding 80 columns
- Combine run_command() and ut_asserteq() -> ut_asserteq(1, run_command(

 test/cmd/Makefile |   1 +
 test/cmd/part.c   | 183 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 184 insertions(+)
 create mode 100644 test/cmd/part.c

Comments

Patrice CHOTARD May 5, 2026, 7:26 a.m. UTC | #1
On 4/30/26 10:06, Dario Binacchi wrote:
> Add unit tests for the 'part' command, specifically for the 'number',
> 'start', and 'size' subcommands.
> 
> These tests establish a baseline for the current partition lookup
> functionality by name. This foundation will be used by subsequent
> patches to extend the command, ensuring consistent behavior as new
> features are introduced.
> 
> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> ---
> 
> Changes in v8:
> - Skip the test in case the CONFIG_MCC is not enabled or the mmc
>   device is not found.
> 
> Changes in v6:
> - Add Reviewed-by of Simon Glass to patch 3/8 "test: cmd: add unit
>   tests for part command"
> 
> Changes in v4:
> - Place the part command tests in the cmd suite rather than the dm
>   suite.
> - Order the include files according the U-Boot coding style.
> 
> Changes in v3:
> - Wrap the lines exceeding 80 columns
> - Combine run_command() and ut_asserteq() -> ut_asserteq(1, run_command(
> 
>  test/cmd/Makefile |   1 +
>  test/cmd/part.c   | 183 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 184 insertions(+)
>  create mode 100644 test/cmd/part.c
> 
> diff --git a/test/cmd/Makefile b/test/cmd/Makefile
> index 5f2815b1bb65..8d6932f1176c 100644
> --- a/test/cmd/Makefile
> +++ b/test/cmd/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_CMD_LOADM) += loadm.o
>  obj-$(CONFIG_CMD_MEMINFO) += meminfo.o
>  obj-$(CONFIG_CMD_MEMORY) += mem_copy.o
>  obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o
> +obj-$(CONFIG_CMD_PART) += part.o
>  ifdef CONFIG_CMD_PCI
>  obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o
>  endif
> diff --git a/test/cmd/part.c b/test/cmd/part.c
> new file mode 100644
> index 000000000000..cac57a1a0e35
> --- /dev/null
> +++ b/test/cmd/part.c
> @@ -0,0 +1,183 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Test for part command
> + *
> + * Copyright (C) 2026 Amarula Solutions
> + * Written by Dario Binacchi <dario.binacchi@amarulasolutions.com>
> + */
> +
> +#include <command.h>
> +#include <dm.h>
> +#include <env.h>
> +#include <part.h>
> +#include <vsprintf.h>
> +#include <dm/test.h>
> +#include <test/cmd.h>
> +#include <test/test.h>
> +#include <test/ut.h>
> +
> +static struct disk_partition gpt_parts[] = {
> +	{
> +		.start = 48,
> +		.size = 1,
> +		.name = "test1",
> +		.uuid = "c5bce7a2-03f0-4d03-9048-01ff23b9d527",
> +	},
> +	{
> +		.start = 49,
> +		.size = 2,
> +		.name = "test2",
> +		.uuid = "9df346e8-2c53-4cd8-b9ac-3af83f9a9b74",
> +	},
> +};
> +
> +static char disk_guid[UUID_STR_LEN + 1] =
> +	"8d60b397-1bb6-4d33-80ee-b1587d24c2f8";
> +
> +static int setup_gpt_partitions(struct unit_test_state *uts,
> +				unsigned int mmc_dev_num)
> +{
> +	struct blk_desc *mmc_dev_desc;
> +	char dev_str[10];
> +	int i, ret;
> +
> +	if (!CONFIG_IS_ENABLED(MMC))
> +		return -EAGAIN;

Hi Dario

Is there any reason to return -EAGAIN ? -ENODEV seems more appropriate ?

Thanks
Patrice

> +
> +	snprintf(dev_str, sizeof(dev_str), "%u", mmc_dev_num);
> +
> +	ret = blk_get_device_by_str("mmc", dev_str, &mmc_dev_desc);
> +	if (ret == -ENODEV)
> +		return -EAGAIN;
> +
> +	ut_asserteq(mmc_dev_num, ret);
> +
> +	if (CONFIG_IS_ENABLED(RANDOM_UUID)) {
> +		for (i = 0; i < ARRAY_SIZE(gpt_parts); i++)
> +			gen_rand_uuid_str(gpt_parts[i].uuid,
> +					  UUID_STR_FORMAT_STD);
> +
> +		gen_rand_uuid_str(disk_guid, UUID_STR_FORMAT_STD);
> +	}
> +
> +	ut_assertok(gpt_restore(mmc_dev_desc, disk_guid, gpt_parts,
> +				ARRAY_SIZE(gpt_parts)));
> +	return 0;
> +}
> +
> +static int cmd_test_part_number(struct unit_test_state *uts)
> +{
> +	unsigned int mmc_dev_num = 2;
> +	char expected[10];
> +	int i, ret;
> +
> +	ret = setup_gpt_partitions(uts, mmc_dev_num);
> +	if (ret == -EAGAIN)
> +		return ret;
> +
> +	ut_assertok(ret);
> +
> +	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> +		env_set("partnum", NULL);
> +		ut_assertok(run_commandf("part number mmc %u %s partnum",
> +					 mmc_dev_num, gpt_parts[i].name));
> +		snprintf(expected, sizeof(expected), "0x%x", i + 1);
> +		ut_asserteq_str(expected, env_get("partnum"));
> +	}
> +
> +	env_set("partnum", NULL);
> +	ut_asserteq(1, run_commandf("part number mmc %u bogus partnum",
> +				    mmc_dev_num));
> +	ut_assertnull(env_get("partnum"));
> +
> +	return 0;
> +}
> +CMD_TEST(cmd_test_part_number, UTF_CONSOLE);
> +
> +static int cmd_test_part_start(struct unit_test_state *uts)
> +{
> +	unsigned int mmc_dev_num = 2;
> +	char expected[32];
> +	int i, ret;
> +
> +	ret = setup_gpt_partitions(uts, mmc_dev_num);
> +	if (ret == -EAGAIN)
> +		return ret;
> +
> +	ut_assertok(ret);
> +
> +	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> +		env_set("partstart", NULL);
> +		ut_assertok(run_commandf("part start mmc %u %d partstart",
> +					 mmc_dev_num, i + 1));
> +		snprintf(expected, sizeof(expected), "%lx",
> +			 (unsigned long)gpt_parts[i].start);
> +		ut_asserteq_str(expected, env_get("partstart"));
> +	}
> +
> +	env_set("partstart", NULL);
> +	ut_asserteq(1, run_commandf("part start mmc %u 3 partstart",
> +				    mmc_dev_num));
> +	ut_assertnull(env_get("partstart"));
> +
> +	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> +		env_set("partstart", NULL);
> +		ut_assertok(run_commandf("part start mmc %u %s partstart",
> +					 mmc_dev_num, gpt_parts[i].name));
> +		snprintf(expected, sizeof(expected), "%lx",
> +			 (unsigned long)gpt_parts[i].start);
> +		ut_asserteq_str(expected, env_get("partstart"));
> +	}
> +
> +	env_set("partstart", NULL);
> +	ut_asserteq(1, run_commandf("part start mmc %u bogus partstart",
> +				    mmc_dev_num));
> +	ut_assertnull(env_get("partstart"));
> +
> +	return 0;
> +}
> +CMD_TEST(cmd_test_part_start, UTF_CONSOLE);
> +
> +static int cmd_test_part_size(struct unit_test_state *uts)
> +{
> +	unsigned int mmc_dev_num = 2;
> +	char expected[32];
> +	int i, ret;
> +
> +	ret = setup_gpt_partitions(uts, mmc_dev_num);
> +	if (ret == -EAGAIN)
> +		return ret;
> +
> +	ut_assertok(ret);
> +
> +	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> +		env_set("partsize", NULL);
> +		ut_assertok(run_commandf("part size mmc %u %d partsize",
> +					 mmc_dev_num, i + 1));
> +		snprintf(expected, sizeof(expected), "%lx",
> +			 (unsigned long)gpt_parts[i].size);
> +		ut_asserteq_str(expected, env_get("partsize"));
> +	}
> +
> +	env_set("partsize", NULL);
> +	ut_asserteq(1, run_commandf("part size mmc %u 3 partsize",
> +				    mmc_dev_num));
> +	ut_assertnull(env_get("partsize"));
> +
> +	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> +		env_set("partsize", NULL);
> +		ut_assertok(run_commandf("part size mmc %u %s partsize",
> +					 mmc_dev_num, gpt_parts[i].name));
> +		snprintf(expected, sizeof(expected), "%lx",
> +			 (unsigned long)gpt_parts[i].size);
> +		ut_asserteq_str(expected, env_get("partsize"));
> +	}
> +
> +	env_set("partsize", NULL);
> +	ut_asserteq(1, run_commandf("part size mmc %u bogus partsize",
> +				    mmc_dev_num));
> +	ut_assertnull(env_get("partsize"));
> +
> +	return 0;
> +}
> +CMD_TEST(cmd_test_part_size, UTF_CONSOLE);

To unsubscribe from this group and stop receiving emails from it, send an email to linux-amarula+unsubscribe@amarulasolutions.com.
Dario Binacchi May 5, 2026, 7:55 a.m. UTC | #2
Hi Patrice,

On Tue, May 5, 2026 at 9:26 AM Patrice CHOTARD <patrice.chotard@foss.st.com>
wrote:

>
>
> On 4/30/26 10:06, Dario Binacchi wrote:
> > Add unit tests for the 'part' command, specifically for the 'number',
> > 'start', and 'size' subcommands.
> >
> > These tests establish a baseline for the current partition lookup
> > functionality by name. This foundation will be used by subsequent
> > patches to extend the command, ensuring consistent behavior as new
> > features are introduced.
> >
> > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
> > Reviewed-by: Simon Glass <sjg@chromium.org>
> >
> > ---
> >
> > Changes in v8:
> > - Skip the test in case the CONFIG_MCC is not enabled or the mmc
> >   device is not found.
> >
> > Changes in v6:
> > - Add Reviewed-by of Simon Glass to patch 3/8 "test: cmd: add unit
> >   tests for part command"
> >
> > Changes in v4:
> > - Place the part command tests in the cmd suite rather than the dm
> >   suite.
> > - Order the include files according the U-Boot coding style.
> >
> > Changes in v3:
> > - Wrap the lines exceeding 80 columns
> > - Combine run_command() and ut_asserteq() -> ut_asserteq(1, run_command(
> >
> >  test/cmd/Makefile |   1 +
> >  test/cmd/part.c   | 183 ++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 184 insertions(+)
> >  create mode 100644 test/cmd/part.c
> >
> > diff --git a/test/cmd/Makefile b/test/cmd/Makefile
> > index 5f2815b1bb65..8d6932f1176c 100644
> > --- a/test/cmd/Makefile
> > +++ b/test/cmd/Makefile
> > @@ -26,6 +26,7 @@ obj-$(CONFIG_CMD_LOADM) += loadm.o
> >  obj-$(CONFIG_CMD_MEMINFO) += meminfo.o
> >  obj-$(CONFIG_CMD_MEMORY) += mem_copy.o
> >  obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o
> > +obj-$(CONFIG_CMD_PART) += part.o
> >  ifdef CONFIG_CMD_PCI
> >  obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o
> >  endif
> > diff --git a/test/cmd/part.c b/test/cmd/part.c
> > new file mode 100644
> > index 000000000000..cac57a1a0e35
> > --- /dev/null
> > +++ b/test/cmd/part.c
> > @@ -0,0 +1,183 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Test for part command
> > + *
> > + * Copyright (C) 2026 Amarula Solutions
> > + * Written by Dario Binacchi <dario.binacchi@amarulasolutions.com>
> > + */
> > +
> > +#include <command.h>
> > +#include <dm.h>
> > +#include <env.h>
> > +#include <part.h>
> > +#include <vsprintf.h>
> > +#include <dm/test.h>
> > +#include <test/cmd.h>
> > +#include <test/test.h>
> > +#include <test/ut.h>
> > +
> > +static struct disk_partition gpt_parts[] = {
> > +     {
> > +             .start = 48,
> > +             .size = 1,
> > +             .name = "test1",
> > +             .uuid = "c5bce7a2-03f0-4d03-9048-01ff23b9d527",
> > +     },
> > +     {
> > +             .start = 49,
> > +             .size = 2,
> > +             .name = "test2",
> > +             .uuid = "9df346e8-2c53-4cd8-b9ac-3af83f9a9b74",
> > +     },
> > +};
> > +
> > +static char disk_guid[UUID_STR_LEN + 1] =
> > +     "8d60b397-1bb6-4d33-80ee-b1587d24c2f8";
> > +
> > +static int setup_gpt_partitions(struct unit_test_state *uts,
> > +                             unsigned int mmc_dev_num)
> > +{
> > +     struct blk_desc *mmc_dev_desc;
> > +     char dev_str[10];
> > +     int i, ret;
> > +
> > +     if (!CONFIG_IS_ENABLED(MMC))
> > +             return -EAGAIN;
>
> Hi Dario
>
> Is there any reason to return -EAGAIN ? -ENODEV seems more appropriate ?
>

In the testing framework, returning -EAGAIN explicitly signals that the
test should be skipped*.*

As highlighted in the documentation for ut_run_test():

*Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1
if any failed*


Since the necessary preconditions weren't met for some configuration in our
case, I decided to skip.

Thanks and regards,

Dario


> Thanks
> Patrice
>
> > +
> > +     snprintf(dev_str, sizeof(dev_str), "%u", mmc_dev_num);
> > +
> > +     ret = blk_get_device_by_str("mmc", dev_str, &mmc_dev_desc);
> > +     if (ret == -ENODEV)
> > +             return -EAGAIN;
> > +
> > +     ut_asserteq(mmc_dev_num, ret);
> > +
> > +     if (CONFIG_IS_ENABLED(RANDOM_UUID)) {
> > +             for (i = 0; i < ARRAY_SIZE(gpt_parts); i++)
> > +                     gen_rand_uuid_str(gpt_parts[i].uuid,
> > +                                       UUID_STR_FORMAT_STD);
> > +
> > +             gen_rand_uuid_str(disk_guid, UUID_STR_FORMAT_STD);
> > +     }
> > +
> > +     ut_assertok(gpt_restore(mmc_dev_desc, disk_guid, gpt_parts,
> > +                             ARRAY_SIZE(gpt_parts)));
> > +     return 0;
> > +}
> > +
> > +static int cmd_test_part_number(struct unit_test_state *uts)
> > +{
> > +     unsigned int mmc_dev_num = 2;
> > +     char expected[10];
> > +     int i, ret;
> > +
> > +     ret = setup_gpt_partitions(uts, mmc_dev_num);
> > +     if (ret == -EAGAIN)
> > +             return ret;
> > +
> > +     ut_assertok(ret);
> > +
> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> > +             env_set("partnum", NULL);
> > +             ut_assertok(run_commandf("part number mmc %u %s partnum",
> > +                                      mmc_dev_num, gpt_parts[i].name));
> > +             snprintf(expected, sizeof(expected), "0x%x", i + 1);
> > +             ut_asserteq_str(expected, env_get("partnum"));
> > +     }
> > +
> > +     env_set("partnum", NULL);
> > +     ut_asserteq(1, run_commandf("part number mmc %u bogus partnum",
> > +                                 mmc_dev_num));
> > +     ut_assertnull(env_get("partnum"));
> > +
> > +     return 0;
> > +}
> > +CMD_TEST(cmd_test_part_number, UTF_CONSOLE);
> > +
> > +static int cmd_test_part_start(struct unit_test_state *uts)
> > +{
> > +     unsigned int mmc_dev_num = 2;
> > +     char expected[32];
> > +     int i, ret;
> > +
> > +     ret = setup_gpt_partitions(uts, mmc_dev_num);
> > +     if (ret == -EAGAIN)
> > +             return ret;
> > +
> > +     ut_assertok(ret);
> > +
> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> > +             env_set("partstart", NULL);
> > +             ut_assertok(run_commandf("part start mmc %u %d partstart",
> > +                                      mmc_dev_num, i + 1));
> > +             snprintf(expected, sizeof(expected), "%lx",
> > +                      (unsigned long)gpt_parts[i].start);
> > +             ut_asserteq_str(expected, env_get("partstart"));
> > +     }
> > +
> > +     env_set("partstart", NULL);
> > +     ut_asserteq(1, run_commandf("part start mmc %u 3 partstart",
> > +                                 mmc_dev_num));
> > +     ut_assertnull(env_get("partstart"));
> > +
> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> > +             env_set("partstart", NULL);
> > +             ut_assertok(run_commandf("part start mmc %u %s partstart",
> > +                                      mmc_dev_num, gpt_parts[i].name));
> > +             snprintf(expected, sizeof(expected), "%lx",
> > +                      (unsigned long)gpt_parts[i].start);
> > +             ut_asserteq_str(expected, env_get("partstart"));
> > +     }
> > +
> > +     env_set("partstart", NULL);
> > +     ut_asserteq(1, run_commandf("part start mmc %u bogus partstart",
> > +                                 mmc_dev_num));
> > +     ut_assertnull(env_get("partstart"));
> > +
> > +     return 0;
> > +}
> > +CMD_TEST(cmd_test_part_start, UTF_CONSOLE);
> > +
> > +static int cmd_test_part_size(struct unit_test_state *uts)
> > +{
> > +     unsigned int mmc_dev_num = 2;
> > +     char expected[32];
> > +     int i, ret;
> > +
> > +     ret = setup_gpt_partitions(uts, mmc_dev_num);
> > +     if (ret == -EAGAIN)
> > +             return ret;
> > +
> > +     ut_assertok(ret);
> > +
> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> > +             env_set("partsize", NULL);
> > +             ut_assertok(run_commandf("part size mmc %u %d partsize",
> > +                                      mmc_dev_num, i + 1));
> > +             snprintf(expected, sizeof(expected), "%lx",
> > +                      (unsigned long)gpt_parts[i].size);
> > +             ut_asserteq_str(expected, env_get("partsize"));
> > +     }
> > +
> > +     env_set("partsize", NULL);
> > +     ut_asserteq(1, run_commandf("part size mmc %u 3 partsize",
> > +                                 mmc_dev_num));
> > +     ut_assertnull(env_get("partsize"));
> > +
> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
> > +             env_set("partsize", NULL);
> > +             ut_assertok(run_commandf("part size mmc %u %s partsize",
> > +                                      mmc_dev_num, gpt_parts[i].name));
> > +             snprintf(expected, sizeof(expected), "%lx",
> > +                      (unsigned long)gpt_parts[i].size);
> > +             ut_asserteq_str(expected, env_get("partsize"));
> > +     }
> > +
> > +     env_set("partsize", NULL);
> > +     ut_asserteq(1, run_commandf("part size mmc %u bogus partsize",
> > +                                 mmc_dev_num));
> > +     ut_assertnull(env_get("partsize"));
> > +
> > +     return 0;
> > +}
> > +CMD_TEST(cmd_test_part_size, UTF_CONSOLE);
>
>
Dario Binacchi May 12, 2026, 7:08 a.m. UTC | #3
Hi everyone,

I am resending my previous reply because I received a delivery failure
notification last week indicating that Patrice's mailbox was full.

Patrice, did you have a chance to verify if the tests are passing fine now?
Please let me know if everything looks good or if you need

me to make any further modifications.

Thanks and regards

Dario

On Tue, May 5, 2026 at 9:55 AM Dario Binacchi <
dario.binacchi@amarulasolutions.com> wrote:

> Hi Patrice,
>
> On Tue, May 5, 2026 at 9:26 AM Patrice CHOTARD <
> patrice.chotard@foss.st.com> wrote:
>
>>
>>
>> On 4/30/26 10:06, Dario Binacchi wrote:
>> > Add unit tests for the 'part' command, specifically for the 'number',
>> > 'start', and 'size' subcommands.
>> >
>> > These tests establish a baseline for the current partition lookup
>> > functionality by name. This foundation will be used by subsequent
>> > patches to extend the command, ensuring consistent behavior as new
>> > features are introduced.
>> >
>> > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
>> > Reviewed-by: Simon Glass <sjg@chromium.org>
>> >
>> > ---
>> >
>> > Changes in v8:
>> > - Skip the test in case the CONFIG_MCC is not enabled or the mmc
>> >   device is not found.
>> >
>> > Changes in v6:
>> > - Add Reviewed-by of Simon Glass to patch 3/8 "test: cmd: add unit
>> >   tests for part command"
>> >
>> > Changes in v4:
>> > - Place the part command tests in the cmd suite rather than the dm
>> >   suite.
>> > - Order the include files according the U-Boot coding style.
>> >
>> > Changes in v3:
>> > - Wrap the lines exceeding 80 columns
>> > - Combine run_command() and ut_asserteq() -> ut_asserteq(1, run_command(
>> >
>> >  test/cmd/Makefile |   1 +
>> >  test/cmd/part.c   | 183 ++++++++++++++++++++++++++++++++++++++++++++++
>> >  2 files changed, 184 insertions(+)
>> >  create mode 100644 test/cmd/part.c
>> >
>> > diff --git a/test/cmd/Makefile b/test/cmd/Makefile
>> > index 5f2815b1bb65..8d6932f1176c 100644
>> > --- a/test/cmd/Makefile
>> > +++ b/test/cmd/Makefile
>> > @@ -26,6 +26,7 @@ obj-$(CONFIG_CMD_LOADM) += loadm.o
>> >  obj-$(CONFIG_CMD_MEMINFO) += meminfo.o
>> >  obj-$(CONFIG_CMD_MEMORY) += mem_copy.o
>> >  obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o
>> > +obj-$(CONFIG_CMD_PART) += part.o
>> >  ifdef CONFIG_CMD_PCI
>> >  obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o
>> >  endif
>> > diff --git a/test/cmd/part.c b/test/cmd/part.c
>> > new file mode 100644
>> > index 000000000000..cac57a1a0e35
>> > --- /dev/null
>> > +++ b/test/cmd/part.c
>> > @@ -0,0 +1,183 @@
>> > +// SPDX-License-Identifier: GPL-2.0+
>> > +/*
>> > + * Test for part command
>> > + *
>> > + * Copyright (C) 2026 Amarula Solutions
>> > + * Written by Dario Binacchi <dario.binacchi@amarulasolutions.com>
>> > + */
>> > +
>> > +#include <command.h>
>> > +#include <dm.h>
>> > +#include <env.h>
>> > +#include <part.h>
>> > +#include <vsprintf.h>
>> > +#include <dm/test.h>
>> > +#include <test/cmd.h>
>> > +#include <test/test.h>
>> > +#include <test/ut.h>
>> > +
>> > +static struct disk_partition gpt_parts[] = {
>> > +     {
>> > +             .start = 48,
>> > +             .size = 1,
>> > +             .name = "test1",
>> > +             .uuid = "c5bce7a2-03f0-4d03-9048-01ff23b9d527",
>> > +     },
>> > +     {
>> > +             .start = 49,
>> > +             .size = 2,
>> > +             .name = "test2",
>> > +             .uuid = "9df346e8-2c53-4cd8-b9ac-3af83f9a9b74",
>> > +     },
>> > +};
>> > +
>> > +static char disk_guid[UUID_STR_LEN + 1] =
>> > +     "8d60b397-1bb6-4d33-80ee-b1587d24c2f8";
>> > +
>> > +static int setup_gpt_partitions(struct unit_test_state *uts,
>> > +                             unsigned int mmc_dev_num)
>> > +{
>> > +     struct blk_desc *mmc_dev_desc;
>> > +     char dev_str[10];
>> > +     int i, ret;
>> > +
>> > +     if (!CONFIG_IS_ENABLED(MMC))
>> > +             return -EAGAIN;
>>
>> Hi Dario
>>
>> Is there any reason to return -EAGAIN ? -ENODEV seems more appropriate ?
>>
>
> In the testing framework, returning -EAGAIN explicitly signals that the
> test should be skipped*.*
>
> As highlighted in the documentation for ut_run_test():
>
> *Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1
> if any failed*
>
>
> Since the necessary preconditions weren't met for some configuration in
> our case, I decided to skip.
>
> Thanks and regards,
>
> Dario
>
>
>> Thanks
>> Patrice
>>
>> > +
>> > +     snprintf(dev_str, sizeof(dev_str), "%u", mmc_dev_num);
>> > +
>> > +     ret = blk_get_device_by_str("mmc", dev_str, &mmc_dev_desc);
>> > +     if (ret == -ENODEV)
>> > +             return -EAGAIN;
>> > +
>> > +     ut_asserteq(mmc_dev_num, ret);
>> > +
>> > +     if (CONFIG_IS_ENABLED(RANDOM_UUID)) {
>> > +             for (i = 0; i < ARRAY_SIZE(gpt_parts); i++)
>> > +                     gen_rand_uuid_str(gpt_parts[i].uuid,
>> > +                                       UUID_STR_FORMAT_STD);
>> > +
>> > +             gen_rand_uuid_str(disk_guid, UUID_STR_FORMAT_STD);
>> > +     }
>> > +
>> > +     ut_assertok(gpt_restore(mmc_dev_desc, disk_guid, gpt_parts,
>> > +                             ARRAY_SIZE(gpt_parts)));
>> > +     return 0;
>> > +}
>> > +
>> > +static int cmd_test_part_number(struct unit_test_state *uts)
>> > +{
>> > +     unsigned int mmc_dev_num = 2;
>> > +     char expected[10];
>> > +     int i, ret;
>> > +
>> > +     ret = setup_gpt_partitions(uts, mmc_dev_num);
>> > +     if (ret == -EAGAIN)
>> > +             return ret;
>> > +
>> > +     ut_assertok(ret);
>> > +
>> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>> > +             env_set("partnum", NULL);
>> > +             ut_assertok(run_commandf("part number mmc %u %s partnum",
>> > +                                      mmc_dev_num, gpt_parts[i].name));
>> > +             snprintf(expected, sizeof(expected), "0x%x", i + 1);
>> > +             ut_asserteq_str(expected, env_get("partnum"));
>> > +     }
>> > +
>> > +     env_set("partnum", NULL);
>> > +     ut_asserteq(1, run_commandf("part number mmc %u bogus partnum",
>> > +                                 mmc_dev_num));
>> > +     ut_assertnull(env_get("partnum"));
>> > +
>> > +     return 0;
>> > +}
>> > +CMD_TEST(cmd_test_part_number, UTF_CONSOLE);
>> > +
>> > +static int cmd_test_part_start(struct unit_test_state *uts)
>> > +{
>> > +     unsigned int mmc_dev_num = 2;
>> > +     char expected[32];
>> > +     int i, ret;
>> > +
>> > +     ret = setup_gpt_partitions(uts, mmc_dev_num);
>> > +     if (ret == -EAGAIN)
>> > +             return ret;
>> > +
>> > +     ut_assertok(ret);
>> > +
>> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>> > +             env_set("partstart", NULL);
>> > +             ut_assertok(run_commandf("part start mmc %u %d partstart",
>> > +                                      mmc_dev_num, i + 1));
>> > +             snprintf(expected, sizeof(expected), "%lx",
>> > +                      (unsigned long)gpt_parts[i].start);
>> > +             ut_asserteq_str(expected, env_get("partstart"));
>> > +     }
>> > +
>> > +     env_set("partstart", NULL);
>> > +     ut_asserteq(1, run_commandf("part start mmc %u 3 partstart",
>> > +                                 mmc_dev_num));
>> > +     ut_assertnull(env_get("partstart"));
>> > +
>> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>> > +             env_set("partstart", NULL);
>> > +             ut_assertok(run_commandf("part start mmc %u %s partstart",
>> > +                                      mmc_dev_num, gpt_parts[i].name));
>> > +             snprintf(expected, sizeof(expected), "%lx",
>> > +                      (unsigned long)gpt_parts[i].start);
>> > +             ut_asserteq_str(expected, env_get("partstart"));
>> > +     }
>> > +
>> > +     env_set("partstart", NULL);
>> > +     ut_asserteq(1, run_commandf("part start mmc %u bogus partstart",
>> > +                                 mmc_dev_num));
>> > +     ut_assertnull(env_get("partstart"));
>> > +
>> > +     return 0;
>> > +}
>> > +CMD_TEST(cmd_test_part_start, UTF_CONSOLE);
>> > +
>> > +static int cmd_test_part_size(struct unit_test_state *uts)
>> > +{
>> > +     unsigned int mmc_dev_num = 2;
>> > +     char expected[32];
>> > +     int i, ret;
>> > +
>> > +     ret = setup_gpt_partitions(uts, mmc_dev_num);
>> > +     if (ret == -EAGAIN)
>> > +             return ret;
>> > +
>> > +     ut_assertok(ret);
>> > +
>> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>> > +             env_set("partsize", NULL);
>> > +             ut_assertok(run_commandf("part size mmc %u %d partsize",
>> > +                                      mmc_dev_num, i + 1));
>> > +             snprintf(expected, sizeof(expected), "%lx",
>> > +                      (unsigned long)gpt_parts[i].size);
>> > +             ut_asserteq_str(expected, env_get("partsize"));
>> > +     }
>> > +
>> > +     env_set("partsize", NULL);
>> > +     ut_asserteq(1, run_commandf("part size mmc %u 3 partsize",
>> > +                                 mmc_dev_num));
>> > +     ut_assertnull(env_get("partsize"));
>> > +
>> > +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>> > +             env_set("partsize", NULL);
>> > +             ut_assertok(run_commandf("part size mmc %u %s partsize",
>> > +                                      mmc_dev_num, gpt_parts[i].name));
>> > +             snprintf(expected, sizeof(expected), "%lx",
>> > +                      (unsigned long)gpt_parts[i].size);
>> > +             ut_asserteq_str(expected, env_get("partsize"));
>> > +     }
>> > +
>> > +     env_set("partsize", NULL);
>> > +     ut_asserteq(1, run_commandf("part size mmc %u bogus partsize",
>> > +                                 mmc_dev_num));
>> > +     ut_assertnull(env_get("partsize"));
>> > +
>> > +     return 0;
>> > +}
>> > +CMD_TEST(cmd_test_part_size, UTF_CONSOLE);
>>
>>
>
> --
> *Dario Binacchi*
> Senior Embedded Software Engineer
> M. +39 328 0625246
> dario.binacchi@amarulasolutions.com
> ―――――――――――――――
> Amarula Solutions SRL
>  Via Felice Cavallotti 25D, 41012 Carpi, MO, IT
> info@amarulasolutions.com
> www.amarulasolutions.com
>
Patrice CHOTARD May 12, 2026, 9:45 a.m. UTC | #4
On 5/12/26 09:08, Dario Binacchi wrote:
> Hi everyone,
> 
> I am resending my previous reply because I received a delivery failure
> notification last week indicating that Patrice's mailbox was full.
> 
> Patrice, did you have a chance to verify if the tests are passing fine now?
> Please let me know if everything looks good or if you need
> 
> me to make any further modifications.
> 
> Thanks and regards
> 
> Dario


Hi Dario

My mailbox has been cleaned ;-), i expected to respin this series for test tomorrow or next week.

Thanks
Patrice
> 
> On Tue, May 5, 2026 at 9:55 AM Dario Binacchi <
> dario.binacchi@amarulasolutions.com> wrote:
> 
>> Hi Patrice,
>>
>> On Tue, May 5, 2026 at 9:26 AM Patrice CHOTARD <
>> patrice.chotard@foss.st.com> wrote:
>>
>>>
>>>
>>> On 4/30/26 10:06, Dario Binacchi wrote:
>>>> Add unit tests for the 'part' command, specifically for the 'number',
>>>> 'start', and 'size' subcommands.
>>>>
>>>> These tests establish a baseline for the current partition lookup
>>>> functionality by name. This foundation will be used by subsequent
>>>> patches to extend the command, ensuring consistent behavior as new
>>>> features are introduced.
>>>>
>>>> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
>>>> Reviewed-by: Simon Glass <sjg@chromium.org>
>>>>
>>>> ---
>>>>
>>>> Changes in v8:
>>>> - Skip the test in case the CONFIG_MCC is not enabled or the mmc
>>>>   device is not found.
>>>>
>>>> Changes in v6:
>>>> - Add Reviewed-by of Simon Glass to patch 3/8 "test: cmd: add unit
>>>>   tests for part command"
>>>>
>>>> Changes in v4:
>>>> - Place the part command tests in the cmd suite rather than the dm
>>>>   suite.
>>>> - Order the include files according the U-Boot coding style.
>>>>
>>>> Changes in v3:
>>>> - Wrap the lines exceeding 80 columns
>>>> - Combine run_command() and ut_asserteq() -> ut_asserteq(1, run_command(
>>>>
>>>>  test/cmd/Makefile |   1 +
>>>>  test/cmd/part.c   | 183 ++++++++++++++++++++++++++++++++++++++++++++++
>>>>  2 files changed, 184 insertions(+)
>>>>  create mode 100644 test/cmd/part.c
>>>>
>>>> diff --git a/test/cmd/Makefile b/test/cmd/Makefile
>>>> index 5f2815b1bb65..8d6932f1176c 100644
>>>> --- a/test/cmd/Makefile
>>>> +++ b/test/cmd/Makefile
>>>> @@ -26,6 +26,7 @@ obj-$(CONFIG_CMD_LOADM) += loadm.o
>>>>  obj-$(CONFIG_CMD_MEMINFO) += meminfo.o
>>>>  obj-$(CONFIG_CMD_MEMORY) += mem_copy.o
>>>>  obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o
>>>> +obj-$(CONFIG_CMD_PART) += part.o
>>>>  ifdef CONFIG_CMD_PCI
>>>>  obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o
>>>>  endif
>>>> diff --git a/test/cmd/part.c b/test/cmd/part.c
>>>> new file mode 100644
>>>> index 000000000000..cac57a1a0e35
>>>> --- /dev/null
>>>> +++ b/test/cmd/part.c
>>>> @@ -0,0 +1,183 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +/*
>>>> + * Test for part command
>>>> + *
>>>> + * Copyright (C) 2026 Amarula Solutions
>>>> + * Written by Dario Binacchi <dario.binacchi@amarulasolutions.com>
>>>> + */
>>>> +
>>>> +#include <command.h>
>>>> +#include <dm.h>
>>>> +#include <env.h>
>>>> +#include <part.h>
>>>> +#include <vsprintf.h>
>>>> +#include <dm/test.h>
>>>> +#include <test/cmd.h>
>>>> +#include <test/test.h>
>>>> +#include <test/ut.h>
>>>> +
>>>> +static struct disk_partition gpt_parts[] = {
>>>> +     {
>>>> +             .start = 48,
>>>> +             .size = 1,
>>>> +             .name = "test1",
>>>> +             .uuid = "c5bce7a2-03f0-4d03-9048-01ff23b9d527",
>>>> +     },
>>>> +     {
>>>> +             .start = 49,
>>>> +             .size = 2,
>>>> +             .name = "test2",
>>>> +             .uuid = "9df346e8-2c53-4cd8-b9ac-3af83f9a9b74",
>>>> +     },
>>>> +};
>>>> +
>>>> +static char disk_guid[UUID_STR_LEN + 1] =
>>>> +     "8d60b397-1bb6-4d33-80ee-b1587d24c2f8";
>>>> +
>>>> +static int setup_gpt_partitions(struct unit_test_state *uts,
>>>> +                             unsigned int mmc_dev_num)
>>>> +{
>>>> +     struct blk_desc *mmc_dev_desc;
>>>> +     char dev_str[10];
>>>> +     int i, ret;
>>>> +
>>>> +     if (!CONFIG_IS_ENABLED(MMC))
>>>> +             return -EAGAIN;
>>>
>>> Hi Dario
>>>
>>> Is there any reason to return -EAGAIN ? -ENODEV seems more appropriate ?
>>>
>>
>> In the testing framework, returning -EAGAIN explicitly signals that the
>> test should be skipped*.*
>>
>> As highlighted in the documentation for ut_run_test():
>>
>> *Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1
>> if any failed*
>>
>>
>> Since the necessary preconditions weren't met for some configuration in
>> our case, I decided to skip.
>>
>> Thanks and regards,
>>
>> Dario
>>
>>
>>> Thanks
>>> Patrice
>>>
>>>> +
>>>> +     snprintf(dev_str, sizeof(dev_str), "%u", mmc_dev_num);
>>>> +
>>>> +     ret = blk_get_device_by_str("mmc", dev_str, &mmc_dev_desc);
>>>> +     if (ret == -ENODEV)
>>>> +             return -EAGAIN;
>>>> +
>>>> +     ut_asserteq(mmc_dev_num, ret);
>>>> +
>>>> +     if (CONFIG_IS_ENABLED(RANDOM_UUID)) {
>>>> +             for (i = 0; i < ARRAY_SIZE(gpt_parts); i++)
>>>> +                     gen_rand_uuid_str(gpt_parts[i].uuid,
>>>> +                                       UUID_STR_FORMAT_STD);
>>>> +
>>>> +             gen_rand_uuid_str(disk_guid, UUID_STR_FORMAT_STD);
>>>> +     }
>>>> +
>>>> +     ut_assertok(gpt_restore(mmc_dev_desc, disk_guid, gpt_parts,
>>>> +                             ARRAY_SIZE(gpt_parts)));
>>>> +     return 0;
>>>> +}
>>>> +
>>>> +static int cmd_test_part_number(struct unit_test_state *uts)
>>>> +{
>>>> +     unsigned int mmc_dev_num = 2;
>>>> +     char expected[10];
>>>> +     int i, ret;
>>>> +
>>>> +     ret = setup_gpt_partitions(uts, mmc_dev_num);
>>>> +     if (ret == -EAGAIN)
>>>> +             return ret;
>>>> +
>>>> +     ut_assertok(ret);
>>>> +
>>>> +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>>>> +             env_set("partnum", NULL);
>>>> +             ut_assertok(run_commandf("part number mmc %u %s partnum",
>>>> +                                      mmc_dev_num, gpt_parts[i].name));
>>>> +             snprintf(expected, sizeof(expected), "0x%x", i + 1);
>>>> +             ut_asserteq_str(expected, env_get("partnum"));
>>>> +     }
>>>> +
>>>> +     env_set("partnum", NULL);
>>>> +     ut_asserteq(1, run_commandf("part number mmc %u bogus partnum",
>>>> +                                 mmc_dev_num));
>>>> +     ut_assertnull(env_get("partnum"));
>>>> +
>>>> +     return 0;
>>>> +}
>>>> +CMD_TEST(cmd_test_part_number, UTF_CONSOLE);
>>>> +
>>>> +static int cmd_test_part_start(struct unit_test_state *uts)
>>>> +{
>>>> +     unsigned int mmc_dev_num = 2;
>>>> +     char expected[32];
>>>> +     int i, ret;
>>>> +
>>>> +     ret = setup_gpt_partitions(uts, mmc_dev_num);
>>>> +     if (ret == -EAGAIN)
>>>> +             return ret;
>>>> +
>>>> +     ut_assertok(ret);
>>>> +
>>>> +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>>>> +             env_set("partstart", NULL);
>>>> +             ut_assertok(run_commandf("part start mmc %u %d partstart",
>>>> +                                      mmc_dev_num, i + 1));
>>>> +             snprintf(expected, sizeof(expected), "%lx",
>>>> +                      (unsigned long)gpt_parts[i].start);
>>>> +             ut_asserteq_str(expected, env_get("partstart"));
>>>> +     }
>>>> +
>>>> +     env_set("partstart", NULL);
>>>> +     ut_asserteq(1, run_commandf("part start mmc %u 3 partstart",
>>>> +                                 mmc_dev_num));
>>>> +     ut_assertnull(env_get("partstart"));
>>>> +
>>>> +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>>>> +             env_set("partstart", NULL);
>>>> +             ut_assertok(run_commandf("part start mmc %u %s partstart",
>>>> +                                      mmc_dev_num, gpt_parts[i].name));
>>>> +             snprintf(expected, sizeof(expected), "%lx",
>>>> +                      (unsigned long)gpt_parts[i].start);
>>>> +             ut_asserteq_str(expected, env_get("partstart"));
>>>> +     }
>>>> +
>>>> +     env_set("partstart", NULL);
>>>> +     ut_asserteq(1, run_commandf("part start mmc %u bogus partstart",
>>>> +                                 mmc_dev_num));
>>>> +     ut_assertnull(env_get("partstart"));
>>>> +
>>>> +     return 0;
>>>> +}
>>>> +CMD_TEST(cmd_test_part_start, UTF_CONSOLE);
>>>> +
>>>> +static int cmd_test_part_size(struct unit_test_state *uts)
>>>> +{
>>>> +     unsigned int mmc_dev_num = 2;
>>>> +     char expected[32];
>>>> +     int i, ret;
>>>> +
>>>> +     ret = setup_gpt_partitions(uts, mmc_dev_num);
>>>> +     if (ret == -EAGAIN)
>>>> +             return ret;
>>>> +
>>>> +     ut_assertok(ret);
>>>> +
>>>> +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>>>> +             env_set("partsize", NULL);
>>>> +             ut_assertok(run_commandf("part size mmc %u %d partsize",
>>>> +                                      mmc_dev_num, i + 1));
>>>> +             snprintf(expected, sizeof(expected), "%lx",
>>>> +                      (unsigned long)gpt_parts[i].size);
>>>> +             ut_asserteq_str(expected, env_get("partsize"));
>>>> +     }
>>>> +
>>>> +     env_set("partsize", NULL);
>>>> +     ut_asserteq(1, run_commandf("part size mmc %u 3 partsize",
>>>> +                                 mmc_dev_num));
>>>> +     ut_assertnull(env_get("partsize"));
>>>> +
>>>> +     for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
>>>> +             env_set("partsize", NULL);
>>>> +             ut_assertok(run_commandf("part size mmc %u %s partsize",
>>>> +                                      mmc_dev_num, gpt_parts[i].name));
>>>> +             snprintf(expected, sizeof(expected), "%lx",
>>>> +                      (unsigned long)gpt_parts[i].size);
>>>> +             ut_asserteq_str(expected, env_get("partsize"));
>>>> +     }
>>>> +
>>>> +     env_set("partsize", NULL);
>>>> +     ut_asserteq(1, run_commandf("part size mmc %u bogus partsize",
>>>> +                                 mmc_dev_num));
>>>> +     ut_assertnull(env_get("partsize"));
>>>> +
>>>> +     return 0;
>>>> +}
>>>> +CMD_TEST(cmd_test_part_size, UTF_CONSOLE);
>>>
>>>
>>
>> --
>> *Dario Binacchi*
>> Senior Embedded Software Engineer
>> M. +39 328 0625246
>> dario.binacchi@amarulasolutions.com
>> ―――――――――――――――
>> Amarula Solutions SRL
>>  Via Felice Cavallotti 25D, 41012 Carpi, MO, IT
>> info@amarulasolutions.com
>> www.amarulasolutions.com
>>
> 
> 

To unsubscribe from this group and stop receiving emails from it, send an email to linux-amarula+unsubscribe@amarulasolutions.com.

Patch

diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index 5f2815b1bb65..8d6932f1176c 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -26,6 +26,7 @@  obj-$(CONFIG_CMD_LOADM) += loadm.o
 obj-$(CONFIG_CMD_MEMINFO) += meminfo.o
 obj-$(CONFIG_CMD_MEMORY) += mem_copy.o
 obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o
+obj-$(CONFIG_CMD_PART) += part.o
 ifdef CONFIG_CMD_PCI
 obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o
 endif
diff --git a/test/cmd/part.c b/test/cmd/part.c
new file mode 100644
index 000000000000..cac57a1a0e35
--- /dev/null
+++ b/test/cmd/part.c
@@ -0,0 +1,183 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for part command
+ *
+ * Copyright (C) 2026 Amarula Solutions
+ * Written by Dario Binacchi <dario.binacchi@amarulasolutions.com>
+ */
+
+#include <command.h>
+#include <dm.h>
+#include <env.h>
+#include <part.h>
+#include <vsprintf.h>
+#include <dm/test.h>
+#include <test/cmd.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static struct disk_partition gpt_parts[] = {
+	{
+		.start = 48,
+		.size = 1,
+		.name = "test1",
+		.uuid = "c5bce7a2-03f0-4d03-9048-01ff23b9d527",
+	},
+	{
+		.start = 49,
+		.size = 2,
+		.name = "test2",
+		.uuid = "9df346e8-2c53-4cd8-b9ac-3af83f9a9b74",
+	},
+};
+
+static char disk_guid[UUID_STR_LEN + 1] =
+	"8d60b397-1bb6-4d33-80ee-b1587d24c2f8";
+
+static int setup_gpt_partitions(struct unit_test_state *uts,
+				unsigned int mmc_dev_num)
+{
+	struct blk_desc *mmc_dev_desc;
+	char dev_str[10];
+	int i, ret;
+
+	if (!CONFIG_IS_ENABLED(MMC))
+		return -EAGAIN;
+
+	snprintf(dev_str, sizeof(dev_str), "%u", mmc_dev_num);
+
+	ret = blk_get_device_by_str("mmc", dev_str, &mmc_dev_desc);
+	if (ret == -ENODEV)
+		return -EAGAIN;
+
+	ut_asserteq(mmc_dev_num, ret);
+
+	if (CONFIG_IS_ENABLED(RANDOM_UUID)) {
+		for (i = 0; i < ARRAY_SIZE(gpt_parts); i++)
+			gen_rand_uuid_str(gpt_parts[i].uuid,
+					  UUID_STR_FORMAT_STD);
+
+		gen_rand_uuid_str(disk_guid, UUID_STR_FORMAT_STD);
+	}
+
+	ut_assertok(gpt_restore(mmc_dev_desc, disk_guid, gpt_parts,
+				ARRAY_SIZE(gpt_parts)));
+	return 0;
+}
+
+static int cmd_test_part_number(struct unit_test_state *uts)
+{
+	unsigned int mmc_dev_num = 2;
+	char expected[10];
+	int i, ret;
+
+	ret = setup_gpt_partitions(uts, mmc_dev_num);
+	if (ret == -EAGAIN)
+		return ret;
+
+	ut_assertok(ret);
+
+	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
+		env_set("partnum", NULL);
+		ut_assertok(run_commandf("part number mmc %u %s partnum",
+					 mmc_dev_num, gpt_parts[i].name));
+		snprintf(expected, sizeof(expected), "0x%x", i + 1);
+		ut_asserteq_str(expected, env_get("partnum"));
+	}
+
+	env_set("partnum", NULL);
+	ut_asserteq(1, run_commandf("part number mmc %u bogus partnum",
+				    mmc_dev_num));
+	ut_assertnull(env_get("partnum"));
+
+	return 0;
+}
+CMD_TEST(cmd_test_part_number, UTF_CONSOLE);
+
+static int cmd_test_part_start(struct unit_test_state *uts)
+{
+	unsigned int mmc_dev_num = 2;
+	char expected[32];
+	int i, ret;
+
+	ret = setup_gpt_partitions(uts, mmc_dev_num);
+	if (ret == -EAGAIN)
+		return ret;
+
+	ut_assertok(ret);
+
+	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
+		env_set("partstart", NULL);
+		ut_assertok(run_commandf("part start mmc %u %d partstart",
+					 mmc_dev_num, i + 1));
+		snprintf(expected, sizeof(expected), "%lx",
+			 (unsigned long)gpt_parts[i].start);
+		ut_asserteq_str(expected, env_get("partstart"));
+	}
+
+	env_set("partstart", NULL);
+	ut_asserteq(1, run_commandf("part start mmc %u 3 partstart",
+				    mmc_dev_num));
+	ut_assertnull(env_get("partstart"));
+
+	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
+		env_set("partstart", NULL);
+		ut_assertok(run_commandf("part start mmc %u %s partstart",
+					 mmc_dev_num, gpt_parts[i].name));
+		snprintf(expected, sizeof(expected), "%lx",
+			 (unsigned long)gpt_parts[i].start);
+		ut_asserteq_str(expected, env_get("partstart"));
+	}
+
+	env_set("partstart", NULL);
+	ut_asserteq(1, run_commandf("part start mmc %u bogus partstart",
+				    mmc_dev_num));
+	ut_assertnull(env_get("partstart"));
+
+	return 0;
+}
+CMD_TEST(cmd_test_part_start, UTF_CONSOLE);
+
+static int cmd_test_part_size(struct unit_test_state *uts)
+{
+	unsigned int mmc_dev_num = 2;
+	char expected[32];
+	int i, ret;
+
+	ret = setup_gpt_partitions(uts, mmc_dev_num);
+	if (ret == -EAGAIN)
+		return ret;
+
+	ut_assertok(ret);
+
+	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
+		env_set("partsize", NULL);
+		ut_assertok(run_commandf("part size mmc %u %d partsize",
+					 mmc_dev_num, i + 1));
+		snprintf(expected, sizeof(expected), "%lx",
+			 (unsigned long)gpt_parts[i].size);
+		ut_asserteq_str(expected, env_get("partsize"));
+	}
+
+	env_set("partsize", NULL);
+	ut_asserteq(1, run_commandf("part size mmc %u 3 partsize",
+				    mmc_dev_num));
+	ut_assertnull(env_get("partsize"));
+
+	for (i = 0; i < ARRAY_SIZE(gpt_parts); i++) {
+		env_set("partsize", NULL);
+		ut_assertok(run_commandf("part size mmc %u %s partsize",
+					 mmc_dev_num, gpt_parts[i].name));
+		snprintf(expected, sizeof(expected), "%lx",
+			 (unsigned long)gpt_parts[i].size);
+		ut_asserteq_str(expected, env_get("partsize"));
+	}
+
+	env_set("partsize", NULL);
+	ut_asserteq(1, run_commandf("part size mmc %u bogus partsize",
+				    mmc_dev_num));
+	ut_assertnull(env_get("partsize"));
+
+	return 0;
+}
+CMD_TEST(cmd_test_part_size, UTF_CONSOLE);