Commit 0445756a authored by Vitali Stupin's avatar Vitali Stupin
Browse files

Merge pull request #4 in XTIIM/csapi from vitali to develop

* commit '26ebc189':
  Adding status API
  Work in progress
parents bb866133 26ebc189
......@@ -383,6 +383,27 @@ def incorrect_client(client_dn):
'msg': 'Client certificate is not allowed: {}'.format(client_dn)})
def test_db():
"""Add new X-Road subsystem to Central Server"""
conf = get_db_conf()
if not conf['username'] or not conf['password'] or not conf['database']:
LOGGER.error('DB_CONF_ERROR: Cannot access database configuration')
return {
'http_status': 500, 'code': 'DB_CONF_ERROR',
'msg': 'Cannot access database configuration'}
with get_db_connection(conf) as conn:
with conn.cursor() as cur:
cur.execute("""select 1 from system_parameters where key='instanceIdentifier'""")
rec = cur.fetchone()
if rec:
return {
'http_status': 200, 'code': 'OK',
'msg': 'API is ready'}
return {'http_status': 500, 'code': 'DB_ERROR', 'msg': 'Unexpected DB state'}
class MemberApi(Resource):
"""Member API class for Flask"""
def __init__(self, config):
......@@ -459,3 +480,24 @@ class SubsystemApi(Resource):
'msg': 'Unclassified database error'}
return make_response(response)
class StatusApi(Resource):
"""Status API class for Flask"""
def __init__(self, config):
self.config = config
@staticmethod
def get():
"""GET method"""
LOGGER.info('Incoming status request')
try:
response = test_db()
except psycopg2.Error as err:
LOGGER.error('DB_ERROR: Unclassified database error: %s', err)
response = {
'http_status': 500, 'code': 'DB_ERROR',
'msg': 'Unclassified database error'}
return make_response(response)
......@@ -3,7 +3,7 @@
import logging
from flask import Flask
from flask_restful import Api
from csapi import MemberApi, SubsystemApi, load_config
from csapi import MemberApi, SubsystemApi, StatusApi, load_config
handler = logging.FileHandler('/var/log/xroad/csapi.log')
handler.setFormatter(logging.Formatter('%(asctime)s - %(process)d - %(levelname)s: %(message)s'))
......@@ -24,5 +24,6 @@ app = Flask(__name__)
api = Api(app)
api.add_resource(MemberApi, '/member', resource_class_kwargs={'config': config})
api.add_resource(SubsystemApi, '/subsystem', resource_class_kwargs={'config': config})
api.add_resource(StatusApi, '/status', resource_class_kwargs={'config': config})
logger.info('Starting Central Server API')
......@@ -17,6 +17,8 @@ class MainTestCase(unittest.TestCase):
'config': {'allow_all': True}})
self.api.add_resource(csapi.SubsystemApi, '/subsystem', resource_class_kwargs={
'config': {'allow_all': True}})
self.api.add_resource(csapi.StatusApi, '/status', resource_class_kwargs={
'config': {'allow_all': True}})
@patch('builtins.open', return_value=io.StringIO('''adapter=postgresql
encoding=utf8
......@@ -858,6 +860,125 @@ reconnect=true
'member_class': 'MEMBER_CLASS', 'member_code': 'MEMBER_CODE',
'subsystem_code': 'SUBSYSTEM_CODE'})
@patch('csapi.get_db_connection')
@patch('csapi.get_db_conf', return_value={
'database': 'centerui_production',
'password': 'centerui_pass',
'username': 'centerui_user'})
def test_test_db_ok(self, mock_get_db_conf, mock_get_db_connection):
mock_get_db_connection.execute = MagicMock()
mock_get_db_connection.fetchone = MagicMock(return_value=1)
self.assertEqual(
{'code': 'OK', 'http_status': 200, 'msg': 'API is ready'},
csapi.test_db())
mock_get_db_conf.assert_called_with()
mock_get_db_connection.assert_called_with({
'database': 'centerui_production', 'password': 'centerui_pass',
'username': 'centerui_user'})
@patch('csapi.get_db_connection')
@patch('csapi.get_db_conf', return_value={
'database': 'centerui_production',
'password': 'centerui_pass',
'username': 'centerui_user'})
def test_test_db_not_ok(self, mock_get_db_conf, mock_get_db_connection):
mock_cur = mock_get_db_connection.return_value.__enter__.return_value.cursor.return_value
mock_cur.__enter__.return_value.fetchone.return_value = None
self.assertEqual(
{'code': 'DB_ERROR', 'http_status': 500, 'msg': 'Unexpected DB state'},
csapi.test_db())
mock_get_db_conf.assert_called_with()
mock_get_db_connection.assert_called_with({
'database': 'centerui_production', 'password': 'centerui_pass',
'username': 'centerui_user'})
@patch('csapi.get_db_connection')
@patch('csapi.get_db_conf', return_value={
'database': '',
'password': 'centerui_pass',
'username': 'centerui_user'})
def test_test_db_no_database(self, mock_get_db_conf, mock_get_db_connection):
with self.assertLogs(csapi.LOGGER, level='INFO') as cm:
self.assertEqual(
{
'code': 'DB_CONF_ERROR', 'http_status': 500,
'msg': 'Cannot access database configuration'},
csapi.test_db())
self.assertEqual(
['ERROR:csapi:DB_CONF_ERROR: Cannot access database configuration'], cm.output)
mock_get_db_conf.assert_called_with()
mock_get_db_connection.assert_not_called()
@patch('csapi.get_db_connection')
@patch('csapi.get_db_conf', return_value={
'database': 'centerui_production',
'password': '',
'username': 'centerui_user'})
def test_test_db_no_password(self, mock_get_db_conf, mock_get_db_connection):
with self.assertLogs(csapi.LOGGER, level='INFO') as cm:
self.assertEqual(
{
'code': 'DB_CONF_ERROR', 'http_status': 500,
'msg': 'Cannot access database configuration'},
csapi.test_db())
self.assertEqual(
['ERROR:csapi:DB_CONF_ERROR: Cannot access database configuration'], cm.output)
mock_get_db_conf.assert_called_with()
mock_get_db_connection.assert_not_called()
@patch('csapi.get_db_connection')
@patch('csapi.get_db_conf', return_value={
'database': 'centerui_production',
'password': 'centerui_pass',
'username': ''})
def test_test_db_no_username(self, mock_get_db_conf, mock_get_db_connection):
with self.assertLogs(csapi.LOGGER, level='INFO') as cm:
self.assertEqual(
{
'code': 'DB_CONF_ERROR', 'http_status': 500,
'msg': 'Cannot access database configuration'},
csapi.test_db())
self.assertEqual(
['ERROR:csapi:DB_CONF_ERROR: Cannot access database configuration'], cm.output)
mock_get_db_conf.assert_called_with()
mock_get_db_connection.assert_not_called()
@patch('csapi.test_db', side_effect=psycopg2.Error('DB_ERROR_MSG'))
def test_status_db_error_handled(self, mock_test_db):
with self.app.app_context():
with self.assertLogs(csapi.LOGGER, level='INFO') as cm:
response = self.client.get('/status')
self.assertEqual(500, response.status_code)
self.assertEqual(
jsonify({
'code': 'DB_ERROR',
'msg': 'Unclassified database error'}).json,
response.json
)
self.assertEqual([
'INFO:csapi:Incoming status request',
'ERROR:csapi:DB_ERROR: Unclassified database error: DB_ERROR_MSG',
"INFO:csapi:Response: {'http_status': 500, 'code': 'DB_ERROR', 'msg': "
"'Unclassified database error'}"], cm.output)
mock_test_db.assert_called_with()
@patch('csapi.test_db', return_value={
'http_status': 200, 'code': 'OK', 'msg': 'All Correct'})
def test_status_ok(self, mock_test_db):
with self.app.app_context():
with self.assertLogs(csapi.LOGGER, level='INFO') as cm:
response = self.client.get('/status')
self.assertEqual(200, response.status_code)
self.assertEqual(
jsonify({'code': 'OK', 'msg': 'All Correct'}).json,
response.json
)
self.assertEqual([
'INFO:csapi:Incoming status request',
"INFO:csapi:Response: {'http_status': 200, 'code': 'OK', 'msg': 'All "
"Correct'}"], cm.output)
mock_test_db.assert_called_with()
class NoConfTestCase(unittest.TestCase):
def setUp(self):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment