Merge pull request #183 from manalilatkar/2106

2106
This commit is contained in:
Andrew Melton
2013-09-13 12:25:30 -07:00
10 changed files with 643 additions and 48 deletions

View File

@@ -4,6 +4,7 @@
"settle_units": "minutes", "settle_units": "minutes",
"pool_size": 2, "pool_size": 2,
"enable_notifications": true, "enable_notifications": true,
"validation_level": "all",
"rabbit": { "rabbit": {
"durable_queue": false, "durable_queue": false,
"host": "10.0.0.1", "host": "10.0.0.1",

View File

@@ -457,7 +457,7 @@ class ImageExists(models.Model):
(FAILED, 'Failed Verification'), (FAILED, 'Failed Verification'),
] ]
uuid = models.CharField(max_length=50, db_index=True) uuid = models.CharField(max_length=50, db_index=True, null=True)
created_at = models.DecimalField(max_digits=20, created_at = models.DecimalField(max_digits=20,
decimal_places=6, db_index=True, decimal_places=6, db_index=True,
null=True) null=True)

View File

@@ -32,6 +32,8 @@ from tests.unit import StacktachBaseTestCase
from utils import IMAGE_UUID_1 from utils import IMAGE_UUID_1
from utils import make_verifier_config from utils import make_verifier_config
from verifier import glance_verifier from verifier import glance_verifier
from verifier import NullFieldException
from verifier import WrongTypeException
from verifier import FieldMismatch from verifier import FieldMismatch
from verifier import NotFound from verifier import NotFound
from verifier import VerificationException from verifier import VerificationException
@@ -261,12 +263,156 @@ class GlanceVerifierTestCase(StacktachBaseTestCase):
self.assertEqual(fm.actual, decimal.Decimal('6.1')) self.assertEqual(fm.actual, decimal.Decimal('6.1'))
self.mox.VerifyAll() self.mox.VerifyAll()
def test_should_verify_that_image_size_in_exist_is_not_null(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
exist.size = None
exist.created_at = decimal.Decimal('5.1')
exist.uuid = 'abcd1234'
self.mox.ReplayAll()
try:
glance_verifier._verify_validity(exist)
self.fail()
except NullFieldException as nf:
self.assertEqual(nf.field_name, 'image_size')
self.assertEqual(nf.reason, "image_size field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_that_created_at_in_exist_is_not_null(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
exist.size = 'size'
exist.created_at = None
exist.uuid = 'abcd1234'
self.mox.ReplayAll()
try:
glance_verifier._verify_validity(exist)
self.fail()
except NullFieldException as nf:
self.assertEqual(nf.field_name, 'created_at')
self.assertEqual(nf.reason, "created_at field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_that_uuid_in_exist_is_not_null(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
exist.size = 'size'
exist.created_at = decimal.Decimal('5.1')
exist.uuid = None
self.mox.ReplayAll()
try:
glance_verifier._verify_validity(exist)
self.fail()
except NullFieldException as nf:
self.assertEqual(nf.field_name, 'uuid')
self.assertEqual(nf.reason, "uuid field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_that_owner_in_exist_is_not_null(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
exist.size = 1234
exist.created_at = decimal.Decimal('5.1')
exist.uuid = 'abcd1234'
exist.owner = None
self.mox.ReplayAll()
try:
glance_verifier._verify_validity(exist)
self.fail()
except NullFieldException as nf:
self.assertEqual(nf.field_name, 'owner')
self.assertEqual(nf.reason, "owner field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_that_uuid_value_is_uuid_like(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
exist.size = 'size'
exist.created_at = decimal.Decimal('5.1')
exist.uuid = "asdfe-fgh"
self.mox.ReplayAll()
try:
glance_verifier._verify_validity(exist)
self.fail()
except WrongTypeException as wt:
self.assertEqual(wt.field_name, 'uuid')
self.assertEqual(wt.reason, "{ uuid : asdfe-fgh } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_created_at_is_decimal(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
exist.size = 'size'
exist.created_at = "123.a"
exist.uuid = "58fb036d-5ef8-47a8-b503-7571276c400a"
self.mox.ReplayAll()
try:
glance_verifier._verify_validity(exist)
self.fail()
except WrongTypeException as wt:
self.assertEqual(wt.field_name, 'created_at')
self.assertEqual(wt.reason, "{ created_at : 123.a } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_image_size_is_of_type_decimal(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
exist.size = 'size'
exist.created_at = decimal.Decimal('5.1')
exist.uuid = "58fb036d-5ef8-47a8-b503-7571276c400a"
self.mox.ReplayAll()
try:
glance_verifier._verify_validity(exist)
self.fail()
except WrongTypeException as wt:
self.assertEqual(wt.field_name, 'size')
self.assertEqual(wt.reason, "{ size : size } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_owner_is_of_type_hex(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
exist.size = 1234L
exist.created_at = decimal.Decimal('5.1')
exist.uuid = "58fb036d-5ef8-47a8-b503-7571276c400a"
exist.owner = "3762854cd6f6435998188d5120e4c271,kl"
self.mox.ReplayAll()
try:
glance_verifier._verify_validity(exist)
self.fail()
except WrongTypeException as wt:
self.assertEqual(wt.field_name, 'owner')
self.assertEqual(wt.reason, "{ owner : 3762854cd6f6435998188d5120e4c271,kl } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_correctly_for_all_non_null_and_valid_types(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
exist.size = 983040L
exist.created_at = decimal.Decimal('5.1')
exist.uuid = "58fb036d-5ef8-47a8-b503-7571276c400a"
exist.owner = "3762854cd6f6435998188d5120e4c271"
self.mox.ReplayAll()
glance_verifier._verify_validity(exist)
self.mox.VerifyAll()
def test_verify_should_verify_exists_for_usage_and_delete(self): def test_verify_should_verify_exists_for_usage_and_delete(self):
exist = self.mox.CreateMockAnything() exist = self.mox.CreateMockAnything()
self.mox.StubOutWithMock(glance_verifier, '_verify_for_usage') self.mox.StubOutWithMock(glance_verifier, '_verify_for_usage')
glance_verifier._verify_for_usage(exist) glance_verifier._verify_for_usage(exist)
self.mox.StubOutWithMock(glance_verifier, '_verify_for_delete') self.mox.StubOutWithMock(glance_verifier, '_verify_for_delete')
glance_verifier._verify_for_delete(exist) glance_verifier._verify_for_delete(exist)
self.mox.StubOutWithMock(glance_verifier, '_verify_validity')
glance_verifier._verify_validity(exist)
exist.mark_verified() exist.mark_verified()
self.mox.ReplayAll() self.mox.ReplayAll()
@@ -413,4 +559,5 @@ class GlanceVerifierTestCase(StacktachBaseTestCase):
self.glance_verifier.send_verified_notification(exist, exchange, self.glance_verifier.send_verified_notification(exist, exchange,
connection) connection)
self.mox.VerifyAll() self.mox.VerifyAll()

View File

@@ -45,6 +45,8 @@ from utils import TENANT_ID_1
from utils import TENANT_ID_2 from utils import TENANT_ID_2
from utils import INSTANCE_TYPE_ID_1 from utils import INSTANCE_TYPE_ID_1
from verifier import nova_verifier from verifier import nova_verifier
from verifier import NullFieldException
from verifier import WrongTypeException
from verifier import AmbiguousResults from verifier import AmbiguousResults
from verifier import FieldMismatch from verifier import FieldMismatch
from verifier import NotFound from verifier import NotFound
@@ -288,12 +290,11 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
results.count().AndReturn(0) results.count().AndReturn(0)
self.mox.ReplayAll() self.mox.ReplayAll()
try: with self.assertRaises(NotFound) as nf:
nova_verifier._verify_for_launch(exist) nova_verifier._verify_for_launch(exist)
self.fail() exception = nf.exception
except NotFound, nf: self.assertEqual(exception.object_type, 'InstanceUsage')
self.assertEqual(nf.object_type, 'InstanceUsage') self.assertEqual(exception.search_params, {'instance': INSTANCE_ID_1})
self.assertEqual(nf.search_params, {'instance': INSTANCE_ID_1})
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -313,17 +314,346 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
results.count().AndReturn(2) results.count().AndReturn(2)
self.mox.ReplayAll() self.mox.ReplayAll()
try: with self.assertRaises(AmbiguousResults) as ar:
nova_verifier._verify_for_launch(exist) nova_verifier._verify_for_launch(exist)
self.fail() exception = ar.exception
except AmbiguousResults, nf: self.assertEqual(exception.object_type, 'InstanceUsage')
self.assertEqual(nf.object_type, 'InstanceUsage') search_params = {'instance': INSTANCE_ID_1,
search_params = {'instance': INSTANCE_ID_1, 'launched_at': decimal.Decimal('1.1')}
'launched_at': decimal.Decimal('1.1')} self.assertEqual(exception.search_params, search_params)
self.assertEqual(nf.search_params, search_params)
self.mox.VerifyAll() self.mox.VerifyAll()
def test_should_verify_that_tenant_in_exist_is_not_null(self):
exist = self.mox.CreateMockAnything()
exist.tenant = None
exist.id = 23
self.mox.ReplayAll()
with self.assertRaises(NullFieldException) as nf:
nova_verifier._verify_validity(exist, 'all')
exception = nf.exception
self.assertEqual(exception.field_name, 'tenant')
self.assertEqual(exception.reason,
"tenant field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_that_launched_at_in_exist_is_not_null(self):
exist = self.mox.CreateMockAnything()
exist.tenant = 'tenant'
exist.id = 23
exist.launched_at = None
self.mox.ReplayAll()
with self.assertRaises(NullFieldException) as nf:
nova_verifier._verify_validity(exist, 'all')
exception = nf.exception
self.assertEqual(exception.field_name, 'launched_at')
self.assertEqual(exception.reason,
"launched_at field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_that_instance_type_id_in_exist_is_not_null(self):
exist = self.mox.CreateMockAnything()
exist.tenant = 'tenant'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.instance_type_id = None
self.mox.ReplayAll()
with self.assertRaises(NullFieldException) as nf:
nova_verifier._verify_validity(exist, 'all')
exception = nf.exception
self.assertEqual(exception.field_name, 'instance_type_id')
self.assertEqual(exception.reason,
"instance_type_id field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_tenant_id_is_of_type_hex(self):
exist = self.mox.CreateMockAnything()
exist.tenant = 'tenant'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.instance_type_id = 2
self.mox.ReplayAll()
with self.assertRaises(WrongTypeException) as wt:
nova_verifier._verify_validity(exist, 'all')
exception = wt.exception
self.assertEqual(exception.field_name, 'tenant')
self.assertEqual(
exception.reason,
"{ tenant : tenant } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_flavor_is_of_type_integer(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.instance_type_id = 'flavor'
self.mox.ReplayAll()
with self.assertRaises(WrongTypeException) as wt:
nova_verifier._verify_validity(exist, 'all')
exception = wt.exception
self.assertEqual(exception.field_name, 'instance_type_id')
self.assertEqual(
exception.reason,
"{ instance_type_id : flavor } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_launched_at_is_of_type_decimal(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = 111
exist.instance_type_id = 4
self.mox.ReplayAll()
with self.assertRaises(WrongTypeException) as wt:
nova_verifier._verify_validity(exist, 'all')
exception = wt.exception
self.assertEqual(exception.field_name, 'launched_at')
self.assertEqual(
exception.reason,
"{ launched_at : 111 } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_deleted_at_is_of_decimal_type_if_present(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.instance_type_id = 4
exist.deleted_at = 20
self.mox.ReplayAll()
with self.assertRaises(WrongTypeException) as wt:
nova_verifier._verify_validity(exist, 'all')
exception = wt.exception
self.assertEqual(exception.field_name, 'deleted_at')
self.assertEqual(
exception.reason,
"{ deleted_at : 20 } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_rax_options_should_be_of_integer_type(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = 4
exist.rax_options = 'a'
self.mox.ReplayAll()
with self.assertRaises(WrongTypeException) as wt:
nova_verifier._verify_validity(exist, 'all')
exception = wt.exception
self.assertEqual(exception.field_name, 'rax_options')
self.assertEqual(
exception.reason,
"{ rax_options : a } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_rax_options_should_not_be_empty(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = 4
exist.rax_options = ''
self.mox.ReplayAll()
with self.assertRaises(NullFieldException) as nf:
nova_verifier._verify_validity(exist, 'all')
exception = nf.exception
self.assertEqual(exception.field_name, 'rax_options')
self.assertEqual(exception.reason, "rax_options field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_os_arch_should_be_alphanumeric(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = 4
exist.rax_options = 12
exist.os_architecture = 'x64,'
self.mox.ReplayAll()
with self.assertRaises(WrongTypeException) as wt:
nova_verifier._verify_validity(exist, 'all')
exception = wt.exception
self.assertEqual(exception.field_name, 'os_architecture')
self.assertEqual(
exception.reason,
"{ os_architecture : x64, } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_os_arch_should_not_be_empty(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = 4
exist.rax_options = 12
exist.os_architecture = ''
self.mox.ReplayAll()
with self.assertRaises(NullFieldException) as nf:
nova_verifier._verify_validity(exist, 'all')
exception = nf.exception
self.assertEqual(exception.field_name, 'os_architecture')
self.assertEqual(
exception.reason,
"os_architecture field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_os_distro_should_be_alphanumeric(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = 4
exist.rax_options = 12
exist.os_architecture = 'x64'
exist.os_distro = 'com.microsoft.server,'
self.mox.ReplayAll()
with self.assertRaises(WrongTypeException) as wt:
nova_verifier._verify_validity(exist, 'all')
exception = wt.exception
self.assertEqual(exception.field_name, 'os_distro')
self.assertEqual(
exception.reason,
"{ os_distro : com.microsoft.server, } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_os_distro_should_not_be_empty(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = 4
exist.rax_options = 12
exist.os_architecture = 'x64'
exist.os_distro = ''
self.mox.ReplayAll()
with self.assertRaises(NullFieldException) as nf:
nova_verifier._verify_validity(exist, 'all')
exception = nf.exception
self.assertEqual(exception.field_name, 'os_distro')
self.assertEqual(
exception.reason,
"os_distro field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_os_version_should_be_alphanumeric(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = 4
exist.rax_options = 12
exist.os_architecture = 'x64'
exist.os_distro = 'com.microsoft.server'
exist.os_version = '2008.2,'
self.mox.ReplayAll()
with self.assertRaises(WrongTypeException) as wt:
nova_verifier._verify_validity(exist, 'all')
exception = wt.exception
self.assertEqual(exception.field_name, 'os_version')
self.assertEqual(
exception.reason,
"{ os_version : 2008.2, } of incorrect type for exist id 23")
self.mox.VerifyAll()
def test_should_verify_os_version_should_not_be_empty(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = 4
exist.rax_options = 12
exist.os_architecture = 'x64'
exist.os_distro = 'com.microsoft.server'
exist.os_version = ''
self.mox.ReplayAll()
with self.assertRaises(NullFieldException) as nf:
nova_verifier._verify_validity(exist, 'all')
exception = nf.exception
self.assertEqual(exception.field_name, 'os_version')
self.assertEqual(
exception.reason, "os_version field was null for exist id 23")
self.mox.VerifyAll()
def test_should_verify_all_exist_fields_when_validity_check_value_is_all(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = '4'
exist.rax_options = '12'
exist.os_architecture = 'x64'
exist.os_distro = 'com.microsoft.server'
exist.os_version = '2008.2'
self.mox.ReplayAll()
nova_verifier._verify_validity(exist, 'all')
self.mox.VerifyAll()
def test_should_verify_only_basic_exist_fields_when_validity_check_value_is_basic(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = decimal.Decimal('5.1')
exist.instance_type_id = '4'
self.mox.ReplayAll()
nova_verifier._verify_validity(exist, 'basic')
self.mox.VerifyAll()
def test_should_not_verify_any_fields_if_validity_check_value_is_none(self):
exist = self.mox.CreateMockAnything()
exist.id = 23
self.mox.ReplayAll()
nova_verifier._verify_validity(exist, 'none')
self.mox.VerifyAll()
def test_should_verify_exist_fields_even_if_deleted_at_is_none(self):
exist = self.mox.CreateMockAnything()
exist.tenant = '3762854cd6f6435998188d5120e4c271'
exist.id = 23
exist.launched_at = decimal.Decimal('1.1')
exist.deleted_at = None
exist.instance_type_id = 4
exist.rax_options = 12
exist.os_architecture = 'x64'
exist.os_distro = 'com.microsoft.server'
exist.os_version = '2008.2'
self.mox.ReplayAll()
nova_verifier._verify_validity(exist, 'all')
self.mox.VerifyAll()
def test_verify_for_delete(self): def test_verify_for_delete(self):
exist = self.mox.CreateMockAnything() exist = self.mox.CreateMockAnything()
exist.delete = self.mox.CreateMockAnything() exist.delete = self.mox.CreateMockAnything()
@@ -394,12 +724,11 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
try: with self.assertRaises(VerificationException) as ve:
nova_verifier._verify_for_delete(exist) nova_verifier._verify_for_delete(exist)
self.fail() exception = ve.exception
except VerificationException, ve: msg = 'Found InstanceDeletes for non-delete exist'
msg = 'Found InstanceDeletes for non-delete exist' self.assertEqual(exception.reason, msg)
self.assertEqual(ve.reason, msg)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -412,13 +741,12 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
exist.delete.deleted_at = decimal.Decimal('5.1') exist.delete.deleted_at = decimal.Decimal('5.1')
self.mox.ReplayAll() self.mox.ReplayAll()
try: with self.assertRaises(FieldMismatch) as fm:
nova_verifier._verify_for_delete(exist) nova_verifier._verify_for_delete(exist)
self.fail() exception = fm.exception
except FieldMismatch, fm: self.assertEqual(exception.field_name, 'launched_at')
self.assertEqual(fm.field_name, 'launched_at') self.assertEqual(exception.expected, decimal.Decimal('1.1'))
self.assertEqual(fm.expected, decimal.Decimal('1.1')) self.assertEqual(exception.actual, decimal.Decimal('2.1'))
self.assertEqual(fm.actual, decimal.Decimal('2.1'))
self.mox.VerifyAll() self.mox.VerifyAll()
def test_verify_for_delete_deleted_at_mismatch(self): def test_verify_for_delete_deleted_at_mismatch(self):
@@ -430,13 +758,12 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
exist.delete.deleted_at = decimal.Decimal('6.1') exist.delete.deleted_at = decimal.Decimal('6.1')
self.mox.ReplayAll() self.mox.ReplayAll()
try: with self.assertRaises(FieldMismatch) as fm:
nova_verifier._verify_for_delete(exist) nova_verifier._verify_for_delete(exist)
self.fail() exception = fm.exception
except FieldMismatch, fm: self.assertEqual(exception.field_name, 'deleted_at')
self.assertEqual(fm.field_name, 'deleted_at') self.assertEqual(exception.expected, decimal.Decimal('5.1'))
self.assertEqual(fm.expected, decimal.Decimal('5.1')) self.assertEqual(exception.actual, decimal.Decimal('6.1'))
self.assertEqual(fm.actual, decimal.Decimal('6.1'))
self.mox.VerifyAll() self.mox.VerifyAll()
def test_verify_with_reconciled_data(self): def test_verify_with_reconciled_data(self):
@@ -571,12 +898,14 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
exist.launched_at = decimal.Decimal('1.1') exist.launched_at = decimal.Decimal('1.1')
self.mox.StubOutWithMock(nova_verifier, '_verify_for_launch') self.mox.StubOutWithMock(nova_verifier, '_verify_for_launch')
self.mox.StubOutWithMock(nova_verifier, '_verify_for_delete') self.mox.StubOutWithMock(nova_verifier, '_verify_for_delete')
self.mox.StubOutWithMock(nova_verifier, '_verify_validity')
self.mox.StubOutWithMock(exist, 'mark_verified') self.mox.StubOutWithMock(exist, 'mark_verified')
nova_verifier._verify_for_launch(exist) nova_verifier._verify_for_launch(exist)
nova_verifier._verify_for_delete(exist) nova_verifier._verify_for_delete(exist)
nova_verifier._verify_validity(exist, 'all')
exist.mark_verified() exist.mark_verified()
self.mox.ReplayAll() self.mox.ReplayAll()
result, exists = nova_verifier._verify(exist) result, exists = nova_verifier._verify(exist, 'all')
self.assertTrue(result) self.assertTrue(result)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -591,7 +920,7 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
nova_verifier._verify_with_reconciled_data(exist)\ nova_verifier._verify_with_reconciled_data(exist)\
.AndRaise(NotFound('InstanceReconcile', {})) .AndRaise(NotFound('InstanceReconcile', {}))
self.mox.ReplayAll() self.mox.ReplayAll()
result, exists = nova_verifier._verify(exist) result, exists = nova_verifier._verify(exist, 'all')
self.assertFalse(result) self.assertFalse(result)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -607,7 +936,7 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
.AndRaise(VerificationException('test2')) .AndRaise(VerificationException('test2'))
exist.mark_failed(reason='test2') exist.mark_failed(reason='test2')
self.mox.ReplayAll() self.mox.ReplayAll()
result, exists = nova_verifier._verify(exist) result, exists = nova_verifier._verify(exist, 'none')
self.assertFalse(result) self.assertFalse(result)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -624,7 +953,7 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
.AndRaise(NotFound('InstanceReconcile', {})) .AndRaise(NotFound('InstanceReconcile', {}))
exist.mark_failed(reason='test') exist.mark_failed(reason='test')
self.mox.ReplayAll() self.mox.ReplayAll()
result, exists = nova_verifier._verify(exist) result, exists = nova_verifier._verify(exist, 'none')
self.assertFalse(result) self.assertFalse(result)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -640,7 +969,7 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
nova_verifier._verify_with_reconciled_data(exist) nova_verifier._verify_with_reconciled_data(exist)
exist.mark_verified(reconciled=True) exist.mark_verified(reconciled=True)
self.mox.ReplayAll() self.mox.ReplayAll()
result, exists = nova_verifier._verify(exist) result, exists = nova_verifier._verify(exist, 'none')
self.assertTrue(result) self.assertTrue(result)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -657,7 +986,7 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
.AndRaise(Exception()) .AndRaise(Exception())
exist.mark_failed(reason='Exception') exist.mark_failed(reason='Exception')
self.mox.ReplayAll() self.mox.ReplayAll()
result, exists = nova_verifier._verify(exist) result, exists = nova_verifier._verify(exist, 'none')
self.assertFalse(result) self.assertFalse(result)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -675,7 +1004,7 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
.AndRaise(NotFound('InstanceReconcile', {})) .AndRaise(NotFound('InstanceReconcile', {}))
exist.mark_failed(reason='test') exist.mark_failed(reason='test')
self.mox.ReplayAll() self.mox.ReplayAll()
result, exists = nova_verifier._verify(exist) result, exists = nova_verifier._verify(exist, 'none')
self.assertFalse(result) self.assertFalse(result)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -688,7 +1017,7 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
nova_verifier._verify_for_launch(exist).AndRaise(Exception()) nova_verifier._verify_for_launch(exist).AndRaise(Exception())
exist.mark_failed(reason='Exception') exist.mark_failed(reason='Exception')
self.mox.ReplayAll() self.mox.ReplayAll()
result, exists = nova_verifier._verify(exist) result, exists = nova_verifier._verify(exist, 'none')
self.assertFalse(result) self.assertFalse(result)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -702,7 +1031,7 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
nova_verifier._verify_for_delete(exist).AndRaise(Exception()) nova_verifier._verify_for_delete(exist).AndRaise(Exception())
exist.mark_failed(reason='Exception') exist.mark_failed(reason='Exception')
self.mox.ReplayAll() self.mox.ReplayAll()
result, exists = nova_verifier._verify(exist) result, exists = nova_verifier._verify(exist, 'none')
self.assertFalse(result) self.assertFalse(result)
self.mox.VerifyAll() self.mox.VerifyAll()
@@ -722,9 +1051,9 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
exist2.update_status('verifying') exist2.update_status('verifying')
exist1.save() exist1.save()
exist2.save() exist2.save()
self.pool.apply_async(nova_verifier._verify, args=(exist1,), self.pool.apply_async(nova_verifier._verify, args=(exist1, 'all'),
callback=None) callback=None)
self.pool.apply_async(nova_verifier._verify, args=(exist2,), self.pool.apply_async(nova_verifier._verify, args=(exist2, 'all'),
callback=None) callback=None)
self.mox.ReplayAll() self.mox.ReplayAll()
self.verifier.verify_for_range(when_max) self.verifier.verify_for_range(when_max)
@@ -747,9 +1076,9 @@ class NovaVerifierTestCase(StacktachBaseTestCase):
exist2.update_status('verifying') exist2.update_status('verifying')
exist1.save() exist1.save()
exist2.save() exist2.save()
self.pool.apply_async(nova_verifier._verify, args=(exist1,), self.pool.apply_async(nova_verifier._verify, args=(exist1, 'all'),
callback=callback) callback=callback)
self.pool.apply_async(nova_verifier._verify, args=(exist2,), self.pool.apply_async(nova_verifier._verify, args=(exist2, 'all'),
callback=callback) callback=callback)
self.mox.ReplayAll() self.mox.ReplayAll()
self.verifier.verify_for_range(when_max, callback=callback) self.verifier.verify_for_range(when_max, callback=callback)

View File

@@ -163,6 +163,7 @@ class FakeVerifierConfig(object):
self.durable_queue = lambda: durable_queue self.durable_queue = lambda: durable_queue
self.topics = lambda: topics self.topics = lambda: topics
self.enable_notifications = lambda: notifs self.enable_notifications = lambda: notifs
self.validation_level = lambda: 'all'
def make_verifier_config(notifs): def make_verifier_config(notifs):

View File

@@ -51,3 +51,15 @@ class FieldMismatch(VerificationException):
self.reason = "Expected %s to be '%s' got '%s'" % (self.field_name, self.reason = "Expected %s to be '%s' got '%s'" % (self.field_name,
self.expected, self.expected,
self.actual) self.actual)
class NullFieldException(VerificationException):
def __init__(self, field_name, exist_id):
self.field_name = field_name
self.reason = "%s field was null for exist id %s" %(field_name, exist_id)
class WrongTypeException(VerificationException):
def __init__(self, field_name, value, exist_id):
self.field_name = field_name
self.reason = "{ %s : %s } of incorrect type for exist id %s"\
%(field_name, value, exist_id)

View File

@@ -19,7 +19,9 @@
# IN THE SOFTWARE. # IN THE SOFTWARE.
import datetime import datetime
import decimal
import os import os
import re
import sys import sys
import time import time
import multiprocessing import multiprocessing
@@ -32,6 +34,8 @@ POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'stacktach')): if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'stacktach')):
sys.path.insert(0, POSSIBLE_TOPDIR) sys.path.insert(0, POSSIBLE_TOPDIR)
from verifier import WrongTypeException
from stacktach import stacklog, message_service from stacktach import stacklog, message_service
LOG = stacklog.get_logger('verifier') LOG = stacklog.get_logger('verifier')
@@ -65,6 +69,39 @@ def _verify_date_field(d1, d2, same_second=False):
return False return False
def _is_like_uuid(attr_name, attr_value, exist_id):
if not re.match("[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$",
attr_value):
raise WrongTypeException(attr_name, attr_value, exist_id)
def _is_like_date(attr_name, attr_value, exist_id):
if not isinstance(attr_value, decimal.Decimal):
raise WrongTypeException(attr_name, attr_value, exist_id)
def _is_long(attr_name, attr_value, exist_id):
if not isinstance(attr_value, long):
raise WrongTypeException(attr_name, attr_value, exist_id)
def _is_int_in_char(attr_name, attr_value, exist_id):
try:
int(attr_value)
except ValueError:
raise WrongTypeException(attr_name, attr_value, exist_id)
def _is_hex_owner_id(attr_name, attr_value, exist_id):
if not re.match("[0-9a-f]{32}$", attr_value):
raise WrongTypeException(attr_name, attr_value, exist_id)
def _is_alphanumeric(attr_name, attr_value, exist_id):
if not re.match("[a-zA-Z0-9.]+$", attr_value):
raise WrongTypeException(attr_name, attr_value, exist_id)
class Verifier(object): class Verifier(object):
def __init__(self, config, pool=None, reconciler=None): def __init__(self, config, pool=None, reconciler=None):
self.config = config self.config = config

View File

@@ -87,3 +87,7 @@ def password():
def virtual_host(): def virtual_host():
return config['rabbit']['virtual_host'] return config['rabbit']['virtual_host']
def validation_level():
return config['validation_level']

View File

@@ -31,7 +31,10 @@ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'stacktach')):
sys.path.insert(0, POSSIBLE_TOPDIR) sys.path.insert(0, POSSIBLE_TOPDIR)
from stacktach import models from stacktach import models
from verifier import FieldMismatch, VerificationException, base_verifier from verifier import FieldMismatch
from verifier import VerificationException
from verifier import base_verifier
from verifier import NullFieldException
from verifier import NotFound from verifier import NotFound
from stacktach import datetime_to_decimal as dt from stacktach import datetime_to_decimal as dt
import datetime import datetime
@@ -54,6 +57,18 @@ def _verify_field_mismatch(exists, usage):
usage.size) usage.size)
def _verify_validity(exist):
fields = {exist.size: 'image_size', exist.created_at: 'created_at',
exist.uuid: 'uuid', exist.owner: 'owner'}
for (field_value, field_name) in fields.items():
if field_value is None:
raise NullFieldException(field_name, exist.id)
base_verifier._is_like_uuid('uuid', exist.uuid, exist.id)
base_verifier._is_like_date('created_at', exist.created_at, exist.id)
base_verifier._is_long('size', exist.size, exist.id)
base_verifier._is_hex_owner_id('owner', exist.owner, exist.id)
def _verify_for_usage(exist, usage=None): def _verify_for_usage(exist, usage=None):
usage_type = "ImageUsage" usage_type = "ImageUsage"
if not usage and exist.usage: if not usage and exist.usage:
@@ -116,6 +131,7 @@ def _verify(exist):
try: try:
_verify_for_usage(exist) _verify_for_usage(exist)
_verify_for_delete(exist) _verify_for_delete(exist)
_verify_validity(exist)
verified = True verified = True
exist.mark_verified() exist.mark_verified()

View File

@@ -18,7 +18,6 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE. # IN THE SOFTWARE.
import argparse
import datetime import datetime
import json import json
import os import os
@@ -32,6 +31,7 @@ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'stacktach')):
sys.path.insert(0, POSSIBLE_TOPDIR) sys.path.insert(0, POSSIBLE_TOPDIR)
from verifier import base_verifier from verifier import base_verifier
from verifier import NullFieldException
from stacktach import models from stacktach import models
from stacktach import datetime_to_decimal as dt from stacktach import datetime_to_decimal as dt
from verifier import FieldMismatch from verifier import FieldMismatch
@@ -145,6 +145,52 @@ def _verify_for_delete(exist, delete=None,
'deleted_at', exist.deleted_at, delete.deleted_at) 'deleted_at', exist.deleted_at, delete.deleted_at)
def _verify_basic_validity(exist):
fields = {exist.tenant: 'tenant',
exist.launched_at: 'launched_at',
exist.instance_type_id: 'instance_type_id'}
for (field_value, field_name) in fields.items():
if field_value is None:
raise NullFieldException(field_name, exist.id)
base_verifier._is_hex_owner_id('tenant', exist.tenant, exist.id)
base_verifier._is_int_in_char('instance_type_id', exist.instance_type_id,
exist.id)
base_verifier._is_like_date('launched_at', exist.launched_at, exist.id)
if exist.deleted_at is not None:
base_verifier._is_like_date('deleted_at', exist.deleted_at, exist.id)
def _verify_optional_validity(exist):
fields = {exist.rax_options: 'rax_options',
exist.os_architecture: 'os_architecture',
exist.os_version: 'os_version',
exist.os_distro: 'os_distro'}
for (field_value, field_name) in fields.items():
if field_value == '':
raise NullFieldException(field_name, exist.id)
base_verifier._is_int_in_char('rax_options', exist.rax_options, exist.id)
base_verifier._is_alphanumeric('os_architecture', exist.os_architecture, exist.id)
base_verifier._is_alphanumeric('os_distro', exist.os_distro, exist.id)
base_verifier._is_alphanumeric('os_version', exist.os_version, exist.id)
def verify_fields_not_null(exist_id, null_value, fields):
for (field_value, field_name) in fields.items():
print "value: %s, name = %s" % (field_value, field_name)
if field_value == null_value:
raise NullFieldException(field_name, exist_id)
def _verify_validity(exist, validation_level):
if validation_level == 'none':
return
if validation_level == 'basic':
_verify_basic_validity(exist)
if validation_level == 'all':
_verify_basic_validity(exist)
_verify_optional_validity(exist)
def _verify_with_reconciled_data(exist): def _verify_with_reconciled_data(exist):
if not exist.launched_at: if not exist.launched_at:
raise VerificationException("Exists without a launched_at") raise VerificationException("Exists without a launched_at")
@@ -193,12 +239,13 @@ def _attempt_reconciled_verify(exist, orig_e):
return verified return verified
def _verify(exist): def _verify(exist, validation_level):
verified = False verified = False
try: try:
if not exist.launched_at: if not exist.launched_at:
raise VerificationException("Exists without a launched_at") raise VerificationException("Exists without a launched_at")
_verify_validity(exist, validation_level)
_verify_for_launch(exist) _verify_for_launch(exist)
_verify_for_delete(exist) _verify_for_delete(exist)
@@ -247,8 +294,9 @@ class NovaVerifier(base_verifier.Verifier):
for exist in exists[0:1000]: for exist in exists[0:1000]:
exist.update_status(models.InstanceExists.VERIFYING) exist.update_status(models.InstanceExists.VERIFYING)
exist.save() exist.save()
validation_level = self.config.validation_level()
result = self.pool.apply_async( result = self.pool.apply_async(
_verify, args=(exist,), _verify, args=(exist, validation_level),
callback=callback) callback=callback)
self.results.append(result) self.results.append(result)
added += 1 added += 1