# Copyright 2013 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import re import unittest from oslo_config import types class ConfigTypeTests(unittest.TestCase): def test_none_concrete_class(self): class MyString(types.ConfigType): def __init__(self, type_name='mystring value'): super(MyString, self).__init__(type_name=type_name) self.assertRaises(TypeError, MyString) def test_concrete_class(self): class MyString(types.ConfigType): def __init__(self, type_name='mystring value'): super(MyString, self).__init__(type_name=type_name) def _formatter(self, value): return value MyString() class TypeTestHelper(object): def setUp(self): super(TypeTestHelper, self).setUp() self.type_instance = self.type def assertConvertedValue(self, s, expected): self.assertEqual(expected, self.type_instance(s)) def assertInvalid(self, value): self.assertRaises(ValueError, self.type_instance, value) class StringTypeTests(TypeTestHelper, unittest.TestCase): type = types.String() def test_empty_string_passes(self): self.assertConvertedValue('', '') def test_should_return_same_string_if_valid(self): self.assertConvertedValue('foo bar', 'foo bar') def test_listed_value(self): self.type_instance = types.String(choices=['foo', 'bar']) self.assertConvertedValue('foo', 'foo') def test_listed_value_tuple(self): self.type_instance = types.String(choices=('foo', 'bar')) self.assertConvertedValue('foo', 'foo') def test_listed_value_dict(self): self.type_instance = types.String(choices=[ ('foo', 'ab'), ('bar', 'xy')]) self.assertConvertedValue('foo', 'foo') def test_unlisted_value(self): self.type_instance = types.String(choices=['foo', 'bar']) self.assertInvalid('baz') def test_with_no_values_returns_error(self): self.type_instance = types.String(choices=[]) self.assertInvalid('foo') def test_string_with_non_closed_quote_is_invalid(self): self.type_instance = types.String(quotes=True) self.assertInvalid('"foo bar') self.assertInvalid("'bar baz") def test_quotes_are_stripped(self): self.type_instance = types.String(quotes=True) self.assertConvertedValue('"foo bar"', 'foo bar') def test_trailing_quote_is_ok(self): self.type_instance = types.String(quotes=True) self.assertConvertedValue('foo bar"', 'foo bar"') def test_single_quote_is_invalid(self): self.type_instance = types.String(quotes=True) self.assertInvalid('"') self.assertInvalid("'") def test_repr(self): t = types.String() self.assertEqual('String', repr(t)) def test_repr_with_choices(self): t = types.String(choices=['foo', 'bar']) self.assertEqual('String(choices=[\'foo\', \'bar\'])', repr(t)) def test_repr_with_choices_tuple(self): t = types.String(choices=('foo', 'bar')) self.assertEqual('String(choices=[\'foo\', \'bar\'])', repr(t)) def test_repr_with_choices_dict(self): t = types.String(choices=[('foo', 'ab'), ('bar', 'xy')]) self.assertEqual('String(choices=[\'foo\', \'bar\'])', repr(t)) def test_equal(self): self.assertTrue(types.String() == types.String()) def test_equal_with_same_choices(self): t1 = types.String(choices=['foo', 'bar']) t2 = types.String(choices=['foo', 'bar']) t3 = types.String(choices=('foo', 'bar')) t4 = types.String(choices=['bar', 'foo']) t5 = types.String(choices=[('foo', 'ab'), ('bar', 'xy')]) self.assertTrue(t1 == t2 == t3 == t4 == t5) def test_not_equal_with_different_choices(self): t1 = types.String(choices=['foo', 'bar']) t2 = types.String(choices=['foo', 'baz']) t3 = types.String(choices=('foo', 'baz')) self.assertFalse(t1 == t2) self.assertFalse(t1 == t3) def test_equal_with_equal_quote_falgs(self): t1 = types.String(quotes=True) t2 = types.String(quotes=True) self.assertTrue(t1 == t2) def test_not_equal_with_different_quote_falgs(self): t1 = types.String(quotes=False) t2 = types.String(quotes=True) self.assertFalse(t1 == t2) def test_not_equal_to_other_class(self): self.assertFalse(types.String() == types.Integer()) def test_regex_matches(self): self.type_instance = types.String(regex=re.compile("^[A-Z]")) self.assertConvertedValue("Foo", "Foo") def test_regex_matches_uncompiled(self): self.type_instance = types.String(regex="^[A-Z]") self.assertConvertedValue("Foo", "Foo") def test_regex_fails(self): self.type_instance = types.String(regex=re.compile("^[A-Z]")) self.assertInvalid("foo") def test_regex_and_choices_raises(self): self.assertRaises(ValueError, types.String, regex=re.compile("^[A-Z]"), choices=["Foo", "Bar", "baz"]) def test_equal_with_same_regex(self): t1 = types.String(regex=re.compile("^[A-Z]")) t2 = types.String(regex=re.compile("^[A-Z]")) self.assertTrue(t1 == t2) def test_not_equal_with_different_regex(self): t1 = types.String(regex=re.compile("^[A-Z]")) t2 = types.String(regex=re.compile("^[a-z]")) self.assertFalse(t1 == t2) def test_ignore_case(self): self.type_instance = types.String(choices=['foo', 'bar'], ignore_case=True) self.assertConvertedValue('Foo', 'Foo') self.assertConvertedValue('bAr', 'bAr') def test_ignore_case_raises(self): self.type_instance = types.String(choices=['foo', 'bar'], ignore_case=False) self.assertRaises(ValueError, self.assertConvertedValue, 'Foo', 'Foo') def test_regex_and_ignore_case(self): self.type_instance = types.String(regex=re.compile("^[A-Z]"), ignore_case=True) self.assertConvertedValue("foo", "foo") def test_regex_and_ignore_case_str(self): self.type_instance = types.String(regex="^[A-Z]", ignore_case=True) self.assertConvertedValue("foo", "foo") def test_regex_preserve_flags(self): self.type_instance = types.String(regex=re.compile("^[A-Z]", re.I), ignore_case=False) self.assertConvertedValue("foo", "foo") def test_max_length(self): self.type_instance = types.String(max_length=5) self.assertInvalid('123456') self.assertConvertedValue('12345', '12345') class BooleanTypeTests(TypeTestHelper, unittest.TestCase): type = types.Boolean() def test_True(self): self.assertConvertedValue('True', True) def test_yes(self): self.assertConvertedValue('yes', True) def test_on(self): self.assertConvertedValue('on', True) def test_1(self): self.assertConvertedValue('1', True) def test_False(self): self.assertConvertedValue('False', False) def test_no(self): self.assertConvertedValue('no', False) def test_off(self): self.assertConvertedValue('off', False) def test_0(self): self.assertConvertedValue('0', False) def test_other_values_produce_error(self): self.assertInvalid('foo') def test_repr(self): self.assertEqual('Boolean', repr(types.Boolean())) def test_equal(self): self.assertEqual(types.Boolean(), types.Boolean()) def test_not_equal_to_other_class(self): self.assertFalse(types.Boolean() == types.String()) class IntegerTypeTests(TypeTestHelper, unittest.TestCase): type = types.Integer() def test_empty_string(self): self.assertConvertedValue('', None) def test_whitespace_string(self): self.assertConvertedValue(" \t\t\t\t", None) def test_positive_values_are_valid(self): self.assertConvertedValue('123', 123) def test_zero_is_valid(self): self.assertConvertedValue('0', 0) def test_negative_values_are_valid(self): self.assertConvertedValue('-123', -123) def test_leading_whitespace_is_ignored(self): self.assertConvertedValue(' 5', 5) def test_trailing_whitespace_is_ignored(self): self.assertConvertedValue('7 ', 7) def test_non_digits_are_invalid(self): self.assertInvalid('12a45') def test_repr(self): t = types.Integer() self.assertEqual('Integer', repr(t)) def test_repr_with_min(self): t = types.Integer(min=123) self.assertEqual('Integer(min=123)', repr(t)) def test_repr_with_max(self): t = types.Integer(max=456) self.assertEqual('Integer(max=456)', repr(t)) def test_repr_with_min_and_max(self): t = types.Integer(min=123, max=456) self.assertEqual('Integer(min=123, max=456)', repr(t)) t = types.Integer(min=0, max=0) self.assertEqual('Integer(min=0, max=0)', repr(t)) def test_repr_with_choices(self): t = types.Integer(choices=[80, 457]) self.assertEqual('Integer(choices=[80, 457])', repr(t)) def test_repr_with_choices_tuple(self): t = types.Integer(choices=(80, 457)) self.assertEqual('Integer(choices=[80, 457])', repr(t)) def test_repr_with_choices_dict(self): t = types.Integer(choices=[(80, 'ab'), (457, 'xy')]) self.assertEqual('Integer(choices=[80, 457])', repr(t)) def test_equal(self): self.assertTrue(types.Integer() == types.Integer()) def test_equal_with_same_min_and_no_max(self): self.assertTrue(types.Integer(min=123) == types.Integer(min=123)) def test_equal_with_same_max_and_no_min(self): self.assertTrue(types.Integer(max=123) == types.Integer(max=123)) def test_equal_with_same_min_and_max(self): t1 = types.Integer(min=1, max=123) t2 = types.Integer(min=1, max=123) self.assertTrue(t1 == t2) def test_equal_with_same_choices(self): t1 = types.Integer(choices=[80, 457]) t2 = types.Integer(choices=[457, 80]) t3 = types.Integer(choices=(457, 80)) t4 = types.Integer(choices=[(80, 'ab'), (457, 'xy')]) self.assertTrue(t1 == t2 == t3 == t4) def test_not_equal(self): self.assertFalse(types.Integer(min=123) == types.Integer(min=456)) self.assertFalse(types.Integer(choices=[80, 457]) == types.Integer(choices=[80, 40])) self.assertFalse(types.Integer(choices=[80, 457]) == types.Integer()) def test_not_equal_to_other_class(self): self.assertFalse(types.Integer() == types.String()) def test_choices_with_min_max(self): self.assertRaises(ValueError, types.Integer, min=100, choices=[50, 60]) self.assertRaises(ValueError, types.Integer, max=10, choices=[50, 60]) types.Integer(min=10, max=100, choices=[50, 60]) def test_min_greater_max(self): self.assertRaises(ValueError, types.Integer, min=100, max=50) self.assertRaises(ValueError, types.Integer, min=-50, max=-100) self.assertRaises(ValueError, types.Integer, min=0, max=-50) self.assertRaises(ValueError, types.Integer, min=50, max=0) def test_with_max_and_min(self): t = types.Integer(min=123, max=456) self.assertRaises(ValueError, t, 122) t(123) t(300) t(456) self.assertRaises(ValueError, t, 0) self.assertRaises(ValueError, t, 457) def test_with_min_zero(self): t = types.Integer(min=0, max=456) self.assertRaises(ValueError, t, -1) t(0) t(123) t(300) t(456) self.assertRaises(ValueError, t, -201) self.assertRaises(ValueError, t, 457) def test_with_max_zero(self): t = types.Integer(min=-456, max=0) self.assertRaises(ValueError, t, 1) t(0) t(-123) t(-300) t(-456) self.assertRaises(ValueError, t, 201) self.assertRaises(ValueError, t, -457) def _test_with_choices(self, t): self.assertRaises(ValueError, t, 1) self.assertRaises(ValueError, t, 200) self.assertRaises(ValueError, t, -457) t(80) t(457) def test_with_choices_list(self): t = types.Integer(choices=[80, 457]) self._test_with_choices(t) def test_with_choices_tuple(self): t = types.Integer(choices=(80, 457)) self._test_with_choices(t) def test_with_choices_dict(self): t = types.Integer(choices=[(80, 'ab'), (457, 'xy')]) self._test_with_choices(t) class FloatTypeTests(TypeTestHelper, unittest.TestCase): type = types.Float() def test_decimal_format(self): v = self.type_instance('123.456') self.assertAlmostEqual(v, 123.456) def test_decimal_format_negative_float(self): v = self.type_instance('-123.456') self.assertAlmostEqual(v, -123.456) def test_exponential_format(self): v = self.type_instance('123e-2') self.assertAlmostEqual(v, 1.23) def test_non_float_is_invalid(self): self.assertInvalid('123,345') self.assertInvalid('foo') def test_repr(self): self.assertEqual('Float', repr(types.Float())) def test_repr_with_min(self): t = types.Float(min=1.1) self.assertEqual('Float(min=1.1)', repr(t)) def test_repr_with_max(self): t = types.Float(max=2.2) self.assertEqual('Float(max=2.2)', repr(t)) def test_repr_with_min_and_max(self): t = types.Float(min=1.1, max=2.2) self.assertEqual('Float(min=1.1, max=2.2)', repr(t)) t = types.Float(min=1.0, max=2) self.assertEqual('Float(min=1, max=2)', repr(t)) t = types.Float(min=0, max=0) self.assertEqual('Float(min=0, max=0)', repr(t)) def test_equal(self): self.assertTrue(types.Float() == types.Float()) def test_equal_with_same_min_and_no_max(self): self.assertTrue(types.Float(min=123.1) == types.Float(min=123.1)) def test_equal_with_same_max_and_no_min(self): self.assertTrue(types.Float(max=123.1) == types.Float(max=123.1)) def test_not_equal(self): self.assertFalse(types.Float(min=123.1) == types.Float(min=456.1)) self.assertFalse(types.Float(max=123.1) == types.Float(max=456.1)) self.assertFalse(types.Float(min=123.1) == types.Float(max=123.1)) self.assertFalse(types.Float(min=123.1, max=456.1) == types.Float(min=123.1, max=456.2)) def test_not_equal_to_other_class(self): self.assertFalse(types.Float() == types.Integer()) def test_equal_with_same_min_and_max(self): t1 = types.Float(min=1.1, max=2.2) t2 = types.Float(min=1.1, max=2.2) self.assertTrue(t1 == t2) def test_min_greater_max(self): self.assertRaises(ValueError, types.Float, min=100.1, max=50) self.assertRaises(ValueError, types.Float, min=-50, max=-100.1) self.assertRaises(ValueError, types.Float, min=0.1, max=-50.0) self.assertRaises(ValueError, types.Float, min=50.0, max=0.0) def test_with_max_and_min(self): t = types.Float(min=123.45, max=678.9) self.assertRaises(ValueError, t, 123) self.assertRaises(ValueError, t, 123.1) t(124.1) t(300) t(456.0) self.assertRaises(ValueError, t, 0) self.assertRaises(ValueError, t, 800.5) def test_with_min_zero(self): t = types.Float(min=0, max=456.1) self.assertRaises(ValueError, t, -1) t(0.0) t(123.1) t(300.2) t(456.1) self.assertRaises(ValueError, t, -201.0) self.assertRaises(ValueError, t, 457.0) def test_with_max_zero(self): t = types.Float(min=-456.1, max=0) self.assertRaises(ValueError, t, 1) t(0.0) t(-123.0) t(-300.0) t(-456.0) self.assertRaises(ValueError, t, 201.0) self.assertRaises(ValueError, t, -457.0) class ListTypeTests(TypeTestHelper, unittest.TestCase): type = types.List() def test_empty_value(self): self.assertConvertedValue('', []) def test_single_value(self): self.assertConvertedValue(' foo bar ', ['foo bar']) def test_tuple_of_values(self): self.assertConvertedValue(('foo', 'bar'), ['foo', 'bar']) def test_list_of_values(self): self.assertConvertedValue(' foo bar, baz ', ['foo bar', 'baz']) def test_list_of_values_containing_commas(self): self.type_instance = types.List(types.String(quotes=True)) self.assertConvertedValue('foo,"bar, baz",bam', ['foo', 'bar, baz', 'bam']) def test_list_of_values_containing_trailing_comma(self): self.assertConvertedValue('foo, bar, baz, ', ['foo', 'bar', 'baz']) def test_list_of_lists(self): self.type_instance = types.List( types.List(types.String(), bounds=True) ) self.assertConvertedValue('[foo],[bar, baz],[bam]', [['foo'], ['bar', 'baz'], ['bam']]) def test_list_of_custom_type(self): self.type_instance = types.List(types.Integer()) self.assertConvertedValue('1,2,3,5', [1, 2, 3, 5]) def test_list_of_custom_type_containing_trailing_comma(self): self.type_instance = types.List(types.Integer()) self.assertConvertedValue('1,2,3,5,', [1, 2, 3, 5]) def test_tuple_of_custom_type(self): self.type_instance = types.List(types.Integer()) self.assertConvertedValue(('1', '2', '3', '5'), [1, 2, 3, 5]) def test_bounds_parsing(self): self.type_instance = types.List(types.Integer(), bounds=True) self.assertConvertedValue('[1,2,3]', [1, 2, 3]) def test_bounds_required(self): self.type_instance = types.List(types.Integer(), bounds=True) self.assertInvalid('1,2,3') self.assertInvalid('[1,2,3') self.assertInvalid('1,2,3]') def test_repr(self): t = types.List(types.Integer()) self.assertEqual('List of Integer', repr(t)) def test_equal(self): self.assertTrue(types.List() == types.List()) def test_equal_with_equal_custom_item_types(self): it1 = types.Integer() it2 = types.Integer() self.assertTrue(types.List(it1) == types.List(it2)) def test_not_equal_with_non_equal_custom_item_types(self): it1 = types.Integer() it2 = types.String() self.assertFalse(it1 == it2) self.assertFalse(types.List(it1) == types.List(it2)) def test_not_equal_to_other_class(self): self.assertFalse(types.List() == types.Integer()) class RangeTypeTests(TypeTestHelper, unittest.TestCase): type = types.Range() def assertRange(self, s, r1, r2, step=1): self.assertEqual(list(range(r1, r2, step)), list(self.type_instance(s))) def test_range(self): self.assertRange('0-2', 0, 3) self.assertRange('-2-0', -2, 1) self.assertRange('2-0', 2, -1, -1) self.assertRange('-3--1', -3, 0) self.assertRange('-1--3', -1, -4, -1) self.assertRange('-1', -1, 0) self.assertInvalid('--1') self.assertInvalid('4-') self.assertInvalid('--') self.assertInvalid('1.1-1.2') self.assertInvalid('a-b') def test_range_bounds(self): self.type_instance = types.Range(1, 3) self.assertRange('1-3', 1, 4) self.assertRange('2-2', 2, 3) self.assertRange('2', 2, 3) self.assertInvalid('1-4') self.assertInvalid('0-3') self.assertInvalid('0-4') def test_range_exclusive(self): self.type_instance = types.Range(inclusive=False) self.assertRange('0-2', 0, 2) self.assertRange('-2-0', -2, 0) self.assertRange('2-0', 2, 0, -1) self.assertRange('-3--1', -3, -1) self.assertRange('-1--3', -1, -3, -1) self.assertRange('-1', -1, -1) class DictTypeTests(TypeTestHelper, unittest.TestCase): type = types.Dict() def test_empty_value(self): self.assertConvertedValue('', {}) def test_single_value(self): self.assertConvertedValue(' foo: bar ', {'foo': 'bar'}) def test_dict_of_values(self): self.assertConvertedValue(' foo: bar, baz: 123 ', {'foo': 'bar', 'baz': '123'}) def test_custom_value_type(self): self.type_instance = types.Dict(types.Integer()) self.assertConvertedValue('foo:123, bar: 456', {'foo': 123, 'bar': 456}) def test_dict_of_values_containing_commas(self): self.type_instance = types.Dict(types.String(quotes=True)) self.assertConvertedValue('foo:"bar, baz",bam:quux', {'foo': 'bar, baz', 'bam': 'quux'}) def test_dict_of_dicts(self): self.type_instance = types.Dict( types.Dict(types.String(), bounds=True) ) self.assertConvertedValue('k1:{k1:v1,k2:v2},k2:{k3:v3}', {'k1': {'k1': 'v1', 'k2': 'v2'}, 'k2': {'k3': 'v3'}}) def test_bounds_parsing(self): self.type_instance = types.Dict(types.String(), bounds=True) self.assertConvertedValue('{foo:bar,baz:123}', {'foo': 'bar', 'baz': '123'}) def test_bounds_required(self): self.type_instance = types.Dict(types.String(), bounds=True) self.assertInvalid('foo:bar,baz:123') self.assertInvalid('{foo:bar,baz:123') self.assertInvalid('foo:bar,baz:123}') def test_no_mapping_produces_error(self): self.assertInvalid('foo,bar') def test_repr(self): t = types.Dict(types.Integer()) self.assertEqual('Dict of Integer', repr(t)) def test_equal(self): self.assertTrue(types.Dict() == types.Dict()) def test_equal_with_equal_custom_item_types(self): it1 = types.Integer() it2 = types.Integer() self.assertTrue(types.Dict(it1) == types.Dict(it2)) def test_not_equal_with_non_equal_custom_item_types(self): it1 = types.Integer() it2 = types.String() self.assertFalse(it1 == it2) self.assertFalse(types.Dict(it1) == types.Dict(it2)) def test_not_equal_to_other_class(self): self.assertFalse(types.Dict() == types.Integer()) class IPAddressTypeTests(TypeTestHelper, unittest.TestCase): type = types.IPAddress() def test_ipv4_address(self): self.assertConvertedValue('192.168.0.1', '192.168.0.1') def test_ipv6_address(self): self.assertConvertedValue('abcd:ef::1', 'abcd:ef::1') def test_strings(self): self.assertInvalid('') self.assertInvalid('foo') def test_numbers(self): self.assertInvalid(1) self.assertInvalid(-1) self.assertInvalid(3.14) class IPv4AddressTypeTests(IPAddressTypeTests): type = types.IPAddress(4) def test_ipv6_address(self): self.assertInvalid('abcd:ef::1') class IPv6AddressTypeTests(IPAddressTypeTests): type = types.IPAddress(6) def test_ipv4_address(self): self.assertInvalid('192.168.0.1') class HostAddressTypeTests(TypeTestHelper, unittest.TestCase): type = types.HostAddress() def test_invalid_host_addresses(self): self.assertInvalid('-1') self.assertInvalid('_foo') self.assertInvalid('3.14') self.assertInvalid('10.0') self.assertInvalid('host..name') self.assertInvalid('org.10') self.assertInvalid('0.0.00') def test_valid_host_addresses(self): self.assertConvertedValue('foo.bar', 'foo.bar') self.assertConvertedValue('192.168.0.1', '192.168.0.1') self.assertConvertedValue('abcd:ef::1', 'abcd:ef::1') self.assertConvertedValue('home-site-here.org.com', 'home-site-here.org.com') self.assertConvertedValue('3com.com', '3com.com') self.assertConvertedValue('10.org', '10.org') self.assertConvertedValue('cell1.nova.site1', 'cell1.nova.site1') self.assertConvertedValue('ab-c.com', 'ab-c.com') self.assertConvertedValue('abc.com-org', 'abc.com-org') self.assertConvertedValue('abc.0-0', 'abc.0-0') class HostDomainTypeTests(TypeTestHelper, unittest.TestCase): type = types.HostDomain() def test_invalid_host_addresses(self): self.assertInvalid('-1') self.assertInvalid('3.14') self.assertInvalid('10.0') self.assertInvalid('host..name') self.assertInvalid('org.10') self.assertInvalid('0.0.00') def test_valid_host_addresses(self): self.assertConvertedValue('_foo', '_foo') self.assertConvertedValue('host_name', 'host_name') self.assertConvertedValue( 'overcloud-novacompute_edge1-0.internalapi.localdomain', 'overcloud-novacompute_edge1-0.internalapi.localdomain') self.assertConvertedValue('host_01.co.uk', 'host_01.co.uk') self.assertConvertedValue('_site01001', '_site01001') class HostnameTypeTests(TypeTestHelper, unittest.TestCase): type = types.Hostname() def assertConvertedEqual(self, value): self.assertConvertedValue(value, value) def test_empty_hostname_fails(self): self.assertInvalid('') def test_should_return_same_hostname_if_valid(self): self.assertConvertedEqual('foo.bar') def test_trailing_quote_is_invalid(self): self.assertInvalid('foo.bar"') def test_repr(self): self.assertEqual('Hostname', repr(types.Hostname())) def test_equal(self): self.assertEqual(types.Hostname(), types.Hostname()) def test_not_equal_to_other_class(self): self.assertNotEqual(types.Hostname(), types.Integer()) self.assertNotEqual(types.Hostname(), types.String()) def test_invalid_characters(self): self.assertInvalid('"host"') self.assertInvalid("h'ost'") self.assertInvalid("h'ost") self.assertInvalid("h$ost") self.assertInvalid("host_01.co.uk") self.assertInvalid("h%ost") self.assertInvalid("host;name=99") self.assertInvalid('___site0.1001') self.assertInvalid('_site01001') self.assertInvalid("host..name") self.assertInvalid(".host.name.com") self.assertInvalid("no spaces") def test_invalid_hostnames_with_numeric_characters(self): self.assertInvalid("10.0.0.0") self.assertInvalid("3.14") self.assertInvalid('___site0.1001') self.assertInvalid("org.10") self.assertInvalid('0.0.00') def test_no_start_end_hyphens(self): self.assertInvalid("-host.com") self.assertInvalid("-hostname.com-") self.assertInvalid("hostname.co.uk-") def test_strip_trailing_dot(self): self.assertConvertedValue('cell1.nova.site1.', 'cell1.nova.site1') self.assertConvertedValue('cell1.', 'cell1') def test_valid_hostname(self): self.assertConvertedEqual('cell1.nova.site1') self.assertConvertedEqual('site01001') self.assertConvertedEqual('home-site-here.org.com') self.assertConvertedEqual('localhost') self.assertConvertedEqual('3com.com') self.assertConvertedEqual('10.org') self.assertConvertedEqual('10ab.10ab') self.assertConvertedEqual('ab-c.com') self.assertConvertedEqual('abc.com-org') self.assertConvertedEqual('abc.0-0') def test_max_segment_size(self): self.assertConvertedEqual('host.%s.com' % ('x' * 63)) self.assertInvalid('host.%s.com' % ('x' * 64)) def test_max_hostname_size(self): test_str = '.'.join('x'*31 for x in range(8)) self.assertEqual(255, len(test_str)) self.assertInvalid(test_str) self.assertConvertedEqual(test_str[:-2]) class URITypeTests(TypeTestHelper, unittest.TestCase): type = types.URI() def test_uri(self): self.assertConvertedValue('http://example.com', 'http://example.com') self.assertInvalid('invalid') # it doesn't include a scheme self.assertInvalid('http://') # it doesn't include an authority def test_repr(self): self.assertEqual('URI', repr(types.URI())) def test_max_length(self): self.type_instance = types.String(max_length=30) self.assertInvalid('http://www.example.com/versions') self.assertConvertedValue('http://www.example.com', 'http://www.example.com') def test_equality(self): a = types.URI() b = types.URI() self.assertEqual(a, b) def test_equality_length(self): a = types.URI(max_length=5) b = types.URI(max_length=5) self.assertEqual(a, b) def test_equality_length_not(self): a = types.URI() b = types.URI(max_length=5) c = types.URI(max_length=10) self.assertNotEqual(a, b) self.assertNotEqual(c, b) def test_equality_schemes(self): a = types.URI(schemes=['ftp']) b = types.URI(schemes=['ftp']) self.assertEqual(a, b) def test_equality_schemes_not(self): a = types.URI() b = types.URI(schemes=['ftp']) c = types.URI(schemes=['http']) self.assertNotEqual(a, b) self.assertNotEqual(c, b) class PortTypeTests(TypeTestHelper, unittest.TestCase): type = types.Port() def test_port(self): self.assertInvalid(-1) self.assertInvalid(65536) self.assertConvertedValue('80', 80) self.assertConvertedValue('65535', 65535) def test_repr(self): self.assertEqual('Port(min=0, max=65535)', repr(types.Port())) def test_repr_with_min(self): t = types.Port(min=123) self.assertEqual('Port(min=123, max=65535)', repr(t)) def test_repr_with_max(self): t = types.Port(max=456) self.assertEqual('Port(min=0, max=456)', repr(t)) def test_repr_with_min_and_max(self): t = types.Port(min=123, max=456) self.assertEqual('Port(min=123, max=456)', repr(t)) t = types.Port(min=0, max=0) self.assertEqual('Port(min=0, max=0)', repr(t)) def test_repr_with_choices(self): t = types.Port(choices=[80, 457]) self.assertEqual('Port(choices=[80, 457])', repr(t)) def test_repr_with_choices_tuple(self): t = types.Port(choices=(80, 457)) self.assertEqual('Port(choices=[80, 457])', repr(t)) def _test_with_choices(self, t): self.assertRaises(ValueError, t, 1) self.assertRaises(ValueError, t, 200) self.assertRaises(ValueError, t, -457) t(80) t(457) def test_with_choices_list(self): t = types.Port(choices=[80, 457]) self._test_with_choices(t) def test_with_choices_tuple(self): t = types.Port(choices=(80, 457)) self._test_with_choices(t) def test_with_choices_dict(self): t = types.Port(choices=[(80, 'ab'), (457, 'xy')]) self._test_with_choices(t) def test_invalid_choices(self): """Check for choices that are specifically invalid for ports.""" self.assertRaises(ValueError, types.Port, choices=[-1, 457]) self.assertRaises(ValueError, types.Port, choices=[1, 2, 3, 65536]) def test_equal(self): self.assertTrue(types.Port() == types.Port()) def test_equal_with_same_min_and_no_max(self): self.assertTrue(types.Port(min=123) == types.Port(min=123)) def test_equal_with_same_max_and_no_min(self): self.assertTrue(types.Port(max=123) == types.Port(max=123)) def test_equal_with_same_min_and_max(self): t1 = types.Port(min=1, max=123) t2 = types.Port(min=1, max=123) self.assertTrue(t1 == t2) def test_equal_with_same_choices(self): t1 = types.Port(choices=[80, 457]) t2 = types.Port(choices=[457, 80]) t3 = types.Port(choices=(457, 80)) t4 = types.Port(choices=[(457, 'ab'), (80, 'xy')]) self.assertTrue(t1 == t2 == t3 == t4) def test_not_equal(self): self.assertFalse(types.Port(min=123) == types.Port(min=456)) self.assertFalse(types.Port(choices=[80, 457]) == types.Port(choices=[80, 40])) self.assertFalse(types.Port(choices=[80, 457]) == types.Port()) def test_not_equal_to_other_class(self): self.assertFalse(types.Port() == types.Integer()) def test_choices_with_min_max(self): self.assertRaises(ValueError, types.Port, min=100, choices=[50, 60]) self.assertRaises(ValueError, types.Port, max=10, choices=[50, 60]) types.Port(min=10, max=100, choices=[50, 60]) def test_min_greater_max(self): self.assertRaises(ValueError, types.Port, min=100, max=50) self.assertRaises(ValueError, types.Port, min=-50, max=-100) self.assertRaises(ValueError, types.Port, min=0, max=-50) self.assertRaises(ValueError, types.Port, min=50, max=0) def test_illegal_min(self): self.assertRaises(ValueError, types.Port, min=-1, max=50) self.assertRaises(ValueError, types.Port, min=-50) def test_illegal_max(self): self.assertRaises(ValueError, types.Port, min=100, max=65537) self.assertRaises(ValueError, types.Port, max=100000) def test_with_max_and_min(self): t = types.Port(min=123, max=456) self.assertRaises(ValueError, t, 122) t(123) t(300) t(456) self.assertRaises(ValueError, t, 0) self.assertRaises(ValueError, t, 457) def test_with_min_zero(self): t = types.Port(min=0, max=456) self.assertRaises(ValueError, t, -1) t(0) t(123) t(300) t(456) self.assertRaises(ValueError, t, -201) self.assertRaises(ValueError, t, 457) def test_with_max_zero(self): t = types.Port(max=0) self.assertRaises(ValueError, t, 1) t(0) class FormatSampleDefaultTests(unittest.TestCase): def test_string(self): t = types.String() self.assertEqual([' bar '], t.format_defaults('foo', sample_default=' bar ')) def test_string_non_str(self): t = types.String() e = Exception('bar') self.assertEqual(['bar'], t.format_defaults('', sample_default=e)) def test_string_non_str_spaces(self): t = types.String() e = Exception(' bar ') self.assertEqual(['" bar "'], t.format_defaults('', sample_default=e)) def test_list_string(self): t = types.List(item_type=types.String()) test_list = ['foo', Exception(' bar ')] self.assertEqual(['foo," bar "'], t.format_defaults('', sample_default=test_list)) def test_list_no_type(self): t = types.List() test_list = ['foo', Exception(' bar ')] self.assertEqual(['foo," bar "'], t.format_defaults('', sample_default=test_list)) def test_list_not_list(self): t = types.List() self.assertEqual(['foo'], t.format_defaults('', sample_default=Exception('foo')))