fuel-web/nailgun/nailgun/test/integration/test_orchestrator_handlers.py

254 lines
9.2 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import nailgun
from nailgun import objects
from mock import patch
from nailgun.db.sqlalchemy.models import Cluster
from nailgun.openstack.common import jsonutils
from nailgun.test.base import BaseIntegrationTest
from nailgun.test.base import fake_tasks
from nailgun.test.base import reverse
def nodes_filter_param(node_ids):
return '?nodes={0}'.format(','.join(node_ids))
class TestOrchestratorInfoHandlers(BaseIntegrationTest):
def setUp(self):
super(TestOrchestratorInfoHandlers, self).setUp()
self.cluster = self.env.create_cluster(api=False)
def check_info_handler(
self, handler_name, get_info, orchestrator_data, default=[]):
# updating provisioning info
put_resp = self.app.put(
reverse(handler_name,
kwargs={'cluster_id': self.cluster.id}),
jsonutils.dumps(orchestrator_data),
headers=self.default_headers)
self.assertEqual(put_resp.status_code, 200)
self.assertEqual(get_info(), orchestrator_data)
# getting provisioning info
get_resp = self.app.get(
reverse(handler_name,
kwargs={'cluster_id': self.cluster.id}),
headers=self.default_headers)
self.assertEqual(get_resp.status_code, 200)
self.datadiff(orchestrator_data, get_resp.json_body)
# deleting provisioning info
delete_resp = self.app.delete(
reverse(handler_name,
kwargs={'cluster_id': self.cluster.id}),
headers=self.default_headers)
self.assertEqual(delete_resp.status_code, 202)
self.assertEqual(get_info(), default)
def test_cluster_provisioning_info(self):
orchestrator_data = {'engine': {}, 'nodes': []}
for node in self.env.nodes:
orchestrator_data['nodes'].append(
{"field": "test", "uid": node.uid})
self.check_info_handler(
'ProvisioningInfo',
lambda: objects.Cluster.get_provisioning_info(self.cluster),
orchestrator_data,
default={})
def test_cluster_deployment_info(self):
orchestrator_data = []
for node in self.env.nodes:
orchestrator_data.append({"field": "test", "uid": node.uid})
self.check_info_handler(
'DeploymentInfo',
lambda: objects.Cluster.get_deployment_info(self.cluster),
orchestrator_data)
class TestDefaultOrchestratorInfoHandlers(BaseIntegrationTest):
def setUp(self):
super(TestDefaultOrchestratorInfoHandlers, self).setUp()
cluster = self.env.create(
nodes_kwargs=[
{'roles': ['controller'], 'pending_addition': True},
{'roles': ['compute'], 'pending_addition': True},
{'roles': ['cinder'], 'pending_addition': True}])
self.cluster = self.db.query(Cluster).get(cluster['id'])
def customization_handler_helper(self, handler_name, get_info, facts):
resp = self.app.put(
reverse(handler_name,
kwargs={'cluster_id': self.cluster.id}),
jsonutils.dumps(facts),
headers=self.default_headers)
self.assertEqual(resp.status_code, 200)
self.assertTrue(self.cluster.is_customized)
self.datadiff(get_info(), facts)
def test_default_deployment_handler(self):
resp = self.app.get(
reverse('DefaultDeploymentInfo',
kwargs={'cluster_id': self.cluster.id}),
headers=self.default_headers)
self.assertEqual(resp.status_code, 200)
self.assertEqual(3, len(resp.json_body))
def test_default_provisioning_handler(self):
resp = self.app.get(
reverse('DefaultProvisioningInfo',
kwargs={'cluster_id': self.cluster.id}),
headers=self.default_headers)
self.assertEqual(resp.status_code, 200)
self.assertEqual(3, len(resp.json_body['nodes']))
def test_default_provisioning_handler_for_selected_nodes(self):
node_ids = [node.uid for node in self.cluster.nodes][:2]
url = reverse(
'DefaultProvisioningInfo',
kwargs={'cluster_id': self.cluster.id}) + \
nodes_filter_param(node_ids)
resp = self.app.get(url, headers=self.default_headers)
self.assertEqual(resp.status_code, 200)
data = resp.json_body['nodes']
self.assertEqual(2, len(data))
actual_uids = [node['uid'] for node in data]
self.assertItemsEqual(actual_uids, node_ids)
def test_default_deployment_handler_for_selected_nodes(self):
node_ids = [node.uid for node in self.cluster.nodes][:2]
url = reverse(
'DefaultDeploymentInfo',
kwargs={'cluster_id': self.cluster.id}) + \
nodes_filter_param(node_ids)
resp = self.app.get(url, headers=self.default_headers)
self.assertEqual(resp.status_code, 200)
self.assertEqual(2, len(resp.json_body))
actual_uids = [node['uid'] for node in resp.json_body]
self.assertItemsEqual(actual_uids, node_ids)
def test_cluster_provisioning_customization(self):
facts = {'engine': {'1': '2'}}
nodes = []
for node in self.env.nodes:
nodes.append({"key": "value", "uid": node.uid})
facts['nodes'] = nodes
self.customization_handler_helper(
'ProvisioningInfo',
lambda: objects.Cluster.get_provisioning_info(self.cluster),
facts
)
def test_cluster_deployment_customization(self):
facts = []
for node in self.env.nodes:
facts.append({"key": "value", "uid": node.uid})
self.customization_handler_helper(
'DeploymentInfo',
lambda: objects.Cluster.get_deployment_info(self.cluster),
facts
)
def test_deployment_with_one_compute_node(self):
cluster = self.env.create(
nodes_kwargs=[
{'roles': ['compute']}
]
)
response = self.app.get(
reverse('DefaultDeploymentInfo',
kwargs={'cluster_id': cluster['id']}),
headers=self.default_headers
)
self.assertEqual(response.status_code, 200)
class TestSelectedNodesAction(BaseIntegrationTest):
def setUp(self):
super(TestSelectedNodesAction, self).setUp()
self.env.create(
nodes_kwargs=[
{'roles': ['controller'], 'pending_addition': True},
{'roles': ['controller'], 'pending_addition': True},
{'roles': ['controller'], 'pending_addition': True},
{'roles': ['cinder'], 'pending_addition': True},
{'roles': ['compute'], 'pending_addition': True},
{'roles': ['mongo'], 'pending_addition': True},
{'roles': ['mongo'], 'pending_addition': True},
{'roles': ['cinder'], 'pending_addition': True}])
self.cluster = self.env.clusters[0]
self.node_uids = [n.uid for n in self.cluster.nodes][:3]
def send_empty_put(self, url):
return self.app.put(
url, '', headers=self.default_headers, expect_errors=True)
@fake_tasks(fake_rpc=False, mock_rpc=False)
@patch('nailgun.rpc.cast')
def test_start_provisioning_on_selected_nodes(self, mock_rpc):
action_url = reverse(
'ProvisionSelectedNodes',
kwargs={'cluster_id': self.cluster.id}) + \
nodes_filter_param(self.node_uids)
self.send_empty_put(action_url)
args, kwargs = nailgun.task.manager.rpc.cast.call_args
provisioned_uids = [
n['uid'] for n in args[1]['args']['provisioning_info']['nodes']]
self.assertEqual(3, len(provisioned_uids))
self.assertItemsEqual(self.node_uids, provisioned_uids)
@fake_tasks(fake_rpc=False, mock_rpc=False)
@patch('nailgun.rpc.cast')
def test_start_deployment_on_selected_nodes(self, mock_rpc):
# if cluster is ha, then DeploySelectedNodes must call
# TaskHelper.nodes_to_deploy_ha(cluster, nodes) and it must
# append third controller to the list of nodes which are to deploy
node_uids = [n.uid for n in self.cluster.nodes][2:3]
action_url = reverse(
'DeploySelectedNodes',
kwargs={'cluster_id': self.cluster.id}) + \
nodes_filter_param(node_uids)
self.send_empty_put(action_url)
args, kwargs = nailgun.task.manager.rpc.cast.call_args
deployed_uids = [n['uid'] for n in args[1]['args']['deployment_info']]
self.assertEqual(3, len(deployed_uids))
self.assertItemsEqual(self.node_uids, deployed_uids)