~launchpad-pqm/launchpad/devel

63.1.137 by Robert Collins
add reset to autotest button for product series
1
#!/usr/bin/env python2.4
620 by Canonical.com Patch Queue Manager
Now checks pagetests on merge. Much work on page tests. Refactor of forgotten password pages.
2
3
# Ideas for extra features:
4
#
5
# * Press a key to split a single run into multiple text files
6
#   named in sequence.
7
#
8
# * Keep tcpwatch running all the time, but tell it to log just sometimes,
9
#   so you don't have to keep switching browser URLs.
10
11
import sys
12
import os
13
import tempfile
14
import StringIO
15
import textwrap
16
17
here = os.path.dirname(os.path.realpath(__file__))
18
listen_port = 9000
1786 by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget
19
forward_port = 8086
620 by Canonical.com Patch Queue Manager
Now checks pagetests on merge. Much work on page tests. Refactor of forgotten password pages.
20
21
EXIT_SYNTAX_ERROR = 2
22
EXIT_ERROR = 1
23
EXIT_OK = 0
24
25
def rm_dash_r(top):
26
    # Delete everything reachable from the directory named in 'top'.
27
    # CAUTION:  This is dangerous!  For example, if top == '/', it
28
    # could delete all your disk files.
29
    for root, dirs, files in os.walk(top, topdown=False):
30
        for name in files:
31
            os.remove(os.path.join(root, name))
32
        for name in dirs:
33
            os.rmdir(os.path.join(root, name))
34
    os.rmdir(top)
35
36
def print_usage():
37
    scriptname = sys.argv[0]
38
    usage = """
39
        %(scriptname)s: make a pagetest and write it to the 'pagetests'
40
        directory.
41
        Usage: %(scriptname)s ([priority]) [name of test]
42
43
        'priority' is either ++, xx or two decimal digits such as 00, 45 or 99.
44
        When 'priority' is ++, the test's filename will start with '++', and
45
        so will not be committed to an arch archive.
46
        The 'priority' of 'xx' means "no priority" and is for tests that both
47
        have no dependents and do not depend on other tests.
48
49
        'name of test' should be a short description of the test, to appear
50
        in the test's filename.  Quoting the name of the test is optional,
51
        even if it contains spaces.
52
53
        To use, run %(scriptname)s with a suitable priority and filename.
54
        Ensure that launchpad is running and listening on port 8085.
55
        Using your browser, go to a URL on port 9000.  Use launchpad.
56
        When you have finished, press ctrl+c.  The pagetest will be written
57
        to the pagetests directory.
58
59
        See also lib/canonical/launchpad/pagetests/README.txt
60
        """ % {'scriptname': scriptname}
61
    usage = textwrap.dedent(usage)
62
    paras = usage.split('\n\n')
63
    print
64
    for para in paras:
65
        print textwrap.fill(para)
66
        print
67
68
def pathfromhere(path):
69
    if path.startswith(here):
70
        return os.path.join('.', path[len(here)+1:])
71
72
def main():
73
    pagetest_directory = os.path.join(
74
        here, 'lib', 'canonical', 'launchpad', 'pagetests'
75
        )
76
77
    args = sys.argv[1:]
78
    if not args:
79
        print_usage()
80
        return EXIT_SYNTAX_ERROR
81
82
    priority = 'xx-'  # The default priority.
83
84
    filename = '-'.join(args)
85
86
    if len(filename) > 2:
87
        if filename.startswith('++'):
88
            priority = '++'
89
            filename = filename[2:]
90
        elif filename.startswith('xx'):
91
            priority = 'xx-'
92
            filename = filename[2:]
93
        elif filename[:2].isdigit():
94
            priority = filename[:2] + '-'
95
            filename = filename[2:]
96
    if filename.startswith('-'):
97
        filename = filename[1:]
98
99
    if len(filename) < 2:
100
        print_usage()
101
        return EXIT_SYNTAX_ERROR
102
103
    # sanitize filename
104
    L = []
105
    for char in filename:
106
        if char == '-' or char.isalnum():
107
            L.append(char)
108
        else:
109
            L.append('_')
110
    filename = ''.join(L)
111
112
    filename = '%s%s.txt' % (priority, filename)
113
    fq_filename = os.path.join(pagetest_directory, filename)
114
    if os.path.exists(fq_filename):
115
        print "file exists:", pathfromhere(fq_filename)
116
        return EXIT_ERROR
117
    print "Writing to file '%s'" % pathfromhere(fq_filename)
118
119
    print "Starting tcpwatch.  Press ^c when finished."
120
    print
121
122
    # The necessary evil of munging the PYTHONPATH so that we can import
123
    # zope libraries, launchpad stuff, and tcpwatch.
1806 by Canonical.com Patch Queue Manager
Always use sys.path.insert instead of sys.path.append to give precedence for launchpad libs that are inside our tree. r=stub
124
    sys.path.insert(0, os.path.join(here, 'lib'))
125
    sys.path.insert(0, os.path.join(here, 'utilities', 'tcpwatch'))
620 by Canonical.com Patch Queue Manager
Now checks pagetests on merge. Much work on page tests. Refactor of forgotten password pages.
126
    import tcpwatch
127
    import zope.app.tests.dochttp as dochttp
128
129
    tempdir = tempfile.mkdtemp(prefix='page-test.')
130
    original_stdout = sys.stdout
131
    sys.stdout = outputfile = StringIO.StringIO()
132
    try:
133
        tcpwatch.main(
134
            ['-L', '%s:%s' % (listen_port, forward_port), '-r', tempdir, '-s']
135
            )
136
        # At this point, tcpwatch waits for a KeyboardInterrupt before
137
        # continuing.
138
1428 by Canonical.com Patch Queue Manager
PO import/export scripts; keep Accept-Language header in page test generation
139
        # The default dochttp options remove the Accept-Language header from
140
        # the request; however, we want to keep it. Remove the option that
141
        # removes the header.
142
        new_defaults = list(dochttp.default_options)
143
        position_of_lang_header = new_defaults.index('Accept-Language')
144
        # Remove the 'Accept-Language' and the '-I' that is in the position
145
        # that precedes it.
146
        del new_defaults[position_of_lang_header-1:position_of_lang_header+1]
147
620 by Canonical.com Patch Queue Manager
Now checks pagetests on merge. Much work on page tests. Refactor of forgotten password pages.
148
        # Remove stdout from tcpwatch from the output.
149
        outputfile.truncate(0)
1428 by Canonical.com Patch Queue Manager
PO import/export scripts; keep Accept-Language header in page test generation
150
        dochttp.dochttp(args=[tempdir], default=new_defaults)
683 by Canonical.com Patch Queue Manager
Rewrote the way the suburls work to fix serious bug in it that revealed itself when I added robots.txt files. Added robots.txt files. Removed IHasSuburls dead chickens.
151
        rm_dash_r(tempdir)
620 by Canonical.com Patch Queue Manager
Now checks pagetests on merge. Much work on page tests. Refactor of forgotten password pages.
152
    finally:
153
        sys.stdout = original_stdout
683 by Canonical.com Patch Queue Manager
Rewrote the way the suburls work to fix serious bug in it that revealed itself when I added robots.txt files. Added robots.txt files. Removed IHasSuburls dead chickens.
154
        # Don't delete the tempdir if there was an error.  We may want to
155
        # forensically examine it.
156
        ##rm_dash_r(tempdir)
620 by Canonical.com Patch Queue Manager
Now checks pagetests on merge. Much work on page tests. Refactor of forgotten password pages.
157
158
    print  # A blank line to separate tcpwatch output from what follows.
159
160
    output = outputfile.getvalue()
161
    if not output:
162
        print "Not writing a file because there was no output."
163
        return EXIT_ERROR
164
    else:
165
        # write the output into pagetests
166
        # We check to see if the file exists at the start of this function.
167
        # Let's check again now, and gracefully handle the case when the
168
        # file does already exist.  It would have had to be added while
169
        # tcpwatch was doing its stuff.
170
        copycount = 0
171
        orig_filename = fq_filename
172
        while os.path.exists(fq_filename):
173
            print "File exists:", pathfromhere(fq_filename)
174
            copycount += 1
175
            fq_filename = orig_filename + '.%s' % copycount
176
            print "Using file:", pathfromhere(fq_filename)
177
        print "Writing pagetest to file:", pathfromhere(fq_filename)
178
        outputfile = file(fq_filename, 'w')
179
        outputfile.write(output)
180
        outputfile.close()
181
        return EXIT_OK
182
183
if __name__ == '__main__':
184
    sys.exit(main())