Added UI tests
Added selenium tests for savanna-dashboard Implements blueprint savanna-dashboard-ui-tests Change-Id: I8b57a3339aa4b30750b9ec7b7ebcf9a340fd2d57
This commit is contained in:
parent
b8f32f9d4b
commit
75426a1bdd
|
@ -34,3 +34,4 @@ pylint-report.txt
|
|||
ChangeLog
|
||||
cscope.out
|
||||
horizon
|
||||
savannadashboard/tests/configs/config.conf
|
||||
|
|
1
AUTHORS
1
AUTHORS
|
@ -5,3 +5,4 @@ Nikita Konovalov <nkonovalov@mirantis.com>
|
|||
Nikolay Mahotkin <nmakhotkin@mirantis.com>
|
||||
Sergey Lukjanov <slukjanov@mirantis.com>
|
||||
Sergey Reshetnyak <sreshetniak@mirantis.com>
|
||||
Vadim Rovachev <vrovachev@mirantis.com>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
UI tests for Savanna dashboard
|
||||
=====================================
|
||||
|
||||
How to run
|
||||
----------
|
||||
|
||||
Create config file for selenium tests - `/savannadashboard/tests/configs/config.conf`.
|
||||
You can take a look at the sample config file - `/savannadashboard/tests/configs/config.conf.sample`.
|
||||
All values used in `/savannadashboard/tests/configs/config.py` file are
|
||||
defaults, so, if they are applicable for your environment then you can skip
|
||||
config file creation.
|
||||
|
||||
Install virtual framebuffer X server for X Version 11 (Xvfb):
|
||||
sudo apt-get -y install xvfb
|
||||
|
||||
Install Firefox:
|
||||
sudo add-apt-repository ppa:ubuntu-mozilla-security/ppa
|
||||
sudo apt-get update
|
||||
sudo apt-get install firefox libstdc++5
|
||||
|
||||
To run ui tests you should use the corresponding tox env: `tox -e tests`.
|
||||
|
|
@ -0,0 +1,519 @@
|
|||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import nose.plugins.attrib
|
||||
import pyvirtualdisplay
|
||||
from selenium import webdriver
|
||||
import selenium.webdriver.common.by as by
|
||||
import testtools
|
||||
import time
|
||||
import unittest2
|
||||
|
||||
import savannadashboard.tests.configs.config as cfg
|
||||
|
||||
|
||||
def attr(*args, **kwargs):
|
||||
def decorator(f):
|
||||
if 'type' in kwargs and isinstance(kwargs['type'], str):
|
||||
f = testtools.testcase.attr(kwargs['type'])(f)
|
||||
elif 'type' in kwargs and isinstance(kwargs['type'], list):
|
||||
for attr in kwargs['type']:
|
||||
f = testtools.testcase.attr(attr)(f)
|
||||
return nose.plugins.attrib.attr(*args, **kwargs)(f)
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
class UITestCase(unittest2.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.display = pyvirtualdisplay.Display(visible=0, size=(1024, 768))
|
||||
cls.display.start()
|
||||
cls.driver = webdriver.Firefox()
|
||||
cls.driver.get(cfg.common.base_url + "/")
|
||||
cls.find_clear_send(by.By.ID, "id_username", cfg.common.user)
|
||||
cls.find_clear_send(by.By.ID, "id_password", cfg.common.password)
|
||||
cls.driver.find_element_by_xpath("//button[@type='submit']").click()
|
||||
|
||||
def image_registry(self, image_name, user_name=None, description=None,
|
||||
tags_to_add=None, tags_to_remove=None, positive=True,
|
||||
close_window=True, message=''):
|
||||
if positive:
|
||||
message = 'Success: Image registered.'
|
||||
self.image_registry_helper(image_name, user_name, description,
|
||||
tags_to_add, tags_to_remove, positive,
|
||||
close_window, message, 'Registry')
|
||||
|
||||
def edit_tags_by_image_name(self, image_name, user_name=None,
|
||||
description=None, tags_to_add=None,
|
||||
positive=True, message=None, close_window=True,
|
||||
tags_to_remove=None):
|
||||
if positive:
|
||||
message = 'Success: Image updated.'
|
||||
self.image_registry_helper(image_name, user_name, description,
|
||||
tags_to_add, tags_to_remove, positive,
|
||||
close_window, message, 'Edit')
|
||||
|
||||
def create_node_group_template(
|
||||
self, name, list_processes, plugin, flavor="m1.tiny", params=None,
|
||||
storage={'type': 'Ephemeral Drive'}, description=None,
|
||||
positive=True, message=None, close_window=True):
|
||||
driver = self.driver
|
||||
driver.get(cfg.common.base_url + "/savanna/nodegroup_templates/")
|
||||
self.await_element(by.By.ID, "nodegroup_templates__action_create")
|
||||
driver.find_element_by_id("nodegroup_templates__action_create").click()
|
||||
self.choose_plugin_name(plugin.plugin_name, plugin.hadoop_version,
|
||||
name, description, "id_nodegroup_name")
|
||||
self.driver.find_element_by_xpath(
|
||||
"//select[@id='id_flavor']/option[text()='%s']" % flavor).click()
|
||||
self.driver.find_element_by_xpath(
|
||||
"//*[@id='id_storage']/option[text()='%s']"
|
||||
% storage['type']).click()
|
||||
if storage['type'] == "Cinder Volume":
|
||||
self.find_clear_send(by.By.ID, "id_volumes_per_node",
|
||||
storage['volume_per_node'])
|
||||
self.find_clear_send(by.By.ID, "id_volumes_size",
|
||||
storage['volume_size'])
|
||||
processes = []
|
||||
for process in list_processes:
|
||||
number_pr = self.search_id_processes(process, plugin)
|
||||
driver.find_element_by_id(
|
||||
"id_processes_%d" % number_pr).click()
|
||||
processes.append(driver.find_element_by_id(
|
||||
"id_processes_%d" % number_pr).
|
||||
find_element_by_xpath('..').text)
|
||||
if params:
|
||||
self.config_helper(params)
|
||||
driver.find_element_by_xpath("//input[@value='Create']").click()
|
||||
if not message:
|
||||
message = "Success: Created Node Group Template %s" % name
|
||||
if close_window:
|
||||
self.check_create_object(
|
||||
name, positive, message,
|
||||
[{2: [name]},
|
||||
{3: [plugin.plugin_overview_name]},
|
||||
{4: [plugin.hadoop_version]}, {5: processes}])
|
||||
else:
|
||||
self.error_helper(message)
|
||||
|
||||
def create_cluster_template(
|
||||
self, name, node_groups, plugin, description=None,
|
||||
close_window=True, anti_affinity_groups=None, positive=True,
|
||||
message=None, params=None):
|
||||
driver = self.driver
|
||||
driver.get(cfg.common.base_url + "/savanna/cluster_templates/")
|
||||
self.await_element(by.By.ID, "cluster_templates__action_create")
|
||||
driver.find_element_by_id("cluster_templates__action_create").click()
|
||||
self.choose_plugin_name(plugin.plugin_name, plugin.hadoop_version,
|
||||
name, description, "id_cluster_template_name")
|
||||
if anti_affinity_groups:
|
||||
for group in anti_affinity_groups:
|
||||
driver.find_element_by_id(
|
||||
"id_anti_affinity_%d" % self.search_id_processes(
|
||||
group, plugin)).click()
|
||||
driver.find_element_by_link_text("Node Groups").click()
|
||||
number_to_add = 0
|
||||
node_groups_list = []
|
||||
for node_group, count in node_groups.items():
|
||||
driver.find_element_by_xpath(
|
||||
"//select[@id='template_id']/option[text()='%s']"
|
||||
% node_group).click()
|
||||
driver.find_element_by_id("add_group_button").click()
|
||||
self.find_clear_send(by.By.ID, "count_%d" % number_to_add, count)
|
||||
node_groups_list.append("%s: %d" % (node_group, count))
|
||||
number_to_add += 1
|
||||
if params:
|
||||
self.config_helper(params)
|
||||
driver.find_element_by_xpath("//input[@value='Create']").click()
|
||||
if not message:
|
||||
message = "Success: Created Cluster Template %s" % name
|
||||
if close_window:
|
||||
self.check_create_object(
|
||||
name, positive, message,
|
||||
[{2: [name]},
|
||||
{3: [plugin.plugin_overview_name]},
|
||||
{4: [plugin.hadoop_version]}, {5: node_groups_list},
|
||||
{6: [description if description else '']}])
|
||||
else:
|
||||
self.error_helper(message)
|
||||
|
||||
def create_cluster(self, name, cluster_template, keypair, plugin,
|
||||
close_window=True, description=None, positive=True,
|
||||
await_run=True, message=None):
|
||||
driver = self.driver
|
||||
driver.get(cfg.common.base_url + "/savanna/")
|
||||
self.await_element(by.By.ID, "clusters__action_create")
|
||||
driver.find_element_by_id("clusters__action_create").click()
|
||||
self.choose_plugin_name(plugin.plugin_name, plugin.hadoop_version,
|
||||
name, description, "id_cluster_name")
|
||||
driver.find_element_by_xpath("//select[@id='id_cluster_template']/"
|
||||
"option[text()='%s']" %
|
||||
cluster_template).click()
|
||||
driver.find_element_by_xpath("//select[@id='id_image']/option"
|
||||
"[text()='%s']" %
|
||||
plugin.base_image).click()
|
||||
driver.find_element_by_xpath("//select[@id='id_keypair']"
|
||||
"/option[text()='%s']" % keypair).click()
|
||||
driver.find_element_by_xpath("//input[@value='Create']").click()
|
||||
if not message:
|
||||
message = 'Success: Created Cluster %s' % name
|
||||
if close_window:
|
||||
self.check_create_object(name, positive, message)
|
||||
else:
|
||||
self.error_helper(message)
|
||||
if await_run:
|
||||
self.await_cluster_active(name)
|
||||
|
||||
def delete_node_group_templates(self, names, undelete_names=None):
|
||||
url = "/savanna/nodegroup_templates/"
|
||||
delete_button_id = 'nodegroup_templates__action_' \
|
||||
'delete_nodegroup_template'
|
||||
self.delete_and_validate(url, delete_button_id, names, undelete_names)
|
||||
|
||||
def delete_cluster_templates(self, names, undelete_names=None):
|
||||
url = "/savanna/cluster_templates/"
|
||||
delete_button_id = "cluster_templates__action_delete_cluster_template"
|
||||
self.delete_and_validate(url, delete_button_id, names, undelete_names)
|
||||
|
||||
def delete_clusters(self, names, undelete_names=None):
|
||||
url = "/savanna/"
|
||||
delete_button_id = "clusters__action_delete"
|
||||
msg = "Success: Deleted Cluster"
|
||||
self.delete_and_validate(url, delete_button_id, names, undelete_names,
|
||||
succes_msg=msg)
|
||||
|
||||
def unregister_images(self, names, undelete_names=[]):
|
||||
url = '/savanna/image_registry/'
|
||||
delete_button_id = "image_registry__action_Unregister"
|
||||
msg = "Success: Unregistered Image"
|
||||
self.delete_and_validate(url, delete_button_id, names, undelete_names,
|
||||
succes_msg=msg)
|
||||
|
||||
#-------------------------helpers_methods--------------------------------------
|
||||
|
||||
@classmethod
|
||||
def find_clear_send(cls, by_find, find_element, send):
|
||||
cls.driver.find_element(by=by_find, value=find_element).clear()
|
||||
cls.driver.find_element(by=by_find, value=find_element).send_keys(send)
|
||||
|
||||
def delete_and_validate(self, url, delete_button_id, names, undelete_names,
|
||||
succes_msg='Success: Deleted Template',
|
||||
error_msg='Error: Unable to delete template',
|
||||
info_msg='Info: Deleted Template'):
|
||||
driver = self.driver
|
||||
driver.get(cfg.common.base_url + url)
|
||||
self.await_element(by.By.ID, delete_button_id)
|
||||
for name in names:
|
||||
# choose checkbox for this element
|
||||
driver.find_element_by_link_text("%s" % name).\
|
||||
find_element_by_xpath("../../td[1]/input").click()
|
||||
# click deletebutton
|
||||
driver.find_element_by_id(delete_button_id).click()
|
||||
# wait window to confirm the deletion
|
||||
self.await_element(by.By.CLASS_NAME, "btn-primary")
|
||||
# confirm the deletion
|
||||
driver.find_element_by_class_name("btn-primary").click()
|
||||
exp_del_obj = list(set(names).symmetric_difference(set(
|
||||
undelete_names if undelete_names else [])))
|
||||
if not undelete_names:
|
||||
if len(names) > 1:
|
||||
succes_msg += "s"
|
||||
succes_msg += ": "
|
||||
self.check_alert("alert-success", succes_msg, names, deleted=True)
|
||||
elif not exp_del_obj:
|
||||
if len(undelete_names) > 1:
|
||||
error_msg += "s"
|
||||
error_msg += ": "
|
||||
self.check_alert("alert-error", error_msg, undelete_names,
|
||||
deleted=False)
|
||||
else:
|
||||
if len(undelete_names) > 1:
|
||||
error_msg += "s"
|
||||
error_msg += ": "
|
||||
if len(exp_del_obj) > 1:
|
||||
info_msg += "s"
|
||||
info_msg += ": "
|
||||
self.check_alert("alert-error", error_msg, undelete_names,
|
||||
deleted=False)
|
||||
self.check_alert("alert-info", info_msg, exp_del_obj, deleted=True)
|
||||
driver.refresh()
|
||||
|
||||
def error_helper(self, message):
|
||||
driver = self.driver
|
||||
messages = message.split(", ")
|
||||
self.await_element(by.By.CLASS_NAME, "error")
|
||||
errors = driver.find_elements_by_class_name("error")
|
||||
for message in messages:
|
||||
mes = message.split(":")
|
||||
if len(mes) > 1:
|
||||
# if word count for error mesage > 1, then error message
|
||||
# can be on the open tab or on another
|
||||
if len(mes) > 2:
|
||||
# if word count for error mesage > 2, then error message
|
||||
# on another tab
|
||||
# Click the tab indicated in the message
|
||||
driver.find_element_by_link_text(mes.pop(0)).click()
|
||||
error = errors.pop(0).text.split("\n")
|
||||
self.assertEqual(mes[0], error[0])
|
||||
self.assertEqual(mes[1], error[1])
|
||||
else:
|
||||
self.assertEqual(mes[0], errors.pop(0).text)
|
||||
self.assertEqual(errors, [])
|
||||
driver.refresh()
|
||||
|
||||
def config_helper(self, config_list):
|
||||
driver = self.driver
|
||||
for pair in config_list:
|
||||
for par, value in pair.iteritems():
|
||||
if len(par.split(":")) > 1:
|
||||
driver.find_element_by_link_text(par.split(":")[0]).click()
|
||||
config_id = "id_CONF:%s" % par.split(":")[0].split(" ")[0]
|
||||
if config_id == "id_CONF:General":
|
||||
config_id = "id_CONF:general"
|
||||
par = par.split(":")[1]
|
||||
if par == "Show_param":
|
||||
if value:
|
||||
|
||||
self.waiting_element_in_visible_state(
|
||||
by.By.LINK_TEXT, "Show full configuration")
|
||||
driver.find_element_by_link_text(
|
||||
"Show full configuration").click()
|
||||
self.waiting_element_in_visible_state(
|
||||
by.By.LINK_TEXT, "Hide full configuration")
|
||||
else:
|
||||
self.waiting_element_in_visible_state(
|
||||
by.By.LINK_TEXT, "Hide full configuration")
|
||||
driver.find_element_by_link_text(
|
||||
"Hide full configuration").click()
|
||||
self.waiting_element_in_visible_state(
|
||||
by.By.LINK_TEXT, "Show full configuration")
|
||||
elif par == "Filter":
|
||||
self.find_clear_send(
|
||||
by.By.XPATH, "//input[@class='field-filter']", value)
|
||||
else:
|
||||
self.waiting_element_in_visible_state(
|
||||
by.By.ID, "%s:%s" % (config_id, par))
|
||||
if isinstance(value, bool):
|
||||
if driver.find_element_by_id(
|
||||
"%s:%s" % (config_id,
|
||||
par)).is_selected() != value:
|
||||
driver.find_element_by_id(
|
||||
"%s:%s" % (config_id, par)).click()
|
||||
else:
|
||||
self.find_clear_send(
|
||||
by.By.ID, "%s:%s" % (config_id, par), value)
|
||||
|
||||
def image_registry_helper(self, image_name, user_name, description,
|
||||
tags_to_add, tags_to_remove, positive,
|
||||
close_window, message, operation):
|
||||
driver = self.driver
|
||||
list_for_check_tags = []
|
||||
driver.get(cfg.common.base_url + "/savanna/image_registry/")
|
||||
self.await_element(by.By.ID, "image_registry__action_register")
|
||||
if operation == 'Registry':
|
||||
driver.find_element_by_id(
|
||||
"image_registry__action_register").click()
|
||||
else:
|
||||
#Add existing tags in the list
|
||||
list_for_check_tags = driver.\
|
||||
find_element(by=by.By.LINK_TEXT, value='latest-ci-image').\
|
||||
find_element_by_xpath('../../td[3]').text.split('\n')
|
||||
# Click "Edit Tags"
|
||||
driver.find_element(by=by.By.LINK_TEXT, value=image_name).\
|
||||
find_element_by_xpath('../../td[4]').\
|
||||
find_element(by=by.By.LINK_TEXT, value='Edit Tags').click()
|
||||
self.await_element(by.By.ID, 'id_user_name')
|
||||
if operation == 'Registry':
|
||||
driver.find_element_by_xpath("//select[@id='id_image_id']"
|
||||
"/option[text()='%s']"
|
||||
% image_name).click()
|
||||
if user_name:
|
||||
self.find_clear_send(by.By.ID, 'id_user_name', user_name)
|
||||
if description:
|
||||
self.find_clear_send(by.By.ID, 'id_description', user_name)
|
||||
if tags_to_add:
|
||||
for tag in tags_to_add:
|
||||
for first, second in tag.iteritems():
|
||||
if first in ["vanilla", 'hdp']:
|
||||
driver.find_element_by_xpath(
|
||||
"//select[@id='plugin_select']/option[text()='%s']"
|
||||
% first).click()
|
||||
driver.find_element_by_xpath(
|
||||
"//select[@id='hadoop_version_%s']"
|
||||
"/option[text()='%s']" % (first, second)).click()
|
||||
driver.find_element_by_id('add_all_btn').click()
|
||||
if first not in list_for_check_tags:
|
||||
list_for_check_tags.append(first)
|
||||
if second not in list_for_check_tags:
|
||||
list_for_check_tags.append(second)
|
||||
elif first == 'custom_tag':
|
||||
self.find_clear_send(by.By.ID, '_savanna_image_tag',
|
||||
second)
|
||||
driver.find_element_by_id('add_tag_btn').click()
|
||||
if second not in list_for_check_tags:
|
||||
list_for_check_tags.append(second)
|
||||
else:
|
||||
self.fail("Tag:%s, %s is unknown" % (first, second))
|
||||
if tags_to_remove:
|
||||
for tag in tags_to_remove:
|
||||
#click "x" in tag
|
||||
driver.find_element_by_xpath(
|
||||
"//div[@id='image_tags_list']//span[contains(.,'%s')]//i"
|
||||
% tag).click()
|
||||
if tag in list_for_check_tags:
|
||||
list_for_check_tags.remove(tag)
|
||||
driver.find_element_by_id('edit_image_tags_btn').click()
|
||||
if positive:
|
||||
self.check_create_object(image_name, positive, message,
|
||||
[{3: list_for_check_tags}])
|
||||
else:
|
||||
if not close_window:
|
||||
self.error_helper(message)
|
||||
else:
|
||||
self.check_create_object(image_name, positive, message)
|
||||
|
||||
def choose_plugin_name(self, plugin_name, hadoop_version, name,
|
||||
description, id_name):
|
||||
self.await_element(by.By.XPATH, "//*[@id='modal_wrapper']"
|
||||
"/div/form/div[4]/input")
|
||||
self.driver.find_element_by_xpath(
|
||||
"//select[@id='id_plugin_name']/option[text()='%s']" %
|
||||
plugin_name).click()
|
||||
if plugin_name == "Hortonworks Data Platform":
|
||||
version_id = "id_hdp_version"
|
||||
elif plugin_name == "Vanilla Apache Hadoop":
|
||||
version_id = "id_vanilla_version"
|
||||
else:
|
||||
self.fail("plugin_name:%s is wrong" % plugin_name)
|
||||
self.driver.find_element_by_id(version_id).find_element_by_xpath(
|
||||
"option[text()='%s']" % hadoop_version).click()
|
||||
self.driver.find_element_by_xpath("//input[@value='Create']").click()
|
||||
self.await_element(by.By.ID, id_name)
|
||||
self.find_clear_send(by.By.ID, id_name, name)
|
||||
if description:
|
||||
self.find_clear_send(by.By.ID, "id_description", description)
|
||||
|
||||
def check_alert(self, alert, message, list_obj, deleted=True):
|
||||
self.await_element(by.By.CLASS_NAME, alert)
|
||||
if self.find_alert_message(alert, first_character=2,
|
||||
last_character=len(message)+2) != message:
|
||||
self.fail("%s != %s" % (alert, message))
|
||||
not_expected_objs = list(set(self.find_alert_message(
|
||||
alert, first_character=len(message)+2).split(
|
||||
", ")).symmetric_difference(set(list_obj)))
|
||||
if not_expected_objs:
|
||||
self.fail("have deleted objects: %s" % not_expected_objs)
|
||||
for name in list_obj:
|
||||
if self.does_element_present(by.By.LINK_TEXT, name) == deleted:
|
||||
if deleted:
|
||||
errmsg = "object with name:%s is not deleted" % name
|
||||
else:
|
||||
errmsg = "object with name:%s is deleted" % name
|
||||
self.fail(errmsg)
|
||||
|
||||
def find_alert_message(self, name, first_character=None,
|
||||
last_character=None):
|
||||
driver = self.driver
|
||||
return str(driver.find_element_by_class_name("%s" % name).text[
|
||||
first_character:last_character])
|
||||
|
||||
def search_id_processes(self, process, plugin):
|
||||
return plugin.processes[process]
|
||||
|
||||
def waiting_element_in_visible_state(self, how, what):
|
||||
for i in range(cfg.common.await_element):
|
||||
if self.driver.find_element(by=how, value=what).is_displayed():
|
||||
break
|
||||
time.sleep(1)
|
||||
else:
|
||||
self.fail("time out for await visible: %s , %s" % (how, what))
|
||||
|
||||
def does_element_present(self, how, what):
|
||||
try:
|
||||
self.driver.find_element(by=how, value=what)
|
||||
except Exception as e:
|
||||
print(e.message)
|
||||
return False
|
||||
return True
|
||||
|
||||
def await_element(self, by, value, message=""):
|
||||
for i in range(cfg.common.await_element):
|
||||
if self.does_element_present(by, value):
|
||||
break
|
||||
time.sleep(1)
|
||||
else:
|
||||
if not message:
|
||||
message = "time out for await: %s , %s" % (by, value)
|
||||
self.fail(message)
|
||||
|
||||
def check_create_object(self, name, positive, expected_message,
|
||||
check_columns=None):
|
||||
driver = self.driver
|
||||
expected_alert = "alert-error"
|
||||
unexpected_alert = "alert-success"
|
||||
if positive:
|
||||
expected_alert = "alert-success"
|
||||
unexpected_alert = "alert-error"
|
||||
for i in range(cfg.common.await_element):
|
||||
if self.does_element_present(by.By.CLASS_NAME, expected_alert):
|
||||
break
|
||||
elif self.does_element_present(by.By.CLASS_NAME, unexpected_alert):
|
||||
fail_mesg = self.driver.find_element(
|
||||
by=by.By.CLASS_NAME, value=unexpected_alert).text[2:]
|
||||
self.fail("Result of creation %s is not expected: %s != %s"
|
||||
% (name, expected_alert, fail_mesg))
|
||||
time.sleep(1)
|
||||
else:
|
||||
self.fail("alert check:%s time out" % expected_alert)
|
||||
actual_message = self.driver.find_element(
|
||||
by=by.By.CLASS_NAME, value=expected_alert).text[2:]
|
||||
if positive:
|
||||
self.assertEqual(expected_message, str(actual_message))
|
||||
if not self.does_element_present(by.By.LINK_TEXT, name):
|
||||
self.fail("object with name:%s not found" % name)
|
||||
if check_columns:
|
||||
for column in check_columns:
|
||||
for column_number, expected_values in column.iteritems():
|
||||
actual_values = driver.\
|
||||
find_element_by_link_text(name).\
|
||||
find_element_by_xpath(
|
||||
'../../td[%d]' % column_number).\
|
||||
text.split('\n')
|
||||
self.assertItemsEqual(actual_values, expected_values)
|
||||
else:
|
||||
if expected_message:
|
||||
self.assertEqual(expected_message, str(actual_message))
|
||||
self.driver.refresh()
|
||||
|
||||
def await_cluster_active(self, name):
|
||||
driver = self.driver
|
||||
status = driver.find_element_by_link_text(name).\
|
||||
find_element_by_xpath("../../td[3]").text
|
||||
i = 1
|
||||
while str(status) != 'Active':
|
||||
if i > cfg.common.cluster_creation_timeout * 6:
|
||||
self.fail(
|
||||
'cluster is not getting status \'Active\', '
|
||||
'passed %d minutes' % cfg.common.cluster_creation_timeout)
|
||||
status = driver.find_element_by_link_text("selenium-cl").\
|
||||
find_element_by_xpath("../../td[3]").text
|
||||
time.sleep(10)
|
||||
i += 1
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.driver.quit()
|
||||
cls.display.stop()
|
|
@ -0,0 +1,47 @@
|
|||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import testtools
|
||||
|
||||
from savannadashboard.tests import base
|
||||
import savannadashboard.tests.configs.config as cfg
|
||||
|
||||
|
||||
class UINegativeCreateClusterTemplateTest(base.UITestCase):
|
||||
|
||||
@base.attr(tags='cluster_template')
|
||||
@testtools.skip
|
||||
@testtools.skipIf(cfg.vanilla.skip_plugin_tests,
|
||||
'tests for vanilla plugin skipped')
|
||||
def test_create_vanilla_cluster_template_with_wrong_fields(self):
|
||||
self.create_node_group_template('selenium-master', ["NN", "JT"],
|
||||
cfg.vanilla)
|
||||
self.create_node_group_template('selenium-worker', ["DN", "TT"],
|
||||
cfg.vanilla)
|
||||
self.create_cluster_template(
|
||||
"", {'selenium-master': 1, 'selenium-worker': 2}, cfg.vanilla,
|
||||
anti_affinity_groups=["NN", "DN", "TT"],
|
||||
params=[{"General Parameters:Enable Swift": False},
|
||||
{"HDFS Parameters:io.file.buffer.size": "str"},
|
||||
{"MapReduce Parameters:mapreduce.job.counters.max":
|
||||
"str"}],
|
||||
positive=False, close_window=False, message=
|
||||
'Details, HDFS Parameters, MapReduce Parameters, '
|
||||
'Template Name:This field is required., '
|
||||
'HDFS Parameters:io.file.buffer.size:Enter a whole number., '
|
||||
'MapReduce Parameters:mapreduce.job.counters.max:'
|
||||
'Enter a whole number.')
|
||||
self.delete_node_group_templates(["selenium-master",
|
||||
"selenium-worker"])
|
|
@ -0,0 +1,77 @@
|
|||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import testtools
|
||||
|
||||
from savannadashboard.tests import base
|
||||
import savannadashboard.tests.configs.config as cfg
|
||||
|
||||
|
||||
class UICreateClusterTemplate(base.UITestCase):
|
||||
|
||||
@base.attr(tags=['cluster_template', 'vanilla'])
|
||||
@testtools.skipIf(cfg.vanilla.skip_plugin_tests,
|
||||
'tests for vanilla plugin skipped')
|
||||
def test_create_cluster_template_for_vanilla(self):
|
||||
self.create_node_group_template('selenium-master', ["NN", "JT"],
|
||||
cfg.vanilla)
|
||||
self.create_node_group_template('selenium-worker', ["DN", "TT"],
|
||||
cfg.vanilla)
|
||||
self.create_node_group_template('selenium-delete', ["NN", "OZ"],
|
||||
cfg.vanilla)
|
||||
self.create_cluster_template(
|
||||
"selenium-clstr-tmpl", {'selenium-master': 1,
|
||||
'selenium-worker': 2},
|
||||
cfg.vanilla, anti_affinity_groups=["NN", "DN", "TT"], params=
|
||||
[{"General Parameters:Enable Swift": False},
|
||||
{"HDFS Parameters:dfs.replication": 2},
|
||||
{"MapReduce Parameters:mapred.output.compress": False}])
|
||||
msg = 'Error: Cluster template with name \'selenium-clstr-tmpl\'' \
|
||||
' already exists'
|
||||
self.create_cluster_template('selenium-clstr-tmpl',
|
||||
{'selenium-delete': 1,
|
||||
'selenium-worker': 2},
|
||||
cfg.vanilla, positive=False, message=msg)
|
||||
self.delete_node_group_templates(["selenium-master", "selenium-worker",
|
||||
"selenium-delete"],
|
||||
undelete_names=["selenium-master",
|
||||
"selenium-worker"])
|
||||
self.delete_cluster_templates(['selenium-clstr-tmpl'])
|
||||
self.delete_node_group_templates(["selenium-master",
|
||||
"selenium-worker"])
|
||||
|
||||
@base.attr('cluster_template', 'hdp')
|
||||
@testtools.skipIf(cfg.hdp.skip_plugin_tests,
|
||||
'tests for hdp plugin skipped')
|
||||
def test_create_cluster_template_for_hdp(self):
|
||||
self.create_node_group_template(
|
||||
'selenium-hdp-master',
|
||||
["NN", "JT", "SNN", "GANGLIA_SERVER", "GANGLIA_MONITOR",
|
||||
"NAGIOS_SERVER", "AMBARI_SERVER", "AMBARI_AGENT"], cfg.hdp)
|
||||
self.create_node_group_template(
|
||||
'selenium-hdp-worker',
|
||||
["TT", "DN", "GANGLIA_MONITOR", "HDFS_CLIENT", "MAPREDUCE_CLIENT",
|
||||
"AMBARI_AGENT"], cfg.hdp)
|
||||
self.create_cluster_template(
|
||||
"selenium-hdp", {'selenium-hdp-master': 1,
|
||||
'selenium-hdp-worker': 2}, cfg.hdp,
|
||||
description="hdp plugin", anti_affinity_groups=["NN", "DN", "TT"],
|
||||
params=[{"General Parameters:Show_param": True},
|
||||
{"hadoop_heapsize": 512},
|
||||
{"HDFS Parameters:Show_param": True},
|
||||
{"HDFS Parameters:dfs.replication": 2}])
|
||||
self.delete_cluster_templates(['selenium-hdp'])
|
||||
self.delete_node_group_templates(["selenium-hdp-master",
|
||||
"selenium-hdp-worker"])
|
|
@ -0,0 +1,75 @@
|
|||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import testtools
|
||||
|
||||
from savannadashboard.tests import base
|
||||
import savannadashboard.tests.configs.config as cfg
|
||||
|
||||
|
||||
class UICreateCluster(base.UITestCase):
|
||||
|
||||
@base.attr('cluster', 'vanilla', speed='slow')
|
||||
@testtools.skipIf(cfg.vanilla.skip_plugin_tests,
|
||||
'tests for vanilla plugin skipped')
|
||||
def test_create_vanilla_cluster(self):
|
||||
try:
|
||||
self.create_node_group_template('selenium-master', ["NN", "JT"],
|
||||
cfg.vanilla,
|
||||
storage={'type': 'Cinder Volume',
|
||||
"volume_per_node": 1,
|
||||
'volume_size': 5})
|
||||
self.create_node_group_template('selenium-worker', ["DN", "TT"],
|
||||
cfg.vanilla)
|
||||
self.create_node_group_template('selenium-del1', ["NN", "JT",
|
||||
"DN", "TT"],
|
||||
cfg.vanilla)
|
||||
self.create_node_group_template('selenium-del2',
|
||||
["DN", "TT", "OZ"],
|
||||
cfg.vanilla)
|
||||
self.create_cluster_template("selenium-cl-tmpl",
|
||||
{'selenium-master': 1,
|
||||
'selenium-worker': 2}, cfg.vanilla,
|
||||
anti_affinity_groups=["NN",
|
||||
"DN", "TT"])
|
||||
self.create_cluster_template("selenium-cl-tmpl2",
|
||||
{'selenium-master': 1,
|
||||
'selenium-del2': 2},
|
||||
cfg.vanilla,
|
||||
anti_affinity_groups=
|
||||
["NN", "DN", "TT", "JT"])
|
||||
self.create_cluster('selenium-cl', 'selenium-cl-tmpl', 'vrovachev',
|
||||
cfg.vanilla, await_run=False)
|
||||
self.delete_node_group_templates(["selenium-master",
|
||||
"selenium-worker",
|
||||
"selenium-del1",
|
||||
"selenium-del2"],
|
||||
undelete_names=["selenium-master",
|
||||
"selenium-worker",
|
||||
"selenium-del2"])
|
||||
self.delete_cluster_templates(['selenium-cl-tmpl',
|
||||
'selenium-cl-tmpl2'],
|
||||
undelete_names=["selenium-cl-tmpl"])
|
||||
self.delete_node_group_templates(["selenium-master",
|
||||
"selenium-worker",
|
||||
"selenium-del2"],
|
||||
undelete_names=[
|
||||
"selenium-master",
|
||||
"selenium-worker"])
|
||||
finally:
|
||||
self.delete_clusters(['selenium-cl'])
|
||||
self.delete_cluster_templates(['selenium-cl-tmpl'])
|
||||
self.delete_node_group_templates(["selenium-master",
|
||||
"selenium-worker"])
|
|
@ -0,0 +1,22 @@
|
|||
[common]
|
||||
base_url = "http://127.0.0.1:8080"
|
||||
user = "admin"
|
||||
password = "admin"
|
||||
# in minutes
|
||||
cluster_creation_timeout = 10
|
||||
# in seconds
|
||||
await_element = 10
|
||||
image_name_for_register = 'image_name'
|
||||
image_name_for_edit = 'image_name'
|
||||
[vanilla]
|
||||
skip_plugin_tests = False
|
||||
plugin_name = "Vanilla Apache Hadoop"
|
||||
plugin_overview_name = "vanilla"
|
||||
hadoop_version = "1.2.1"
|
||||
processes = {"NN": 0, "DN": 1, "SNN": 2, "OZ": 3, "TT": 4, "JT": 5}
|
||||
base_image = "image_name"
|
||||
[hdp]
|
||||
skip_plugin_tests = False
|
||||
plugin_name = "Hortonworks Data Platform"
|
||||
hadoop_version = "1.3.0"
|
||||
base_image = "image_name"
|
|
@ -0,0 +1,119 @@
|
|||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
from oslo.config import cfg
|
||||
|
||||
common_group = cfg.OptGroup(name='common', title="common configs")
|
||||
|
||||
CommonGroup = [
|
||||
cfg.StrOpt('base_url',
|
||||
default='http://127.0.0.1:8080',
|
||||
help="savanna url"),
|
||||
cfg.StrOpt('user',
|
||||
default='admin',
|
||||
help="keystone user"),
|
||||
cfg.StrOpt('password',
|
||||
default='pass',
|
||||
help="password for keystone user"),
|
||||
cfg.IntOpt('cluster_creation_timeout',
|
||||
default=10,
|
||||
help="cluster timeout in minutes"),
|
||||
cfg.IntOpt('await_element',
|
||||
default=10,
|
||||
help="await each web element in seconds"),
|
||||
cfg.StrOpt('image_name_for_register',
|
||||
default='fedora_19',
|
||||
help='Image name for register to Savanna'),
|
||||
cfg.StrOpt('image_name_for_edit',
|
||||
default='latest-ci-image',
|
||||
help='Image name for edit in image registry in Savanna')
|
||||
]
|
||||
|
||||
vanilla_group = cfg.OptGroup(name='vanilla', title="vanilla configs")
|
||||
|
||||
VanillaGroup = [
|
||||
cfg.BoolOpt('skip_plugin_tests',
|
||||
default=False,
|
||||
help="""
|
||||
If this variable is True then
|
||||
tests for vanilla will be skipped
|
||||
"""),
|
||||
cfg.StrOpt('plugin_name',
|
||||
default='Vanilla Apache Hadoop',
|
||||
help="plugin title, default: Vanilla Apache Hadoop"),
|
||||
cfg.StrOpt('plugin_overview_name',
|
||||
default='vanilla',
|
||||
help="plugin name in overview"),
|
||||
cfg.StrOpt('hadoop_version',
|
||||
default='1.2.1',
|
||||
help="hadoop version for plugin"),
|
||||
cfg.ListOpt('processes',
|
||||
default={"NN": 0, "DN": 1, "SNN": 2,
|
||||
"OZ": 3, "TT": 4, "JT": 5},
|
||||
help='numbers of processes for vanilla in savannabashboard'),
|
||||
cfg.StrOpt('base_image',
|
||||
default='latest-ci-image',
|
||||
help="image name for start vanilla cluster")
|
||||
]
|
||||
|
||||
hdp_group = cfg.OptGroup(name='hdp', title="hdp configs")
|
||||
|
||||
HdpGroup = [
|
||||
cfg.BoolOpt('skip_plugin_tests',
|
||||
default=False,
|
||||
help="""
|
||||
If this variable is True then
|
||||
tests for hdp will be skipped
|
||||
"""),
|
||||
cfg.StrOpt('plugin_name',
|
||||
default='Hortonworks Data Platform',
|
||||
help="plugin title, default: Hortonworks Data Platform"),
|
||||
cfg.StrOpt('plugin_overview_name',
|
||||
default='hdp',
|
||||
help="plugin name in overview"),
|
||||
cfg.StrOpt('hadoop_version',
|
||||
default='1.3.0',
|
||||
help="hadoop version for plugin"),
|
||||
cfg.ListOpt('processes',
|
||||
default=
|
||||
{"NN": 0, "DN": 1, "SNN": 2, "HDFS_CLIENT": 3,
|
||||
"GANGLIA_SERVER": 4, "GANGLIA_MONITOR": 5, "AMBARI_SERVER": 6,
|
||||
"AMBARI_AGENT": 7, "JT": 8, "TT": 9, "MAPREDUCE_CLIENT": 10,
|
||||
"NAGIOS_SERVER": 11},
|
||||
help='numbers of processes for hdp in savannabashboard'),
|
||||
cfg.StrOpt('base_image',
|
||||
default='latest-ci-image',
|
||||
help="image name for start hdp cluster")
|
||||
]
|
||||
|
||||
|
||||
def register_config(config, config_group, config_opts):
|
||||
|
||||
config.register_group(config_group)
|
||||
config.register_opts(config_opts, config_group)
|
||||
|
||||
path = os.path.join("%s/tests/configs/config.conf" % os.getcwd())
|
||||
|
||||
if os.path.exists(path):
|
||||
cfg.CONF([], project='savannadashboard', default_config_files=[path])
|
||||
|
||||
register_config(cfg.CONF, common_group, CommonGroup)
|
||||
register_config(cfg.CONF, vanilla_group, VanillaGroup)
|
||||
register_config(cfg.CONF, hdp_group, HdpGroup)
|
||||
|
||||
common = cfg.CONF.common
|
||||
vanilla = cfg.CONF.vanilla
|
||||
hdp = cfg.CONF.hdp
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from savannadashboard.tests import base
|
||||
import savannadashboard.tests.configs.config as cfg
|
||||
|
||||
|
||||
class UIImageRegistry(base.UITestCase):
|
||||
|
||||
@base.attr(tags='image_registry')
|
||||
def test_edit_tags_for_image(self):
|
||||
self.edit_tags_by_image_name(cfg.common.image_name_for_edit,
|
||||
tags_to_add=[
|
||||
{cfg.hdp.plugin_overview_name:
|
||||
cfg.hdp.hadoop_version},
|
||||
{'custom_tag': 'blabla'}])
|
||||
self.edit_tags_by_image_name(cfg.common.image_name_for_edit,
|
||||
tags_to_add=[{'custom_tag': 'qweqwe'}],
|
||||
tags_to_remove=['qweqwe', 'blabla'])
|
||||
|
||||
@base.attr(tags='image_registry')
|
||||
def test_registry_vanilla_image(self):
|
||||
self.image_registry(cfg.common.image_name_for_register,
|
||||
user_name='cloud_user',
|
||||
tags_to_add=[{cfg.vanilla.plugin_overview_name:
|
||||
cfg.vanilla.hadoop_version},
|
||||
{'custom_tag': 'blabla'}])
|
||||
self.unregister_images([cfg.common.image_name_for_register])
|
|
@ -0,0 +1,49 @@
|
|||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import testtools
|
||||
|
||||
from savannadashboard.tests import base
|
||||
import savannadashboard.tests.configs.config as cfg
|
||||
|
||||
|
||||
class UINegativeCreateNodeGroupTemplate(base.UITestCase):
|
||||
|
||||
@base.attr(tags='node_group_template')
|
||||
@testtools.skipIf(cfg.vanilla.skip_plugin_tests,
|
||||
'tests for vanilla plugin skipped')
|
||||
def test_create_vanilla_node_group_template_with_wrong_parameters(self):
|
||||
self.create_node_group_template(
|
||||
"", ["NN", "JT"], cfg.vanilla, flavor="m1.small",
|
||||
params=[{"HDFS Parameters:dfs.datanode.handler.count": "str"},
|
||||
{"MapReduce Parameters:io.sort.mb": "str"}],
|
||||
positive=False, close_window=False,
|
||||
message='Configure Node Group Template, '
|
||||
'HDFS Parameters, MapReduce Parameters, '
|
||||
'Template Name:This field is required., '
|
||||
'HDFS Parameters:dfs.datanode.handler.count:'
|
||||
'Enter a whole number., '
|
||||
'MapReduce Parameters:io.sort.mb:'
|
||||
'Enter a whole number.')
|
||||
|
||||
@base.attr(tags='node_group_template')
|
||||
@testtools.skipIf(cfg.vanilla.skip_plugin_tests,
|
||||
'tests for vanilla plugin skipped')
|
||||
def test_create_vanilla_node_group_template_with_missing_parameters(self):
|
||||
self.create_node_group_template(
|
||||
"", [], cfg.vanilla, positive=False, close_window=False,
|
||||
message='Configure Node Group Template, '
|
||||
'Template Name:This field is required., '
|
||||
'Processes:This field is required.')
|
|
@ -0,0 +1,61 @@
|
|||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import testtools
|
||||
|
||||
from savannadashboard.tests import base
|
||||
import savannadashboard.tests.configs.config as cfg
|
||||
|
||||
|
||||
class UICreateNodeGroupTemplate(base.UITestCase):
|
||||
|
||||
@base.attr('node_group_template', 'vanilla')
|
||||
@testtools.skipIf(cfg.vanilla.skip_plugin_tests,
|
||||
'tests for vanilla plugin skipped')
|
||||
def test_create_node_group_template_vanilla(self):
|
||||
self.create_node_group_template(
|
||||
"selenium-vanilla", ["NN", "JT"], cfg.vanilla, flavor="m1.small",
|
||||
storage={'type': "Cinder Volume", 'volume_per_node': '2',
|
||||
'volume_size': '6'}, description='selenium-test',
|
||||
params=[{"HDFS Parameters:Show_param": True},
|
||||
{"hadoop.native.lib": False}, {"Filter": "heap"},
|
||||
{"Name Node Heap Size": 512},
|
||||
{"Data Node Heap Size": 512},
|
||||
{"Show_param": False}, {"Filter": ""},
|
||||
{"dfs.datanode.max.xcievers": 3555},
|
||||
{"MapReduce Parameters:io.sort.mb": 200},
|
||||
{"mapred.child.java.opts": "-Xmx300m"}])
|
||||
msg = "Error: NodeGroup template with name 'selenium-vanilla'" \
|
||||
" already exists"
|
||||
self.create_node_group_template("selenium-vanilla", ["NN", "JT"],
|
||||
cfg.vanilla, positive=False,
|
||||
message=msg)
|
||||
self.delete_node_group_templates(['selenium-vanilla'])
|
||||
|
||||
@base.attr('node_group_template', 'hdp')
|
||||
@testtools.skipIf(cfg.hdp.skip_plugin_tests,
|
||||
'tests for hdp plugin skipped')
|
||||
def test_create_node_group_template_hdp(self):
|
||||
self.create_node_group_template(
|
||||
"sel-hdp", ["NN", "JT", "HDFS_CLIENT", "AMBARI_SERVER",
|
||||
"AMBARI_AGENT"], cfg.hdp,
|
||||
flavor="m1.small", storage={'type': "Cinder Volume",
|
||||
'volume_per_node': '2',
|
||||
'volume_size': '6'},
|
||||
description='selenium-test')
|
||||
msg = "Error: NodeGroup template with name 'sel-hdp' already exists"
|
||||
self.create_node_group_template("sel-hdp", ["NN", "JT"], cfg.hdp,
|
||||
positive=False, message=msg)
|
||||
self.delete_node_group_templates(['sel-hdp'])
|
11
setup.cfg
11
setup.cfg
|
@ -23,3 +23,14 @@ setup-hooks = pbr.hooks.setup_hook
|
|||
[files]
|
||||
packages =
|
||||
savannadashboard
|
||||
|
||||
[nosetests]
|
||||
cover-package=savanna
|
||||
cover-html=true
|
||||
cover-xml=true
|
||||
cover-xml-file=coverage.xml
|
||||
cover-erase=true
|
||||
cover-inclusive=true
|
||||
verbosity=3
|
||||
detailed-errors=1
|
||||
where=savannadashboard/
|
|
@ -10,3 +10,7 @@ nose
|
|||
openstack.nose_plugin>=0.7
|
||||
pylint==0.25.2
|
||||
unittest2
|
||||
selenium==2.33.0
|
||||
pyvirtualdisplay
|
||||
testtools>=0.9.32
|
||||
oslo.config>=1.1.0
|
13
tox.ini
13
tox.ini
|
@ -17,6 +17,19 @@ deps =
|
|||
-r{toxinidir}/test-requirements.txt
|
||||
commands = nosetests {posargs}
|
||||
|
||||
[testenv:tests]
|
||||
sitepackages = False
|
||||
setenv =
|
||||
VIRTUAL_ENV={envdir}
|
||||
NOSE_WITH_OPENSTACK=1
|
||||
NOSE_OPENSTACK_COLOR=1
|
||||
NOSE_OPENSTACK_RED=200
|
||||
NOSE_OPENSTACK_YELLOW=150
|
||||
NOSE_OPENSTACK_SHOW_ELAPSED=1
|
||||
NOSE_OPENSTACK_STDOUT=1
|
||||
NOSE_XUNIT=1
|
||||
commands = nosetests -w tests -x {posargs}
|
||||
|
||||
[testenv:cover]
|
||||
setenv = NOSE_WITH_COVERAGE=1
|
||||
|
||||
|
|
Loading…
Reference in New Issue