diff options
| author | Eric Fried <openstack@fried.cc> | 2019-10-29 15:55:11 -0500 |
|---|---|---|
| committer | melanie witt <melwittt@gmail.com> | 2020-07-21 03:25:22 +0000 |
| commit | 3228713ea302a962c11eb96ce34918b94528205e (patch) | |
| tree | a5a472a8275c1f5c4d4516ed1626e46b0b1e27ed | |
| parent | d2e809f12086171d227a06fd7ea19e0e36ed12f8 (diff) | |
| download | python-openstackclient-3228713ea302a962c11eb96ce34918b94528205e.tar.gz | |
Fix functional tests for py3
Fix various things so the functional tests will work under python3:
- A hashlib.md5() can only be update()d with an encoded string in py3.
- There's no dict.iteritems(), change to dict.items() (which is already
an iterator).
- Open temp files with 'w+' mode rather than the default 'w+b' (as an
alternative to encoding all the write and expected-read payloads as
bytes).
- (This is a weird one) Explicitly raise SkipTest from unittest (rather
than unittest2, which is where cls.skipException landed). Not sure why
this is busted, but this moves the ball.
Conflict/issue with raising SkipTest on this branch.
(cherry picked from commit f1d742f32adeb662a3fdf8fa3ef3bc391e71ed81)
(cherry picked from commit b866202f54afddca66a77cd989b082e193a96956)
Includes squash of:
Before writing object data to stdout, re-open it in binary mode
Otherwise, you can hit TypeErrors on Python3.
Closes-Bug: 1775482
(cherry picked from commit 415b48056d9d021e04ec972029040a89a6b13928)
Conflicts:
openstackclient/tests/functional/identity/v3/common.py
NOTE(melwitt): The conflicts are due to the following changes not in
Queens:
Id8377363f7a3248b45aeeba21d2acc02684a0305
I7c44bbb60557378b66c5c43a7ba917f40dc2b633
Change-Id: Ic9b2b47848a600e87a3674289ae7ae8c3e091fee
(cherry picked from commit 47f0277208362a3224f8e587bbdd60dd5aebf846)
7 files changed, 35 insertions, 10 deletions
diff --git a/openstackclient/api/object_store_v1.py b/openstackclient/api/object_store_v1.py index 31033525..d1e5dfaf 100644 --- a/openstackclient/api/object_store_v1.py +++ b/openstackclient/api/object_store_v1.py @@ -378,8 +378,9 @@ class APIv1(api.BaseAPI): ) if response.status_code == 200: if file == '-': - for chunk in response.iter_content(64 * 1024): - sys.stdout.write(chunk) + with os.fdopen(sys.stdout.fileno(), 'wb') as f: + for chunk in response.iter_content(64 * 1024): + f.write(chunk) else: if not os.path.exists(os.path.dirname(file)): if len(os.path.dirname(file)) > 0: diff --git a/openstackclient/tests/functional/common/test_help.py b/openstackclient/tests/functional/common/test_help.py index 7f274099..88f7ddbd 100644 --- a/openstackclient/tests/functional/common/test_help.py +++ b/openstackclient/tests/functional/common/test_help.py @@ -80,7 +80,7 @@ class HelpTests(base.TestCase): """Check help commands without auth info.""" # Pop all auth info. os.environ will be changed in loop, so do not # replace os.environ.keys() to os.environ - for key in os.environ.keys(): + for key in list(os.environ): if key.startswith('OS_'): self.useFixture(fixtures.EnvironmentVariable(key, None)) diff --git a/openstackclient/tests/functional/compute/v2/test_agent.py b/openstackclient/tests/functional/compute/v2/test_agent.py index 1a112e82..25d8c868 100644 --- a/openstackclient/tests/functional/compute/v2/test_agent.py +++ b/openstackclient/tests/functional/compute/v2/test_agent.py @@ -21,10 +21,10 @@ class ComputeAgentTests(base.TestCase): # Generate two different md5hash MD5HASH1 = hashlib.md5() - MD5HASH1.update('agent_1') + MD5HASH1.update('agent_1'.encode('utf-8')) MD5HASH1 = MD5HASH1.hexdigest() MD5HASH2 = hashlib.md5() - MD5HASH2.update('agent_2') + MD5HASH2.update('agent_2'.encode('utf-8')) MD5HASH2 = MD5HASH2.hexdigest() def test_compute_agent_delete(self): diff --git a/openstackclient/tests/functional/compute/v2/test_keypair.py b/openstackclient/tests/functional/compute/v2/test_keypair.py index 9a88e66f..42f334a4 100644 --- a/openstackclient/tests/functional/compute/v2/test_keypair.py +++ b/openstackclient/tests/functional/compute/v2/test_keypair.py @@ -88,7 +88,7 @@ class KeypairTests(KeypairBase): 1) Create keypair with given public key 2) Delete keypair """ - with tempfile.NamedTemporaryFile() as f: + with tempfile.NamedTemporaryFile(mode='w+') as f: f.write(self.PUBLIC_KEY) f.flush() @@ -108,7 +108,7 @@ class KeypairTests(KeypairBase): 1) Create keypair with private key file 2) Delete keypair """ - with tempfile.NamedTemporaryFile() as f: + with tempfile.NamedTemporaryFile(mode='w+') as f: cmd_output = json.loads(self.openstack( 'keypair create -f json --private-key %s tmpkey' % f.name, )) diff --git a/openstackclient/tests/functional/object/v1/test_object.py b/openstackclient/tests/functional/object/v1/test_object.py index 226ef8ad..b3f23e52 100644 --- a/openstackclient/tests/functional/object/v1/test_object.py +++ b/openstackclient/tests/functional/object/v1/test_object.py @@ -33,7 +33,7 @@ class ObjectTests(common.ObjectStoreTests): self.skipTest("No object-store service present") def test_object(self): - with tempfile.NamedTemporaryFile() as f: + with tempfile.NamedTemporaryFile(mode='w+') as f: f.write('test content') f.flush() self._test_object(f.name) diff --git a/openstackclient/tests/unit/object/v1/test_object_all.py b/openstackclient/tests/unit/object/v1/test_object_all.py index 363f2ea2..08a7534d 100644 --- a/openstackclient/tests/unit/object/v1/test_object_all.py +++ b/openstackclient/tests/unit/object/v1/test_object_all.py @@ -241,7 +241,25 @@ class TestObjectSave(TestObjectAll): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('sys.stdout', new=six.BytesIO()) as fake_stdout: + class FakeStdout(six.BytesIO): + def __init__(self): + six.BytesIO.__init__(self) + self.context_manager_calls = [] + + def __enter__(self): + self.context_manager_calls.append('__enter__') + return self + + def __exit__(self, *a): + self.context_manager_calls.append('__exit__') + + with mock.patch('sys.stdout') as fake_stdout, mock.patch( + 'os.fdopen', return_value=FakeStdout()) as fake_fdopen: + fake_stdout.fileno.return_value = 123 self.cmd.take_action(parsed_args) - self.assertEqual(fake_stdout.getvalue(), object_fakes.object_1_content) + self.assertEqual(fake_fdopen.return_value.getvalue(), + object_fakes.object_1_content) + self.assertEqual(fake_fdopen.mock_calls, [mock.call(123, 'wb')]) + self.assertEqual(fake_fdopen.return_value.context_manager_calls, + ['__enter__', '__exit__']) diff --git a/releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml b/releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml new file mode 100644 index 00000000..88d9890a --- /dev/null +++ b/releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Re-open stdout in binary mode before writing object data in + ``object save --file -`` command. + [Bug `1775482 <https://bugs.launchpad.net/python-openstackclient/+bug/1775482>`_] |
