def compare_expected(name, recipe_id, actual): expected = pkg_resources.resource_string('bkr.inttest', 'server/kickstarts/%s.expected' % name) # Unfortunately there are a few things that vary for each test run, # so we have to substitute them: vars = { '@RECIPEID@': str(recipe_id), '@BEAKER@': get_server_base(), '@REPOS@': urlparse.urljoin(get_server_base(), '/repos/'), '@HARNESS@': urlparse.urljoin(get_server_base(), '/harness/'), } for var, value in vars.iteritems(): expected = expected.replace(var, value) expected = expected.rstrip('\n') actual = actual.rstrip('\n') if expected != actual: expected_path = pkg_resources.resource_filename('bkr.inttest', 'server/kickstarts/%s.expected' % name) # Undo the substitutions, so that we get a sensible diff actual = re.sub(r'\b%s\b' % vars.pop('@RECIPEID@'), '@RECIPEID@', actual) for var, value in vars.iteritems(): actual = actual.replace(value, var) actual_temp = tempfile.NamedTemporaryFile(prefix='beaker-kickstart-test-', suffix='-actual', delete=False) actual_temp.write(actual) raise AssertionError('actual kickstart does not match expected\n' 'diff -u %s %s\nmv %s %s' % (expected_path, actual_temp.name, actual_temp.name, expected_path))
def test_submit_task(self): test_package_name = '/distribution/beaker/task_test' b = self.browser # upload v1.1 first... b.get(get_server_base() + 'tasks/new') b.find_element_by_id('task_task_rpm').send_keys( pkg_resources.resource_filename('bkr.inttest.server', 'task-rpms/tmp-distribution-beaker-task_test-1.1-0.noarch.rpm')) b.find_element_by_xpath('//button[text()="Upload"]').click() self.assert_task_upload_task_header(test_package_name) self.assert_task_correct_v1_1() self.assertEqual(self.get_task_info_field('Uploader'), self.uploader.user_name) self.assertEqual(self.get_task_info_field_href('Uploader'), 'mailto:%s' % self.uploader.email_address) # ...then upload v2.0... b.get(get_server_base() + 'tasks/new') b.find_element_by_id('task_task_rpm').send_keys( pkg_resources.resource_filename('bkr.inttest.server', 'task-rpms/tmp-distribution-beaker-task_test-2.0-5.noarch.rpm')) b.find_element_by_xpath('//button[text()="Upload"]').click() self.assert_task_upload_task_header(test_package_name) # ...and make sure everything was updated self.assert_task_correct_v2_0()
def test_non_ascii_username_and_display_name(self): user_name = u'ломоносов' display_name = u'Михаил Ломоносов' email = '*****@*****.**' s = requests.Session() requests_login(s) response = post_json(get_server_base() + 'users/', session=s, data={ 'user_name': user_name, 'display_name': display_name, 'email_address': email}) response.raise_for_status() # Test that search works as well response = s.get(get_server_base() + 'users/', params={'q': u'user_name:%s' % user_name}, headers={'Accept': 'application/json'}) response.raise_for_status() self.assertEqual(response.json()['count'], 1) self.assertEqual(response.json()['entries'][0]['user_name'], user_name) # Test that typeahead works as well response = s.get(get_server_base() + 'users/+typeahead', params={'q': user_name[:4]}, headers={'Accept': 'application/json'}) self.assertEqual(response.json()['data'][0]['user_name'], user_name)
def test_user_resource_counts_are_accurate_when_removing(self): with session.begin(): user = data_setup.create_user() job = data_setup.create_job(owner=user) data_setup.mark_job_running(job) owned_system = data_setup.create_system(owner=user) loaned_system = data_setup.create_system() loaned_system.loaned = user owned_pool = data_setup.create_system_pool(owning_user=user) group = data_setup.create_group(owner=user) s = requests.Session() requests_login(s) response = s.get(get_server_base() + 'users/%s' % user.user_name, headers={'Accept': 'application/json'}) response.raise_for_status() self.assertEquals(response.json()['job_count'], 1) self.assertEquals(response.json()['reservation_count'], 1) self.assertEquals(response.json()['loan_count'], 1) self.assertEquals(response.json()['owned_system_count'], 1) self.assertEquals(response.json()['owned_pool_count'], 1) response = patch_json(get_server_base() + 'users/%s' % user.user_name, data={'removed': 'now'}, session=s) response.raise_for_status() # The bug was that the counts in the PATCH response would still show # their old values, because the queries for producing the counts were # being run before all the removals were flushed to the database. # Note that job_count stays as 1, because the job has been cancelled # but it will still be running until the next iteration of beakerd's # update_dirty_jobs. self.assertEquals(response.json()['job_count'], 1) self.assertEquals(response.json()['reservation_count'], 0) self.assertEquals(response.json()['loan_count'], 0) self.assertEquals(response.json()['owned_system_count'], 0) self.assertEquals(response.json()['owned_pool_count'], 0)
def test_export_xml(self): b = self.browser # Make sure the Export button is present in the jobs grid. We can't # actually click it because it triggers a download, which WebDriver # can't handle. b.get(get_server_base() + 'jobs/') b.find_element_by_name('simplesearch').send_keys(unicode(self.job_to_export.id)) b.find_element_by_name('jobsearch_simple').submit() b.find_element_by_xpath( '//tr[normalize-space(string(./td[1]))="%s"]' '//a[text()="Export"]' % self.job_to_export.t_id) # Make sure the Export button is present on the job page. b.get(get_server_base() + 'jobs/%s' % self.job_to_export.id) b.find_element_by_link_text('Export') # Fetch the exported XML directly. response = requests.get(get_server_base() + 'to_xml?taskid=%s&pretty=False' % self.job_to_export.t_id) xml_export = response.content with session.begin(): job = Job.by_id(self.job_to_export.id) xml_export = job.to_xml().toxml() xml_export_tree = lxml.etree.parse(StringIO(xml_export)) pretty_xml = lxml.etree.tostring(xml_export_tree, pretty_print=False) self.assert_(pretty_xml == xml_export)
def test_nacked_recipe_results_not_shown(self): with session.begin(): data_setup.create_completed_job( whiteboard=self.job_whiteboard, result=TaskResult.fail, recipe_whiteboard=self.recipe_whiteboard) data_setup.create_completed_job( whiteboard=self.job_whiteboard, result=TaskResult.warn, recipe_whiteboard=self.recipe_whiteboard) owner = data_setup.create_user(password='******') self.passed_job.owner = owner b = self.browser login(b, user=owner.user_name, password='******') b.get(get_server_base() + 'matrix') b.find_element_by_xpath("//select[@name='whiteboard']/option[@value='%s']" % self.job_whiteboard).click() b.find_element_by_xpath("//input[@name='toggle_nacks_on']").click() b.find_element_by_xpath('//input[@value="Generate"]').click() report_text = b.find_element_by_xpath("//div[@id='matrix-report']").text self.assert_('Pass: 1' in report_text) # Nack Recipe with session.begin(): response = Response.by_response('nak') self.passed_job.recipesets[0].nacked = RecipeSetResponse(response_id=response.id) # Assert it is no longer there b.get(get_server_base() + 'matrix') b.find_element_by_xpath("//select[@name='whiteboard']/option[@value='%s']" % self.job_whiteboard).click() b.find_element_by_xpath("//input[@name='toggle_nacks_on']").click() b.find_element_by_xpath('//input[@value="Generate"]').click() report_text = b.find_element_by_xpath("//div[@id='matrix-report']").text self.assert_('Pass: 1' not in report_text)
def test_anonymous(self): b = self.browser b.get(get_server_base() + 'keytypes/') try: b.find_element_by_link_text('Add') self.fail('Must fail') except NoSuchElementException: pass try: b.find_element_by_link_text('Remove') self.fail('Must fail') except NoSuchElementException: pass b.get(get_server_base() + 'powertypes/save') self.assertEquals(b.find_element_by_css_selector('#message').text, 'Please log in.') b.get(get_server_base() + 'powertypes/new') self.assertEquals(b.find_element_by_css_selector('#message').text, 'Please log in.') b.get(get_server_base() + 'powertypes/edit') self.assertEquals(b.find_element_by_css_selector('#message').text, 'Please log in.') b.get(get_server_base() + 'powertypes/remove') self.assertEquals(b.find_element_by_css_selector('#message').text, 'Please log in.')
def test_task_anchor(self): with session.begin(): recipes = [data_setup.create_recipe(distro_tree=self.distro_tree) for _ in range(10)] job = data_setup.create_job_for_recipes(recipes, owner=self.user) b = self.browser recipe = recipes[0] task = job.recipesets[0].recipes[0].tasks[0].id # bkr/recipes/id#task<id> b.get(get_server_base() + 'recipes/%s#task%s' %(recipe.id,task)) # give 10 seconds for the element to be displayed WebDriverWait(b, 10).until(lambda driver : driver.find_element_by_id('task_items_%s' %recipe.id).is_displayed()) self.assertTrue(b.find_element_by_id('task_items_%s' %recipe.id).is_displayed()) # bkr/jobs/id#task<id> # for multi recipe jobs, only the recipe to which the task belongs should be visible # choose a recipe and task somewhere in the middle task = job.recipesets[0].recipes[6].tasks[0].id recipe = recipes[6] b.get(get_server_base() + 'jobs/%s#task%s' %(job.id,task)) # give 10 seconds for the element to be displayed WebDriverWait(b, 10).until(lambda driver : driver.find_element_by_id('task_items_%s' %recipe.id).is_displayed()) self.assertTrue(b.find_element_by_id('task_items_%s' %recipe.id).is_displayed()) recipes.remove(recipe) for r in recipes: # be fair and give 10 seconds for the element to be displayed, if at all WebDriverWait(b, 10).until(lambda driver : driver.find_element_by_id('task_items_%s' %recipe.id).is_displayed()) self.assertTrue(not b.find_element_by_id('task_items_%s' %r.id).is_displayed())
def test_remove_self_admin_group(self): with session.begin(): user = data_setup.create_admin(password='******') b = self.browser login(b, user=user.user_name, password='******') # admin should be in groups/mine b.get(get_server_base() + 'groups/mine') b.find_element_by_link_text('admin').click() # remove self b.find_element_by_xpath('//td/a[text()="Remove (-)" and ../preceding-sibling::td[2]/text()="%s"]' % user.user_name).click() # admin should not be in groups/mine b.get(get_server_base() + 'groups/mine') self.assertTrue(not is_text_present(b, 'admin')) logout(b) # login as admin login(b) group = Group.by_name('admin') group_users = group.users # remove all other users from 'admin' b.get(get_server_base() + 'groups/edit?group_id=1') for usr in group_users: if usr.user_id != 1: b.find_element_by_xpath('//td/a[text()="Remove (-)" and ../preceding-sibling::td[2]/text()="%s"]' % usr.user_name).click() # attempt to remove admin user b.find_element_by_xpath('//a[@href="removeUser?group_id=1&id=1"]').click() self.assert_('Cannot remove member' in b.find_element_by_class_name('flash').text)
def test_task_anchor(self): with session.begin(): recipes = [data_setup.create_recipe(distro_tree=self.distro_tree) for _ in range(10)] job = data_setup.create_job_for_recipes(recipes, owner=self.user) b = self.browser recipe = recipes[0] task = job.recipesets[0].recipes[0].tasks[0].id # bkr/recipes/id#task<id> b.get(get_server_base() + 'recipes/%s#task%s' %(recipe.id,task)) # "Show Results" should be activated for the recipe b.find_element_by_css_selector('#recipe%s .results-tab.active' % recipe.id) # bkr/jobs/id#task<id> # for multi recipe jobs, only the recipe to which the task belongs should be visible # choose a recipe and task somewhere in the middle task = job.recipesets[0].recipes[6].tasks[0].id recipe = recipes[6] b.get(get_server_base() + 'jobs/%s#task%s' %(job.id,task)) # "Show Results" should be activated for the recipe b.find_element_by_css_selector('#recipe%s .results-tab.active' % recipe.id) recipes.remove(recipe) for r in recipes: # "Hide Results" should be activated for the recipe b.find_element_by_css_selector('#recipe%s .hide-results-tab.active' % r.id)
def test_modifying_email(self): current_user_email = self.user.email_address b = self.browser # Try and use the same email as an existing user e = b.find_element_by_name("email_address") e.clear() e.send_keys(self.user2.email_address) b.find_element_by_id("UserPrefs").submit() self.assert_(is_text_present(b, "Email address is not unique")) # Check invalid email self.browser.get(get_server_base() + "prefs") e = b.find_element_by_name("email_address") e.clear() e.send_keys("InvalidEmailAddress") b.find_element_by_id("UserPrefs").submit() self.assert_(is_text_present(b, "An email address must contain a single @")) # Check new unused and valid email self.browser.get(get_server_base() + "prefs") e = b.find_element_by_name("email_address") e.clear() e.send_keys("*****@*****.**" % data_setup.unique_name("dude%s")) b.find_element_by_id("UserPrefs").submit() self.assert_(is_text_present(b, "Email address changed"))
def test_modifying_email(self): current_user_email = self.user.email_address b = self.browser # Try and use the same email as an existing user # (This used to be forbidden, now it is allowed.) e = b.find_element_by_name("email_address") e.clear() e.send_keys(self.user2.email_address) b.find_element_by_id('UserPrefs').submit() self.assertEquals(b.find_element_by_class_name('flash').text, 'Email address changed') # Check invalid email self.browser.get(get_server_base() + 'prefs') e = b.find_element_by_name("email_address") e.clear() e.send_keys('InvalidEmailAddress') b.find_element_by_id('UserPrefs').submit() error_msg = b.find_element_by_css_selector( '#UserPrefs .help-block.error').text self.assertEquals(error_msg, 'An email address must contain a single @') # Check new unused and valid email self.browser.get(get_server_base() + 'prefs') e = b.find_element_by_name("email_address") e.clear() e.send_keys('*****@*****.**' % data_setup.unique_name('dude%s')) b.find_element_by_id('UserPrefs').submit() self.assertEquals(b.find_element_by_class_name('flash').text, 'Email address changed')
def test_remove_and_add(self): b = self.browser self.assert_(any(lca.lab_controller == self.lc for lca in self.distro_tree.lab_controller_assocs)) #Remove b.get(get_server_base() + 'labcontrollers/') b.find_element_by_xpath('//tr[normalize-space(string(td[1]))="%s"]' '//a[contains(text(), "Remove")]' % self.lc.fqdn).click() self.assertEquals(b.find_element_by_class_name('flash').text, '%s removed' % self.lc) with session.begin(): session.refresh(self.system) self.assert_(self.system.lab_controller is None) session.refresh(self.distro_tree) self.assert_(not any(lca.lab_controller == self.lc for lca in self.distro_tree.lab_controller_assocs)) #Re add b.get(get_server_base() + 'labcontrollers/') b.find_element_by_xpath('//tr[normalize-space(string(td[1]))="%s"]' '//a[contains(text(), "Re-Add")]' % self.lc.fqdn).click() self.assertEquals(b.find_element_by_class_name('flash').text, 'Successfully re-added %s' % self.lc)
def test_creating_a_system_with_hardware_details(self): s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.user.user_name, 'password': u'password'}).raise_for_status() fqdn = data_setup.unique_name(u'newsystem%s') data = { 'fqdn': fqdn, 'hypervisor': u'KVM', 'vendor': u'dummyvendor', 'location': u'dummylocation', 'model': u'dummymodel', 'serial_number': u'dummynumber', 'mac_address': u'dummymacaddress', 'memory': 111111, 'numa_nodes': 5, } response = post_json(get_server_base() + 'systems/', session=s, data=data) with session.begin(): system = System.by_fqdn(fqdn, self.user) self.assertEquals(system.fqdn, fqdn) self.assertEquals(system.hypervisor, Hypervisor.by_name(u'KVM')) self.assertEquals(system.location, u'dummylocation') self.assertEquals(system.serial, u'dummynumber') self.assertEquals(system.mac_address, u'dummymacaddress') self.assertEquals(system.memory, 111111) self.assertEquals(system.numa.nodes, 5)
def test_save_policy(self): s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.owner.user_name, 'password': '******'}).raise_for_status() response = put_json(get_server_base() + 'systems/%s/access-policy' % self.system.fqdn, session=s, data={'rules': [ # keep two existing rules, drop the other {'id': self.policy.rules[0].id, 'permission': 'view', 'everybody': True, 'user': None, 'group': None}, {'id': self.policy.rules[2].id, 'permission': 'edit_system', 'user': None, 'group': self.privileged_group.group_name}, # .. and add a new rule {'permission': 'control_system', 'everybody': True, 'user': None, 'group': None}, ]}) response.raise_for_status() with session.begin(): session.expire_all() self.assertEquals(len(self.policy.rules), 3) self.assertEquals(self.policy.rules[0].permission, SystemPermission.view) self.assertEquals(self.policy.rules[1].permission, SystemPermission.edit_system) self.assertEquals(self.policy.rules[2].permission, SystemPermission.control_system) self.assertEquals(self.policy.rules[2].everybody, True)
def test_add_rule_for_new_user(self): with session.begin(): data_setup.create_user(user_name=u'marple') b = self.browser login(b, user=self.system_owner.user_name, password='******') b.get(get_server_base() + 'view/%s/' % self.system.fqdn) b.find_element_by_link_text('Access Policy').click() # grant edit_policy permission to marple user pane = b.find_element_by_id('access-policy') pane.find_element_by_xpath('.//input[@placeholder="Username"]')\ .send_keys('marple') # There is a small race here between typing and the typeahead # suggestions appearing. I don't think humans can hit it, but the tests # can, so we make sure the typeahead suggestion has appeared before we # press tab. pane.find_element_by_xpath('.//div[@class="tt-suggestion" and ' 'contains(string(.), "marple")]') pane.find_element_by_xpath('.//input[@placeholder="Username"]')\ .send_keys('\t') self.find_checkbox('marple', 'Edit this policy').click() self.check_row_is_dirty('marple') pane.find_element_by_xpath('.//button[text()="Save changes"]').click() self.check_row_is_not_dirty('marple') # refresh to check it has been persisted b.get(get_server_base() + 'view/%s/' % self.system.fqdn) b.find_element_by_link_text('Access Policy').click() self.assertTrue(self.find_checkbox('marple', 'Edit this policy').is_selected())
def test_ackability(self): # XXX If this test gets any more complicated, we should break # it up b = self.browser login(b, user=self.user_1.user_name, password=self.password) b.get(get_server_base() + 'jobs/%d' % self.job.id) #This tests that the ack is there for owner b.find_element_by_name("response_box_%d" % self.job.recipesets[0].id) logout(b) # Not there for non owner login(b, user=self.user_2.user_name, password=self.password) b.get(get_server_base() + 'jobs/%d' % self.job.id) b.find_element_by_xpath("//td[normalize-space(text())='RS:%s' and " "not(./input[@name='response_box_%s'])]" % ( self.job.recipesets[0].id, self.job.recipesets[0].id)) # Is there for job owner's group co-member. with session.begin(): data_setup.add_user_to_group(self.user_1, self.group) data_setup.add_user_to_group(self.user_3, self.group) logout(b) login(b, user=self.user_3.user_name, password=self.password) b.get(get_server_base() + 'jobs/%d' % self.job.id) b.find_element_by_xpath("//input[@name='response_box_%s']" % self.job.recipesets[0].id) # There for job's group member with session.begin(): self.job.group = self.group self.user_2.groups.append(self.group) logout(b) login(b, user=self.user_2.user_name, password=self.password) b.get(get_server_base() + 'jobs/%s' % self.job.id) b.find_element_by_name("response_box_%s" % self.job.recipesets[0].id)
def test_group_remove_on_different_pages(self): b1 = self.browser b2 = self.get_browser() login(b1) login(b2) b1.get(get_server_base() + 'groups/') b1.find_element_by_xpath("//input[@name='group.text']").clear() b1.find_element_by_xpath("//input[@name='group.text']").send_keys(self.group.group_name) b1.find_element_by_id('Search').submit() b2.get(get_server_base() + 'groups/') b2.find_element_by_xpath("//input[@name='group.text']").clear() b2.find_element_by_xpath("//input[@name='group.text']").send_keys(self.group.group_name) b2.find_element_by_id('Search').submit() delete_and_confirm(b1, "//tr[td/a[normalize-space(text())='%s']]" % self.group.group_name, delete_text='Delete Group') self.assertEqual( b1.find_element_by_class_name('flash').text, '%s deleted' % self.group.display_name) delete_and_confirm(b2, "//tr[td/a[normalize-space(text())='%s']]" % self.group.group_name, delete_text='Delete Group') self.assertEqual( b2.find_element_by_class_name('flash').text, 'Invalid group or already removed')
def test_system_pool_activity(self): with session.begin(): pool1 = data_setup.create_system_pool() act1 = pool1.record_activity(service=u'testdata', user=User.by_user_name(data_setup.ADMIN_USER), action=u'Nothing', field=u'Nonsense', old=u'asdf', new=u'omgwtfbbq') pool2 = data_setup.create_system_pool() act2 = pool2.record_activity(service=u'testdata', user=User.by_user_name(data_setup.ADMIN_USER), action=u'Nothing', field=u'Nonsense', old=u'asdf', new=u'lollercopter') b = self.browser b.get(get_server_base() + 'activity/pool') b.find_element_by_class_name('search-query').send_keys( 'pool.name:%s' % pool1.name) b.find_element_by_class_name('grid-filter').submit() check_activity_search_results(b, present=[act1], absent=[act2]) # search by pool owner b.get(get_server_base() + 'activity/pool') b.find_element_by_class_name('search-query').send_keys( 'pool.owner.user_name:%s' % pool2.owner.user_name) b.find_element_by_class_name('grid-filter').submit() check_activity_search_results(b, present=[act2], absent=[act1]) with session.begin(): pool1.owning_user = None pool1.owning_group = data_setup.create_group() b.get(get_server_base() + 'activity/pool') b.find_element_by_class_name('search-query').send_keys( 'pool.owner.group_name:%s' % pool1.owner.group_name) b.find_element_by_class_name('grid-filter').submit() check_activity_search_results(b, present=[act1], absent=[act2])
def test_group_removal_is_noticed(self): self.group.systems.append(self.system) session.flush() b = self.browser login(b) b.get(get_server_base() + 'groups/') b.find_element_by_xpath("//input[@name='group.text']").clear() b.find_element_by_xpath("//input[@name='group.text']").send_keys(self.group.group_name) b.find_element_by_id('Search').submit() delete_and_confirm(b, "//tr[td/a[normalize-space(text())='%s']]" % self.group.group_name, 'Remove') should_have_deleted_msg = b.find_element_by_xpath('//body').text self.assert_('%s deleted' % self.group.display_name in should_have_deleted_msg) # Check it's recorded in System Activity b.get(get_server_base() + 'activity/system') b.find_element_by_link_text('Show Search Options').click() b.find_element_by_xpath("//select[@id='activitysearch_0_table']/option[@value='Action']").click() b.find_element_by_xpath("//select[@id='activitysearch_0_operation']/option[@value='is']").click() b.find_element_by_xpath("//input[@id='activitysearch_0_value']").send_keys('Removed') b.find_element_by_link_text('Add').click() b.find_element_by_xpath("//select[@id='activitysearch_1_table']/option[@value='Old Value']").click() b.find_element_by_xpath("//select[@id='activitysearch_1_operation']/option[@value='is']").click() b.find_element_by_xpath("//input[@id='activitysearch_1_value']").send_keys(self.group.display_name) b.find_element_by_id('searchform').submit() self.assert_(is_activity_row_present(b,via='WEBUI', action='Removed', old_value=self.group.display_name, new_value='', object_='System: %s' % self.system.fqdn))
def test_generate_by_whiteboard(self): b = self.browser b.get(get_server_base() + 'matrix/') Select(b.find_element_by_name('whiteboard'))\ .select_by_visible_text(self.job_whiteboard) b.find_element_by_xpath('//button[text()="Generate"]').click() b.find_element_by_xpath('//table[@id="matrix_datagrid"]' '//td[normalize-space(string(.))="Pass: 1"]') with session.begin(): new_job = data_setup.create_completed_job( whiteboard=self.job_whiteboard, result=TaskResult.pass_, recipe_whiteboard=self.recipe_whiteboard) b.find_element_by_xpath('//button[text()="Generate"]').click() b.find_element_by_xpath('//table[@id="matrix_datagrid"]' '//td[normalize-space(string(.))="Pass: 2"]') #Try with multiple whiteboards with session.begin(): another_new_job = data_setup.create_completed_job( whiteboard=self.job_whiteboard_2, result=TaskResult.pass_, recipe_whiteboard=self.recipe_whiteboard) b.get(get_server_base() + 'matrix/') whiteboard = Select(b.find_element_by_name('whiteboard')) whiteboard.select_by_visible_text(self.job_whiteboard) whiteboard.select_by_visible_text(self.job_whiteboard_2) b.find_element_by_xpath('//button[text()="Generate"]').click() b.find_element_by_xpath('//table[@id="matrix_datagrid"]' '//td[normalize-space(string(.))="Pass: 3"]')
def test_can_return_manual_reservation_when_automated(self): with session.begin(): user = data_setup.create_user(password='******') system = data_setup.create_system(owner=user, status=SystemStatus.manual) b = self.browser login(b, user=user.user_name, password="******") # Take b.get(get_server_base() + 'view/%s' % system.fqdn) b.find_element_by_link_text('Take').click() b.find_element_by_xpath('//div[contains(@class, "system-quick-usage")]' '//span[@class="label" and text()="Reserved"]') # toggle status to Automated with session.begin(): system.lab_controller = data_setup.create_labcontroller() system.status = SystemStatus.automated # Attempt to return b.get(get_server_base() + 'view/%s' % system.fqdn) b.find_element_by_link_text('Return').click() b.find_element_by_xpath('//div[contains(@class, "system-quick-usage")]' '//span[@class="label" and text()="Idle"]')
def test_update_system_pool(self): s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.owner.user_name, 'password': '******'}).raise_for_status() response = patch_json(get_server_base() + 'pools/%s/' % self.pool.name, session=s, data={'name': 'newname', 'description': 'newdescription', 'owner': {'user_name': self.user.user_name}}) response.raise_for_status() with session.begin(): session.expire_all() self.assertEquals(self.pool.name, 'newname') self.assertEquals(self.pool.description, 'newdescription') self.assertEquals(self.pool.owner.user_name, self.user.user_name) s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.user.user_name, 'password': '******'}).raise_for_status() response = patch_json(get_server_base() + 'pools/%s/' % self.pool.name, session=s, data={'name': 'newname', 'description': 'newdescription', 'owner': {'group_name': self.group.group_name}}) response.raise_for_status() with session.begin(): session.expire_all() self.assertEquals(self.pool.owner, self.group) self.assertFalse(self.pool.owning_user)
def test_deleted_job_results_not_shown(self): with session.begin(): data_setup.create_completed_job( whiteboard=self.job_whiteboard, result=TaskResult.fail, recipe_whiteboard=self.recipe_whiteboard) data_setup.create_completed_job( whiteboard=self.job_whiteboard, result=TaskResult.warn, recipe_whiteboard=self.recipe_whiteboard) owner = data_setup.create_user(password='******') self.passed_job.owner = owner b = self.browser login(b, user=owner.user_name, password='******') b.get(get_server_base() + 'matrix') b.find_element_by_xpath("//select[@name='whiteboard']/option[@value='%s']" % self.job_whiteboard).click() b.find_element_by_xpath('//button[@type="submit" and text()="Generate"]').click() report_text = b.find_element_by_xpath("//div[@id='matrix-report']").text self.assert_('Pass: 1' in report_text) # Delete Job with session.begin(): self.passed_job.soft_delete() # Assert it is no longer there b.get(get_server_base() + 'matrix') b.find_element_by_xpath("//select[@name='whiteboard']/option[@value='%s']" % self.job_whiteboard).click() b.find_element_by_xpath('//button[@type="submit" and text()="Generate"]').click() report_text = b.find_element_by_xpath("//div[@id='matrix-report']").text self.assert_('Pass: 1' not in report_text)
def test_add_system_to_pool(self): with session.begin(): other_system = data_setup.create_system(owner=self.owner) s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.owner.user_name, 'password': '******'}).raise_for_status() response = post_json(get_server_base() + 'pools/%s/systems/' % self.pool.name, session=s, data={'fqdn': other_system.fqdn}) response.raise_for_status() with session.begin(): session.expire_all() self.assertItemsEqual(self.pool.systems, [self.system, other_system]) self.assertEquals(self.pool.activity[-1].field_name, 'System') self.assertEquals(self.pool.activity[-1].action, 'Added') self.assertEquals(self.pool.activity[-1].new_value, unicode(other_system)) self.assertEquals(other_system.activity[-1].field_name, 'Pool') self.assertEquals(other_system.activity[-1].action, 'Added') self.assertEquals(other_system.activity[-1].new_value, unicode(self.pool)) # adding to a pool that doesn't exist is a 404 response = post_json(get_server_base() + 'pools/nosuchpool/systems/', session=s, data={'fqdn': other_system.fqdn}) self.assertEquals(response.status_code, 404) self.assertEquals(response.text, 'System pool nosuchpool does not exist') # adding a system that doesn't exist is a 400 response = post_json(get_server_base() + 'pools/%s/systems/' % self.pool.name, session=s, data={'fqdn': 'nosuchsystem'}) self.assertEquals(response.status_code, 400) self.assertEquals(response.text, "System 'nosuchsystem' does not exist")
def test_group_remove_link_visibility(self): with session.begin(): user = data_setup.create_user(password="******") user.groups.append(self.group) group = data_setup.create_group(owner=user) b = self.browser # login as admin login(b) b.get(get_server_base() + "groups/") b.find_element_by_xpath("//input[@name='group.text']").clear() b.find_element_by_xpath("//input[@name='group.text']").send_keys(self.group.group_name) b.find_element_by_xpath("//input[@value='Search']").submit() self.assert_( "Remove (-)" in b.find_element_by_xpath("//tr[(td[1]/a[text()='%s'])]" % self.group.group_name).text ) logout(b) # login as another user login(b, user=user.user_name, password="******") b.get(get_server_base() + "groups/") b.find_element_by_xpath("//input[@name='group.text']").clear() b.find_element_by_xpath("//input[@name='group.text']").send_keys(self.group.group_name) b.find_element_by_xpath("//input[@value='Search']").submit() self.assert_( "Remove (-)" not in b.find_element_by_xpath("//tr[(td[1]/a[text()='%s'])]" % self.group.group_name).text ) b.find_element_by_xpath("//input[@name='group.text']").clear() b.find_element_by_xpath("//input[@name='group.text']").send_keys(group.group_name) b.find_element_by_xpath("//input[@value='Search']").submit() self.assert_("Remove (-)" in b.find_element_by_xpath("//tr[(td[1]/a[text()='%s'])]" % group.group_name).text)
def test_set_active_policy_to_custom_policy(self): with session.begin(): user1 = data_setup.create_user() user2 = data_setup.create_user() self.system.custom_access_policy.add_rule( permission=SystemPermission.edit_system, user=user1) pool = data_setup.create_system_pool() pool.access_policy.add_rule( permission=SystemPermission.edit_system, user=user2) self.system.active_access_policy = pool.access_policy self.assertFalse(self.system.active_access_policy.grants (user1, SystemPermission.edit_system)) self.assertTrue(self.system.active_access_policy.grants (user2, SystemPermission.edit_system)) s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.owner.user_name, 'password': '******'}).raise_for_status() response = patch_json(get_server_base() + 'systems/%s/' % self.system.fqdn, session=s, data={'active_access_policy': {'custom': True}}, ) response.raise_for_status() with session.begin(): session.expire_all() self.assertTrue(self.system.active_access_policy.grants \ (user1, SystemPermission.edit_system))
def test_creating_a_system_with_power_settings(self): s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.user.user_name, 'password': u'password'}).raise_for_status() fqdn = data_setup.unique_name(u'newsystem%s') data = { 'fqdn': fqdn, 'lab_controller_id': self.lc.id, 'power_type': u'apc_snmp_then_etherwake', 'power_address': u'dummyaddress', 'power_user': u'dummyuser', 'power_password': u'dummypassword', 'power_id': u'dummyvm', 'power_quiescent_period': 5, 'release_action': u'LeaveOn', 'reprovision_distro_tree': {'id': self.distro_tree.id}, } response = post_json(get_server_base() + 'systems/', session=s, data=data) with session.begin(): system = System.by_fqdn(fqdn, self.user) self.assertEquals(system.power.power_type, PowerType.by_name(u'apc_snmp_then_etherwake')) self.assertEquals(system.power.power_address, u'dummyaddress') self.assertEquals(system.power.power_user, u'dummyuser') self.assertEquals(system.power.power_passwd, u'dummypassword') self.assertEquals(system.power.power_id, u'dummyvm') self.assertEquals(system.power.power_quiescent_period, 5) self.assertEquals(system.release_action, ReleaseAction.leave_on) self.assertEquals(system.reprovision_distro_tree, self.distro_tree)
def test_add_and_remove_permission(self): b = self.browser login(b) b.get(get_server_base() + 'groups/edit?group_id=%d' % self.group.group_id) b.find_element_by_id('Permissions_permissions_text').send_keys(self.perm1.permission_name) b.find_element_by_id('Permissions').submit() #Test that permission dynamically updated b.find_element_by_xpath('//table[@id="group_permission_grid"]//td[text()="%s"]' % self.perm1.permission_name) #Test that the permission was persisted by reopening the current page b.get(get_server_base() + 'groups/edit?group_id=%d' % self.group.group_id) b.find_element_by_xpath('//table[@id="group_permission_grid"]//td[text()="%s"]' % self.perm1.permission_name) #Let's try and remove it delete_and_confirm(b, '//td[preceding-sibling::td/text()="%s"]' % self.perm1.permission_name, 'Remove') #Check it has been removed from the table b.find_element_by_xpath('//table[@id="group_permission_grid" and ' 'not(.//td/text()="%s")]' % self.perm1.permission_name) #Reload to make sure it has been removed from the DB b.get(get_server_base() + 'groups/edit?group_id=%d' % self.group.group_id) b.find_element_by_xpath('//table[@id="group_permission_grid" and ' 'not(.//td/text()="%s")]' % self.perm1.permission_name)
def test_add_remove_owner_group(self): with session.begin(): user = data_setup.create_user(password='******') group = data_setup.create_group(owner=user) user1 = data_setup.create_user(password='******') b = self.browser login(b, user=user.user_name, password='******') b.get(get_server_base() + 'groups/mine') # remove self (as only owner) b.find_element_by_link_text(group.group_name).click() b.find_element_by_xpath('//td[preceding-sibling::td/text()="%s"]' % user.user_name)\ .find_element_by_link_text('Remove').click() flash_text = b.find_element_by_class_name('flash').text self.assert_("Cannot remove the only owner" in flash_text) # add a new user as owner b.find_element_by_xpath('//input[@id="GroupUser_user_text"]').send_keys(user1.user_name) b.find_element_by_id('GroupUser').submit() b.find_element_by_xpath('//td[text()="%s"]' % user1.user_name) b.find_element_by_xpath('//td[preceding-sibling::td/text()="%s"]' % user1.user_name)\ .find_element_by_link_text('Add').click() b.find_element_by_xpath('//td[preceding-sibling::td/text()="%s"]' % user1.user_name)\ .find_element_by_link_text('Remove') logout(b) # login as the new user and check for ownership login(b, user=user1.user_name, password='******') b.get(get_server_base() + 'groups/mine') b.find_element_by_link_text(group.group_name).click() b.find_element_by_xpath('//input') with session.begin(): self.assertEquals(Activity.query.filter_by(service=u'WEBUI', field_name=u'Owner', action=u'Added', new_value=user1.user_name).count(), 1) group = Group.by_name(group.group_name) self.assert_(group.has_owner(user1)) self.assertEquals(group.activity[-1].action, u'Added') self.assertEquals(group.activity[-1].field_name, u'Owner') self.assertEquals(group.activity[-1].new_value, user1.user_name) self.assertEquals(group.activity[-1].service, u'WEBUI') # remove self as owner b.find_element_by_xpath('//td[preceding-sibling::td/text()="%s"]' % user1.user_name)\ .find_element_by_link_text('Remove').click() b.find_element_by_xpath('//title[text()="My Groups"]') with session.begin(): self.assertEquals(Activity.query.filter_by(service=u'WEBUI', field_name=u'Owner', action=u'Removed', old_value=user1.user_name).count(), 1) session.refresh(group) self.assertEquals(group.activity[-1].action, u'Removed') self.assertEquals(group.activity[-1].field_name, u'Owner') self.assertEquals(group.activity[-1].old_value, user1.user_name) self.assertEquals(group.activity[-1].service, u'WEBUI')
def test_owner_view(self): b = self.browser login(b, user=self.system_owner.user_name, password='******') b.get(get_server_base() + 'view/%s/' % self.system.fqdn) b.find_element_by_link_text('Access Policy').click() self.check_checkboxes()
def test_get_system(self): response = requests.get(get_server_base() + '/systems/%s/' % self.system.fqdn, headers={'Accept': 'application/json'}) response.raise_for_status() self.assertEquals(response.json()['fqdn'], self.system.fqdn)
def test_anonymous_cannot_save_policy(self): response = put_json(get_server_base() + 'systems/%s/access-policy' % self.system.fqdn, data={'rules': []}) self.assertEquals(response.status_code, 401)
def go_to_loan_page(self): b = self.browser b.get(get_server_base() + 'view/%s' % self.system.fqdn) b.find_element_by_xpath('//ul[contains(@class, "system-nav")]' '//a[text()="Loan"]').click()
def check_can_change_product(self, job, new_product): b = self.browser b.get(get_server_base() + 'jobs/%s' % job.id) Select(b.find_element_by_id('job_product')) \ .select_by_visible_text(new_product.name) b.find_element_by_xpath('//div[text()="Product has been updated"]')
def test_delete_system_pool(self): with session.begin(): system = data_setup.create_system() random_user = data_setup.create_user(password='******') pool_owner = data_setup.create_user(password='******') pool_name = data_setup.unique_name('mypool%s') pool = data_setup.create_system_pool(name=pool_name, owning_user=pool_owner, systems=[system]) pool.access_policy.add_rule( user=self.user, permission=SystemPermission.edit_system) system.active_access_policy = pool.access_policy unicode_pool = unicode(pool) self.assertIn(pool, system.pools) self.assertTrue( system.active_access_policy.grants(self.user, SystemPermission.edit_system)) # first as a random user s = requests.Session() s.post(get_server_base() + 'login', data={ 'user_name': random_user.user_name, 'password': '******' }).raise_for_status() response = s.delete(get_server_base() + 'pools/%s/' % pool_name) self.assertEquals(response.status_code, 403) # now as the pool owner s = requests.Session() s.post(get_server_base() + 'login', data={ 'user_name': pool_owner.user_name, 'password': '******' }).raise_for_status() response = s.delete(get_server_base() + 'pools/%s/' % pool_name) response.raise_for_status() with session.begin(): session.expire_all() with self.assertRaises(NoResultFound): SystemPool.by_name(pool_name) self.assertNotIn(pool, system.pools) self.assertFalse( system.active_access_policy.grants( self.user, SystemPermission.edit_system)) self.assertEquals(system.activity[-1].field_name, 'Pool') self.assertEquals(system.activity[-1].action, 'Removed') self.assertEquals(system.activity[-1].old_value, unicode_pool) self.assertEquals(system.activity[-2].field_name, 'Active Access Policy') self.assertEquals(system.activity[-2].old_value, 'Pool policy: %s' % pool_name) self.assertEquals(system.activity[-2].new_value, 'Custom access policy') self.assertEquals( 1, Activity.query.filter(Activity.field_name == u'Pool').filter( Activity.action == u'Deleted').filter( Activity.old_value == pool_name).count(), 'Expected to find activity record for pool deletion')
def test_create_button_is_absent_when_not_logged_in(self): b = self.browser b.get(get_server_base() + 'pools/') b.find_element_by_xpath( '//div[@id="grid" and ' 'not(.//button[normalize-space(string(.))="Create"])]')
def test_system_reserved_notification_on(self): with session.begin(): owner = data_setup.create_user( email_address=u'*****@*****.**') system = data_setup.create_system( fqdn=u'funcooker.ge.invalid', lab_controller=data_setup.create_labcontroller()) distro_tree = data_setup.create_distro_tree( distro_name=u'MicrowaveOS-20141016.0', variant=u'ThreeHeats', arch=u'x86_64') job = data_setup.create_running_job( owner=owner, system=system, distro_tree=distro_tree, whiteboard=u'Chain Reaction of Mental Anguish', recipe_whiteboard=u'Christmas Attack Zone') recipe = job.recipesets[0].recipes[0] mail_capture_thread.start_capturing() with session.begin(): bkr.server.mail.reservesys_notify(job.recipesets[0].recipes[0]) captured_mails = mail_capture_thread.stop_capturing() self.assertEqual(len(captured_mails), 1) sender, rcpts, raw_msg = captured_mails[0] self.assertEqual(rcpts, [owner.email_address]) msg = email.message_from_string(raw_msg) self.assertEqual(msg['To'], owner.email_address) self.assertEqual(msg['Subject'], '[Beaker System Reserved] funcooker.ge.invalid') self.assertEqual(msg['X-Beaker-Notification'], 'system-reservation') expected_mail_body = u"""\ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** This System is reserved by [email protected] To return this system early, you can click on 'Release System' against this recipe from the Web UI. Ensure you have your logs off the system before returning to Beaker. %(base)srecipes/%(recipeid)s For ssh, kvm, serial and power control operations please look here: %(base)sview/funcooker.ge.invalid For the default root password, see: %(base)sprefs Beaker Test information: HOSTNAME=funcooker.ge.invalid JOBID=%(jobid)s RECIPEID=%(recipeid)s DISTRO=MicrowaveOS-20141016.0 ThreeHeats x86_64 ARCHITECTURE=x86_64 Job Whiteboard: Chain Reaction of Mental Anguish Recipe Whiteboard: Christmas Attack Zone ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **""" \ % dict(base=get_server_base(), recipeid=recipe.id, jobid=job.id) actual_mail_body = msg.get_payload(decode=True) self.assertEqual(actual_mail_body, expected_mail_body)
def test_add_remove_owner_group(self): with session.begin(): user = data_setup.create_user(password='******') group = data_setup.create_group(owner=user) user1 = data_setup.create_user(password='******') b = self.browser login(b, user=user.user_name, password='******') b.get(get_server_base() + 'groups/mine') # remove self (as only owner) b.find_element_by_link_text(group.group_name).click() b.find_element_by_xpath('//td[preceding-sibling::td/text()="%s"]' % user.user_name)\ .find_element_by_link_text('Remove').click() flash_text = b.find_element_by_class_name('flash').text self.assert_("Cannot remove the only owner" in flash_text) # add a new user as owner b.find_element_by_xpath( '//input[@id="GroupUser_user_text"]').send_keys(user1.user_name) b.find_element_by_id('GroupUser').submit() b.find_element_by_xpath('//td[text()="%s"]' % user1.user_name) b.find_element_by_xpath('//td[preceding-sibling::td/text()="%s"]' % user1.user_name)\ .find_element_by_link_text('Add').click() b.find_element_by_xpath('//td[preceding-sibling::td/text()="%s"]' % user1.user_name)\ .find_element_by_link_text('Remove') logout(b) # login as the new user and check for ownership login(b, user=user1.user_name, password='******') b.get(get_server_base() + 'groups/mine') b.find_element_by_link_text(group.group_name).click() b.find_element_by_xpath('//input') with session.begin(): self.assertEquals( Activity.query.filter_by(service=u'WEBUI', field_name=u'Owner', action=u'Added', new_value=user1.user_name).count(), 1) group = Group.by_name(group.group_name) self.assert_(group.has_owner(user1)) self.assertEquals(group.activity[-1].action, u'Added') self.assertEquals(group.activity[-1].field_name, u'Owner') self.assertEquals(group.activity[-1].new_value, user1.user_name) self.assertEquals(group.activity[-1].service, u'WEBUI') # remove self as owner b.find_element_by_xpath('//td[preceding-sibling::td/text()="%s"]' % user1.user_name)\ .find_element_by_link_text('Remove').click() b.find_element_by_xpath('//title[text()="My Groups"]') with session.begin(): self.assertEquals( Activity.query.filter_by(service=u'WEBUI', field_name=u'Owner', action=u'Removed', old_value=user1.user_name).count(), 1) session.refresh(group) self.assertEquals(group.activity[-1].action, u'Removed') self.assertEquals(group.activity[-1].field_name, u'Owner') self.assertEquals(group.activity[-1].old_value, user1.user_name) self.assertEquals(group.activity[-1].service, u'WEBUI')
def check_cannot_change_retention_tag(self, job): b = self.browser b.get(get_server_base() + 'jobs/%s' % job.id) self.assertFalse(b.find_element_by_id('job_retentiontag').is_enabled())
def test_task_disable_not_available_normal_user(self): login(self.browser, user=self.normal_user.user_name, password=u'secret') b = self.browser b.get(get_server_base() + 'tasks/%s' % self.my_task.id) b.find_element_by_xpath('//button[not(contains(text(), "Disable"))]')
def go_to_listing(self): self.browser.get(get_server_base())
def test_atom_feed_link_is_present(self): b = self.browser b.get(get_server_base()) b.find_element_by_xpath( '/html/head/link[@rel="feed" ' 'and @title="Atom feed" and contains(@href, "tg_format=atom")]')
def test_it(self): b = self.browser b.get(get_server_base()) click_menu_item(b, 'Reports', 'Matrix') b.find_element_by_name('whiteboard_filter').send_keys( self.job_whiteboard) b.find_element_by_xpath('//button[text()="Filter"]').click() Select(b.find_element_by_name('whiteboard'))\ .select_by_visible_text(self.job_whiteboard) b.find_element_by_xpath('//button[text()="Generate"]').click() thead = b.find_element_by_xpath( '//div[@class="dataTables_scrollHeadInner"]/table[1]/thead') self.assertEquals( thead.find_element_by_xpath('tr[1]/th[1]').text, 'Task') self.assertEquals( thead.find_element_by_xpath('tr[1]/th[2]').text, 'i386') self.assertEquals( thead.find_element_by_xpath('tr[1]/th[3]').text, 'ia64') self.assertEquals( thead.find_element_by_xpath('tr[1]/th[4]').text, 'x86_64') tbody = b.find_element_by_xpath('//table[@id="matrix_datagrid"]/tbody') tbody.find_element_by_xpath( './/td[normalize-space(string(.))="Pass: 1"]') tbody.find_element_by_xpath( './/td[normalize-space(string(.))="Warn: 1"]') tbody.find_element_by_xpath( './/td[normalize-space(string(.))="Fail: 1"]') self.assertEquals( thead.find_element_by_xpath('tr[2]/th[2]').text, self.recipe_whiteboard) self.assertEquals( thead.find_element_by_xpath('tr[2]/th[3]').text, self.recipe_whiteboard) self.assertEquals( thead.find_element_by_xpath('tr[2]/th[4]').text, self.recipe_whiteboard) b.find_element_by_link_text('Pass: 1').click() b.find_element_by_xpath('//title[text()="Executed Tasks"]') self.assertEquals( b.find_element_by_name('whiteboard').get_attribute('value'), self.recipe_whiteboard) self.assertEquals( b.find_element_by_xpath('//table/tbody/tr[1]/td[1]').text, self.passed_job.recipesets[0].recipes[0].tasks[0].t_id) b.back() b.find_element_by_link_text('Warn: 1').click() b.find_element_by_xpath('//title[text()="Executed Tasks"]') self.assertEquals( b.find_element_by_name('whiteboard').get_attribute('value'), self.recipe_whiteboard) self.assertEquals( b.find_element_by_xpath('//table/tbody/tr[1]/td[1]').text, self.warned_job.recipesets[0].recipes[0].tasks[0].t_id) b.back() b.find_element_by_link_text('Fail: 1').click() b.find_element_by_xpath('//title[text()="Executed Tasks"]') self.assertEquals( b.find_element_by_name('whiteboard').get_attribute('value'), self.recipe_whiteboard) self.assertEquals( b.find_element_by_xpath('//table/tbody/tr[1]/td[1]').text, self.failed_job.recipesets[0].recipes[0].tasks[0].t_id)
def test_message_when_not_logged_in(self): b = self.browser b.get(get_server_base() + 'jobs/mine') # XXX should check for 403 response code self.assertEquals( b.find_element_by_css_selector('#message').text, 'Please log in.')
def test_submit_no_task(self): b = self.browser b.get(get_server_base() + 'tasks/new') b.find_element_by_xpath('//button[text()="Upload"]').click() self.assertEquals(b.find_element_by_class_name('flash').text, "No task RPM specified")
def go_to_distro_view(browser, distro): browser.get(get_server_base() + 'distros/view?id=%s' % distro.id)
def test_message_when_explicitly_logging_in(self): b = self.browser b.get(get_server_base()) b.find_element_by_link_text('Log in').click() self.assertEquals( b.find_element_by_css_selector('#message').text, 'Please log in.')
def go_to_pool_edit(self, pool=None): if pool is None: pool = self.pool b = self.browser b.get(get_server_base() + 'pools/%s/' % pool.name)
def test_search_is_not_there(self): b = self.browser b.get(get_server_base() + 'distrofamily/') b.find_element_by_xpath('//div[@class="page-header" and ' 'not(..//form[@id="Search"]//' 'input[@name="osversion.text"])]')
def go_to_provision_tab(self, system): b = self.browser b.get(get_server_base() + 'view/%s' % system.fqdn) b.find_element_by_link_text('Provision').click() return b.find_element_by_id('provision')
def test_get_access_policy_for_nonexistent_system(self): response = requests.get(get_server_base() + 'systems/notexist/access-policy') self.assertEquals(response.status_code, 404)
def test_single_job(self): with session.begin(): unique_whiteboard = data_setup.unique_name('whiteboard%s') non_unique_whiteboard = data_setup.unique_name('whiteboard%s') non_unique_rwhiteboard = data_setup.unique_name('rwhiteboard%s') distro_tree = data_setup.create_distro_tree(arch=u'i386') for i in range(0, 9): data_setup.create_completed_job( whiteboard=non_unique_whiteboard, result=TaskResult.pass_, recipe_whiteboard=non_unique_rwhiteboard, distro_tree=distro_tree) single_job = data_setup.create_completed_job( whiteboard=unique_whiteboard, result=TaskResult.pass_, recipe_whiteboard=data_setup.unique_name('rwhiteboard%s'), distro_tree=distro_tree) b = self.browser b.get(get_server_base() + 'matrix') # No need to filter the whiteboard, we just created the jobs so they # will be at the top of the list of whiteboards. b.find_element_by_xpath("//select/option[@value='%s']" % unique_whiteboard).click() b.find_element_by_xpath( '//button[@type="submit" and text()="Generate"]').click() b.find_element_by_link_text('Pass: 1').click() # Should take us to Executed Tasks filtered by whiteboard. # There should only be one task in the results. tasks_table = b.find_element_by_css_selector('table.tasks') task_ids = [ e.text for e in tasks_table.find_elements_by_xpath( 'tbody/tr/td[1][@class="task"]') ] self.assertEquals(task_ids, [single_job.recipesets[0].recipes[0].tasks[0].t_id]) # Test by job id # See https://bugzilla.redhat.com/show_bug.cgi?id=803713 with session.begin(): single_job_2 = data_setup.create_completed_job( whiteboard=non_unique_whiteboard, result=TaskResult.pass_, recipe_whiteboard=non_unique_rwhiteboard, distro_tree=distro_tree) b = self.browser b.get(get_server_base() + 'matrix') b.find_element_by_id('remote_form_job_ids').send_keys( str(single_job_2.id)) b.find_element_by_xpath( '//button[@type="submit" and text()="Generate"]').click() b.find_element_by_link_text('Pass: 1').click() # Should take us to Executed Tasks filtered by whiteboard and job ID. # There should only be one task in the results. tasks_table = b.find_element_by_css_selector('table.tasks') task_ids = [ e.text for e in tasks_table.find_elements_by_xpath( 'tbody/tr/td[1][@class="task"]') ] self.assertEquals( task_ids, [single_job_2.recipesets[0].recipes[0].tasks[0].t_id])
def test_mine_filter_needs_authentication(self): response = requests.get(get_server_base() + 'systems/%s/access-policy?mine=1' % self.system.fqdn) self.assertEquals(response.status_code, 401) self.assertEquals(response.text, "The 'mine' access policy filter requires authentication")
def check_can_change_retention_tag(self, job, new_tag): b = self.browser b.get(get_server_base() + 'jobs/%s' % job.id) Select(b.find_element_by_id('job_retentiontag')) \ .select_by_visible_text(new_tag) b.find_element_by_xpath('//div[text()="Tag has been updated"]')
def test_unknown_uuid(self): response = requests.get(get_server_base() + 'systems/by-uuid/%s/ipxe-script' % uuid.uuid4()) self.assertEquals(response.status_code, 404)
def test_sort_grid_doesnt_blow_up(self): b = self.browser b.get(get_server_base() + 'osversions/') b.find_element_by_xpath( "//th/a[normalize-space(text())='Alias']").click() b.find_element_by_xpath("//title[text()='OS Versions']")
def go_to_system_view(self, system): b = self.browser b.get(get_server_base() + 'view/%s' % system.fqdn) b.find_element_by_xpath('//title[normalize-space(text())="%s"]' % system.fqdn)
def test_invalid_uuid(self): response = requests.get(get_server_base() + 'systems/by-uuid/blerg/ipxe-script') self.assertEquals(response.status_code, 404)
def test_reserved_openstack_instance(self): with session.begin(): owner = data_setup.create_user( email_address=u'*****@*****.**') distro_tree = data_setup.create_distro_tree( distro_name=u'MicrowaveOS-20141016.1', variant=u'ThreeHeats', arch=u'x86_64') job = data_setup.create_job( owner=owner, distro_tree=distro_tree, whiteboard=u'Operation Righteous Cowboy Lightning', recipe_whiteboard=u'Everything Sunny All the Time Always') recipe = job.recipesets[0].recipes[0] data_setup.mark_recipe_running( recipe, virt=True, instance_id=uuid.UUID('00000000-1111-2222-3333-444444444444'), fqdn=u'bitenuker.ge.invalid') mail_capture_thread.start_capturing() with session.begin(): bkr.server.mail.reservesys_notify(recipe) captured_mails = mail_capture_thread.stop_capturing() self.assertEqual(len(captured_mails), 1) sender, rcpts, raw_msg = captured_mails[0] self.assertEqual(rcpts, [owner.email_address]) msg = email.message_from_string(raw_msg) self.assertEqual(msg['To'], owner.email_address) self.assertEqual(msg['Subject'], '[Beaker System Reserved] bitenuker.ge.invalid') self.assertEqual(msg['X-Beaker-Notification'], 'system-reservation') expected_mail_body = u"""\ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** This System is reserved by [email protected] To return this system early, you can click on 'Release System' against this recipe from the Web UI. Ensure you have your logs off the system before returning to Beaker. %(base)srecipes/%(recipeid)s For system details, see: http://openstack.example.invalid/dashboard/project/instances/00000000-1111-2222-3333-444444444444/ For the default root password, see: %(base)sprefs Beaker Test information: HOSTNAME=bitenuker.ge.invalid JOBID=%(jobid)s RECIPEID=%(recipeid)s DISTRO=MicrowaveOS-20141016.1 ThreeHeats x86_64 ARCHITECTURE=x86_64 Job Whiteboard: Operation Righteous Cowboy Lightning Recipe Whiteboard: Everything Sunny All the Time Always ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **""" \ % dict(base=get_server_base(), recipeid=recipe.id, jobid=job.id) actual_mail_body = msg.get_payload(decode=True) self.assertMultiLineEqual(actual_mail_body, expected_mail_body)