示例#1
0
  def check_server_groups_endpoint(self, kind, image, has_lb=True):
    name = self.TEST_APP + '-' + kind
    account = self.bindings['SPINNAKER_KUBERNETES_V2_ACCOUNT']
    builder = HttpContractBuilder(self.agent)
    lb_pred = (
        jp.LIST_MATCHES([jp.STR_EQ('service {}-service'.format(self.TEST_APP))])
        if has_lb else jp.LIST_EQ([])
    )
    (builder.new_clause_builder('Has recorded a server group for the deployed manifest')
       .get_url_path('/applications/{}/serverGroups'.format(self.TEST_APP))
       .EXPECT(
           ov_factory.value_list_contains(jp.DICT_MATCHES({
               'name': jp.STR_SUBSTR(name),
               'cluster': jp.STR_EQ(kind + ' ' + name),
               'account': jp.STR_EQ(account),
               'cloudProvider': jp.STR_EQ('kubernetes'),
               'buildInfo': jp.DICT_MATCHES({
                   'images': jp.LIST_MATCHES([jp.STR_EQ(image)]),
               }),
               'loadBalancers': lb_pred,
           }))
    ))

    return st.OperationContract(
        NoOpOperation('Has recorded a server group'),
        contract=builder.build())
示例#2
0
    def check_load_balancers_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 load balancer',
            retryable_for_secs=120).get_url_path(
                '/applications/{}/loadBalancers'.format(self.TEST_APP)).EXPECT(
                    ov_factory.value_list_contains(
                        jp.DICT_MATCHES({
                            'name':
                            jp.STR_EQ(name),
                            'kind':
                            jp.STR_EQ(kind),
                            'account':
                            jp.STR_EQ(account),
                            'cloudProvider':
                            jp.STR_EQ('kubernetes'),
                            'serverGroups':
                            jp.LIST_MATCHES([
                                jp.DICT_MATCHES({
                                    'account':
                                    jp.STR_EQ(account),
                                    'name':
                                    jp.STR_SUBSTR(self.TEST_APP),
                                }),
                            ]),
                        }))))

        return st.OperationContract(
            NoOpOperation('Has recorded a load balancer'),
            contract=builder.build())
示例#3
0
    def check_server_groups_endpoint(self, kind, image, has_lb=True):
        name = self.TEST_APP + '-' + kind
        account = self.bindings['SPINNAKER_KUBERNETES_V2_ACCOUNT']
        builder = HttpContractBuilder(self.agent)
        lb_pred = (jp.LIST_MATCHES([
            jp.STR_EQ('service {}-service'.format(self.TEST_APP))
        ]) if has_lb else jp.LIST_EQ([]))
        (builder.new_clause_builder(
            'Has recorded a server group for the deployed manifest',
            retryable_for_secs=120).get_url_path(
                '/applications/{}/serverGroups'.format(self.TEST_APP)).EXPECT(
                    ov_factory.value_list_contains(
                        jp.DICT_MATCHES({
                            'name':
                            jp.STR_SUBSTR(name),
                            'cluster':
                            jp.STR_EQ(kind + ' ' + name),
                            'account':
                            jp.STR_EQ(account),
                            'cloudProvider':
                            jp.STR_EQ('kubernetes'),
                            'buildInfo':
                            jp.DICT_MATCHES({
                                'images':
                                jp.LIST_MATCHES([jp.STR_EQ(image)]),
                            }),
                            'loadBalancers':
                            lb_pred,
                        }))))

        return st.OperationContract(
            NoOpOperation('Has recorded a server group'),
            contract=builder.build())
示例#4
0
    def check_detailed_clusters_endpoint(self, kind):
        name = kind + ' ' + self.TEST_APP + '-' + kind
        url_name = name.replace(' ', '%20')
        account = self.bindings['SPINNAKER_KUBERNETES_V2_ACCOUNT']
        builder = HttpContractBuilder(self.agent)
        (builder.new_clause_builder(
            'Has recorded a cluster for the deployed manifest').get_url_path(
                '/applications/{app}/clusters/{account}/{name}'.format(
                    app=self.TEST_APP, account=account, name=url_name)).EXPECT(
                        ov_factory.value_list_contains(
                            jp.DICT_MATCHES({
                                'accountName':
                                jp.STR_EQ(account),
                                'name':
                                jp.STR_EQ(name),
                                'serverGroups':
                                jp.LIST_MATCHES([
                                    jp.DICT_MATCHES({
                                        'account':
                                        jp.STR_EQ(account),
                                    })
                                ]),
                            }))))

        return st.OperationContract(NoOpOperation('Has recorded a cluster'),
                                    contract=builder.build())
示例#5
0
    def check_load_balancers_endpoint_empty(self):
        builder = HttpContractBuilder(self.agent)
        (builder.new_clause_builder('Has no load balancer').get_url_path(
            '/applications/{}/loadBalancers'.format(self.TEST_APP)).EXPECT(
                ov_factory.value_list_matches([])))

        return st.OperationContract(NoOpOperation('Has no load balancer'),
                                    contract=builder.build())
示例#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.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())
示例#7
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())
示例#8
0
  def test_contract_ok(self):
    builder = HttpContractBuilder(self.agent)

    # Here we're setting the observer_factory to make an HttpResponseObserver
    # so that the observation objects are the HttpResponseType instance rather
    # than the normal HttpObjectObserver where the objects are the payload data.
    (builder.new_clause_builder('Expect OK')
     .get_url_path('testpath?code=202', observer_factory=HttpResponseObserver)
     .EXPECT(ov_factory.value_list_contains(HttpResponsePredicate(http_code=202))))
    contract = builder.build()
    results = contract.verify(self.context)
    self.assertTrue(results)
示例#9
0
    def test_contract_ok(self):
        builder = HttpContractBuilder(self.agent)

        # Here we're setting the observer_factory to make an HttpResponseObserver
        # so that the observation objects are the HttpResponseType instance rather
        # than the normal HttpObjectObserver where the objects are the payload data.
        (builder.new_clause_builder('Expect OK').get_url_path(
            'testpath?code=202', observer_factory=HttpResponseObserver).EXPECT(
                ov_factory.value_list_contains(
                    HttpResponsePredicate(http_code=202))))
        contract = builder.build()
        results = contract.verify(self.context)
        self.assertTrue(results)
示例#10
0
    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())
示例#11
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.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())
示例#12
0
  def check_applications_endpoint(self):
    account = self.bindings['SPINNAKER_KUBERNETES_V2_ACCOUNT']
    builder = HttpContractBuilder(self.agent)
    (builder.new_clause_builder('Has recorded an app for the deployed manifest')
       .get_url_path('/applications')
       .EXPECT(
           ov_factory.value_list_contains(jp.DICT_MATCHES({
               'name': jp.STR_EQ(self.TEST_APP),
               'accounts': jp.STR_SUBSTR(account),
           }))
    ))

    return st.OperationContract(
        NoOpOperation('Has recorded an application'),
        contract=builder.build())
示例#13
0
    def check_applications_endpoint(self):
        account = self.bindings['SPINNAKER_KUBERNETES_V2_ACCOUNT']
        builder = HttpContractBuilder(self.agent)
        (builder.new_clause_builder(
            'Has recorded an app for the deployed manifest',
            retryable_for_secs=120).get_url_path('/applications').EXPECT(
                ov_factory.value_list_contains(
                    jp.DICT_MATCHES({
                        'name': jp.STR_EQ(self.TEST_APP),
                        'accounts': jp.STR_SUBSTR(account),
                    }))))

        return st.OperationContract(
            NoOpOperation('Has recorded an application'),
            contract=builder.build())
示例#14
0
  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')
       .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 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').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())
示例#16
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')
       .add_constraint(jp.PathPredicate(jp.DONT_ENUMERATE_TERMINAL,
                                        jp.EQUIVALENT(expect_images))))

    return st.OperationContract(
        NoOpOperation('List Available Images'),
        contract=builder.build())
示例#17
0
  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())
示例#18
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).
        gcloud_agent = self.gce_observer
        service_account = self.bindings.get('GCE_SERVICE_ACCOUNT', None)
        extra_args = ['--account', service_account] if service_account else []
        logger.debug('Looking up available images.')
        cli_result = gcloud_agent.list_resources('images',
                                                 extra_args=extra_args)

        if not cli_result.ok():
            raise RuntimeError('GCloud failed with: {0}'.format(
                str(cli_result)))
        json_doc = json_module.JSONDecoder().decode(cli_result.output)

        # 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'])

        # pylint: disable=bad-continuation
        builder = HttpContractBuilder(self.agent)
        (builder.new_clause_builder('Has Expected Images').get_url_path(
            '/gce/images/find').add_constraint(
                jp.PathPredicate(jp.DONT_ENUMERATE_TERMINAL,
                                 jp.EQUIVALENT(expect_images))))

        return st.OperationContract(NoOpOperation('List Available Images'),
                                    contract=builder.build())
示例#19
0
  def test_contract_failure_ok(self):
    builder = HttpContractBuilder(self.agent)

    # Here we're setting the observer_factory to make an HttpResponseObserver
    # so that the observation objects are the HttpResponseType instance rather
    # than the normal HttpObjectObserver where the objects are the payload data.
    #
    # When we encounter the HTTP error, the HttpResponseType is wrapped in an
    # HttpAgentError object and put into the observation error list.
    # So we need to dig it back out of there.
    # In addition, we're using error_list_matches rather than error_list_contains
    # so we can strict=True to show exactly the one error. "matches" takes a list
    # of predicates, so we wrap the error check into a list.
    (builder.new_clause_builder('Expect NotFound')
     .get_url_path('testpath?code=404', observer_factory=HttpResponseObserver)
     .EXPECT(ov_factory.error_list_matches(
          [HttpAgentErrorPredicate(HttpResponsePredicate(http_code=404))],
          strict=True)))  # Only the one error in the list
    contract = builder.build()
    results = contract.verify(self.context)
    self.assertTrue(results)
示例#20
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).
    gcloud_agent = self.gce_observer
    service_account = self.bindings.get('GCE_SERVICE_ACCOUNT', None)
    extra_args = ['--account', service_account] if service_account else []
    logger.debug('Looking up available images.')
    cli_result = gcloud_agent.list_resources('images', extra_args=extra_args)

    if not cli_result.ok():
      raise RuntimeError('GCloud failed with: {0}'.format(str(cli_result)))
    json_doc = json_module.JSONDecoder().decode(cli_result.output)

    # 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'])

    # pylint: disable=bad-continuation
    builder = HttpContractBuilder(self.agent)
    (builder.new_clause_builder('Has Expected Images')
       .get_url_path('/gce/images/find')
       .add_constraint(jp.PathPredicate(jp.DONT_ENUMERATE_TERMINAL,
                                        jp.EQUIVALENT(expect_images))))

    return st.OperationContract(
        NoOpOperation('List Available Images'),
        contract=builder.build())
示例#21
0
  def check_detailed_clusters_endpoint(self, kind):
    name = kind + ' ' + self.TEST_APP + '-' + kind
    url_name = name.replace(' ', '%20')
    account = self.bindings['SPINNAKER_KUBERNETES_V2_ACCOUNT']
    builder = HttpContractBuilder(self.agent)
    (builder.new_clause_builder('Has recorded a cluster for the deployed manifest')
       .get_url_path('/applications/{app}/clusters/{account}/{name}'.format(
         app=self.TEST_APP, account=account, name=url_name))
       .EXPECT(
           ov_factory.value_list_contains(jp.DICT_MATCHES({
               'accountName': jp.STR_EQ(account),
               'name': jp.STR_EQ(name),
               'serverGroups': jp.LIST_MATCHES([
                 jp.DICT_MATCHES({
                   'account': jp.STR_EQ(account),
                 })
               ]),
           }))
    ))

    return st.OperationContract(
        NoOpOperation('Has recorded a cluster'),
        contract=builder.build())
示例#22
0
    def test_contract_failure_ok(self):
        builder = HttpContractBuilder(self.agent)

        # Here we're setting the observer_factory to make an HttpResponseObserver
        # so that the observation objects are the HttpResponseType instance rather
        # than the normal HttpObjectObserver where the objects are the payload data.
        #
        # When we encounter the HTTP error, the HttpResponseType is wrapped in an
        # HttpAgentError object and put into the observation error list.
        # So we need to dig it back out of there.
        # In addition, we're using error_list_matches rather than error_list_contains
        # so we can strict=True to show exactly the one error. "matches" takes a list
        # of predicates, so we wrap the error check into a list.
        (builder.new_clause_builder('Expect NotFound').get_url_path(
            'testpath?code=404', observer_factory=HttpResponseObserver).EXPECT(
                ov_factory.error_list_matches([
                    HttpAgentErrorPredicate(
                        HttpResponsePredicate(http_code=404))
                ],
                                              strict=True))
         )  # Only the one error in the list
        contract = builder.build()
        results = contract.verify(self.context)
        self.assertTrue(results)
示例#23
0
  def check_load_balancers_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 load balancer')
       .get_url_path('/applications/{}/loadBalancers'.format(self.TEST_APP))
       .EXPECT(
           ov_factory.value_list_contains(jp.DICT_MATCHES({
               'name': jp.STR_EQ(name),
               'kind': jp.STR_EQ(kind),
               'account': jp.STR_EQ(account),
               'cloudProvider': jp.STR_EQ('kubernetes'),
               'serverGroups': jp.LIST_MATCHES([
                 jp.DICT_MATCHES({
                   'account': jp.STR_EQ(account),
                   'name': jp.STR_SUBSTR(self.TEST_APP),
                 }),
               ]),
           }))
    ))

    return st.OperationContract(
        NoOpOperation('Has recorded a load balancer'),
        contract=builder.build())