import signal
import hashlib
+import os
+import time
+import socket
+
+from lxml import etree
+from contextlib import closing
+
def line_count(file_path):
line_count = 0
return sha256.hexdigest()
+# TODO: timeout as a parameter or Settings
+# TODO: Custom exception
+def wait_for_file(path):
+ i = 0
+ timeout = 60
+ while not os.path.exists(path):
+ time.sleep(1)
+ i = i + 1
+ if i > timeout:
+ raise Exception("File still does not exists. Timeout expired")
+
+
+# TODO: find better exception
+def create_empty_file(path):
+ if os.path.exists(path):
+ raise Exception("Path already exist")
+ open(path, 'w').close()
+
+
def __dummy_sigusr1_handler():
pass
-def sessiond_spawn(runtime):
- previous_handler = signal.signal(signal.SIGUSR1, __dummy_sigusr1_handler)
- sessiond = runtime.spawn_subprocess("lttng-sessiond -vvv -S")
- signal.sigtimedwait({signal.SIGUSR1}, 60)
- previous_handler = signal.signal(signal.SIGUSR1, previous_handler)
- return sessiond
+def sessiond_spawn(runtime, opt_args=""):
+ agent_port = find_free_port()
+ previous_handler = signal.signal(signal.SIGUSR1, __dummy_sigusr1_handler)
+ cmd = "lttng-sessiond -vvv --verbose-consumer -S --agent-tcp-port {}".format(agent_port)
+ cmd = " ".join([cmd, opt_args])
+ sessiond = runtime.spawn_subprocess(cmd)
+ signal.sigtimedwait({signal.SIGUSR1}, 60)
+ previous_handler = signal.signal(signal.SIGUSR1, previous_handler)
+ return sessiond
+
+
+def relayd_spawn(runtime, url="localhost"):
+ """
+ Return a tuple (relayd_uuid, ctrl_port, data_port, live_port)
+ """
+ ports = find_multiple_free_port(3)
+ data_port = ports.pop()
+ ctrl_port = ports.pop()
+ live_port = ports.pop()
+
+ base_cmd = "lttng-relayd -vvv"
+ data_string = "-D tcp://{}:{}".format(url, data_port)
+ ctrl_string = "-C tcp://{}:{}".format(url, ctrl_port)
+ live_string = "-L tcp://{}:{}".format(url, live_port)
+
+ cmd = " ".join([base_cmd, data_string, ctrl_string, live_string])
+ relayd = runtime.spawn_subprocess(cmd)
+
+ # Synchronization based on verbosity since no -S is available for
+ # lttng-relayd yet.
+ log_path = runtime.get_subprocess_stderr_path(relayd)
+
+ # TODO: Move to settings.
+ ready_cue = "Listener accepting live viewers connections"
+ # TODO: Move to settings.
+ timeout = 60
+ ready = False
+ for i in range(timeout):
+ if file_contains(log_path, ready_cue):
+ ready = True
+ break
+ time.sleep(1)
+
+ if not ready:
+ # Cleanup is performed by runtime
+ raise Exception("Relayd readyness timeout expired")
+
+ return (relayd, ctrl_port, data_port, live_port)
+
+
+def find_free_port():
+ # There is no guarantee that the port will be free at runtime but should be
+ # good enough
+ with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
+ s.bind(('', 0))
+ return s.getsockname()[1]
+
+
+def find_multiple_free_port(number):
+ """
+ Return a list of supposedly free port
+ """
+ assert(number >= 0)
+ ports = []
+ while(len(ports) != number):
+ port = find_free_port()
+ if port in ports:
+ continue
+ ports.append(port)
+ return ports
+
+
+def file_contains(file_path, list_of_string):
+ with open(file_path, 'r') as f:
+ for line in f:
+ for s in list_of_string:
+ if s in line:
+ return True
+
+
+def find_dir(root, name):
+ """
+ Returns the absolute path or None.
+ """
+ abs_path = None
+ for base, dirs, files in os.walk(root):
+ for tmp in dirs:
+ if tmp.endswith(name):
+ abs_path = os.path.abspath(os.path.join(base, tmp))
+ return abs_path
+
+
+def find_file(root, name):
+ """
+ Returns the absolute path or None.
+ """
+ abs_path = None
+ for base, dirs, files in os.walk(root):
+ for tmp in files:
+ if tmp.endswith(name):
+ abs_path = os.path.abspath(os.path.join(base, tmp))
+ return abs_path
+
+
+def validate(xml_path, xsd_path):
+
+ xmlschema_doc = etree.parse(xsd_path)
+ xmlschema = etree.XMLSchema(xmlschema_doc)
+
+ xml_doc = etree.parse(xml_path)
+ result = xmlschema.validate(xml_doc)
+
+ return result
+
+def xpath_query(xml_file, xpath):
+ """
+ Return a list of xml node corresponding to the xpath. The list can be of lenght
+ zero.
+ """
+ with open(xml_file, 'r') as f:
+ tree = etree.parse(f)
+ root = tree.getroot()
+ # Remove all namespace
+ # https://stackoverflow.com/questions/18159221/remove-namespace-and-prefix-from-xml-in-python-using-lxml
+ for elem in root.getiterator():
+ if not hasattr(elem.tag, 'find'):
+ continue
+ i = elem.tag.find('}')
+ if i >= 0:
+ elem.tag = elem.tag[i+1:]
+
+ return root.xpath(xpath)