Example #1
0
 def test_multiple_response_job(self):
     out = run_client(['bkr', 'job-modify', self.job.t_id, self.job_for_rs.t_id,  '--response', 'ack'])
     self.assert_(out == 'Successfully modified jobs %s %s\n' % (self.job.t_id, self.job_for_rs.t_id))
     j = TaskBase.get_by_t_id(self.job.t_id)
     for rs in j.recipesets:
         self.assert_('%s' % rs.nacked.response == 'ack')
     j2 = TaskBase.get_by_t_id(self.job_for_rs.t_id)
     for rs in j2.recipesets:
         self.assert_('%s' % rs.nacked.response == 'ack')
Example #2
0
 def test_multiple_response_recipeset(self):
     out = run_client(['bkr', 'job-modify', self.job.recipesets[0].t_id,
                       self.job_for_rs.recipesets[0].t_id,  '--response', 'ack'])
     self.assert_('Successfully modified jobs' in out and \
                  self.job_for_rs.recipesets[0].t_id in out and \
                  self.job.recipesets[0].t_id in out,)
     rs = TaskBase.get_by_t_id(self.job.recipesets[0].t_id)
     self.assert_('%s' % rs.nacked.response == 'ack')
     rs = TaskBase.get_by_t_id(self.job_for_rs.recipesets[0].t_id)
     self.assert_('%s' % rs.nacked.response == 'ack')
Example #3
0
    def test_multiple_response_job(self):
        out = run_client(['bkr', 'job-modify', self.job.t_id, self.job_for_rs.t_id,  '--response', 'ack'])

        self.assert_('Successfully modified jobs' in out and
                     self.job.t_id in out and
                     self.job_for_rs.t_id in out)
        j = TaskBase.get_by_t_id(self.job.t_id)
        for rs in j.recipesets:
            self.assert_('%s' % rs.nacked.response == 'ack')
        j2 = TaskBase.get_by_t_id(self.job_for_rs.t_id)
        for rs in j2.recipesets:
            self.assert_('%s' % rs.nacked.response == 'ack')
 def test_can_reserve_manual_system(self):
     with session.begin():
         broken_system = data_setup.create_system(arch=u'i386', shared=True,
                                                  status=SystemStatus.broken,
                                                  lab_controller=self.lc)
         manual_system = data_setup.create_system(arch=u'i386', shared=True,
                                                  status=SystemStatus.manual,
                                                  lab_controller=self.lc)
     b = self.browser
     login(b)
     # broken system should not be present
     go_to_reserve_systems(b, distro_tree=self.distro_tree_i386)
     search_for_system(b, broken_system)
     check_system_search_results(b, absent=[broken_system])
     # provision manual system
     go_to_reserve_systems(b, distro_tree=self.distro_tree_i386)
     search_for_system(b, manual_system)
     row = b.find_element_by_xpath('//tr[normalize-space(string(td))="%s"]' % manual_system.fqdn)
     row.find_element_by_link_text('Reserve Now').click()
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//td[preceding-sibling::th/text()="Job ID"]/a').text
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         cloned_job_xml = job.to_xml(clone=True).toxml() # cloning re-parses hostRequires
         self.assertIn(
             u'<hostRequires force="%s"/>' % manual_system.fqdn,
             cloned_job_xml)
Example #5
0
def update_recipeset_by_taskspec(taskspec):
    """
    Updates the attributes of a recipe set identified by a taskspec. The valid type
    of a taskspec is either J(job) or RS(recipe-set). If a taskspec format is
    J:<id>, all the recipe sets in this job will be updated. The request must be
    :mimetype:`application/json`.

    :param taskspec: A taskspec argument that identifies a job or recipe set.
    :jsonparam string priority: Priority for the recipe set. Must be one of 
      'Low', 'Medium', 'Normal', 'High', or 'Urgent'. This can only be changed 
      while a recipe set is still queued. Job owners can generally only 
      *decrease* the priority of their recipe set, queue admins can increase 
      it.
    :jsonparam boolean waived: If true, the recipe set will be waived, regardless
      of its result.
    """
    if not taskspec.startswith(('J', 'RS')):
        raise BadRequest400('Taskspec type must be one of [J, RS]')
    try:
        obj = TaskBase.get_by_t_id(taskspec)
    except BeakerException as exc:
        raise NotFound404(unicode(exc))
    data = read_json_request(request)
    if isinstance(obj, Job):
        for rs in obj.recipesets:
            _update_recipeset(rs, data)
    elif isinstance(obj, RecipeSet):
        _update_recipeset(obj, data)
    return jsonify(obj.__json__())
Example #6
0
    def set_retention_product(self, job_t_id, retention_tag_name, product_name):
        """
        XML-RPC method to update a job's retention tag, product, or both.

        There is an important distinction between product_name of None, which 
        means do not change the existing value, vs. empty string, which means 
        clear the existing product.
        """
        job = TaskBase.get_by_t_id(job_t_id)
        if job.can_change_product(identity.current.user) and \
            job.can_change_retention_tag(identity.current.user):
            if retention_tag_name and product_name:
                retention_tag = RetentionTag.by_name(retention_tag_name)
                product = Product.by_name(product_name)
                result = Utility.update_retention_tag_and_product(job,
                        retention_tag, product)
            elif retention_tag_name and product_name == '':
                retention_tag = RetentionTag.by_name(retention_tag_name)
                result = Utility.update_retention_tag_and_product(job,
                        retention_tag, None)
            elif retention_tag_name:
                retention_tag = RetentionTag.by_name(retention_tag_name)
                result = Utility.update_retention_tag(job, retention_tag)
            elif product_name:
                product = Product.by_name(product_name)
                result = Utility.update_product(job, product)
            elif product_name == '':
                result = Utility.update_product(job, None)
            else:
                result = {'success': False, 'msg': 'Nothing to do'}

            if not result['success'] is True:
                raise BeakerException('Job %s not updated: %s' % (job.id, result.get('msg', 'Unknown reason')))
        else:
            raise BeakerException('No permission to modify %s' % job)
Example #7
0
 def test_preserves_lab_requirement(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + 'reserveworkflow')
     Select(b.find_element_by_name('osmajor'))\
         .select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name('distro')).select_by_visible_text(
         self.distro.name)
     Select(b.find_element_by_name('distro_tree_id'))\
         .select_by_visible_text('%s Server i386' % self.distro.name)
     b.find_element_by_xpath(
         '//label[contains(string(.), "Any system from lab:")]'
         '/input[@type="radio"]').click()
     Select(b.find_element_by_name('lab')).select_by_visible_text(
         self.lc.fqdn)
     b.find_element_by_xpath(
         '//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//h1//span[@class="job-id"]').text
     wb_descr = (WORKFLOW_DESCR %
                 (self.distro.name, "any lab system", "86400"))
     wboard = b.find_element_by_class_name('job-whiteboard')
     self.assertIn(wb_descr,
                   wboard.text,
                   msg="Fail to match default whiteboard")
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         cloned_job_xml = lxml.etree.tostring(
             job.to_xml(clone=True),
             encoding=unicode)  # cloning re-parses hostRequires
         self.assertIn(
             u'<hostRequires><labcontroller op="=" value="%s"/>'
             u'<system_type op="=" value="Machine"/></hostRequires>' %
             self.lc.fqdn, cloned_job_xml)
Example #8
0
 def test_reserve_time(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + 'reserveworkflow/')
     Select(b.find_element_by_name('osmajor'))\
         .select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name('distro')).select_by_visible_text(
         self.distro.name)
     Select(b.find_element_by_name('distro_tree_id'))\
         .select_by_visible_text('%s Server i386' % self.distro.name)
     b.find_element_by_name('reserve_duration').clear()
     b.find_element_by_name('reserve_duration').send_keys('96')
     b.find_element_by_xpath('.//button[text()="Hours"]').click()
     b.find_element_by_xpath(
         '//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     jid = b.find_element_by_xpath('//h1//span[@class="job-id"]').text
     with session.begin():
         job = TaskBase.get_by_t_id(jid)
         reserve_task = job.recipesets[0].recipes[0].tasks[1]
         self.assertEquals(reserve_task.task.name,
                           '/distribution/reservesys')
         self.assertEquals(reserve_task.params[0].name, 'RESERVETIME')
         self.assertEquals(reserve_task.params[0].value,
                           '345600')  # 4 days in seconds
Example #9
0
 def test_can_reserve_manual_system(self):
     with session.begin():
         broken_system = data_setup.create_system(
             arch=u"i386", shared=True, status=SystemStatus.broken, lab_controller=self.lc
         )
         manual_system = data_setup.create_system(
             arch=u"i386", shared=True, status=SystemStatus.manual, lab_controller=self.lc
         )
     b = self.browser
     login(b)
     # broken system should not be present
     go_to_reserve_systems(b, distro_tree=self.distro_tree_i386)
     search_for_system(b, broken_system)
     check_system_search_results(b, absent=[broken_system])
     # provision manual system
     go_to_reserve_systems(b, distro_tree=self.distro_tree_i386)
     search_for_system(b, manual_system)
     row = b.find_element_by_xpath('//tr[normalize-space(string(td))="%s"]' % manual_system.fqdn)
     row.find_element_by_link_text("Reserve Now").click()
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//td[preceding-sibling::th/text()="Job ID"]/a').text
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         cloned_job_xml = job.to_xml(clone=True).toxml()  # cloning re-parses hostRequires
         self.assertIn(u'<hostRequires force="%s"/>' % manual_system.fqdn, cloned_job_xml)
Example #10
0
    def set_retention_product(self, job_t_id, retention_tag_name,
                              product_name):
        """
        XML-RPC method to update a job's retention tag, product, or both.

        There is an important distinction between product_name of None, which 
        means do not change the existing value, vs. empty string, which means 
        clear the existing product.
        """
        job = TaskBase.get_by_t_id(job_t_id)
        if job.can_change_product(identity.current.user) and \
            job.can_change_retention_tag(identity.current.user):
            if retention_tag_name and product_name:
                retention_tag = RetentionTag.by_name(retention_tag_name)
                product = Product.by_name(product_name)
                old_tag = job.retention_tag if job.retention_tag else None
                result = Utility.update_retention_tag_and_product(
                    job, retention_tag, product)
                job.record_activity(user=identity.current.user,
                                    service=u'XMLRPC',
                                    field=u'Retention Tag',
                                    action='Changed',
                                    old=old_tag.tag,
                                    new=retention_tag.tag)
            elif retention_tag_name and product_name == '':
                retention_tag = RetentionTag.by_name(retention_tag_name)
                old_tag = job.retention_tag if job.retention_tag else None
                result = Utility.update_retention_tag_and_product(
                    job, retention_tag, None)
                job.record_activity(user=identity.current.user,
                                    service=u'XMLRPC',
                                    field=u'Retention Tag',
                                    action='Changed',
                                    old=old_tag.tag,
                                    new=retention_tag.tag)
            elif retention_tag_name:
                retention_tag = RetentionTag.by_name(retention_tag_name)
                old_tag = job.retention_tag if job.retention_tag else None
                result = Utility.update_retention_tag(job, retention_tag)
                job.record_activity(user=identity.current.user,
                                    service=u'XMLRPC',
                                    field=u'Retention Tag',
                                    action='Changed',
                                    old=old_tag.tag,
                                    new=retention_tag.tag)
            elif product_name:
                product = Product.by_name(product_name)
                result = Utility.update_product(job, product)
            elif product_name == '':
                result = Utility.update_product(job, None)
            else:
                result = {'success': False, 'msg': 'Nothing to do'}

            if not result['success'] is True:
                raise BeakerException(
                    'Job %s not updated: %s' %
                    (job.id, result.get('msg', 'Unknown reason')))
        else:
            raise BeakerException('No permission to modify %s' % job)
Example #11
0
 def test_external_tasks(self):
     job_tid = self.server.jobs.upload('''
         <job>
             <whiteboard>job with external task</whiteboard>
             <recipeSet>
                 <recipe>
                     <distroRequires>
                         <distro_name op="=" value="BlueShoeLinux5-5" />
                     </distroRequires>
                     <hostRequires/>
                     <task name="/distribution/install" />
                     <task name="/distribution/example">
                         <fetch url="git://example.com/externaltasks/example#master"/>
                     </task>
                     <task>
                         <fetch url="git://example.com/externaltasks/example2#master"/>
                     </task>
                     <task name="/distribution/example3">
                         <fetch url="git://example.com/externaltasks#master"
                                subdir="examples/3" />
                     </task>
                     <task>
                         <fetch url="git://example.com/externaltasks#master"
                                subdir="examples/4" />
                     </task>
                 </recipe>
             </recipeSet>
         </job>
         ''')
     self.assert_(job_tid.startswith('J:'))
     with session.begin():
         job = TaskBase.get_by_t_id(job_tid)
         recipe = job.recipesets[0].recipes[0]
         self.assertEquals(len(recipe.tasks), 5)
         self.assertEquals(recipe.tasks[0].name, u'/distribution/install')
         self.assertEquals(recipe.tasks[0].task.name, u'/distribution/install')
         self.assertEquals(recipe.tasks[0].fetch_url, None)
         self.assertEquals(recipe.tasks[1].name, u'/distribution/example')
         self.assertEquals(recipe.tasks[1].task, None)
         self.assertEquals(recipe.tasks[1].fetch_url,
                  'git://example.com/externaltasks/example#master')
         self.assertEquals(recipe.tasks[2].name,
                 u'git://example.com/externaltasks/example2#master')
         self.assertEquals(recipe.tasks[2].task, None)
         self.assertEquals(recipe.tasks[2].fetch_url,
                 u'git://example.com/externaltasks/example2#master')
         self.assertEquals(recipe.tasks[3].name, u'/distribution/example3')
         self.assertEquals(recipe.tasks[3].task, None)
         self.assertEquals(recipe.tasks[3].fetch_url,
                 u'git://example.com/externaltasks#master')
         self.assertEquals(recipe.tasks[3].fetch_subdir, u'examples/3')
         self.assertEquals(recipe.tasks[4].name,
                 u'git://example.com/externaltasks#master examples/4')
         self.assertEquals(recipe.tasks[4].task, None)
         self.assertEquals(recipe.tasks[4].fetch_url,
                 u'git://example.com/externaltasks#master')
         self.assertEquals(recipe.tasks[4].fetch_subdir, u'examples/4')
Example #12
0
    def files(self, taskid):
        """
        Returns an array of XML-RPC structures (dicts) describing each of the 
        result files for the given job component and its descendants.

        :param taskid: see above
        :type taskid: string
        """
        return [l.dict for l in TaskBase.get_by_t_id(taskid).all_logs()]
Example #13
0
    def task_info(self, taskid,flat=True):
        """
        Returns an XML-RPC structure (dict) describing the current state of the 
        given job component.

        :param taskid: see above
        :type taskid: string
        """
        return TaskBase.get_by_t_id(taskid).task_info()
Example #14
0
    def delete_jobs(self,
                    jobs=None,
                    tag=None,
                    complete_days=None,
                    family=None,
                    dryrun=False,
                    product=None):
        """
        delete_jobs will mark the job to be deleted

        To select jobs by id, pass an array for the *jobs* argument. Elements
        of the array must be strings of the form ``'J:123'``.
        Alternatively, pass some combination of the *tag*, *complete_days*, or
        *family* arguments to select jobs for deletion. These arguments behave
        as per the :meth:`jobs.list` method.

        If *dryrun* is True, deletions will be reported but nothing will be
        modified.

        Admins are not be able to delete jobs which are not owned by
        themselves by using the tag, complete_days etc kwargs, instead, they
        should do that via the *jobs* argument.
        """
        if jobs:  #Turn them into job objects
            if not isinstance(jobs, list):
                jobs = [jobs]
            jobs_to_try_to_del = []
            for j_id in jobs:
                job = TaskBase.get_by_t_id(j_id)
                if not isinstance(job, Job):
                    raise BeakerException('Incorrect task type passed %s' %
                                          j_id)
                if not job.can_delete(identity.current.user):
                    raise BeakerException(
                        "You don't have permission to delete job %s" % j_id)
                jobs_to_try_to_del.append(job)
            delete_jobs_kw = dict(jobs=jobs_to_try_to_del)
        else:
            # only allow people to delete their own jobs while using these kwargs
            delete_jobs_kw = dict(
                query=Job.find_jobs(tag=tag,
                                    complete_days=complete_days,
                                    family=family,
                                    product=product,
                                    owner=identity.current.user.user_name))

        deleted_jobs = Job.delete_jobs(**delete_jobs_kw)

        msg = 'Jobs deleted'
        if dryrun:
            session.rollback()
            msg = 'Dryrun only. %s' % (msg)
        return '%s: %s' % (msg, [j.t_id for j in deleted_jobs])
Example #15
0
 def test_retention_tag_product(self):
     with session.begin():
         rt1 = data_setup.create_retention_tag()
         rt2 = data_setup.create_retention_tag(needs_product=True)
         p1 = data_setup.create_product()
     out = run_client(['bkr', 'job-modify', self.job.t_id,  '--retention-tag', '%s' % rt1.tag])
     self.assert_(out == 'Successfully modified jobs %s\n' % self.job.t_id)
     session.expunge_all()
     j = TaskBase.get_by_t_id(self.job.t_id)
     self.assert_(j.retention_tag.tag == rt1.tag)
     out = run_client(['bkr', 'job-modify', self.job.t_id, '--retention-tag', '%s' % rt2.tag, '--product', '%s' % p1.name])
     self.assert_(out == 'Successfully modified jobs %s\n' % self.job.t_id)
     session.expunge_all()
     j = TaskBase.get_by_t_id(self.job.t_id)
     self.assert_(j.retention_tag.tag == rt2.tag)
     self.assert_(j.product.name == p1.name)
     out = run_client(['bkr', 'job-modify', self.job.t_id, '--retention-tag', '%s' % rt1.tag, '--product='])
     self.assert_(out == 'Successfully modified jobs %s\n' % self.job.t_id)
     session.expunge_all()
     j = TaskBase.get_by_t_id(self.job.t_id)
     self.assert_(j.retention_tag.tag == rt1.tag)
     self.assert_(j.product is None)
Example #16
0
 def test_retention_tag_product(self):
     with session.begin():
         rt1 = data_setup.create_retention_tag()
         rt2 = data_setup.create_retention_tag(needs_product=True)
         p1 = data_setup.create_product()
     out = run_client(['bkr', 'job-modify', self.job.t_id,  '--retention-tag', '%s' % rt1.tag])
     self.assert_(out == 'Successfully modified jobs %s\n' % self.job.t_id)
     session.expunge_all()
     j = TaskBase.get_by_t_id(self.job.t_id)
     self.assert_(j.retention_tag.tag == rt1.tag)
     out = run_client(['bkr', 'job-modify', self.job.t_id, '--retention-tag', '%s' % rt2.tag, '--product', '%s' % p1.name])
     self.assert_(out == 'Successfully modified jobs %s\n' % self.job.t_id)
     session.expunge_all()
     j = TaskBase.get_by_t_id(self.job.t_id)
     self.assert_(j.retention_tag.tag == rt2.tag)
     self.assert_(j.product.name == p1.name)
     out = run_client(['bkr', 'job-modify', self.job.t_id, '--retention-tag', '%s' % rt1.tag, '--product='])
     self.assert_(out == 'Successfully modified jobs %s\n' % self.job.t_id)
     session.expunge_all()
     j = TaskBase.get_by_t_id(self.job.t_id)
     self.assert_(j.retention_tag.tag == rt1.tag)
     self.assert_(j.product is None)
Example #17
0
    def set_response(self, taskid, response):
        """
        Updates the response (ack/nak) for a recipe set, or for all recipe sets 
        in a job. This is part of the results reviewing system.

        :param taskid: see above
        :type taskid: string
        :param response: new response, either ``'ack'`` or ``'nak'``
        :type response: string
        """
        job = TaskBase.get_by_t_id(taskid)
        if job.can_set_response(identity.current.user):
            job.set_response(response)
        else:
            raise BeakerException('No permission to modify %s' % job)
Example #18
0
 def test_only_reserves_machines(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + "reserveworkflow")
     Select(b.find_element_by_name("tag")).select_by_visible_text("None selected")
     Select(b.find_element_by_name("osmajor")).select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name("distro")).select_by_visible_text(self.distro.name)
     Select(b.find_element_by_name("distro_tree_id")).select_by_visible_text("%s Server i386" % self.distro.name)
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//td[preceding-sibling::th/text()="Job ID"]/a').text
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         recipe = job.recipesets[0].recipes[0]
         self.assertEquals(recipe.host_requires, u'<hostRequires><system_type value="Machine"/></hostRequires>')
Example #19
0
    def set_response(self, taskid, response):
        """
        Updates the response (ack/nak) for a recipe set, or for all recipe sets 
        in a job. This is part of the results reviewing system.

        :param taskid: see above
        :type taskid: string
        :param response: new response, either ``'ack'`` or ``'nak'``
        :type response: string
        """
        job = TaskBase.get_by_t_id(taskid)
        if job.can_set_response(identity.current.user):
            job.set_response(response)
        else:
            raise BeakerException('No permission to modify %s' % job)
 def test_uses_new_check_install_task(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + 'reserveworkflow/')
     Select(b.find_element_by_name('osmajor'))\
         .select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name('distro')).select_by_visible_text(self.distro.name)
     Select(b.find_element_by_name('distro_tree_id'))\
         .select_by_visible_text('%s Server i386' % self.distro.name)
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     jid = b.find_element_by_xpath('//h1//span[@class="job-id"]').text
     with session.begin():
         job = TaskBase.get_by_t_id(jid)
         # first task in the recipe should be our new check-install task
         first_task = job.recipesets[0].recipes[0].tasks[0]
         self.assertEquals(first_task.task.name, '/distribution/check-install')
 def test_only_reserves_machines(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + 'reserveworkflow')
     Select(b.find_element_by_name('tag')).select_by_visible_text('None selected')
     Select(b.find_element_by_name('osmajor'))\
         .select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name('distro')).select_by_visible_text(self.distro.name)
     Select(b.find_element_by_name('distro_tree_id'))\
         .select_by_visible_text('%s Server i386' % self.distro.name)
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//td[preceding-sibling::th/text()="Job ID"]/a').text
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         recipe = job.recipesets[0].recipes[0]
         self.assertEquals(recipe.host_requires,
                 u'<hostRequires><system_type value="Machine"/></hostRequires>')
Example #22
0
 def test_reserve_time(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + "reserveworkflow/")
     Select(b.find_element_by_name("osmajor")).select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name("distro")).select_by_visible_text(self.distro.name)
     Select(b.find_element_by_name("distro_tree_id")).select_by_visible_text("%s Server i386" % self.distro.name)
     b.find_element_by_name("reserve_days").clear()
     b.find_element_by_name("reserve_days").send_keys("4")
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     jid = b.find_element_by_xpath('//td[preceding-sibling::th/text()="Job ID"]/a').text
     with session.begin():
         job = TaskBase.get_by_t_id(jid)
         reserve_task = job.recipesets[0].recipes[0].tasks[1]
         self.assertEquals(reserve_task.task.name, "/distribution/reservesys")
         self.assertEquals(reserve_task.params[0].name, "RESERVETIME")
         self.assertEquals(reserve_task.params[0].value, "345600")  # 4 days in seconds
Example #23
0
 def test_only_reserves_machines(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + 'reserveworkflow')
     Select(b.find_element_by_name('tag')).select_by_visible_text('None selected')
     Select(b.find_element_by_name('osmajor'))\
         .select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name('distro')).select_by_visible_text(self.distro.name)
     Select(b.find_element_by_name('distro_tree_id'))\
         .select_by_visible_text('%s Server i386' % self.distro.name)
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//h1//span[@class="job-id"]').text
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         recipe = job.recipesets[0].recipes[0]
         self.assertEquals(recipe.host_requires,
                 u'<hostRequires><system_type value="Machine"/></hostRequires>')
Example #24
0
    def delete_jobs(self, jobs=None, tag=None, complete_days=None, family=None, dryrun=False, product=None):
        """
        delete_jobs will mark the job to be deleted

        To select jobs by id, pass an array for the *jobs* argument. Elements
        of the array must be strings of the form ``'J:123'``.
        Alternatively, pass some combination of the *tag*, *complete_days*, or
        *family* arguments to select jobs for deletion. These arguments behave
        as per the :meth:`jobs.list` method.

        If *dryrun* is True, deletions will be reported but nothing will be
        modified.

        Admins are not be able to delete jobs which are not owned by
        themselves by using the tag, complete_days etc kwargs, instead, they
        should do that via the *jobs* argument.
        """
        if jobs: #Turn them into job objects
            if not isinstance(jobs,list):
                jobs = [jobs]
            jobs_to_try_to_del = []
            for j_id in jobs:
                job = TaskBase.get_by_t_id(j_id)
                if not isinstance(job,Job):
                    raise BeakerException('Incorrect task type passed %s' % j_id )
                if not job.can_delete(identity.current.user):
                    raise BeakerException("You don't have permission to delete job %s" % j_id)
                jobs_to_try_to_del.append(job)
            delete_jobs_kw = dict(jobs=jobs_to_try_to_del)
        else:
            # only allow people to delete their own jobs while using these kwargs
            delete_jobs_kw = dict(query=Job.find_jobs(tag=tag,
                complete_days=complete_days,
                family=family, product=product,
                owner=identity.current.user.user_name))

        deleted_jobs = Job.delete_jobs(**delete_jobs_kw)

        msg = 'Jobs deleted'
        if dryrun:
            session.rollback()
            msg = 'Dryrun only. %s' % (msg)
        return '%s: %s' % (msg, [j.t_id for j in deleted_jobs])
Example #25
0
 def test_preserves_lab_requirement(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + "reserveworkflow")
     Select(b.find_element_by_name("osmajor")).select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name("distro")).select_by_visible_text(self.distro.name)
     Select(b.find_element_by_name("distro_tree_id")).select_by_visible_text("%s Server i386" % self.distro.name)
     b.find_element_by_xpath('//label[contains(string(.), "Any system from lab:")]' '/input[@type="radio"]').click()
     Select(b.find_element_by_name("lab")).select_by_visible_text(self.lc.fqdn)
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//td[preceding-sibling::th/text()="Job ID"]/a').text
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         cloned_job_xml = job.to_xml(clone=True).toxml()  # cloning re-parses hostRequires
         self.assertIn(
             u'<hostRequires><labcontroller op="=" value="%s"/>'
             u'<system_type op="=" value="Machine"/></hostRequires>' % self.lc.fqdn,
             cloned_job_xml,
         )
Example #26
0
 def test_uses_new_check_install_task(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + 'reserveworkflow/')
     Select(b.find_element_by_name('osmajor'))\
         .select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name('distro')).select_by_visible_text(
         self.distro.name)
     Select(b.find_element_by_name('distro_tree_id'))\
         .select_by_visible_text('%s Server i386' % self.distro.name)
     b.find_element_by_xpath(
         '//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     jid = b.find_element_by_xpath('//h1//span[@class="job-id"]').text
     with session.begin():
         job = TaskBase.get_by_t_id(jid)
         # first task in the recipe should be our new check-install task
         first_task = job.recipesets[0].recipes[0].tasks[0]
         self.assertEquals(first_task.task.name,
                           '/distribution/check-install')
Example #27
0
 def test_reserve_time(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + 'reserveworkflow/')
     Select(b.find_element_by_name('osmajor'))\
         .select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name('distro')).select_by_visible_text(self.distro.name)
     Select(b.find_element_by_name('distro_tree_id'))\
         .select_by_visible_text('%s Server i386' % self.distro.name)
     b.find_element_by_name('reserve_duration').clear()
     b.find_element_by_name('reserve_duration').send_keys('96')
     b.find_element_by_xpath('.//button[text()="Hours"]').click()
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     jid = b.find_element_by_xpath('//h1//span[@class="job-id"]').text
     with session.begin():
         job = TaskBase.get_by_t_id(jid)
         reserve_task = job.recipesets[0].recipes[0].tasks[1]
         self.assertEquals(reserve_task.task.name, '/distribution/reservesys')
         self.assertEquals(reserve_task.params[0].name, 'RESERVETIME')
         self.assertEquals(reserve_task.params[0].value, '345600') # 4 days in seconds
Example #28
0
 def test_can_reserve_manual_system(self):
     with session.begin():
         broken_system = data_setup.create_system(
             arch=u'i386',
             shared=True,
             status=SystemStatus.broken,
             lab_controller=self.lc)
         manual_system = data_setup.create_system(
             arch=u'i386',
             shared=True,
             status=SystemStatus.manual,
             lab_controller=self.lc)
     b = self.browser
     login(b)
     # broken system should not be present
     go_to_reserve_systems(b, distro_tree=self.distro_tree_i386)
     search_for_system(b, broken_system)
     check_system_search_results(b, absent=[broken_system])
     # provision manual system
     go_to_reserve_systems(b, distro_tree=self.distro_tree_i386)
     search_for_system(b, manual_system)
     row = b.find_element_by_xpath(
         '//tr[normalize-space(string(td))="%s"]' % manual_system.fqdn)
     row.find_element_by_link_text('Reserve Now').click()
     b.find_element_by_xpath(
         '//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//h1//span[@class="job-id"]').text
     wb_descr = (WORKFLOW_DESCR % ("None", "a specific system", "86400"))
     wboard = b.find_element_by_class_name('job-whiteboard')
     self.assertIn(wb_descr,
                   wboard.text,
                   msg="Fail to match default whiteboard")
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         cloned_job_xml = lxml.etree.tostring(
             job.to_xml(clone=True),
             encoding=unicode)  # cloning re-parses hostRequires
         self.assertIn(u'<hostRequires force="%s"/>' % manual_system.fqdn,
                       cloned_job_xml)
Example #29
0
def extend_watchdog_by_taskspec(taskspec):
    """
    Extend the watchdog for a recipe identified by a taskspec. The valid type
    of a taskspec is either R(recipe) or T(recipe-task).
    See :ref:`Specifying tasks <taskspec>` in :manpage:`bkr(1)`.

    :param taskspec: A taskspec argument that identifies a recipe or recipe task.
    :jsonparam string kill_time: Time in seconds to extend the watchdog by.
    """
    if not taskspec.startswith(('R', 'T')):
        raise BadRequest400('Taskspec type must be one of [R, T]')

    try:
        obj = TaskBase.get_by_t_id(taskspec)
    except BeakerException as exc:
        raise NotFound404(unicode(exc))

    if isinstance(obj, Recipe):
        recipe = obj
    else:
        recipe = obj.recipe
    data = read_json_request(request)
    return _extend_watchdog(recipe.id, data)
Example #30
0
def extend_watchdog_by_taskspec(taskspec):
    """
    Extend the watchdog for a recipe identified by a taskspec. The valid type
    of a taskspec is either R(recipe) or T(recipe-task).
    See :ref:`Specifying tasks <taskspec>` in :manpage:`bkr(1)`.

    :param taskspec: A taskspec argument that identifies a recipe or recipe task.
    :jsonparam string kill_time: Time in seconds to extend the watchdog by.
    """
    if not taskspec.startswith(('R', 'T')):
        raise BadRequest400('Taskspec type must be one of [R, T]')

    try:
        obj = TaskBase.get_by_t_id(taskspec)
    except BeakerException as exc:
        raise NotFound404(unicode(exc))

    if isinstance(obj, Recipe):
        recipe = obj
    else:
        recipe = obj.recipe
    data = read_json_request(request)
    return _extend_watchdog(recipe.id, data)
Example #31
0
 def test_preserves_lab_requirement(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + 'reserveworkflow')
     Select(b.find_element_by_name('osmajor'))\
         .select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name('distro')).select_by_visible_text(self.distro.name)
     Select(b.find_element_by_name('distro_tree_id'))\
         .select_by_visible_text('%s Server i386' % self.distro.name)
     b.find_element_by_xpath(
             '//label[contains(string(.), "Any system from lab:")]'
             '/input[@type="radio"]').click()
     Select(b.find_element_by_name('lab')).select_by_visible_text(self.lc.fqdn)
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//h1//span[@class="job-id"]').text
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         cloned_job_xml = lxml.etree.tostring(job.to_xml(clone=True), encoding=unicode)  # cloning re-parses hostRequires
         self.assertIn(
                 u'<hostRequires><labcontroller op="=" value="%s"/>'
                 u'<system_type op="=" value="Machine"/></hostRequires>'
                 % self.lc.fqdn,
                 cloned_job_xml)
 def test_preserves_lab_requirement(self):
     login(self.browser)
     b = self.browser
     b.get(get_server_base() + 'reserveworkflow')
     Select(b.find_element_by_name('osmajor'))\
         .select_by_visible_text(self.distro.osversion.osmajor.osmajor)
     Select(b.find_element_by_name('distro')).select_by_visible_text(self.distro.name)
     Select(b.find_element_by_name('distro_tree_id'))\
         .select_by_visible_text('%s Server i386' % self.distro.name)
     b.find_element_by_xpath(
             '//label[contains(string(.), "Any system from lab:")]'
             '/input[@type="radio"]').click()
     Select(b.find_element_by_name('lab')).select_by_visible_text(self.lc.fqdn)
     b.find_element_by_xpath('//button[normalize-space(text())="Submit job"]').click()
     # should end up on the job page
     job_id = b.find_element_by_xpath('//td[preceding-sibling::th/text()="Job ID"]/a').text
     with session.begin():
         job = TaskBase.get_by_t_id(job_id)
         cloned_job_xml = job.to_xml(clone=True).toxml() # cloning re-parses hostRequires
         self.assertIn(
                 u'<hostRequires><labcontroller op="=" value="%s"/>'
                 u'<system_type op="=" value="Machine"/></hostRequires>'
                 % self.lc.fqdn,
                 cloned_job_xml)
Example #33
0
 def files(self, taskid):
     """
     Returns an array of XML-RPC structures (dicts) describing each of the 
     result files for the given job component and its descendants.
     """
     return TaskBase.get_by_t_id(taskid).all_logs
Example #34
0
 def files(self, taskid):
     """
     Returns an array of XML-RPC structures (dicts) describing each of the 
     result files for the given job component and its descendants.
     """
     return TaskBase.get_by_t_id(taskid).all_logs
Example #35
0
 def _delete_job(self, t_id):
     job = TaskBase.get_by_t_id(t_id)
     self._check_job_deletability(t_id, job)
     Job.delete_jobs([job])
     return [t_id]
Example #36
0
 def set_response(self, job_t_id, response):
     job = TaskBase.get_by_t_id(job_t_id)
     if job.can_set_response(identity.current.user):
         job.set_response(response)
     else:
         raise BeakerException('No permission to modify %s' % job)
Example #37
0
 def test_ack_job(self):
     out = run_client(['bkr', 'job-modify', self.job.t_id,  '--response', 'ack'])
     self.assert_(out == 'Successfully modified jobs %s\n' % self.job.t_id)
     j = TaskBase.get_by_t_id(self.job.t_id)
     for rs in j.recipesets:
         self.assert_('%s' % rs.nacked.response == 'ack')
Example #38
0
 def test_nak_rs(self):
     out = run_client(['bkr', 'job-modify', self.job.recipesets[0].t_id,  '--response', 'nak'])
     self.assert_(out == 'Successfully modified jobs %s\n' % self.job.recipesets[0].t_id)
     rs = TaskBase.get_by_t_id(self.job.recipesets[0].t_id)
     self.assert_('%s' % rs.nacked.response == 'nak')
Example #39
0
 def _delete_job(self, t_id):
     job = TaskBase.get_by_t_id(t_id)
     self._check_job_deletability(t_id, job)
     Job.delete_jobs([job])
     return [t_id]