import hashlib
import os
import time
+import socket
+
+from lxml import etree
+from contextlib import closing
+
def line_count(file_path):
line_count = 0
pass
-def sessiond_spawn(runtime):
+def sessiond_spawn(runtime, opt_args=""):
+ agent_port = find_free_port()
previous_handler = signal.signal(signal.SIGUSR1, __dummy_sigusr1_handler)
- sessiond = runtime.spawn_subprocess("lttng-sessiond -vvv -S")
+ 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(stderr_file, list_of_string):
- with open(stderr_file, 'r') as stderr:
- for line in stderr:
+
+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)