def __lazy_binding_initializer(self, bindings, key): normalized_key = key.upper() ec2_client = None if normalized_key == 'TEST_AWS_VPC_ID': # We need to figure out a specific aws vpc id to use. logger = logging.getLogger(__name__) logger.info('Determine default AWS VpcId...') if not ec2_client: ec2_client = self.observer.make_boto_client('ec2') # If we want the name defaultvpc then do this # filters = [{'Name': 'tag:Name', 'Values': ['defaultvpc']}] # I think we want the VPC that is the default # filters = [{'Name': 'isDefault', 'Values': ['true']}] filters = [{'Name': 'tag:Name', 'Values': ['defaultvpc']}] response = self.observer.call_method(ExecutionContext(), ec2_client.describe_vpcs, Filters=filters) vpc_list = response['Vpcs'] if not vpc_list: raise ValueError( 'There is no vpc matching filter {0}'.format(filters)) found = vpc_list[0]['VpcId'] logger.info('Using discovered default VpcId=%s', str(found)) return found if normalized_key == 'TEST_AWS_SECURITY_GROUP_ID': # We need to figure out a specific security group that is compatable # with the VpcId we are using. logger = logging.getLogger(__name__) logger.info('Determine default AWS SecurityGroupId...') if not ec2_client: ec2_client = self.observer.make_boto_client('ec2') response = self.observer.call_method( ExecutionContext(), ec2_client.describe_security_groups) sg_list = response['SecurityGroups'] found = None vpc_id = bindings['TEST_AWS_VPC_ID'] for entry in sg_list: if entry.get('VpcId', None) == vpc_id: found = entry['GroupId'] break if not found: raise ValueError( 'Could not find a security group for AWS_VPC_ID {0}'. format(vpc_id)) logger.info('Using discovered default SecurityGroupId=%s', str(found)) return found raise KeyError(key)
def __lazy_binding_initializer(self, bindings, key): normalized_key = key.upper() if normalized_key == 'TEST_AWS_VPC_ID': # We need to figure out a specific aws vpc id to use. logger = logging.getLogger(__name__) logger.info('Determine default AWS VpcId...') vpc_list = self.observer.get_resource_list( ExecutionContext(), root_key='Vpcs', aws_command='describe-vpcs', args=['--filters', 'Name=tag:Name,Values=defaultvpc'], region=bindings['TEST_AWS_REGION'], aws_module='ec2', profile=self.observer.profile) if not vpc_list: raise ValueError('There is no vpc tagged as "defaultvpc"') found = vpc_list[0]['VpcId'] logger.info('Using discovered default VpcId=%s', str(found)) return found if normalized_key == 'TEST_AWS_SECURITY_GROUP_ID': # We need to figure out a specific security group that is compatable # with the VpcId we are using. logger = logging.getLogger(__name__) logger.info('Determine default AWS SecurityGroupId...') sg_list = self.observer.get_resource_list( ExecutionContext(), root_key='SecurityGroups', aws_command='describe-security-groups', args=[], region=bindings['TEST_AWS_REGION'], aws_module='ec2', profile=self.observer.profile) found = None vpc_id = bindings['TEST_AWS_VPC_ID'] for entry in sg_list: if entry.get('VpcId', None) == vpc_id: found = entry['GroupId'] break if not found: raise ValueError( 'Could not find a security group for AWS_VPC_ID {0}'. format(vpc_id)) logger.info('Using discovered default SecurityGroupId=%s', str(found)) return found raise KeyError(key)
def verify_quota(title, gcp_agent, project_quota, regions): """Verify that the observed GCP project has sufficient quota. Args: title: [string] What the quota is for, for logging purposes only. gcp_agent: [GcpAgent] Observation agent on the desired project. project_quota: [dict] Minimum desired values keyed by quota metric for the observed project. regions: [array of (name, dict) tuple]: A list of regions and their individual quotas to check. Returns: json_contract.ContractVerifyResult against the quota check. """ execution_context = ExecutionContext() contract = make_quota_contract(gcp_agent, project_quota, regions) verify_results = None context_relation = 'ERROR' try: JournalLogger.begin_context(title) verify_results = contract.verify(execution_context) context_relation = 'VALID' if verify_results else 'INVALID' finally: if verify_results is not None: journal = get_global_journal() if journal is not None: journal.store(verify_results) JournalLogger.end_context(relation=context_relation) return verify_results
def test_condition_else_fail(self): context = ExecutionContext() aA = jp.PathEqPredicate('a', 'A') bB = jp.PathEqPredicate('b', 'B') cC = jp.PathEqPredicate('c', 'C') ifAthenBelseC = jc.IF(aA, bB, cC) # False if all conditions are false # False if "if" is true and "then" is false even if "else" matches. test_cases = [{'a':'A', 'b':'X', 'c':'C'}, {'a':'X', 'b':'B', 'c':'D'}] for i in range(2): test = test_cases[i] tried = [aA(context, test)] if i < 1: # First has true IF so tries THEN tried.append(bB(context, test)) else: # Remainder has false IF so tries ELSE tried.append(cC(context, test)) expect = jc.CompositePredicateResult( valid=False, pred=ifAthenBelseC, results=tried) result = ifAthenBelseC(context, test) self.assertFalse(result) self.assertEqual(expect, result)
def _do_init_bindings(self): """Hook to initialize custom test bindings so journaling is scoped.""" context = ExecutionContext() config = self.agent.deployed_config # If we're running this test and dont have a config, assume it is favorable. enabled = config.get('spinnaker.gcs.enabled', True) if enabled == False: raise ValueError('spinnaker.gcs.enabled is not True') if not self.bindings['GCS_BUCKET'] and not config[ 'spinnaker.gcs.bucket']: raise ValueError('The GCS bucket name is not specified') if not self.bindings['GCS_BASE_PATH'] and not config[ 'spinnaker.gcs.rootFolder']: raise ValueError('The GCS rootFolder is not specified') self.BUCKET = self.bindings['GCS_BUCKET'] or config[ 'spinnaker.gcs.bucket'] self.BASE_PATH = self.bindings['GCS_BASE_PATH'] or config[ 'spinnaker.gcs.rootFolder'] self.TEST_APP = self.bindings['TEST_APP'] self.TEST_PIPELINE_NAME = 'My {app} Pipeline'.format(app=self.TEST_APP) self.TEST_PIPELINE_ID = '{app}-pipeline-id'.format(app=self.TEST_APP) self.gcs_observer = gcp.GcpStorageAgent.make_agent( credentials_path=self.bindings['GCS_JSON_PATH'], scopes=(gcp.gcp_storage_agent.STORAGE_FULL_SCOPE if self.bindings['GCS_JSON_PATH'] else None)) metadata = self.gcs_observer.inspect_bucket(context, self.BUCKET) self.versioning_enabled = (metadata.get('versioning', {}).get('enabled', False)) if not self.versioning_enabled: self.logger.info('bucket=%s versioning enabled=%s', self.BUCKET, self.versioning_enabled)
def _do_init_bindings(self): """Hook to initialize custom test bindings so journaling is scoped.""" context = ExecutionContext() config = self.agent.deployed_config # If we're running this test and dont have a config, assume it is favorable. enabled = config.get("spinnaker.gcs.enabled", True) if enabled == False: raise ValueError("spinnaker.gcs.enabled is not True") if not self.bindings["GCS_BUCKET"] and not config[ "spinnaker.gcs.bucket"]: raise ValueError("The GCS bucket name is not specified") if (not self.bindings["GCS_BASE_PATH"] and not config["spinnaker.gcs.rootFolder"]): raise ValueError("The GCS rootFolder is not specified") self.BUCKET = self.bindings["GCS_BUCKET"] or config[ "spinnaker.gcs.bucket"] self.BASE_PATH = (self.bindings["GCS_BASE_PATH"] or config["spinnaker.gcs.rootFolder"]) self.TEST_APP = self.bindings["TEST_APP"] self.TEST_PIPELINE_NAME = "My {app} Pipeline".format(app=self.TEST_APP) self.TEST_PIPELINE_ID = "{app}-pipeline-id".format(app=self.TEST_APP) self.gcs_observer = gcp.GcpStorageAgent.make_agent( credentials_path=self.bindings["GCS_JSON_PATH"], scopes=gcp.gcp_storage_agent.STORAGE_FULL_SCOPE, ) metadata = self.gcs_observer.inspect_bucket(context, self.BUCKET) self.versioning_enabled = metadata.get("versioning", {}).get("enabled", False) if not self.versioning_enabled: self.logger.info("bucket=%s versioning enabled=%s", self.BUCKET, self.versioning_enabled)
def test_dict_specific_operator_type_mismatch(self): context = ExecutionContext() operand = {'a': 'A'} for value in [['a'], 'a', 1]: for factory in [jp.DICT_SUBSET]: self.simple_operand_type_mismatch_helper( context, dict, factory, operand, value)
def test_collect_from_list_identity(self): context = ExecutionContext() letters = ['A', 'B', 'C'] pred = PathPredicate('') values = pred(context, letters) self.assertEqual([ PathValue('[0]', 'A'), PathValue('[1]', 'B'), PathValue('[2]', 'C') ], values.path_values) self.assertEqual([], values.path_failures) pred = PathPredicate(DONT_ENUMERATE_TERMINAL) values = pred(context, letters) self.assertEqual([PathValue('', letters)], values.path_values) self.assertEqual([], values.path_failures) pred = PathPredicate(PATH_SEP) values = pred(context, letters) self.assertEqual([ PathValue('[0]', 'A'), PathValue('[1]', 'B'), PathValue('[2]', 'C') ], values.path_values) self.assertEqual([], values.path_failures)
def test_obsolete_observation_failure_or_found(self): context = ExecutionContext() observation = jc.Observation() observation.add_error(ValueError('not the error')) failure_verifier = TestObsoleteObservationFailureVerifier( 'Verify', 'NotFound') comment = failure_verifier._error_not_found_comment(observation) failure_result = jp.PredicateResult(valid=False, comment=comment) # We've already established this result is what we expect bad_observation_result = failure_verifier(context, observation) success_pred_result = jp.PredicateResult(valid=True) good_observation_result = _makeObservationVerifyResult( valid=True, good_results=[success_pred_result], observation=observation) success_verifier = FakeObservationVerifier( 'Found', dnf_verifier=[], result=good_observation_result) builder = jc.ObservationVerifierBuilder(title='Observation Verifier') builder.EXPECT(failure_verifier).OR(success_verifier) verifier = builder.build() expect = jc.ObservationVerifyResult( valid=True, observation=observation, bad_results=bad_observation_result.bad_results, good_results=good_observation_result.good_results, failed_constraints=[]) got = verifier(context, observation) self.assertEqual(expect, got)
def test_obsolete_observation_failure_not_ok(self): error_text = 'the error' context = ExecutionContext() observation = jc.Observation() error = ValueError('not the error') observation.add_error(error) failure_verifier = TestObsoleteObservationFailureVerifier( 'Test', error_text) comment = failure_verifier._error_not_found_comment(observation) failure_pred_result = jp.PredicateResult(valid=False, comment=comment) expect_failure = jc.ObservationVerifyResult( valid=False, observation=observation, bad_results=[jp.ObjectResultMapAttempt(observation, failure_pred_result)], good_results=[], failed_constraints=[], comment=comment) self.assertEqual(expect_failure, failure_verifier(context, observation)) builder = jc.ObservationVerifierBuilder(title='Test Verifier') builder.EXPECT(failure_verifier) verifier = builder.build() expect = jc.ObservationVerifyResult( valid=False, observation=observation, bad_results=expect_failure.bad_results, good_results=[], failed_constraints=[]) got = verifier(context, observation) self.assertEqual(expect, got)
def test_obsolete_observation_failure_ok(self): error_text = 'the error' context = ExecutionContext() observation = jc.Observation() error = ValueError(error_text) observation.add_error(error) failure_verifier = TestObsoleteObservationFailureVerifier( 'Test', error_text) failure_pred_result = jc.ObservationFailedError([error], valid=True) expect_failure = jc.ObservationVerifyResult( valid=True, observation=observation, good_results=[jp.ObjectResultMapAttempt(observation, failure_pred_result)], bad_results=[], failed_constraints=[], comment=_TEST_FOUND_ERROR_COMMENT) got = failure_verifier(context, observation) self.assertEqual(expect_failure, got) builder = jc.ObservationVerifierBuilder(title='Test') builder.EXPECT(failure_verifier) verifier = builder.build() expect = jc.ObservationVerifyResult( valid=True, observation=observation, good_results=expect_failure.good_results, bad_results=[], failed_constraints=[]) got = verifier(context, observation) self.assertEqual(expect, got)
def test_result_observation_verifier_disjunction_failure(self): context = ExecutionContext() observation = jc.Observation() builder = jc.ObservationVerifierBuilder(title='Test') verifiers = [] results = [] pred_results = [jp.PredicateResult(False, comment='Result %d' % i) for i in range(2)] for i in range(2): result = _makeObservationVerifyResult(observation=observation, valid=False, bad_results=[pred_results[i]]) fake_verifier = FakeObservationVerifier( title=i, dnf_verifier=[], result=result) verifiers.append(fake_verifier) results.append(result) builder.OR(fake_verifier) verifier = builder.build() self.assertEqual([verifiers[0:1], verifiers[1:2]], verifier.dnf_verifiers) expect = _makeObservationVerifyResult( False, observation=observation, bad_results=pred_results) global _called_verifiers _called_verifiers = [] got = verifier(context, observation) self.assertEqual(expect, got) self.assertEqual(verifiers, _called_verifiers)
def test_result_observation_verifier_disjunction_success_aborts_early(self): context = ExecutionContext() builder = jc.ObservationVerifierBuilder(title='Test') verifiers = [] results = [] pred_results = [jp.PredicateResult(False, comment='Result %d' % i) for i in range(2)] for i in range(2): result = _makeObservationVerifyResult( valid=True, good_results=[pred_results[i]]) fake_verifier = FakeObservationVerifier( title=i, dnf_verifier=[], result=result) verifiers.append(fake_verifier) results.append(result) builder.OR(fake_verifier) verifier = builder.build() self.assertEqual([verifiers[0:1], verifiers[1:2]], verifier.dnf_verifiers) expect = _makeObservationVerifyResult(True, good_results=[pred_results[0]]) global _called_verifiers _called_verifiers = [] got = verifier(context, jc.Observation()) self.assertEqual(expect, got) self.assertEqual(verifiers[:1], _called_verifiers)
def test_result_observation_verifier_conjunction_failure_aborts_early(self): context = ExecutionContext() builder = jc.ObservationVerifierBuilder(title='Test') verifiers = [] results = [] pred_results = [jp.PredicateResult(False, comment='Result %d' % i) for i in range(3)] for i in range(3): result = _makeObservationVerifyResult( valid=False, bad_results=[pred_results[i]]) fake_verifier = FakeObservationVerifier( title=i, dnf_verifier=[], result=result) verifiers.append(fake_verifier) results.append(result) builder.AND(fake_verifier) # verify build can work multiple times self.assertEqual(builder.build(), builder.build()) verifier = builder.build() self.assertEqual([verifiers], verifier.dnf_verifiers) expect = _makeObservationVerifyResult( False, bad_results=[pred_results[0]]) global _called_verifiers _called_verifiers = [] got = verifier(context, jc.Observation()) self.assertEqual(expect, got) self.assertEqual(verifiers[:1], _called_verifiers)
def test_result_observation_verifier_conjunction_ok(self): context = ExecutionContext() builder = jc.ObservationVerifierBuilder(title='Test') verifiers = [] pred_results = [] for i in range(3): this_result = jp.PredicateResult(True, comment='Pred {0}'.format(i)) pred_results.append(this_result) result = _makeObservationVerifyResult( valid=True, good_results=[this_result]) fake_verifier = FakeObservationVerifier( title=i, dnf_verifier=[], result=result) verifiers.append(fake_verifier) builder.AND(fake_verifier) # verify build can work multiple times self.assertEqual(builder.build(), builder.build()) verifier = builder.build() self.assertEqual([verifiers], verifier.dnf_verifiers) expect = _makeObservationVerifyResult(True, good_results=pred_results) global _called_verifiers _called_verifiers = [] got = verifier(context, jc.Observation()) self.assertEqual(expect, got) self.assertEqual(verifiers, _called_verifiers)
def test_collect_with_dict_subset(self): # See test_dict_subset_with_array_nodes for comparision. context = ExecutionContext() letters = {'a':'A', 'b':'B', 'c':'C'} numbers = {'a':1, 'b':2} both = [letters, numbers] source = {'items': both} letter_subset_pred = jp.DICT_SUBSET({'a':'A'}) path_pred = jp.PathPredicate('items', pred=letter_subset_pred) result = path_pred(context, source) mismatch_error = jp.TypeMismatchError( expect_type=(int, long, float), got_type=str, source=source, target_path=jp.PATH_SEP.join(['items', 'a']), path_value=PathValue('items[1]', numbers)) valid_result = letter_subset_pred(context, letters).clone_with_source( source=source, base_target_path='items', base_value_path='items[0]') self.assertEqual( # pylint: disable=bad-continuation jp.PathPredicateResultBuilder(source, path_pred) .add_result_candidate(PathValue('items[0]', letters), valid_result) .add_result_candidate(PathValue('items[1]', numbers), mismatch_error) .build(True), result)
def test_string_ne(self): context = ExecutionContext() ne_abc = jp.STR_NE('abc') self.assertGoodResult(PathValue('', 'abcd'), ne_abc, ne_abc(context, 'abcd')) self.assertBadResult(PathValue('', 'abc'), ne_abc, ne_abc(context, 'abc'))
def test_empty_builder(self): context = ExecutionContext() agent = self.testing_agent contract_builder = gt.GcpContractBuilder(agent) contract = contract_builder.build() results = contract.verify(context) self.assertTrue(results)
def test_collect_from_nested_list_found(self): # """Ambiguous path through nested lists.""" context = ExecutionContext() source = {'outer': [_LETTER_DICT, _NUMBER_DICT]} pred = PathPredicate(PATH_SEP.join(['outer', 'a'])) values = pred(context, source) self.assertEqual([ PathValue(PATH_SEP.join(['outer[0]', 'a']), 'A'), PathValue(PATH_SEP.join(['outer[1]', 'a']), 1) ], values.path_values) pred = PathPredicate(PATH_SEP.join(['outer', 'z'])) values = pred(context, source) self.assertEqual([PathValue(PATH_SEP.join(['outer[0]', 'z']), 'Z')], values.path_values) self.assertEqual([ MissingPathError(_NUMBER_DICT, 'z', path_value=PathValue('outer[1]', _NUMBER_DICT)) ], values.path_failures) pred = PathPredicate(PATH_SEP.join(['outer', 'three'])) values = pred(context, source) self.assertEqual([PathValue(PATH_SEP.join(['outer[1]', 'three']), 3)], values.path_values) self.assertEqual([ MissingPathError(_LETTER_DICT, 'three', path_value=PathValue('outer[0]', _LETTER_DICT)) ], values.path_failures)
def test_inspect_not_found_ok(self): context = ExecutionContext() response = Mock() response.status = 404 response.reason = 'Not Found' default_variables = {'project': 'PROJECT'} service = MyFakeGcpService([HttpError(response, 'Not Found')]) agent = TestGcpAgent.make_test_agent( service=service, default_variables=default_variables) contract_builder = gt.GcpContractBuilder(agent) c1 = contract_builder.new_clause_builder('TITLE') verifier = c1.inspect_resource( 'regions', resource_id='us-central1-f', no_resource_ok=True) verifier.contains_path_value('field', 'value') self.assertTrue(isinstance(verifier, jc.ValueObservationVerifierBuilder)) contract = contract_builder.build() verification_result = contract.verify(context) self.assertTrue(verification_result, JsonSnapshotHelper.ValueToEncodedJson(verification_result)) self.assertEquals({'project': 'PROJECT', 'region': 'us-central1-f'}, agent.service.last_get_args)
def test_string_specific_operator_type_mismatch(self): context = ExecutionContext() operand = 'valid string operand.' for value in [['value'], {'a': 'A'}, 1]: for factory in [jp.STR_SUBSTR]: self.simple_operand_type_mismatch_helper( context, basestring, factory, operand, value)
def test_bad(self): context = ExecutionContext() source = [{ 'metric': 'A', 'limit': 100.0, 'usage': 0.0 }, { 'metric': 'B', 'limit': 100.0, 'usage': 90.0 }, { 'metric': 'C', 'limit': 100.0, 'usage': 100.0 }] require = {'A': 95.0, 'B': 15.0} pred = QuotaPredicate(require) builder = KeyedPredicateResultBuilder(pred) builder.add_result( 'A', make_quota_result(context, True, source, require, 'A')) builder.add_result( 'B', make_quota_result(context, False, source, require, 'B')) builder.comment = 'Insufficient C.' result = pred(context, source) self.assertFalse(result)
def __elem_exists(self, agent, resource_type, elem, aggregated): """Determine if a pending delete on an instance has completed or not.""" context = ExecutionContext() params = {} if aggregated: name = elem[1] param_name, param_value = elem[0].split('/', 1) if param_name[-1] == 's': param_name = param_name[:-1] # Just because the aggregation returned a parameter # does not mean the get API takes it. Confirm before adding. if (agent.resource_type_to_discovery_info(resource_type).get( 'methods', {}).get('get', {}).get('parameters', {}).get(param_name)): params[param_name] = param_value name = elem[1] if aggregated else elem try: agent.get_resource(context, resource_type, resource_id=name, **params) return True except HttpError as http_error: if http_error.resp.status == HTTPStatus.NOT_FOUND: return False if http_error.resp.status in self.__RETRYABLE_DELETE_HTTP_CODES: return True print('Unexpected error while waiting for delete: {0} {1}={2}'. format(resource_type, name, http_error)) return False
def test_contract_bad(self): context = ExecutionContext() source = [{ 'metric': 'A', 'limit': 100.0, 'usage': 0.0 }, { 'metric': 'B', 'limit': 100.0, 'usage': 90.0 }, { 'metric': 'C', 'limit': 100.0, 'usage': 100.0 }] mock_service = self.make_mock_service(source, source) observer = GcpAgent(service=mock_service, discovery_doc=MOCK_DISCOVERY, default_variables={'project': 'PROJECT'}) project_quota = {'A': 95.0, 'B': 10.0} regions = [('region1', project_quota), ('region2', {'C': 1.0})] contract = make_quota_contract(observer, project_quota, regions) result = contract.verify(context) self.assertFalse(result) self.assertEqual(3, len(result.clause_results)) self.assertTrue(result.clause_results[0]) self.assertTrue(result.clause_results[1]) self.assertFalse(result.clause_results[2])
def mixed_exclude_helper(self, strict): context = ExecutionContext() observation = jc.Observation() observation.add_object('A') observation.add_object('B') observation.add_object('C') fake_observer = FakeObserver(observation) # We dont expect to see B in the list. # This can be interpreted two ways -- strictly or not strictly. # Strictly means no results should ever contain B. # Non strict means some result should not contain B. builder = jc.ValueObservationVerifierBuilder('Test Excludes', strict=strict) builder.excludes_path_value(None, 'B') clause = jc.ContractClause('TestClause', fake_observer, builder.build()) contract = jc.Contract() contract.add_clause(clause) # Doesnt matter whether strict or not since this is checking cardinality # over the entire list via the excludes clause. expect_result = jc.contract.ContractVerifyResult( False, [clause.verify(context)]) result = contract.verify(context) self.assertEqual(expect_result, result) self.assertEqual(False, result.valid)
def test_good(self): context = ExecutionContext() source = [{ 'metric': 'A', 'limit': 100.0, 'usage': 0.0 }, { 'metric': 'B', 'limit': 100.0, 'usage': 90.0 }, { 'metric': 'C', 'limit': 100.0, 'usage': 100.0 }] require = {'A': 95.0, 'B': 10.0} pred = QuotaPredicate(require) builder = KeyedPredicateResultBuilder(pred) builder.add_result( 'A', make_quota_result(context, True, source, require, 'A')) builder.add_result( 'B', make_quota_result(context, True, source, require, 'B')) builder.comment = 'Satisfied all 2 metrics.' result = pred(context, source) self.assertTrue(result) self.assertEqual(result, builder.build(True))
def test_condition_else_success(self): context = ExecutionContext(a='A', b='B', c='C') aA = jp.PathEqPredicate('a', lambda x: x['a']) bB = jp.PathEqPredicate('b', lambda x: x['b']) cC = jp.PathEqPredicate('c', lambda x: x['c']) ifAthenBelseC = jc.IF(aA, bB, cC) # True if all conditions are true. # True if "if" satisfied and "then" matches. # True if only else condition is true. test_cases = [_LETTER_DICT, {'a':'A', 'b':'B', 'c':'X'}, {'a':'X', 'b':'B', 'c':'C'}, {'a':'X', 'b':'X', 'c':'C'}, ] for i in range(3): test = test_cases[i] tried = [aA(context, test)] if i < 2: # First two have true IF to just execute THEN tried.append(bB(context, test)) else: # Remainder have false IF to just execute ELSE tried.append(cC(context, test)) expect = jc.CompositePredicateResult( valid=True, pred=ifAthenBelseC, results=tried) result = ifAthenBelseC(context, test) self.assertTrue(result) self.assertEqual(expect, result)
def test_standard_string_operator_type_mismatch(self): context = ExecutionContext() for value in [['value'], {'a':'A'}, 1]: for factory in [jp.STR_EQ, jp.STR_NE]: self.standard_operand_type_mismatch_helper( context, basestring, factory, good_operand='test value', bad_operand=value)
def test_list(self): # Return a list of two objects -- a dictionary and an array. context = ExecutionContext() default_response = st.CliResponseType(0, '[{"field":"value"}, [1,2,3]]', '') gcloud = fake_gcloud_agent.FakeGCloudAgent( 'PROJECT', 'ZONE', default_response=default_response) contract_builder = gt.GCloudContractBuilder(gcloud) c1 = contract_builder.new_clause_builder('TITLE') extra_args = ['arg1', 'arg2', 'arg3'] verifier = c1.list_resources('instances', extra_args=extra_args) verifier.contains_path_value('field', 'value') self.assertTrue( isinstance(verifier, jc.ValueObservationVerifierBuilder)) # When we build and run the contract, it is going to call the observer. # The clause has no constraints so it will succeed. We do this so that # we can verify the contract will call the clause which in turn will # call the agent with the expected parameters we test for below. contract = contract_builder.build() self.assertTrue(contract.verify(context)) command = gcloud.build_gcloud_command_args('instances', ['list'] + extra_args, project='PROJECT') self.assertEquals(command, gcloud.last_run_params)
def test_standard_dict_operator_type_mismatch(self): context = ExecutionContext() operand = {'a': 'A'} for value in [['a'], 'a', 1]: for factory in [jp.DICT_EQ, jp.DICT_NE]: self.standard_operand_type_mismatch_helper( context, dict, factory, good_operand=operand, bad_operand=value)