blob: 99b2d46d57ccdd2225f2ba4d0fc4b4f6a85abe0b [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 os
16import cPickle
17import subprocess
18
19"""
20 Support for autogenerating mock_modelaccessor.
21
22 Each unit test might have its own requirements for the set of xprotos that make
23 up its model testing framework. These should always include the core, and
24 optionally include one or more services.
25"""
26
27
28def build_mock_modelaccessor(
29 dest_dir, xos_dir, services_dir, service_xprotos, target="mock_classes.xtarget"
30):
Scott Bakerc2fddaa2019-01-30 15:45:03 -080031 # TODO: deprecate the dest_dir argument
32
33 # force modelaccessor to be found in /tmp
34 dest_dir="/tmp/mock_modelaccessor"
35 if not os.path.exists(dest_dir):
36 os.makedirs(dest_dir)
Scott Bakerbba67b62019-01-28 17:38:21 -080037 dest_fn = os.path.join(dest_dir, "mock_modelaccessor.py")
38
39 args = ["xosgenx", "--target", target]
40 args.append(os.path.join(xos_dir, "core/models/core.xproto"))
41 for xproto in service_xprotos:
42 args.append(os.path.join(services_dir, xproto))
43
44 # Check to see if we've already run xosgenx. If so, don't run it again.
45 context_fn = dest_fn + ".context"
46 this_context = (xos_dir, services_dir, service_xprotos, target)
47 need_xosgenx = True
48 if os.path.exists(context_fn):
49 try:
50 context = cPickle.loads(open(context_fn).read())
51 if context == this_context:
52 return
53 except (cPickle.UnpicklingError, EOFError):
54 # Something went wrong with the file read or depickling
55 pass
56
57 if os.path.exists(context_fn):
58 os.remove(context_fn)
59
60 if os.path.exists(dest_fn):
61 os.remove(dest_fn)
62
63 p = subprocess.Popen(
64 " ".join(args) + " > " + dest_fn,
65 shell=True,
66 stdout=subprocess.PIPE,
67 stderr=subprocess.STDOUT,
68 )
69 (stdoutdata, stderrdata) = p.communicate()
70 if (p.returncode != 0) or (not os.path.exists(dest_fn)):
71 raise Exception(
72 "Failed to create mock model accessor, returncode=%d, stdout=%s"
73 % (p.returncode, stdoutdata)
74 )
75
76 # Save the context of this invocation of xosgenx
77 open(context_fn, "w").write(cPickle.dumps(this_context))
Scott Bakerc2fddaa2019-01-30 15:45:03 -080078
79# generate model from xproto
80def get_models_fn(services_dir, service_name, xproto_name):
81 name = os.path.join(service_name, "xos", xproto_name)
82 if os.path.exists(os.path.join(services_dir, name)):
83 return name
84 else:
85 name = os.path.join(service_name, "xos", "synchronizer", "models", xproto_name)
86 if os.path.exists(os.path.join(services_dir, name)):
87 return name
88 raise Exception("Unable to find service=%s xproto=%s" % (service_name, xproto_name))
89# END generate model from xproto
90
91def mock_modelaccessor_config(test_dir, services):
92 """ Automatically configure the mock modelaccessor.
93
94 We start from the test directory, and then back up until we find the orchestration directory. From there we
95 can find the other xproto (core, services) that we need to build the mock modelaccessor.
96 """
97
98 orchestration_dir = test_dir
99 while not orchestration_dir.endswith("orchestration"):
100 # back up a level
101 orchestration_dir = os.path.dirname(orchestration_dir)
102 if len(orchestration_dir)<10:
103 raise Exception("Failed to autodiscovery repository tree")
104
105 xos_dir = os.path.join(orchestration_dir, "xos", "xos")
106 services_dir = os.path.join(orchestration_dir, "xos_services")
107
108 service_xprotos=[]
109 for (service_name, xproto_name) in services:
110 service_xprotos.append(get_models_fn(services_dir, service_name, xproto_name))
111
112 build_mock_modelaccessor(None, xos_dir, services_dir, service_xprotos)