From ffa01d37cab3cc876b3a15069146d177d33d8640 Mon Sep 17 00:00:00 2001 From: Renata Date: Wed, 18 Sep 2024 17:03:32 -0400 Subject: [PATCH 01/19] test, fix: add a test for origin and user's repos with divergent histories, fix removal of unpushed commits --- taf/git.py | 4 +- taf/tests/test_git/test_git.py | 6 +-- taf/tests/test_updater/conftest.py | 7 ++++ .../test_update/test_validation_and_sync.py | 37 ++++++++++++++++++- taf/tests/test_updater/update_utils.py | 18 ++++++--- taf/updater/updater_pipeline.py | 32 ++++++++++------ 6 files changed, 82 insertions(+), 22 deletions(-) diff --git a/taf/git.py b/taf/git.py index 3fa11dc3..96b36b5f 100644 --- a/taf/git.py +++ b/taf/git.py @@ -817,7 +817,7 @@ def checkout_commit(self, commit: str) -> None: reraise_error=True, ) - def is_branch_with_unpushed_commits(self, branch_name): + def branch_unpushed_commits(self, branch_name): repo = self.pygit_repo local_branch = repo.branches.get(branch_name) @@ -849,7 +849,7 @@ def is_branch_with_unpushed_commits(self, branch_name): else: break - return bool(unpushed_commits) + return [commit.id for commit in unpushed_commits] def commit(self, message: str) -> str: self._git("add -A") diff --git a/taf/tests/test_git/test_git.py b/taf/tests/test_git/test_git.py index be2145dd..ed15c8e6 100644 --- a/taf/tests/test_git/test_git.py +++ b/taf/tests/test_git/test_git.py @@ -11,14 +11,14 @@ def test_clone_from_local(repository, clone_repository): assert len(commits) -def test_is_branch_with_unpushed_commits(repository, clone_repository): +def test_branch_unpushed_commits(repository, clone_repository): clone_repository.clone_from_disk(repository.path, keep_remote=True) branch = clone_repository.branches()[0] clone_repository.reset_num_of_commits(1, True) - assert not clone_repository.is_branch_with_unpushed_commits(branch) + assert not clone_repository._branch_unpushed_commits(branch) (clone_repository.path / "test3.txt").write_text("Updated test3") clone_repository.commit(message="Update test3.txt") - assert clone_repository.is_branch_with_unpushed_commits(branch) + assert clone_repository._branch_unpushed_commits(branch) def test_is_git_repository_root_bare(repository): diff --git a/taf/tests/test_updater/conftest.py b/taf/tests/test_updater/conftest.py index 71e95fb6..993ee124 100644 --- a/taf/tests/test_updater/conftest.py +++ b/taf/tests/test_updater/conftest.py @@ -332,6 +332,8 @@ def _init_auth_repo( def initialize_git_repo(library_dir: Path, repo_name: str) -> GitRepository: repo_path = Path(library_dir, repo_name) + if repo_path.is_dir(): + shutil.rmtree(repo_path, onerror=on_rm_error) repo_path.mkdir(parents=True, exist_ok=True) repo = GitRepository(path=repo_path) repo.init_repo() @@ -495,6 +497,11 @@ def add_unauthenticated_commits_to_all_target_repos(target_repos: list): update_target_files(target_repo, "Update target files") +def add_unauthenticated_commits_to_target_repo(target_repos: list): + for target_repo in target_repos: + update_target_files(target_repo, "Update target files") + + def create_new_target_orphan_branches( auth_repo: AuthenticationRepository, target_repos: list, branch_name: str ): diff --git a/taf/tests/test_updater/test_update/test_validation_and_sync.py b/taf/tests/test_updater/test_update/test_validation_and_sync.py index 99beea9b..20d8fa13 100644 --- a/taf/tests/test_updater/test_update/test_validation_and_sync.py +++ b/taf/tests/test_updater/test_update/test_validation_and_sync.py @@ -265,7 +265,6 @@ def test_mixed_target_repo_states(origin_auth_repo, client_dir): updated_repo = client_target_repos[1] # target2 old_commit = reverted_repo.head_commit_sha() - # Add valid commits first to setup_manager.add_task(add_valid_target_commits) setup_manager.add_task( @@ -289,3 +288,39 @@ def test_mixed_target_repo_states(origin_auth_repo, client_dir): ) verify_client_repos_state(client_dir, origin_auth_repo) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [ + {"name": "target1", "allow_unauthenticated_commits": True}, + {"name": "target2", "allow_unauthenticated_commits": True}, + ], + } + ], + indirect=True, +) +def test_update_when_unauthenticated_allowed_different_commits_on_remote(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_unauthenticated_commits_to_all_target_repos) + setup_manager.execute_tasks() + + client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) + setup_manager = SetupManager(client_auth_repo) + setup_manager.add_task(add_unauthenticated_commits_to_all_target_repos) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + force=True, + num_of_commits_to_remove=1, + ) + diff --git a/taf/tests/test_updater/update_utils.py b/taf/tests/test_updater/update_utils.py index b0f74d09..9b6135f2 100644 --- a/taf/tests/test_updater/update_utils.py +++ b/taf/tests/test_updater/update_utils.py @@ -1,4 +1,5 @@ import os +import shutil import pytest from pathlib import Path from freezegun import freeze_time @@ -118,6 +119,8 @@ def clone_repositories( excluded_target_globs=None, ): + if clients_dir.is_dir(): + shutil.rmtree(clients_dir) config = UpdateConfig( operation=OperationType.CLONE, url=str(origin_auth_repo.path), @@ -159,14 +162,18 @@ def _get_valid_update_time(origin_auth_repo_path): return datetime.strptime(expires, "%Y-%m-%dT%H:%M:%SZ").date().strftime("%Y-%m-%d") -def _get_head_commit_shas(client_repos): +def _get_head_commit_shas(client_repos, num_of_commits_to_remove=0): start_head_shas = defaultdict(dict) if client_repos is not None: for repo_rel_path, repo in client_repos.items(): for branch in repo.branches(): - start_head_shas[repo_rel_path][branch] = repo.top_commit_of_branch( - branch - ) + if not num_of_commits_to_remove: + start_head_shas[repo_rel_path][branch] = repo.top_commit_of_branch( + branch + ) + else: + all_commits = repo.all_commits_on_branch(branch) + start_head_shas[repo_rel_path][branch] = all_commits[-num_of_commits_to_remove-1] return start_head_shas @@ -200,6 +207,7 @@ def update_and_check_commit_shas( bare=False, no_upstream=False, skip_check_last_validated=False, + num_of_commits_to_remove=0, ): client_repos = load_target_repositories(origin_auth_repo, clients_dir) client_repos = { @@ -212,7 +220,7 @@ def update_and_check_commit_shas( clients_auth_repo = GitRepository(path=clients_auth_repo_path) if clients_auth_repo_path.is_dir(): client_repos[clients_auth_repo.name] = clients_auth_repo - start_head_shas = _get_head_commit_shas(client_repos) + start_head_shas = _get_head_commit_shas(client_repos, num_of_commits_to_remove) config = UpdateConfig( operation=operation, diff --git a/taf/updater/updater_pipeline.py b/taf/updater/updater_pipeline.py index cd7c3bb7..bf4167ad 100644 --- a/taf/updater/updater_pipeline.py +++ b/taf/updater/updater_pipeline.py @@ -459,17 +459,15 @@ def check_if_local_repositories_clean(self): ) dirty_index_repos.append(auth_repo.name) - if auth_repo.is_branch_with_unpushed_commits(auth_repo.default_branch): + + unpushed_commits = auth_repo.branch_unpushed_commits(auth_repo.default_branch) + if unpushed_commits: if self.force: taf_logger.info( f"Resetting repository {auth_repo.name} to clean state for a forced update." ) - auth_repo.clean_and_reset() - last_remote_commit = auth_repo.get_last_remote_commit( - auth_repo.urls[0] - ) - if last_remote_commit: - auth_repo.reset_to_commit(last_remote_commit, hard=True) + _remove_unpushed_commtis(auth_repo, branch, unpushed_commits) + else: unpushed_commits_repos_and_branches.append( (auth_repo.name, auth_repo.default_branch) @@ -495,12 +493,13 @@ def check_if_local_repositories_clean(self): target = auth_repo.get_target(repository.name) if target and "branch" in target: branch = target["branch"] - if repository.is_branch_with_unpushed_commits(branch): + unpushed_commits = repository.branch_unpushed_commits(branch) + if unpushed_commits: if self.force: taf_logger.info( f"Resetting repository {repository.name} to clean state for a forced update." ) - repository.clean_and_reset() + _remove_unpushed_commtis(repository, branch, unpushed_commits) else: unpushed_commits_repos_and_branches.append( (repository.name, branch) @@ -513,7 +512,6 @@ def check_if_local_repositories_clean(self): raise MultipleRepositoriesNotCleanError( dirty_index_repos, unpushed_commits_repos_and_branches ) - return UpdateStatus.SUCCESS except Exception as e: self.state.errors.append(e) @@ -737,6 +735,7 @@ def validate_commit_in_remote(repo, commit_sha): f"Last validated commit {last_validated_commit} is not in the remote repository." ) else: + import pdb; pdb.set_trace() # Re-validate from the point of divergence commits_since = validation_repo.all_commits_since_commit( since_commit=last_validated_commit, branch=branch @@ -1027,6 +1026,7 @@ def fetch_commits(repository, branch, old_head): fetched_commits.index(old_head) + 1 : ] else: + import pdb; pdb.set_trace() fetched_commits_on_target_repo_branch = ( repository.all_commits_since_commit(old_head, branch) ) @@ -1034,6 +1034,7 @@ def fetch_commits(repository, branch, old_head): if commit not in fetched_commits_on_target_repo_branch: fetched_commits_on_target_repo_branch.append(commit) else: + import pdb; pdb.set_trace() fetched_commits_on_target_repo_branch = ( repository.all_commits_since_commit(old_head, branch) ) @@ -1111,7 +1112,8 @@ def check_if_local_target_repositories_clean(self): for branch in self.state.target_branches_data_from_auth_repo[ repository.name ]: - if repository.is_branch_with_unpushed_commits(branch): + + if repository.branch_unpushed_commits(branch): unpushed_commits_repos_and_branches_error.append( (repository.name, branch) ) @@ -1606,6 +1608,12 @@ def _is_unauthenticated_allowed(repository): return repository.custom.get("allow-unauthenticated-commits", False) +def _remove_unpushed_commtis(repository, branch, unpushed_commits): + repository.clean_and_reset() + repository.checkout_branch(branch) + repository.reset_num_of_commits(len(unpushed_commits), hard=True) + + def _run_tuf_updater(git_fetcher, auth_repo_name): auth_repo_name = auth_repo_name or "" taf_logger.info(f"{auth_repo_name}: Running TUF validation...") @@ -1808,3 +1816,5 @@ def _merge_commit(repository, branch, commit_to_merge, force_revert=True): format_commit(commit_to_merge), branch, ) + + From 372ded81d9436c58f88dd32db7ed4fb5530b9b01 Mon Sep 17 00:00:00 2001 From: Renata Date: Wed, 18 Sep 2024 17:04:13 -0400 Subject: [PATCH 02/19] chore: formatting --- .../test_update/test_validation_and_sync.py | 5 ++-- taf/tests/test_updater/update_utils.py | 4 +++- taf/updater/updater_pipeline.py | 23 ++++++++++++------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/taf/tests/test_updater/test_update/test_validation_and_sync.py b/taf/tests/test_updater/test_update/test_validation_and_sync.py index 20d8fa13..0263c792 100644 --- a/taf/tests/test_updater/test_update/test_validation_and_sync.py +++ b/taf/tests/test_updater/test_update/test_validation_and_sync.py @@ -302,7 +302,9 @@ def test_mixed_target_repo_states(origin_auth_repo, client_dir): ], indirect=True, ) -def test_update_when_unauthenticated_allowed_different_commits_on_remote(origin_auth_repo, client_dir): +def test_update_when_unauthenticated_allowed_different_commits_on_remote( + origin_auth_repo, client_dir +): clone_repositories( origin_auth_repo, client_dir, @@ -323,4 +325,3 @@ def test_update_when_unauthenticated_allowed_different_commits_on_remote(origin_ force=True, num_of_commits_to_remove=1, ) - diff --git a/taf/tests/test_updater/update_utils.py b/taf/tests/test_updater/update_utils.py index 9b6135f2..57944bf2 100644 --- a/taf/tests/test_updater/update_utils.py +++ b/taf/tests/test_updater/update_utils.py @@ -173,7 +173,9 @@ def _get_head_commit_shas(client_repos, num_of_commits_to_remove=0): ) else: all_commits = repo.all_commits_on_branch(branch) - start_head_shas[repo_rel_path][branch] = all_commits[-num_of_commits_to_remove-1] + start_head_shas[repo_rel_path][branch] = all_commits[ + -num_of_commits_to_remove - 1 + ] return start_head_shas diff --git a/taf/updater/updater_pipeline.py b/taf/updater/updater_pipeline.py index bf4167ad..acd3dfe8 100644 --- a/taf/updater/updater_pipeline.py +++ b/taf/updater/updater_pipeline.py @@ -459,8 +459,9 @@ def check_if_local_repositories_clean(self): ) dirty_index_repos.append(auth_repo.name) - - unpushed_commits = auth_repo.branch_unpushed_commits(auth_repo.default_branch) + unpushed_commits = auth_repo.branch_unpushed_commits( + auth_repo.default_branch + ) if unpushed_commits: if self.force: taf_logger.info( @@ -499,7 +500,9 @@ def check_if_local_repositories_clean(self): taf_logger.info( f"Resetting repository {repository.name} to clean state for a forced update." ) - _remove_unpushed_commtis(repository, branch, unpushed_commits) + _remove_unpushed_commtis( + repository, branch, unpushed_commits + ) else: unpushed_commits_repos_and_branches.append( (repository.name, branch) @@ -735,7 +738,9 @@ def validate_commit_in_remote(repo, commit_sha): f"Last validated commit {last_validated_commit} is not in the remote repository." ) else: - import pdb; pdb.set_trace() + import pdb + + pdb.set_trace() # Re-validate from the point of divergence commits_since = validation_repo.all_commits_since_commit( since_commit=last_validated_commit, branch=branch @@ -1026,7 +1031,9 @@ def fetch_commits(repository, branch, old_head): fetched_commits.index(old_head) + 1 : ] else: - import pdb; pdb.set_trace() + import pdb + + pdb.set_trace() fetched_commits_on_target_repo_branch = ( repository.all_commits_since_commit(old_head, branch) ) @@ -1034,7 +1041,9 @@ def fetch_commits(repository, branch, old_head): if commit not in fetched_commits_on_target_repo_branch: fetched_commits_on_target_repo_branch.append(commit) else: - import pdb; pdb.set_trace() + import pdb + + pdb.set_trace() fetched_commits_on_target_repo_branch = ( repository.all_commits_since_commit(old_head, branch) ) @@ -1816,5 +1825,3 @@ def _merge_commit(repository, branch, commit_to_merge, force_revert=True): format_commit(commit_to_merge), branch, ) - - From 08589fe9561c06edc5530d1bb5781987aa896e59 Mon Sep 17 00:00:00 2001 From: Renata Date: Wed, 18 Sep 2024 17:08:01 -0400 Subject: [PATCH 03/19] chore: fix branch name --- taf/updater/updater_pipeline.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/taf/updater/updater_pipeline.py b/taf/updater/updater_pipeline.py index acd3dfe8..49c5fc6a 100644 --- a/taf/updater/updater_pipeline.py +++ b/taf/updater/updater_pipeline.py @@ -467,7 +467,9 @@ def check_if_local_repositories_clean(self): taf_logger.info( f"Resetting repository {auth_repo.name} to clean state for a forced update." ) - _remove_unpushed_commtis(auth_repo, branch, unpushed_commits) + _remove_unpushed_commtis( + auth_repo, auth_repo.default_branch, unpushed_commits + ) else: unpushed_commits_repos_and_branches.append( From c9d7a88e2f4be51c2df9eba192f3fea25541da56 Mon Sep 17 00:00:00 2001 From: Renata Date: Wed, 18 Sep 2024 17:58:27 -0400 Subject: [PATCH 04/19] test: add a test for the case when one target repo completely empty --- taf/api/targets.py | 5 +++ taf/tests/test_git/test_git.py | 4 +-- taf/tests/test_updater/conftest.py | 24 +++++++++---- .../test_clone/test_clone_valid.py | 29 +++++++++++++++ .../test_update/test_update_valid.py | 35 +++++++++++++++++++ 5 files changed, 89 insertions(+), 8 deletions(-) diff --git a/taf/api/targets.py b/taf/api/targets.py index 34b59a95..6c1906e2 100644 --- a/taf/api/targets.py +++ b/taf/api/targets.py @@ -658,6 +658,11 @@ def _update_target_repos( return target_repo = GitRepository(path=target_repo_path) if target_repo.is_git_repository: + if target_repo.head_commit_sha() is None: + taf_logger.warning( + f"Repository {repo_path} does not have the HEAD reference" + ) + return data = {"commit": target_repo.head_commit_sha()} if add_branch: data["branch"] = target_repo.get_current_branch() diff --git a/taf/tests/test_git/test_git.py b/taf/tests/test_git/test_git.py index ed15c8e6..3015c3c3 100644 --- a/taf/tests/test_git/test_git.py +++ b/taf/tests/test_git/test_git.py @@ -15,10 +15,10 @@ def test_branch_unpushed_commits(repository, clone_repository): clone_repository.clone_from_disk(repository.path, keep_remote=True) branch = clone_repository.branches()[0] clone_repository.reset_num_of_commits(1, True) - assert not clone_repository._branch_unpushed_commits(branch) + assert not len(clone_repository.branch_unpushed_commits(branch)) (clone_repository.path / "test3.txt").write_text("Updated test3") clone_repository.commit(message="Update test3.txt") - assert clone_repository._branch_unpushed_commits(branch) + assert len(clone_repository.branch_unpushed_commits(branch)) def test_is_git_repository_root_bare(repository): diff --git a/taf/tests/test_updater/conftest.py b/taf/tests/test_updater/conftest.py index 993ee124..db2771b7 100644 --- a/taf/tests/test_updater/conftest.py +++ b/taf/tests/test_updater/conftest.py @@ -173,9 +173,15 @@ def execute_tasks(self): class RepositoryConfig: - def __init__(self, name: str, allow_unauthenticated_commits: bool = False): + def __init__( + self, + name: str, + allow_unauthenticated_commits: bool = False, + is_empty: bool = False, + ): self.name = name self.allow_unauthenticated_commits = allow_unauthenticated_commits + self.is_empty = is_empty @pytest.fixture @@ -209,6 +215,7 @@ def origin_auth_repo(request, test_name: str, origin_dir: Path): RepositoryConfig( f"{test_name}/{targets_config['name']}", targets_config.get("allow_unauthenticated_commits", False), + targets_config.get("is_empty", False), ) for targets_config in targets_config_list ] @@ -351,10 +358,11 @@ def initialize_target_repositories( else: target_repo = GitRepository(library_dir, target_config.name) # create some files, content of these repositories is not important - for i in range(1, 3): - random_text = _generate_random_text() - (target_repo.path / f"test{i}.txt").write_text(random_text) - target_repo.commit("Initial commit") + if not target_config.is_empty: + for i in range(1, 3): + random_text = _generate_random_text() + (target_repo.path / f"test{i}.txt").write_text(random_text) + target_repo.commit("Initial commit") def sign_target_repositories(library_dir: Path, repo_name: str, keystore: Path): @@ -480,8 +488,12 @@ def setup_repository_no_target_repositories( return AuthenticationRepository(origin_dir, repo_name) -def add_valid_target_commits(auth_repo: AuthenticationRepository, target_repos: list): +def add_valid_target_commits( + auth_repo: AuthenticationRepository, target_repos: list, add_if_empty: bool = True +): for target_repo in target_repos: + if not add_if_empty and target_repo.head_commit_sha() is None: + continue update_target_files(target_repo, "Update target files") sign_target_repositories(TEST_DATA_ORIGIN_PATH, auth_repo.name, KEYSTORE_PATH) diff --git a/taf/tests/test_updater/test_clone/test_clone_valid.py b/taf/tests/test_updater/test_clone/test_clone_valid.py index 36b21d8b..e2be25c9 100644 --- a/taf/tests/test_updater/test_clone/test_clone_valid.py +++ b/taf/tests/test_updater/test_clone/test_clone_valid.py @@ -12,6 +12,7 @@ ) from taf.tests.test_updater.update_utils import ( clone_client_target_repos_without_updater, + load_target_repositories, update_and_check_commit_shas, ) from taf.updater.types.update import OperationType, UpdateType @@ -316,3 +317,31 @@ def test_clone_valid_when_no_upstream_top_commits_unsigned( expected_repo_type=UpdateType.EITHER, no_upstream=True, ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [ + {"name": "notempty"}, + {"name": "empty", "is_empty": True}, + ], + }, + ], + indirect=True, +) +def test_clone_when_target_empty(origin_auth_repo, client_dir): + + update_and_check_commit_shas( + OperationType.CLONE, + origin_auth_repo, + client_dir, + expected_repo_type=UpdateType.EITHER, + ) + client_repos = load_target_repositories(origin_auth_repo, client_dir) + for name, repo in client_repos.items(): + if "notempty" in name: + assert repo.path.is_dir() + else: + assert not repo.path.is_dir() diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index 478fa0d7..fdaea313 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -729,3 +729,38 @@ def test_update_with_no_last_validated_commit(origin_auth_repo, client_dir): last_validated_commit_file.unlink() # Remove the file update_and_check_commit_shas(OperationType.UPDATE, origin_auth_repo, client_dir) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [ + {"name": "notempty"}, + {"name": "empty", "is_empty": True}, + ], + }, + ], + indirect=True, +) +def test_update_when_target_empty(origin_auth_repo, client_dir): + + clone_repositories(origin_auth_repo, client_dir) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits, kwargs={"add_if_empty": False}) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + skip_check_last_validated=True, + ) + + client_repos = load_target_repositories(origin_auth_repo, client_dir) + for name, repo in client_repos.items(): + if "notempty" in name: + assert repo.path.is_dir() + else: + assert not repo.path.is_dir() From 25a785a8ac95232ba9a51e8e8510e6e3d853555e Mon Sep 17 00:00:00 2001 From: Renata Date: Wed, 18 Sep 2024 18:08:28 -0400 Subject: [PATCH 05/19] fix: all commits since commit should not fail if repo is empty - no head --- taf/git.py | 13 ++++++++++++- taf/tests/test_git/conftest.py | 11 +++++++++++ taf/tests/test_git/test_git.py | 6 ++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/taf/git.py b/taf/git.py index 96b36b5f..78e809da 100644 --- a/taf/git.py +++ b/taf/git.py @@ -371,6 +371,11 @@ def all_commits_on_branch( ) latest_commit_id = branch_obj.target else: + if self.head_commit_sha() is None: + raise GitError( + self, + message=f"Error occurred while getting commits of branch {branch}. No HEAD reference", + ) latest_commit_id = repo[repo.head.target].id sort = pygit2.GIT_SORT_REVERSE if reverse else pygit2.GIT_SORT_NONE @@ -392,7 +397,11 @@ def all_commits_since_commit( """ if since_commit is None: - return self.all_commits_on_branch(branch=branch, reverse=reverse) + try: + return self.all_commits_on_branch(branch=branch, reverse=reverse) + except GitError as e: + self._log_warning(e) + return [] try: self.commit_exists(commit_sha=since_commit) @@ -407,6 +416,8 @@ def all_commits_since_commit( return [] latest_commit_id = branch_obj.target else: + if repo.head_commit_sha() is None: + return [] latest_commit_id = repo[repo.head.target].id if repo.descendant_of(since_commit, latest_commit_id): diff --git a/taf/tests/test_git/conftest.py b/taf/tests/test_git/conftest.py index a59b6f69..c328bf4c 100644 --- a/taf/tests/test_git/conftest.py +++ b/taf/tests/test_git/conftest.py @@ -41,3 +41,14 @@ def clone_repository(): yield repo repo.cleanup() shutil.rmtree(path, onerror=on_rm_error) + + +@fixture +def empty_repository(): + path = TEST_DIR / CLONE_REPO_NAME + path.mkdir(exist_ok=True, parents=True) + repo = GitRepository(path=path) + repo.init_repo() + yield repo + repo.cleanup() + shutil.rmtree(path, onerror=on_rm_error) diff --git a/taf/tests/test_git/test_git.py b/taf/tests/test_git/test_git.py index 3015c3c3..7968e140 100644 --- a/taf/tests/test_git/test_git.py +++ b/taf/tests/test_git/test_git.py @@ -41,3 +41,9 @@ def test_head_commit_sha(): match=f"Repo {repo.name}: The path '{repo.path.as_posix()}' is not a Git repository.", ): repo.head_commit_sha() is not None + + +def test_all_commits_since_commit_when_repo_empty(empty_repository): + all_commits_empty = empty_repository.all_commits_since_commit() + assert isinstance(all_commits_empty, list) + assert len(all_commits_empty) == 0 From 6230e0be7896aba38b90ea0ffe73fe76bcd0936d Mon Sep 17 00:00:00 2001 From: Renata Date: Wed, 18 Sep 2024 18:19:48 -0400 Subject: [PATCH 06/19] chore: fix mypy error --- taf/git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taf/git.py b/taf/git.py index 78e809da..0d750b40 100644 --- a/taf/git.py +++ b/taf/git.py @@ -400,7 +400,7 @@ def all_commits_since_commit( try: return self.all_commits_on_branch(branch=branch, reverse=reverse) except GitError as e: - self._log_warning(e) + self._log_warning(str(e)) return [] try: From 0588d0b7aa1556e8b70badcd677d096ed534d585 Mon Sep 17 00:00:00 2001 From: Renata Date: Wed, 18 Sep 2024 18:36:03 -0400 Subject: [PATCH 07/19] chore: typo fix --- taf/git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taf/git.py b/taf/git.py index 0d750b40..68b65563 100644 --- a/taf/git.py +++ b/taf/git.py @@ -416,7 +416,7 @@ def all_commits_since_commit( return [] latest_commit_id = branch_obj.target else: - if repo.head_commit_sha() is None: + if self.head_commit_sha() is None: return [] latest_commit_id = repo[repo.head.target].id From d2f7b06e2fd94192a312f1d815353e478b51aead Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 00:16:13 -0400 Subject: [PATCH 08/19] test: add tests for the cases when target repos exist but target files do not --- taf/tests/test_updater/conftest.py | 12 ++++++ .../test_clone/test_clone_valid.py | 39 +++++++++++++++---- .../test_update/test_update_valid.py | 9 +---- taf/tests/test_updater/update_utils.py | 34 +++++++++++++++- taf/updater/updater_pipeline.py | 10 +---- 5 files changed, 79 insertions(+), 25 deletions(-) diff --git a/taf/tests/test_updater/conftest.py b/taf/tests/test_updater/conftest.py index db2771b7..5a0af638 100644 --- a/taf/tests/test_updater/conftest.py +++ b/taf/tests/test_updater/conftest.py @@ -509,6 +509,12 @@ def add_unauthenticated_commits_to_all_target_repos(target_repos: list): update_target_files(target_repo, "Update target files") +def add_unauthenticated_commit_to_target_repo(target_repos: list, target_name: str): + for target_repo in target_repos: + if target_name in target_repo.name: + update_target_files(target_repo, "Update target files") + + def add_unauthenticated_commits_to_target_repo(target_repos: list): for target_repo in target_repos: update_target_files(target_repo, "Update target files") @@ -650,11 +656,17 @@ def update_and_sign_metadata_without_clean_check( def update_target_files(target_repo: GitRepository, commit_message: str): text_to_add = _generate_random_text() # Iterate over all files in the repository directory + is_empty = True for file_path in target_repo.path.iterdir(): if file_path.is_file(): + is_empty = False existing_content = file_path.read_text(encoding="utf-8") new_content = existing_content + "\n" + text_to_add file_path.write_text(new_content, encoding="utf-8") + + if is_empty: + random_text = _generate_random_text() + (target_repo.path / "test.txt").write_text(random_text) target_repo.commit(commit_message) diff --git a/taf/tests/test_updater/test_clone/test_clone_valid.py b/taf/tests/test_updater/test_clone/test_clone_valid.py index e2be25c9..1c415c0e 100644 --- a/taf/tests/test_updater/test_clone/test_clone_valid.py +++ b/taf/tests/test_updater/test_clone/test_clone_valid.py @@ -1,6 +1,7 @@ import pytest from taf.tests.test_updater.conftest import ( SetupManager, + add_unauthenticated_commit_to_target_repo, add_unauthenticated_commits_to_all_target_repos, add_valid_target_commits, add_valid_unauthenticated_commits, @@ -12,8 +13,8 @@ ) from taf.tests.test_updater.update_utils import ( clone_client_target_repos_without_updater, - load_target_repositories, update_and_check_commit_shas, + verify_repos_eixsts, ) from taf.updater.types.update import OperationType, UpdateType @@ -339,9 +340,33 @@ def test_clone_when_target_empty(origin_auth_repo, client_dir): client_dir, expected_repo_type=UpdateType.EITHER, ) - client_repos = load_target_repositories(origin_auth_repo, client_dir) - for name, repo in client_repos.items(): - if "notempty" in name: - assert repo.path.is_dir() - else: - assert not repo.path.is_dir() + verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [ + {"name": "target1"}, + {"name": "target2", "is_empty": True}, + ], + }, + ], + indirect=True, +) +def test_clone_when_no_target_file_and_commit(origin_auth_repo, client_dir): + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task( + add_unauthenticated_commit_to_target_repo, kwargs={"target_name": "target2"} + ) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.CLONE, + origin_auth_repo, + client_dir, + expected_repo_type=UpdateType.EITHER, + ) + verify_repos_eixsts(client_dir, origin_auth_repo, exists=["target1"]) diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index fdaea313..be03a1c6 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -23,6 +23,7 @@ clone_repositories, load_target_repositories, update_and_check_commit_shas, + verify_repos_eixsts, ) from taf.updater.types.update import OperationType, UpdateType @@ -757,10 +758,4 @@ def test_update_when_target_empty(origin_auth_repo, client_dir): client_dir, skip_check_last_validated=True, ) - - client_repos = load_target_repositories(origin_auth_repo, client_dir) - for name, repo in client_repos.items(): - if "notempty" in name: - assert repo.path.is_dir() - else: - assert not repo.path.is_dir() + verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) \ No newline at end of file diff --git a/taf/tests/test_updater/update_utils.py b/taf/tests/test_updater/update_utils.py index 57944bf2..41983e8f 100644 --- a/taf/tests/test_updater/update_utils.py +++ b/taf/tests/test_updater/update_utils.py @@ -180,7 +180,11 @@ def _get_head_commit_shas(client_repos, num_of_commits_to_remove=0): def load_target_repositories( - auth_repo, library_dir=None, excluded_target_globs=None, commits=None + auth_repo, + library_dir=None, + excluded_target_globs=None, + commits=None, + only_load_targets=False, ): if library_dir is None: library_dir = auth_repo.path.parent.parent @@ -188,7 +192,7 @@ def load_target_repositories( repositoriesdb.load_repositories( auth_repo, library_dir=library_dir, - only_load_targets=True, + only_load_targets=only_load_targets, excluded_target_globs=excluded_target_globs, commits=commits, ) @@ -317,6 +321,32 @@ def _update_expect_error(): assert not client_repository.path.exists() +def verify_repos_eixsts( + client_dir: Path, origin_auth_repo: AuthenticationRepository, exists: list +): + client_auth_repo = AuthenticationRepository(path=client_dir / origin_auth_repo.name) + client_target_repos = load_target_repositories( + client_auth_repo, library_dir=client_dir + ) + for repo in client_target_repos.values(): + if repo.name.split("/")[-1] in exists: + assert repo.is_git_repository + else: + assert not repo.path.is_dir() + + +def verify_repo_empty( + client_dir: Path, origin_auth_repo: AuthenticationRepository, target_name_part: str +): + client_auth_repo = AuthenticationRepository(path=client_dir / origin_auth_repo.name) + client_target_repos = load_target_repositories( + client_auth_repo, library_dir=client_dir + ) + for name, repo in client_target_repos.items(): + if target_name_part in name: + assert not len(repo.all_commits_on_branch()) + + def verify_client_repos_state( client_dir: Path, origin_auth_repo: AuthenticationRepository ): diff --git a/taf/updater/updater_pipeline.py b/taf/updater/updater_pipeline.py index 49c5fc6a..2d55ad6b 100644 --- a/taf/updater/updater_pipeline.py +++ b/taf/updater/updater_pipeline.py @@ -740,9 +740,6 @@ def validate_commit_in_remote(repo, commit_sha): f"Last validated commit {last_validated_commit} is not in the remote repository." ) else: - import pdb - - pdb.set_trace() # Re-validate from the point of divergence commits_since = validation_repo.all_commits_since_commit( since_commit=last_validated_commit, branch=branch @@ -1033,9 +1030,6 @@ def fetch_commits(repository, branch, old_head): fetched_commits.index(old_head) + 1 : ] else: - import pdb - - pdb.set_trace() fetched_commits_on_target_repo_branch = ( repository.all_commits_since_commit(old_head, branch) ) @@ -1043,9 +1037,6 @@ def fetch_commits(repository, branch, old_head): if commit not in fetched_commits_on_target_repo_branch: fetched_commits_on_target_repo_branch.append(commit) else: - import pdb - - pdb.set_trace() fetched_commits_on_target_repo_branch = ( repository.all_commits_since_commit(old_head, branch) ) @@ -1433,6 +1424,7 @@ def merge_commits(self): _merge_commit( repository, branch, commit_to_merge, force_revert=True ) + return self.state.update_status except Exception as e: self.state.errors.append(e) From 116499936c852ffa57b0b40c76d5fe5963405f0e Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 00:18:45 -0400 Subject: [PATCH 09/19] chroe: formatting --- taf/tests/test_updater/test_update/test_update_valid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index be03a1c6..bcca708c 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -758,4 +758,4 @@ def test_update_when_target_empty(origin_auth_repo, client_dir): client_dir, skip_check_last_validated=True, ) - verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) \ No newline at end of file + verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) From 3a398c07ab81dd8da6349277e6176e38acc5103c Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 02:10:19 -0400 Subject: [PATCH 10/19] fix: update remote-tracking branch when merging commits --- taf/git.py | 6 + taf/tests/test_updater/conftest.py | 2 - .../test_update/test_update_valid.py | 1437 +++++++++-------- taf/tests/test_updater/update_utils.py | 5 +- taf/updater/updater_pipeline.py | 1 - 5 files changed, 749 insertions(+), 702 deletions(-) diff --git a/taf/git.py b/taf/git.py index 68b65563..644aef66 100644 --- a/taf/git.py +++ b/taf/git.py @@ -1333,9 +1333,15 @@ def merge_commit( commit: str, fast_forward_only: Optional[bool] = False, check_if_merge_completed: Optional[bool] = False, + update_remote_tracking: Optional[bool] = True, ) -> bool: fast_forward_only_flag = "--ff-only" if fast_forward_only else "" self._git("merge {} {}", commit, fast_forward_only_flag, log_error=True) + if update_remote_tracking: + current_branch = self.get_current_branch() + self._git( + f"update-ref refs/remotes/origin/{current_branch} HEAD", log_error=True + ) # Update remote tracking if check_if_merge_completed: try: self._git("rev-parse -q --verify MERGE_HEAD") diff --git a/taf/tests/test_updater/conftest.py b/taf/tests/test_updater/conftest.py index 5a0af638..a2885612 100644 --- a/taf/tests/test_updater/conftest.py +++ b/taf/tests/test_updater/conftest.py @@ -691,8 +691,6 @@ def add_file_without_commit(repo_path: str, filename: str): def remove_commits( - auth_repo: AuthenticationRepository, - target_repos: list, repo_path: str, num_commits: int = 1, ): diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index bcca708c..90306cea 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -28,648 +28,737 @@ from taf.updater.types.update import OperationType, UpdateType -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_happy_path(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(add_valid_target_commits) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_happy_path_bare_flag(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(add_valid_target_commits) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - bare=True, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [ - {"name": "target1", "allow_unauthenticated_commits": True}, - {"name": "target2", "allow_unauthenticated_commits": True}, - ], - }, - { - "targets_config": [ - {"name": "target1"}, - {"name": "target2", "allow_unauthenticated_commits": True}, - ], - }, - ], - indirect=True, -) -def test_update_valid_when_unauthenticated_commits(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(add_valid_unauthenticated_commits) - setup_manager.add_task(add_valid_target_commits) - setup_manager.add_task(add_valid_unauthenticated_commits) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "is_test_repo": True, - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_test_repository(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(add_valid_target_commits) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - expected_repo_type=UpdateType.TEST, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_expiration_dates_updated(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(update_expiration_dates) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "date": "2020-01-01", - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_epxirated_metadata_no_strict_flag( - origin_auth_repo, client_dir -): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(update_expiration_dates, kwargs={"date": "2021-01-01"}) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_multiple_target_branches(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - - setup_manager.add_task( - create_new_target_orphan_branches, kwargs={"branch_name": "branch1"} - ) - setup_manager.add_task(add_valid_target_commits) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_update_root_metadata(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(update_expiration_dates, kwargs={"roles": ["root"]}) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_root_version_skipped(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task( - update_role_metadata_without_signing, kwargs={"role": "root"} - ) - setup_manager.add_task( - update_and_sign_metadata_without_clean_check, kwargs={"roles": ["root"]} - ) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_when_no_update_necessary(origin_auth_repo, client_dir): - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(add_valid_target_commits) - setup_manager.execute_tasks() - - clone_repositories( - origin_auth_repo, - client_dir, - ) - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_when_auth_repo_exists_no_targets(origin_auth_repo, client_dir): - clone_client_auth_repo_without_updater(origin_auth_repo, client_dir) - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_last_validated_commit_deleted(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - remove_last_validate_commit(origin_auth_repo, client_dir) - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_last_validated_commit_reverted(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - revert_last_validated_commit(origin_auth_repo, client_dir) - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_no_upstream_when_contain_unsigned_commits( - origin_auth_repo, client_dir -): - - clone_repositories( - origin_auth_repo, - client_dir, - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(add_unauthenticated_commits_to_all_target_repos) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - no_upstream=True, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_dirty_index_auth_repo_update_file(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - client_auth_repo_path = client_dir / origin_auth_repo.name - update_file_without_commit(str(client_auth_repo_path), "dirty_file.txt") - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - force=True, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_dirty_index_auth_repo_add_file(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - client_auth_repo_path = client_dir / origin_auth_repo.name - add_file_without_commit(str(client_auth_repo_path), "new_file.txt") - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - force=True, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_dirty_index_target_repo_update_file(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - client_target_repo_path = client_dir / origin_auth_repo.name / "namespace/target1" - update_file_without_commit(str(client_target_repo_path), "dirty_file.txt") - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - force=True, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_dirty_index_target_repo_add_file(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - client_target_repo_path = client_dir / origin_auth_repo.name / "namespace/target1" - add_file_without_commit(str(client_target_repo_path), "dirty_file.txt") - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - force=True, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_remove_commits_from_target_repo(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - - client_target_repo_path = ( - client_dir - / origin_auth_repo.name - / "targets/test_remove_commits_from_target_repo0/target1" - ) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task( - remove_commits, kwargs={"repo_path": client_target_repo_path, "num_commits": 1} - ) - setup_manager.execute_tasks() - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - force=True, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_with_force_flag_when_repos_not_clean( - origin_auth_repo, client_dir -): - # Set up a scenario where repositories are not clean - clone_repositories( - origin_auth_repo, - client_dir, - ) - client_auth_repo_path = client_dir / origin_auth_repo.name - - update_file_without_commit(str(client_auth_repo_path), "dirty_file.txt") - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - force=True, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_valid_when_detached_head(origin_auth_repo, client_dir): - # Set up a scenario where the auth repo is in a detached HEAD state - clone_repositories( - origin_auth_repo, - client_dir, - ) - client_auth_repo_path = client_dir / origin_auth_repo.name - - checkout_detached_head(str(client_auth_repo_path)) - - update_and_check_commit_shas( - OperationType.UPDATE, origin_auth_repo, client_dir, force=True - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_partial_with_invalid_commits(origin_auth_repo, client_dir): - clone_repositories( - origin_auth_repo, - client_dir, - ) - client_auth_repo_path = client_dir / origin_auth_repo.name - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(add_valid_target_commits) - setup_manager.execute_tasks() - - setup_manager.add_task(set_head_commit) - - setup_manager.add_task(add_valid_target_commits) - setup_manager.execute_tasks() - - update_file_without_commit( - str(client_auth_repo_path / "targets/target1"), "invalid_file.txt" - ) - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - force=True, - ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_with_removed_commits_in_auth_repo(origin_auth_repo, client_dir): - clone_repositories(origin_auth_repo, client_dir) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(add_valid_target_commits) - setup_manager.execute_tasks() - - client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) - client_target_repos = load_target_repositories(client_auth_repo) - remove_commits( - auth_repo=client_auth_repo, - target_repos=client_target_repos, - repo_path=str(client_auth_repo.path), - num_commits=1, - ) - - update_and_check_commit_shas( - OperationType.UPDATE, - origin_auth_repo, - client_dir, - ) +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_happy_path(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_happy_path_bare_flag(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# bare=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [ +# {"name": "target1", "allow_unauthenticated_commits": True}, +# {"name": "target2", "allow_unauthenticated_commits": True}, +# ], +# }, +# { +# "targets_config": [ +# {"name": "target1"}, +# {"name": "target2", "allow_unauthenticated_commits": True}, +# ], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_unauthenticated_commits(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_valid_unauthenticated_commits) +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.add_task(add_valid_unauthenticated_commits) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "is_test_repo": True, +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_test_repository(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# expected_repo_type=UpdateType.TEST, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_expiration_dates_updated(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(update_expiration_dates) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "date": "2020-01-01", +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_epxirated_metadata_no_strict_flag( +# origin_auth_repo, client_dir +# ): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(update_expiration_dates, kwargs={"date": "2021-01-01"}) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_multiple_target_branches(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) + +# setup_manager.add_task( +# create_new_target_orphan_branches, kwargs={"branch_name": "branch1"} +# ) +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_update_root_metadata(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(update_expiration_dates, kwargs={"roles": ["root"]}) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_root_version_skipped(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task( +# update_role_metadata_without_signing, kwargs={"role": "root"} +# ) +# setup_manager.add_task( +# update_and_sign_metadata_without_clean_check, kwargs={"roles": ["root"]} +# ) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_when_no_update_necessary(origin_auth_repo, client_dir): + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.execute_tasks() + +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_when_auth_repo_exists_no_targets(origin_auth_repo, client_dir): +# clone_client_auth_repo_without_updater(origin_auth_repo, client_dir) + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_last_validated_commit_deleted(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# remove_last_validate_commit(origin_auth_repo, client_dir) + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_last_validated_commit_reverted(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# revert_last_validated_commit(origin_auth_repo, client_dir) + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_no_upstream_when_contain_unsigned_commits( +# origin_auth_repo, client_dir +# ): + +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_unauthenticated_commits_to_all_target_repos) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# no_upstream=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_dirty_index_auth_repo_update_file(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# client_auth_repo_path = client_dir / origin_auth_repo.name +# update_file_without_commit(str(client_auth_repo_path), "dirty_file.txt") + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# force=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_dirty_index_auth_repo_add_file(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# client_auth_repo_path = client_dir / origin_auth_repo.name +# add_file_without_commit(str(client_auth_repo_path), "new_file.txt") + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# force=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_dirty_index_target_repo_update_file(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# client_target_repo_path = client_dir / origin_auth_repo.name / "namespace/target1" +# update_file_without_commit(str(client_target_repo_path), "dirty_file.txt") + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# force=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_dirty_index_target_repo_add_file(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# client_target_repo_path = client_dir / origin_auth_repo.name / "namespace/target1" +# add_file_without_commit(str(client_target_repo_path), "dirty_file.txt") + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# force=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_remove_commits_from_target_repo(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) + +# client_target_repo_path = ( +# client_dir +# / origin_auth_repo.name +# / "targets/test_remove_commits_from_target_repo0/target1" +# ) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task( +# remove_commits, kwargs={"repo_path": client_target_repo_path, "num_commits": 1} +# ) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# force=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_with_force_flag_when_repos_not_clean( +# origin_auth_repo, client_dir +# ): +# # Set up a scenario where repositories are not clean +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) +# client_auth_repo_path = client_dir / origin_auth_repo.name + +# update_file_without_commit(str(client_auth_repo_path), "dirty_file.txt") + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# force=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_valid_when_detached_head(origin_auth_repo, client_dir): +# # Set up a scenario where the auth repo is in a detached HEAD state +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) +# client_auth_repo_path = client_dir / origin_auth_repo.name + +# checkout_detached_head(str(client_auth_repo_path)) + +# update_and_check_commit_shas( +# OperationType.UPDATE, origin_auth_repo, client_dir, force=True +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_partial_with_invalid_commits(origin_auth_repo, client_dir): +# clone_repositories( +# origin_auth_repo, +# client_dir, +# ) +# client_auth_repo_path = client_dir / origin_auth_repo.name + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.execute_tasks() + +# setup_manager.add_task(set_head_commit) + +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.execute_tasks() + +# update_file_without_commit( +# str(client_auth_repo_path / "targets/target1"), "invalid_file.txt" +# ) + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# force=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_with_removed_commits_in_auth_repo(origin_auth_repo, client_dir): +# clone_repositories(origin_auth_repo, client_dir) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.execute_tasks() + +# client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) +# client_target_repos = load_target_repositories(client_auth_repo) +# remove_commits( +# auth_repo=client_auth_repo, +# target_repos=client_target_repos, +# repo_path=str(client_auth_repo.path), +# num_commits=1, +# ) + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_with_last_validated_commit_not_in_local_repo( +# origin_auth_repo, client_dir +# ): +# clone_repositories(origin_auth_repo, client_dir) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_valid_target_commits) +# setup_manager.execute_tasks() + +# origin_top_commit_sha = origin_auth_repo.head_commit_sha() +# client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) +# client_auth_repo.set_last_validated_commit(origin_top_commit_sha) + +# client_target_repos = load_target_repositories(client_auth_repo) +# remove_commits( +# auth_repo=client_auth_repo, +# target_repos=client_target_repos, +# repo_path=str(client_auth_repo.path), +# num_commits=1, +# ) +# # Skips udpater commit hash checks. Currently the update runs fully but the commit validation fails. +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# skip_check_last_validated=True, +# ) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [{"name": "target1"}, {"name": "target2"}], +# }, +# ], +# indirect=True, +# ) +# def test_update_with_no_last_validated_commit(origin_auth_repo, client_dir): +# clone_repositories(origin_auth_repo, client_dir) + +# client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) +# last_validated_commit_file = ( +# Path(client_auth_repo.conf_dir) / client_auth_repo.LAST_VALIDATED_FILENAME +# ) +# if last_validated_commit_file.exists(): +# last_validated_commit_file.unlink() # Remove the file + +# update_and_check_commit_shas(OperationType.UPDATE, origin_auth_repo, client_dir) + + +# @pytest.mark.parametrize( +# "origin_auth_repo", +# [ +# { +# "targets_config": [ +# {"name": "notempty"}, +# {"name": "empty", "is_empty": True}, +# ], +# }, +# ], +# indirect=True, +# ) +# def test_update_when_target_empty(origin_auth_repo, client_dir): + +# clone_repositories(origin_auth_repo, client_dir) + +# setup_manager = SetupManager(origin_auth_repo) +# setup_manager.add_task(add_valid_target_commits, kwargs={"add_if_empty": False}) +# setup_manager.execute_tasks() + +# update_and_check_commit_shas( +# OperationType.UPDATE, +# origin_auth_repo, +# client_dir, +# skip_check_last_validated=True, +# ) +# verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) @pytest.mark.parametrize( @@ -688,74 +777,28 @@ def test_update_with_last_validated_commit_not_in_local_repo( setup_manager = SetupManager(origin_auth_repo) setup_manager.add_task(add_valid_target_commits) + setup_manager.add_task(add_valid_target_commits) + setup_manager.add_task(add_valid_target_commits) setup_manager.execute_tasks() - origin_top_commit_sha = origin_auth_repo.head_commit_sha() - client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) - client_auth_repo.set_last_validated_commit(origin_top_commit_sha) - - client_target_repos = load_target_repositories(client_auth_repo) - remove_commits( - auth_repo=client_auth_repo, - target_repos=client_target_repos, - repo_path=str(client_auth_repo.path), - num_commits=1, - ) - # Skips udpater commit hash checks. Currently the update runs fully but the commit validation fails. update_and_check_commit_shas( OperationType.UPDATE, origin_auth_repo, client_dir, skip_check_last_validated=True, ) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [{"name": "target1"}, {"name": "target2"}], - }, - ], - indirect=True, -) -def test_update_with_no_last_validated_commit(origin_auth_repo, client_dir): - clone_repositories(origin_auth_repo, client_dir) - client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) - last_validated_commit_file = ( - Path(client_auth_repo.conf_dir) / client_auth_repo.LAST_VALIDATED_FILENAME - ) - if last_validated_commit_file.exists(): - last_validated_commit_file.unlink() # Remove the file - - update_and_check_commit_shas(OperationType.UPDATE, origin_auth_repo, client_dir) - - -@pytest.mark.parametrize( - "origin_auth_repo", - [ - { - "targets_config": [ - {"name": "notempty"}, - {"name": "empty", "is_empty": True}, - ], - }, - ], - indirect=True, -) -def test_update_when_target_empty(origin_auth_repo, client_dir): - - clone_repositories(origin_auth_repo, client_dir) - - setup_manager = SetupManager(origin_auth_repo) - setup_manager.add_task(add_valid_target_commits, kwargs={"add_if_empty": False}) + client_target_repos = load_target_repositories(client_auth_repo) + setup_manager = SetupManager(client_auth_repo) + for target_repo in client_target_repos.values(): + setup_manager.add_task( + remove_commits, kwargs={"repo_path": target_repo.path, "num_commits": 1} + ) + break setup_manager.execute_tasks() - update_and_check_commit_shas( OperationType.UPDATE, origin_auth_repo, client_dir, skip_check_last_validated=True, ) - verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) diff --git a/taf/tests/test_updater/update_utils.py b/taf/tests/test_updater/update_utils.py index 41983e8f..efd53416 100644 --- a/taf/tests/test_updater/update_utils.py +++ b/taf/tests/test_updater/update_utils.py @@ -242,9 +242,9 @@ def update_and_check_commit_shas( ) if operation == OperationType.CLONE: - clone_repository(config) + update_ret = clone_repository(config) else: - update_repository(config) + update_ret = update_repository(config) origin_root_dir = origin_auth_repo.path.parent.parent check_if_commits_match( @@ -266,6 +266,7 @@ def update_and_check_commit_shas( if fnmatch.fnmatch(target_repo.name, excluded_target_glob): assert not target_repo.path.is_dir() break + return update_ret def update_invalid_repos_and_check_if_repos_exist( diff --git a/taf/updater/updater_pipeline.py b/taf/updater/updater_pipeline.py index 2d55ad6b..fb01ca94 100644 --- a/taf/updater/updater_pipeline.py +++ b/taf/updater/updater_pipeline.py @@ -1794,7 +1794,6 @@ def _merge_commit(repository, branch, commit_to_merge, force_revert=True): commits_since_to_merge = repository.all_commits_since_commit( commit_to_merge, branch=branch ) - if not len(commits_since_to_merge): taf_logger.info( "{} Merging commit {} into branch {}", From 3399560688c7eb2ae8391a656fee470e895276a6 Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 02:13:04 -0400 Subject: [PATCH 11/19] chore: uncomment code --- .../test_update/test_update_valid.py | 1462 ++++++++--------- 1 file changed, 731 insertions(+), 731 deletions(-) diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index 90306cea..f90cd212 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -28,737 +28,737 @@ from taf.updater.types.update import OperationType, UpdateType -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_happy_path(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_happy_path_bare_flag(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# bare=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [ -# {"name": "target1", "allow_unauthenticated_commits": True}, -# {"name": "target2", "allow_unauthenticated_commits": True}, -# ], -# }, -# { -# "targets_config": [ -# {"name": "target1"}, -# {"name": "target2", "allow_unauthenticated_commits": True}, -# ], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_unauthenticated_commits(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_valid_unauthenticated_commits) -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.add_task(add_valid_unauthenticated_commits) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "is_test_repo": True, -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_test_repository(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# expected_repo_type=UpdateType.TEST, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_expiration_dates_updated(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(update_expiration_dates) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "date": "2020-01-01", -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_epxirated_metadata_no_strict_flag( -# origin_auth_repo, client_dir -# ): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(update_expiration_dates, kwargs={"date": "2021-01-01"}) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_multiple_target_branches(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) - -# setup_manager.add_task( -# create_new_target_orphan_branches, kwargs={"branch_name": "branch1"} -# ) -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_update_root_metadata(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(update_expiration_dates, kwargs={"roles": ["root"]}) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_root_version_skipped(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task( -# update_role_metadata_without_signing, kwargs={"role": "root"} -# ) -# setup_manager.add_task( -# update_and_sign_metadata_without_clean_check, kwargs={"roles": ["root"]} -# ) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_when_no_update_necessary(origin_auth_repo, client_dir): - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.execute_tasks() - -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_when_auth_repo_exists_no_targets(origin_auth_repo, client_dir): -# clone_client_auth_repo_without_updater(origin_auth_repo, client_dir) - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_last_validated_commit_deleted(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# remove_last_validate_commit(origin_auth_repo, client_dir) - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_last_validated_commit_reverted(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# revert_last_validated_commit(origin_auth_repo, client_dir) - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_no_upstream_when_contain_unsigned_commits( -# origin_auth_repo, client_dir -# ): - -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_unauthenticated_commits_to_all_target_repos) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# no_upstream=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_dirty_index_auth_repo_update_file(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# client_auth_repo_path = client_dir / origin_auth_repo.name -# update_file_without_commit(str(client_auth_repo_path), "dirty_file.txt") - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# force=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_dirty_index_auth_repo_add_file(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# client_auth_repo_path = client_dir / origin_auth_repo.name -# add_file_without_commit(str(client_auth_repo_path), "new_file.txt") - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# force=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_dirty_index_target_repo_update_file(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# client_target_repo_path = client_dir / origin_auth_repo.name / "namespace/target1" -# update_file_without_commit(str(client_target_repo_path), "dirty_file.txt") - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# force=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_dirty_index_target_repo_add_file(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# client_target_repo_path = client_dir / origin_auth_repo.name / "namespace/target1" -# add_file_without_commit(str(client_target_repo_path), "dirty_file.txt") - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# force=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_remove_commits_from_target_repo(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) - -# client_target_repo_path = ( -# client_dir -# / origin_auth_repo.name -# / "targets/test_remove_commits_from_target_repo0/target1" -# ) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task( -# remove_commits, kwargs={"repo_path": client_target_repo_path, "num_commits": 1} -# ) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# force=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_with_force_flag_when_repos_not_clean( -# origin_auth_repo, client_dir -# ): -# # Set up a scenario where repositories are not clean -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) -# client_auth_repo_path = client_dir / origin_auth_repo.name - -# update_file_without_commit(str(client_auth_repo_path), "dirty_file.txt") - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# force=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_valid_when_detached_head(origin_auth_repo, client_dir): -# # Set up a scenario where the auth repo is in a detached HEAD state -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) -# client_auth_repo_path = client_dir / origin_auth_repo.name - -# checkout_detached_head(str(client_auth_repo_path)) - -# update_and_check_commit_shas( -# OperationType.UPDATE, origin_auth_repo, client_dir, force=True -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_partial_with_invalid_commits(origin_auth_repo, client_dir): -# clone_repositories( -# origin_auth_repo, -# client_dir, -# ) -# client_auth_repo_path = client_dir / origin_auth_repo.name - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.execute_tasks() - -# setup_manager.add_task(set_head_commit) - -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.execute_tasks() - -# update_file_without_commit( -# str(client_auth_repo_path / "targets/target1"), "invalid_file.txt" -# ) - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# force=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_with_removed_commits_in_auth_repo(origin_auth_repo, client_dir): -# clone_repositories(origin_auth_repo, client_dir) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.execute_tasks() - -# client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) -# client_target_repos = load_target_repositories(client_auth_repo) -# remove_commits( -# auth_repo=client_auth_repo, -# target_repos=client_target_repos, -# repo_path=str(client_auth_repo.path), -# num_commits=1, -# ) - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_with_last_validated_commit_not_in_local_repo( -# origin_auth_repo, client_dir -# ): -# clone_repositories(origin_auth_repo, client_dir) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_valid_target_commits) -# setup_manager.execute_tasks() - -# origin_top_commit_sha = origin_auth_repo.head_commit_sha() -# client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) -# client_auth_repo.set_last_validated_commit(origin_top_commit_sha) - -# client_target_repos = load_target_repositories(client_auth_repo) -# remove_commits( -# auth_repo=client_auth_repo, -# target_repos=client_target_repos, -# repo_path=str(client_auth_repo.path), -# num_commits=1, -# ) -# # Skips udpater commit hash checks. Currently the update runs fully but the commit validation fails. -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# skip_check_last_validated=True, -# ) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [{"name": "target1"}, {"name": "target2"}], -# }, -# ], -# indirect=True, -# ) -# def test_update_with_no_last_validated_commit(origin_auth_repo, client_dir): -# clone_repositories(origin_auth_repo, client_dir) - -# client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) -# last_validated_commit_file = ( -# Path(client_auth_repo.conf_dir) / client_auth_repo.LAST_VALIDATED_FILENAME -# ) -# if last_validated_commit_file.exists(): -# last_validated_commit_file.unlink() # Remove the file - -# update_and_check_commit_shas(OperationType.UPDATE, origin_auth_repo, client_dir) - - -# @pytest.mark.parametrize( -# "origin_auth_repo", -# [ -# { -# "targets_config": [ -# {"name": "notempty"}, -# {"name": "empty", "is_empty": True}, -# ], -# }, -# ], -# indirect=True, -# ) -# def test_update_when_target_empty(origin_auth_repo, client_dir): - -# clone_repositories(origin_auth_repo, client_dir) - -# setup_manager = SetupManager(origin_auth_repo) -# setup_manager.add_task(add_valid_target_commits, kwargs={"add_if_empty": False}) -# setup_manager.execute_tasks() - -# update_and_check_commit_shas( -# OperationType.UPDATE, -# origin_auth_repo, -# client_dir, -# skip_check_last_validated=True, -# ) -# verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_happy_path(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_happy_path_bare_flag(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + bare=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [ + {"name": "target1", "allow_unauthenticated_commits": True}, + {"name": "target2", "allow_unauthenticated_commits": True}, + ], + }, + { + "targets_config": [ + {"name": "target1"}, + {"name": "target2", "allow_unauthenticated_commits": True}, + ], + }, + ], + indirect=True, +) +def test_update_valid_when_unauthenticated_commits(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_unauthenticated_commits) + setup_manager.add_task(add_valid_target_commits) + setup_manager.add_task(add_valid_unauthenticated_commits) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "is_test_repo": True, + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_test_repository(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + expected_repo_type=UpdateType.TEST, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_expiration_dates_updated(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(update_expiration_dates) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "date": "2020-01-01", + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_epxirated_metadata_no_strict_flag( + origin_auth_repo, client_dir +): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(update_expiration_dates, kwargs={"date": "2021-01-01"}) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_multiple_target_branches(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + + setup_manager.add_task( + create_new_target_orphan_branches, kwargs={"branch_name": "branch1"} + ) + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_update_root_metadata(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(update_expiration_dates, kwargs={"roles": ["root"]}) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_root_version_skipped(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task( + update_role_metadata_without_signing, kwargs={"role": "root"} + ) + setup_manager.add_task( + update_and_sign_metadata_without_clean_check, kwargs={"roles": ["root"]} + ) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_when_no_update_necessary(origin_auth_repo, client_dir): + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + clone_repositories( + origin_auth_repo, + client_dir, + ) + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_when_auth_repo_exists_no_targets(origin_auth_repo, client_dir): + clone_client_auth_repo_without_updater(origin_auth_repo, client_dir) + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_last_validated_commit_deleted(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + remove_last_validate_commit(origin_auth_repo, client_dir) + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_last_validated_commit_reverted(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + revert_last_validated_commit(origin_auth_repo, client_dir) + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_no_upstream_when_contain_unsigned_commits( + origin_auth_repo, client_dir +): + + clone_repositories( + origin_auth_repo, + client_dir, + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_unauthenticated_commits_to_all_target_repos) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + no_upstream=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_dirty_index_auth_repo_update_file(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + client_auth_repo_path = client_dir / origin_auth_repo.name + update_file_without_commit(str(client_auth_repo_path), "dirty_file.txt") + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + force=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_dirty_index_auth_repo_add_file(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + client_auth_repo_path = client_dir / origin_auth_repo.name + add_file_without_commit(str(client_auth_repo_path), "new_file.txt") + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + force=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_dirty_index_target_repo_update_file(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + client_target_repo_path = client_dir / origin_auth_repo.name / "namespace/target1" + update_file_without_commit(str(client_target_repo_path), "dirty_file.txt") + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + force=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_dirty_index_target_repo_add_file(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + client_target_repo_path = client_dir / origin_auth_repo.name / "namespace/target1" + add_file_without_commit(str(client_target_repo_path), "dirty_file.txt") + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + force=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_remove_commits_from_target_repo(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + + client_target_repo_path = ( + client_dir + / origin_auth_repo.name + / "targets/test_remove_commits_from_target_repo0/target1" + ) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task( + remove_commits, kwargs={"repo_path": client_target_repo_path, "num_commits": 1} + ) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + force=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_with_force_flag_when_repos_not_clean( + origin_auth_repo, client_dir +): + # Set up a scenario where repositories are not clean + clone_repositories( + origin_auth_repo, + client_dir, + ) + client_auth_repo_path = client_dir / origin_auth_repo.name + + update_file_without_commit(str(client_auth_repo_path), "dirty_file.txt") + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + force=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_detached_head(origin_auth_repo, client_dir): + # Set up a scenario where the auth repo is in a detached HEAD state + clone_repositories( + origin_auth_repo, + client_dir, + ) + client_auth_repo_path = client_dir / origin_auth_repo.name + + checkout_detached_head(str(client_auth_repo_path)) + + update_and_check_commit_shas( + OperationType.UPDATE, origin_auth_repo, client_dir, force=True + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_partial_with_invalid_commits(origin_auth_repo, client_dir): + clone_repositories( + origin_auth_repo, + client_dir, + ) + client_auth_repo_path = client_dir / origin_auth_repo.name + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + setup_manager.add_task(set_head_commit) + + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + update_file_without_commit( + str(client_auth_repo_path / "targets/target1"), "invalid_file.txt" + ) + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + force=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_with_removed_commits_in_auth_repo(origin_auth_repo, client_dir): + clone_repositories(origin_auth_repo, client_dir) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) + client_target_repos = load_target_repositories(client_auth_repo) + remove_commits( + auth_repo=client_auth_repo, + target_repos=client_target_repos, + repo_path=str(client_auth_repo.path), + num_commits=1, + ) + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_with_last_validated_commit_not_in_local_repo( + origin_auth_repo, client_dir +): + clone_repositories(origin_auth_repo, client_dir) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + origin_top_commit_sha = origin_auth_repo.head_commit_sha() + client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) + client_auth_repo.set_last_validated_commit(origin_top_commit_sha) + + client_target_repos = load_target_repositories(client_auth_repo) + remove_commits( + auth_repo=client_auth_repo, + target_repos=client_target_repos, + repo_path=str(client_auth_repo.path), + num_commits=1, + ) + # Skips udpater commit hash checks. Currently the update runs fully but the commit validation fails. + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + skip_check_last_validated=True, + ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_with_no_last_validated_commit(origin_auth_repo, client_dir): + clone_repositories(origin_auth_repo, client_dir) + + client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) + last_validated_commit_file = ( + Path(client_auth_repo.conf_dir) / client_auth_repo.LAST_VALIDATED_FILENAME + ) + if last_validated_commit_file.exists(): + last_validated_commit_file.unlink() # Remove the file + + update_and_check_commit_shas(OperationType.UPDATE, origin_auth_repo, client_dir) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [ + {"name": "notempty"}, + {"name": "empty", "is_empty": True}, + ], + }, + ], + indirect=True, +) +def test_update_when_target_empty(origin_auth_repo, client_dir): + + clone_repositories(origin_auth_repo, client_dir) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits, kwargs={"add_if_empty": False}) + setup_manager.execute_tasks() + + update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + skip_check_last_validated=True, + ) + verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) @pytest.mark.parametrize( From a9ce1420450a3d48288d076d5e14bc46dc4848aa Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 02:18:22 -0400 Subject: [PATCH 12/19] chore: rename test --- taf/tests/test_updater/test_update/test_update_valid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index f90cd212..df408d11 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -770,7 +770,7 @@ def test_update_when_target_empty(origin_auth_repo, client_dir): ], indirect=True, ) -def test_update_with_last_validated_commit_not_in_local_repo( +def test_update_valid_when_several_updates( origin_auth_repo, client_dir ): clone_repositories(origin_auth_repo, client_dir) From 3e2f52ac912c0024626874bff3399642083b582e Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 02:20:57 -0400 Subject: [PATCH 13/19] chore: formatting --- taf/tests/test_updater/test_update/test_update_valid.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index df408d11..4b488c46 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -770,9 +770,7 @@ def test_update_when_target_empty(origin_auth_repo, client_dir): ], indirect=True, ) -def test_update_valid_when_several_updates( - origin_auth_repo, client_dir -): +def test_update_valid_when_several_updates(origin_auth_repo, client_dir): clone_repositories(origin_auth_repo, client_dir) setup_manager = SetupManager(origin_auth_repo) From f2c24c6cf9ba044d233f2fab739d94ef333213c7 Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 02:34:57 -0400 Subject: [PATCH 14/19] chore: update changelog --- CHANGELOG.md | 3 +++ taf/tests/test_updater/test_update/test_update_valid.py | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eaff264b..007cc59a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,10 +39,13 @@ and this project adheres to [Semantic Versioning][semver]. ### Fixed +- Fix merge-commit which wasn't updating the remote-tracking branch ([532]) +- Fix removal of additional local commits ([532]) - Fix top-level authentication repository update to correctly update child auth repos ([528]) - Fix setup role when specifying public keys in keys-description ([511]) - `check_if_repositories_clean` error now returns a list of repositories which aren't clean, instead of a single repository ([525]) +[532]: https://github.com/openlawlibrary/taf/pull/532 [528]: https://github.com/openlawlibrary/taf/pull/528 [525]: https://github.com/openlawlibrary/taf/pull/525 [511]: https://github.com/openlawlibrary/taf/pull/511 diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index 4b488c46..44b16b8b 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -657,10 +657,7 @@ def test_update_with_removed_commits_in_auth_repo(origin_auth_repo, client_dir): setup_manager.execute_tasks() client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) - client_target_repos = load_target_repositories(client_auth_repo) remove_commits( - auth_repo=client_auth_repo, - target_repos=client_target_repos, repo_path=str(client_auth_repo.path), num_commits=1, ) From fb618a3a4c088f1236a6061b413f3e0a34174c8b Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 02:42:23 -0400 Subject: [PATCH 15/19] fix: fix wrong function call --- taf/tests/test_updater/test_update/test_update_valid.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index 44b16b8b..2e04fbbb 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -691,10 +691,7 @@ def test_update_with_last_validated_commit_not_in_local_repo( client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) client_auth_repo.set_last_validated_commit(origin_top_commit_sha) - client_target_repos = load_target_repositories(client_auth_repo) remove_commits( - auth_repo=client_auth_repo, - target_repos=client_target_repos, repo_path=str(client_auth_repo.path), num_commits=1, ) From f7747e5bd8d345288550c4ffb099b046b3158d6e Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 20:41:42 -0400 Subject: [PATCH 16/19] fix: returen status changed if a target repo was updated and the auth repo was not --- .../test_update/test_updater_output.py | 63 +++++++++++++++++++ taf/updater/updater_pipeline.py | 10 ++- 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 taf/tests/test_updater/test_update/test_updater_output.py diff --git a/taf/tests/test_updater/test_update/test_updater_output.py b/taf/tests/test_updater/test_update/test_updater_output.py new file mode 100644 index 00000000..414e9403 --- /dev/null +++ b/taf/tests/test_updater/test_update/test_updater_output.py @@ -0,0 +1,63 @@ +import pytest +from taf.auth_repo import AuthenticationRepository +from taf.tests.test_updater.conftest import ( + SetupManager, + add_valid_target_commits, + remove_commits, +) +from taf.tests.test_updater.update_utils import ( + clone_repositories, + load_target_repositories, + update_and_check_commit_shas, +) +from taf.updater.types.update import OperationType + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + }, + ], + indirect=True, +) +def test_update_valid_when_several_updates(origin_auth_repo, client_dir): + clone_repositories(origin_auth_repo, client_dir) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task(add_valid_target_commits) + setup_manager.add_task(add_valid_target_commits) + setup_manager.add_task(add_valid_target_commits) + setup_manager.execute_tasks() + + update_output = update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + skip_check_last_validated=True, + ) + update_output["changed"] = True + client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) + client_target_repos = load_target_repositories(client_auth_repo) + setup_manager = SetupManager(client_auth_repo) + for target_repo in client_target_repos.values(): + setup_manager.add_task( + remove_commits, kwargs={"repo_path": target_repo.path, "num_commits": 1} + ) + break + setup_manager.execute_tasks() + update_output = update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + skip_check_last_validated=True, + ) + update_output["changed"] = True + update_output = update_and_check_commit_shas( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + skip_check_last_validated=True, + ) + update_output["changed"] = False diff --git a/taf/updater/updater_pipeline.py b/taf/updater/updater_pipeline.py index fb01ca94..24ba5b73 100644 --- a/taf/updater/updater_pipeline.py +++ b/taf/updater/updater_pipeline.py @@ -1406,6 +1406,7 @@ def merge_commits(self): taf_logger.info( f"{self.state.auth_repo_name}: Merging commits into target repositories..." ) + events_list = [] try: if self.only_validate: return self.state.update_status @@ -1421,10 +1422,14 @@ def merge_commits(self): ].items(): last_validated_commit = validated_commits[-1] commit_to_merge = last_validated_commit - _merge_commit( + update_status = _merge_commit( repository, branch, commit_to_merge, force_revert=True ) + events_list.append(update_status) + if self.state.event == Event.UNCHANGED and Event.CHANGED in events_list: + # the law repository was not updated, but one of the target repositories was + self.state.event = Event.CHANGED return self.state.update_status except Exception as e: self.state.errors.append(e) @@ -1789,7 +1794,7 @@ def _merge_commit(repository, branch, commit_to_merge, force_revert=True): ) if repository.top_commit_of_branch(branch) == commit_to_merge: - return + return Event.UNCHANGED commits_since_to_merge = repository.all_commits_since_commit( commit_to_merge, branch=branch @@ -1818,3 +1823,4 @@ def _merge_commit(repository, branch, commit_to_merge, force_revert=True): format_commit(commit_to_merge), branch, ) + return Event.CHANGED From b2bea1f9bd12d6fc563d6a77685e7d79d18796d3 Mon Sep 17 00:00:00 2001 From: Renata Date: Thu, 19 Sep 2024 23:49:30 -0400 Subject: [PATCH 17/19] chore: fix typos --- taf/tests/test_updater/test_clone/test_clone_valid.py | 6 +++--- taf/tests/test_updater/test_update/test_update_valid.py | 4 ++-- taf/tests/test_updater/update_utils.py | 2 +- taf/updater/updater_pipeline.py | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/taf/tests/test_updater/test_clone/test_clone_valid.py b/taf/tests/test_updater/test_clone/test_clone_valid.py index 1c415c0e..5ee63338 100644 --- a/taf/tests/test_updater/test_clone/test_clone_valid.py +++ b/taf/tests/test_updater/test_clone/test_clone_valid.py @@ -14,7 +14,7 @@ from taf.tests.test_updater.update_utils import ( clone_client_target_repos_without_updater, update_and_check_commit_shas, - verify_repos_eixsts, + verify_repos_eixst, ) from taf.updater.types.update import OperationType, UpdateType @@ -340,7 +340,7 @@ def test_clone_when_target_empty(origin_auth_repo, client_dir): client_dir, expected_repo_type=UpdateType.EITHER, ) - verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) + verify_repos_eixst(client_dir, origin_auth_repo, exists=["notempty"]) @pytest.mark.parametrize( @@ -369,4 +369,4 @@ def test_clone_when_no_target_file_and_commit(origin_auth_repo, client_dir): client_dir, expected_repo_type=UpdateType.EITHER, ) - verify_repos_eixsts(client_dir, origin_auth_repo, exists=["target1"]) + verify_repos_eixst(client_dir, origin_auth_repo, exists=["target1"]) diff --git a/taf/tests/test_updater/test_update/test_update_valid.py b/taf/tests/test_updater/test_update/test_update_valid.py index 2e04fbbb..b4e0e9d8 100644 --- a/taf/tests/test_updater/test_update/test_update_valid.py +++ b/taf/tests/test_updater/test_update/test_update_valid.py @@ -23,7 +23,7 @@ clone_repositories, load_target_repositories, update_and_check_commit_shas, - verify_repos_eixsts, + verify_repos_eixst, ) from taf.updater.types.update import OperationType, UpdateType @@ -752,7 +752,7 @@ def test_update_when_target_empty(origin_auth_repo, client_dir): client_dir, skip_check_last_validated=True, ) - verify_repos_eixsts(client_dir, origin_auth_repo, exists=["notempty"]) + verify_repos_eixst(client_dir, origin_auth_repo, exists=["notempty"]) @pytest.mark.parametrize( diff --git a/taf/tests/test_updater/update_utils.py b/taf/tests/test_updater/update_utils.py index efd53416..3b49db2b 100644 --- a/taf/tests/test_updater/update_utils.py +++ b/taf/tests/test_updater/update_utils.py @@ -322,7 +322,7 @@ def _update_expect_error(): assert not client_repository.path.exists() -def verify_repos_eixsts( +def verify_repos_eixst( client_dir: Path, origin_auth_repo: AuthenticationRepository, exists: list ): client_auth_repo = AuthenticationRepository(path=client_dir / origin_auth_repo.name) diff --git a/taf/updater/updater_pipeline.py b/taf/updater/updater_pipeline.py index 24ba5b73..b5f13b6d 100644 --- a/taf/updater/updater_pipeline.py +++ b/taf/updater/updater_pipeline.py @@ -467,7 +467,7 @@ def check_if_local_repositories_clean(self): taf_logger.info( f"Resetting repository {auth_repo.name} to clean state for a forced update." ) - _remove_unpushed_commtis( + _remove_unpushed_commits( auth_repo, auth_repo.default_branch, unpushed_commits ) @@ -502,7 +502,7 @@ def check_if_local_repositories_clean(self): taf_logger.info( f"Resetting repository {repository.name} to clean state for a forced update." ) - _remove_unpushed_commtis( + _remove_unpushed_commits( repository, branch, unpushed_commits ) else: @@ -1428,7 +1428,7 @@ def merge_commits(self): events_list.append(update_status) if self.state.event == Event.UNCHANGED and Event.CHANGED in events_list: - # the law repository was not updated, but one of the target repositories was + # the auth repository was not updated, but one of the target repositories was self.state.event = Event.CHANGED return self.state.update_status except Exception as e: @@ -1616,7 +1616,7 @@ def _is_unauthenticated_allowed(repository): return repository.custom.get("allow-unauthenticated-commits", False) -def _remove_unpushed_commtis(repository, branch, unpushed_commits): +def _remove_unpushed_commits(repository, branch, unpushed_commits): repository.clean_and_reset() repository.checkout_branch(branch) repository.reset_num_of_commits(len(unpushed_commits), hard=True) From 36deb3949acace5cbda954f061d8141ad808e751 Mon Sep 17 00:00:00 2001 From: Renata Date: Fri, 20 Sep 2024 01:39:35 -0400 Subject: [PATCH 18/19] test: add a test for update when targets metadata file is invalid --- CHANGELOG.md | 1 + taf/tests/test_updater/conftest.py | 2 +- .../test_update/test_update_invalid.py | 36 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8b0c1fa..d849bcb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning][semver]. ### Fixed +- Fix update status when a target repo was updated and the auth repo was not ([532]) - Fix merge-commit which wasn't updating the remote-tracking branch ([532]) - Fix removal of additional local commits ([532]) - Fix top-level authentication repository update to correctly update child auth repos ([528]) diff --git a/taf/tests/test_updater/conftest.py b/taf/tests/test_updater/conftest.py index a2885612..37f27a72 100644 --- a/taf/tests/test_updater/conftest.py +++ b/taf/tests/test_updater/conftest.py @@ -623,7 +623,7 @@ def update_role_metadata_invalid_signature( content["signatures"][0]["sign"] = "invalid signature" version = content["signed"]["version"] content["signed"]["version"] = version + 1 - role_metadata_path.write_text(json.dumps(content)) + role_metadata_path.write_text(json.dumps(content, indent=4)) auth_repo.commit("Invalid metadata update") diff --git a/taf/tests/test_updater/test_update/test_update_invalid.py b/taf/tests/test_updater/test_update/test_update_invalid.py index 32f0cd6f..fae84326 100644 --- a/taf/tests/test_updater/test_update/test_update_invalid.py +++ b/taf/tests/test_updater/test_update/test_update_invalid.py @@ -1,6 +1,7 @@ import pytest from taf.auth_repo import AuthenticationRepository from taf.tests.test_updater.conftest import ( + INVALID_KEYS_PATTERN, TARGET_MISSMATCH_PATTERN, FORCED_UPDATE_PATTERN, UNCOMMITTED_CHANGES, @@ -10,9 +11,12 @@ add_unauthenticated_commits_to_all_target_repos, add_valid_target_commits, create_index_lock, + update_expiration_dates, update_file_without_commit, + update_role_metadata_invalid_signature, ) from taf.tests.test_updater.update_utils import ( + check_if_last_validated_commit_exists, clone_repositories, update_invalid_repos_and_check_if_repos_exist, ) @@ -237,3 +241,35 @@ def test_update_with_invalid_last_validated_commit(origin_auth_repo, client_dir) COMMIT_NOT_FOUND_PATTERN, True, ) + + +@pytest.mark.parametrize( + "origin_auth_repo", + [ + { + "targets_config": [{"name": "target1"}, {"name": "target2"}], + } + ], + indirect=True, +) +def test_update_invalid_target_invalid_singature(origin_auth_repo, client_dir): + + clone_repositories(origin_auth_repo, client_dir) + + setup_manager = SetupManager(origin_auth_repo) + setup_manager.add_task( + update_role_metadata_invalid_signature, kwargs={"role": "targets"} + ) + setup_manager.add_task(update_expiration_dates) + setup_manager.execute_tasks() + + update_invalid_repos_and_check_if_repos_exist( + OperationType.UPDATE, + origin_auth_repo, + client_dir, + INVALID_KEYS_PATTERN, + True, + ) + client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) + # make sure that the last validated commit does not exist + check_if_last_validated_commit_exists(client_auth_repo, True) From 68622b167366331fca3c4b0065917dffe046fb81 Mon Sep 17 00:00:00 2001 From: Renata Date: Fri, 20 Sep 2024 20:20:05 -0400 Subject: [PATCH 19/19] test: add missing asserts --- taf/tests/test_updater/test_update/test_updater_output.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/taf/tests/test_updater/test_update/test_updater_output.py b/taf/tests/test_updater/test_update/test_updater_output.py index 414e9403..56832ac2 100644 --- a/taf/tests/test_updater/test_update/test_updater_output.py +++ b/taf/tests/test_updater/test_update/test_updater_output.py @@ -37,7 +37,7 @@ def test_update_valid_when_several_updates(origin_auth_repo, client_dir): client_dir, skip_check_last_validated=True, ) - update_output["changed"] = True + assert update_output["changed"] client_auth_repo = AuthenticationRepository(client_dir, origin_auth_repo.name) client_target_repos = load_target_repositories(client_auth_repo) setup_manager = SetupManager(client_auth_repo) @@ -53,11 +53,11 @@ def test_update_valid_when_several_updates(origin_auth_repo, client_dir): client_dir, skip_check_last_validated=True, ) - update_output["changed"] = True + assert update_output["changed"] update_output = update_and_check_commit_shas( OperationType.UPDATE, origin_auth_repo, client_dir, skip_check_last_validated=True, ) - update_output["changed"] = False + assert not update_output["changed"]