summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorSimon Westphahl <simon.westphahl@bmw.de>2022-03-08 12:00:06 +0100
committerSimon Westphahl <simon.westphahl@bmw.de>2022-03-09 08:20:52 +0100
commitc3796915332956393c872b89189369b03c7a3dc1 (patch)
tree9fc2587a70ee383e33c41615c4ae33476d1a7f42 /tests
parent6f122dc18d9abb1a05de5dfecb6d3e0c3d647a7d (diff)
downloadzuul-c3796915332956393c872b89189369b03c7a3dc1.tar.gz
Include original path of renamed file for a PR
When a file is moved/renamed Github will only return an entry for the file with the new name. However, the previous path also needs to be included in the list of files. This is especially important when a Zuul config file is renamed but also when `job.[irrelevant-]files` is used. Change-Id: Ieba250bed57c8a9c2e7811476c202d530f2b30f1
Diffstat (limited to 'tests')
-rw-r--r--tests/base.py35
-rw-r--r--tests/fakegithub.py17
-rw-r--r--tests/unit/test_github_driver.py13
3 files changed, 51 insertions, 14 deletions
diff --git a/tests/base.py b/tests/base.py
index 262e2d595..fc30c0882 100644
--- a/tests/base.py
+++ b/tests/base.py
@@ -2239,11 +2239,15 @@ class GithubChangeReference(git.Reference):
class FakeGithubPullRequest(object):
def __init__(self, github, number, project, branch,
- subject, upstream_root, files=[], number_of_commits=1,
+ subject, upstream_root, files=None, number_of_commits=1,
writers=[], body=None, body_text=None, draft=False,
base_sha=None):
"""Creates a new PR with several commits.
- Sends an event about opened PR."""
+ Sends an event about opened PR.
+
+ If the `files` argument is provided it must be a dictionary of
+ file names OR FakeFile instances -> content.
+ """
self.github = github
self.source = github
self.number = number
@@ -2255,7 +2259,8 @@ class FakeGithubPullRequest(object):
self.draft = draft
self.number_of_commits = 0
self.upstream_root = upstream_root
- self.files = []
+ # Dictionary of FakeFile -> content
+ self.files = {}
self.comments = []
self.labels = []
self.statuses = {}
@@ -2272,12 +2277,12 @@ class FakeGithubPullRequest(object):
self._addCommitToRepo(files=files)
self._updateTimeStamp()
- def addCommit(self, files=[]):
+ def addCommit(self, files=None):
"""Adds a commit on top of the actual PR head."""
self._addCommitToRepo(files=files)
self._updateTimeStamp()
- def forcePush(self, files=[]):
+ def forcePush(self, files=None):
"""Clears actual commits and add a commit on top of the base."""
self._addCommitToRepo(files=files, reset=True)
self._updateTimeStamp()
@@ -2443,7 +2448,7 @@ class FakeGithubPullRequest(object):
GithubChangeReference.create(
repo, self.getPRReference(), base_sha)
- def _addCommitToRepo(self, files=[], reset=False):
+ def _addCommitToRepo(self, files=None, reset=False):
repo = self._getRepo()
ref = repo.references[self.getPRReference()]
if reset:
@@ -2455,13 +2460,23 @@ class FakeGithubPullRequest(object):
repo.git.clean('-x', '-f', '-d')
if files:
- self.files = files
+ # Normalize the dictionary of 'Union[str,FakeFile] -> content'
+ # to 'FakeFile -> content'.
+ normalized_files = {}
+ for fn, content in files.items():
+ if isinstance(fn, tests.fakegithub.FakeFile):
+ normalized_files[fn] = content
+ else:
+ normalized_files[tests.fakegithub.FakeFile(fn)] = content
+ self.files = normalized_files
else:
fn = '%s-%s' % (self.branch.replace('/', '_'), self.number)
- self.files = {fn: "test %s %s\n" % (self.branch, self.number)}
+ content = f"test {self.branch} {self.number}\n"
+ self.files = {tests.fakegithub.FakeFile(fn): content}
+
msg = self.subject + '-' + str(self.number_of_commits)
- for fn, content in self.files.items():
- fn = os.path.join(repo.working_dir, fn)
+ for fake_file, content in self.files.items():
+ fn = os.path.join(repo.working_dir, fake_file.filename)
with open(fn, 'w') as f:
f.write(content)
repo.index.add([fn])
diff --git a/tests/fakegithub.py b/tests/fakegithub.py
index d5252bd44..ad8c48542 100644
--- a/tests/fakegithub.py
+++ b/tests/fakegithub.py
@@ -13,6 +13,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
+import functools
import urllib
from collections import defaultdict
@@ -468,9 +469,20 @@ class FakeIssue(object):
return self._fake_pull_request.number
+@functools.total_ordering
class FakeFile(object):
- def __init__(self, filename):
+ def __init__(self, filename, previous_filename=None):
self.filename = filename
+ if previous_filename is not None:
+ self.previous_filename = previous_filename
+
+ def __eq__(self, other):
+ return self.filename == other.filename
+
+ def __lt__(self, other):
+ return self.filename < other.filename
+
+ __hash__ = object.__hash__
class FakePull(object):
@@ -482,8 +494,7 @@ class FakePull(object):
def files(self):
# Github lists max. 300 files of a PR in alphabetical order
- return [FakeFile(fn)
- for fn in sorted(self._fake_pull_request.files)][:300]
+ return sorted(self._fake_pull_request.files)[:300]
def reviews(self):
return self._fake_pull_request.reviews
diff --git a/tests/unit/test_github_driver.py b/tests/unit/test_github_driver.py
index 80e99cbc9..f8c693e0e 100644
--- a/tests/unit/test_github_driver.py
+++ b/tests/unit/test_github_driver.py
@@ -25,7 +25,7 @@ from unittest import mock, skip
import git
import github3.exceptions
-from tests.fakegithub import FakeGithubEnterpriseClient
+from tests.fakegithub import FakeFile, FakeGithubEnterpriseClient
from zuul.driver.github.githubconnection import GithubShaCache
from zuul.zk.layout import LayoutState
from zuul.lib import strings
@@ -171,6 +171,17 @@ class TestGithubDriver(ZuulTestCase):
changes="%s,%s" % (A.number, A.head_sha)),
])
+ @simple_layout('layouts/files-github.yaml', driver='github')
+ def test_pull_file_rename(self):
+ A = self.fake_github.openFakePullRequest(
+ 'org/project', 'master', 'A', files={
+ FakeFile("moved", previous_filename="foobar-requires"): "test"
+ })
+
+ self.fake_github.emitEvent(A.getPullRequestOpenedEvent())
+ self.waitUntilSettled()
+ self.assertEqual(1, len(self.history))
+
@simple_layout('layouts/basic-github.yaml', driver='github')
def test_pull_github_files_error(self):
A = self.fake_github.openFakePullRequest(