Initialization of tox for conductor and portas. Add new webUI automated tests.

This commit is contained in:
Timur Nurlygayanov 2013-04-04 18:11:31 +04:00
parent 0719dfcb9d
commit 9223f3b9a4
10 changed files with 470 additions and 138 deletions

46
conductor/tox.ini Normal file
View File

@ -0,0 +1,46 @@
[tox]
envlist = py26,py27,pep8
[testenv]
setenv = VIRTUAL_ENV={envdir}
NOSE_WITH_OPENSTACK=1
NOSE_OPENSTACK_COLOR=1
NOSE_OPENSTACK_RED=0.05
NOSE_OPENSTACK_YELLOW=0.025
NOSE_OPENSTACK_SHOW_ELAPSED=1
deps = -r{toxinidir}/tools/pip-requires
-r{toxinidir}/tools/test-requires
commands = nosetests
[testenv:pep8]
deps = pep8==1.3.3
commands = pep8 --repeat --show-source conductor setup.py
[testenv:venv]
commands = {posargs}
[testenv:cover]
commands = nosetests --cover-erase --cover-package=conductor --with-xcoverage
[tox:jenkins]
downloadcache = ~/cache/pip
[testenv:jenkins26]
basepython = python2.6
setenv = NOSE_WITH_XUNIT=1
deps = file://{toxinidir}/.cache.bundle
[testenv:jenkins27]
basepython = python2.7
setenv = NOSE_WITH_XUNIT=1
deps = file://{toxinidir}/.cache.bundle
[testenv:jenkinscover]
deps = file://{toxinidir}/.cache.bundle
setenv = NOSE_WITH_XUNIT=1
commands = nosetests --cover-erase --cover-package=conductor --with-xcoverage
[testenv:jenkinsvenv]
deps = file://{toxinidir}/.cache.bundle
setenv = NOSE_WITH_XUNIT=1
commands = {posargs}

46
portas/tox.ini Normal file
View File

@ -0,0 +1,46 @@
[tox]
envlist = py26,py27,pep8
[testenv]
setenv = VIRTUAL_ENV={envdir}
NOSE_WITH_OPENSTACK=1
NOSE_OPENSTACK_COLOR=1
NOSE_OPENSTACK_RED=0.05
NOSE_OPENSTACK_YELLOW=0.025
NOSE_OPENSTACK_SHOW_ELAPSED=1
deps = -r{toxinidir}/tools/pip-requires
-r{toxinidir}/tools/test-requires
commands = nosetests
[testenv:pep8]
deps = pep8==1.3.3
commands = pep8 --repeat --show-source portas setup.py
[testenv:venv]
commands = {posargs}
[testenv:cover]
commands = nosetests --cover-erase --cover-package=portas --with-xcoverage
[tox:jenkins]
downloadcache = ~/cache/pip
[testenv:jenkins26]
basepython = python2.6
setenv = NOSE_WITH_XUNIT=1
deps = file://{toxinidir}/.cache.bundle
[testenv:jenkins27]
basepython = python2.7
setenv = NOSE_WITH_XUNIT=1
deps = file://{toxinidir}/.cache.bundle
[testenv:jenkinscover]
deps = file://{toxinidir}/.cache.bundle
setenv = NOSE_WITH_XUNIT=1
commands = nosetests --cover-erase --cover-package=portas --with-xcoverage
[testenv:jenkinsvenv]
deps = file://{toxinidir}/.cache.bundle
setenv = NOSE_WITH_XUNIT=1
commands = {posargs}

View File

@ -1,4 +1,4 @@
[server]
address=http://172.18.124.101
address=http://172.18.124.101:8080
user=admin
password=swordfish

View File

@ -4,15 +4,13 @@ import page
class DataCentersPage(page.Page):
name = 'DataCenters'
def create_data_center(self, name):
self.Refresh()
self.Button('Create Windows Data Center').Click()
self.EditBox('id_name').Set(name)
xpath = "//input[@value='Create']"
self.Button(xpath).Click()
self.Button('Create').Click()
def delete_data_center(self, name):
self.Refresh()
@ -20,13 +18,10 @@ class DataCentersPage(page.Page):
link = self.Link(name).Address()
datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1]
xpath = ".//*[@id='windc__row__%s']/td[4]/div/a[2]" % datacenter_id
self.Button(xpath).Click()
button_id = "windc__row_%s__action_delete" % datacenter_id
self.Button(button_id).Click()
self.Button("Delete Data Center").Click()
self.Button('More', datacenter_id).Click()
self.Button('Delete', datacenter_id).Click()
# confirm:
self.Button('Delete Data Center').Click()
def select_data_center(self, name):
self.Link(name).Click()
@ -39,16 +34,13 @@ class DataCentersPage(page.Page):
link = self.Link(name).Address()
datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1]
xpath = ".//*[@id='windc__row__%s']/td[4]/div/a[2]" % datacenter_id
self.Button(xpath).Click()
button_id = "windc__row_%s__action_deploy" % datacenter_id
self.Button(button_id).Click()
self.Button('More', datacenter_id).Click()
self.Button('Deploy', datacenter_id).Click()
def get_datacenter_status(self, name):
self.Navigate('Windows Data Centers')
self.Refresh()
link = self.Link(name).Address()
datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1]
xpath = ".//*[@id='windc__row__%s']/td[3]" % datacenter_id
return self.TableCell(xpath).Text()
return self.TableCell('Status', datacenter_id).Text()

View File

@ -0,0 +1,73 @@
<objects>
<object>
<type>Button</type>
<name>Create</name>
<parameter>//input[@value='Create']</parameter>
</object>
<object>
<type>Button</type>
<pagename>Services</pagename>
<name>More</name>
<parameter>.//*[@id='services__row__%s']/td[5]/div/a[2]</parameter>
</object>
<object>
<type>Button</type>
<pagename>Services</pagename>
<name>Delete</name>
<parameter>services__row_%s__action_delete</parameter>
</object>
<object>
<type>Button</type>
<pagename>Services</pagename>
<name>CreateService</name>
<parameter>services__action_CreateService</parameter>
</object>
<object>
<type>Button</type>
<pagename>DataCenters</pagename>
<name>More</name>
<parameter>.//*[@id='windc__row__%s']/td[4]/div/a[2]</parameter>
</object>
<object>
<type>Button</type>
<pagename>DataCenters</pagename>
<name>Delete</name>
<parameter>windc__row_%s__action_delete</parameter>
</object>
<object>
<type>Button</type>
<pagename>DataCenters</pagename>
<name>Deploy</name>
<parameter>windc__row_%s__action_deploy</parameter>
</object>
<object>
<type>TableCell</type>
<pagename>DataCenters</pagename>
<name>Status</name>
<parameter>.//*[@id='windc__row__%s']/td[3]</parameter>
</object>
<object>
<type>TableCell</type>
<pagename>ServicesDetails</pagename>
<name>Name</name>
<parameter>.//*[@id='services_details___service']/div/dl/dd[1]</parameter>
</object>
<object>
<type>TableCell</type>
<pagename>ServicesDetails</pagename>
<name>Domain</name>
<parameter>.//*[@id='services_details___service']/div/dl/dd[3]</parameter>
</object>
<object>
<type>Link</type>
<pagename>ServicesDetails</pagename>
<name>Service</name>
<parameter>.//*[@id='services_details']/li[1]/a</parameter>
</object>
<object>
<type>TableCell</type>
<pagename>Services</pagename>
<name>Status</name>
<parameter>.//*[@id='services__row__%s']/td[4]</parameter>
</object>
</objects>

View File

@ -1,7 +1,46 @@
import logging
from selenium.webdriver.support.ui import Select
import xml.etree.ElementTree as ET
logging.basicConfig()
LOG = logging.getLogger(' Page object: ')
"""
Disable selenium logging:
"""
logger = logging.getLogger('selenium.webdriver.remote.remote_connection')
logger.setLevel('ERROR')
class ObjectsLibrary:
file = None
objects = []
def __init__(self, file_name='objects.xml'):
"""
Initialization of the Objects Library.
Read objects descriptions from XML file.
"""
self.file = file_name
tree = ET.parse(self.file)
objects = tree.getroot()
self.objects = []
for element in objects:
object = {}
for parameter in element:
object.update({parameter.tag: parameter.text})
self.objects.append(object)
def get_object(self, name, pagename):
"""
Search objects in Objects Library.
"""
for object in self.objects:
obj_pagename = object.get('pagename', None)
if object['name'] == name and (obj_pagename == pagename
or obj_pagename is None):
return object['parameter']
return None
class TableCellClass:
@ -14,7 +53,8 @@ class TableCellClass:
def Text(self):
if self.table:
return self.table.text()
LOG.critical(self.table.text)
return self.table.text
else:
return ''
@ -75,8 +115,11 @@ class EditBoxClass:
def Set(self, value):
if self.edit:
self.edit.clear()
self.edit.send_keys(value)
try:
self.edit.clear()
self.edit.send_keys(value)
except:
LOG.error('Can not set value for text box.')
def Text(self):
if self.edit:
@ -100,7 +143,11 @@ class DropDownListClass:
def Set(self, value):
if self.select:
Select(self.select).select_by_visible_text(value)
try:
Select(self.select).select_by_visible_text(value)
except:
LOG.error('Can not select element %s from drop down list.'
.format(value))
def Text(self):
if self.select:
@ -118,40 +165,57 @@ error_msg = """
class Page:
driver = None
timeout = 30
timeout = 10
lib = None
name = None
def __init__(self, driver):
driver.set_page_load_timeout(30)
driver.set_page_load_timeout(self.timeout)
driver.implicitly_wait(0.01)
self.driver = driver
def _find_element(self, parameter):
def _find_element(self, name, parameter=None):
"""
This method allows to find element,
based on descriptions in Object Library,
xpath, id, name or pertial link text.
If parameter != None will be used name % parameter
"""
lib = ObjectsLibrary()
if lib.get_object(name, self.name):
name = lib.get_object(name, self.name)
if parameter:
name = name % parameter
obj = None
k = 0
while (obj is None and k < self.timeout):
k += 1
try:
obj = self.driver.find_element_by_name(parameter)
obj = self.driver.find_element_by_name(name)
return obj
except:
pass
try:
obj = self.driver.find_element_by_id(parameter)
obj = self.driver.find_element_by_id(name)
return obj
except:
pass
try:
obj = self.driver.find_element_by_xpath(parameter)
obj = self.driver.find_element_by_xpath(name)
return obj
except:
pass
try:
obj = self.driver.find_element_by_partial_link_text(parameter)
obj = self.driver.find_element_by_partial_link_text(name)
return obj
except:
pass
LOG.error(error_msg % parameter)
LOG.error(error_msg % name)
return None
def Open(self, url):
@ -160,32 +224,37 @@ class Page:
def Refresh(self):
self.driver.refresh()
def TableCell(self, name):
obj = self._find_element(name)
def TableCell(self, name, parameter=None):
obj = self._find_element(name, parameter)
table = TableCellClass(obj)
return table
def Button(self, name):
obj = self._find_element(name)
def Button(self, name, parameter=None):
obj = self._find_element(name, parameter)
button = ButtonClass(obj)
return button
def Link(self, name):
obj = self._find_element(name)
def Link(self, name, parameter=None):
obj = self._find_element(name, parameter)
link = LinkClass(obj)
return link
def EditBox(self, name):
obj = self._find_element(name)
def EditBox(self, name, parameter=None):
obj = self._find_element(name, parameter)
edit = EditBoxClass(obj)
return edit
def DropDownList(self, name):
obj = self._find_element(name)
def DropDownList(self, name, parameter=None):
obj = self._find_element(name, parameter)
select = DropDownListClass(obj)
return select
def Navigate(self, path):
"""
This method allows to navigate by
webUI menu button and links to
the specific page
"""
steps = path.split(':')
for step in steps:

View File

@ -0,0 +1,16 @@
import page
class ServicesDetailsPage(page.Page):
name = 'ServicesDetails'
def get_service_name(self):
self.Refresh()
self.Link('Service').Click()
return self.TableCell('Name').Text()
def get_service_domain(self):
self.Refresh()
self.Link('Service').Click()
return self.TableCell('Domain').Text()

View File

@ -1,20 +1,32 @@
import page
import re
from services_details_page import ServicesDetailsPage
class ServicesPage(page.Page):
name = 'Services'
def create_service(self, service_type, parameters):
def create_service(self, parameters):
service_type = parameters[0]
parameters = parameters[1]
self.Refresh()
self.Button('services__action_CreateService').Click()
self.Button('CreateService').Click()
self.DropDownList('0-service').Set(service_type)
self.Button('wizard_goto_step').Click()
for key in parameters:
self.EditBox(key).Set(parameters[key])
try:
self.EditBox(key).Set(parameters[key])
except:
pass
try:
self.DropDownList(key).Set(parameters[key])
except:
pass
self.Button("//input[@value='Create']").Click()
self.Button('Create').Click()
def delete_service(self, name):
self.Refresh()
@ -23,10 +35,20 @@ class ServicesPage(page.Page):
service_id = re.search('windc/(\S+)', link).group(0)[6:-1]
xpath = ".//*[@id='services__row__%s']/td[5]/div/a[2]" % service_id
self.Button(xpath).Click()
self.Button('More', service_id).Click()
self.Button('Delete', service_id).Click()
# confirm:
self.Button('Delete Service').Click()
button_id = "services__row_%s__action_delete" % service_id
self.Button(button_id).Click()
def select_service(self, name):
self.Link(name).Click()
page = ServicesDetailsPage(self.driver)
return page
self.Button("Delete Service").Click()
def get_service_status(self, name):
self.Refresh()
link = self.Link(name).Address()
service_id = re.search('windc/(\S+)', link).group(0)[6:-8]
return self.TableCell('Status', service_id).Text()

View File

@ -1,15 +1,47 @@
# -*- coding: utf-8 -*-
import unittest2
import logging
from login_page import LoginPage
from datacenters_page import DataCentersPage
from test_case import TestCase
from selenium import webdriver
logging.basicConfig()
LOG = logging.getLogger(' Tests: ')
def generate_ad(name="test", count=1):
"""
This function generates parameters for
Active Directory service
"""
ad_parameters = {'1-dc_name': name,
'1-dc_count': count,
'1-adm_password': "P@ssw0rd",
'1-recovery_password': "P@ssw0rd2"}
return ['Active Directory', ad_parameters]
def generate_iis(name="test", domain="test"):
"""
This function generates parameters for
Internet Information Services service
"""
iis_parameters = {'1-iis_name': name,
'1-adm_password': "P@ssw0rd",
'1-iis_domain': domain}
return ['Internet Information Services', iis_parameters]
class SanityTests(unittest2.TestCase):
@classmethod
def setUpClass(self):
"""
Open browser, navigate to the login page,
login and navigate to the Windows Data Centers page
"""
driver = webdriver.Firefox()
self.page = LoginPage(driver)
self.page.login()
@ -18,23 +50,46 @@ class SanityTests(unittest2.TestCase):
@classmethod
def tearDownClass(self):
"""
Close browser
"""
self.page.driver.close()
def test_01_create_data_center(self):
def test_001_create_data_center(self):
self.page.create_data_center('dc1')
assert self.page.Link('dc1').isPresented()
def test_02_delete_data_center(self):
def test_002_delete_data_center(self):
self.page.delete_data_center('dc1')
assert not self.page.Link('dc1').isPresented()
def test_03_create_data_centers(self):
def test_003_deploy_data_center(self):
ad_name = "AD.net"
iis_name = "iis_server"
self.page.Navigate('Windows Data Centers')
self.page.create_data_center('data_center_for_deploy')
self.page = self.page.select_data_center('data_center_for_deploy')
self.page.create_service(generate_ad(ad_name, 2))
assert self.page.Link(ad_name).isPresented()
self.page.create_service(generate_iis(iis_name, ad_name))
assert self.page.Link(iis_name).isPresented()
self.page.Navigate('Windows Data Centers')
self.page = DataCentersPage(self.page.driver)
self.page.deploy_data_center('data_center_for_deploy')
status = self.page.get_datacenter_status('data_center_for_deploy')
assert 'Deploy in progress' in status
def test_004_create_data_centers(self):
for i in range(1, 10):
name = 'datacenter' + str(i)
name = "datacenter" + str(i)
self.page.create_data_center(name)
assert self.page.Link(name).isPresented()
def test_04_delete_data_centers(self):
def test_005_delete_data_centers(self):
self.page.delete_data_center('datacenter1')
self.page.delete_data_center('datacenter9')
assert not self.page.Link('datacenter1').isPresented()
@ -44,111 +99,98 @@ class SanityTests(unittest2.TestCase):
name = 'datacenter' + str(i)
assert self.page.Link(name).isPresented()
def test_05_create_service_ad(self):
name = 'dc001.local'
def test_006_create_service_ad(self):
name = "dc001.local"
self.page.Navigate('Windows Data Centers')
self.page = DataCentersPage(self.page.driver)
self.page.create_data_center('test05')
self.page = self.page.select_data_center('test05')
ad_parameters = {'1-dc_name': name,
'1-dc_count': 1,
'1-adm_password': 'AkvareL707!',
'1-recovery_password': 'AkvareL707!'}
self.page.create_service('Active Directory', ad_parameters)
self.page.create_service(generate_ad(name, 1))
assert self.page.Link(name).isPresented()
test_case = TestCase(self.page.driver, test_name)
assert test_case.verify(self.page.Link(name).isPresented())
def test_06_create_service_ad_two_instances(self):
name = 'dc002.local'
def test_007_create_service_ad_two_instances(self):
test_name = "Create AD service with two instances"
name = "dc002.local"
self.page.Navigate('Windows Data Centers')
self.page = DataCentersPage(self.page.driver)
self.page.create_data_center('test06')
self.page = self.page.select_data_center('test06')
ad_parameters = {'1-dc_name': name,
'1-dc_count': 2,
'1-adm_password': 'P@ssw0rd2',
'1-recovery_password': 'P@ssw0rd'}
self.page.create_service('Active Directory', ad_parameters)
self.page.create_service(generate_ad(name, 2))
assert self.page.Link(name).isPresented()
test_case = TestCase(self.page.driver, test_name)
assert test_case.verify(self.page.Link(name).isPresented())
def test_07_create_service_ad_with_iis(self):
ad_name = 'dc003.local'
def test_008_create_service_ad_with_iis(self):
test_name = "Create data center with a few services"
ad_name = "dc003.local"
self.page.Navigate('Windows Data Centers')
self.page = DataCentersPage(self.page.driver)
self.page.create_data_center('test07')
self.page = self.page.select_data_center('test07')
ad_parameters = {'1-dc_name': ad_name,
'1-dc_count': 3,
'1-adm_password': 'P@ssw0rd',
'1-recovery_password': 'P@ssw0rd2'}
self.page.create_service('Active Directory', ad_parameters)
self.page.create_service(generate_ad(ad_name, 3))
assert self.page.Link(ad_name).isPresented()
test_case = TestCase(self.page.driver, test_name)
assert test_case.verify(self.page.Link(ad_name).isPresented())
iis_name = 'iis_server1'
iis_parameters = {'1-iis_name': iis_name,
'1-adm_password': 'P@ssw0rd',
'1-iis_domain': 'dc003.local',
'1-domain_user_name': 'Administrator',
'1-domain_user_password': 'P@ssw0rd'}
self.page.create_service('Internet Information Services',
iis_parameters)
for i in range(5):
iis_name = 'iis_server' + str(i)
self.page.create_service(generate_iis(iis_name, ad_name))
assert test_case.verify(self.page.Link(iis_name).isPresented())
assert self.page.Link(iis_name).isPresented()
iis_name = 'iis_server2'
iis_parameters = {'1-iis_name': iis_name,
'1-adm_password': 'P@ssw0rd',
'1-iis_domain': 'dc003.local',
'1-domain_user_name': 'Administrator',
'1-domain_user_password': 'P@ssw0rd'}
self.page.create_service('Internet Information Services',
iis_parameters)
assert self.page.Link(iis_name).isPresented()
iis_name = 'iis_server3'
iis_parameters = {'1-iis_name': iis_name,
'1-adm_password': 'P@ssw0rd',
'1-iis_domain': 'dc003.local',
'1-domain_user_name': 'Administrator',
'1-domain_user_password': 'P@ssw0rd'}
self.page.create_service('Internet Information Services',
iis_parameters)
assert self.page.Link(iis_name).isPresented()
def test_08_deploy_data_center(self):
ad_name = 'AD.net'
self.page.Navigate('Windows Data Centers')
self.page.create_data_center('test08')
self.page = self.page.select_data_center('test08')
ad_parameters = {'1-dc_name': ad_name,
'1-dc_count': 2,
'1-adm_password': 'P@ssw0rd',
'1-recovery_password': 'P@ssw0rd2'}
self.page.create_service('Active Directory', ad_parameters)
assert self.page.Link(ad_name).isPresented()
iis_parameters = {'1-iis_name': 'iis_server',
'1-adm_password': 'P@ssw0rd',
'1-iis_domain': 'AD.net',
'1-domain_user_name': 'Administrator',
'1-domain_user_password': 'P@ssw0rd'}
self.page.create_service('Internet Information Services',
iis_parameters)
assert self.page.Link('iis_server').isPresented()
def test_009_delete_data_center_with_services(self):
test_name = "Delete data center with a few services with status ready to deploy"
dc_name = "test07"
self.page.Navigate('Windows Data Centers')
self.page = DataCentersPage(self.page.driver)
self.page.deploy_data_center('test08')
self.page.delete_data_center(dc_name)
status = self.page.get_datacenter_status('test08')
assert 'Deploy in progress' in status
test_case = TestCase(self.page.driver, test_name)
assert test_case.verify(not self.page.Link(dc_name).isPresented())
def test_010_service_deploy_in_progress_status(self):
test_name = "Check status for services in deploing state"
dc_name = "data_center_for_deploy"
ad_name = "AD.net"
iis_name = "iis_server"
self.page.Navigate('Windows Data Centers')
self.page = DataCentersPage(self.page.driver)
self.page = self.page.select_data_center(dc_name)
ad_status = self.page.get_service_status(ad_name)
iis_status = self.page.get_service_status(iis_name)
test_case = TestCase(self.page.driver, test_name)
assert test_case.verify('Deploy in progress' in ad_status)
assert test_case.verify('Deploy in progress' in iis_status)
def test_011_show_service_details_for_deploy(self):
test_name = "Check IIS service details page"
dc_name = "data_center_for_deploy"
ad_name = "AD.net"
iis_name = "iis_server"
self.page.Navigate('Windows Data Centers')
self.page = DataCentersPage(self.page.driver)
self.page = self.page.select_data_center(dc_name)
self.page = self.page.select_service(iis_name)
name = self.page.get_service_name()
domain = self.page.get_service_domain()
test_case = TestCase(self.page.driver, test_name)
assert test_case.verify(name == iis_name)
assert test_case.verify(name == ad_name)
if __name__ == '__main__':

View File

@ -0,0 +1,26 @@
import logging
logging.basicConfig()
LOG = logging.getLogger(' Test Case: ')
class TestCase:
name = None
driver = None
def __init__(self, driver, name):
self.name = name
self.driver = driver
def verify(self, condition):
try:
self.driver.save_screenshot(self.name)
except:
LOG.critical("Can not create screenshot file.")
if condition:
LOG.info(self.name + " PASSED")
return True
else:
LOG.critical(self.name + " FAILED")
return False