From 89292b7d70719d3f24bb5e6bd832df9ecc8057a5 Mon Sep 17 00:00:00 2001 From: Csók Tamás <godhak@gmail.com> Date: Fri, 13 Mar 2015 20:32:03 +0100 Subject: [PATCH] selenium: logging revisited, errors corrected --- circle/dashboard/tests/selenium/basic_tests.py | 43 +++++++++++++++++++++++-------------------- circle/dashboard/tests/selenium/config.py | 10 ++++++++++ circle/dashboard/tests/selenium/util.py | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------- 3 files changed, 114 insertions(+), 77 deletions(-) diff --git a/circle/dashboard/tests/selenium/basic_tests.py b/circle/dashboard/tests/selenium/basic_tests.py index 66be58c..3014edc 100644 --- a/circle/dashboard/tests/selenium/basic_tests.py +++ b/circle/dashboard/tests/selenium/basic_tests.py @@ -17,7 +17,6 @@ # You should have received a copy of the GNU General Public License along # with CIRCLE. If not, see <http://www.gnu.org/licenses/>. import logging -from sys import stdout import random import re import urlparse @@ -34,10 +33,14 @@ from vm.models import Instance from .config import SeleniumConfig from .util import CircleSeleniumMixin, SeleniumMixin -logger = logging.getLogger(__name__) -consoleHandler = logging.StreamHandler(stdout) -logger.addHandler(consoleHandler) conf = SeleniumConfig() +log_formatter = logging.Formatter(conf.log_format) +logger = logging.getLogger(conf.logger_name) +fileHandler = logging.handlers.RotatingFileHandler( + conf.log_file, maxBytes=conf.log_size, backupCount=conf.log_backup) +fileHandler.setFormatter(log_formatter) +fileHandler.setLevel(logging.WARNING) +logger.addHandler(fileHandler) class BasicSeleniumTests(SeleniumTestCase, SeleniumMixin, CircleSeleniumMixin): @@ -82,9 +85,9 @@ class BasicSeleniumTests(SeleniumTestCase, SeleniumMixin, CircleSeleniumMixin): elif len(template_pool) == 1: chosen = template_pool[0] else: - logging.warning("Selenium did not found any templates") - logging.exception( - "System did not meet required conditions to continue") + logger.exception("Selenium did not found any templates") + raise Exception( + "Selenium did not found any templates") self.driver.get('%s/dashboard/template/%s/' % (conf.host, chosen)) acces_form = self.driver.find_element_by_css_selector( "form[action*='/dashboard/template/%(template_id)s/acl/']" @@ -106,10 +109,10 @@ class BasicSeleniumTests(SeleniumTestCase, SeleniumMixin, CircleSeleniumMixin): user_text = re.split(r':[ ]?', user.text) if len(user_text) == 2: found_name = re.search(r'[\w\W]+(?=\))', user_text[1]).group() - logging.info("'%(user)s' found in ACL " - "list for template %(id)s" % { - 'user': found_name, - 'id': chosen}) + logger.warning("'%(user)s' found in ACL " + "list for template %(id)s" % { + 'user': found_name, + 'id': chosen}) found_users.append(found_name) self.assertIn(conf.client_name, found_users, "Could not add user to template's ACL") @@ -124,7 +127,7 @@ class BasicSeleniumTests(SeleniumTestCase, SeleniumMixin, CircleSeleniumMixin): By.ID, 'confirmation-modal'))) template_list = self.driver.find_elements_by_class_name( 'template-choose-list-element') - logging.info('Selenium found %(count)s template possibilities' % { + logger.warning('Selenium found %(count)s template possibilities' % { 'count': len(template_list)}) (self.assertIsNotNone( template_list, "Selenium can not find the create template list") or @@ -157,7 +160,7 @@ class BasicSeleniumTests(SeleniumTestCase, SeleniumMixin, CircleSeleniumMixin): success = False self.login() for template_id in self.template_ids: - logging.info("Deleting template %s" % template_id) + logger.warning("Deleting template %s" % template_id) self.delete_template(template_id) existing_templates = self.get_template_id() if len(existing_templates) == 0: @@ -181,9 +184,9 @@ class BasicSeleniumTests(SeleniumTestCase, SeleniumMixin, CircleSeleniumMixin): By.ID, 'confirmation-modal'))) vm_list = self.driver.find_elements_by_class_name( 'vm-create-template-summary') - logging.info("Selenium found %(vm_number)s virtual machine template " - " possibilities" % { - 'vm_number': len(vm_list)}) + logger.warning("Selenium found %(vm_number)s virtual machine template " + " possibilities" % { + 'vm_number': len(vm_list)}) (self.assertIsNotNone( vm_list, "Selenium can not find the VM list") or self.assertGreater(len(vm_list), 0, "The create VM list is empty")) @@ -200,8 +203,8 @@ class BasicSeleniumTests(SeleniumTestCase, SeleniumMixin, CircleSeleniumMixin): "none", "", "block", "none"] states = self.view_change("vm") - logging.info('states: [%s]' % ', '.join(map(str, states))) - logging.info('expected: [%s]' % ', '.join(map(str, expected_states))) + logger.warning('states: [%s]' % ', '.join(map(str, states))) + logger.warning('expected: [%s]' % ', '.join(map(str, expected_states))) self.assertListEqual(states, expected_states, "The view mode does not change for VM listing") @@ -211,8 +214,8 @@ class BasicSeleniumTests(SeleniumTestCase, SeleniumMixin, CircleSeleniumMixin): "none", "", "block", "none"] states = self.view_change("node") - logging.info('states: [%s]' % ', '.join(map(str, states))) - logging.info('expected: [%s]' % ', '.join(map(str, expected_states))) + logger.warning('states: [%s]' % ', '.join(map(str, states))) + logger.warning('expected: [%s]' % ', '.join(map(str, expected_states))) self.assertListEqual(states, expected_states, "The view mode does not change for NODE listing") diff --git a/circle/dashboard/tests/selenium/config.py b/circle/dashboard/tests/selenium/config.py index 37bcdb8..47bbe00 100644 --- a/circle/dashboard/tests/selenium/config.py +++ b/circle/dashboard/tests/selenium/config.py @@ -24,6 +24,16 @@ class SeleniumConfig: wait_max_sec = 10 # How much sec can pass before the activity is no longer happened recently recently_sec = 90 + # Name of the logger (necessary to override test logger) + logger_name = "selenium" + # File where the log should be stored + log_file = "selenium.log" + # Log file max size in Bytes + log_size = 1024 * 100 + # Format of the log file + log_format = "%(asctime)s: %(name)s: %(levelname)s: %(message)s" + # Backup count of the logfiles + log_backup = 5 # Accented letters from which selenium can choose to name stuff accents = u"áéíöóúűÁÉÍÖÓÜÚŰ" diff --git a/circle/dashboard/tests/selenium/util.py b/circle/dashboard/tests/selenium/util.py index cdd8bee..433eef5 100644 --- a/circle/dashboard/tests/selenium/util.py +++ b/circle/dashboard/tests/selenium/util.py @@ -18,7 +18,6 @@ # with CIRCLE. If not, see <http://www.gnu.org/licenses/>. from datetime import datetime import logging -from sys import stdout import random import re import time @@ -30,9 +29,9 @@ from selenium.webdriver.support import expected_conditions as ec from selenium.webdriver.support.select import Select from selenium.webdriver.support.ui import WebDriverWait -logger = logging.getLogger(__name__) -consoleHandler = logging.StreamHandler(stdout) -logger.addHandler(consoleHandler) +from .config import SeleniumConfig + +logger = logging.getLogger(SeleniumConfig.logger_name) class CircleSeleniumMixin(object): @@ -73,7 +72,8 @@ class CircleSeleniumMixin(object): except: time.sleep(0.5) except: - logging.exception('Selenium cannot find the form controls') + logger.exception("Selenium cannot find the form controls") + raise Exception('Cannot find the form controls') def wait_and_accept_operation(self, argument=None): """ @@ -97,8 +97,10 @@ class CircleSeleniumMixin(object): form.send_keys(argument) accept.click() except: - logging.exception( - 'Selenium cannot accept the operation confirmation') + logger.exception("Selenium cannot accept the" + " operation confirmation") + raise Exception( + 'Cannot accept the operation confirmation') def save_template_from_vm(self, name): try: @@ -111,9 +113,9 @@ class CircleSeleniumMixin(object): recent_deploy = self.recently(self.get_timeline_elements( "vm.Instance.deploy")) if not self.check_operation_result(recent_deploy): - logging.warning("Selenium cannot deploy the " - "chosen template virtual machine") - logging.exception('Cannot deploy the virtual machine') + logger.warning("Selenium cannot deploy the " + "chosen template virtual machine") + raise Exception('Cannot deploy the virtual machine') self.click_on_link(WebDriverWait( self.driver, self.conf.wait_max_sec).until( ec.element_to_be_clickable(( @@ -123,9 +125,9 @@ class CircleSeleniumMixin(object): recent_shut_off = self.recently(self.get_timeline_elements( "vm.Instance.shut_off")) if not self.check_operation_result(recent_shut_off): - logging.warning("Selenium cannot shut off the " - "chosen template virtual machine") - logging.exception('Cannot shut off the virtual machine') + logger.warning("Selenium cannot shut off the " + "chosen template virtual machine") + raise Exception('Cannot shut off the virtual machine') self.click_on_link(WebDriverWait( self.driver, self.conf.wait_max_sec).until( ec.element_to_be_clickable(( @@ -134,8 +136,9 @@ class CircleSeleniumMixin(object): self.wait_and_accept_operation(name) return name except: - logging.exception( - 'Selenium cannot save a vm as a template') + logger.exception("Selenium cannot save a vm as a template") + raise Exception( + 'Cannot save a vm as a template') def create_base_template(self, name=None, architecture="x86-64", method=None, op_system=None, lease=None, @@ -171,8 +174,10 @@ class CircleSeleniumMixin(object): "input.btn[type='submit']").click() return self.save_template_from_vm(name) except: - logging.exception( - 'Selenium cannot create a base template virtual machine') + logger.exception("Selenium cannot create a base" + " template virtual machine") + raise Exception( + 'Cannot create a base template virtual machine') def get_template_id(self, name=None, from_all=False): """ @@ -195,7 +200,8 @@ class CircleSeleniumMixin(object): ec.presence_of_element_located(( By.CSS_SELECTOR, css_selector_of_a_template))) except: - logging.warning("Selenium could not locate any templates") + logger.warning("Selenium could not locate any templates") + raise Exception("Could not locate any templates") template_table = self.driver.find_element_by_css_selector( "table[class*='template-list-table']") templates = template_table.find_elements_by_css_selector("td.name") @@ -209,22 +215,24 @@ class CircleSeleniumMixin(object): r'\d+', template_link.get_attribute("outerHTML")).group() found_template_ids.append(template_id) - logging.info("Found '%(name)s' " - "template's ID as %(id)s" % { - 'name': template.text, - 'id': template_id}) + logger.warning("Found '%(name)s' " + "template's ID as %(id)s" % { + 'name': template.text, + 'id': template_id}) except NoSuchElementException: pass except: raise if not found_template_ids and name is not None: - logging.warning("Selenium could not find the specified " - "%(name)s template in the list" % { - 'name': name}) + logger.warning("Selenium could not find the specified " + "%(name)s template in the list" % { + 'name': name}) + raise Exception("Could not find the specified template") return found_template_ids except: - logging.exception( - 'Selenium cannot found the template\'s id') + logger.exception('Selenium cannot find the template\'s id') + raise Exception( + 'Cannot find the template\'s id') def check_operation_result(self, operation_id, restore=True): """ @@ -246,7 +254,7 @@ class CircleSeleniumMixin(object): result = WebDriverWait(self.driver, self.conf.wait_max_sec).until( ec.visibility_of_element_located(( By.ID, "activity_status"))) - logging.info("%(id)s result text is '%(result)s'" % { + logger.warning("%(id)s result text is '%(result)s'" % { 'id': operation_id, 'result': result.text}) if (result.text == "success"): @@ -257,12 +265,14 @@ class CircleSeleniumMixin(object): else: out = False if restore: - logging.info("Restoring to %s url" % url_save) + logger.warning("Restoring to %s url" % url_save) self.driver.get(url_save) return out except: - logging.exception( - 'Selenium cannot check the result of an operation') + logger.exception("Selenium cannot check the" + " result of an operation") + raise Exception( + 'Cannot check the result of an operation') def recently(self, timeline_dict, second=None): if second is None: @@ -275,8 +285,10 @@ class CircleSeleniumMixin(object): if delta.total_seconds() <= second: return value except: - logging.exception( - 'Selenium cannot filter timeline activities to recent') + logger.exception("Selenium cannot filter" + " timeline activities to recent") + raise Exception( + 'Cannot filter timeline activities to recent') def get_timeline_elements(self, code=None): try: @@ -297,19 +309,20 @@ class CircleSeleniumMixin(object): By.ID, "activity-timeline"))) searched_activity = timeline.find_elements_by_css_selector( css_activity_selector) - logging.info("Found activity list for %s:" % code) + logger.warning("Found activity list for %s:" % code) for activity in searched_activity: activity_id = activity.get_attribute('data-activity-id') activity_text = activity.text key = re.search( r'\d+-\d+-\d+ \d+:\d+,', activity_text).group()[:-1] - logging.info("%(id)s @ %(activity)s" % { + logger.warning("%(id)s @ %(activity)s" % { 'id': activity_id, 'activity': key}) activity_dict[key] = activity_id return activity_dict except: - logging.exception('Selenium cannot find the searched activity') + logger.exception('Selenium cannot find the searched activity') + raise Exception('Cannot find the searched activity') def create_template_from_base(self, delete_disk=True, name=None): try: @@ -346,13 +359,15 @@ class CircleSeleniumMixin(object): self.get_timeline_elements( "vm.Instance.remove_disk")) if not self.check_operation_result(recent_remove_disk): - logging.warning("Selenium cannot delete disk " - "of the chosen template") - logging.exception('Cannot delete disk') + logger.warning("Selenium cannot delete disk " + "of the chosen template") + raise Exception('Cannot delete disk') return self.save_template_from_vm(name) except: - logging.exception( - 'Selenium cannot start a template from a base one') + logger.exception("Selenium cannot start a" + " template from a base one") + raise Exception( + 'Cannot start a template from a base one') def delete_template(self, template_id): try: @@ -368,10 +383,12 @@ class CircleSeleniumMixin(object): By.CLASS_NAME, 'alert-success'))) url = urlparse.urlparse(self.driver.current_url) if "/template/list/" not in url.path: - logging.exception( + logger.warning('CIRCLE does not redirect to /template/list/') + raise Exception( 'System does not redirect to template listing') except: - logging.exception('Selenium cannot delete the desired template') + logger.exception("Selenium cannot delete the desired template") + raise Exception('Cannot delete the desired template') def create_random_vm(self): try: @@ -392,7 +409,8 @@ class CircleSeleniumMixin(object): pk = re.search(r'\d+', url.path).group() return pk except: - logging.exception('Selenium cannot start a VM') + logger.exception("Selenium cannot start a VM") + raise Exception('Cannot start a VM') def view_change(self, target_box): driver = self.driver @@ -438,10 +456,10 @@ class CircleSeleniumMixin(object): recent_destroy_vm = self.recently( self.get_timeline_elements("vm.Instance.destroy")) if not self.check_operation_result(recent_destroy_vm): - logging.warning("Selenium cannot destroy " - "the chosen %(id)s vm" % { - 'id': pk}) - logging.exception('Cannot destroy the specified vm') + logger.warning("Selenium cannot destroy " + "the chosen %(id)s vm" % { + 'id': pk}) + raise Exception('Cannot destroy the specified vm') self.driver.get('%s/dashboard/vm/%s/' % (self.conf.host, pk)) try: WebDriverWait(self.driver, self.conf.wait_max_sec).until( @@ -452,7 +470,8 @@ class CircleSeleniumMixin(object): except: return False except: - logging.exception("Selenium can not destroy a VM") + logger.exception("Selenium can not destroy a VM") + raise Exception("Can not destroy a VM") class SeleniumMixin(object): @@ -466,8 +485,10 @@ class SeleniumMixin(object): option_dic[key] = [option.text] return option_dic except: - logging.exception( - 'Selenium cannot list the select possibilities') + logger.exception("Selenium cannot list the" + " select possibilities") + raise Exception( + 'Cannot list the select possibilities') def select_option(self, select, what=None): """ @@ -497,8 +518,9 @@ class SeleniumMixin(object): 0, len(my_choose_list) - 1)] select.select_by_value(my_choice) except: - logging.exception( - 'Selenium cannot select the chosen one') + logger.exception("Selenium cannot select the chosen one") + raise Exception( + 'Cannot select the chosen one') def get_link_by_href(self, target_href, attributes=None): try: @@ -517,8 +539,9 @@ class SeleniumMixin(object): if perfect_fit: return link except: - logging.exception( - 'Selenium cannot find the href=%s link' % target_href) + logger.exception( + "Selenium cannot find the href=%s link" % target_href) + raise Exception('Cannot find the requested href') def click_on_link(self, link): """ @@ -544,5 +567,6 @@ class SeleniumMixin(object): "}") self.driver.execute_script(javascript, link) except: - logging.exception( - 'Selenium cannot inject javascript to the page') + logger.exception("Selenium cannot inject javascript to the page") + raise Exception( + 'Cannot inject javascript to the page') -- libgit2 0.26.0