def test_list_equivalent(self): context = ExecutionContext() source = [{'a':'A', 'b':'B'}, {'one':1, 'two':2}] pred = jp.EQUIVALENT([source[1], source[0]]) result = pred(context, source) self.assertEqual( jp.PathValueResult(valid=True, source=source, target_path='', path_value=PathValue('', source), pred=jp.LIST_SIMILAR(pred.operand)), result)
def test_list_equivalent_indirect(self): context = ExecutionContext(testB='B', second={'one':1, 'two':2}) source = [{'a':'A', 'b': lambda x: x['testB']}, lambda x: x['second']] actual_source = [{'a':'A', 'b':'B'}, {'one':1, 'two':2}] pred = jp.EQUIVALENT(source) result = pred(context, actual_source) self.assertEqual( jp.PathValueResult(valid=True, source=actual_source, target_path='', path_value=PathValue('', actual_source), pred=jp.LIST_SIMILAR(actual_source)), result)
def upsert_load_balancer(self, use_vpc): """Creates OperationContract for upsertLoadBalancer. Calls Spinnaker's upsertLoadBalancer with a configuration, then verifies that the expected resources and configurations are visible on AWS. See the contract builder for more info on what the expectations are. Args: use_vpc: [bool] if True configure a VPC otherwise dont. """ bindings = self.bindings context = citest.base.ExecutionContext() # We're assuming that the given region has 'A' and 'B' availability # zones. This seems conservative but might be brittle since we permit # any region. region = bindings['TEST_AWS_REGION'] avail_zones = [region + 'a', region + 'b'] load_balancer_name = self.lb_name if use_vpc: # TODO(ewiseblatt): 20160301 # We're hardcoding the VPC here, but not sure which we really want. # I think this comes from the spinnaker.io installation instructions. # What's interesting about this is that it is a 10.* CidrBlock, # as opposed to the others, which are public IPs. All this is sensitive # as to where the TEST_AWS_VPC_ID came from so this is going to be # brittle. Ideally we only need to know the vpc_id and can figure the # rest out based on what we have available. subnet_type = 'internal (defaultvpc)' vpc_id = bindings['TEST_AWS_VPC_ID'] # Not really sure how to determine this value in general. security_groups = ['default'] # The resulting load balancer will only be available in the zone of # the subnet we are using. We'll figure that out by looking up the # subnet we want. subnet_details = self.aws_observer.get_resource_list( context, root_key='Subnets', aws_command='describe-subnets', aws_module='ec2', args=[ '--filters', 'Name=vpc-id,Values={vpc_id}' ',Name=tag:Name,Values=defaultvpc.internal.{region}'. format(vpc_id=vpc_id, region=region) ]) try: expect_avail_zones = [subnet_details[0]['AvailabilityZone']] except KeyError: raise ValueError( 'vpc_id={0} appears to be unknown'.format(vpc_id)) else: subnet_type = "" vpc_id = None security_groups = None expect_avail_zones = avail_zones # This will be a second load balancer not used in other tests. # Decorate the name so as not to confuse it. load_balancer_name += '-pub' listener = {'Listener': {'InstancePort': 80, 'LoadBalancerPort': 80}} health_check = { 'HealthyThreshold': 8, 'UnhealthyThreshold': 3, 'Interval': 12, 'Timeout': 6, 'Target': 'HTTP:%d/' % listener['Listener']['InstancePort'] } payload = self.agent.make_json_payload_from_kwargs( job=[{ 'type': 'upsertLoadBalancer', 'cloudProvider': 'aws', # 'loadBalancerName': load_balancer_name, 'credentials': bindings['SPINNAKER_AWS_ACCOUNT'], 'name': load_balancer_name, 'stack': bindings['TEST_STACK'], 'detail': self.lb_detail, 'region': bindings['TEST_AWS_REGION'], 'availabilityZones': { region: avail_zones }, 'regionZones': avail_zones, 'listeners': [{ 'internalProtocol': 'HTTP', 'internalPort': listener['Listener']['InstancePort'], 'externalProtocol': 'HTTP', 'externalPort': listener['Listener']['LoadBalancerPort'] }], 'healthCheck': health_check['Target'], 'healthCheckProtocol': 'HTTP', 'healthCheckPort': listener['Listener']['LoadBalancerPort'], 'healthCheckPath': '/', 'healthTimeout': health_check['Timeout'], 'healthInterval': health_check['Interval'], 'healthyThreshold': health_check['HealthyThreshold'], 'unhealthyThreshold': health_check['UnhealthyThreshold'], 'user': '******', 'usePreferredZones': True, 'vpcId': vpc_id, 'subnetType': subnet_type, # If I set security group to this then I get an error it is missing. # bindings['TEST_AWS_SECURITY_GROUP_ID']], 'securityGroups': security_groups }], description='Create Load Balancer: ' + load_balancer_name, application=self.TEST_APP) builder = aws.AwsContractBuilder(self.aws_observer) (builder.new_clause_builder( 'Load Balancer Added', retryable_for_secs=10).collect_resources( aws_module='elb', command='describe-load-balancers', args=[ '--load-balancer-names', load_balancer_name ]).contains_path_match( 'LoadBalancerDescriptions', { 'HealthCheck': jp.DICT_MATCHES({ key: jp.EQUIVALENT(value) for key, value in health_check.items() }), 'AvailabilityZones': jp.LIST_SIMILAR(expect_avail_zones), 'ListenerDescriptions/Listener': jp.DICT_MATCHES({ key: jp.NUM_EQ(value) for key, value in listener['Listener'].items() }) })) title_decorator = '_with_vpc' if use_vpc else '_without_vpc' return st.OperationContract(self.new_post_operation( title='upsert_load_balancer' + title_decorator, data=payload, path='tasks'), contract=builder.build())
def upsert_load_balancer(self): """Creates OperationContract for upsertLoadBalancer. Calls Spinnaker's upsertLoadBalancer with a configuration, then verifies that the expected resources and configurations are visible on AWS. See the contract builder for more info on what the expectations are. """ detail_raw_name = 'katotestlb' + self.test_id self.__use_lb_name = detail_raw_name bindings = self.bindings region = bindings['TEST_AWS_REGION'] avail_zones = [region + 'a', region + 'b'] listener = { 'Listener': { 'InstancePort':7001, 'LoadBalancerPort':80 } } health_check = { 'HealthyThreshold':8, 'UnhealthyThreshold':3, 'Interval':123, 'Timeout':12, 'Target':'HTTP:%d/healthcheck' % listener['Listener']['InstancePort'] } payload = self.agent.type_to_payload( 'upsertAmazonLoadBalancerDescription', { 'credentials': bindings['SPINNAKER_AWS_ACCOUNT'], 'clusterName': bindings['TEST_APP'], 'name': detail_raw_name, 'availabilityZones': {region: avail_zones}, 'listeners': [{ 'internalProtocol': 'HTTP', 'internalPort': listener['Listener']['InstancePort'], 'externalProtocol': 'HTTP', 'externalPort': listener['Listener']['LoadBalancerPort'] }], 'healthCheck': health_check['Target'], 'healthTimeout': health_check['Timeout'], 'healthInterval': health_check['Interval'], 'healthyThreshold': health_check['HealthyThreshold'], 'unhealthyThreshold': health_check['UnhealthyThreshold'] }) builder = aws.AwsContractBuilder(self.aws_observer) (builder.new_clause_builder('Load Balancer Added', retryable_for_secs=30) .collect_resources( aws_module='elb', command='describe-load-balancers', args=['--load-balancer-names', self.__use_lb_name]) .contains_pred_list([ jp.PathContainsPredicate( 'LoadBalancerDescriptions/HealthCheck', health_check), jp.PathPredicate( 'LoadBalancerDescriptions/AvailabilityZones{0}'.format( jp.DONT_ENUMERATE_TERMINAL), jp.LIST_SIMILAR(avail_zones)), jp.PathElementsContainPredicate( 'LoadBalancerDescriptions/ListenerDescriptions', listener) ]) ) return st.OperationContract( self.new_post_operation( title='upsert_amazon_load_balancer', data=payload, path='ops'), contract=builder.build())