Refactoring test_address aka 'ec2' style.

Added list by filter test.

Change-Id: I21b5de480c5216dbf31cc8105750baeffa7dd5d1
This commit is contained in:
alexey-mr 2015-11-12 16:36:30 +03:00
parent 350e260b28
commit aa787e0fd6
2 changed files with 103 additions and 36 deletions

View File

@ -14,16 +14,13 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
from gceapi.tests.functional import test_base
CREATE_ADDRESS_TEMPLATE = {
"name": "${name}",
}
def _prepare_address_create_parameters(**kwargs):
return test_base.insert_json_parameters(CREATE_ADDRESS_TEMPLATE, **kwargs)
IPV4_PATTERN = ('^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}'
'(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$')
class TestAddressesBase(test_base.GCETestCase):
@ -39,12 +36,11 @@ class TestAddressesBase(test_base.GCETestCase):
cfg = self.cfg
project_id = cfg.project_id
region = cfg.region
config = _prepare_address_create_parameters(**options)
self.trace('Crete address with options {}'.format(config))
self.trace('Crete address with options {}'.format(options))
request = self.addresses.insert(
project=project_id,
region=region,
body=config)
body=options)
self._add_cleanup(self._delete_address, options['name'])
self._execute_async_request(request, project_id, region=region)
@ -61,7 +57,7 @@ class TestAddressesBase(test_base.GCETestCase):
self._execute_async_request(request, project_id, region=region)
self._remove_cleanup(self._delete_address, name)
def _list_addresses(self):
def _list_addresses(self, filter=None):
cfg = self.cfg
project_id = cfg.project_id
region = cfg.region
@ -69,7 +65,8 @@ class TestAddressesBase(test_base.GCETestCase):
format(project_id, region))
request = self.addresses.list(
project=project_id,
region=region)
region=region,
filter=filter)
result = request.execute()
self.trace('Addresses: {}'.format(result))
self.api.validate_schema(value=result, schema_name='AddressList')
@ -90,8 +87,31 @@ class TestAddressesBase(test_base.GCETestCase):
self.api.validate_schema(value=result, schema_name='Address')
return result
def _get_expected_address(self, options):
address = copy.deepcopy(options)
address['kind'] = u'compute#address'
if 'status' not in options:
address['status'] = u'RESERVED'
if 'selfLink' not in options:
address_link = 'addresses/{}'.format(address['name'])
address['selfLink'] = self.api.get_region_url(address_link)
if 'region' not in options:
address['region'] = self.api.get_region_url()
if 'address' not in options:
address['address'] = IPV4_PATTERN
if 'id' not in options:
address['id'] = '[0-9]{1,32}'
return address
class TestAddressesCRUD(TestAddressesBase):
def _ensure_address_created(self, options):
name = options['name']
address = self._get_address(name)
expected_address = self._get_expected_address(options)
self.assertObject(expected_address, address)
return address
class TestAddressess(TestAddressesBase):
@property
def addresses(self):
res = self.api.compute.addresses()
@ -101,29 +121,46 @@ class TestAddressesCRUD(TestAddressesBase):
return res
def setUp(self):
super(TestAddressesCRUD, self).setUp()
self._address_name = self._rand_name('testaddr')
super(TestAddressess, self).setUp()
def _create(self):
def test_create_delete_address(self):
name = self._rand_name('testaddr')
options = {
'name': self._address_name
'name': name
}
self._create_address(options)
self._ensure_address_created(options)
self._delete_address(name)
def _read(self):
result = self._get_address(self._address_name)
self.assertEqual(self._address_name, result['name'])
def test_list_addresses(self):
name = self._rand_name('testaddr')
options = {
'name': name
}
self._create_address(options)
address = self._ensure_address_created(options)
result = self._list_addresses()
self.assertFind(self._address_name, result)
result = self.assertFind(name, result)
self.assertObject(address, result)
self._delete_address(name)
def _update(self):
pass
def _delete(self):
self._delete_address(self._address_name)
def test_crud(self):
self._create()
self._read()
self._update()
self._delete()
def test_list_addresses_by_filter_name(self):
# Goole's free evaluation account quote is 1 external IP
count = 3 if not self.is_real_gce else 1
names = [self._rand_name('testaddr') for _ in range(0, count)]
# prepare resources
addresses = dict()
for name in names:
options = {
'name': name
}
self._create_address(options)
addresses[name] = self._ensure_address_created(options)
# do list by filter test
for name in names:
result = self._list_addresses(filter='name eq {}'.format(name))
self.assertEqual(1, len(result['items']))
self.assertObject(addresses[name], result['items'][0])
# delete resources
for name in names:
self._delete_address(name)

View File

@ -15,6 +15,7 @@
# under the License.
import json
import re
import string
import time
import traceback
@ -151,6 +152,17 @@ class GCEApi(object):
return z
return '{}/{}'.format(z, resource)
def get_region_url(self, resource=None, region=None):
r = region
if r is None:
r = CONF.region
if not self._is_absolute_url(r):
t = '{}/{}' if r.startswith('regions/') else '{}/regions/{}'
r = t.format(self.project_url, r)
if resource is None:
return r
return '{}/{}'.format(r, resource)
def get_global_url(self, resource):
if self._is_absolute_url(resource):
return resource
@ -200,10 +212,28 @@ class GCETestCase(base.BaseTestCase):
self.fail(
'There is no required item {} in the list {}'.format(item, items))
def assertObject(self, expected, observed):
self.trace('Validate object: \n\texpected: {}\n\tobserved: {}'.
format(expected, observed))
self.assertDictContainsSubset(expected, observed)
def assertObject(self, expected, actual):
self.trace('Validate object: \n\texpected: {}\n\tactual: {}'.
format(expected, actual))
# aka self.assertDictContainsSubset(expected, observed) but
# with regexp matching instead of '=='
missing = []
mismatched = []
for key, value in expected.items():
if key not in actual:
missing.append(key)
elif not re.compile(value).match(actual[key]):
msg = 'key {}: actual={} is not match to expected={}'
mismatched.append(msg.format(key, actual[key], value))
err = ''
if missing:
err = 'Missing: {}'.format(','.join(m for m in missing))
if mismatched:
if err:
err += '; '
err += 'Mismatched values: {}'.format(','.join(mismatched))
if err:
self.fail(err)
@property
def is_real_gce(self):