SEBA-405 Convert synchronizer framework to library

Change-Id: If8562f23dc15c7d18d7a8b040b33756708b3c5ec
diff --git a/lib/xos-synchronizer/xossynchronizer/mock_modelaccessor_build.py b/lib/xos-synchronizer/xossynchronizer/mock_modelaccessor_build.py
new file mode 100644
index 0000000..5c389cf
--- /dev/null
+++ b/lib/xos-synchronizer/xossynchronizer/mock_modelaccessor_build.py
@@ -0,0 +1,71 @@
+# 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
+import cPickle
+import 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(
+    dest_dir, xos_dir, services_dir, service_xprotos, target="mock_classes.xtarget"
+):
+    dest_fn = os.path.join(dest_dir, "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))