Multiple framework fixes
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Tue, 24 Oct 2017 14:49:43 +0000 (10:49 -0400)
committerJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Tue, 24 Oct 2017 14:49:43 +0000 (10:49 -0400)
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
lttng_ivc/config.yaml
lttng_ivc/settings.py
lttng_ivc/tests/ust_soname_vs_tools/test_ust_so_name_vs_tools.py
lttng_ivc/utils/ProjectFactory.py
lttng_ivc/utils/project.py
lttng_ivc/utils/runtime.py

index bc0281bc050aa69a75c943966d8ebddd60e90334..a70a15639ca97bb22cb4641087607418d10ee2be 100644 (file)
@@ -2,23 +2,51 @@ lttng-tools:
         - marker: lttng-tools-2.7
           url: https://github.com/lttng/lttng-tools
           ref: stable-2.7
+          precook_deps: [lttng-ust-2.7]
         - marker: lttng-tools-2.8
           url: https://github.com/lttng/lttng-tools
           ref: stable-2.8
+          precook_deps: [lttng-ust-2.8]
+        - marker: lttng-tools-2.9
+          url: https://github.com/lttng/lttng-tools
+          ref: stable-2.9
+          precook_deps: [lttng-ust-2.9]
+        - marker: lttng-tools-2.10
+          url: https://github.com/lttng/lttng-tools
+          ref: stable-2.10
+          precook_deps: [lttng-ust-2.10]
 lttng-ust:
         - marker: lttng-ust-2.7
           url: https://github.com/lttng/lttng-ust
           ref: stable-2.7
+        - marker: lttng-ust-2.8
+          url: https://github.com/lttng/lttng-ust
+          ref: stable-2.8
+        - marker: lttng-ust-2.9
+          url: https://github.com/lttng/lttng-ust
+          ref: stable-2.9
         - marker: lttng-ust-2.10
           url: https://github.com/lttng/lttng-ust
-          ref: stable-2.7
+          ref: stable-2.10
 
 lttng-modules:
         - marker: lttng-modules-2.7
           url: https://github.com/lttng/lttng-modules
           ref: stable-2.7
+        - marker: lttng-modules-2.8
+          url: https://github.com/lttng/lttng-modules
+          ref: stable-2.8
+        - marker: lttng-modules-2.9
+          url: https://github.com/lttng/lttng-modules
+          ref: stable-2.9
+        - marker: lttng-modules-2.10
+          url: https://github.com/lttng/lttng-modules
+          ref: stable-2.10
 
 babeltrace:
+        - marker: babeltrace-1.5
+          url: https://github.com/efficios/babeltrace
+          ref: stable-1.5
         - marker: babeltrace-master
           url: https://github.com/efficios/babeltrace
           ref: master
index 3a67f5a663960ab2bb0cc4fa4f037e59bb5d5293..a2a1b2fb7897e4837ed679293b72a9d57beb9597 100644 (file)
@@ -1,10 +1,17 @@
 # All tests are run if empty
 import os
 
-test_only = {"lttng-ust-2.7"}
+test_only = {}
 
 configuration_file = os.path.dirname(os.path.abspath(__file__)) + "/config.yaml"
 run_configuration_file = os.path.dirname(os.path.abspath(__file__)) + "/run_configuration.yaml"
 
 projects_cache_folder = os.path.dirname(os.path.abspath(__file__)) + "/runtime/projects_cache"
 git_remote_folder = os.path.dirname(os.path.abspath(__file__)) + "/runtime/git_remote"
+app_folder = os.path.dirname(os.path.abspath(__file__)) + "/runtime/git_remote"
+apps_folder = os.path.dirname(os.path.abspath(__file__)) + "/apps"
+apps_gen_events_folder = os.path.join(apps_folder, "gen_ust_events")
+
+tmp_object_prefix = "lttng-ivc-"
+
+default_babeltrace = "babeltrace-1.5"
index fbb2a1396d53e4377a6b3cdf058a718d7acec288..5e06fd629ced45eaa75d9d73a9434accd0a2a7c5 100644 (file)
@@ -74,8 +74,8 @@ else:
 
 @pytest.mark.parametrize("ust_label,tools_label,base_tools_ust_dep,should_pass", runtime_matrix_label)
 def test_soname_configure(tmpdir, ust_label, tools_label, base_tools_ust_dep, should_pass):
-    ust = ProjectFactory.get(ust_label, str(tmpdir.mkdir("lttng-ust")))
-    tools = ProjectFactory.get(tools_label, str(tmpdir.mkdir("lttng-tools")))
+    ust = ProjectFactory.get_fresh(ust_label, str(tmpdir.mkdir("lttng-ust")))
+    tools = ProjectFactory.get_fresh(tools_label, str(tmpdir.mkdir("lttng-tools")))
 
     ust.autobuild()
 
index e50e290a2ef56dcdd62cf06643144d1610eadc13..5daba558e17006ec24e512f6a600d6b3c667231b 100644 (file)
@@ -37,7 +37,7 @@ def get_fresh(label, tmpdir):
 
 
 def _validate_pickle(pickle, label):
-    _logger.warn("Checking validate for {} {}".format(pickle,
+    _logger.debug("Checking validate for {} {}".format(pickle,
         label))
     if pickle.label != label:
         _logger.warn("Label  {} and {} are not the same".format(pickle.label,
index 50df68796cdcd0d646c00232f6f3e979517852dc..7e9957113502fda537d2cc1115c979148e56188b 100644 (file)
@@ -19,6 +19,7 @@ class Project(object):
         if ccache is not None:
             self.custom_configure_flags.append("CC={} gcc".format(ccache))
             self.custom_configure_flags.append("CXX={} g++".format(ccache))
+        self.custom_configure_flags.append("CFLAGS=-g -O0".format(ccache))
 
         """ A collection of Project dependencies """
         self.dependencies = {}
@@ -34,6 +35,10 @@ class Project(object):
         self.source_path = os.path.join(tmpdir, "source")
         self.installation_path = os.path.join(tmpdir, "install")
 
+        if os.path.isdir(self.basedir):
+            # Perform cleanup since it should not happen
+            shutil.rmtree(self.basedir)
+
         os.makedirs(self.log_path)
         os.makedirs(self.source_path)
         os.makedirs(self.installation_path)
@@ -130,12 +135,26 @@ class Project(object):
         if self.isConfigured ^ self.isBuilt ^ self.isInstalled:
             raise Exception("Project steps where manually triggered. Can't autobuild")
 
-        _logger.debug("% Autobuild configure", self.label)
-        self.configure()
-        _logger.debug("% Autobuild build", self.label)
-        self.build()
-        _logger.debug("% Autobuild install", self.label)
-        self.install()
+        _logger.debug("{} Autobuild configure".format(self.label))
+        try:
+            self.configure()
+        except subprocess.CalledProcessError as e:
+            _logger.error("{} Configure failed. See {} for more details.".format(self.label, self.log_path))
+            raise e
+
+        _logger.debug("{} Autobuild build".format(self.label))
+        try:
+            self.build()
+        except subprocess.CalledProcessError as e:
+            _logger.error("{} Build failed. See {} for more details.".format(self.label, self.log_path))
+            raise e
+
+        _logger.debug("{} Autobuild install".format(self.label))
+        try:
+            self.install()
+        except subprocess.CalledProcessError as e:
+            _logger.error("{} Install failed. See {} for more details.".format(self.label, self.log_path))
+            raise e
 
     def checkout(self):
         if self._immutable:
@@ -209,13 +228,13 @@ class Project(object):
         os.chdir(self.source_path)
         args = ['make']
         env = self.get_env()
-        env['CFLAGS'] = '-g -O0'
 
         # Number of usable cpu
         # https://docs.python.org/3/library/os.html#os.cpu_count
         num_cpu = str(len(os.sched_getaffinity(0)))
         args.append('-j')
         args.append(num_cpu)
+        args.append('V=1')
 
         # TODO: log output and add INFO log point with args
         with open(out, 'w') as stdout, open(err, 'w') as stderr:
@@ -233,8 +252,8 @@ class Project(object):
         if self._immutable:
             raise Exception("Object is immutable. Illegal install")
 
-        out = os.path.join(self.log_path, "build.out")
-        err = os.path.join(self.log_path, "build.err")
+        out = os.path.join(self.log_path, "install.out")
+        err = os.path.join(self.log_path, "install.err")
 
         os.chdir(self.source_path)
         args = ['make', 'install']
@@ -255,6 +274,11 @@ class Project(object):
 
 
 class Lttng_modules(Project):
+    def __init__(self, label, git_path, sha1, tmpdir):
+        super(Lttng_modules, self).__init__(label=label, git_path=git_path,
+                                            sha1=sha1, tmpdir=tmpdir)
+        self.add_special_env_variable("MODPROBE_OPTIONS","-b {}".format(self.installation_path))
+
     def bootstrap(self):
         pass
 
index 1bd8cbf6dbe1abb1c790d8b62ff83b1f0036bbb9..c2d0b8397299b5f0453bcb2550873e108aee28ea 100644 (file)
@@ -1,12 +1,29 @@
 import os
+import sys
 import shlex
 import subprocess
 import uuid
 import logging
+import shutil
+import contextlib
+import pprint
+import traceback
 
+from tempfile import TemporaryDirectory
+
+import lttng_ivc.settings as Settings
 _logger = logging.getLogger("Runtime")
 
 
+@contextlib.contextmanager
+def get_runtime(runtime_dir):
+    runtime = Runtime(runtime_dir)
+    try:
+        yield runtime
+    finally:
+        runtime.close()
+
+
 class Runtime(object):
     def __init__(self, runtime_dir):
         """
@@ -20,16 +37,32 @@ class Runtime(object):
         self.__runtime_log = os.path.join(runtime_dir, "log")
         self.__runtime_log_sub = os.path.join(self.__runtime_log, "subprocess")
 
+        """
+        Path of the copy of lttng_home folder after Runtime.close() is issued. This is
+        to be used for post runtime analysis and mostly debugging on error.
+        """
+        self.__post_runtime_lttng_home_path = os.path.join(runtime_dir,
+                "lttng_home")
+
         self._runtime_log_aggregation = os.path.join(self.__runtime_log, "runtime.log")
 
         self._run_command_count = 0
 
-        self.lttng_home = os.path.join(runtime_dir, "lttng_home")
+        self.special_env_variables = {"LTTNG_UST_DEBUG": "1",
+                                      #"LTTNG_APP_SOCKET_TIMEOUT": "-1",
+                                      #"LTTNG_UST_REGISTER_TIMEOUT": "-1",
+                                      "LTTNG_NETWORK_SOCKET_TIMEOUT": "-1"}
 
-        # TODO move exist_ok to false !!!! ONLY for testing
-        os.makedirs(self.__runtime_log, exist_ok=True)
-        os.makedirs(self.__runtime_log_sub, exist_ok=True)
-        os.makedirs(self.lttng_home, exist_ok=True)
+        # Keep a reference on the object to keep it alive. It will close/clean on
+        # exit.
+        self.__lttng_home_dir = TemporaryDirectory(prefix=Settings.tmp_object_prefix)
+        self.lttng_home = self.__lttng_home_dir.name
+
+        if len(self.lttng_home) > 88:
+            raise Exception("TemporaryDirectory for lttng_home is to long. Use a short TMPDIR")
+
+        os.makedirs(self.__runtime_log)
+        os.makedirs(self.__runtime_log_sub)
 
     def add_project(self, project):
         self.__projects.append(project)
@@ -44,6 +77,7 @@ class Runtime(object):
         stdout, stderr = self.__stdout_stderr[subprocess_uuid]
         stdout.close()
         stderr.close()
+        return process
 
     def subprocess_kill(self, subprocess_uuid):
         process = self.__subprocess[subprocess_uuid]
@@ -52,6 +86,7 @@ class Runtime(object):
         stdout, stderr = self.__stdout_stderr[subprocess_uuid]
         stdout.close()
         stderr.close()
+        return process
 
     def get_subprocess_stdout_path(self, subprocess_uuid):
         stdout, stderr = self.__stdout_stderr[subprocess_uuid]
@@ -61,22 +96,31 @@ class Runtime(object):
         stdout, stderr = self.__stdout_stderr[subprocess_uuid]
         return stderr.name
 
-    def spawn_subprocess(self, command_line):
+    def spawn_subprocess(self, command_line, cwd=None):
         args = shlex.split(command_line)
         env = self.get_env()
 
+        if not os.path.isdir(self.lttng_home):
+            raise Exception("lttng home does not exist")
+
         tmp_id = uuid.uuid1()
         out_path = os.path.join(self.__runtime_log_sub, str(tmp_id) + ".out")
         err_path = os.path.join(self.__runtime_log_sub, str(tmp_id) + ".err")
-        stdout = open(out_path, "w")
-        stderr = open(err_path, "w")
+
+        stdout = open(out_path, 'w')
+        stderr = open(err_path, 'w')
+
+        env_path = os.path.join(self.__runtime_log_sub, str(tmp_id) + ".env")
+        with open(env_path, 'w') as env_out:
+            pprint.pprint(env, stream=env_out)
 
         p = subprocess.Popen(args, stdout=stdout, stderr=stderr, env=env)
         self.__subprocess[tmp_id] = p
         self.__stdout_stderr[tmp_id] = (stdout, stderr)
         _logger.debug("Spawned sub pid: {} args: {} stdout: {} stderr{}".format(p.pid, p.args, out_path, err_path))
+        return tmp_id
 
-    def run(self, command_line):
+    def run(self, command_line, cwd=None, check_return=True):
         """
         Run the command and return a tuple of a (CompletedProcess, stdout_path,
         stderr_path). The subprocess is already executed and returned. The
@@ -88,35 +132,38 @@ class Runtime(object):
         tmp_id = self._run_command_count
         self._run_command_count += 1
 
+        cmd_map = os.path.join(self.__runtime_log, "cmd.map")
+        with open(cmd_map, 'a') as out:
+            out.write("{}: {}\n".format(tmp_id, args))
+
         out_path = os.path.join(self.__runtime_log, str(tmp_id) + ".out")
         err_path = os.path.join(self.__runtime_log, str(tmp_id) + ".err")
         stdout = open(out_path, "w")
         stderr = open(err_path, "w")
 
-        stdout.write("Output for command #{} {}\n".format(tmp_id, command_line))
-        stdout.write("Start >>>>>>>>>>>>>>>>\n")
-        stdout.flush()
-
-        stderr.write("Output for command #{} {}\n".format(tmp_id, command_line))
-        stderr.write("Start >>>>>>>>>>>>>>>>\n")
-        stderr.flush()
+        env_path = os.path.join(self.__runtime_log, str(tmp_id) + ".env")
+        with open(env_path, 'w') as env_out:
+            pprint.pprint(env, stream=env_out)
 
-        cp = subprocess.run(args, stdout=stdout, stderr=stderr, env=env)
+        cp = subprocess.run(args, stdout=stdout, stderr=stderr, env=env, cwd=cwd)
         _logger.debug("Command #{} args: {} stdout: {} stderr{}".format(tmp_id, cp.args, out_path, err_path))
 
-        stdout.write("End <<<<<<<<<<<<<<<<\n")
-        stdout.close()
-
-        stderr.write("End <<<<<<<<<<<<<<<<\n")
-        stderr.close()
-
         # Add to the global log file. This can help a little. Leave the other
         # file available for per-run analysis
         with open(self._runtime_log_aggregation, "a") as log:
             with open(out_path, "r") as out:
+                log.write("Output for command #{} {}\n".format(tmp_id, command_line))
+                log.write("Start >>>>>>>>>>>>>>>>\n")
                 log.write(out.read())
+                log.write("End <<<<<<<<<<<<<<<<\n")
             with open(err_path, "r") as out:
+                log.write("Error for command #{} {}\n".format(tmp_id, command_line))
+                log.write("Start >>>>>>>>>>>>>>>>\n")
                 log.write(out.read())
+                log.write("End <<<<<<<<<<<<<<<<\n")
+
+        if check_return:
+            cp.check_returncode()
 
         return (cp, out_path, err_path)
 
@@ -151,7 +198,7 @@ class Runtime(object):
 
         env_fetch = {"CPPFLAGS": (self.get_cppflags(), " "),
                      "LDFLAGS": (self.get_ldflags(), " "),
-                     "LD_LIRABRY_PATH": (self.get_ld_library_path(), ":"),
+                     "LD_LIBRARY_PATH": (self.get_ld_library_path(), ":"),
                      "PATH": (self.get_bin_path(), ":"),
                      }
         for key, (value, delimiter) in env_fetch.items():
@@ -160,6 +207,15 @@ class Runtime(object):
                 tmp_var = env[key]
             env[key] = delimiter.join([value, tmp_var])
 
+        for var, value in self.special_env_variables.items():
+            if var in env:
+                # Raise for now since no special cases is known
+                _logger.warning("% Special var % is already defined",
+                                self.label, var)
+                raise Exception("Multiple definition of a special environment variable")
+            else:
+                env[var] = value
+
         for project in self.__projects:
             for var, value in project.special_env_variables.items():
                 if var in env:
@@ -175,13 +231,13 @@ class Runtime(object):
         for key, subp in self.__subprocess.items():
             subp.terminate()
         for key, subp in self.__subprocess.items():
-            try:
-                # TODO move timeout to settings
-                subp.wait(timeout=60)
-            except subprocess.TimeoutExpired as e:
-                # Force a little bit
-                subp.kill()
-                subp.wait()
+            # TODO move timeout to settings
+            subp.wait(timeout=60)
         for key, (stdout, stderr) in self.__stdout_stderr.items():
             stdout.close()
             stderr.close()
+
+        # Copy the lttng_home used at runtime using hardlink to prevent useless
+        # data duplication
+        shutil.copytree(self.lttng_home, self.__post_runtime_lttng_home_path, copy_function=os.link)
+
This page took 0.02953 seconds and 5 git commands to generate.