mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Add symlinks sanity test. (#46467)
* Add symlinks sanity test. * Replace legacy test symlinks with actual content. * Remove dir symlink from template_jinja2_latest. * Update import test to use generated library dir. * Fix copy test symlink setup.
This commit is contained in:
parent
a4961ff32a
commit
e2b6047514
21 changed files with 259 additions and 16 deletions
6
docs/docsite/rst/dev_guide/testing/sanity/symlinks.rst
Normal file
6
docs/docsite/rst/dev_guide/testing/sanity/symlinks.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
Sanity Tests » symlinks
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Symbolic links are only permitted for files that exist to ensure proper tarball generation during a release.
|
||||||
|
|
||||||
|
If other types of symlinks are needed for tests they must be created as part of the test.
|
|
@ -1 +0,0 @@
|
||||||
/tmp/ansible-test-abs-link
|
|
|
@ -1 +0,0 @@
|
||||||
/tmp/ansible-test-abs-link-dir
|
|
|
@ -1 +0,0 @@
|
||||||
invalid
|
|
|
@ -1 +0,0 @@
|
||||||
../invalid
|
|
|
@ -1 +0,0 @@
|
||||||
/tmp/ansible-test-link-dir/out_of_tree_circle
|
|
|
@ -1 +0,0 @@
|
||||||
../subdir2/subdir3
|
|
|
@ -9,15 +9,25 @@
|
||||||
local_temp_dir: '{{ tempfile_result.stdout }}'
|
local_temp_dir: '{{ tempfile_result.stdout }}'
|
||||||
# output_dir is hardcoded in test/runner/lib/executor.py and created there
|
# output_dir is hardcoded in test/runner/lib/executor.py and created there
|
||||||
remote_dir: '{{ output_dir }}'
|
remote_dir: '{{ output_dir }}'
|
||||||
|
symlinks:
|
||||||
|
ansible-test-abs-link: /tmp/ansible-test-abs-link
|
||||||
|
ansible-test-abs-link-dir: /tmp/ansible-test-abs-link-dir
|
||||||
|
circles: ../
|
||||||
|
invalid: invalid
|
||||||
|
invalid2: ../invalid
|
||||||
|
out_of_tree_circle: /tmp/ansible-test-link-dir/out_of_tree_circle
|
||||||
|
subdir3: ../subdir2/subdir3
|
||||||
|
|
||||||
- file: path={{local_temp_dir}} state=directory
|
- file: path={{local_temp_dir}} state=directory
|
||||||
name: ensure temp dir exists
|
name: ensure temp dir exists
|
||||||
|
|
||||||
# file cannot do this properly, use command instead
|
# file cannot do this properly, use command instead
|
||||||
- name: Create circular symbolic link
|
- name: Create symbolic link
|
||||||
command: ln -s ../ circles
|
command: "ln -s '{{ item.value }}' '{{ item.key }}'"
|
||||||
args:
|
args:
|
||||||
chdir: '{{role_path}}/files/subdir/subdir1'
|
chdir: '{{role_path}}/files/subdir/subdir1'
|
||||||
|
warn: no
|
||||||
|
with_dict: "{{ symlinks }}"
|
||||||
|
|
||||||
- name: Create remote unprivileged remote user
|
- name: Create remote unprivileged remote user
|
||||||
user:
|
user:
|
||||||
|
@ -55,11 +65,12 @@
|
||||||
state: absent
|
state: absent
|
||||||
connection: local
|
connection: local
|
||||||
|
|
||||||
- name: Remove circular symbolic link
|
- name: Remove symbolic link
|
||||||
file:
|
file:
|
||||||
path: '{{ role_path }}/files/subdir/subdir1/circles'
|
path: '{{ role_path }}/files/subdir/subdir1/{{ item.key }}'
|
||||||
state: absent
|
state: absent
|
||||||
connection: local
|
connection: local
|
||||||
|
with_dict: "{{ symlinks }}"
|
||||||
|
|
||||||
- name: Remote unprivileged remote user
|
- name: Remote unprivileged remote user
|
||||||
user:
|
user:
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../../template
|
|
|
@ -18,4 +18,7 @@ source "${MYTMPDIR}/jinja2/bin/activate"
|
||||||
|
|
||||||
pip install -U jinja2
|
pip install -U jinja2
|
||||||
|
|
||||||
|
ANSIBLE_ROLES_PATH="$(dirname "$(pwd)")"
|
||||||
|
export ANSIBLE_ROLES_PATH
|
||||||
|
|
||||||
ansible-playbook -i ../../inventory main.yml -e @../../integration_config.yml -v "$@"
|
ansible-playbook -i ../../inventory main.yml -e @../../integration_config.yml -v "$@"
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../../integration/targets/setup_ec2
|
|
2
test/legacy/roles/setup_ec2/defaults/main.yml
Normal file
2
test/legacy/roles/setup_ec2/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
resource_prefix: 'ansible-testing-'
|
119
test/legacy/roles/setup_ec2/tasks/common.yml
Normal file
119
test/legacy/roles/setup_ec2/tasks/common.yml
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: test with no parameters
|
||||||
|
action: "{{module_name}}"
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: assert failure when called with no parameters
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- 'result.failed'
|
||||||
|
- 'result.msg == "missing required arguments: name"'
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: test with only name
|
||||||
|
action: "{{module_name}} name={{ec2_key_name}}"
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: assert failure when called with only 'name'
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- 'result.failed'
|
||||||
|
- 'result.msg == "Either region or ec2_url must be specified"'
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: test invalid region parameter
|
||||||
|
action: "{{module_name}} name='{{ec2_key_name}}' region='asdf querty 1234'"
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: assert invalid region parameter
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- 'result.failed'
|
||||||
|
- 'result.msg.startswith("value of region must be one of:")'
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: test valid region parameter
|
||||||
|
action: "{{module_name}} name='{{ec2_key_name}}' region='{{ec2_region}}'"
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: assert valid region parameter
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- 'result.failed'
|
||||||
|
- 'result.msg.startswith("No handler was ready to authenticate.")'
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: test environment variable EC2_REGION
|
||||||
|
action: "{{module_name}} name='{{ec2_key_name}}'"
|
||||||
|
environment:
|
||||||
|
EC2_REGION: '{{ec2_region}}'
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: assert environment variable EC2_REGION
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- 'result.failed'
|
||||||
|
- 'result.msg.startswith("No handler was ready to authenticate.")'
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: test invalid ec2_url parameter
|
||||||
|
action: "{{module_name}} name='{{ec2_key_name}}'"
|
||||||
|
environment:
|
||||||
|
EC2_URL: bogus.example.com
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: assert invalid ec2_url parameter
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- 'result.failed'
|
||||||
|
- 'result.msg.startswith("No handler was ready to authenticate.")'
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: test valid ec2_url parameter
|
||||||
|
action: "{{module_name}} name='{{ec2_key_name}}'"
|
||||||
|
environment:
|
||||||
|
EC2_URL: '{{ec2_url}}'
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: assert valid ec2_url parameter
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- 'result.failed'
|
||||||
|
- 'result.msg.startswith("No handler was ready to authenticate.")'
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: test credentials from environment
|
||||||
|
action: "{{module_name}} name='{{ec2_key_name}}'"
|
||||||
|
environment:
|
||||||
|
EC2_REGION: '{{ec2_region}}'
|
||||||
|
EC2_ACCESS_KEY: bogus_access_key
|
||||||
|
EC2_SECRET_KEY: bogus_secret_key
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: assert ec2_key with valid ec2_url
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- 'result.failed'
|
||||||
|
- '"EC2ResponseError: 401 Unauthorized" in result.msg'
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: test credential parameters
|
||||||
|
action: "{{module_name}} name='{{ec2_key_name}}' ec2_region='{{ec2_region}}' ec2_access_key=bogus_access_key ec2_secret_key=bogus_secret_key"
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: assert credential parameters
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- 'result.failed'
|
||||||
|
- '"EC2ResponseError: 401 Unauthorized" in result.msg'
|
3
test/legacy/roles/setup_ec2/vars/main.yml
Normal file
3
test/legacy/roles/setup_ec2/vars/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
ec2_url: ec2.amazonaws.com
|
||||||
|
ec2_region: us-east-1
|
|
@ -1 +0,0 @@
|
||||||
../../integration/targets/setup_sshkey
|
|
55
test/legacy/roles/setup_sshkey/tasks/main.yml
Normal file
55
test/legacy/roles/setup_sshkey/tasks/main.yml
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
# (c) 2014, James Laska <jlaska@ansible.com>
|
||||||
|
|
||||||
|
# This file is part of Ansible
|
||||||
|
#
|
||||||
|
# Ansible is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ansible is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
- name: create a temp file
|
||||||
|
tempfile:
|
||||||
|
state: file
|
||||||
|
register: sshkey_file
|
||||||
|
tags:
|
||||||
|
- prepare
|
||||||
|
|
||||||
|
- name: generate sshkey
|
||||||
|
shell: echo 'y' | ssh-keygen -P '' -f {{ sshkey_file.path }}
|
||||||
|
tags:
|
||||||
|
- prepare
|
||||||
|
|
||||||
|
- name: create another temp file
|
||||||
|
tempfile:
|
||||||
|
state: file
|
||||||
|
register: another_sshkey_file
|
||||||
|
tags:
|
||||||
|
- prepare
|
||||||
|
|
||||||
|
- name: generate another_sshkey
|
||||||
|
shell: echo 'y' | ssh-keygen -P '' -f {{ another_sshkey_file.path }}
|
||||||
|
tags:
|
||||||
|
- prepare
|
||||||
|
|
||||||
|
- name: record fingerprint
|
||||||
|
shell: openssl rsa -in {{ sshkey_file.path }} -pubout -outform DER 2>/dev/null | openssl md5 -c
|
||||||
|
register: fingerprint
|
||||||
|
tags:
|
||||||
|
- prepare
|
||||||
|
|
||||||
|
- name: set facts for future roles
|
||||||
|
set_fact:
|
||||||
|
sshkey: '{{ sshkey_file.path }}'
|
||||||
|
key_material: "{{ lookup('file', sshkey_file.path ~ '.pub') }}"
|
||||||
|
another_key_material: "{{ lookup('file', another_sshkey_file.path ~ '.pub') }}"
|
||||||
|
fingerprint: '{{ fingerprint.stdout.split()[1] }}'
|
||||||
|
tags:
|
||||||
|
- prepare
|
|
@ -20,6 +20,7 @@ from lib.util import (
|
||||||
find_python,
|
find_python,
|
||||||
read_lines_without_comments,
|
read_lines_without_comments,
|
||||||
parse_to_list_of_dict,
|
parse_to_list_of_dict,
|
||||||
|
make_dirs,
|
||||||
)
|
)
|
||||||
|
|
||||||
from lib.ansible_util import (
|
from lib.ansible_util import (
|
||||||
|
@ -81,9 +82,24 @@ class ImportTest(SanityMultipleVersion):
|
||||||
if not args.explain:
|
if not args.explain:
|
||||||
os.symlink(os.path.abspath('test/sanity/import/importer.py'), importer_path)
|
os.symlink(os.path.abspath('test/sanity/import/importer.py'), importer_path)
|
||||||
|
|
||||||
|
# create a minimal python library
|
||||||
|
python_path = os.path.abspath('test/runner/.tox/import/lib')
|
||||||
|
ansible_path = os.path.join(python_path, 'ansible')
|
||||||
|
ansible_init = os.path.join(ansible_path, '__init__.py')
|
||||||
|
ansible_link = os.path.join(ansible_path, 'module_utils')
|
||||||
|
|
||||||
|
if not args.explain:
|
||||||
|
make_dirs(ansible_path)
|
||||||
|
|
||||||
|
with open(ansible_init, 'w'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not os.path.exists(ansible_link):
|
||||||
|
os.symlink('../../../../../../lib/ansible/module_utils', ansible_link)
|
||||||
|
|
||||||
# activate the virtual environment
|
# activate the virtual environment
|
||||||
env['PATH'] = '%s:%s' % (virtual_environment_bin, env['PATH'])
|
env['PATH'] = '%s:%s' % (virtual_environment_bin, env['PATH'])
|
||||||
env['PYTHONPATH'] = os.path.abspath('test/sanity/import/lib')
|
env['PYTHONPATH'] = python_path
|
||||||
|
|
||||||
# make sure coverage is available in the virtual environment if needed
|
# make sure coverage is available in the virtual environment if needed
|
||||||
if args.coverage:
|
if args.coverage:
|
||||||
|
|
4
test/sanity/code-smell/symlinks.json
Normal file
4
test/sanity/code-smell/symlinks.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"always": true,
|
||||||
|
"output": "path-message"
|
||||||
|
}
|
35
test/sanity/code-smell/symlinks.py
Executable file
35
test/sanity/code-smell/symlinks.py
Executable file
|
@ -0,0 +1,35 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
skip_dirs = set([
|
||||||
|
'.tox',
|
||||||
|
])
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk('.'):
|
||||||
|
for skip_dir in skip_dirs:
|
||||||
|
if skip_dir in dirs:
|
||||||
|
dirs.remove(skip_dir)
|
||||||
|
|
||||||
|
if root == '.':
|
||||||
|
root = ''
|
||||||
|
elif root.startswith('./'):
|
||||||
|
root = root[2:]
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
path = os.path.join(root, file)
|
||||||
|
|
||||||
|
if not os.path.exists(path):
|
||||||
|
print('%s: broken symlinks are not allowed' % path)
|
||||||
|
|
||||||
|
for directory in dirs:
|
||||||
|
path = os.path.join(root, directory)
|
||||||
|
|
||||||
|
if os.path.islink(path):
|
||||||
|
print('%s: symlinks to directories are not allowed' % path)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -1 +0,0 @@
|
||||||
"""Empty placeholder for import sanity test."""
|
|
|
@ -1 +0,0 @@
|
||||||
../../../../../lib/ansible/module_utils
|
|
Loading…
Add table
Reference in a new issue