Files
mongo/buildscripts/bazel_rules_mongo/tests/test_changed_files.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

170 lines
6.3 KiB
Python
Raw Normal View History

import os
import platform
import shutil
import sys
import tempfile
import unittest
from git import Repo
from mock import MagicMock
from buildscripts.bazel_rules_mongo.utils import evergreen_git
changed_file_name = "changed_file.txt"
new_file_name = "new_file.txt"
def write_file(repo: Repo, file_name: str) -> None:
# just adding more text to the file so git thinks it has changed or is created
with open(os.path.join(repo.working_tree_dir, file_name), "a+") as file:
file.write("change\n")
@unittest.skipIf(
sys.platform == "win32" or platform.machine().lower() in {"ppc64le", "s390x"},
reason="This test breaks on windows and only needs to work on linux",
)
class TestChangedFiles(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.tmp_dir = tempfile.mkdtemp()
root_repo = Repo()
# commit of HEAD
commit = root_repo.head.commit.hexsha
files_to_copy = set()
# copy the current repo into a temp dir to do testing on
root_repo.git.execute(["git", "worktree", "add", cls.tmp_dir, commit])
# get tracked files that have been changed that are tracked by git
diff_output = root_repo.git.execute(
["git", "diff", "--name-only", "--diff-filter=d", commit]
)
files_to_copy.update(diff_output.split("\n"))
# gets all the untracked changes in the current repo
untracked_changes = root_repo.git.execute(["git", "add", ".", "-n"])
for line in untracked_changes.split("\n"):
if not line:
continue
files_to_copy.add(line.strip()[5:-1])
# copy all changed files from the current repo to the new worktree for testing.
for file in files_to_copy:
if not file:
continue
if not os.path.exists(file):
raise RuntimeError(f"Changed file was found and does not exist: {file}")
# This means the file is an embeded git repo, this happens when other evergreen modules
# are present, we can just ignore them
if os.path.isdir(file):
continue
new_dest = os.path.join(cls.tmp_dir, file)
os.makedirs(os.path.dirname(new_dest), exist_ok=True)
shutil.copy(file, new_dest)
cls.repo = Repo(cls.tmp_dir)
# add a testing file to this original commit so we can treat it as a preexisting file that
# is going to be modified
write_file(cls.repo, changed_file_name)
cls.repo.git.execute(["git", "add", "."])
cls.repo.git.execute(["git", "commit", "-m", "Commit changed files"])
# this new commit is out base revision to compare changes against
cls.base_revision = cls.repo.head.commit.hexsha
cls.original_dir = os.path.abspath(os.curdir)
os.chdir(cls.tmp_dir)
@classmethod
def tearDownClass(cls):
os.chdir(cls.original_dir)
shutil.rmtree(cls.tmp_dir)
def setUp(self):
# change the file already commited to the repo
write_file(self.repo, changed_file_name)
# make a new file that has not been commited yet
write_file(self.repo, new_file_name)
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=False) as tmp:
tmp.write("fake_expansion: true\n")
self.expansions_file = tmp.name
def tearDown(self):
# reset to the original state between tests
self.repo.git.execute(["git", "reset", "--hard", self.base_revision])
os.unlink(self.expansions_file)
def test_local_unchanged_files(self):
evergreen_git.get_remote_branch_ref = MagicMock(return_value=self.base_revision)
new_files = evergreen_git.get_new_files()
self.assertEqual(
new_files, [], msg="New files list was not empty when no new files were added to git."
)
changed_files = evergreen_git.get_changed_files()
self.assertEqual(
changed_files, [changed_file_name], msg="Changed file list was not as expected."
)
self.repo.git.execute(["git", "add", "."])
# random file not tracked by git
write_file(self.repo, "random_other_untracked_file.txt")
new_files = evergreen_git.get_new_files()
self.assertEqual(
new_files,
[new_file_name],
msg="New file list did not contain the new file added to git.",
)
changed_files = evergreen_git.get_changed_files()
self.assertEqual(
changed_files,
[changed_file_name, new_file_name],
msg="Changed file list was not as expected.",
)
def test_evergreen_patch(self):
# the files in evergreen patches live as uncommited files added to the index
with open(self.expansions_file, "a") as tmp:
tmp.write("is_patch: true\n")
tmp.write(f"revision: {self.base_revision}\n")
self.repo.git.execute(["git", "add", "."])
new_files = evergreen_git.get_new_files(expansions_file=self.expansions_file)
self.assertEqual(
new_files, [new_file_name], msg="New file list did not contain the new file."
)
changed_files = evergreen_git.get_changed_files(expansions_file=self.expansions_file)
self.assertEqual(
changed_files,
[changed_file_name, new_file_name],
msg="Changed file list was not as expected.",
)
def test_evergreen_waterfall(self):
# Evergreen waterfall runs just check against the last commit so we need to commit the changes
self.repo.git.execute(["git", "add", "."])
self.repo.git.execute(["git", "commit", "-m", "Fake waterfall changes"])
new_files = evergreen_git.get_new_files(expansions_file=self.expansions_file)
self.assertEqual(
new_files, [new_file_name], msg="New file list did not contain the new file."
)
changed_files = evergreen_git.get_changed_files(expansions_file=self.expansions_file)
self.assertEqual(
changed_files,
[changed_file_name, new_file_name],
msg="Changed file list was not as expected.",
)
def test_remote_picker(self):
remote = evergreen_git.get_mongodb_remote(self.repo)
self.assertIn("10gen/mongo", remote.url, msg="The wrong remote was found.")