def test_job_data_type_validation(self):

        tj = TreeherderJob(self.job_data[0])

        # Test detection of undefined value
        tj.data['job'] = []
        self.assertRaises(TreeherderClientError, tj.validate)

        # Test detection of incorrect property type
        tj.data['job'] = ['blah', 'blah', 'blah']
        self.assertRaises(TreeherderClientError, tj.validate)
    def test_job_data_type_validation(self):

        tj = TreeherderJob(self.job_data[0])

        # Test detection of undefined value
        tj.data['job'] = []
        self.assertRaises(TreeherderClientError, tj.validate)

        # Test detection of incorrect property type
        tj.data['job'] = ['blah', 'blah', 'blah']
        self.assertRaises(TreeherderClientError, tj.validate)
 def serve_forever(self):
     logger = utils.getLogger()
     while not self.shutdown_requested:
         wait_seconds = 1  # avoid busy loop
         job = self.jobs.get_next_treeherder_job()
         if job:
             tjc = TreeherderJobCollection()
             for data in job['job_collection']:
                 tj = TreeherderJob(data)
                 tjc.add(tj)
             if self.post_request(job['machine'], job['project'], tjc,
                                  job['attempts'], job['last_attempt']):
                 self.jobs.treeherder_job_completed(job['id'])
                 wait_seconds = 0
             else:
                 attempts = int(job['attempts'])
                 wait_seconds = min(self.retry_wait * attempts, 3600)
                 logger.debug(
                     'AutophoneTreeherder waiting for %d seconds after '
                     'failed attempt %d', wait_seconds, attempts)
         if wait_seconds > 0:
             for i in range(wait_seconds):
                 if self.shutdown_requested:
                     break
                 time.sleep(1)
Пример #4
0
    def __init__(self, job_type, product_name, locale, update_number=None):
        TreeherderJob.__init__(self, data={})

        self._details = []

        self.add_job_guid(str(uuid.uuid4()))
        self.add_tier(3)

        self.add_state('running')

        self.add_product_name(product_name)

        # Add platform and build information
        self.add_machine(socket.getfqdn())
        platform = self._get_treeherder_platform()
        self.add_machine_info(*platform)
        self.add_build_info(*platform)

        # TODO debug or others?
        self.add_option_collection({'opt': True})

        group_name = 'Firefox UI Test - {type}'.format(type=job_type)
        group_symbol = 'F{type_id}'.format(type_id=job_type[0])

        # Bug 1174973 - for now we need unique job names even in different groups
        job_name = '{group} ({locale}{update_number})'.format(
            group=group_name,
            locale=locale,
            update_number='-{}'.format(update_number) if update_number else ''
        )
        job_symbol = '{locale}{update_number}'.format(
            locale=locale,
            update_number='-{}'.format(update_number) if update_number else ''
        )

        # TODO: Add e10s group later
        self.add_group_name(group_name)
        self.add_group_symbol(group_symbol)

        self.add_job_name(job_name)
        self.add_job_symbol(job_symbol)

        self.add_start_timestamp(int(time.time()))

        # Bug 1175559 - Workaround for HTTP Error
        self.add_end_timestamp(0)
    def test_job_collection(self):
        """Confirm the collection matches the sample data"""
        tjc = TreeherderJobCollection()

        for job in self.job_data:
            tj = TreeherderJob(job)
            tjc.add(tj)

        self.assertTrue(len(self.job_data) == len(tjc.data))
    def test_job_guid_validation(self):

        tj = TreeherderJob(self.job_data[0])
        tj.data['job']['job_guid'] = None

        self.assertRaises(TreeherderClientError, tj.validate)
    def test_job_sample_data(self):

        for job in self.job_data:

            tj = TreeherderJob()

            tj.add_revision_hash( job['revision_hash'] )
            tj.add_project( job['project'] )
            tj.add_coalesced_guid( job['coalesced'] )
            tj.add_job_guid( job['job']['job_guid'] )
            tj.add_job_name( job['job']['name'] )
            tj.add_job_symbol( job['job']['job_symbol'] )
            tj.add_group_name( job['job']['group_name'] )
            tj.add_group_symbol( job['job']['group_symbol'] )
            tj.add_description( job['job']['desc'] )
            tj.add_product_name( job['job']['product_name'] )
            tj.add_state( job['job']['state'] )
            tj.add_result( job['job']['result'] )
            tj.add_reason( job['job']['reason'] )
            tj.add_who( job['job']['who'] )
            tj.add_submit_timestamp( job['job']['submit_timestamp'] )
            tj.add_start_timestamp( job['job']['start_timestamp'] )
            tj.add_end_timestamp( job['job']['end_timestamp'] )
            tj.add_machine( job['job']['machine'] )
            tj.add_build_url( job['job']['build_url'] )

            tj.add_build_info(
                job['job']['build_platform']['os_name'],
                job['job']['build_platform']['platform'],
                job['job']['build_platform']['architecture']
                )

            tj.add_machine_info(
                job['job']['machine_platform']['os_name'],
                job['job']['machine_platform']['platform'],
                job['job']['machine_platform']['architecture']
                )

            tj.add_option_collection( job['job']['option_collection'] )

            tj.add_log_reference(
                'builds-4h', job['job']['log_references'][0]['url'] )

            # if the blob is empty, TreeherderJob will ignore the insertion
            job['job']['artifacts'][0]['blob'] = "some value"

            tj.add_artifact(
                job['job']['artifacts'][0]['name'],
                job['job']['artifacts'][0]['type'],
                job['job']['artifacts'][0]['blob'])

            self.compare_structs(tj.data, job)

            # Confirm we get the same dict if we initialize from
            # a job dict
            tj_dict = TreeherderJob(job)
            self.compare_structs(tj.data, tj_dict.data)
    def create_job(self, guid, **kwargs):
        job = TreeherderJob()

        job.add_job_guid(guid)

        job.add_product_name('mozreview')

        job.add_project(self.repository)
        job.add_revision(self.revision)

        # Add platform and build information
        job.add_machine(socket.getfqdn())
        platform = self.get_treeherder_platform()

        job.add_machine_info(*platform)
        job.add_build_info(*platform)

        # TODO debug or others?
        job.add_option_collection({'opt': True})

        # TODO: Add e10s group once we run those tests
        job.add_group_name(self.settings['treeherder']['group_name'].format(**kwargs))
        job.add_group_symbol(self.settings['treeherder']['group_symbol'].format(**kwargs))

        # Bug 1174973 - for now we need unique job names even in different groups
        job.add_job_name(self.settings['treeherder'][self.test_suite]['job_name'].format(**kwargs))
        job.add_job_symbol(self.settings['treeherder'][self.test_suite]['job_symbol'].format(**kwargs))

        # request time and start time same is fine
        job.add_submit_timestamp(int(self.start_time))

        # test start time for that paraticular app is set in jenkins job itself
        job.add_start_timestamp(int(self.start_time))

        # Bug 1175559 - Workaround for HTTP Error
        job.add_end_timestamp(0)

        return job
Пример #9
0
def create_treeherder_job(repo, revision, client, nodes, s3=None):
    """
    Creates a treeherder job for the given set of data.

    :param repo: The repository this build came from.
    :param revision: The mercurial revision of the build.
    :param client: The TreeherderClient to use.
    :param nodes: The dataset for this build.
    :param s3: Optional Amazon S3 bucket to upload logs to.
    """
    tj = TreeherderJob()
    tj.add_tier(2)
    tj.add_revision(revision)
    tj.add_project(repo)

    tj.add_job_name('awsy 1')
    tj.add_job_symbol('a1')
    tj.add_group_name('awsy')
    tj.add_group_symbol('AWSY')

    tj.add_product_name('firefox')
    tj.add_state('completed')
    tj.add_result('success')
    submit_timestamp = int(time.time())
    tj.add_submit_timestamp(submit_timestamp)
    tj.add_start_timestamp(submit_timestamp)
    tj.add_end_timestamp(submit_timestamp)
    tj.add_machine(socket.getfqdn())

    tj.add_build_info('linux', 'linux64', 'x86_64')
    tj.add_machine_info('linux', 'linux64', 'x86_64')
    tj.add_option_collection({'opt': True})

    perf_blob = create_perf_data(nodes)
    perf_data = json.dumps({ 'performance_data': perf_blob })

    # Set the job guid to a combination of the revision and the job data. This
    # gives us a reasonably unique guid, but is also reproducible for the same
    # set of data.
    job_guid = hashlib.sha1(revision + perf_data)
    tj.add_job_guid(job_guid.hexdigest())

    # NB: The job guid must be set prior to adding artifacts.
    tj.add_artifact('performance_data', 'json', perf_data)

    # If an S3 connection is provided the logs for this revision are uploaded.
    # Addtionally a 'Job Info' blob is built up with links to the logs that
    # will be displayed in the 'Job details' pane in treeherder.
    if s3:
        job_details = []

        # To avoid overwriting existing data (perhaps if a job is retriggered)
        # the job guid is included in the key.
        log_prefix = "%s/%s/%s" % (repo, revision, job_guid.hexdigest())

        # Add the test log.
        log_id = '%s/%s' % (log_prefix, 'awsy_test_raw.log')
        job_detail = upload_artifact(s3, 'logs/%s.test.log' % revision,
                                     log_id, 'awsy_test.log')
        if 'url' in job_detail:
            # The test log is the main log and will be linked to the log
            # viewer and raw log icons in treeherder.
            tj.add_log_reference('test.log', job_detail['url'])
        job_details.append(job_detail)

        # Add the gecko log.
        log_id = '%s/%s' % (log_prefix, 'gecko.log')
        job_detail = upload_artifact(s3, "logs/%s.gecko.log" % revision,
                                     log_id, 'gecko.log')
        job_details.append(job_detail)

        tj.add_artifact('Job Info', 'json', { 'job_details': job_details })

    return tj
Пример #10
0
    def create_job(self, guid, **kwargs):
        job = TreeherderJob()

        job.add_job_guid(guid)
        job.add_tier(self.settings['treeherder']['tier'])

        job.add_product_name('firefox')

        job.add_project(self.repository)
        job.add_revision_hash(self.retrieve_revision_hash())

        # Add platform and build information
        job.add_machine(socket.getfqdn())
        platform = self._get_treeherder_platform()
        job.add_machine_info(*platform)
        job.add_build_info(*platform)

        # TODO debug or others?
        job.add_option_collection({'opt': True})

        # TODO: Add e10s group once we run those tests
        job.add_group_name(self.settings['treeherder']['group_name'].format(**kwargs))
        job.add_group_symbol(self.settings['treeherder']['group_symbol'].format(**kwargs))

        # Bug 1174973 - for now we need unique job names even in different groups
        job.add_job_name(self.settings['treeherder']['job_name'].format(**kwargs))
        job.add_job_symbol(self.settings['treeherder']['job_symbol'].format(**kwargs))

        job.add_start_timestamp(int(time.time()))

        # Bug 1175559 - Workaround for HTTP Error
        job.add_end_timestamp(0)

        return job
    def test_sample_data_validation(self):

        for job in self.job_data:

            tj = TreeherderJob(job)
            tj.validate()
    def test_project_validation(self):

        tj = TreeherderJob(self.job_data[0])
        tj.data['project'] = None
        self.assertRaises(TreeherderClientError, tj.validate)
    def test_job_guid_validation(self):

        tj = TreeherderJob(self.job_data[0])
        tj.data['job']['job_guid'] = None

        self.assertRaises(TreeherderClientError, tj.validate)
    def test_job_sample_data(self):

        for job in self.job_data:

            tj = TreeherderJob()

            tj.add_revision_hash(job['revision_hash'])
            tj.add_project(job['project'])
            tj.add_coalesced_guid(job['coalesced'])
            tj.add_job_guid(job['job']['job_guid'])
            tj.add_job_name(job['job']['name'])
            tj.add_job_symbol(job['job']['job_symbol'])
            tj.add_group_name(job['job']['group_name'])
            tj.add_group_symbol(job['job']['group_symbol'])
            tj.add_description(job['job']['desc'])
            tj.add_product_name(job['job']['product_name'])
            tj.add_state(job['job']['state'])
            tj.add_result(job['job']['result'])
            tj.add_reason(job['job']['reason'])
            tj.add_who(job['job']['who'])
            tj.add_submit_timestamp(job['job']['submit_timestamp'])
            tj.add_start_timestamp(job['job']['start_timestamp'])
            tj.add_end_timestamp(job['job']['end_timestamp'])
            tj.add_machine(job['job']['machine'])
            tj.add_build_url(job['job']['build_url'])

            tj.add_build_info(job['job']['build_platform']['os_name'],
                              job['job']['build_platform']['platform'],
                              job['job']['build_platform']['architecture'])

            tj.add_machine_info(job['job']['machine_platform']['os_name'],
                                job['job']['machine_platform']['platform'],
                                job['job']['machine_platform']['architecture'])

            tj.add_option_collection(job['job']['option_collection'])

            tj.add_log_reference('builds-4h',
                                 job['job']['log_references'][0]['url'])

            # if the blob is empty, TreeherderJob will ignore the insertion
            job['job']['artifacts'][0]['blob'] = "some value"

            tj.add_artifact(job['job']['artifacts'][0]['name'],
                            job['job']['artifacts'][0]['type'],
                            job['job']['artifacts'][0]['blob'])

            self.compare_structs(tj.data, job)

            # Confirm we get the same dict if we initialize from
            # a job dict
            tj_dict = TreeherderJob(job)
            self.compare_structs(tj.data, tj_dict.data)
    def test_project_validation(self):

        tj = TreeherderJob(self.job_data[0])
        tj.data['project'] = None
        self.assertRaises(TreeherderClientError, tj.validate)
    def create_job(self, guid, **kwargs):
        job = TreeherderJob()

        job.add_job_guid(guid)

        job.add_product_name('raptor')

        job.add_project(self.repository)
        job.add_revision_hash(self.retrieve_revision_hash())

        # Add platform and build information
        job.add_machine(socket.getfqdn())
        platform = ("", "B2G Raptor %s %s" % (self.device, self.memory), "")
        job.add_machine_info(*platform)
        job.add_build_info(*platform)

        # TODO debug or others?
        job.add_option_collection({'opt': True})

        # TODO: Add e10s group once we run those tests
        job.add_group_name(self.settings['treeherder']['group_name'].format(**kwargs))
        job.add_group_symbol(self.settings['treeherder']['group_symbol'].format(**kwargs))

        # Bug 1174973 - for now we need unique job names even in different groups
        job.add_job_name(self.settings['treeherder']['job_name'].format(**kwargs) + ' (' + self.app_name + ')')
        if self.test_type == COLD_LAUNCH:
            job.add_job_symbol(self.settings['treeherder']['job_symbol'][self.app_name].format(**kwargs))
        else:
            job.add_job_symbol(self.settings['treeherder']['job_symbol'].format(**kwargs))

        # request time will be the jenkins TEST_TIME i.e. when jenkins job started
        job.add_submit_timestamp(int(os.environ['TEST_TIME']))

        # test start time for that paraticular app is set in jenkins job itself
        job.add_start_timestamp(int(self.start_time))

        # Bug 1175559 - Workaround for HTTP Error
        job.add_end_timestamp(0)

        return job
    def test_sample_data_validation(self):

        for job in self.job_data:

            tj = TreeherderJob(job)
            tj.validate()
    def create_job(self, guid, **kwargs):
        job = TreeherderJob()

        job.add_job_guid(guid)

        job.add_product_name('raptor')

        job.add_project(self.repository)
        job.add_revision_hash(self.retrieve_revision_hash())

        # Add platform and build information
        job.add_machine(socket.getfqdn())
        platform = ("", "B2G Raptor %s %s" % (self.device, self.memory), "")
        job.add_machine_info(*platform)
        job.add_build_info(*platform)

        # TODO debug or others?
        job.add_option_collection({'opt': True})

        # TODO: Add e10s group once we run those tests
        job.add_group_name(
            self.settings['treeherder']['group_name'].format(**kwargs))
        job.add_group_symbol(
            self.settings['treeherder']['group_symbol'].format(**kwargs))

        # Bug 1174973 - for now we need unique job names even in different groups
        job.add_job_name(self.settings['treeherder']['job_name'].format(
            **kwargs) + ' (' + self.app_name + ')')
        if self.test_type == COLD_LAUNCH:
            job.add_job_symbol(self.settings['treeherder']['job_symbol'][
                self.app_name].format(**kwargs))
        else:
            job.add_job_symbol(
                self.settings['treeherder']['job_symbol'].format(**kwargs))

        # request time will be the jenkins TEST_TIME i.e. when jenkins job started
        job.add_submit_timestamp(int(os.environ['TEST_TIME']))

        # test start time for that paraticular app is set in jenkins job itself
        job.add_start_timestamp(int(self.start_time))

        # Bug 1175559 - Workaround for HTTP Error
        job.add_end_timestamp(0)

        return job
Пример #19
0
    def create_job(self, data=None, **kwargs):
        """Creates a new instance of a Treeherder job for submission.

        :param data: Job data to use for initilization, e.g. from a previous submission, optional
        :param kwargs: Dictionary of necessary values to build the job details. The
            properties correlate to the placeholders in config.py.

        """
        data = data or {}

        job = TreeherderJob(data=data)

        # If no data is available we have to set all properties
        if not data:
            job.add_job_guid(str(uuid.uuid4()))
            job.add_tier(self.settings['treeherder']['tier'])

            job.add_product_name('firefox')

            job.add_project(self.repository)
            job.add_revision_hash(self.retrieve_revision_hash())

            # Add platform and build information
            job.add_machine(socket.getfqdn())
            platform = self._get_treeherder_platform()
            job.add_machine_info(*platform)
            job.add_build_info(*platform)

            # TODO debug or others?
            job.add_option_collection({'opt': True})

            # TODO: Add e10s group once we run those tests
            job.add_group_name(self.settings['treeherder']['group_name'].format(**kwargs))
            job.add_group_symbol(self.settings['treeherder']['group_symbol'].format(**kwargs))

            # Bug 1174973 - for now we need unique job names even in different groups
            job.add_job_name(self.settings['treeherder']['job_name'].format(**kwargs))
            job.add_job_symbol(self.settings['treeherder']['job_symbol'].format(**kwargs))

            job.add_start_timestamp(int(time.time()))

            # Bug 1175559 - Workaround for HTTP Error
            job.add_end_timestamp(0)

        return job
Пример #20
0
def create_treeherder_job(repo, revision, client, nodes):
    """
    Creates a treeherder job for the given set of data.

    :param repo: The repository this build came from.
    :param revision: The mercurial revision of the build.
    :param client: The TreeherderClient to use.
    :param nodes: The dataset for this build.
    """
    rev_hash = client.get_resultsets(repo, revision=revision)[0]['revision_hash']

    tj = TreeherderJob()
    tj.add_tier(2)
    tj.add_revision_hash(rev_hash)
    tj.add_project(repo)
    tj.add_job_guid(str(uuid.uuid4()))

    tj.add_job_name('awsy 1')
    tj.add_job_symbol('a1')
    tj.add_group_name('awsy')
    tj.add_group_symbol('AWSY')

    tj.add_product_name('firefox')
    tj.add_state('completed')
    tj.add_result('success')
    submit_timestamp = int(time.time())
    tj.add_submit_timestamp(submit_timestamp)
    tj.add_start_timestamp(submit_timestamp)
    tj.add_end_timestamp(submit_timestamp)
    tj.add_machine(socket.getfqdn())

    tj.add_build_info('linux', 'linux64', 'x86_64')
    tj.add_machine_info('linux', 'linux64', 'x86_64')
    tj.add_option_collection({'opt': True})

    perf_blob = create_perf_data(nodes)
    tj.add_artifact('performance_data', 'json', json.dumps({ 'performance_data': perf_blob }))

    return tj