2025-08-12 18:39:24 +02:00

157 lines
5.5 KiB
Python

import subprocess
import time
import os
from robot.api.deco import keyword
import re
connector = None
class ConnectorLibrary:
def __init__(self):
self.process = None
def ctn_start_connector(self, command=["/usr/lib64/centreon-connector/centreon_connector_perl", "--log-file=/tmp/connector.log", "--debug"]):
if self.process is None or self.process.poll() is not None:
self.process = subprocess.Popen(
command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, # Capture stdout!
text=True
)
print("Connector started")
def ctn_send_to_connector(self, idf: int, command: str, timeout: int, command_log="/tmp/connector.commands.log"):
now = int(time.time())
# Log to console
print(f"[Connector] Sending command (id={idf}, timeout={timeout}): {command}")
# Log to file
try:
with open(command_log, "a") as logf:
logf.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} id={idf} timeout={timeout} command={command}\n")
except Exception as e:
print(f"[Connector] Could not write to command log file: {e}")
buf = bytearray()
buf.extend(b"2\0")
buf.extend(f"{idf}\0".encode('utf-8'))
buf.extend(f"{timeout}\0".encode('utf-8'))
buf.extend(f"{now}\0".encode('utf-8'))
buf.extend(f"{command}\0\0\0\0".encode('utf-8'))
if self.process and self.process.stdin:
self.process.stdin.write(buf.decode('utf-8'))
self.process.stdin.flush()
else:
raise RuntimeError("Connector is not running.")
def ctn_write_next_output_to_file(self, output_file="/tmp/connector.output"):
"""
Reads the next line from the connector's stdout and appends it to output_file.
"""
if self.process and self.process.stdout:
line = self.process.stdout.readline()
if line:
with open(output_file, "a") as f:
f.write(line)
return line
return None
def ctn_kill_connector(self):
if self.process:
self.process.terminate()
self.process = None
print("Connector stopped")
def ctn_wait_for_output_file(output_file="/tmp/connector.output", timeout=10, poll_interval=0.2):
end_time = time.time() + timeout
while time.time() < end_time:
if os.path.exists(output_file):
return True
time.sleep(poll_interval)
raise FileNotFoundError(f"Output file {output_file} not found after {timeout} seconds")
def ctn_start_connector():
global connector
connector = ConnectorLibrary()
connector.ctn_start_connector()
return connector
def ctn_kill_connector():
global connector
if connector:
connector.ctn_kill_connector()
connector = None
else:
print("No connector to stop.")
def ctn_send_to_connector(idf: int, command: str, timeout: int = 5, output_file=None, command_log="/tmp/connector.commands.log"):
global connector
if connector:
connector.ctn_send_to_connector(idf, command, timeout, command_log)
# Capture the output line after sending command
output_file = output_file or f"/tmp/connector.output.{idf}"
line = connector.ctn_write_next_output_to_file(output_file)
# Copy per-test file to common output
if output_file != "/tmp/connector.output":
import shutil
shutil.copyfile(output_file, "/tmp/connector.output")
return line # Return the actual line written!
else:
raise RuntimeError("Connector is not running.")
def ctn_clean_connector_output(line):
if not isinstance(line, str):
line = str(line)
line = line.strip()
print(f"CLEAN DEBUG RAW: {repr(line)}") # This will show hidden chars
idx = line.find("OK:")
if idx != -1:
cleaned = line[idx:]
else:
# Fallback to regex if 'OK:' not found
cleaned = re.sub(r"^[^\w]*", "", line)
print(f"CLEANED: {repr(cleaned)}")
return cleaned
@keyword
def ctn_extract_multiline_result_from_log(tc, log_path="/tmp/connector.log", output_path=None, timeout=10):
"""
Extracts multi-line result for check ID from log, waits up to `timeout` seconds.
"""
import re
deadline = time.time() + timeout
result_lines = []
while time.time() < deadline:
with open(log_path, 'r') as f:
lines = f.readlines()
result_lines.clear()
in_result = False
for line in lines:
if not in_result:
m = re.search(r'reporting check result #(\d+) check:' + str(tc) + ' .*output:(.*)', line)
if m:
result_lines.append(m.group(2).strip())
in_result = True
else:
if line.strip().startswith("error:") or re.match(r"^\d+ \[20.*", line):
break
result_lines.append(line.strip())
if result_lines:
output_path = output_path or f"/tmp/connector.output.{tc}"
with open(output_path, 'w') as out:
out.write('\n'.join(result_lines))
if output_path != "/tmp/connector.output":
import shutil
shutil.copyfile(output_path, "/tmp/connector.output")
return '\n'.join(result_lines)
time.sleep(0.2) # wait before retry
raise Exception(f"No result found for id {tc} in log {log_path} after {timeout}s")