blob: edccf21e44bcc94ea052eda7a071644fb483963e [file] [log] [blame]
Matteo Scandolod2044a42017-08-07 16:08:28 -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
16
Scott Bakerf0ee0dc2017-05-15 10:10:05 -070017""" fake_stub.py
18
19 Implements a simple fake grpc stub to use for unit testing.
20"""
21
22import functools
23
Scott Bakerf0ee0dc2017-05-15 10:10:05 -070024ContentTypeMap = {}
25
26class FakeObj(object):
Scott Bakerff104cc2017-08-14 15:24:41 -070027 BASES=[]
28
Scott Baker03a163f2017-05-17 09:21:47 -070029 def __init__(self, fields=[], **kwargs):
Scott Bakerf0ee0dc2017-05-15 10:10:05 -070030 super(FakeObj, self).__setattr__("is_set", {})
31 super(FakeObj, self).__setattr__("fields", [])
32
Scott Baker03a163f2017-05-17 09:21:47 -070033 for f in fields:
34 name = f["name"]
35 self.fields.append(name)
36 setattr(self, name, f["default"])
Scott Bakerf0ee0dc2017-05-15 10:10:05 -070037
38 super(FakeObj, self).__setattr__("is_set", {})
39 for (k,v) in kwargs.items():
40 setattr(self, k, v)
41
42 def __repr__(self):
43 lines = []
44 for k in self.fields:
45 if self.is_set.get(k, False):
46 lines.append('%s: "%s"' % (k, getattr(self, k)))
47 if lines:
48 return "\n".join(lines) + "\n"
49 else:
50 return ""
51
52 def __setattr__(self, name, value):
53 self.is_set[name] = True
54 super(FakeObj, self).__setattr__(name, value)
55
Scott Baker500f8c72017-05-19 09:41:50 -070056 @property
57 def self_content_type_id(self):
58 return "xos.%s" % self.__class__.__name__.lower()
59
Scott Bakerf0ee0dc2017-05-15 10:10:05 -070060class FakeExtensionManager(object):
61 def __init__(self, obj, extensions):
62 self.obj = obj
63 self.extensions = extensions
64
65 def _FindExtensionByName(self, name):
66 return name
67
68 def __getitem__(self, name, default=None):
69 if name in self.extensions:
70 return self.extensions[name]
71 return default
72
Scott Baker03a163f2017-05-17 09:21:47 -070073class FakeFieldOption(object):
74 def __init__(self, modelName=None):
75 self.modelName = modelName
76
77class FakeField(object):
78 def __init__(self, field):
79 extensions = {}
80
81 fk_model = field.get("fk_model", None)
82 if fk_model:
83 extensions["xos.foreignKey"] = FakeFieldOption(modelName=fk_model)
84
85 fk_reverse = field.get("fk_reverse", None)
86 if fk_reverse:
87 extensions["xos.reverseForeignKey"] = FakeFieldOption(modelName=fk_reverse)
88
89 self.Extensions = FakeExtensionManager(self, extensions)
90
91 def GetOptions(self):
92 return self
93
Scott Bakerf0ee0dc2017-05-15 10:10:05 -070094class FakeDescriptor(object):
95 def __init__(self, objName):
96 global ContentTypeIdCounter
97 global ContentTypeMap
Scott Baker03a163f2017-05-17 09:21:47 -070098 self.objName = objName
Scott Bakerf0ee0dc2017-05-15 10:10:05 -070099 if objName in ContentTypeMap:
100 ct = ContentTypeMap[objName]
101 else:
Scott Baker500f8c72017-05-19 09:41:50 -0700102 ct = "xos.%s" % objName.lower()
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700103 ContentTypeMap[objName] = ct
104 self.Extensions = FakeExtensionManager(self, {"xos.contentTypeId": ct})
105
106 def GetOptions(self):
107 return self
108
109 @property
110 def fields_by_name(self):
Scott Baker03a163f2017-05-17 09:21:47 -0700111 cls = globals()[self.objName]
112 fbn = {}
113 for field in cls.FIELDS:
114 fake_field = FakeField(field)
115 fbn[ field["name"] ] = fake_field
116
117 return fbn
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700118
Scott Baker5f38c7b2017-08-18 10:12:49 -0700119class Controller(FakeObj):
120 FIELDS = ( {"name": "id", "default": 0},
121 {"name": "name", "default": ""},
122 {"name": "deployment_id", "default": 0, "fk_model": "Deployment"}
123 )
124
125 def __init__(self, **kwargs):
126 return super(Controller, self).__init__(self.FIELDS, **kwargs)
127
128 DESCRIPTOR = FakeDescriptor("Controller")
129
130class Deployment(FakeObj):
131 FIELDS = ( {"name": "id", "default": 0},
132 {"name": "name", "default": ""},
133 )
134
135 def __init__(self, **kwargs):
136 return super(Deployment, self).__init__(self.FIELDS, **kwargs)
137
138 DESCRIPTOR = FakeDescriptor("Controller")
139
Scott Bakerff104cc2017-08-14 15:24:41 -0700140class User(FakeObj):
141 FIELDS = ( {"name": "id", "default": 0},
142 {"name": "email", "default": ""},
143 {"name": "site_id", "default": 0, "fk_model": "Site"}, )
144
145 def __init__(self, **kwargs):
146 return super(User, self).__init__(self.FIELDS, **kwargs)
147
148 DESCRIPTOR = FakeDescriptor("User")
149
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700150class Slice(FakeObj):
Scott Baker03a163f2017-05-17 09:21:47 -0700151 FIELDS = ( {"name": "id", "default": 0},
152 {"name": "name", "default": ""},
Scott Bakerff104cc2017-08-14 15:24:41 -0700153 {"name": "site_id", "default": 0, "fk_model": "Site"},
Scott Baker5f38c7b2017-08-18 10:12:49 -0700154 {"name": "service_id", "default": 0, "fk_model": "Service"},
Scott Bakerff104cc2017-08-14 15:24:41 -0700155 {"name": "creator_id", "default": 0, "fk_model": "User"},
Scott Baker5f38c7b2017-08-18 10:12:49 -0700156 {"name": "networks_ids", "default": [], "fk_reverse": "Network"},
157 {"name": "network", "default": ""},
Scott Bakerff104cc2017-08-14 15:24:41 -0700158 {"name": "leaf_model_name", "default": "Slice"} )
Scott Baker03a163f2017-05-17 09:21:47 -0700159
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700160 def __init__(self, **kwargs):
Scott Baker03a163f2017-05-17 09:21:47 -0700161 return super(Slice, self).__init__(self.FIELDS, **kwargs)
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700162
163 DESCRIPTOR = FakeDescriptor("Slice")
164
Scott Baker03a163f2017-05-17 09:21:47 -0700165class Site(FakeObj):
166 FIELDS = ( {"name": "id", "default": 0},
167 {"name": "name", "default": ""},
Scott Baker5f38c7b2017-08-18 10:12:49 -0700168 {"name": "slice_ids", "default": [], "fk_reverse": "Slice"},
Scott Bakerff104cc2017-08-14 15:24:41 -0700169 {"name": "leaf_model_name", "default": "Site"})
Scott Baker03a163f2017-05-17 09:21:47 -0700170
171 def __init__(self, **kwargs):
172 return super(Site, self).__init__(self.FIELDS, **kwargs)
173
174 DESCRIPTOR = FakeDescriptor("Site")
175
Scott Baker500f8c72017-05-19 09:41:50 -0700176class Service(FakeObj):
177 FIELDS = ( {"name": "id", "default": 0},
Scott Bakerff104cc2017-08-14 15:24:41 -0700178 {"name": "name", "default": ""},
Scott Baker5f38c7b2017-08-18 10:12:49 -0700179 {"name": "slices_ids", "default": [], "fk_reverse": "Slice"},
Scott Bakerff104cc2017-08-14 15:24:41 -0700180 {"name": "leaf_model_name", "default": "Service"})
Scott Baker500f8c72017-05-19 09:41:50 -0700181
182 def __init__(self, **kwargs):
183 return super(Service, self).__init__(self.FIELDS, **kwargs)
184
185 DESCRIPTOR = FakeDescriptor("Service")
186
Scott Baker8f36c3f2017-09-26 16:44:36 -0700187class ServiceInstance(FakeObj):
188 FIELDS = ( {"name": "id", "default": 0},
189 {"name": "owher", "default": 0, "fk_model": "Service"},
190 {"name": "leaf_model_name", "default": "ServiceInstance"})
191
192 def __init__(self, **kwargs):
193 return super(ServiceInstance, self).__init__(self.FIELDS, **kwargs)
194
195 DESCRIPTOR = FakeDescriptor("ServiceInstance")
196
Scott Bakerff104cc2017-08-14 15:24:41 -0700197class ONOSService(FakeObj):
198 FIELDS = ( {"name": "id", "default": 0},
199 {"name": "name", "default": ""},
200 {"name": "leaf_model_name", "default": "ONOSService"})
201
202 BASES = ["Service"]
203
204 def __init__(self, **kwargs):
205 return super(ONOSService, self).__init__(self.FIELDS, **kwargs)
206
207 DESCRIPTOR = FakeDescriptor("ONOSService")
208
Scott Baker5f38c7b2017-08-18 10:12:49 -0700209class Network(FakeObj):
210 FIELDS = ( {"name": "id", "default": 0},
211 {"name": "name", "default": ""},
212 {"name": "owner_id", "default": 0, "fk_model": "Slice"},
213 {"name": "template_id", "default": 0, "fk_model": "NetworkTemplate"},
214 {"name": "controllernetworks_ids", "default": [], "fk_reverse": "ControllerNetwork"},
215 {"name": "leaf_model_name", "default": "Network"})
216
217 def __init__(self, **kwargs):
218 return super(Network, self).__init__(self.FIELDS, **kwargs)
219
220 DESCRIPTOR = FakeDescriptor("Network")
221
222class NetworkTemplate(FakeObj):
223 FIELDS = ( {"name": "id", "default": 0},
224 {"name": "name", "default": ""},
225 {"name": "vtn_kind", "default": ""},
226 {"name": "leaf_model_name", "default": "NetworkTemplate"})
227
228 def __init__(self, **kwargs):
229 return super(NetworkTemplate, self).__init__(self.FIELDS, **kwargs)
230
231 DESCRIPTOR = FakeDescriptor("NetworkTemplate")
232
233class ControllerNetwork(FakeObj):
234 FIELDS = ( {"name": "id", "default": 0},
235 {"name": "network_id", "default": 0, "fk_model": "Network"},
236 {"name": "controller_id", "default": 0, "fk_model": "Controller"},
237 {"name": "leaf_model_name", "default": "ControllerNetwork"})
238
239 def __init__(self, **kwargs):
240 return super(ControllerNetwork, self).__init__(self.FIELDS, **kwargs)
241
242 DESCRIPTOR = FakeDescriptor("ControllerNetwork")
243
244class NetworkSlice(FakeObj):
245 FIELDS = ( {"name": "id", "default": 0},
246 {"name": "network_id", "default": 0, "fk_model": "Network"},
247 {"name": "slice_id", "default": 0, "fk_model": "Slice"},
248 {"name": "leaf_model_name", "default": "ControllerNetwork"})
249
250 def __init__(self, **kwargs):
251 return super(NetworkSlice, self).__init__(self.FIELDS, **kwargs)
252
253 DESCRIPTOR = FakeDescriptor("NetworkSlice")
254
Scott Baker500f8c72017-05-19 09:41:50 -0700255class Tag(FakeObj):
256 FIELDS = ( {"name": "id", "default": 0},
257 {"name": "service_id", "default": None},
258 {"name": "name", "default": ""},
259 {"name": "value", "default": ""},
260 {"name": "content_type", "default": None},
261 {"name": "object_id", "default": None},
Scott Bakerff104cc2017-08-14 15:24:41 -0700262 {"name": "leaf_model_name", "default": "Tag"})
Scott Baker500f8c72017-05-19 09:41:50 -0700263
264 def __init__(self, **kwargs):
265 return super(Tag, self).__init__(self.FIELDS, **kwargs)
266
267 DESCRIPTOR = FakeDescriptor("Tag")
268
269class ID(FakeObj):
270 pass
271
272class FakeItemList(object):
273 def __init__(self, items):
274 self.items = items
275
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700276class FakeStub(object):
277 def __init__(self):
Scott Baker500f8c72017-05-19 09:41:50 -0700278 self.id_counter = 1
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700279 self.objs = {}
Scott Baker8f36c3f2017-09-26 16:44:36 -0700280 for name in ["Controller", "Deployment", "Slice", "Site", "Tag", "Service", "ServiceInstance", "ONOSService", "User", "Network", "NetworkTemplate", "ControllerNetwork", "NetworkSlice"]:
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700281 setattr(self, "Get%s" % name, functools.partial(self.get, name))
282 setattr(self, "List%s" % name, functools.partial(self.list, name))
283 setattr(self, "Create%s" % name, functools.partial(self.create, name))
284 setattr(self, "Delete%s" % name, functools.partial(self.delete, name))
285 setattr(self, "Update%s" % name, functools.partial(self.update, name))
286
287
288 def make_key(self, name, id):
289 return "%s:%d" % (name, id.id)
290
Scott Baker500f8c72017-05-19 09:41:50 -0700291 def get(self, classname, id, metadata=None):
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700292 obj = self.objs.get(self.make_key(classname, id), None)
293 return obj
294
Scott Baker500f8c72017-05-19 09:41:50 -0700295 def list(self, classname, empty, metadata=None):
296 items = []
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700297 for (k,v) in self.objs.items():
298 (this_classname, id) = k.split(":")
299 if this_classname == classname:
300 items.append(v)
Scott Baker500f8c72017-05-19 09:41:50 -0700301 return FakeItemList(items)
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700302
Scott Baker500f8c72017-05-19 09:41:50 -0700303 def create(self, classname, obj, metadata=None):
304 obj.id = self.id_counter
305 self.id_counter = self.id_counter + 1
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700306 k = self.make_key(classname, FakeObj(id=obj.id))
307 self.objs[k] = obj
Scott Bakerff104cc2017-08-14 15:24:41 -0700308
309 for base_classname in obj.BASES:
310 base_class = globals()[base_classname]
311 base_obj = base_class(id=obj.id, leaf_model_name = classname)
312 k = self.make_key(base_classname, base_obj)
313 self.objs[k] = base_obj
314
Scott Baker500f8c72017-05-19 09:41:50 -0700315 return obj
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700316
Scott Baker500f8c72017-05-19 09:41:50 -0700317 def update(self, classname, obj, metadata=None):
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700318 # TODO: partial update support?
319 k = self.make_key(classname, FakeObj(id=obj.id))
320 self.objs[k] = obj
Scott Baker500f8c72017-05-19 09:41:50 -0700321 return obj
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700322
Scott Baker500f8c72017-05-19 09:41:50 -0700323 def delete(self, classname, id, metadata=None):
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700324 k = self.make_key(classname, id)
325 del self.objs[k]
326
327class FakeSymDb(object):
328 def __init__(self):
329 self._classes = {}
Scott Baker8f36c3f2017-09-26 16:44:36 -0700330 for name in ["Controller", "Deployment", "Slice", "Site", "ID", "Tag", "Service", "ServiceInstance", "ONOSService", "User", "Network", "NetworkTemplate", "ControllerNetwork", "NetworkSlice"]:
Scott Bakerf0ee0dc2017-05-15 10:10:05 -0700331 self._classes["xos.%s" % name] = globals()[name]
332
333
334