]>
git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/test/crossrunner/collect.py
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
10 # http://www.apache.org/licenses/LICENSE-2.0
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
22 from itertools
import product
24 from .util
import merge_dict
25 from .test
import TestEntry
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
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
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)
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
58 def _collect_testlibs(config
, server_match
, client_match
=[None]):
59 """Collects server/client configurations from library configurations"""
60 def expand_libs(config
):
62 sv
= lib
.pop('server', None)
63 cl
= lib
.pop('client', None)
66 def yield_testlibs(base_configs
, configs
, match
):
67 for base
, conf
in zip(base_configs
, configs
):
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
)
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
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
))
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
):
91 if not isinstance(v
, set):
95 return cached_set(o1
, key
) & cached_set(o2
, key
)
97 def intersect_with_spec(key
, o1
, o2
):
98 # store as set of (spec, impl) tuple
100 def to_spec_impl_tuples(values
):
102 spec
, _
, impl
= v
.partition(':')
103 yield spec
, impl
or spec
105 if not isinstance(v
, set):
106 v
= set(to_spec_impl_tuples(set(v
)))
109 for spec1
, impl1
in cached_set(o1
):
110 for spec2
, impl2
in cached_set(o2
):
112 name
= impl1
if impl1
== impl2
else '%s-%s' % (impl1
, impl2
)
113 yield name
, impl1
, impl2
115 def maybe_max(key
, o1
, o2
, default
):
116 """maximum of two if present, otherwise default value"""
119 return max(v1
, v2
) if v1
and v2
else v1
or v2
or default
121 def filter_with_validkeys(o
):
123 for key
in VALID_JSON_KEYS
:
128 def merge_metadata(o
, **ret
):
129 for key
in VALID_JSON_KEYS
:
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
):
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
),
150 def _filter_entries(tests
, regex
):
152 return filter(lambda t
: re
.search(regex
, TestEntry
.get_name(**t
)), tests
)
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
))
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
))