def setup_test_sub_steps(): step_result1 = StepResult('step1', 'sub1', 'implementer1') step_result1.add_artifact('artifact1', 'value1', 'description1') step_result1.add_artifact('artifact2', 'value2', 'description2') step_result1.add_artifact('artifact3', 'value3') step_result1.add_artifact('artifact4', False) step_result1.add_evidence('evidence1', 'value1', 'description1') step_result1.add_evidence('evidence2', 'value2', 'description2') step_result1.add_evidence('evidence3', 'value3') step_result1.add_evidence('evidence4', False) step_result2 = StepResult('step1', 'sub2', 'implementer2') step_result2.add_artifact('artifact1', True) step_result2.add_artifact('artifact2', False) step_result2.add_artifact('artifact5', 'value5') step_result2.add_evidence('evidence1', True) step_result2.add_evidence('evidence2', False) step_result2.add_evidence('evidence5', 'value5') wfr = WorkflowResult() wfr.add_step_result(step_result1) wfr.add_step_result(step_result2) return wfr
def test_load_from_pickle_file_no_file(self): pickle_wfr = WorkflowResult.load_from_pickle_file('test.pkl') expected_wfr = WorkflowResult() self.assertEqual( pickle_wfr._WorkflowResult__get_all_step_results_dict(), expected_wfr._WorkflowResult__get_all_step_results_dict() )
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_load_from_pickle_file_empty_file(self): with TempDirectory() as temp_dir: pickle_file = temp_dir.path + '/test.pkl' open(pickle_file, 'a').close() pickle_wfr = WorkflowResult.load_from_pickle_file(pickle_file) expected_wfr = WorkflowResult() self.assertEqual( pickle_wfr._WorkflowResult__get_all_step_results_dict(), expected_wfr._WorkflowResult__get_all_step_results_dict())
def test_load_from_pickle_file_exception(self): with TempDirectory() as temp_dir: pickle_file_name = temp_dir.path + '/test.pkl' pickle_file = open(pickle_file_name, 'w+') pickle_file.write("This is not a Workflow Result.") pickle_file.close() with self.assertRaises(StepRunnerException): WorkflowResult.load_from_pickle_file(pickle_file)
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)
def test_load_from_pickle_file_no_workflowresult(self): with TempDirectory() as temp_dir: pickle_file = temp_dir.path + '/test.pkl' not_wfr = {"step1": "value1", "step2": "value2"} with open(pickle_file, 'wb') as file: pickle.dump(not_wfr, file) with self.assertRaisesRegex( StepRunnerException, f'error {pickle_file} has invalid data'): WorkflowResult.load_from_pickle_file(pickle_file)
def create_given_step_implementer( self, step_implementer, step_config={}, step_name='', environment=None, implementer='', workflow_result=None, parent_work_dir_path='', ): config = Config({ Config.CONFIG_KEY: { step_name: [{ 'implementer': implementer, 'config': step_config }] } }) step_config = config.get_step_config(step_name) sub_step_config = step_config.get_sub_step(implementer) if not workflow_result: workflow_result = WorkflowResult() step_implementer = step_implementer( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=sub_step_config, environment=environment) return step_implementer
def _run_step_implementer_test( self, config, step, expected_step_results, test_dir, environment=None ): working_dir_path = os.path.join(test_dir.path, 'step-runner-working') factory = StepRunner( config=config, results_file_name='step-runner-results.yml', work_dir_path=working_dir_path ) factory.run_step( step_name=step, environment=environment ) pickle = f'{working_dir_path}/step-runner-results.pkl' workflow_result = WorkflowResult.load_from_pickle_file(pickle) step_result = workflow_result.get_step_result( step_name=step ) self.assertEqual(step_result, expected_step_results)
def test_from_step_implementer_with_env(self): config = Config({ 'step-runner-config': { 'foo': { 'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer', 'config': {} } } }) step_config = config.get_step_config('foo') sub_step = step_config.get_sub_step( 'tests.helpers.sample_step_implementers.FooStepImplementer') step = FooStepImplementer(workflow_result=WorkflowResult(), parent_work_dir_path=None, config=sub_step, environment='blarg') step_result = StepResult.from_step_implementer(step) expected_step_result = StepResult( step_name='foo', sub_step_name= 'tests.helpers.sample_step_implementers.FooStepImplementer', sub_step_implementer_name= 'tests.helpers.sample_step_implementers.FooStepImplementer', environment='blarg') self.assertEqual(step_result, expected_step_result)
def test_write_working_file_touch(self): config = Config({ 'step-runner-config': { 'foo': { 'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer', 'config': {} } } }) step_config = config.get_step_config('foo') sub_step = step_config.get_sub_step( 'tests.helpers.sample_step_implementers.FooStepImplementer') with TempDirectory() as test_dir: working_dir_path = os.path.join(test_dir.path, 'step-runner-working') step = FooStepImplementer(workflow_result=WorkflowResult(), parent_work_dir_path=working_dir_path, config=sub_step) step.write_working_file('foo/test.json') working_file_path = os.path.join(working_dir_path, 'foo/foo/test.json') self.assertTrue(os.path.exists(working_file_path)) with open(working_file_path, 'r') as working_file: self.assertEqual(working_file.read(), '')
def test_create_working_dir_sub_dir(self): config = Config({ 'step-runner-config': { 'foo': { 'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer', 'config': {} } } }) step_config = config.get_step_config('foo') sub_step = step_config.get_sub_step( 'tests.helpers.sample_step_implementers.FooStepImplementer') with TempDirectory() as test_dir: working_dir_path = os.path.join(test_dir.path, 'step-runner-working') step = FooStepImplementer(workflow_result=WorkflowResult(), parent_work_dir_path=working_dir_path, config=sub_step) sub = step.create_working_dir_sub_dir('folder1') self.assertEqual(sub, f'{working_dir_path}/foo/folder1') self.assertEqual(True, os.path.isdir(sub)) sub = step.create_working_dir_sub_dir('folder1/folder2/folder3') self.assertEqual( sub, f'{working_dir_path}/foo/folder1/folder2/folder3') self.assertEqual(True, os.path.isdir(sub))
def test_upload_to_rekor(self, rekor_mock, create_mock): 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': self.TEST_REKOR_SERVER_URL, 'signer-pgp-private-key': self.TEST_PGP_SIGNER_PRIVATE_KEY } step_implementer = self.create_step_implementer( step_config=step_config, parent_work_dir_path=parent_work_dir_path, artifact_to_sign_uri_config_key=self.TEST_ARTIFACT_TO_SIGN_URI) artifact_data_file = os.path.join(parent_work_dir_path, 'automated-governance', 'automated-governance.json') artifact_data_file_path = Path(artifact_data_file) WorkflowResult().write_results_to_json_file( artifact_data_file_path) rekor_entry_path_name = os.path.join(parent_work_dir_path, 'automated-governance', 'entry.json') def create_mock_side_effect(signer_pgp_public_key_path, signer_pgp_private_key_user, extra_data_file): return self.TEST_REKOR_ENTRY def rekor_mock_side_effect(*args, **kwargs): return 'Created entry at: ' + args[ 2] + '/api/v1/log/entries/' + self.TEST_REKOR_UUID create_mock.side_effect = create_mock_side_effect rekor_mock.side_effect = rekor_mock_side_effect rekor_entry_path = Path(rekor_entry_path_name) rekor_entry_path.touch() result_uuid = step_implementer._upload_to_rekor( rekor_server=self.TEST_REKOR_SERVER_URL, rekor_entry=self.TEST_REKOR_ENTRY) rekor_mock.assert_called_once_with('upload', '--rekor_server', self.TEST_REKOR_SERVER_URL, '--entry', rekor_entry_path_name, _out=Any(IOBase), _err_to_out=True, _tee='out') self.assertEqual(result_uuid, self.TEST_REKOR_UUID)
def test_use_object_property_no_config_value(self): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = None step_implementer = ToxGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, tox_env='test') self.assertEqual(step_implementer.tox_env, 'test')
def test_use_object_property_no_config_value(self): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = None step_implementer = NpmGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, npm_args=['run fake:script']) self.assertEqual(step_implementer.npm_args, ['run fake:script'])
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_use_object_property_no_config_value(self): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = None step_implementer = MavenGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, maven_phases_and_goals=['fake-phase']) self.assertEqual(step_implementer.maven_phases_and_goals, ['fake-phase'])
def test_defaults(self, mock_super_init): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = {} Maven(workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config) mock_super_init.assert_called_once_with( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, environment=None)
def test_defaults(self, mock_super_init): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = {} MavenDeploy(workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config) mock_super_init.assert_called_once_with( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, environment=None, maven_phases_and_goals=['deploy'])
def test_given_environment(self, mock_super_init): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = {} MavenTest(workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, environment='mock-env') mock_super_init.assert_called_once_with( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, environment='mock-env', maven_phases_and_goals=['test'])
def test_no_environment_no_tox_args(self, mock_super_init): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = {} step_implementer = ToxGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config) self.assertIsNone(step_implementer._ToxGeneric__tox_env) mock_super_init.assert_called_once_with( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, environment=None)
def setup_test(): step_result1 = StepResult('step1', 'sub1', 'implementer1') step_result1.add_artifact('artifact1', 'value1', 'description1') step_result1.add_artifact('artifact2', 'value2', 'description2') step_result1.add_artifact('artifact3', 'value3') step_result1.add_artifact('artifact4', False) step_result1.add_artifact('same-artifact-all-env-and-no-env', 'result1') step_result1.add_evidence('evidence1', 'value1', 'description1') step_result1.add_evidence('evidence2', 'value2', 'description2') step_result1.add_evidence('evidence3', 'value3') step_result1.add_evidence('evidence4', False) step_result1.add_evidence('same-evidence-all-env-and-no-env', 'result1') step_result2 = StepResult('step2', 'sub2', 'implementer2') step_result2.add_artifact('artifact1', True) step_result2.add_artifact('artifact2', False) step_result2.add_artifact('artifact5', 'value5') step_result2.add_evidence('evidence1', True) step_result2.add_evidence('evidence2', False) step_result2.add_evidence('evidence5', 'value5') step_result3 = StepResult('deploy', 'deploy-sub', 'helm', 'dev') step_result3.add_artifact('same-artifact-diff-env', 'value-dev-env') step_result3.add_artifact('unique-artifact-to-step-and-environment-1', 'value1-dev-env') step_result3.add_artifact('same-artifact-all-env-and-no-env', 'result3-dev-env') step_result3.add_evidence('same-evidence-diff-env', 'value-dev-env') step_result3.add_evidence('unique-evidence-to-step-and-environment-1', 'value1-dev-env') step_result3.add_evidence('same-evidence-all-env-and-no-env', 'result3-dev-env') step_result4 = StepResult('deploy', 'deploy-sub', 'helm', 'test') step_result4.add_artifact('artifact1', True) step_result4.add_artifact('artifact2', False) step_result4.add_artifact('artifact5', 'value5') step_result4.add_artifact('same-artifact-diff-env', 'value-test-env') step_result4.add_artifact('unique-artifact-to-step-and-environment-2', 'value2-test-env') step_result4.add_artifact('same-artifact-all-env-and-no-env', 'result4-test-env') step_result4.add_evidence('evidence1', True) step_result4.add_evidence('evidence2', False) step_result4.add_evidence('evidence5', 'value5') step_result4.add_evidence('same-evidence-diff-env', 'value-test-env') step_result4.add_evidence('unique-evidence-to-step-and-environment-2', 'value2-test-env') step_result4.add_evidence('same-evidence-all-env-and-no-env', 'result4-test-env') wfr = WorkflowResult() wfr.add_step_result(step_result1) wfr.add_step_result(step_result2) wfr.add_step_result(step_result3) wfr.add_step_result(step_result4) return wfr
def test_has_config_value(self): config = Config({ 'step-runner-config': { 'foo': { 'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer', 'config': { 'test': 'hello world', 'env-config-override-key': 'override-me', 'username': '******', 'password': '******' }, 'environment-config': { 'SAMPLE-ENV-1': { 'env-config-override-key': 'step env config - env 1 value - 1' }, 'SAMPLE-ENV-2': { 'env-config-override-key': 'step env config - env 2 value - 1' } }, } } }) step_config = config.get_step_config('foo') sub_step = step_config.get_sub_step( 'tests.helpers.sample_step_implementers.FooStepImplementer') with TempDirectory() as test_dir: working_dir_path = os.path.join(test_dir.path, 'step-runner-working') step = FooStepImplementer(workflow_result=WorkflowResult(), parent_work_dir_path=working_dir_path, config=sub_step, environment='SAMPLE-ENV-1') self.assertFalse(step.has_config_value('bar')) self.assertFalse(step.has_config_value(['bar'])) self.assertFalse(step.has_config_value(['username', 'foo'], False)) self.assertTrue(step.has_config_value(['username', 'foo'], True)) self.assertTrue( step.has_config_value(['username', 'password'], False)) self.assertTrue( step.has_config_value(['username', 'password'], True))
def test_with_environment_no_npm_args(self, mock_super_init): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = {} step_implementer = NpmGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, environment='test-env') self.assertIsNone(step_implementer._NpmGeneric__npm_args) mock_super_init.assert_called_once_with( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, environment='test-env')
def test_no_environment_with_npm_args(self, mock_super_init): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = {} step_implementer = NpmGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, npm_args=['fake-arg']) self.assertEqual(step_implementer._NpmGeneric__npm_args, ['fake-arg']) mock_super_init.assert_called_once_with( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, environment=None)
def test_no_environment_no_maven_phases_and_goals(self, mock_super_init): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' config = {} step_implementer = MavenGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config) self.assertIsNone(step_implementer._MavenGeneric__maven_settings_file) self.assertIsNone( step_implementer._MavenGeneric__maven_phases_and_goals) mock_super_init.assert_called_once_with( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, environment=None)
def test_use_object_property_with_config_value(self): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' step_config = {'tox-env': 'config-value-fake-env'} config = Config({ Config.CONFIG_KEY: { 'foo': [{ 'implementer': 'ToxGeneric', 'config': step_config }] } }) step_implementer = ToxGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, tox_env='object-property-fake-env') self.assertEqual(step_implementer.tox_env, 'object-property-fake-env')
def test_use_object_property_with_config_value(self): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' step_config = {'maven-phases-and-goals': ['config-value-fake-phase']} config = Config({ Config.CONFIG_KEY: { 'foo': [{ 'implementer': 'MavenGeneric', 'config': step_config }] } }) step_implementer = MavenGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, maven_phases_and_goals=['object-property-fake-phase']) self.assertEqual(step_implementer.maven_phases_and_goals, ['object-property-fake-phase'])
def test_use_object_property_with_config_value(self): workflow_result = WorkflowResult() parent_work_dir_path = '/fake/path' step_config = {'npm-args': ['config-value-fake-arg']} config = Config({ Config.CONFIG_KEY: { 'foo': [{ 'implementer': 'NpmGeneric', 'config': step_config }] } }) step_implementer = NpmGeneric( workflow_result=workflow_result, parent_work_dir_path=parent_work_dir_path, config=config, npm_args=['object-property-fake-arg']) self.assertEqual(step_implementer.npm_args, ['object-property-fake-arg'])
def test_get_config_value_with_env(self): config = Config({ 'step-runner-config': { 'foo': { 'implementer': 'tests.helpers.sample_step_implementers.FooStepImplementer', 'config': { 'test': 'hello world', 'env-config-override-key': 'override-me' }, 'environment-config': { 'SAMPLE-ENV-1': { 'env-config-override-key': 'step env config - env 1 value - 1' }, 'SAMPLE-ENV-2': { 'env-config-override-key': 'step env config - env 2 value - 1' } }, } } }) step_config = config.get_step_config('foo') sub_step = step_config.get_sub_step( 'tests.helpers.sample_step_implementers.FooStepImplementer') with TempDirectory() as test_dir: working_dir_path = os.path.join(test_dir.path, 'step-runner-working') step = FooStepImplementer(workflow_result=WorkflowResult(), parent_work_dir_path=working_dir_path, config=sub_step, environment='SAMPLE-ENV-1') self.assertEqual(step.get_config_value('test'), 'hello world') self.assertIsNone(step.get_config_value('does-not-exist')) self.assertEqual(step.get_config_value('env-config-override-key'), 'step env config - env 1 value - 1')