Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test_no_duplicate_egg_info fails with wrong egg_base #270

Open
bnavigator opened this issue Oct 15, 2020 · 3 comments
Open

test_no_duplicate_egg_info fails with wrong egg_base #270

bnavigator opened this issue Oct 15, 2020 · 3 comments

Comments

@bnavigator
Copy link

[   18s] __________________________ test_no_duplicate_egg_info __________________________
[   18s] 
[   18s]     def test_no_duplicate_egg_info():
[   18s]         """When the package has 'src' directory, do not write egg-info in base
[   18s]         dir."""
[   18s]         base_dir = vistir.compat.Path(os.path.abspath(os.getcwd())).as_posix()
[   18s]         r = Requirement.from_line("-e {}".format(base_dir))
[   18s]         egg_info_name = "{}.egg-info".format(r.name.replace("-", "_"))
[   18s]         distinfo_name = "{0}.dist-info".format(r.name.replace("-", "_"))
[   18s]     
[   18s]         def find_metadata(path):
[   18s]             metadata_names = [
[   18s]                 os.path.join(path, name) for name in (egg_info_name, distinfo_name)
[   18s]             ]
[   18s]             if not os.path.isdir(path):
[   18s]                 return None
[   18s]             pth = next(iter(pth for pth in metadata_names if os.path.isdir(pth)), None)
[   18s]             if not pth:
[   18s]                 pth = next(
[   18s]                     iter(
[   18s]                         pth
[   18s]                         for pth in os.listdir(path)
[   18s]                         if any(
[   18s]                             pth.endswith(md_ending)
[   18s]                             for md_ending in [".egg-info", ".dist-info", ".whl"]
[   18s]                         )
[   18s]                     ),
[   18s]                     None,
[   18s]                 )
[   18s]             return pth
[   18s]     
[   18s]         assert not find_metadata(base_dir)
[   18s]         assert not find_metadata(os.path.join(base_dir, "reqlib-metadata"))
[   18s]         assert not find_metadata(os.path.join(base_dir, "src", "reqlib-metadata"))
[   18s]         assert r.req.setup_info and os.path.isdir(r.req.setup_info.egg_base)
[   18s]         setup_info = r.req.setup_info
[   18s]         setup_info.get_info()
[   18s] >       assert (
[   18s]             find_metadata(setup_info.egg_base)
[   18s]             or find_metadata(setup_info.extra_kwargs["build_dir"])
[   18s]             or setup_info.get_egg_metadata()
[   18s]         )
[   18s] E       AssertionError: assert (None or None or None)

Maybe this is wrong:

(Pdb) print(setup_info.egg_base)
/home/abuild/rpmbuild/BUILD/requirementslib-1.5.13/reqlib-metadata

Full log with package version information:
requirementslib_log.txt

@frostming
Copy link
Member

Will you try again on the main branch?

@bnavigator
Copy link
Author

Still an issue with 1.6.1:

>       assert (
            find_metadata(setup_info.egg_base)
            or find_metadata(setup_info.extra_kwargs["build_dir"])
            or setup_info.get_egg_metadata()
        )
E       AssertionError: assert (None or None or None)
E        +  where None = <function test_no_duplicate_egg_info.<locals>.find_metadata at 0x7f2a7cedfea0>('/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/reqlib-metadata')
E        +    where '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/reqlib-metadata' = SetupInfo(name=None, base_dir='/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1', _version=None, _requirements=frozen...ExitStack object at 0x7f2a7bd6ea20>, _finalizer=<finalize object at 0x7f2a7c1e6460; for 'SetupInfo' at 0x7f2a7bd1c498>).egg_base
E        +  and   None = <function test_no_duplicate_egg_info.<locals>.find_metadata at 0x7f2a7cedfea0>('/tmp/reqlib-build_3uy8y5o')
E        +  and   None = <bound method SetupInfo.get_egg_metadata of SetupInfo(name=None, base_dir='/home/abuild/rpmbuild/BUILD/requirementslib...xitStack object at 0x7f2a7bd6ea20>, _finalizer=<finalize object at 0x7f2a7c1e6460; for 'SetupInfo' at 0x7f2a7bd1c498>)>()
E        +    where <bound method SetupInfo.get_egg_metadata of SetupInfo(name=None, base_dir='/home/abuild/rpmbuild/BUILD/requirementslib...xitStack object at 0x7f2a7bd6ea20>, _finalizer=<finalize object at 0x7f2a7c1e6460; for 'SetupInfo' at 0x7f2a7bd1c498>)> = SetupInfo(name=None, base_dir='/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1', _version=None, _requirements=frozen...ExitStack object at 0x7f2a7bd6ea20>, _finalizer=<finalize object at 0x7f2a7c1e6460; for 'SetupInfo' at 0x7f2a7bd1c498>).get_egg_metadata

tests/unit/test_setup_info.py:85: AssertionError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PDB post_mortem (IO-capturing turned off) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> /home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/unit/test_setup_info.py(85)test_no_duplicate_egg_info()
-> assert (
(Pdb) p setup_info.egg_base
'/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/reqlib-metadata'
(Pdb) 

@bnavigator
Copy link
Author

More of setup_info is broken:


[   21s] =================================== FAILURES ===================================
[   21s] ________________________ test_local_req[test_artifact0] ________________________
[   21s] 
[   21s] test_artifact = PosixPath('/tmp/pytest-of-abuild/pytest-21/test_local_req_test_artifact0_0/environ_config')
[   21s] 
[   21s]     @pytest.mark.skipif(os.name == "nt", reason="Building this is broken on windows")
[   21s]     @pytest.mark.parametrize(
[   21s]         "test_artifact",
[   21s]         [
[   21s]             {"name": "environ_config", "as_artifact": False},
[   21s]             {"name": "environ_config", "as_artifact": True},
[   21s]         ],
[   21s]         indirect=True,
[   21s]     )
[   21s]     def test_local_req(test_artifact):
[   21s]         r = Requirement.from_line(test_artifact.as_posix())
[   21s]         assert r.name.replace("_", "-") == "environ-config"
[   21s]         setup_dict = r.req.setup_info.as_dict()
[   21s] >       assert sorted(list(setup_dict.get("requires").keys())) == ["attrs"]
[   21s] E       AttributeError: 'NoneType' object has no attribute 'keys'
[   21s] 
[   21s] tests/unit/test_setup_info.py:25: AttributeError
[   21s] ________________________ test_local_req[test_artifact1] ________________________
[   21s] 
[   21s] test_artifact = PosixPath('/tmp/pytest-of-abuild/pytest-21/test_local_req_test_artifact1_0/18.2.0.zip')
[   21s] 
[   21s]     @pytest.mark.skipif(os.name == "nt", reason="Building this is broken on windows")
[   21s]     @pytest.mark.parametrize(
[   21s]         "test_artifact",
[   21s]         [
[   21s]             {"name": "environ_config", "as_artifact": False},
[   21s]             {"name": "environ_config", "as_artifact": True},
[   21s]         ],
[   21s]         indirect=True,
[   21s]     )
[   21s]     def test_local_req(test_artifact):
[   21s]         r = Requirement.from_line(test_artifact.as_posix())
[   21s] >       assert r.name.replace("_", "-") == "environ-config"
[   21s] E       AttributeError: 'NoneType' object has no attribute 'replace'
[   21s] 
[   21s] tests/unit/test_setup_info.py:23: AttributeError
[   21s] _________________ test_ast_parser_handles_repeated_assignments _________________
[   21s] 
[   21s] setup_py_dir = PosixPath('/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/fixtures/setup_py')
[   21s] 
[   21s]     def test_ast_parser_handles_repeated_assignments(setup_py_dir):
[   21s]         target = (
[   21s]             setup_py_dir.joinpath("package_with_repeated_assignments").absolute().as_posix()
[   21s]         )
[   21s]         r = Requirement.from_line(target)
[   21s]         setup_dict = r.req.setup_info.as_dict()
[   21s] >       assert setup_dict["name"] == "test-package-with-repeated-assignments"
[   21s] E       KeyError: 'name'
[   21s] 
[   21s] tests/unit/test_setup_info.py:234: KeyError
[   21s] ______________________ test_ast_parser_handles_exceptions ______________________
[   21s] 
[   21s] self = <[AttributeError("'Requirement' object has no attribute 'name'") raised in repr()] Requirement object at 0x7fbabb3a2670>
[   21s] requirement_string = '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts/git/pyinstaller'
[   21s] 
[   21s]     def __init__(self, requirement_string):
[   21s]         # type: (str) -> None
[   21s]         try:
[   21s] >           req = REQUIREMENT.parseString(requirement_string)
[   21s] 
[   21s] /usr/lib/python3.9/site-packages/packaging/requirements.py:113: 
[   21s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   21s] 
[   21s] self = {stringStart Combine:({W:(abcd...) [{W:(abcd...) | {[W:(-_.)]... W:(abcd...)}}]...}) [{Suppress:("[") [{Combine:({W:(a...tation" | "python_implementation" | "extra"} | {quoted string, starting with ' ending with ' | qu Empty}}]}} stringEnd}
[   21s] instring = '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts/git/pyinstaller'
[   21s] parseAll = False
[   21s] 
[   21s]     def parseString(self, instring, parseAll=False):
[   21s]         """
[   21s]         Execute the parse expression with the given string.
[   21s]         This is the main interface to the client code, once the complete
[   21s]         expression has been built.
[   21s]     
[   21s]         Returns the parsed data as a :class:`ParseResults` object, which may be
[   21s]         accessed as a list, or as a dict or object with attributes if the given parser
[   21s]         includes results names.
[   21s]     
[   21s]         If you want the grammar to require that the entire input string be
[   21s]         successfully parsed, then set ``parseAll`` to True (equivalent to ending
[   21s]         the grammar with ``StringEnd()``).
[   21s]     
[   21s]         Note: ``parseString`` implicitly calls ``expandtabs()`` on the input string,
[   21s]         in order to report proper column numbers in parse actions.
[   21s]         If the input string contains tabs and
[   21s]         the grammar uses parse actions that use the ``loc`` argument to index into the
[   21s]         string being parsed, you can ensure you have a consistent view of the input
[   21s]         string by:
[   21s]     
[   21s]         - calling ``parseWithTabs`` on your grammar before calling ``parseString``
[   21s]           (see :class:`parseWithTabs`)
[   21s]         - define your parse action using the full ``(s, loc, toks)`` signature, and
[   21s]           reference the input string using the parse action's ``s`` argument
[   21s]         - explictly expand the tabs in your input string before calling
[   21s]           ``parseString``
[   21s]     
[   21s]         Example::
[   21s]     
[   21s]             Word('a').parseString('aaaaabaaa')  # -> ['aaaaa']
[   21s]             Word('a').parseString('aaaaabaaa', parseAll=True)  # -> Exception: Expected end of text
[   21s]         """
[   21s]         ParserElement.resetCache()
[   21s]         if not self.streamlined:
[   21s]             self.streamline()
[   21s]             # ~ self.saveAsList = True
[   21s]         for e in self.ignoreExprs:
[   21s]             e.streamline()
[   21s]         if not self.keepTabs:
[   21s]             instring = instring.expandtabs()
[   21s]         try:
[   21s]             loc, tokens = self._parse(instring, 0)
[   21s]             if parseAll:
[   21s]                 loc = self.preParse(instring, loc)
[   21s]                 se = Empty() + StringEnd()
[   21s]                 se._parse(instring, loc)
[   21s]         except ParseBaseException as exc:
[   21s]             if ParserElement.verbose_stacktrace:
[   21s]                 raise
[   21s]             else:
[   21s]                 # catch and re-raise exception from here, clearing out pyparsing internal stack trace
[   21s]                 if getattr(exc, '__traceback__', None) is not None:
[   21s]                     exc.__traceback__ = self._trim_traceback(exc.__traceback__)
[   21s] >               raise exc
[   21s] 
[   21s] /usr/lib/python3.9/site-packages/pyparsing.py:1955: 
[   21s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   21s] 
[   21s] self = W:(abcd...)
[   21s] instring = '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts/git/pyinstaller'
[   21s] loc = 0, doActions = True
[   21s] 
[   21s]     def parseImpl(self, instring, loc, doActions=True):
[   21s]         result = self.re_match(instring, loc)
[   21s]         if not result:
[   21s] >           raise ParseException(instring, loc, self.errmsg, self)
[   21s] E           pyparsing.ParseException: Expected W:(abcd...), found '/'  (at char 0), (line:1, col:1)
[   21s] 
[   21s] /usr/lib/python3.9/site-packages/pyparsing.py:3250: ParseException
[   21s] 
[   21s] During handling of the above exception, another exception occurred:
[   21s] 
[   21s] self = <Line (editable=False, name=None, path=None, uri=None, extras=(), markers=None, vcs=None, specifier=None, pyproject=None, pyproject_requires=None, pyproject_backend=None, ireq=None)>
[   21s] 
[   21s]     def _parse_name_from_line(self):
[   21s]         # type: () -> Optional[STRING_TYPE]
[   21s]         if not self.is_named:
[   21s]             pass
[   21s]         try:
[   21s] >           self._requirement = init_requirement(self.line)
[   21s] 
[   21s] ../../BUILDROOT/python-requirementslib-1.6.1-0.x86_64/usr/lib/python3.9/site-packages/requirementslib/models/requirements.py:966: 
[   21s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   21s] 
[   21s] name = '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts/git/pyinstaller'
[   21s] 
[   21s]     def init_requirement(name):
[   21s]         # type: (AnyStr) -> TRequirement
[   21s]     
[   21s]         if not isinstance(name, str):
[   21s]             raise TypeError("must supply a name to generate a requirement")
[   21s]         from pkg_resources import Requirement
[   21s]     
[   21s] >       req = Requirement.parse(name)
[   21s] 
[   21s] ../../BUILDROOT/python-requirementslib-1.6.1-0.x86_64/usr/lib/python3.9/site-packages/requirementslib/models/utils.py:197: 
[   21s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   21s] 
[   21s] s = '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts/git/pyinstaller'
[   21s] 
[   21s]     @staticmethod
[   21s]     def parse(s):
[   21s] >       req, = parse_requirements(s)
[   21s] 
[   21s] /usr/lib/python3.9/site-packages/pkg_resources/__init__.py:3139: 
[   21s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   21s] 
[   21s] strs = '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts/git/pyinstaller'
[   21s] 
[   21s]     def parse_requirements(strs):
[   21s]         """Yield ``Requirement`` objects for each specification in `strs`
[   21s]     
[   21s]         `strs` must be a string, or a (possibly-nested) iterable thereof.
[   21s]         """
[   21s]         # create a steppable iterator, so we can handle \-continuations
[   21s]         lines = iter(yield_lines(strs))
[   21s]     
[   21s]         for line in lines:
[   21s]             # Drop comments -- a hash without a space may be in a URL.
[   21s]             if ' #' in line:
[   21s]                 line = line[:line.find(' #')]
[   21s]             # If there is a line continuation, drop it, and append the next line.
[   21s]             if line.endswith('\\'):
[   21s]                 line = line[:-2].strip()
[   21s]                 try:
[   21s]                     line += next(lines)
[   21s]                 except StopIteration:
[   21s]                     return
[   21s] >           yield Requirement(line)
[   21s] 
[   21s] /usr/lib/python3.9/site-packages/pkg_resources/__init__.py:3084: 
[   21s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   21s] 
[   21s] self = <[AttributeError("'Requirement' object has no attribute 'name'") raised in repr()] Requirement object at 0x7fbabb3a2670>
[   21s] requirement_string = '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts/git/pyinstaller'
[   21s] 
[   21s]     def __init__(self, requirement_string):
[   21s]         """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
[   21s] >       super(Requirement, self).__init__(requirement_string)
[   21s] 
[   21s] /usr/lib/python3.9/site-packages/pkg_resources/__init__.py:3094: 
[   21s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   21s] 
[   21s] self = <[AttributeError("'Requirement' object has no attribute 'name'") raised in repr()] Requirement object at 0x7fbabb3a2670>
[   21s] requirement_string = '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts/git/pyinstaller'
[   21s] 
[   21s]     def __init__(self, requirement_string):
[   21s]         # type: (str) -> None
[   21s]         try:
[   21s]             req = REQUIREMENT.parseString(requirement_string)
[   21s]         except ParseException as e:
[   21s] >           raise InvalidRequirement(
[   21s]                 'Parse error at "{0!r}": {1}'.format(
[   21s]                     requirement_string[e.loc : e.loc + 8], e.msg
[   21s]                 )
[   21s]             )
[   21s] E           packaging.requirements.InvalidRequirement: Parse error at "'/home/ab'": Expected W:(abcd...)
[   21s] 
[   21s] /usr/lib/python3.9/site-packages/packaging/requirements.py:115: InvalidRequirement
[   21s] 
[   21s] During handling of the above exception, another exception occurred:
[   21s] 
[   21s] artifact_dir = PosixPath('/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts')
[   21s] 
[   21s]     def test_ast_parser_handles_exceptions(artifact_dir):
[   21s]         path = artifact_dir.joinpath("git/pyinstaller")
[   21s] >       r = Requirement.from_line(path.as_posix())
[   21s] 
[   21s] tests/unit/test_setup_info.py:240: 
[   21s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   21s] ../../BUILDROOT/python-requirementslib-1.6.1-0.x86_64/usr/lib/python3.9/site-packages/requirementslib/models/requirements.py:2674: in from_line
[   21s]     parsed_line = Line(line)
[   21s] ../../BUILDROOT/python-requirementslib-1.6.1-0.x86_64/usr/lib/python3.9/site-packages/requirementslib/models/requirements.py:171: in __init__
[   21s]     self.parse()
[   21s] ../../BUILDROOT/python-requirementslib-1.6.1-0.x86_64/usr/lib/python3.9/site-packages/requirementslib/models/requirements.py:1304: in parse
[   21s]     self.parse_name()
[   21s] ../../BUILDROOT/python-requirementslib-1.6.1-0.x86_64/usr/lib/python3.9/site-packages/requirementslib/models/requirements.py:1027: in parse_name
[   21s]     name = self._parse_name_from_line()
[   21s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[   21s] 
[   21s] self = <Line (editable=False, name=None, path=None, uri=None, extras=(), markers=None, vcs=None, specifier=None, pyproject=None, pyproject_requires=None, pyproject_backend=None, ireq=None)>
[   21s] 
[   21s]     def _parse_name_from_line(self):
[   21s]         # type: () -> Optional[STRING_TYPE]
[   21s]         if not self.is_named:
[   21s]             pass
[   21s]         try:
[   21s]             self._requirement = init_requirement(self.line)
[   21s]         except Exception:
[   21s] >           raise RequirementError(
[   21s]                 "Failed parsing requirement from {0!r}".format(self.line)
[   21s]             )
[   21s] E           requirementslib.exceptions.RequirementError: Failed parsing requirement from '/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/artifacts/git/pyinstaller'
[   21s] 
[   21s] ../../BUILDROOT/python-requirementslib-1.6.1-0.x86_64/usr/lib/python3.9/site-packages/requirementslib/models/requirements.py:968: RequirementError
[   21s] ____________________ test_read_requirements_with_list_comp _____________________
[   21s] 
[   21s] setup_py_dir = PosixPath('/home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/fixtures/setup_py')
[   21s] 
[   21s]     def test_read_requirements_with_list_comp(setup_py_dir):
[   21s]         req = Requirement.from_line(
[   21s]             f"-e {(setup_py_dir / 'package_with_setup_with_list_comp').as_posix()}"
[   21s]         )
[   21s]         setup_info = req.req.setup_info.as_dict()
[   21s] >       assert sorted(setup_info["requires"]) == ["requests"]
[   21s] E       KeyError: 'requires'
[   21s] 
[   21s] tests/unit/test_setup_info.py:257: KeyError
[   21s] =============================== warnings summary ===============================
[   21s] tests/conftest.py:49
[   21s]   /home/abuild/rpmbuild/BUILD/requirementslib-1.6.1/tests/conftest.py:49: RuntimeWarning: Failed connecting to internet: http://clients3.google.com/generate_204
[   21s]     warnings.warn("Failed connecting to internet: {0}".format(url), RuntimeWarning)
[   21s] 
[   21s] -- Docs: https://docs.pytest.org/en/stable/warnings.html
[   21s] =========================== short test summary info ============================
[   21s] FAILED tests/unit/test_setup_info.py::test_local_req[test_artifact0] - Attrib...
[   21s] FAILED tests/unit/test_setup_info.py::test_local_req[test_artifact1] - Attrib...
[   21s] FAILED tests/unit/test_setup_info.py::test_ast_parser_handles_repeated_assignments
[   21s] FAILED tests/unit/test_setup_info.py::test_ast_parser_handles_exceptions - re...
[   21s] FAILED tests/unit/test_setup_info.py::test_read_requirements_with_list_comp
[   21s] =========== 5 failed, 162 passed, 20 deselected, 1 warning in 11.65s ===========

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

No branches or pull requests

2 participants