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 failures in Fedora 36 (to be released) #53

Open
ibotty opened this issue Jan 24, 2022 · 2 comments
Open

test failures in Fedora 36 (to be released) #53

ibotty opened this issue Jan 24, 2022 · 2 comments

Comments

@ibotty
Copy link
Contributor

ibotty commented Jan 24, 2022

From the CI rebuild for Fedora 36 https://koji.fedoraproject.org/koji/taskinfo?taskID=81559080
Complete build log: https://kojipkgs.fedoraproject.org//work/tasks/9080/81559080/build.log

Notably it uses ansible-5.2.0-1.fc36.noarch and ansible-core-2.12.1-3.fc36.noarch. So it might be that. The complete (python) package list can be found in https://kojipkgs.fedoraproject.org//work/tasks/9080/81559080/root.log

I am a little lost what the error might be.

+ /usr/bin/py.test
============================= test session starts ==============================
platform linux -- Python 3.10.2, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /builddir/build/BUILD/paternoster-3.3.0, configfile: tox.ini, testpaths: paternoster/test
plugins: cov-3.0.0
collected 279 items
paternoster/test/test_ansible_runner.py .....FF............              [  6%]
paternoster/test/test_parameters.py .................................... [ 19%]
................................                                         [ 31%]
paternoster/test/test_paternoster.py ..                                  [ 31%]
paternoster/test/test_prompt.py ........................................ [ 46%]
..............................                                           [ 56%]
paternoster/test/test_root.py ..........                                 [ 60%]
paternoster/test/test_types.py ......................................... [ 75%]
.....................................................................    [100%]
=================================== FAILURES ===================================
__________________ test_verbose[True-keywords1-notkeywords1] ___________________
self = <ansible.executor.task_queue_manager.TaskQueueManager object at 0x7fff9aefad40>
method_name = 'v2_playbook_on_play_start', args = (all,), kwargs = {}
callback_plugin = <ansible.plugins.callback.default.CallbackModule object at 0x7fff9aefaf20>
wants_implicit_tasks = False
methods = [<bound method CallbackModule.v2_playbook_on_play_start of <ansible.plugins.callback.default.CallbackModule object at ...>, <bound method CallbackBase.v2_on_any of <ansible.plugins.callback.default.CallbackModule object at 0x7fff9aefaf20>>]
possible = 'v2_on_any'
gotit = <bound method CallbackBase.v2_on_any of <ansible.plugins.callback.default.CallbackModule object at 0x7fff9aefaf20>>
new_args = [all], is_implicit_task = False, arg = all
method = <bound method CallbackModule.v2_playbook_on_play_start of <ansible.plugins.callback.default.CallbackModule object at 0x7fff9aefaf20>>
    @lock_decorator(attr='_callback_lock')
    def send_callback(self, method_name, *args, **kwargs):
        for callback_plugin in [self._stdout_callback] + self._callback_plugins:
            # a plugin that set self.disabled to True will not be called
            # see osx_say.py example for such a plugin
            if getattr(callback_plugin, 'disabled', False):
                continue
    
            # a plugin can opt in to implicit tasks (such as meta). It does this
            # by declaring self.wants_implicit_tasks = True.
            wants_implicit_tasks = getattr(callback_plugin, 'wants_implicit_tasks', False)
    
            # try to find v2 method, fallback to v1 method, ignore callback if no method found
            methods = []
            for possible in [method_name, 'v2_on_any']:
                gotit = getattr(callback_plugin, possible, None)
                if gotit is None:
                    gotit = getattr(callback_plugin, possible.replace('v2_', ''), None)
                if gotit is not None:
                    methods.append(gotit)
    
            # send clean copies
            new_args = []
    
            # If we end up being given an implicit task, we'll set this flag in
            # the loop below. If the plugin doesn't care about those, then we
            # check and continue to the next iteration of the outer loop.
            is_implicit_task = False
    
            for arg in args:
                # FIXME: add play/task cleaners
                if isinstance(arg, TaskResult):
                    new_args.append(arg.clean_copy())
                # elif isinstance(arg, Play):
                # elif isinstance(arg, Task):
                else:
                    new_args.append(arg)
    
                if isinstance(arg, Task) and arg.implicit:
                    is_implicit_task = True
    
            if is_implicit_task and not wants_implicit_tasks:
                continue
    
            for method in methods:
                try:
>                   method(*new_args, **kwargs)
/usr/lib/python3.10/site-packages/ansible/executor/task_queue_manager.py:450: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <ansible.plugins.callback.default.CallbackModule object at 0x7fff9aefaf20>
play = all
    def v2_playbook_on_play_start(self, play):
        name = play.get_name().strip()
        if play.check_mode and self.check_mode_markers:
            checkmsg = " [CHECK MODE]"
        else:
            checkmsg = ""
        if not name:
            msg = u"PLAY%s" % checkmsg
        else:
            msg = u"PLAY [%s]%s" % (name, checkmsg)
    
        self._play = play
    
>       self._display.banner(msg)
/usr/lib/python3.10/site-packages/ansible/plugins/callback/default.py:245: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <ansible.utils.display.Display object at 0x7fff9cd8c6a0>
msg = 'PLAY [all]', color = None, cows = True
    def banner(self, msg, color=None, cows=True):
        '''
        Prints a header-looking line with cowsay or stars with length depending on terminal width (3 minimum)
        '''
        msg = to_text(msg)
    
        if self.b_cowsay and cows:
            try:
                self.banner_cowsay(msg)
                return
            except OSError:
                self.warning("somebody cleverly deleted cowsay or something during the PB run.  heh.")
    
        msg = msg.strip()
        try:
>           star_len = self.columns - get_text_width(msg)
/usr/lib/python3.10/site-packages/ansible/utils/display.py:431: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
text = 'PLAY [all]'
    def get_text_width(text):
        """Function that utilizes ``wcswidth`` or ``wcwidth`` to determine the
        number of columns used to display a text string.
    
        We try first with ``wcswidth``, and fallback to iterating each
        character and using wcwidth individually, falling back to a value of 0
        for non-printable wide characters
    
        On Py2, this depends on ``locale.setlocale(locale.LC_ALL, '')``,
        that in the case of Ansible is done in ``bin/ansible``
        """
        if not isinstance(text, text_type):
            raise TypeError('get_text_width requires text, not %s' % type(text))
    
        if _LOCALE_INITIALIZATION_ERR:
            Display().warning(
                'An error occurred while calling ansible.utils.display.initialize_locale '
                '(%s). This may result in incorrectly calculated text widths that can '
                'cause Display to print incorrect line lengths' % _LOCALE_INITIALIZATION_ERR
            )
        elif not _LOCALE_INITIALIZED:
>           Display().warning(
                'ansible.utils.display.initialize_locale has not been called, '
                'this may result in incorrectly calculated text widths that can '
                'cause Display to print incorrect line lengths'
            )
/usr/lib/python3.10/site-packages/ansible/utils/display.py:100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
msg = 'ansible.utils.display.initialize_locale has not been called, this may result in incorrectly calculated text widths that can cause Display to print incorrect line lengths'
args = (), kwargs = {}
    def display_warning(msg, *args, **kwargs):
        if not msg.startswith('Could not match supplied host pattern'):
>           __main__._real_warning(msg, *args, **kwargs)
paternoster/runners/ansiblerunner.py:144: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
msg = 'ansible.utils.display.initialize_locale has not been called, this may result in incorrectly calculated text widths that can cause Display to print incorrect line lengths'
args = (), kwargs = {}
    def display_warning(msg, *args, **kwargs):
        if not msg.startswith('Could not match supplied host pattern'):
>           __main__._real_warning(msg, *args, **kwargs)
E           RecursionError: maximum recursion depth exceeded in comparison
paternoster/runners/ansiblerunner.py:144: RecursionError
!!! Recursion detected (same locals & position)
During handling of the above exception, another exception occurred:
verbosity = True, keywords = ['TASK [debug]', 'PLAY RECAP']
notkeywords = ['ESTABLISH LOCAL CONNECTION']
capsys = <_pytest.capture.CaptureFixture object at 0x7fff9ae54790>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fff9ae57ac0>
    @pytest.mark.skipif(SKIP_ANSIBLE_TESTS, reason="ansible <2.4 requires python2")
    @pytest.mark.parametrize("verbosity,keywords,notkeywords", [
        (False, [], ["TASK [debug]", "PLAY RECAP"]),
        (True, ["TASK [debug]", "PLAY RECAP"], ["ESTABLISH LOCAL CONNECTION"]),
        (3, ["TASK [debug]", "PLAY RECAP", "task path"], []),
    ])
    def test_verbose(verbosity, keywords, notkeywords, capsys, monkeypatch):
        import os
        from ..runners.ansiblerunner import AnsibleRunner
    
        playbook_path = '/tmp/paternoster-test-playbook.yml'
        playbook = """
        - hosts: all
          gather_facts: no
          tasks:
            - debug: msg=a
        """
    
        with open(playbook_path, 'w') as f:
            f.write(playbook)
    
        monkeypatch.setattr(os, 'chdir', lambda *args, **kwargs: None)
>       AnsibleRunner(playbook_path).run([], verbosity)
paternoster/test/test_ansible_runner.py:59: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
paternoster/runners/ansiblerunner.py:238: in run
    status = self._get_playbook_executor(variables, verbosity).run()
/usr/lib/python3.10/site-packages/ansible/executor/playbook_executor.py:190: in run
    result = self._tqm.run(play=play)
/usr/lib/python3.10/site-packages/ansible/executor/task_queue_manager.py:281: in run
    self.send_callback('v2_playbook_on_play_start', new_play)
/usr/lib/python3.10/site-packages/ansible/utils/lock.py:41: in inner
    return func(*args, **kwargs)
/usr/lib/python3.10/site-packages/ansible/executor/task_queue_manager.py:453: in send_callback
    display.warning(u"Failure using method (%s) in callback plugin (%s): %s" % (to_text(method_name), to_text(callback_plugin), to_text(e)))
paternoster/runners/ansiblerunner.py:144: in display_warning
    __main__._real_warning(msg, *args, **kwargs)
paternoster/runners/ansiblerunner.py:144: in display_warning
    __main__._real_warning(msg, *args, **kwargs)
E   RecursionError: maximum recursion depth exceeded in comparison
!!! Recursion detected (same locals & position)
____________________ test_verbose[3-keywords2-notkeywords2] ____________________
self = <ansible.executor.task_queue_manager.TaskQueueManager object at 0x7fff997d2ec0>
method_name = 'v2_playbook_on_start'
args = (<ansible.playbook.Playbook object at 0x7fff997d2ce0>,), kwargs = {}
callback_plugin = <ansible.plugins.callback.default.CallbackModule object at 0x7fff997d2cb0>
wants_implicit_tasks = False
methods = [<bound method CallbackModule.v2_playbook_on_start of <ansible.plugins.callback.default.CallbackModule object at 0x7ff...>, <bound method CallbackBase.v2_on_any of <ansible.plugins.callback.default.CallbackModule object at 0x7fff997d2cb0>>]
possible = 'v2_on_any'
gotit = <bound method CallbackBase.v2_on_any of <ansible.plugins.callback.default.CallbackModule object at 0x7fff997d2cb0>>
new_args = [<ansible.playbook.Playbook object at 0x7fff997d2ce0>]
is_implicit_task = False
arg = <ansible.playbook.Playbook object at 0x7fff997d2ce0>
method = <bound method CallbackModule.v2_playbook_on_start of <ansible.plugins.callback.default.CallbackModule object at 0x7fff997d2cb0>>
    @lock_decorator(attr='_callback_lock')
    def send_callback(self, method_name, *args, **kwargs):
        for callback_plugin in [self._stdout_callback] + self._callback_plugins:
            # a plugin that set self.disabled to True will not be called
            # see osx_say.py example for such a plugin
            if getattr(callback_plugin, 'disabled', False):
                continue
    
            # a plugin can opt in to implicit tasks (such as meta). It does this
            # by declaring self.wants_implicit_tasks = True.
            wants_implicit_tasks = getattr(callback_plugin, 'wants_implicit_tasks', False)
    
            # try to find v2 method, fallback to v1 method, ignore callback if no method found
            methods = []
            for possible in [method_name, 'v2_on_any']:
                gotit = getattr(callback_plugin, possible, None)
                if gotit is None:
                    gotit = getattr(callback_plugin, possible.replace('v2_', ''), None)
                if gotit is not None:
                    methods.append(gotit)
    
            # send clean copies
            new_args = []
    
            # If we end up being given an implicit task, we'll set this flag in
            # the loop below. If the plugin doesn't care about those, then we
            # check and continue to the next iteration of the outer loop.
            is_implicit_task = False
    
            for arg in args:
                # FIXME: add play/task cleaners
                if isinstance(arg, TaskResult):
                    new_args.append(arg.clean_copy())
                # elif isinstance(arg, Play):
                # elif isinstance(arg, Task):
                else:
                    new_args.append(arg)
    
                if isinstance(arg, Task) and arg.implicit:
                    is_implicit_task = True
    
            if is_implicit_task and not wants_implicit_tasks:
                continue
    
            for method in methods:
                try:
>                   method(*new_args, **kwargs)
/usr/lib/python3.10/site-packages/ansible/executor/task_queue_manager.py:450: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <ansible.plugins.callback.default.CallbackModule object at 0x7fff997d2cb0>
playbook = <ansible.playbook.Playbook object at 0x7fff997d2ce0>
    def v2_playbook_on_start(self, playbook):
        if self._display.verbosity > 1:
            from os.path import basename
>           self._display.banner("PLAYBOOK: %s" % basename(playbook._file_name))
/usr/lib/python3.10/site-packages/ansible/plugins/callback/default.py:383: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <ansible.utils.display.Display object at 0x7fff9cd8c6a0>
msg = 'PLAYBOOK: paternoster-test-playbook.yml', color = None, cows = True
    def banner(self, msg, color=None, cows=True):
        '''
        Prints a header-looking line with cowsay or stars with length depending on terminal width (3 minimum)
        '''
        msg = to_text(msg)
    
        if self.b_cowsay and cows:
            try:
                self.banner_cowsay(msg)
                return
            except OSError:
                self.warning("somebody cleverly deleted cowsay or something during the PB run.  heh.")
    
        msg = msg.strip()
        try:
>           star_len = self.columns - get_text_width(msg)
/usr/lib/python3.10/site-packages/ansible/utils/display.py:431: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
text = 'PLAYBOOK: paternoster-test-playbook.yml'
    def get_text_width(text):
        """Function that utilizes ``wcswidth`` or ``wcwidth`` to determine the
        number of columns used to display a text string.
    
        We try first with ``wcswidth``, and fallback to iterating each
        character and using wcwidth individually, falling back to a value of 0
        for non-printable wide characters
    
        On Py2, this depends on ``locale.setlocale(locale.LC_ALL, '')``,
        that in the case of Ansible is done in ``bin/ansible``
        """
        if not isinstance(text, text_type):
            raise TypeError('get_text_width requires text, not %s' % type(text))
    
        if _LOCALE_INITIALIZATION_ERR:
            Display().warning(
                'An error occurred while calling ansible.utils.display.initialize_locale '
                '(%s). This may result in incorrectly calculated text widths that can '
                'cause Display to print incorrect line lengths' % _LOCALE_INITIALIZATION_ERR
            )
        elif not _LOCALE_INITIALIZED:
>           Display().warning(
                'ansible.utils.display.initialize_locale has not been called, '
                'this may result in incorrectly calculated text widths that can '
                'cause Display to print incorrect line lengths'
            )
/usr/lib/python3.10/site-packages/ansible/utils/display.py:100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
msg = 'ansible.utils.display.initialize_locale has not been called, this may result in incorrectly calculated text widths that can cause Display to print incorrect line lengths'
args = (), kwargs = {}
    def display_warning(msg, *args, **kwargs):
        if not msg.startswith('Could not match supplied host pattern'):
>           __main__._real_warning(msg, *args, **kwargs)
paternoster/runners/ansiblerunner.py:144: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
msg = 'ansible.utils.display.initialize_locale has not been called, this may result in incorrectly calculated text widths that can cause Display to print incorrect line lengths'
args = (), kwargs = {}
    def display_warning(msg, *args, **kwargs):
        if not msg.startswith('Could not match supplied host pattern'):
>           __main__._real_warning(msg, *args, **kwargs)
E           RecursionError: maximum recursion depth exceeded in comparison
paternoster/runners/ansiblerunner.py:144: RecursionError
!!! Recursion detected (same locals & position)
During handling of the above exception, another exception occurred:
verbosity = 3, keywords = ['TASK [debug]', 'PLAY RECAP', 'task path']
notkeywords = []
capsys = <_pytest.capture.CaptureFixture object at 0x7fff997d3eb0>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fff997d3910>
    @pytest.mark.skipif(SKIP_ANSIBLE_TESTS, reason="ansible <2.4 requires python2")
    @pytest.mark.parametrize("verbosity,keywords,notkeywords", [
        (False, [], ["TASK [debug]", "PLAY RECAP"]),
        (True, ["TASK [debug]", "PLAY RECAP"], ["ESTABLISH LOCAL CONNECTION"]),
        (3, ["TASK [debug]", "PLAY RECAP", "task path"], []),
    ])
    def test_verbose(verbosity, keywords, notkeywords, capsys, monkeypatch):
        import os
        from ..runners.ansiblerunner import AnsibleRunner
    
        playbook_path = '/tmp/paternoster-test-playbook.yml'
        playbook = """
        - hosts: all
          gather_facts: no
          tasks:
            - debug: msg=a
        """
    
        with open(playbook_path, 'w') as f:
            f.write(playbook)
    
        monkeypatch.setattr(os, 'chdir', lambda *args, **kwargs: None)
>       AnsibleRunner(playbook_path).run([], verbosity)
paternoster/test/test_ansible_runner.py:59: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
paternoster/runners/ansiblerunner.py:238: in run
    status = self._get_playbook_executor(variables, verbosity).run()
/usr/lib/python3.10/site-packages/ansible/executor/playbook_executor.py:120: in run
    self._tqm.send_callback('v2_playbook_on_start', pb)
/usr/lib/python3.10/site-packages/ansible/utils/lock.py:41: in inner
    return func(*args, **kwargs)
/usr/lib/python3.10/site-packages/ansible/executor/task_queue_manager.py:453: in send_callback
    display.warning(u"Failure using method (%s) in callback plugin (%s): %s" % (to_text(method_name), to_text(callback_plugin), to_text(e)))
paternoster/runners/ansiblerunner.py:144: in display_warning
    __main__._real_warning(msg, *args, **kwargs)
paternoster/runners/ansiblerunner.py:144: in display_warning
    __main__._real_warning(msg, *args, **kwargs)
E   RecursionError: maximum recursion depth exceeded in comparison
!!! Recursion detected (same locals & position)
----------------------------- Captured stdout call -----------------------------
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
=============================== warnings summary ===============================
paternoster/runners/ansiblerunner.py:5
  /builddir/build/BUILD/paternoster-3.3.0/paternoster/runners/ansiblerunner.py:5: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
    from distutils.version import LooseVersion
-- Docs: https://docs.pytest.org/en/stable/warnings.html
---------- coverage: platform linux, python 3.10.2-final-0 -----------
Coverage HTML written to dir htmlcov
=========================== short test summary info ============================
FAILED paternoster/test/test_ansible_runner.py::test_verbose[True-keywords1-notkeywords1]
FAILED paternoster/test/test_ansible_runner.py::test_verbose[3-keywords2-notkeywords2]
================== 2 failed, 277 passed, 1 warning in 12.65s ===================
@ibotty
Copy link
Contributor Author

ibotty commented Aug 26, 2022

Any update? I cannot get it to work on Fedora 36 and Fedora 37. This will most likely mean, that it won't work on other future distributions either.

@luto
Copy link
Member

luto commented Aug 26, 2022

We currently only test up to ansible 2.10. Since the ansible team has a habit of changing their project and (internal) API structure around regularly, Paternoster likely doesn't work with newer versions until someone steps up and fixes it.

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