Files
freezer-api/tests/test_db_init.py
Fabrizio Vanni 5573da32c0 elasticsearch init script
Adds a script to initialize the mappings of the elasticsearch db
used by the api.

The location of the elasticsearch db server can be provided using
command-line arguments or guessed by the script looking at the
freezer-api configuration file.

The script asks confirmation prior to deleting each of the
elasticsearch types whose mapping needs to be updated,
but it can be instructed to always assume a confirmation to ease
the invocation by scripts or deployment tools.

Change-Id: I0938c7cfde9bae440bf85f536a56079429d772a9
Implements: blueprint freezer-api-db-init
2015-07-15 12:25:34 +01:00

239 lines
11 KiB
Python

"""
Copyright 2015 Hewlett-Packard
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.
This product includes cryptographic software written by Eric Young
(eay@cryptsoft.com). This product includes software written by Tim
Hudson (tjh@cryptsoft.com).
========================================================================
"""
import os
import unittest
from mock import Mock, patch
from freezer_api.cmd.db_init import (ElastichsearchEngine,
get_args,
find_config_file,
parse_config_file,
get_db_params,
main,
DEFAULT_CONF_PATH)
from freezer_api.common import db_mappings
class TestElasticsearchEngine(unittest.TestCase):
def setUp(self):
self.test_mappings = {
'jobs': {"properties": {"job_id": {"type": "string"}}},
'backups': {"properties": {"backup_id": {"type": "string"}}},
'clients': {"properties": {"client_id": {"type": "string"}}},
}
self.mock_resp = Mock()
self.es_manager = ElastichsearchEngine(es_url='http://test:9333',
es_index='freezerindex',
test_only=False,
always_yes=False,
verbose=True)
def test_new(self):
self.assertIsInstance(self.es_manager, ElastichsearchEngine)
@patch.object(ElastichsearchEngine, 'mapping_match')
@patch.object(ElastichsearchEngine, 'askput_mapping')
def test_put_mappings_does_nothing_when_mappings_match(self, mock_askput_mapping, mock_mapping_match):
self.es_manager.put_mappings(self.test_mappings)
self.assertEquals(mock_askput_mapping.call_count, 0)
@patch.object(ElastichsearchEngine, 'mapping_match')
@patch.object(ElastichsearchEngine, 'askput_mapping')
def test_put_mappings_calls_askput_when_mappings_match_not(self, mock_askput_mapping, mock_mapping_match):
mock_mapping_match.return_value = False
self.es_manager.put_mappings(self.test_mappings)
self.assertEquals(mock_askput_mapping.call_count, 3)
@patch.object(ElastichsearchEngine, 'proceed')
@patch.object(ElastichsearchEngine, 'delete_type')
@patch.object(ElastichsearchEngine, 'put_mapping')
def test_askput_calls_delete_and_put_mappunts_when_always_yes(self,
mock_put_mapping,
mock_delete_type,
mock_proceed):
self.es_manager.always_yes = True
res = self.es_manager.askput_mapping('jobs', self.test_mappings['jobs'])
mock_delete_type.assert_called_once_with('jobs')
mock_put_mapping.assert_called_once_with('jobs', self.test_mappings['jobs'])
def test_askput_does_nothing_when_test_only(self):
self.es_manager.test_only = True
res = self.es_manager.askput_mapping('jobs', self.test_mappings['jobs'])
self.assertEquals(None, res)
@patch('freezer_api.cmd.db_init.requests')
def test_mapping_match_not_found_returns_false(self, mock_requests):
self.mock_resp.status_code = 404
mock_requests.get.return_value = self.mock_resp
res = self.es_manager.mapping_match('jobs', self.test_mappings['jobs'])
self.assertFalse(res)
@patch('freezer_api.cmd.db_init.requests')
def test_mapping_match_raises_Exception_on_response_not_in_200_404(self, mock_requests):
self.mock_resp.status_code = 500
mock_requests.get.return_value = self.mock_resp
self.assertRaises(Exception, self.es_manager.mapping_match,
'jobs', self.test_mappings['jobs'])
@patch('freezer_api.cmd.db_init.requests')
def test_mapping_match_return_true_when_mapping_matches(self, mock_requests):
self.mock_resp.status_code = 200
self.mock_resp.text = '{"freezerindex": {"mappings": {"jobs":{"properties": {"job_id": {"type": "string"}}}}}}'
mock_requests.get.return_value = self.mock_resp
res = self.es_manager.mapping_match('jobs', self.test_mappings['jobs'])
self.assertTrue(res)
@patch('freezer_api.cmd.db_init.requests')
def test_mapping_match_return_false_when_mapping_matches_not(self, mock_requests):
self.mock_resp.status_code = 200
self.mock_resp.text = '{"freezerindex": {"mappings": {"jobs":{"properties": {"job_id": {"type": "balloon"}}}}}}'
mock_requests.get.return_value = self.mock_resp
res = self.es_manager.mapping_match('jobs', self.test_mappings['jobs'])
self.assertFalse(res)
@patch('freezer_api.cmd.db_init.requests')
def test_delete_type_returns_none_on_success(self, mock_requests):
self.mock_resp.status_code = 200
mock_requests.delete.return_value = self.mock_resp
res = self.es_manager.delete_type('jobs')
self.assertIsNone(res)
@patch('freezer_api.cmd.db_init.requests')
def test_delete_type_raises_Exception_on_response_code_not_200(self, mock_requests):
self.mock_resp.status_code = 400
mock_requests.delete.return_value = self.mock_resp
self.assertRaises(Exception, self.es_manager.delete_type, 'jobs')
@patch('freezer_api.cmd.db_init.requests')
def test_put_mapping_returns_none_on_success(self, mock_requests):
self.mock_resp.status_code = 200
mock_requests.put.return_value = self.mock_resp
res = self.es_manager.put_mapping('jobs', self.test_mappings['jobs'])
self.assertIsNone(res)
url = 'http://test:9333/freezerindex/_mapping/jobs'
data = '{"properties": {"job_id": {"type": "string"}}}'
mock_requests.put.assert_called_with(url, data=data)
@patch('freezer_api.cmd.db_init.requests')
def test_put_mapping_raises_Exception_on_response_code_not_200(self, mock_requests):
self.mock_resp.status_code = 500
mock_requests.put.return_value = self.mock_resp
self.assertRaises(Exception, self.es_manager.put_mapping, 'jobs', self.test_mappings['jobs'])
def test_proceed_returns_true_on_user_y(self):
with patch('__builtin__.raw_input', return_value='y') as _raw_input:
res = self.es_manager.proceed('fancy a drink ?')
self.assertTrue(res)
_raw_input.assert_called_once_with('fancy a drink ?')
def test_proceed_returns_false_on_user_n(self):
with patch('__builtin__.raw_input', return_value='n') as _raw_input:
res = self.es_manager.proceed('are you drunk ?')
self.assertFalse(res)
_raw_input.assert_called_once_with('are you drunk ?')
def test_proceed_returns_true_when_always_yes(self):
self.es_manager.always_yes = True
res = self.es_manager.proceed('ask me not')
self.assertTrue(res)
class TestDbInit(unittest.TestCase):
@patch('freezer_api.cmd.db_init.argparse.ArgumentParser')
def test_get_args_calls_add_argument(self, mock_ArgumentParser):
mock_arg_parser = Mock()
mock_ArgumentParser.return_value = mock_arg_parser
retval = get_args()
call_count = mock_arg_parser.add_argument.call_count
self.assertGreater(call_count, 6)
@patch('freezer_api.cmd.db_init.os.path.isfile')
@patch('freezer_api.cmd.db_init.os.getcwd')
def test_find_config_file_returns_file_in_cwd(self, mock_os_getcwd, mock_os_path_isfile):
mock_os_getcwd.return_value = '/home/woohoo'
mock_os_path_isfile.return_value = True
res = find_config_file()
self.assertEquals('/home/woohoo/freezer-api.conf', res)
@patch('freezer_api.cmd.db_init.os.path.isfile')
@patch('freezer_api.cmd.db_init.os.getcwd')
def test_find_config_file_returns_defaultfile(self, mock_os_getcwd, mock_os_path_isfile):
mock_os_getcwd.return_value = '/home/woohoo'
mock_os_path_isfile.side_effect = [False, True, False]
res = find_config_file()
self.assertEquals(DEFAULT_CONF_PATH, res)
@patch('freezer_api.cmd.db_init.ConfigParser.ConfigParser')
def test_parse_config_file_return_config_file_params(self, mock_ConfigParser):
mock_config = Mock()
mock_ConfigParser.return_value = mock_config
mock_config.get.side_effect = lambda *x: {('storage', 'endpoint'): 'http://iperuranio:1999',
('storage', 'index'): 'ohyes'}[x]
host, port, index = parse_config_file('dontcare')
self.assertEquals(host, 'iperuranio')
self.assertEquals(port, 1999)
self.assertEquals(index, 'ohyes')
@patch('freezer_api.cmd.db_init.parse_config_file')
def test_get_db_params_returns_args_parameters(self, mock_parse_config_file):
mock_parse_config_file.return_value = (None, None, None)
mock_args = Mock()
mock_args.host = 'pumpkin'
mock_args.port = 12345
mock_args.index = 'ciccio'
elasticsearch_url, elasticsearch_index = get_db_params(mock_args)
self.assertEquals(elasticsearch_url, 'http://pumpkin:12345')
self.assertEquals(elasticsearch_index, 'ciccio')
@patch('freezer_api.cmd.db_init.ElastichsearchEngine')
@patch('freezer_api.cmd.db_init.get_db_params')
@patch('freezer_api.cmd.db_init.get_args')
def test_main_calls_esmanager_put_mappings_with_mappings(self, mock_get_args, mock_get_db_params,
mock_ElastichsearchEngine):
mock_get_db_params.return_value = Mock(), Mock()
mock_es_manager = Mock()
mock_ElastichsearchEngine.return_value = mock_es_manager
res = main()
self.assertEquals(res, os.EX_OK)
mappings = db_mappings.get_mappings()
mock_es_manager.put_mappings.assert_called_with(mappings)
@patch('freezer_api.cmd.db_init.ElastichsearchEngine')
@patch('freezer_api.cmd.db_init.get_db_params')
@patch('freezer_api.cmd.db_init.get_args')
def test_main_return_EX_DATAERR_exitcode_on_error(self, mock_get_args, mock_get_db_params,
mock_ElastichsearchEngine):
mock_get_db_params.return_value = Mock(), Mock()
mock_es_manager = Mock()
mock_ElastichsearchEngine.return_value = mock_es_manager
mock_es_manager.put_mappings.side_effect = Exception('test error')
res = main()
self.assertEquals(res, os.EX_DATAERR)