def test_run_step_pass(self): 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> <version>42.1</version> </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.add_artifact(name='app-version', value='42.1') self.assertEqual(result, expected_step_result)
def test_merge(self): sr1 = StepResult('step1', 'sub1', 'implementer1') sr1.add_artifact('artifact1', 'value1', 'description1') sr1.add_artifact('artifact2', 'value2', 'description2') sr1.add_evidence('evidence1', 'value1', 'description1') sr1.add_evidence('evidence2', 'value2', 'description2') sr2 = StepResult('step1', 'sub1', 'implementer1') sr2.add_artifact('artifact1', 'changed-value1', 'changed-description1') sr2.add_evidence('evidence1', 'changed-value1', 'changed-description1') sr1.merge(sr2) artifact1 = sr1.get_artifact('artifact1') artifact2 = sr1.get_artifact('artifact2') evidence1 = sr1.get_evidence('evidence1') evidence2 = sr1.get_evidence('evidence2') # changed by SR2 self.assertEqual(artifact1.value, 'changed-value1') self.assertEqual(artifact1.description, 'changed-description1') self.assertEqual(evidence1.value, 'changed-value1') self.assertEqual(evidence1.description, 'changed-description1') # unchanged by SR2 self.assertEqual(artifact2.value, 'value2') self.assertEqual(artifact2.description, 'description2') self.assertEqual(evidence2.value, 'value2') self.assertEqual(evidence2.description, 'description2')
def test_run_step_pass(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", "version": "42.1" }''') 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.add_artifact(name='app-version', value='42.1') self.assertEqual(result, expected_step_result)
def test_run_step_pass(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': test_file_path } } 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.add_artifact(name='configlint-yml-path', value=test_file_path) 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')
def test__run_step_pass_no_container_image_version(self, buildah_mock): with TempDirectory() as temp_dir: parent_work_dir_path = os.path.join(temp_dir.path, 'working') temp_dir.write('Containerfile',b'''testing''') step_config = { 'containers-config-auth-file': 'buildah-auth.json', 'imagespecfile': 'Containerfile', 'context': temp_dir.path, 'tls-verify': True, 'format': 'oci', 'service-name': 'service-name', 'application-name': 'app-name' } step_implementer = self.create_step_implementer( step_config=step_config, step_name='create-container-image', implementer='Buildah', parent_work_dir_path=parent_work_dir_path, ) result = step_implementer._run_step() expected_step_result = StepResult( step_name='create-container-image', sub_step_name='Buildah', sub_step_implementer_name='Buildah' ) expected_step_result.add_artifact( name='container-image-version', value='localhost/app-name/service-name:latest' ) expected_step_result.add_artifact( name='image-tar-file', value=f'{step_implementer.work_dir_path}/image-app-name-service-name-latest.tar' ) buildah_mock.bud.assert_called_once_with( '--storage-driver=vfs', '--format=oci', '--tls-verify=true', '--layers', '-f', 'Containerfile', '-t', 'localhost/app-name/service-name:latest', '--authfile', 'buildah-auth.json', temp_dir.path, _out=sys.stdout, _err=sys.stderr, _tee='err' ) buildah_mock.push.assert_called_once_with( '--storage-driver=vfs', 'localhost/app-name/service-name:latest', f'docker-archive:{step_implementer.work_dir_path}/image-app-name-service-name-latest.tar', _out=sys.stdout, _err=sys.stderr, _tee='err' ) self.assertEqual(result, expected_step_result)
def test_run_step_tls_verify_false(self, mvn_mock): with TempDirectory() as temp_dir: artifact_id = 'my-app' version = '1.0' package = 'war' 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> <version>1.0</version> <package>war</package> </project>''') pom_file_path = os.path.join(temp_dir.path, 'pom.xml') step_config = { 'pom-file': pom_file_path, 'tls-verify': False } artifact_file_name = f'{artifact_id}-{version}.{package}' step_implementer = self.create_step_implementer( step_config=step_config, step_name='package', implementer='Maven', parent_work_dir_path=parent_work_dir_path, ) mvn_mock.side_effect = TestStepImplementerMavenPackageBase.create_mvn_side_effect( pom_file_path, 'target', [artifact_file_name]) result = step_implementer._run_step() package_artifacts = { 'path': temp_dir.path + '/target/my-app-1.0.war', 'artifact-id': 'my-app', 'group-id': 'com.mycompany.app', 'package-type': 'war', 'pom-path': pom_file_path } expected_step_result = StepResult( step_name='package', sub_step_name='Maven', sub_step_implementer_name='Maven' ) expected_step_result.add_artifact(name='package-artifacts', value=[package_artifacts]) mvn_output_file_path = os.path.join( step_implementer.work_dir_path, 'mvn_test_output.txt' ) expected_step_result.add_artifact( description="Standard out and standard error from 'mvn install'.", name='maven-output', value=mvn_output_file_path ) self.assertEqual(expected_step_result, result)
def test__run_step_pass_audit_success(self, audit_attestation_mock, download_source_to_destination_mock): 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', 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 ) download_source_to_destination_mock.side_effect = [ parent_work_dir_path + '/workflow_attestion.json', parent_work_dir_path + '/workflow_policy.rego'] audit_attestation_mock.return_value = "Audit was successful", 0 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.add_artifact( name='audit-results', value='Audit was successful' ) expected_step_result.message = 'Audit was successful' self.assertEqual(step_result, expected_step_result) audit_attestation_mock.assert_called_once_with(parent_work_dir_path + '/workflow_attestion.json', parent_work_dir_path + '/workflow_policy.rego', "data.workflowResult.passAll") download_source_to_destination_mock.assert_has_calls([ mock.call(workflow_attestation_uri, parent_work_dir_path + '/audit_attestation'), mock.call(workflow_policy_uri, parent_work_dir_path + '/audit_attestation') ] )
def test_run_step_pass_alternate_java_truststore(self, sonar_mock): 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') temp_dir.write('alternate.jks', b'''testing''') java_truststore = os.path.join(temp_dir.path, 'alternate.jks') 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': '******', 'java-truststore': java_truststore } 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.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=True ) sonar_mock.assert_called_once_with( '-Dproject.settings=' + properties_path, '-Dsonar.host.url=https://sonarqube-sonarqube.apps.ploigos_step_runner.rht-set.com', '-Dsonar.projectVersion=1.0-123abc', '-Dsonar.projectKey=app-name:service-name', '-Dsonar.login=username', '-Dsonar.password=password', '-Dsonar.working.directory=' + step_implementer.work_dir_path, _env={'SONAR_SCANNER_OPTS': f'-Djavax.net.ssl.trustStore={java_truststore}'}, _out=sys.stdout, _err=sys.stderr ) self.assertEqual(result, expected_step_result)
def test___create_archive_string_result_with_env(self): 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' } step_result = StepResult( step_name='test-step', sub_step_name='test-sub-step', sub_step_implementer_name='test-sub-step-implementer', environment='test-env1') step_result.add_artifact(name='test-step-result-str', value='hello world') 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) archive_path = step_implementer._ResultArtifactsArchive__create_archive( ) archive_zip = zipfile.ZipFile(archive_path) artifact_file_path = f"{step_config['organization']}-" \ f"{step_config['application-name']}-{step_config['service-name']}-" \ f"{step_config['version']}/test-step/test-sub-step/test-env1/test-step-result-str" with archive_zip.open(artifact_file_path, 'r') as artifact_file: artifact_file_contents = artifact_file.read().decode('UTF-8') self.assertEqual(artifact_file_contents, 'hello world')
def test__run_step_pass_with_evidence(self, generate_evidence_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' } step_implementer = self.create_step_implementer( step_config=step_config, parent_work_dir_path=parent_work_dir_path) step_result = step_implementer._run_step() expected_step_result = StepResult( step_name='generate_evidence', sub_step_name='GenerateEvidence', sub_step_implementer_name='GenerateEvidence') expected_step_result.message = 'Evidence successfully packaged ' \ 'in JSON file but was not uploaded to data store (no '\ 'destination URI specified).' expected_step_result.add_artifact( name='evidence-path', value=os.path.join( parent_work_dir_path, 'generate_evidence', "test-ORG-test-APP-test-SERVICE-42.0-test-evidence.json"), description='File path of evidence.') print(str(step_result) + "\n\n" + str(expected_step_result)) self.assertEqual(step_result, expected_step_result) generate_evidence_mock.assert_called_once()
def test_success(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 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') # 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(self, upload_mock): """Testing extra_data in rekor_entry """ with TempDirectory() as temp_dir: parent_work_dir_path = os.path.join(temp_dir.path, 'working') signer_pgp_public_key_path = os.path.join( os.path.dirname(__file__), '../../helpers', 'files', 'ploigos-step-runner-tests-public.key') step_config = { 'rekor-server-url': TestStepImplementerAutomatedGovernanceRekor.TEST_REKOR_SERVER, 'signer-pgp-public-key-path': signer_pgp_public_key_path, 'signer-pgp-private-key-user': TestStepImplementerAutomatedGovernanceRekor. TEST_signer_pgp_private_key_user } step_implementer = self.create_step_implementer( step_config=step_config, parent_work_dir_path=parent_work_dir_path, ) expected_step_result = StepResult( step_name='automated-governance', sub_step_name='Rekor', sub_step_implementer_name='Rekor') expected_step_result.add_artifact( name='rekor-entry', value=TestStepImplementerAutomatedGovernanceRekor. TEST_REKOR_ENTRY) expected_step_result.add_artifact( name='rekor-uuid', value=TestStepImplementerAutomatedGovernanceRekor. TEST_REKOR_UUID) def upload_mock_side_effect(rekor_server, extra_data_file, signer_pgp_public_key_path, signer_pgp_private_key_user): return TestStepImplementerAutomatedGovernanceRekor.TEST_REKOR_ENTRY, TestStepImplementerAutomatedGovernanceRekor.TEST_REKOR_UUID upload_mock.side_effect = upload_mock_side_effect extra_data_file = os.path.join(step_implementer.work_dir_path, 'automated-governance.json') result = step_implementer._run_step() upload_mock.assert_called_once_with( rekor_server=TestStepImplementerAutomatedGovernanceRekor. TEST_REKOR_SERVER, extra_data_file=extra_data_file, signer_pgp_public_key_path=signer_pgp_public_key_path, signer_pgp_private_key_user= TestStepImplementerAutomatedGovernanceRekor. TEST_signer_pgp_private_key_user) self.assertEqual(result.get_step_result_dict(), expected_step_result.get_step_result_dict())
def setup_previous_result(self, work_dir_path, artifact_config={}): step_result = StepResult( step_name='test-step', sub_step_name='test-sub-step-name', sub_step_implementer_name='test-step-implementer-name') for key1, val1 in artifact_config.items(): description = '' value = '' for key2, val2 in val1.items(): if key2 == 'description': description = val2 elif key2 == 'value': value = val2 else: raise StepRunnerException( f'Given field is not apart of an artifact: {key2}') step_result.add_artifact( name=key1, value=value, description=description, ) workflow_result = WorkflowResult() workflow_result.add_step_result(step_result=step_result) pickle_filename = os.path.join(work_dir_path, 'step-runner-results.pkl') workflow_result.write_to_pickle_file(pickle_filename=pickle_filename) return workflow_result
def test_boolean_false_config_variable(self): config = { 'step-runner-config': { 'write-config-as-results': { 'implementer': 'tests.helpers.sample_step_implementers.' 'WriteConfigAsResultsStepImplementer', 'config': { 'required-config-key': False } } } } config_expected_step_results = StepResult( step_name='write-config-as-results', sub_step_name='tests.helpers.sample_step_implementers.' 'WriteConfigAsResultsStepImplementer', sub_step_implementer_name='tests.helpers.sample_step_implementers.' 'WriteConfigAsResultsStepImplementer') config_expected_step_results.success = True config_expected_step_results.add_artifact(name='required-config-key', value=False) with TempDirectory() as test_dir: self._run_step_implementer_test(config, 'write-config-as-results', config_expected_step_results, test_dir)
def test_success_pom_specified_absolute_reports_dir( self, mock_effective_pom_element, 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} step_implementer = self.create_step_implementer( step_config=step_config, parent_work_dir_path=parent_work_dir_path, ) # setup sideeffects surefire_reports_dir = os.path.join(test_dir.path, 'mock-abs/fake/reports') mock_effective_pom_element.side_effect = [ 'mock surefire element', Mock(text=surefire_reports_dir) ] group_id = 'com.ploigos.app' artifact_id = 'my-app' surefire_artifact_names = [ f'{group_id}.{artifact_id}.ClassNameTest.txt', f'TEST-{group_id}.{artifact_id}.ClassNameTest.xml' ] def run_maven_side_effect(mvn_output_file_path): os.makedirs(surefire_reports_dir, exist_ok=True) for artifact_name in surefire_artifact_names: artifact_path = os.path.join(surefire_reports_dir, artifact_name) Path(artifact_path).touch() mock_run_maven_step.side_effect = run_maven_side_effect # run step actual_step_result = step_implementer._run_step() # create expected step result expected_step_result = StepResult( step_name='unit-test', sub_step_name='MavenTest', sub_step_implementer_name='MavenTest') 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="Surefire reports generated by maven.", name='surefire-reports', value=surefire_reports_dir) # 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_no_commit_history(self): with TempDirectory() as temp_dir: work_dir_path = os.path.join(temp_dir.path, 'working') Repo.init(str(temp_dir.path)) step_config = {'repo-root': str(temp_dir.path)} step_implementer = self.create_step_implementer( step_config=step_config, step_name='generate-metadata', implementer='Git', work_dir_path=work_dir_path, ) result = step_implementer._run_step() expected_step_result = StepResult(step_name='generate-metadata', sub_step_name='Git', sub_step_implementer_name='Git') expected_step_result.add_artifact(name='pre-release', value='master') expected_step_result.success = False expected_step_result.message = 'Given directory (repo_root) is a ' \ 'git branch (git_branch) with no commit history' self.assertEqual(result.get_step_result_dict(), expected_step_result.get_step_result_dict())
def test__run_step_pass(self, create_archive_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' } step_implementer = self.create_step_implementer( step_config=step_config, parent_work_dir_path=parent_work_dir_path, ) step_result = step_implementer._run_step() 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.' ) self.assertEqual(step_result, expected_step_result) create_archive_mock.assert_called_once()
def test__run_step_pass_no_evidence(self, generate_evidence_mock): step_config = { 'organization': 'test-ORG', 'application-name': 'test-APP', 'service-name': 'test-SERVICE', 'version': '42.0-test' } step_implementer = self.create_step_implementer( step_config=step_config, ) #Set mock method to return None generate_evidence_mock.return_value = None step_result = step_implementer._run_step() expected_step_result = StepResult( step_name='generate_evidence', sub_step_name='GenerateEvidence', sub_step_implementer_name='GenerateEvidence') expected_step_result.add_artifact( name='result-generate-evidence', value='No evidence to generate.', description='Evidence from all previously run steps.') expected_step_result.message = "No evidence generated from previously run steps" self.assertEqual(step_result, expected_step_result) generate_evidence_mock.assert_called_once()
def test_write_to_pickle_file_with_merge(self): with TempDirectory() as temp_dir: pickle_file = temp_dir.path + '/test.pkl' on_disk_wfr = setup_test() on_disk_wfr.write_to_pickle_file(pickle_file) in_mem_wfr1 = WorkflowResult.load_from_pickle_file(pickle_file) in_mem_wfr2 = WorkflowResult.load_from_pickle_file(pickle_file) sr1 = StepResult('compliance-scan', 'scan with stackrox', 'stackrox', 'prod') sr1.add_artifact('compliance-scan-result', 'pass') sr2 = StepResult('vulnerability-scan', 'scan with stackrox', 'stackrox', 'prod') sr2.add_artifact('vulnerability-scan-result', 'fail') in_mem_wfr1.add_step_result(sr1) in_mem_wfr2.add_step_result(sr2) in_mem_wfr1.merge_with_pickle_file(pickle_file) in_mem_wfr1.write_to_pickle_file(pickle_file) in_mem_wfr2.merge_with_pickle_file(pickle_file) in_mem_wfr2.write_to_pickle_file(pickle_file) resulting_wfr = WorkflowResult.load_from_pickle_file(pickle_file) # ensure: # - both our new StepResults are present # - all StepResults from the original pickle file are present self.assertIn(sr1, resulting_wfr.workflow_list) self.assertIn(sr2, resulting_wfr.workflow_list) for sr in on_disk_wfr.workflow_list: self.assertIn(sr, resulting_wfr.workflow_list)
def test_run_step_error_git_push(self, git_push_mock, git_tag_mock, git_url_mock, get_tag_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') 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) def get_tag_side_effect(): return tag get_tag_mock.side_effect = get_tag_side_effect def git_url_side_effect(): return url git_url_mock.side_effect = git_url_side_effect # this is the test here git_push_mock.side_effect = StepRunnerException('mock 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 = "mock error" # verifying all mocks were called get_tag_mock.assert_called_once_with() git_tag_mock.assert_called_once_with(tag) git_url_mock.assert_called_once_with() git_push_mock.assert_called_once_with(None) self.assertEqual(result, expected_step_result)
def test_run_step_tls_verify_false(self, mvn_mock): with TempDirectory() as temp_dir: parent_work_dir_path = os.path.join(temp_dir.path, 'working') step_config = { 'maven-push-artifact-repo-url': 'pass', 'maven-push-artifact-repo-id': 'pass', 'tls-verify': False } # Previous (fake) results package_artifacts = [{ 'path': 'test-path', 'group-id': 'test-group-id', 'artifact-id': 'test-artifact-id', 'package-type': 'test-package-type' }] artifact_config = { 'package-artifacts': { 'value': package_artifacts }, 'version': { 'value': 'test-version' } } workflow_result = self.setup_previous_result( parent_work_dir_path, artifact_config) # Actual results step_implementer = self.create_step_implementer( step_config=step_config, step_name='push-artifacts', implementer='Maven', workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path) result = step_implementer._run_step() # Expected results push_artifacts = [{ 'artifact-id': 'test-artifact-id', 'group-id': 'test-group-id', 'version': 'test-version', 'path': 'test-path', 'packaging': 'test-package-type', }] expected_step_result = StepResult( step_name='push-artifacts', sub_step_name='Maven', sub_step_implementer_name='Maven') expected_step_result.add_artifact(name='push-artifacts', value=push_artifacts) mvn_output_file_path = os.path.join(step_implementer.work_dir_path, 'mvn_test_output.txt') expected_step_result.add_artifact( description= "Standard out and standard error from 'mvn install'.", name='maven-output', value=mvn_output_file_path) self.assertEqual(expected_step_result, result)
def test_success_error_finding_label_on_build_image_inspection_details( self, mock_create_working_dir_sub_dir, mock_write_working_file, mock_container_registries_login, mock_inspect_container_image, mock_s2i ): # setup step_config = { 's2i-builder-image': 'mock.io/awesome-image:v42' } step_implementer = self.create_step_implementer( step_config=step_config ) # setup mocks mock_inspect_container_image.return_value = {} # run test actual_step_result= step_implementer._run_step() # validate expected_step_result = StepResult( step_name='create-container-image', sub_step_name='SourceToImage', sub_step_implementer_name='SourceToImage' ) expected_step_result.message = "WARNING: failed to find s2i scripts url label" \ " (io.openshift.s2i.scripts-url) on s2i builder image" \ " (mock.io/awesome-image:v42) to dynamically determine image scripts url." \ " S2I default will be used: Could not find key ('OCIv1').\n" expected_step_result.add_artifact( name='imagespecfile', value='/mock/working/s2i-context/Containerfile.s2i-gen', description='File defining the container image to build generated by s2i' ) expected_step_result.add_artifact( name='context', value='/mock/working/s2i-context', description='Context to use when building the imagespecfile generated by S2I.' ) self.assertEqual(actual_step_result, expected_step_result) mock_inspect_container_image.assert_called_once_with( container_image_uri='mock.io/awesome-image:v42', containers_config_auth_file='create-container-image/container-auth.json' ) mock_s2i.build.assert_called_once_with( '.', 'mock.io/awesome-image:v42', '--loglevel', 1, '--tlsverify', '--as-dockerfile', '/mock/working/s2i-context/Containerfile.s2i-gen', _out=ANY, _err=ANY, _tee='err' )
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()
def test_success(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 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.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_called_with( mvn_output_file_path='/mock/mvn_deploy_output.txt', step_implementer_additional_arguments=[ '-DaltDeploymentRepository=' \ f'{maven_push_artifact_repo_id}::default::{maven_push_artifact_repo_url}' ] )
def test_run_step_pass_no_username_and_password(self, sonar_mock): with TempDirectory() as temp_dir: results_dir_path = os.path.join(temp_dir.path, 'step-runner-results') results_file_name = 'step-runner-results.yml' 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') step_config = { 'properties': properties_path, 'url': 'https://sonarqube-sonarqube.apps.ploigos_step_runner.rht-set.com', 'application-name': 'app-name', 'service-name': 'service-name' } step_implementer = self.create_step_implementer( step_config=step_config, step_name='static-code-analysis', implementer='SonarQube', results_dir_path=results_dir_path, results_file_name=results_file_name, work_dir_path=work_dir_path, ) artifact_config = { 'version': { 'description': '', 'value': '1.0-123abc' }, } self.setup_previous_result(work_dir_path, artifact_config) 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.add_artifact( name='sonarqube-result-set', value=f'{temp_dir.path}/working/report-task.txt') sonar_mock.assert_called_once_with( '-Dproject.settings=' + properties_path, '-Dsonar.host.url=https://sonarqube-sonarqube.apps.ploigos_step_runner.rht-set.com', '-Dsonar.projectVersion=1.0-123abc', '-Dsonar.projectKey=app-name:service-name', '-Dsonar.working.directory=' + work_dir_path, _out=sys.stdout, _err=sys.stderr) self.assertEqual(result.get_step_result_dict(), expected_step_result.get_step_result_dict())
def test___create_archive_dir_result(self): 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' } artifact_dir_name = 'test-result-artifact-dir' temp_dir.makedir(artifact_dir_name) artifact_file_name_1 = f'{artifact_dir_name}/test-artifact1.txt' temp_dir.write(artifact_file_name_1, bytes('hello world 1', 'utf-8')) artifact_file_name_2 = f'{artifact_dir_name}/test-artifact2.txt' temp_dir.write(artifact_file_name_2, bytes('hello world 2', 'utf-8')) 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(name='test-step-result-dir', value=os.path.join( temp_dir.path, artifact_dir_name)) 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) archive_path = step_implementer._ResultArtifactsArchive__create_archive( ) archive_zip = zipfile.ZipFile(archive_path) artifact_file_path_1 = f"{step_config['organization']}-" \ f"{step_config['application-name']}-{step_config['service-name']}-" \ f"{step_config['version']}/test-step/test-sub-step/test-step-result-dir/" \ f"{artifact_file_name_1}" with archive_zip.open(artifact_file_path_1, 'r') as artifact_file: artifact_file_contents = artifact_file.read().decode('UTF-8') self.assertEqual(artifact_file_contents, 'hello world 1') artifact_file_path_2 = f"{step_config['organization']}-" \ f"{step_config['application-name']}-{step_config['service-name']}-" \ f"{step_config['version']}/test-step/test-sub-step/test-step-result-dir/" \ f"{artifact_file_name_1}" with archive_zip.open(artifact_file_path_2, 'r') as artifact_file: artifact_file_contents = artifact_file.read().decode('UTF-8') self.assertEqual(artifact_file_contents, 'hello world 1')
def __run__run_step_fail_sonar_scanner_error_test( self, sonar_scanner_error, expected_result_message_regex, sonar_mock): with TempDirectory() as temp_dir: results_dir_path = os.path.join(temp_dir.path, 'step-runner-results') results_file_name = 'step-runner-results.yml' 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') 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', results_dir_path=results_dir_path, results_file_name=results_file_name, work_dir_path=work_dir_path, ) artifact_config = { 'version': { 'description': '', 'value': '1.0-123abc' }, } self.setup_previous_result(work_dir_path, artifact_config) sonar_mock.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/report-task.txt') 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_fail_mvn_error(self, mvn_mock): with TempDirectory() as temp_dir: results_dir_path = os.path.join(temp_dir.path, 'step-runner-results') results_file_name = 'step-runner-results.yml' 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> <version>1.0</version> </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='package', implementer='Maven', results_dir_path=results_dir_path, results_file_name=results_file_name, work_dir_path=work_dir_path, ) mvn_mock.side_effect = sh.ErrorReturnCode('mvn', b'mock out', b'mock error') result = step_implementer._run_step() expected_step_result = StepResult( step_name='package', sub_step_name='Maven', sub_step_implementer_name='Maven') mvn_output_file_path = os.path.join(work_dir_path, 'package', 'mvn_test_output.txt') expected_step_result.add_artifact( description= "Standard out and standard error from 'mvn install'.", name='maven-output', value=mvn_output_file_path) expected_step_result.success = False self.assertEqual(result.success, expected_step_result.success) self.assertRegex( result.message, re.compile( r"Package failures. See 'maven-output' report artifacts for details:" r".*RAN: mvn" r".*STDOUT:" r".*mock out" r".*STDERR:" r".*mock error", re.DOTALL)) self.assertEqual(result.artifacts, expected_step_result.artifacts)
def _setup_get_value_with_env_test(self, test_dir, environment): step_config = { 'test': 'hello world', 'old-param-name': 'foo42', 'new-param-name': 'bar42' } parent_work_dir_path = os.path.join(test_dir.path, 'working') workflow_result = WorkflowResult() step_result_no_evn = StepResult(step_name='foo', sub_step_name='Mock', sub_step_implementer_name='Mock') step_result_no_evn.add_artifact(name='container-image-tag', value='localhost/mock:0.42.0-weird') workflow_result.add_step_result(step_result=step_result_no_evn) step_result_deploy_test = StepResult( step_name='deploy', sub_step_name='ArgoCD', sub_step_implementer_name='ArgoCD', environment='TEST') step_result_deploy_test.add_artifact( name='deployed-host-urls', value='https://awesome-app.test.ploigos.xyz') step_result_deploy_test.add_artifact( name='container-image-tag', value='localhost/test/mock:0.42.0-weird') workflow_result.add_step_result(step_result=step_result_deploy_test) step_result_deploy_prod = StepResult( step_name='deploy', sub_step_name='ArgoCD', sub_step_implementer_name='ArgoCD', environment='PROD') step_result_deploy_prod.add_artifact( name='deployed-host-urls', value='https://awesome-app.prod.ploigos.xyz') step_result_deploy_test.add_artifact( name='container-image-tag', value='localhost/prod/mock:0.42.0-weird') workflow_result.add_step_result(step_result=step_result_deploy_prod) pickle_filename = os.path.join(parent_work_dir_path, 'step-runner-results.pkl') workflow_result.write_to_pickle_file(pickle_filename=pickle_filename) return self.create_given_step_implementer( step_implementer=FooStepImplementer, step_config=step_config, step_name='foo', implementer='FooStepImplementer', workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, environment=environment)