def test_run_step_fail_missing_path_file_from_deploy(self):
        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            test_file_name = 'yamlnotused'
            test_file_path = os.path.join(temp_dir.path, test_file_name)
            temp_dir.write(test_file_path, b'ignored')

            step_config = {}
            artifact_config = {
                'argocd-deployed-manifest': {
                    'value': f'{test_file_path}.bad'
                }
            }
            workflow_result = self.setup_previous_result(
                parent_work_dir_path, artifact_config)

            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='validate-environment-configuration',
                implementer='ConfiglintArgocd',
                workflow_result=workflow_result,
                parent_work_dir_path=parent_work_dir_path)

            result = step_implementer._run_step()

            expected_step_result = StepResult(
                step_name='validate-environment-configuration',
                sub_step_name='ConfiglintArgocd',
                sub_step_implementer_name='ConfiglintArgocd')
            expected_step_result.success = False
            expected_step_result.message = f'File specified in argocd-deployed-manifest {test_file_path}.bad not found'
            self.assertEqual(expected_step_result, result)
    def test_run_step_fail_missing_version_in_package_file(self):
        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            temp_dir.write(
                'package.json', b'''{
              "name": "my-awesome-package"
            }''')
            package_file_path = os.path.join(temp_dir.path, 'package.json')

            step_config = {'package-file': package_file_path}

            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='generate-metadata',
                implementer='Npm',
                parent_work_dir_path=parent_work_dir_path,
            )

            result = step_implementer._run_step()

            expected_step_result = StepResult(
                step_name='generate-metadata',
                sub_step_name='Npm',
                sub_step_implementer_name='Npm',
            )
            expected_step_result.success = False
            expected_step_result.message = f"Given npm package file ({package_file_path})" + \
                ' does not contain a \"version\" key.'

            self.assertEqual(result, expected_step_result)
Beispiel #3
0
    def test_fail_git_repo_bare(
        self,
        mock_repo,
        mock_git_url,
        mock_git_commit_utc_timestamp
    ):
        with TempDirectory() as temp_dir:
            # setup
            step_config = {
                'repo-root': temp_dir.path
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='generate-metadata',
                implementer='Git'
            )

            # setup mocks
            mock_repo().bare = True

            # run test
            actual_step_result = step_implementer._run_step()

            # verify results
            expected_step_result = StepResult(
                step_name='generate-metadata',
                sub_step_name='Git',
                sub_step_implementer_name='Git'
            )
            expected_step_result.success = False
            expected_step_result.message = f'Given git-repo-root is not a Git repository'

            self.assertEqual(actual_step_result, expected_step_result)
Beispiel #4
0
    def test_fail_getting_git_repo(
        self,
        mock_repo,
        mock_git_url,
        mock_git_commit_utc_timestamp
    ):
        with TempDirectory() as temp_dir:
            # setup
            step_config = {
                'repo-root': temp_dir.path
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='generate-metadata',
                implementer='Git'
            )

            # setup mocks
            mock_repo.side_effect = StepRunnerException('mock error')

            # run test
            actual_step_result = step_implementer._run_step()

            # verify results
            expected_step_result = StepResult(
                step_name='generate-metadata',
                sub_step_name='Git',
                sub_step_implementer_name='Git'
            )
            expected_step_result.success = False
            expected_step_result.message = f'mock error'

            self.assertEqual(actual_step_result, expected_step_result)
Beispiel #5
0
    def test_fail_is_detached(
        self,
        mock_repo,
        mock_git_url,
        mock_git_commit_utc_timestamp
    ):
        with TempDirectory() as temp_dir:
            # setup
            step_config = {
                'git-repo-root': temp_dir.path
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='generate-metadata',
                implementer='Git'
            )

            # setup mocks
            mock_repo().bare = False
            mock_repo().head.is_detached = True

            # run test
            actual_step_result = step_implementer._run_step()

            # verify results
            expected_step_result = StepResult(
                step_name='generate-metadata',
                sub_step_name='Git',
                sub_step_implementer_name='Git'
            )
            expected_step_result.success = False
            expected_step_result.message = f'Expected a Git branch in given git repo root' \
                f' but has a detached head'

            self.assertEqual(actual_step_result, expected_step_result)
    def test_run_step_fail_bad_rule_path(self, config_lint_mock):
        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            test_file_name = 'rules'
            test_file_path = os.path.join(temp_dir.path, test_file_name)
            temp_dir.write(test_file_path, b'ignored')
            step_config = {
                'configlint-yml-path': test_file_path,
                'rules': 'invalid_file'
            }

            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='validate-environment-configuration',
                implementer='Configlint',
                parent_work_dir_path=parent_work_dir_path,
            )

            result = step_implementer._run_step()

            expected_step_result = StepResult(
                step_name='validate-environment-configuration',
                sub_step_name='Configlint',
                sub_step_implementer_name='Configlint'
            )

            expected_step_result.success = False
            expected_step_result.message = 'File specified in rules not found: invalid_file'
            self.assertEqual(expected_step_result, result)
    def test_fail(self, mock_write_working_file, mock_run_maven_step):
        with TempDirectory() as test_dir:
            parent_work_dir_path = os.path.join(test_dir.path, 'working')

            step_config = {}
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path,
            )

            # run step with mock failure
            mock_run_maven_step.side_effect = StepRunnerException(
                'Mock error running maven')
            actual_step_result = step_implementer._run_step()

            # create expected step result
            expected_step_result = StepResult(
                step_name='foo',
                sub_step_name='MavenGeneric',
                sub_step_implementer_name='MavenGeneric')
            expected_step_result.add_artifact(
                description="Standard out and standard error from maven.",
                name='maven-output',
                value='/mock/mvn_output.txt')
            expected_step_result.message = "Error running maven. " \
                "More details maybe found in 'maven-output' report artifact: "\
                "Mock error running maven"
            expected_step_result.success = False

            # verify step result
            self.assertEqual(actual_step_result, expected_step_result)

            mock_write_working_file.assert_called_once()
            mock_run_maven_step.assert_called_with(
                mvn_output_file_path='/mock/mvn_output.txt')
Beispiel #8
0
    def test_fail_no_properties_and_project_key(self, mock_sonar, mock_is_release_branch):
        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')

            artifact_config = {
                'version': {'description': '', 'value': '1.0-123abc'},
            }
            workflow_result = self.setup_previous_result(parent_work_dir_path, artifact_config)

            step_config = {
                'url': 'https://sonarqube-sonarqube.apps.ploigos_step_runner.rht-set.com',
                'application-name': 'app-name',
                'service-name': 'service-name',
                'project-key': 'project-key'

            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='static-code-analysis',
                implementer='SonarQube',
                workflow_result=workflow_result,
                parent_work_dir_path=parent_work_dir_path
            )

            result = step_implementer._run_step()

            expected_step_result = StepResult(
                step_name='static-code-analysis',
                sub_step_name='SonarQube',
                sub_step_implementer_name='SonarQube'
            )
            expected_step_result.success = False
            expected_step_result.message = 'Properties file not found: ./sonar-project.properties'

            self.assertEqual(result, expected_step_result)
Beispiel #9
0
    def test_run_step_multiple_sub_steps_first_sub_step_fail_contine_sub_steps_on_failure_str(
        self,
        foo_step_implementer_run_step_mock,
        foo_step_implementer2_run_step_mock
    ):
        config = {
            'step-runner-config': {
                'foo': [
                    {
                        'name': 'Mock Sub Step 1',
                        'continue-sub-steps-on-failure': 'true',
                        'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer'
                    },
                    {
                        'name': 'Mock Sub Step 2',
                        'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer2'
                    }
                ]
            }
        }

        # mock return value
        mock_sub_step_1_result = StepResult(
            step_name='foo',
            sub_step_name='Mock Sub Step 1',
            sub_step_implementer_name='tests.helpers.sample_step_implementers.FooStepImplementer'
        )
        mock_sub_step_1_result.success = False
        mock_sub_step_2_result = StepResult(
            step_name='foo',
            sub_step_name='Mock Sub Step 2',
            sub_step_implementer_name='tests.helpers.sample_step_implementers.FooStepImplementer'
        )
        mock_sub_step_2_result.success = True

        foo_step_implementer_run_step_mock.return_value = mock_sub_step_1_result
        foo_step_implementer2_run_step_mock.return_value = mock_sub_step_2_result

        # run test
        step_runner = StepRunner(config)
        actual_success = step_runner.run_step('foo')

        # validate
        self.assertFalse(actual_success)
        foo_step_implementer_run_step_mock.assert_called_once()
        foo_step_implementer2_run_step_mock.assert_called_once()
    def test_fail_set_version(self, mock_settings_file,
                              mock_write_working_file, mock_run_maven_step,
                              mock_run_maven):
        with TempDirectory() as test_dir:
            parent_work_dir_path = os.path.join(test_dir.path, 'working')

            pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
            maven_push_artifact_repo_id = 'mock-repo-id'
            maven_push_artifact_repo_url = 'https://mock-repo.ploigos.com'
            version = '0.42.0-mock'
            step_config = {
                'pom-file': pom_file,
                'maven-push-artifact-repo-id': maven_push_artifact_repo_id,
                'maven-push-artifact-repo-url': maven_push_artifact_repo_url,
                'version': version
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path,
            )

            # run step with mvn version:set failure
            mock_run_maven.side_effect = StepRunnerException(
                'mock error setting new pom version')
            actual_step_result = step_implementer._run_step()

            # create expected step result
            expected_step_result = StepResult(
                step_name='deploy',
                sub_step_name='MavenDeploy',
                sub_step_implementer_name='MavenDeploy')
            expected_step_result.success = False
            expected_step_result.message = "Error running 'maven deploy' to push artifacts. " \
                "More details maybe found in 'maven-output' report artifact: " \
                "mock error setting new pom version"
            expected_step_result.add_artifact(
                description=
                "Standard out and standard error from running maven to update version.",
                name='maven-update-version-output',
                value='/mock/mvn_versions_set_output.txt')
            expected_step_result.add_artifact(
                description="Standard out and standard error from running maven to " \
                    "push artifacts to repository.",
                name='maven-push-artifacts-output',
                value='/mock/mvn_deploy_output.txt'
            )

            # verify step result
            self.assertEqual(actual_step_result, expected_step_result)

            mock_write_working_file.assert_called()
            mock_run_maven.assert_called_with(
                mvn_output_file_path='/mock/mvn_versions_set_output.txt',
                settings_file='/fake/settings.xml',
                pom_file=pom_file,
                phases_and_goals=['versions:set'],
                additional_arguments=[f'-DnewVersion={version}'])
            mock_run_maven_step.assert_not_called()
Beispiel #11
0
    def test_run_step_pass_with_existing_tags(self, MockRepo, mock_sh):
        previous_dir = os.getcwd()

        try:
            with TempDirectory() as temp_dir:
                parent_work_dir_path = os.path.join(temp_dir.path, 'working')
                repo = Repo.init(str(temp_dir.path))

                temp_dir.write(
                    '.cz.json', b'''{
                    "commitizen": {
                        "bump_message": "build: bump $current_version \\u2192 $new_version [skip-ci]",
                        "name": "cz_conventional_commits",
                        "tag_format": "$version",
                        "update_changelog_on_bump": true
                    }
                }''')
                cz_json_path = os.path.join(temp_dir.path, '.cz.json')

                step_config = {
                    'cz-json': cz_json_path,
                    'repo-root': temp_dir.path
                }
                step_implementer = self.create_step_implementer(
                    step_config=step_config,
                    step_name='generate-metadata',
                    implementer='Commitizen',
                    parent_work_dir_path=parent_work_dir_path,
                )

                mock_sh.cz.bump.side_effect = functools.partial(
                    self._mock_cz_bump,
                    path=os.path.join(temp_dir.path, '.cz.json'),
                    increment_type='minor')
                tag = collections.namedtuple('Tag', 'name')
                MockRepo().tags = [
                    tag(name='v_0.1.0__'),
                    tag(name='0.3.0'),
                    tag(name='version_4.34.0'),
                    tag(name='5.2.7-prerelease'),
                    tag(name='v3.142.0-test_abcxyz')
                ]
                result = step_implementer._run_step()

                expected_step_result = StepResult(
                    step_name='generate-metadata',
                    sub_step_name='Commitizen',
                    sub_step_implementer_name='Commitizen')
                expected_step_result.success = True
                expected_step_result.add_artifact(name='app-version',
                                                  value='5.3.0')

                self.assertEqual(result, expected_step_result)
        finally:
            os.chdir(previous_dir)
Beispiel #12
0
    def __run__fail_sonar_scanner_error_test(
        self,
        sonar_scanner_error,
        expected_result_message_regex,
        mock_sonar
    ):
        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            temp_dir.write('sonar-project.properties',b'''testing''')
            properties_path = os.path.join(temp_dir.path, 'sonar-project.properties')

            artifact_config = {
                'version': {'description': '', 'value': '1.0-123abc'},
            }
            workflow_result = self.setup_previous_result(parent_work_dir_path, artifact_config)

            step_config = {
                'properties': properties_path,
                'url': 'https://sonarqube-sonarqube.apps.ploigos_step_runner.rht-set.com',
                'application-name': 'app-name',
                'service-name': 'service-name',
                'username': '******',
                'password': '******'

            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='static-code-analysis',
                implementer='SonarQube',
                workflow_result=workflow_result,
                parent_work_dir_path=parent_work_dir_path,
            )

            mock_sonar.side_effect = sonar_scanner_error

            result = step_implementer._run_step()

            expected_step_result = StepResult(
                step_name='static-code-analysis',
                sub_step_name='SonarQube',
                sub_step_implementer_name='SonarQube'
            )
            expected_step_result.success = False
            expected_step_result.add_artifact(
                name='sonarqube-result-set',
                value=f'{temp_dir.path}/working/static-code-analysis/report-task.txt'
            )
            expected_step_result.add_evidence(
                name='sonarqube-quality-gate-pass',
                value=False
            )

            self.assertEqual(result.success, expected_step_result.success)
            self.assertEqual(result.artifacts, expected_step_result.artifacts)
            self.assertRegex(result.message, expected_result_message_regex)
    def test__run_step_pass_upload_to_remote_with_auth_failure(
            self, create_archive_mock, upload_file_mock):
        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            step_config = {
                'organization': 'test-ORG',
                'application-name': 'test-APP',
                'service-name': 'test-SERVICE',
                'version': '42.0-test',
                'results-archive-destination-url':
                'https://ploigos.com/mock/results-archives',
                'results-archive-destination-username': '******',
                'results-archive-destination-password': '******'
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path,
            )

            # mock the upload results
            upload_file_mock.side_effect = RuntimeError('mock upload error')

            # run the step
            step_result = step_implementer._run_step()

            # verify results
            expected_step_result = StepResult(
                step_name='report',
                sub_step_name='ResultArtifactsArchive',
                sub_step_implementer_name='ResultArtifactsArchive')
            expected_step_result.add_artifact(
                name='result-artifacts-archive',
                value='/fake/archive/path/foo.zip',
                description=
                'Archive of all of the step result artifacts marked for archiving.'
            )
            expected_step_result.add_artifact(
                name='results-archive-uri',
                description='URI of the uploaded results archive.',
                value=
                'https://ploigos.com/mock/results-archives/test-ORG/test-APP/test-SERVICE/foo.zip'
            )
            expected_step_result.success = False
            expected_step_result.message = 'mock upload error'

            # verify mocks called
            create_archive_mock.assert_called_once()
            upload_file_mock.assert_called_once_with(
                file_path=mock.ANY,
                destination_uri=
                'https://ploigos.com/mock/results-archives/test-ORG/test-APP/test-SERVICE/foo.zip',
                username='******',
                password='******')
Beispiel #14
0
    def test_fail_sign_image(self, mock_sign_image, mock_import_pgp_key,
                             mock_upload_file, mock_container_registries_login,
                             mock_get_deploy_time_container_image_address):
        with TempDirectory() as temp_dir:
            # setup
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            pgp_private_key_fingerprint = 'abc123'
            step_config = TestStepImplementerSignContainerImagePodmanBase.generate_config(
            )

            # setup mocks
            def import_pgp_key_side_effect(pgp_private_key):
                return pgp_private_key_fingerprint

            mock_import_pgp_key.side_effect = import_pgp_key_side_effect

            mock_sign_image.side_effect = StepRunnerException(
                'mock error signing image')

            # run test
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='sign-container-image',
                implementer='PodmanSign',
                parent_work_dir_path=parent_work_dir_path)
            result = step_implementer._run_step()

            # validate
            mock_import_pgp_key.assert_called_once_with(
                pgp_private_key=step_config['signer-pgp-private-key'])
            mock_sign_image.assert_called_once_with(
                pgp_private_key_fingerprint=pgp_private_key_fingerprint,
                image_signatures_directory=os.path.join(
                    parent_work_dir_path,
                    'sign-container-image/image-signature'),
                container_image_address=
                'mock-deploy-time-container-image-address')
            mock_container_registries_login.assert_called_once_with(
                registries=None,
                containers_config_tls_verify=True,
                container_command_short_name='podman')
            mock_get_deploy_time_container_image_address.assert_called_once()

            expected_step_result = StepResult(
                step_name='sign-container-image',
                sub_step_name='PodmanSign',
                sub_step_implementer_name='PodmanSign')
            expected_step_result.add_artifact(
                name='container-image-signature-signer-private-key-fingerprint',
                value=pgp_private_key_fingerprint)
            expected_step_result.success = False
            expected_step_result.message = 'mock error signing image'
            self.assertEqual(expected_step_result, result)
    def test_run_step_error_git_push(self, git_repo_mock, git_url_mock, get_tag_value_mock):
        # Test data setup
        tag = '1.0+69442c8'
        url = '[email protected]:ploigos/ploigos-step-runner.git'
        error = 'oh no. ohhhhh no.'
        branch_name = 'feature/no-feature'

        # Mock setup
        get_tag_value_mock.return_value = tag
        git_url_mock.return_value = url
        git_repo_mock.active_branch.name = branch_name

        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            artifact_config = {
                'version': {'description': '', 'value': tag},
                'container-image-version': {'description': '', 'value': tag}
            }
            workflow_result = self.setup_previous_result(parent_work_dir_path, artifact_config)

            step_config = {
                'url': url,
                'git-username': '******',
                'git-password': '******'
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                workflow_result=workflow_result,
                parent_work_dir_path=parent_work_dir_path
            )

            # this is the test here
            git_repo_mock.git.push.side_effect = Exception(error)
            result = step_implementer._run_step()

            # verify the test results
            expected_step_result = StepResult(
                step_name='tag-source',
                sub_step_name='Git',
                sub_step_implementer_name='Git'
            )
            expected_step_result.add_artifact(name='tag', value=tag)
            expected_step_result.success = False
            expected_step_result.message = f"Error tagging and pushing tags: Error pushing tags to remote ({url})" \
                f" on current branch ({branch_name}): {error}"

            # verifying all mocks were called
            git_repo_mock.create_tag.assert_called_once_with(tag, force=True)
            git_url_mock.assert_called_once_with()
            git_repo_mock.git.push.assert_called_once_with(url, '--tag')

            self.assertEqual(result, expected_step_result)
    def test_fail_with_report_dir(self, mock_gather_evidence,
                                  mock_get_test_report_dir,
                                  mock_write_working_file,
                                  mock_run_maven_step):
        with TempDirectory() as test_dir:
            # setup test
            parent_work_dir_path = os.path.join(test_dir.path, 'working')
            pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
            step_config = {
                'pom-file': pom_file,
                'target-host-url-maven-argument-name':
                'mock.target-host-url-param',
                'deployed-host-urls': ['https://mock.ploigos.org/mock-app-1']
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path,
            )

            # setup mocks
            mock_run_maven_step.side_effect = StepRunnerException('mock error')

            # run test
            actual_step_result = step_implementer._run_step()

            # verify results
            expected_step_result = StepResult(
                step_name='unit-test',
                sub_step_name='MavenIntegrationTest',
                sub_step_implementer_name='MavenIntegrationTest')
            expected_step_result.success = False
            expected_step_result.message = "Error running maven. " \
                "More details maybe found in report artifacts: " \
                "mock error"
            expected_step_result.add_artifact(
                description="Standard out and standard error from maven.",
                name='maven-output',
                value='/mock/mvn_output.txt')
            expected_step_result.add_artifact(
                description="Test report generated when running unit tests.",
                name='test-report',
                value='/mock/test-results-dir')
            self.assertEqual(actual_step_result, expected_step_result)

            mock_run_maven_step.assert_called_once_with(
                mvn_output_file_path='/mock/mvn_output.txt',
                step_implementer_additional_arguments=[
                    '-Dmock.target-host-url-param=https://mock.ploigos.org/mock-app-1'
                ])
            mock_gather_evidence.assert_called_once_with(
                step_result=Any(StepResult),
                test_report_dirs='/mock/test-results-dir')
Beispiel #17
0
    def test_run_step_fail_commit_changes_and_push(
        self,
        mock_repo,
        mock_git_url,
        mock_git_commit_utc_timestamp
    ):
        # Data setup
        git_branch = 'main'
        error = 'Holy guacamole..!'

        with TempDirectory() as temp_dir:
            # setup
            step_config = {
                'repo-root': temp_dir.path,
                'git-commit-and-push-changes': True
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='generate-metadata',
                implementer='Git'
            )

            # setup mocks
            mock_repo().bare = False
            mock_repo().head.is_detached = False
            mock_repo().active_branch.name = git_branch
            mock_repo().git.commit.side_effect = Exception(error)

            # run test
            actual_step_result = step_implementer._run_step()

            # verify results
            expected_step_result = StepResult(
                step_name='generate-metadata',
                sub_step_name='Git',
                sub_step_implementer_name='Git'
            )
            expected_step_result.add_artifact(
                name='branch',
                value=git_branch
            )
            expected_step_result.add_artifact(
                name='is-pre-release',
                value=False
            )
            expected_step_result.success = False
            expected_step_result.message = f'Error committing and pushing changes: Error committing changes ' \
                                           f'to current branch ({git_branch}): {error}'

            self.assertEqual(actual_step_result, expected_step_result)
    def test_run_step_fail_scan(self, configlint_mock):
        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            file_to_validate_contents = 'notused'
            temp_dir.write('config-file-to-validate.yml', file_to_validate_contents.encode())
            file_to_validate_file_path = str(os.path.join(temp_dir.path, 'config-file-to-validate.yml'))

            # write config-lint rules file
            configlint_rules_content = 'not used'
            config_lint_rules_file_name = 'config-lint-test-rules.yml'
            temp_dir.write(config_lint_rules_file_name, configlint_rules_content.encode())
            config_lint_rules_file_path = os.path.join(temp_dir.path, config_lint_rules_file_name)

            step_config = {
                'configlint-yml-path': file_to_validate_file_path,
                'rules': config_lint_rules_file_path
            }

            configlint_mock.side_effect = \
                TestStepImplementerConfiglint.create_config_lint_side_effect(
                    config_lint_fail=True
                )

            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='validate-environment-configuration',
                implementer='Configlint',
                parent_work_dir_path=parent_work_dir_path,
            )

            result = step_implementer._run_step()

            expected_step_result = StepResult(
                step_name='validate-environment-configuration',
                sub_step_name='Configlint',
                sub_step_implementer_name='Configlint'
            )

            expected_step_result.success = False
            expected_step_result.message = 'Failed config-lint scan.'
            expected_step_result.add_artifact(
                name='configlint-result-set',
                value=f'{step_implementer.work_dir_path}/configlint_results_file.txt'
            )
            expected_step_result.add_artifact(
                name='configlint-yml-path',
                value=file_to_validate_file_path
            )
            self.assertEqual(expected_step_result, result)
Beispiel #19
0
    def test_fail_no_commit_history(
        self,
        mock_repo,
        mock_git_url,
        mock_git_commit_utc_timestamp
    ):
        # Data setup
        git_branch = 'main'

        with TempDirectory() as temp_dir:
            # setup
            step_config = {
                'repo-root': temp_dir.path
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='generate-metadata',
                implementer='Git'
            )

            # setup mocks
            mock_repo().bare = False
            mock_repo().head.is_detached = False
            mock_repo().active_branch.name = git_branch
            type(mock_repo().head.reference).commit = PropertyMock(side_effect=ValueError)

            # run test
            actual_step_result = step_implementer._run_step()

            # verify results
            expected_step_result = StepResult(
                step_name='generate-metadata',
                sub_step_name='Git',
                sub_step_implementer_name='Git'
            )
            expected_step_result.add_artifact(
                name='branch',
                value=git_branch
            )
            expected_step_result.add_artifact(
                name='is-pre-release',
                value=False
            )
            expected_step_result.success = False
            expected_step_result.message = f'Given Git repository root is a' \
                f' git branch ({git_branch}) with no commit history.'

            self.assertEqual(actual_step_result, expected_step_result)
    def test_run_step_error_git_url(self, git_repo_mock, git_url_mock, get_tag_value_mock):
        with TempDirectory() as temp_dir:
            tag = '1.0+69442c8'
            url = '[email protected]:ploigos/ploigos-step-runner.git'
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            error = 'uh oh spaghetti-os'

            artifact_config = {
                'version': {'description': '', 'value': tag},
                'container-image-version': {'description': '', 'value': tag}
            }
            workflow_result = self.setup_previous_result(parent_work_dir_path, artifact_config)

            step_config = {
                'url': url,
                'git-username': '******',
                'git-password': '******'
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                workflow_result=workflow_result,
                parent_work_dir_path=parent_work_dir_path
            )

            get_tag_value_mock.return_value = tag

            # this is the test here
            git_url_mock.side_effect = StepRunnerException(error)
            result = step_implementer._run_step()

            # verify test results
            expected_step_result = StepResult(
                step_name='tag-source',
                sub_step_name='Git',
                sub_step_implementer_name='Git'
            )
            expected_step_result.add_artifact(name='tag', value=tag)
            expected_step_result.success = False
            expected_step_result.message = f"Error tagging and pushing tags: {error}"

            # verifying correct mocks were called
            git_repo_mock.create_tag.assert_called_once_with(tag, force=True)
            git_url_mock.assert_called_once()

            self.assertEqual(result, expected_step_result)
    def test__run_step_pass_upload_to_remote_with_auth_failure(self, gather_evidence_mock, upload_file_mock):
        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')

            step_config = {
                'organization': 'test-ORG',
                'application-name': 'test-APP',
                'service-name': 'test-SERVICE',
                'version': '42.0-test',
                'evidence-destination-url': self.DEST_URL,
                'evidence-destination-username': '******',
                'evidence-destination-password': '******'
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path
            )

            # mock the upload results
            upload_file_mock.side_effect = RuntimeError('mock upload error')
            upload_file_mock.return_value = "mock upload results"

            # run the step
            step_result = step_implementer._run_step()

            # verify results
            expected_step_result = StepResult(
                step_name='generate_evidence',
                sub_step_name='GenerateEvidence',
                sub_step_implementer_name='GenerateEvidence'
            )

            expected_step_result.success = False
            expected_step_result.message = 'mock upload error'

            self.assertEqual(step_result, expected_step_result)

            # verify mocks called
            gather_evidence_mock.assert_called_once()
            upload_file_mock.assert_called_once_with(
                file_path=mock.ANY,
                destination_uri=self.DEST_URI,
                username='******',
                password='******'
            )
Beispiel #22
0
    def test_fail_import_pgp_key(self, mock_sign_image, mock_import_pgp_key,
                                 mock_upload_file,
                                 mock_container_registries_login,
                                 mock_get_deploy_time_container_image_address):
        with TempDirectory() as temp_dir:
            # setup
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            step_config = TestStepImplementerSignContainerImagePodmanBase.generate_config(
            )
            signature_name = 'does/not/matter/signature-0'

            # setup mocks
            mock_import_pgp_key.side_effect = RuntimeError(
                'mock error importing pgp key')

            def sign_image_side_effect(pgp_private_key_fingerprint,
                                       image_signatures_directory,
                                       container_image_address):
                return os.path.join(image_signatures_directory, signature_name)

            mock_sign_image.side_effect = sign_image_side_effect

            # run test
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='sign-container-image',
                implementer='PodmanSign',
                parent_work_dir_path=parent_work_dir_path)
            result = step_implementer._run_step()

            # validate
            mock_import_pgp_key.assert_called_once_with(
                pgp_private_key=step_config['signer-pgp-private-key'])
            mock_upload_file.assert_not_called()
            mock_container_registries_login.assert_not_called()
            mock_get_deploy_time_container_image_address.assert_called_once()

            expected_step_result = StepResult(
                step_name='sign-container-image',
                sub_step_name='PodmanSign',
                sub_step_implementer_name='PodmanSign')
            expected_step_result.success = False
            expected_step_result.message = 'mock error importing pgp key'

            self.assertEqual(expected_step_result, result)
    def test_push_error(self, mock_pelorus_prometheus_job,
                        mock_pelorus_prometheus_pushgateway_url,
                        mock_commit_utc_timestamp, mock_container_image_digest,
                        mock_commit_hash, mock_pelorus_app_name,
                        mock_push_to_gateway):
        # setup mocks
        mock_pelorus_prometheus_job.return_value = 'mock-job'
        mock_pelorus_prometheus_pushgateway_url.return_value = 'mock-push-url'
        mock_commit_utc_timestamp.return_value = '1642079293.0'
        mock_container_image_digest.return_value = 'mock-digest'
        mock_commit_hash.return_value = 'mock-commit-hash'
        mock_pelorus_app_name.return_value = 'mock-app-name'
        mock_push_to_gateway.side_effect = Exception('mock push error')

        # setup
        step_implementer = self.create_step_implementer()

        # run step
        actual_result = step_implementer._run_step()

        # verify
        expected_step_result = StepResult(
            step_name='push-container-image',
            sub_step_name='PelorusCommitTimestampMetric',
            sub_step_implementer_name='PelorusCommitTimestampMetric')
        expected_step_result.success = False
        expected_step_result.message = "Error pushing Pelorus Commit Timestamp metric to" \
            " Prometheus Pushgateway (mock-push-url): mock push error"
        self.assertEqual(actual_result, expected_step_result)
        mock_push_to_gateway.assert_called_once_with(gateway='mock-push-url',
                                                     job='mock-job',
                                                     grouping_key={
                                                         'job':
                                                         'mock-job',
                                                         'app':
                                                         'mock-app-name',
                                                         'commit':
                                                         'mock-commit-hash'
                                                     },
                                                     registry=ANY)
    def test_run_step_fail_missing_version_in_pom_file(
            self,
            mock_run_maven
    ):
        mock_run_maven.side_effect = StepRunnerException("no version found")

        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')

            temp_dir.write('pom.xml', b'''<project>
                <modelVersion>4.0.0</modelVersion>
                <groupId>com.mycompany.app</groupId>
                <artifactId>my-app</artifactId>
            </project>''')
            pom_file_path = os.path.join(temp_dir.path, 'pom.xml')

            step_config = {
                'pom-file': pom_file_path
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='generate-metadata',
                implementer='Maven',
                parent_work_dir_path=parent_work_dir_path,
            )

            result = step_implementer._run_step()

            expected_step_result = StepResult(
                step_name='generate-metadata',
                sub_step_name='Maven',
                sub_step_implementer_name='Maven'
            )
            expected_step_result.success = False
            expected_step_result.message = f'Error running maven to get the project version: ' \
                    f'no version found' \
                    f'Could not get project version from given pom file' \
                    f' ({pom_file_path})'

            self.assertEqual(result, expected_step_result)
Beispiel #25
0
    def test__run_step_fail_audit_fail_missing_workflow_attestation(self):
        with TempDirectory() as temp_dir:

            workflow_attestation_uri = 'https://foo.bar/evidence.json'
            workflow_policy_uri = 'https://foo.bar/policy.json'

            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            step_config = {
                'workflow-policy-uri': workflow_policy_uri
            }

            step_result = StepResult(
            step_name='test-step',
            sub_step_name='test-sub-step',
            sub_step_implementer_name='test-sub-step-implementer'
            )
            step_result.add_artifact('evidence-uri-wrong-key', workflow_attestation_uri, 'URI of the uploaded results archive.')

            workflow_result = WorkflowResult()
            workflow_result.add_step_result(step_result)

            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path,
                workflow_result=workflow_result
            )

            step_result = step_implementer._run_step()

            expected_step_result = StepResult(
                step_name='audit_attestation',
                sub_step_name='OpenPolicyAgent',
                sub_step_implementer_name='OpenPolicyAgent'
            )

            expected_step_result.success = False
            expected_step_result.message = "No value found for evidence-uri"

            self.assertEqual(step_result, expected_step_result)
    def test_fail_no_report_dir(self, mock_gather_evidence,
                                mock_get_test_report_dir,
                                mock_write_working_file, mock_run_maven_step):
        with TempDirectory() as test_dir:
            # setup test
            parent_work_dir_path = os.path.join(test_dir.path, 'working')
            pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
            step_config = {'pom-file': pom_file}
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path,
            )

            # setup mocks
            mock_run_maven_step.side_effect = StepRunnerException('mock error')
            mock_get_test_report_dir.return_value = None

            # run test
            actual_step_result = step_implementer._run_step()

            # verify results
            expected_step_result = StepResult(
                step_name='unit-test',
                sub_step_name='MavenTest',
                sub_step_implementer_name='MavenTest')
            expected_step_result.success = False
            expected_step_result.message = "Error running maven. " \
                "More details maybe found in report artifacts: " \
                "mock error"
            expected_step_result.add_artifact(
                description="Standard out and standard error from maven.",
                name='maven-output',
                value='/mock/mvn_output.txt')
            self.assertEqual(actual_step_result, expected_step_result)

            mock_run_maven_step.assert_called_once_with(
                mvn_output_file_path='/mock/mvn_output.txt')
            mock_gather_evidence.assert_not_called()
    def test_fail_no_find_artifacts(self, mock_write_working_file,
                                    mock_run_maven_step):
        with TempDirectory() as test_dir:
            parent_work_dir_path = os.path.join(test_dir.path, 'working')

            pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
            step_config = {
                'pom-file': pom_file,
                'artifact-parent-dir': 'mock/does-not-exist'
            }
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path,
            )

            # run step
            actual_step_result = step_implementer._run_step()

            # create expected step result
            expected_step_result = StepResult(
                step_name='package',
                sub_step_name='MavenPackage',
                sub_step_implementer_name='MavenPackage')
            expected_step_result.success = False
            expected_step_result.message = \
                "Error finding artifacts after running maven package:" \
                f" [Errno 2] No such file or directory: '{test_dir.path}/mock/does-not-exist'"
            expected_step_result.add_artifact(
                description="Standard out and standard error from maven.",
                name='maven-output',
                value='/mock/mvn_output.txt')

            # verify step result
            self.assertEqual(actual_step_result, expected_step_result)

            mock_write_working_file.assert_called_once()
            mock_run_maven_step.assert_called_with(
                mvn_output_file_path='/mock/mvn_output.txt')
    def test_run_step_pass(self, config_lint_mock):
        with TempDirectory() as temp_dir:
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')
            test_file_name = 'file.txt'
            test_file_path = os.path.join(temp_dir.path, test_file_name)
            temp_dir.write(test_file_path, b'ignored')
            step_config = {
                'rules': test_file_path,
                'configlint-yml-path': test_file_path
            }

            step_implementer = self.create_step_implementer(
                step_config=step_config,
                step_name='validate-environment-configuration',
                implementer='Configlint',
                parent_work_dir_path=parent_work_dir_path,
            )

            config_lint_mock.side_effect = sh.ErrorReturnCode('config_lint', b'mock out', b'mock error')
            result = step_implementer._run_step()

            expected_step_result = StepResult(
                step_name='validate-environment-configuration',
                sub_step_name='Configlint',
                sub_step_implementer_name='Configlint'
            )

            expected_step_result.success = False
            expected_step_result.message = 'Unexpected Error invoking config-lint.'
            expected_step_result.add_artifact(
                name='configlint-result-set',
                value=f'{step_implementer.work_dir_path}/configlint_results_file.txt'
            )
            expected_step_result.add_artifact(
                name='configlint-yml-path',
                value=test_file_path
            )
            self.assertEqual(expected_step_result, result)
    def test_run_step_success(
            self,
            mock_argocd,
            argocd_sign_in_mock,
            get_app_name_mock
    ):
        with TempDirectory() as temp_dir:
            # Test setup: Test inputs / mocks
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')

            argocd_cascade = True
            argocd_propagation_policy = 'background'

            step_config = {
                'argocd-username': '******',
                'argocd-password': '******',
                'argocd-api': 'https://argo.ploigos.xyz',
                'argocd-skip-tls': False,
                'argocd-cascade': argocd_cascade,
                'argocd-propagation-policy': argocd_propagation_policy
            }

            # Test setup: Expected outputs
            expected_step_result = StepResult(
                step_name='delete',
                sub_step_name='ArgoCDDelete',
                sub_step_implementer_name='ArgoCDDelete',
                environment='PROD'
            )
            expected_step_result.success = True
            expected_step_result.add_artifact(
                name='argocd-app-name',
                value='test-app-name'
            )

            # Test execution
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path,
                environment='PROD'
            )
            actual_step_results = step_implementer._run_step()

            # Test verification: Step results
            self.assertEqual(actual_step_results, expected_step_result)

            # Test verification: Mock method calls
            get_app_name_mock.assert_called_once_with()
            argocd_sign_in_mock.assert_called_once_with(
                argocd_api=step_config['argocd-api'],
                username=step_config['argocd-username'],
                password=step_config['argocd-password'],
                insecure=step_config['argocd-skip-tls']
            )
            mock_argocd.app.delete.assert_called_once_with(
                'test-app-name',
                f'--cascade={argocd_cascade}',
                f'--propagation-policy={argocd_propagation_policy}',
                '--yes',
                _out=ANY,
                _err=ANY
            )
    def test_run_step_failure(
            self,
            mock_argocd,
            argocd_sign_in_mock,
            get_app_name_mock
    ):
        with TempDirectory() as temp_dir:
            # Test setup: Test inputs / mocks
            parent_work_dir_path = os.path.join(temp_dir.path, 'working')

            argocd_cascade = True
            argocd_propagation_policy = 'background'
            environment = 'PROD'

            step_config = {
                'argocd-username': '******',
                'argocd-password': '******',
                'argocd-api': 'https://argo.ploigos.xyz',
                'argocd-skip-tls': False,
                'argocd-cascade': argocd_cascade,
                'argocd-propagation-policy': argocd_propagation_policy
            }

            # Test setup: Expected outputs
            delete_error_return = sh.ErrorReturnCode('argocd', b'mock out', b'mock argocd sign-in failure')
            delete_failure_error_msg = f"Error deleting ArgoCD app (test-app-name): {delete_error_return}"
            delete_exception = StepRunnerException(delete_failure_error_msg)

            expected_step_result = StepResult(
                step_name='delete',
                sub_step_name='ArgoCDDelete',
                sub_step_implementer_name='ArgoCDDelete',
                environment=environment
            )
            expected_step_result.success = False
            expected_step_result.message = f"Error deleting environment ({environment}):" \
                                           f" {str(delete_exception)}"
            expected_step_result.add_artifact(
                name='argocd-app-name',
                value='test-app-name'
            )

            # Test setup: Mock behaviors
            mock_argocd.app.delete.side_effect = create_sh_side_effect(
                exception=delete_error_return
            )

            # Test execution
            step_implementer = self.create_step_implementer(
                step_config=step_config,
                parent_work_dir_path=parent_work_dir_path,
                environment='PROD'
            )
            actual_step_results = step_implementer._run_step()

            # Test verification: Step results
            self.assertEqual(actual_step_results, expected_step_result)

            # Test verification: Mock method calls
            get_app_name_mock.assert_called_once_with()
            argocd_sign_in_mock.assert_called_once_with(
                argocd_api=step_config['argocd-api'],
                username=step_config['argocd-username'],
                password=step_config['argocd-password'],
                insecure=step_config['argocd-skip-tls']
            )