~launchpad-pqm/launchpad/devel

10637.3.1 by Guilherme Salgado
Use the default python version instead of a hard-coded version
1
#!/usr/bin/python -S
8687.15.7 by Karl Fogel
Add the copyright header block to more files.
2
#
3
# Copyright 2009 Canonical Ltd.  This software is licensed under the
4
# GNU Affero General Public License version 3 (see the file LICENSE).
5
4935.3.7 by Curtis Hovey
Added bad name suppression to cronscripts.
6
# pylint: disable-msg=C0103,W0403
4868.1.1 by Guilherme Salgado
Make TeamMembership.setStatus call flush_db_updates() and add a script to fix the db corruption caused by the lack of flush_db_updates() on setStatus when it's called from the flag-expired-memberships script
7
7052.1.1 by Guilherme Salgado
Fix check-teamparticipation.py to use a logger rather than printing stuff to stdout
8
"""Check for invalid/missing TeamParticipation entries.
4868.1.6 by Guilherme Salgado
Turn the script that was supposed to fix invalid team participation entries into something that just reports the invalid ones, to be run from staging
9
7052.1.1 by Guilherme Salgado
Fix check-teamparticipation.py to use a logger rather than printing stuff to stdout
10
Invalid TP entries are the ones for which there are no active TeamMemberships
11
leading to.
4868.1.6 by Guilherme Salgado
Turn the script that was supposed to fix invalid team participation entries into something that just reports the invalid ones, to be run from staging
12
13
This script is usually run on staging to find discrepancies between the
7052.1.1 by Guilherme Salgado
Fix check-teamparticipation.py to use a logger rather than printing stuff to stdout
14
TeamMembership and TeamParticipation tables which are a good indication of
4868.1.6 by Guilherme Salgado
Turn the script that was supposed to fix invalid team participation entries into something that just reports the invalid ones, to be run from staging
15
bugs in the code which maintains the TeamParticipation table.
16
17
Ideally there should be database constraints to prevent this sort of
18
situation, but that's not a simple thing and this should do for now.
19
"""
20
9641.1.4 by Gary Poster
more updates for _pythonpath. Still need to update all subprocess calls to python to use -S; still need to update z3c.recipe.filetemplate to provide sys.modules from -S run.
21
import _pythonpath
22
7052.1.1 by Guilherme Salgado
Fix check-teamparticipation.py to use a logger rather than printing stuff to stdout
23
import optparse
24
import sys
25
4868.1.1 by Guilherme Salgado
Make TeamMembership.setStatus call flush_db_updates() and add a script to fix the db corruption caused by the lack of flush_db_updates() on setStatus when it's called from the flag-expired-memberships script
26
from canonical.database.sqlbase import cursor
7052.1.1 by Guilherme Salgado
Fix check-teamparticipation.py to use a logger rather than printing stuff to stdout
27
from canonical.launchpad.scripts import (
28
    execute_zcml_for_scripts, logger_options, logger)
4868.1.1 by Guilherme Salgado
Make TeamMembership.setStatus call flush_db_updates() and add a script to fix the db corruption caused by the lack of flush_db_updates() on setStatus when it's called from the flag-expired-memberships script
29
from canonical.lp import initZopeless
30
31
4868.1.6 by Guilherme Salgado
Turn the script that was supposed to fix invalid team participation entries into something that just reports the invalid ones, to be run from staging
32
if __name__ == '__main__':
7052.1.1 by Guilherme Salgado
Fix check-teamparticipation.py to use a logger rather than printing stuff to stdout
33
    parser = optparse.OptionParser(
34
        description="Check for invalid/missing TeamParticipation entries.")
35
    logger_options(parser)
36
    options, args = parser.parse_args(sys.argv[1:])
37
    log = logger(options, 'check-teamparticipation')
4868.1.6 by Guilherme Salgado
Turn the script that was supposed to fix invalid team participation entries into something that just reports the invalid ones, to be run from staging
38
8847.1.1 by Celso Providelo
Integrating the tree script checker into the test suite.
39
    execute_zcml_for_scripts()
40
    ztm = initZopeless(implicitBegin=False)
41
6010.1.1 by Guilherme Salgado
Change the check-teamparticipation.py script to check for people/teams which are not members of themselves.
42
    # Check self-participation.
43
    query = """
44
        SELECT id, name
6010.1.2 by Guilherme Salgado
Fix a few stylistic things.
45
        FROM Person WHERE id NOT IN (
46
            SELECT person FROM Teamparticipation WHERE person = team
6010.1.1 by Guilherme Salgado
Change the check-teamparticipation.py script to check for people/teams which are not members of themselves.
47
            ) AND merged IS NULL
48
        """
4868.1.6 by Guilherme Salgado
Turn the script that was supposed to fix invalid team participation entries into something that just reports the invalid ones, to be run from staging
49
    ztm.begin()
6010.1.1 by Guilherme Salgado
Change the check-teamparticipation.py script to check for people/teams which are not members of themselves.
50
    cur = cursor()
51
    cur.execute(query)
52
    non_self_participants = cur.fetchall()
53
    if len(non_self_participants) > 0:
7052.1.1 by Guilherme Salgado
Fix check-teamparticipation.py to use a logger rather than printing stuff to stdout
54
        log.warn("Some people/teams are not members of themselves: %s"
55
                 % non_self_participants)
6010.1.1 by Guilherme Salgado
Change the check-teamparticipation.py script to check for people/teams which are not members of themselves.
56
7052.1.3 by Guilherme Salgado
Make check-teamparticipation.py detect circular references between teams.
57
    # Check if there are any circular references between teams.
58
    cur.execute("""
59
        SELECT tp.team, tp2.team
60
        FROM teamparticipation AS tp, teamparticipation AS tp2
61
        WHERE tp.team = tp2.person
62
            AND tp.person = tp2.team
63
            AND tp.id != tp2.id;
64
        """)
65
    circular_references = cur.fetchall()
66
    if len(circular_references) > 0:
67
        log.warn("Circular references found: %s" % circular_references)
68
        sys.exit(1)
69
7052.1.2 by Guilherme Salgado
Fix the bug.
70
    # Check if there are any missing/spurious TeamParticipation entries.
71
    cur.execute("SELECT id FROM Person WHERE teamowner IS NOT NULL")
72
    team_ids = cur.fetchall()
4868.1.6 by Guilherme Salgado
Turn the script that was supposed to fix invalid team participation entries into something that just reports the invalid ones, to be run from staging
73
    ztm.abort()
74
7052.1.2 by Guilherme Salgado
Fix the bug.
75
    def get_participants(team):
76
        """Recurse through the team's members to get all its participants."""
77
        participants = set()
78
        for member in team.activemembers:
79
            participants.add(member)
80
            if member.is_team:
81
                participants.update(get_participants(member))
82
        return participants
83
8971.22.1 by Guilherme Salgado
Remove all 'from lp.registry.model.<module> import *' lines from canonical.launchpad.database.__init__
84
    from lp.registry.model.person import Person
7052.1.2 by Guilherme Salgado
Fix the bug.
85
    batch = team_ids[:50]
86
    team_ids = team_ids[50:]
4868.1.6 by Guilherme Salgado
Turn the script that was supposed to fix invalid team participation entries into something that just reports the invalid ones, to be run from staging
87
    while batch:
88
        for [id] in batch:
89
            ztm.begin()
7052.1.2 by Guilherme Salgado
Fix the bug.
90
            team = Person.get(id)
91
            expected = get_participants(team)
92
            found = set(team.allmembers)
93
            difference = expected.difference(found)
94
            if len(difference) > 0:
95
                people = ", ".join("%s (%s)" % (person.name, person.id)
96
                                   for person in difference)
97
                log.warn("%s (%s): missing TeamParticipation entries for %s."
98
                         % (team.name, team.id, people))
99
            reverse_difference = found.difference(expected)
100
            if len(reverse_difference) > 0:
101
                people = ", ".join("%s (%s)" % (person.name, person.id)
102
                                   for person in reverse_difference)
103
                log.warn("%s (%s): spurious TeamParticipation entries for %s."
104
                         % (team.name, team.id, people))
4868.1.6 by Guilherme Salgado
Turn the script that was supposed to fix invalid team participation entries into something that just reports the invalid ones, to be run from staging
105
            ztm.abort()
7052.1.2 by Guilherme Salgado
Fix the bug.
106
        batch = team_ids[:50]
107
        team_ids = team_ids[50:]