CORD-1993 add model_policy support features to mock framework;
Cherry-pick of change 7067 commit 0090b57e08858360c7b9082f60a1b006e5eb82e0

Change-Id: I0bef7f8d232156fbdf3f43a9da2abe4a2e47f866
diff --git a/lib/xos-genx/xosgenx/targets/mock_classes.xtarget b/lib/xos-genx/xosgenx/targets/mock_classes.xtarget
index a28f4c3..bbc5ae2 100644
--- a/lib/xos-genx/xosgenx/targets/mock_classes.xtarget
+++ b/lib/xos-genx/xosgenx/targets/mock_classes.xtarget
@@ -20,10 +20,65 @@
     e.all = lambda:items
     return e
 
-class Object:
-    objects = Mock()
-    save = Mock()
-    delete = Mock()
+# A list of all mock object stores that have been created
+AllMockObjectStores = []
+
+class MockObjectList:
+    item_list = None
+
+    def __init__(self, initial=None):
+        self.id_counter = 0
+        if initial:
+            self.item_list=initial
+        elif self.item_list is None:
+            self.item_list=[]
+
+    def get_items(self):
+        return self.item_list
+
+    def count(self):
+        return len(self.get_items())
+
+    def first(self):
+        return self.get_items()[0]
+
+    def all(self):
+        return self.get_items()
+
+    def filter(self, **kwargs):
+        items = self.get_items()
+        for (k,v) in kwargs.items():
+            items = [x for x in items if getattr(x,k) == v]
+        return items
+
+    def get(self, **kwargs):
+        objs = self.filter(**kwargs)
+        if not objs:
+            raise Exception("No objects matching %s" % str(kwargs))
+        return objs[0]
+
+class MockObjectStore(MockObjectList):
+    def save(self, o):
+        if (not hasattr(o,"id")) or (not o.id) or (o.id==98052):
+            for item in self.get_items():
+                if item.id >= self.id_counter:
+                    self.id_counter = item.id + 1
+
+            o.id = self.id_counter
+            self.id_counter = self.id_counter + 1
+
+        for item in self.get_items():
+            if item.id == o.id:
+                item = o
+                break
+        else:
+            self.get_items().append(o)
+
+class MockObject:
+    objects = None
+    id = None
+    deleted = False
+
     def __init__(self, **kwargs):
         setattr(self, 'backend_code', 0)
         setattr(self, 'id', 98052)
@@ -32,15 +87,29 @@
         for (k,v) in kwargs.items():
             setattr(self,k,v)
 
+    @property
+    def self_content_type_id(self):
+        return self.__class__.__name__
+
+    @property
+    def leaf_model(self):
+        return self
+
+    def save(self):
+        if self.objects:
+            self.objects.save(self)
+
+    def delete(self):
+        pass
 
     def tologdict(self):
         return {}
 
-class ONOSService(Object):
-    leaf_model_name = 'ONOSService'
-
-class ONOSApp(Object):
-    leaf_model_name = 'ONOSApp'
+def get_MockObjectStore(x):
+    store = globals()["Mock%sObjects" % x]()
+    if not store in AllMockObjectStores:
+        AllMockObjectStores.append(store)
+    return store
 
 class ModelAccessor:
     def check_db_connection_ok(self):
@@ -65,6 +134,10 @@
         
         return object_list
 
+    def reset_all_object_stores(self):
+        for store in AllMockObjectStores:
+            store.items = []
+
 model_accessor = ModelAccessor()
 
 class ObjectSet(object):
@@ -79,9 +152,12 @@
 # 
 
 {% for m in proto.messages -%}
-class {{ m.name }}(Object):
+class Mock{{ m.name }}Objects(MockObjectStore): pass
+class {{ m.name }}(MockObject):
+    objects = get_MockObjectStore("{{ m.name }}")
     {% for f in xproto_base_fields(m, proto.message_table) +  m.fields -%}
     {{ f.name }} = {{ xproto_first_non_empty([f.options.default, "None"]) }}
+    {% if f.link -%}{{ f.name }}_id = None{% endif %}
     {% endfor %}
     leaf_model_name = "{{ m.name }}"
 {% endfor %}
diff --git a/xos/synchronizers/new_base/mock_modelaccessor.py b/xos/synchronizers/new_base/mock_modelaccessor.py
deleted file mode 100644
index 804c1a1..0000000
--- a/xos/synchronizers/new_base/mock_modelaccessor.py
+++ /dev/null
@@ -1,1441 +0,0 @@
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from mock import Mock
-import random
-
-def mock_enumerator(items):
-    e = lambda:None
-    e.all = lambda:items
-    return e
-
-class Object:
-    objects = Mock()
-    save = Mock()
-    delete = Mock()
-    def __init__(self, **kwargs):
-        setattr(self, 'backend_code', 0)
-        setattr(self, 'id', 98052)
-        setattr(self, 'pk', random.randint(0, 1<<30))
-        
-        for (k,v) in kwargs.items():
-            setattr(self,k,v)
-
-
-    def tologdict(self):
-        return {}
-
-class ONOSService(Object):
-    leaf_model_name = 'ONOSService'
-
-class ONOSApp(Object):
-    leaf_model_name = 'ONOSApp'
-
-class ModelAccessor:
-    def check_db_connection_ok(self):
-        return True
-
-    def fetch_pending(self, model, deleted = False):
-        num = random.randint(1, 5)
-        object_list = []
-
-        for i in range(num):
-            if isinstance(model, list):
-                model = model[0]
-
-            try:
-                obj = model()
-            except:
-                import pdb
-                pdb.set_trace()
-
-            obj.name = "Opinionated Berry %d"%i
-            object_list.append(obj)
-        
-        return object_list
-
-model_accessor = ModelAccessor()
-
-class ObjectSet(object):
-    def __init__(self, objects):
-        self.objects = objects
-
-    def all(self):
-        return self.objects
-    
-#####
-# DO NOT MODIFY THE CLASSES BELOW. THEY ARE AUTOGENERATED.
-# 
-
-class XOSBase(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    
-    leaf_model_name = "XOSBase"
-class User(Object):
-    email = None
-    username = "Something"
-    password = "Something"
-    last_login = None
-    firstname = None
-    lastname = None
-    phone = None
-    user_url = None
-    site = None
-    public_key = None
-    is_active = True
-    is_admin = False
-    is_staff = True
-    is_readonly = False
-    is_registering = False
-    is_appuser = False
-    login_page = None
-    created = None
-    updated = None
-    enacted = None
-    policed = None
-    backend_status = "Provisioning in progress"
-    backend_need_delete = False
-    backend_need_reap = False
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    timezone = "America/New_York"
-    policy_status = "0 - Policy in process"
-    leaf_model_name = None
-    
-    leaf_model_name = "User"
-class Privilege(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    accessor_id = None
-    accessor_type = None
-    controller_id = None
-    object_id = None
-    object_type = None
-    permission = "all"
-    granted = None
-    expires = None
-    
-    leaf_model_name = "Privilege"
-class AddressPool(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    addresses = None
-    gateway_ip = None
-    gateway_mac = None
-    cidr = None
-    inuse = None
-    service = None
-    
-    leaf_model_name = "AddressPool"
-class Controller(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    backend_type = None
-    version = None
-    auth_url = None
-    admin_user = None
-    admin_password = None
-    admin_tenant = None
-    domain = None
-    rabbit_host = None
-    rabbit_user = None
-    rabbit_password = None
-    deployment = None
-    
-    leaf_model_name = "Controller"
-class ControllerImages(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    image = None
-    controller = None
-    glance_image_id = None
-    
-    leaf_model_name = "ControllerImages"
-class ControllerNetwork(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    network = None
-    controller = None
-    subnet = None
-    start_ip = None
-    stop_ip = None
-    net_id = None
-    router_id = None
-    subnet_id = None
-    gateway = None
-    segmentation_id = None
-    
-    leaf_model_name = "ControllerNetwork"
-class ControllerRole(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    role = None
-    
-    leaf_model_name = "ControllerRole"
-class ControllerSite(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    site = None
-    controller = None
-    tenant_id = None
-    
-    leaf_model_name = "ControllerSite"
-class ControllerPrivilege(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    controller = None
-    privilege = None
-    role_id = None
-    
-    leaf_model_name = "ControllerPrivilege"
-class ControllerSitePrivilege(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    controller = None
-    site_privilege = None
-    role_id = None
-    
-    leaf_model_name = "ControllerSitePrivilege"
-class ControllerSlice(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    controller = None
-    slice = None
-    tenant_id = None
-    
-    leaf_model_name = "ControllerSlice"
-class ControllerSlicePrivilege(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    controller = None
-    slice_privilege = None
-    role_id = None
-    
-    leaf_model_name = "ControllerSlicePrivilege"
-class ControllerUser(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    user = None
-    controller = None
-    kuser_id = None
-    
-    leaf_model_name = "ControllerUser"
-class Deployment(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    accessControl = "allow all"
-    
-    leaf_model_name = "Deployment"
-class DeploymentPrivilege(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    user = None
-    deployment = None
-    role = None
-    
-    leaf_model_name = "DeploymentPrivilege"
-class DeploymentRole(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    role = None
-    
-    leaf_model_name = "DeploymentRole"
-class Diag(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    
-    leaf_model_name = "Diag"
-class Flavor(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    description = None
-    flavor = None
-    
-    leaf_model_name = "Flavor"
-class Image(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    kind = "vm"
-    disk_format = None
-    container_format = None
-    path = None
-    tag = None
-    
-    leaf_model_name = "Image"
-class ImageDeployments(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    image = None
-    deployment = None
-    
-    leaf_model_name = "ImageDeployments"
-class Instance(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    instance_id = None
-    instance_uuid = None
-    name = None
-    instance_name = None
-    ip = None
-    image = None
-    creator = None
-    slice = None
-    deployment = None
-    node = None
-    numberCores = 0
-    flavor = None
-    userData = None
-    isolation = "vm"
-    volumes = None
-    parent = None
-    
-    leaf_model_name = "Instance"
-class Network(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    template = None
-    subnet = None
-    start_ip = None
-    end_ip = None
-    ports = None
-    labels = None
-    owner = None
-    permit_all_slices = False
-    autoconnect = True
-    permitted_slices = None
-    slices = None
-    instances = None
-    
-    leaf_model_name = "Network"
-class NetworkParameter(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    parameter = None
-    value = None
-    content_type = None
-    object_id = None
-    
-    leaf_model_name = "NetworkParameter"
-class NetworkParameterType(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    description = None
-    
-    leaf_model_name = "NetworkParameterType"
-class NetworkSlice(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    network = None
-    slice = None
-    
-    leaf_model_name = "NetworkSlice"
-class NetworkTemplate(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    description = None
-    visibility = "private"
-    translation = "none"
-    access = None
-    shared_network_name = None
-    shared_network_id = None
-    topology_kind = "bigswitch"
-    controller_kind = None
-    vtn_kind = "PRIVATE"
-    
-    leaf_model_name = "NetworkTemplate"
-class Node(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    site_deployment = None
-    
-    leaf_model_name = "Node"
-class NodeLabel(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    node = None
-    
-    leaf_model_name = "NodeLabel"
-class Port(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    network = None
-    instance = None
-    ip = None
-    port_id = None
-    mac = None
-    xos_created = False
-    
-    leaf_model_name = "Port"
-class Role(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    role_type = None
-    role = None
-    description = None
-    
-    leaf_model_name = "Role"
-class Service(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    description = None
-    enabled = True
-    kind = "generic"
-    name = None
-    versionNumber = None
-    published = True
-    view_url = None
-    icon_url = None
-    public_key = None
-    private_key_fn = None
-    service_specific_id = None
-    service_specific_attribute = None
-    
-    leaf_model_name = "Service"
-class ServiceAttribute(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    value = None
-    service = None
-    
-    leaf_model_name = "ServiceAttribute"
-class ServiceDependency(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    provider_service = None
-    subscriber_service = None
-    connect_method = "none"
-    
-    leaf_model_name = "ServiceDependency"
-class ServiceMonitoringAgentInfo(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    service = None
-    target_uri = None
-    
-    leaf_model_name = "ServiceMonitoringAgentInfo"
-class ServicePrivilege(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    user = None
-    service = None
-    role = None
-    
-    leaf_model_name = "ServicePrivilege"
-class ServiceRole(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    role = None
-    
-    leaf_model_name = "ServiceRole"
-class Site(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    site_url = None
-    enabled = True
-    hosts_nodes = True
-    hosts_users = True
-    longitude = None
-    latitude = None
-    login_base = None
-    is_public = True
-    abbreviated_name = None
-    deployments = None
-    
-    leaf_model_name = "Site"
-class SiteDeployment(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    site = None
-    deployment = None
-    controller = None
-    availability_zone = None
-    
-    leaf_model_name = "SiteDeployment"
-class SitePrivilege(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    user = None
-    site = None
-    role = None
-    
-    leaf_model_name = "SitePrivilege"
-class SiteRole(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    role = None
-    
-    leaf_model_name = "SiteRole"
-class Slice(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    enabled = True
-    description = None
-    slice_url = None
-    site = None
-    max_instances = 10
-    service = None
-    network = None
-    exposed_ports = None
-    creator = None
-    default_flavor = None
-    default_image = None
-    default_node = None
-    mount_data_sets = "GenBank"
-    default_isolation = "vm"
-    
-    leaf_model_name = "Slice"
-class SlicePrivilege(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    user = None
-    slice = None
-    role = None
-    
-    leaf_model_name = "SlicePrivilege"
-class SliceRole(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    role = None
-    
-    leaf_model_name = "SliceRole"
-class Tag(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    service = None
-    name = None
-    value = None
-    content_type = None
-    object_id = None
-    
-    leaf_model_name = "Tag"
-class InterfaceType(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    direction = None
-    
-    leaf_model_name = "InterfaceType"
-class ServiceInterface(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    service = None
-    interface_type = None
-    
-    leaf_model_name = "ServiceInterface"
-class ServiceInstance(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    owner = None
-    service_specific_id = None
-    service_specific_attribute = None
-    link_deleted_count = 0
-    
-    leaf_model_name = "ServiceInstance"
-class ServiceInstanceLink(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    provider_service_instance = None
-    provider_service_interface = None
-    subscriber_service_instance = None
-    subscriber_service = None
-    subscriber_network = None
-    
-    leaf_model_name = "ServiceInstanceLink"
-class ServiceInstanceAttribute(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    value = None
-    service_instance = None
-    
-    leaf_model_name = "ServiceInstanceAttribute"
-class TenantWithContainer(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    owner = None
-    service_specific_id = None
-    service_specific_attribute = None
-    link_deleted_count = 0
-    instance = None
-    creator = None
-    external_hostname = None
-    external_container = None
-    
-    leaf_model_name = "TenantWithContainer"
-class XOS(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = "XOS"
-    
-    leaf_model_name = "XOS"
-class XOSGuiExtension(Object):
-    created = None
-    updated = "now()"
-    enacted = None
-    policed = None
-    backend_register = "{}"
-    backend_need_delete = False
-    backend_need_reap = False
-    backend_status = "Provisioning in progress"
-    backend_code = 0
-    deleted = False
-    write_protect = False
-    lazy_blocked = False
-    no_sync = False
-    no_policy = False
-    policy_status = "Policy in process"
-    policy_code = 0
-    leaf_model_name = None
-    backend_need_delete_policy = False
-    name = None
-    files = None
-    
-    leaf_model_name = "XOSGuiExtension"
diff --git a/xos/synchronizers/new_base/mock_modelaccessor_build.py b/xos/synchronizers/new_base/mock_modelaccessor_build.py
new file mode 100644
index 0000000..3ab635e
--- /dev/null
+++ b/xos/synchronizers/new_base/mock_modelaccessor_build.py
@@ -0,0 +1,58 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os, cPickle, subprocess
+
+"""
+    Support for autogenerating mock_modelaccessor.
+
+    Each unit test might have its own requirements for the set of xprotos that make
+    up its model testing framework. These should always include the core, and   
+    optionally include one or more services. 
+"""
+
+def build_mock_modelaccessor(xos_dir, services_dir, service_xprotos, target="mock_classes.xtarget"):
+    dest_fn = os.path.join(xos_dir, "synchronizers", "new_base", "mock_modelaccessor.py")
+
+    args = ["xosgenx", "--target", target]
+    args.append(os.path.join(xos_dir, "core/models/core.xproto"))
+    for xproto in service_xprotos:
+        args.append(os.path.join(services_dir, xproto))
+
+    # Check to see if we've already run xosgenx. If so, don't run it again.
+    context_fn = dest_fn + ".context"
+    this_context = (xos_dir, services_dir, service_xprotos, target)
+    need_xosgenx = True
+    if os.path.exists(context_fn):
+        try:
+            context = cPickle.loads(open(context_fn).read())
+            if (context == this_context):
+                return
+        except (cPickle.UnpicklingError, EOFError):
+            # Something went wrong with the file read or depickling
+            pass
+
+    if os.path.exists(context_fn):
+        os.remove(context_fn)
+
+    if os.path.exists(dest_fn):
+        os.remove(dest_fn)
+
+    p = subprocess.Popen(" ".join(args) + " > " + dest_fn, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    (stdoutdata, stderrdata) = p.communicate();
+    if (p.returncode!=0) or (not os.path.exists(dest_fn)):
+        raise Exception("Failed to create mock model accessor, returncode=%d, stdout=%s" % (p.returncode, stdoutdata))
+
+    # Save the context of this invocation of xosgenx
+    open(context_fn, "w").write(cPickle.dumps(this_context))
diff --git a/xos/synchronizers/new_base/model_policies/test_model_policy_tenantwithcontainer.py b/xos/synchronizers/new_base/model_policies/test_model_policy_tenantwithcontainer.py
index f6ba6a2..82f5fd4 100644
--- a/xos/synchronizers/new_base/model_policies/test_model_policy_tenantwithcontainer.py
+++ b/xos/synchronizers/new_base/model_policies/test_model_policy_tenantwithcontainer.py
@@ -32,12 +32,15 @@
         self.sys_path_save = sys.path
         self.cwd_save = os.getcwd()
         sys.path.append(xos_dir)
-        #sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
         sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base', 'model_policies'))
 
         config = basic_conf = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/test_config.yaml")
         Config.clear() # in case left unclean by a previous test case
         Config.init(config, 'synchronizer-config-schema.yaml')
+
+        from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
+        build_mock_modelaccessor(xos_dir, services_dir=None, service_xprotos=[])
+
         import model_policy_tenantwithcontainer
         from model_policy_tenantwithcontainer import TenantWithContainerPolicy, LeastLoadedNodeScheduler
 
diff --git a/xos/synchronizers/new_base/tests/test_controller_dependencies.py b/xos/synchronizers/new_base/tests/test_controller_dependencies.py
index 2e65d23..3ebf3d4 100644
--- a/xos/synchronizers/new_base/tests/test_controller_dependencies.py
+++ b/xos/synchronizers/new_base/tests/test_controller_dependencies.py
@@ -41,6 +41,9 @@
         Config.clear()
         Config.init(config, 'synchronizer-config-schema.yaml')
 
+        from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
+        build_mock_modelaccessor(xos_dir, services_dir=None, service_xprotos=[])
+
         os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
 
         import event_loop
diff --git a/xos/synchronizers/new_base/tests/test_load.py b/xos/synchronizers/new_base/tests/test_load.py
index 165aca9..ae267a5 100644
--- a/xos/synchronizers/new_base/tests/test_load.py
+++ b/xos/synchronizers/new_base/tests/test_load.py
@@ -36,6 +36,9 @@
         Config.clear()
         Config.init(config, 'synchronizer-config-schema.yaml')
 
+        from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
+        build_mock_modelaccessor(xos_dir, services_dir=None, service_xprotos=[])
+
         os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
 
         import event_loop
diff --git a/xos/synchronizers/new_base/tests/test_payload.py b/xos/synchronizers/new_base/tests/test_payload.py
index 953681a..56357f1 100644
--- a/xos/synchronizers/new_base/tests/test_payload.py
+++ b/xos/synchronizers/new_base/tests/test_payload.py
@@ -52,6 +52,9 @@
         Config.clear()
         Config.init(config, 'synchronizer-config-schema.yaml')
 
+        from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
+        build_mock_modelaccessor(xos_dir, services_dir=None, service_xprotos=[])
+
         os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
 
         import event_loop
diff --git a/xos/synchronizers/new_base/tests/test_run.py b/xos/synchronizers/new_base/tests/test_run.py
index 8b089a4..72167ec 100644
--- a/xos/synchronizers/new_base/tests/test_run.py
+++ b/xos/synchronizers/new_base/tests/test_run.py
@@ -49,6 +49,9 @@
         Config.clear()
         Config.init(config, 'synchronizer-config-schema.yaml')
 
+        from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
+        build_mock_modelaccessor(xos_dir, services_dir=None, service_xprotos=[])
+
         os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
 
         import event_loop
diff --git a/xos/synchronizers/new_base/tests/test_scheduler.py b/xos/synchronizers/new_base/tests/test_scheduler.py
index 5c6d6c5..3e7119c 100644
--- a/xos/synchronizers/new_base/tests/test_scheduler.py
+++ b/xos/synchronizers/new_base/tests/test_scheduler.py
@@ -41,6 +41,9 @@
         Config.clear()
         Config.init(config, 'synchronizer-config-schema.yaml')
 
+        from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
+        build_mock_modelaccessor(xos_dir, services_dir=None, service_xprotos=[])
+
         os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
 
         import event_loop
diff --git a/xos/synchronizers/new_base/tests/test_services.py b/xos/synchronizers/new_base/tests/test_services.py
index 7c92d9a..4e46f38 100644
--- a/xos/synchronizers/new_base/tests/test_services.py
+++ b/xos/synchronizers/new_base/tests/test_services.py
@@ -39,6 +39,9 @@
         Config.clear()
         Config.init(config, 'synchronizer-config-schema.yaml')
 
+        from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
+        build_mock_modelaccessor(xos_dir, services_dir=None, service_xprotos=[])
+
         os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
 
         import event_loop