summaryrefslogtreecommitdiffstats
path: root/test/integration/targets/var_precedence
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-14 20:03:01 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-14 20:03:01 +0000
commita453ac31f3428614cceb99027f8efbdb9258a40b (patch)
treef61f87408f32a8511cbd91799f9cececb53e0374 /test/integration/targets/var_precedence
parentInitial commit. (diff)
downloadansible-upstream.tar.xz
ansible-upstream.zip
Adding upstream version 2.10.7+merged+base+2.10.8+dfsg.upstream/2.10.7+merged+base+2.10.8+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/integration/targets/var_precedence')
-rw-r--r--test/integration/targets/var_precedence/aliases1
-rwxr-xr-xtest/integration/targets/var_precedence/ansible-var-precedence-check.py541
-rw-r--r--test/integration/targets/var_precedence/host_vars/testhost2
-rw-r--r--test/integration/targets/var_precedence/inventory13
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence/meta/main.yml4
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence/tasks/main.yml10
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_dep/defaults/main.yml5
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_dep/tasks/main.yml14
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_dep/vars/main.yml4
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_inven_override/tasks/main.yml5
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role1/defaults/main.yml5
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role1/meta/main.yml2
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role1/tasks/main.yml14
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role1/vars/main.yml4
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role2/defaults/main.yml5
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role2/tasks/main.yml14
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role2/vars/main.yml5
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role3/defaults/main.yml7
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role3/tasks/main.yml14
-rw-r--r--test/integration/targets/var_precedence/roles/test_var_precedence_role3/vars/main.yml3
-rwxr-xr-xtest/integration/targets/var_precedence/runme.sh9
-rw-r--r--test/integration/targets/var_precedence/test_var_precedence.yml44
-rw-r--r--test/integration/targets/var_precedence/vars/test_var_precedence.yml5
23 files changed, 730 insertions, 0 deletions
diff --git a/test/integration/targets/var_precedence/aliases b/test/integration/targets/var_precedence/aliases
new file mode 100644
index 00000000..3005e4b2
--- /dev/null
+++ b/test/integration/targets/var_precedence/aliases
@@ -0,0 +1 @@
+shippable/posix/group4
diff --git a/test/integration/targets/var_precedence/ansible-var-precedence-check.py b/test/integration/targets/var_precedence/ansible-var-precedence-check.py
new file mode 100755
index 00000000..f19cd1c5
--- /dev/null
+++ b/test/integration/targets/var_precedence/ansible-var-precedence-check.py
@@ -0,0 +1,541 @@
+#!/usr/bin/env python
+
+# A tool to check the order of precedence for ansible variables
+# https://github.com/ansible/ansible/blob/devel/test/integration/test_var_precedence.yml
+
+import json
+import os
+import sys
+import shutil
+import stat
+import subprocess
+import tempfile
+import yaml
+from pprint import pprint
+from optparse import OptionParser
+from jinja2 import Environment
+
+ENV = Environment()
+TESTDIR = tempfile.mkdtemp()
+
+
+def run_command(args, cwd=None):
+ p = subprocess.Popen(
+ args,
+ stderr=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ shell=True,
+ cwd=cwd,
+ )
+ (so, se) = p.communicate()
+ return (p.returncode, so, se)
+
+
+def clean_test_dir():
+ if os.path.isdir(TESTDIR):
+ shutil.rmtree(TESTDIR)
+ os.makedirs(TESTDIR)
+
+
+class Role(object):
+ def __init__(self, name):
+ self.name = name
+ self.load = True
+ self.dependencies = []
+ self.defaults = False
+ self.vars = False
+ self.tasks = []
+ self.params = dict()
+
+ def write_role(self):
+
+ fpath = os.path.join(TESTDIR, 'roles', self.name)
+ if not os.path.isdir(fpath):
+ os.makedirs(fpath)
+
+ if self.defaults:
+ # roles/x/defaults/main.yml
+ fpath = os.path.join(TESTDIR, 'roles', self.name, 'defaults')
+ if not os.path.isdir(fpath):
+ os.makedirs(fpath)
+ fname = os.path.join(fpath, 'main.yml')
+ with open(fname, 'w') as f:
+ f.write('findme: %s\n' % self.name)
+
+ if self.vars:
+ # roles/x/vars/main.yml
+ fpath = os.path.join(TESTDIR, 'roles', self.name, 'vars')
+ if not os.path.isdir(fpath):
+ os.makedirs(fpath)
+ fname = os.path.join(fpath, 'main.yml')
+ with open(fname, 'w') as f:
+ f.write('findme: %s\n' % self.name)
+
+ if self.dependencies:
+ fpath = os.path.join(TESTDIR, 'roles', self.name, 'meta')
+ if not os.path.isdir(fpath):
+ os.makedirs(fpath)
+ fname = os.path.join(fpath, 'main.yml')
+ with open(fname, 'w') as f:
+ f.write('dependencies:\n')
+ for dep in self.dependencies:
+ f.write('- { role: %s }\n' % dep)
+
+
+class DynamicInventory(object):
+ BASESCRIPT = '''#!/usr/bin/python
+import json
+data = """{{ data }}"""
+data = json.loads(data)
+print(json.dumps(data, indent=2, sort_keys=True))
+'''
+
+ BASEINV = {
+ '_meta': {
+ 'hostvars': {
+ 'testhost': {}
+ }
+ }
+ }
+
+ def __init__(self, features):
+ self.ENV = Environment()
+ self.features = features
+ self.fpath = None
+ self.inventory = self.BASEINV.copy()
+ self.build()
+
+ def build(self):
+ xhost = 'testhost'
+ if 'script_host' in self.features:
+ self.inventory['_meta']['hostvars'][xhost]['findme'] = 'script_host'
+ else:
+ self.inventory['_meta']['hostvars'][xhost] = {}
+
+ if 'script_child' in self.features:
+ self.inventory['child'] = {
+ 'hosts': [xhost],
+ 'vars': {'findme': 'script_child'}
+ }
+
+ if 'script_parent' in self.features:
+
+ self.inventory['parent'] = {
+ 'vars': {'findme': 'script_parent'}
+ }
+
+ if 'script_child' in self.features:
+ self.inventory['parent']['children'] = ['child']
+ else:
+ self.inventory['parent']['hosts'] = [xhost]
+
+ if 'script_all' in self.features:
+ self.inventory['all'] = {
+ 'hosts': [xhost],
+ 'vars': {
+ 'findme': 'script_all'
+ },
+ }
+ else:
+ self.inventory['all'] = {
+ 'hosts': [xhost],
+ }
+
+ def write_script(self):
+ fdir = os.path.join(TESTDIR, 'inventory')
+ if not os.path.isdir(fdir):
+ os.makedirs(fdir)
+ fpath = os.path.join(fdir, 'hosts')
+ # fpath = os.path.join(TESTDIR, 'inventory')
+ self.fpath = fpath
+
+ data = json.dumps(self.inventory)
+ t = self.ENV.from_string(self.BASESCRIPT)
+ fdata = t.render(data=data)
+ with open(fpath, 'w') as f:
+ f.write(fdata + '\n')
+ st = os.stat(fpath)
+ os.chmod(fpath, st.st_mode | stat.S_IEXEC)
+
+
+class VarTestMaker(object):
+ def __init__(self, features, dynamic_inventory=False):
+ clean_test_dir()
+ self.dynamic_inventory = dynamic_inventory
+ self.di = None
+ self.features = features[:]
+ self.inventory = ''
+ self.playvars = dict()
+ self.varsfiles = []
+ self.playbook = dict(hosts='testhost', gather_facts=False)
+ self.tasks = []
+ self.roles = []
+ self.ansible_command = None
+ self.stdout = None
+
+ def write_playbook(self):
+ fname = os.path.join(TESTDIR, 'site.yml')
+ pb_copy = self.playbook.copy()
+
+ if self.playvars:
+ pb_copy['vars'] = self.playvars
+ if self.varsfiles:
+ pb_copy['vars_files'] = self.varsfiles
+ if self.roles:
+ pb_copy['roles'] = []
+ for role in self.roles:
+ role.write_role()
+ role_def = dict(role=role.name)
+ role_def.update(role.params)
+ pb_copy['roles'].append(role_def)
+ if self.tasks:
+ pb_copy['tasks'] = self.tasks
+
+ with open(fname, 'w') as f:
+ pb_yaml = yaml.dump([pb_copy], f, default_flow_style=False, indent=2)
+
+ def build(self):
+
+ if self.dynamic_inventory:
+ # python based inventory file
+ self.di = DynamicInventory(self.features)
+ self.di.write_script()
+ else:
+ # ini based inventory file
+ if 'ini_host' in self.features:
+ self.inventory += 'testhost findme=ini_host\n'
+ else:
+ self.inventory += 'testhost\n'
+ self.inventory += '\n'
+
+ if 'ini_child' in self.features:
+ self.inventory += '[child]\n'
+ self.inventory += 'testhost\n'
+ self.inventory += '\n'
+ self.inventory += '[child:vars]\n'
+ self.inventory += 'findme=ini_child\n'
+ self.inventory += '\n'
+
+ if 'ini_parent' in self.features:
+ if 'ini_child' in self.features:
+ self.inventory += '[parent:children]\n'
+ self.inventory += 'child\n'
+ else:
+ self.inventory += '[parent]\n'
+ self.inventory += 'testhost\n'
+ self.inventory += '\n'
+ self.inventory += '[parent:vars]\n'
+ self.inventory += 'findme=ini_parent\n'
+ self.inventory += '\n'
+
+ if 'ini_all' in self.features:
+ self.inventory += '[all:vars]\n'
+ self.inventory += 'findme=ini_all\n'
+ self.inventory += '\n'
+
+ # default to a single file called inventory
+ invfile = os.path.join(TESTDIR, 'inventory', 'hosts')
+ ipath = os.path.join(TESTDIR, 'inventory')
+ if not os.path.isdir(ipath):
+ os.makedirs(ipath)
+
+ with open(invfile, 'w') as f:
+ f.write(self.inventory)
+
+ hpath = os.path.join(TESTDIR, 'inventory', 'host_vars')
+ if not os.path.isdir(hpath):
+ os.makedirs(hpath)
+ gpath = os.path.join(TESTDIR, 'inventory', 'group_vars')
+ if not os.path.isdir(gpath):
+ os.makedirs(gpath)
+
+ if 'ini_host_vars_file' in self.features:
+ hfile = os.path.join(hpath, 'testhost')
+ with open(hfile, 'w') as f:
+ f.write('findme: ini_host_vars_file\n')
+
+ if 'ini_group_vars_file_all' in self.features:
+ hfile = os.path.join(gpath, 'all')
+ with open(hfile, 'w') as f:
+ f.write('findme: ini_group_vars_file_all\n')
+
+ if 'ini_group_vars_file_child' in self.features:
+ hfile = os.path.join(gpath, 'child')
+ with open(hfile, 'w') as f:
+ f.write('findme: ini_group_vars_file_child\n')
+
+ if 'ini_group_vars_file_parent' in self.features:
+ hfile = os.path.join(gpath, 'parent')
+ with open(hfile, 'w') as f:
+ f.write('findme: ini_group_vars_file_parent\n')
+
+ if 'pb_host_vars_file' in self.features:
+ os.makedirs(os.path.join(TESTDIR, 'host_vars'))
+ fname = os.path.join(TESTDIR, 'host_vars', 'testhost')
+ with open(fname, 'w') as f:
+ f.write('findme: pb_host_vars_file\n')
+
+ if 'pb_group_vars_file_parent' in self.features:
+ if not os.path.isdir(os.path.join(TESTDIR, 'group_vars')):
+ os.makedirs(os.path.join(TESTDIR, 'group_vars'))
+ fname = os.path.join(TESTDIR, 'group_vars', 'parent')
+ with open(fname, 'w') as f:
+ f.write('findme: pb_group_vars_file_parent\n')
+
+ if 'pb_group_vars_file_child' in self.features:
+ if not os.path.isdir(os.path.join(TESTDIR, 'group_vars')):
+ os.makedirs(os.path.join(TESTDIR, 'group_vars'))
+ fname = os.path.join(TESTDIR, 'group_vars', 'child')
+ with open(fname, 'w') as f:
+ f.write('findme: pb_group_vars_file_child\n')
+
+ if 'pb_group_vars_file_all' in self.features:
+ if not os.path.isdir(os.path.join(TESTDIR, 'group_vars')):
+ os.makedirs(os.path.join(TESTDIR, 'group_vars'))
+ fname = os.path.join(TESTDIR, 'group_vars', 'all')
+ with open(fname, 'w') as f:
+ f.write('findme: pb_group_vars_file_all\n')
+
+ if 'play_var' in self.features:
+ self.playvars['findme'] = 'play_var'
+
+ if 'set_fact' in self.features:
+ self.tasks.append(dict(set_fact='findme="set_fact"'))
+
+ if 'vars_file' in self.features:
+ self.varsfiles.append('varsfile.yml')
+ fname = os.path.join(TESTDIR, 'varsfile.yml')
+ with open(fname, 'w') as f:
+ f.write('findme: vars_file\n')
+
+ if 'include_vars' in self.features:
+ self.tasks.append(dict(include_vars='included_vars.yml'))
+ fname = os.path.join(TESTDIR, 'included_vars.yml')
+ with open(fname, 'w') as f:
+ f.write('findme: include_vars\n')
+
+ if 'role_var' in self.features:
+ role = Role('role_var')
+ role.vars = True
+ role.load = True
+ self.roles.append(role)
+
+ if 'role_parent_default' in self.features:
+ role = Role('role_default')
+ role.load = False
+ role.defaults = True
+ self.roles.append(role)
+
+ role = Role('role_parent_default')
+ role.dependencies.append('role_default')
+ role.defaults = True
+ role.load = True
+ if 'role_params' in self.features:
+ role.params = dict(findme='role_params')
+ self.roles.append(role)
+
+ elif 'role_default' in self.features:
+ role = Role('role_default')
+ role.defaults = True
+ role.load = True
+ if 'role_params' in self.features:
+ role.params = dict(findme='role_params')
+ self.roles.append(role)
+
+ debug_task = dict(debug='var=findme')
+ test_task = {'assert': dict(that=['findme == "%s"' % self.features[0]])}
+ if 'task_vars' in self.features:
+ test_task['vars'] = dict(findme="task_vars")
+ if 'registered_vars' in self.features:
+ test_task['register'] = 'findme'
+
+ if 'block_vars' in self.features:
+ block_wrapper = [
+ debug_task,
+ {
+ 'block': [test_task],
+ 'vars': dict(findme="block_vars"),
+ }
+ ]
+ else:
+ block_wrapper = [debug_task, test_task]
+
+ if 'include_params' in self.features:
+ self.tasks.append(dict(name='including tasks', include='included_tasks.yml', vars=dict(findme='include_params')))
+ else:
+ self.tasks.append(dict(include='included_tasks.yml'))
+
+ fname = os.path.join(TESTDIR, 'included_tasks.yml')
+ with open(fname, 'w') as f:
+ f.write(yaml.dump(block_wrapper))
+
+ self.write_playbook()
+
+ def run(self):
+ '''
+ if self.dynamic_inventory:
+ cmd = 'ansible-playbook -c local -i inventory/hosts site.yml'
+ else:
+ cmd = 'ansible-playbook -c local -i inventory site.yml'
+ '''
+ cmd = 'ansible-playbook -c local -i inventory site.yml'
+ if 'extra_vars' in self.features:
+ cmd += ' --extra-vars="findme=extra_vars"'
+ cmd = cmd + ' -vvvvv'
+ self.ansible_command = cmd
+ (rc, so, se) = run_command(cmd, cwd=TESTDIR)
+ self.stdout = so
+
+ if rc != 0:
+ raise Exception("playbook failed (rc=%s), stdout: '%s' stderr: '%s'" % (rc, so, se))
+
+ def show_tree(self):
+ print('## TREE')
+ cmd = 'tree %s' % TESTDIR
+ (rc, so, se) = run_command(cmd)
+ lines = so.split('\n')
+ lines = lines[:-3]
+ print('\n'.join(lines))
+
+ def show_content(self):
+ print('## CONTENT')
+ cmd = 'find %s -type f | xargs tail -n +1' % TESTDIR
+ (rc, so, se) = run_command(cmd)
+ print(so)
+
+ def show_stdout(self):
+ print('## COMMAND')
+ print(self.ansible_command)
+ print('## STDOUT')
+ print(self.stdout)
+
+
+def main():
+ features = [
+ 'extra_vars',
+ 'include_params',
+ # 'role_params', # FIXME: we don't yet validate tasks within a role
+ 'set_fact',
+ # 'registered_vars', # FIXME: hard to simulate
+ 'include_vars',
+ # 'role_dep_params',
+ 'task_vars',
+ 'block_vars',
+ 'role_var',
+ 'vars_file',
+ 'play_var',
+ # 'host_facts', # FIXME: hard to simulate
+ 'pb_host_vars_file',
+ 'ini_host_vars_file',
+ 'ini_host',
+ 'pb_group_vars_file_child',
+ # 'ini_group_vars_file_child', #FIXME: this contradicts documented precedence pb group vars files should override inventory ones
+ 'pb_group_vars_file_parent',
+ 'ini_group_vars_file_parent',
+ 'pb_group_vars_file_all',
+ 'ini_group_vars_file_all',
+ 'ini_child',
+ 'ini_parent',
+ 'ini_all',
+ 'role_parent_default',
+ 'role_default',
+ ]
+
+ parser = OptionParser()
+ parser.add_option('-f', '--feature', action='append')
+ parser.add_option('--use_dynamic_inventory', action='store_true')
+ parser.add_option('--show_tree', action='store_true')
+ parser.add_option('--show_content', action='store_true')
+ parser.add_option('--show_stdout', action='store_true')
+ parser.add_option('--copy_testcases_to_local_dir', action='store_true')
+ (options, args) = parser.parse_args()
+
+ if options.feature:
+ for f in options.feature:
+ if f not in features:
+ print('%s is not a valid feature' % f)
+ sys.exit(1)
+ features = [x for x in options.feature]
+
+ fdesc = {
+ 'ini_host': 'host var inside the ini',
+ 'script_host': 'host var inside the script _meta',
+ 'ini_child': 'child group var inside the ini',
+ 'script_child': 'child group var inside the script',
+ 'ini_parent': 'parent group var inside the ini',
+ 'script_parent': 'parent group var inside the script',
+ 'ini_all': 'all group var inside the ini',
+ 'script_all': 'all group var inside the script',
+ 'ini_host_vars_file': 'var in inventory/host_vars/host',
+ 'ini_group_vars_file_parent': 'var in inventory/group_vars/parent',
+ 'ini_group_vars_file_child': 'var in inventory/group_vars/child',
+ 'ini_group_vars_file_all': 'var in inventory/group_vars/all',
+ 'pb_group_vars_file_parent': 'var in playbook/group_vars/parent',
+ 'pb_group_vars_file_child': 'var in playbook/group_vars/child',
+ 'pb_group_vars_file_all': 'var in playbook/group_vars/all',
+ 'pb_host_vars_file': 'var in playbook/host_vars/host',
+ 'play_var': 'var set in playbook header',
+ 'role_parent_default': 'var in roles/role_parent/defaults/main.yml',
+ 'role_default': 'var in roles/role/defaults/main.yml',
+ 'role_var': 'var in ???',
+ 'include_vars': 'var in included file',
+ 'set_fact': 'var made by set_fact',
+ 'vars_file': 'var in file added by vars_file',
+ 'block_vars': 'vars defined on the block',
+ 'task_vars': 'vars defined on the task',
+ 'extra_vars': 'var passed via the cli'
+ }
+
+ dinv = options.use_dynamic_inventory
+ if dinv:
+ # some features are specific to ini, so swap those
+ for (idx, x) in enumerate(features):
+ if x.startswith('ini_') and 'vars_file' not in x:
+ features[idx] = x.replace('ini_', 'script_')
+
+ dinv = options.use_dynamic_inventory
+
+ index = 1
+ while features:
+ VTM = VarTestMaker(features, dynamic_inventory=dinv)
+ VTM.build()
+
+ if options.show_tree or options.show_content or options.show_stdout:
+ print('')
+ if options.show_tree:
+ VTM.show_tree()
+ if options.show_content:
+ VTM.show_content()
+
+ try:
+ print("CHECKING: %s (%s)" % (features[0], fdesc.get(features[0], '')))
+ res = VTM.run()
+ if options.show_stdout:
+ VTM.show_stdout()
+
+ features.pop(0)
+
+ if options.copy_testcases_to_local_dir:
+ topdir = 'testcases'
+ if index == 1 and os.path.isdir(topdir):
+ shutil.rmtree(topdir)
+ if not os.path.isdir(topdir):
+ os.makedirs(topdir)
+ thisindex = str(index)
+ if len(thisindex) == 1:
+ thisindex = '0' + thisindex
+ thisdir = os.path.join(topdir, '%s.%s' % (thisindex, res))
+ shutil.copytree(TESTDIR, thisdir)
+
+ except Exception as e:
+ print("ERROR !!!")
+ print(e)
+ print('feature: %s failed' % features[0])
+ sys.exit(1)
+ finally:
+ shutil.rmtree(TESTDIR)
+ index += 1
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test/integration/targets/var_precedence/host_vars/testhost b/test/integration/targets/var_precedence/host_vars/testhost
new file mode 100644
index 00000000..7d533554
--- /dev/null
+++ b/test/integration/targets/var_precedence/host_vars/testhost
@@ -0,0 +1,2 @@
+# Var precedence testing
+defaults_file_var_role3: "overridden from inventory"
diff --git a/test/integration/targets/var_precedence/inventory b/test/integration/targets/var_precedence/inventory
new file mode 100644
index 00000000..3b52d041
--- /dev/null
+++ b/test/integration/targets/var_precedence/inventory
@@ -0,0 +1,13 @@
+[local]
+testhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"
+
+[all:vars]
+extra_var_override=FROM_INVENTORY
+inven_var=inventory_var
+
+[inven_overridehosts]
+invenoverride ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"
+
+[inven_overridehosts:vars]
+foo=foo
+var_dir=vars
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence/meta/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence/meta/main.yml
new file mode 100644
index 00000000..423b94e3
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence/meta/main.yml
@@ -0,0 +1,4 @@
+dependencies:
+ - { role: test_var_precedence_role1, param_var: "param_var_role1" }
+ - { role: test_var_precedence_role2, param_var: "param_var_role2" }
+ - { role: test_var_precedence_role3, param_var: "param_var_role3" }
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence/tasks/main.yml
new file mode 100644
index 00000000..7850e6b6
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence/tasks/main.yml
@@ -0,0 +1,10 @@
+- debug: var=extra_var
+- debug: var=vars_var
+- debug: var=vars_files_var
+- debug: var=vars_files_var_role
+- assert:
+ that:
+ - 'extra_var == "extra_var"'
+ - 'vars_var == "vars_var"'
+ - 'vars_files_var == "vars_files_var"'
+ - 'vars_files_var_role == "vars_files_var_role3"'
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_dep/defaults/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/defaults/main.yml
new file mode 100644
index 00000000..dda4224c
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/defaults/main.yml
@@ -0,0 +1,5 @@
+---
+# should be overridden by vars_files in the main play
+vars_files_var: "BAD!"
+# should be seen in role1 (no override)
+defaults_file_var_role1: "defaults_file_var_role1"
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_dep/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/tasks/main.yml
new file mode 100644
index 00000000..2f8e1709
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/tasks/main.yml
@@ -0,0 +1,14 @@
+- debug: var=extra_var
+- debug: var=param_var
+- debug: var=vars_var
+- debug: var=vars_files_var
+- debug: var=vars_files_var_role
+- debug: var=defaults_file_var_role1
+- assert:
+ that:
+ - 'extra_var == "extra_var"'
+ - 'param_var == "param_var_role1"'
+ - 'vars_var == "vars_var"'
+ - 'vars_files_var == "vars_files_var"'
+ - 'vars_files_var_role == "vars_files_var_dep"'
+ - 'defaults_file_var_role1 == "defaults_file_var_role1"'
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_dep/vars/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/vars/main.yml
new file mode 100644
index 00000000..a69efad5
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_dep/vars/main.yml
@@ -0,0 +1,4 @@
+---
+# should override the global vars_files_var since it's local to the role
+# but will be set to the value in the last role included which defines it
+vars_files_var_role: "vars_files_var_dep"
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_inven_override/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_inven_override/tasks/main.yml
new file mode 100644
index 00000000..942ae4ec
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_inven_override/tasks/main.yml
@@ -0,0 +1,5 @@
+---
+- debug: var=foo
+- assert:
+ that:
+ - 'foo == "bar"'
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role1/defaults/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/defaults/main.yml
new file mode 100644
index 00000000..dda4224c
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/defaults/main.yml
@@ -0,0 +1,5 @@
+---
+# should be overridden by vars_files in the main play
+vars_files_var: "BAD!"
+# should be seen in role1 (no override)
+defaults_file_var_role1: "defaults_file_var_role1"
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role1/meta/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/meta/main.yml
new file mode 100644
index 00000000..c8b410b5
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+ - test_var_precedence_dep
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role1/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/tasks/main.yml
new file mode 100644
index 00000000..95b2a0bb
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/tasks/main.yml
@@ -0,0 +1,14 @@
+- debug: var=extra_var
+- debug: var=param_var
+- debug: var=vars_var
+- debug: var=vars_files_var
+- debug: var=vars_files_var_role
+- debug: var=defaults_file_var_role1
+- assert:
+ that:
+ - 'extra_var == "extra_var"'
+ - 'param_var == "param_var_role1"'
+ - 'vars_var == "vars_var"'
+ - 'vars_files_var == "vars_files_var"'
+ - 'vars_files_var_role == "vars_files_var_role1"'
+ - 'defaults_file_var_role1 == "defaults_file_var_role1"'
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role1/vars/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/vars/main.yml
new file mode 100644
index 00000000..2f7613d3
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role1/vars/main.yml
@@ -0,0 +1,4 @@
+---
+# should override the global vars_files_var since it's local to the role
+# but will be set to the value in the last role included which defines it
+vars_files_var_role: "vars_files_var_role1"
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role2/defaults/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/defaults/main.yml
new file mode 100644
index 00000000..8ed63ced
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/defaults/main.yml
@@ -0,0 +1,5 @@
+---
+# should be overridden by vars_files in the main play
+vars_files_var: "BAD!"
+# should be overridden by the vars file in role2
+defaults_file_var_role2: "BAD!"
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role2/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/tasks/main.yml
new file mode 100644
index 00000000..a862389c
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/tasks/main.yml
@@ -0,0 +1,14 @@
+- debug: var=extra_var
+- debug: var=param_var
+- debug: var=vars_var
+- debug: var=vars_files_var
+- debug: var=vars_files_var_role
+- debug: var=defaults_file_var_role1
+- assert:
+ that:
+ - 'extra_var == "extra_var"'
+ - 'param_var == "param_var_role2"'
+ - 'vars_var == "vars_var"'
+ - 'vars_files_var == "vars_files_var"'
+ - 'vars_files_var_role == "vars_files_var_role2"'
+ - 'defaults_file_var_role2 == "overridden by role vars"'
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role2/vars/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/vars/main.yml
new file mode 100644
index 00000000..483c5ea2
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role2/vars/main.yml
@@ -0,0 +1,5 @@
+---
+# should override the global vars_files_var since it's local to the role
+vars_files_var_role: "vars_files_var_role2"
+# should override the value in defaults/main.yml for role 2
+defaults_file_var_role2: "overridden by role vars"
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role3/defaults/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/defaults/main.yml
new file mode 100644
index 00000000..763b0d50
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+# should be overridden by vars_files in the main play
+vars_files_var: "BAD!"
+# should override the defaults var for role 1 and 2
+defaults_file_var: "last one wins"
+# should be overridden from the inventory value
+defaults_file_var_role3: "BAD!"
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role3/tasks/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/tasks/main.yml
new file mode 100644
index 00000000..12346ecd
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/tasks/main.yml
@@ -0,0 +1,14 @@
+- debug: var=extra_var
+- debug: var=param_var
+- debug: var=vars_var
+- debug: var=vars_files_var
+- debug: var=vars_files_var_role
+- debug: var=defaults_file_var_role1
+- assert:
+ that:
+ - 'extra_var == "extra_var"'
+ - 'param_var == "param_var_role3"'
+ - 'vars_var == "vars_var"'
+ - 'vars_files_var == "vars_files_var"'
+ - 'vars_files_var_role == "vars_files_var_role3"'
+ - 'defaults_file_var_role3 == "overridden from inventory"'
diff --git a/test/integration/targets/var_precedence/roles/test_var_precedence_role3/vars/main.yml b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/vars/main.yml
new file mode 100644
index 00000000..3cfb1b1c
--- /dev/null
+++ b/test/integration/targets/var_precedence/roles/test_var_precedence_role3/vars/main.yml
@@ -0,0 +1,3 @@
+---
+# should override the global vars_files_var since it's local to the role
+vars_files_var_role: "vars_files_var_role3"
diff --git a/test/integration/targets/var_precedence/runme.sh b/test/integration/targets/var_precedence/runme.sh
new file mode 100755
index 00000000..0f0811c3
--- /dev/null
+++ b/test/integration/targets/var_precedence/runme.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook test_var_precedence.yml -i inventory -v "$@" \
+ -e 'extra_var=extra_var' \
+ -e 'extra_var_override=extra_var_override'
+
+./ansible-var-precedence-check.py
diff --git a/test/integration/targets/var_precedence/test_var_precedence.yml b/test/integration/targets/var_precedence/test_var_precedence.yml
new file mode 100644
index 00000000..58584bfb
--- /dev/null
+++ b/test/integration/targets/var_precedence/test_var_precedence.yml
@@ -0,0 +1,44 @@
+---
+- hosts: testhost
+ vars:
+ - ansible_hostname: "BAD!"
+ - vars_var: "vars_var"
+ - param_var: "BAD!"
+ - vars_files_var: "BAD!"
+ - extra_var_override_once_removed: "{{ extra_var_override }}"
+ - from_inventory_once_removed: "{{ inven_var | default('BAD!') }}"
+ vars_files:
+ - vars/test_var_precedence.yml
+ roles:
+ - { role: test_var_precedence, param_var: "param_var" }
+ tasks:
+ - name: register a result
+ command: echo 'BAD!'
+ register: registered_var
+ - name: use set_fact to override the registered_var
+ set_fact: registered_var="this is from set_fact"
+ - debug: var=extra_var
+ - debug: var=extra_var_override_once_removed
+ - debug: var=vars_var
+ - debug: var=vars_files_var
+ - debug: var=vars_files_var_role
+ - debug: var=registered_var
+ - debug: var=from_inventory_once_removed
+ - assert:
+ that: item
+ with_items:
+ - 'extra_var == "extra_var"'
+ - 'extra_var_override == "extra_var_override"'
+ - 'extra_var_override_once_removed == "extra_var_override"'
+ - 'vars_var == "vars_var"'
+ - 'vars_files_var == "vars_files_var"'
+ - 'vars_files_var_role == "vars_files_var_role3"'
+ - 'registered_var == "this is from set_fact"'
+ - 'from_inventory_once_removed == "inventory_var"'
+
+- hosts: inven_overridehosts
+ vars_files:
+ - "test_var_precedence.yml"
+ roles:
+ - role: test_var_precedence_inven_override
+ foo: bar
diff --git a/test/integration/targets/var_precedence/vars/test_var_precedence.yml b/test/integration/targets/var_precedence/vars/test_var_precedence.yml
new file mode 100644
index 00000000..19d65cba
--- /dev/null
+++ b/test/integration/targets/var_precedence/vars/test_var_precedence.yml
@@ -0,0 +1,5 @@
+---
+extra_var: "BAD!"
+role_var: "BAD!"
+vars_files_var: "vars_files_var"
+vars_files_var_role: "should be overridden by roles"