def prompt_gather(self, interface): # Resolve dependencies resolver = Resolver() for key in self._jobs.iterkeys(): depends = self._depends.get(key, []) resolver.add(key, *depends) # Build options options = {} for job in resolver.get_dependents(): suboptions = options dependencies = resolver.get_dependencies(job) for dependency in dependencies: suboptions = suboptions.setdefault(self._jobs[dependency], {}) # Build defaults defaults = self.persist.get("default") if defaults is None: defaults = copy.deepcopy(options) # Only prompt if not recovering if interface.direction == PREV or not self._recover: self._recover = False # Get results defaults = interface.show_tree(_("Select the suites to test"), options, defaults) self.persist.set("default", defaults) # Get tests to ignore def get_ignore_jobs(options, results): jobs = [] for k, v in options.iteritems(): if not v and k not in results: jobs.append(k) else: jobs.extend(get_ignore_jobs(options[k], results.get(k, {}))) return jobs ignore_jobs = get_ignore_jobs(options, defaults) self._manager.reactor.fire("ignore-jobs", ignore_jobs)
def prompt_gather(self, interface): # Resolve dependencies resolver = Resolver() for key in self._jobs.iterkeys(): depends = self._depends.get(key, []) resolver.add(key, *depends) # Build options options = {} for job in resolver.get_dependents(): suboptions = options dependencies = resolver.get_dependencies(job) for dependency in dependencies: value = self._statuses.get(dependency, {}) suboptions = suboptions.setdefault(self._jobs[dependency], value) # Build defaults defaults = self.persist.get("default") if defaults is None: defaults = copy.deepcopy(options) # Get results defaults = interface.show_tree(_("Select the suites to test"), options, defaults) self.persist.set("default", defaults) # Get tests to ignore def get_ignore_jobs(options, results): jobs = [] if isinstance(options,dict): for k, v in options.iteritems(): if v == UNINITIATED and k not in results: jobs.append(k) else: jobs.extend(get_ignore_jobs(options[k], results.get(k, {}))) return jobs ignore_jobs = get_ignore_jobs(options, defaults) self._manager.reactor.fire("ignore-jobs", ignore_jobs)
def test_dependents_two(self): resolver = Resolver() resolver.add('a') resolver.add('b', 'a') resolver.add('c', 'b') results = resolver.get_dependents('a') self.assertListEqual(results, ['b', 'c'])
def setUp(self): self.resolver = Resolver()
class ResolverTest(unittest.TestCase): def setUp(self): self.resolver = Resolver() def test_dependencies_none(self): try: self.resolver.get_dependencies('a') except Exception as error: self.assertTrue(error.args[0].startswith('no dependencies')) else: self.fail('non existing element accepted by resolver') def test_dependencies_one_level(self): self.resolver.add('a') results = self.resolver.get_dependencies('a') self.assertListEqual(results, ['a']) def test_dependencies_two_level(self): self.resolver.add('a') self.resolver.add('b', 'a') results = self.resolver.get_dependencies('b') self.assertListEqual(results, ['a', 'b']) def test_dependencies_multiple(self): self.resolver.add('a') # A appears as a dependency multiple times # in b and c, but isn't a circular dependency self.resolver.add('b', 'a') self.resolver.add('c', 'a', 'b') results = self.resolver.get_dependencies('c') self.assertListEqual(results, ['a', 'b', 'c']) def test_dependencies_circular(self): try: self.resolver.add('a', 'b') self.resolver.add('b', 'a') self.resolver.get_dependencies('a') except Exception as error: self.assertTrue(error.args[0].startswith('circular dependency')) else: self.fail('circular dependency not detected') def test_dependents_none(self): self.resolver.add('a') results = self.resolver.get_dependents('a') self.assertTrue(len(results) == 0) def test_dependents_one(self): self.resolver.add('a') self.resolver.add('b', 'a') results = self.resolver.get_dependents('a') self.assertListEqual(results, ['b']) def test_dependents_two(self): resolver = Resolver() resolver.add('a') resolver.add('b', 'a') resolver.add('c', 'b') results = resolver.get_dependents('a') self.assertListEqual(results, ['b', 'c']) def test_multiple_resolve_steps(self): self.resolver.add('a', 'b') results = self.resolver.get_dependents() self.assertListEqual(results, ['a']) self.resolver.add('b') results = self.resolver.get_dependents() self.assertListEqual(results, ['b', 'a'])
def gather(self): # Register temporary handler for report-message events messages = [] def report_message(message): if self.whitelist_patterns: name = message["name"] names = [name for p in self.whitelist_patterns if p.match(name)] if not names: return messages.append(message) # Set domain and message event handler old_domain = gettext.textdomain() gettext.textdomain(self.domain) event_id = self._manager.reactor.call_on( "report-message", report_message, 100) for directory in self.directories: self._manager.reactor.fire("message-directory", directory) for message in messages: self._manager.reactor.fire("report-job", message) # Unset domain and event handler self._manager.reactor.cancel_call(event_id) gettext.textdomain(old_domain) # Get unique messages from the now complete list messages = self.get_unique_messages(messages) # Apply whitelist ordering if self.whitelist_patterns: def key_function(obj): name = obj["name"] for pattern in self.whitelist_patterns: if pattern.match(name): return self.whitelist_patterns.index(pattern) messages = sorted(messages, key=key_function) if not self.check_ordered_messages(messages): #One of two things may have happened if we enter this code path. #Either the jobs are not in topological ordering, #Or they are in topological ordering but a dependency is #missing. old_message_names = [ message["name"] + "\n" for message in messages] resolver = Resolver(key_func=lambda m: m["name"]) for message in messages: resolver.add( message, *message.get("depends", [])) messages = resolver.get_dependents() if (self.whitelist_patterns and logging.getLogger().getEffectiveLevel() <= logging.DEBUG): new_message_names = [ message["name"] + "\n" for message in messages] #This will contain a report of out-of-order jobs. detailed_text = "".join( difflib.unified_diff( old_message_names, new_message_names, "old whitelist", "new whitelist")) #First, we report missing dependencies, if any. if self._missing_dependencies_report: primary = _("Dependencies are missing so some jobs " "will not run.") secondary = _("To fix this, close checkbox and add " "the missing dependencies to the " "whitelist.") self._manager.reactor.fire("prompt-warning", self.interface, primary, secondary, self._missing_dependencies_report) #If detailed_text is empty, it means the problem #was missing dependencies, which we already reported. #Otherwise, we also need to report reordered jobs here. if detailed_text: primary = _("Whitelist not topologically ordered") secondary = _("Jobs will be reordered to fix broken " "dependencies") self._manager.reactor.fire("prompt-warning", self.interface, primary, secondary, detailed_text) self._manager.reactor.fire("report-jobs", messages)
def prompt_gather(self, interface): # Resolve dependencies interface.show_progress_start(_("Gathering information from your system...")) resolver = Resolver() for key in self._jobs.keys(): depends = self._depends.get(key, []) resolver.add(key, *depends) # Build options options = {} self._manager.reactor.fire("expose-msgstore") offset = self.store.get_pending_offset() self.store.set_pending_offset(0) messages = self.store.get_pending_messages() self.store.add_pending_offset(offset) tests = dict([(m["name"], m) for m in messages if m.get("type") in ("test", "metric")]) def walk_dependencies(job, all_dependencies): for dependency in resolver.get_dependencies(job)[:-1]: walk_dependencies(dependency, all_dependencies) all_dependencies.append(job) for job in resolver.get_dependents(): suboptions = options dependencies = [] walk_dependencies(job, dependencies) for dependency in dependencies: if dependency in tests: value = tests[dependency]["status"] else: value = self._statuses.get(dependency, {}) suboptions = suboptions.setdefault(self._jobs[dependency], value) # Build defaults defaults = self.persist.get("default") if defaults is None: defaults = copy.deepcopy(options) # Get results interface.show_progress_stop() defaults = interface.show_tree( _("Choose tests to run on your system:"), options, defaults, self.deselect_warning) self.persist.set("default", defaults) # Get tests to ignore def get_ignore_jobs(options, results): jobs = [] if isinstance(options, dict): for k, v in options.items(): if v == UNINITIATED and k not in results: jobs.append(k) else: jobs.extend(get_ignore_jobs(options[k], results.get(k, {}))) return jobs ignore_jobs = get_ignore_jobs(options, defaults) self._manager.reactor.fire("ignore-jobs", ignore_jobs)
def prompt_gather(self, interface): # Resolve dependencies interface.show_progress_start( _("Gathering information from your system...")) resolver = Resolver() for key in self._jobs.keys(): depends = self._depends.get(key, []) resolver.add(key, *depends) # Build options options = {} self._manager.reactor.fire("expose-msgstore") offset = self.store.get_pending_offset() self.store.set_pending_offset(0) messages = self.store.get_pending_messages() self.store.add_pending_offset(offset) tests = dict([(m["name"], m) for m in messages if m.get("type") in ("test", "metric")]) def walk_dependencies(job, all_dependencies): for dependency in resolver.get_dependencies(job)[:-1]: walk_dependencies(dependency, all_dependencies) all_dependencies.append(job) for job in resolver.get_dependents(): suboptions = options dependencies = [] walk_dependencies(job, dependencies) for dependency in dependencies: if dependency in tests: value = tests[dependency]["status"] else: value = self._statuses.get(dependency, {}) suboptions = suboptions.setdefault(self._jobs[dependency], value) # Build defaults defaults = self.persist.get("default") if defaults is None: defaults = copy.deepcopy(options) # Get results interface.show_progress_stop() defaults = interface.show_tree( _("Choose tests to run on your system:"), options, defaults, self.deselect_warning) self.persist.set("default", defaults) # Get tests to ignore def get_ignore_jobs(options, results): jobs = [] if isinstance(options, dict): for k, v in options.items(): if v == UNINITIATED and k not in results: jobs.append(k) else: jobs.extend( get_ignore_jobs(options[k], results.get(k, {}))) return jobs ignore_jobs = get_ignore_jobs(options, defaults) self._manager.reactor.fire("ignore-jobs", ignore_jobs)
def gather(self): # Register temporary handler for report-message events messages = [] def report_message(message): if self.whitelist_patterns: name = message["name"] names = [ name for p in self.whitelist_patterns if p.match(name) ] if not names: return messages.append(message) # Set domain and message event handler old_domain = gettext.textdomain() gettext.textdomain(self.domain) event_id = self._manager.reactor.call_on("report-message", report_message, 100) for directory in self.directories: self._manager.reactor.fire("message-directory", directory) for message in messages: self._manager.reactor.fire("report-job", message) # Unset domain and event handler self._manager.reactor.cancel_call(event_id) gettext.textdomain(old_domain) # Get unique messages from the now complete list messages = self.get_unique_messages(messages) # Apply whitelist ordering if self.whitelist_patterns: def key_function(obj): name = obj["name"] for pattern in self.whitelist_patterns: if pattern.match(name): return self.whitelist_patterns.index(pattern) messages = sorted(messages, key=key_function) if not self.check_ordered_messages(messages): #One of two things may have happened if we enter this code path. #Either the jobs are not in topological ordering, #Or they are in topological ordering but a dependency is #missing. old_message_names = [ message["name"] + "\n" for message in messages ] resolver = Resolver(key_func=lambda m: m["name"]) for message in messages: resolver.add(message, *message.get("depends", [])) messages = resolver.get_dependents() if (self.whitelist_patterns and logging.getLogger().getEffectiveLevel() <= logging.DEBUG): new_message_names = [ message["name"] + "\n" for message in messages ] #This will contain a report of out-of-order jobs. detailed_text = "".join( difflib.unified_diff(old_message_names, new_message_names, "old whitelist", "new whitelist")) #First, we report missing dependencies, if any. if self._missing_dependencies_report: primary = _("Dependencies are missing so some jobs " "will not run.") secondary = _("To fix this, close checkbox and add " "the missing dependencies to the " "whitelist.") self._manager.reactor.fire( "prompt-warning", self.interface, primary, secondary, self._missing_dependencies_report) #If detailed_text is empty, it means the problem #was missing dependencies, which we already reported. #Otherwise, we also need to report reordered jobs here. if detailed_text: primary = _("Whitelist not topologically ordered") secondary = _("Jobs will be reordered to fix broken " "dependencies") self._manager.reactor.fire("prompt-warning", self.interface, primary, secondary, detailed_text) self._manager.reactor.fire("report-jobs", messages)