[Fuel] scenario for add and remove node
add node and remove node to/from environment Change-Id: Ib7da11d8ffe6c692018a241a20ac978eb450f624
This commit is contained in:
parent
d2b123fb50
commit
093cefb18f
@ -20,3 +20,20 @@
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
FuelNodes.add_and_remove_node:
|
||||
-
|
||||
context:
|
||||
fuel_environments:
|
||||
environments: 2
|
||||
release_id: 1
|
||||
network_provider: "neutron"
|
||||
deployment_mode: "ha_compact"
|
||||
net_segment_type: "vlan"
|
||||
resource_management_workers: 1
|
||||
runner:
|
||||
type: "serial"
|
||||
times: 20
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
128
rally/plugins/openstack/context/fuel.py
Normal file
128
rally/plugins/openstack/context/fuel.py
Normal file
@ -0,0 +1,128 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 collections
|
||||
|
||||
from rally.common import broker
|
||||
from rally.common.i18n import _
|
||||
from rally.common import log as logging
|
||||
from rally.common import utils as rutils
|
||||
from rally import consts
|
||||
from rally import exceptions
|
||||
from rally.plugins.openstack.scenarios.fuel import utils as fuel_utils
|
||||
from rally.task import context as base
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@base.configure(name="fuel_environments", order=110)
|
||||
class FuelEnvGenerator(base.Context):
|
||||
"""Context for generating Fuel environments."""
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
"type": "object",
|
||||
"$schema": consts.JSON_SCHEMA,
|
||||
"properties": {
|
||||
"environments": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"release_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"network_provider": {
|
||||
"type": "string"
|
||||
},
|
||||
"net_segment_type": {
|
||||
"type": "string"
|
||||
},
|
||||
"deployment_mode": {
|
||||
"type": "string"
|
||||
},
|
||||
"resource_management_workers": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
},
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
"environments": 5,
|
||||
"release_id": 1,
|
||||
"network_provider": "neutron",
|
||||
"deployment_mode": "ha_compact",
|
||||
"net_segment_type": "vlan",
|
||||
"resource_management_workers": 2
|
||||
}
|
||||
|
||||
def _create_envs(self):
|
||||
threads = self.config["resource_management_workers"]
|
||||
|
||||
envs = collections.deque()
|
||||
|
||||
def publish(queue):
|
||||
kwargs = {"release_id": self.config["release_id"],
|
||||
"network_provider": self.config["network_provider"],
|
||||
"deployment_mode": self.config["deployment_mode"],
|
||||
"net_segment_type": self.config["net_segment_type"]}
|
||||
|
||||
for i in range(self.config["environments"]):
|
||||
queue.append(kwargs)
|
||||
|
||||
def consume(cache, kwargs):
|
||||
env_id = self.fscenario._create_environment(**kwargs)
|
||||
envs.append(env_id)
|
||||
|
||||
broker.run(publish, consume, threads)
|
||||
|
||||
return list(envs)
|
||||
|
||||
def _delete_envs(self):
|
||||
threads = self.config["resource_management_workers"]
|
||||
|
||||
def publish(queue):
|
||||
queue.extend(self.context["fuel"]["environments"])
|
||||
|
||||
def consume(cache, env_id):
|
||||
self.fscenario._delete_environment(env_id)
|
||||
|
||||
broker.run(publish, consume, threads)
|
||||
self.context["fuel"] = {}
|
||||
|
||||
@rutils.log_task_wrapper(LOG.info, _("Enter context: `fuel_environments`"))
|
||||
def setup(self):
|
||||
"""Create Fuel environments, using the broker pattern."""
|
||||
|
||||
self.context.setdefault("fuel", {})
|
||||
self.context["fuel"].setdefault("environments", [])
|
||||
threads = self.config["resource_management_workers"]
|
||||
|
||||
LOG.debug("Creating %(envs)d environments using %(threads)s threads" %
|
||||
{"envs": self.config["environments"],
|
||||
"threads": threads})
|
||||
self.fscenario = fuel_utils.FuelScenario(self.context)
|
||||
self.context["fuel"]["environments"] = self._create_envs()
|
||||
|
||||
if len(self.context[
|
||||
"fuel"]["environments"]) != self.config["environments"]:
|
||||
raise exceptions.ContextSetupFailure(
|
||||
ctx_name=self.get_name(),
|
||||
msg=_("failed to create the requested"
|
||||
" number of environments."))
|
||||
|
||||
@rutils.log_task_wrapper(LOG.info, _("Exit context: `fuel_environments`"))
|
||||
def cleanup(self):
|
||||
"""Delete environments, using the broker pattern."""
|
||||
self._delete_envs()
|
40
rally/plugins/openstack/scenarios/fuel/nodes.py
Normal file
40
rally/plugins/openstack/scenarios/fuel/nodes.py
Normal file
@ -0,0 +1,40 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 random
|
||||
|
||||
from rally.plugins.openstack import scenario
|
||||
from rally.plugins.openstack.scenarios.fuel import utils
|
||||
from rally.task import validation
|
||||
|
||||
|
||||
class FuelNodes(utils.FuelScenario):
|
||||
"""Benchmark scenarios for Fuel nodes."""
|
||||
|
||||
@validation.required_clients("fuel", admin=True)
|
||||
@validation.required_openstack(admin=True)
|
||||
@validation.required_contexts("fuel_environments")
|
||||
@scenario.configure()
|
||||
def add_and_remove_node(self, node_roles=None):
|
||||
"""Add node to environment and remove
|
||||
|
||||
:param node_roles: list. Roles, which node should be assigned to
|
||||
env with
|
||||
"""
|
||||
|
||||
env_id = random.choice(self.context["fuel"]["environments"])
|
||||
|
||||
node_id = self._get_free_node_id()
|
||||
self._add_node(env_id, [node_id], node_roles)
|
||||
self._remove_node(env_id, node_id)
|
@ -14,6 +14,7 @@
|
||||
|
||||
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
|
||||
import six
|
||||
@ -138,5 +139,60 @@ class FuelScenario(scenario.OpenStackScenario):
|
||||
|
||||
@atomic.action_timer("fuel.delete_environment")
|
||||
def _delete_environment(self, env_id, retries=5):
|
||||
self.admin_clients("fuel").environment.delete(
|
||||
env_id, retries)
|
||||
self.admin_clients("fuel").environment.delete(env_id, retries)
|
||||
|
||||
@atomic.action_timer("fuel.add_node")
|
||||
def _add_node(self, env_id, node_ids, node_roles=None):
|
||||
"""Add node to environment
|
||||
|
||||
:param env_id environment id
|
||||
:param node_ids list of node ids
|
||||
:param node_roles list of roles
|
||||
"""
|
||||
|
||||
node_roles = node_roles or ["compute"]
|
||||
|
||||
try:
|
||||
self.admin_clients("fuel").environment.client.add_nodes(
|
||||
env_id, node_ids, node_roles)
|
||||
except BaseException as e:
|
||||
raise RuntimeError(
|
||||
"Unable to add node(s) to environment. Fuel client exited "
|
||||
"with error %s" % e)
|
||||
|
||||
@atomic.action_timer("fuel.delete_node")
|
||||
def _remove_node(self, env_id, node_id):
|
||||
|
||||
env = FuelClient.fuelclient_module.objects.environment.Environment(
|
||||
env_id)
|
||||
try:
|
||||
env.unassign([node_id])
|
||||
except BaseException as e:
|
||||
raise RuntimeError(
|
||||
"Unable to add node(s) to environment. Fuel client exited "
|
||||
"with error %s" % e)
|
||||
|
||||
@atomic.action_timer("fuel.list_nodes")
|
||||
def _list_node_ids(self, env_id=None):
|
||||
result = self.admin_clients("fuel").node.get_all(
|
||||
environment_id=env_id)
|
||||
return [x["id"] for x in result]
|
||||
|
||||
def _node_is_assigned(self, node_id):
|
||||
try:
|
||||
node = self.admin_clients("fuel").node.get_by_id(node_id)
|
||||
return bool(node["cluster"])
|
||||
except BaseException as e:
|
||||
raise RuntimeError(
|
||||
"Unable to add node(s) to environment. Fuel client exited "
|
||||
"with error %s" % e)
|
||||
|
||||
def _get_free_node_id(self):
|
||||
node_ids = self._list_node_ids()
|
||||
random.shuffle(node_ids)
|
||||
|
||||
for node_id in node_ids:
|
||||
if not self._node_is_assigned(node_id):
|
||||
return node_id
|
||||
else:
|
||||
raise RuntimeError("Can not found free node.")
|
||||
|
24
samples/tasks/scenarios/fuel/add_and_remove_nodes.json
Normal file
24
samples/tasks/scenarios/fuel/add_and_remove_nodes.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"FuelNodes.add_and_remove_node": [
|
||||
{
|
||||
"args": {
|
||||
"node_roles": ["compute"]
|
||||
},
|
||||
"context": {
|
||||
"fuel_environments": {
|
||||
"environments": 5,
|
||||
"release_id": 1,
|
||||
"network_provider": "neutron",
|
||||
"deployment_mode": "ha_compact",
|
||||
"net_segment_type": "vlan",
|
||||
"resource_management_workers": 2
|
||||
}
|
||||
},
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"times": 200,
|
||||
"concurrency": 10
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
17
samples/tasks/scenarios/fuel/add_and_remove_nodes.yaml
Normal file
17
samples/tasks/scenarios/fuel/add_and_remove_nodes.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
FuelNodes.add_and_remove_node:
|
||||
-
|
||||
args:
|
||||
node_roles: ["compute"]
|
||||
context:
|
||||
fuel_environments:
|
||||
environments: 5
|
||||
release_id: 1
|
||||
network_provider: "neutron"
|
||||
deployment_mode: "ha_compact"
|
||||
net_segment_type: "vlan"
|
||||
resource_management_workers: 2
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 200
|
||||
concurrency: 10
|
@ -602,12 +602,13 @@ class FuelEnvironmentTestCase(test.TestCase):
|
||||
|
||||
@mock.patch("%s.FuelEnvironment._manager" % BASE)
|
||||
def test_is_deleted(self, mock__manager):
|
||||
mock__manager.return_value.get.return_value = []
|
||||
mock__manager.return_value.get.return_value = None
|
||||
fres = resources.FuelEnvironment()
|
||||
fres.id = mock.Mock()
|
||||
self.assertTrue(fres.is_deleted())
|
||||
mock__manager.return_value.get.return_value = ["env"]
|
||||
mock__manager.return_value.get.return_value = "env"
|
||||
self.assertFalse(fres.is_deleted())
|
||||
mock__manager.return_value.get.assert_called_with(fres.id.return_value)
|
||||
|
||||
@mock.patch("%s.FuelEnvironment._manager" % BASE)
|
||||
def test_list(self, mock__manager):
|
||||
|
108
tests/unit/plugins/openstack/context/test_fuel.py
Normal file
108
tests/unit/plugins/openstack/context/test_fuel.py
Normal file
@ -0,0 +1,108 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 mock
|
||||
|
||||
from rally import exceptions
|
||||
from rally.plugins.openstack.context import fuel
|
||||
from tests.unit import test
|
||||
|
||||
BASE = "rally.plugins.openstack.context.fuel"
|
||||
|
||||
|
||||
class FuelEnvGeneratorTestCase(test.TestCase):
|
||||
|
||||
@mock.patch(BASE + ".FuelEnvGenerator._create_envs",
|
||||
return_value=["env1"])
|
||||
@mock.patch(BASE + ".fuel_utils.FuelScenario")
|
||||
def test_setup(self, mock_fuel_scenario, mock__create_envs):
|
||||
context = {}
|
||||
context["config"] = {"fuel_environments": {"environments": 1}}
|
||||
context["task"] = {"uuid": "some_uuid"}
|
||||
context["admin"] = {"endpoint": "some_endpoint"}
|
||||
|
||||
env_ctx = fuel.FuelEnvGenerator(context)
|
||||
env_ctx.setup()
|
||||
self.assertIn("fuel", env_ctx.context)
|
||||
self.assertIn("environments", env_ctx.context["fuel"])
|
||||
|
||||
mock__create_envs.assert_called_once_with()
|
||||
mock_fuel_scenario.assert_called_once_with(context)
|
||||
|
||||
@mock.patch(BASE + ".FuelEnvGenerator._create_envs",
|
||||
return_value=["env1"])
|
||||
@mock.patch(BASE + ".fuel_utils.FuelScenario")
|
||||
def test_setup_error(self, mock_fuel_scenario, mock__create_envs):
|
||||
context = {}
|
||||
context["config"] = {"fuel_environments": {"environments": 5}}
|
||||
context["task"] = {"uuid": "some_uuid"}
|
||||
context["admin"] = {"endpoint": "some_endpoint"}
|
||||
|
||||
env_ctx = fuel.FuelEnvGenerator(context)
|
||||
self.assertRaises(exceptions.ContextSetupFailure, env_ctx.setup)
|
||||
|
||||
def test__create_envs(self):
|
||||
config = {"environments": 4,
|
||||
"release_id": 42,
|
||||
"network_provider": "provider",
|
||||
"deployment_mode": "mode",
|
||||
"net_segment_type": "type",
|
||||
"resource_management_workers": 3}
|
||||
|
||||
context = {"task": {},
|
||||
"config": {"fuel_environments": config}}
|
||||
|
||||
env_ctx = fuel.FuelEnvGenerator(context)
|
||||
env_ctx.fscenario = mock.Mock()
|
||||
env_ctx.fscenario.return_value._create_environment.return_value = "id"
|
||||
self.assertEqual(config["environments"], len(env_ctx._create_envs()))
|
||||
enves = config.pop("environments")
|
||||
config.pop("resource_management_workers")
|
||||
exp_calls = [mock.call(**config) for i in range(enves)]
|
||||
self.assertEqual(
|
||||
exp_calls,
|
||||
env_ctx.fscenario._create_environment.mock_calls)
|
||||
|
||||
def test__delete_envs(self):
|
||||
config = {"release_id": 42,
|
||||
"network_provider": "provider",
|
||||
"deployment_mode": "mode",
|
||||
"net_segment_type": "type",
|
||||
"resource_management_workers": 3}
|
||||
|
||||
context = {"task": {},
|
||||
"config": {"fuel_environments": config},
|
||||
"fuel": {"environments": ["id", "id", "id"]}}
|
||||
|
||||
env_ctx = fuel.FuelEnvGenerator(context)
|
||||
env_ctx.fscenario = mock.Mock()
|
||||
|
||||
env_ctx._delete_envs()
|
||||
self.assertEqual({}, context["fuel"])
|
||||
|
||||
def test_cleanup(self):
|
||||
config = {"release_id": 42,
|
||||
"network_provider": "provider",
|
||||
"deployment_mode": "mode",
|
||||
"net_segment_type": "type",
|
||||
"resource_management_workers": 3}
|
||||
|
||||
context = {"task": {"uuid": "some_id"},
|
||||
"config": {"fuel_environments": config},
|
||||
"fuel": {"environments": ["id", "id", "id"]}}
|
||||
|
||||
env_ctx = fuel.FuelEnvGenerator(context)
|
||||
env_ctx._delete_envs = mock.Mock()
|
||||
env_ctx.cleanup()
|
||||
env_ctx._delete_envs.assert_called_once_with()
|
48
tests/unit/plugins/openstack/scenarios/fuel/test_nodes.py
Normal file
48
tests/unit/plugins/openstack/scenarios/fuel/test_nodes.py
Normal file
@ -0,0 +1,48 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 mock
|
||||
|
||||
from rally.plugins.openstack.scenarios.fuel import nodes
|
||||
from tests.unit import test
|
||||
|
||||
|
||||
class FuelNodesTestCase(test.TestCase):
|
||||
|
||||
context = {"fuel": {"environments": ["1"]}}
|
||||
|
||||
def test_add_and_remove_node(self):
|
||||
scenario = nodes.FuelNodes(self.context)
|
||||
scenario._list_node_ids = mock.Mock(return_value=["1"])
|
||||
scenario._node_is_assigned = mock.Mock(return_value=False)
|
||||
scenario._add_node = mock.Mock()
|
||||
scenario._remove_node = mock.Mock()
|
||||
|
||||
scenario.add_and_remove_node(node_roles="some_role")
|
||||
|
||||
scenario._list_node_ids.assert_called_once_with()
|
||||
scenario._node_is_assigned.assert_called_once_with("1")
|
||||
scenario._add_node.assert_called_once_with("1", ["1"], "some_role")
|
||||
scenario._remove_node.assert_called_once_with("1", "1")
|
||||
|
||||
def test_add_and_remove_nodes_error(self):
|
||||
scenario = nodes.FuelNodes(self.context)
|
||||
scenario._list_node_ids = mock.Mock(return_value=["1"])
|
||||
scenario._node_is_assigned = mock.Mock(return_value=True)
|
||||
scenario._add_node = mock.Mock()
|
||||
scenario._remove_node = mock.Mock()
|
||||
|
||||
self.assertRaises(RuntimeError,
|
||||
scenario.add_and_remove_node,
|
||||
node_roles="some_role")
|
@ -190,7 +190,78 @@ class FuelScenarioTestCase(test.ScenarioTestCase):
|
||||
|
||||
def test__delete_environment(self):
|
||||
fuel_scenario = utils.FuelScenario()
|
||||
|
||||
fuel_scenario.admin_clients = self.admin_clients
|
||||
fuel_scenario._delete_environment(42, 33)
|
||||
tmp_mock = fuel_scenario.admin_clients("fuel")
|
||||
tmp_mock.environment.delete.assert_called_once_with(42, 33)
|
||||
|
||||
def test__add_nodes(self):
|
||||
fscen = utils.FuelScenario()
|
||||
fscen.admin_clients = mock.Mock()
|
||||
fscen._add_node("1", ["42"], node_roles=["some_role"])
|
||||
tmp_mock = fscen.admin_clients.return_value.environment.client
|
||||
tmp_mock.add_nodes.assert_called_once_with("1", ["42"], ["some_role"])
|
||||
|
||||
def test__add_nodes_error(self):
|
||||
fscen = utils.FuelScenario()
|
||||
fscen.admin_clients = mock.Mock()
|
||||
tmp_mock = fscen.admin_clients.return_value.environment.client
|
||||
tmp_mock.add_nodes.side_effect = BaseException
|
||||
self.assertRaises(RuntimeError, fscen._add_node, "1", "42",
|
||||
node_roles="some_role")
|
||||
|
||||
@mock.patch(UTILS + "FuelClient")
|
||||
def test__remove_nodes(self, mock_fuel_client):
|
||||
mock_tmp = mock_fuel_client.fuelclient_module.objects
|
||||
mock_env = mock_tmp.environment.Environment
|
||||
mock_env.return_value = mock.Mock()
|
||||
fscen = utils.FuelScenario()
|
||||
fscen._remove_node("1", "2")
|
||||
mock_env.assert_called_once_with("1")
|
||||
mock_env.return_value.unassign.assert_called_once_with(["2"])
|
||||
|
||||
@mock.patch(UTILS + "FuelClient")
|
||||
def test__remove_nodes_error(self, mock_fuel_client):
|
||||
mock_tmp = mock_fuel_client.fuelclient_module.objects
|
||||
mock_env = mock_tmp.environment.Environment
|
||||
mock_env.return_value = mock.Mock()
|
||||
mock_env.return_value.unassign.side_effect = BaseException
|
||||
fscen = utils.FuelScenario()
|
||||
self.assertRaises(RuntimeError, fscen._remove_node, "1", "2")
|
||||
|
||||
def test__list_node_ids(self):
|
||||
fscen = utils.FuelScenario()
|
||||
fscen.admin_clients = mock.Mock()
|
||||
fscen.admin_clients.return_value.node.get_all.return_value = [
|
||||
{"id": "id1"}, {"id": "id2"}]
|
||||
res = fscen._list_node_ids("env")
|
||||
self.assertEqual(["id1", "id2"], res)
|
||||
tmp_mock = fscen.admin_clients.return_value.node.get_all
|
||||
tmp_mock.assert_called_once_with(environment_id="env")
|
||||
|
||||
def test__node_is_assigned(self):
|
||||
fscen = utils.FuelScenario()
|
||||
fscen.admin_clients = mock.Mock()
|
||||
fscen.admin_clients.return_value.node.get_by_id.return_value = {
|
||||
"id": "id1", "cluster": "some_id"}
|
||||
self.assertTrue(fscen._node_is_assigned("id1"))
|
||||
fscen.admin_clients.return_value.node.get_by_id.return_value[
|
||||
"cluster"] = ""
|
||||
self.assertFalse(fscen._node_is_assigned("id2"))
|
||||
|
||||
@mock.patch(UTILS + "FuelScenario._node_is_assigned", return_value=False)
|
||||
@mock.patch(UTILS + "FuelScenario._list_node_ids",
|
||||
return_value=["id1", "id2"])
|
||||
def test__get_free_node_id(self, mock__list_node_ids,
|
||||
mock__node_is_assigned):
|
||||
node_id = utils.FuelScenario()._get_free_node_id()
|
||||
self.assertIn(node_id, mock__list_node_ids.return_value)
|
||||
|
||||
@mock.patch(UTILS + "FuelScenario._node_is_assigned", return_value=True)
|
||||
@mock.patch(UTILS + "FuelScenario._list_node_ids",
|
||||
return_value=["id1", "id2"])
|
||||
def test__get_free_node_id_exception(self, mock__list_node_ids,
|
||||
mock__node_is_assigned):
|
||||
self.assertRaises(RuntimeError,
|
||||
utils.FuelScenario()._get_free_node_id)
|
||||
|
Loading…
x
Reference in New Issue
Block a user