blob: 4c8b41ec4948ffa0039da9ec07b2a1aa2fee681c [file] [log] [blame]
Matteo Scandoloaf3c9942018-06-27 14:03:12 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
Scott Bakere9855012019-04-01 15:01:34 -070016#from __future__ import absolute_import
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070017
Scott Bakere9855012019-04-01 15:01:34 -070018import imp
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070019import unittest
20import ipaddress
Scott Bakere9855012019-04-01 15:01:34 -070021from mock import patch, Mock
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070022
Scott Bakere9855012019-04-01 15:01:34 -070023import os
24import sys
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070025
Scott Bakere9855012019-04-01 15:01:34 -070026test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
27
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070028
29class TestComputeNodePolicy(unittest.TestCase):
30 def setUp(self):
31 global ComputeNodePolicy, MockObjectList
32
33 self.sys_path_save = sys.path
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070034
35 config = os.path.join(test_path, "../test_config.yaml")
36 from xosconfig import Config
37 Config.clear()
38 Config.init(config, 'synchronizer-config-schema.yaml')
39
Scott Baker382366d2019-02-04 10:58:43 -080040 from xossynchronizer.mock_modelaccessor_build import mock_modelaccessor_config
41 mock_modelaccessor_config(test_path, [("fabric", "fabric.xproto")])
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070042
Scott Baker382366d2019-02-04 10:58:43 -080043 import xossynchronizer.modelaccessor
44 import mock_modelaccessor
Scott Bakere9855012019-04-01 15:01:34 -070045 imp.reload(mock_modelaccessor) # in case nose2 loaded it in a previous test
46 imp.reload(xossynchronizer.modelaccessor) # in case nose2 loaded it in a previous test
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070047
48 from model_policy_compute_nodes import ComputeNodePolicy, model_accessor
49
Scott Baker382366d2019-02-04 10:58:43 -080050 self.model_accessor = model_accessor
51
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070052 from mock_modelaccessor import MockObjectList
53
54 # import all class names to globals
55 for (k, v) in model_accessor.all_model_classes.items():
56 globals()[k] = v
57
Scott Bakere9855012019-04-01 15:01:34 -070058 # Some of the functions we call have side-effects. For example, creating a VSGServiceInstance may lead to
59 # creation of tags. Ideally, this wouldn't happen, but it does. So make sure we reset the world.
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070060 model_accessor.reset_all_object_stores()
61
62 self.policy = ComputeNodePolicy
63 self.model = Mock()
64
65 def tearDown(self):
66 sys.path = self.sys_path_save
67
68 def test_getLastAddress(self):
69
Scott Bakere9855012019-04-01 15:01:34 -070070 dataPlaneIp = u"10.6.1.2/24"
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070071 interface = ipaddress.ip_interface(dataPlaneIp)
72 subnet = ipaddress.ip_network(interface.network)
73 last_ip = self.policy.getLastAddress(subnet)
74 self.assertEqual(str(last_ip), "10.6.1.254/24")
75
76 def test_generateVlan(self):
77
Scott Bakere9855012019-04-01 15:01:34 -070078 used_vlans = list(range(16, 4093))
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070079 used_vlans.remove(1000)
80
81 vlan = self.policy.generateVlan(used_vlans)
82
83 self.assertEqual(vlan, 1000)
84
85 def test_generateVlanFail(self):
86
Scott Bakere9855012019-04-01 15:01:34 -070087 used_vlans = list(range(16, 4093))
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070088
89 with self.assertRaises(Exception) as e:
90 self.policy.generateVlan(used_vlans)
91
92 self.assertEqual(e.exception.message, "No VLANs left")
93
94 def test_getVlanByCidr_same_subnet(self):
95
Scott Bakere9855012019-04-01 15:01:34 -070096 mock_pi_ip = u"10.6.1.2/24"
97
Matteo Scandoloaf3c9942018-06-27 14:03:12 -070098 mock_pi = Mock()
99 mock_pi.vlanUntagged = 1234
100 mock_pi.ips = str(self.policy.getPortCidrByIp(mock_pi_ip))
101
Scott Bakere9855012019-04-01 15:01:34 -0700102 test_ip = u"10.6.1.1/24"
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700103 test_subnet = self.policy.getPortCidrByIp(test_ip)
104
105 with patch.object(PortInterface.objects, "get_items") as get_pi:
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700106 get_pi.return_value = [mock_pi]
107 vlan = self.policy.getVlanByCidr(test_subnet)
108
109 self.assertEqual(vlan, mock_pi.vlanUntagged)
110
111 def test_getVlanByCidr_different_subnet(self):
112
Scott Bakere9855012019-04-01 15:01:34 -0700113 mock_pi_ip = u"10.6.1.2/24"
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700114 mock_pi = Mock()
115 mock_pi.vlanUntagged = 1234
116 mock_pi.ips = str(self.policy.getPortCidrByIp(mock_pi_ip))
117
Scott Bakere9855012019-04-01 15:01:34 -0700118 test_ip = u"192.168.1.1/24"
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700119 test_subnet = self.policy.getPortCidrByIp(test_ip)
120
121 with patch.object(PortInterface.objects, "get_items") as get_pi:
122
123 get_pi.return_value = [mock_pi]
124 vlan = self.policy.getVlanByCidr(test_subnet)
125
126 self.assertNotEqual(vlan, mock_pi.vlanUntagged)
127
128 def test_handle_create(self):
129
Scott Baker382366d2019-02-04 10:58:43 -0800130 policy = self.policy(model_accessor=self.model_accessor)
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700131 with patch.object(policy, "handle_update") as handle_update:
132 policy.handle_create(self.model)
133 handle_update.assert_called_with(self.model)
134
135 def test_handle_update_do_nothing(self):
136
Scott Bakere9855012019-04-01 15:01:34 -0700137 mock_pi_ip = u"10.6.1.2/24"
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700138 mock_pi = Mock()
139 mock_pi.port_id = 1
140 mock_pi.name = "test_interface"
141 mock_pi.ips = str(self.policy.getPortCidrByIp(mock_pi_ip))
142
Scott Baker382366d2019-02-04 10:58:43 -0800143 policy = self.policy(model_accessor=self.model_accessor)
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700144
145 self.model.port.id = 1
146 self.model.node.dataPlaneIntf = "test_interface"
147
148 with patch.object(PortInterface.objects, "get_items") as get_pi, \
Scott Bakere9855012019-04-01 15:01:34 -0700149 patch.object(self.policy, "getPortCidrByIp") as get_subnet, \
150 patch.object(PortInterface, 'save') as mock_save:
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700151
152 get_pi.return_value = [mock_pi]
153 get_subnet.return_value = mock_pi.ips
154
155 policy.handle_update(self.model)
156
157 mock_save.assert_not_called()
158
159 def test_handle_update(self):
160
Scott Baker382366d2019-02-04 10:58:43 -0800161 policy = self.policy(model_accessor=self.model_accessor)
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700162
163 self.model.port.id = 1
164 self.model.node.dataPlaneIntf = "test_interface"
Scott Bakere9855012019-04-01 15:01:34 -0700165 self.model.node.dataPlaneIp = u"10.6.1.2/24"
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700166
167 with patch.object(PortInterface.objects, "get_items") as get_pi, \
Scott Bakere9855012019-04-01 15:01:34 -0700168 patch.object(self.policy, "getVlanByCidr") as get_vlan, \
169 patch.object(PortInterface, "save", autospec=True) as mock_save:
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700170
171 get_pi.return_value = []
172 get_vlan.return_value = "1234"
173
174 policy.handle_update(self.model)
175
176 self.assertEqual(mock_save.call_count, 1)
177 pi = mock_save.call_args[0][0]
178
179 self.assertEqual(pi.name, self.model.node.dataPlaneIntf)
180 self.assertEqual(pi.port_id, self.model.port.id)
181 self.assertEqual(pi.vlanUntagged, "1234")
182 self.assertEqual(pi.ips, "10.6.1.254/24")
183
184
185if __name__ == '__main__':
Scott Baker382366d2019-02-04 10:58:43 -0800186 sys.path.append("../steps") # so we can import helpers from steps directory
Matteo Scandoloaf3c9942018-06-27 14:03:12 -0700187 unittest.main()