Example #1
0
    def _post_json_data(url, data):

        th_collection = data[jm.project]

        OAuthCredentials.set_credentials( SampleData.get_credentials() )
        credentials = OAuthCredentials.get_credentials(jm.project)

        tr = TreeherderRequest(
            protocol='http',
            host='localhost',
            project=jm.project,
            oauth_key=credentials['consumer_key'],
            oauth_secret=credentials['consumer_secret']
            )
        signed_uri = tr.oauth_client.get_signed_uri(
            th_collection.to_json(),
            tr.get_uri(th_collection.endpoint_base),
            "POST"
            )

        response = TestApp(application).post_json(
            str(signed_uri), params=th_collection.get_collection_data()
            )

        response.getcode = lambda: response.status_int
        return response
Example #2
0
def post_collection(project, th_collection, status=None, expect_errors=False, consumer_key=None, consumer_secret=None):

    # Set the credentials
    OAuthCredentials.set_credentials(SampleData.get_credentials())

    credentials = OAuthCredentials.get_credentials(project)

    # The only time the credentials should be overridden are when
    # a client needs to test authentication failure confirmation
    if consumer_key:
        credentials["consumer_key"] = consumer_key

    if consumer_secret:
        credentials["consumer_secret"] = consumer_secret

    tr = TreeherderRequest(
        protocol="http",
        host="localhost",
        project=project,
        oauth_key=credentials["consumer_key"],
        oauth_secret=credentials["consumer_secret"],
    )

    signed_uri = tr.oauth_client.get_signed_uri(
        th_collection.to_json(), tr.get_uri(th_collection.endpoint_base), "POST"
    )

    response = TestApp(application).post_json(
        str(signed_uri), params=th_collection.get_collection_data(), status=status
    )

    return response
Example #3
0
def post_collection(
        project, th_collection, status=None, expect_errors=False,
        consumer_key=None, consumer_secret=None):

    # Set the credentials
    OAuthCredentials.set_credentials(SampleData.get_credentials())

    credentials = OAuthCredentials.get_credentials(project)

    # The only time the credentials should be overridden are when
    # a client needs to test authentication failure confirmation
    if consumer_key:
        credentials['consumer_key'] = consumer_key

    if consumer_secret:
        credentials['consumer_secret'] = consumer_secret

    cli = TreeherderClient(
        protocol='http',
        host='localhost',
    )

    jsondata = th_collection.to_json()
    signed_uri = cli._get_uri(project, th_collection.endpoint_base,
                              data=jsondata,
                              oauth_key=credentials['consumer_key'],
                              oauth_secret=credentials['consumer_secret'],
                              method='POST')

    response = TestApp(application).post_json(
        str(signed_uri), params=th_collection.get_collection_data(),
        status=status
    )

    return response
def post_job_data(project, uri, data, status=None, expect_errors=False):

    # Since the uri is passed in it's not generated by the
    # treeherder request or collection and is missing the protocol
    # and host. Add those missing elements here.
    uri = 'http://localhost{0}'.format(uri)

    # Set the credentials
    OAuthCredentials.set_credentials(SampleData.get_credentials())

    credentials = OAuthCredentials.get_credentials(project)

    tr = TreeherderRequest(protocol='http',
                           host='localhost',
                           project=project,
                           oauth_key=credentials['consumer_key'],
                           oauth_secret=credentials['consumer_secret'])

    signed_uri = tr.get_signed_uri(json.dumps(data), uri)

    response = TestApp(application).post_json(str(signed_uri),
                                              params=data,
                                              status=status,
                                              expect_errors=expect_errors)

    return response
Example #5
0
def post_collection(
        project, th_collection, status=None, expect_errors=False,
        consumer_key=None, consumer_secret=None):

    # Set the credentials
    OAuthCredentials.set_credentials(SampleData.get_credentials())

    credentials = OAuthCredentials.get_credentials(project)

    # The only time the credentials should be overridden are when
    # a client needs to test authentication failure confirmation
    consumer_key = consumer_key or credentials['consumer_key']
    consumer_secret = consumer_secret or credentials['consumer_secret']

    auth = TreeherderAuth(consumer_key, consumer_secret, project)
    client = TreeherderClient(protocol='http', host='localhost', auth=auth)
    uri = client._get_project_uri(project, th_collection.endpoint_base)

    req = Request('POST', uri,
                  json=th_collection.get_collection_data(),
                  auth=auth)
    prepped_request = req.prepare()

    response = TestApp(application).post_json(
        prepped_request.url,
        params=th_collection.get_collection_data(),
        status=status
    )

    return response
Example #6
0
def post_job_data(
    project, uri, data, status=None, expect_errors=False):

    # Since the uri is passed in it's not generated by the
    # treeherder request or collection and is missing the protocol
    # and host. Add those missing elements here.
    uri = 'http://localhost{0}'.format(uri)

    # Set the credentials
    OAuthCredentials.set_credentials( SampleData.get_credentials() )

    credentials = OAuthCredentials.get_credentials(project)

    tr = TreeherderRequest(
        protocol='http',
        host='localhost',
        project=project,
        oauth_key=credentials['consumer_key'],
        oauth_secret=credentials['consumer_secret']
        )

    signed_uri = tr.get_signed_uri(
        json.dumps(data), uri
        )

    response = TestApp(application).post_json(
        str(signed_uri), params=data, status=status,
        expect_errors=expect_errors
        )

    return response
Example #7
0
    def authenticate(self, request):

        if not self.auth_detected(request):
            return None

        user = request.resolver_match.kwargs.get('project') or request.query_params['user']
        project_credentials = OAuthCredentials.get_credentials(user)

        if not project_credentials:
            raise exceptions.ValidationError(
                'project {0} has no OAuth credentials'.format(user)
            )
        parameters = OAuthCredentials.get_parameters(request.query_params)

        oauth_consumer_key = parameters['oauth_consumer_key']

        if oauth_consumer_key != project_credentials['consumer_key']:
            raise exceptions.AuthenticationFailed(
                'oauth_consumer_key does not match credentials for project {0}'.format(user)
            )

        uri = '{0}://{1}{2}'.format(
            settings.TREEHERDER_REQUEST_PROTOCOL,
            request.get_host(),
            request.path
        )
        # Construct the OAuth request based on the django request object
        json_renderer = JSONRenderer()
        req_obj = oauth.Request(
            method=request.method,
            url=uri,
            parameters=parameters,
            body=json_renderer.render(request.data),
        )
        server = oauth.Server()
        token = oauth.Token(key='', secret='')
        # Get the consumer object
        cons_obj = oauth.Consumer(
            oauth_consumer_key,
            project_credentials['consumer_secret']
        )
        # Set the signature method
        server.add_signature_method(oauth.SignatureMethod_HMAC_SHA1())

        try:
            # verify oauth django request and consumer object match
            server.verify_request(req_obj, cons_obj, token)
        except oauth.Error:
            raise exceptions.AuthenticationFailed(
                'Client authentication failed for project {0}'.format(user)
            )
        request.legacy_oauth_authenticated = True
        return (DummyUser(), None)
Example #8
0
def test_artifact_create_text_log_summary_and_bug_suggestions(
        webapp, test_project, eleven_jobs_processed,
        mock_post_collection, mock_error_summary,
        sample_data):
    """
    test submitting text_log_summary and Bug suggestions artifacts

    This should NOT generate a Bug suggestions artifact, just post the one
    submitted.
    """

    credentials = OAuthCredentials.get_credentials(test_project)

    with JobsModel(test_project) as jobs_model:
        job = jobs_model.get_job_list(0, 1)[0]
    tls = sample_data.text_log_summary
    bs_blob = ["flim", "flam"]

    tac = client.TreeherderArtifactCollection()
    tac.add(client.TreeherderArtifact({
        'type': 'json',
        'name': 'text_log_summary',
        'blob': json.dumps(tls['blob']),
        'job_guid': job['job_guid']
    }))
    tac.add(client.TreeherderArtifact({
        'type': 'json',
        'name': 'Bug suggestions',
        'blob': json.dumps(bs_blob),
        'job_guid': job['job_guid']
    }))

    cli = client.TreeherderClient(protocol='http', host='localhost')
    credentials = OAuthCredentials.get_credentials(test_project)
    cli.post_collection(test_project, credentials['consumer_key'],
                        credentials['consumer_secret'], tac)

    with ArtifactsModel(test_project) as artifacts_model:
        artifacts = artifacts_model.get_job_artifact_list(0, 10, conditions={
            'job_id': {('=', job["id"])}
        })

    assert len(artifacts) == 2
    artifact_names = {x['name'] for x in artifacts}
    act_bs_obj = [x['blob'] for x in artifacts if x['name'] == 'Bug suggestions'][0]

    assert set(artifact_names) == {'Bug suggestions', 'text_log_summary'}
    assert bs_blob == act_bs_obj
Example #9
0
def post_log_artifacts(project, job_guid, job_log_url, retry_task,
                       extract_artifacts_cb):
    """Post a list of artifacts to a job."""
    def _retry(e):
        # Initially retry after 1 minute, then for each subsequent retry
        # lengthen the retry time by another minute.
        retry_task.retry(exc=e,
                         countdown=(1 + retry_task.request.retries) * 60)
        # .retry() raises a RetryTaskError exception,
        # so nothing after this function will be executed

    log_description = "%s %s (%s)" % (project, job_guid, job_log_url['url'])
    logger.debug("Downloading/parsing log for %s", log_description)

    credentials = OAuthCredentials.get_credentials(project)
    auth = TreeherderAuth(credentials.get('consumer_key'),
                          credentials.get('consumer_secret'), project)
    client = TreeherderClient(protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
                              host=settings.TREEHERDER_REQUEST_HOST,
                              auth=auth)

    try:
        artifact_list = extract_artifacts_cb(job_log_url['url'], job_guid)
    except Exception as e:
        client.update_parse_status(project, job_log_url['id'], 'failed')
        # unrecoverable http error (doesn't exist or permission denied)
        # (apparently this can happen somewhat often with taskcluster if
        # the job fails, so just warn about it -- see
        # https://bugzilla.mozilla.org/show_bug.cgi?id=1154248)
        if isinstance(e, urllib2.HTTPError) and e.code in (403, 404):
            logger.warning("Unable to retrieve log for %s: %s",
                           log_description, e)
            return
        # possibly recoverable http error (e.g. problems on our end)
        elif isinstance(e, urllib2.URLError):
            logger.error("Failed to download log for %s: %s", log_description,
                         e)
            _retry(e)
        # parse error or other unrecoverable error
        else:
            logger.error("Failed to download/parse log for %s: %s",
                         log_description, e)
        # re-raise exception if we're not retrying, so new relic sees the
        # error
        raise

    # store the artifacts generated
    tac = TreeherderArtifactCollection()
    for artifact in artifact_list:
        ta = tac.get_artifact(artifact)
        tac.add(ta)

    try:
        client.post_collection(project, tac)
        client.update_parse_status(project, job_log_url['id'], 'parsed')
        logger.debug("Finished posting artifact for %s %s", project, job_guid)
    except Exception as e:
        logger.error("Failed to upload parsed artifact for %s: %s",
                     log_description, e)
        _retry(e)
Example #10
0
def post_treeherder_collections(th_collections, chunk_size=1):

    errors = []
    cli = TreeherderClient(
        protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
        host=settings.TREEHERDER_REQUEST_HOST,
    )

    for project in th_collections:

        credentials = OAuthCredentials.get_credentials(project)

        auth = TreeherderAuth(credentials.get('consumer_key'),
                              credentials.get('consumer_secret'),
                              project)

        logger.info(
            "collection loading request for project {0}: {1}".format(
                project,
                th_collections[project].endpoint_base))

        collection_chunks = th_collections[project].get_chunks(chunk_size)

        for collection in collection_chunks:
            try:
                cli.post_collection(project, collection, auth=auth)
            except Exception:
                errors.append({
                    "project": project,
                    "url": th_collections[project].endpoint_base,
                    "message": traceback.format_exc()
                })

    if errors:
        raise CollectionNotLoadedException(errors)
Example #11
0
def post_treeherder_collections(th_collections):
    errors = []
    for project in th_collections:

        credentials = OAuthCredentials.get_credentials(project)

        th_request = TreeherderRequest(
            protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
            host=settings.TREEHERDER_REQUEST_HOST,
            project=project,
            oauth_key=credentials.get('consumer_key', None),
            oauth_secret=credentials.get('consumer_secret', None)
        )

        logger.info(
            "collection loading request: {0}".format(
                th_request.get_uri(th_collections[project].endpoint_base)))
        response = th_request.post(th_collections[project])

        if not response or response.status_code != 200:
            errors.append({
                "project": project,
                "url": th_collections[project].endpoint_base,
                "message": response.text
            })

    if errors:
        raise CollectionNotLoadedException(errors)
Example #12
0
    def load(self, th_collections):
        errors = []
        for project in th_collections:

            credentials = OAuthCredentials.get_credentials(project)

            th_request = TreeherderRequest(
                protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
                host=settings.TREEHERDER_REQUEST_HOST,
                project=project,
                oauth_key=credentials.get('consumer_key', None),
                oauth_secret=credentials.get('consumer_secret', None)
            )

            logger.info(
                "collection loading request: {0}".format(
                    th_request.get_uri(th_collections[project].endpoint_base)))
            response = th_request.post(th_collections[project])

            if not response or response.status != 200:
                errors.append({
                    "project": project,
                    "url": th_collections[project].endpoint_base,
                    "message": response.read()
                })
        if errors:
            raise CollectionNotLoadedException(errors)
Example #13
0
def post_treeherder_collections(th_collections, chunk_size=1):

    errors = []
    cli = TreeherderClient(
        protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
        host=settings.TREEHERDER_REQUEST_HOST,
    )

    for project in th_collections:

        credentials = OAuthCredentials.get_credentials(project)

        logger.info("collection loading request for project {0}: {1}".format(
            project, th_collections[project].endpoint_base))

        collection_chunks = th_collections[project].get_chunks(chunk_size)

        for collection in collection_chunks:
            try:
                cli.post_collection(project, credentials.get('consumer_key'),
                                    credentials.get('consumer_secret'),
                                    collection)
            except Exception:
                errors.append({
                    "project": project,
                    "url": th_collections[project].endpoint_base,
                    "message": traceback.format_exc()
                })

    if errors:
        raise CollectionNotLoadedException(errors)
Example #14
0
    def authenticate(self, request):

        if not self.auth_detected(request):
            return None

        user = request.resolver_match.kwargs.get(
            'project') or request.query_params['user']
        project_credentials = OAuthCredentials.get_credentials(user)

        if not project_credentials:
            raise exceptions.ValidationError(
                'project {0} has no OAuth credentials'.format(user))
        parameters = OAuthCredentials.get_parameters(request.query_params)

        oauth_consumer_key = parameters['oauth_consumer_key']

        if oauth_consumer_key != project_credentials['consumer_key']:
            raise exceptions.AuthenticationFailed(
                'oauth_consumer_key does not match credentials for project {0}'
                .format(user))

        uri = '{0}://{1}{2}'.format(settings.TREEHERDER_REQUEST_PROTOCOL,
                                    request.get_host(), request.path)
        # Construct the OAuth request based on the django request object
        json_renderer = JSONRenderer()
        req_obj = oauth.Request(
            method=request.method,
            url=uri,
            parameters=parameters,
            body=json_renderer.render(request.DATA),
        )
        server = oauth.Server()
        token = oauth.Token(key='', secret='')
        # Get the consumer object
        cons_obj = oauth.Consumer(oauth_consumer_key,
                                  project_credentials['consumer_secret'])
        # Set the signature method
        server.add_signature_method(oauth.SignatureMethod_HMAC_SHA1())

        try:
            # verify oauth django request and consumer object match
            server.verify_request(req_obj, cons_obj, token)
        except oauth.Error:
            raise exceptions.AuthenticationFailed(
                'Client authentication failed for project {0}'.format(user))
        request.legacy_oauth_authenticated = True
        return (DummyUser(), None)
Example #15
0
def do_post_collection(project, collection):
    # assume if there were no exceptions we're ok
    cli = client.TreeherderClient(protocol='http', host='localhost')
    credentials = OAuthCredentials.get_credentials(project)
    auth = TreeherderAuth(credentials['consumer_key'],
                          credentials['consumer_secret'], project)

    cli.post_collection(project, collection, auth=auth)
Example #16
0
def post_log_artifacts(project,
                       job_guid,
                       job_log_url,
                       retry_task,
                       extract_artifacts_cb,
                       check_errors=False):
    """Post a list of artifacts to a job."""
    def _retry(e):
        # Initially retry after 1 minute, then for each subsequent retry
        # lengthen the retry time by another minute.
        retry_task.retry(exc=e,
                         countdown=(1 + retry_task.request.retries) * 60)
        # .retry() raises a RetryTaskError exception,
        # so nothing after this function will be executed

    log_description = "%s %s (%s)" % (project, job_guid, job_log_url['url'])
    logger.debug("Downloading/parsing log for %s", log_description)

    credentials = OAuthCredentials.get_credentials(project)
    req = TreeherderRequest(
        protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
        host=settings.TREEHERDER_REQUEST_HOST,
        project=project,
        oauth_key=credentials.get('consumer_key', None),
        oauth_secret=credentials.get('consumer_secret', None),
    )

    try:
        artifact_list = extract_artifacts_cb(job_log_url['url'], job_guid,
                                             check_errors)
    except Exception as e:
        update_parse_status(req, job_log_url, 'failed')
        if isinstance(e, urllib2.HTTPError) and e.code == 404:
            logger.debug("Log not found for %s", log_description)
            return
        logger.error("Failed to download/parse log for %s: %s",
                     log_description, e)
        _retry(e)

    # store the artifacts generated
    tac = TreeherderArtifactCollection()
    for artifact in artifact_list:
        ta = tac.get_artifact({
            "job_guid": artifact[0],
            "name": artifact[1],
            "type": artifact[2],
            "blob": artifact[3]
        })
        tac.add(ta)

    try:
        req.post(tac)
        update_parse_status(req, job_log_url, 'parsed')
        logger.debug("Finished posting artifact for %s %s", project, job_guid)
    except Exception as e:
        logger.error("Failed to upload parsed artifact for %s: %s",
                     log_description, e)
        _retry(e)
def do_post_collection(project, collection):
    # assume if there were no exceptions we're ok
    cli = client.TreeherderClient(protocol='http', host='localhost')
    credentials = OAuthCredentials.get_credentials(project)
    auth = TreeherderAuth(credentials['consumer_key'],
                          credentials['consumer_secret'],
                          project)

    cli.post_collection(project, collection, auth=auth)
Example #18
0
    def _send(th_request, th_collection):

        OAuthCredentials.set_credentials(SampleData.get_credentials())
        credentials = OAuthCredentials.get_credentials(jm.project)

        th_request.oauth_key = credentials['consumer_key']
        th_request.oauth_secret = credentials['consumer_secret']

        signed_uri = th_request.get_signed_uri(
            th_collection.to_json(), th_request.get_uri(th_collection)
        )

        response = TestApp(application).post_json(
            str(signed_uri), params=th_collection.get_collection_data()
        )

        response.getcode = lambda: response.status_int
        return response
def post_log_artifacts(project,
                       job_guid,
                       job_log_url,
                       retry_task,
                       extract_artifacts_cb,
                       check_errors=False):
    """Post a list of artifacts to a job."""
    def _retry(e):
        # Initially retry after 1 minute, then for each subsequent retry
        # lengthen the retry time by another minute.
        retry_task.retry(exc=e, countdown=(1 + retry_task.request.retries) * 60)
        # .retry() raises a RetryTaskError exception,
        # so nothing after this function will be executed

    log_description = "%s %s (%s)" % (project, job_guid, job_log_url['url'])
    logger.debug("Downloading/parsing log for %s", log_description)

    credentials = OAuthCredentials.get_credentials(project)
    req = TreeherderRequest(
        protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
        host=settings.TREEHERDER_REQUEST_HOST,
        project=project,
        oauth_key=credentials.get('consumer_key', None),
        oauth_secret=credentials.get('consumer_secret', None),
    )

    try:
        artifact_list = extract_artifacts_cb(job_log_url['url'],
                                             job_guid, check_errors)
    except Exception as e:
        update_parse_status(req, job_log_url, 'failed')
        if isinstance(e, urllib2.HTTPError) and e.code == 404:
            logger.debug("Log not found for %s", log_description)
            return
        logger.error("Failed to download/parse log for %s: %s", log_description, e)
        _retry(e)

    # store the artifacts generated
    tac = TreeherderArtifactCollection()
    for artifact in artifact_list:
        ta = tac.get_artifact({
            "job_guid": artifact[0],
            "name": artifact[1],
            "type": artifact[2],
            "blob": artifact[3]
        })
        tac.add(ta)

    try:
        req.post(tac)
        update_parse_status(req, job_log_url, 'parsed')
        logger.debug("Finished posting artifact for %s %s", project, job_guid)
    except Exception as e:
        logger.error("Failed to upload parsed artifact for %s: %s", log_description, e)
        _retry(e)
Example #20
0
def post_log_artifacts(project,
                       job_guid,
                       job_log_url,
                       retry_task,
                       extract_artifacts_cb,
                       check_errors=False):
    """Post a list of artifacts to a job."""
    def _retry(e):
        # Initially retry after 1 minute, then for each subsequent retry
        # lengthen the retry time by another minute.
        retry_task.retry(exc=e, countdown=(1 + retry_task.request.retries) * 60)
        # .retry() raises a RetryTaskError exception,
        # so nothing after this function will be executed

    log_description = "%s %s (%s)" % (project, job_guid, job_log_url['url'])
    logger.debug("Downloading/parsing log for %s", log_description)

    credentials = OAuthCredentials.get_credentials(project)
    client = TreeherderClient(
        protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
        host=settings.TREEHERDER_REQUEST_HOST
    )

    try:
        artifact_list = extract_artifacts_cb(job_log_url['url'],
                                             job_guid, check_errors)
    except Exception as e:
        client.update_parse_status(project, credentials.get('consumer_key'),
                                   credentials.get('consumer_secret'),
                                   job_log_url['id'], 'failed')
        if isinstance(e, urllib2.HTTPError) and e.code in (403, 404):
            logger.debug("Unable to retrieve log for %s: %s", log_description, e)
            return
        logger.error("Failed to download/parse log for %s: %s", log_description, e)
        _retry(e)

    # store the artifacts generated
    tac = TreeherderArtifactCollection()
    for artifact in artifact_list:
        ta = tac.get_artifact(artifact)
        tac.add(ta)

    try:
        client.post_collection(project, credentials.get('consumer_key'),
                               credentials.get('consumer_secret'),
                               tac)
        client.update_parse_status(project, credentials.get('consumer_key'),
                                   credentials.get('consumer_secret'),
                                   job_log_url['id'], 'parsed')
        logger.debug("Finished posting artifact for %s %s", project, job_guid)
    except Exception as e:
        logger.error("Failed to upload parsed artifact for %s: %s", log_description, e)
        _retry(e)
Example #21
0
    def _send(th_request, endpoint, method=None, data=None):

        OAuthCredentials.set_credentials(SampleData.get_credentials())
        credentials = OAuthCredentials.get_credentials(jm.project)

        th_request.oauth_key = credentials['consumer_key']
        th_request.oauth_secret = credentials['consumer_secret']

        if data and not isinstance(data, str):
            data = json.dumps(data)

        signed_uri = th_request.oauth_client.get_signed_uri(
            data, th_request.get_uri(endpoint), method)

        response = getattr(TestApp(application),
                           method.lower())(str(signed_uri),
                                           params=data,
                                           content_type='application/json')

        response.getcode = lambda: response.status_int
        return response
Example #22
0
def post_collection(project,
                    th_collection,
                    status=None,
                    expect_errors=False,
                    consumer_key=None,
                    consumer_secret=None):

    # Set the credentials
    OAuthCredentials.set_credentials(SampleData.get_credentials())

    credentials = OAuthCredentials.get_credentials(project)

    # The only time the credentials should be overridden are when
    # a client needs to test authentication failure confirmation
    if consumer_key:
        credentials['consumer_key'] = consumer_key

    if consumer_secret:
        credentials['consumer_secret'] = consumer_secret

    cli = TreeherderClient(
        protocol='http',
        host='localhost',
    )

    jsondata = th_collection.to_json()
    signed_uri = cli._get_project_uri(
        project,
        th_collection.endpoint_base,
        data=jsondata,
        oauth_key=credentials['consumer_key'],
        oauth_secret=credentials['consumer_secret'],
        method='POST')

    response = TestApp(application).post_json(
        str(signed_uri),
        params=th_collection.get_collection_data(),
        status=status)

    return response
Example #23
0
def test_artifact_create_text_log_summary(webapp, test_project,
                                          eleven_jobs_processed,
                                          mock_post_collection,
                                          mock_error_summary, sample_data):
    """
    test submitting a text_log_summary artifact which auto-generates bug suggestions
    """

    credentials = OAuthCredentials.get_credentials(test_project)

    with JobsModel(test_project) as jobs_model:
        job = jobs_model.get_job_list(0, 1)[0]
    tls = sample_data.text_log_summary

    tac = client.TreeherderArtifactCollection()
    ta = client.TreeherderArtifact({
        'type': 'json',
        'name': 'text_log_summary',
        'blob': json.dumps(tls['blob']),
        'job_guid': job['job_guid']
    })
    tac.add(ta)

    cli = client.TreeherderClient(protocol='http', host='localhost')
    credentials = OAuthCredentials.get_credentials(test_project)
    cli.post_collection(test_project, credentials['consumer_key'],
                        credentials['consumer_secret'], tac)

    with ArtifactsModel(test_project) as artifacts_model:
        artifacts = artifacts_model.get_job_artifact_list(
            0, 10, conditions={'job_id': {('=', job["id"])}})

    artifact_names = {x['name'] for x in artifacts}
    act_bs_obj = [
        x['blob'] for x in artifacts if x['name'] == 'Bug suggestions'
    ][0]

    assert set(artifact_names) == {'Bug suggestions', 'text_log_summary'}
    assert mock_error_summary == act_bs_obj
    def _send(th_request, endpoint,  method=None, data=None):

        OAuthCredentials.set_credentials(SampleData.get_credentials())
        credentials = OAuthCredentials.get_credentials(jm.project)

        th_request.oauth_key = credentials['consumer_key']
        th_request.oauth_secret = credentials['consumer_secret']

        if data and not isinstance(data, str):
            data = json.dumps(data)

        signed_uri = th_request.oauth_client.get_signed_uri(
            data, th_request.get_uri(endpoint), method
        )

        response = getattr(TestApp(application), method.lower())(
            str(signed_uri),
            params=data,
            content_type='application/json'
        )

        response.getcode = lambda: response.status_int
        return response
def test_artifact_create_text_log_summary(webapp, test_project, eleven_jobs_processed,
                                          mock_post_collection, mock_error_summary,
                                          sample_data):
    """
    test submitting a text_log_summary artifact which auto-generates bug suggestions
    """

    credentials = OAuthCredentials.get_credentials(test_project)

    with JobsModel(test_project) as jobs_model:
        job = jobs_model.get_job_list(0, 1)[0]
    tls = sample_data.text_log_summary

    tac = client.TreeherderArtifactCollection()
    ta = client.TreeherderArtifact({
        'type': 'json',
        'name': 'text_log_summary',
        'blob': json.dumps(tls['blob']),
        'job_guid': job['job_guid']
    })
    tac.add(ta)

    cli = client.TreeherderClient(protocol='http', host='localhost')
    credentials = OAuthCredentials.get_credentials(test_project)
    cli.post_collection(test_project, credentials['consumer_key'],
                        credentials['consumer_secret'], tac)

    with ArtifactsModel(test_project) as artifacts_model:
        artifacts = artifacts_model.get_job_artifact_list(0, 10, conditions={
            'job_id': {('=', job["id"])}
        })

    artifact_names = {x['name'] for x in artifacts}
    act_bs_obj = [x['blob'] for x in artifacts if x['name'] == 'Bug suggestions'][0]

    assert set(artifact_names) == {'Bug suggestions', 'text_log_summary'}
    assert mock_error_summary == act_bs_obj
Example #26
0
def test_artifact_create_text_log_summary_and_bug_suggestions(
        webapp, test_project, eleven_jobs_stored, mock_post_json,
        mock_error_summary, sample_data):
    """
    test submitting text_log_summary and Bug suggestions artifacts

    This should NOT generate a Bug suggestions artifact, just post the one
    submitted.
    """

    with JobsModel(test_project) as jobs_model:
        job = jobs_model.get_job_list(0, 1)[0]
    tls = sample_data.text_log_summary
    bs_blob = ["flim", "flam"]

    tac = client.TreeherderArtifactCollection()
    tac.add(
        client.TreeherderArtifact({
            'type': 'json',
            'name': 'text_log_summary',
            'blob': json.dumps(tls['blob']),
            'job_guid': job['job_guid']
        }))
    tac.add(
        client.TreeherderArtifact({
            'type': 'json',
            'name': 'Bug suggestions',
            'blob': bs_blob,
            'job_guid': job['job_guid']
        }))

    credentials = OAuthCredentials.get_credentials(test_project)
    auth = TreeherderAuth(credentials['consumer_key'],
                          credentials['consumer_secret'], test_project)
    cli = client.TreeherderClient(protocol='http', host='localhost', auth=auth)
    cli.post_collection(test_project, tac)

    with ArtifactsModel(test_project) as artifacts_model:
        artifacts = artifacts_model.get_job_artifact_list(
            0, 10, conditions={'job_id': {('=', job["id"])}})

    assert len(artifacts) == 2
    artifact_names = {x['name'] for x in artifacts}
    act_bs_obj = [
        x['blob'] for x in artifacts if x['name'] == 'Bug suggestions'
    ][0]

    assert set(artifact_names) == {'Bug suggestions', 'text_log_summary'}
    assert bs_blob == act_bs_obj
def test_post_job_with_parsed_log(test_project, result_set_stored,
                                  mock_send_request):
    """
    test submitting a job with a pre-parsed log gets the right job_log_url
    parse_status value.
    """

    credentials = OAuthCredentials.get_credentials(test_project)

    tjc = client.TreeherderJobCollection()
    tj = client.TreeherderJob({
        'project': test_project,
        'revision_hash': result_set_stored[0]['revision_hash'],
        'job': {
            'job_guid': 'd22c74d4aa6d2a1dcba96d95dccbd5fdca70cf33',
            'state': 'completed',
            'log_references': [{
                'url': 'http://ftp.mozilla.org/pub/mozilla.org/spidermonkey/...',
                'name': 'builbot_text',
                'parse_status': 'parsed'
            }]
        }
    })

    tjc.add(tj)

    req = client.TreeherderRequest(
        protocol='http',
        host='localhost',
        project=test_project,
        oauth_key=credentials['consumer_key'],
        oauth_secret=credentials['consumer_secret']
        )

    # Post the request to treeherder
    resp = req.post(tjc)
    assert resp.status_int == 200
    assert resp.body == '{"message": "well-formed JSON stored"}'

    with JobsModel(test_project) as jm:
        jm.process_objects(10)

        job_ids = [x['id'] for x in jm.get_job_list(0, 20)]
        job_log_list = jm.get_job_log_url_list(job_ids)

        assert len(job_log_list) == 1
        assert job_log_list[0]['parse_status'] == 'parsed'
Example #28
0
    def load(self, th_collections):

        for project in th_collections:

            credentials = OAuthCredentials.get_credentials(project)

            th_request = TreeherderRequest(
                protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
                host=settings.TREEHERDER_REQUEST_HOST,
                project=project,
                oauth_key=credentials.get('consumer_key', None),
                oauth_secret=credentials.get('consumer_secret', None))

            response = th_request.post(th_collections[project])

            if not response or response.status != 200:
                message = response.read()
                logger.error("collection loading failed: {0}".format(message))
    def load(self, th_collections):

        for project in th_collections:

            credentials = OAuthCredentials.get_credentials(project)

            th_request = TreeherderRequest(
                protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
                host=settings.TREEHERDER_REQUEST_HOST,
                project=project,
                oauth_key=credentials.get('consumer_key', None),
                oauth_secret=credentials.get('consumer_secret', None)
            )

            response = th_request.post(th_collections[project])

            if not response or response.status != 200:
                message = response.read()
                logger.error("collection loading failed: {0}".format(message))
Example #30
0
def test_two_legged_oauth_project_via_user(monkeypatch, jm, set_oauth_credentials):
    view = AuthenticatedView.as_view()
    credentials = OAuthCredentials.get_credentials(jm.project)

    test_url = '/api/'
    request = factory.get(test_url, {
        'oauth_body_hash': '',
        'oauth_consumer_key': credentials['consumer_key'],
        'oauth_nonce': '',
        'oauth_signature_method': '',
        'oauth_timestamp': '',
        'oauth_token': '',
        'oauth_version': '',
        'oauth_signature': '',
        'user': jm.project
    })
    monkeypatch.setattr(oauth.Server, 'verify_request', lambda *x, **y: True)
    request.resolver_match = resolve(test_url)
    response = view(request)

    assert response.data == {'authenticated': True}
Example #31
0
    def load(self, th_collections):
        for project in th_collections:

            credentials = OAuthCredentials.get_credentials(project)

            th_request = TreeherderRequest(
                protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
                host=settings.TREEHERDER_REQUEST_HOST,
                project=project,
                oauth_key=credentials.get('consumer_key', None),
                oauth_secret=credentials.get('consumer_secret', None)
            )

            logger.info(
                "collection loading request: {0}".format(
                    th_request.get_uri(th_collections[project].endpoint_base)))
            response = th_request.post(th_collections[project])

            if not response or response.status != 200:
                message = response.read()
                logger.error('[{0}]Error posting data to {1} : {2}'.format(
                    project, th_collections[project].endpoint_base, message))
Example #32
0
def test_two_legged_oauth_project_via_user(monkeypatch, jm,
                                           set_oauth_credentials):
    view = AuthenticatedView.as_view()
    credentials = OAuthCredentials.get_credentials(jm.project)

    test_url = '/api/'
    request = factory.get(
        test_url, {
            'oauth_body_hash': '',
            'oauth_consumer_key': credentials['consumer_key'],
            'oauth_nonce': '',
            'oauth_signature_method': '',
            'oauth_timestamp': '',
            'oauth_token': '',
            'oauth_version': '',
            'oauth_signature': '',
            'user': jm.project
        })
    monkeypatch.setattr(oauth.Server, 'verify_request', lambda *x, **y: True)
    request.resolver_match = resolve(test_url)
    response = view(request)

    assert response.data == {'authenticated': True}
Example #33
0
    def wrap_oauth(cls, *args, **kwargs):

        # First argument must be request object
        request = args[0]

        # Get the project keyword argumet
        project = kwargs.get('project', None)

        # Get the project credentials
        project_credentials = OAuthCredentials.get_credentials(project)

        if not project_credentials:
            msg = {
                'response': "invalid_request",
                'detail':
                "project, {0}, has no OAuth credentials".format(project)
            }
            return Response(msg, 500)

        parameters = OAuthCredentials.get_parameters(request.QUERY_PARAMS)

        oauth_body_hash = parameters.get('oauth_body_hash', None)
        oauth_signature = parameters.get('oauth_signature', None)
        oauth_consumer_key = parameters.get('oauth_consumer_key', None)
        oauth_token = parameters.get('oauth_token', None)

        if not oauth_body_hash or not oauth_signature or not oauth_consumer_key:

            msg = {
                'response': "invalid_request",
                'detail': "Required oauth parameters not provided in the uri"
            }

            return Response(msg, 500)

        if oauth_consumer_key != project_credentials['consumer_key']:
            msg = {
                'response':
                "access_denied",
                'detail':
                "oauth_consumer_key does not match project, {0}, credentials".
                format(project)
            }

            return Response(msg, 403)

        uri = '{0}://{1}{2}'.format(settings.TREEHERDER_REQUEST_PROTOCOL,
                                    request.get_host(), request.path)

        #Construct the OAuth request based on the django request object
        req_obj = oauth.Request(
            method=request.method,
            url=uri,
            parameters=parameters,
            body=json.dumps(request.DATA),
        )

        server = oauth.Server()
        token = oauth.Token(key='', secret='')

        #Get the consumer object
        cons_obj = oauth.Consumer(oauth_consumer_key,
                                  project_credentials['consumer_secret'])

        #Set the signature method
        server.add_signature_method(oauth.SignatureMethod_HMAC_SHA1())

        try:
            #verify oauth django request and consumer object match
            server.verify_request(req_obj, cons_obj, token)
        except oauth.Error:
            msg = {
                'response':
                "invalid_client",
                'detail':
                "Client authentication failed for project, {0}".format(project)
            }

            return Response(msg, 403)

        return func(request, *args, **kwargs)
Example #34
0
def post_log_artifacts(project,
                       job_guid,
                       job_log_url,
                       retry_task,
                       extract_artifacts_cb):
    """Post a list of artifacts to a job."""
    def _retry(e):
        # Initially retry after 1 minute, then for each subsequent retry
        # lengthen the retry time by another minute.
        retry_task.retry(exc=e, countdown=(1 + retry_task.request.retries) * 60)
        # .retry() raises a RetryTaskError exception,
        # so nothing after this function will be executed

    log_description = "%s %s (%s)" % (project, job_guid, job_log_url['url'])
    logger.debug("Downloading/parsing log for %s", log_description)

    credentials = OAuthCredentials.get_credentials(project)
    auth = TreeherderAuth(credentials.get('consumer_key'),
                          credentials.get('consumer_secret'),
                          project)
    client = TreeherderClient(
        protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
        host=settings.TREEHERDER_REQUEST_HOST,
        auth=auth
    )

    try:
        artifact_list = extract_artifacts_cb(project, job_log_url['url'],
                                             job_guid)
    except Exception as e:
        client.update_parse_status(project, job_log_url['id'], 'failed')
        # unrecoverable http error (doesn't exist or permission denied)
        # (apparently this can happen somewhat often with taskcluster if
        # the job fails, so just warn about it -- see
        # https://bugzilla.mozilla.org/show_bug.cgi?id=1154248)
        if isinstance(e, urllib2.HTTPError) and e.code in (403, 404):
            logger.warning("Unable to retrieve log for %s: %s",
                           log_description, e)
            return
        # possibly recoverable http error (e.g. problems on our end)
        elif isinstance(e, urllib2.URLError):
            logger.error("Failed to download log for %s: %s",
                         log_description, e)
            _retry(e)
        # parse error or other unrecoverable error
        else:
            logger.error("Failed to download/parse log for %s: %s",
                         log_description, e)
        # re-raise exception if we're not retrying, so new relic sees the
        # error
        raise

    # store the artifacts generated
    tac = TreeherderArtifactCollection()
    for artifact in artifact_list:
        ta = tac.get_artifact(artifact)
        tac.add(ta)

    try:
        client.post_collection(project, tac)
        client.update_parse_status(project, job_log_url['id'], 'parsed')
        logger.debug("Finished posting artifact for %s %s", project, job_guid)
    except Exception as e:
        logger.error("Failed to upload parsed artifact for %s: %s", log_description, e)
        _retry(e)
Example #35
0
def set_oauth_credentials():
    OAuthCredentials.set_credentials(SampleData.get_credentials())
Example #36
0
def set_oauth_credentials():
    OAuthCredentials.set_credentials(SampleData.get_credentials())
Example #37
0
def parse_log(project, job_log_url, job_guid, check_errors=False):
    """
    Call ArtifactBuilderCollection on the given job.
    """

    # if parse_status is not available, consider it pending
    parse_status = job_log_url.get("parse_status", "pending")
    # don't parse a log if it's already been parsed
    if parse_status == "parsed":
        return

    try:
        credentials = OAuthCredentials.get_credentials(project)
        req = TreeherderRequest(
            protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
            host=settings.TREEHERDER_REQUEST_HOST,
            project=project,
            oauth_key=credentials.get('consumer_key', None),
            oauth_secret=credentials.get('consumer_secret', None),
        )
        update_endpoint = 'job-log-url/{0}/update_parse_status'.format(
            job_log_url['id'])

        artifact_list = extract_log_artifacts(job_log_url['url'], job_guid,
                                              check_errors)
        # store the artifacts generated
        tac = TreeherderArtifactCollection()
        for artifact in artifact_list:
            ta = tac.get_artifact({
                "job_guid": artifact[0],
                "name": artifact[1],
                "type": artifact[2],
                "blob": artifact[3]
            })
            tac.add(ta)

        req.post(tac)

        # send an update to job_log_url
        # the job_log_url status changes from pending to parsed
        current_timestamp = time.time()
        req.send(update_endpoint,
                 method='POST',
                 data={
                     'parse_status': 'parsed',
                     'parse_timestamp': current_timestamp
                 })
    except Exception, e:
        # send an update to job_log_url
        #the job_log_url status changes from pending/running to failed
        current_timestamp = time.time()
        req.send(update_endpoint,
                 method='POST',
                 data={
                     'parse_status': 'failed',
                     'parse_timestamp': current_timestamp
                 })
        # for every retry, set the countdown to 10 minutes
        # .retry() raises a RetryTaskError exception,
        # so nothing below this line will be executed.
        parse_log.retry(exc=e, countdown=10 * 60)
Example #38
0
def post_log_artifacts(project,
                       job_guid,
                       job_log_url,
                       retry_task,
                       extract_artifacts_cb,
                       check_errors=False):
    """Post a list of artifacts to a job."""
    def _retry(e):
        # Initially retry after 1 minute, then for each subsequent retry
        # lengthen the retry time by another minute.
        retry_task.retry(exc=e, countdown=(1 + retry_task.request.retries) * 60)
        # .retry() raises a RetryTaskError exception,
        # so nothing after this function will be executed

    credentials = OAuthCredentials.get_credentials(project)
    update_endpoint = 'job-log-url/{0}/update_parse_status'.format(
        job_log_url['id']
    )

    log_description = "%s %s (%s)" % (project, job_guid, job_log_url['url'])
    logger.debug("Downloading/parsing log for %s", log_description)

    req = TreeherderRequest(
        protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
        host=settings.TREEHERDER_REQUEST_HOST,
        project=project,
        oauth_key=credentials.get('consumer_key', None),
        oauth_secret=credentials.get('consumer_secret', None),
    )

    try:
        artifact_list = extract_artifacts_cb(job_log_url['url'],
                                             job_guid, check_errors)
    except Exception as e:
        logger.error("Failed to download/parse log for %s: %s", log_description, e)
        current_timestamp = time.time()
        req.send(
            update_endpoint,
            method='POST',
            data={
                'parse_status': 'failed',
                'parse_timestamp': current_timestamp
            }
        )
        _retry(e)

    # store the artifacts generated
    tac = TreeherderArtifactCollection()
    for artifact in artifact_list:
        ta = tac.get_artifact({
            "job_guid": artifact[0],
            "name": artifact[1],
            "type": artifact[2],
            "blob": artifact[3]
        })
        tac.add(ta)

    try:
        req.post(tac)

        # send an update to job_log_url
        # the job_log_url status changes from pending to parsed
        current_timestamp = time.time()
        req.send(
            update_endpoint,
            method='POST',
            data={
                'parse_status': 'parsed',
                'parse_timestamp': current_timestamp
            }
        )
        logger.debug("Finished posting artifact for %s %s", project, job_guid)
    except Exception as e:
        logger.error("Failed to upload parsed artifact for %s: %s", log_description, e)
        _retry(e)
def parse_log(project, job_log_url, job_guid, check_errors=False):
    """
    Call ArtifactBuilderCollection on the given job.
    """
    credentials = OAuthCredentials.get_credentials(project)
    req = TreeherderRequest(
        protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
        host=settings.TREEHERDER_REQUEST_HOST,
        project=project,
        oauth_key=credentials.get('consumer_key', None),
        oauth_secret=credentials.get('consumer_secret', None),
    )
    update_endpoint = 'job-log-url/{0}/update_parse_status'.format(job_log_url['id'])

    try:
        log_url = job_log_url['url']
        bug_suggestions = []
        bugscache_uri = '{0}{1}'.format(
            settings.API_HOSTNAME,
            reverse("bugscache-list")
        )
        terms_requested = {}

        if log_url:
            # parse a log given its url
            artifact_bc = ArtifactBuilderCollection(log_url,
                                                    check_errors=check_errors)
            artifact_bc.parse()

            artifact_list = []
            for name, artifact in artifact_bc.artifacts.items():
                artifact_list.append((job_guid, name, 'json',
                                      json.dumps(artifact)))
            if check_errors:
                all_errors = artifact_bc.artifacts.get(
                    'Structured Log', {}
                    ).get(
                        'step_data', {}
                        ).get(
                            'all_errors', [] )

                for err in all_errors:
                    # remove the mozharness prefix
                    clean_line = get_mozharness_substring(err['line'])
                    # get a meaningful search term out of the error line
                    search_term = get_error_search_term(clean_line)
                    bugs = dict(open_recent=[], all_others=[])

                    # collect open recent and all other bugs suggestions
                    if search_term:
                        if not search_term in terms_requested:
                            # retrieve the list of suggestions from the api
                            bugs = get_bugs_for_search_term(
                                search_term,
                                bugscache_uri
                            )
                            terms_requested[search_term] = bugs
                        else:
                            bugs = terms_requested[search_term]

                    if not bugs or not (bugs['open_recent']
                                        or bugs['all_others']):
                        # no suggestions, try to use
                        # the crash signature as search term
                        crash_signature = get_crash_signature(clean_line)
                        if crash_signature:
                            if not crash_signature in terms_requested:
                                bugs = get_bugs_for_search_term(
                                    crash_signature,
                                    bugscache_uri
                                )
                                terms_requested[crash_signature] = bugs
                            else:
                                bugs = terms_requested[crash_signature]

                    bug_suggestions.append({
                        "search": clean_line,
                        "bugs": bugs
                    })

            artifact_list.append((job_guid, 'Bug suggestions', 'json', json.dumps(bug_suggestions)))

            # store the artifacts generated
            tac = TreeherderArtifactCollection()
            for artifact in artifact_list:
                ta = tac.get_artifact({
                    "job_guid": artifact[0],
                    "name": artifact[1],
                    "type": artifact[2],
                    "blob": artifact[3]
                })
                tac.add(ta)

            req.post(tac)

            # send an update to job_log_url
            # the job_log_url status changes
            # from pending to running
            current_timestamp = time.time()
            status = 'parsed'
            req.send(
                update_endpoint,
                method='POST',
                data={
                    'parse_status': status,
                    'parse_timestamp': current_timestamp
                }
            )

    except Exception, e:
        parse_log.retry(exc=e)
        # send an update to job_log_url
        # the job_log_url status changes
        # from pending to running
        current_timestamp = time.time()
        status = 'failed'
        req.send(
            update_endpoint,
            method='POST',
            data={
                'parse_status': status,
                'parse_timestamp': current_timestamp
            }
        )
        # re raise the exception to leave a trace in the log
        raise
Example #40
0
def parse_log(project, job_log_url, job_guid, check_errors=False):
    """
    Call ArtifactBuilderCollection on the given job.
    """
    credentials = OAuthCredentials.get_credentials(project)
    req = TreeherderRequest(
        protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
        host=settings.TREEHERDER_REQUEST_HOST,
        project=project,
        oauth_key=credentials.get('consumer_key', None),
        oauth_secret=credentials.get('consumer_secret', None),
    )
    update_endpoint = 'job-log-url/{0}/update_parse_status'.format(
        job_log_url['id'])

    try:
        log_url = job_log_url['url']
        bug_suggestions = []
        bugscache_uri = '{0}{1}'.format(settings.API_HOSTNAME,
                                        reverse("bugscache-list"))
        terms_requested = {}

        if log_url:
            # parse a log given its url
            artifact_bc = ArtifactBuilderCollection(log_url,
                                                    check_errors=check_errors)
            artifact_bc.parse()

            artifact_list = []
            for name, artifact in artifact_bc.artifacts.items():
                artifact_list.append(
                    (job_guid, name, 'json', json.dumps(artifact)))
            if check_errors:
                all_errors = artifact_bc.artifacts.get(
                    'Structured Log', {}).get('step_data',
                                              {}).get('all_errors', [])

                for err in all_errors:
                    # remove the mozharness prefix
                    clean_line = get_mozharness_substring(err['line'])
                    # get a meaningful search term out of the error line
                    search_term = get_error_search_term(clean_line)
                    bugs = dict(open_recent=[], all_others=[])

                    # collect open recent and all other bugs suggestions
                    if search_term:
                        if not search_term in terms_requested:
                            # retrieve the list of suggestions from the api
                            bugs = get_bugs_for_search_term(
                                search_term, bugscache_uri)
                            terms_requested[search_term] = bugs
                        else:
                            bugs = terms_requested[search_term]

                    if not bugs or not (bugs['open_recent']
                                        or bugs['all_others']):
                        # no suggestions, try to use
                        # the crash signature as search term
                        crash_signature = get_crash_signature(clean_line)
                        if crash_signature:
                            if not crash_signature in terms_requested:
                                bugs = get_bugs_for_search_term(
                                    crash_signature, bugscache_uri)
                                terms_requested[crash_signature] = bugs
                            else:
                                bugs = terms_requested[crash_signature]

                    bug_suggestions.append({
                        "search": clean_line,
                        "bugs": bugs
                    })

            artifact_list.append((job_guid, 'Bug suggestions', 'json',
                                  json.dumps(bug_suggestions)))

            # store the artifacts generated
            tac = TreeherderArtifactCollection()
            for artifact in artifact_list:
                ta = tac.get_artifact({
                    "job_guid": artifact[0],
                    "name": artifact[1],
                    "type": artifact[2],
                    "blob": artifact[3]
                })
                tac.add(ta)

            req.post(tac)

            # send an update to job_log_url
            # the job_log_url status changes
            # from pending to running
            current_timestamp = time.time()
            status = 'parsed'
            req.send(update_endpoint,
                     method='POST',
                     data={
                         'parse_status': status,
                         'parse_timestamp': current_timestamp
                     })

    except Exception, e:
        parse_log.retry(exc=e)
        # send an update to job_log_url
        # the job_log_url status changes
        # from pending to running
        current_timestamp = time.time()
        status = 'failed'
        req.send(update_endpoint,
                 method='POST',
                 data={
                     'parse_status': status,
                     'parse_timestamp': current_timestamp
                 })
        # re raise the exception to leave a trace in the log
        raise
Example #41
0
def parse_log(project, log_url, job_guid, resultset, check_errors=False):
    """
    Call ArtifactBuilderCollection on the given job.
    """
    mozharness_pattern = re.compile(
        '^\d+:\d+:\d+[ ]+(?:DEBUG|INFO|WARNING|ERROR|CRITICAL|FATAL) - [ ]?'
    )

    bugs_cache = {'open': {}, 'closed': {}}
    bug_suggestions = {'open': {}, 'closed': {}}

    status_publisher = JobStatusPublisher(settings.BROKER_URL)
    failure_publisher = JobFailurePublisher(settings.BROKER_URL)

    try:
        # return the resultset with the job id to identify if the UI wants
        # to fetch the whole thing.

        bugscache_uri = '{0}{1}'.format(
            settings.API_HOSTNAME,
            reverse("bugscache-list")
        )

        credentials = OAuthCredentials.get_credentials(project)

        if log_url:
            # parse a log given its url
            artifact_bc = ArtifactBuilderCollection(
                log_url,
                check_errors=check_errors,
            )
            artifact_bc.parse()

            artifact_list = []
            for name, artifact in artifact_bc.artifacts.items():
                artifact_list.append((job_guid, name, 'json', json.dumps(artifact)))

            if check_errors:
                all_errors = artifact_bc.artifacts['Structured Log']['step_data']['all_errors']
                for err in all_errors:
                    # remove the mozharness prefix
                    clean_line = mozharness_pattern.sub('', err['line']).strip()
                    # get a meaningful search term out of the error line
                    search_term = get_error_search_term(clean_line)
                    # collect open and closed bugs suggestions
                    for status in ('open', 'closed'):
                        if not search_term:
                            bug_suggestions[status][clean_line] = []
                            continue
                        if search_term not in bugs_cache[status]:
                            # retrieve the list of suggestions from the api
                            bugs_cache[status][search_term] = get_bugs_for_search_term(
                                search_term,
                                status,
                                bugscache_uri
                            )
                            # no suggestions, try to use the crash signature as search term
                            if not bugs_cache[status][search_term]:
                                crash_signature = get_crash_signature(search_term)
                                if crash_signature:
                                    bugs_cache[status][search_term] = get_bugs_for_search_term(
                                        search_term,
                                        status,
                                        bugscache_uri
                                    )
                        bug_suggestions[status][clean_line] = bugs_cache[status][search_term]

                artifact_list.append((job_guid, 'Open bugs', 'json', json.dumps(bug_suggestions['open'])))
                artifact_list.append((job_guid, 'Closed bugs', 'json', json.dumps(bug_suggestions['closed'])))

            # store the artifacts generated
            tac = TreeherderArtifactCollection()
            for artifact in artifact_list:
                ta = tac.get_artifact({
                    "job_guid": artifact[0],
                    "name": artifact[1],
                    "type": artifact[2],
                    "blob": artifact[3]
                })
                tac.add(ta)
            req = TreeherderRequest(
                protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
                host=settings.TREEHERDER_REQUEST_HOST,
                project=project,
                oauth_key=credentials.get('consumer_key', None),
                oauth_secret=credentials.get('consumer_secret', None),
            )
            req.send(tac)

        status_publisher.publish(job_guid, resultset, project, 'processed')
        if check_errors:
            failure_publisher.publish(job_guid, project)

    finally:
        status_publisher.disconnect()
        failure_publisher.disconnect()
Example #42
0
def parse_log(project, job_log_url, job_guid, check_errors=False):
    """
    Call ArtifactBuilderCollection on the given job.
    """

    # if parse_status is not available, consider it pending
    parse_status = job_log_url.get("parse_status", "pending")
    # don't parse a log if it's already been parsed
    if parse_status == "parsed":
        return

    try:
        credentials = OAuthCredentials.get_credentials(project)
        req = TreeherderRequest(
            protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
            host=settings.TREEHERDER_REQUEST_HOST,
            project=project,
            oauth_key=credentials.get('consumer_key', None),
            oauth_secret=credentials.get('consumer_secret', None),
        )
        update_endpoint = 'job-log-url/{0}/update_parse_status'.format(
            job_log_url['id'])

        logger.debug("Downloading and extracting log information for guid "
                     "'%s' (from %s)" % (job_guid, job_log_url['url']))

        artifact_list = extract_log_artifacts(job_log_url['url'], job_guid,
                                              check_errors)
        # store the artifacts generated
        tac = TreeherderArtifactCollection()
        for artifact in artifact_list:
            ta = tac.get_artifact({
                "job_guid": artifact[0],
                "name": artifact[1],
                "type": artifact[2],
                "blob": artifact[3]
            })
            tac.add(ta)

        logger.debug("Finished downloading and processing artifact for guid "
                     "'%s'" % job_guid)

        req.post(tac)

        # send an update to job_log_url
        # the job_log_url status changes from pending to parsed
        current_timestamp = time.time()
        req.send(update_endpoint,
                 method='POST',
                 data={
                     'parse_status': 'parsed',
                     'parse_timestamp': current_timestamp
                 })

        logger.debug("Finished posting artifact for guid '%s'" % job_guid)

    except Exception, e:
        # send an update to job_log_url
        #the job_log_url status changes from pending/running to failed
        logger.warn("Failed to download and/or parse artifact for guid '%s'" %
                    job_guid)
        current_timestamp = time.time()
        req.send(update_endpoint,
                 method='POST',
                 data={
                     'parse_status': 'failed',
                     'parse_timestamp': current_timestamp
                 })
        # Initially retry after 1 minute, then for each subsequent retry
        # lengthen the retry time by another minute.
        parse_log.retry(exc=e, countdown=(1 + parse_log.request.retries) * 60)
Example #43
0
    def wrap_oauth(cls, *args, **kwargs):

        # First argument must be request object
        request = args[0]

        # Get the project keyword argumet
        project = kwargs.get('project', None)

        # Get the project credentials
        project_credentials = OAuthCredentials.get_credentials(project)

        if not project_credentials:
            msg = {
                'response': "invalid_request",
                'detail': "project, {0}, has no OAuth credentials".format(project)
            }
            return Response(msg, 500)

        parameters = OAuthCredentials.get_parameters(request.QUERY_PARAMS)

        oauth_body_hash = parameters.get('oauth_body_hash', None)
        oauth_signature = parameters.get('oauth_signature', None)
        oauth_consumer_key = parameters.get('oauth_consumer_key', None)
        oauth_token = parameters.get('oauth_token', None)

        if not oauth_body_hash or not oauth_signature or not oauth_consumer_key:

            msg = {
                'response':"invalid_request",
                'detail':"Required oauth parameters not provided in the uri"
                }

            return Response(msg, 500)

        if oauth_consumer_key != project_credentials['consumer_key']:
            msg = {
                'response':"access_denied",
                'detail':"oauth_consumer_key does not match project, {0}, credentials".format(project)
                }

            return Response(msg, 403)

        uri = '{0}://{1}{2}'.format(
            settings.TREEHERDER_REQUEST_PROTOCOL, request.get_host(),
            request.path
            )

        #Construct the OAuth request based on the django request object
        req_obj = oauth.Request(
            method=request.method,
            url=uri,
            parameters=parameters,
            body=json.dumps(request.DATA),
            )

        server = oauth.Server()
        token = oauth.Token(key='', secret='')

        #Get the consumer object
        cons_obj = oauth.Consumer(
            oauth_consumer_key,
            project_credentials['consumer_secret']
            )

        #Set the signature method
        server.add_signature_method(oauth.SignatureMethod_HMAC_SHA1())

        try:
            #verify oauth django request and consumer object match
            server.verify_request(req_obj, cons_obj, token)
        except oauth.Error:
            msg = {
                'response':"invalid_client",
                'detail':"Client authentication failed for project, {0}".format(project)
                }

            return Response(msg, 403)

        return func(request, *args, **kwargs)
Example #44
0
def parse_log(project, job_log_url, job_guid, check_errors=False):
    """
    Call ArtifactBuilderCollection on the given job.
    """

    # if parse_status is not available, consider it pending
    parse_status = job_log_url.get("parse_status", "pending")
    # don't parse a log if it's already been parsed
    if parse_status == "parsed":
        return

    try:
        credentials = OAuthCredentials.get_credentials(project)
        req = TreeherderRequest(
            protocol=settings.TREEHERDER_REQUEST_PROTOCOL,
            host=settings.TREEHERDER_REQUEST_HOST,
            project=project,
            oauth_key=credentials.get('consumer_key', None),
            oauth_secret=credentials.get('consumer_secret', None),
        )
        update_endpoint = 'job-log-url/{0}/update_parse_status'.format(
            job_log_url['id']
        )

        artifact_list = extract_log_artifacts(job_log_url['url'],
                                              job_guid, check_errors)
        # store the artifacts generated
        tac = TreeherderArtifactCollection()
        for artifact in artifact_list:
            ta = tac.get_artifact({
                "job_guid": artifact[0],
                "name": artifact[1],
                "type": artifact[2],
                "blob": artifact[3]
            })
            tac.add(ta)

        req.post(tac)

        # send an update to job_log_url
        # the job_log_url status changes from pending to parsed
        current_timestamp = time.time()
        req.send(
            update_endpoint,
            method='POST',
            data={
                'parse_status': 'parsed',
                'parse_timestamp': current_timestamp
            }
        )
    except Exception, e:
        # send an update to job_log_url
        #the job_log_url status changes from pending/running to failed
        current_timestamp = time.time()
        req.send(
            update_endpoint,
            method='POST',
            data={
                'parse_status': 'failed',
                'parse_timestamp': current_timestamp
            }
        )
        # for every retry, set the countdown to 10 minutes
        # .retry() raises a RetryTaskError exception,
        # so nothing below this line will be executed.
        parse_log.retry(exc=e, countdown=10*60)