Skip to content

Commit 205d208

Browse files
backend: Deduplicate hosts returned by get_backends() (#572)
If a host appears multiple times in host specs (which can typically happen if a host is a member of multiple Ansible groups for instance), testinfra would run tests on that host multiple times. If a host finds itself listed multiple times with the same backend and connection parameters, testinfra will run the tests on that host only once. Signed-off-by: Benoît Knecht <[email protected]> Co-Authored-By: Philippe Pepiot <[email protected]>
1 parent 75dcf1c commit 205d208

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

test/test_backends.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,3 +519,16 @@ def test_ssh_hostspec(hostspec, expected):
519519
cmd, cmd_args = backend._build_ssh_command('true')
520520
command = backend.quote(' '.join(cmd), *cmd_args)
521521
assert command == expected
522+
523+
524+
def test_get_hosts():
525+
# Hosts returned by get_host must be deduplicated (by name & kwargs) and in
526+
# same order as asked
527+
hosts = testinfra.backend.get_backends([
528+
'ssh://foo', 'ssh://a', 'ssh://a', 'ssh://a?timeout=1',
529+
])
530+
assert [(h.host.name, h.timeout) for h in hosts] == [
531+
('foo', 10),
532+
('a', 10),
533+
('a', 1),
534+
]

testinfra/backend/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def get_backend(hostspec, **kwargs):
7777

7878

7979
def get_backends(hosts, **kwargs):
80-
backends = []
80+
backends = {}
8181
for hostspec in hosts:
8282
host, kw = parse_hostspec(hostspec)
8383
for k, v in kwargs.items():
@@ -89,8 +89,12 @@ def get_backends(hosts, **kwargs):
8989
connection = "paramiko"
9090
klass = get_backend_class(connection)
9191
for name in klass.get_hosts(host, **kw):
92+
key = (name, frozenset(kw.items()))
93+
if key in backends:
94+
continue
9295
if connection == "local":
93-
backends.append(klass(**kw))
96+
backend = klass(**kw)
9497
else:
95-
backends.append(klass(name, **kw))
96-
return backends
98+
backend = klass(name, **kw)
99+
backends[key] = backend
100+
return list(backends.values())

0 commit comments

Comments
 (0)