From a93d9fed2fed5c88d7bbf2d843159173b829d27c Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Sep 25 2025 21:45:22 +0000 Subject: [PATCH 1/5] avoid mocking open in test_download_file --- diff --git a/tests/test_cli/test_download_file.py b/tests/test_cli/test_download_file.py index 955adfe..4bb2d06 100644 --- a/tests/test_cli/test_download_file.py +++ b/tests/test_cli/test_download_file.py @@ -15,14 +15,6 @@ import unittest from koji_cli.lib import download_file, _download_progress -def mock_open(): - """Return the right patch decorator for open""" - if six.PY2: - return mock.patch('__builtin__.open') - else: - return mock.patch('builtins.open') - - class TestDownloadFile(unittest.TestCase): # Show long diffs in error output... maxDiff = None @@ -61,10 +53,8 @@ class TestDownloadFile(unittest.TestCase): @mock.patch('os.utime') @mock.patch('os.unlink') - @mock_open() - def test_handle_download_file(self, m_open, os_unlink, os_utime): + def test_handle_download_file(self, os_unlink, os_utime): self.reset_mock() - m_open.return_value.tell.return_value = 0 rsp_head = self.head.return_value rsp_head.status_code = 200 rsp_head.headers = {'Content-Length': '5'} @@ -74,7 +64,7 @@ class TestDownloadFile(unittest.TestCase): '5', # content-length 'Thu, 02 Mar 2023 11:21:12 GMT', # last-modified ] - response.iter_content.return_value = ['abcde'] + response.iter_content.return_value = [six.b('abcde')] rv = download_file("http://url", self.filename) @@ -88,16 +78,14 @@ class TestDownloadFile(unittest.TestCase): self.assertIsNone(rv) @mock.patch('os.unlink') - @mock_open() - def test_handle_download_file_undefined_length(self, m_open, os_unlink): + def test_handle_download_file_undefined_length(self, os_unlink): self.reset_mock() - m_open.return_value.tell.return_value = 0 rsp_head = self.head.return_value rsp_head.status_code = 200 rsp_head.headers = {'Content-Length': str(65536 * 2)} response = mock.MagicMock() response.headers.get.return_value = None # content-length - response.iter_content.return_value = ['a' * 65536, 'b' * 65536] + response.iter_content.return_value = [six.b('a' * 65536), six.b('b' * 65536)] self.get_mock.return_value = response rv = download_file("http://url", self.filename) @@ -108,7 +96,6 @@ class TestDownloadFile(unittest.TestCase): self.assertMultiLineEqual(actual, expected) self.get_mock.assert_called_once() - m_open.assert_called_once() response.headers.get.assert_called_once() response.iter_content.assert_called_once() self.assertIsNone(rv) From 77cd4546b53aee8e43d0c100a2980496d51ae4d4 Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Sep 25 2025 21:45:22 +0000 Subject: [PATCH 2/5] avoid mocking os.path in test_list_tagged.py --- diff --git a/tests/test_cli/test_list_tagged.py b/tests/test_cli/test_list_tagged.py index 52f179a..04fb9b0 100644 --- a/tests/test_cli/test_list_tagged.py +++ b/tests/test_cli/test_list_tagged.py @@ -1,4 +1,6 @@ import os +import shutil +import tempfile import time try: @@ -7,6 +9,7 @@ except ImportError: import mock import six +from koji import PathInfo from koji_cli.commands import anon_handle_list_tagged from . import utils @@ -14,6 +17,9 @@ from . import utils class TestCliListTagged(utils.CliTestCase): def setUp(self): + self.tempdir = tempfile.mkdtemp() + self.pathinfo = PathInfo(self.tempdir) + mock.patch('koji.pathinfo', new=self.pathinfo).start() self.maxDiff = None self.original_timezone = os.environ.get('TZ') os.environ['TZ'] = 'US/Eastern' @@ -30,56 +36,51 @@ class TestCliListTagged(utils.CliTestCase): self.event_id = 1000 self.type = 'maven' self.session.getTag.return_value = {'id': 1} - self.session.listTaggedRPMS.return_value = [[{'id': 100, - 'build_id': 1, - 'name': 'rpmA', - 'version': '0.0.1', - 'release': '1.el6', - 'arch': 'noarch', - 'sigkey': 'sigkey', - 'extra': 'extra-value'}, - {'id': 101, - 'build_id': 1, - 'name': 'rpmA', - 'version': '0.0.1', - 'release': '1.el6', - 'arch': 'x86_64', - 'sigkey': 'sigkey', - 'extra': None}, - {'id': 102, - 'build_id': 2, - 'name': 'rpmA', - 'version': '0.0.1', - 'release': '2.el6', - 'arch': 'x86_64', - 'sigkey': 'sigkey', - 'draft': True, - 'extra': None} - ], [{'id': 1, - 'name': 'packagename', - 'version': 'version', - 'release': '1.el6', - 'nvr': 'n-v-r', - 'tag_name': 'tag', - 'owner_name': 'owner', - 'extra': 'extra-value-2'}, - {'id': 2, - 'name': 'packagename', - 'version': 'version', - 'release': '2.el6,draft_2', - 'nvr': 'n-v-r', - 'draft': True, - 'tag_name': 'tag', - 'owner_name': 'owner', - 'extra': 'extra-value-2'}]] - self.session.listTagged.return_value = [{'id': 1, - 'name': 'packagename', - 'version': 'version', - 'release': '1.el6', - 'nvr': 'n-v-r', - 'tag_name': 'tag', - 'owner_name': 'owner', - 'extra': 'extra-value-2'}] + self.rpms = [{'id': 100, + 'build_id': 1, + 'name': 'rpmA', + 'version': '0.0.1', + 'release': '1.el6', + 'arch': 'noarch', + 'sigkey': 'sigkey', + 'extra': 'extra-value'}, + {'id': 101, + 'build_id': 1, + 'name': 'rpmA', + 'version': '0.0.1', + 'release': '1.el6', + 'arch': 'x86_64', + 'sigkey': 'sigkey', + 'extra': None}, + {'id': 102, + 'build_id': 2, + 'name': 'rpmA', + 'version': '0.0.1', + 'release': '2.el6', + 'arch': 'x86_64', + 'sigkey': 'sigkey', + 'draft': True, + 'extra': None} + ] + self.builds = [{'id': 1, + 'name': 'packagename', + 'version': 'version', + 'release': '1.el6', + 'nvr': 'n-v-r', + 'tag_name': 'tag', + 'owner_name': 'owner', + 'extra': 'extra-value-2'}, + {'id': 2, + 'name': 'packagename', + 'version': 'version', + 'release': '2.el6,draft_2', + 'nvr': 'n-v-r', + 'draft': True, + 'tag_name': 'tag', + 'owner_name': 'owner', + 'extra': 'extra-value-2'}] + self.session.listTaggedRPMS.return_value = [self.rpms, self.builds] + self.session.listTagged.return_value = [self.builds[0]] # XXX self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start() def tearDown(self): @@ -89,6 +90,7 @@ class TestCliListTagged(utils.CliTestCase): os.environ['TZ'] = self.original_timezone time.tzset() mock.patch.stopall() + shutil.rmtree(self.tempdir) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji.util.eventFromOpts', return_value={'id': 1000, @@ -147,11 +149,9 @@ sigkey rpmA-0.0.1-2.el6.x86_64 (,draft_2) self.session.listTagged.assert_not_called() self.assert_console_message(stdout, expected) - @mock.patch('os.path.isdir', return_value=True) - @mock.patch('os.path.exists', return_value=True) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji.util.eventFromOpts', return_value=None) - def test_list_tagged_rpms_paths(self, event_from_opts_mock, stdout, os_path_exists, isdir): + def test_list_tagged_rpms_paths(self, event_from_opts_mock, stdout): expected = """/mnt/koji/packages/packagename/version/1.el6/noarch/rpmA-0.0.1-1.el6.noarch.rpm /mnt/koji/packages/packagename/version/1.el6/x86_64/rpmA-0.0.1-1.el6.x86_64.rpm /mnt/koji/packages/packagename/version/2.el6,draft_2/x86_64/rpmA-0.0.1-2.el6.x86_64.rpm @@ -166,15 +166,14 @@ sigkey rpmA-0.0.1-2.el6.x86_64 (,draft_2) self.tag, package=self.pkg, inherit=None, latest=3, arch=['x86_64']) self.session.listTagged.assert_not_called() - @mock.patch('os.path.exists') @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji.util.eventFromOpts', return_value=None) - def test_list_tagged_sigs_paths(self, event_from_opts_mock, stdout, os_path_exists): + def test_list_tagged_sigs_paths(self, event_from_opts_mock, stdout): expected = "" args = [self.tag, self.pkg, '--latest-n=3', '--rpms', '--sigs', '--arch=x86_64', '--paths'] + # TODO - write fake signed copies to tempdir - os_path_exists.side_effect = [True, False, False] anon_handle_list_tagged(self.options, self.session, args) self.assert_console_message(stdout, expected) self.ensure_connection_mock.assert_called_once_with(self.session, self.options) From a2a82efa7e4af883be253207d02fe6a574e00afa Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Sep 25 2025 21:45:22 +0000 Subject: [PATCH 3/5] tweak mock data --- diff --git a/tests/test_cli/test_list_tagged.py b/tests/test_cli/test_list_tagged.py index 04fb9b0..3a006b8 100644 --- a/tests/test_cli/test_list_tagged.py +++ b/tests/test_cli/test_list_tagged.py @@ -74,13 +74,13 @@ class TestCliListTagged(utils.CliTestCase): 'name': 'packagename', 'version': 'version', 'release': '2.el6,draft_2', - 'nvr': 'n-v-r', + 'nvr': 'n-v-r,draft_2', 'draft': True, 'tag_name': 'tag', 'owner_name': 'owner', 'extra': 'extra-value-2'}] self.session.listTaggedRPMS.return_value = [self.rpms, self.builds] - self.session.listTagged.return_value = [self.builds[0]] # XXX + self.session.listTagged.return_value = self.builds self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start() def tearDown(self): @@ -103,6 +103,7 @@ n-v-r tag owner """ args = [self.tag, self.pkg, '--no-draft', '--latest', '--inherit', '--event', str(self.event_id)] + self.session.listTagged.return_value = [self.builds[0]] # no draft build anon_handle_list_tagged(self.options, self.session, args) self.ensure_connection_mock.assert_called_once_with(self.session, self.options) @@ -118,9 +119,10 @@ n-v-r tag owner def test_list_tagged_builds_paths(self, event_from_opts_mock, stdout): expected = """Build Tag Built by ---------------------------------------- -------------------- ---------------- -/mnt/koji/packages/packagename/version/1.el6 tag owner +/mnt/koji/packages/packagename/version/2.el6,draft_2 tag owner """ args = [self.tag, self.pkg, '--latest', '--inherit', '--paths', '--draft-only'] + self.session.listTagged.return_value = [self.builds[1]] # just the draft build anon_handle_list_tagged(self.options, self.session, args) self.assert_console_message(stdout, expected) From cab4bf70f20b9e3436119266d05d1f54954dca2b Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Sep 29 2025 15:02:57 +0000 Subject: [PATCH 4/5] also mock BASEDIR --- diff --git a/tests/test_cli/test_list_tagged.py b/tests/test_cli/test_list_tagged.py index 3a006b8..6e44331 100644 --- a/tests/test_cli/test_list_tagged.py +++ b/tests/test_cli/test_list_tagged.py @@ -18,8 +18,10 @@ class TestCliListTagged(utils.CliTestCase): def setUp(self): self.tempdir = tempfile.mkdtemp() + os.mkdir(self.tempdir + '/packages') self.pathinfo = PathInfo(self.tempdir) mock.patch('koji.pathinfo', new=self.pathinfo).start() + mock.patch('koji.BASEDIR', new=self.tempdir).start() self.maxDiff = None self.original_timezone = os.environ.get('TZ') os.environ['TZ'] = 'US/Eastern' From 0b83bcf3ac4b8fabe27ab2f52a41004b68c046a8 Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Sep 29 2025 15:42:41 +0000 Subject: [PATCH 5/5] fix fallout --- diff --git a/tests/test_cli/test_list_tagged.py b/tests/test_cli/test_list_tagged.py index 6e44331..f3df409 100644 --- a/tests/test_cli/test_list_tagged.py +++ b/tests/test_cli/test_list_tagged.py @@ -121,8 +121,8 @@ n-v-r tag owner def test_list_tagged_builds_paths(self, event_from_opts_mock, stdout): expected = """Build Tag Built by ---------------------------------------- -------------------- ---------------- -/mnt/koji/packages/packagename/version/2.el6,draft_2 tag owner -""" +%s/packages/packagename/version/2.el6,draft_2 tag owner +""" % self.tempdir args = [self.tag, self.pkg, '--latest', '--inherit', '--paths', '--draft-only'] self.session.listTagged.return_value = [self.builds[1]] # just the draft build @@ -156,10 +156,12 @@ sigkey rpmA-0.0.1-2.el6.x86_64 (,draft_2) @mock.patch('sys.stdout', new_callable=six.StringIO) @mock.patch('koji.util.eventFromOpts', return_value=None) def test_list_tagged_rpms_paths(self, event_from_opts_mock, stdout): - expected = """/mnt/koji/packages/packagename/version/1.el6/noarch/rpmA-0.0.1-1.el6.noarch.rpm -/mnt/koji/packages/packagename/version/1.el6/x86_64/rpmA-0.0.1-1.el6.x86_64.rpm -/mnt/koji/packages/packagename/version/2.el6,draft_2/x86_64/rpmA-0.0.1-2.el6.x86_64.rpm -""" + expected = ''.join(["%s/%s\n" % (self.tempdir, p) for p in + ["packages/packagename/version/1.el6/noarch/rpmA-0.0.1-1.el6.noarch.rpm", + "packages/packagename/version/1.el6/x86_64/rpmA-0.0.1-1.el6.x86_64.rpm", + "packages/packagename/version/2.el6,draft_2/x86_64/rpmA-0.0.1-2.el6.x86_64.rpm", + ] + ]) args = [self.tag, self.pkg, '--latest-n=3', '--rpms', '--arch=x86_64', '--paths'] anon_handle_list_tagged(self.options, self.session, args) @@ -217,8 +219,8 @@ n-v-r tag group def test_list_tagged_type_paths(self, event_from_opts_mock, stdout): expected = """Build Tag Group Id Artifact Id Built by ---------------------------------------- -------------------- -------------------- -------------------- ---------------- -/mnt/koji/packages/packagename/version/1.el6/maven tag group artifact owner -""" +%s/packages/packagename/version/1.el6/maven tag group artifact owner +""" % self.tempdir args = [self.tag, self.pkg, '--latest-n=3', '--type', self.type, '--paths'] self.session.listTagged.return_value = [{'id': 1, 'name': 'packagename',