Repository: ansible/ansible
Pull request: ansible-test - Show Python version before install
##### SUMMARY

Always indicate the Python version being used before installing requirements.

Resolves https://github.com/ansible/ansible/issues/72855

##### ISSUE TYPE

Bugfix Pull Request

##### COMPONENT NAME

ansible-test


Problem statement:
ansible-test fails to mention which interpreter as soon it picks one
<!--- Verify first that your issue is not already reported on GitHub -->
<!--- Also test if the latest release and devel branch are affected too -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
ansible-test fails to mention which interpreter as soon it picks one, causing confusing errors where user has no clue why pip install may complain about missing wheel when in fact he has wheel installed.

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
ansible-test

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```paste below
ansible 2.10.2
  config file = /Users/ssbarnea/.ansible.cfg
  configured module search path = ['/Users/ssbarnea/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/ssbarnea/.pyenv/versions/3.9.0/lib/python3.9/site-packages/ansible
  executable location = /Users/ssbarnea/.pyenv/versions/3.9.0/bin/ansible
  python version = 3.9.0 (default, Oct 10 2020, 09:43:04) [Clang 11.0.0 (clang-1100.0.33.8)]
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->
```paste below

```

##### OS / ENVIRONMENT
any

##### STEPS TO REPRODUCE
* assure that you have two python interpreters available, lets say py27 and py36
* remove wheel from python2.7, `pip2.7 uninstall wheel`
* run `ansible-test units --requirements` 


<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS

After the expected WARNING around skipping Python 2.6 due to being missing, I would expect to see an INFO message telling me that ansible-test started using next interpreter, "Python 2.7" in the list, so I would know if pip fails which pip it was as it was clearly not the one from default interpreter.

##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes -->
```paste below
WARNING: Skipping unit tests on Python 2.6 due to missing interpreter.
Could not build wheels for pip, since package 'wheel' is not installed.
Could not build wheels for setuptools, since package 'wheel' is not installed.
Could not build wheels for cryptography, since package 'wheel' is not installed.
Could not build wheels for ipaddress, since package 'wheel' is not installed.
Could not build wheels for six, since package 'wheel' is not installed.
Could not build wheels for cffi, since package 'wheel' is not installed.
....
```

Hints from issue discussion:
Files identified in the description:
* [`bin/ansible-test`](https://github.com/ansible/ansible/blob/devel/bin/ansible-test)

If these files are incorrect, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
Does adding `-vv` help with that?
@ssbarnea Is this issue about `ansible-test sanity` or `ansible-test units`? The steps to reproduce indicate `sanity`, yet the output listed for actual results is for `units` instead.

needs_info
In fact the problem is valid to units and integrations tests, not sanity as on sanity it appears to mention which python version is using.

Still for the others, if called with `command --requirements` any failure to install requirements will be opaque, as pip will start to report errors like the ones I showed which do not mention the used interpreter. This in combination with the fact that the tools loops over all interpreters in order, it will produce an output like I put in the example.

I think that this can easily be avoided by adding another line near the `WARNING: Skipping unit tests on Python 2.6 due to missing interpreter.` which would say `INFO: Running ,.... on Python x.y interpreter` and assure that this line is visible with default verbosity levels.

Alternative would to print something like "Installing requrements for Python x.y.", but I am sure you got the idea, just be sure there is a line mentioning python interpreter being use before pip install is called.

Commit message: ansible-test - Show Python version before install

Always indicate the Python version being used before installing requirements.

Patch to review:
diff --git a/changelogs/fragments/ansible-test-requirements-message.yml b/changelogs/fragments/ansible-test-requirements-message.yml
new file mode 100644
index 00000000000000..864567be6a674c
--- /dev/null
+++ b/changelogs/fragments/ansible-test-requirements-message.yml
@@ -0,0 +1,3 @@
+bugfixes:
+  - ansible-test - Always indicate the Python version being used before installing requirements.
+                   Resolves issue https://github.com/ansible/ansible/issues/72855
diff --git a/test/lib/ansible_test/_internal/python_requirements.py b/test/lib/ansible_test/_internal/python_requirements.py
index 0e133f913fc647..6def2fb4ab63d0 100644
--- a/test/lib/ansible_test/_internal/python_requirements.py
+++ b/test/lib/ansible_test/_internal/python_requirements.py
@@ -48,6 +48,7 @@
 from .host_configs import (
     PosixConfig,
     PythonConfig,
+    VirtualPythonConfig,
 )
 
 from .connections import (
@@ -265,6 +266,20 @@ def run_pip(
     connection = connection or LocalConnection(args)
     script = prepare_pip_script(commands)
 
+    if isinstance(args, IntegrationConfig):
+        # Integration tests can involve two hosts (controller and target).
+        # The connection type can be used to disambiguate between the two.
+        context = " (controller)" if isinstance(connection, LocalConnection) else " (target)"
+    else:
+        context = ""
+
+    if isinstance(python, VirtualPythonConfig):
+        context += " (venv)"
+
+    # The interpreter path is not included below.
+    # It can be seen by running ansible-test with increased verbosity (showing all commands executed).
+    display.info(f'Installing requirements for Python {python.version}{context}')
+
     if not args.explain:
         try:
             connection.run([python.path], data=script, capture=False)


Code review comments:
diff_hunk: @@ -265,6 +266,20 @@ def run_pip(
     connection = connection or LocalConnection(args)
     script = prepare_pip_script(commands)
 
+    if isinstance(args, IntegrationConfig):
+        # Integration tests can involve two hosts (controller and target).
+        # The connection type can be used to disambiguate between the two.
+        context = " (controller)" if isinstance(connection, LocalConnection) else " (target)"
+    else:
+        context = ""
+
+    if isinstance(python, VirtualPythonConfig):
+        context += " (venv)"
path: test/lib/ansible_test/_internal/python_requirements.py
text: @user1:
How about using a different type of parens here to have visual difference between different context aspects?
```suggestion
        context += " [venv]"
```

@author:
I thought about this originally, but decided against it at the time. I don't have any strong feelings on it either way, so I'll go ahead and include it.