~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
*******************************
Using launchpadlib in pagetests
*******************************

As an alternative to crafting HTTP requests with the 'webservice'
object, you can write pagetests using launchpadlib.

Two helper functions make it easy to set up Launchpad objects that
can access the web service. With launchpadlib_for() you can set up a
Launchpad object for a given user with a single call.

    >>> launchpad = launchpadlib_for(
    ...     'launchpadlib test', 'salgado', 'WRITE_PUBLIC')
    >>> print launchpad.me.name
    salgado

    # XXX leonardr 2010-03-31 bug=552732
    # launchpadlib doesn't work with a credential scoped to a context
    # like 'firefox', because the service root resource is considered
    # out of scope. This test should pass, but it doesn't.
    #
    # When you fix this, be sure to show that an attempt to access
    # something that really is out of scope (like launchpad.me.name)
    # yields a 401 error.
    #
    #>>> launchpad = launchpadlib_for(
    #...     'launchpadlib test', 'no-priv', 'READ_PRIVATE', 'firefox',
    #...      version="devel")
    #>>> print launchpad.projects['firefox'].name
    #firefox

With launchpadlib_credentials_for() you can get a launchpadlib
Credentials object.

    >>> from lp.testing import launchpadlib_credentials_for
    >>> credentials = launchpadlib_credentials_for(
    ...     'launchpadlib test', 'no-priv', 'READ_PUBLIC')
    >>> credentials
    <launchpadlib.credentials.Credentials object ...>

    >>> print credentials.consumer.key
    launchpadlib test
    >>> print credentials.access_token
    oauth_token_secret=...&oauth_token=...

This can be used to create your own Launchpad object.  Note you cannot
use launchpadlib.uris.DEV_SERVICE_ROOT as the URL as it uses the https
scheme which does not work in the test environment.

    >>> from launchpadlib.launchpad import Launchpad
    >>> launchpad = Launchpad(
    ...     credentials, None, None, 'http://api.launchpad.dev/')
    >>> print launchpad.me.name
    no-priv

Anonymous access
================

    >>> lp_anon = Launchpad.login_anonymously('launchpadlib test',
    ...                                       'http://api.launchpad.dev/')

The Launchpad object for the anonymous user can be used to access
public information.

    >>> apache_results = lp_anon.project_groups.search(text="Apache")
    >>> print apache_results[0].name
    apache

But trying to access information that requires a logged in user
results in an error.

    >>> print lp_anon.me.name
    Traceback (most recent call last):
      ...
    Unauthorized: HTTP Error 401: Unauthorized...


Caching
=======

Let's make sure Launchpad serves caching-related headers that make
launchpadlib work correctly. First, we set up a temporary directory to
store the cache.

    >>> import tempfile
    >>> cache = tempfile.mkdtemp()

Then we make it possible to view the HTTP traffic between launchpadlib
and Launchpad.

    >>> import httplib2
    >>> old_debug_level = httplib2.debuglevel
    >>> httplib2.debuglevel = 1

Now create a Launchpad object and observe how it populates the cache.

    >>> launchpad = Launchpad(
    ...     credentials, None, None, 'http://api.launchpad.dev/',
    ...     cache=cache)
    send: 'GET /1.0/ ...accept: application/vnd.sun.wadl+xml...'
    reply: 'HTTP/1.0 200 Ok\n'
    ...
    send: 'GET /1.0/ ...accept: application/json...'
    reply: 'HTTP/1.0 200 Ok\n'
    ...

Create a second Launchpad object, and the cached documents will be
used instead of new HTTP requests being used.

    >>> launchpad = Launchpad(
    ...     credentials, None, None, 'http://api.launchpad.dev/',
    ...     cache=cache)

Cleanup.

    >>> import shutil
    >>> shutil.rmtree(cache)
    >>> httplib2.debuglevel = old_debug_level

Cache location
--------------

The cache location for Launchpad objects created via launchpadlib_for are a
temp directory.

    >>> launchpad = launchpadlib_for(
    ...     'launchpadlib test', 'salgado', 'WRITE_PUBLIC')

    >>> launchpad._browser._connection.cache.cache
    '/.../launchpadlib-cache-...'

If we create another Launchpad object, it'll get its own cache directory.

    >>> launchpad_2 = launchpadlib_for(
    ...     'launchpadlib test', 'salgado', 'WRITE_PUBLIC')

    >>> cache_dir_1 = launchpad._browser._connection.cache.cache
    >>> cache_dir_2 = launchpad_2._browser._connection.cache.cache

    >>> cache_dir_2 != cache_dir_1
    True

We use zope.testing.cleanup to manage cleaning up of the cache directories,
therefore we can peek inside its registry of clean-up actions and see the
clean-up functions biding their time.

    >>> import zope.testing.cleanup
    >>> zope.testing.cleanup._cleanups
    [...(<function _clean_up_cache...>, ('/.../launchpadlib-cache-...'...)...]