Skip to content

Commit aa5e2f6

Browse files
committed
Test if whether a shell is used is logged
The log message shows "Popen(...)", not "execute(...)". So it should faithfully report what is about to be passed to Popen in cases where a user reading the log would otherwise be misled into thinking this is what has happened. Reporting the actual "shell=" argument passed to Popen is also more useful to log than the argument passed to Git.execute (at least if only one of them is to be logged).
1 parent 5944060 commit aa5e2f6

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

test/test_git.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
# This module is part of GitPython and is released under
66
# the BSD License: https://opensource.org/license/bsd-3-clause/
77
import contextlib
8+
import logging
89
import os
910
import os.path as osp
11+
import re
1012
import shutil
1113
import subprocess
1214
import sys
@@ -74,28 +76,51 @@ def test_it_transforms_kwargs_into_git_command_arguments(self):
7476
res = self.git.transform_kwargs(**{"s": True, "t": True})
7577
self.assertEqual({"-s", "-t"}, set(res))
7678

77-
@ddt.data(
79+
_shell_cases = (
80+
# value_in_call, value_from_class, expected_popen_arg
7881
(None, False, False),
7982
(None, True, True),
8083
(False, True, False),
8184
(False, False, False),
8285
(True, False, True),
8386
(True, True, True),
8487
)
88+
89+
@ddt.idata(_shell_cases)
8590
@mock.patch.object(cmd, "Popen", wraps=cmd.Popen) # Since it is gotten via a "from" import.
8691
def test_it_uses_shell_or_not_as_specified(self, case, mock_popen):
8792
"""A bool passed as ``shell=`` takes precedence over `Git.USE_SHELL`."""
8893
value_in_call, value_from_class, expected_popen_arg = case
89-
# FIXME: Check what gets logged too!
94+
9095
with mock.patch.object(Git, "USE_SHELL", value_from_class):
9196
with contextlib.suppress(GitCommandError):
9297
self.git.execute(
9398
"git", # No args, so it runs with or without a shell, on all OSes.
9499
shell=value_in_call,
95100
)
101+
96102
mock_popen.assert_called_once()
97103
self.assertIs(mock_popen.call_args.kwargs["shell"], expected_popen_arg)
98104

105+
@ddt.idata(full_case[:2] for full_case in _shell_cases)
106+
@mock.patch.object(cmd, "Popen", wraps=cmd.Popen) # Since it is gotten via a "from" import.
107+
def test_it_logs_if_it_uses_a_shell(self, case, mock_popen):
108+
"""``shell=`` in the log message agrees with what is passed to `Popen`."""
109+
value_in_call, value_from_class = case
110+
111+
with self.assertLogs(cmd.log, level=logging.DEBUG) as log_watcher:
112+
with mock.patch.object(Git, "USE_SHELL", value_from_class):
113+
with contextlib.suppress(GitCommandError):
114+
self.git.execute(
115+
"git", # No args, so it runs with or without a shell, on all OSes.
116+
shell=value_in_call,
117+
)
118+
119+
popen_shell_arg = mock_popen.call_args.kwargs["shell"]
120+
expected_message = re.compile(rf"DEBUG:git.cmd:Popen\(.*\bshell={popen_shell_arg}\b.*\)")
121+
match_attempts = [expected_message.fullmatch(message) for message in log_watcher.output]
122+
self.assertTrue(any(match_attempts), repr(log_watcher.output))
123+
99124
def test_it_executes_git_and_returns_result(self):
100125
self.assertRegex(self.git.execute(["git", "version"]), r"^git version [\d\.]{2}.*$")
101126

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy