Merge pull request #293 from ramielrowe/usage_exists_stats

Usage exists stats
This commit is contained in:
Andrew Melton 2014-02-27 15:45:05 -05:00
commit 98e30312ec
5 changed files with 408 additions and 109 deletions

View File

@ -41,7 +41,7 @@ Write APIs
********** **********
db/confirm/usage/exists/batch/ db/confirm/usage/exists/batch/
===================================== ==============================
.. http:put:: http://example.com/db/confirm/usage/exists/batch/ .. http:put:: http://example.com/db/confirm/usage/exists/batch/
@ -100,6 +100,139 @@ Uses the provided message_id's and http status codes to update image and instanc
Read APIs Read APIs
********* *********
db/stats/events
===============
.. http:get:: http://example.com/db/stats/events/
Returns a count of events stored in Stacktach's Rawdata tables from
``when_min`` to ``when_max``
**Query Parameters**
* ``event``: event type to filter by
* ``when_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``when_max``: datetime (yyyy-mm-dd hh:mm:ss)
* ``service``: ``nova`` or ``glance``. default="nova"
**Example request**:
.. sourcecode:: http
GET db/stats/events/ HTTP/1.1
Host: example.com
Accept: application/json
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
count: 10
}
db/stats/nova/exists/
=====================
.. http:get:: http://example.com/db/stats/nova/exists
Returns a list of status combinations and count of events with those status combinations.
Note: Only status combinations with >0 count will show up.
**Query Parameters**
* ``audit_period_beginning_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``audit_period_beginning_max``: datetime (yyyy-mm-dd hh:mm:ss)
* ``audit_period_ending_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``audit_period_ending_max``: datetime (yyyy-mm-dd hh:mm:ss)
* ``launched_at_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``launched_at_max``: datetime (yyyy-mm-dd hh:mm:ss)
* ``deleted_at_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``deleted_at_max``: datetime (yyyy-mm-dd hh:mm:ss)
* ``received_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``received_max``: datetime (yyyy-mm-dd hh:mm:ss)
**Example request**:
.. sourcecode:: http
GET /db/stats/nova/exists/ HTTP/1.1
Host: example.com
Accept: application/json
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"stats":
[
{"status": "pending", "send_status": 0, "event_count": 1},
{"status": "verified", "send_status": 200, "event_count": 100},
{"status": "reconciled", "send_status": 200, "event_count": 2},
{"status": "failed", "send_status": 0, "event_count": 1},
]
}
db/stats/glance/exists/
=======================
.. http:get:: http://example.com/db/status/usage/glance/exists
Returns a list of status combinations and count of events with those status combinations.
Note: Only status combinations with >0 count will show up.
**Query Parameters**
* ``audit_period_beginning_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``audit_period_beginning_max``: datetime (yyyy-mm-dd hh:mm:ss)
* ``audit_period_ending_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``audit_period_ending_max``: datetime (yyyy-mm-dd hh:mm:ss)
* ``created_at_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``created_at_max``: datetime (yyyy-mm-dd hh:mm:ss)
* ``deleted_at_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``deleted_at_max``: datetime (yyyy-mm-dd hh:mm:ss)
* ``received_min``: datetime (yyyy-mm-dd hh:mm:ss)
* ``received_max``: datetime (yyyy-mm-dd hh:mm:ss)
**Example request**:
.. sourcecode:: http
GET /db/stats/nova/exists/ HTTP/1.1
Host: example.com
Accept: application/json
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"stats":
[
{"status": "verified", "send_status": 200, "event_count": 200},
{"status": "failed", "send_status": 0, "event_count": 2},
]
}
db/usage/launches/ db/usage/launches/
================== ==================
@ -781,45 +914,10 @@ Returns a single instance exists matching provided id
} }
} }
db/count/verified/ /db/repair
================== ==========
.. http:get:: http://example.com/count/verified/ .. http:post:: http://example.com/db/repair/
Returns a count of .verified events stored in Stacktach's Rawdata table from
``audit_period_beginning`` to ``audit_period_ending``
**Query Parameters**
* ``audit_period_beginning``: datetime (yyyy-mm-dd)
* ``audit_period_ending``: datetime (yyyy-mm-dd)
* ``service``: ``nova`` or ``glance``. default="nova"
**Example request**:
.. sourcecode:: http
GET db/count/verified/ HTTP/1.1
Host: example.com
Accept: application/json
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
count: 10
}
repair
======
.. http:post:: http://example.com/repair/
Changes the status of all the exists of message-ids sent with the request Changes the status of all the exists of message-ids sent with the request
from 'pending' to 'sent_unverified' so that the verifier does not end up from 'pending' to 'sent_unverified' so that the verifier does not end up
@ -831,7 +929,7 @@ repair
.. sourcecode::http .. sourcecode::http
POST /repair/ HTTP/1.1 POST /db/repair/ HTTP/1.1
Host: example.com Host: example.com
Accept: application/json Accept: application/json
@ -850,4 +948,4 @@ repair
} }
:query message_ids: list of message_ids of exists messages :query message_ids: list of message_ids of exists messages
:query service: ``nova`` or ``glance``. default="nova" :query service: ``nova`` or ``glance``. default="nova"

View File

@ -1,4 +1,4 @@
Django>=1.4.2 Django>=1.4.2, <1.6.0
MySQL-python>=1.2.3 MySQL-python>=1.2.3
eventlet>=0.9.17 eventlet>=0.9.17
kombu>=2.4.7 kombu>=2.4.7
@ -9,4 +9,4 @@ Pympler
requests requests
south south
sphinxcontrib-httpdomain sphinxcontrib-httpdomain
pbr pbr

View File

@ -24,6 +24,7 @@ import json
from datetime import datetime from datetime import datetime
from django.db import transaction from django.db import transaction
from django.db.models import Count
from django.db.models import FieldDoesNotExist from django.db.models import FieldDoesNotExist
from django.forms.models import model_to_dict from django.forms.models import model_to_dict
from django.http import HttpResponse from django.http import HttpResponse
@ -200,22 +201,7 @@ def list_usage_exists_glance(request):
def list_usage_exists_with_service(request, service): def list_usage_exists_with_service(request, service):
model = _exists_model_factory(service) model = _exists_model_factory(service)
try: custom_filters = _get_exists_filter_args(request)
custom_filters = {}
if 'received_min' in request.GET:
received_min = request.GET['received_min']
custom_filters['received_min'] = {}
custom_filters['received_min']['raw__when__gte'] = \
utils.str_time_to_unix(received_min)
if 'received_max' in request.GET:
received_max = request.GET['received_max']
custom_filters['received_max'] = {}
custom_filters['received_max']['raw__when__lte'] = \
utils.str_time_to_unix(received_max)
except AttributeError:
msg = "Range filters must be dates."
raise BadRequestException(message=msg)
objects = get_db_objects(model['klass'], request, 'id', objects = get_db_objects(model['klass'], request, 'id',
custom_filters=custom_filters) custom_filters=custom_filters)
dicts = _convert_model_list(objects, _exists_extra_values) dicts = _convert_model_list(objects, _exists_extra_values)
@ -233,6 +219,28 @@ def get_usage_exist_glance(request, exist_id):
_exists_extra_values)} _exists_extra_values)}
@api_call
def get_usage_exist_stats(request):
return {'stats': _get_exist_stats(request, 'nova')}
@api_call
def get_usage_exist_stats_glance(request):
return {'stats': _get_exist_stats(request, 'glance')}
def _get_exist_stats(request, service):
klass = _exists_model_factory(service)['klass']
exists_filters = _get_exists_filter_args(request)
filters = _get_filter_args(klass, request,
custom_filters=exists_filters)
for value in exists_filters.values():
filters.update(value)
query = klass.objects.filter(**filters)
values = query.values('status', 'send_status')
stats = values.annotate(event_count=Count('send_status'))
return stats
@api_call @api_call
def exists_send_status(request, message_id): def exists_send_status(request, message_id):
if request.method not in ['PUT', 'POST']: if request.method not in ['PUT', 'POST']:
@ -331,6 +339,25 @@ def _check_has_field(klass, field_name):
raise BadRequestException(msg) raise BadRequestException(msg)
def _get_exists_filter_args(request):
try:
custom_filters = {}
if 'received_min' in request.GET:
received_min = request.GET['received_min']
custom_filters['received_min'] = {}
custom_filters['received_min']['raw__when__gte'] = \
utils.str_time_to_unix(received_min)
if 'received_max' in request.GET:
received_max = request.GET['received_max']
custom_filters['received_max'] = {}
custom_filters['received_max']['raw__when__lte'] = \
utils.str_time_to_unix(received_max)
except AttributeError:
msg = "Range filters must be dates."
raise BadRequestException(message=msg)
return custom_filters
def _get_filter_args(klass, request, custom_filters=None): def _get_filter_args(klass, request, custom_filters=None):
filter_args = {} filter_args = {}
if 'instance' in request.GET: if 'instance' in request.GET:
@ -432,23 +459,26 @@ def _rawdata_factory(service):
@api_call @api_call
def get_verified_count(request): def get_event_stats(request):
try: try:
audit_period_beginning = datetime.strptime( filters = {}
request.GET.get("audit_period_beginning"), "%Y-%m-%d") if 'when_min' in request.GET:
audit_period_ending = datetime.strptime( when_min = utils.str_time_to_unix(request.GET['when_min'])
request.GET.get("audit_period_ending"), "%Y-%m-%d") filters['when__gte'] = when_min
if 'when_max' in request.GET:
when_max = utils.str_time_to_unix(request.GET['when_max'])
filters['when__lte'] = when_max
if 'event' in request.GET:
filters['event'] = request.GET['event']
service = request.GET.get("service", "nova") service = request.GET.get("service", "nova")
rawdata = _rawdata_factory(service) rawdata = _rawdata_factory(service)
filters = { return {'stats': {'count': rawdata.filter(**filters).count()}}
'when__gte': dt.dt_to_decimal(audit_period_beginning), except (KeyError, TypeError):
'when__lte': dt.dt_to_decimal(audit_period_ending),
'event': "compute.instance.exists.verified"
}
return {'count': rawdata.filter(**filters).count()}
except KeyError and TypeError:
raise BadRequestException(message="Invalid/absent query parameter") raise BadRequestException(message="Invalid/absent query parameter")
except ValueError: except (ValueError, AttributeError):
raise BadRequestException(message="Invalid format for date (Correct " raise BadRequestException(message="Invalid format for date (Correct "
"format should be %YYYY-%mm-%dd)") "format should be %YYYY-%mm-%dd)")

View File

@ -7,8 +7,22 @@ web_logger = stacklog.get_logger('stacktach-web')
web_logger_listener = stacklog.LogListener(web_logger) web_logger_listener = stacklog.LogListener(web_logger)
web_logger_listener.start() web_logger_listener.start()
urlpatterns = patterns('', web_urls = (
url(r'^$', 'stacktach.views.welcome', name='welcome'), url(r'^$', 'stacktach.views.welcome', name='welcome'),
url(r'^(?P<deployment_id>\d+)/$', 'stacktach.views.home', name='home'),
url(r'^(?P<deployment_id>\d+)/details/(?P<column>\w+)/(?P<row_id>\d+)/$',
'stacktach.views.details', name='details'),
url(r'^(?P<deployment_id>\d+)/search/$',
'stacktach.views.search', name='search'),
url(r'^(?P<deployment_id>\d+)/expand/(?P<row_id>\d+)/$',
'stacktach.views.expand', name='expand'),
url(r'^(?P<deployment_id>\d+)/latest_raw/$',
'stacktach.views.latest_raw', name='latest_raw'),
url(r'^(?P<deployment_id>\d+)/instance_status/$',
'stacktach.views.instance_status', name='instance_status'),
)
stacky_urls = (
url(r'stacky/deployments/$', 'stacktach.stacky_server.do_deployments'), url(r'stacky/deployments/$', 'stacktach.stacky_server.do_deployments'),
url(r'stacky/events/$', 'stacktach.stacky_server.do_events'), url(r'stacky/events/$', 'stacktach.stacky_server.do_events'),
url(r'stacky/hosts/$', 'stacktach.stacky_server.do_hosts'), url(r'stacky/hosts/$', 'stacktach.stacky_server.do_hosts'),
@ -35,7 +49,9 @@ urlpatterns = patterns('',
'stacktach.stacky_server.do_list_usage_deletes'), 'stacktach.stacky_server.do_list_usage_deletes'),
url(r'stacky/usage/exists/$', url(r'stacky/usage/exists/$',
'stacktach.stacky_server.do_list_usage_exists'), 'stacktach.stacky_server.do_list_usage_exists'),
)
dbapi_urls = (
url(r'db/usage/launches/$', url(r'db/usage/launches/$',
'stacktach.dbapi.list_usage_launches'), 'stacktach.dbapi.list_usage_launches'),
url(r'db/usage/nova/launches/$', url(r'db/usage/nova/launches/$',
@ -71,18 +87,12 @@ urlpatterns = patterns('',
'stacktach.dbapi.get_usage_exist_glance'), 'stacktach.dbapi.get_usage_exist_glance'),
url(r'db/confirm/usage/exists/(?P<message_id>[\w\-]+)/$', url(r'db/confirm/usage/exists/(?P<message_id>[\w\-]+)/$',
'stacktach.dbapi.exists_send_status'), 'stacktach.dbapi.exists_send_status'),
url(r'db/count/verified', 'stacktach.dbapi.get_verified_count'), url(r'db/stats/nova/exists$',
'stacktach.dbapi.get_usage_exist_stats'),
url(r'db/stats/glance/exists$',
'stacktach.dbapi.get_usage_exist_stats_glance'),
url(r'db/stats/events', 'stacktach.dbapi.get_event_stats'),
url(r'db/repair/', 'stacktach.dbapi.repair_stacktach_down'), url(r'db/repair/', 'stacktach.dbapi.repair_stacktach_down'),
url(r'^(?P<deployment_id>\d+)/$', 'stacktach.views.home', name='home'),
url(r'^(?P<deployment_id>\d+)/details/(?P<column>\w+)/(?P<row_id>\d+)/$',
'stacktach.views.details', name='details'),
url(r'^(?P<deployment_id>\d+)/search/$',
'stacktach.views.search', name='search'),
url(r'^(?P<deployment_id>\d+)/expand/(?P<row_id>\d+)/$',
'stacktach.views.expand', name='expand'),
url(r'^(?P<deployment_id>\d+)/latest_raw/$',
'stacktach.views.latest_raw', name='latest_raw'),
url(r'^(?P<deployment_id>\d+)/instance_status/$',
'stacktach.views.instance_status', name='instance_status')
) )
urlpatterns = patterns('', *(web_urls + stacky_urls + dbapi_urls))

View File

@ -22,6 +22,7 @@ import datetime
from decimal import Decimal from decimal import Decimal
import json import json
from django.db.models import Count
from django.db.models import FieldDoesNotExist from django.db.models import FieldDoesNotExist
from django.db import transaction from django.db import transaction
import mox import mox
@ -44,6 +45,10 @@ class DBAPITestCase(StacktachBaseTestCase):
mor_exception = models.InstanceExists.MultipleObjectsReturned mor_exception = models.InstanceExists.MultipleObjectsReturned
self.mox.StubOutWithMock(models, 'InstanceExists', self.mox.StubOutWithMock(models, 'InstanceExists',
use_mock_anything=True) use_mock_anything=True)
self.mox.StubOutWithMock(models, 'ImageExists',
use_mock_anything=True)
models.InstanceExists._meta = self.mox.CreateMockAnything()
models.ImageExists._meta = self.mox.CreateMockAnything()
models.InstanceExists.objects = self.mox.CreateMockAnything() models.InstanceExists.objects = self.mox.CreateMockAnything()
models.ImageExists.objects = self.mox.CreateMockAnything() models.ImageExists.objects = self.mox.CreateMockAnything()
models.InstanceExists.DoesNotExist = dne_exception models.InstanceExists.DoesNotExist = dne_exception
@ -932,12 +937,179 @@ class DBAPITestCase(StacktachBaseTestCase):
self.assertEqual(json.loads(resp.content), {'deletes': deletes}) self.assertEqual(json.loads(resp.content), {'deletes': deletes})
self.mox.VerifyAll() self.mox.VerifyAll()
def test_get_usage_exist_stats_nova(self):
fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET'
fake_request.GET = {}
query = self.mox.CreateMockAnything()
models.InstanceExists.objects.filter().AndReturn(query)
query.values('status', 'send_status').AndReturn(query)
result = [
{'status': 'verified', 'send_status': 201L, 'event_count': 2},
{'status': 'failed', 'send_status': 0L, 'event_count': 1}
]
query.annotate(event_count=mox.IsA(Count)).AndReturn(result)
self.mox.ReplayAll()
response = dbapi.get_usage_exist_stats(fake_request)
self.assertEqual(response.status_code, 200)
expected_response = json.dumps({'stats': result})
self.assertEqual(expected_response, response.content)
self.mox.VerifyAll()
def test_get_usage_exist_stats_nova_received_min(self):
fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET'
now = datetime.datetime.utcnow()
fake_request.GET = {'received_min': str(now)}
query = self.mox.CreateMockAnything()
filters = {'raw__when__gte': utils.decimal_utc(now)}
models.InstanceExists.objects.filter(**filters).AndReturn(query)
query.values('status', 'send_status').AndReturn(query)
result = [
{'status': 'verified', 'send_status': 201L, 'event_count': 2},
{'status': 'failed', 'send_status': 0L, 'event_count': 1}
]
query.annotate(event_count=mox.IsA(Count)).AndReturn(result)
self.mox.ReplayAll()
response = dbapi.get_usage_exist_stats(fake_request)
self.assertEqual(response.status_code, 200)
expected_response = json.dumps({'stats': result})
self.assertEqual(expected_response, response.content)
self.mox.VerifyAll()
def test_get_usage_exist_stats_nova_received_max(self):
fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET'
now = datetime.datetime.utcnow()
fake_request.GET = {'received_max': str(now)}
query = self.mox.CreateMockAnything()
filters = {'raw__when__lte': utils.decimal_utc(now)}
models.InstanceExists.objects.filter(**filters).AndReturn(query)
query.values('status', 'send_status').AndReturn(query)
result = [
{'status': 'verified', 'send_status': 201L, 'event_count': 2},
{'status': 'failed', 'send_status': 0L, 'event_count': 1}
]
query.annotate(event_count=mox.IsA(Count)).AndReturn(result)
self.mox.ReplayAll()
response = dbapi.get_usage_exist_stats(fake_request)
self.assertEqual(response.status_code, 200)
expected_response = json.dumps({'stats': result})
self.assertEqual(expected_response, response.content)
self.mox.VerifyAll()
def test_get_usage_exist_stats_nova_class_field_filter(self):
fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET'
now = datetime.datetime.utcnow()
fake_request.GET = {'audit_period_ending_min': str(now)}
query = self.mox.CreateMockAnything()
models.InstanceExists._meta.get_field_by_name('audit_period_ending')
filters = {'audit_period_ending__gte': utils.decimal_utc(now)}
models.InstanceExists.objects.filter(**filters).AndReturn(query)
query.values('status', 'send_status').AndReturn(query)
result = [
{'status': 'verified', 'send_status': 201L, 'event_count': 2},
{'status': 'failed', 'send_status': 0L, 'event_count': 1}
]
query.annotate(event_count=mox.IsA(Count)).AndReturn(result)
self.mox.ReplayAll()
response = dbapi.get_usage_exist_stats(fake_request)
self.assertEqual(response.status_code, 200)
expected_response = json.dumps({'stats': result})
self.assertEqual(expected_response, response.content)
self.mox.VerifyAll()
def test_get_usage_exist_stats_glance(self):
fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET'
fake_request.GET = {}
query = self.mox.CreateMockAnything()
models.ImageExists.objects.filter().AndReturn(query)
query.values('status', 'send_status').AndReturn(query)
result = [
{'status': 'verified', 'send_status': 201L, 'event_count': 2},
{'status': 'failed', 'send_status': 0L, 'event_count': 1}
]
query.annotate(event_count=mox.IsA(Count)).AndReturn(result)
self.mox.ReplayAll()
response = dbapi.get_usage_exist_stats_glance(fake_request)
self.assertEqual(response.status_code, 200)
expected_response = json.dumps({'stats': result})
self.assertEqual(expected_response, response.content)
self.mox.VerifyAll()
def test_get_usage_exist_stats_glance_received_min(self):
fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET'
now = datetime.datetime.utcnow()
fake_request.GET = {'received_min': str(now)}
query = self.mox.CreateMockAnything()
filters = {'raw__when__gte': utils.decimal_utc(now)}
models.ImageExists.objects.filter(**filters).AndReturn(query)
query.values('status', 'send_status').AndReturn(query)
result = [
{'status': 'verified', 'send_status': 201L, 'event_count': 2},
{'status': 'failed', 'send_status': 0L, 'event_count': 1}
]
query.annotate(event_count=mox.IsA(Count)).AndReturn(result)
self.mox.ReplayAll()
response = dbapi.get_usage_exist_stats_glance(fake_request)
self.assertEqual(response.status_code, 200)
expected_response = json.dumps({'stats': result})
self.assertEqual(expected_response, response.content)
self.mox.VerifyAll()
def test_get_usage_exist_stats_glance_received_max(self):
fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET'
now = datetime.datetime.utcnow()
fake_request.GET = {'received_max': str(now)}
query = self.mox.CreateMockAnything()
filters = {'raw__when__lte': utils.decimal_utc(now)}
models.ImageExists.objects.filter(**filters).AndReturn(query)
query.values('status', 'send_status').AndReturn(query)
result = [
{'status': 'verified', 'send_status': 201L, 'event_count': 2},
{'status': 'failed', 'send_status': 0L, 'event_count': 1}
]
query.annotate(event_count=mox.IsA(Count)).AndReturn(result)
self.mox.ReplayAll()
response = dbapi.get_usage_exist_stats_glance(fake_request)
self.assertEqual(response.status_code, 200)
expected_response = json.dumps({'stats': result})
self.assertEqual(expected_response, response.content)
self.mox.VerifyAll()
def test_get_usage_exist_stats_glance_class_field_filter(self):
fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET'
now = datetime.datetime.utcnow()
fake_request.GET = {'audit_period_ending_min': str(now)}
query = self.mox.CreateMockAnything()
models.ImageExists._meta.get_field_by_name('audit_period_ending')
filters = {'audit_period_ending__gte': utils.decimal_utc(now)}
models.ImageExists.objects.filter(**filters).AndReturn(query)
query.values('status', 'send_status').AndReturn(query)
result = [
{'status': 'verified', 'send_status': 201L, 'event_count': 2},
{'status': 'failed', 'send_status': 0L, 'event_count': 1}
]
query.annotate(event_count=mox.IsA(Count)).AndReturn(result)
self.mox.ReplayAll()
response = dbapi.get_usage_exist_stats_glance(fake_request)
self.assertEqual(response.status_code, 200)
expected_response = json.dumps({'stats': result})
self.assertEqual(expected_response, response.content)
self.mox.VerifyAll()
def test_get_verified_count(self): def test_get_verified_count(self):
fake_request = self.mox.CreateMockAnything() fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET' fake_request.method = 'GET'
fake_request.GET = {'audit_period_beginning': "2014-02-26", fake_request.GET = {'when_min': "2014-02-26 00:00:00",
'audit_period_ending': "2014-02-27", 'when_max': "2014-02-27 00:00:00",
'service': "nova"} 'service': "nova",
'event': 'compute.instance.exists.verified'}
mock_query = self.mox.CreateMockAnything() mock_query = self.mox.CreateMockAnything()
self.mox.StubOutWithMock(models.RawData.objects, "filter") self.mox.StubOutWithMock(models.RawData.objects, "filter")
models.RawData.objects.filter(event='compute.instance.exists.verified', models.RawData.objects.filter(event='compute.instance.exists.verified',
@ -947,21 +1119,22 @@ class DBAPITestCase(StacktachBaseTestCase):
mock_query.count().AndReturn(100) mock_query.count().AndReturn(100)
self.mox.ReplayAll() self.mox.ReplayAll()
response = dbapi.get_verified_count(fake_request) response = dbapi.get_event_stats(fake_request)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(json.loads(response.content), {'count': 100}) self.assertEqual(json.loads(response.content),
{'stats': {'count': 100}})
self.mox.VerifyAll() self.mox.VerifyAll()
def test_get_verified_count_wrong_date_format_returns_400(self): def test_get_verified_count_wrong_date_format_returns_400(self):
fake_request = self.mox.CreateMockAnything() fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET' fake_request.method = 'GET'
fake_request.GET = {'audit_period_beginning': "2014-020-26", fake_request.GET = {'when_min': "2014-020-26",
'service': "nova"} 'service': "nova"}
self.mox.ReplayAll() self.mox.ReplayAll()
response = dbapi.get_verified_count(fake_request) response = dbapi.get_event_stats(fake_request)
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
self.assertEqual(json.loads(response.content)['message'], self.assertEqual(json.loads(response.content)['message'],
"Invalid format for date" "Invalid format for date"
@ -971,30 +1144,18 @@ class DBAPITestCase(StacktachBaseTestCase):
def test_get_verified_count_wrong_service_returns_400(self): def test_get_verified_count_wrong_service_returns_400(self):
fake_request = self.mox.CreateMockAnything() fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET' fake_request.method = 'GET'
fake_request.GET = {'audit_period_beginning': "2014-02-26", fake_request.GET = {'when_min': "2014-02-26 00:00:00",
"audit_period_ending": "2014-02-27", "when_min": "2014-02-27 00:00:00",
'service': "qonos"} 'service': "qonos"}
self.mox.ReplayAll() self.mox.ReplayAll()
response = dbapi.get_verified_count(fake_request) response = dbapi.get_event_stats(fake_request)
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
self.assertEqual(json.loads(response.content)['message'], self.assertEqual(json.loads(response.content)['message'],
"Invalid service") "Invalid service")
self.mox.VerifyAll() self.mox.VerifyAll()
def test_get_verified_count_invalid_query_parameter_returns_400(self):
fake_request = self.mox.CreateMockAnything()
fake_request.method = 'GET'
fake_request.GET = {'audit_period': "2014-02-26",}
self.mox.ReplayAll()
response = dbapi.get_verified_count(fake_request)
self.assertEqual(response.status_code, 400)
self.assertEqual(json.loads(response.content)['message'],
"Invalid/absent query parameter")
self.mox.VerifyAll()
class StacktachRepairScenarioApi(StacktachBaseTestCase): class StacktachRepairScenarioApi(StacktachBaseTestCase):
def setUp(self): def setUp(self):
@ -1045,4 +1206,4 @@ class StacktachRepairScenarioApi(StacktachBaseTestCase):
self.assertEqual(response_data['exists_not_pending'], []) self.assertEqual(response_data['exists_not_pending'], [])
self.assertEqual(response_data['absent_exists'], []) self.assertEqual(response_data['absent_exists'], [])
self.mox.VerifyAll() self.mox.VerifyAll()