455 lines
19 KiB
Python
455 lines
19 KiB
Python
# Copyright 2014 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.
|
|
|
|
|
|
import falcon
|
|
import json
|
|
|
|
from monasca_events_api.common.repositories.mysql.streams_repository import StreamsRepository
|
|
from monasca_events_api.v2.stream_definitions import StreamDefinitions
|
|
|
|
import mock
|
|
from monasca_events_api.common.repositories.exceptions import AlreadyExistsException
|
|
from monasca_events_api.common.repositories.exceptions import RepositoryException
|
|
|
|
|
|
import unittest
|
|
|
|
|
|
class StreamDefinitionsSubClass(StreamDefinitions):
|
|
|
|
def __init__(self):
|
|
self._default_authorized_roles = ['user', 'domainuser',
|
|
'domainadmin', 'monasca-user']
|
|
self._post_events_authorized_roles = [
|
|
'user',
|
|
'domainuser',
|
|
'domainadmin',
|
|
'monasca-user',
|
|
'monasca-agent']
|
|
self._stream_definitions_repo = None
|
|
self.stream_definition_event_message_queue = None
|
|
self._region = 'useast'
|
|
|
|
|
|
class Test_StreamDefinitions(unittest.TestCase):
|
|
|
|
def _generate_req(self):
|
|
"""Generate a mock HTTP request"""
|
|
req = mock.MagicMock()
|
|
req.get_param.return_value = None
|
|
|
|
req.headers = {
|
|
'X-Auth-User': 'mini-mon',
|
|
'X-Auth-Token': 'ABCD',
|
|
'X-Auth-Key': 'password',
|
|
'X-TENANT-ID': '0ab1ac0a-2867-402d',
|
|
'X-ROLES': 'user, domainuser, domainadmin, monasca-user, monasca-agent',
|
|
'Accept': 'application/json',
|
|
'User-Agent': 'python-monascaclient',
|
|
'Content-Type': 'application/json'}
|
|
|
|
req.body = {}
|
|
req.uri = "/v2.0/stream-definitions/{stream_id}"
|
|
req.content_type = 'application/json'
|
|
return req
|
|
|
|
@mock.patch('monasca_events_api.v2.common.helpers.add_links_to_resource')
|
|
@mock.patch(
|
|
'monasca_events_api.common.repositories.mysql.mysql_repository.mdb')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.normalize_offset')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_query_name')
|
|
@mock.patch(
|
|
'monasca_events_api.common.repositories.mysql.mysql_repository.mdb')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_tenant_id')
|
|
def test_on_get_stream_fail_db_down(
|
|
self,
|
|
tenant_id,
|
|
validate,
|
|
mysqlRepo,
|
|
qname,
|
|
normalize,
|
|
repo,
|
|
getlinks):
|
|
"""GET Method FAIL Single Stream"""
|
|
repo.connect.side_effect = RepositoryException(
|
|
"Database Connection Error")
|
|
validate.return_value = True
|
|
normalize.return_value = 5
|
|
qname.return_value = "Test"
|
|
tenant_id.return_value = '0ab1ac0a-2867-402d'
|
|
|
|
stream_id = "1"
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
streamsObj._stream_definitions_repo = StreamsRepository()
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
try:
|
|
streamsObj.on_get(self._generate_req(), res, stream_id)
|
|
self.assertFalse(
|
|
1,
|
|
msg="Database Down, GET should fail but succeeded")
|
|
except Exception as e:
|
|
self.assertRaises(falcon.HTTPInternalServerError)
|
|
self.assertEqual(e.status, '500 Internal Server Error')
|
|
|
|
@mock.patch(
|
|
'monasca_events_api.common.repositories.mysql.mysql_repository.mdb')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.StreamDefinitions._stream_definition_show')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.add_links_to_resource')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_tenant_id')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
def test_on_get_streamid_pass(
|
|
self,
|
|
validate,
|
|
tenant_id,
|
|
getlinks,
|
|
definitionshow,
|
|
mysqlRepo):
|
|
"""GET Method SUCCESS Single Stream"""
|
|
|
|
validate.return_value = True
|
|
tenant_id.return_value = '0ab1ac0a-2867-402d'
|
|
returnStream = [{"region": "useast", "tenantId": "0ab1ac0a-2867-402d",
|
|
"creation_time": "1434331190", "stream": "1"}]
|
|
definitionshow.return_value = returnStream
|
|
getlinks.return_value = "/v2.0/stream-definitions/{stream_id}"
|
|
mysqlRepo.connect.return_value = True
|
|
stream_id = "1"
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
streamsObj._stream_definitions_repo = StreamsRepository()
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
streamsObj.on_get(self._generate_req(), res, stream_id)
|
|
self.assertEqual(returnStream, json.loads(res.body))
|
|
self.assertEqual(res.status, '200 OK')
|
|
|
|
@mock.patch('monasca_events_api.v2.common.helpers.normalize_offset')
|
|
@mock.patch(
|
|
'monasca_events_api.common.repositories.mysql.mysql_repository.mdb')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_tenant_id')
|
|
def test_on_get_streams_fail_db_down(
|
|
self,
|
|
tenant_id,
|
|
validate,
|
|
mysqlRepo,
|
|
normalize):
|
|
"""GET Method FAILS Multiple Streams"""
|
|
mysqlRepo.connect.side_effect = RepositoryException(
|
|
"Database Connection Error")
|
|
validate.return_value = True
|
|
tenant_id.return_value = '0ab1ac0a-2867-402d'
|
|
normalize.return_value = 5
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
streamsObj._stream_definitions_repo = StreamsRepository()
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
try:
|
|
streamsObj.on_get(self._generate_req(), res, None)
|
|
self.assertFalse(
|
|
1,
|
|
msg="Database Down, GET should fail but succeeded")
|
|
except Exception as e:
|
|
self.assertRaises(falcon.HTTPInternalServerError)
|
|
self.assertEqual(e.status, '500 Internal Server Error')
|
|
|
|
@mock.patch('monasca_events_api.v2.common.helpers.normalize_offset')
|
|
@mock.patch(
|
|
'monasca_events_api.common.repositories.mysql.mysql_repository.mdb')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.StreamDefinitions._stream_definition_list')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.add_links_to_resource')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_tenant_id')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
def test_on_get_streams_pass(
|
|
self,
|
|
validate,
|
|
tenant_id,
|
|
getlinks,
|
|
definitionlist,
|
|
mysqlRepo,
|
|
normalize):
|
|
"""GET Method SUCCESS Streams List"""
|
|
|
|
validate.return_value = True
|
|
tenant_id.return_value = '0ab1ac0a-2867-402d'
|
|
returnStreams = [{"region": "useast", "tenantId": "0ab1ac0a-2867-402d",
|
|
"creation_time": "1434331190", "stream": "1"},
|
|
{"region": "useast", "tenantId": "0ab1ac0a-2866-403d",
|
|
"creation_time": "1234567890", "stream": "2"}]
|
|
definitionlist.return_value = returnStreams
|
|
normalize.return_value = 5
|
|
getlinks.return_value = "/v2.0/stream-definitions/"
|
|
mysqlRepo.connect.return_value = True
|
|
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
streamsObj._stream_definitions_repo = StreamsRepository()
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
streamsObj.on_get(self._generate_req(), res, None)
|
|
self.assertEqual(returnStreams, json.loads(res.body))
|
|
self.assertEqual(res.status, '200 OK')
|
|
|
|
@mock.patch(
|
|
'monasca_events_api.common.repositories.mysql.mysql_repository.mdb')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_expire_actions')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_fire_actions')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_description')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_name')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.StreamDefinitions._validate_stream_definition')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.read_json_msg_body')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.common.helpers.validate_json_content_type')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_tenant_id')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
def test_on_post_integrity_error(
|
|
self,
|
|
validate,
|
|
tenantid,
|
|
json,
|
|
readjson,
|
|
streamvalid,
|
|
getname,
|
|
desc,
|
|
fireactions,
|
|
expire,
|
|
repo):
|
|
"""POST method failed due to integrity error"""
|
|
validate.return_value = True
|
|
repo.connect.side_effect = AlreadyExistsException()
|
|
fireactions.return_value = "fire_actions"
|
|
getname.return_value = "Test"
|
|
expire.return_value = "expire_actions"
|
|
desc.return_value = "Stream_Description"
|
|
readjson.return_value = {
|
|
u'fire_criteria': [
|
|
{
|
|
u'event_type': u'compute.instance.create.start'},
|
|
{
|
|
u'event_type': u'compute.instance.create.end'}],
|
|
u'description': u'provisioning duration',
|
|
u'group_by': [u'instance_id'],
|
|
u'expiration': 90000,
|
|
u'select': [
|
|
{
|
|
u'event_type': u'compute.instance.create.*'}],
|
|
u'name': u'buzz'}
|
|
|
|
tenantid.return_value = '0ab1ac0a-2867-402d'
|
|
streamvalid.return_value = True
|
|
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
streamsObj._stream_definitions_repo = StreamsRepository()
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
try:
|
|
streamsObj.on_post(self._generate_req(), res)
|
|
self.assertFalse(
|
|
1,
|
|
msg="DB Integrity Error, should fail but passed")
|
|
except Exception as e:
|
|
self.assertRaises(falcon.HTTPConflict)
|
|
self.assertEqual(e.status, '409 Conflict')
|
|
|
|
@mock.patch('monasca_events_api.v2.common.helpers.add_links_to_resource')
|
|
@mock.patch(
|
|
'monasca_events_api.common.messaging.kafka_publisher.KafkaPublisher')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.StreamDefinitions._stream_definition_create')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_expire_actions')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_fire_actions')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_description')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_name')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.StreamDefinitions._validate_stream_definition')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.read_json_msg_body')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_tenant_id')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
def test_on_post_pass__validate_stream_definition(
|
|
self,
|
|
validate,
|
|
tenantid,
|
|
readjson,
|
|
streamvalid,
|
|
getname,
|
|
desc,
|
|
fireactions,
|
|
expire,
|
|
streamsrepo,
|
|
kafka,
|
|
addlink):
|
|
"""POST method successful"""
|
|
validate.return_value = True
|
|
fireactions.return_value = "fire_actions"
|
|
getname.return_value = "Test"
|
|
addlink.return_value = "/v2.0/stream-definitions/{stream_id}"
|
|
expire.return_value = "expire_actions"
|
|
desc.return_value = "Stream_Description"
|
|
responseObj = {u'fire_criteria': [{u'event_type': u'compute.instance.create.start'},
|
|
{u'event_type': u'compute.instance.create.end'}],
|
|
u'description': u'provisioning duration',
|
|
u'group_by': [u'instance_id'],
|
|
u'expiration': 90000,
|
|
u'select': [{u'event_type': u'compute.instance.create.*'}],
|
|
u'name': u'buzz'}
|
|
|
|
readjson.return_value = responseObj
|
|
streamsrepo.return_value = responseObj
|
|
tenantid.return_value = '0ab1ac0a-2867-402d'
|
|
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
streamsObj._stream_definitions_repo = StreamsRepository()
|
|
streamsObj.stream_definition_event_message_queue = kafka
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
streamsObj.on_post(self._generate_req(), res)
|
|
self.assertEqual(falcon.HTTP_201, res.status)
|
|
self.assertEqual(responseObj, json.loads(res.body))
|
|
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.read_http_resource')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.add_links_to_resource')
|
|
@mock.patch(
|
|
'monasca_events_api.common.messaging.kafka_publisher.KafkaPublisher')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_expire_actions')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_fire_actions')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_description')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.read_json_msg_body')
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.get_query_stream_definition_name')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_tenant_id')
|
|
def test_on_post_fail__validate_stream_definition(
|
|
self,
|
|
tenantid,
|
|
getname,
|
|
readjson,
|
|
desc,
|
|
fireactions,
|
|
expire,
|
|
kafka,
|
|
addlink,
|
|
httpRes,
|
|
authorization):
|
|
"""POST method failed due to invalid body"""
|
|
fireactions.return_value = "fire_actions"
|
|
getname.return_value = "Test"
|
|
addlink.return_value = "/v2.0/stream-definitions/{stream_id}"
|
|
expire.return_value = "expire_actions"
|
|
desc.return_value = "Stream_Description"
|
|
"""name removed from body"""
|
|
responseObj = {u'fire_criteria': [{u'event_type': u'compute.instance.create.start'},
|
|
{u'event_type': u'compute.instance.create.end'}],
|
|
u'description': u'provisioning duration',
|
|
u'group_by': [u'instance_id'],
|
|
u'expiration': 90000,
|
|
u'name': u'buzz'}
|
|
tenantid.return_value = '0ab1ac0a-2867-402d'
|
|
readjson.return_value = responseObj
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
streamsObj._stream_definitions_repo = StreamsRepository()
|
|
streamsObj.stream_definition_event_message_queue = kafka
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
try:
|
|
streamsObj.on_post(self._generate_req(), res)
|
|
self.assertFalse(1, msg="Bad Request Sent, should fail but passed")
|
|
except Exception as e:
|
|
self.assertRaises(falcon.HTTPBadRequest)
|
|
self.assertEqual(e.status, '400 Bad Request')
|
|
|
|
@mock.patch('monasca_events_api.v2.common.helpers.read_json_msg_body')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
def test_on_post_badrequest(self, validate, readjson):
|
|
"""POST method Fail Due to bad request"""
|
|
validate.return_value = True
|
|
readjson.side_effect = falcon.HTTPBadRequest(
|
|
'Bad request',
|
|
'Request body is not valid JSON')
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
try:
|
|
streamsObj.on_post(self._generate_req(), res)
|
|
self.assertFalse(1, msg="Bad Request Sent, should fail but passed")
|
|
except Exception as e:
|
|
self.assertRaises(falcon.HTTPBadRequest)
|
|
self.assertEqual(e.status, '400 Bad Request')
|
|
|
|
@mock.patch(
|
|
'monasca_events_api.common.repositories.mysql.streams_repository.StreamsRepository.delete_stream_definition')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_tenant_id')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
def test_on_delete_fail(self, validate, tenantid, deleteStream):
|
|
"""DELETEE method failed due to database down """
|
|
validate.return_value = True
|
|
tenantid.return_value = '0ab1ac0a-2867-402d'
|
|
deleteStream.side_effect = RepositoryException(
|
|
"Database Connection Error")
|
|
stream_id = "1"
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
try:
|
|
streamsObj.on_delete(self._generate_req(), res, stream_id)
|
|
self.assertFalse(1, msg="Database Down, should fail but passed")
|
|
except Exception as e:
|
|
self.assertRaises(falcon.HTTPInternalServerError)
|
|
self.assertEqual(e.status, '500 Internal Server Error')
|
|
|
|
@mock.patch(
|
|
'monasca_events_api.v2.stream_definitions.StreamDefinitions._stream_definition_delete')
|
|
@mock.patch(
|
|
'monasca_events_api.common.repositories.mysql.mysql_repository.mdb')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.get_tenant_id')
|
|
@mock.patch('monasca_events_api.v2.common.helpers.validate_authorization')
|
|
def test_on_delete_pass(self, validate, tenantid, mysql, deleteStream):
|
|
"""DELETE method successful """
|
|
validate.return_value = True
|
|
tenantid.return_value = '0ab1ac0a-2867-402d'
|
|
|
|
deleteStream.return_value = True
|
|
stream_id = "1"
|
|
|
|
streamsObj = StreamDefinitionsSubClass()
|
|
streamsObj._stream_definitions_repo = StreamsRepository()
|
|
res = mock.MagicMock()
|
|
res.body = {}
|
|
res.status = 0
|
|
streamsObj.on_delete(self._generate_req(), res, stream_id)
|
|
self.assertEqual("204 No Content", res.status)
|