diff mbox series

kselftest/alsa: Use card name rather than number in test names

Message ID 20240711-alsa-kselftest-board-name-v1-1-ab5cf2dbbea6@kernel.org (mailing list archive)
State New, archived
Headers show
Series kselftest/alsa: Use card name rather than number in test names | expand

Commit Message

Mark Brown July 11, 2024, 2:33 p.m. UTC
Currently for the PCM and mixer tests we report test names which identify
the card being tested with the card number. This ensures we have unique
names but since card numbers are dynamically assigned at runtime the names
we end up with will often not be stable on systems with multiple cards
especially where those cards are provided by separate modules loeaded at
runtime. This makes it difficult for automated systems and UIs to relate
test results between runs on affected platforms.

Address this by replacing our use of card numbers with card names which are
more likely to be stable across runs. We use the long name since in the
case where we have two of the same card it is more likely to include
deduplication information (eg, HDA cards include the address/IRQ). The
resulting information is not the most beautiful for human readers but the
majority of kselftest output consumption is automated systems and it wasn't
that great anyway.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 tools/testing/selftests/alsa/mixer-test.c | 76 ++++++++++++++++---------------
 tools/testing/selftests/alsa/pcm-test.c   | 35 ++++++++------
 2 files changed, 60 insertions(+), 51 deletions(-)


---
base-commit: f2661062f16b2de5d7b6a5c42a9a5c96326b8454
change-id: 20240711-alsa-kselftest-board-name-e4a1add4cfa0

Best regards,

Comments

Jaroslav Kysela July 11, 2024, 4:08 p.m. UTC | #1
On 11. 07. 24 16:33, Mark Brown wrote:
> Currently for the PCM and mixer tests we report test names which identify
> the card being tested with the card number. This ensures we have unique
> names but since card numbers are dynamically assigned at runtime the names
> we end up with will often not be stable on systems with multiple cards
> especially where those cards are provided by separate modules loeaded at
> runtime. This makes it difficult for automated systems and UIs to relate
> test results between runs on affected platforms.
> 
> Address this by replacing our use of card numbers with card names which are
> more likely to be stable across runs. We use the long name since in the
> case where we have two of the same card it is more likely to include
> deduplication information (eg, HDA cards include the address/IRQ). The
> resulting information is not the most beautiful for human readers but the
> majority of kselftest output consumption is automated systems and it wasn't
> that great anyway.
> 
> Signed-off-by: Mark Brown <broonie@kernel.org>

I think that a combination of card number and card ID may be sufficient (and a 
compromise). It's shorter and user-friendly. Additionally, a table may be 
printed at the beginning of report with card number, card ID and long card 
name for further processing and identification.

					Jaroslav
Mark Brown July 11, 2024, 4:19 p.m. UTC | #2
On Thu, Jul 11, 2024 at 06:08:38PM +0200, Jaroslav Kysela wrote:
> On 11. 07. 24 16:33, Mark Brown wrote:

> > Address this by replacing our use of card numbers with card names which are
> > more likely to be stable across runs. We use the long name since in the

> I think that a combination of card number and card ID may be sufficient (and
> a compromise). It's shorter and user-friendly. Additionally, a table may be
> printed at the beginning of report with card number, card ID and long card
> name for further processing and identification.

These don't help, the problem is that anything which includes the card
number in the test name result is going to result in unstable test names
depending on race conditions at boot.  There are automated systems that
parse kselftest output generically, I'm not sure there's a great deal of
enthusiasm for writing a custom parser for the ALSA selftests
specifically.
Takashi Iwai July 12, 2024, 8:21 a.m. UTC | #3
On Thu, 11 Jul 2024 18:19:25 +0200,
Mark Brown wrote:
> 
> On Thu, Jul 11, 2024 at 06:08:38PM +0200, Jaroslav Kysela wrote:
> > On 11. 07. 24 16:33, Mark Brown wrote:
> 
> > > Address this by replacing our use of card numbers with card names which are
> > > more likely to be stable across runs. We use the long name since in the
> 
> > I think that a combination of card number and card ID may be sufficient (and
> > a compromise). It's shorter and user-friendly. Additionally, a table may be
> > printed at the beginning of report with card number, card ID and long card
> > name for further processing and identification.
> 
> These don't help, the problem is that anything which includes the card
> number in the test name result is going to result in unstable test names
> depending on race conditions at boot.  There are automated systems that
> parse kselftest output generically, I'm not sure there's a great deal of
> enthusiasm for writing a custom parser for the ALSA selftests
> specifically.

OTOH, longname can be really ugly to read, and it can vary because it
often embeds address or irq numbers in the string.

If a general name is the goal, how about using shortname instead?

Or use id field, as Jaroslav suggested, but without the card number
suffix; then it's unique among multiple cards.


thanks,

Takashi
Jaroslav Kysela July 12, 2024, 9:20 a.m. UTC | #4
On 12. 07. 24 10:21, Takashi Iwai wrote:
> On Thu, 11 Jul 2024 18:19:25 +0200,
> Mark Brown wrote:
>>
>> On Thu, Jul 11, 2024 at 06:08:38PM +0200, Jaroslav Kysela wrote:
>>> On 11. 07. 24 16:33, Mark Brown wrote:
>>
>>>> Address this by replacing our use of card numbers with card names which are
>>>> more likely to be stable across runs. We use the long name since in the
>>
>>> I think that a combination of card number and card ID may be sufficient (and
>>> a compromise). It's shorter and user-friendly. Additionally, a table may be
>>> printed at the beginning of report with card number, card ID and long card
>>> name for further processing and identification.
>>
>> These don't help, the problem is that anything which includes the card
>> number in the test name result is going to result in unstable test names
>> depending on race conditions at boot.  There are automated systems that
>> parse kselftest output generically, I'm not sure there's a great deal of
>> enthusiasm for writing a custom parser for the ALSA selftests
>> specifically.
> 
> OTOH, longname can be really ugly to read, and it can vary because it
> often embeds address or irq numbers in the string.
> 
> If a general name is the goal, how about using shortname instead?
> 
> Or use id field, as Jaroslav suggested, but without the card number
> suffix; then it's unique among multiple cards.

I prefer this (use only ID field). This string can be also set in the user 
space using sysfs/udev, so the administrator may change it if the default is 
not ideal.

					Jaroslav
Mark Brown July 12, 2024, 1 p.m. UTC | #5
On Fri, Jul 12, 2024 at 11:20:05AM +0200, Jaroslav Kysela wrote:
> On 12. 07. 24 10:21, Takashi Iwai wrote:

> > OTOH, longname can be really ugly to read, and it can vary because it
> > often embeds address or irq numbers in the string.

Capturing that variation is one of the goals - it should mostly be
stable between runs.

> > If a general name is the goal, how about using shortname instead?

> > Or use id field, as Jaroslav suggested, but without the card number
> > suffix; then it's unique among multiple cards.

> I prefer this (use only ID field). This string can be also set in the user
> space using sysfs/udev, so the administrator may change it if the default is
> not ideal.

The trouble with the ID field is that it's too short and seems likely to
create collisions, for example HDA stuff just seems to default to NVidia
for nVidia cards which seems very likely to create collisions if someone
has two graphics cards in their system.
Jaroslav Kysela July 12, 2024, 4:25 p.m. UTC | #6
On 12. 07. 24 15:00, Mark Brown wrote:
> On Fri, Jul 12, 2024 at 11:20:05AM +0200, Jaroslav Kysela wrote:
>> On 12. 07. 24 10:21, Takashi Iwai wrote:
> 
>>> OTOH, longname can be really ugly to read, and it can vary because it
>>> often embeds address or irq numbers in the string.
> 
> Capturing that variation is one of the goals - it should mostly be
> stable between runs.
> 
>>> If a general name is the goal, how about using shortname instead?
> 
>>> Or use id field, as Jaroslav suggested, but without the card number
>>> suffix; then it's unique among multiple cards.
> 
>> I prefer this (use only ID field). This string can be also set in the user
>> space using sysfs/udev, so the administrator may change it if the default is
>> not ideal.
> 
> The trouble with the ID field is that it's too short and seems likely to
> create collisions, for example HDA stuff just seems to default to NVidia
> for nVidia cards which seems very likely to create collisions if someone
> has two graphics cards in their system.

The default IDs are always unique - see snd_card_set_id_no_lock() in 
sound/core/init.c . Basically, the suffix will follow the device probe order 
in this case.

				Jaroslav
Mark Brown July 12, 2024, 6:19 p.m. UTC | #7
On Fri, Jul 12, 2024 at 06:25:21PM +0200, Jaroslav Kysela wrote:
> On 12. 07. 24 15:00, Mark Brown wrote:

> > The trouble with the ID field is that it's too short and seems likely to
> > create collisions, for example HDA stuff just seems to default to NVidia
> > for nVidia cards which seems very likely to create collisions if someone
> > has two graphics cards in their system.

> The default IDs are always unique - see snd_card_set_id_no_lock() in
> sound/core/init.c . Basically, the suffix will follow the device probe order
> in this case.

Sure, but the genesis of this patch is that probe order isn't
sufficiently stable and we want to avoid names based on it...  using the
ID will be more likely to work out stable than just pure probe order but
it's still got the same issue.
Takashi Iwai July 13, 2024, 6:46 a.m. UTC | #8
On Fri, 12 Jul 2024 20:19:33 +0200,
Mark Brown wrote:
> 
> On Fri, Jul 12, 2024 at 06:25:21PM +0200, Jaroslav Kysela wrote:
> > On 12. 07. 24 15:00, Mark Brown wrote:
> 
> > > The trouble with the ID field is that it's too short and seems likely to
> > > create collisions, for example HDA stuff just seems to default to NVidia
> > > for nVidia cards which seems very likely to create collisions if someone
> > > has two graphics cards in their system.
> 
> > The default IDs are always unique - see snd_card_set_id_no_lock() in
> > sound/core/init.c . Basically, the suffix will follow the device probe order
> > in this case.
> 
> Sure, but the genesis of this patch is that probe order isn't
> sufficiently stable and we want to avoid names based on it...  using the
> ID will be more likely to work out stable than just pure probe order but
> it's still got the same issue.

Are you trying to solve the issue with two cards of the same driver,
which are swapped sometimes at the probe time?  Or the mixture of
different cards that are swapped?

In the latter case, id should work well.  The id is primarily created
from the (short)name string, and the suffix is added only when
conflicting.

OTOH, if the former is the problem, using longname won't help,
either, rather it can be confusing.  I noticed that the test output
truncates the name string, hence both cards look identical in the
actual output (except for the card listing at the beginning).


Takashi
Jaroslav Kysela July 13, 2024, 7:35 a.m. UTC | #9
On 12. 07. 24 20:19, Mark Brown wrote:
> On Fri, Jul 12, 2024 at 06:25:21PM +0200, Jaroslav Kysela wrote:
>> On 12. 07. 24 15:00, Mark Brown wrote:
> 
>>> The trouble with the ID field is that it's too short and seems likely to
>>> create collisions, for example HDA stuff just seems to default to NVidia
>>> for nVidia cards which seems very likely to create collisions if someone
>>> has two graphics cards in their system.
> 
>> The default IDs are always unique - see snd_card_set_id_no_lock() in
>> sound/core/init.c . Basically, the suffix will follow the device probe order
>> in this case.
> 
> Sure, but the genesis of this patch is that probe order isn't
> sufficiently stable and we want to avoid names based on it...  using the
> ID will be more likely to work out stable than just pure probe order but
> it's still got the same issue.

The probe order is almost stable for the drivers with the non-deferred probe. 
Also, administrators may set persistent ID for complex hardware configuration 
cases based on other keys like serial number or so (sysfs/udev).

For long name - the device path may change (USB moved to different port, PCI 
card moved to different slot), so the stability of this string is also 
questionable.

					Jaroslav
Mark Brown July 15, 2024, 12:48 p.m. UTC | #10
On Sat, Jul 13, 2024 at 09:35:36AM +0200, Jaroslav Kysela wrote:
> On 12. 07. 24 20:19, Mark Brown wrote:

> > Sure, but the genesis of this patch is that probe order isn't
> > sufficiently stable and we want to avoid names based on it...  using the
> > ID will be more likely to work out stable than just pure probe order but
> > it's still got the same issue.

> The probe order is almost stable for the drivers with the non-deferred
> probe. Also, administrators may set persistent ID for complex hardware

It's not very stable for modules being loaded, there's enough going on
and enough module loads happening simultaneously that it's very easy for
drivers to come up in different orders.  I'm seeing these issues quite
frequently in my test farm.

> configuration cases based on other keys like serial number or so
> (sysfs/udev).

For a lot of test scenarios that's just not really relevant - with a
pool of machines any per machine keys get hard to manage, and for
something like kernelci.org customising the rootfs for even classes of
boards never mind specific boards is going to be an unreasonable ask.

> For long name - the device path may change (USB moved to different port, PCI
> card moved to different slot), so the stability of this string is also
> questionable.

The concern here is repeated boots on the same system in an automated
context, if someone changes the hardware then it's reasonable that the
set of cards would change.
Mark Brown July 15, 2024, 1:18 p.m. UTC | #11
On Sat, Jul 13, 2024 at 08:46:43AM +0200, Takashi Iwai wrote:
> Mark Brown wrote:

> > Sure, but the genesis of this patch is that probe order isn't
> > sufficiently stable and we want to avoid names based on it...  using the
> > ID will be more likely to work out stable than just pure probe order but
> > it's still got the same issue.

> Are you trying to solve the issue with two cards of the same driver,
> which are swapped sometimes at the probe time?  Or the mixture of
> different cards that are swapped?

The one I'm running into personally is due to the load order of the
sound card drivers themselves, but it seems good to try to address the
issue in general especially with ASoC where you're waiting for multiple
drivers for individual components in the card.  That means that even for
a single driver the ordering might not be stable.

> In the latter case, id should work well.  The id is primarily created
> from the (short)name string, and the suffix is added only when
> conflicting.

Yeah, it's more stable but there's still a potential issue.

> OTOH, if the former is the problem, using longname won't help,
> either, rather it can be confusing.  I noticed that the test output
> truncates the name string, hence both cards look identical in the
> actual output (except for the card listing at the beginning).

Interesting - I was mainly developing on a system with multiple HDA
cards and was getting fairly clearly unique names.
Takashi Iwai July 15, 2024, 1:23 p.m. UTC | #12
On Mon, 15 Jul 2024 15:18:44 +0200,
Mark Brown wrote:
> 
> On Sat, Jul 13, 2024 at 08:46:43AM +0200, Takashi Iwai wrote:
> > Mark Brown wrote:
> 
> > OTOH, if the former is the problem, using longname won't help,
> > either, rather it can be confusing.  I noticed that the test output
> > truncates the name string, hence both cards look identical in the
> > actual output (except for the card listing at the beginning).
> 
> Interesting - I was mainly developing on a system with multiple HDA
> cards and was getting fairly clearly unique names.

An AMD system usually has two HD-audio entries, and both are "HD-audio
Generic".


Takashi
Mark Brown July 15, 2024, 5:31 p.m. UTC | #13
On Mon, Jul 15, 2024 at 03:23:24PM +0200, Takashi Iwai wrote:
> Mark Brown wrote:

> > Interesting - I was mainly developing on a system with multiple HDA
> > cards and was getting fairly clearly unique names.

> An AMD system usually has two HD-audio entries, and both are "HD-audio
> Generic".

Right, that won't do.  My legacy system here is getting the addresses in
there so deduplicates successfully.
diff mbox series

Patch

diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c
index 1c04e5f638a0..df9ae3b4e2df 100644
--- a/tools/testing/selftests/alsa/mixer-test.c
+++ b/tools/testing/selftests/alsa/mixer-test.c
@@ -33,6 +33,7 @@ 
 struct card_data {
 	snd_ctl_t *handle;
 	int card;
+	const char *card_name;
 	struct pollfd pollfd;
 	int num_ctls;
 	snd_ctl_elem_list_t *ctls;
@@ -91,6 +92,7 @@  static void find_controls(void)
 		err = snd_card_get_longname(card, &card_longname);
 		if (err != 0)
 			card_longname = "Unknown";
+		card_data->card_name = card_longname;
 		ksft_print_msg("Card %d - %s (%s)\n", card,
 			       card_name, card_longname);
 
@@ -389,16 +391,16 @@  static void test_ctl_get_value(struct ctl_data *ctl)
 	/* If the control is turned off let's be polite */
 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
 		ksft_print_msg("%s is inactive\n", ctl->name);
-		ksft_test_result_skip("get_value.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("get_value.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
 	/* Can't test reading on an unreadable control */
 	if (!snd_ctl_elem_info_is_readable(ctl->info)) {
 		ksft_print_msg("%s is not readable\n", ctl->name);
-		ksft_test_result_skip("get_value.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("get_value.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
@@ -413,8 +415,8 @@  static void test_ctl_get_value(struct ctl_data *ctl)
 		err = -EINVAL;
 
 out:
-	ksft_test_result(err >= 0, "get_value.%d.%d\n",
-			 ctl->card->card, ctl->elem);
+	ksft_test_result(err >= 0, "get_value.%s.%d\n",
+			 ctl->card->card_name, ctl->elem);
 }
 
 static bool strend(const char *haystack, const char *needle)
@@ -431,7 +433,7 @@  static void test_ctl_name(struct ctl_data *ctl)
 {
 	bool name_ok = true;
 
-	ksft_print_msg("%d.%d %s\n", ctl->card->card, ctl->elem,
+	ksft_print_msg("%s.%d %s\n", ctl->card->card_name, ctl->elem,
 		       ctl->name);
 
 	/* Only boolean controls should end in Switch */
@@ -453,8 +455,8 @@  static void test_ctl_name(struct ctl_data *ctl)
 		}
 	}
 
-	ksft_test_result(name_ok, "name.%d.%d\n",
-			 ctl->card->card, ctl->elem);
+	ksft_test_result(name_ok, "name.%s.%d\n",
+			 ctl->card->card_name, ctl->elem);
 }
 
 static void show_values(struct ctl_data *ctl, snd_ctl_elem_value_t *orig_val,
@@ -682,30 +684,30 @@  static void test_ctl_write_default(struct ctl_data *ctl)
 	/* If the control is turned off let's be polite */
 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
 		ksft_print_msg("%s is inactive\n", ctl->name);
-		ksft_test_result_skip("write_default.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("write_default.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
 		ksft_print_msg("%s is not writeable\n", ctl->name);
-		ksft_test_result_skip("write_default.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("write_default.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
 	/* No idea what the default was for unreadable controls */
 	if (!snd_ctl_elem_info_is_readable(ctl->info)) {
 		ksft_print_msg("%s couldn't read default\n", ctl->name);
-		ksft_test_result_skip("write_default.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("write_default.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
 	err = write_and_verify(ctl, ctl->def_val, NULL);
 
-	ksft_test_result(err >= 0, "write_default.%d.%d\n",
-			 ctl->card->card, ctl->elem);
+	ksft_test_result(err >= 0, "write_default.%s.%d\n",
+			 ctl->card->card_name, ctl->elem);
 }
 
 static bool test_ctl_write_valid_boolean(struct ctl_data *ctl)
@@ -815,15 +817,15 @@  static void test_ctl_write_valid(struct ctl_data *ctl)
 	/* If the control is turned off let's be polite */
 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
 		ksft_print_msg("%s is inactive\n", ctl->name);
-		ksft_test_result_skip("write_valid.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("write_valid.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
 		ksft_print_msg("%s is not writeable\n", ctl->name);
-		ksft_test_result_skip("write_valid.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("write_valid.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
@@ -846,16 +848,16 @@  static void test_ctl_write_valid(struct ctl_data *ctl)
 
 	default:
 		/* No tests for this yet */
-		ksft_test_result_skip("write_valid.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("write_valid.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
 	/* Restore the default value to minimise disruption */
 	write_and_verify(ctl, ctl->def_val, NULL);
 
-	ksft_test_result(pass, "write_valid.%d.%d\n",
-			 ctl->card->card, ctl->elem);
+	ksft_test_result(pass, "write_valid.%s.%d\n",
+			 ctl->card->card_name, ctl->elem);
 }
 
 static bool test_ctl_write_invalid_value(struct ctl_data *ctl,
@@ -1027,15 +1029,15 @@  static void test_ctl_write_invalid(struct ctl_data *ctl)
 	/* If the control is turned off let's be polite */
 	if (snd_ctl_elem_info_is_inactive(ctl->info)) {
 		ksft_print_msg("%s is inactive\n", ctl->name);
-		ksft_test_result_skip("write_invalid.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("write_invalid.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
 	if (!snd_ctl_elem_info_is_writable(ctl->info)) {
 		ksft_print_msg("%s is not writeable\n", ctl->name);
-		ksft_test_result_skip("write_invalid.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("write_invalid.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
@@ -1058,28 +1060,28 @@  static void test_ctl_write_invalid(struct ctl_data *ctl)
 
 	default:
 		/* No tests for this yet */
-		ksft_test_result_skip("write_invalid.%d.%d\n",
-				      ctl->card->card, ctl->elem);
+		ksft_test_result_skip("write_invalid.%s.%d\n",
+				      ctl->card->card_name, ctl->elem);
 		return;
 	}
 
 	/* Restore the default value to minimise disruption */
 	write_and_verify(ctl, ctl->def_val, NULL);
 
-	ksft_test_result(pass, "write_invalid.%d.%d\n",
-			 ctl->card->card, ctl->elem);
+	ksft_test_result(pass, "write_invalid.%s.%d\n",
+			 ctl->card->card_name, ctl->elem);
 }
 
 static void test_ctl_event_missing(struct ctl_data *ctl)
 {
-	ksft_test_result(!ctl->event_missing, "event_missing.%d.%d\n",
-			 ctl->card->card, ctl->elem);
+	ksft_test_result(!ctl->event_missing, "event_missing.%s.%d\n",
+			 ctl->card->card_name, ctl->elem);
 }
 
 static void test_ctl_event_spurious(struct ctl_data *ctl)
 {
-	ksft_test_result(!ctl->event_spurious, "event_spurious.%d.%d\n",
-			 ctl->card->card, ctl->elem);
+	ksft_test_result(!ctl->event_spurious, "event_spurious.%s.%d\n",
+			 ctl->card->card_name, ctl->elem);
 }
 
 int main(void)
diff --git a/tools/testing/selftests/alsa/pcm-test.c b/tools/testing/selftests/alsa/pcm-test.c
index de664dedb541..a7b1e6e876c5 100644
--- a/tools/testing/selftests/alsa/pcm-test.c
+++ b/tools/testing/selftests/alsa/pcm-test.c
@@ -24,6 +24,7 @@  typedef struct timespec timestamp_t;
 
 struct card_data {
 	int card;
+	const char *name;
 	pthread_t thread;
 	struct card_data *next;
 };
@@ -35,6 +36,7 @@  struct pcm_data {
 	int card;
 	int device;
 	int subdevice;
+	const char *card_name;
 	snd_pcm_stream_t stream;
 	snd_config_t *pcm_config;
 	struct pcm_data *next;
@@ -191,6 +193,7 @@  static void find_pcms(void)
 		if (!card_data)
 			ksft_exit_fail_msg("Out of memory\n");
 		card_data->card = card;
+		card_data->name = card_longname;
 		card_data->next = card_list;
 		card_list = card_data;
 
@@ -232,6 +235,7 @@  static void find_pcms(void)
 					pcm_data->card = card;
 					pcm_data->device = dev;
 					pcm_data->subdevice = subdev;
+					pcm_data->card_name = card_name;
 					pcm_data->stream = stream;
 					pcm_data->pcm_config = conf_get_subtree(card_config, key, NULL);
 					pcm_data->next = pcm_list;
@@ -294,9 +298,9 @@  static void test_pcm_time(struct pcm_data *data, enum test_class class,
 
 	desc = conf_get_string(pcm_cfg, "description", NULL, NULL);
 	if (desc)
-		ksft_print_msg("%s.%s.%d.%d.%d.%s - %s\n",
+		ksft_print_msg("%s.%s.%s.%d.%d.%s - %s\n",
 			       test_class_name, test_name,
-			       data->card, data->device, data->subdevice,
+			       data->card_name, data->device, data->subdevice,
 			       snd_pcm_stream_name(data->stream),
 			       desc);
 
@@ -352,9 +356,9 @@  static void test_pcm_time(struct pcm_data *data, enum test_class class,
 			old_format = format;
 			format = snd_pcm_format_value(alt_formats[i]);
 			if (format != SND_PCM_FORMAT_UNKNOWN) {
-				ksft_print_msg("%s.%d.%d.%d.%s.%s format %s -> %s\n",
+				ksft_print_msg("%s.%s.%d.%d.%s.%s format %s -> %s\n",
 						 test_name,
-						 data->card, data->device, data->subdevice,
+						 data->card_name, data->device, data->subdevice,
 						 snd_pcm_stream_name(data->stream),
 						 snd_pcm_access_name(access),
 						 snd_pcm_format_name(old_format),
@@ -430,9 +434,9 @@  static void test_pcm_time(struct pcm_data *data, enum test_class class,
 		goto __close;
 	}
 
-	ksft_print_msg("%s.%s.%d.%d.%d.%s hw_params.%s.%s.%ld.%ld.%ld.%ld sw_params.%ld\n",
+	ksft_print_msg("%s.%s.%s.%d.%d.%s hw_params.%s.%s.%ld.%ld.%ld.%ld sw_params.%ld\n",
 		         test_class_name, test_name,
-			 data->card, data->device, data->subdevice,
+			 data->card_name, data->device, data->subdevice,
 			 snd_pcm_stream_name(data->stream),
 			 snd_pcm_access_name(access),
 			 snd_pcm_format_name(format),
@@ -491,9 +495,10 @@  static void test_pcm_time(struct pcm_data *data, enum test_class class,
 		 * Anything specified as specific to this system
 		 * should always be supported.
 		 */
-		ksft_test_result(!skip, "%s.%s.%d.%d.%d.%s.params\n",
+		ksft_test_result(!skip, "%s.%s.%s.%d.%d.%s.params\n",
 				 test_class_name, test_name,
-				 data->card, data->device, data->subdevice,
+				 data->card_name, data->device,
+				 data->subdevice,
 				 snd_pcm_stream_name(data->stream));
 		break;
 	default:
@@ -501,14 +506,16 @@  static void test_pcm_time(struct pcm_data *data, enum test_class class,
 	}
 
 	if (!skip)
-		ksft_test_result(pass, "%s.%s.%d.%d.%d.%s\n",
+		ksft_test_result(pass, "%s.%s.%s.%d.%d.%s\n",
 				 test_class_name, test_name,
-				 data->card, data->device, data->subdevice,
+				 data->card_name, data->device,
+				 data->subdevice,
 				 snd_pcm_stream_name(data->stream));
 	else
-		ksft_test_result_skip("%s.%s.%d.%d.%d.%s\n",
+		ksft_test_result_skip("%s.%s.%s.%d.%d.%s\n",
 				 test_class_name, test_name,
-				 data->card, data->device, data->subdevice,
+				 data->card_name, data->device,
+				 data->subdevice,
 				 snd_pcm_stream_name(data->stream));
 
 	if (msg[0])
@@ -609,8 +616,8 @@  int main(void)
 					      conf->filename, conf->config_id);
 
 	for (pcm = pcm_missing; pcm != NULL; pcm = pcm->next) {
-		ksft_test_result(false, "test.missing.%d.%d.%d.%s\n",
-				 pcm->card, pcm->device, pcm->subdevice,
+		ksft_test_result(false, "test.missing.%s.%d.%d.%s\n",
+				 pcm->card_name, pcm->device, pcm->subdevice,
 				 snd_pcm_stream_name(pcm->stream));
 	}