Exemple #1
0
    def test_dict_subset_with_array_values(self):
        small = {'a': ['A'], 'b': [1, 2]}
        big = {'a': ['A', 'B', 'C'], 'b': [1, 2, 3], 'c': ['red', 'yellow']}
        small_nested = {'first': small}
        big_nested = {'first': big, 'second': big}

        small_subset_pred = jp.DICT_SUBSET(small)
        nested_subset_pred = jp.DICT_SUBSET(small_nested)

        # These are matching the outer source objects because they contain
        # the subset we are looking for.
        self.assertGoodResult(PathValue('', big), small_subset_pred,
                              small_subset_pred(big))
        self.assertGoodResult(PathValue('', big_nested), nested_subset_pred,
                              nested_subset_pred(big_nested))
Exemple #2
0
  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)
Exemple #3
0
  def test_dict_subset_with_array_values_bad(self):
    context = ExecutionContext()
    small = {'a':['A'], 'b':[1, 2]}
    big = {'a':['A', 'B', 'C'], 'b':[1, 2]}
    small_nested = {'first':small}
    big_nested = {'first':big, 'second':big}

    big_subset_pred = jp.DICT_SUBSET(big)
    nested_subset_pred = jp.DICT_SUBSET(big_nested)
    list_subset_pred = jp.LIST_SUBSET(big['a'])

    self.assertBadResult(
        expect_value=PathValue('a', small['a']),
        pred=list_subset_pred,
        got_result=big_subset_pred(context, small),
        source=small, target_path='a')
Exemple #4
0
    def test_dict_nested_subset(self):
        small = {'first': 'Apple', 'second': 'Banana'}
        small_subset_pred = jp.DICT_SUBSET(small)

        big = {'first': 'Apple', 'second': 'Banana', 'third': 'Cherry'}

        self.assertGoodResult(PathValue('', big), small_subset_pred,
                              small_subset_pred(big))

        small_nested = {'outer': small}
        small_nested_subset_pred = jp.DICT_SUBSET(small_nested)

        big_nested = {'outer': big, 'another': big}
        self.assertGoodResult(PathValue('', big_nested),
                              small_nested_subset_pred,
                              small_nested_subset_pred(big_nested))
    def list_available_images(self):
        """Creates a test that confirms expected available images.

        Returns:
          st.OperationContract
        """
        logger = logging.getLogger(__name__)

        # Get the list of images available (to the service account we are using).
        context = citest.base.ExecutionContext()
        gcp_agent = self.gcp_observer
        JournalLogger.begin_context("Collecting expected available images")
        relation_context = "ERROR"
        try:
            logger.debug("Looking up available images.")

            json_doc = gcp_agent.list_resource(context, "images")
            for project in GCP_STANDARD_IMAGES.keys():
                logger.info("Looking for images from project=%s", project)
                found = gcp_agent.list_resource(context,
                                                "images",
                                                project=project)
                for image in found:
                    if not image.get("deprecated", None):
                        json_doc.append(image)

            # Produce the list of images that we expect to receive from spinnaker
            # (visible to the primary service account).
            spinnaker_account = self.bindings["SPINNAKER_GOOGLE_ACCOUNT"]

            logger.debug('Configured with Spinnaker account "%s"',
                         spinnaker_account)
            expect_images = [{
                "account": spinnaker_account,
                "imageName": image["name"]
            } for image in json_doc]
            expect_images = sorted(expect_images, key=lambda k: k["imageName"])
            relation_context = "VALID"
        finally:
            JournalLogger.end_context(relation=relation_context)

        # pylint: disable=bad-continuation
        builder = HttpContractBuilder(self.agent)
        (builder.new_clause_builder("Has Expected Images").get_url_path(
            "/gce/images/find").EXPECT(
                ov_factory.value_list_matches(
                    [
                        jp.DICT_SUBSET(image_entry)
                        for image_entry in expect_images
                    ],
                    strict=True,
                    unique=True,
                )))

        return st.OperationContract(NoOpOperation("List Available Images"),
                                    contract=builder.build())
Exemple #6
0
    def list_available_images(self):
        """Creates a test that confirms expected available images.

    Returns:
      st.OperationContract
    """
        logger = logging.getLogger(__name__)

        # Get the list of images available (to the service account we are using).
        context = citest.base.ExecutionContext()
        gcp_agent = self.gcp_observer
        JournalLogger.begin_context('Collecting expected available images')
        relation_context = 'ERROR'
        try:
            logger.debug('Looking up available images.')

            json_doc = gcp_agent.list_resource(context, 'images')
            for project in GCP_STANDARD_IMAGES.keys():
                logger.info('Looking for images from project=%s', project)
                found = gcp_agent.list_resource(context,
                                                'images',
                                                project=project)
                for image in found:
                    if not image.get('deprecated', None):
                        json_doc.append(image)

            # Produce the list of images that we expect to receive from spinnaker
            # (visible to the primary service account).
            spinnaker_account = self.agent.deployed_config.get(
                'providers.google.primaryCredentials.name')

            logger.debug('Configured with Spinnaker account "%s"',
                         spinnaker_account)
            expect_images = [{
                'account': spinnaker_account,
                'imageName': image['name']
            } for image in json_doc]
            expect_images = sorted(expect_images, key=lambda k: k['imageName'])
            relation_context = 'VALID'
        finally:
            JournalLogger.end_context(relation=relation_context)

        # pylint: disable=bad-continuation
        builder = HttpContractBuilder(self.agent)
        (builder.new_clause_builder('Has Expected Images').get_url_path(
            '/gce/images/find').contains_match(
                [jp.DICT_SUBSET(image_entry) for image_entry in expect_images],
                match_kwargs={
                    'strict': True,
                    'unique': True
                }))

        return st.OperationContract(NoOpOperation('List Available Images'),
                                    contract=builder.build())
Exemple #7
0
  def test_dict_nested_subset_exact_keys(self):
    context = ExecutionContext()
    small_dict = {'first':'Apple', 'second':'Banana'}
    small_nested_dict = {'outer':small_dict}

    # In dictionary we want exact key matches, not subkeys.
    operand = {'out':{'first':'Apple'}}
    subset_pred = jp.DICT_SUBSET(operand)
    self.assertEqual(
        jp.MissingPathError(source=small_nested_dict, target_path='out',
                            path_value=PathValue('', small_nested_dict)),
        subset_pred(context, small_nested_dict))

    # In dictionary we want exact key matches, not subkeys.
    nested_operand = {'fir':'Apple'}
    operand = {'outer':nested_operand}
    subset_pred = jp.DICT_SUBSET(operand)
    self.assertEqual(
        jp.MissingPathError(source=small_nested_dict,
                            target_path=jp.PATH_SEP.join(['outer', 'fir']),
                            path_value=PathValue('outer', small_dict)),
        subset_pred(context, small_nested_dict))
Exemple #8
0
  def test_dict_simple_subset(self):
    context = ExecutionContext()
    letters = {'a':'A', 'b':'B', 'c':'C'}
    operand = {'a': 'A', 'b': 'B'}
    subset_pred = jp.DICT_SUBSET(operand)

    self.assertGoodResult(PathValue('', letters),
                          subset_pred, subset_pred(context, letters))
    self.assertGoodResult(PathValue('', operand),
                          subset_pred, subset_pred(context, operand))
    source = {'a':'A'}
    self.assertEqual(
        jp.MissingPathError(source=source, target_path='b',
                            path_value=PathValue('', source)),
        subset_pred(context, source))
Exemple #9
0
  def test_dict_subset_with_array_nodes(self):
    # See test_collect_with_dict_subset for comparison.
    context = ExecutionContext()
    letters = {'a':'A', 'b':'B', 'c':'C'}
    numbers = {'a':1, 'b':2}
    both = [letters, numbers]
    source = {'items': both}

    # This doesnt traverse through the list because we are looking for
    # a dictionary subset. We were expecting a dict with an 'a' but we
    # found only a dict with 'items'.
    letter_subset_pred = jp.DICT_SUBSET({'a':'A'})
    self.assertEqual(
        jp.MissingPathError(source=source, target_path='a',
                            path_value=PathValue('', source)),
        letter_subset_pred(context, source))
Exemple #10
0
  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 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 GCE. See
    the contract builder for more info on what the expectations are.
    """
        bindings = self.bindings
        target_pool_name = '{0}/targetPools/{1}-tp'.format(
            bindings['TEST_GCE_REGION'], self.__lb_name)

        spec = {
            'checkIntervalSec': 9,
            'healthyThreshold': 3,
            'unhealthyThreshold': 5,
            'timeoutSec': 2,
            'port': 80
        }

        payload = self.agent.make_json_payload_from_kwargs(
            job=[{
                'cloudProvider': 'gce',
                'provider': 'gce',
                'stack': bindings['TEST_STACK'],
                'detail': self.__lb_detail,
                'credentials': bindings['GCE_CREDENTIALS'],
                'region': bindings['TEST_GCE_REGION'],
                'ipProtocol': 'TCP',
                'portRange': spec['port'],
                'loadBalancerName': self.__lb_name,
                'healthCheck': {
                    'port': spec['port'],
                    'timeoutSec': spec['timeoutSec'],
                    'checkIntervalSec': spec['checkIntervalSec'],
                    'healthyThreshold': spec['healthyThreshold'],
                    'unhealthyThreshold': spec['unhealthyThreshold'],
                },
                'type': 'upsertLoadBalancer',
                'availabilityZones': {
                    bindings['TEST_GCE_REGION']: []
                },
                'user': '******'
            }],
            description='Create Load Balancer: ' + self.__lb_name,
            application=self.TEST_APP)

        builder = gcp.GcpContractBuilder(self.gcp_observer)
        (builder.new_clause_builder(
            'Health Check Added', retryable_for_secs=30).list_resource(
                'httpHealthChecks').contains_pred_list([
                    jp.PathContainsPredicate('name', '%s-hc' % self.__lb_name),
                    jp.DICT_SUBSET(spec)
                ]))
        (builder.new_clause_builder('Target Pool Added',
                                    retryable_for_secs=30).list_resource(
                                        'targetPools').contains_path_value(
                                            'name', '%s-tp' % self.__lb_name))
        (builder.new_clause_builder(
            'Forwarding Rules Added', retryable_for_secs=30).list_resource(
                'forwardingRules').contains_pred_list([
                    jp.PathContainsPredicate('name', self.__lb_name),
                    jp.PathContainsPredicate('target', target_pool_name)
                ]))

        return st.OperationContract(self.new_post_operation(
            title='upsert_load_balancer', data=payload, path='tasks'),
                                    contract=builder.build())