blob: 054baeac42f8aeab0b4a6456966ea360fcbed600 [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
Scott Baker7848fa52019-04-01 17:54:36 -070018from mock import patch, Mock
Matteo Scandolo0b986e22018-06-04 14:07:33 -070019import requests_mock
20
Scott Baker7848fa52019-04-01 17:54:36 -070021import os
22import sys
Matteo Scandolo0b986e22018-06-04 14:07:33 -070023
Scott Baker7848fa52019-04-01 17:54:36 -070024test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
Matteo Scandolo0b986e22018-06-04 14:07:33 -070025
Matteo Scandolo0b986e22018-06-04 14:07:33 -070026
27def match_json(desired, req):
Scott Baker7848fa52019-04-01 17:54:36 -070028 if desired != req.json():
Matteo Scandolo0b986e22018-06-04 14:07:33 -070029 raise Exception("Got request %s, but body is not matching" % req.url)
30 return False
31 return True
32
Scott Baker7848fa52019-04-01 17:54:36 -070033
Matteo Scandolo0b986e22018-06-04 14:07:33 -070034class TestSyncOnosService(unittest.TestCase):
35
36 def setUp(self):
37
38 self.sys_path_save = sys.path
Matteo Scandolo0b986e22018-06-04 14:07:33 -070039
40 # Setting up the config module
41 from xosconfig import Config
42 config = os.path.join(test_path, "../test_config.yaml")
43 Config.clear()
44 Config.init(config, "synchronizer-config-schema.yaml")
45 # END Setting up the config module
46
Scott Baker806d4b72019-02-26 19:01:59 -080047 from xossynchronizer.mock_modelaccessor_build import mock_modelaccessor_config
Scott Baker7848fa52019-04-01 17:54:36 -070048 mock_modelaccessor_config(test_path, [("onos-service", "onos.xproto"), ])
Scott Baker806d4b72019-02-26 19:01:59 -080049
50 import xossynchronizer.modelaccessor
51 import mock_modelaccessor
Scott Baker7848fa52019-04-01 17:54:36 -070052 reload(mock_modelaccessor) # in case nose2 loaded it in a previous test
Scott Baker806d4b72019-02-26 19:01:59 -080053 reload(xossynchronizer.modelaccessor) # in case nose2 loaded it in a previous test
Matteo Scandolo0b986e22018-06-04 14:07:33 -070054
55 from sync_onos_service import SyncONOSService, model_accessor
56
Scott Baker806d4b72019-02-26 19:01:59 -080057 self.model_accessor = model_accessor
58
Matteo Scandolo0b986e22018-06-04 14:07:33 -070059 # import all class names to globals
60 for (k, v) in model_accessor.all_model_classes.items():
61 globals()[k] = v
62
Matteo Scandolo0b986e22018-06-04 14:07:33 -070063 self.sync_step = SyncONOSService
64
65 self.onos = Mock(spec=[
66 'id',
67 'name',
68 "rest_hostname",
69 "rest_port",
70 "rest_username",
71 "rest_password",
72 "class_names"
73 ])
74 self.onos.id = 1
75 self.onos.name = "onos"
76 self.onos.rest_hostname = "onos-url"
77 self.onos.rest_port = "8181"
78 self.onos.rest_username = "karaf"
79 self.onos.rest_password = "karaf"
80 self.onos.class_names = "ONOSService"
81
82 self.service = Mock()
83 self.service.id = 1
84 self.service.serviceattribute_dict = {}
85 self.service.leaf_model = self.onos
86
87 self.onos_service_attribute = Mock(spec=[
88 'id',
89 'service',
90 'name',
91 'value'
92 ])
93 self.onos_service_attribute.service = self.service
94 self.onos_service_attribute.name = "/onos/v1/network/configuration/apps/org.opencord.olt"
95 self.onos_service_attribute.value = {
96 "kafka": {
97 "bootstrapServers": "cord-kafka-kafka.default.svc.cluster.local:9092"
98 }
99 }
100
101 def tearDown(self):
102 self.onos = None
103 sys.path = self.sys_path_save
104
105 @requests_mock.Mocker()
106 def test_sync_no_service_attributes(self, m):
107 with patch.object(Service.objects, "get_items") as service_mock:
108 service_mock.return_value = [self.service]
Scott Baker806d4b72019-02-26 19:01:59 -0800109 self.sync_step(model_accessor=self.model_accessor).sync_record(self.onos)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700110 self.assertFalse(m.called)
111
112 @requests_mock.Mocker()
113 def test_sync_service_attributes_from_service(self, m):
114 expected_conf = '{"foo": "bar"}'
115
116 self.service.serviceattribute_dict = {
117 '/onos/v1/network/configuration/apps/org.onosproject.olt': expected_conf,
118 '/onos/v1/network/configuration/apps/org.onosproject.dhcp': expected_conf
119 }
120
121 m.post("http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.olt",
122 status_code=200,
123 additional_matcher=functools.partial(match_json, json.loads(expected_conf)))
124
125 m.post("http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.dhcp",
126 status_code=200,
127 additional_matcher=functools.partial(match_json, json.loads(expected_conf)))
128
129 with patch.object(Service.objects, "get_items") as service_mock:
130 service_mock.return_value = [self.service]
Scott Baker806d4b72019-02-26 19:01:59 -0800131 self.sync_step(model_accessor=self.model_accessor).sync_record(self.onos)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700132 self.assertTrue(m.called)
133 self.assertEqual(m.call_count, 2)
134
135 @requests_mock.Mocker()
136 def test_sync_service_attributes_from_attribute(self, m):
137 expected_conf = '{"foo": "bar"}'
138 self.service.serviceattribute_dict = {
139 '/onos/v1/network/configuration/apps/org.onosproject.olt': expected_conf,
140 }
141 m.post("http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.olt",
142 status_code=200,
143 additional_matcher=functools.partial(match_json, json.loads(expected_conf)))
144
145 with patch.object(Service.objects, "get_items") as service_mock:
146 service_mock.return_value = [self.service]
Scott Baker806d4b72019-02-26 19:01:59 -0800147 self.sync_step(model_accessor=self.model_accessor).sync_record(self.onos_service_attribute)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700148
149 self.assertTrue(m.called)
150 self.assertEqual(m.call_count, 1)
151
152 @requests_mock.Mocker()
153 def test_sync_service_attributes_err(self, m):
154 expected_conf = '{"foo": "bar"}'
155
156 self.service.serviceattribute_dict = {
157 '/onos/v1/network/configuration/apps/org.onosproject.olt': expected_conf,
158 }
159
160 m.post("http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.olt",
161 status_code=500,
162 text="Mock Error",
163 additional_matcher=functools.partial(match_json, json.loads(expected_conf)))
164
165 with self.assertRaises(Exception) as e, \
Scott Baker7848fa52019-04-01 17:54:36 -0700166 patch.object(Service.objects, "get_items") as service_mock:
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700167
168 service_mock.return_value = [self.service]
Scott Baker806d4b72019-02-26 19:01:59 -0800169 self.sync_step(model_accessor=self.model_accessor).sync_record(self.onos)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700170
171 self.assertTrue(m.called)
172 self.assertEqual(m.call_count, 1)
Scott Baker7848fa52019-04-01 17:54:36 -0700173 self.assertEqual(
174 e.exception.message,
175 "Failed to add config http://onos-url:8181/onos/v1/network/configuration/apps/org.onosproject.olt in ONOS")
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700176
177 @requests_mock.Mocker()
178 def test_delete(self, m):
179 m.delete("http://onos-url:8181%s" % self.onos_service_attribute.name,
180 status_code=204)
181
Scott Baker806d4b72019-02-26 19:01:59 -0800182 self.sync_step(model_accessor=self.model_accessor).delete_record(self.onos_service_attribute)
Matteo Scandolo0b986e22018-06-04 14:07:33 -0700183 self.assertTrue(m.called)
Scott Baker806d4b72019-02-26 19:01:59 -0800184 self.assertEqual(m.call_count, 1)
185
Scott Baker7848fa52019-04-01 17:54:36 -0700186
Scott Baker806d4b72019-02-26 19:01:59 -0800187if __name__ == '__main__':
188 unittest.main()