Skip to content

Add full_testcase_name parameter#4333

Closed
nickzhq wants to merge 1 commit intoavocado-framework:masterfrom
nickzhq:keep_at_default
Closed

Add full_testcase_name parameter#4333
nickzhq wants to merge 1 commit intoavocado-framework:masterfrom
nickzhq:keep_at_default

Conversation

@nickzhq
Copy link
Copy Markdown
Contributor

@nickzhq nickzhq commented Mar 6, 2026

ID: KVMAUTOMA-5109

@nickzhq nickzhq marked this pull request as draft March 6, 2026 08:29
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the avocado-vt framework by providing a new option to control the naming convention of test variants. It allows for the explicit inclusion of @-prefixed variants in generated short names, offering greater flexibility and clarity in test identification. This change involves adding a new command-line argument and a corresponding configuration setting, which are then integrated into the core parsing logic.

Highlights

  • New Command-Line Option: Introduced a new command-line option, --vt-keep-at-variants-in-shortnames, which allows users to preserve @-prefixed variants (e.g., @default) in test short names when --vt-short-names-when-config is also enabled.
  • New Configuration Setting: Added a corresponding configuration setting, vt.keep_at_variants_in_shortnames, to allow for persistent control over the preservation of @-prefixed variants in short names.
  • Cartesian Config Parser Enhancement: Modified the cartesian_config.Parser to accept and utilize the new keep_at_variants_in_shortnames flag, directly influencing the logic for generating test variant short names.
Changelog
  • avocado_vt/options.py
    • Passed the vt.keep_at_variants_in_shortnames configuration value to the cartesian_config.Parser constructor.
  • avocado_vt/plugins/vt.py
    • Added the --vt-keep-at-variants-in-shortnames command-line option with its help message.
  • avocado_vt/plugins/vt_init.py
    • Registered the keep_at_variants_in_shortnames boolean setting with a default value of False.
  • virttest/cartesian_config.py
    • Modified the Parser's __init__ method to accept a keep_at_variants_in_shortnames argument.
    • Updated the _parse method to conditionally set append_to_shortname based on the new keep_at_variants_in_shortnames flag.
Activity
  • No specific activity (comments, reviews, or progress updates) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new option --vt-keep-at-variants-in-shortnames to preserve @-prefixed variants in short names. The changes are implemented across several files to add the command-line option, register it in the configuration, and pass it down to the cartesian_config.Parser where the logic is applied. The implementation appears correct and well-integrated. I have one suggestion to improve the code quality by addressing a mutable default argument in the Parser's __init__ method.

Comment thread virttest/cartesian_config.py Outdated
Comment on lines 1483 to 1487
def __init__(self, filename=None, defaults=False, expand_defaults=[], debug=False, keep_at_variants_in_shortnames=False):
self.node = Node()
self.debug = debug
self.defaults = defaults
self.expand_defaults = [LIdentifier(x) for x in expand_defaults]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The __init__ method uses a mutable default argument expand_defaults=[]. This is a common pitfall in Python that can lead to unexpected behavior, as the same list object is shared across all calls that don't explicitly provide a value for expand_defaults.

While I see that the pylint warning W0102 for this is disabled, it's a good practice to avoid mutable default arguments to prevent potential bugs.

A safer approach is to use None as the default value and initialize an empty list inside the method if None is received.

Suggested change
def __init__(self, filename=None, defaults=False, expand_defaults=[], debug=False, keep_at_variants_in_shortnames=False):
self.node = Node()
self.debug = debug
self.defaults = defaults
self.expand_defaults = [LIdentifier(x) for x in expand_defaults]
def __init__(self, filename=None, defaults=False, expand_defaults=None, debug=False, keep_at_variants_in_shortnames=False):
if expand_defaults is None:
expand_defaults = []
self.node = Node()
self.debug = debug
self.defaults = defaults
self.expand_defaults = [LIdentifier(x) for x in expand_defaults]

@nickzhq nickzhq force-pushed the keep_at_default branch 5 times, most recently from b2692c9 to 8d3ce9f Compare March 9, 2026 11:40
@nickzhq nickzhq marked this pull request as ready for review March 10, 2026 06:56
Comment thread avocado_vt/plugins/vt_init.py Outdated
help_msg=help_msg,
)

help_msg = (
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look those code changes are not necessary since you already implemented them in add_basic_vt_options of avocado_vt/plugins/vt.py

@Yingshun
Copy link
Copy Markdown
Contributor

virtio_scsi_test.scsi_function_test.HostCpuVendor.intel.Host_RHEL.m10.u2.Hx86_64.vnc.bridge.ovmf.no_virtio_rng.filesystem.no_9p_export.smallpages.no_pci_assignable.qcow2.virtio_scsi.up.virtio_net.package.Guest.Linux.RHEL.10.2.x86_64.type_specific.io-github-autotest-libvirt.virtual_network.qemu_test.packet_stress.user_type_iface.q35.HostCpuFamily.skylake.HostCpuVersion.4210R.HostCpuVendor.intel.Host.RHEL.m10.u2.Host_arch_x86_64: STARTED
Is it expected that some variants appear more than once?

@Yingshun Yingshun requested a review from YongxueHong March 13, 2026 07:12
Comment thread avocado_vt/plugins/vt.py Outdated
add_option(
parser,
dest="vt.keep_at_variants_in_shortnames",
arg="--vt-keep-at-variants-in-shortnames",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @nickzhq
As we discussed, actually, we do not need to add a new option to implement this functionality; instead, we could create a new item(e.g: fullname) to display the complete name for the return dictionary from the process of the cartesian_parser.get_dicts().

Thanks.

@nickzhq nickzhq changed the title FEAT: Add --vt-keep-at-variants-in-shortnames option to preserve @def… Add full_testcase_name parameter Mar 19, 2026
@nickzhq nickzhq force-pushed the keep_at_default branch 3 times, most recently from 4f8c4ff to 531f351 Compare March 19, 2026 02:42
@nickzhq
Copy link
Copy Markdown
Contributor Author

nickzhq commented Mar 19, 2026

The new parameter is params["full_testcase_name"], the format is as follows:
type_specific.io-github-autotest-qemu.guest_iommu_test.eim_off.default => guest_iommu_test.eim_off.default
io-github-autotest-qemu.boot => boot

@nickzhq
Copy link
Copy Markdown
Contributor Author

nickzhq commented Mar 19, 2026

Hello @Yingshun @YongxueHong @chunfuwen , please take a review, thanks!

Copy link
Copy Markdown
Contributor

@chunfuwen chunfuwen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`

import re
test_case1 = 'type_specific.io-github-autotest-qemu.guest_iommu_test.eim_off.default'
test_case2 = 'io-github-autotest-qemu.boot'
t1 = re.sub(r"^(type_specific.)?(io-[^.]+.)", "", test_case1)
t1
'guest_iommu_test.eim_off.default'
t1 = re.sub(r"^(type_specific.)?(io-[^.]+.)", "", test_case2)
t1
'boot'
`

After validation, the code looks goods.

@Yingshun
Copy link
Copy Markdown
Contributor

@YongxueHong @PaulYuuu Please prioritize the review of this PR so we can proceed with the remaining KAR related tasks. We are currently blocked, awaiting its approval and merge. Thx!

Copy link
Copy Markdown
Contributor

@YvanY0 YvanY0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a short talk with @YongxueHong, we all think the fullname should not cut from the short name, the pattern may take mistake.

The solution is find out where _short_name_map_file be generated, and add the new fullname from that code block.

@gemini-code-assist, please help to show where generates _short_name_map_file, and show us the logic, and the fullname should be added in the near code block, not using re module.

@YongxueHong
Copy link
Copy Markdown

@YongxueHong @PaulYuuu Please prioritize the review of this PR so we can proceed with the remaining KAR related tasks. We are currently blocked, awaiting its approval and merge. Thx!

Hi @Yingshun
I am working on it and trying to figure out a proper solution based on the short talk with @PaulYuuu, I will comment on it later, thanks.

@nickzhq
Copy link
Copy Markdown
Contributor Author

nickzhq commented Mar 24, 2026

@YongxueHong @PaulYuuu Please prioritize the review of this PR so we can proceed with the remaining KAR related tasks. We are currently blocked, awaiting its approval and merge. Thx!

Hi @Yingshun I am working on it and trying to figure out a proper solution based on the short talk with @PaulYuuu, I will comment on it later, thanks.

Hello @YongxueHong @PaulYuuu , I got your point. The _short_name_map_file is created at cartesian_config.py.
I'm working on it.
Thanks!
cc @Yingshun

@YvanY0
Copy link
Copy Markdown
Contributor

YvanY0 commented Mar 24, 2026

diff --git a/virttest/cartesian_config.py b/virttest/cartesian_config.py
index 95a5ee56..0176ae56 100755
--- a/virttest/cartesian_config.py
+++ b/virttest/cartesian_config.py
@@ -140,7 +140,7 @@ import re
 import sys

 _reserved_keys = set(
-    ("name", "shortname", "dep", "_short_name_map_file", "_name_map_file")
+    ("name", "shortname", "dep", "_short_name_map_file", "_name_map_file", "testcase_id")
 )
 options = None
 num_failed_cases = 5
@@ -521,6 +521,7 @@ class Node(object):
         "children",
         "labels",
         "append_to_shortname",
+        "append_to_testcase_id",
         "failed_cases",
         "default",
         "q_dict",
@@ -535,6 +536,7 @@ class Node(object):
         self.children = []
         self.labels = set()
         self.append_to_shortname = False
+        self.append_to_testcase_id = False
         self.failed_cases = collections.deque()
         self.default = False

@@ -1789,6 +1791,11 @@ class Parser(object):

                         node3.append_to_shortname = not is_default

+                        # Mark variants from subtests.cfg to be included in testcase_id
+                        node3.append_to_testcase_id = (
+                            lexer.filename != "<string>" and os.path.basename(lexer.filename) == "subtests.cfg"
+                        )
+
                         op = LUpdateFileMap()
                         op.set_operands(
                             lexer.filename, ".".join(str(x) for x in node3.name)
@@ -1999,12 +2006,13 @@ class Parser(object):
             self._debug("%s  %s:  %s" % (lexer.filename, lexer.linenum, lexer.line))
             raise

-    def get_dicts(self, node=None, ctx=[], content=[], shortname=[], dep=[]):
+    def get_dicts(self, node=None, ctx=[], content=[], shortname=[], dep=[], testcase_id=[]):
         """
         Process 'join' entry, unpack join filter for node.

         :param ctx: node labels/names
         :param content: previous content in plain
+        :param testcase_id: accumulated testcase_id parts from subtests.cfg variants
         :returns: dictionary

         1) join filter_1 filter_2 ....
@@ -2050,7 +2058,7 @@ class Parser(object):

         if not joins:
             # Return generator
-            for d in self.get_dicts_plain(node, ctx, content, shortname, dep):
+            for d in self.get_dicts_plain(node, ctx, content, shortname, dep, testcase_id):
                 yield _drop_suffixes(d) if parent else d
         else:
             # Rewrite all separate joins in one node as many `only'
@@ -2063,7 +2071,7 @@ class Parser(object):

             old_content = node.content[:]
             node.content = new_content
-            for d in self.multiply_join(onlys, node, ctx, content, shortname, dep):
+            for d in self.multiply_join(onlys, node, ctx, content, shortname, dep, testcase_id):
                 yield _drop_suffixes(d) if parent else d
             node.content = old_content[:]

@@ -2079,7 +2087,7 @@ class Parser(object):
             name = p1 + "." + p2
         return name

-    def multiply_join(self, onlys, node=None, ctx=[], content=[], shortname=[], dep=[]):
+    def multiply_join(self, onlys, node=None, ctx=[], content=[], shortname=[], dep=[], testcase_id=[]):
         """
         Multiply all joins. Return dictionaries one by one
         Each `join' is the same as `only' filter
@@ -2093,14 +2101,14 @@ class Parser(object):
         node.content += only

         if not remains:
-            for d in self.get_dicts_plain(node, ctx, content, shortname, dep):
+            for d in self.get_dicts_plain(node, ctx, content, shortname, dep, testcase_id):
                 yield d
         else:
-            for d1 in self.get_dicts_plain(node, ctx, content, shortname, dep):
+            for d1 in self.get_dicts_plain(node, ctx, content, shortname, dep, testcase_id):
                 # Current frame multiply by all variants from bottom
                 node.content = content_orig
                 for d2 in self.multiply_join(
-                    remains, node, ctx, content, shortname, dep
+                    remains, node, ctx, content, shortname, dep, testcase_id
                 ):

                     d = d1.copy()
@@ -2109,11 +2117,12 @@ class Parser(object):
                     d["shortname"] = self.mk_name(d1["shortname"], d2["shortname"])
                     yield d

-    def get_dicts_plain(self, node=None, ctx=[], content=[], shortname=[], dep=[]):
+    def get_dicts_plain(self, node=None, ctx=[], content=[], shortname=[], dep=[], testcase_id=[]):
         """
         Generate dictionaries from the code parsed so far.  This should
         be called after parsing something.

+        :param testcase_id: accumulated testcase_id parts from subtests.cfg variants
         :return: A dict generator.
         """

@@ -2217,6 +2226,11 @@ class Parser(object):
         ctx = ctx + node.name
         ctx_set = set(ctx)
         labels = node.labels
+
+        # Update testcase_id (only for variants from subtests.cfg)
+        if node.append_to_testcase_id:
+            testcase_id = node.name if node.var_name == "subtest" else testcase_id + node.name
+
         # Get the current name
         name = ".".join([str(label) for label in ctx])

@@ -2257,23 +2271,25 @@ class Parser(object):
         count = 0
         if self.defaults and node.var_name not in self.expand_defaults:
             for n in node.children:
-                for d in self.get_dicts(n, ctx, new_content, shortname, dep):
+                for d in self.get_dicts(n, ctx, new_content, shortname, dep, testcase_id):
                     count += 1
                     yield d
                 if n.default and count:
                     break
         else:
             for n in node.children:
-                for d in self.get_dicts(n, ctx, new_content, shortname, dep):
+                for d in self.get_dicts(n, ctx, new_content, shortname, dep, testcase_id):
                     count += 1
                     yield d
         # Reached leaf?
         if not node.children:
             self._debug("    reached leaf, returning it")
+
             d = {
                 "name": name,
                 "dep": dep,
                 "shortname": ".".join([str(sn.name) for sn in shortname]),
+                "testcase_id": ".".join([str(t.name) for t in testcase_id]),
             }
             for _, _, op in new_content:
                 op.apply_to_dict(d)

This version will introduce the testcase_id as the unique ID with provider prefix.

And let me explain why we need to include provider prefix here. The problem is name collisions across test providers(tp-qemu/tp-libvirt). e.g., the boot test case in tp-qemu is the top level case and only has 1 test case, and this case can be used for tp-libvirt, but this case is a middle level in tp-libvirt test cases, if only test with boot, then vt_type=libvirt will run 121 test cases(io-github-autotest-libvirt.virsh.boot.by_ovmf.positive_test.options.boot.cdrom.boot_dev.os_firmware.with_secure_option, io-github-autotest-libvirt.guest_os_booting.lifecycle.boot.boot_order, io-github-autotest-qemu.boot etc), we should use io-github-autotest-qemu.boot as the unique ID.

Adding provider prefix willnot break anything, in tp-qemu test loop we always drop io-github-autotest-qemu, but with it, the test case can also be run, just like in the command line using --testcase=io-github-autotest-qemu.multi_nics_verify.

@nickzhq
Copy link
Copy Markdown
Contributor Author

nickzhq commented Mar 24, 2026

diff --git a/virttest/cartesian_config.py b/virttest/cartesian_config.py
index 95a5ee56..0176ae56 100755
--- a/virttest/cartesian_config.py
+++ b/virttest/cartesian_config.py
@@ -140,7 +140,7 @@ import re
 import sys

 _reserved_keys = set(
-    ("name", "shortname", "dep", "_short_name_map_file", "_name_map_file")
+    ("name", "shortname", "dep", "_short_name_map_file", "_name_map_file", "testcase_id")
 )
 options = None
 num_failed_cases = 5
@@ -521,6 +521,7 @@ class Node(object):
         "children",
         "labels",
         "append_to_shortname",
+        "append_to_testcase_id",
         "failed_cases",
         "default",
         "q_dict",
@@ -535,6 +536,7 @@ class Node(object):
         self.children = []
         self.labels = set()
         self.append_to_shortname = False
+        self.append_to_testcase_id = False
         self.failed_cases = collections.deque()
         self.default = False

@@ -1789,6 +1791,11 @@ class Parser(object):

                         node3.append_to_shortname = not is_default

+                        # Mark variants from subtests.cfg to be included in testcase_id
+                        node3.append_to_testcase_id = (
+                            lexer.filename != "<string>" and os.path.basename(lexer.filename) == "subtests.cfg"
+                        )
+
                         op = LUpdateFileMap()
                         op.set_operands(
                             lexer.filename, ".".join(str(x) for x in node3.name)
@@ -1999,12 +2006,13 @@ class Parser(object):
             self._debug("%s  %s:  %s" % (lexer.filename, lexer.linenum, lexer.line))
             raise

-    def get_dicts(self, node=None, ctx=[], content=[], shortname=[], dep=[]):
+    def get_dicts(self, node=None, ctx=[], content=[], shortname=[], dep=[], testcase_id=[]):
         """
         Process 'join' entry, unpack join filter for node.

         :param ctx: node labels/names
         :param content: previous content in plain
+        :param testcase_id: accumulated testcase_id parts from subtests.cfg variants
         :returns: dictionary

         1) join filter_1 filter_2 ....
@@ -2050,7 +2058,7 @@ class Parser(object):

         if not joins:
             # Return generator
-            for d in self.get_dicts_plain(node, ctx, content, shortname, dep):
+            for d in self.get_dicts_plain(node, ctx, content, shortname, dep, testcase_id):
                 yield _drop_suffixes(d) if parent else d
         else:
             # Rewrite all separate joins in one node as many `only'
@@ -2063,7 +2071,7 @@ class Parser(object):

             old_content = node.content[:]
             node.content = new_content
-            for d in self.multiply_join(onlys, node, ctx, content, shortname, dep):
+            for d in self.multiply_join(onlys, node, ctx, content, shortname, dep, testcase_id):
                 yield _drop_suffixes(d) if parent else d
             node.content = old_content[:]

@@ -2079,7 +2087,7 @@ class Parser(object):
             name = p1 + "." + p2
         return name

-    def multiply_join(self, onlys, node=None, ctx=[], content=[], shortname=[], dep=[]):
+    def multiply_join(self, onlys, node=None, ctx=[], content=[], shortname=[], dep=[], testcase_id=[]):
         """
         Multiply all joins. Return dictionaries one by one
         Each `join' is the same as `only' filter
@@ -2093,14 +2101,14 @@ class Parser(object):
         node.content += only

         if not remains:
-            for d in self.get_dicts_plain(node, ctx, content, shortname, dep):
+            for d in self.get_dicts_plain(node, ctx, content, shortname, dep, testcase_id):
                 yield d
         else:
-            for d1 in self.get_dicts_plain(node, ctx, content, shortname, dep):
+            for d1 in self.get_dicts_plain(node, ctx, content, shortname, dep, testcase_id):
                 # Current frame multiply by all variants from bottom
                 node.content = content_orig
                 for d2 in self.multiply_join(
-                    remains, node, ctx, content, shortname, dep
+                    remains, node, ctx, content, shortname, dep, testcase_id
                 ):

                     d = d1.copy()
@@ -2109,11 +2117,12 @@ class Parser(object):
                     d["shortname"] = self.mk_name(d1["shortname"], d2["shortname"])
                     yield d

-    def get_dicts_plain(self, node=None, ctx=[], content=[], shortname=[], dep=[]):
+    def get_dicts_plain(self, node=None, ctx=[], content=[], shortname=[], dep=[], testcase_id=[]):
         """
         Generate dictionaries from the code parsed so far.  This should
         be called after parsing something.

+        :param testcase_id: accumulated testcase_id parts from subtests.cfg variants
         :return: A dict generator.
         """

@@ -2217,6 +2226,11 @@ class Parser(object):
         ctx = ctx + node.name
         ctx_set = set(ctx)
         labels = node.labels
+
+        # Update testcase_id (only for variants from subtests.cfg)
+        if node.append_to_testcase_id:
+            testcase_id = node.name if node.var_name == "subtest" else testcase_id + node.name
+
         # Get the current name
         name = ".".join([str(label) for label in ctx])

@@ -2257,23 +2271,25 @@ class Parser(object):
         count = 0
         if self.defaults and node.var_name not in self.expand_defaults:
             for n in node.children:
-                for d in self.get_dicts(n, ctx, new_content, shortname, dep):
+                for d in self.get_dicts(n, ctx, new_content, shortname, dep, testcase_id):
                     count += 1
                     yield d
                 if n.default and count:
                     break
         else:
             for n in node.children:
-                for d in self.get_dicts(n, ctx, new_content, shortname, dep):
+                for d in self.get_dicts(n, ctx, new_content, shortname, dep, testcase_id):
                     count += 1
                     yield d
         # Reached leaf?
         if not node.children:
             self._debug("    reached leaf, returning it")
+
             d = {
                 "name": name,
                 "dep": dep,
                 "shortname": ".".join([str(sn.name) for sn in shortname]),
+                "testcase_id": ".".join([str(t.name) for t in testcase_id]),
             }
             for _, _, op in new_content:
                 op.apply_to_dict(d)

This version will introduce the testcase_id as the unique ID with provider prefix.

And let me explain why we need to include provider prefix here. The problem is name collisions across test providers(tp-qemu/tp-libvirt). e.g., the boot test case in tp-qemu is the top level case and only has 1 test case, and this case can be used for tp-libvirt, but this case is a middle level in tp-libvirt test cases, if only test with boot, then vt_type=libvirt will run 121 test cases(io-github-autotest-libvirt.virsh.boot.by_ovmf.positive_test.options.boot.cdrom.boot_dev.os_firmware.with_secure_option, io-github-autotest-libvirt.guest_os_booting.lifecycle.boot.boot_order, io-github-autotest-qemu.boot etc), we should use io-github-autotest-qemu.boot as the unique ID.

Adding provider prefix willnot break anything, in tp-qemu test loop we always drop io-github-autotest-qemu, but with it, the test case can also be run, just like in the command line using --testcase=io-github-autotest-qemu.multi_nics_verify.

So... close this patch and use testcase_id at Kar project? @PaulYuuu

@nickzhq nickzhq force-pushed the keep_at_default branch 2 times, most recently from 3bc76e5 to 9228b8f Compare March 24, 2026 09:05
@YvanY0
Copy link
Copy Markdown
Contributor

YvanY0 commented Mar 24, 2026

So... close this patch and use testcase_id at Kar project? @PaulYuuu

No, testcase_id is new one, shortname, name and id cannot meet our requirement.

@nickzhq nickzhq force-pushed the keep_at_default branch 2 times, most recently from b2d0667 to 3c24500 Compare March 24, 2026 09:21
@nickzhq
Copy link
Copy Markdown
Contributor Author

nickzhq commented Mar 24, 2026

So... close this patch and use testcase_id at Kar project? @PaulYuuu

No, testcase_id is new one, shortname, name and id cannot meet our requirement.

I got confused by the whole comments on this patch.
The current solution has a new parameter full_testcase_name = guest_iommu_test.eim_off.default. The Kar will use guest_iommu_test.eim_off.default as a filter.

Or, you guys prefer full_testcase_name = io-github-autotest-qemu.guest_iommu_test.eim_off.default way?
Any comments before review?
@YongxueHong @PaulYuuu

@nickzhq nickzhq requested a review from YvanY0 March 25, 2026 02:27
@nickzhq nickzhq force-pushed the keep_at_default branch 3 times, most recently from c906fb2 to cf3d4c9 Compare March 25, 2026 11:15
@nickzhq
Copy link
Copy Markdown
Contributor Author

nickzhq commented Mar 25, 2026

Hi @YongxueHong @PaulYuuu,  after a deep debugging, I  found the subtests.cfg was as same as we want.
Key logs:
`
DEBUG: _short_name_map_file = {'machines.cfg': 'q35', 'subtests.cfg': 'type_specific.io-github-autotest-qemu.guest_iommu_test.eim_off.default', 'guest-os.cfg': 'Guest.Linux.RHEL.10.1.x86_64', 'guest-mode.cfg': 'package', 'guest-hw.cfg': '[bridge.ovmf.no](http://bridge.ovmf.no/)_[virtio_rng.filesystem.no](http://virtio_rng.filesystem.no/)_[9p_export.smallpages.no](http://9p_export.smallpages.no/)_pci_assignable.qcow2.virtio_scsi.up.virtio_net', 'guest-hw-internal.cfg': 'vnc', 'host-os-internal.cfg': 'HostCpuVendor.intel.Host_RHEL.m10.u2.Hx86_64', 'tests-example.cfg': 'run_test'}

DEBUG: _short_name_map_file = {'machines.cfg': 'q35', 'subtests.cfg': 'io-github-autotest-qemu.boot', 'guest-os.cfg': 'Guest.Linux.RHEL.10.1.x86_64', 'guest-mode.cfg': 'package', 'guest-hw.cfg': '[bridge.ovmf.no](http://bridge.ovmf.no/)_[virtio_rng.filesystem.no](http://virtio_rng.filesystem.no/)_[9p_export.smallpages.no](http://9p_export.smallpages.no/)_pci_assignable.qcow2.virtio_scsi.up.virtio_net', 'guest-hw-internal.cfg': 'vnc', 'host-os-internal.cfg': 'HostCpuVendor.intel.Host_RHEL.m10.u2.Hx86_64', 'tests-example.cfg': 'run_test'}
`
So, just copy subtests.cfg to subtest_id at the top level where the final dict is yielded.
Please check the  code for details!

Note: type_specific may be not in the subtests.cfg

@nickzhq
Copy link
Copy Markdown
Contributor Author

nickzhq commented Mar 25, 2026

@Yingshun please use this patch for test. Only subtest_id is what you need.
Usage: params["subtest_id"]

Thanks!

Copies subtests.cfg value to subtest_id in the existing
_short_name_map_file dictionary at dict generation time,
preserving all subtest labels including type_specific and
io-* provider prefixes.

Usage: params["subtest_id"]

Assisted-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Houqi (Nick) Zuo <hzuo@redhat.com>
@YongxueHong
Copy link
Copy Markdown

Hi @YongxueHong @PaulYuuu,  after a deep debugging, I  found the subtests.cfg was as same as we want. Key logs: ` DEBUG: short_name_map_file = {'machines.cfg': 'q35', 'subtests.cfg': 'type_specific.io-github-autotest-qemu.guest_iommu_test.eim_off.default', 'guest-os.cfg': 'Guest.Linux.RHEL.10.1.x86_64', 'guest-mode.cfg': 'package', 'guest-hw.cfg': '[bridge.ovmf.no]([http://bridge.ovmf.no/)virtio_rng.filesystem.no_9p_export.smallpages.no_pci_assignable.qcow2.virtio_scsi.up.virtio_net](http://bridge.ovmf.no/)_%5Bvirtio_rng.filesystem.no%5D(http://virtio_rng.filesystem.no/)_%5B9p_export.smallpages.no%5D(http://9p_export.smallpages.no/)_pci_assignable.qcow2.virtio_scsi.up.virtio_net)', 'guest-hw-internal.cfg': 'vnc', 'host-os-internal.cfg': 'HostCpuVendor.intel.Host_RHEL.m10.u2.Hx86_64', 'tests-example.cfg': 'run_test'}

DEBUG: short_name_map_file = {'machines.cfg': 'q35', 'subtests.cfg': 'io-github-autotest-qemu.boot', 'guest-os.cfg': 'Guest.Linux.RHEL.10.1.x86_64', 'guest-mode.cfg': 'package', 'guest-hw.cfg': '[bridge.ovmf.no]([http://bridge.ovmf.no/)virtio_rng.filesystem.no_9p_export.smallpages.no_pci_assignable.qcow2.virtio_scsi.up.virtio_net](http://bridge.ovmf.no/)_%5Bvirtio_rng.filesystem.no%5D(http://virtio_rng.filesystem.no/)_%5B9p_export.smallpages.no%5D(http://9p_export.smallpages.no/)_pci_assignable.qcow2.virtio_scsi.up.virtio_net)', 'guest-hw-internal.cfg': 'vnc', 'host-os-internal.cfg': 'HostCpuVendor.intel.Host_RHEL.m10.u2.Hx86_64', 'tests-example.cfg': 'run_test'} ` So, just copy subtests.cfg to subtest_id at the leaf level where the final dict is yielded. Please check the  code for details!

Note: type_specific may be not in the subtests.cfg

Hi @nickzhq
The current solution is good for me. Thanks a lot.
BTW, there is another improvement way is that we could expose the _short_name_map_file as a public parameter for the vt_params since it includes not only the subtest variants, but also contains the others, like guest-os, guset-mode, and so on, which may be needed in the future if the user wants. However, it may be another topic.
Thanks.

@YongxueHong YongxueHong requested a review from chunfuwen March 26, 2026 08:31
Copy link
Copy Markdown

@YongxueHong YongxueHong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@nickzhq
Copy link
Copy Markdown
Contributor Author

nickzhq commented Mar 30, 2026

Since the requirements had been changed last week, this patch is NOT needed.
Close it.
Thanks!

@nickzhq nickzhq closed this Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants