summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLee Garrett <lgarrett@rocketjump.eu>2023-09-12 12:22:07 +0200
committerLee Garrett <lgarrett@rocketjump.eu>2023-09-12 12:22:07 +0200
commit2c596bd3b9cdb541ea70fc0dc584da466b84c794 (patch)
treeea0280f48fb7cd7e50ffb55bd1143df70b208442 /test
parentbda5b278e6632ca997f58b67f99f159544a63a57 (diff)
downloaddebian-ansible-core-2c596bd3b9cdb541ea70fc0dc584da466b84c794.zip
New upstream version 2.14.10
Diffstat (limited to 'test')
-rw-r--r--test/integration/targets/ansible-galaxy-collection/library/setup_collections.py7
-rw-r--r--test/integration/targets/ansible-test-installed/aliases4
-rw-r--r--test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases1
-rwxr-xr-xtest/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh24
-rwxr-xr-xtest/integration/targets/ansible-test-installed/runme.sh21
-rw-r--r--test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps14
-rw-r--r--test/lib/ansible_test/_data/completion/remote.txt2
-rw-r--r--test/lib/ansible_test/_internal/ansible_util.py59
-rw-r--r--test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py4
-rw-r--r--test/lib/ansible_test/_internal/commands/sanity/validate_modules.py6
-rw-r--r--test/lib/ansible_test/_internal/constants.py1
-rw-r--r--test/lib/ansible_test/_internal/delegation.py7
-rw-r--r--test/lib/ansible_test/_internal/util.py2
-rw-r--r--test/lib/ansible_test/_util/target/setup/bootstrap.sh2
-rw-r--r--test/support/windows-integration/plugins/module_utils/Ansible.Service.cs3
15 files changed, 128 insertions, 19 deletions
diff --git a/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py b/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py
index 35b18dec..f4a51c4b 100644
--- a/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py
+++ b/test/integration/targets/ansible-galaxy-collection/library/setup_collections.py
@@ -152,7 +152,12 @@ def publish_collection(module, collection):
# Extract the tarfile to sign the MANIFEST.json
with tarfile.open(collection_path, mode='r') as collection_tar:
- collection_tar.extractall(path=os.path.join(collection_dir, '%s-%s-%s' % (namespace, name, version)))
+ # deprecated: description='extractall fallback without filter' python_version='3.11'
+ # Replace 'tar_filter' with 'data_filter' and 'filter=tar' with 'filter=data' once Python 3.12 is minimum requirement.
+ if hasattr(tarfile, 'tar_filter'):
+ collection_tar.extractall(path=os.path.join(collection_dir, '%s-%s-%s' % (namespace, name, version)), filter='tar')
+ else:
+ collection_tar.extractall(path=os.path.join(collection_dir, '%s-%s-%s' % (namespace, name, version)))
manifest_path = os.path.join(collection_dir, '%s-%s-%s' % (namespace, name, version), 'MANIFEST.json')
signature_path = os.path.join(module.params['signature_dir'], '%s-%s-%s-MANIFEST.json.asc' % (namespace, name, version))
diff --git a/test/integration/targets/ansible-test-installed/aliases b/test/integration/targets/ansible-test-installed/aliases
new file mode 100644
index 00000000..7741d444
--- /dev/null
+++ b/test/integration/targets/ansible-test-installed/aliases
@@ -0,0 +1,4 @@
+shippable/posix/group3 # runs in the distro test containers
+shippable/generic/group1 # runs in the default test container
+context/controller
+needs/target/collection
diff --git a/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases b/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases
new file mode 100644
index 00000000..1af1cf90
--- /dev/null
+++ b/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases
@@ -0,0 +1 @@
+context/controller
diff --git a/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh b/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh
new file mode 100755
index 00000000..9de3820a
--- /dev/null
+++ b/test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+# This test ensures that the bin entry points created by ansible-test work
+# when ansible-test is running from an install instead of from source.
+
+set -eux
+
+# The third PATH entry is the injected bin directory created by ansible-test.
+bin_dir="$(python -c 'import os; print(os.environ["PATH"].split(":")[2])')"
+
+while IFS= read -r name
+do
+ bin="${bin_dir}/${name}"
+
+ entry_point="${name//ansible-/}"
+ entry_point="${entry_point//ansible/adhoc}"
+
+ echo "=== ${name} (${entry_point})=${bin} ==="
+
+ if [ "${name}" == "ansible-test" ]; then
+ echo "skipped - ansible-test does not support self-testing from an install"
+ else
+ "${bin}" --version | tee /dev/stderr | grep -Eo "(^${name}\ \[core\ .*|executable location = ${bin}$)"
+ fi
+done < entry-points.txt
diff --git a/test/integration/targets/ansible-test-installed/runme.sh b/test/integration/targets/ansible-test-installed/runme.sh
new file mode 100755
index 00000000..8315357e
--- /dev/null
+++ b/test/integration/targets/ansible-test-installed/runme.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+base_dir="$(dirname "$(dirname "$(dirname "$(dirname "${OUTPUT_DIR}")")")")"
+bin_dir="${base_dir}/bin"
+
+source ../collection/setup.sh
+source virtualenv.sh
+
+unset PYTHONPATH
+
+# find the bin entry points to test
+ls "${bin_dir}" > tests/integration/targets/installed/entry-points.txt
+
+# deps are already installed, using --no-deps to avoid re-installing them
+pip install "${base_dir}" --disable-pip-version-check --no-deps
+
+# verify entry point generation without delegation
+ansible-test integration --color --truncate 0 "${@}"
+
+# verify entry point generation with same-host delegation
+ansible-test integration --venv --color --truncate 0 "${@}"
diff --git a/test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps1 b/test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps1
index 6e363211..163d035a 100644
--- a/test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps1
+++ b/test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps1
@@ -48,7 +48,6 @@ $test_whoami = {
Add-Type -TypeDefinition @'
using Microsoft.Win32.SafeHandles;
using System;
-using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
@@ -212,7 +211,6 @@ namespace Ansible
{
public SafeLsaMemoryBuffer() : base(true) { }
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
UInt32 res = NativeMethods.LsaFreeReturnBuffer(handle);
@@ -232,7 +230,6 @@ namespace Ansible
base.SetHandle(handle);
}
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(handle);
@@ -245,7 +242,6 @@ namespace Ansible
public SafeNativeHandle() : base(true) { }
public SafeNativeHandle(IntPtr handle) : base(true) { this.handle = handle; }
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
return NativeMethods.CloseHandle(handle);
diff --git a/test/lib/ansible_test/_data/completion/remote.txt b/test/lib/ansible_test/_data/completion/remote.txt
index 192298bf..4e607b7a 100644
--- a/test/lib/ansible_test/_data/completion/remote.txt
+++ b/test/lib/ansible_test/_data/completion/remote.txt
@@ -2,7 +2,7 @@ alpine/3.16 python=3.10 become=doas_sudo provider=aws arch=x86_64
alpine become=doas_sudo provider=aws arch=x86_64
fedora/36 python=3.10 become=sudo provider=aws arch=x86_64
fedora become=sudo provider=aws arch=x86_64
-freebsd/12.3 python=3.8 python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
+freebsd/12.4 python=3.9 python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
freebsd/13.1 python=3.8,3.7,3.9,3.10 python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
freebsd python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
macos/12.0 python=3.10 python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64
diff --git a/test/lib/ansible_test/_internal/ansible_util.py b/test/lib/ansible_test/_internal/ansible_util.py
index be88ccd8..885489f4 100644
--- a/test/lib/ansible_test/_internal/ansible_util.py
+++ b/test/lib/ansible_test/_internal/ansible_util.py
@@ -3,9 +3,11 @@ from __future__ import annotations
import json
import os
+import shutil
import typing as t
from .constants import (
+ ANSIBLE_BIN_SYMLINK_MAP,
SOFT_RLIMIT_NOFILE,
)
@@ -17,12 +19,15 @@ from .util import (
common_environment,
ApplicationError,
ANSIBLE_LIB_ROOT,
+ ANSIBLE_TEST_ROOT,
ANSIBLE_TEST_DATA_ROOT,
- ANSIBLE_BIN_PATH,
+ ANSIBLE_ROOT,
ANSIBLE_SOURCE_ROOT,
ANSIBLE_TEST_TOOLS_ROOT,
+ MODE_FILE_EXECUTE,
get_ansible_version,
raw_command,
+ verified_chmod,
)
from .util_common import (
@@ -78,8 +83,10 @@ def ansible_environment(args: CommonConfig, color: bool = True, ansible_config:
env = common_environment()
path = env['PATH']
- if not path.startswith(ANSIBLE_BIN_PATH + os.path.pathsep):
- path = ANSIBLE_BIN_PATH + os.path.pathsep + path
+ ansible_bin_path = get_ansible_bin_path(args)
+
+ if not path.startswith(ansible_bin_path + os.path.pathsep):
+ path = ansible_bin_path + os.path.pathsep + path
if not ansible_config:
# use the default empty configuration unless one has been provided
@@ -197,6 +204,52 @@ def configure_plugin_paths(args: CommonConfig) -> dict[str, str]:
@mutex
+def get_ansible_bin_path(args: CommonConfig) -> str:
+ """
+ Return a directory usable for PATH, containing only the ansible entry points.
+ If a temporary directory is required, it will be cached for the lifetime of the process and cleaned up at exit.
+ """
+ try:
+ return get_ansible_bin_path.bin_path # type: ignore[attr-defined]
+ except AttributeError:
+ pass
+
+ if ANSIBLE_SOURCE_ROOT:
+ # when running from source there is no need for a temporary directory since we already have known entry point scripts
+ bin_path = os.path.join(ANSIBLE_ROOT, 'bin')
+ else:
+ # when not running from source the installed entry points cannot be relied upon
+ # doing so would require using the interpreter specified by those entry points, which conflicts with using our interpreter and injector
+ # instead a temporary directory is created which contains only ansible entry points
+ # symbolic links cannot be used since the files are likely not executable
+ bin_path = create_temp_dir(prefix='ansible-test-', suffix='-bin')
+ bin_links = {os.path.join(bin_path, name): get_cli_path(path) for name, path in ANSIBLE_BIN_SYMLINK_MAP.items()}
+
+ if not args.explain:
+ for dst, src in bin_links.items():
+ shutil.copy(src, dst)
+ verified_chmod(dst, MODE_FILE_EXECUTE)
+
+ get_ansible_bin_path.bin_path = bin_path # type: ignore[attr-defined]
+
+ return bin_path
+
+
+def get_cli_path(path: str) -> str:
+ """Return the absolute path to the CLI script from the given path which is relative to the `bin` directory of the original source tree layout."""
+ path_rewrite = {
+ '../lib/ansible/': ANSIBLE_LIB_ROOT,
+ '../test/lib/ansible_test/': ANSIBLE_TEST_ROOT,
+ }
+
+ for prefix, destination in path_rewrite.items():
+ if path.startswith(prefix):
+ return os.path.join(destination, path[len(prefix):])
+
+ raise RuntimeError(path)
+
+
+@mutex
def get_ansible_python_path(args: CommonConfig) -> str:
"""
Return a directory usable for PYTHONPATH, containing only the ansible package.
diff --git a/test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py b/test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py
index 8f4fe8a4..6c7618d1 100644
--- a/test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py
+++ b/test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py
@@ -32,7 +32,7 @@ from ...payload import (
)
from ...util import (
- ANSIBLE_BIN_PATH,
+ ANSIBLE_SOURCE_ROOT,
)
@@ -52,7 +52,7 @@ class BinSymlinksTest(SanityVersionNeutral):
return True
def test(self, args: SanityConfig, targets: SanityTargets) -> TestResult:
- bin_root = ANSIBLE_BIN_PATH
+ bin_root = os.path.join(ANSIBLE_SOURCE_ROOT, 'bin')
bin_names = os.listdir(bin_root)
bin_paths = sorted(os.path.join(bin_root, path) for path in bin_names)
diff --git a/test/lib/ansible_test/_internal/commands/sanity/validate_modules.py b/test/lib/ansible_test/_internal/commands/sanity/validate_modules.py
index 72616e77..3153bc99 100644
--- a/test/lib/ansible_test/_internal/commands/sanity/validate_modules.py
+++ b/test/lib/ansible_test/_internal/commands/sanity/validate_modules.py
@@ -154,7 +154,11 @@ class ValidateModulesTest(SanitySingleVersion):
temp_dir = process_scoped_temporary_directory(args)
with tarfile.open(path) as file:
- file.extractall(temp_dir)
+ # deprecated: description='extractall fallback without filter' python_version='3.11'
+ if hasattr(tarfile, 'data_filter'):
+ file.extractall(temp_dir, filter='data') # type: ignore[call-arg]
+ else:
+ file.extractall(temp_dir)
cmd.extend([
'--original-plugins', temp_dir,
diff --git a/test/lib/ansible_test/_internal/constants.py b/test/lib/ansible_test/_internal/constants.py
index b6072fbe..fdf2d954 100644
--- a/test/lib/ansible_test/_internal/constants.py
+++ b/test/lib/ansible_test/_internal/constants.py
@@ -33,6 +33,7 @@ SECCOMP_CHOICES = [
# This bin symlink map must exactly match the contents of the bin directory.
# It is necessary for payload creation to reconstruct the bin directory when running ansible-test from an installed version of ansible.
# It is also used to construct the injector directory at runtime.
+# It is also used to construct entry points when not running ansible-test from source.
ANSIBLE_BIN_SYMLINK_MAP = {
'ansible': '../lib/ansible/cli/adhoc.py',
'ansible-config': '../lib/ansible/cli/config.py',
diff --git a/test/lib/ansible_test/_internal/delegation.py b/test/lib/ansible_test/_internal/delegation.py
index 7114f2ab..f9e54455 100644
--- a/test/lib/ansible_test/_internal/delegation.py
+++ b/test/lib/ansible_test/_internal/delegation.py
@@ -33,7 +33,6 @@ from .util import (
SubprocessError,
display,
filter_args,
- ANSIBLE_BIN_PATH,
ANSIBLE_LIB_ROOT,
ANSIBLE_TEST_ROOT,
OutputStream,
@@ -44,6 +43,10 @@ from .util_common import (
process_scoped_temporary_directory,
)
+from .ansible_util import (
+ get_ansible_bin_path,
+)
+
from .containers import (
support_container_context,
ContainerDatabase,
@@ -145,7 +148,7 @@ def delegate_command(args: EnvironmentConfig, host_state: HostState, exclude: li
con.extract_archive(chdir=working_directory, src=payload_file)
else:
content_root = working_directory
- ansible_bin_path = ANSIBLE_BIN_PATH
+ ansible_bin_path = get_ansible_bin_path(args)
command = generate_command(args, host_state.controller_profile.python, ansible_bin_path, content_root, exclude, require)
diff --git a/test/lib/ansible_test/_internal/util.py b/test/lib/ansible_test/_internal/util.py
index a5a9faba..1859be5b 100644
--- a/test/lib/ansible_test/_internal/util.py
+++ b/test/lib/ansible_test/_internal/util.py
@@ -74,14 +74,12 @@ ANSIBLE_TEST_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# assume running from install
ANSIBLE_ROOT = os.path.dirname(ANSIBLE_TEST_ROOT)
-ANSIBLE_BIN_PATH = os.path.dirname(os.path.abspath(sys.argv[0]))
ANSIBLE_LIB_ROOT = os.path.join(ANSIBLE_ROOT, 'ansible')
ANSIBLE_SOURCE_ROOT = None
if not os.path.exists(ANSIBLE_LIB_ROOT):
# running from source
ANSIBLE_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(ANSIBLE_TEST_ROOT)))
- ANSIBLE_BIN_PATH = os.path.join(ANSIBLE_ROOT, 'bin')
ANSIBLE_LIB_ROOT = os.path.join(ANSIBLE_ROOT, 'lib', 'ansible')
ANSIBLE_SOURCE_ROOT = ANSIBLE_ROOT
diff --git a/test/lib/ansible_test/_util/target/setup/bootstrap.sh b/test/lib/ansible_test/_util/target/setup/bootstrap.sh
index f2e82fbc..ea17dad3 100644
--- a/test/lib/ansible_test/_util/target/setup/bootstrap.sh
+++ b/test/lib/ansible_test/_util/target/setup/bootstrap.sh
@@ -163,6 +163,8 @@ bootstrap_remote_freebsd()
# Declare platform/python version combinations which do not have supporting OS packages available.
# For these combinations ansible-test will use pip to install the requirements instead.
case "${platform_version}/${python_version}" in
+ "12.4/3.9")
+ ;;
*)
jinja2_pkg="" # not available
cryptography_pkg="" # not available
diff --git a/test/support/windows-integration/plugins/module_utils/Ansible.Service.cs b/test/support/windows-integration/plugins/module_utils/Ansible.Service.cs
index be0f3db3..4b963a9d 100644
--- a/test/support/windows-integration/plugins/module_utils/Ansible.Service.cs
+++ b/test/support/windows-integration/plugins/module_utils/Ansible.Service.cs
@@ -2,7 +2,6 @@ using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
@@ -274,7 +273,6 @@ namespace Ansible.Service
base.SetHandle(handle);
}
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(handle);
@@ -287,7 +285,6 @@ namespace Ansible.Service
public SafeServiceHandle() : base(true) { }
public SafeServiceHandle(IntPtr handle) : base(true) { this.handle = handle; }
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
return NativeMethods.CloseServiceHandle(handle);