blob: 12e5ce0bdee7298c7ca01d61104ecc75240b9dd9 [file] [log] [blame]
Scott Bakerbba67b62019-01-28 17:38:21 -08001# 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
16from mock import patch
17import mock
18import pdb
19import networkx as nx
20
21import os
22import sys
23
24test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
25sync_lib_dir = os.path.join(test_path, "..", "xossynchronizer")
26xos_dir = os.path.join(test_path, "..", "..", "..", "xos")
27
28class TestScheduling(unittest.TestCase):
29
30 __test__ = False
31
32 def setUp(self):
33 global mock_enumerator, event_loop
34
35 self.sys_path_save = sys.path
36 self.cwd_save = os.getcwd()
37
38 config = os.path.join(test_path, "test_config.yaml")
39 from xosconfig import Config
40
41 Config.clear()
42 Config.init(config, "synchronizer-config-schema.yaml")
43
44 from xossynchronizer.mock_modelaccessor_build import (
45 build_mock_modelaccessor,
46 )
47
48 build_mock_modelaccessor(sync_lib_dir, xos_dir, services_dir=None, service_xprotos=[])
49
50 os.chdir(os.path.join(test_path, "..")) # config references tests/model-deps
51
52 import xossynchronizer.event_loop
53
54 reload(xossynchronizer.event_loop)
55 import xossynchronizer.backend
56
57 reload(xossynchronizer.backend)
58 from xossynchronizer.mock_modelaccessor import mock_enumerator
59 from xossynchronizer.modelaccessor import model_accessor
60
61 # import all class names to globals
62 for (k, v) in model_accessor.all_model_classes.items():
63 globals()[k] = v
64
65 b = xossynchronizer.backend.Backend()
66 steps_dir = Config.get("steps_dir")
67 self.steps = b.load_sync_step_modules(steps_dir)
Scott Bakerc2fddaa2019-01-30 15:45:03 -080068 self.synchronizer = xossynchronizer.event_loop.XOSObserver(self.steps, model_accessor)
Scott Bakerbba67b62019-01-28 17:38:21 -080069
70 def tearDown(self):
71 sys.path = self.sys_path_save
72 os.chdir(self.cwd_save)
73
74 def test_same_object_trivial(self):
75 s = Slice(pk=4)
76 t = Slice(pk=4)
77 same, t = self.synchronizer.same_object(s, t)
78 self.assertTrue(same)
79 self.assertEqual(t, event_loop.DIRECT_EDGE)
80
81 def test_same_object_trivial2(self):
82 s = Slice(pk=4)
83 t = Slice(pk=5)
84 same, t = self.synchronizer.same_object(s, t)
85 self.assertFalse(same)
86
87 def test_same_object_lst(self):
88 s = Slice(pk=5)
89 t = ControllerSlice(slice=s)
90 u = ControllerSlice(slice=s)
91
92 s.controllerslices = mock_enumerator([t, u])
93
94 same, et = self.synchronizer.same_object(s.controllerslices, u)
95 self.assertTrue(same)
96 self.assertEqual(et, event_loop.PROXY_EDGE)
97
98 same, et = self.synchronizer.same_object(s.controllerslices, t)
99
100 self.assertTrue(same)
101 self.assertEqual(et, event_loop.PROXY_EDGE)
102
103 def test_same_object_lst_dc(self):
104 r = Slice(pk=4)
105 s = Slice(pk=5)
106 t = ControllerSlice(slice=r)
107 u = ControllerSlice(slice=s)
108
109 s.controllerslices = mock_enumerator([u])
110
111 same, et = self.synchronizer.same_object(s.controllerslices, t)
112 self.assertFalse(same)
113
114 same, et = self.synchronizer.same_object(s.controllerslices, u)
115 self.assertTrue(same)
116
117 def test_concrete_path_no_model_path(self):
118 p = Port()
119 n = NetworkParameter()
120 verdict, _ = self.synchronizer.concrete_path_exists(p, n)
121 self.assertFalse(verdict)
122
123 def test_concrete_no_object_path_adjacent(self):
124 p = Instance()
125 s1 = Slice()
126 s2 = Slice()
127 p.slice = s2
128 verdict, _ = self.synchronizer.concrete_path_exists(p, s1)
129
130 self.assertFalse(verdict)
131
132 def test_concrete_object_path_adjacent(self):
133 p = Instance()
134 s = Slice()
135 p.slice = s
136 verdict, edge_type = self.synchronizer.concrete_path_exists(p, s)
137
138 self.assertTrue(verdict)
139 self.assertEqual(edge_type, event_loop.DIRECT_EDGE)
140
141 def test_concrete_object_controller_path_adjacent(self):
142 p = Instance()
143 q = Instance()
144 cs = ControllerSlice()
145 cs2 = ControllerSlice()
146 s1 = Slice()
147 s2 = Slice()
148 p.slice = s1
149 q.slice = s2
150 cs.slice = s1
151 s1.controllerslices = mock_enumerator([cs])
152 s2.controllerslices = mock_enumerator([])
153
154 verdict1, edge_type1 = self.synchronizer.concrete_path_exists(p, cs)
155 verdict2, _ = self.synchronizer.concrete_path_exists(q, cs)
156 verdict3, _ = self.synchronizer.concrete_path_exists(p, cs2)
157
158 self.assertTrue(verdict1)
159 self.assertFalse(verdict2)
160 self.assertFalse(verdict3)
161
162 self.assertEqual(edge_type1, event_loop.PROXY_EDGE)
163
164 def test_concrete_object_controller_path_distant(self):
165 p = Instance()
166 s = Slice()
167 t = Site()
168 ct = ControllerSite()
169 ct.site = t
170 p.slice = s
171 s.site = t
172 verdict = self.synchronizer.concrete_path_exists(p, ct)
173 self.assertTrue(verdict)
174
175 def test_concrete_object_path_distant(self):
176 p = Instance()
177 s = Slice()
178 t = Site()
179 p.slice = s
180 s.site = t
181 verdict = self.synchronizer.concrete_path_exists(p, t)
182 self.assertTrue(verdict)
183
184 def test_concrete_no_object_path_distant(self):
185 p = Instance()
186 s = Slice()
187 s.controllerslice = mock_enumerator([])
188
189 t = Site()
190 t.controllersite = mock_enumerator([])
191
192 ct = ControllerSite()
193 ct.site = Site()
194 p.slice = s
195 s.site = t
196
197 verdict, _ = self.synchronizer.concrete_path_exists(p, ct)
198 self.assertFalse(verdict)
199
200 def test_cohorting_independent(self):
201 i = Image()
202
203 p = Slice()
204 c = Instance()
205 c.slice = None
206 c.image = None
207
208 cohorts = self.synchronizer.compute_dependent_cohorts([i, p, c], False)
209 self.assertEqual(len(cohorts), 3)
210
211 def test_cohorting_related(self):
212 i = Image()
213 p = Port()
214 c = Instance()
215 c.image = i
216 s = ControllerSlice()
217
218 cohorts = self.synchronizer.compute_dependent_cohorts([i, p, c, s], False)
219 self.assertIn([i, c], cohorts)
220 self.assertIn([p], cohorts)
221 self.assertIn([s], cohorts)
222
223 def test_cohorting_related_multi(self):
224 i = Image()
225 p = Port()
226 c = Instance()
227 c.image = i
228 cs = ControllerSlice()
229 s = Slice()
230 cs.slice = s
231 s.controllerslices = mock_enumerator([cs])
232 c.slice = s
233
234 cohorts = self.synchronizer.compute_dependent_cohorts([i, p, c, s, cs], False)
235
236 big_cohort = max(cohorts, key=len)
237 self.assertGreater(big_cohort.index(c), big_cohort.index(i))
238 self.assertGreater(big_cohort.index(cs), big_cohort.index(s))
239 self.assertIn([p], cohorts)
240
241 def test_cohorting_related_multi_delete(self):
242 i = Image()
243 p = Port()
244 c = Instance()
245 c.image = i
246 cs = ControllerSlice()
247 s = Slice()
248 cs.slice = s
249 c.slice = s
250
251 cohorts = self.synchronizer.compute_dependent_cohorts([i, p, c, s, cs], True)
252
253 big_cohort = max(cohorts, key=len)
254 self.assertGreater(big_cohort.index(i), big_cohort.index(c))
255 self.assertGreater(big_cohort.index(s), big_cohort.index(cs))
256 self.assertIn([p], cohorts)
257
258 def test_cohorting_related_delete(self):
259 i = Image()
260 p = Port()
261 c = Instance()
262 c.image = i
263 s = ControllerSlice()
264
265 cohorts = self.synchronizer.compute_dependent_cohorts([i, p, c, s], True)
266 self.assertIn([c, i], cohorts)
267 self.assertIn([p], cohorts)
268 self.assertIn([s], cohorts)
269
270
271if __name__ == "__main__":
272 unittest.main()