181 lines
7.7 KiB
Python
181 lines
7.7 KiB
Python
# Copyright (c) 2017 Ericsson AB
|
|
# 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.
|
|
#
|
|
# Copyright (c) 2017 Wind River Systems, Inc.
|
|
#
|
|
# The right to copy, distribute, modify, or otherwise make use
|
|
# of this software may be licensed only pursuant to the terms
|
|
# of an applicable Wind River license agreement.
|
|
#
|
|
|
|
import copy
|
|
import mock
|
|
import six
|
|
import webtest
|
|
|
|
from dcmanager.api.controllers.v1 import sw_update_strategy
|
|
from dcmanager.common import consts
|
|
from dcmanager.rpc import client as rpc_client
|
|
from dcmanager.tests.unit.api import test_root_controller as testroot
|
|
from dcmanager.tests import utils
|
|
|
|
FAKE_TENANT = utils.UUID1
|
|
FAKE_ID = '1'
|
|
FAKE_URL = '/v1.0/sw-update-strategy'
|
|
FAKE_HEADERS = {'X-Tenant-Id': FAKE_TENANT, 'X_ROLE': 'admin',
|
|
'X-Identity-Status': 'Confirmed'}
|
|
|
|
FAKE_SW_UPDATE_DATA = {
|
|
"type": consts.SW_UPDATE_TYPE_PATCH,
|
|
"subcloud-apply-type": consts.SUBCLOUD_APPLY_TYPE_PARALLEL,
|
|
"max-parallel-subclouds": "10",
|
|
"stop-on-failure": "true"
|
|
}
|
|
|
|
FAKE_SW_UPDATE_APPLY_DATA = {
|
|
"action": consts.SW_UPDATE_ACTION_APPLY
|
|
}
|
|
|
|
FAKE_SW_UPDATE_ABORT_DATA = {
|
|
"action": consts.SW_UPDATE_ACTION_ABORT
|
|
}
|
|
|
|
|
|
class TestSwUpdateStrategy(testroot.DCManagerApiTest):
|
|
def setUp(self):
|
|
super(TestSwUpdateStrategy, self).setUp()
|
|
self.ctx = utils.dummy_context()
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_post_sw_update(self, mock_db_api, mock_rpc_client):
|
|
data = FAKE_SW_UPDATE_DATA
|
|
mock_rpc_client().create_sw_update_strategy.return_value = True
|
|
response = self.app.post_json(FAKE_URL,
|
|
headers=FAKE_HEADERS,
|
|
params=data)
|
|
mock_rpc_client().create_sw_update_strategy.assert_called_once_with(
|
|
mock.ANY,
|
|
data)
|
|
self.assertEqual(response.status_int, 200)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_post_sw_update_bad_type(self, mock_db_api, mock_rpc_client):
|
|
data = copy.copy(FAKE_SW_UPDATE_DATA)
|
|
data["type"] = "bad type"
|
|
six.assertRaisesRegex(self, webtest.app.AppError, "400 *",
|
|
self.app.post_json, FAKE_URL,
|
|
headers=FAKE_HEADERS, params=data)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_post_sw_update_bad_apply_type(self, mock_db_api, mock_rpc_client):
|
|
data = copy.copy(FAKE_SW_UPDATE_DATA)
|
|
data["subcloud-apply-type"] = "bad type"
|
|
six.assertRaisesRegex(self, webtest.app.AppError, "400 *",
|
|
self.app.post_json, FAKE_URL,
|
|
headers=FAKE_HEADERS, params=data)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_post_sw_update_bad_max_parallel(
|
|
self, mock_db_api, mock_rpc_client):
|
|
data = copy.copy(FAKE_SW_UPDATE_DATA)
|
|
data["max-parallel-subclouds"] = "not an integer"
|
|
six.assertRaisesRegex(self, webtest.app.AppError, "400 *",
|
|
self.app.post_json, FAKE_URL,
|
|
headers=FAKE_HEADERS, params=data)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
def test_post_no_body(self, mock_rpc_client):
|
|
data = {}
|
|
six.assertRaisesRegex(self, webtest.app.AppError, "400 *",
|
|
self.app.post_json, FAKE_URL,
|
|
headers=FAKE_HEADERS, params=data)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
def test_post_no_type(self, mock_rpc_client):
|
|
data = copy.copy(FAKE_SW_UPDATE_DATA)
|
|
del data['type']
|
|
six.assertRaisesRegex(self, webtest.app.AppError, "400 *",
|
|
self.app.post_json, FAKE_URL,
|
|
headers=FAKE_HEADERS, params=data)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_post_sw_update_apply(self, mock_db_api, mock_rpc_client):
|
|
data = FAKE_SW_UPDATE_APPLY_DATA
|
|
mock_rpc_client().apply_sw_update_strategy.return_value = True
|
|
response = self.app.post_json(FAKE_URL + '/actions',
|
|
headers=FAKE_HEADERS,
|
|
params=data)
|
|
mock_rpc_client().apply_sw_update_strategy.assert_called_once()
|
|
self.assertEqual(response.status_int, 200)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_post_sw_update_abort(self, mock_db_api, mock_rpc_client):
|
|
mock_rpc_client().abort_sw_update_strategy.return_value = True
|
|
data = FAKE_SW_UPDATE_ABORT_DATA
|
|
response = self.app.post_json(FAKE_URL + '/actions',
|
|
headers=FAKE_HEADERS,
|
|
params=data)
|
|
mock_rpc_client().abort_sw_update_strategy.assert_called_once()
|
|
self.assertEqual(response.status_int, 200)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_post_sw_update_bad_action(self, mock_db_api, mock_rpc_client):
|
|
data = copy.copy(FAKE_SW_UPDATE_APPLY_DATA)
|
|
data["action"] = "bad action"
|
|
six.assertRaisesRegex(self, webtest.app.AppError, "400 *",
|
|
self.app.post_json, FAKE_URL,
|
|
headers=FAKE_HEADERS, params=data)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_delete_sw_update_strategy(self, mock_db_api, mock_rpc_client):
|
|
delete_url = FAKE_URL
|
|
mock_rpc_client().delete_sw_update_strategy.return_value = True
|
|
response = self.app.delete_json(delete_url, headers=FAKE_HEADERS)
|
|
mock_rpc_client().delete_sw_update_strategy.assert_called_once_with(
|
|
mock.ANY)
|
|
self.assertEqual(response.status_int, 200)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_get_sw_update_strategy(self, mock_db_api, mock_rpc_client):
|
|
get_url = FAKE_URL
|
|
mock_db_api.sw_update_strategy_db_model_to_dict.return_value = {}
|
|
self.app.get(get_url, headers=FAKE_HEADERS)
|
|
self.assertEqual(1, mock_db_api.sw_update_strategy_get.call_count)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_get_sw_update_strategy_steps(self, mock_db_api, mock_rpc_client):
|
|
get_url = FAKE_URL + '/steps'
|
|
self.app.get(get_url, headers=FAKE_HEADERS)
|
|
self.assertEqual(1, mock_db_api.strategy_step_get_all.call_count)
|
|
|
|
@mock.patch.object(rpc_client, 'ManagerClient')
|
|
@mock.patch.object(sw_update_strategy, 'db_api')
|
|
def test_get_sw_update_strategy_single_step(
|
|
self, mock_db_api, mock_rpc_client):
|
|
get_url = FAKE_URL + '/steps/subcloud1'
|
|
mock_db_api.strategy_step_db_model_to_dict.return_value = {}
|
|
self.app.get(get_url, headers=FAKE_HEADERS)
|
|
self.assertEqual(1, mock_db_api.strategy_step_get_by_name.call_count)
|