Skip to content

Commit 036b924

Browse files
author
vshepard
committed
Fix initdb error on Windows - fix pgbench
1 parent edb5708 commit 036b924

File tree

6 files changed

+31
-69
lines changed

6 files changed

+31
-69
lines changed

testgres/operations/local_ops.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,7 @@ def _run_command(cmd, shell, input, timeout, encoding, temp_file=None):
5555
stdout=stdout,
5656
stderr=stderr,
5757
)
58-
59-
try:
60-
return process.communicate(input=input.encode(encoding) if input else None, timeout=timeout), process
61-
except subprocess.TimeoutExpired:
62-
process.kill()
63-
raise ExecUtilException("Command timed out after {} seconds.".format(timeout))
58+
return process
6459

6560
@staticmethod
6661
def _raise_exec_exception(message, command, exit_code, output):
@@ -151,10 +146,12 @@ def _exec_command_windows(self, cmd, wait_exit=False, verbose=False,
151146
input=None, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
152147
get_process=None, timeout=None):
153148
with tempfile.NamedTemporaryFile(mode='w+b') as temp_file:
154-
_, process = self._run_command(cmd, shell, input, timeout, encoding, temp_file)
155-
if get_process:
156-
return process
157-
output = self._process_output(process, encoding, temp_file)
149+
process = self._run_command(cmd, shell, input, timeout, encoding, temp_file)
150+
try:
151+
output = process.communicate(input=input.encode(encoding) if input else None, timeout=timeout)
152+
except subprocess.TimeoutExpired:
153+
process.kill()
154+
raise ExecUtilException("Command timed out after {} seconds.".format(timeout))
158155

159156
if process.returncode != 0 or has_errors(output):
160157
if process.returncode == 0:

testgres/operations/remote_ops.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ def __init__(self, conn_params: ConnectionParams):
4545
self.conn_params = conn_params
4646
self.host = conn_params.host
4747
self.ssh_key = conn_params.ssh_key
48+
if self.ssh_key:
49+
self.ssh_cmd = ["-i", self.ssh_key]
50+
else:
51+
self.ssh_cmd = []
4852
self.remote = True
4953
self.username = conn_params.username or self.get_user()
5054
self.add_known_host(self.host)
@@ -91,9 +95,9 @@ def exec_command(self, cmd, wait_exit=False, verbose=False, expect_error=False,
9195
"""
9296
ssh_cmd = []
9397
if isinstance(cmd, str):
94-
ssh_cmd = ['ssh', f"{self.username}@{self.host}", '-i', self.ssh_key, cmd]
98+
ssh_cmd = ['ssh', f"{self.username}@{self.host}"] + self.ssh_cmd + [cmd]
9599
elif isinstance(cmd, list):
96-
ssh_cmd = ['ssh', f"{self.username}@{self.host}", '-i', self.ssh_key] + cmd
100+
ssh_cmd = ['ssh', f"{self.username}@{self.host}"] + self.ssh_cmd + cmd
97101
process = subprocess.Popen(ssh_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
98102
if get_process:
99103
return process
@@ -242,9 +246,9 @@ def mkdtemp(self, prefix=None):
242246
- prefix (str): The prefix of the temporary directory name.
243247
"""
244248
if prefix:
245-
command = ["ssh", "-i", self.ssh_key, f"{self.username}@{self.host}", f"mktemp -d {prefix}XXXXX"]
249+
command = ["ssh"] + self.ssh_cmd + [f"{self.username}@{self.host}", f"mktemp -d {prefix}XXXXX"]
246250
else:
247-
command = ["ssh", "-i", self.ssh_key, f"{self.username}@{self.host}", "mktemp -d"]
251+
command = ["ssh"] + self.ssh_cmd + [f"{self.username}@{self.host}", "mktemp -d"]
248252

249253
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
250254

@@ -288,7 +292,7 @@ def write(self, filename, data, truncate=False, binary=False, read_and_write=Fal
288292

289293
with tempfile.NamedTemporaryFile(mode=mode, delete=False) as tmp_file:
290294
if not truncate:
291-
scp_cmd = ['scp', '-i', self.ssh_key, f"{self.username}@{self.host}:{filename}", tmp_file.name]
295+
scp_cmd = ['scp'] + self.ssh_cmd + [f"{self.username}@{self.host}:{filename}", tmp_file.name]
292296
subprocess.run(scp_cmd, check=False) # The file might not exist yet
293297
tmp_file.seek(0, os.SEEK_END)
294298

@@ -304,12 +308,11 @@ def write(self, filename, data, truncate=False, binary=False, read_and_write=Fal
304308
tmp_file.write(data)
305309

306310
tmp_file.flush()
307-
308-
scp_cmd = ['scp', '-i', self.ssh_key, tmp_file.name, f"{self.username}@{self.host}:{filename}"]
311+
scp_cmd = ['scp'] + self.ssh_cmd + [tmp_file.name, f"{self.username}@{self.host}:{filename}"]
309312
subprocess.run(scp_cmd, check=True)
310313

311314
remote_directory = os.path.dirname(filename)
312-
mkdir_cmd = ['ssh', '-i', self.ssh_key, f"{self.username}@{self.host}", f"mkdir -p {remote_directory}"]
315+
mkdir_cmd = ['ssh'] + self.ssh_cmd + [f"{self.username}@{self.host}", f"mkdir -p {remote_directory}"]
313316
subprocess.run(mkdir_cmd, check=True)
314317

315318
os.remove(tmp_file.name)
@@ -374,7 +377,7 @@ def get_pid(self):
374377
return int(self.exec_command("echo $$", encoding=get_default_encoding()))
375378

376379
def get_process_children(self, pid):
377-
command = ["ssh", "-i", self.ssh_key, f"{self.username}@{self.host}", f"pgrep -P {pid}"]
380+
command = ["ssh"] + self.ssh_cmd + [f"{self.username}@{self.host}", f"pgrep -P {pid}"]
378381

379382
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
380383

testgres/utils.py

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@
44
from __future__ import print_function
55

66
import os
7-
import random
8-
import socket
97

108
import sys
119

1210
from contextlib import contextmanager
1311
from packaging.version import Version, InvalidVersion
1412
import re
1513

16-
from port_for import PortForException
1714
from six import iteritems
1815

16+
from helpers.port_manager import PortManager
1917
from .exceptions import ExecUtilException
2018
from .config import testgres_config as tconf
2119

@@ -40,49 +38,13 @@ def reserve_port():
4038
"""
4139
Generate a new port and add it to 'bound_ports'.
4240
"""
43-
port = select_random(exclude_ports=bound_ports)
41+
port_mng = PortManager()
42+
port = port_mng.find_free_port(exclude_ports=bound_ports)
4443
bound_ports.add(port)
4544

4645
return port
4746

4847

49-
def select_random(
50-
ports=None,
51-
exclude_ports=None,
52-
) -> int:
53-
"""
54-
Return random unused port number.
55-
Standard function from port_for does not work on Windows because of error
56-
'port_for.exceptions.PortForException: Can't select a port'
57-
We should update it.
58-
"""
59-
if ports is None:
60-
ports = set(range(1024, 65535))
61-
62-
if exclude_ports is None:
63-
exclude_ports = set()
64-
65-
ports.difference_update(set(exclude_ports))
66-
67-
sampled_ports = random.sample(tuple(ports), min(len(ports), 100))
68-
69-
for port in sampled_ports:
70-
if is_port_free(port):
71-
return port
72-
73-
raise PortForException("Can't select a port")
74-
75-
76-
def is_port_free(port: int) -> bool:
77-
"""Check if a port is free to use."""
78-
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
79-
try:
80-
s.bind(("", port))
81-
return True
82-
except OSError:
83-
return False
84-
85-
8648
def release_port(port):
8749
"""
8850
Free port provided by reserve_port().

tests/test_remote.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ class TestRemoteOperations:
1111

1212
@pytest.fixture(scope="function", autouse=True)
1313
def setup(self):
14-
conn_params = ConnectionParams(host=os.getenv('RDBMS_TESTPOOL1_HOST') or '172.18.0.3',
15-
username='dev',
16-
ssh_key=os.getenv(
17-
'RDBMS_TESTPOOL_SSHKEY') or '../../container_files/postgres/ssh/id_ed25519')
14+
conn_params = ConnectionParams(host=os.getenv('RDBMS_TESTPOOL1_HOST') or '127.0.0.1',
15+
username=os.getenv('USER'),
16+
ssh_key=os.getenv('RDBMS_TESTPOOL_SSHKEY'))
1817
self.operations = RemoteOperations(conn_params)
1918

2019
def test_exec_command_success(self):
@@ -41,7 +40,7 @@ def test_is_executable_true(self):
4140
"""
4241
Test is_executable for an existing executable.
4342
"""
44-
cmd = "postgres"
43+
cmd = os.getenv('PG_CONFIG')
4544
response = self.operations.is_executable(cmd)
4645

4746
assert response is True

tests/test_simple.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ def test_pgbench(self):
763763
out, _ = proc.communicate()
764764
out = out.decode('utf-8')
765765

766+
proc.stdout.close()
767+
766768
self.assertTrue('tps' in out)
767769

768770
def test_pg_config(self):

tests/test_simple_remote.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@
5252
from testgres.utils import PgVer
5353
from testgres.node import ProcessProxy, ConnectionParams
5454

55-
conn_params = ConnectionParams(host=os.getenv('RDBMS_TESTPOOL1_HOST') or '172.18.0.3',
56-
username='dev',
57-
ssh_key=os.getenv(
58-
'RDBMS_TESTPOOL_SSHKEY') or '../../container_files/postgres/ssh/id_ed25519')
55+
conn_params = ConnectionParams(host=os.getenv('RDBMS_TESTPOOL1_HOST') or '127.0.0.1',
56+
username=os.getenv('USER'),
57+
ssh_key=os.getenv('RDBMS_TESTPOOL_SSHKEY'))
5958
os_ops = RemoteOperations(conn_params)
6059
testgres_config.set_os_ops(os_ops=os_ops)
6160

0 commit comments

Comments
 (0)