def test_disable_legacy_perms(self): try: stop_process('gunicorn') except ValueError: # It seems gunicorn is not a running process raise SkipTest('Can only run this test against gunicorn') try: tmp_config = edit_file( CONFIG_FILE, 'beaker.deprecated_job_group_permissions.on = True', 'beaker.deprecated_job_group_permissions.on = False') start_process('gunicorn', env={'BEAKER_CONFIG_FILE': tmp_config.name}) with session.begin(): owner = data_setup.create_user() member = data_setup.create_user(password=u'group_member') group = data_setup.create_group() data_setup.add_user_to_group(owner, group) data_setup.add_user_to_group(member, group) job = data_setup.create_job(owner=owner, group=None) data_setup.mark_job_complete(job, result=TaskResult.fail) b = self.browser login(b, user=member.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) self.check_cannot_review() finally: stop_process('gunicorn') start_process('gunicorn')
def test_disable_legacy_perms(self): try: stop_process('gunicorn') except ValueError: # It seems gunicorn is not a running process raise SkipTest('Can only run this test against gunicorn') try: tmp_config = edit_file(CONFIG_FILE, 'beaker.deprecated_job_group_permissions.on = True', 'beaker.deprecated_job_group_permissions.on = False') start_process('gunicorn', env={'BEAKER_CONFIG_FILE': tmp_config.name}) with session.begin(): owner = data_setup.create_user() member = data_setup.create_user(password=u'group_member') group = data_setup.create_group() data_setup.add_user_to_group(owner, group) data_setup.add_user_to_group(member, group) job = data_setup.create_job(owner=owner, group=None) data_setup.mark_job_complete(job, result=TaskResult.fail) b = self.browser login(b, user=member.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) self.check_cannot_review() finally: stop_process('gunicorn') start_process('gunicorn')
def test_distro_name(self): with session.begin(): job = data_setup.create_job() data_setup.mark_job_complete(job, result=TaskResult.fail) self.assertEqual(len(self.mail_capture.captured_mails), 1) sender, rcpts, raw_msg = self.mail_capture.captured_mails[0] msg = email.message_from_string(raw_msg) self.assertNotIn('Distro(', msg.get_payload(decode=True))
def test_job_completion_notification_off(self): with session.begin(): job_owner = data_setup.create_user(notify_job_completion=False) job = data_setup.create_job(owner=job_owner) session.flush() data_setup.mark_job_complete(job) self.assertEqual(len(self.mail_capture.captured_mails), 0)
def test_get_junit_xml(self): with session.begin(): data_setup.mark_job_complete(self.job) response = requests.get(get_server_base() + 'recipes/%s.junit.xml' % self.recipe.id) response.raise_for_status() self.assertEquals(response.status_code, 200) junitxml = lxml.etree.fromstring(response.content) self.assertEqual(junitxml.tag, 'testsuites')
def test_owner_can_review(self): with session.begin(): owner = data_setup.create_user(password=u'owner') job = data_setup.create_job(owner=owner) data_setup.mark_job_complete(job, result=TaskResult.fail) b = self.browser login(b, user=owner.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) self.review(job.recipesets[0])
def test_cannot_update_reservation_request_on_completed_recipe(self): with session.begin(): data_setup.mark_job_complete(self.job) s = requests.Session() requests_login(s, user=self.owner, password=u'theowner') response = patch_json(get_server_base() + 'recipes/%s/reservation-request' % self.recipe_with_reservation_request.id, session=s, data={'reserve': True, 'duration': False}) self.assertEquals(response.status_code, 403)
def test_other_users_cannot_review(self): with session.begin(): user = data_setup.create_user(password=u'other_user') job = data_setup.create_job() data_setup.mark_job_complete(job, result=TaskResult.fail) b = self.browser login(b, user=user.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) self.check_cannot_review()
def test_job_completion_notification_off(self): mail_capture_thread.start_capturing() with session.begin(): job_owner = data_setup.create_user(notify_job_completion=False) job = data_setup.create_job(owner=job_owner) session.flush() data_setup.mark_job_complete(job) captured_mails = mail_capture_thread.stop_capturing(wait=False) self.assertEqual(len(captured_mails), 0)
def test_subject_format(self): with session.begin(): job_owner = data_setup.create_user() job = data_setup.create_job(owner=job_owner) session.flush() data_setup.mark_job_complete(job) self.assertEqual(len(self.mail_capture.captured_mails), 1) sender, rcpts, raw_msg = self.mail_capture.captured_mails[0] msg = email.message_from_string(raw_msg) self.assert_('[Beaker Job Completion] [Completed/Pass]' in msg['Subject'])
def test_passed_recipeset_is_acked_by_default(self): with session.begin(): owner = data_setup.create_user(password=u'owner') job = data_setup.create_job(owner=owner) data_setup.mark_job_complete(job, result=TaskResult.pass_) self.assertEquals(job.result, TaskResult.pass_) b = self.browser login(b, user=owner.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) ack_checkbox = b.find_element_by_xpath('//label[normalize-space(string(.))="Ack"]/input') self.assertTrue(ack_checkbox.is_selected())
def test_contains_recipe_hyperlink(self): with session.begin(): recipe = data_setup.create_recipe() job = data_setup.create_job_for_recipes([recipe]) data_setup.mark_job_complete(job, result=TaskResult.fail) sender, rcpts, raw_msg = self.mail_capture.captured_mails[0] msg = email.message_from_string(raw_msg) recipe_link = u'<%srecipes/%d' % (get_server_base(), recipe.id) recipe_line = msg.get_payload(decode=True).splitlines()[2] self.assertIn(recipe_link, recipe_line)
def test_headers_for_avoiding_autoreplies(self): mail_capture_thread.start_capturing() with session.begin(): job = data_setup.create_job() data_setup.mark_job_complete(job) captured_mails = mail_capture_thread.stop_capturing() self.assertEqual(len(captured_mails), 1) sender, rcpts, raw_msg = captured_mails[0] msg = email.message_from_string(raw_msg) self.assertEquals(msg['Auto-Submitted'], 'auto-generated') self.assertEquals(msg['Precedence'], 'bulk')
def test_subject_format(self): with session.begin(): job_owner = data_setup.create_user() job = data_setup.create_job(owner=job_owner) session.flush() data_setup.mark_job_complete(job) self.assertEqual(len(self.mail_capture.captured_mails), 1) sender, rcpts, raw_msg = self.mail_capture.captured_mails[0] msg = email.message_from_string(raw_msg) self.assert_( '[Beaker Job Completion] [Completed/Pass]' in msg['Subject'])
def test_cannot_delete_system_which_has_been_used_for_recipes(self): with session.begin(): job = data_setup.create_job() data_setup.mark_job_complete(job, system=self.system) try: out = run_client(['bkr', 'system-delete', self.system.fqdn], config=self.client_config) fail('should raise') except ClientError, e: self.assertEqual(e.status, 1) self.assert_(e.stderr_output.find('with reservations') != -1)
def test_watch_job(self): with session.begin(): job = data_setup.create_job() p = start_client(["bkr", "job-watch", job.t_id]) time.sleep(1) # XXX better would be to read the client's stdout with session.begin(): data_setup.mark_job_complete(job) out, err = p.communicate() self.assertEquals(p.returncode, 0, err) self.assert_(out.startswith("Watching tasks"), out) self.assert_("New: 1 [total: 1]" in out, out) self.assert_("Completed: 1 [total: 1]" in out, out)
def test_job_owner_is_notified(self): with session.begin(): job_owner = data_setup.create_user() job = data_setup.create_job(owner=job_owner) session.flush() data_setup.mark_job_complete(job) self.assertEqual(len(self.mail_capture.captured_mails), 1) sender, rcpts, raw_msg = self.mail_capture.captured_mails[0] msg = email.message_from_string(raw_msg) self.assertEqual([job_owner.email_address], rcpts) self.assertEqual(job_owner.email_address, msg['To']) self.assert_('[Beaker Job Completion]' in msg['Subject'])
def test_subject_contains_whiteboard(self): with session.begin(): whiteboard = u'final space shuttle launch' job = data_setup.create_job(whiteboard=whiteboard) session.flush() data_setup.mark_job_complete(job) self.assertEqual(len(self.mail_capture.captured_mails), 1) sender, rcpts, raw_msg = self.mail_capture.captured_mails[0] msg = email.message_from_string(raw_msg) # Subject header might be split across multiple lines subject = re.sub(r'\s+', ' ', msg['Subject']) self.assert_(whiteboard in subject, subject)
def test_group_member_can_review_group_job(self): with session.begin(): owner = data_setup.create_user() member = data_setup.create_user(password=u'group_member') group = data_setup.create_group() data_setup.add_user_to_group(owner, group) data_setup.add_user_to_group(member, group) job = data_setup.create_job(owner=owner, group=group) data_setup.mark_job_complete(job, result=TaskResult.fail) b = self.browser login(b, user=member.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) self.review(job.recipesets[0])
def test_install_duration_by_resource(self): system_recipe = data_setup.create_recipe() guest_recipe = data_setup.create_guestrecipe(host=system_recipe) data_setup.mark_job_complete( data_setup.create_job_for_recipes([system_recipe, guest_recipe])) virt_recipe = data_setup.create_recipe() data_setup.create_job_for_recipes([virt_recipe]) virt_recipe2 = data_setup.create_recipe() data_setup.create_job_for_recipes([virt_recipe2]) data_setup.mark_recipe_complete(virt_recipe, virt=True) data_setup.mark_recipe_complete(virt_recipe2, virt=True) system_recipe2 = data_setup.create_recipe() guest_recipe2 = data_setup.create_guestrecipe(host=system_recipe2) job2 = data_setup.create_job_for_recipes([system_recipe2, guest_recipe2]) data_setup.mark_job_complete(job2, system=system_recipe.resource.system) one_hour = datetime.timedelta(hours=1) two_hours = datetime.timedelta(hours=2) three_hours = datetime.timedelta(hours=3) virt_recipe.installation.install_finished = virt_recipe.installation.install_started + one_hour virt_recipe2.installation.install_finished = virt_recipe2.installation.install_started + two_hours guest_recipe.installation.install_finished = guest_recipe.installation.install_started + two_hours guest_recipe2.installation.install_finished = guest_recipe2.installation.install_started + three_hours system_recipe.installation.install_finished = system_recipe.installation.install_started + one_hour system_recipe2.installation.install_finished = system_recipe2.installation.install_started + three_hours session.flush() rows = self.execute_reporting_query('install-duration-by-resource') all_rows = rows.fetchall() guest_rows = [row for row in all_rows if row.fqdn == 'All Guest'] virt_rows = [row for row in all_rows if row.fqdn == 'All OpenStack'] system_rows = [row for row in all_rows if row.fqdn == system_recipe.resource.fqdn] self.assertEquals(len(virt_rows), 1, virt_rows) self.assertEquals(virt_rows[0].min_install_hours, 1) self.assertEquals(virt_rows[0].max_install_hours, 2) self.assertEquals(virt_rows[0].avg_install_hours, Decimal('1.5')) self.assertEquals(len(guest_rows), 1, guest_rows) self.assertEquals(guest_rows[0].min_install_hours, 2) self.assertEquals(guest_rows[0].max_install_hours, 3) self.assertEquals(guest_rows[0].avg_install_hours, Decimal('2.5')) self.assertEquals(len(system_rows), 1, system_rows) self.assertEquals(system_rows[0].min_install_hours, 1) self.assertEquals(system_rows[0].max_install_hours, 3) self.assertEquals(system_rows[0].avg_install_hours, Decimal('2.0'))
def test_resource_install_failures(self): # Get existing state to later compare against rows = self.execute_reporting_query('install-failure-count-by-resource') all_rows = [row for row in rows] guest_rows = [row for row in all_rows if row.fqdn == 'All Guest'] virt_rows = [row for row in all_rows if row.fqdn == 'All oVirt'] existing_failed_guests = guest_rows[0].failed_recipes existing_failed_virt = virt_rows[0].failed_recipes system_recipe = data_setup.create_recipe() guest_recipe = data_setup.create_guestrecipe(host=system_recipe) virt_recipe = data_setup.create_recipe() job = data_setup.create_job_for_recipes([guest_recipe, virt_recipe, system_recipe]) data_setup.mark_recipe_running(virt_recipe, virt=True) data_setup.mark_recipe_running(system_recipe) data_setup.mark_recipe_running(guest_recipe) session.flush() # Test we don't count runinng recipes rows = self.execute_reporting_query('install-failure-count-by-resource') all_rows = [row for row in rows] system_rows = [row for row in all_rows if row.fqdn == system_recipe.resource.fqdn] self.assertEquals(len(virt_rows), 1, virt_rows) self.assertEquals(existing_failed_virt, virt_rows[0].failed_recipes) self.assertEquals(len(guest_rows), 1, guest_rows) self.assertEquals(existing_failed_guests, guest_rows[0].failed_recipes) self.assertEquals(len(system_rows), 1, system_rows) self.assertEquals(system_rows[0].failed_recipes, 0) # Test completed recipes data_setup.mark_job_complete(job, only=True) session.flush() rows = self.execute_reporting_query('install-failure-count-by-resource') all_rows = [row for row in rows] guest_rows = [row for row in all_rows if row.fqdn == 'All Guest'] virt_rows = [row for row in all_rows if row.fqdn == 'All oVirt'] system_rows = [row for row in all_rows if row.fqdn == system_recipe.resource.fqdn] self.assertEquals(len(virt_rows), 1, virt_rows) self.assertEquals(virt_rows[0].failed_recipes, existing_failed_virt + 1) self.assertEquals(len(guest_rows), 1, guest_rows) self.assertEquals(guest_rows[0].failed_recipes, existing_failed_guests + 1) self.assertEquals(len(system_rows), 1, system_rows) self.assertEquals(system_rows[0].failed_recipes, 1)
def test_group_member_can_review_non_group_job(self): # This is a legacy permission which will go away eventually (see below) with session.begin(): owner = data_setup.create_user() member = data_setup.create_user(password=u'group_member') group = data_setup.create_group() data_setup.add_user_to_group(owner, group) data_setup.add_user_to_group(member, group) job = data_setup.create_job(owner=owner, group=None) data_setup.mark_job_complete(job, result=TaskResult.fail) b = self.browser login(b, user=member.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) self.review(job.recipesets[0])
def test_group_member_can_review_group_job(self): with session.begin(): owner = data_setup.create_user() member = data_setup.create_user(password=u"group_member") member.use_old_job_page = True group = data_setup.create_group() group.add_member(owner) group.add_member(member) job = data_setup.create_job(owner=owner, group=group) data_setup.mark_job_complete(job, result=TaskResult.fail) b = self.browser login(b, user=member.user_name, password="******") b.get(get_server_base() + "jobs/%s" % job.id) self.review(job.recipesets[0])
def test_contains_job_hyperlink(self): with session.begin(): job = data_setup.create_job() session.flush() data_setup.mark_job_complete(job) self.assertEqual(len(self.mail_capture.captured_mails), 1) sender, rcpts, raw_msg = self.mail_capture.captured_mails[0] msg = email.message_from_string(raw_msg) job_link = u'<%sjobs/%d>' % (get_server_base(), job.id) first_line = msg.get_payload(decode=True).splitlines()[0] self.assert_(job_link in first_line, 'Job link %r should appear in first line %r' % (job_link, first_line))
def test_post_comment_to_task_result(self): with session.begin(): recipe = data_setup.create_recipe() job = data_setup.create_job_for_recipes([recipe]) data_setup.mark_job_complete(job) result = recipe.tasks[0].results[0] comment_text = u'Never gonna run around and desert you' out = run_client(['bkr', 'job-comment', result.t_id, '--message', comment_text]) with session.begin(): session.expire_all() self.assertEqual(result.comments[0].comment, comment_text)
def test_watch_job(self): with session.begin(): job = data_setup.create_job(whiteboard=u'jobwb') p = start_client(['bkr', 'job-watch', job.t_id]) self.assertEquals(p.stdout.readline(), 'Watching tasks (this may be safely interrupted)...\n') self.assertEquals(p.stdout.readline(), '%s jobwb: New\n' % job.t_id) self.assertEquals(p.stdout.readline(), '--> New: 1 [total: 1]\n') with session.begin(): data_setup.mark_job_complete(job) out, err = p.communicate() self.assertEquals(p.returncode, 0, err) self.assertEquals(out, '%s jobwb: New -> Completed\n' '--> Completed: 1 [total: 1]\n' % job.t_id)
def test_contains_job_hyperlink(self): with session.begin(): job = data_setup.create_job() session.flush() data_setup.mark_job_complete(job) self.assertEqual(len(self.mail_capture.captured_mails), 1) sender, rcpts, raw_msg = self.mail_capture.captured_mails[0] msg = email.message_from_string(raw_msg) job_link = u'<%sjobs/%d>' % (get_server_base(), job.id) first_line = msg.get_payload(decode=True).splitlines()[0] self.assert_( job_link in first_line, 'Job link %r should appear in first line %r' % (job_link, first_line))
def test_failed_recipeset_is_not_reviewed_by_default(self): with session.begin(): owner = data_setup.create_user(password=u'owner') job = data_setup.create_job(owner=owner) data_setup.mark_job_complete(job, result=TaskResult.fail) self.assertEquals(job.result, TaskResult.fail) b = self.browser login(b, user=owner.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) review_checkbox = b.find_element_by_xpath( '//label[normalize-space(string(.))="Needs Review"]/input') self.assertTrue(review_checkbox.is_selected()) # comment link should be hidden until the recipe set is reviewed comment_link = b.find_element_by_xpath( '//*[@class="recipeset"]//a[text()="comment"]') self.assertFalse(comment_link.is_displayed())
def test_watch_recipe(self): with session.begin(): job = data_setup.create_job(recipe_whiteboard=u'recipewb') recipe = job.recipesets[0].recipes[0] p = start_client(['bkr', 'job-watch', recipe.t_id]) self.assertEquals(p.stdout.readline(), 'Watching tasks (this may be safely interrupted)...\n') self.assertEquals(p.stdout.readline(), '%s recipewb: New\n' % recipe.t_id) self.assertEquals(p.stdout.readline(), '--> New: 1 [total: 1]\n') with session.begin(): data_setup.mark_job_complete(job) out, err = p.communicate() self.assertEquals(p.returncode, 0, err) self.assertEquals(out, '%s recipewb: New -> Completed (%s)\n' '--> Completed: 1 [total: 1]\n' % (recipe.t_id, recipe.resource.fqdn))
def test_record_ack_change(self): with session.begin(): owner = data_setup.create_user(password=u'owner') job = data_setup.create_job(owner=owner) data_setup.mark_job_complete(job, result=TaskResult.pass_) self.assertEquals(job.result, TaskResult.pass_) b = self.browser login(b, user=owner.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) rs = b.find_element_by_xpath('//*[@id="RS_%s"]' % job.recipesets[0].id) rs.find_element_by_xpath('.//label[normalize-space(string(.))="Nak"]/input').click() rs.find_element_by_xpath('.//span[text()="Success"]') with session.begin(): self.assertEquals(job.recipesets[0].activity[0].service, u'WEBUI') self.assertEquals(job.recipesets[0].activity[0].field_name, 'Ack/Nak') self.assertEquals(job.recipesets[0].activity[0].object_name(), 'RecipeSet: %s' % job.recipesets[0].id) self.assertEquals(job.recipesets[0].activity[0].old_value, u'ack') self.assertEquals(job.recipesets[0].activity[0].new_value, u'nak')
def test_job_cc_list_is_notified(self): mail_capture_thread.start_capturing() with session.begin(): job_owner = data_setup.create_user() job = data_setup.create_job(owner=job_owner, cc=[u'*****@*****.**', u'*****@*****.**']) session.flush() data_setup.mark_job_complete(job) captured_mails = mail_capture_thread.stop_capturing() self.assertEqual(len(captured_mails), 1) sender, rcpts, raw_msg = captured_mails[0] msg = email.message_from_string(raw_msg) self.assertEqual([job_owner.email_address, '*****@*****.**', '*****@*****.**'], rcpts) self.assertEqual(job_owner.email_address, msg['To']) self.assertEqual('[email protected], [email protected]', msg['Cc']) self.assert_('[Beaker Job Completion]' in msg['Subject'])
def test_task_durations(self): short_task = data_setup.create_task() long_task = data_setup.create_task() r = data_setup.create_recipe(task_list=[short_task, long_task]) data_setup.mark_job_complete( data_setup.create_job_for_recipes([r])) r.tasks[0].start_time = datetime.datetime(2012, 10, 15, 10, 54, 0) r.tasks[0].finish_time = datetime.datetime(2012, 10, 15, 11, 0, 0) r.tasks[1].start_time = datetime.datetime(2012, 10, 15, 11, 0, 0) r.tasks[1].finish_time = datetime.datetime(2012, 10, 15, 21, 0, 0) session.flush() rows = list(self.execute_reporting_query('task-durations-by-arch')) short_task_row, = [row for row in rows if row.task == short_task.name] self.assertEquals(short_task_row.executions, 1) self.assertEquals(short_task_row.avg_duration, Decimal('0.1')) long_task_row, = [row for row in rows if row.task == long_task.name] self.assertEquals(long_task_row.executions, 1) self.assertEquals(long_task_row.avg_duration, Decimal('10.0'))
def test_html_in_comments_is_escaped(self): with session.begin(): owner = data_setup.create_user(password=u'owner') job = data_setup.create_job(owner=owner) data_setup.mark_job_complete(job) bad_comment = '<script>alert("xss")</script>' b = self.browser login(b, user=owner.user_name, password='******') b.get(get_server_base() + 'jobs/%s' % job.id) self.review(job.recipesets[0], comment=bad_comment) # reload the page, showing the comment should not execute a script b.get(get_server_base() + 'jobs/%s' % job.id) rs = b.find_element_by_xpath('//*[@id="RS_%s"]' % job.recipesets[0].id) # click comment link rs.find_element_by_link_text('comment').click() # check dialog contents dialog_content = b.find_element_by_xpath('//*[contains(@class, "ui-dialog-content")]') self.assertEquals(dialog_content.text, bad_comment) # click edit button in modal b.find_element_by_xpath('//*[contains(@class, "ui-dialog")]' '//button[text()="Edit"]').click() # check textarea contents textarea = b.find_element_by_xpath('//*[contains(@class, "ui-dialog")]//textarea') self.assertEquals(textarea.text, bad_comment)