Added tenant_id in verification of instanceexists and instanceusages
This commit is contained in:
parent
6af84ef178
commit
25fa31ffc5
3
.gitignore
vendored
3
.gitignore
vendored
@ -7,3 +7,6 @@ worker.log
|
|||||||
worker.log.*
|
worker.log.*
|
||||||
etc/stacktach_config.sh
|
etc/stacktach_config.sh
|
||||||
etc/stacktach_worker_config.json
|
etc/stacktach_worker_config.json
|
||||||
|
etc/stacktach_verifier_config.json
|
||||||
|
verifier.log
|
||||||
|
verifier.log.*
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE stacktach_instanceexists ADD `tenant` varchar(50);
|
||||||
|
CREATE INDEX `stacktach_instanceexists_1384d482` ON `stacktach_instanceexists` (`tenant`);
|
||||||
|
|
||||||
|
ALTER TABLE stacktach_instanceusage ADD `tenant` varchar(50);
|
||||||
|
CREATE INDEX `stacktach_instanceusage_1384d482` ON `stacktach_instanceusage` (`tenant`);
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
# Copyright (c) 2013 - Rackspace Inc.
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||||
|
os.pardir, os.pardir))
|
||||||
|
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'stacktach')):
|
||||||
|
sys.path.insert(0, POSSIBLE_TOPDIR)
|
||||||
|
|
||||||
|
from stacktach import models
|
||||||
|
|
||||||
|
if __name__ != '__main__':
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def add_past_exists(instance_tenant_id_maps):
|
||||||
|
update_count = 0
|
||||||
|
for map in instance_tenant_id_maps:
|
||||||
|
update_count += models.InstanceExists.objects.filter(instance=map['instance']).update(tenant=map['tenant'])
|
||||||
|
print "updated %s rows" % update_count
|
||||||
|
|
||||||
|
distinct_exists_instances = models.InstanceExists.objects.all().values('instance').distinct()
|
||||||
|
instance_tenant_id_maps = models.RawData.objects.filter(instance__in=distinct_exists_instances).distinct().values('instance', 'tenant')
|
||||||
|
add_past_exists(instance_tenant_id_maps)
|
@ -0,0 +1,43 @@
|
|||||||
|
# Copyright (c) 2013 - Rackspace Inc.
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||||
|
os.pardir, os.pardir))
|
||||||
|
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'stacktach')):
|
||||||
|
sys.path.insert(0, POSSIBLE_TOPDIR)
|
||||||
|
|
||||||
|
from stacktach import models
|
||||||
|
|
||||||
|
if __name__ != '__main__':
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def add_past_usages(instance_tenant_id_maps):
|
||||||
|
update_count = 0
|
||||||
|
for map in instance_tenant_id_maps:
|
||||||
|
update_count += models.InstanceUsage.objects.filter(instance=map['instance']).update(tenant=map['tenant'])
|
||||||
|
print "updated %s rows" % update_count
|
||||||
|
|
||||||
|
distinct_usage_instances = models.InstanceUsage.objects.all().values('instance').distinct()
|
||||||
|
instance_tenant_id_maps = models.RawData.objects.filter(instance__in=distinct_usage_instances).distinct().values('instance', 'tenant')
|
||||||
|
add_past_usages(instance_tenant_id_maps)
|
@ -86,7 +86,8 @@ class InstanceUsage(models.Model):
|
|||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
db_index=True)
|
db_index=True)
|
||||||
|
tenant = models.CharField(max_length=50, null=True, blank=True,
|
||||||
|
db_index=True)
|
||||||
|
|
||||||
class InstanceDeletes(models.Model):
|
class InstanceDeletes(models.Model):
|
||||||
instance = models.CharField(max_length=50, null=True,
|
instance = models.CharField(max_length=50, null=True,
|
||||||
@ -135,6 +136,8 @@ class InstanceExists(models.Model):
|
|||||||
usage = models.ForeignKey(InstanceUsage, related_name='+', null=True)
|
usage = models.ForeignKey(InstanceUsage, related_name='+', null=True)
|
||||||
delete = models.ForeignKey(InstanceDeletes, related_name='+', null=True)
|
delete = models.ForeignKey(InstanceDeletes, related_name='+', null=True)
|
||||||
send_status = models.IntegerField(null=True, default=0, db_index=True)
|
send_status = models.IntegerField(null=True, default=0, db_index=True)
|
||||||
|
tenant = models.CharField(max_length=50, null=True, blank=True,
|
||||||
|
db_index=True)
|
||||||
|
|
||||||
|
|
||||||
class Timing(models.Model):
|
class Timing(models.Model):
|
||||||
|
@ -180,7 +180,8 @@ def make_resize_revert_end_json(launched_at, instance_type_id='1',
|
|||||||
|
|
||||||
def create_raw(deployment, when, event, instance=INSTANCE_ID_1,
|
def create_raw(deployment, 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', service='compute', json=''):
|
host='compute', service='compute', json='',
|
||||||
|
tenant='default_tenant_id'):
|
||||||
raw_values = {
|
raw_values = {
|
||||||
'deployment': deployment,
|
'deployment': deployment,
|
||||||
'host': host,
|
'host': host,
|
||||||
@ -191,7 +192,8 @@ def create_raw(deployment, when, event, instance=INSTANCE_ID_1,
|
|||||||
'event': event,
|
'event': event,
|
||||||
'instance': instance,
|
'instance': instance,
|
||||||
'request_id': request_id,
|
'request_id': request_id,
|
||||||
'json': json
|
'json': json,
|
||||||
|
'tenant': tenant
|
||||||
}
|
}
|
||||||
raw = RawData(**raw_values)
|
raw = RawData(**raw_values)
|
||||||
raw.save()
|
raw.save()
|
||||||
|
@ -240,6 +240,7 @@ def _process_usage_for_new_launch(raw, body):
|
|||||||
# though, because we may have already received the end event
|
# though, because we may have already received the end event
|
||||||
usage.launched_at = utils.str_time_to_unix(payload['launched_at'])
|
usage.launched_at = utils.str_time_to_unix(payload['launched_at'])
|
||||||
|
|
||||||
|
usage.tenant = payload['tenant_id']
|
||||||
STACKDB.save(usage)
|
STACKDB.save(usage)
|
||||||
|
|
||||||
|
|
||||||
@ -261,6 +262,7 @@ def _process_usage_for_updates(raw, body):
|
|||||||
elif raw.event == INSTANCE_EVENT['resize_prep_end']:
|
elif raw.event == INSTANCE_EVENT['resize_prep_end']:
|
||||||
usage.instance_type_id = payload['new_instance_type_id']
|
usage.instance_type_id = payload['new_instance_type_id']
|
||||||
|
|
||||||
|
usage.tenant = payload['tenant_id']
|
||||||
STACKDB.save(usage)
|
STACKDB.save(usage)
|
||||||
|
|
||||||
|
|
||||||
@ -302,6 +304,7 @@ def _process_exists(raw, body):
|
|||||||
if usage:
|
if usage:
|
||||||
values['usage'] = usage
|
values['usage'] = usage
|
||||||
values['raw'] = raw
|
values['raw'] = raw
|
||||||
|
values['tenant'] = payload['tenant_id']
|
||||||
|
|
||||||
deleted_at = payload.get('deleted_at')
|
deleted_at = payload.get('deleted_at')
|
||||||
if deleted_at and deleted_at != '':
|
if deleted_at and deleted_at != '':
|
||||||
|
@ -20,21 +20,18 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import mox
|
import mox
|
||||||
|
|
||||||
import utils
|
import utils
|
||||||
from utils import INSTANCE_ID_1
|
from utils import INSTANCE_ID_1
|
||||||
from utils import INSTANCE_ID_2
|
|
||||||
from utils import MESSAGE_ID_1
|
from utils import MESSAGE_ID_1
|
||||||
from utils import MESSAGE_ID_2
|
|
||||||
from utils import REQUEST_ID_1
|
from utils import REQUEST_ID_1
|
||||||
from utils import REQUEST_ID_2
|
|
||||||
from utils import REQUEST_ID_3
|
|
||||||
from utils import TENANT_ID_1
|
from utils import TENANT_ID_1
|
||||||
|
from utils import INSTANCE_TYPE_ID_1
|
||||||
|
from utils import DUMMY_TIME
|
||||||
|
from utils import INSTANCE_TYPE_ID_2
|
||||||
from stacktach import views
|
from stacktach import views
|
||||||
|
|
||||||
|
|
||||||
@ -415,7 +412,7 @@ class StacktachLifecycleTestCase(unittest.TestCase):
|
|||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
|
||||||
class StacktackUsageParsingTestCase(unittest.TestCase):
|
class StacktachUsageParsingTestCase(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.mox = mox.Mox()
|
self.mox = mox.Mox()
|
||||||
views.STACKDB = self.mox.CreateMockAnything()
|
views.STACKDB = self.mox.CreateMockAnything()
|
||||||
@ -423,137 +420,142 @@ class StacktackUsageParsingTestCase(unittest.TestCase):
|
|||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.mox.UnsetStubs()
|
self.mox.UnsetStubs()
|
||||||
|
|
||||||
def test_process_usage_for_new_launch(self):
|
def test_process_usage_for_new_launch_create_start(self):
|
||||||
when = utils.decimal_utc()
|
kwargs = {'launched': str(DUMMY_TIME), 'tenant_id': TENANT_ID_1 }
|
||||||
notif = utils.create_nova_notif(request_id=REQUEST_ID_1)
|
notification = utils.create_nova_notif(request_id=REQUEST_ID_1, **kwargs)
|
||||||
json_str = json.dumps(notif)
|
|
||||||
event = 'compute.instance.create.start'
|
event = 'compute.instance.create.start'
|
||||||
raw = utils.create_raw(self.mox, when, event=event, json_str=json_str)
|
raw, usage = self._setup_process_usage_mocks(event, notification)
|
||||||
usage = self.mox.CreateMockAnything()
|
|
||||||
views.STACKDB.get_or_create_instance_usage(instance=INSTANCE_ID_1,
|
views._process_usage_for_new_launch(raw, notification[1])
|
||||||
request_id=REQUEST_ID_1)\
|
|
||||||
.AndReturn((usage, True))
|
|
||||||
views.STACKDB.save(usage)
|
|
||||||
self.mox.ReplayAll()
|
|
||||||
views._process_usage_for_new_launch(raw, notif[1])
|
|
||||||
self.assertEquals(usage.instance_type_id, '1')
|
self.assertEquals(usage.instance_type_id, '1')
|
||||||
|
self.assertEquals(usage.tenant, TENANT_ID_1)
|
||||||
|
|
||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
def test_process_usage_for_new_launch_resize_no_launched_at_in_db(self):
|
def test_process_usage_for_new_launch_rebuild_start(self):
|
||||||
now = datetime.datetime.utcnow()
|
kwargs = {'launched': str(DUMMY_TIME), 'tenant_id': TENANT_ID_1}
|
||||||
when = utils.decimal_utc(now)
|
notification = utils.create_nova_notif(request_id=REQUEST_ID_1, **kwargs)
|
||||||
notif = utils.create_nova_notif(request_id=REQUEST_ID_1,
|
event = 'compute.instance.rebuild.start'
|
||||||
launched=str(now))
|
raw, usage = self._setup_process_usage_mocks(event, notification)
|
||||||
json_str = json.dumps(notif)
|
|
||||||
event = 'compute.instance.resize.prep.start'
|
views._process_usage_for_new_launch(raw, notification[1])
|
||||||
raw = utils.create_raw(self.mox, when, event=event, json_str=json_str)
|
|
||||||
usage = self.mox.CreateMockAnything()
|
self.assertEquals(usage.instance_type_id, '1')
|
||||||
|
self.assertEquals(usage.tenant, TENANT_ID_1)
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
def test_process_usage_for_new_launch_rebuild_start_when_no_launched_at_in_db(self):
|
||||||
|
kwargs = {'launched': str(DUMMY_TIME), 'tenant_id': TENANT_ID_1}
|
||||||
|
notification = utils.create_nova_notif(request_id=REQUEST_ID_1, **kwargs)
|
||||||
|
event = 'compute.instance.rebuild.start'
|
||||||
|
raw, usage = self._setup_process_usage_mocks(event, notification)
|
||||||
usage.launched_at = None
|
usage.launched_at = None
|
||||||
views.STACKDB.get_or_create_instance_usage(instance=INSTANCE_ID_1,
|
|
||||||
request_id=REQUEST_ID_1) \
|
views._process_usage_for_new_launch(raw, notification[1])
|
||||||
.AndReturn((usage, True))
|
|
||||||
views.STACKDB.save(usage)
|
self.assertEqual(usage.launched_at, utils.decimal_utc(DUMMY_TIME))
|
||||||
self.mox.ReplayAll()
|
self.assertEquals(usage.tenant, TENANT_ID_1)
|
||||||
views._process_usage_for_new_launch(raw, notif[1])
|
|
||||||
self.assertEqual(usage.launched_at, when)
|
|
||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
def test_process_usage_for_new_launch_resize_launched_at_in_db(self):
|
def test_process_usage_for_new_launch_resize_prep_start_when_no_launched_at_in_db(self):
|
||||||
now = datetime.datetime.utcnow()
|
kwargs = {'launched': str(DUMMY_TIME), 'tenant_id': TENANT_ID_1}
|
||||||
when = utils.decimal_utc(now)
|
notification = utils.create_nova_notif(request_id=REQUEST_ID_1, **kwargs)
|
||||||
notif = utils.create_nova_notif(request_id=REQUEST_ID_1,
|
|
||||||
launched=str(now))
|
|
||||||
json_str = json.dumps(notif)
|
|
||||||
event = 'compute.instance.resize.prep.start'
|
event = 'compute.instance.resize.prep.start'
|
||||||
raw = utils.create_raw(self.mox, when, event=event, json_str=json_str)
|
raw, usage = self._setup_process_usage_mocks(event, notification)
|
||||||
usage = self.mox.CreateMockAnything()
|
usage.launched_at = None
|
||||||
orig_launched_at = utils.decimal_utc(now - datetime.timedelta(days=1))
|
|
||||||
|
views._process_usage_for_new_launch(raw, notification[1])
|
||||||
|
|
||||||
|
self.assertEqual(usage.launched_at, utils.decimal_utc(DUMMY_TIME))
|
||||||
|
self.assertEquals(usage.tenant, TENANT_ID_1)
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
def test_process_usage_for_new_launch_resize_revert_start_when_no_launched_at_in_db(self):
|
||||||
|
kwargs = {'launched': str(DUMMY_TIME), 'tenant_id': TENANT_ID_1}
|
||||||
|
notification = utils.create_nova_notif(request_id=REQUEST_ID_1, **kwargs)
|
||||||
|
event = 'compute.instance.resize.revert.start'
|
||||||
|
raw, usage = self._setup_process_usage_mocks(event, notification)
|
||||||
|
usage.launched_at = None
|
||||||
|
|
||||||
|
views._process_usage_for_new_launch(raw, notification[1])
|
||||||
|
|
||||||
|
self.assertEquals(usage.tenant, TENANT_ID_1)
|
||||||
|
self.assertEqual(usage.launched_at, utils.decimal_utc(DUMMY_TIME))
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
def test_process_usage_for_new_launch_resize_prep_start_when_launched_at_in_db(self):
|
||||||
|
kwargs = {'launched': str(DUMMY_TIME), 'tenant_id': TENANT_ID_1}
|
||||||
|
notification = utils.create_nova_notif(request_id=REQUEST_ID_1, **kwargs)
|
||||||
|
event = 'compute.instance.resize.prep.start'
|
||||||
|
raw, usage = self._setup_process_usage_mocks(event, notification)
|
||||||
|
orig_launched_at = utils.decimal_utc(DUMMY_TIME - datetime.timedelta(days=1))
|
||||||
usage.launched_at = orig_launched_at
|
usage.launched_at = orig_launched_at
|
||||||
|
|
||||||
|
views._process_usage_for_new_launch(raw, notification[1])
|
||||||
|
|
||||||
|
self.assertEqual(usage.launched_at, orig_launched_at)
|
||||||
|
self.assertEqual(usage.tenant, TENANT_ID_1)
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
def test_process_usage_for_updates_create_end(self):
|
||||||
|
kwargs = {'launched': str(DUMMY_TIME), 'tenant_id': TENANT_ID_1}
|
||||||
|
notification = utils.create_nova_notif(request_id=REQUEST_ID_1, **kwargs)
|
||||||
|
event = 'compute.instance.create.end'
|
||||||
|
raw, usage = self._setup_process_usage_mocks(event, notification)
|
||||||
|
|
||||||
|
views._process_usage_for_updates(raw, notification[1])
|
||||||
|
|
||||||
|
self.assertEqual(usage.launched_at, utils.decimal_utc(DUMMY_TIME))
|
||||||
|
self.assertEqual(usage.tenant, TENANT_ID_1)
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
def test_process_usage_for_updates_revert_end(self):
|
||||||
|
kwargs = {'launched': str(DUMMY_TIME), 'type_id': INSTANCE_TYPE_ID_1, 'tenant_id': TENANT_ID_1}
|
||||||
|
notification = utils.create_nova_notif(request_id=REQUEST_ID_1, **kwargs)
|
||||||
|
event = 'compute.instance.resize.revert.end'
|
||||||
|
raw, usage = self._setup_process_usage_mocks(event, notification)
|
||||||
|
|
||||||
|
views._process_usage_for_updates(raw, notification[1])
|
||||||
|
|
||||||
|
self.assertEqual(usage.instance_type_id, INSTANCE_TYPE_ID_1)
|
||||||
|
self.assertEqual(usage.launched_at, utils.decimal_utc(DUMMY_TIME))
|
||||||
|
self.assertEquals(usage.tenant, TENANT_ID_1)
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
def test_process_usage_for_updates_prep_end(self):
|
||||||
|
kwargs = {'launched': str(DUMMY_TIME), 'new_type_id': INSTANCE_TYPE_ID_2, 'tenant_id': TENANT_ID_1}
|
||||||
|
notification = utils.create_nova_notif(request_id=REQUEST_ID_1, **kwargs)
|
||||||
|
event = 'compute.instance.resize.prep.end'
|
||||||
|
raw, usage = self._setup_process_usage_mocks(event, notification)
|
||||||
|
|
||||||
|
views._process_usage_for_updates(raw, notification[1])
|
||||||
|
|
||||||
|
self.assertEqual(usage.instance_type_id, INSTANCE_TYPE_ID_2)
|
||||||
|
self.assertEquals(usage.tenant, TENANT_ID_1)
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
def _setup_process_usage_mocks(self, event, notification):
|
||||||
|
when_time = DUMMY_TIME
|
||||||
|
when_decimal = utils.decimal_utc(when_time)
|
||||||
|
json_str = json.dumps(notification)
|
||||||
|
raw = utils.create_raw(self.mox, when_decimal, event=event,
|
||||||
|
json_str=json_str)
|
||||||
|
usage = self.mox.CreateMockAnything()
|
||||||
views.STACKDB.get_or_create_instance_usage(instance=INSTANCE_ID_1,
|
views.STACKDB.get_or_create_instance_usage(instance=INSTANCE_ID_1,
|
||||||
request_id=REQUEST_ID_1) \
|
request_id=REQUEST_ID_1) \
|
||||||
.AndReturn((usage, True))
|
.AndReturn((usage, True))
|
||||||
views.STACKDB.save(usage)
|
views.STACKDB.save(usage)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
views._process_usage_for_new_launch(raw, notif[1])
|
return raw, usage
|
||||||
self.assertEqual(usage.launched_at, orig_launched_at)
|
|
||||||
self.mox.VerifyAll()
|
|
||||||
|
|
||||||
def test_process_usage_for_updates_create_end(self):
|
|
||||||
when_time = datetime.datetime.utcnow()
|
|
||||||
when_str = str(when_time)
|
|
||||||
when_decimal = utils.decimal_utc(when_time)
|
|
||||||
notif = utils.create_nova_notif(request_id=REQUEST_ID_1,
|
|
||||||
launched=str(when_time))
|
|
||||||
json_str = json.dumps(notif)
|
|
||||||
event = 'compute.instance.create.end'
|
|
||||||
raw = utils.create_raw(self.mox, when_decimal, event=event,
|
|
||||||
json_str=json_str)
|
|
||||||
usage = self.mox.CreateMockAnything()
|
|
||||||
usage.instance = INSTANCE_ID_1
|
|
||||||
usage.request_id = REQUEST_ID_1
|
|
||||||
usage.instance_type_id = '1'
|
|
||||||
views.STACKDB.get_or_create_instance_usage(instance=INSTANCE_ID_1,
|
|
||||||
request_id=REQUEST_ID_1)\
|
|
||||||
.AndReturn((usage, True))
|
|
||||||
views.STACKDB.save(usage)
|
|
||||||
self.mox.ReplayAll()
|
|
||||||
|
|
||||||
views._process_usage_for_updates(raw, notif[1])
|
|
||||||
self.assertEqual(usage.instance, INSTANCE_ID_1)
|
|
||||||
self.assertEqual(usage.request_id, REQUEST_ID_1)
|
|
||||||
self.assertEqual(usage.instance_type_id, '1')
|
|
||||||
self.assertEqual(usage.launched_at, when_decimal)
|
|
||||||
self.mox.VerifyAll()
|
|
||||||
|
|
||||||
def test_process_usage_for_updates_revert_end(self):
|
|
||||||
when_time = datetime.datetime.utcnow()
|
|
||||||
when_decimal = utils.decimal_utc(when_time)
|
|
||||||
notif = utils.create_nova_notif(request_id=REQUEST_ID_1,
|
|
||||||
launched=str(when_time))
|
|
||||||
json_str = json.dumps(notif)
|
|
||||||
event = 'compute.instance.resize.revert.end'
|
|
||||||
raw = utils.create_raw(self.mox, when_decimal, event=event,
|
|
||||||
json_str=json_str)
|
|
||||||
usage = self.mox.CreateMockAnything()
|
|
||||||
usage.instance = INSTANCE_ID_1
|
|
||||||
usage.request_id = REQUEST_ID_1
|
|
||||||
usage.instance_type_id = '1'
|
|
||||||
views.STACKDB.get_or_create_instance_usage(instance=INSTANCE_ID_1,
|
|
||||||
request_id=REQUEST_ID_1)\
|
|
||||||
.AndReturn((usage, True))
|
|
||||||
views.STACKDB.save(usage)
|
|
||||||
self.mox.ReplayAll()
|
|
||||||
|
|
||||||
views._process_usage_for_updates(raw, notif[1])
|
|
||||||
self.assertEqual(usage.instance, INSTANCE_ID_1)
|
|
||||||
self.assertEqual(usage.request_id, REQUEST_ID_1)
|
|
||||||
self.assertEqual(usage.instance_type_id, '1')
|
|
||||||
self.assertEqual(usage.launched_at, when_decimal)
|
|
||||||
self.mox.VerifyAll()
|
|
||||||
|
|
||||||
def test_process_usage_for_updates_prep_end(self):
|
|
||||||
when_time = datetime.datetime.utcnow()
|
|
||||||
when_decimal = utils.decimal_utc(when_time)
|
|
||||||
notif = utils.create_nova_notif(request_id=REQUEST_ID_1,
|
|
||||||
new_type_id='2')
|
|
||||||
json_str = json.dumps(notif)
|
|
||||||
event = 'compute.instance.resize.prep.end'
|
|
||||||
raw = utils.create_raw(self.mox, when_decimal, event=event,
|
|
||||||
json_str=json_str)
|
|
||||||
usage = self.mox.CreateMockAnything()
|
|
||||||
usage.instance = INSTANCE_ID_1
|
|
||||||
usage.request_id = REQUEST_ID_1
|
|
||||||
views.STACKDB.get_or_create_instance_usage(instance=INSTANCE_ID_1,
|
|
||||||
request_id=REQUEST_ID_1)\
|
|
||||||
.AndReturn((usage, True))
|
|
||||||
views.STACKDB.save(usage)
|
|
||||||
self.mox.ReplayAll()
|
|
||||||
|
|
||||||
views._process_usage_for_updates(raw, notif[1])
|
|
||||||
self.assertEqual(usage.instance, INSTANCE_ID_1)
|
|
||||||
self.assertEqual(usage.request_id, REQUEST_ID_1)
|
|
||||||
self.assertEqual(usage.instance_type_id, '2')
|
|
||||||
self.mox.VerifyAll()
|
|
||||||
|
|
||||||
def test_process_delete(self):
|
def test_process_delete(self):
|
||||||
delete_time = datetime.datetime.utcnow()
|
delete_time = datetime.datetime.utcnow()
|
||||||
@ -619,7 +621,8 @@ class StacktackUsageParsingTestCase(unittest.TestCase):
|
|||||||
audit_ending_decimal = utils.decimal_utc(current_time)
|
audit_ending_decimal = utils.decimal_utc(current_time)
|
||||||
notif = utils.create_nova_notif(launched=str(launch_time),
|
notif = utils.create_nova_notif(launched=str(launch_time),
|
||||||
audit_period_beginning=str(audit_beginning),
|
audit_period_beginning=str(audit_beginning),
|
||||||
audit_period_ending=str(current_time))
|
audit_period_ending=str(current_time),
|
||||||
|
tenant_id=TENANT_ID_1)
|
||||||
json_str = json.dumps(notif)
|
json_str = json.dumps(notif)
|
||||||
event = 'compute.instance.exists'
|
event = 'compute.instance.exists'
|
||||||
raw = utils.create_raw(self.mox, current_decimal, event=event,
|
raw = utils.create_raw(self.mox, current_decimal, event=event,
|
||||||
@ -638,6 +641,7 @@ class StacktackUsageParsingTestCase(unittest.TestCase):
|
|||||||
'instance_type_id': '1',
|
'instance_type_id': '1',
|
||||||
'usage': usage,
|
'usage': usage,
|
||||||
'raw': raw,
|
'raw': raw,
|
||||||
|
'tenant': TENANT_ID_1
|
||||||
}
|
}
|
||||||
exists = self.mox.CreateMockAnything()
|
exists = self.mox.CreateMockAnything()
|
||||||
views.STACKDB.create_instance_exists(**exists_values).AndReturn(exists)
|
views.STACKDB.create_instance_exists(**exists_values).AndReturn(exists)
|
||||||
@ -659,7 +663,8 @@ class StacktackUsageParsingTestCase(unittest.TestCase):
|
|||||||
notif = utils.create_nova_notif(launched=str(launch_time),
|
notif = utils.create_nova_notif(launched=str(launch_time),
|
||||||
deleted=str(deleted_time),
|
deleted=str(deleted_time),
|
||||||
audit_period_beginning=str(audit_beginning),
|
audit_period_beginning=str(audit_beginning),
|
||||||
audit_period_ending=str(current_time))
|
audit_period_ending=str(current_time),
|
||||||
|
tenant_id= TENANT_ID_1)
|
||||||
json_str = json.dumps(notif)
|
json_str = json.dumps(notif)
|
||||||
event = 'compute.instance.exists'
|
event = 'compute.instance.exists'
|
||||||
raw = utils.create_raw(self.mox, current_decimal, event=event,
|
raw = utils.create_raw(self.mox, current_decimal, event=event,
|
||||||
@ -684,6 +689,7 @@ class StacktackUsageParsingTestCase(unittest.TestCase):
|
|||||||
'usage': usage,
|
'usage': usage,
|
||||||
'delete': delete,
|
'delete': delete,
|
||||||
'raw': raw,
|
'raw': raw,
|
||||||
|
'tenant': TENANT_ID_1
|
||||||
}
|
}
|
||||||
exists = self.mox.CreateMockAnything()
|
exists = self.mox.CreateMockAnything()
|
||||||
views.STACKDB.create_instance_exists(**exists_values).AndReturn(exists)
|
views.STACKDB.create_instance_exists(**exists_values).AndReturn(exists)
|
||||||
|
@ -32,10 +32,10 @@ import multiprocessing
|
|||||||
|
|
||||||
from stacktach import datetime_to_decimal as dt
|
from stacktach import datetime_to_decimal as dt
|
||||||
from stacktach import models
|
from stacktach import models
|
||||||
import utils
|
|
||||||
from utils import INSTANCE_ID_1
|
from utils import INSTANCE_ID_1
|
||||||
from utils import INSTANCE_ID_2
|
from utils import TENANT_ID_1
|
||||||
from utils import REQUEST_ID_1
|
from utils import TENANT_ID_2
|
||||||
|
from utils import INSTANCE_TYPE_ID_1
|
||||||
|
|
||||||
from verifier import dbverifier
|
from verifier import dbverifier
|
||||||
from verifier import AmbiguousResults
|
from verifier import AmbiguousResults
|
||||||
@ -75,14 +75,18 @@ class VerifierTestCase(unittest.TestCase):
|
|||||||
|
|
||||||
def test_verify_for_launch(self):
|
def test_verify_for_launch(self):
|
||||||
exist = self.mox.CreateMockAnything()
|
exist = self.mox.CreateMockAnything()
|
||||||
exist.usage = self.mox.CreateMockAnything()
|
|
||||||
exist.launched_at = decimal.Decimal('1.1')
|
exist.launched_at = decimal.Decimal('1.1')
|
||||||
exist.instance_type_id = 2
|
exist.instance_type_id = INSTANCE_TYPE_ID_1
|
||||||
|
exist.tenant = TENANT_ID_1
|
||||||
|
|
||||||
|
exist.usage = self.mox.CreateMockAnything()
|
||||||
exist.usage.launched_at = decimal.Decimal('1.1')
|
exist.usage.launched_at = decimal.Decimal('1.1')
|
||||||
exist.usage.instance_type_id = 2
|
exist.usage.instance_type_id = INSTANCE_TYPE_ID_1
|
||||||
|
exist.usage.tenant = TENANT_ID_1
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
dbverifier._verify_for_launch(exist)
|
dbverifier._verify_for_launch(exist)
|
||||||
|
|
||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
def test_verify_for_launch_launched_at_in_range(self):
|
def test_verify_for_launch_launched_at_in_range(self):
|
||||||
@ -137,6 +141,24 @@ class VerifierTestCase(unittest.TestCase):
|
|||||||
|
|
||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
def test_verify_for_launch_tenant_id_mismatch(self):
|
||||||
|
exist = self.mox.CreateMockAnything()
|
||||||
|
exist.tenant = TENANT_ID_1
|
||||||
|
|
||||||
|
exist.usage = self.mox.CreateMockAnything()
|
||||||
|
exist.usage.tenant = TENANT_ID_2
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
with self.assertRaises(FieldMismatch) as cm:
|
||||||
|
dbverifier._verify_for_launch(exist)
|
||||||
|
exception = cm.exception
|
||||||
|
|
||||||
|
self.assertEqual(exception.field_name, 'tenant')
|
||||||
|
self.assertEqual(exception.expected, TENANT_ID_1)
|
||||||
|
self.assertEqual(exception.actual, TENANT_ID_2)
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
def test_verify_for_launch_late_usage(self):
|
def test_verify_for_launch_late_usage(self):
|
||||||
exist = self.mox.CreateMockAnything()
|
exist = self.mox.CreateMockAnything()
|
||||||
exist.usage = None
|
exist.usage = None
|
||||||
|
@ -19,17 +19,20 @@
|
|||||||
# IN THE SOFTWARE.
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
TENANT_ID_1 = 'testtenantid1'
|
TENANT_ID_1 = 'testtenantid1'
|
||||||
|
TENANT_ID_2 = 'testtenantid2'
|
||||||
|
|
||||||
from stacktach import datetime_to_decimal as dt
|
from stacktach import datetime_to_decimal as dt
|
||||||
|
|
||||||
INSTANCE_ID_1 = "08f685d9-6352-4dbc-8271-96cc54bf14cd"
|
INSTANCE_ID_1 = "08f685d9-6352-4dbc-8271-96cc54bf14cd"
|
||||||
INSTANCE_ID_2 = "515adf96-41d3-b86d-5467-e584edc61dab"
|
INSTANCE_ID_2 = "515adf96-41d3-b86d-5467-e584edc61dab"
|
||||||
|
|
||||||
|
INSTANCE_TYPE_ID_1 = "12345"
|
||||||
|
INSTANCE_TYPE_ID_2 = '54321'
|
||||||
|
|
||||||
|
DUMMY_TIME = datetime.datetime.utcnow()
|
||||||
|
|
||||||
MESSAGE_ID_1 = "7f28f81b-29a2-43f2-9ba1-ccb3e53ab6c8"
|
MESSAGE_ID_1 = "7f28f81b-29a2-43f2-9ba1-ccb3e53ab6c8"
|
||||||
MESSAGE_ID_2 = "4d596126-0f04-4329-865f-7b9a7bd69bcf"
|
MESSAGE_ID_2 = "4d596126-0f04-4329-865f-7b9a7bd69bcf"
|
||||||
|
|
||||||
@ -45,7 +48,7 @@ def decimal_utc(t = datetime.datetime.utcnow()):
|
|||||||
def create_nova_notif(request_id=None, instance=INSTANCE_ID_1, type_id='1',
|
def create_nova_notif(request_id=None, instance=INSTANCE_ID_1, type_id='1',
|
||||||
launched=None, deleted=None, new_type_id=None,
|
launched=None, deleted=None, new_type_id=None,
|
||||||
message_id=MESSAGE_ID_1, audit_period_beginning=None,
|
message_id=MESSAGE_ID_1, audit_period_beginning=None,
|
||||||
audit_period_ending=None):
|
audit_period_ending=None, tenant_id = None):
|
||||||
notif = ['', {
|
notif = ['', {
|
||||||
'message_id': message_id,
|
'message_id': message_id,
|
||||||
'payload': {
|
'payload': {
|
||||||
@ -66,6 +69,8 @@ def create_nova_notif(request_id=None, instance=INSTANCE_ID_1, type_id='1',
|
|||||||
notif[1]['payload']['audit_period_beginning'] = audit_period_beginning
|
notif[1]['payload']['audit_period_beginning'] = audit_period_beginning
|
||||||
if audit_period_ending:
|
if audit_period_ending:
|
||||||
notif[1]['payload']['audit_period_ending'] = audit_period_ending
|
notif[1]['payload']['audit_period_ending'] = audit_period_ending
|
||||||
|
if tenant_id:
|
||||||
|
notif[1]['payload']['tenant_id'] = tenant_id
|
||||||
|
|
||||||
return notif
|
return notif
|
||||||
|
|
||||||
|
@ -126,6 +126,21 @@ def _verify_date_field(d1, d2, same_second=False):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _verify_field_mismatch(exists, launch):
|
||||||
|
if not _verify_date_field(launch.launched_at, exists.launched_at,
|
||||||
|
same_second=True):
|
||||||
|
raise FieldMismatch('launched_at', exists.launched_at,
|
||||||
|
launch.launched_at)
|
||||||
|
|
||||||
|
if launch.instance_type_id != exists.instance_type_id:
|
||||||
|
raise FieldMismatch('instance_type_id', exists.instance_type_id,
|
||||||
|
launch.instance_type_id)
|
||||||
|
|
||||||
|
if launch.tenant != exists.tenant:
|
||||||
|
raise FieldMismatch('tenant', exists.tenant,
|
||||||
|
launch.tenant)
|
||||||
|
|
||||||
|
|
||||||
def _verify_for_launch(exist):
|
def _verify_for_launch(exist):
|
||||||
if exist.usage:
|
if exist.usage:
|
||||||
launch = exist.usage
|
launch = exist.usage
|
||||||
@ -147,14 +162,7 @@ def _verify_for_launch(exist):
|
|||||||
else:
|
else:
|
||||||
raise NotFound('InstanceUsage', {'instance': exist.instance})
|
raise NotFound('InstanceUsage', {'instance': exist.instance})
|
||||||
|
|
||||||
if not _verify_date_field(launch.launched_at, exist.launched_at,
|
_verify_field_mismatch(exist, launch)
|
||||||
same_second=True):
|
|
||||||
raise FieldMismatch('launched_at', exist.launched_at,
|
|
||||||
launch.launched_at)
|
|
||||||
|
|
||||||
if launch.instance_type_id != exist.instance_type_id:
|
|
||||||
raise FieldMismatch('instance_type_id', exist.instance_type_id,
|
|
||||||
launch.instance_type_id)
|
|
||||||
|
|
||||||
|
|
||||||
def _verify_for_delete(exist):
|
def _verify_for_delete(exist):
|
||||||
|
Loading…
Reference in New Issue
Block a user