Esempio n. 1
0
    def _get_product_info(self, product, href, resource, max_):
        penv = ProductEnvironment(self.env, product.prefix)
        results = []

        # some queries return a list/tuple, some a generator,
        # hence count() to get the result length
        def count(iter_):
            try:
                return len(iter_)
            except TypeError:
                return sum(1 for _ in iter_)

        query = resource['type'].select(penv)
        for q in itertools.islice(query, max_):
            q.url = href(resource['name'], q.name) \
                if resource.get('hrefurl') \
                else Query.from_string(penv,
                    '%s=%s&%s&col=%s' % (resource['name'], q.name,
                                         self.COMMON_QUERY, resource['name'])
            ).get_href(href)
            q.ticket_count = penv.db_query("""
                SELECT COUNT(*) FROM ticket WHERE ticket.%s='%s'
                AND ticket.status <> 'closed'
                """ % (resource['name'], q.name))[0][0]

            results.append(q)

        # add a '(No <milestone/component/version>)' entry if there are
        # tickets without an assigned resource in the product
        ticket_count = penv.db_query(
            """SELECT COUNT(*) FROM ticket WHERE %s=''
               AND status <> 'closed'""" % (resource['name'],))[0][0]
        if ticket_count != 0:
            q = resource['type'](penv)
            q.name = '(No %s)' % (resource['name'],)
            q.url = Query.from_string(penv,
               'status=!closed&col=id&col=summary&col=owner'
               '&col=status&col=priority&order=priority&%s='
               % (resource['name'],)
            ).get_href(href)
            q.ticket_count = ticket_count
            results.append(q)

        results.sort(key=lambda x: x.ticket_count, reverse=True)

        # add a link to the resource list if there are
        # more than max resources defined
        if count(query) > max_:
            q = resource['type'](penv)
            q.name = _('... more')
            q.ticket_count = None
            q.url = href(resource['name']) if resource.get('hrefurl') \
                else href.dashboard()
            results.append(q)

        return results
Esempio n. 2
0
class ProductMilestoneTestCase(MilestoneTestCase, MultiproductTestCase):
    def setUp(self):
        self.global_env = self._setup_test_env(create_folder=True)
        self._upgrade_mp(self.global_env)
        self._setup_test_log(self.global_env)
        self._load_product_from_data(self.global_env, self.default_product)

        self.env = ProductEnvironment(self.global_env, self.default_product)
        self._load_default_data(self.env)

    def tearDown(self):
        shutil.rmtree(self.global_env.path)
        self.global_env.reset_db()
        self.env = self.global_env = None

    def test_update_milestone(self):

        self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')")

        milestone = Milestone(self.env, 'Test')
        t1 = datetime(2001, 01, 01, tzinfo=utc)
        t2 = datetime(2002, 02, 02, tzinfo=utc)
        milestone.due = t1
        milestone.completed = t2
        milestone.description = 'Foo bar'
        milestone.update()

        self.assertEqual(
            [('Test', to_utimestamp(t1), to_utimestamp(t2), 'Foo bar', 
                    self.default_product)],
            self.env.db_query("SELECT * FROM milestone WHERE name='Test'"))
Esempio n. 3
0
class ProductMilestoneTestCase(MilestoneTestCase, MultiproductTestCase):
    def setUp(self):
        self.global_env = self._setup_test_env(create_folder=True)
        self._upgrade_mp(self.global_env)
        self._setup_test_log(self.global_env)
        self._load_product_from_data(self.global_env, self.default_product)

        self.env = ProductEnvironment(self.global_env, self.default_product)
        self._load_default_data(self.env)

    def tearDown(self):
        shutil.rmtree(self.global_env.path)
        self.global_env.reset_db()
        self.env = self.global_env = None

    @unittest.skipUnless(threading, 'Threading required for test')
    def test_milestone_threads(self):
        """ Ensure that in threaded (e.g. mod_wsgi) situations, we get
        an accurate list of milestones from Milestone.list

        The basic strategy is:
            thread-1 requests a list of milestones
            thread-2 adds a milestone
            thread-1 requests a new list of milestones
        To pass, thread-1 should have a list of milestones that matches
        those that are in the database.
        """
        lock = threading.RLock()
        results = []
        # two events to coordinate the workers and ensure that the threads
        # alternate appropriately
        e1 = threading.Event()
        e2 = threading.Event()

        def task(add):
            """the thread task - either we are discovering or adding events"""
            with lock:
                env = ProductEnvironment(self.global_env, self.default_product)
                if add:
                    name = 'milestone_from_' + threading.current_thread().name
                    milestone = Milestone(env)
                    milestone.name = name
                    milestone.insert()
                else:
                    # collect the names of milestones reported by Milestone and
                    # directly from the db - as sets to ease comparison later
                    results.append({
                        'from_t':
                        set([m.name for m in Milestone.select(env)]),
                        'from_db':
                        set([
                            v[0] for v in self.env.db_query(
                                "SELECT name FROM milestone")
                        ])
                    })

        def worker1():
            """ check milestones in this thread twice either side of ceding
            control to worker2
            """
            task(False)
            e1.set()
            e2.wait()
            task(False)

        def worker2():
            """ adds a milestone when worker1 allows us to then cede control
            back to worker1
            """
            e1.wait()
            task(True)
            e2.set()

        t1, t2 = [threading.Thread(target=f) for f in (worker1, worker2)]
        t1.start()
        t2.start()
        t1.join()
        t2.join()

        r = results[-1]  # note we only care about the final result
        self.assertEqual(r['from_t'], r['from_db'])

    def test_update_milestone(self):

        self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')")

        milestone = Milestone(self.env, 'Test')
        t1 = datetime(2001, 01, 01, tzinfo=utc)
        t2 = datetime(2002, 02, 02, tzinfo=utc)
        milestone.due = t1
        milestone.completed = t2
        milestone.description = 'Foo bar'
        milestone.update()

        self.assertEqual(
            [('Test', to_utimestamp(t1), to_utimestamp(t2), 'Foo bar',
              self.default_product)],
            self.env.db_query("SELECT * FROM milestone WHERE name='Test'"))
Esempio n. 4
0
class ProductMilestoneTestCase(MilestoneTestCase, MultiproductTestCase):
    def setUp(self):
        self.global_env = self._setup_test_env(create_folder=True)
        self._upgrade_mp(self.global_env)
        self._setup_test_log(self.global_env)
        self._load_product_from_data(self.global_env, self.default_product)

        self.env = ProductEnvironment(self.global_env, self.default_product)
        self._load_default_data(self.env)

    def tearDown(self):
        shutil.rmtree(self.global_env.path)
        self.global_env.reset_db()
        self.env = self.global_env = None

    @unittest.skipUnless(threading, 'Threading required for test')
    def test_milestone_threads(self):
        """ Ensure that in threaded (e.g. mod_wsgi) situations, we get
        an accurate list of milestones from Milestone.list

        The basic strategy is:
            thread-1 requests a list of milestones
            thread-2 adds a milestone
            thread-1 requests a new list of milestones
        To pass, thread-1 should have a list of milestones that matches
        those that are in the database.
        """
        lock = threading.RLock()
        results = []
        # two events to coordinate the workers and ensure that the threads
        # alternate appropriately
        e1 = threading.Event()
        e2 = threading.Event()

        def task(add):
            """the thread task - either we are discovering or adding events"""
            with lock:
                env = ProductEnvironment(self.global_env,
                                         self.default_product)
                if add:
                    name = 'milestone_from_' + threading.current_thread().name
                    milestone = Milestone(env)
                    milestone.name = name
                    milestone.insert()
                else:
                    # collect the names of milestones reported by Milestone and
                    # directly from the db - as sets to ease comparison later
                    results.append({
                        'from_t': set([m.name for m in Milestone.select(env)]),
                        'from_db': set(
                            [v[0] for v in self.env.db_query(
                                "SELECT name FROM milestone")])})

        def worker1():
            """ check milestones in this thread twice either side of ceding
            control to worker2
            """
            task(False)
            e1.set()
            e2.wait()
            task(False)

        def worker2():
            """ adds a milestone when worker1 allows us to then cede control
            back to worker1
            """
            e1.wait()
            task(True)
            e2.set()

        t1, t2 = [threading.Thread(target=f) for f in (worker1, worker2)]
        t1.start()
        t2.start()
        t1.join()
        t2.join()

        r = results[-1]  # note we only care about the final result
        self.assertEqual(r['from_t'], r['from_db'])

    def test_update_milestone(self):

        self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')")

        milestone = Milestone(self.env, 'Test')
        t1 = datetime(2001, 01, 01, tzinfo=utc)
        t2 = datetime(2002, 02, 02, tzinfo=utc)
        milestone.due = t1
        milestone.completed = t2
        milestone.description = 'Foo bar'
        milestone.update()

        self.assertEqual(
            [('Test', to_utimestamp(t1), to_utimestamp(t2), 'Foo bar',
                    self.default_product)],
            self.env.db_query("SELECT * FROM milestone WHERE name='Test'"))