def test_clause_failure(self): context = ExecutionContext() observation = jc.Observation() observation.add_object('B') fake_observer = FakeObserver(observation) eq_A = jp.STR_EQ('A') verifier = jc.ValueObservationVerifier('Has A', constraints=[eq_A]) clause = jc.ContractClause('TestClause', fake_observer, verifier) expect_result = jc.contract.ContractClauseVerifyResult( False, clause, verifier(context, observation)) result = clause.verify(context) self.assertEqual(expect_result, result) self.assertFalse(result)
def test_map_predicate_good_and_bad_min_indirect(self): context = ExecutionContext(min=2) aA = jp.PathPredicate('a', jp.STR_EQ('A')) expect_result = jp.MapPredicateResult( valid=False, pred=aA, obj_list=[_NUMBER_DICT, _LETTER_DICT], all_results=[aA(context, _NUMBER_DICT), aA(context, _LETTER_DICT)], good_map=[jp.ObjectResultMapAttempt(_LETTER_DICT, aA(context, _LETTER_DICT))], bad_map=[jp.ObjectResultMapAttempt(_NUMBER_DICT, aA(context, _NUMBER_DICT))]) self._try_map( context, aA, [_NUMBER_DICT, _LETTER_DICT], False, expect_result, min=lambda x: x['min'])
def check_clusters_endpoint(self, kind): name = kind + " " + self.TEST_APP + "-" + kind account = self.bindings["SPINNAKER_KUBERNETES_V2_ACCOUNT"] builder = HttpContractBuilder(self.agent) (builder.new_clause_builder( "Has recorded a cluster for the deployed manifest", retryable_for_secs=120, ).get_url_path("/applications/{}/clusters".format( self.TEST_APP)).EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ account: jp.LIST_MATCHES([jp.STR_EQ(name)]), })))) return st.OperationContract(NoOpOperation("Has recorded a cluster"), contract=builder.build())
def test_clause_failure(self): context = ExecutionContext() observation = jc.Observation() observation.add_object('B') fake_observer = FakeObserver(observation) eq_A = jp.LIST_MATCHES([jp.STR_EQ('A')]) verifier = jc.ValueObservationVerifierBuilder('Has A').EXPECT( eq_A).build() clause = jc.ContractClause('TestClause', fake_observer, verifier) expect_result = jc.contract.ContractClauseVerifyResult( False, clause, verifier(context, observation)) result = clause.verify(context) self.assertEqual(expect_result, result) self.assertFalse(result)
def test_object_filter_cases(self): context = ExecutionContext() aA = jp.PathPredicate('a', jp.STR_EQ('A')) self._try_map(context, aA, _LETTER_DICT, True) self._try_map(context, aA, _COMPOSITE_DICT, False) self._try_map(context, aA, _NUMBER_DICT, False) self._try_map(context, aA, _MULTI_ARRAY, True) self._try_map(context, aA, [_COMPOSITE_DICT, _COMPOSITE_DICT], False) self._try_map(context, aA, _MIXED_DICT, True) AandB = jp.AND([PathEqPredicate('a', 'A'), PathEqPredicate('b', 'B')]) self._try_map(context, AandB, _LETTER_DICT, True) self._try_map(context, AandB, _COMPOSITE_DICT, False) self._try_map(context, AandB, _NUMBER_DICT, False) self._try_map(context, AandB, _MULTI_ARRAY, True) self._try_map(context, AandB, _MIXED_DICT, False)
def test_dict_nested_subset_exact_values(self): context = ExecutionContext() small = {'first':'Apple', 'second':'Banana'} small_nested = {'outer':small} # In dictionary we want exact matches of strings, not substrings. nested_operand = {'first':'A'} operand = {'outer':nested_operand} subset_pred = jp.DICT_SUBSET(operand) self.assertEqual( jp.PathValueResult( valid=False, pred=jp.STR_EQ('A'), path_value=PathValue(jp.PATH_SEP.join(['outer', 'first']), 'Apple'), source=small_nested, target_path=jp.PATH_SEP.join(['outer', 'first'])), subset_pred(context, small_nested))
def test_map_predicate_good_and_bad_min_1(self): context = ExecutionContext() aA = jp.PathPredicate('a', jp.STR_EQ('A')) aa_number_attempt = jp.ObjectResultMapAttempt(_NUMBER_DICT, aA(context, _NUMBER_DICT)) aa_letter_attempt = jp.ObjectResultMapAttempt(_LETTER_DICT, aA(context, _LETTER_DICT)) expect_result = jp.MapPredicateResult( valid=True, pred=aA, obj_list=[_NUMBER_DICT, _LETTER_DICT], all_results=[aa_number_attempt.result, aa_letter_attempt.result], good_map=[aa_letter_attempt], bad_map=[aa_number_attempt]) self._try_map(context, aA, [_NUMBER_DICT, _LETTER_DICT], True, expect_result)
def deployment_image_predicate(self, image): return ov_factory.value_list_contains( jp.DICT_MATCHES({ 'spec': jp.DICT_MATCHES({ 'template': jp.DICT_MATCHES({ 'spec': jp.DICT_MATCHES({ 'containers': jp.LIST_MATCHES( [jp.DICT_MATCHES({'image': jp.STR_EQ(image)})]) }) }) }), 'status': jp.DICT_MATCHES({'availableReplicas': jp.NUM_GE(1)}) }))
def test_result_builder_add_bad_result(self): observation = jc.Observation() observation.add_object('A') pred = jp.PathPredicate(None, jp.STR_EQ('B')) builder = jc.ObservationVerifyResultBuilder(observation) map_pred = jp.MapPredicate(pred) map_result = map_pred(observation.objects) builder.add_map_result(map_result) verify_results = builder.build(False) self.assertFalse(verify_results) self.assertEqual(observation, verify_results.observation) self.assertEqual([], verify_results.good_results) self.assertEqual([pred], verify_results.failed_constraints) self.assertEqual(map_result.bad_object_result_mappings, verify_results.bad_results)
def test_contract_failure(self): observation = jc.Observation() observation.add_object('B') fake_observer = FakeObserver(observation) eq_A = jp.STR_EQ('A') verifier = jc.ValueObservationVerifier('Has A', constraints=[eq_A]) clause = jc.ContractClause('TestClause', fake_observer, verifier) contract = jc.Contract() contract.add_clause(clause) expect_result = jc.contract.ContractVerifyResult( False, [clause.verify()]) result = contract.verify() self.assertEqual(expect_result, result) self.assertFalse(result)
def create_server_group(self): group_name = frigga.Naming.server_group( app=self.TEST_APP, stack=self.bindings['TEST_STACK'], version='v000') job_spec = { 'application': self.TEST_APP, 'stack': self.TEST_STACK, 'credentials': self.bindings['SPINNAKER_APPENGINE_ACCOUNT'], 'repositoryUrl': self.__test_repository_url, 'applicationDirectoryRoot': self.__app_directory_root, 'configFiles': [self.__app_yaml], 'type': 'createServerGroup', 'cloudProvider': 'appengine', 'region': 'us-central' } storageAccountName = self.bindings.get('TEST_STORAGE_ACCOUNT_NAME') if storageAccountName is not None: job_spec['storageAccountName'] = storageAccountName if not self.__test_repository_url.startswith('gs://'): job_spec.update({ 'gitCredentialType': 'NONE', 'branch': self.__branch }) payload = self.agent.make_json_payload_from_kwargs( job=[job_spec], description='Create Server Group in ' + group_name, application=self.TEST_APP) builder = gcp.GcpContractBuilder(self.appengine_observer) (builder.new_clause_builder( 'Version Added', retryable_for_secs=30).inspect_resource( 'apps.services.versions', group_name, appsId=self.__gcp_project, servicesId=self.__lb_name).EXPECT( ov_factory.value_list_path_contains( 'servingStatus', jp.STR_EQ('SERVING')))) return st.OperationContract(self.new_post_operation( title='create_server_group', data=payload, path='tasks'), contract=builder.build())
def check_manifest_endpoint_exists(self, kind): name = self.TEST_APP + '-' + kind account = self.bindings['SPINNAKER_KUBERNETES_V2_ACCOUNT'] builder = HttpContractBuilder(self.agent) (builder.new_clause_builder('Has recorded a manifest') .get_url_path('/manifests/{account}/{namespace}/{name}'.format( account=account, namespace=self.TEST_NAMESPACE, name='{}%20{}'.format(kind, name) )) .EXPECT( ov_factory.value_list_contains(jp.DICT_MATCHES({ 'account': jp.STR_EQ(account) })) )) return st.OperationContract( NoOpOperation('Has recorded a manifest'), contract=builder.build())
def delete_a_security_group(self): """Creates azContract for deleteServerGroup. To verify the operation, we just check that the spinnaker security group for the given application was deleted. """ payload = self.agent.make_json_payload_from_kwargs( job = [{ "Provider": "azure", "appName": self.bindings['TEST_APP'], "region": self.bindings['TEST_AZURE_RG_LOCATION'], "regions": [self.bindings['TEST_AZURE_RG_LOCATION']], "credentials": self.bindings['SPINNAKER_AZURE_ACCOUNT'], "securityGroupName": self.TEST_SECURITY_GROUP, "cloudProvider": "azure", "type": "deleteSecurityGroup", "user": "******" }], application=self.bindings['TEST_APP'], description='Delete Security Group: : ' + self.TEST_SECURITY_GROUP) builder = az.AzContractBuilder(self.az_observer) (builder.new_clause_builder( 'Security Group Deleted', retryable_for_secs=30) .collect_resources( az_resource='network', command='nsg', args=['list', '--resource-group', self.TEST_SECURITY_GROUP_RG]) .EXPECT(ov_factory.error_list_contains( jp.ExceptionMatchesPredicate( klass=st.CliAgentRunError, regex='(?:.* operation: Cannot find .*)|(?:.*\(.*NotFound\).*)'))) .OR(ov_factory.value_list_path_excludes( 'name', jp.STR_EQ(self.TEST_SECURITY_GROUP))) ) return st.OperationContract( self.new_post_operation( title='delete_security_group', data=payload, path='applications/{app}/tasks'.format(app=self.bindings['TEST_APP'])), contract=builder.build())
def test_contract_success(self): context = ExecutionContext() observation = jc.Observation() observation.add_object('A') fake_observer = FakeObserver(observation) eq_A = jp.STR_EQ('A') verifier = jc.ValueObservationVerifier('Has A', constraints=[eq_A]) clause = jc.ContractClause('TestClause', fake_observer, verifier) contract = jc.Contract() contract.add_clause(clause) expect_result = jc.contract.ContractVerifyResult( True, [clause.verify(context)]) result = contract.verify(context) self.assertEqual(expect_result, result) self.assertTrue(result)
def trigger_deploy_pipeline(self): name = "app.tar" command = "tar -cvf {tar} {git_dir}/{app_root}/*".format( tar=name, git_dir=self.temp, app_root=self.bindings["APP_DIRECTORY_ROOT"]) logging.info( "Tar-ing %s/%s for GCS upload", self.temp, self.bindings["APP_DIRECTORY_ROOT"], ) subprocess.Popen(command, stderr=sys.stderr, shell=True).wait() group_name = frigga.Naming.server_group( app=self.TEST_APP, stack=self.bindings["TEST_STACK"], version="v000") # Triggered pipeline does a deploy, check for that server group. server_group_path = "applications/{app}/serverGroups".format( app=self.TEST_APP) builder = st.HttpContractBuilder(self.agent) (builder.new_clause_builder( "GAE Deploy Pipeline Succeeded", retryable_for_secs=300).get_url_path(server_group_path).EXPECT( ov_factory.value_list_matches( [jp.DICT_MATCHES({"name": jp.STR_EQ(group_name)})]))) executions_path = "executions?pipelineConfigIds={}".format( self.__pipeline_id) return st.OperationContract( self.__gcs_pubsub_agent.new_gcs_pubsub_trigger_operation( gate_agent=self.agent, title="monitor_gcs_pubsub_pipeline", bucket_name=self.bucket, upload_path="{}".format(name), local_filename=os.path.abspath(name), status_class=gate.GatePipelineStatus, status_path=executions_path, ), contract=builder.build(), )
def test_contract_observation_failure(self): context = ExecutionContext() observation = jc.Observation() observation.add_error( jp.PredicateResult(False, comment='Observer Failed')) fake_observer = FakeObserver(observation) eq_A = jp.STR_EQ('A') verifier = jc.ValueObservationVerifier('Has A', constraints=[eq_A]) clause = jc.ContractClause('TestClause', fake_observer, verifier) contract = jc.Contract() contract.add_clause(clause) expect_result = jc.contract.ContractVerifyResult( False, [clause.verify(context)]) result = contract.verify(context) self.assertEqual(expect_result, result) self.assertFalse(result)
def trigger_deploy_pipeline(self): name = 'app.tar' command = 'tar -cvf {tar} {git_dir}/{app_root}/*'.format( tar=name, git_dir=self.temp, app_root=self.bindings['APP_DIRECTORY_ROOT']) logging.info('Tar-ing %s/%s for GCS upload', self.temp, self.bindings['APP_DIRECTORY_ROOT']) subprocess.Popen(command, stderr=sys.stderr, shell=True).wait() group_name = frigga.Naming.server_group( app=self.TEST_APP, stack=self.bindings['TEST_STACK'], version='v000') # Triggered pipeline does a deploy, check for that server group. server_group_path = 'applications/{app}/serverGroups'.format( app=self.TEST_APP) builder = st.HttpContractBuilder(self.agent) (builder.new_clause_builder( 'GAE Deploy Pipeline Succeeded', retryable_for_secs=300).get_url_path(server_group_path).EXPECT( ov_factory.value_list_matches( [jp.DICT_MATCHES({'name': jp.STR_EQ(group_name)})]))) executions_path = 'executions?pipelineConfigIds={}&limit=1&statuses=SUCCEEDED'.format( self.__pipeline_id) return st.OperationContract( self.__gcs_pubsub_agent.new_gcs_pubsub_trigger_operation( gate_agent=self.agent, title='monitor_gcs_pubsub_pipeline', bucket_name=self.bucket, upload_path='{}'.format(name), local_filename=os.path.abspath(name), status_class=None, status_path=executions_path), contract=builder.build())
def test_indirect_string(self): context = ExecutionContext(TEST='abc') eq_abc = jp.STR_EQ(lambda x: x['TEST']) self.assertGood('abc', eq_abc, context=context) self.assertBad('abcd', eq_abc, context=context)
# See the License for the specific language governing permissions and # limitations under the License. # pylint: disable=missing-docstring # pylint: disable=redefined-builtin import unittest from citest.base import (ExecutionContext, JsonSnapshotHelper) from citest.json_predicate import PathValue import citest.json_predicate as jp _CAB = ['C', 'A', 'B'] # pylint: disable=invalid-name _eq_A = jp.STR_EQ('A') _eq_B = jp.STR_EQ('B') _eq_X = jp.STR_EQ('X') _AorX = jp.OR([_eq_A, _eq_X]) _AorB = jp.OR([_eq_A, _eq_B]) class CardinalityPredicateTest(unittest.TestCase): def assertEqual(self, expect, have, msg=''): try: JsonSnapshotHelper.AssertExpectedValue(expect, have, msg) except AssertionError: print '\nEXPECT\n{0!r}\n\nGOT\n{1!r}\n'.format(expect, have) raise def test_cardinality_bounds_1(self):
def _add_contract_clauses(self, contract_builder, upsert): '''Add the proper predicates to the contract builder for a given upsert description. ''' host_rules = upsert['hostRules'] # Host rules will be distinct. backend_services = [upsert['defaultService']] for host_rule in host_rules: path_matcher = host_rule['pathMatcher'] backend_services.append(path_matcher['defaultService']) for path_rule in path_matcher['pathRules']: backend_services.append(path_rule['backendService']) health_checks = [ service['healthCheck'] for service in backend_services ] hc_clause_builder = (contract_builder.new_clause_builder( 'Health Checks Created', retryable_for_secs=30).list_resource('httpHealthChecks')) for hc in health_checks: hc_clause_builder.contains_match({ 'name': jp.STR_EQ(hc['name']), 'requestPath': jp.STR_EQ(hc['requestPath']), 'port': jp.NUM_EQ(hc['port']) }) bs_clause_builder = (contract_builder.new_clause_builder( 'Backend Services Created', retryable_for_secs=30).list_resource('backendServices')) for bs in backend_services: bs_clause_builder.contains_match({ 'name': jp.STR_EQ(bs['name']), 'portName': jp.STR_EQ('http'), 'healthChecks': jp.LIST_MATCHES( [jp.STR_EQ(self._get_hc_link(bs['healthCheck']['name']))]) }) url_map_clause_builder = (contract_builder.new_clause_builder( 'Url Map Created', retryable_for_secs=30).list_resource('urlMaps')) for hr in host_rules: pm = hr['pathMatcher'] path_rules_spec = [ jp.DICT_MATCHES({ 'service': jp.STR_EQ(self._get_bs_link(pr['backendService']['name'])), 'paths': jp.LIST_MATCHES([jp.STR_EQ(path) for path in pr['paths']]) }) for pr in pm['pathRules'] ] path_matchers_spec = { 'defaultService': jp.STR_EQ(self._get_bs_link(pm['defaultService']['name'])), 'pathRules': jp.LIST_MATCHES(path_rules_spec) } url_map_clause_builder.contains_match({ 'name': jp.STR_EQ(self.__lb_name), 'defaultService': jp.STR_EQ(self._get_bs_link(upsert['defaultService']['name'])), 'hostRules/hosts': jp.LIST_MATCHES( [jp.STR_SUBSTR(host) for host in hr['hostPatterns']]), 'pathMatchers': jp.LIST_MATCHES([jp.DICT_MATCHES(path_matchers_spec)]), }) port_string = '443-443' if upsert['certificate'] == '': port_string = '%s-%s' % (upsert['portRange'], upsert['portRange']) (contract_builder.new_clause_builder( 'Forwarding Rule Created', retryable_for_secs=30).list_resource( 'globalForwardingRules').contains_match({ 'name': jp.STR_EQ(self.__lb_name), 'portRange': jp.STR_EQ(port_string) })) proxy_clause_builder = contract_builder.new_clause_builder( 'Target Proxy Created', retryable_for_secs=30) self._add_proxy_clause(upsert['certificate'], proxy_clause_builder)
def test_string_eq(self): eq_abc = jp.STR_EQ('abc') self.assertGood('abc', eq_abc) self.assertBad('abcd', eq_abc)
def test_indirect_string(self): context = ExecutionContext(TEST='abc') eq_abc = jp.STR_EQ(lambda x: x['TEST']) self.assertGoodResult(PathValue('', 'abc'), eq_abc, eq_abc(context, 'abc')) self.assertBadResult(PathValue('', 'abcd'), eq_abc, eq_abc(context, 'abcd'))
def create_http_load_balancer(self): logical_http_lb_name = 'katotest-httplb-' + self.test_id self.__use_http_lb_name = logical_http_lb_name # TODO(ewiseblatt): 20150530 # This needs to be abbreviated to hc. self.__use_http_lb_hc_name = logical_http_lb_name + '-health-check' # TODO(ewiseblatt): 20150530 # This needs to be abbreviated to bs. self.__use_http_lb_bs_name = logical_http_lb_name + '-backend-service' self.__use_http_lb_fr_name = logical_http_lb_name # TODO(ewiseblatt): 20150530 # This should be abbreviated (um?). self.__use_http_lb_map_name = logical_http_lb_name + '-url-map' # TODO(ewiseblatt): 20150530 # This should be abbreviated (px)?. self.__use_http_lb_proxy_name = logical_http_lb_name + '-target-http-proxy' interval = 231 healthy = 8 unhealthy = 9 timeout = 65 path = '/hello/world' # TODO(ewiseblatt): 20150530 # This field might be broken. 123-456 still resolves to 80-80 # Changing it for now so the test passes. port_range = "80-80" # TODO(ewiseblatt): 20150530 # Specify explicit backends? health_check = { 'checkIntervalSec': interval, 'healthyThreshold': healthy, 'unhealthyThreshold': unhealthy, 'timeoutSec': timeout, 'requestPath': path } # pylint: disable=bad-continuation payload = self.agent.type_to_payload( 'createGoogleHttpLoadBalancerDescription', { 'healthCheck': health_check, 'portRange': port_range, 'loadBalancerName': logical_http_lb_name, 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'] }) hc_dict = dict(health_check) del hc_dict['requestPath'] hc_match = {name: jp.NUM_EQ(value) for name, value in health_check.items()} hc_match['requestPath'] = jp.STR_EQ(path) hc_match['name'] = jp.STR_SUBSTR(self.__use_http_lb_hc_name), builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder('Http Health Check Added') .list_resource('httpHealthChecks') .contains_match(hc_match)) (builder.new_clause_builder('Global Forwarding Rule Added', retryable_for_secs=15) .list_resource('globalForwardingRules') .contains_match({ 'name': jp.STR_SUBSTR(self.__use_http_lb_fr_name), 'portRante': jp.STR_EQ(port_range)})) (builder.new_clause_builder('Backend Service Added') .list_resource('backendServices') .contains_match({ 'name': jp.STR_SUBSTR(self.__use_http_lb_bs_name), 'healthChecks': jp.STR_SUBSTR(self.__use_http_lb_hc_name)})) (builder.new_clause_builder('Url Map Added') .list_resource('urlMaps') .contains_match({ 'name': jp.STR_SUBSTR(self.__use_http_lb_map_name), 'defaultService': jp.STR_SUBSTR(self.__use_http_lb_bs_name)})) (builder.new_clause_builder('Target Http Proxy Added') .list_resource('targetHttpProxies') .contains_match({ 'name': jp.STR_SUBSTR(self.__use_http_lb_proxy_name), 'urlMap': jp.STR_SUBSTR(self.__use_http_lb_map_name)})) return st.OperationContract( self.new_post_operation( title='create_http_load_balancer', data=payload, path='ops'), contract=builder.build())
def create_http_load_balancer(self): logical_http_lb_name = "katotest-httplb-" + self.test_id self.__use_http_lb_name = logical_http_lb_name self.__use_http_lb_hc_name = logical_http_lb_name + "-health-check" self.__use_http_lb_bs_name = logical_http_lb_name + "-backend-service" self.__use_http_lb_fr_name = logical_http_lb_name self.__use_http_lb_map_name = logical_http_lb_name + "-url-map" self.__use_http_lb_proxy_name = logical_http_lb_name + "-target-http-proxy" interval = 231 healthy = 8 unhealthy = 9 timeout = 65 path = "/hello/world" port_range = "123-456" health_check = { "checkIntervalSec": interval, "healthyThreshold": healthy, "unhealthyThreshold": unhealthy, "timeoutSec": timeout, "requestPath": path, } # pylint: disable=bad-continuation payload = self.agent.type_to_payload( "createGoogleHttpLoadBalancerDescription", { "healthCheck": health_check, "portRange": port_range, "loadBalancerName": logical_http_lb_name, "credentials": self.bindings["SPINNAKER_GOOGLE_ACCOUNT"], }, ) hc_dict = dict(health_check) del hc_dict["requestPath"] hc_match = { name: jp.NUM_EQ(value) for name, value in health_check.items() } hc_match["requestPath"] = jp.STR_EQ(path) hc_match["name"] = (jp.STR_SUBSTR(self.__use_http_lb_hc_name), ) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder("Http Health Check Added").list_resource( "httpHealthChecks").EXPECT( ov_factory.value_list_contains(jp.DICT_MATCHES(hc_match)))) (builder.new_clause_builder( "Global Forwarding Rule Added", retryable_for_secs=15).list_resource( "globalForwardingRules").EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ "name": jp.STR_SUBSTR(self.__use_http_lb_fr_name), "portRange": jp.STR_EQ(port_range), })))) (builder.new_clause_builder("Backend Service Added").list_resource( "backendServices").EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ "name": jp.STR_SUBSTR(self.__use_http_lb_bs_name), "healthChecks": jp.STR_SUBSTR(self.__use_http_lb_hc_name), })))) (builder.new_clause_builder("Url Map Added").list_resource( "urlMaps").EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ "name": jp.STR_SUBSTR(self.__use_http_lb_map_name), "defaultService": jp.STR_SUBSTR(self.__use_http_lb_bs_name), })))) (builder.new_clause_builder("Target Http Proxy Added").list_resource( "targetHttpProxies").EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ "name": jp.STR_SUBSTR(self.__use_http_lb_proxy_name), "urlMap": jp.STR_SUBSTR(self.__use_http_lb_map_name), })))) return st.OperationContract( self.new_post_operation(title="create_http_load_balancer", data=payload, path="ops"), contract=builder.build(), )
def test_string_eq(self): context = ExecutionContext() eq_abc = jp.STR_EQ('abc') self.assertGoodResult(PathValue('', 'abc'), eq_abc, eq_abc(context, 'abc')) self.assertBadResult(PathValue('', 'abcd'), eq_abc, eq_abc(context, 'abcd'))
def upsert_load_balancer(self): self.__use_lb_name = "katotest-lb-" + self.test_id self.__use_lb_hc_name = "%s-hc" % self.__use_lb_name self.__use_lb_tp_name = "%s-tp" % self.__use_lb_name self.__use_lb_target = "{0}/targetPools/{1}".format( self.bindings["TEST_GCE_REGION"], self.__use_lb_tp_name) interval = 123 healthy = 4 unhealthy = 5 timeout = 78 path = "/" + self.__use_lb_target health_check = { "checkIntervalSec": interval, "healthyThreshold": healthy, "unhealthyThreshold": unhealthy, "timeoutSec": timeout, "requestPath": path, } # pylint: disable=bad-continuation payload = self.agent.type_to_payload( "upsertGoogleLoadBalancerDescription", { "healthCheck": health_check, "region": self.bindings["TEST_GCE_REGION"], "credentials": self.bindings["SPINNAKER_GOOGLE_ACCOUNT"], "loadBalancerName": self.__use_lb_name, }, ) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( "Forwarding Rules Added", retryable_for_secs=30).list_resource("forwardingRules").EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ "name": jp.STR_SUBSTR(self.__use_lb_name), "target": jp.STR_SUBSTR(self.__use_lb_target), })))) (builder.new_clause_builder( "Target Pool Added", retryable_for_secs=15).list_resource("targetPools").EXPECT( ov_factory.value_list_path_contains( "name", jp.STR_SUBSTR(self.__use_lb_tp_name)))) # We list the resources here because the name isnt exact # and the list also returns the details we need. hc_dict = dict(health_check) del hc_dict["requestPath"] hc_match = {name: jp.NUM_EQ(value) for name, value in hc_dict.items()} hc_match["requestPath"] = jp.STR_EQ(path) hc_match["name"] = jp.STR_SUBSTR(self.__use_http_lb_hc_name) (builder.new_clause_builder( "Health Check Added", retryable_for_secs=15).list_resource("httpHealthChecks").EXPECT( ov_factory.value_list_contains(jp.DICT_MATCHES(hc_match)))) return st.OperationContract( self.new_post_operation(title="upsert_load_balancer", data=payload, path="ops"), contract=builder.build(), )
def create_application_gateway(self): """Create OperationContract that create a new Application gateway To verify the operation, we just check that the spinnaker load balancer for the given application was created. """ self.__lb_type = "Azure Application Gateway" healthyCheck = [{ "probeName": "{lb}-probe".format(lb=self.__full_lb_name), "probeProtocol": "HTTP", "probePort": "80", "probePath": "/", "probeInterval": 30, "unhealthyThreshold": 8, "timeout": 120 }] rules = [{ "ruleName": "{lb}-rule0".format(lb=self.__full_lb_name), "protocol": "HTTP", "externalPort": 80, "backendPort": 80, "probeName": "{lb}-probe".format(lb=self.__full_lb_name), "persistence": "None", "idleTimeout": 4 }] subnets = [{ "account": self.ACCOUNT, "addressPrefix": self.__subnet[0]['ADDRESS'], "device": [], "id": '/subscriptions/{id}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{name}' .format(id=self.__subscription_id, rg=self.__rg_name, vnet=self.__vnet_name, name=self.__subnet[0]['NAME']), "name": self.__subnet[0]['NAME'], "purpose": 'TBD', "region": self.__rg_location, "type": 'azure', "vnet": self.__vnet_name }, { "account": self.ACCOUNT, "addressPrefix": self.__subnet[1]['ADDRESS'], "device": [], "id": '/subscriptions/{id}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vnet}/subnets/{name}' .format(id=self.__subscription_id, rg=self.__rg_name, vnet=self.__vnet_name, name=self.__subnet[1]['NAME']), "name": self.__subnet[1]['NAME'], "purpose": 'TBD', "region": self.__rg_location, "type": 'azure', "vnet": self.__vnet_name }] vnet = { "account": self.ACCOUNT, "cloudProvider": "azure", "id": self.__vnet_name, "name": self.__vnet_name, "region": self.__rg_location, "resourceGroup": self.__rg_name, "subnets": subnets } payload = self.agent.make_json_payload_from_kwargs( job=[{ "stack": self.__stack, "detail": self.__detail, "credentials": self.ACCOUNT, "region": self.__rg_location, "cloudProvider": "azure", "vnet": self.__vnet_name, "subnet": self.__subnet[1]['NAME'], "probes": healthyCheck, "securityGroups": [], "loadBalancingRules": rules, "name": self.__full_lb_name, "selectedVnet": vnet, "vnetResourceGroup": self.__rg_name, "selectedSubnet": subnets[1], "type": "upsertLoadBalancer", "loadBalancerType": self.__lb_type, "appName": self.TEST_APP, "loadBalancerName": self.__full_lb_name, "user": "******" }], description="Test - Create application gateway: {lb}".format( lb=self.__full_lb_name), application=self.TEST_APP) builder = az.AzContractBuilder(self.az_observer) (builder.new_clause_builder( 'Application Gateway Created', retryable_for_secs=30).collect_resources( az_resource='network', command='application-gateway', args=[ 'list', '--resource-group', '{app}-{rg}'.format(app=self.TEST_APP, rg=self.__rg_location) ]).EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ 'name': jp.STR_EQ(self.__full_lb_name), 'tags': jp.DICT_MATCHES({ 'vnet': jp.STR_EQ(self.__vnet_name), 'subnet': jp.STR_EQ(self.__subnet[1]['NAME']) }) })))) return st.OperationContract(self.new_post_operation( title="create_application_gateway", data=payload, path=('applications/{app}/tasks').format(app=self.TEST_APP), max_wait_secs=3600), contract=builder.build())
def create_load_balancer(self): """Create OperationContract that create a new Load Balancer To verify the operation, we just check that the spinnaker load balancer for the given application was created. """ self.__lb_type = "Azure Load Balancer" healthyCheck = [{ "probeName": "{lb}-probe".format(lb=self.__full_lb_name), "probeProtocol": "TCP", "probePort": "80", "probeInterval": 30, "unhealthyThreshold": 8, "timeout": 120 }] rules = [{ "ruleName": "{lb}-rule0".format(lb=self.__full_lb_name), "protocol": "TCP", "externalPort": 80, "backendPort": 80, "probeName": "{lb}-probe".format(lb=self.__full_lb_name), "persistence": "None", "idleTimeout": 4 }] payload = self.agent.make_json_payload_from_kwargs( job=[{ "stack": self.__stack, "detail": self.__detail, "credentials": self.ACCOUNT, "region": self.__rg_location, "cloudProvider": "azure", "vnet": None, "subnet": None, "probes": healthyCheck, "securityGroups": [], "loadBalancingRules": rules, "name": self.__full_lb_name, "selectedVnet": None, "vnetResourceGroup": None, "selectedSubnet": None, "type": "upsertLoadBalancer", "loadBalancerType": self.__lb_type, "appName": self.TEST_APP, "loadBalancerName": self.__full_lb_name, "user": "******" }], description="Test - Create load balancer: {lb}".format( lb=self.__full_lb_name), application=self.TEST_APP) builder = az.AzContractBuilder(self.az_observer) (builder.new_clause_builder( 'Load Balancer Created', retryable_for_secs=30).collect_resources( az_resource='network', command='lb', args=[ 'list', '--resource-group', '{app}-{rg}'.format(app=self.TEST_APP, rg=self.__rg_location) ]).EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ 'name': jp.STR_EQ(self.__full_lb_name), 'location': jp.STR_EQ(self.__rg_location) })))) return st.OperationContract(self.new_post_operation( title="create_load_balancer", data=payload, path=('applications/{app}/tasks').format(app=self.TEST_APP), max_wait_secs=2400), contract=builder.build())
def config_map_key_value_predicate(self, key, value): return ov_factory.value_list_contains( jp.DICT_MATCHES({"data": jp.DICT_MATCHES({key: jp.STR_EQ(value)})}) )
def upsert_load_balancer(self): self.__use_lb_name = 'katotest-lb-' + self.test_id self.__use_lb_hc_name = '%s-hc' % self.__use_lb_name self.__use_lb_tp_name = '%s-tp' % self.__use_lb_name self.__use_lb_target = '{0}/targetPools/{1}'.format( self.bindings['TEST_GCE_REGION'], self.__use_lb_tp_name) interval = 123 healthy = 4 unhealthy = 5 timeout = 78 path = '/' + self.__use_lb_target health_check = { 'checkIntervalSec': interval, 'healthyThreshold': healthy, 'unhealthyThreshold': unhealthy, 'timeoutSec': timeout, 'requestPath': path } # pylint: disable=bad-continuation payload = self.agent.type_to_payload( 'upsertGoogleLoadBalancerDescription', { 'healthCheck': health_check, 'region': self.bindings['TEST_GCE_REGION'], 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'loadBalancerName': self.__use_lb_name }) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Forwarding Rules Added', retryable_for_secs=30).list_resource('forwardingRules').EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ 'name': jp.STR_SUBSTR(self.__use_lb_name), 'target': jp.STR_SUBSTR(self.__use_lb_target) })))) (builder.new_clause_builder( 'Target Pool Added', retryable_for_secs=15).list_resource('targetPools').EXPECT( ov_factory.value_list_path_contains( 'name', jp.STR_SUBSTR(self.__use_lb_tp_name)))) # We list the resources here because the name isnt exact # and the list also returns the details we need. hc_dict = dict(health_check) del hc_dict['requestPath'] hc_match = {name: jp.NUM_EQ(value) for name, value in hc_dict.items()} hc_match['requestPath'] = jp.STR_EQ(path) hc_match['name'] = jp.STR_SUBSTR(self.__use_http_lb_hc_name) (builder.new_clause_builder( 'Health Check Added', retryable_for_secs=15).list_resource('httpHealthChecks').EXPECT( ov_factory.value_list_contains(jp.DICT_MATCHES(hc_match)))) return st.OperationContract(self.new_post_operation( title='upsert_load_balancer', data=payload, path='ops'), contract=builder.build())