Add a new 'environment' object to be used to build test environment (#781)
Allowing user to fine tune tests environment variables
This commit is contained in:
parent
8fd8c16a87
commit
a2e7ebc575
|
@ -193,6 +193,41 @@ class ExtractedObjects():
|
|||
self.target = target
|
||||
self.srclist = srclist
|
||||
|
||||
class EnvironmentVariables():
|
||||
def __init__(self):
|
||||
self.envvars = []
|
||||
|
||||
def get_value(self, name, values, kwargs):
|
||||
separator = kwargs.get('separator', os.pathsep)
|
||||
|
||||
value = ''
|
||||
for var in values:
|
||||
value += separator + var
|
||||
return separator, value.strip(separator)
|
||||
|
||||
def set(self, env, name, values, kwargs):
|
||||
return self.get_value(name, values, kwargs)[1]
|
||||
|
||||
def append(self, env, name, values, kwargs):
|
||||
sep, value = self.get_value(name, values, kwargs)
|
||||
if name in env:
|
||||
return env[name] + sep + value
|
||||
return value
|
||||
|
||||
def prepend(self, env, name, values, kwargs):
|
||||
sep, value = self.get_value(name, values, kwargs)
|
||||
if name in env:
|
||||
return value + sep + env[name]
|
||||
|
||||
return value
|
||||
|
||||
def get_env(self, full_env):
|
||||
env = {}
|
||||
for method, name, values, kwargs in self.envvars:
|
||||
env[name] = method(full_env, name, values, kwargs)
|
||||
return env
|
||||
|
||||
|
||||
class BuildTarget():
|
||||
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
||||
self.name = name
|
||||
|
|
|
@ -180,6 +180,37 @@ class ConfigureFileHolder(InterpreterObject):
|
|||
InterpreterObject.__init__(self)
|
||||
self.held_object = build.ConfigureFile(subdir, sourcename, targetname, configuration_data)
|
||||
|
||||
|
||||
class EnvironmentVariablesHolder(InterpreterObject):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.held_object = build.EnvironmentVariables()
|
||||
self.methods.update({'set': self.set_method,
|
||||
'append': self.append_method,
|
||||
'prepend' : self.prepend_method,
|
||||
})
|
||||
|
||||
@stringArgs
|
||||
def add_var(self, method, args, kwargs):
|
||||
if not isinstance(kwargs.get("separator", ""), str):
|
||||
raise InterpreterException("EnvironmentVariablesHolder methods 'separator'"
|
||||
" argument needs to be a string.")
|
||||
if len(args) < 2:
|
||||
raise InterpreterException("EnvironmentVariablesHolder methods require at least"
|
||||
"2 arguments, first is the name of the variable and"
|
||||
" following one are values")
|
||||
self.held_object.envvars.append((method, args[0], args[1:], kwargs))
|
||||
|
||||
def set_method(self, args, kwargs):
|
||||
self.add_var(self.held_object.set, args, kwargs)
|
||||
|
||||
def append_method(self, args, kwargs):
|
||||
self.add_var(self.held_object.append, args, kwargs)
|
||||
|
||||
def prepend_method(self, args, kwargs):
|
||||
self.add_var(self.held_object.prepend, args, kwargs)
|
||||
|
||||
|
||||
class ConfigurationDataHolder(InterpreterObject):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
@ -1124,6 +1155,7 @@ class Interpreter():
|
|||
'files' : self.func_files,
|
||||
'declare_dependency': self.func_declare_dependency,
|
||||
'assert': self.func_assert,
|
||||
'environment' : self.func_environment,
|
||||
}
|
||||
|
||||
def module_method_callback(self, invalues):
|
||||
|
@ -1949,18 +1981,21 @@ class Interpreter():
|
|||
if not isinstance(i, (str, mesonlib.File)):
|
||||
raise InterpreterException('Command line arguments must be strings')
|
||||
envlist = kwargs.get('env', [])
|
||||
if not isinstance(envlist, list):
|
||||
envlist = [envlist]
|
||||
env = {}
|
||||
for e in envlist:
|
||||
if '=' not in e:
|
||||
raise InterpreterException('Env var definition must be of type key=val.')
|
||||
(k, val) = e.split('=', 1)
|
||||
k = k.strip()
|
||||
val = val.strip()
|
||||
if ' ' in k:
|
||||
raise InterpreterException('Env var key must not have spaces in it.')
|
||||
env[k] = val
|
||||
if isinstance(envlist, EnvironmentVariablesHolder):
|
||||
env = envlist.held_object
|
||||
else:
|
||||
if not isinstance(envlist, list):
|
||||
envlist = [envlist]
|
||||
env = {}
|
||||
for e in envlist:
|
||||
if '=' not in e:
|
||||
raise InterpreterException('Env var definition must be of type key=val.')
|
||||
(k, val) = e.split('=', 1)
|
||||
k = k.strip()
|
||||
val = val.strip()
|
||||
if ' ' in k:
|
||||
raise InterpreterException('Env var key must not have spaces in it.')
|
||||
env[k] = val
|
||||
valgrind_args = kwargs.get('valgrind_args', [])
|
||||
if not isinstance(valgrind_args, list):
|
||||
valgrind_args = [valgrind_args]
|
||||
|
@ -2147,6 +2182,10 @@ class Interpreter():
|
|||
else:
|
||||
self.build.global_link_args[lang] = args
|
||||
|
||||
|
||||
def func_environment(self, node, args, kwargs):
|
||||
return EnvironmentVariablesHolder()
|
||||
|
||||
def flatten(self, args):
|
||||
if isinstance(args, mparser.StringNode):
|
||||
return args.value
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
import mesonbuild
|
||||
from .. import build
|
||||
import sys, os, subprocess, time, datetime, pickle, multiprocessing, json
|
||||
import concurrent.futures as conc
|
||||
import argparse
|
||||
|
@ -128,6 +129,9 @@ def run_single_test(wrap, test):
|
|||
cmd = wrap + cmd + test.cmd_args
|
||||
starttime = time.time()
|
||||
child_env = os.environ.copy()
|
||||
if isinstance(test.env, build.EnvironmentVariables):
|
||||
test.env = test.env.get_env(child_env)
|
||||
|
||||
child_env.update(test.env)
|
||||
if len(test.extra_paths) > 0:
|
||||
child_env['PATH'] = child_env['PATH'] + ';'.join([''] + test.extra_paths)
|
||||
|
|
|
@ -4,12 +4,20 @@
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
if(strcmp(getenv("first"), "val1") != 0) {
|
||||
fprintf(stderr, "First envvar is wrong.\n");
|
||||
fprintf(stderr, "First envvar is wrong. %s\n", getenv("first"));
|
||||
return 1;
|
||||
}
|
||||
if(strcmp(getenv("second"), "val2") != 0) {
|
||||
fprintf(stderr, "Second envvar is wrong.\n");
|
||||
return 1;
|
||||
}
|
||||
if(strcmp(getenv("third"), "val3:and_more") != 0) {
|
||||
fprintf(stderr, "Third envvar is wrong.\n");
|
||||
return 1;
|
||||
}
|
||||
if(strstr(getenv("PATH"), "fakepath:") != NULL) {
|
||||
fprintf(stderr, "Third envvar is wrong.\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,12 @@ project('test features', 'c')
|
|||
e1 = executable('cmd_args', 'cmd_args.c')
|
||||
e2 = executable('envvars', 'envvars.c')
|
||||
|
||||
env = environment()
|
||||
env.set('first', 'val1')
|
||||
env.set('second', 'val2')
|
||||
env.set('third', 'val3', 'and_more', separator: ':')
|
||||
env.append('PATH', 'fakepath', separator: ':')
|
||||
|
||||
test('command line arguments', e1, args : ['first', 'second'])
|
||||
test('environment variables', e2, env : ['first=val1', 'second=val2'])
|
||||
test('environment variables', e2, env : env)
|
||||
test('file arg', find_program('tester.py'), args : files('testfile.txt'))
|
||||
|
|
Loading…
Reference in New Issue