示例#1
0
    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)
示例#2
0
    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)
示例#3
0
    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'])
示例#4
0
 def setUp(self):
     self.resolver = Resolver()
示例#5
0
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'])
示例#6
0
    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)
示例#7
0
    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)
示例#8
0
    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)
示例#9
0
    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)