]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/test/crossrunner/collect.py
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / thrift / test / crossrunner / collect.py
1 #
2 # Licensed to the Apache Software Foundation (ASF) under one
3 # or more contributor license agreements. See the NOTICE file
4 # distributed with this work for additional information
5 # regarding copyright ownership. The ASF licenses this file
6 # to you under the Apache License, Version 2.0 (the
7 # "License"); you may not use this file except in compliance
8 # with the License. You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing,
13 # software distributed under the License is distributed on an
14 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 # KIND, either express or implied. See the License for the
16 # specific language governing permissions and limitations
17 # under the License.
18 #
19
20 import platform
21 import re
22 from itertools import product
23
24 from .util import merge_dict
25 from .test import TestEntry
26
27 # Those keys are passed to execution as is.
28 # Note that there are keys other than these, namely:
29 # delay: After server is started, client start is delayed for the value
30 # (seconds).
31 # timeout: Test timeout after client is started (seconds).
32 # platforms: Supported platforms. Should match platform.system() value.
33 # protocols: list of supported protocols
34 # transports: list of supported transports
35 # sockets: list of supported sockets
36 #
37 # protocols and transports entries can be colon separated "spec:impl" pair
38 # (e.g. binary:accel) where test is run for any matching "spec" while actual
39 # argument passed to test executable is "impl".
40 # Otherwise "spec" is equivalent to "spec:spec" pair.
41 # (e.g. "binary" is equivalent to "binary:binary" in tests.json)
42 #
43 VALID_JSON_KEYS = [
44 'name', # name of the library, typically a language name
45 'workdir', # work directory where command is executed
46 'command', # test command
47 'extra_args', # args appended to command after other args are appended
48 'remote_args', # args added to the other side of the program
49 'join_args', # whether args should be passed as single concatenated string
50 'env', # additional environmental variable
51 ]
52
53 DEFAULT_MAX_DELAY = 5
54 DEFAULT_SIGNAL = 1
55 DEFAULT_TIMEOUT = 5
56
57
58 def _collect_testlibs(config, server_match, client_match=[None]):
59 """Collects server/client configurations from library configurations"""
60 def expand_libs(config):
61 for lib in config:
62 sv = lib.pop('server', None)
63 cl = lib.pop('client', None)
64 yield lib, sv, cl
65
66 def yield_testlibs(base_configs, configs, match):
67 for base, conf in zip(base_configs, configs):
68 if conf:
69 if not match or base['name'] in match:
70 platforms = conf.get('platforms') or base.get('platforms')
71 if not platforms or platform.system() in platforms:
72 yield merge_dict(base, conf)
73
74 libs, svs, cls = zip(*expand_libs(config))
75 servers = list(yield_testlibs(libs, svs, server_match))
76 clients = list(yield_testlibs(libs, cls, client_match))
77 return servers, clients
78
79
80 def collect_features(config, match):
81 res = list(map(re.compile, match))
82 return list(filter(lambda c: any(map(lambda r: r.search(c['name']), res)), config))
83
84
85 def _do_collect_tests(servers, clients):
86 def intersection(key, o1, o2):
87 """intersection of two collections.
88 collections are replaced with sets the first time"""
89 def cached_set(o, key):
90 v = o[key]
91 if not isinstance(v, set):
92 v = set(v)
93 o[key] = v
94 return v
95 return cached_set(o1, key) & cached_set(o2, key)
96
97 def intersect_with_spec(key, o1, o2):
98 # store as set of (spec, impl) tuple
99 def cached_set(o):
100 def to_spec_impl_tuples(values):
101 for v in values:
102 spec, _, impl = v.partition(':')
103 yield spec, impl or spec
104 v = o[key]
105 if not isinstance(v, set):
106 v = set(to_spec_impl_tuples(set(v)))
107 o[key] = v
108 return v
109 for spec1, impl1 in cached_set(o1):
110 for spec2, impl2 in cached_set(o2):
111 if spec1 == spec2:
112 name = impl1 if impl1 == impl2 else '%s-%s' % (impl1, impl2)
113 yield name, impl1, impl2
114
115 def maybe_max(key, o1, o2, default):
116 """maximum of two if present, otherwise default value"""
117 v1 = o1.get(key)
118 v2 = o2.get(key)
119 return max(v1, v2) if v1 and v2 else v1 or v2 or default
120
121 def filter_with_validkeys(o):
122 ret = {}
123 for key in VALID_JSON_KEYS:
124 if key in o:
125 ret[key] = o[key]
126 return ret
127
128 def merge_metadata(o, **ret):
129 for key in VALID_JSON_KEYS:
130 if key in o:
131 ret[key] = o[key]
132 return ret
133
134 for sv, cl in product(servers, clients):
135 for proto, proto1, proto2 in intersect_with_spec('protocols', sv, cl):
136 for trans, trans1, trans2 in intersect_with_spec('transports', sv, cl):
137 for sock in intersection('sockets', sv, cl):
138 yield {
139 'server': merge_metadata(sv, **{'protocol': proto1, 'transport': trans1}),
140 'client': merge_metadata(cl, **{'protocol': proto2, 'transport': trans2}),
141 'delay': maybe_max('delay', sv, cl, DEFAULT_MAX_DELAY),
142 'stop_signal': maybe_max('stop_signal', sv, cl, DEFAULT_SIGNAL),
143 'timeout': maybe_max('timeout', sv, cl, DEFAULT_TIMEOUT),
144 'protocol': proto,
145 'transport': trans,
146 'socket': sock
147 }
148
149
150 def _filter_entries(tests, regex):
151 if regex:
152 return filter(lambda t: re.search(regex, TestEntry.get_name(**t)), tests)
153 return tests
154
155
156 def collect_cross_tests(tests_dict, server_match, client_match, regex):
157 sv, cl = _collect_testlibs(tests_dict, server_match, client_match)
158 return list(_filter_entries(_do_collect_tests(sv, cl), regex))
159
160
161 def collect_feature_tests(tests_dict, features_dict, server_match, feature_match, regex):
162 sv, _ = _collect_testlibs(tests_dict, server_match)
163 ft = collect_features(features_dict, feature_match)
164 return list(_filter_entries(_do_collect_tests(sv, ft), regex))