blob: ee6daafcb6490a941fd5a40967aa41b43350981f [file] [log] [blame]
Matteo Scandolo0b986e22018-06-04 14:07:33 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain 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,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import unittest
16import json
17import functools
18from mock import patch, call, Mock, PropertyMock
19import requests_mock
20
21import os, sys
22
Matteo Scandolo0b986e22018-06-04 14:07:33 -070023test_path=os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
Matteo Scandolo0b986e22018-06-04 14:07:33 -070024
Matteo Scandolo0b986e22018-06-04 14:07:33 -070025
26def match_json(desired, req):
27 if desired!=req.json():
28 raise Exception("Got request %s, but body is not matching" % req.url)
29 return False
30 return True
31
32class TestSyncOnosService(unittest.TestCase):
33
34 def setUp(self):
35
36 self.sys_path_save = sys.path
Matteo Scandolo0b986e22018-06-04 14:07:33 -070037
38 # Setting up the config module
39 from xosconfig import Config
40 config = os.path.join(test_path, "../test_config.yaml")
41 Config.clear()
42 Config.init(config, "synchronizer-config-schema.yaml")
43 # END Setting up the config module
44
Scott Baker806d4b72019-02-26 19:01:59 -080045 from xossynchronizer.mock_modelaccessor_build import mock_modelaccessor_config
46 mock_modelaccessor_config(test_path, [("onos-service", "onos.xproto"),])
47
48 import xossynchronizer.modelaccessor
49 import mock_modelaccessor
50 reload(mock_modelaccessor) # in case nose2 loaded it in a previous test
51 reload(xossynchronizer.modelaccessor) # in case nose2 loaded it in a previous test
Matteo Scandolo0b986e22018-06-04 14:07:33 -070052
53 from sync_onos_service import SyncONOSService, model_accessor
54
Scott Baker806d4b72019-02-26 19:01:59 -080055 self.model_accessor = model_accessor
56
Matteo Scandolo0b986e22018-06-04 14:07:33 -070057 # import all class names to globals
58 for (k, v) in model_accessor.all_model_classes.items():
59 globals()[k] = v
60
61
62 self.sync_step = SyncONOSService
63
64 self.onos = Mock(spec=[
65 'id',
66 'name',
67 "rest_hostname",
68 "rest_port",
69 "rest_username",
70 "rest_password",
71 "class_names"
72 ])
73 self.onos.id = 1
74 self.onos.name = "onos"
75 self.onos.rest_hostname = "onos-url"
76 self.onos.rest_port = "8181"
77 self.onos.rest_username = "karaf"
78 self.onos.rest_password = "karaf"
79 self.onos.class_names = "ONOSService"
80
81 self.service = Mock()
82 self.service.id = 1
83 self.service.serviceattribute_dict = {}
84 self.service.leaf_model = self.onos
85
86 self.onos_service_attribute = Mock(spec=[
87 'id',
88 'service',
89 'name',
90 'value'
91 ])
92 self.onos_service_attribute.service = self.service
93 self.onos_service_attribute.name = "/onos/v1/network/configuration/apps/org.opencord.olt"
94 self.onos_service_attribute.value = {
95 "kafka": {
96 "bootstrapServers": "cord-kafka-kafka.default.svc.cluster.local:9092"
97 }
98 }
99
100 def tearDown(self):
101 self.onos = None
102 sys.path = self.sys_path_save
103
104 @requests_mock.Mocker()
105 def test_sync_no_service_attributes(self, m):
106 with patch.object(Service.objects, "get_items") as service_mock:
107 service_mock.return_value = [self.service]
Scott Baker806d4b72019-02-26 19:01:59 -0800108 self.sync_step(model_accessor=self.model_accessor).sync_record(self.onos)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700109 self.assertFalse(m.called)
110
111 @requests_mock.Mocker()
112 def test_sync_service_attributes_from_service(self, m):
113 expected_conf = '{"foo": "bar"}'
114
115 self.service.serviceattribute_dict = {
116 '/onos/v1/network/configuration/apps/org.onosproject.olt': expected_conf,
117 '/onos/v1/network/configuration/apps/org.onosproject.dhcp': expected_conf
118 }
119
120 m.post("http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.olt",
121 status_code=200,
122 additional_matcher=functools.partial(match_json, json.loads(expected_conf)))
123
124 m.post("http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.dhcp",
125 status_code=200,
126 additional_matcher=functools.partial(match_json, json.loads(expected_conf)))
127
128 with patch.object(Service.objects, "get_items") as service_mock:
129 service_mock.return_value = [self.service]
Scott Baker806d4b72019-02-26 19:01:59 -0800130 self.sync_step(model_accessor=self.model_accessor).sync_record(self.onos)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700131 self.assertTrue(m.called)
132 self.assertEqual(m.call_count, 2)
133
134 @requests_mock.Mocker()
135 def test_sync_service_attributes_from_attribute(self, m):
136 expected_conf = '{"foo": "bar"}'
137 self.service.serviceattribute_dict = {
138 '/onos/v1/network/configuration/apps/org.onosproject.olt': expected_conf,
139 }
140 m.post("http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.olt",
141 status_code=200,
142 additional_matcher=functools.partial(match_json, json.loads(expected_conf)))
143
144 with patch.object(Service.objects, "get_items") as service_mock:
145 service_mock.return_value = [self.service]
Scott Baker806d4b72019-02-26 19:01:59 -0800146 self.sync_step(model_accessor=self.model_accessor).sync_record(self.onos_service_attribute)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700147
148 self.assertTrue(m.called)
149 self.assertEqual(m.call_count, 1)
150
151 @requests_mock.Mocker()
152 def test_sync_service_attributes_err(self, m):
153 expected_conf = '{"foo": "bar"}'
154
155 self.service.serviceattribute_dict = {
156 '/onos/v1/network/configuration/apps/org.onosproject.olt': expected_conf,
157 }
158
159 m.post("http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.olt",
160 status_code=500,
161 text="Mock Error",
162 additional_matcher=functools.partial(match_json, json.loads(expected_conf)))
163
164 with self.assertRaises(Exception) as e, \
165 patch.object(Service.objects, "get_items") as service_mock:
166
167 service_mock.return_value = [self.service]
Scott Baker806d4b72019-02-26 19:01:59 -0800168 self.sync_step(model_accessor=self.model_accessor).sync_record(self.onos)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700169
170 self.assertTrue(m.called)
171 self.assertEqual(m.call_count, 1)
172 self.assertEqual(e.exception.message, "Failed to add config http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.olt in ONOS")
173
174 @requests_mock.Mocker()
175 def test_delete(self, m):
176 m.delete("http://onos-url:8181%s" % self.onos_service_attribute.name,
177 status_code=204)
178
Scott Baker806d4b72019-02-26 19:01:59 -0800179 self.sync_step(model_accessor=self.model_accessor).delete_record(self.onos_service_attribute)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700180 self.assertTrue(m.called)
Scott Baker806d4b72019-02-26 19:01:59 -0800181 self.assertEqual(m.call_count, 1)
182
183if __name__ == '__main__':
184 unittest.main()