Browse Source

Unit testing for ip_range

- modifies custom module ip_range.py in such a way that its individual
  stages can be easily tested
- tests for this module (test_ip_range.py) are created

Change-Id: Id1ee5db19c673da318ec21d98bdd02c766a219f5
Partial-Bug: #1594785
Katerina Pilatova 2 years ago
parent
commit
c55fb24813

+ 1
- 0
test-requirements.txt View File

@@ -13,3 +13,4 @@ testrepository>=0.0.18 # Apache-2.0/BSD
13 13
 testscenarios>=0.4 # Apache-2.0/BSD
14 14
 testtools>=1.4.0 # MIT
15 15
 reno>=1.8.0 # Apache-2.0
16
+netaddr>=0.7.13,!=0.7.16 # BSD

+ 1
- 1
tox.ini View File

@@ -5,7 +5,7 @@ skipsdist = True
5 5
 
6 6
 [testenv]
7 7
 usedevelop = True
8
-install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
8
+install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages} "ansible>=2"
9 9
 setenv =
10 10
    VIRTUAL_ENV={envdir}
11 11
 deps = -r{toxinidir}/test-requirements.txt

+ 65
- 0
tripleo_validations/tests/test_ip_range.py View File

@@ -0,0 +1,65 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+# not use this file except in compliance with the License. You may obtain
5
+# a copy of the License at
6
+#
7
+#      http://www.apache.org/licenses/LICENSE-2.0
8
+#
9
+# Unless required by applicable law or agreed to in writing, software
10
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+# License for the specific language governing permissions and limitations
13
+# under the License.
14
+
15
+"""
16
+test_ip_range
17
+----------------------------------
18
+
19
+Tests for `ip_range` module.
20
+"""
21
+
22
+from tripleo_validations.tests import base
23
+import validations.library.ip_range as validation
24
+
25
+
26
+class TestIPRange(base.TestCase):
27
+
28
+    def test_check_arguments_non_IP(self):
29
+        '''Test ip_range when start is not an IP'''
30
+        errors = validation.check_arguments('something', '192.168.0.1', 1)
31
+        self.assertEqual(len(errors), 1)
32
+        self.assertEqual('Argument start (something) must be an IP', errors[0])
33
+
34
+    def test_check_arguments_IP_versions(self):
35
+        '''Test ip_range when start is IPv4 and end is IPv6'''
36
+        errors = validation.check_arguments('191.168.0.1', '::1', 2)
37
+        self.assertEqual(len(errors), 1)
38
+        self.assertEqual('Arguments start, end must share the same IP version',
39
+                         errors[0])
40
+
41
+    def test_check_arguments_neg_range(self):
42
+        '''Test ip_range when min_size is a negative number'''
43
+        errors = validation.check_arguments('192.168.0.1', '192.168.0.2', -3)
44
+        self.assertEqual(len(errors), 1)
45
+        self.assertEqual('Argument min_size(-3) must be greater than 0',
46
+                         errors[0])
47
+
48
+    def test_check_arguments_IPv4_ok(self):
49
+        '''Test ip_range on valid IPv4 arguments'''
50
+        errors = validation.check_arguments('192.168.0.1', '192.169.0.254', 5)
51
+        self.assertEqual(errors, [])
52
+
53
+    def test_check_arguments_IPv6_ok(self):
54
+        '''Test ip_range on valid IPv6 arguments'''
55
+        errors = validation.check_arguments('2001:d8::1', '2001:d8::1:1', 120)
56
+        self.assertEqual(errors, [])
57
+
58
+    def test_check_IP_range_too_small(self):
59
+        '''Test ip_range when range is less than minimal'''
60
+        warnings = validation.check_IP_range('192.168.0.1', '192.168.0.5', 6)
61
+        self.assertEqual(len(warnings), 2)
62
+        self.assertEqual('The IP range 192.168.0.1 - 192.168.0.5 ' +
63
+                         'contains 5 addresses.', warnings[0])
64
+        self.assertEqual('This might not be enough for the deployment ' +
65
+                         'or later scaling.', warnings[1])

+ 0
- 0
validations/__init__.py View File


+ 0
- 0
validations/library/__init__.py View File


+ 54
- 11
validations/library/ip_range.py View File

@@ -19,6 +19,48 @@ import netaddr
19 19
 from ansible.module_utils.basic import *  # NOQA
20 20
 
21 21
 
22
+def check_arguments(start, end, min_size):
23
+    '''Validate format of arguments'''
24
+
25
+    errors = []
26
+
27
+    # Check format of arguments
28
+    try:
29
+        startIP = netaddr.IPAddress(start)
30
+    except netaddr.core.AddrFormatError:
31
+        errors.append('Argument start ({}) must be an IP'.format(start))
32
+
33
+    try:
34
+        endIP = netaddr.IPAddress(end)
35
+    except netaddr.core.AddrFormatError:
36
+        errors.append('Argument end ({}) must be an IP'.format(end))
37
+
38
+    if (not errors) and (startIP.version != endIP.version):
39
+        errors.append('Arguments start, end must share the same IP version')
40
+
41
+    if min_size < 0:
42
+        errors.append('Argument min_size({}) must be greater than 0'
43
+                      .format(min_size))
44
+
45
+    return errors
46
+
47
+
48
+def check_IP_range(start, end, min_size):
49
+    '''Compare IP range with minimum size'''
50
+
51
+    warnings = []
52
+    iprange = netaddr.IPRange(start, end)
53
+
54
+    if len(iprange) < min_size:
55
+        warnings = [
56
+            'The IP range {} - {} contains {} addresses.'.format(
57
+                start, end, len(iprange)),
58
+            'This might not be enough for the deployment or later scaling.'
59
+        ]
60
+
61
+    return warnings
62
+
63
+
22 64
 def main():
23 65
     module = AnsibleModule(argument_spec=dict(
24 66
         start=dict(required=True, type='str'),
@@ -28,19 +70,20 @@ def main():
28 70
 
29 71
     start = module.params.get('start')
30 72
     end = module.params.get('end')
73
+    min_size = module.params.get('min_size')
31 74
 
32
-    iprange = netaddr.IPRange(start, end)
33
-
34
-    if len(iprange) < module.params.get('min_size'):
35
-        module.exit_json(
36
-            changed=True,
37
-            warnings=[
38
-                'The IP range {} - {} contains {} addresses.'.format(
39
-                    start, end, len(iprange)),
40
-                'This might not be enough for the deployment or later scaling.'
41
-            ])
75
+    # Check arguments
76
+    errors = check_arguments(start, end, min_size)
77
+    if errors:
78
+        module.fail_json(msg='\n'.join(errors))
42 79
     else:
43
-        module.exit_json(msg='success')
80
+        # Check IP range
81
+        warnings = check_IP_range(start, end, min_size)
82
+
83
+        if warnings:
84
+            module.exit_json(changed=True, warnings=warnings)
85
+        else:
86
+            module.exit_json(msg='success')
44 87
 
45 88
 
46 89
 if __name__ == '__main__':

Loading…
Cancel
Save