-
Notifications
You must be signed in to change notification settings - Fork 138
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: James <[email protected]>
- Loading branch information
Showing
2 changed files
with
72 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,92 @@ | ||
import platform | ||
import select | ||
import subprocess | ||
import time | ||
from typing import List | ||
import threading | ||
import queue | ||
|
||
# You might want to change the path of the executable based on your build directory | ||
executable_windows_path = "build\\Debug\\cortex-cpp.exe" | ||
executable_unix_path = "build/cortex-cpp" | ||
|
||
def run(name: str, arguments: List[str]): | ||
# Timeout | ||
timeout = 5 # secs | ||
|
||
# Get the executable path based on the platform | ||
def getExecutablePath() -> str: | ||
if platform.system() == "Windows": | ||
executable = "build\\cortex-cpp.exe" | ||
else: | ||
executable = "build/cortex-cpp" | ||
print("Command name", name) | ||
print("Running command: ", [executable] + arguments) | ||
if len(arguments) == 0: | ||
result = subprocess.run(executable, capture_output=True, text=True, timeout=5) | ||
return executable_windows_path | ||
else: | ||
result = subprocess.run( | ||
[executable] + arguments, capture_output=True, text=True, timeout=5 | ||
) | ||
return result.returncode, result.stdout, result.stderr | ||
return executable_unix_path | ||
|
||
# Execute a command | ||
def run(test_name: str, arguments: List[str]): | ||
executable_path = getExecutablePath() | ||
print("Running:", test_name) | ||
print("Command:", [executable_path] + arguments) | ||
|
||
def start_server(timeout=5): | ||
if platform.system() == "Windows": | ||
executable = "build\\cortex-cpp.exe" | ||
else: | ||
executable = "build/cortex-cpp" | ||
result = subprocess.run([executable_path] + arguments, capture_output=True, text=True, timeout=timeout) | ||
return result.returncode, result.stdout, result.stderr | ||
|
||
# Start the API server | ||
# Wait for `Server started` message or failed | ||
def start_server() -> bool: | ||
executable = getExecutablePath() | ||
process = subprocess.Popen( | ||
executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True | ||
executable, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1, universal_newlines=True | ||
) | ||
|
||
success_message = "Server started" | ||
|
||
q_out = queue.Queue() | ||
q_err = queue.Queue() | ||
|
||
def enqueue_output(out, queue): | ||
for line in iter(out.readline, b''): | ||
queue.put(line) | ||
out.close() | ||
|
||
# Start threads to read stdout and stderr | ||
t_out = threading.Thread(target=enqueue_output, args=(process.stdout, q_out)) | ||
t_err = threading.Thread(target=enqueue_output, args=(process.stderr, q_err)) | ||
t_out.daemon = True | ||
t_err.daemon = True | ||
t_out.start() | ||
t_err.start() | ||
|
||
# only wait for defined timeout | ||
start_time = time.time() | ||
while time.time() - start_time < timeout: | ||
# Use select to check if there's data to read from stdout or stderr | ||
readable, _, _ = select.select([process.stdout, process.stderr], [], [], 0.1) | ||
|
||
for stream in readable: | ||
line = stream.readline() | ||
if line: | ||
print(line.strip()) # Print output for debugging | ||
if success_message in line: | ||
# have to wait a bit for server to really up and accept connection | ||
time.sleep(0.3) | ||
return True, process # Success condition met | ||
# Check stdout | ||
try: | ||
line = q_out.get_nowait() | ||
except queue.Empty: | ||
pass | ||
else: | ||
print(f"STDOUT: {line.strip()}") | ||
if success_message in line: | ||
return True | ||
|
||
# Check stderr | ||
try: | ||
line = q_err.get_nowait() | ||
except queue.Empty: | ||
pass | ||
else: | ||
print(f"STDERR: {line.strip()}") | ||
if success_message in line: | ||
# found the message. let's wait for some time for the server successfully started | ||
time.sleep(0.3) | ||
return True, process | ||
|
||
# Check if the process has ended | ||
if process.poll() is not None: | ||
return False, process # Process ended without success message | ||
|
||
return False, process # Timeout reached | ||
return False | ||
|
||
time.sleep(0.1) | ||
|
||
return False | ||
|
||
# Stop the API server | ||
def stop_server(): | ||
run("Stop server", ["stop"]) |