def test_sync_apps_happy_flow(self): SyncAppsCommand(ARGS).execute() assert self.mock_manager.method_calls == [ call.GitRepoApiFactory.create(ARGS, "TEAM_ORGA", "TEAM_REPO",), call.GitRepoApiFactory.create(ARGS, "ROOT_ORGA", "ROOT_REPO",), call.GitRepo(self.team_config_git_repo_api_mock), call.GitRepo(self.root_config_git_repo_api_mock), call.GitRepo_team.get_clone_url(), call.logging.info("Team config repository: %s", "https://team.config.repo.git"), call.GitRepo_root.get_clone_url(), call.logging.info("Root config repository: %s", "https://root.config.repo.git"), call.GitRepo_team.clone(), call.GitRepo_team.get_full_file_path("."), call.os.listdir("/tmp/team-config-repo/."), call.os.path.join("/tmp/team-config-repo/.", "my-app"), call.os.path.isdir("/tmp/team-config-repo/./my-app"), call.logging.info("Found %s app(s) in apps repository: %s", 1, "my-app"), call.logging.info("Searching apps repository in root repository's 'apps/' directory..."), call.GitRepo_root.clone(), call.GitRepo_root.get_full_file_path("bootstrap/values.yaml"), call.yaml_file_load("/tmp/root-config-repo/bootstrap/values.yaml"), call.GitRepo_team.get_clone_url(), call.logging.info("Analyzing %s in root repository", "apps/team-non-prod.yaml"), call.GitRepo_root.get_full_file_path("apps/team-non-prod.yaml"), call.yaml_file_load("/tmp/root-config-repo/apps/team-non-prod.yaml"), call.logging.info("Found apps repository in %s", "apps/team-non-prod.yaml"), call.logging.info("Analyzing %s in root repository", "apps/other-team-non-prod.yaml"), call.GitRepo_root.get_full_file_path("apps/other-team-non-prod.yaml"), call.yaml_file_load("/tmp/root-config-repo/apps/other-team-non-prod.yaml"), call.logging.info("Sync applications in root repository's %s.", "apps/team-non-prod.yaml"), call.merge_yaml_element("/tmp/root-config-repo/apps/team-non-prod.yaml", "applications", {"my-app": {}}), call.GitRepo_team.get_author_from_last_commit(), call.GitRepo_root.commit("GIT_USER", "GIT_EMAIL", "author updated apps/team-non-prod.yaml"), call.GitRepo_root.push(), ]
def test_create_new_preview_invalid_chart_template(self): self.os_mock.path.isdir.side_effect = lambda path: { "/tmp/target-repo/my-app-685912d3-preview": False, # doesn't exist yet -> expect create "/tmp/template-repo/.preview-templates/my-app": True, }[path] self.update_yaml_file_mock.side_effect = KeyError() try: CreatePreviewCommand(ARGS).execute() self.fail() except GitOpsException as ex: self.assertEqual( "Key 'name' not found in file: my-app-685912d3-preview/Chart.yaml", str(ex)) assert self.mock_manager.method_calls == [ call.load_gitops_config( ARGS, "ORGA", "REPO", ), call.yaml_file_dump( INFO_YAML, "/tmp/gitopscli-preview-info.yaml", ), call.GitRepoApiFactory.create( ARGS, "PREVIEW_TARGET_ORG", "PREVIEW_TARGET_REPO", ), call.GitRepo(self.target_git_repo_api_mock), call.GitRepo.clone(None), call.GitRepoApiFactory.create( ARGS, "PREVIEW_TEMPLATE_ORG", "PREVIEW_TEMPLATE_REPO", ), call.GitRepo(self.template_git_repo_api_mock), call.GitRepo.clone("template-branch"), call.GitRepo.get_full_file_path("my-app-685912d3-preview"), call.os.path.isdir("/tmp/target-repo/my-app-685912d3-preview"), call.logging.info("Create new folder for preview: %s", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path(".preview-templates/my-app"), call.os.path.isdir("/tmp/template-repo/.preview-templates/my-app"), call.logging.info("Using the preview template folder: %s", ".preview-templates/my-app"), call.shutil.copytree( "/tmp/template-repo/.preview-templates/my-app", "/tmp/target-repo/my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/Chart.yaml"), call.update_yaml_file( "/tmp/target-repo/my-app-685912d3-preview/Chart.yaml", "name", "my-app-685912d3-preview"), ]
def test_single_commit_single_value_change_happy_flow(self): args = DeployCommand.Args( file="test/file.yml", values={"a.b.c": "foo"}, username="******", password="******", git_user="******", git_email="GIT_EMAIL", create_pr=False, auto_merge=False, single_commit=True, organisation="ORGA", repository_name="REPO", git_provider=GitProvider.GITHUB, git_provider_url=None, commit_message=None, ) DeployCommand(args).execute() assert self.mock_manager.method_calls == [ call.GitRepoApiFactory.create(args, "ORGA", "REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), call.GitRepo.get_full_file_path("test/file.yml"), call.update_yaml_file("/tmp/created-tmp-dir/test/file.yml", "a.b.c", "foo"), call.logging.info("Updated yaml property %s to %s", "a.b.c", "foo"), call.GitRepo.commit("GIT_USER", "GIT_EMAIL", "changed 'a.b.c' to 'foo' in test/file.yml"), call.GitRepo.push(), ]
def test_delete_existing_happy_flow(self): args = DeletePreviewCommand.Args( username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORGA", repository_name="REPO", git_provider=GitProvider.GITHUB, git_provider_url=None, preview_id="PREVIEW_ID", expect_preview_exists=False, ) DeletePreviewCommand(args).execute() assert self.mock_manager.method_calls == [ call.load_gitops_config(args, "ORGA", "REPO"), call.GitRepoApiFactory.create(args, "PREVIEW_TARGET_ORG", "PREVIEW_TARGET_REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone("target-branch"), call.logging.info("Preview folder name: %s", "app-685912d3-preview"), call.GitRepo.get_full_file_path("app-685912d3-preview"), call.os.path.exists("/tmp/created-tmp-dir/app-685912d3-preview"), call.shutil.rmtree("/tmp/created-tmp-dir/app-685912d3-preview", ignore_errors=True), call.GitRepo.commit( "GIT_USER", "GIT_EMAIL", "Delete preview environment for 'APP' and preview id 'PREVIEW_ID'." ), call.GitRepo.push(), ]
def test_delete_missing_happy_flow(self): self.os_mock.path.exists.return_value = False args = DeletePreviewCommand.Args( username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORGA", repository_name="REPO", git_provider=GitProvider.GITHUB, git_provider_url=None, preview_id="PREVIEW_ID", expect_preview_exists=False, ) DeletePreviewCommand(args).execute() assert self.mock_manager.method_calls == [ call.load_gitops_config(args, "ORGA", "REPO"), call.GitRepoApiFactory.create(args, "PREVIEW_TARGET_ORG", "PREVIEW_TARGET_REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone("target-branch"), call.logging.info("Preview folder name: %s", "app-685912d3-preview"), call.GitRepo.get_full_file_path("app-685912d3-preview"), call.os.path.exists("/tmp/created-tmp-dir/app-685912d3-preview"), call.logging.info( "No preview environment for '%s' and preview id '%s'. I'm done here.", "APP", "PREVIEW_ID"), ]
def test_delete_missing_but_expected_error(self): self.os_mock.path.exists.return_value = False args = DeletePreviewCommand.Args( username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORGA", repository_name="REPO", git_provider=GitProvider.GITHUB, git_provider_url=None, preview_id="PREVIEW_ID", expect_preview_exists=True, # we expect an existing preview ) with pytest.raises(GitOpsException) as ex: DeletePreviewCommand(args).execute() self.assertEqual( str(ex.value), "There was no preview with name: app-685912d3-preview") assert self.mock_manager.method_calls == [ call.load_gitops_config(args, "ORGA", "REPO"), call.GitRepoApiFactory.create(args, "PREVIEW_TARGET_ORG", "PREVIEW_TARGET_REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone("target-branch"), call.logging.info("Preview folder name: %s", "app-685912d3-preview"), call.GitRepo.get_full_file_path("app-685912d3-preview"), call.os.path.exists("/tmp/created-tmp-dir/app-685912d3-preview"), ]
def test_nothing_to_update(self): self.update_yaml_file_mock.return_value = False args = DeployCommand.Args( file="test/file.yml", values={"a.b.c": "foo", "a.b.d": "bar"}, username="******", password="******", git_user="******", git_email="GIT_EMAIL", create_pr=False, auto_merge=False, single_commit=False, organisation="ORGA", repository_name="REPO", git_provider=GitProvider.GITHUB, git_provider_url=None, commit_message=None, ) DeployCommand(args).execute() assert self.mock_manager.method_calls == [ call.GitRepoApiFactory.create(args, "ORGA", "REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), call.GitRepo.get_full_file_path("test/file.yml"), call.update_yaml_file("/tmp/created-tmp-dir/test/file.yml", "a.b.c", "foo"), call.logging.info("Yaml property %s already up-to-date", "a.b.c"), call.update_yaml_file("/tmp/created-tmp-dir/test/file.yml", "a.b.d", "bar"), call.logging.info("Yaml property %s already up-to-date", "a.b.d"), call.logging.info("All values already up-to-date. I'm done here."), ]
def test_clone_error(self): clone_exception = GitOpsException("dummy clone error") self.git_repo_mock.clone.side_effect = clone_exception args = DeployCommand.Args( file="test/file.yml", values={ "a.b.c": "foo", "a.b.d": "bar" }, username="******", password="******", git_user="******", git_email="GIT_EMAIL", create_pr=False, auto_merge=False, single_commit=False, organisation="ORGA", repository_name="REPO", git_provider=GitProvider.GITHUB, git_provider_url=None, commit_message=None, ) with pytest.raises(GitOpsException) as ex: DeployCommand(args).execute() self.assertEqual(ex.value, clone_exception) assert self.mock_manager.method_calls == [ call.GitRepoApiFactory.create(args, "ORGA", "REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), ]
def test_key_not_found(self): self.update_yaml_file_mock.side_effect = KeyError("dummy key error") args = DeployCommand.Args( file="test/file.yml", values={ "a.b.c": "foo", "a.b.d": "bar" }, username="******", password="******", git_user="******", git_email="GIT_EMAIL", create_pr=False, auto_merge=False, single_commit=False, organisation="ORGA", repository_name="REPO", git_provider=GitProvider.GITHUB, git_provider_url=None, commit_message=None, ) with pytest.raises(GitOpsException) as ex: DeployCommand(args).execute() self.assertEqual(str(ex.value), "Key 'a.b.c' not found in file: test/file.yml") assert self.mock_manager.method_calls == [ call.GitRepoApiFactory.create(args, "ORGA", "REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), call.GitRepo.get_full_file_path("test/file.yml"), call.update_yaml_file("/tmp/created-tmp-dir/test/file.yml", "a.b.c", "foo"), ]
def test_create_preview_with_invalid_replacement_path(self): self.update_yaml_file_mock.side_effect = KeyError() try: CreatePreviewCommand(ARGS).execute() self.fail() except GitOpsException as ex: self.assertEqual( "Key 'name' not found in file: my-app-685912d3-preview/Chart.yaml", str(ex)) assert self.mock_manager.method_calls == [ call.load_gitops_config( ARGS, "ORGA", "REPO", ), call.yaml_file_dump( INFO_YAML, "/tmp/gitopscli-preview-info.yaml", ), call.GitRepoApiFactory.create( ARGS, "PREVIEW_TARGET_ORG", "PREVIEW_TARGET_REPO", ), call.GitRepo(self.target_git_repo_api_mock), call.GitRepo.clone(None), call.GitRepoApiFactory.create( ARGS, "PREVIEW_TEMPLATE_ORG", "PREVIEW_TEMPLATE_REPO", ), call.GitRepo(self.template_git_repo_api_mock), call.GitRepo.clone("template-branch"), call.GitRepo.get_full_file_path("my-app-685912d3-preview"), call.os.path.isdir("/tmp/target-repo/my-app-685912d3-preview"), call.logging.info("Use existing folder for preview: %s", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/Chart.yaml"), call.update_yaml_file( "/tmp/target-repo/my-app-685912d3-preview/Chart.yaml", "name", "my-app-685912d3-preview", ), ]
def test_create_preview_for_unknown_template(self): self.os_mock.path.isdir.side_effect = lambda path: { "/tmp/target-repo/my-app-685912d3-preview": False, "/tmp/template-repo/.preview-templates/my-app": False, # preview template missing -> expect error }[path] try: CreatePreviewCommand(ARGS).execute() self.fail() except GitOpsException as ex: self.assertEqual( "The preview template folder does not exist: .preview-templates/my-app", str(ex)) assert self.mock_manager.method_calls == [ call.load_gitops_config( ARGS, "ORGA", "REPO", ), call.yaml_file_dump( INFO_YAML, "/tmp/gitopscli-preview-info.yaml", ), call.GitRepoApiFactory.create( ARGS, "PREVIEW_TARGET_ORG", "PREVIEW_TARGET_REPO", ), call.GitRepo(self.target_git_repo_api_mock), call.GitRepo.clone(None), call.GitRepoApiFactory.create( ARGS, "PREVIEW_TEMPLATE_ORG", "PREVIEW_TEMPLATE_REPO", ), call.GitRepo(self.template_git_repo_api_mock), call.GitRepo.clone("template-branch"), call.GitRepo.get_full_file_path("my-app-685912d3-preview"), call.os.path.isdir("/tmp/target-repo/my-app-685912d3-preview"), call.logging.info("Create new folder for preview: %s", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path(".preview-templates/my-app"), call.os.path.isdir("/tmp/template-repo/.preview-templates/my-app"), ]
def test_sync_apps_already_up_to_date(self): self.yaml_file_load_mock.side_effect = lambda file_path: { "/tmp/root-config-repo/bootstrap/values.yaml": { "bootstrap": [{"name": "team-non-prod"}, {"name": "other-team-non-prod"}], }, "/tmp/root-config-repo/apps/team-non-prod.yaml": { "repository": "https://team.config.repo.git", "applications": {"my-app": None}, # my-app already exists }, "/tmp/root-config-repo/apps/other-team-non-prod.yaml": { "repository": "https://other-team.config.repo.git", "applications": {}, }, }[file_path] SyncAppsCommand(ARGS).execute() assert self.mock_manager.method_calls == [ call.GitRepoApiFactory.create(ARGS, "TEAM_ORGA", "TEAM_REPO",), call.GitRepoApiFactory.create(ARGS, "ROOT_ORGA", "ROOT_REPO",), call.GitRepo(self.team_config_git_repo_api_mock), call.GitRepo(self.root_config_git_repo_api_mock), call.GitRepo_team.get_clone_url(), call.logging.info("Team config repository: %s", "https://team.config.repo.git"), call.GitRepo_root.get_clone_url(), call.logging.info("Root config repository: %s", "https://root.config.repo.git"), call.GitRepo_team.clone(), call.GitRepo_team.get_full_file_path("."), call.os.listdir("/tmp/team-config-repo/."), call.os.path.join("/tmp/team-config-repo/.", "my-app"), call.os.path.isdir("/tmp/team-config-repo/./my-app"), call.logging.info("Found %s app(s) in apps repository: %s", 1, "my-app"), call.logging.info("Searching apps repository in root repository's 'apps/' directory..."), call.GitRepo_root.clone(), call.GitRepo_root.get_full_file_path("bootstrap/values.yaml"), call.yaml_file_load("/tmp/root-config-repo/bootstrap/values.yaml"), call.GitRepo_team.get_clone_url(), call.logging.info("Analyzing %s in root repository", "apps/team-non-prod.yaml"), call.GitRepo_root.get_full_file_path("apps/team-non-prod.yaml"), call.yaml_file_load("/tmp/root-config-repo/apps/team-non-prod.yaml"), call.logging.info("Found apps repository in %s", "apps/team-non-prod.yaml"), call.logging.info("Analyzing %s in root repository", "apps/other-team-non-prod.yaml"), call.GitRepo_root.get_full_file_path("apps/other-team-non-prod.yaml"), call.yaml_file_load("/tmp/root-config-repo/apps/other-team-non-prod.yaml"), call.logging.info("Root repository already up-to-date. I'm done here."), ]
def test_create_pr_and_merge_happy_flow(self): args = DeployCommand.Args( file="test/file.yml", values={ "a.b.c": "foo", "a.b.d": "bar" }, username="******", password="******", git_user="******", git_email="GIT_EMAIL", create_pr=True, auto_merge=True, single_commit=False, organisation="ORGA", repository_name="REPO", git_provider=GitProvider.GITHUB, git_provider_url=None, commit_message=None, ) DeployCommand(args).execute() assert self.mock_manager.method_calls == [ call.GitRepoApiFactory.create(args, "ORGA", "REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), call.uuid.uuid4(), call.GitRepo.new_branch("gitopscli-deploy-b973b5bb"), call.GitRepo.get_full_file_path("test/file.yml"), call.update_yaml_file("/tmp/created-tmp-dir/test/file.yml", "a.b.c", "foo"), call.logging.info("Updated yaml property %s to %s", "a.b.c", "foo"), call.GitRepo.commit("GIT_USER", "GIT_EMAIL", "changed 'a.b.c' to 'foo' in test/file.yml"), call.update_yaml_file("/tmp/created-tmp-dir/test/file.yml", "a.b.d", "bar"), call.logging.info("Updated yaml property %s to %s", "a.b.d", "bar"), call.GitRepo.commit("GIT_USER", "GIT_EMAIL", "changed 'a.b.d' to 'bar' in test/file.yml"), call.GitRepo.push(), call.GitRepoApi.create_pull_request_to_default_branch( "gitopscli-deploy-b973b5bb", "Updated values in test/file.yml", "Updated 2 values in `test/file.yml`:\n```yaml\na.b.c: foo\na.b.d: bar\n```\n", ), call.GitRepoApi.merge_pull_request(42, "merge"), call.GitRepoApi.delete_branch("gitopscli-deploy-b973b5bb"), ]
def test_happy_flow(self): gitops_config = load_gitops_config( git_api_config=self.git_api_config, organisation="ORGA", repository_name="REPO" ) assert gitops_config == self.gitops_config_mock assert self.mock_manager.method_calls == [ call.GitRepoApiFactory.create(self.git_api_config, "ORGA", "REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), call.GitRepo.get_full_file_path(".gitops.config.yaml"), call.yaml_file_load("/repo-dir/.gitops.config.yaml"), call.GitOpsConfig.from_yaml({"dummy": "gitopsconfig"}), ]
def test_file_not_found(self): self.yaml_file_load_mock.side_effect = FileNotFoundError("file not found") with pytest.raises(GitOpsException) as ex: load_gitops_config(git_api_config=self.git_api_config, organisation="ORGA", repository_name="REPO") self.assertEqual(str(ex.value), "No such file: .gitops.config.yaml") assert self.mock_manager.method_calls == [ call.GitRepoApiFactory.create(self.git_api_config, "ORGA", "REPO"), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), call.GitRepo.get_full_file_path(".gitops.config.yaml"), call.yaml_file_load("/repo-dir/.gitops.config.yaml"), ]
def test_create_preview_with_invalid_replacement_path(self): self.update_yaml_file_mock.side_effect = KeyError() try: CreatePreviewCommand(ARGS).execute() self.fail() except GitOpsException as ex: self.assertEqual( "Key 'image.tag' not found in file: my-app-685912d3-preview/values.yaml", str(ex)) assert self.mock_manager.method_calls == [ call.load_gitops_config( ARGS, "ORGA", "REPO", ), call.yaml_file_dump( INFO_YAML, "/tmp/gitopscli-preview-info.yaml", ), call.GitRepoApiFactory.create( ARGS, "TEAM_CONFIG_ORG", "TEAM_CONFIG_REPO", ), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), call.GitRepo.get_full_file_path("my-app-685912d3-preview"), call.os.path.isdir("/tmp/created-tmp-dir/my-app-685912d3-preview"), call.logging.info("Use existing folder for preview: %s", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/values.yaml"), call.update_yaml_file( "/tmp/created-tmp-dir/my-app-685912d3-preview/values.yaml", "image.tag", "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9", ), ]
def test_create_new_preview_from_same_template_target_repo(self): gitops_config: GitOpsConfig = self.load_gitops_config_mock.return_value self.load_gitops_config_mock.return_value = GitOpsConfig( api_version=gitops_config.api_version, application_name=gitops_config.application_name, preview_host_template=gitops_config.preview_host_template, preview_template_organisation=gitops_config. preview_target_organisation, # template = target preview_template_repository=gitops_config. preview_target_repository, # template = target preview_template_path_template=gitops_config. preview_template_path_template, preview_template_branch=gitops_config. preview_target_branch, # template = target preview_target_organisation=gitops_config. preview_target_organisation, preview_target_repository=gitops_config.preview_target_repository, preview_target_branch=gitops_config.preview_target_branch, preview_target_namespace_template=gitops_config. preview_target_namespace_template, preview_target_max_namespace_length=gitops_config. preview_target_max_namespace_length, replacements=gitops_config.replacements, ) self.os_mock.path.isdir.side_effect = lambda path: { "/tmp/target-repo/my-app-685912d3-preview": False, # doesn't exist yet -> expect create "/tmp/target-repo/.preview-templates/my-app": True, }[path] deployment_created_callback = Mock(return_value=None) command = CreatePreviewCommand(ARGS) command.register_callbacks( deployment_already_up_to_date_callback=lambda route_host: self. fail("should not be called"), deployment_updated_callback=lambda route_host: self.fail( "should not be called"), deployment_created_callback=deployment_created_callback, ) command.execute() deployment_created_callback.assert_called_once_with( "app.xy-685912d3.example.tld") assert self.mock_manager.method_calls == [ call.load_gitops_config( ARGS, "ORGA", "REPO", ), call.yaml_file_dump( { "previewId": "PREVIEW_ID", "previewIdHash": "685912d3", "routeHost": "app.xy-685912d3.example.tld", "namespace": "my-app-685912d3-preview", }, "/tmp/gitopscli-preview-info.yaml", ), call.GitRepoApiFactory.create( ARGS, "PREVIEW_TARGET_ORG", "PREVIEW_TARGET_REPO", ), # only clone once for template and target call.GitRepo(self.target_git_repo_api_mock), call.GitRepo.clone(None), call.GitRepo.get_full_file_path("my-app-685912d3-preview"), call.os.path.isdir("/tmp/target-repo/my-app-685912d3-preview"), call.logging.info("Create new folder for preview: %s", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path(".preview-templates/my-app"), call.os.path.isdir("/tmp/target-repo/.preview-templates/my-app"), call.logging.info("Using the preview template folder: %s", ".preview-templates/my-app"), call.shutil.copytree("/tmp/target-repo/.preview-templates/my-app", "/tmp/target-repo/my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/Chart.yaml"), call.update_yaml_file( "/tmp/target-repo/my-app-685912d3-preview/Chart.yaml", "name", "my-app-685912d3-preview"), call.logging.info("Replaced property '%s' in '%s' with value: %s", "name", "Chart.yaml", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/values.yaml"), call.update_yaml_file( "/tmp/target-repo/my-app-685912d3-preview/values.yaml", "image.tag", "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9", ), call.logging.info( "Replaced property '%s' in '%s' with value: %s", "image.tag", "values.yaml", "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9", ), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/values.yaml"), call.update_yaml_file( "/tmp/target-repo/my-app-685912d3-preview/values.yaml", "route.host", "app.xy-685912d3.example.tld"), call.logging.info( "Replaced property '%s' in '%s' with value: %s", "route.host", "values.yaml", "app.xy-685912d3.example.tld", ), call.GitRepo.commit( "GIT_USER", "GIT_EMAIL", "Create new preview environment for 'my-app' and git hash '3361723dbd91fcfae7b5b8b8b7d462fbc14187a9'.", ), call.GitRepo.push(), ]
def test_create_new_preview(self): self.os_mock.path.isdir.side_effect = lambda path: { "/tmp/created-tmp-dir/my-app-685912d3-preview": False, # doesn't exist yet -> expect create "/tmp/created-tmp-dir/.preview-templates/my-app": True, }[path] deployment_created_callback = Mock(return_value=None) command = CreatePreviewCommand(ARGS) command.register_callbacks( deployment_already_up_to_date_callback=lambda route_host: self. fail("should not be called"), deployment_updated_callback=lambda route_host: self.fail( "should not be called"), deployment_created_callback=deployment_created_callback, ) command.execute() deployment_created_callback.assert_called_once_with( "app.xy-685912d3.example.tld") assert self.mock_manager.method_calls == [ call.load_gitops_config( ARGS, "ORGA", "REPO", ), call.yaml_file_dump( { "previewId": "PREVIEW_ID", "previewIdHash": "685912d3", "routeHost": "app.xy-685912d3.example.tld", "namespace": "my-app-685912d3-preview", }, "/tmp/gitopscli-preview-info.yaml", ), call.GitRepoApiFactory.create( ARGS, "TEAM_CONFIG_ORG", "TEAM_CONFIG_REPO", ), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), call.GitRepo.get_full_file_path("my-app-685912d3-preview"), call.os.path.isdir("/tmp/created-tmp-dir/my-app-685912d3-preview"), call.logging.info("Create new folder for preview: %s", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path(".preview-templates/my-app"), call.os.path.isdir( "/tmp/created-tmp-dir/.preview-templates/my-app"), call.logging.info("Using the preview template folder: %s", ".preview-templates/my-app"), call.shutil.copytree( "/tmp/created-tmp-dir/.preview-templates/my-app", "/tmp/created-tmp-dir/my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/Chart.yaml"), call.update_yaml_file( "/tmp/created-tmp-dir/my-app-685912d3-preview/Chart.yaml", "name", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/values.yaml"), call.update_yaml_file( "/tmp/created-tmp-dir/my-app-685912d3-preview/values.yaml", "image.tag", "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9", ), call.logging.info("Replaced property '%s' with value: %s", "image.tag", "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/values.yaml"), call.update_yaml_file( "/tmp/created-tmp-dir/my-app-685912d3-preview/values.yaml", "route.host", "app.xy-685912d3.example.tld"), call.logging.info("Replaced property '%s' with value: %s", "route.host", "app.xy-685912d3.example.tld"), call.GitRepo.commit( "GIT_USER", "GIT_EMAIL", "Create new preview environment for 'my-app' and git hash '3361723dbd91fcfae7b5b8b8b7d462fbc14187a9'.", ), call.GitRepo.push(), ]
def test_preview_already_up_to_date(self): self.os_mock.path.isdir.side_effect = lambda path: { "/tmp/target-repo/my-app-685912d3-preview": True, # already exists -> expect update }[path] self.update_yaml_file_mock.return_value = False # nothing updated -> expect already up to date deployment_already_up_to_date_callback = Mock(return_value=None) command = CreatePreviewCommand(ARGS) command.register_callbacks( deployment_already_up_to_date_callback= deployment_already_up_to_date_callback, deployment_updated_callback=lambda route_host: self.fail( "should not be called"), deployment_created_callback=lambda route_host: self.fail( "should not be called"), ) command.execute() deployment_already_up_to_date_callback.assert_called_once_with( "app.xy-685912d3.example.tld") assert self.mock_manager.method_calls == [ call.load_gitops_config( ARGS, "ORGA", "REPO", ), call.yaml_file_dump( INFO_YAML, "/tmp/gitopscli-preview-info.yaml", ), call.GitRepoApiFactory.create( ARGS, "PREVIEW_TARGET_ORG", "PREVIEW_TARGET_REPO", ), call.GitRepo(self.target_git_repo_api_mock), call.GitRepo.clone(None), call.GitRepoApiFactory.create( ARGS, "PREVIEW_TEMPLATE_ORG", "PREVIEW_TEMPLATE_REPO", ), call.GitRepo(self.template_git_repo_api_mock), call.GitRepo.clone("template-branch"), call.GitRepo.get_full_file_path("my-app-685912d3-preview"), call.os.path.isdir("/tmp/target-repo/my-app-685912d3-preview"), call.logging.info("Use existing folder for preview: %s", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/Chart.yaml"), call.update_yaml_file( "/tmp/target-repo/my-app-685912d3-preview/Chart.yaml", "name", "my-app-685912d3-preview"), call.logging.info("Keep property '%s' in '%s' value: %s", "name", "Chart.yaml", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/values.yaml"), call.update_yaml_file( "/tmp/target-repo/my-app-685912d3-preview/values.yaml", "image.tag", "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9", ), call.logging.info( "Keep property '%s' in '%s' value: %s", "image.tag", "values.yaml", "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9", ), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/values.yaml"), call.update_yaml_file( "/tmp/target-repo/my-app-685912d3-preview/values.yaml", "route.host", "app.xy-685912d3.example.tld"), call.logging.info("Keep property '%s' in '%s' value: %s", "route.host", "values.yaml", "app.xy-685912d3.example.tld"), call.logging.info( "The preview is already up-to-date. I'm done here."), ]
def test_update_existing_preview(self): self.os_mock.path.isdir.side_effect = lambda path: { "/tmp/created-tmp-dir/my-app-685912d3-preview": True, # already exists -> expect update }[path] deployment_updated_callback = Mock(return_value=None) command = CreatePreviewCommand(ARGS) command.register_callbacks( deployment_already_up_to_date_callback=lambda route_host: self. fail("should not be called"), deployment_updated_callback=deployment_updated_callback, deployment_created_callback=lambda route_host: self.fail( "should not be called"), ) command.execute() deployment_updated_callback.assert_called_once_with( "app.xy-685912d3.example.tld") assert self.mock_manager.method_calls == [ call.load_gitops_config( ARGS, "ORGA", "REPO", ), call.yaml_file_dump( INFO_YAML, "/tmp/gitopscli-preview-info.yaml", ), call.GitRepoApiFactory.create( ARGS, "TEAM_CONFIG_ORG", "TEAM_CONFIG_REPO", ), call.GitRepo(self.git_repo_api_mock), call.GitRepo.clone(), call.GitRepo.get_full_file_path("my-app-685912d3-preview"), call.os.path.isdir("/tmp/created-tmp-dir/my-app-685912d3-preview"), call.logging.info("Use existing folder for preview: %s", "my-app-685912d3-preview"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/values.yaml"), call.update_yaml_file( "/tmp/created-tmp-dir/my-app-685912d3-preview/values.yaml", "image.tag", "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9", ), call.logging.info("Replaced property '%s' with value: %s", "image.tag", "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9"), call.GitRepo.get_full_file_path( "my-app-685912d3-preview/values.yaml"), call.update_yaml_file( "/tmp/created-tmp-dir/my-app-685912d3-preview/values.yaml", "route.host", "app.xy-685912d3.example.tld"), call.logging.info("Replaced property '%s' with value: %s", "route.host", "app.xy-685912d3.example.tld"), call.GitRepo.commit( "GIT_USER", "GIT_EMAIL", "Update preview environment for 'my-app' and git hash '3361723dbd91fcfae7b5b8b8b7d462fbc14187a9'.", ), call.GitRepo.push(), ]