Skip to content

Commit

Permalink
Merging pull request 132
Browse files Browse the repository at this point in the history
Signed-off-by: Lukáš Doktor <[email protected]>

* github.com:autotest/aexpect:
  fix: Ensure self.tail_thread to be set before add_close_hook
  fix: Raise error when aexpect_helper doesn't work properly
  • Loading branch information
ldoktor committed Aug 2, 2024
2 parents 4e5ac96 + 4699c57 commit 33fd20e
Showing 1 changed file with 51 additions and 19 deletions.
70 changes: 51 additions & 19 deletions aexpect/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,24 +178,8 @@ def __init__(self, command=None, a_id=None, auto_close=False, echo=False,
# Start the server (which runs the command)
if command:
helper_cmd = utils_path.find_command('aexpect_helper')
self._aexpect_helper = subprocess.Popen([helper_cmd], # pylint: disable=R1732
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
pass_fds=pass_fds)
sub = self._aexpect_helper
# Send parameters to the server
sub.stdin.write(f"{self.a_id}\n".encode(self.encoding))
sub.stdin.write(f"{echo}\n".encode(self.encoding))
readers = ",".join(self.readers)
sub.stdin.write(f"{readers}\n".encode(self.encoding))
sub.stdin.write(f"{command}\n".encode(self.encoding))
sub.stdin.flush()
# Wait for the server to complete its initialization
while (f"Server {self.a_id} ready" not in
sub.stdout.readline().decode(self.encoding, "ignore")):
pass
self._aexpect_helper = self._get_aexpect_helper(
helper_cmd, pass_fds, echo, command)

# Open the reading pipes
if is_file_locked(self.lock_server_running_filename):
Expand Down Expand Up @@ -232,6 +216,54 @@ def __del__(self):
if self.auto_close:
self.close()

def _get_aexpect_helper(self, helper_cmd, pass_fds, echo, command):
"""
Start the aexpect_helper server, send the command and wait for the server to
complete its initialization.
:param helper_cmd: The aexpect_helper command location.
:param pass_fds: Optional sequence of file descriptors to keep open
between the parent and child.
:param echo: Boolean indicating whether echo should be initially
enabled for the pseudo terminal running the subprocess. This
parameter has an effect only when starting a new server.
:param command: Command to run, or None if accessing an already running
server.
:returns: The aexpect_helper process object
:raise ExpectTimeoutError: Raised if timeout expires
:raise ExpectProcessTerminatedError: Raised if the child process
terminates while waiting for output
"""
sub = subprocess.Popen([helper_cmd], # pylint: disable=R1732
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
pass_fds=pass_fds)
# Send parameters to the server
sub.stdin.write(f"{self.a_id}\n".encode(self.encoding))
sub.stdin.write(f"{echo}\n".encode(self.encoding))
readers = ",".join(self.readers)
sub.stdin.write(f"{readers}\n".encode(self.encoding))
sub.stdin.write(f"{command}\n".encode(self.encoding))
sub.stdin.flush()
# Wait for the server to complete its initialization
full_output = ""
pattern = f"Server {self.a_id} ready"
end_time = time.time() + 60
while time.time() < end_time:
output = sub.stdout.readline().decode(self.encoding, "ignore")
if pattern in output:
break
full_output += output
sub_status = sub.poll()
if sub_status is not None:
raise ExpectProcessTerminatedError(pattern, sub_status, full_output)
else:
raise ExpectTimeoutError(pattern, full_output)
return sub

def _add_reader(self, reader):
"""
Add a reader whose file descriptor can be obtained with _get_fd().
Expand Down Expand Up @@ -522,6 +554,7 @@ def __init__(self, command=None, a_id=None, auto_close=False, echo=False,
:param encoding: Override text encoding (by default: autodetect by
locale.getpreferredencoding())
"""
self.tail_thread = None
# Add a reader and a close hook
self._add_reader("tail")
self._add_close_hook(Tail._join_thread)
Expand All @@ -542,7 +575,6 @@ def __init__(self, command=None, a_id=None, auto_close=False, echo=False,
self.output_prefix = output_prefix

# Start the thread in the background
self.tail_thread = None
if self.is_alive():
if termination_func or output_func:
self._start_thread()
Expand Down

0 comments on commit 33fd20e

Please sign in to comment.