We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
avocado list --resolver doesn't show the reason of failed resolutions
While the functionality of exposing the resolver was living inside the "avocado nlist" command, the reasons would be displayed on failed resolutions, such as:

```
  avocado-instrumented  /my/file   File "/my/file" does not end with ".py"
  python-unittest       /my/file   File "/my/file" does not end with ".py"
  exec-test             /my/file   File "/my/file" does not exist or is not executable
  tap                   /my/file   File "/my/file" does not exist or is not executable
```

This is very useful, and should be brought back.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `avocado/plugins/list.py`
Content:
```
1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
5 #
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9 #
10 # See LICENSE for more details.
11 #
12 # Copyright: Red Hat Inc. 2013-2014
13 # Author: Lucas Meneghel Rodrigues <lmr@redhat.com>
14 # Author: Beraldo Leal <bleal@redhat.com>
15 
16 import os
17 
18 from avocado.core import exit_codes, loader, parser_common_args
19 from avocado.core.output import LOG_UI, TERM_SUPPORT
20 from avocado.core.plugin_interfaces import CLICmd
21 from avocado.core.resolver import ReferenceResolutionResult
22 from avocado.core.settings import settings
23 from avocado.core.suite import TestSuite
24 from avocado.core.test import Test
25 from avocado.utils.astring import iter_tabular_output
26 
27 
28 def _get_test_tags(test):
29     """Return a list of all tags of a test as string."""
30     params = test[1]
31     tags_repr = []
32     for tag, values in params.get('tags', {}).items():
33         if values:
34             tags_repr.append("%s(%s)" % (tag, ",".join(values)))
35         else:
36             tags_repr.append(tag)
37     return ",".join(tags_repr)
38 
39 
40 class List(CLICmd):
41 
42     """
43     Implements the avocado 'list' subcommand
44     """
45 
46     name = 'list'
47     description = 'List available tests'
48 
49     def _display(self, suite, matrix, resolution=None):
50         header = None
51         verbose = suite.config.get('core.verbose')
52         if verbose:
53             header = (TERM_SUPPORT.header_str('Type'),
54                       TERM_SUPPORT.header_str('Test'),
55                       TERM_SUPPORT.header_str('Tag(s)'))
56 
57         for line in iter_tabular_output(matrix,
58                                         header=header,
59                                         strip=True):
60             LOG_UI.debug(line)
61 
62         if verbose:
63             LOG_UI.info("")
64             LOG_UI.info("TEST TYPES SUMMARY")
65             LOG_UI.info("==================")
66             for key in sorted(suite.stats):
67                 LOG_UI.info("%s: %s", key, suite.stats[key])
68 
69             if suite.tags_stats:
70                 LOG_UI.info("")
71                 LOG_UI.info("TEST TAGS SUMMARY")
72                 LOG_UI.info("=================")
73                 for key in sorted(suite.tags_stats):
74                     LOG_UI.info("%s: %s", key, suite.tags_stats[key])
75 
76             if resolution:
77                 resolution_header = (TERM_SUPPORT.header_str('Resolver'),
78                                      TERM_SUPPORT.header_str('Reference'),
79                                      TERM_SUPPORT.header_str('Info'))
80                 LOG_UI.info("")
81                 for line in iter_tabular_output(resolution,
82                                                 header=resolution_header,
83                                                 strip=True):
84                     LOG_UI.info(line)
85 
86     @staticmethod
87     def _get_test_matrix(suite):
88         """Used for loader."""
89         test_matrix = []
90 
91         type_label_mapping = loader.loader.get_type_label_mapping()
92         decorator_mapping = loader.loader.get_decorator_mapping()
93 
94         verbose = suite.config.get('core.verbose')
95         for cls, params in suite.tests:
96             if isinstance(cls, str):
97                 cls = Test
98             type_label = type_label_mapping[cls]
99             decorator = decorator_mapping[cls]
100             type_label = decorator(type_label)
101 
102             if verbose:
103                 test_matrix.append((type_label,
104                                     params['name'],
105                                     _get_test_tags((cls, params))))
106             else:
107                 test_matrix.append((type_label, params['name']))
108 
109         return test_matrix
110 
111     @staticmethod
112     def _get_resolution_matrix(suite):
113         """Used for resolver."""
114         test_matrix = []
115         verbose = suite.config.get('core.verbose')
116         for test in suite.tests:
117             runnable = test.runnable
118 
119             type_label = TERM_SUPPORT.healthy_str(runnable.kind)
120 
121             if verbose:
122                 tags_repr = []
123                 tags = runnable.tags or {}
124                 for tag, vals in tags.items():
125                     if vals:
126                         tags_repr.append("%s(%s)" % (tag,
127                                                      ",".join(vals)))
128                     else:
129                         tags_repr.append(tag)
130                 tags_repr = ",".join(tags_repr)
131                 test_matrix.append((type_label, runnable.uri, tags_repr))
132             else:
133                 test_matrix.append((type_label, runnable.uri))
134         return test_matrix
135 
136     @staticmethod
137     def save_recipes(suite, directory, matrix_len):
138         fmt = '%%0%uu.json' % len(str(matrix_len))
139         index = 1
140         for resolution in suite.resolutions:
141             if resolution.result == ReferenceResolutionResult.SUCCESS:
142                 for res in resolution.resolutions:
143                     res.write_json(os.path.join(directory, fmt % index))
144                     index += 1
145 
146     def configure(self, parser):
147         """
148         Add the subparser for the list action.
149 
150         :param parser: The Avocado command line application parser
151         :type parser: :class:`avocado.core.parser.ArgumentParser`
152         """
153         parser = super(List, self).configure(parser)
154         help_msg = ('List of test references (aliases or paths). If empty, '
155                     'Avocado will list tests on the configured test source, '
156                     '(see "avocado config --datadir") Also, if there are '
157                     'other test loader plugins active, tests from those '
158                     'plugins might also show up (behavior may vary among '
159                     'plugins)')
160         settings.register_option(section='list',
161                                  key='references',
162                                  default=[],
163                                  nargs='*',
164                                  key_type=list,
165                                  help_msg=help_msg,
166                                  parser=parser,
167                                  positional_arg=True)
168         loader.add_loader_options(parser, 'list')
169 
170         help_msg = ('What is the method used to detect tests? If --resolver '
171                     'used, Avocado will use the Next Runner Resolver method. '
172                     'If not the legacy one will be used.')
173         settings.register_option(section='list',
174                                  key='resolver',
175                                  key_type=bool,
176                                  default=False,
177                                  help_msg=help_msg,
178                                  parser=parser,
179                                  long_arg='--resolver')
180 
181         help_msg = ('Writes runnable recipe files to a directory. Valid only '
182                     'when using --resolver.')
183         settings.register_option(section='list.recipes',
184                                  key='write_to_directory',
185                                  default=None,
186                                  metavar='DIRECTORY',
187                                  help_msg=help_msg,
188                                  parser=parser,
189                                  long_arg='--write-recipes-to-directory')
190 
191         parser_common_args.add_tag_filter_args(parser)
192 
193     def run(self, config):
194         runner = 'nrunner' if config.get('list.resolver') else 'runner'
195         config['run.references'] = config.get('list.references')
196         config['run.ignore_missing_references'] = True
197         config['run.test_runner'] = runner
198         try:
199             suite = TestSuite.from_config(config)
200             if runner == 'nrunner':
201                 matrix = self._get_resolution_matrix(suite)
202                 self._display(suite, matrix)
203 
204                 directory = config.get('list.recipes.write_to_directory')
205                 if directory is not None:
206                     self.save_recipes(suite, directory, len(matrix))
207             else:
208                 matrix = self._get_test_matrix(suite)
209                 self._display(suite, matrix)
210         except KeyboardInterrupt:
211             LOG_UI.error('Command interrupted by user...')
212             return exit_codes.AVOCADO_FAIL
213
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/avocado/plugins/list.py b/avocado/plugins/list.py
--- a/avocado/plugins/list.py
+++ b/avocado/plugins/list.py
@@ -46,7 +46,7 @@
     name = 'list'
     description = 'List available tests'
 
-    def _display(self, suite, matrix, resolution=None):
+    def _display(self, suite, matrix):
         header = None
         verbose = suite.config.get('core.verbose')
         if verbose:
@@ -60,6 +60,32 @@
             LOG_UI.debug(line)
 
         if verbose:
+            if suite.resolutions:
+                resolution_header = (TERM_SUPPORT.header_str('Resolver'),
+                                     TERM_SUPPORT.header_str('Reference'),
+                                     TERM_SUPPORT.header_str('Info'))
+                LOG_UI.info("")
+
+                mapping = {
+                  ReferenceResolutionResult.SUCCESS: TERM_SUPPORT.healthy_str,
+                  ReferenceResolutionResult.NOTFOUND: TERM_SUPPORT.fail_header_str,
+                  ReferenceResolutionResult.ERROR: TERM_SUPPORT.fail_header_str
+                }
+                resolution_matrix = []
+                for r in suite.resolutions:
+                    decorator = mapping.get(r.result,
+                                            TERM_SUPPORT.warn_header_str)
+                    if r.result == ReferenceResolutionResult.SUCCESS:
+                        continue
+                    resolution_matrix.append((decorator(r.origin),
+                                              r.reference,
+                                              r.info or ''))
+
+                for line in iter_tabular_output(resolution_matrix,
+                                                header=resolution_header,
+                                                strip=True):
+                    LOG_UI.info(line)
+
             LOG_UI.info("")
             LOG_UI.info("TEST TYPES SUMMARY")
             LOG_UI.info("==================")
@@ -73,16 +99,6 @@
                 for key in sorted(suite.tags_stats):
                     LOG_UI.info("%s: %s", key, suite.tags_stats[key])
 
-            if resolution:
-                resolution_header = (TERM_SUPPORT.header_str('Resolver'),
-                                     TERM_SUPPORT.header_str('Reference'),
-                                     TERM_SUPPORT.header_str('Info'))
-                LOG_UI.info("")
-                for line in iter_tabular_output(resolution,
-                                                header=resolution_header,
-                                                strip=True):
-                    LOG_UI.info(line)
-
     @staticmethod
     def _get_test_matrix(suite):
         """Used for loader."""

{"golden_diff": "diff --git a/avocado/plugins/list.py b/avocado/plugins/list.py\n--- a/avocado/plugins/list.py\n+++ b/avocado/plugins/list.py\n@@ -46,7 +46,7 @@\n     name = 'list'\n     description = 'List available tests'\n \n-    def _display(self, suite, matrix, resolution=None):\n+    def _display(self, suite, matrix):\n         header = None\n         verbose = suite.config.get('core.verbose')\n         if verbose:\n@@ -60,6 +60,32 @@\n             LOG_UI.debug(line)\n \n         if verbose:\n+            if suite.resolutions:\n+                resolution_header = (TERM_SUPPORT.header_str('Resolver'),\n+                                     TERM_SUPPORT.header_str('Reference'),\n+                                     TERM_SUPPORT.header_str('Info'))\n+                LOG_UI.info(\"\")\n+\n+                mapping = {\n+                  ReferenceResolutionResult.SUCCESS: TERM_SUPPORT.healthy_str,\n+                  ReferenceResolutionResult.NOTFOUND: TERM_SUPPORT.fail_header_str,\n+                  ReferenceResolutionResult.ERROR: TERM_SUPPORT.fail_header_str\n+                }\n+                resolution_matrix = []\n+                for r in suite.resolutions:\n+                    decorator = mapping.get(r.result,\n+                                            TERM_SUPPORT.warn_header_str)\n+                    if r.result == ReferenceResolutionResult.SUCCESS:\n+                        continue\n+                    resolution_matrix.append((decorator(r.origin),\n+                                              r.reference,\n+                                              r.info or ''))\n+\n+                for line in iter_tabular_output(resolution_matrix,\n+                                                header=resolution_header,\n+                                                strip=True):\n+                    LOG_UI.info(line)\n+\n             LOG_UI.info(\"\")\n             LOG_UI.info(\"TEST TYPES SUMMARY\")\n             LOG_UI.info(\"==================\")\n@@ -73,16 +99,6 @@\n                 for key in sorted(suite.tags_stats):\n                     LOG_UI.info(\"%s: %s\", key, suite.tags_stats[key])\n \n-            if resolution:\n-                resolution_header = (TERM_SUPPORT.header_str('Resolver'),\n-                                     TERM_SUPPORT.header_str('Reference'),\n-                                     TERM_SUPPORT.header_str('Info'))\n-                LOG_UI.info(\"\")\n-                for line in iter_tabular_output(resolution,\n-                                                header=resolution_header,\n-                                                strip=True):\n-                    LOG_UI.info(line)\n-\n     @staticmethod\n     def _get_test_matrix(suite):\n         \"\"\"Used for loader.\"\"\"\n", "issue": "avocado list --resolver doesn't show the reason of failed resolutions\nWhile the functionality of exposing the resolver was living inside the \"avocado nlist\" command, the reasons would be displayed on failed resolutions, such as:\r\n\r\n```\r\n  avocado-instrumented  /my/file   File \"/my/file\" does not end with \".py\"\r\n  python-unittest       /my/file   File \"/my/file\" does not end with \".py\"\r\n  exec-test             /my/file   File \"/my/file\" does not exist or is not executable\r\n  tap                   /my/file   File \"/my/file\" does not exist or is not executable\r\n```\r\n\r\nThis is very useful, and should be brought back.\n", "before_files": [{"content": "# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n#\n# See LICENSE for more details.\n#\n# Copyright: Red Hat Inc. 2013-2014\n# Author: Lucas Meneghel Rodrigues <lmr@redhat.com>\n# Author: Beraldo Leal <bleal@redhat.com>\n\nimport os\n\nfrom avocado.core import exit_codes, loader, parser_common_args\nfrom avocado.core.output import LOG_UI, TERM_SUPPORT\nfrom avocado.core.plugin_interfaces import CLICmd\nfrom avocado.core.resolver import ReferenceResolutionResult\nfrom avocado.core.settings import settings\nfrom avocado.core.suite import TestSuite\nfrom avocado.core.test import Test\nfrom avocado.utils.astring import iter_tabular_output\n\n\ndef _get_test_tags(test):\n    \"\"\"Return a list of all tags of a test as string.\"\"\"\n    params = test[1]\n    tags_repr = []\n    for tag, values in params.get('tags', {}).items():\n        if values:\n            tags_repr.append(\"%s(%s)\" % (tag, \",\".join(values)))\n        else:\n            tags_repr.append(tag)\n    return \",\".join(tags_repr)\n\n\nclass List(CLICmd):\n\n    \"\"\"\n    Implements the avocado 'list' subcommand\n    \"\"\"\n\n    name = 'list'\n    description = 'List available tests'\n\n    def _display(self, suite, matrix, resolution=None):\n        header = None\n        verbose = suite.config.get('core.verbose')\n        if verbose:\n            header = (TERM_SUPPORT.header_str('Type'),\n                      TERM_SUPPORT.header_str('Test'),\n                      TERM_SUPPORT.header_str('Tag(s)'))\n\n        for line in iter_tabular_output(matrix,\n                                        header=header,\n                                        strip=True):\n            LOG_UI.debug(line)\n\n        if verbose:\n            LOG_UI.info(\"\")\n            LOG_UI.info(\"TEST TYPES SUMMARY\")\n            LOG_UI.info(\"==================\")\n            for key in sorted(suite.stats):\n                LOG_UI.info(\"%s: %s\", key, suite.stats[key])\n\n            if suite.tags_stats:\n                LOG_UI.info(\"\")\n                LOG_UI.info(\"TEST TAGS SUMMARY\")\n                LOG_UI.info(\"=================\")\n                for key in sorted(suite.tags_stats):\n                    LOG_UI.info(\"%s: %s\", key, suite.tags_stats[key])\n\n            if resolution:\n                resolution_header = (TERM_SUPPORT.header_str('Resolver'),\n                                     TERM_SUPPORT.header_str('Reference'),\n                                     TERM_SUPPORT.header_str('Info'))\n                LOG_UI.info(\"\")\n                for line in iter_tabular_output(resolution,\n                                                header=resolution_header,\n                                                strip=True):\n                    LOG_UI.info(line)\n\n    @staticmethod\n    def _get_test_matrix(suite):\n        \"\"\"Used for loader.\"\"\"\n        test_matrix = []\n\n        type_label_mapping = loader.loader.get_type_label_mapping()\n        decorator_mapping = loader.loader.get_decorator_mapping()\n\n        verbose = suite.config.get('core.verbose')\n        for cls, params in suite.tests:\n            if isinstance(cls, str):\n                cls = Test\n            type_label = type_label_mapping[cls]\n            decorator = decorator_mapping[cls]\n            type_label = decorator(type_label)\n\n            if verbose:\n                test_matrix.append((type_label,\n                                    params['name'],\n                                    _get_test_tags((cls, params))))\n            else:\n                test_matrix.append((type_label, params['name']))\n\n        return test_matrix\n\n    @staticmethod\n    def _get_resolution_matrix(suite):\n        \"\"\"Used for resolver.\"\"\"\n        test_matrix = []\n        verbose = suite.config.get('core.verbose')\n        for test in suite.tests:\n            runnable = test.runnable\n\n            type_label = TERM_SUPPORT.healthy_str(runnable.kind)\n\n            if verbose:\n                tags_repr = []\n                tags = runnable.tags or {}\n                for tag, vals in tags.items():\n                    if vals:\n                        tags_repr.append(\"%s(%s)\" % (tag,\n                                                     \",\".join(vals)))\n                    else:\n                        tags_repr.append(tag)\n                tags_repr = \",\".join(tags_repr)\n                test_matrix.append((type_label, runnable.uri, tags_repr))\n            else:\n                test_matrix.append((type_label, runnable.uri))\n        return test_matrix\n\n    @staticmethod\n    def save_recipes(suite, directory, matrix_len):\n        fmt = '%%0%uu.json' % len(str(matrix_len))\n        index = 1\n        for resolution in suite.resolutions:\n            if resolution.result == ReferenceResolutionResult.SUCCESS:\n                for res in resolution.resolutions:\n                    res.write_json(os.path.join(directory, fmt % index))\n                    index += 1\n\n    def configure(self, parser):\n        \"\"\"\n        Add the subparser for the list action.\n\n        :param parser: The Avocado command line application parser\n        :type parser: :class:`avocado.core.parser.ArgumentParser`\n        \"\"\"\n        parser = super(List, self).configure(parser)\n        help_msg = ('List of test references (aliases or paths). If empty, '\n                    'Avocado will list tests on the configured test source, '\n                    '(see \"avocado config --datadir\") Also, if there are '\n                    'other test loader plugins active, tests from those '\n                    'plugins might also show up (behavior may vary among '\n                    'plugins)')\n        settings.register_option(section='list',\n                                 key='references',\n                                 default=[],\n                                 nargs='*',\n                                 key_type=list,\n                                 help_msg=help_msg,\n                                 parser=parser,\n                                 positional_arg=True)\n        loader.add_loader_options(parser, 'list')\n\n        help_msg = ('What is the method used to detect tests? If --resolver '\n                    'used, Avocado will use the Next Runner Resolver method. '\n                    'If not the legacy one will be used.')\n        settings.register_option(section='list',\n                                 key='resolver',\n                                 key_type=bool,\n                                 default=False,\n                                 help_msg=help_msg,\n                                 parser=parser,\n                                 long_arg='--resolver')\n\n        help_msg = ('Writes runnable recipe files to a directory. Valid only '\n                    'when using --resolver.')\n        settings.register_option(section='list.recipes',\n                                 key='write_to_directory',\n                                 default=None,\n                                 metavar='DIRECTORY',\n                                 help_msg=help_msg,\n                                 parser=parser,\n                                 long_arg='--write-recipes-to-directory')\n\n        parser_common_args.add_tag_filter_args(parser)\n\n    def run(self, config):\n        runner = 'nrunner' if config.get('list.resolver') else 'runner'\n        config['run.references'] = config.get('list.references')\n        config['run.ignore_missing_references'] = True\n        config['run.test_runner'] = runner\n        try:\n            suite = TestSuite.from_config(config)\n            if runner == 'nrunner':\n                matrix = self._get_resolution_matrix(suite)\n                self._display(suite, matrix)\n\n                directory = config.get('list.recipes.write_to_directory')\n                if directory is not None:\n                    self.save_recipes(suite, directory, len(matrix))\n            else:\n                matrix = self._get_test_matrix(suite)\n                self._display(suite, matrix)\n        except KeyboardInterrupt:\n            LOG_UI.error('Command interrupted by user...')\n            return exit_codes.AVOCADO_FAIL\n", "path": "avocado/plugins/list.py"}], "after_files": [{"content": "# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n#\n# See LICENSE for more details.\n#\n# Copyright: Red Hat Inc. 2013-2014\n# Author: Lucas Meneghel Rodrigues <lmr@redhat.com>\n# Author: Beraldo Leal <bleal@redhat.com>\n\nimport os\n\nfrom avocado.core import exit_codes, loader, parser_common_args\nfrom avocado.core.output import LOG_UI, TERM_SUPPORT\nfrom avocado.core.plugin_interfaces import CLICmd\nfrom avocado.core.resolver import ReferenceResolutionResult\nfrom avocado.core.settings import settings\nfrom avocado.core.suite import TestSuite\nfrom avocado.core.test import Test\nfrom avocado.utils.astring import iter_tabular_output\n\n\ndef _get_test_tags(test):\n    \"\"\"Return a list of all tags of a test as string.\"\"\"\n    params = test[1]\n    tags_repr = []\n    for tag, values in params.get('tags', {}).items():\n        if values:\n            tags_repr.append(\"%s(%s)\" % (tag, \",\".join(values)))\n        else:\n            tags_repr.append(tag)\n    return \",\".join(tags_repr)\n\n\nclass List(CLICmd):\n\n    \"\"\"\n    Implements the avocado 'list' subcommand\n    \"\"\"\n\n    name = 'list'\n    description = 'List available tests'\n\n    def _display(self, suite, matrix):\n        header = None\n        verbose = suite.config.get('core.verbose')\n        if verbose:\n            header = (TERM_SUPPORT.header_str('Type'),\n                      TERM_SUPPORT.header_str('Test'),\n                      TERM_SUPPORT.header_str('Tag(s)'))\n\n        for line in iter_tabular_output(matrix,\n                                        header=header,\n                                        strip=True):\n            LOG_UI.debug(line)\n\n        if verbose:\n            if suite.resolutions:\n                resolution_header = (TERM_SUPPORT.header_str('Resolver'),\n                                     TERM_SUPPORT.header_str('Reference'),\n                                     TERM_SUPPORT.header_str('Info'))\n                LOG_UI.info(\"\")\n\n                mapping = {\n                  ReferenceResolutionResult.SUCCESS: TERM_SUPPORT.healthy_str,\n                  ReferenceResolutionResult.NOTFOUND: TERM_SUPPORT.fail_header_str,\n                  ReferenceResolutionResult.ERROR: TERM_SUPPORT.fail_header_str\n                }\n                resolution_matrix = []\n                for r in suite.resolutions:\n                    decorator = mapping.get(r.result,\n                                            TERM_SUPPORT.warn_header_str)\n                    if r.result == ReferenceResolutionResult.SUCCESS:\n                        continue\n                    resolution_matrix.append((decorator(r.origin),\n                                              r.reference,\n                                              r.info or ''))\n\n                for line in iter_tabular_output(resolution_matrix,\n                                                header=resolution_header,\n                                                strip=True):\n                    LOG_UI.info(line)\n\n            LOG_UI.info(\"\")\n            LOG_UI.info(\"TEST TYPES SUMMARY\")\n            LOG_UI.info(\"==================\")\n            for key in sorted(suite.stats):\n                LOG_UI.info(\"%s: %s\", key, suite.stats[key])\n\n            if suite.tags_stats:\n                LOG_UI.info(\"\")\n                LOG_UI.info(\"TEST TAGS SUMMARY\")\n                LOG_UI.info(\"=================\")\n                for key in sorted(suite.tags_stats):\n                    LOG_UI.info(\"%s: %s\", key, suite.tags_stats[key])\n\n    @staticmethod\n    def _get_test_matrix(suite):\n        \"\"\"Used for loader.\"\"\"\n        test_matrix = []\n\n        type_label_mapping = loader.loader.get_type_label_mapping()\n        decorator_mapping = loader.loader.get_decorator_mapping()\n\n        verbose = suite.config.get('core.verbose')\n        for cls, params in suite.tests:\n            if isinstance(cls, str):\n                cls = Test\n            type_label = type_label_mapping[cls]\n            decorator = decorator_mapping[cls]\n            type_label = decorator(type_label)\n\n            if verbose:\n                test_matrix.append((type_label,\n                                    params['name'],\n                                    _get_test_tags((cls, params))))\n            else:\n                test_matrix.append((type_label, params['name']))\n\n        return test_matrix\n\n    @staticmethod\n    def _get_resolution_matrix(suite):\n        \"\"\"Used for resolver.\"\"\"\n        test_matrix = []\n        verbose = suite.config.get('core.verbose')\n        for test in suite.tests:\n            runnable = test.runnable\n\n            type_label = TERM_SUPPORT.healthy_str(runnable.kind)\n\n            if verbose:\n                tags_repr = []\n                tags = runnable.tags or {}\n                for tag, vals in tags.items():\n                    if vals:\n                        tags_repr.append(\"%s(%s)\" % (tag,\n                                                     \",\".join(vals)))\n                    else:\n                        tags_repr.append(tag)\n                tags_repr = \",\".join(tags_repr)\n                test_matrix.append((type_label, runnable.uri, tags_repr))\n            else:\n                test_matrix.append((type_label, runnable.uri))\n        return test_matrix\n\n    @staticmethod\n    def save_recipes(suite, directory, matrix_len):\n        fmt = '%%0%uu.json' % len(str(matrix_len))\n        index = 1\n        for resolution in suite.resolutions:\n            if resolution.result == ReferenceResolutionResult.SUCCESS:\n                for res in resolution.resolutions:\n                    res.write_json(os.path.join(directory, fmt % index))\n                    index += 1\n\n    def configure(self, parser):\n        \"\"\"\n        Add the subparser for the list action.\n\n        :param parser: The Avocado command line application parser\n        :type parser: :class:`avocado.core.parser.ArgumentParser`\n        \"\"\"\n        parser = super(List, self).configure(parser)\n        help_msg = ('List of test references (aliases or paths). If empty, '\n                    'Avocado will list tests on the configured test source, '\n                    '(see \"avocado config --datadir\") Also, if there are '\n                    'other test loader plugins active, tests from those '\n                    'plugins might also show up (behavior may vary among '\n                    'plugins)')\n        settings.register_option(section='list',\n                                 key='references',\n                                 default=[],\n                                 nargs='*',\n                                 key_type=list,\n                                 help_msg=help_msg,\n                                 parser=parser,\n                                 positional_arg=True)\n        loader.add_loader_options(parser, 'list')\n\n        help_msg = ('What is the method used to detect tests? If --resolver '\n                    'used, Avocado will use the Next Runner Resolver method. '\n                    'If not the legacy one will be used.')\n        settings.register_option(section='list',\n                                 key='resolver',\n                                 key_type=bool,\n                                 default=False,\n                                 help_msg=help_msg,\n                                 parser=parser,\n                                 long_arg='--resolver')\n\n        help_msg = ('Writes runnable recipe files to a directory. Valid only '\n                    'when using --resolver.')\n        settings.register_option(section='list.recipes',\n                                 key='write_to_directory',\n                                 default=None,\n                                 metavar='DIRECTORY',\n                                 help_msg=help_msg,\n                                 parser=parser,\n                                 long_arg='--write-recipes-to-directory')\n\n        parser_common_args.add_tag_filter_args(parser)\n\n    def run(self, config):\n        runner = 'nrunner' if config.get('list.resolver') else 'runner'\n        config['run.references'] = config.get('list.references')\n        config['run.ignore_missing_references'] = True\n        config['run.test_runner'] = runner\n        try:\n            suite = TestSuite.from_config(config)\n            if runner == 'nrunner':\n                matrix = self._get_resolution_matrix(suite)\n                self._display(suite, matrix)\n\n                directory = config.get('list.recipes.write_to_directory')\n                if directory is not None:\n                    self.save_recipes(suite, directory, len(matrix))\n            else:\n                matrix = self._get_test_matrix(suite)\n                self._display(suite, matrix)\n        except KeyboardInterrupt:\n            LOG_UI.error('Command interrupted by user...')\n            return exit_codes.AVOCADO_FAIL\n", "path": "avocado/plugins/list.py"}]}