Add automatization for the rest of NICs tests

Change-Id: I6790b5e058ffd00106c117d6755e97a20c749181
This commit is contained in:
ekhomyakova 2016-12-26 14:47:17 +04:00
parent c900955de7
commit e568a1cb1b
11 changed files with 828 additions and 79 deletions

View File

@ -37,6 +37,18 @@ if [ -z "${PLUGIN_RPM}" ]; then
wget --no-check-certificate -O "${PLUGIN_RPM}" "${plugin_url}"
fi
if [ ${TESTS_DIR_NAME} == 'feature_nics' ]; then
export PLUGIN_RPM_SECOND=${PLUGIN_RPM_SECOND:-''}
if [ -z "${PLUGIN_RPM_SECOND}" ]; then
plugins='http://plugins.mirantis.com/repository/f/u/fuel-plugin-vmware-dvs'
path='fuel-plugin-vmware-dvs-3.1-3.1.0-1.noarch.rpm'
plugin_url=${PLUGIN_URL_SECOND:-"${plugins}/${path}"}
export PLUGIN_RPM_SECOND="${CONF_PATH}/plugin2.rpm"
wget --no-check-certificate -O "${PLUGIN_RPM_SECOND}" "${plugin_url}"
fi
fi
# Variables for nailgun
export NAILGUN_PORT=${NAILGUN_PORT:-5544}
export NAILGUN_START_MAX_WAIT_TIME=${NAILGUN_START_MAX_WAIT_TIME:-30}
@ -69,18 +81,23 @@ function install_prepare_plugin {
sudo sed -i -e "s/package_version: .*/package_version: '5.0.0'/" "${meta}"
sudo sed -i -e "s/mitaka-9.0/newton-10.0/" "${meta}" # release version
# Fix components settings
sudo sed -i -e "s/requires/#requires/" ${PLUGIN_PATH}/components.yaml
sudo sed -i -e "s/incompatible/#incompatible/" ${PLUGIN_PATH}/components.yaml
# Fix requirements
sudo sed -i -e '/requires/,$s/^/#/' ${PLUGIN_PATH}/components.yaml
sudo sed -i -e '/error/ s/^/#/' ${PLUGIN_PATH}/environment_config.yaml
fuel --os-username admin --os-password admin plugins \
--register "${plugin_name}==${plugin_version//\'/}"
export INSTALLED_PLUGINS="${INSTALLED_PLUGINS};${plugin_name}==${plugin_version//\'/}"
}
function remove_plugin {
fuel --os-username admin --os-password admin plugins \
--remove "${plugin_name}==${plugin_version//\'/}" 2>/dev/null && \
echo "${plugin_name} was removed" || echo "Can not remove plugin ${plugin_name}"
function remove_plugins {
for plug in $(echo $INSTALLED_PLUGINS | tr ";")
do
fuel --os-username admin --os-password admin plugins \
--remove "${plug}" 2>/dev/null && \
echo "${plug} was removed" || echo "Can not remove plugin ${plug}"
done
}
function run_component_tests {
@ -105,10 +122,19 @@ function run_component_tests {
tox -e stop
tox -e cleanup
tox -e start
./nailgun/manage.py loaddata nailgun/nailgun/fixtures/sample_environment.json
./nailgun/manage.py loaddata ${TESTS_ROOT}/fixture_nodes.json
popd > /dev/null
fi
export INSTALLED_PLUGINS=''
if [ ${TESTS_DIR_NAME} == 'feature_nics' ]; then
install_prepare_plugin "${PLUGIN_RPM_SECOND}"
for conf in 'nic' 'node' 'bond'; do
sudo cp ${CONF_PATH}/${conf}_plugin2.yaml ${PLUGIN_PATH}/${conf}_config.yaml
done
fi
install_prepare_plugin "${PLUGIN_RPM}"
${GULP} build --no-sourcemaps --extra-entries=sinon --static-dir="$NAILGUN_STATIC"
@ -123,7 +149,7 @@ function run_component_tests {
${GULP} functional-tests --no-transpile --suites="${test_case}" || result=1
done
remove_plugin
remove_plugins
if [ "${NO_NAILGUN_START}" -ne 1 ]; then
pushd "$FUEL_WEB_ROOT" > /dev/null

View File

@ -0,0 +1,5 @@
attribute_checkbox_b:
label: "Bond attribute Checkbox B"
description: "Description Checkbox B"
type: "checkbox"
value: false

View File

@ -0,0 +1,15 @@
attribute_checkbox:
label: "Bond attribute Checkbox"
description: "Description for Checkbox"
type: "checkbox"
value: false
weight: 5
attribute_text:
label: "Bond attribute Text Resticted"
description: "Description Text Resticted"
type: "text"
value: ""
weight: 10
restrictions:
- condition: "settings:common.libvirt_type.value != 'kvm'"
action: "hide"

View File

@ -0,0 +1,8 @@
attributes:
metadata:
group: 'other'
vmware_dvs:
value: true
label: "Use the VMware DVS"
weight: 20
type: "checkbox"

View File

@ -0,0 +1,5 @@
attribute_checkbox_b:
label: "NIC attribute Checkbox B"
description: "Description Checkbox B"
type: "checkbox"
value: false

View File

@ -0,0 +1,9 @@
plugin_section_b:
metadata:
group: "some_plugin_section_b"
label: "Section B"
attribute_checkbox_b:
label: "Node attribute Checkbox for section B"
description: "Description Checkbox B"
type: "checkbox"
value: false

View File

@ -0,0 +1,218 @@
/*
* Copyright 2016 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 registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import ClusterPage from 'tests/functional/pages/cluster';
import 'tests/functional/helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal, clusterPage;
var attrLabelPlugin1 = 'span.fuel_plugin_example_v5';
var attrLabelPlugin2 = 'span.fuel-plugin-vmware-dvs';
var bondCheckbox = 'input[type="checkbox"][name="attribute_checkbox"]';
var bondText = 'input[type="text"][name="attribute_text"]';
var itfConfigure = 'button.btn-configure-interfaces';
return {
name: 'BONDs',
timeout: 4 * 60 * 1000,
setup() {
common = new Common(this.remote);
modal = new Modal(this.remote);
clusterPage = new ClusterPage(this.remote);
return this.remote
.then(() => common.getIn());
},
afterEach() {
return this.remote
.deleteCluster(modal);
},
'Set up attributes'() {
return this.remote
.updatePlugin('update_bonds bond_setup')
.newClusterWithPlugin(modal);
},
'Test attributes for BOND interfaces provided by plugin'() {
return this.remote
.newClusterWithPlugin(modal)
// Add one node, open interface configuration
.then(() => common.addNodesToCluster(1, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector(itfConfigure)
// Bond several interfaces and verify that provided attributes are presented for them
.bondInterfaces(-1, -2)
.assertElementExists('.ifc-list > div:nth-child(1) ' + attrLabelPlugin1,
'Bonds attributes are not presented')
// Save changes
.applyItfChanges();
},
'Test Load defaults for BONDs'() {
return this.remote
.newClusterWithPlugin(modal)
// Add one node, open interface configuration
.then(() => common.addNodesToCluster(1, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector(itfConfigure)
// Bond several interfaces and verify that provided attributes are presented for them
.bondInterfaces(-1, -2)
.assertElementExists('input[label="bond0"]', 'Bonds was not created')
.assertElementExists('.ifc-list > div:nth-child(1) ' + attrLabelPlugin1,
'Bonds attributes are not presented')
// Save changes
.applyItfChanges()
// Load Defaults and save changes
.clickByCssSelector('button.btn-defaults')
.waitForCssSelector('.btn-defaults:not(:disabled)', 1000)
.assertElementNotExists('input[label="bond0"]', 'Interfaces were not unbonded')
.applyItfChanges();
},
'Test several plugins with different attributes for BOND'() {
var bondCheckboxDVS = 'input[type="checkbox"][name="attribute_checkbox_b"]';
return this.remote
// Create cluster with plugins
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.clickByCssSelector('input[name="hypervisor:vmware"]')
.pressKeys('\uE007') // Networking
.clickByCssSelector('input[name="network:neutron:ml2:dvs"]')
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.clickByCssSelector('input[name="additional_service:service_plugin_v5_component"]')
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Add one node, open interface configuration
.then(() => common.addNodesToCluster(1, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector(itfConfigure)
// Bond several interfaces, verify attributes provided by both of plugins
.bondInterfaces(-1, -2)
.assertElementExists('input[label="bond0"]', 'Bonds was not created')
.assertElementExists('.ifc-list > div:nth-child(1) ' + attrLabelPlugin1,
'Bond attributes for plugin-1 are not presented')
.assertElementExists('.ifc-list > div:nth-child(1) ' + attrLabelPlugin2,
'Bond attributes for plugin-2 are not presented')
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.setInputValue(bondText, 'some_data')
.assertElementEnabled(bondCheckbox, 'Checkbox is disabled')
.clickByCssSelector(bondCheckbox)
.assertInputValueEquals(bondText, 'some_data', 'Text-input is empty')
.expandNICPropertyByIndex(attrLabelPlugin2, 0)
.assertElementEnabled(bondCheckboxDVS, 'DVS Checkbox is disabled')
.clickByCssSelector(bondCheckboxDVS)
.assertElementExists(bondCheckboxDVS + ':checked', 'DVS Checkbox was not checked')
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.assertElementExists(bondCheckbox + ':checked', 'Checkbox was not checked')
.applyItfChanges()
// Load defaults
.clickByCssSelector('button.btn-defaults')
.waitForCssSelector('.btn-defaults:not(:disabled)', 1000)
// Verify that defaults were loaded
.assertElementNotExists('input[label="bond0"]', 'Defaults were not loaded')
.assertElementNotExists(bondText, 'Defaults were not loaded')
.assertElementNotExists(bondCheckbox, 'Defaults were not loaded')
.assertElementNotExists(bondCheckboxDVS, 'Defaults were not loaded')
// Cancel changes
.clickByCssSelector('button.btn-revert-changes')
.waitForCssSelector('.btn-revert-changes:disabled', 1000)
// Verify that saved values loaded
.assertElementExists('input[label="bond0"]', 'Saved values were not loaded')
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.assertInputValueEquals(bondText, 'some_data', 'Text-input is empty')
.assertElementExists(bondCheckbox + ':checked', 'Checkbox is not checked')
.expandNICPropertyByIndex(attrLabelPlugin2, 0)
.assertElementExists(bondCheckboxDVS + ':checked', 'DVS Checkbox is not checked')
// Load defaults
.clickByCssSelector('button.btn-defaults')
.waitForCssSelector('.btn-defaults:not(:disabled)', 1000)
// Save with default values
.applyItfChanges();
},
'Test restrictions for Bonds'() {
return this.remote
.updatePlugin('update_bonds bond_restrict')
.newClusterWithPlugin(modal)
// Add one node, open interface configuration
.then(() => common.addNodesToCluster(1, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector(itfConfigure)
// Bond several interfaces and save changes
.bondInterfaces(-1, -2)
.assertElementExists('input[label="bond0"]', 'Bonds was not created')
.applyItfChanges()
// Check that Checkbox is visible, but Text-input isn't
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.clickByCssSelector(bondCheckbox)
.assertElementNotExists(bondText, 'Text-input field is displayed')
// Enable KVM
.clickByCssSelector('a.settings.cluster-tab')
.clickByCssSelector('button.btn-danger.proceed-btn') // Discard changes
.then(() => modal.waitToClose())
.clickByCssSelector('a.subtab-link-compute')
.clickByCssSelector('input[name="libvirt_type"][value="kvm"]')
.clickByCssSelector('button.btn-apply-changes')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
// Verify that text input is displayed
.then(() => clusterPage.goToTab('Nodes'))
.clickByCssSelector(itfConfigure)
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.assertElementExists(bondCheckbox, 'Checkbox is not displayed')
.assertElementExists(bondText, 'Text-input field is not displayed');
}
};
});

View File

@ -24,8 +24,17 @@ import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal, clusterPage;
var attrLabelPlugin1 = 'span.fuel_plugin_example_v5';
var attrLabelPlugin2 = 'span.fuel-plugin-vmware-dvs';
var nicCheckbox = 'input[type="checkbox"][name="attribute_checkbox"]';
var nicText = 'input[type="text"][name="attribute_text"]';
var itfConfigure = 'button.btn-configure-interfaces';
return {
name: 'NICs',
timeout: 4 * 60 * 1000,
setup() {
common = new Common(this.remote);
modal = new Modal(this.remote);
@ -47,10 +56,6 @@ registerSuite(() => {
.newClusterWithPlugin(modal);
},
'Test attributes for NIC interfaces'() {
var nicCheckbox = 'input[type="checkbox"][name="attribute_checkbox"]';
var nicText = 'input[type="text"][name="attribute_text"]';
var itfConfigure = 'button.btn-configure-interfaces';
return this.remote
.newClusterWithPlugin(modal)
@ -59,14 +64,14 @@ registerSuite(() => {
.then(() => common.addNodesToCluster(1, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector(itfConfigure)
.assertAmountMatches('span.fuel_plugin_example_v5', 'span.mtu',
'Amount of plugin\'s attributes does not match with interfaces amount')
.assertAmountMatches(attrLabelPlugin1, 'span.mtu', 'Amount of plugin\'s ' +
'attributes does not match with interfaces amount')
// Expand attributes of the first interface, verify that checkbox and input are available
.selectPluginNICPropertyByIndex(0)
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.assertElementEnabled(nicCheckbox, 'Checkbox is disabled')
.clickByCssSelector(nicCheckbox)
.assertElementTextEquals('span.fuel_plugin_example_v5.active button', 'Enabled',
.assertElementTextEquals(attrLabelPlugin1 + '.active button', 'Enabled',
'Checkbox does not enable plugin section')
.assertElementEnabled(nicText, 'Text-input is not available to edit')
.setInputValue(nicText, 'some_data')
@ -75,10 +80,6 @@ registerSuite(() => {
.applyItfChanges();
},
'Test Load defaults attributes for NIC'() {
var nicCheckbox = 'input[type="checkbox"][name="attribute_checkbox"]';
var nicText = 'input[type="text"][name="attribute_text"]';
var itfConfigure = 'button.btn-configure-interfaces';
return this.remote
.newClusterWithPlugin(modal)
@ -88,12 +89,12 @@ registerSuite(() => {
.clickByCssSelector(itfConfigure)
// Expand attributes of the first interface, enable checkbox
.selectPluginNICPropertyByIndex(0)
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.assertElementEnabled(nicCheckbox, 'Checkbox is disabled')
.clickByCssSelector(nicCheckbox)
// Expand attributes of the second interface, input some text
.selectPluginNICPropertyByIndex(1)
.expandNICPropertyByIndex(attrLabelPlugin1, 1)
.setInputValue('.ifc-list > div:nth-child(2) ' + nicText, 'some_data')
// Save changes
@ -101,12 +102,10 @@ registerSuite(() => {
// Load defaults
.clickByCssSelector('button.btn-defaults')
.waitForCssSelector('button.btn-defaults', 3000)
.waitForCssSelector('.btn-defaults:not(:disabled)', 1000)
// Verify that defaults were loaded
.assertElementExists('.ifc-list > div:nth-child(2) ' + nicText + '[value=""]',
'Text-input is not empty')
.assertElementNotExists('.ifc-list > div:nth-child(2) ' + nicText + '[value="some_data"]',
.assertInputValueEquals('.ifc-list > div:nth-child(2) ' + nicText, '',
'Text-input is not empty')
.assertElementsExist(nicCheckbox + ':not(:checked)', 2, 'Checkboxes are still checked')
@ -127,12 +126,12 @@ registerSuite(() => {
// Add one node, verify that NICs plugin attributes are not presented
.then(() => common.addNodesToCluster(1, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector('button.btn-configure-interfaces')
.assertElementNotExists('span.fuel_plugin_example_v5', 'NICs attributes are presented')
.clickByCssSelector(itfConfigure)
.assertElementNotExists(attrLabelPlugin1, 'NICs attributes are presented')
// Verify that plugin attributes are not presented after bonding
.bondInterfaces(-1, -2)
.assertElementNotExists('span.fuel_plugin_example_v5', 'Bonds attributes are presented')
.assertElementNotExists(attrLabelPlugin1, 'Bonds attributes are presented')
.applyItfChanges()
// Verify that nodes plugin attributes are not presented
@ -141,56 +140,126 @@ registerSuite(() => {
.then(() => modal.waitToOpen())
.clickByCssSelector('#headingattributes')
.assertElementNotExists('.setting-section-plugin_section_a', 'Plugin section is presented')
.assertElementNotExists('input[type=checkbox][name="attribute_checkbox"]',
'Checkbox is presented')
.assertElementNotExists('input[type=text][name="attribute_text"]',
'Input field is presented')
.assertElementNotExists('.setting-section-plugin_section_a',
'Plugin section is presented')
.assertElementNotExists(nicCheckbox, 'Checkbox is presented')
.assertElementNotExists(nicText, 'Input field is presented')
.then(() => modal.close())
.then(() => modal.waitToClose());
},
'Test that NIC config may be changed for several nodes simultaneously'() {
var nicText = 'input[type="text"][name="attribute_text"]';
return this.remote
.newClusterWithPlugin(modal)
// Add two nodes, change NIC attributes for the first node
.then(() => common.addNodesToCluster(6, ['Controller']))
.then(() => common.addNodesToCluster(2, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector('button.btn-configure-interfaces')
.selectPluginNICPropertyByIndex(0)
.clickByCssSelector(itfConfigure)
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.setInputValue('.ifc-list > div:nth-child(1) ' + nicText, '1')
.applyItfChanges()
// Change NIC attributes for the second node
.then(() => clusterPage.goToTab('Nodes'))
.selectNodeByIndex(0)
.selectNodeByIndex(-1)
.clickByCssSelector('button.btn-configure-interfaces')
.selectPluginNICPropertyByIndex(1)
.selectNodeByIndex(1)
.clickByCssSelector(itfConfigure)
.expandNICPropertyByIndex(attrLabelPlugin1, 1)
.setInputValue('.ifc-list > div:nth-child(2) ' + nicText, '2')
.applyItfChanges()
// Select both nodes, Configure interfaces, save changes
.then(() => clusterPage.goToTab('Nodes'))
.selectNodeByIndex(0)
.clickByCssSelector('button.btn-configure-interfaces')
.clickByCssSelector(itfConfigure)
.selectPluginNICPropertyByIndex(0)
.selectPluginNICPropertyByIndex(1)
.assertElementExists('.ifc-list > div:nth-child(1) ' + nicText + '[value="1"]',
'Text-input is not empty')
.assertElementExists('.ifc-list > div:nth-child(2) ' + nicText + '[value=""]',
'Text-input is not empty')
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.expandNICPropertyByIndex(attrLabelPlugin1, 1)
.assertInputValueEquals('.ifc-list > div:nth-child(1) ' + nicText, '1',
'Text-input is empty')
.assertInputValueEquals('.ifc-list > div:nth-child(2) ' + nicText, '',
'Text-input is not empty')
.applyItfChanges();
},
'Test several plugins with different attributes for NIC'() {
var nicCheckboxDVS = 'input[type="checkbox"][name="attribute_checkbox_b"]';
var nicTextItf1 = '.ifc-list > div:nth-child(1) ' + nicText;
return this.remote
// Create cluster with plugins
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.clickByCssSelector('input[name="hypervisor:vmware"]')
.pressKeys('\uE007') // Networking
.clickByCssSelector('input[name="network:neutron:ml2:dvs"]')
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.clickByCssSelector('input[name="additional_service:service_plugin_v5_component"]')
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Add one node, open interface configuration
.then(() => common.addNodesToCluster(1, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector(itfConfigure)
// Verify that attributes provided by both of plugins are presented and can be changed
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.setInputValue(nicTextItf1, 'some_data')
.assertElementEnabled(nicCheckbox, 'Checkbox is disabled')
.clickByCssSelector(nicCheckbox)
.assertInputValueEquals(nicTextItf1, 'some_data', 'Text-input is empty')
.expandNICPropertyByIndex(attrLabelPlugin2, 0)
.assertElementEnabled(nicCheckboxDVS, 'DVS Checkbox is disabled')
.clickByCssSelector(nicCheckboxDVS)
.assertElementExists(nicCheckboxDVS + ':checked', 'DVS Checkbox was not checked')
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.assertElementExists(nicCheckbox + ':checked', 'Checkbox was not checked')
.applyItfChanges()
// Load defaults
.clickByCssSelector('button.btn-defaults')
.waitForCssSelector('.btn-defaults:not(:disabled)', 1000)
// Verify that defaults were loaded
.assertInputValueEquals(nicTextItf1, '', 'Text-input is not empty')
.assertElementExists(nicCheckbox + ':not(:checked)', 'Checkbox is still checked')
.expandNICPropertyByIndex(attrLabelPlugin2, 0)
.assertElementExists(nicCheckboxDVS + ':not(:checked)', 'DVS Checkbox is still checked')
// Cancel changes
.clickByCssSelector('button.btn-revert-changes')
.waitForCssSelector('.btn-revert-changes:disabled', 1000)
// Verify that saved values loaded
.assertElementExists(nicCheckboxDVS + ':checked', 'DVS Checkbox is not checked')
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.assertInputValueEquals(nicTextItf1, 'some_data', 'Text-input is empty')
.assertElementExists(nicCheckbox + ':checked', 'Checkbox is not checked')
// Load defaults
.clickByCssSelector('button.btn-defaults')
.waitForCssSelector('.btn-defaults:not(:disabled)', 1000)
// Save with default values
.applyItfChanges();
},
'Test restrictions'() {
var nicCheckbox = 'input[type="checkbox"][name="attribute_checkbox"]';
var nicText = 'input[type="text"][name="attribute_text_r"]';
var itfConfigure = 'button.btn-configure-interfaces';
return this.remote
.updatePlugin('update_nics nic_restrict')
@ -202,7 +271,7 @@ registerSuite(() => {
.clickByCssSelector(itfConfigure)
// Expand attributes of the first interface, verify that checkbox is available
.selectPluginNICPropertyByIndex(0)
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.clickByCssSelector(nicCheckbox)
// Verify that text input is not displayed
@ -222,7 +291,7 @@ registerSuite(() => {
// Verify that text input is displayed
.then(() => clusterPage.goToTab('Nodes'))
.clickByCssSelector(itfConfigure)
.selectPluginNICPropertyByIndex(0)
.expandNICPropertyByIndex(attrLabelPlugin1, 0)
.assertElementExists(nicCheckbox, 'Checkbox is not displayed')
.assertElementExists(nicText, 'Text-input field is not displayed');
}

View File

@ -24,8 +24,15 @@ import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal, clusterPage;
var nodeCheckbox = 'input[type=checkbox][name="attribute_checkbox"]';
var nodeText = 'input[type=text][name="attribute_text"]';
var btnApply = 'button.apply-changes';
var btnLoadDefaults = '.btn-load-defaults';
return {
name: 'Nodes',
timeout: 3 * 60 * 1000,
setup() {
common = new Common(this.remote);
modal = new Modal(this.remote);
@ -41,13 +48,9 @@ registerSuite(() => {
'Set up attributes'() {
return this.remote
.updatePlugin('update_nodes node_setup')
.newClusterWithPlugin(modal);
},
'Test attributes for Nodes'() {
var nodeCheckbox = 'input[type=checkbox][name="attribute_checkbox"]';
var nodeText = 'input[type=text][name="attribute_text"]';
return this.remote
.newClusterWithPlugin(modal)
@ -66,17 +69,14 @@ registerSuite(() => {
.clickByCssSelector(nodeCheckbox)
.setInputValue(nodeText, 'some_data')
.assertElementEnabled('button.apply-changes', 'Apply is disabled')
.clickByCssSelector('button.apply-changes')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
.assertElementEnabled(btnApply, 'Apply is disabled')
.clickByCssSelector(btnApply)
.waitForCssSelector(btnLoadDefaults + ':not(:disabled)', 1000)
.then(() => modal.close())
.then(() => modal.waitToClose());
},
'Test Load defaults for Nodes'() {
var nodeCheckbox = 'input[type=checkbox][name="attribute_checkbox"]';
var nodeText = 'input[type=text][name="attribute_text"]';
return this.remote
.newClusterWithPlugin(modal)
@ -89,29 +89,100 @@ registerSuite(() => {
.clickByCssSelector('#headingattributes')
.clickByCssSelector(nodeCheckbox)
.setInputValue(nodeText, 'some_data')
.clickByCssSelector('button.apply-changes')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
.clickByCssSelector(btnApply)
.waitForCssSelector(btnLoadDefaults + ':not(:disabled)', 1000)
// Load Defaults and verify that default values were loaded
.clickByCssSelector('button.btn-load-defaults')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
.clickByCssSelector(btnLoadDefaults)
.waitForCssSelector(btnLoadDefaults + ':not(:disabled)', 1000)
.assertElementExists(nodeText + '[value=""]', 'Text-input is not empty')
.assertElementNotExists(nodeText + '[value="some_data"]', 'Text-input is not empty')
.assertInputValueEquals(nodeText, '', 'Text-input is not empty')
.assertElementExists(nodeCheckbox + ':not(:checked)', 'Checkbox is still checked')
// Save default values
.assertElementEnabled('button.apply-changes', 'Apply is disabled')
.clickByCssSelector('button.apply-changes')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
.assertElementEnabled(btnApply, 'Apply is disabled')
.clickByCssSelector(btnApply)
.waitForCssSelector(btnLoadDefaults + ':not(:disabled)', 1000)
.then(() => modal.close())
.then(() => modal.waitToClose());
},
'Test several plugins with different attributes for Nodes'() {
var nodeCheckboxDVS = 'input[type=checkbox][name="attribute_checkbox_b"]';
return this.remote
// Create cluster with plugins
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.clickByCssSelector('input[name="hypervisor:vmware"]')
.pressKeys('\uE007') // Networking
.clickByCssSelector('input[name="network:neutron:ml2:dvs"]')
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.clickByCssSelector('input[name="additional_service:service_plugin_v5_component"]')
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Add one node, open settings for it
.then(() => common.addNodesToCluster(1, ['Controller']))
.clickByCssSelector('.node-settings')
.then(() => modal.waitToOpen())
.clickByCssSelector('#headingattributes')
// Verify that attributes provided by both of plugins are presented and can be changed
.setInputValue(nodeText, 'some_data')
.assertElementEnabled(nodeCheckbox, 'Checkbox is disabled')
.clickByCssSelector(nodeCheckbox)
.assertInputValueEquals(nodeText, 'some_data', 'Text-input is empty')
.assertElementEnabled(nodeCheckboxDVS, 'DVS Checkbox is disabled')
.clickByCssSelector(nodeCheckboxDVS)
.assertElementExists(nodeCheckboxDVS + ':checked', 'DVS Checkbox was not checked')
.assertElementExists(nodeCheckbox + ':checked', 'Checkbox was not checked')
// Save changes
.assertElementEnabled(btnApply, 'Apply is disabled')
.clickByCssSelector(btnApply)
.waitForCssSelector(btnLoadDefaults + ':not(:disabled)', 1000)
// Load defaults
.clickByCssSelector(btnLoadDefaults)
.waitForCssSelector(btnLoadDefaults + ':not(:disabled)', 1000)
// Verify that defaults were loaded
.assertInputValueEquals(nodeText, '', 'Text-input is not empty')
.assertElementExists(nodeCheckbox + ':not(:checked)', 'Checkbox is still checked')
.assertElementExists(nodeCheckboxDVS + ':not(:checked)', 'DVS Checkbox is still checked')
// Cancel changes
.clickByCssSelector('button.discard-changes')
.waitForCssSelector('.discard-changes:disabled', 1000)
// Verify that saved values loaded
.assertElementExists(nodeCheckboxDVS + ':checked', 'DVS Checkbox is not checked')
.assertInputValueEquals(nodeText, 'some_data', 'Text-input is empty')
.assertElementExists(nodeCheckbox + ':checked', 'Checkbox is not checked')
// Load defaults
.clickByCssSelector(btnLoadDefaults)
.waitForCssSelector(btnLoadDefaults + ':not(:disabled)', 1000)
// Save with default values
.assertElementEnabled(btnApply, 'Apply is disabled')
.clickByCssSelector(btnApply)
.waitForCssSelector(btnLoadDefaults + ':not(:disabled)', 1000)
.then(() => modal.close())
.then(() => modal.waitToClose());
},
'Test restrictions for Nodes'() {
var nodeCheckbox = 'input[type=checkbox][name="attribute_checkbox"]';
var nodeText = 'input[type=text][name="attribute_text"]';
return this.remote
.updatePlugin('update_nodes node_restrict')
.newClusterWithPlugin(modal)
@ -135,7 +206,7 @@ registerSuite(() => {
.clickByCssSelector('input[name="libvirt_type"][value="kvm"]')
.clickByCssSelector('button.btn-apply-changes')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
.waitForCssSelector(btnLoadDefaults + ':not(:disabled)', 1000)
// Open Settings for the node, check that all attributes are presented
.then(() => clusterPage.goToTab('Nodes'))

View File

@ -0,0 +1,313 @@
[
{
"pk": 1,
"model": "nailgun.node",
"fields": {
"status": "discover",
"name": "Supermicro X9DRW",
"hostname": "node-1",
"ip": "10.20.0.168",
"online": true,
"labels": {},
"pending_addition": false,
"platform_name": "X9DRW",
"mac": "00:25:90:6a:b1:11",
"meta": {
"cpu": {
"real": 2,
"total": 24,
"spec": [
{
"model": "Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz",
"frequency": 2001
}
]
},
"interfaces": [
{
"name": "eth1",
"ip": "172.18.67.167",
"netmask": "255.255.255.240",
"mac": "00:aa:90:67:9f:b7",
"driver": "igb",
"bus_info": "0000:06:00.0",
"max_speed": 1000,
"current_speed": 1000,
"pxe": false,
"interface_properties": {
"sriov": {
"available": true,
"enabled": false,
"pci_id": "1234:5678",
"physnet": "physnet2",
"sriov_numvfs": null,
"sriov_totalvfs": 2
},
"pci_id": "8086:100e"
}
},
{
"name": "eth2",
"ip": "172.18.167.167",
"netmask": "255.255.255.240",
"mac": "00:25:90:67:9f:b8",
"driver": "igb",
"bus_info": "0000:07:00.0",
"max_speed": 1000,
"current_speed": 1000,
"pxe": false,
"interface_properties": {
"pci_id": "8086:100e"
}
},
{
"name": "eth3",
"ip": "172.18.167.167",
"netmask": "255.255.255.240",
"mac": "00:25:90:67:9f:b9",
"driver": "eth_ipoib",
"bus_info": "0000:08:00.0",
"max_speed": 10000,
"current_speed": 10000,
"pxe": false,
"interface_properties": {
"pci_id": "8086:100e"
}
},
{
"ip": "10.20.0.167",
"mac": "00:25:90:67:9f:b6",
"max_speed": 1000,
"name": "eth0",
"current_speed": 1000,
"driver": "igb",
"bus_info": "0000:09:00.0",
"pxe": true,
"interface_properties": {
"pci_id": "8086:100e"
}
},
{
"name": "eth5",
"ip": "172.18.67.170",
"netmask": "255.255.255.240",
"mac": "00:25:90:67:9f:d7",
"driver": "igb",
"bus_info": "0000:06:00.0",
"max_speed": 1000,
"current_speed": 1000,
"pxe": false
}
],
"disks": [
{
"model": "TOSHIBA MK1002TS",
"name": "sda",
"disk": "sda",
"size": 1000204886016
}
],
"system": {
"product": "X9DRW",
"family": "To be filled by O.E.M.",
"fqdn": "srv08-srt.srt.mirantis.net",
"version": "0123456789",
"serial": "0123456789",
"manufacturer": "Supermicro"
},
"memory": {
"slots": 1,
"total": 137455730688,
"maximum_capacity": 274894684160,
"devices": [
{
"frequency": 1333,
"type": "DDR3",
"size": 8589934592
}
]
},
"numa_topology": {
"numa_nodes": [
{
"id": 0,
"memory": 85899345920,
"cpus": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
]
},
{
"id": 1,
"memory": 51539607552,
"cpus": [
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
]
}
],
"supported_hugepages": [2048, 1048576],
"distances": [
["1.0", "2.1"],
["2.1", "1.0"]
]
}
},
"timestamp": "",
"progress": 0,
"pending_deletion": false,
"os_platform": "ubuntu",
"manufacturer": "Supermicro"
}
},
{
"pk": 2,
"model": "nailgun.node",
"fields": {
"status": "discover",
"name": "Dell Inspiron",
"hostname": "node-2",
"ip": "10.20.0.133",
"online": true,
"labels": {},
"pending_addition": false,
"platform_name": "Inspiron N5110",
"mac": "58:91:cF:2a:c4:1b",
"meta": {
"memory": {
"slots": 2,
"total": 8589934592,
"maximum_capacity": 17179869184,
"devices": [
{
"frequency": 1333,
"type": "DDR3",
"size": 4294967296
},
{
"frequency": 1333,
"type": "DDR3",
"size": 4294967296
}
]
},
"interfaces": [
{
"name": "eth1",
"ip": "172.18.67.167",
"netmask": "255.255.255.240",
"mac": "00:aa:90:67:9f:b7",
"driver": "igb",
"bus_info": "0000:06:00.0",
"max_speed": 1000,
"current_speed": 1000,
"pxe": false,
"interface_properties": {
"sriov": {
"available": true,
"enabled": false,
"pci_id": "1234:5678",
"physnet": "physnet2",
"sriov_numvfs": null,
"sriov_totalvfs": 2
},
"pci_id": "8086:100e"
}
},
{
"name": "eth2",
"ip": "172.18.167.167",
"netmask": "255.255.255.240",
"mac": "00:25:90:67:9f:b8",
"driver": "igb",
"bus_info": "0000:07:00.0",
"max_speed": 1000,
"current_speed": 1000,
"pxe": false,
"interface_properties": {
"pci_id": "8086:100e"
}
},
{
"name": "eth3",
"ip": "172.18.167.167",
"netmask": "255.255.255.240",
"mac": "00:25:90:67:9f:b9",
"driver": "eth_ipoib",
"bus_info": "0000:08:00.0",
"max_speed": 10000,
"current_speed": 10000,
"pxe": false,
"interface_properties": {
"pci_id": "8086:100e"
}
},
{
"ip": "10.20.0.167",
"mac": "00:25:90:67:9f:b6",
"max_speed": 1000,
"name": "eth0",
"current_speed": 1000,
"driver": "igb",
"bus_info": "0000:09:00.0",
"pxe": true,
"interface_properties": {
"pci_id": "8086:100e"
}
},
{
"name": "eth5",
"ip": "172.18.67.170",
"netmask": "255.255.255.240",
"mac": "00:25:90:67:9f:d7",
"driver": "igb",
"bus_info": "0000:06:00.0",
"max_speed": 1000,
"current_speed": 1000,
"pxe": false
}
],
"disks": [
{
"model": "Silicon-Power16G",
"name": "sdb",
"disk": "sdb",
"size": 15518924800
}
],
"system": {
"product": "Inspiron N5110",
"serial": "044ED881",
"fqdn": "lab-10",
"manufacturer": "80AD"
},
"cpu": {
"real": 1,
"total": 8,
"spec": [
{
"model": "Intel(R) Core(TM) i7-2670QM CPU @ 2.20GHz",
"frequency": 2201
}
]
},
"numa_topology": {
"numa_nodes": [
{
"id": 0,
"memory": 8589934592,
"cpus": [0, 1, 2, 3, 4, 5, 6, 7]
}
],
"supported_hugepages": [2048, 1048576],
"distances": [
["1.0"]
]
}
},
"timestamp": "",
"progress": 0,
"pending_deletion": false,
"os_platform": "ubuntu",
"manufacturer": "80AD"
}
}
]

View File

@ -78,6 +78,8 @@ _.defaults(Command.prototype, {
deleteCluster(modal) {
return new this.constructor(this, function() {
return this.parent
.clickIfExists('.btn-revert-changes')
.clickIfExists('.discard-changes')
.clickIfExists('a.dashboard.cluster-tab')
.clickIfExists('.btn-danger')
@ -101,10 +103,10 @@ _.defaults(Command.prototype, {
}).end();
});
},
selectPluginNICPropertyByIndex(index) {
expandNICPropertyByIndex(cssPropLabel, index) {
return new this.constructor(this, function() {
return this.parent
.clickObjectByIndex('span.fuel_plugin_example_v5 button', index);
.clickObjectByIndex(cssPropLabel + ' button', index);
});
},
selectNodeByIndex(nodeIndex) {
@ -142,5 +144,13 @@ _.defaults(Command.prototype, {
.clickByCssSelector('button.btn-apply')
.waitForCssSelector('.btn-defaults:not(:disabled)', 1000);
});
},
assertInputValueEquals(cssSelector, value, message) {
return new this.constructor(this, () => {
return this.parent
.findAllByCssSelector(cssSelector).getProperty('value').then((el) => {
return assert.equal(el[0], value, message);
}).end();
});
}
});