X-Git-Url: http://git.efficios.com/?p=deliverable%2Flttng-ivc.git;a=blobdiff_plain;f=lttng_ivc%2Futils%2FProjectFactory.py;h=e50e290a2ef56dcdd62cf06643144d1610eadc13;hp=93b32c1dabf3e701c1fae36cc064c9965d25c87b;hb=fe7b987e59efd97e3f6b879cffa4a120dd469b49;hpb=de9b991ba1163882d83d4b60030014fedb8300cc diff --git a/lttng_ivc/utils/ProjectFactory.py b/lttng_ivc/utils/ProjectFactory.py index 93b32c1..e50e290 100644 --- a/lttng_ivc/utils/ProjectFactory.py +++ b/lttng_ivc/utils/ProjectFactory.py @@ -1,12 +1,13 @@ import os import logging import yaml +import pickle import lttng_ivc.utils.project as Project +import lttng_ivc.settings as Settings _logger = logging.getLogger('project.factory') -_conf_file = os.path.dirname(os.path.abspath(__file__)) + "/../run_configuration.yaml" _project_constructor = { 'babeltrace': Project.Babeltrace, 'lttng-modules': Project.Lttng_modules, @@ -14,14 +15,16 @@ _project_constructor = { 'lttng-ust': Project.Lttng_ust, } +__projects_cache = {} + _markers = None -with open(_conf_file, 'r') as stream: - # This is voluntary static across call, no need to perform this +with open(Settings.run_configuration_file, 'r') as stream: + # This is voluntary static across calls, no need to perform this # every time. _markers = yaml.load(stream) -def get(label, tmpdir): +def get_fresh(label, tmpdir): if label not in _markers: # TODO: specialized exception, handle it caller-side so the caller # can decide to skip or fail test. @@ -31,3 +34,77 @@ def get(label, tmpdir): path = marker['path'] sha1 = marker['sha1'] return constructor(label, path, sha1, tmpdir) + + +def _validate_pickle(pickle, label): + _logger.warn("Checking validate for {} {}".format(pickle, + label)) + if pickle.label != label: + _logger.warn("Label {} and {} are not the same".format(pickle.label, + label)) + return False + if pickle.sha1 != _markers[label]['sha1']: + _logger.warn("Sha1 {} and {} are not the same".format(pickle.sha1, + _markers[label]['sha1'])) + return False + + deps = _markers[label]['deps'] + if len(deps) != len(pickle.dependencies): + _logger.warn("Len {} and {} are not the same".format(len(deps), + len(pickle.dependencies))) + return False + for dep in deps: + if dep not in pickle.dependencies: + _logger.warn("Dep {} is not in {}".format(dep, + pickle.dependencies)) + return False + else: + _logger.debug("Calling validate {} {}".format(pickle.dependencies[dep], + dep)) + valid = _validate_pickle(pickle.dependencies[dep], dep) + if not valid: + return False + return True + + +def get_precook(label): + """ + Retrieve a precooked immutable projects from a cache if present + otherwise the project is built, installed and cached for future access. + """ + if label not in _markers: + # TODO: specialized exception, handle it caller-side so the caller + # can decide to skip or fail test. + raise Exception('Label is no present') + marker = _markers[label] + constructor = _project_constructor[marker['project']] + path = marker['path'] + sha1 = marker['sha1'] + deps = marker['deps'] + + # Cache path for the label + cache_path = os.path.join(Settings.projects_cache_folder, label) + pickle_path = os.path.join(cache_path, label+".pickle") + + # Check if Pickle Rick is present and valid. If so return it asap. + if os.path.exists(pickle_path): + with open(pickle_path, 'rb') as pickle_file: + pickled = pickle.load(pickle_file) + if _validate_pickle(pickled, label): + return pickled + else: + pickled.cleanup() + _logger.warn("Pickle for {} is invalid. Rebuilding".format(label)) + + project = constructor(label, path, sha1, cache_path) + + for dep in deps: + obj_dep = get_precook(dep) + project.dependencies[dep] = obj_dep + + project.autobuild() + project._immutable = True + with open(pickle_path, 'wb') as pickle_file: + pickle.dump(project, pickle_file) + + return project