def test_PUT_recipe_log_after_finished(self): with session.begin(): data_setup.mark_recipe_complete(self.recipe, only=True) assert self.recipe.is_finished() upload_url = '%srecipes/%s/logs/PUT-recipe-log' % (self.get_proxy_url(), self.recipe.id) response = requests.put(upload_url, data='a' * 10) self.assertEquals(response.status_code, 409)
def test_PUT_recipe_log_after_finished(self): with session.begin(): data_setup.mark_recipe_complete(self.recipe, only=True) assert self.recipe.is_finished() upload_url = '%srecipes/%s/logs/PUT-recipe-log' % ( self.get_proxy_url(), self.recipe.id) response = requests.put(upload_url, data='a' * 10) self.assertEquals(response.status_code, 409)
def test_complete_job_results(self): complete_job_xml = pkg_resources.resource_string( 'bkr.inttest', 'complete-job.xml') xmljob = lxml.etree.fromstring(complete_job_xml) job = testutil.call(self.controller.process_xmljob, xmljob, self.user) session.flush() # Complete the job, filling in values to match what's hardcoded in # complete-job-results.xml... recipe = job.recipesets[0].recipes[0] guestrecipe = recipe.guests[0] data_setup.mark_recipe_running( recipe, fqdn=u'system.test-complete-job-results', start_time=datetime.datetime(2016, 1, 31, 23, 0, 0), install_started=datetime.datetime(2016, 1, 31, 23, 0, 1), install_finished=datetime.datetime(2016, 1, 31, 23, 0, 2), postinstall_finished=datetime.datetime(2016, 1, 31, 23, 0, 3), task_start_time=datetime.datetime(2016, 1, 31, 23, 0, 4)) data_setup.mark_recipe_complete( guestrecipe, fqdn=u'guest.test-complete-job-results', mac_address='ff:ff:ff:00:00:00', start_time=datetime.datetime(2016, 1, 31, 23, 30, 0), install_started=datetime.datetime(2016, 1, 31, 23, 30, 1), install_finished=datetime.datetime(2016, 1, 31, 23, 30, 2), postinstall_finished=datetime.datetime(2016, 1, 31, 23, 30, 3), finish_time=datetime.datetime(2016, 1, 31, 23, 30, 4)) data_setup.mark_recipe_complete( recipe, only=True, start_time=datetime.datetime(2016, 1, 31, 23, 0, 4), finish_time=datetime.datetime(2016, 1, 31, 23, 59, 0)) recipe.installation.rendered_kickstart.url = u'http://example.com/recipe.ks' guestrecipe.installation.rendered_kickstart.url = u'http://example.com/guest.ks' session.flush() # Hack up the database ids... This will fail if it's flushed, but it's # the easiest way to make them match the expected values. job.id = 1 job.recipesets[0].id = 1 recipe.id = 1 guestrecipe.id = 2 recipe.tasks[0].id = 1 recipe.tasks[1].id = 2 guestrecipe.tasks[0].id = 3 guestrecipe.tasks[0].results[0].id = 1 recipe.tasks[0].results[0].id = 2 recipe.tasks[1].results[0].id = 3 expected_results_xml = pkg_resources.resource_string( 'bkr.inttest', 'complete-job-results.xml') expected_results_xml = expected_results_xml.replace( '${BEAKER_SERVER_BASE_URL}', get_server_base()) actual_results_xml = lxml.etree.tostring(job.to_xml(clone=False), pretty_print=True, encoding='utf8') self.assertMultiLineEqual(expected_results_xml, actual_results_xml)
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_nonexistent_watchdog(self): with session.begin(): recipe = data_setup.create_recipe() data_setup.create_job_for_recipes([recipe]) data_setup.mark_recipe_complete(recipe) try: run_client(['bkr', 'watchdog-extend', recipe.t_id]) self.fail('Must raise') except ClientError as e: self.assertIn('No watchdog exists for recipe %s' % recipe.id, e.stderr_output)
def test_xmlrpc_recipe_log_after_finished(self): with session.begin(): data_setup.mark_recipe_complete(self.recipe, only=True) assert self.recipe.is_finished() s = xmlrpclib.ServerProxy(self.get_proxy_url(), allow_none=True) try: s.recipe_upload_file(self.recipe.id, '/', 'recipe-log', 10, None, 0, b64encode('a' * 10)) self.fail('should raise') except xmlrpclib.Fault, fault: self.assert_('Cannot register file for finished recipe' in fault.faultString)
def _create_recipe(self, system=None): with session.begin(): install_task = Task.by_name(u'/distribution/install') reserve_task = Task.by_name(u'/distribution/reservesys') lc = create_lab_controller() rhel62_server_x86_64 = create_rhel62_server_x86_64(lab_controller=lc) if not system: system = create_x86_64_automated(lc) recipe = data_setup.create_recipe(distro_tree=rhel62_server_x86_64, task_list=[install_task, reserve_task]) data_setup.create_job_for_recipes([recipe], owner=create_user(), whiteboard=u'') data_setup.mark_recipe_complete(recipe, system=system) self.recipe_id = recipe.id return recipe
def _create_recipe_with_user_defined_distro(self, **kwargs): with session.begin(): install_task = Task.by_name(u'/distribution/check-install') reserve_task = Task.by_name(u'/distribution/reservesys') lc = create_lab_controller() system = create_x86_64_automated(lc) recipe = data_setup.create_recipe(custom_distro=True, osmajor=kwargs['osmajor'], task_list=[install_task, reserve_task]) if \ 'osmajor' in kwargs else data_setup.create_recipe(custom_distro=True, task_list=[install_task, reserve_task]) data_setup.create_job_for_recipes([recipe], owner=create_user(), whiteboard=u'') data_setup.mark_recipe_complete(recipe, system=system) self.recipe_id = recipe.id return recipe
def _create_recipe(self, system=None): with session.begin(): install_task = Task.by_name(u'/distribution/check-install') reserve_task = Task.by_name(u'/distribution/reservesys') lc = create_lab_controller() rhel62_server_x86_64 = create_rhel62_server_x86_64(lab_controller=lc) if not system: system = create_x86_64_automated(lc) recipe = data_setup.create_recipe(distro_tree=rhel62_server_x86_64, task_list=[install_task, reserve_task]) data_setup.create_job_for_recipes([recipe], owner=create_user(), whiteboard=u'') data_setup.mark_recipe_complete(recipe, system=system) self.recipe_id = recipe.id return recipe
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_recipe_view_shows_external_task_results(self): with session.begin(): recipe = data_setup.create_recipe(task_name=u'/distribution/install') external_task = RecipeTask.from_fetch_url( url='git://example.com/externaltasks/example#master', subdir='examples') recipe.tasks.extend([external_task]) data_setup.create_job_for_recipes([recipe], whiteboard='job with external tasks') data_setup.mark_recipe_complete(recipe, result=TaskResult.warn, task_status=TaskStatus.aborted) b = self.browser go_to_recipe_view(b, recipe=recipe, tab='Tasks') b.find_element_by_xpath('//div[@class="task-result-path"]/.[contains(text(), "%s")]' % external_task.fetch_url) b.find_element_by_xpath('//span[@class="task-name"]/.[contains(text(), "%s")]' % external_task.fetch_url)
def test_by_log_server_only_returns_completed_recipesets(self): with session.begin(): dt = data_setup.create_distro_tree() completed_recipe = data_setup.create_recipe(distro_tree=dt) incomplete_recipe = data_setup.create_recipe(distro_tree=dt) job = data_setup.create_job_for_recipes( [completed_recipe, incomplete_recipe]) job.recipesets[0].lab_controller = self.lc data_setup.mark_recipe_running(incomplete_recipe, system=data_setup.create_system(lab_controller=self.lc)) data_setup.mark_recipe_complete(completed_recipe, system=data_setup.create_system(lab_controller=self.lc)) result = self.server.recipes.by_log_server(self.lc.fqdn) self.assertEqual(result, [])
def test_complete_job_results(self): complete_job_xml = pkg_resources.resource_string('bkr.inttest', 'complete-job.xml') xmljob = lxml.etree.fromstring(complete_job_xml) job = testutil.call(self.controller.process_xmljob, xmljob, self.user) session.flush() # Complete the job, filling in values to match what's hardcoded in # complete-job-results.xml... recipe = job.recipesets[0].recipes[0] guestrecipe = recipe.guests[0] data_setup.mark_recipe_running(recipe, fqdn=u'system.test-complete-job-results', start_time=datetime.datetime(2016, 1, 31, 23, 0, 0), install_started=datetime.datetime(2016, 1, 31, 23, 0, 1), install_finished=datetime.datetime(2016, 1, 31, 23, 0, 2), postinstall_finished=datetime.datetime(2016, 1, 31, 23, 0, 3), task_start_time=datetime.datetime(2016, 1, 31, 23, 0, 4)) data_setup.mark_recipe_complete(guestrecipe, fqdn=u'guest.test-complete-job-results', mac_address='ff:ff:ff:00:00:00', start_time=datetime.datetime(2016, 1, 31, 23, 30, 0), install_started=datetime.datetime(2016, 1, 31, 23, 30, 1), install_finished=datetime.datetime(2016, 1, 31, 23, 30, 2), postinstall_finished=datetime.datetime(2016, 1, 31, 23, 30, 3), finish_time=datetime.datetime(2016, 1, 31, 23, 30, 4)) data_setup.mark_recipe_complete(recipe, only=True, start_time=datetime.datetime(2016, 1, 31, 23, 0, 4), finish_time=datetime.datetime(2016, 1, 31, 23, 59, 0)) recipe.installation.rendered_kickstart.url = u'http://example.com/recipe.ks' guestrecipe.installation.rendered_kickstart.url = u'http://example.com/guest.ks' session.flush() # Hack up the database ids... This will fail if it's flushed, but it's # the easiest way to make them match the expected values. job.id = 1 job.recipesets[0].id = 1 recipe.id = 1 guestrecipe.id = 2 recipe.tasks[0].id = 1 recipe.tasks[1].id = 2 guestrecipe.tasks[0].id = 3 guestrecipe.tasks[0].results[0].id = 1 recipe.tasks[0].results[0].id = 2 recipe.tasks[1].results[0].id = 3 expected_results_xml = pkg_resources.resource_string('bkr.inttest', 'complete-job-results.xml') expected_results_xml = expected_results_xml.replace( '${BEAKER_SERVER_BASE_URL}', get_server_base()) actual_results_xml = lxml.etree.tostring(job.to_xml(clone=False), pretty_print=True, encoding='utf8') self.assertMultiLineEqual(expected_results_xml, actual_results_xml)
def test_scheduler_status_is_not_reset_on_already_released_systems(self): first_recipe = data_setup.create_recipe() second_recipe = data_setup.create_recipe() job = data_setup.create_job_for_recipesets([ data_setup.create_recipeset_for_recipes([first_recipe]), data_setup.create_recipeset_for_recipes([second_recipe])]) data_setup.mark_recipe_complete(first_recipe) first_system = first_recipe.resource.system self.assertEquals(first_system.scheduler_status, SystemSchedulerStatus.pending) # Pretend the scheduler has set the system back to idle first_system.scheduler_status = SystemSchedulerStatus.idle data_setup.mark_recipe_scheduled(second_recipe) job.update_status() # The bug was that job.update_status() would reset the *first* recipe's # system back to pending, even though it had already been released and # could potentially be reserved for another recipe already. self.assertEquals(first_system.scheduler_status, SystemSchedulerStatus.idle)
def test_stops_collecting_console_log_when_recipe_aborted(self): first_line = 'Here is the first line of the log file.\n' open(self.console_log, 'w').write(first_line) wait_for_condition(self.check_console_log_registered) wait_for_condition(lambda: self.check_cached_log_contents(first_line)) # Abort the recipe with session.begin(): data_setup.mark_recipe_complete(self.recipe, only=True) # Wait for the watchdog to determine recipe aborted # Give beaker-watchdog a chance to notice time.sleep(get_conf().get('SLEEP_TIME') * 2) second_line = 'Here is the second line of the log file. FNORD FNORD FNORD\n' open(self.console_log, 'a').write(second_line) time.sleep(get_conf().get('SLEEP_TIME') * 2) self.assertTrue(self.check_cached_log_contents(first_line), "Log should just contain first log line")
def test_wait_duration_by_resource(self): system_recipe = data_setup.create_recipe() data_setup.create_job_for_recipes([system_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) data_setup.mark_recipe_complete(system_recipe) system_recipe2 = data_setup.create_recipe() data_setup.create_job_for_recipes([system_recipe2]) data_setup.mark_recipe_complete(system_recipe2, 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.resource.recipe.start_time = virt_recipe.resource.recipe.recipeset.queue_time + one_hour virt_recipe2.resource.recipe.start_time = virt_recipe2.resource.recipe.recipeset.queue_time + two_hours system_recipe.resource.recipe.start_time = system_recipe.resource.recipe.recipeset.queue_time + one_hour system_recipe2.resource.recipe.start_time = system_recipe2.resource.recipe.recipeset.queue_time + three_hours session.flush() rows = self.execute_reporting_query('wait-duration-by-resource') all_rows = rows.fetchall() virt_rows = [row for row in all_rows if row.fqdn == 'All OpenStack'] system_rows = [ row for row in all_rows if row.fqdn in (system_recipe.resource.fqdn, system_recipe2.resource.fqdn) ] self.assertEquals(len(virt_rows), 1, virt_rows) self.assertEquals(virt_rows[0].min_wait_hours, 1) self.assertEquals(virt_rows[0].max_wait_hours, 2) self.assertEquals(virt_rows[0].avg_wait_hours, Decimal('1.5')) self.assertEquals(len(system_rows), 1, system_rows) self.assertEquals(system_rows[0].min_wait_hours, 1) self.assertEquals(system_rows[0].max_wait_hours, 3) self.assertEquals(system_rows[0].avg_wait_hours, 2)
def test_shows_other_recipes_in_recipeset_holding_this_reservation(self): # Beaker keeps all systems in a recipe set reserved until all recipes # in the set are finished. This is to allow for things like multi-host # tests and virt testing, where one recipe might "drop off the end" but # the other machines still want to talk to it. # This is a frequent gotcha for users ("why is this system still # reserved even though the recipe is finished?") so we went to some # lengths in the new recipe page to indicate when this happens. with session.begin(): job = data_setup.create_job(num_recipes=2, num_guestrecipes=1) recipe = job.recipesets[0].recipes[0] data_setup.mark_recipe_complete(recipe) data_setup.mark_recipe_running(job.recipesets[0].recipes[1]) b = self.browser go_to_recipe_view(b, recipe, tab='Reservation') tab = b.find_element_by_id('reservation') self.assertEqual(tab.find_element_by_xpath('div/p[2]').text, 'However, the system has not been released yet because ' 'the following recipes are still running:') running_recipes_list_items = [li.text for li in tab.find_elements_by_xpath('.//ul[@class="running-recipes-list"]/li')] self.assertEqual(running_recipes_list_items, [job.recipesets[0].recipes[1].t_id, job.recipesets[0].recipes[2].t_id])
def test_wait_duration_by_resource(self): system_recipe = data_setup.create_recipe() data_setup.create_job_for_recipes([system_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) data_setup.mark_recipe_complete(system_recipe) system_recipe2 = data_setup.create_recipe() data_setup.create_job_for_recipes([system_recipe2]) data_setup.mark_recipe_complete(system_recipe2, 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.resource.recipe.start_time = virt_recipe.resource.recipe.recipeset.queue_time + one_hour virt_recipe2.resource.recipe.start_time = virt_recipe2.resource.recipe.recipeset.queue_time + two_hours system_recipe.resource.recipe.start_time = system_recipe.resource.recipe.recipeset.queue_time + one_hour system_recipe2.resource.recipe.start_time = system_recipe2.resource.recipe.recipeset.queue_time + three_hours session.flush() rows = self.execute_reporting_query("wait-duration-by-resource") all_rows = rows.fetchall() virt_rows = [row for row in all_rows if row.fqdn == "All oVirt"] system_rows = [ row for row in all_rows if row.fqdn in (system_recipe.resource.fqdn, system_recipe2.resource.fqdn) ] self.assertEquals(len(virt_rows), 1, virt_rows) self.assertEquals(virt_rows[0].min_wait_hours, 1) self.assertEquals(virt_rows[0].max_wait_hours, 2) self.assertEquals(virt_rows[0].avg_wait_hours, Decimal("1.5")) self.assertEquals(len(system_rows), 1, system_rows) self.assertEquals(system_rows[0].min_wait_hours, 1) self.assertEquals(system_rows[0].max_wait_hours, 3) self.assertEquals(system_rows[0].avg_wait_hours, 2)
def test_cee_ops_provided_queries(self): # CEE Ops is a team within Red Hat who relies heavily on Beaker. These # queries are used by their tooling to integrate with Beaker's # inventory. The queries are covered here in our test suite so that # they will know if any Beaker schema changes will affect these # queries. cee_users = data_setup.create_group(group_name=u'cee-users') cee_user = data_setup.create_user(user_name=u'billybob') cee_users.add_member(cee_user) # Create a system which has been manually reserved reserved_system = data_setup.create_system(fqdn=u'gsslab.reserved', status='Manual') data_setup.create_manual_reservation(reserved_system, user=cee_user, start=datetime.datetime( 2016, 1, 1, 0, 0)) # Create a system which is loaned out loaned_system = data_setup.create_system(fqdn=u'gsslab.loaned', status='Manual') data_setup.create_system_loan(loaned_system, user=cee_user, start=datetime.datetime( 2016, 1, 2, 0, 0)) # Create a system which has been provisioned with RHEL7.1 provisioned_system = data_setup.create_system( fqdn=u'gsslab.provisioned', status='Automated', lab_controller=data_setup.create_labcontroller()) recipe = data_setup.create_recipe(distro_name=u'RHEL-7.1', variant=u'Server') data_setup.create_job_for_recipes([recipe], owner=cee_user) data_setup.mark_recipe_complete(recipe, system=provisioned_system) # Create a non-CEE system which has been provisioned 20 times noncee_provisioned_system = data_setup.create_system( fqdn=u'noncee.provisioned', status='Automated', lab_controller=data_setup.create_labcontroller()) for _ in range(20): recipe = data_setup.create_recipe() data_setup.create_job_for_recipes([recipe], owner=cee_user) data_setup.mark_recipe_complete(recipe, system=noncee_provisioned_system) session.flush() rows = self.execute_reporting_query('cee/all-systems').fetchall() self.assertEqual(len(rows), 3) rows = self.execute_reporting_query('cee/reserved-systems').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.reserved') self.assertEqual(rows[0].start_time, datetime.datetime(2016, 1, 1, 0, 0)) rows = self.execute_reporting_query('cee/loaned-systems').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.loaned') rows = self.execute_reporting_query( 'cee/loaned-systems-by-date').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.loaned') self.assertEqual(rows[0].loan_date, datetime.datetime(2016, 1, 2, 0, 0)) rows = self.execute_reporting_query('cee/system-provisions').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.provisioned') self.assertEqual(rows[0].count, 1) rows = self.execute_reporting_query( 'cee/system-reservations').fetchall() self.assertEqual(len(rows), 2) self.assertEqual(rows[0].fqdn, u'gsslab.provisioned') self.assertEqual(rows[0].count, 1) self.assertEqual(rows[1].fqdn, u'gsslab.reserved') self.assertEqual(rows[1].count, 1) rows = self.execute_reporting_query( 'cee/system-distrotrees').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.provisioned') self.assertEqual(rows[0].operatingsystem, u'RHEL-7.1 Server i386') rows = self.execute_reporting_query( 'cee/provisions-by-distrotree').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].operatingsystem, u'RHEL-7.1 Server i386') self.assertEqual(rows[0].count, 1) rows = self.execute_reporting_query( 'cee/provisions-by-user').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].user_name, u'billybob') self.assertEqual(rows[0].count, 21) rows = self.execute_reporting_query( 'cee/non-cee-provisions-by-user').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'noncee.provisioned') self.assertEqual(rows[0].count, 20)
def test_cee_ops_provided_queries(self): # CEE Ops is a team within Red Hat who relies heavily on Beaker. These # queries are used by their tooling to integrate with Beaker's # inventory. The queries are covered here in our test suite so that # they will know if any Beaker schema changes will affect these # queries. cee_users = data_setup.create_group(group_name=u'cee-users') cee_user = data_setup.create_user(user_name=u'billybob') cee_users.add_member(cee_user) # Create a system which has been manually reserved reserved_system = data_setup.create_system(fqdn=u'gsslab.reserved', status='Manual') data_setup.create_manual_reservation(reserved_system, user=cee_user, start=datetime.datetime(2016, 1, 1, 0, 0)) # Create a system which is loaned out loaned_system = data_setup.create_system(fqdn=u'gsslab.loaned', status='Manual') data_setup.create_system_loan(loaned_system, user=cee_user, start=datetime.datetime(2016, 1, 2, 0, 0)) # Create a system which has been provisioned with RHEL7.1 provisioned_system = data_setup.create_system(fqdn=u'gsslab.provisioned', status='Automated', lab_controller=data_setup.create_labcontroller()) recipe = data_setup.create_recipe(distro_name=u'RHEL-7.1', variant=u'Server') data_setup.create_job_for_recipes([recipe], owner=cee_user) data_setup.mark_recipe_complete(recipe, system=provisioned_system) # Create a non-CEE system which has been provisioned 20 times noncee_provisioned_system = data_setup.create_system(fqdn=u'noncee.provisioned', status='Automated', lab_controller=data_setup.create_labcontroller()) for _ in range(20): recipe = data_setup.create_recipe() data_setup.create_job_for_recipes([recipe], owner=cee_user) data_setup.mark_recipe_complete(recipe, system=noncee_provisioned_system) session.flush() rows = self.execute_reporting_query('cee/all-systems').fetchall() self.assertEqual(len(rows), 3) rows = self.execute_reporting_query('cee/reserved-systems').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.reserved') self.assertEqual(rows[0].start_time, datetime.datetime(2016, 1, 1, 0, 0)) rows = self.execute_reporting_query('cee/loaned-systems').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.loaned') rows = self.execute_reporting_query('cee/loaned-systems-by-date').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.loaned') self.assertEqual(rows[0].loan_date, datetime.datetime(2016, 1, 2, 0, 0)) rows = self.execute_reporting_query('cee/system-provisions').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.provisioned') self.assertEqual(rows[0].count, 1) rows = self.execute_reporting_query('cee/system-reservations').fetchall() self.assertEqual(len(rows), 2) self.assertEqual(rows[0].fqdn, u'gsslab.provisioned') self.assertEqual(rows[0].count, 1) self.assertEqual(rows[1].fqdn, u'gsslab.reserved') self.assertEqual(rows[1].count, 1) rows = self.execute_reporting_query('cee/system-distrotrees').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'gsslab.provisioned') self.assertEqual(rows[0].operatingsystem, u'RHEL-7.1 Server i386') rows = self.execute_reporting_query('cee/provisions-by-distrotree').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].operatingsystem, u'RHEL-7.1 Server i386') self.assertEqual(rows[0].count, 1) rows = self.execute_reporting_query('cee/provisions-by-user').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].user_name, u'billybob') self.assertEqual(rows[0].count, 21) rows = self.execute_reporting_query('cee/non-cee-provisions-by-user').fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].fqdn, u'noncee.provisioned') self.assertEqual(rows[0].count, 20)
def test_page_updates_itself_while_recipe_is_running(self): with session.begin(): job = data_setup.create_job(owner=self.user, distro_tree=self.distro_tree) recipe = job.recipesets[0].recipes[0] b = self.browser # Open the recipe page while the recipe is still Queued. go_to_recipe_view(b, recipe) # Let the recipe finish (in reality there are of course many # intermediate steps here, but jumping straight to a finished recipe # still lets us check that all the pieces are updating themselves). with session.begin(): start_time = datetime.datetime.utcnow() finish_time = start_time + datetime.timedelta(seconds=1) system = data_setup.create_system(arch=u'x86_64', fqdn=u'pewlett-hackard-x004.example.com', lab_controller=self.lab_controller) data_setup.mark_recipe_complete(recipe, system=system, result=TaskResult.pass_, start_time=start_time, finish_time=finish_time) # Wait for the page to re-fetch the recipe JSON. time.sleep(30) # Check that everything has updated itself. self.assertEqual( b.find_element_by_xpath('//div[@class="recipe-summary"]/p[1]').text, 'Started a few seconds ago and finished in 00:00:01.') self.assertEqual( b.find_element_by_xpath('//div[@class="recipe-summary"]/p[2]').text, 'Using PurpleUmbrellaLinux5.11-20160428 Server x86_64\n' 'on pewlett-hackard-x004.example.com.') self.assertEqual( b.find_element_by_xpath('//div[@class="recipe-installation-summary"]/div[1]').text, 'Installation of PurpleUmbrellaLinux5.11-20160428 Server x86_64 finished.') b.find_element_by_xpath('//div[@class="recipe-installation-status"]' '/span[@class="label label-success" and text()="Completed"]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "Netboot configured")]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "System rebooted")]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "Installation started")]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "Installation completed")]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "Post-install tasks completed")]') b.find_element_by_xpath('//ul[contains(@class, "recipe-nav")]' '//a[text()="Tasks"]').click() self.assertEqual( b.find_element_by_xpath('//div[@class="recipe-tasks-summary"]/div[1]').text, 'Pass with 1 out of 1 tasks finished.') b.find_element_by_xpath('//div[@class="recipe-progress"]/span[text()="100%"]') b.find_element_by_xpath('//div[@class="recipe-progress"]' '/div[@class="progress"]/div[@class="bar bar-success" and @style="width: 100%;"]') task_element = b.find_element_by_xpath('//div[@id="task%s"]' % recipe.tasks[0].id) self.assertEqual( task_element.find_element_by_class_name('recipe-task-status').text, 'Pass') task_element.find_element_by_class_name('task-icon').click() result_element = task_element.find_element_by_class_name('recipe-task-result') result_element.find_element_by_xpath('div[@class="task-result-id"' ' and normalize-space(string(.))="%s"]' % recipe.tasks[0].results[0].t_id) result_element.find_element_by_xpath('div[@class="task-result-result"]' '/span[@class="label label-result-pass" and text()="Pass"]') b.find_element_by_xpath('//ul[contains(@class, "recipe-nav")]' '//a[text()="Reservation"]').click() self.assertEqual( b.find_element_by_xpath('//div[@id="reservation"]/div/p').text, 'The system was not reserved at the end of the recipe.')
def test_page_updates_itself_while_recipe_is_running(self): with session.begin(): job = data_setup.create_job(owner=self.user, distro_tree=self.distro_tree) recipe = job.recipesets[0].recipes[0] b = self.browser # Open the recipe page while the recipe is still Queued. go_to_recipe_view(b, recipe) # Let the recipe finish (in reality there are of course many # intermediate steps here, but jumping straight to a finished recipe # still lets us check that all the pieces are updating themselves). with session.begin(): start_time = datetime.datetime.utcnow() finish_time = start_time + datetime.timedelta(seconds=1) system = data_setup.create_system(arch=u'x86_64', fqdn=u'pewlett-hackard-x004.example.com', lab_controller=self.lab_controller) data_setup.mark_recipe_complete(recipe, system=system, result=TaskResult.pass_, start_time=start_time, finish_time=finish_time) # Wait for the page to re-fetch the recipe JSON. time.sleep(40) # Check that everything has updated itself. self.assertEqual( b.find_element_by_xpath('//div[@class="recipe-summary"]/p[1]').text, 'Started a few seconds ago and finished in 00:00:01.') self.assertEqual( b.find_element_by_xpath('//div[@class="recipe-summary"]/p[2]').text, 'Using PurpleUmbrellaLinux5.11-20160428 Server x86_64\n' 'on pewlett-hackard-x004.example.com.') self.assertEqual( b.find_element_by_xpath('//div[@class="recipe-installation-summary"]/div[1]').text, 'Installation of PurpleUmbrellaLinux5.11-20160428 Server x86_64 finished.') b.find_element_by_xpath('//div[@class="recipe-installation-status"]' '/span[@class="label label-success" and text()="Completed"]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "Netboot configured")]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "System rebooted")]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "Installation started")]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "Installation completed")]') b.find_element_by_xpath('//div[@class="recipe-installation-progress"]' '//td[contains(text(), "Post-install tasks completed")]') b.find_element_by_xpath('//ul[contains(@class, "recipe-nav")]' '//a[text()="Tasks"]').click() self.assertEqual( b.find_element_by_xpath('//div[@class="recipe-tasks-summary"]/div[1]').text, 'Pass with 1 out of 1 tasks finished.') b.find_element_by_xpath('//div[@class="recipe-progress"]/span[text()="100%"]') b.find_element_by_xpath('//div[@class="recipe-progress"]' '/div[@class="progress"]/div[@class="bar bar-success" and @style="width: 100%;"]') task_element = b.find_element_by_xpath('//div[@id="task%s"]' % recipe.tasks[0].id) self.assertEqual( task_element.find_element_by_class_name('recipe-task-status').text, 'Pass') task_element.find_element_by_class_name('task-icon').click() result_element = task_element.find_element_by_class_name('recipe-task-result') result_element.find_element_by_xpath('div[@class="task-result-id"' ' and normalize-space(string(.))="%s"]' % recipe.tasks[0].results[0].t_id) result_element.find_element_by_xpath('div[@class="task-result-result"]' '/span[@class="label label-result-pass" and text()="Pass"]') b.find_element_by_xpath('//ul[contains(@class, "recipe-nav")]' '//a[text()="Reservation"]').click() self.assertEqual( b.find_element_by_xpath('//div[@id="reservation"]/div/p').text, 'The system was not reserved at the end of the recipe.')