Bug 1379773

Summary: Weird errors with py3
Product: [Fedora] Fedora Reporter: Fabio Alessandro Locati <fale>
Component: python-clickAssignee: Robert Kuska <rkuska>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: rawhideCC: fale, mail, pviktori, python-sig, rkuska
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-10-11 22:21:41 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Fabio Alessandro Locati 2016-09-27 15:52:36 UTC
I'm trying to build python-ansible-tower-cli and all tests are ok with py2.7.
When they are run on py3.5, the following tests fail:

======================================================================
ERROR: Establish that if connection fails and protocol not given,
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_api.py", line 199, in test_failed_suggestion_protocol
    secho.assert_called()
  File "/usr/lib64/python3.5/unittest/mock.py", line 583, in __getattr__
    raise AttributeError(name)
AttributeError: assert_called

======================================================================
FAIL: Establish that if `tower-cli config` is sent an invalid key,
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 193, in test_error_invalid_key
    self.assertEqual(result.exit_code, 1)
AssertionError: -1 != 1

======================================================================
FAIL: Establish that if no global config file exists, that tower-cli
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 214, in test_error_no_global_config_file
    isdir.assert_called_once_with('/etc/tower/')
  File "/usr/lib64/python3.5/unittest/mock.py", line 802, in assert_called_once_with
    raise AssertionError(msg)
AssertionError: Expected 'isdir' to be called once. Called 0 times.

======================================================================
FAIL: Establish that if `tower-cli config` is called with both a value
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 202, in test_error_value_and_unset
    self.assertEqual(result.exit_code, 2)
AssertionError: -1 != 2

======================================================================
FAIL: Establish that if we are given a key and no value, that the
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 59, in test_key_and_no_value
    self.assertEqual(result.exit_code, 0)
AssertionError: -1 != 0

======================================================================
FAIL: Establish that if `tower-cli config` is called with no arguments,
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 46, in test_no_arguments
    self.assertEqual(result.exit_code, 0)
AssertionError: -1 != 0

======================================================================
FAIL: Warn user if configuration file permissions can not be set
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 101, in test_permissions_warning
    warn.assert_called_once_with(mock.ANY, UserWarning)
  File "/usr/lib64/python3.5/unittest/mock.py", line 802, in assert_called_once_with
    raise AssertionError(msg)
AssertionError: Expected 'warn' to be called once. Called 0 times.

======================================================================
FAIL: Establish that calling `tower-cli config --unset` works in the
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 180, in test_unset
    self.assertEqual(result.exit_code, 0)
AssertionError: -1 != 0

======================================================================
FAIL: Establish that if we attempt to write a valid setting, that
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 126, in test_write_global_setting
    isdir.assert_called_once_with('/etc/tower/')
  File "/usr/lib64/python3.5/unittest/mock.py", line 802, in assert_called_once_with
    raise AssertionError(msg)
AssertionError: Expected 'isdir' to be called once. Called 0 times.

======================================================================
FAIL: Establish that if we attempt to write a valid setting locally, that
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 154, in test_write_local_setting
    chmod.assert_called_once_with(filename, int('0600', 8))
  File "/usr/lib64/python3.5/unittest/mock.py", line 802, in assert_called_once_with
    raise AssertionError(msg)
AssertionError: Expected 'chmod' to be called once. Called 0 times.

======================================================================
FAIL: Establish that if we attempt to write a valid setting, that
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 75, in test_write_setting
    chmod.assert_called_once_with(filename, int('0600', 8))
  File "/usr/lib64/python3.5/unittest/mock.py", line 802, in assert_called_once_with
    raise AssertionError(msg)
AssertionError: Expected 'chmod' to be called once. Called 0 times.

======================================================================
FAIL: Establish that if we attempt to write a valid setting, that
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_config.py", line 264, in test_write_global_setting_deprecated
    DeprecationWarning)
  File "/usr/lib64/python3.5/unittest/mock.py", line 802, in assert_called_once_with
    raise AssertionError(msg)
AssertionError: Expected 'warn' to be called once. Called 0 times.

======================================================================
FAIL: Establish that the version command gives a nice error in cases
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_version.py", line 58, in test_cannot_connect
    self.assertEqual(result.exit_code, 1)
AssertionError: -1 != 1

======================================================================
FAIL: Establish that the version command returns the output we
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_commands_version.py", line 45, in test_version_command
    self.assertEqual(result.exit_code, 0)
AssertionError: -1 != 0

======================================================================
FAIL: Establish that no_args_is_help causes the help to be printed,
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_utils_command.py", line 42, in test_dash_dash_help
    self.assertEqual(self.runner.invoke(foo, ['bar']).output, 'bar\n')
AssertionError: '' != 'bar\n'
+ bar


Looking the code, it seems like those tests rely heavily on click: https://github.com/ansible/tower-cli/blob/master/tests/test_commands_config.py
https://github.com/ansible/tower-cli/blob/master/tests/test_commands_version.py
https://github.com/ansible/tower-cli/blob/master/tests/test_utils_command.py

Upstream is running the same tests without problem, so I guess it has to be something with out python3-click build

Comment 1 Petr Viktorin 2016-09-27 16:06:35 UTC
Robert, do you want to investigate this issue? Please reassign to me if you want Python-Maint to do it.

Comment 2 Robert Kuska 2016-09-28 12:19:30 UTC
Traceback (most recent call last):
  File "/builddir/build/BUILD/tower-cli-3.0.1/tests/test_api.py", line 199, in test_failed_suggestion_protocol
    secho.assert_called()
  File "/usr/lib64/python3.5/unittest/mock.py", line 583, in __getattr__
    raise AttributeError(name)
AttributeError: assert_called

python3-click is alright, actually upstream doesn't support python3.5 yet[0].

This is casued by simply MagicMock object not containing `assert_called`, this attribute is missing also in Python-3.4' mock, my guess is that it is somehow called via overloaded __getattr__ function[1].

I couldn't reproduce the other errors using:

> https://github.com/ansible/tower-cli.git && cd towe-cli
> git checkout tags/v3.0.1
> # edited tox to include py3.5
> tox

I suggest you to contact upstream. Feel free to reopen if you disagree with my findings :-) 

[0] https://travis-ci.org/ansible/tower-cli/jobs/163117680
[1] https://github.com/python/cpython/blob/3.4/Lib/unittest/mock.py#L569

Comment 3 Robert Kuska 2016-09-28 12:25:59 UTC
To reword:

This is casued by simply MagicMock object not containing `assert_called` so the failure is expected. This attribute is missing also in Python-3.4' mock, the reason why tests pass there is probably overloaded function `__getattr__`[1] but I don't really have a time to deep dive into Mock implementation :-).

Python 3.5.1 (default, Sep 19 2016, 10:16:17) 
[GCC 6.1.1 20160621 (Red Hat 6.1.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from unittest import mock
>>> dir(mock.MagicMock())
['assert_any_call', 'assert_called_once_with', 'assert_called_with', 'assert_has_calls', 'assert_not_called', 'attach_mock', 'call_args', 'call_args_list', 'call_count', 'called', 'configure_mock', 'method_calls', 'mock_add_spec', 'mock_calls', 'reset_mock', 'return_value', 'side_effect']
>>> mock.MagicMock().assert_called
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.5/unittest/mock.py", line 583, in __getattr__
    raise AttributeError(name)
AttributeError: assert_called


Python 3.4.3 (default, Jun 29 2015, 12:16:01) 
[GCC 5.1.1 20150618 (Red Hat 5.1.1-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from unittest import mock
>>> mock.MagicMock().assert_called
<MagicMock name='mock.assert_called' id='139786006442560'>
>>> dir(mock.MagicMock())
['assert_any_call', 'assert_called_once_with', 'assert_called_with', 'assert_has_calls', 'attach_mock', 'call_args', 'call_args_list', 'call_count', 'called', 'configure_mock', 'method_calls', 'mock_add_spec', 'mock_calls', 'reset_mock', 'return_value', 'side_effect']

Comment 4 Fabio Alessandro Locati 2016-09-29 08:35:47 UTC
Aside from the first error (which upstream had too, and has now been fixed by me) all the other errors are click related in my opinion.

Comment 5 Robert Kuska 2016-09-29 08:44:26 UTC
To quote myself:

> I couldn't reproduce the other errors using:
> 
> > git clone https://github.com/ansible/tower-cli.git && cd tower-cli
> > git checkout tags/v3.0.1
> > # edited tox to include py3.5
> > tox

You have to provide a reproducer, the template for reporting a bug exists for a reason.

Comment 6 Fabio Alessandro Locati 2016-10-05 12:43:14 UTC
Sorry for the delay.

So, I'm trying to create an RPM, and this is the SRPM: https://fale.fedorapeople.org/rpms/python-ansible-tower-cli-3.0.1-1.fc24.src.rpm
This is the spec file: https://fale.fedorapeople.org/rpms/python-ansible-tower-cli.spec
This is the patch I'm applying: https://fale.fedorapeople.org/rpms/tower-cli-fix_py35_tests.patch (that is a cherrypick of https://github.com/ansible/tower-cli/commit/3317c834a30bb4c616eedad82a28bcd1f95bbe66). This patch does solve the assert_called problem.

Trying to build this on F24, this is the result: http://koji.fedoraproject.org/koji/taskinfo?taskID=15951996

Comment 7 Robert Kuska 2016-10-11 16:59:36 UTC
I couldn't reproduce the issue unless I run

mkdir -p /etc/tower
touch /etc/tower/tower_cli.cfg

before running tests, without it tests pass just fine, looking at the tower-cli CI [0] I can't see them to create tower_cli.cfg so I assume thats the reason for failing the other tests.

[0] https://travis-ci.org/ansible/tower-cli/jobs/166447312

Comment 8 Fabio Alessandro Locati 2016-10-11 22:21:41 UTC
Thanks a lot for the help and sorry for the bug that was not right