Migrate to Conductor
Co-Authored-By: Dmitry Mescheryakov <dmescheryakov@mirantis.com> Co-Authored-By: Sergey Lukjanov <slukjanov@mirantis.com> Change-Id: If12fd3a4e4dea876be081202f2b426e94c291d9b
This commit is contained in:
committed by
Dmitry Mescheryakov
parent
c801ad317c
commit
bb1221cd3e
@@ -15,42 +15,56 @@
|
||||
|
||||
import mock
|
||||
|
||||
from savanna import context as ctx
|
||||
import savanna.db.models as m
|
||||
from savanna import conductor as cond
|
||||
from savanna.conductor import resource as r
|
||||
from savanna import context
|
||||
from savanna.service import instances
|
||||
from savanna.tests.unit import base as models_test_base
|
||||
import savanna.utils.crypto as c
|
||||
|
||||
|
||||
conductor = cond.API
|
||||
|
||||
|
||||
def _resource_passthrough(*args, **kwargs):
|
||||
return True
|
||||
|
||||
|
||||
class TestClusterRollBack(models_test_base.DbTestCase):
|
||||
def setUp(self):
|
||||
r.Resource._is_passthrough_type = _resource_passthrough
|
||||
super(TestClusterRollBack, self).setUp()
|
||||
|
||||
@mock.patch('savanna.utils.openstack.nova.client')
|
||||
def test_cluster_creation_with_errors(self, novaclient):
|
||||
node_groups = [m.NodeGroup("test_group", "test_flavor",
|
||||
["data node", "test tracker"], 2)]
|
||||
node_groups[0]._username = "root"
|
||||
node_groups = [_make_ng_dict('test_group', 'test_flavor',
|
||||
['data node', 'task tracker'], 2)]
|
||||
|
||||
cluster = _create_cluster_mock(node_groups, [])
|
||||
|
||||
nova = _create_nova_mock(novaclient)
|
||||
nova.servers.create.side_effect = [_mock_instance(1),
|
||||
Exception("test")]
|
||||
MockException("test")]
|
||||
|
||||
nova.servers.list = mock.MagicMock(return_value=[_mock_instance(1)])
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
with self.assertRaises(MockException):
|
||||
instances.create_cluster(cluster)
|
||||
|
||||
session = ctx.ctx().session
|
||||
with session.begin():
|
||||
self.assertEqual(session.query(m.Instance).count(), 0)
|
||||
ctx = context.ctx()
|
||||
cluster_obj = conductor.cluster_get_all(ctx)[0]
|
||||
self.assertEqual(len(cluster_obj.node_groups[0].instances), 0)
|
||||
|
||||
|
||||
class NodePlacementTest(models_test_base.DbTestCase):
|
||||
def setUp(self):
|
||||
r.Resource._is_passthrough_type = _resource_passthrough
|
||||
super(NodePlacementTest, self).setUp()
|
||||
|
||||
@mock.patch('savanna.utils.openstack.nova.client')
|
||||
def test_one_node_groups_and_one_affinity_group(self, novaclient):
|
||||
node_groups = [m.NodeGroup("test_group", "test_flavor",
|
||||
["data node", "test tracker"], 2)]
|
||||
node_groups[0]._username = "root"
|
||||
node_groups = [_make_ng_dict('test_group', 'test_flavor',
|
||||
['data node'], 2)]
|
||||
cluster = _create_cluster_mock(node_groups, ["data node"])
|
||||
nova = _create_nova_mock(novaclient)
|
||||
instances._create_instances(cluster)
|
||||
@@ -71,15 +85,15 @@ class NodePlacementTest(models_test_base.DbTestCase):
|
||||
key_name='user_keypair')],
|
||||
any_order=False)
|
||||
|
||||
session = ctx.ctx().session
|
||||
with session.begin():
|
||||
self.assertEqual(session.query(m.Instance).count(), 2)
|
||||
ctx = context.ctx()
|
||||
cluster_obj = conductor.cluster_get_all(ctx)[0]
|
||||
self.assertEqual(len(cluster_obj.node_groups[0].instances), 2)
|
||||
|
||||
@mock.patch('savanna.utils.openstack.nova.client')
|
||||
def test_one_node_groups_and_no_affinity_group(self, novaclient):
|
||||
node_groups = [m.NodeGroup("test_group", "test_flavor",
|
||||
["data node", "test tracker"], 2)]
|
||||
node_groups[0]._username = "root"
|
||||
node_groups = [_make_ng_dict('test_group', 'test_flavor',
|
||||
['data node', 'task tracker'], 2)]
|
||||
|
||||
cluster = _create_cluster_mock(node_groups, [])
|
||||
nova = _create_nova_mock(novaclient)
|
||||
instances._create_instances(cluster)
|
||||
@@ -100,18 +114,17 @@ class NodePlacementTest(models_test_base.DbTestCase):
|
||||
key_name='user_keypair')],
|
||||
any_order=False)
|
||||
|
||||
session = ctx.ctx().session
|
||||
with session.begin():
|
||||
self.assertEqual(session.query(m.Instance).count(), 2)
|
||||
ctx = context.ctx()
|
||||
cluster_obj = conductor.cluster_get_all(ctx)[0]
|
||||
self.assertEqual(len(cluster_obj.node_groups[0].instances), 2)
|
||||
|
||||
@mock.patch('savanna.utils.openstack.nova.client')
|
||||
def test_two_node_groups_and_one_affinity_group(self, novaclient):
|
||||
node_groups = [m.NodeGroup("test_group_1", "test_flavor",
|
||||
["data node", "test tracker"], 2),
|
||||
m.NodeGroup("test_group_2", "test_flavor",
|
||||
["data node", "test tracker"], 1)]
|
||||
node_groups[0]._username = "root"
|
||||
node_groups[1]._username = "root"
|
||||
node_groups = [_make_ng_dict("test_group_1", "test_flavor",
|
||||
["data node", "test tracker"], 2),
|
||||
_make_ng_dict("test_group_2", "test_flavor",
|
||||
["data node", "test tracker"], 1)]
|
||||
|
||||
cluster = _create_cluster_mock(node_groups, ["data node"])
|
||||
nova = _create_nova_mock(novaclient)
|
||||
instances._create_instances(cluster)
|
||||
@@ -138,20 +151,35 @@ class NodePlacementTest(models_test_base.DbTestCase):
|
||||
key_name='user_keypair')],
|
||||
any_order=False)
|
||||
|
||||
session = ctx.ctx().session
|
||||
with session.begin():
|
||||
self.assertEqual(session.query(m.Instance).count(), 3)
|
||||
ctx = context.ctx()
|
||||
cluster_obj = conductor.cluster_get_all(ctx)[0]
|
||||
inst_number = len(cluster_obj.node_groups[0].instances)
|
||||
inst_number += len(cluster_obj.node_groups[1].instances)
|
||||
self.assertEqual(inst_number, 3)
|
||||
|
||||
|
||||
def _make_ng_dict(name, flavor, processes, count):
|
||||
return {'name': name, 'flavor_id': flavor, 'node_processes': processes,
|
||||
'count': count}
|
||||
|
||||
|
||||
def _create_cluster_mock(node_groups, aa):
|
||||
cluster = m.Cluster("test_cluster", "tenant_id", "mock_plugin",
|
||||
"mock_version", "initial",
|
||||
user_keypair_id='user_keypair', anti_affinity=aa)
|
||||
|
||||
cluster._user_kp = mock.Mock()
|
||||
cluster._user_kp.public_key = "123"
|
||||
cluster.private_key = c.generate_private_key()
|
||||
cluster.node_groups = node_groups
|
||||
user_kp = mock.Mock()
|
||||
user_kp.public_key = "123"
|
||||
private_key = c.generate_private_key()
|
||||
|
||||
dct = {'name': 'test_cluster',
|
||||
'plugin_name': 'mock_plugin',
|
||||
'hadoop_version': 'mock_version',
|
||||
'default_image_id': 'initial',
|
||||
'user_keypair_id': 'user_keypair',
|
||||
'anti_affinity': aa,
|
||||
'_user_kp': user_kp,
|
||||
'private_key': private_key,
|
||||
'node_groups': node_groups}
|
||||
|
||||
cluster = conductor.cluster_create(context.ctx(), dct)
|
||||
|
||||
return cluster
|
||||
|
||||
@@ -187,3 +215,7 @@ def _create_nova_mock(novalcient):
|
||||
images.username = "root"
|
||||
nova.images.get = lambda x: images
|
||||
return nova
|
||||
|
||||
|
||||
class MockException(Exception):
|
||||
pass
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
import mock
|
||||
|
||||
from cinderclient.v1 import volumes as v
|
||||
from savanna.db import models as m
|
||||
|
||||
from savanna.conductor import resource as r
|
||||
from savanna.service import volumes
|
||||
from savanna.tests.unit import base as models_test_base
|
||||
|
||||
@@ -25,7 +26,7 @@ class TestAttachVolume(models_test_base.DbTestCase):
|
||||
@mock.patch(
|
||||
'savanna.utils.remote.BulkInstanceInteropHelper.execute_command')
|
||||
def test_mount_volume(self, p_ex_cmd):
|
||||
instance = m.Instance(None, None, None)
|
||||
instance = r.InstanceResource({'instance_id': '123454321'})
|
||||
|
||||
p_ex_cmd.return_value = (0, None)
|
||||
self.assertIsNone(volumes._mount_volume(instance, '123', '456'))
|
||||
@@ -41,25 +42,24 @@ class TestAttachVolume(models_test_base.DbTestCase):
|
||||
@mock.patch('cinderclient.v1.volumes.Volume.detach')
|
||||
@mock.patch('savanna.utils.openstack.cinder.get_volume')
|
||||
def test_detach_volumes(self, p_get_volume, p_detach, p_delete):
|
||||
instance = m.Instance(None, None, None)
|
||||
instance.volumes.append("123")
|
||||
instance = {'instance_id': '123454321',
|
||||
'volumes': [123]}
|
||||
|
||||
ng = r.NodeGroupResource({'instances': [instance]})
|
||||
|
||||
p_get_volume.return_value = v.Volume(None, {'id': '123'})
|
||||
p_detach.return_value = None
|
||||
p_delete.return_value = None
|
||||
self.assertIsNone(
|
||||
volumes.detach_from_instances([instance]))
|
||||
volumes.detach_from_instances([ng.instances[0]]))
|
||||
|
||||
ng = m.NodeGroup(None, None, None, None)
|
||||
ng.instances.append(instance)
|
||||
cluster = m.Cluster(None, None, None, None)
|
||||
cluster.node_groups.append(ng)
|
||||
cluster = r.ClusterResource({'node_groups': [ng]})
|
||||
p_delete.side_effect = RuntimeError
|
||||
self.assertRaises(RuntimeError, volumes.detach, cluster)
|
||||
|
||||
@mock.patch('savanna.utils.remote.InstanceInteropHelper.execute_command')
|
||||
def test_get_free_device_path(self, p_ex_cmd):
|
||||
instance = m.Instance(None, None, None)
|
||||
instance = r.InstanceResource({'instance_id': '123454321'})
|
||||
|
||||
p_ex_cmd.return_value = (1, None)
|
||||
self.assertRaises(RuntimeError, volumes._get_free_device_path,
|
||||
@@ -92,16 +92,18 @@ class TestAttachVolume(models_test_base.DbTestCase):
|
||||
p_create_attach_vol.return_value = None
|
||||
p_await.return_value = None
|
||||
p_mount.return_value = None
|
||||
ng = m.NodeGroup(None, None, None, None, volumes_per_node=2,
|
||||
volumes_size=2)
|
||||
instance1 = m.Instance(None, None, '123')
|
||||
instance2 = m.Instance(None, None, '456')
|
||||
instance1.node_group_id = ng.id
|
||||
instance2.node_group_id = ng.id
|
||||
ng.instances.append(instance1)
|
||||
ng.instances.append(instance2)
|
||||
cluster = m.Cluster(None, None, None, None)
|
||||
cluster.node_groups.append(ng)
|
||||
|
||||
instance1 = {'instance_id': '123',
|
||||
'instance_name': 'inst_1'}
|
||||
instance2 = {'instance_id': '456',
|
||||
'instance_name': 'inst_2'}
|
||||
|
||||
ng = {'volumes_per_node': 2,
|
||||
'volumes_size': 2,
|
||||
'volume_mount_prefix': '/mnt/vols',
|
||||
'instances': [instance1, instance2]}
|
||||
|
||||
cluster = r.ClusterResource({'node_groups': [ng]})
|
||||
|
||||
volumes.attach(cluster)
|
||||
self.assertEqual(p_create_attach_vol.call_count, 4)
|
||||
@@ -114,7 +116,7 @@ class TestAttachVolume(models_test_base.DbTestCase):
|
||||
p_mount.reset_mock()
|
||||
p_dev_path.reset_mock()
|
||||
|
||||
instances = [instance1, instance2]
|
||||
instances = cluster.node_groups[0].instances
|
||||
volumes.attach_to_instances(instances)
|
||||
|
||||
self.assertEqual(p_create_attach_vol.call_count, 4)
|
||||
@@ -127,7 +129,8 @@ class TestAttachVolume(models_test_base.DbTestCase):
|
||||
def test_await_attach_volume(self, dev_paths, p_sleep):
|
||||
dev_paths.return_value = ['/dev/vda', '/dev/vdb']
|
||||
p_sleep.return_value = None
|
||||
instance = m.Instance(None, None, None)
|
||||
instance = r.InstanceResource({'instance_id': '123454321',
|
||||
'instance_name': 'instt'})
|
||||
self.assertIsNone(volumes._await_attach_volume(instance, '/dev/vdb'))
|
||||
self.assertRaises(RuntimeError, volumes._await_attach_volume,
|
||||
instance, '/dev/vdc')
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
import mock
|
||||
import unittest2
|
||||
|
||||
import savanna.db.models as m
|
||||
#import savanna.db.models as m
|
||||
from savanna import exceptions as ex
|
||||
from savanna.plugins.vanilla import plugin
|
||||
from savanna.service import api
|
||||
import savanna.service.validation as v
|
||||
from savanna.service.validations import clusters_scaling as c_s
|
||||
from savanna.tests.unit.plugins.vanilla import test_utils as tu
|
||||
from savanna.tests.unit.service.validation import utils as u
|
||||
|
||||
|
||||
@@ -55,17 +56,19 @@ class TestScalingValidation(unittest2.TestCase):
|
||||
raise e
|
||||
|
||||
def test_check_cluster_scaling_resize_ng(self):
|
||||
cluster = m.Cluster('test-cluster', 'tenant', 'vanilla', '1.2.2')
|
||||
cluster.status = 'Validating'
|
||||
ng = m.NodeGroup('ng', '42', ['namenode'], 1)
|
||||
cluster.node_groups.append(ng)
|
||||
ng1 = tu._make_ng_dict('ng', '42', ['namenode'], 1)
|
||||
cluster = tu._create_cluster("cluster1", "tenant1", "vanilla", "1.1.2",
|
||||
[ng1], status='Validating', id='12321')
|
||||
|
||||
self._assert_check_scaling(data={}, cluster=cluster,
|
||||
expected_message=
|
||||
"Cluster cannot be scaled "
|
||||
"not in 'Active' "
|
||||
"status. Cluster status: "
|
||||
"Validating")
|
||||
cluster.status = 'Active'
|
||||
|
||||
cluster = tu._create_cluster("cluster1", "tenant1", "vanilla", "1.1.2",
|
||||
[ng1], status='Active', id='12321')
|
||||
data = {
|
||||
'resize_node_groups': [
|
||||
{
|
||||
@@ -97,10 +100,10 @@ class TestScalingValidation(unittest2.TestCase):
|
||||
'group names are detected')
|
||||
|
||||
def test_check_cluster_scaling_add_ng(self):
|
||||
cluster = m.Cluster('test-cluster', 'tenant', 'vanilla', '1.2.2')
|
||||
ng = m.NodeGroup('ng', '42', ['namenode'], 1)
|
||||
cluster.node_groups.append(ng)
|
||||
cluster.status = 'Active'
|
||||
ng1 = tu._make_ng_dict('ng', '42', ['namenode'], 1)
|
||||
cluster = tu._create_cluster("test-cluster", "tenant", "vanilla",
|
||||
"1.2.2", [ng1], status='Active',
|
||||
id='12321')
|
||||
data = {
|
||||
'add_node_groups': [
|
||||
{
|
||||
@@ -296,10 +299,6 @@ class TestScalingValidation(unittest2.TestCase):
|
||||
|
||||
def test_cluster_scaling_v_right_data(self):
|
||||
self._create_object_fun = c_s.check_cluster_scaling
|
||||
cluster = m.Cluster('test-cluster', 'tenant', 'vanilla', '1.2.2')
|
||||
ng = m.NodeGroup('ng', '42', ['namenode'], 1)
|
||||
cluster.node_groups.append(ng)
|
||||
cluster.status = 'Active'
|
||||
|
||||
data = {
|
||||
'resize_node_groups': [
|
||||
|
||||
@@ -17,9 +17,13 @@ import mock
|
||||
import novaclient.exceptions as nova_ex
|
||||
import unittest2
|
||||
|
||||
import savanna.db.models as m
|
||||
#import savanna.db.models as m
|
||||
from savanna.conductor import resource as r
|
||||
from savanna.plugins.vanilla import plugin
|
||||
import savanna.service.validation as v
|
||||
from savanna.tests.unit.plugins.vanilla import test_utils as tu
|
||||
|
||||
m = {}
|
||||
|
||||
_types_checks = {
|
||||
"string": [1, (), {}],
|
||||
@@ -131,28 +135,34 @@ def start_patch():
|
||||
get_image.side_effect = _get_image
|
||||
nova().images.list_registered.return_value = [Image(),
|
||||
Image(name='wrong_name')]
|
||||
cluster = m.Cluster('test', 't', 'vanilla', '1.2.2')
|
||||
cluster.id = 1
|
||||
cluster.status = 'Active'
|
||||
cluster.node_groups = [m.NodeGroup('ng', '42', ['namenode'], 1)]
|
||||
ng_dict = tu._make_ng_dict('ng', '42', ['namenode'], 1)
|
||||
cluster = tu._create_cluster('test', 't', 'vanilla', '1.2.2', [ng_dict],
|
||||
id=1, status='Active')
|
||||
# stub clusters list
|
||||
get_clusters.return_value = [cluster]
|
||||
get_cluster.return_value = cluster
|
||||
# stub node templates
|
||||
get_ng_templates.return_value = [m.NodeGroupTemplate('test', 't', '42',
|
||||
'vanilla', '1.2.2',
|
||||
['namenode'])]
|
||||
|
||||
get_cl_templates.return_value = [m.ClusterTemplate('test', 't',
|
||||
'vanilla', '1.2.2')]
|
||||
# stub node templates
|
||||
ngt_dict = {'name': 'test', 'tenant_id': 't', 'flavor_id': '42',
|
||||
'plugin_name': 'vanilla', 'hadoop_version': '1.2.2',
|
||||
#'id': '1234321',
|
||||
'id': '550e8400-e29b-41d4-a716-446655440000',
|
||||
'node_processes': ['namenode']}
|
||||
|
||||
get_ng_templates.return_value = [r.NodeGroupTemplateResource(ngt_dict)]
|
||||
|
||||
ct_dict = {'name': 'test', 'tenant_id': 't',
|
||||
'plugin_name': 'vanilla', 'hadoop_version': '1.2.2'}
|
||||
|
||||
get_cl_templates.return_value = [r.ClusterTemplateResource(ct_dict)]
|
||||
|
||||
vanilla = plugin.VanillaProvider()
|
||||
vanilla.name = 'vanilla'
|
||||
get_plugins.return_value = [vanilla]
|
||||
|
||||
def _get_ng_template(name):
|
||||
def _get_ng_template(id):
|
||||
for template in get_ng_templates():
|
||||
if template.name == name:
|
||||
if template.id == id:
|
||||
return template
|
||||
return None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user