Add tests for NICs feature, adapt as plugin-tests

Change-Id: I299d857ce74e5f2373e1b8a8a2e2c69c7e350d28
This commit is contained in:
ekhomyakova 2016-12-13 16:47:05 +04:00 committed by Ekaterina Khomyakova
parent a4eebede2d
commit 90f92f0dd6
40 changed files with 662 additions and 89 deletions

View File

@ -18,7 +18,7 @@
"unit-tests": "gulp unit-tests",
"func-tests": "./run_ui_func_tests.sh",
"nightly-func-tests": "./run_ui_func_tests.sh static/tests/functional/nightly/*.js",
"component-tests": "./run_component_registry_tests.sh"
"plugin-tests": "./run_real_plugin_tests.sh"
},
"dependencies": {
"async-props": "0.3.2",

View File

@ -17,20 +17,24 @@
set -eu
# Variables for tests
export NO_NAILGUN_START=${NO_NAILGUN_START:-0}
export TESTS_ROOT="$(pwd)/static/tests/functional/real_plugin"
export SCRIPT_PATH="${TESTS_ROOT}/update_plugin.sh"
export TEST_PREFIX=${TEST_PREFIX:-'test_*'}
export TESTS_DIR_NAME=${TESTS_DIR_NAME:-'feature_nics'}
export CONF_PATH="${TESTS_ROOT}/${TESTS_DIR_NAME}/plugin_conf"
export NO_NAILGUN_START=${NO_NAILGUN_START:-0}
export FUEL_WEB_ROOT=$(readlink -f ${FUEL_WEB_ROOT:-"$(dirname $0)/../fuel-web"})
export ARTIFACTS=${ARTIFACTS:-"$(pwd)/test_run/ui_component"}
export CONF_PATH="$(pwd)/static/tests/functional/component_registry/plugin_conf"
export SCRIPT_PATH="${CONF_PATH}/update_components.sh"
export PLUGIN_RPM=${PLUGIN_RPM:-''}
if [ -z "${PLUGIN_RPM}" ]; then
plugins='https://product-ci.infra.mirantis.net/view/All/job/9.0.build-fuel-plugins'
path='lastSuccessfulBuild/artifact/built_plugins/fuel_plugin_example_v4-4.0-4.0.0-1.noarch.rpm'
path='lastSuccessfulBuild/artifact/built_plugins/fuel_plugin_example_v5-1.0-1.0.0-1.noarch.rpm'
plugin_url=${PLUGIN_URL:-"${plugins}/${path}"}
export PLUGIN_RPM="${CONF_PATH}/plugin.rpm"
wget -O "${PLUGIN_RPM}" "${plugin_url}"
wget --no-check-certificate -O "${PLUGIN_RPM}" "${plugin_url}"
fi
# Variables for nailgun
@ -49,7 +53,7 @@ export NAILGUN_CHECK_URL='/api/version'
mkdir -p "$ARTIFACTS"
function install_plugin {
function install_prepare_plugin {
plugin_rpm=$1
mkdir -p "${nailgun_plugins_path}"
@ -60,9 +64,14 @@ function install_plugin {
plugin_name=$(grep -oP '^name: \K(.*)' "${meta}")
plugin_version=$(grep -oP '^version: \K(.*)' "${meta}")
sudo sed -i -e "s/fuel_version: \['8.0'\]/fuel_version: \['10.0'\]/" "${meta}"
sudo sed -i -e "s/fuel_version: \['9.0'\]/fuel_version: \['10.0'\]/" "${meta}"
sudo sed -i -e "s/mitaka-9.0/newton-10.0/" "${meta}"
# Fix versions
sudo sed -i -e "s/fuel_version: .*/fuel_version: \['10.0'\]/" "${meta}"
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
fuel --os-username admin --os-password admin plugins \
--register "${plugin_name}==${plugin_version//\'/}"
@ -70,14 +79,14 @@ function install_plugin {
function remove_plugin {
fuel --os-username admin --os-password admin plugins \
--remove "${plugin_name}==${plugin_version//\'/}" 2>/dev/null || \
echo "${plugin_name} was removed"
--remove "${plugin_name}==${plugin_version//\'/}" 2>/dev/null && \
echo "${plugin_name} was removed" || echo "Can not remove plugin ${plugin_name}"
}
function run_component_tests {
local GULP='./node_modules/.bin/gulp'
local TESTS_DIR='static/tests/functional/component_registry'
local TESTS=$TESTS_DIR/${TEST_PREFIX}.js
local TESTS_DIR="static/tests/functional/real_plugin/${TESTS_DIR_NAME}"
local TESTS=${TESTS_DIR}/${TEST_PREFIX}.js
local result=0
export SERVER_ADDRESS=${SERVER_ADDRESS:-'127.0.0.1'}
@ -96,16 +105,17 @@ function run_component_tests {
tox -e stop
tox -e cleanup
tox -e start
./nailgun/manage.py loaddata nailgun/nailgun/fixtures/sample_environment.json
popd > /dev/null
fi
install_prepare_plugin "${PLUGIN_RPM}"
${GULP} build --no-sourcemaps --extra-entries=sinon --static-dir="$NAILGUN_STATIC"
if [ $? -ne 0 ]; then
return 1
fi
install_plugin "${PLUGIN_RPM}"
for test_case in $TESTS; do
echo "INFO: Running test case ${test_case}"

View File

@ -1,59 +0,0 @@
/*
* 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 _ from 'intern/dojo/node!lodash';
import childProcess from 'intern/dojo/node!child_process';
import Command from 'intern/dojo/node!leadfoot/Command';
import 'tests/functional/helpers';
_.defaults(Command.prototype, {
updatePlugin(files) {
return new this.constructor(this, function() {
return this.parent
.then(() => {
childProcess.exec('/bin/sh ${SCRIPT_PATH} ' + files,
(err) => {
if (err) return;
});
})
.sleep(250); // wait for plugin update
});
},
newClusterFillName(modal) {
return new this.constructor(this, function() {
return this.parent
.clickByCssSelector('.create-cluster')
.then(() => modal.waitToOpen())
.setInputValue('[name=name]', 'Temp');
});
},
assertNextButtonEnabled() {
return new this.constructor(this, function() {
return this.parent
.assertElementNotExists('button.next-pane-btn.disabled',
'Next button is disabled');
});
},
deleteCluster(modal) {
return new this.constructor(this, function() {
return this.parent
.clickByCssSelector('button.delete-environment-btn')
.then(() => modal.waitToOpen())
.clickByCssSelector('button.remove-cluster-btn')
.then(() => modal.waitToClose());
});
}
});

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
default=${CONF_PATH}/$1.yaml
components_file=${CONF_PATH}/$2.yaml
sudo sh -c "cat ${components_file} ${default} > ${PLUGIN_PATH}/components.yaml"
fuel --os-username admin --os-password admin plugins --sync

View File

@ -18,7 +18,7 @@ import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/component_registry/component_helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;

View File

@ -18,7 +18,7 @@ import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/component_registry/component_helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;

View File

@ -18,7 +18,7 @@ import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/component_registry/component_helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;

View File

@ -18,7 +18,7 @@ import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/component_registry/component_helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;
@ -74,7 +74,7 @@ registerSuite(() => {
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal).sleep(10000);
.deleteCluster(modal);
},
'Test storage -storage:image'() {
var nfs = 'input[value=storage\\:image\\:nfs]';

View File

@ -18,7 +18,7 @@ import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/component_registry/component_helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;

View File

@ -0,0 +1,12 @@
attribute_checkbox:
label: "Bond attribute Checkbox"
description: "Description for Checkbox"
type: "checkbox"
value: false
weight: 5
attribute_text:
label: "Bond attribute Text"
description: "Description Text"
type: "text"
value: ""
weight: 10

View File

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

View File

@ -0,0 +1,12 @@
attribute_checkbox:
label: "NIC attribute Checkbox"
description: "Description for Checkbox"
type: "checkbox"
value: false
weight: 5
attribute_text:
label: "NIC attribute Text"
description: "Description for attribute Text"
type: "text"
value: ""
weight: 10

View File

@ -0,0 +1,17 @@
plugin_section_a:
metadata:
group: "Plugin_section"
label: "Plugin's attributes section"
attribute_checkbox:
label: "Node attribute Checkbox for plugin's section"
description: "Description Checkbox"
type: "checkbox"
value: false
attribute_text:
label: "Node attribute Text for plugin's section"
description: "Description Text"
type: "text"
value: ""
restrictions:
- condition: "settings:common.libvirt_type.value != 'kvm'"
action: "hide"

View File

@ -0,0 +1,14 @@
plugin_section_a:
metadata:
group: "Plugin_section"
label: "Plugin's attributes section"
attribute_checkbox:
label: "Node attribute Checkbox for plugin's section"
description: "Description Checkbox"
type: "checkbox"
value: false
attribute_text:
label: "Node attribute Text for plugin's section"
description: "Description Text"
type: "text"
value: ""

View File

@ -0,0 +1,230 @@
/*
* 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;
return {
name: 'NICs',
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 all attributes'() {
return this.remote
.updatePlugin('update_nics nic_setup')
.updatePlugin('update_nodes node_setup')
.updatePlugin('update_bonds bond_setup')
.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)
// Add one node, open interface configuration,
// verify that plugin's attributes for nics are presented
.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')
// Expand attributes of the first interface, verify that checkbox and input are available
.selectPluginNICPropertyByIndex(0)
.assertElementEnabled(nicCheckbox, 'Checkbox is disabled')
.clickByCssSelector(nicCheckbox)
.assertElementTextEquals('span.fuel_plugin_example_v5.active button', 'Enabled',
'Checkbox does not enable plugin section')
.assertElementEnabled(nicText, 'Text-input is not available to edit')
.setInputValue(nicText, 'some_data')
// Save changes
.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)
// Add one node, open interface configuration
.then(() => common.addNodesToCluster(1, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector(itfConfigure)
// Expand attributes of the first interface, enable checkbox
.selectPluginNICPropertyByIndex(0)
.assertElementEnabled(nicCheckbox, 'Checkbox is disabled')
.clickByCssSelector(nicCheckbox)
// Expand attributes of the second interface, input some text
.selectPluginNICPropertyByIndex(1)
.setInputValue('.ifc-list > div:nth-child(2) ' + nicText, 'some_data')
// Save changes
.applyItfChanges()
// Load defaults
.clickByCssSelector('button.btn-defaults')
.waitForCssSelector('button.btn-defaults', 3000)
// 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"]',
'Text-input is not empty')
.assertElementsExist(nicCheckbox + ':not(:checked)', 2, 'Checkboxes are still checked')
// Save with default values
.applyItfChanges();
},
'Test cluster without plugin has only core attributes'() {
return this.remote
.then(() => common.createCluster('test')) // Create cluster without plugin
// Enable KVM
.then(() => clusterPage.goToTab('Settings'))
.clickByCssSelector('a.subtab-link-compute')
.clickByCssSelector('input[name="libvirt_type"][value="kvm"]')
.clickByCssSelector('button.btn-apply-changes')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
// 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')
// Verify that plugin attributes are not presented after bonding
.bondInterfaces(-1, -2)
.assertElementNotExists('span.fuel_plugin_example_v5', 'Bonds attributes are presented')
.applyItfChanges()
// Verify that nodes plugin attributes are not presented
.then(() => clusterPage.goToTab('Nodes'))
.clickByCssSelector('.node-settings')
.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')
.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']))
.selectNodeByIndex(0)
.clickByCssSelector('button.btn-configure-interfaces')
.selectPluginNICPropertyByIndex(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)
.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')
.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')
.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')
.newClusterWithPlugin(modal)
// Add one node, open interface configuration
.then(() => common.addNodesToCluster(1, ['Controller']))
.selectNodeByIndex(0)
.clickByCssSelector(itfConfigure)
// Expand attributes of the first interface, verify that checkbox is available
.selectPluginNICPropertyByIndex(0)
.clickByCssSelector(nicCheckbox)
// Verify that text input is not displayed
.assertElementNotExists(nicText, '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)
.selectPluginNICPropertyByIndex(0)
.assertElementExists(nicCheckbox, 'Checkbox is not displayed')
.assertElementExists(nicText, 'Text-input field is not displayed');
}
};
});

View File

@ -0,0 +1,152 @@
/*
* 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;
return {
name: 'Nodes',
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_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)
// Add node and open settings for it
.then(() => common.addNodesToCluster(1, ['Controller']))
.clickByCssSelector('.node-settings')
.then(() => modal.waitToOpen())
// Verify that provided attributes are presented
.clickByCssSelector('#headingattributes')
.assertElementExists('.setting-section-plugin_section_a', 'Plugin section is not presented')
.assertElementExists(nodeCheckbox, 'Checkbox is not presented')
.assertElementExists(nodeText, 'Input field is not presented')
.clickByCssSelector(nodeCheckbox)
.setInputValue(nodeText, 'some_data')
.assertElementEnabled('button.apply-changes', 'Apply is disabled')
.clickByCssSelector('button.apply-changes')
.waitForCssSelector('.btn-load-defaults: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)
// Add node and open settings for it
.then(() => common.addNodesToCluster(1, ['Controller']))
.clickByCssSelector('.node-settings')
.then(() => modal.waitToOpen())
// Change default values for attributes provided by plugin and apply the changes
.clickByCssSelector('#headingattributes')
.clickByCssSelector(nodeCheckbox)
.setInputValue(nodeText, 'some_data')
.clickByCssSelector('button.apply-changes')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
// Load Defaults and verify that default values were loaded
.clickByCssSelector('button.btn-load-defaults')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
.assertElementExists(nodeText + '[value=""]', 'Text-input is not empty')
.assertElementNotExists(nodeText + '[value="some_data"]', '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)
.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)
// Add node and open settings for it
.then(() => common.addNodesToCluster(1, ['Controller']))
.clickByCssSelector('.node-settings')
.then(() => modal.waitToOpen())
// Check that Checkbox is visible, but Text-input isn't
.clickByCssSelector('#headingattributes')
.assertElementExists(nodeCheckbox, 'Checkbox is not presented')
.assertElementNotExists(nodeText, 'Text-input is presented')
// Enable KVM in Settings -> Compute
.then(() => modal.close())
.then(() => modal.waitToClose())
.clickByCssSelector('a.settings.cluster-tab')
.clickByCssSelector('a.subtab-link-compute')
.clickByCssSelector('input[name="libvirt_type"][value="kvm"]')
.clickByCssSelector('button.btn-apply-changes')
.waitForCssSelector('.btn-load-defaults:not(:disabled)', 1000)
// Open Settings for the node, check that all attributes are presented
.then(() => clusterPage.goToTab('Nodes'))
.clickByCssSelector('.node-settings')
.then(() => modal.waitToOpen())
.clickByCssSelector('#headingattributes')
.assertElementExists(nodeCheckbox, 'Checkbox is not presented')
.assertElementExists(nodeText, 'Text-input is not presented')
.then(() => modal.close())
.then(() => modal.waitToClose());
}
};
});

View File

@ -0,0 +1,146 @@
/*
* 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 _ from 'intern/dojo/node!lodash';
import childProcess from 'intern/dojo/node!child_process';
import Command from 'intern/dojo/node!leadfoot/Command';
import 'tests/functional/helpers';
import assert from 'intern/chai!assert';
_.defaults(Command.prototype, {
updatePlugin(params) {
return new this.constructor(this, function() {
return this.parent
.then(() => {
childProcess.exec('/bin/bash ${SCRIPT_PATH} ' + params,
(err) => {
if (err) return;
});
})
.sleep(250); // wait for plugin update
});
},
newClusterFillName(modal) {
return new this.constructor(this, function() {
return this.parent
.clickByCssSelector('.create-cluster')
.then(() => modal.waitToOpen())
.setInputValue('[name=name]', 'Temp');
});
},
newClusterWithPlugin(modal) {
return new this.constructor(this, function() {
return this.parent
.clickByCssSelector('.create-cluster')
.then(() => modal.waitToOpen())
.setInputValue('[name=name]', 'Temp')
.pressKeys('\uE007') // go to Compute
.pressKeys('\uE007') // Networking
.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());
});
},
assertNextButtonEnabled() {
return new this.constructor(this, function() {
return this.parent
.assertElementNotExists('button.next-pane-btn.disabled', 'Next button is disabled');
});
},
clickIfExists(cssSelector) {
return new this.constructor(this, function() {
return this.parent
.findAllByCssSelector(cssSelector).then((elements) => {
if (elements.length === 1) {
elements[0].click();
}
}).end();
});
},
deleteCluster(modal) {
return new this.constructor(this, function() {
return this.parent
.clickIfExists('a.dashboard.cluster-tab')
.clickIfExists('.btn-danger')
.then(() => modal.waitToClose())
.clickIfExists('button.delete-environment-btn')
.then(() => modal.waitToOpen())
.clickIfExists('button.remove-cluster-btn')
.then(() => modal.waitToClose());
});
},
clickObjectByIndex(objectsCssSelector, index) {
return new this.constructor(this, function() {
return this.parent
.findAllByCssSelector(objectsCssSelector).then((elements) => {
if (index < 0) {
index = elements.length + index;
}
elements[index].click();
}).end();
});
},
selectPluginNICPropertyByIndex(index) {
return new this.constructor(this, function() {
return this.parent
.clickObjectByIndex('span.fuel_plugin_example_v5 button', index);
});
},
selectNodeByIndex(nodeIndex) {
return new this.constructor(this, function() {
return this.parent
.clickObjectByIndex('div.node-list.row div:nth-child(2) div.checkbox-group.pull-left',
nodeIndex);
});
},
bondInterfaces(itfIndex1, itfIndex2) {
var itfList = '.ifc-list > div .ifc-header .common-ifc-name .custom-tumbler';
return new this.constructor(this, function() {
return this.parent
.clickObjectByIndex(itfList, itfIndex1)
.clickObjectByIndex(itfList, itfIndex2)
.clickByCssSelector('.btn-bond');
});
},
assertAmountMatches(cssSelector1, cssSelector2, message) {
return new this.constructor(this, () => {
var amount;
return this.parent
.findAllByCssSelector(cssSelector1).then((elements) => {
amount = elements.length;
}).end()
.findAllByCssSelector(cssSelector2).then((elements) => {
return assert.equal(elements.length, amount, message);
}).end();
});
},
applyItfChanges() {
return new this.constructor(this, () => {
return this.parent
.assertElementEnabled('button.btn-apply', 'Apply is disabled')
.clickByCssSelector('button.btn-apply')
.waitForCssSelector('.btn-defaults:not(:disabled)', 1000);
});
}
});

View File

@ -0,0 +1,32 @@
#!/usr/bin/env bash
function update_components {
default=${CONF_PATH}/$1.yaml
components_file=${CONF_PATH}/$2.yaml
sudo sh -c "cat ${components_file} ${default} > ${PLUGIN_PATH}/components.yaml"
}
function update_nics {
nic_file=${CONF_PATH}/$1.yaml
sudo cp ${nic_file} ${PLUGIN_PATH}/nic_config.yaml
}
function update_nodes {
node_file=${CONF_PATH}/$1.yaml
sudo cp ${node_file} ${PLUGIN_PATH}/node_config.yaml
}
function update_bonds {
bond_file=${CONF_PATH}/$1.yaml
sudo cp ${bond_file} ${PLUGIN_PATH}/bond_config.yaml
}
case $1 in
update_components|update_nics|update_nodes|update_bonds) func=$1; params="${@:2}";;
*) func=update_components; params="$@";;
esac
$func $params
fuel --os-username admin --os-password admin plugins --sync