More lifecycle/KPI unit tests and some cleanup

This commit is contained in:
Andrew Melton 2013-01-24 14:27:30 -05:00
parent 57fea75478
commit 61a6bda63c
10 changed files with 152 additions and 83 deletions

View File

@ -12,5 +12,11 @@ def create_timing(**kwargs):
def find_timings(**kwargs): def find_timings(**kwargs):
return models.Timing.objects.select_related().filter(**kwargs) return models.Timing.objects.select_related().filter(**kwargs)
def create_request_tracker(**kwargs):
return models.RequestTracker(**kwargs)
def find_request_trackers(**kwargs):
return models.RequestTracker.objects.filter(**kwargs)
def save(obj): def save(obj):
obj.save() obj.save()

View File

@ -17,27 +17,6 @@ from test_utils import create_raw
import views import views
class DatetimeToDecimalTestCase(unittest.TestCase):
def test_datetime_to_and_from_decimal(self):
now = datetime.datetime.utcnow()
d = datetime_to_decimal.dt_to_decimal(now)
daittyme = datetime_to_decimal.dt_from_decimal(d)
self.assertEqual(now, daittyme)
def test_datetime_to_decimal(self):
expected_decimal = decimal.Decimal('1356093296.123')
utc_datetime = datetime.datetime.utcfromtimestamp(expected_decimal)
actual_decimal = datetime_to_decimal.dt_to_decimal(utc_datetime)
self.assertEqual(actual_decimal, expected_decimal)
def test_decimal_to_datetime(self):
expected_decimal = decimal.Decimal('1356093296.123')
expected_datetime = datetime.datetime.utcfromtimestamp(expected_decimal)
actual_datetime = datetime_to_decimal.dt_from_decimal(expected_decimal)
self.assertEqual(actual_datetime, expected_datetime)
class ViewsUtilsTestCase(unittest.TestCase): class ViewsUtilsTestCase(unittest.TestCase):
def test_srt_time_to_unix(self): def test_srt_time_to_unix(self):

View File

@ -67,7 +67,7 @@ def _compute_update_message(routing_key, body):
resp = dict(host=host, instance=instance, publisher=publisher, resp = dict(host=host, instance=instance, publisher=publisher,
service=service, event=event, tenant=tenant, service=service, event=event, tenant=tenant,
request_id=request_id) request_id=request_id)
payload = data.get('payload', {}) payload = body.get('payload', {})
resp.update(_extract_states(payload)) resp.update(_extract_states(payload))
return resp return resp
@ -87,15 +87,15 @@ def start_kpi_tracking(lifecycle, raw):
if "api" not in raw.host: if "api" not in raw.host:
return return
tracker = models.RequestTracker(request_id=raw.request_id, tracker = STACKDB.create_request_tracker(request_id=raw.request_id,
start=raw.when, start=raw.when,
lifecycle=lifecycle, lifecycle=lifecycle,
last_timing=None, last_timing=None,
duration=str(0.0)) duration=str(0.0))
tracker.save() STACKDB.save(tracker)
def update_kpi(lifecycle, timing, raw): def update_kpi(timing, raw):
"""Whenever we get a .end event, use the Timing object to """Whenever we get a .end event, use the Timing object to
compute our current end-to-end duration. compute our current end-to-end duration.
@ -106,15 +106,14 @@ def update_kpi(lifecycle, timing, raw):
Until then, we'll take the lazy route and be aware of these Until then, we'll take the lazy route and be aware of these
potential fence-post issues.""" potential fence-post issues."""
trackers = models.RequestTracker.objects.\ trackers = STACKDB.find_request_trackers(request_id=raw.request_id)
filter(request_id=raw.request_id)
if len(trackers) == 0: if len(trackers) == 0:
return return
tracker = trackers[0] tracker = trackers[0]
tracker.last_timing = timing tracker.last_timing = timing
tracker.duration = timing.end_when - tracker.start tracker.duration = timing.end_when - tracker.start
tracker.save() STACKDB.save(tracker)
def aggregate_lifecycle(raw): def aggregate_lifecycle(raw):
@ -198,7 +197,7 @@ def aggregate_lifecycle(raw):
if timing.start_when: if timing.start_when:
timing.diff = timing.end_when - timing.start_when timing.diff = timing.end_when - timing.start_when
# Looks like a valid pair ... # Looks like a valid pair ...
update_kpi(lifecycle, timing, raw) update_kpi(timing, raw)
STACKDB.save(timing) STACKDB.save(timing)

View File

@ -1,6 +0,0 @@
import os
import sys
print "!!!!!!! %s" %__package__
#sys.path = [os.path.abspath(os.path.dirname(__package__))] + sys.path

View File

View File

@ -0,0 +1 @@
settings.py

View File

@ -0,0 +1,21 @@
import datetime
import decimal
import unittest
import utils
utils.setup_sys_path()
from stacktach import datetime_to_decimal
class DatetimeToDecimalTestCase(unittest.TestCase):
def test_datetime_to_decimal(self):
expected_decimal = decimal.Decimal('1356093296.123')
utc_datetime = datetime.datetime.utcfromtimestamp(expected_decimal)
actual_decimal = datetime_to_decimal.dt_to_decimal(utc_datetime)
self.assertEqual(actual_decimal, expected_decimal)
def test_decimal_to_datetime(self):
expected_decimal = decimal.Decimal('1356093296.123')
expected_datetime = datetime.datetime.utcfromtimestamp(expected_decimal)
actual_datetime = datetime_to_decimal.dt_from_decimal(expected_decimal)
self.assertEqual(actual_datetime, expected_datetime)

View File

@ -5,14 +5,16 @@ import unittest
import mox import mox
INSTANCE_ID_1 = 'testinstanceid1' import utils
INSTANCE_ID_2 = 'testinstanceid2' utils.setup_sys_path()
from utils import INSTANCE_ID_1
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' from utils import INSTANCE_ID_2
sys.path = [os.path.abspath(os.path.dirname('stacktach'))] + sys.path from utils import MESSAGE_ID_1
from utils import MESSAGE_ID_2
from utils import REQUEST_ID_1
from utils import REQUEST_ID_2
from utils import REQUEST_ID_3
from stacktach import views from stacktach import views
import test_utils as utils
class StacktachLifecycleTestCase(unittest.TestCase): class StacktachLifecycleTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
@ -20,15 +22,77 @@ class StacktachLifecycleTestCase(unittest.TestCase):
views.STACKDB = self.mox.CreateMockAnything() views.STACKDB = self.mox.CreateMockAnything()
def tearDown(self): def tearDown(self):
pass self.mox.UnsetStubs()
def test_start_kpi_tracking_not_update(self):
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.create.start'
self.mox.ReplayAll()
views.start_kpi_tracking(None, raw)
self.mox.VerifyAll()
def test_start_kpi_tracking_not_from_api(self):
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.update'
raw.host = 'compute'
self.mox.ReplayAll()
views.start_kpi_tracking(None, raw)
self.mox.VerifyAll()
def test_start_kpi_tracking(self):
lifecycle = self.mox.CreateMockAnything()
tracker = self.mox.CreateMockAnything()
when = utils.decimal_utcnow()
raw = utils.create_raw(self.mox, when, 'compute.instance.update',
host='api')
views.STACKDB.create_request_tracker(lifecycle=lifecycle,
request_id=REQUEST_ID_1,
start=when,
last_timing=None,
duration=str(0.0))\
.AndReturn(tracker)
views.STACKDB.save(tracker)
self.mox.ReplayAll()
views.start_kpi_tracking(lifecycle, raw)
self.mox.VerifyAll()
def test_update_kpi_no_trackers(self):
raw = self.mox.CreateMockAnything()
raw.request_id = REQUEST_ID_1
views.STACKDB.find_request_trackers(request_id=REQUEST_ID_1)\
.AndReturn([])
self.mox.ReplayAll()
views.update_kpi(None, raw)
self.mox.VerifyAll()
def test_update_kpi(self):
lifecycle = self.mox.CreateMockAnything()
end = utils.decimal_utcnow()
raw = self.mox.CreateMockAnything()
raw.request_id = REQUEST_ID_1
raw.when=end
timing = utils.create_timing(self.mox, 'compute.instance.create',
lifecycle, end_when=end)
start = utils.decimal_utcnow()
tracker = utils.create_tracker(self.mox, REQUEST_ID_1, lifecycle,
start)
views.STACKDB.find_request_trackers(request_id=REQUEST_ID_1)\
.AndReturn([tracker])
views.STACKDB.save(tracker)
self.mox.ReplayAll()
views.update_kpi(timing, raw)
self.assertEqual(tracker.request_id, REQUEST_ID_1)
self.assertEqual(tracker.lifecycle, lifecycle)
self.assertEqual(tracker.last_timing, timing)
self.assertEqual(tracker.start, start)
self.assertEqual(tracker.duration, end-start)
self.mox.VerifyAll()
def test_aggregate_lifecycle_no_instance(self): def test_aggregate_lifecycle_no_instance(self):
raw = self.mox.CreateMockAnything() raw = self.mox.CreateMockAnything()
raw.instance = None raw.instance = None
views.aggregate_lifecycle(raw)
self.mox.ReplayAll() self.mox.ReplayAll()
views.aggregate_lifecycle(raw)
self.mox.VerifyAll() self.mox.VerifyAll()
def test_aggregate_lifecycle_start(self): def test_aggregate_lifecycle_start(self):
@ -82,7 +146,7 @@ class StacktachLifecycleTestCase(unittest.TestCase):
views.STACKDB.find_timings(name=event_name, lifecycle=lifecycle).AndReturn([timing]) views.STACKDB.find_timings(name=event_name, lifecycle=lifecycle).AndReturn([timing])
self.mox.StubOutWithMock(views, "update_kpi") self.mox.StubOutWithMock(views, "update_kpi")
views.update_kpi(lifecycle, timing, end_raw) views.update_kpi(timing, end_raw)
views.STACKDB.save(timing) views.STACKDB.save(timing)
self.mox.ReplayAll() self.mox.ReplayAll()
@ -98,7 +162,6 @@ class StacktachLifecycleTestCase(unittest.TestCase):
self.assertEqual(timing.end_when, end_when) self.assertEqual(timing.end_when, end_when)
self.assertEqual(timing.diff, end_when-start_when) self.assertEqual(timing.diff, end_when-start_when)
self.mox.UnsetStubs()
self.mox.VerifyAll() self.mox.VerifyAll()
@ -122,5 +185,4 @@ class StacktachLifecycleTestCase(unittest.TestCase):
self.assertEqual(lifecycle.last_state, 'active') self.assertEqual(lifecycle.last_state, 'active')
self.assertEqual(lifecycle.last_task_state, 'reboot') self.assertEqual(lifecycle.last_task_state, 'reboot')
self.mox.UnsetStubs()
self.mox.VerifyAll() self.mox.VerifyAll()

View File

@ -1,3 +1,7 @@
import datetime
import os
import sys
import unittest
INSTANCE_ID_1 = 'testinstanceid1' INSTANCE_ID_1 = 'testinstanceid1'
INSTANCE_ID_2 = 'testinstanceid2' INSTANCE_ID_2 = 'testinstanceid2'
@ -9,6 +13,27 @@ REQUEST_ID_1 = 'testrequestid1'
REQUEST_ID_2 = 'testrequestid2' REQUEST_ID_2 = 'testrequestid2'
REQUEST_ID_3 = 'testrequestid3' REQUEST_ID_3 = 'testrequestid3'
def setup_sys_path():
sys.path = [os.path.abspath(os.path.dirname('stacktach'))] + sys.path
def setup_environment():
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
os.environ['STACKTACH_DB_ENGINE'] = 'django.db.backends.sqlite3'
when = str(datetime.datetime.utcnow())
os.environ['STACKTACH_DB_NAME'] = '/tmp/stacktach.%s.sqlite' % when
os.environ['STACKTACH_DB_HOST'] = ''
os.environ['STACKTACH_DB_USERNAME'] = ''
os.environ['STACKTACH_DB_PASSWORD'] = ''
install_dir = os.path.abspath(os.path.dirname('stacktach'))
os.environ['STACKTACH_INSTALL_DIR'] = install_dir
setup_sys_path()
setup_environment()
from stacktach import datetime_to_decimal as dt
def decimal_utcnow():
return dt.dt_to_decimal(datetime.datetime.utcnow())
def create_raw(mox, when, event, instance=INSTANCE_ID_1, def create_raw(mox, when, event, instance=INSTANCE_ID_1,
request_id=REQUEST_ID_1, state='active', old_task='', request_id=REQUEST_ID_1, state='active', old_task='',
host='compute', json=''): host='compute', json=''):
@ -19,7 +44,7 @@ def create_raw(mox, when, event, instance=INSTANCE_ID_1,
raw.when = when raw.when = when
raw.state = state raw.state = state
raw.old_task = old_task raw.old_task = old_task
raw.request_id = request_id, raw.request_id = request_id
raw.json = json raw.json = json
return raw return raw
@ -42,3 +67,13 @@ def create_timing(mox, name, lifecycle, start_raw=None, start_when=None,
timing.end_when = end_when timing.end_when = end_when
timing.diff = diff timing.diff = diff
return timing return timing
def create_tracker(mox, request_id, lifecycle, start, last_timing=None,
duration=str(0.0)):
tracker = mox.CreateMockAnything()
tracker.request_id=request_id
tracker.lifecycle=lifecycle
tracker.start=start
tracker.last_timing=last_timing
tracker.duration=duration
return tracker

28
tox.ini
View File

@ -1,28 +0,0 @@
[tox]
envlist = py26,py27,pep8
[testenv]
setenv = VIRTUAL_ENV={envdir}
# NOSE_WITH_OPENSTACK=1
# NOSE_OPENSTACK_COLOR=1
# NOSE_OPENSTACK_RED=0.05
# NOSE_OPENSTACK_YELLOW=0.025
# NOSE_OPENSTACK_SHOW_ELAPSED=1
# NOSE_OPENSTACK_STDOUT=1
#deps = -r{toxinidir}/tools/pip-requires
# -r{toxinidir}/tools/test-requires
#commands = nosetests {posargs}
[tox:jenkins]
downloadcache = ~/cache/pip
[testenv:pep8]
deps = pep8==1.3.3
commands =
pep8 --ignore=E125,E126,E711,E712 --repeat --show-source --exclude=.venv,.tox,dist,doc,openstack .
[testenv:cover]
setenv = NOSE_WITH_COVERAGE=1
[testenv:venv]
commands = {posargs}