Merge lp://qastaging/~james-w/desktopcouch/context-for-tests into lp://qastaging/desktopcouch

Proposed by James Westby
Status: Merged
Approved by: Nicola Larosa
Approved revision: 122
Merged at revision: not available
Proposed branch: lp://qastaging/~james-w/desktopcouch/context-for-tests
Merge into: lp://qastaging/desktopcouch
Diff against target: 134 lines (+54/-47)
1 file modified
desktopcouch/local_files.py (+54/-47)
To merge this branch: bzr merge lp://qastaging/~james-w/desktopcouch/context-for-tests
Reviewer Review Type Date Requested Status
Nicola Larosa (community) Approve
Eric Casteleijn (community) Approve
Review via email: mp+20485@code.qastaging.launchpad.net

Commit message

Add with_auth and with_keyring arguments to Context.

If with_auth is False then a couch started in the created context won't require or accept credentials. This makes it not really a desktopcouch, but the facilities for starting and stopping couchdb with a restricted configuration can be hugely useful to other projects to use in e.g. test suites.

If with_keyring is False then the credentials won't be read from or stored to gnome-keyring, so that if it is a non-default context (e.g. in a testsuite) it doesn't intefere with the user's desktopcouch, as gnome-keyring is the only global object that Context interacts with.

To post a comment you must log in.
Revision history for this message
James Westby (james-w) wrote :

Hi,

This implements fixes for a couple of bugs that I filed to
make it easier to use desktopcouch in testing other projects.

The first use-case is testing against a private desktopcouch
for projects that use it, without stomping on the information
stored in gnome-keyring.

After that I wanted to re-use desktopcouch's knowledge of stopping
and starting couchdb in a project where I wanted to use plain couch,
not a desktop one, so I added with_auth to just have it skip all
the credentials stuff and just start a couchdb in a private area
for testing.

There aren't any tests for it, for two reasons:

  * The setup of a private context is done at import time, which
    is then re-used. I could do a similar thing in a couple of tests
    to change the arguments, but...

  * The tests themselves are not isolated from gnome-keyring. Therefore
    I wondered if they wanted to make use of the with_keyring argument,
    though that would mean that codepath wasn't tested.

Therefore I would like some guidance on what the preferred testing
strategy would be for this.

Thanks,

James

Revision history for this message
Eric Casteleijn (thisfred) wrote :

This looks like a great improvement! I would love for the tests *not* to use the user's keyring, which always seemed wrong to me. It's probably way beyond the scope of this branch, but the ideal way of testing realistic authentication would be to use a fake/mock keyring.

All tests green.

review: Approve
Revision history for this message
James Westby (james-w) wrote :

On Wed, 03 Mar 2010 15:07:02 -0000, Eric Casteleijn <email address hidden> wrote:
> Review: Approve
> This looks like a great improvement! I would love for the tests *not* to use the user's keyring, which always seemed wrong to me. It's probably way beyond the scope of this branch, but the ideal way of testing realistic authentication would be to use a fake/mock keyring.

That seemed to me like it would be the best solution, so that the tests
are isolated, but the code paths are still run. Does u1 have a preferred
mocking library/strategy?

Thanks for the approval.

James

Revision history for this message
Chad Miller (cmiller) wrote :

We do not, so far, use any library to mock, outside of ubuntuone-server. A class or module inside testing/ with a similar interface would satisfy me.

Revision history for this message
Nicola Larosa (teknico) wrote :

Looks good.

review: Approve
Revision history for this message
Elliot Murphy (statik) wrote :

> We do not, so far, use any library to mock, outside of ubuntuone-server. A
> class or module inside testing/ with a similar interface would satisfy me.

We use niemeyers mocker.py in ubuntuone-client code, and if a mocker library is needed I'd like to stick with that one unless there is some compelling reason to choose another. mocker.py is also very lightweight, it's a single file that could be dropped into a contrib/ or testing/ directory. http://labix.org/mocker

of course, if just putting in a class or module inside testing/ is easier than using mocker.py, that would be fine too.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'desktopcouch/local_files.py'
2--- desktopcouch/local_files.py 2010-02-05 00:04:44 +0000
3+++ desktopcouch/local_files.py 2010-03-02 20:26:14 +0000
4@@ -66,37 +66,6 @@
5 except (IOError, ValueError, IndexError):
6 pass # Loading failed. Let's fill it with sensible defaults.
7
8- try:
9- data = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET,
10- {'desktopcouch': 'basic'})
11- admin_username, admin_password = data[0].secret.split(":", 1)
12- except gnomekeyring.NoMatchError:
13- admin_username = self._make_random_string(10)
14- admin_password = self._make_random_string(10)
15-
16- try:
17- # save admin account details in keyring
18- item_id = gnomekeyring.item_create_sync(None,
19- gnomekeyring.ITEM_GENERIC_SECRET,
20- 'Desktop Couch user authentication',
21- {'desktopcouch': 'basic'},
22- ":".join([admin_username, admin_password]), True)
23- except gnomekeyring.NoKeyringDaemonError:
24- logging.warn("There is no keyring to store our admin credentials.")
25-
26- consumer_key = self._make_random_string(10)
27- consumer_secret = self._make_random_string(10)
28- token = self._make_random_string(10)
29- token_secret = self._make_random_string(10)
30-
31- # Save the new OAuth creds so that 3rd-party apps can authenticate by
32- # accessing the keyring first. This is one-way. We don't read from keyring.
33- item_id = gnomekeyring.item_create_sync(
34- None, gnomekeyring.ITEM_GENERIC_SECRET,
35- 'Desktop Couch user authentication', {'desktopcouch': 'oauth'},
36- ":".join([consumer_key, consumer_secret, token, token_secret]),
37- True)
38-
39 local = {
40 'couchdb': {
41 'database_dir': ctx.db_dir,
42@@ -110,23 +79,58 @@
43 'file': ctx.file_log,
44 'level': ctx.couchdb_log_level,
45 },
46- 'admins': {
47- admin_username: admin_password
48- },
49- 'oauth_consumer_secrets': {
50- consumer_key: consumer_secret
51- },
52- 'oauth_token_secrets': {
53- token: token_secret
54- },
55- 'oauth_token_users': {
56- token: admin_username
57- },
58- 'couch_httpd_auth': {
59- 'require_valid_user': 'true'
60- }
61 }
62
63+ if ctx.with_auth:
64+ admin_username = self._make_random_string(10)
65+ admin_password = self._make_random_string(10)
66+ if ctx.with_keyring:
67+ try:
68+ data = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET,
69+ {'desktopcouch': 'basic'})
70+ admin_username, admin_password = data[0].secret.split(":", 1)
71+ except gnomekeyring.NoMatchError:
72+ try:
73+ # save admin account details in keyring
74+ item_id = gnomekeyring.item_create_sync(None,
75+ gnomekeyring.ITEM_GENERIC_SECRET,
76+ 'Desktop Couch user authentication',
77+ {'desktopcouch': 'basic'},
78+ ":".join([admin_username, admin_password]), True)
79+ except gnomekeyring.NoKeyringDaemonError:
80+ logging.warn("There is no keyring to store our admin credentials.")
81+
82+ consumer_key = self._make_random_string(10)
83+ consumer_secret = self._make_random_string(10)
84+ token = self._make_random_string(10)
85+ token_secret = self._make_random_string(10)
86+
87+ if ctx.with_keyring:
88+ # Save the new OAuth creds so that 3rd-party apps can authenticate by
89+ # accessing the keyring first. This is one-way. We don't read from keyring.
90+ item_id = gnomekeyring.item_create_sync(
91+ None, gnomekeyring.ITEM_GENERIC_SECRET,
92+ 'Desktop Couch user authentication', {'desktopcouch': 'oauth'},
93+ ":".join([consumer_key, consumer_secret, token, token_secret]),
94+ True)
95+
96+ local.update({'admins': {
97+ admin_username: admin_password
98+ },
99+ 'oauth_consumer_secrets': {
100+ consumer_key: consumer_secret
101+ },
102+ 'oauth_token_secrets': {
103+ token: token_secret
104+ },
105+ 'oauth_token_users': {
106+ token: admin_username
107+ },
108+ 'couch_httpd_auth': {
109+ 'require_valid_user': 'true'
110+ }
111+ })
112+
113 self._fill_from_structure(local)
114 self.save_to_file(self.file_name_used)
115
116@@ -192,7 +196,8 @@
117 """A mimic of xdg BaseDirectory, with overridable values that do not
118 depend on environment variables."""
119
120- def __init__(self, run_dir, db_dir, config_dir): # (cache, data, config)
121+ def __init__(self, run_dir, db_dir, config_dir, with_auth=True,
122+ with_keyring=True): # (cache, data, config)
123
124 self.couchdb_log_level = 'info'
125
126@@ -205,6 +210,8 @@
127 self.run_dir = os.path.realpath(run_dir)
128 self.config_dir = os.path.realpath(config_dir)
129 self.db_dir = os.path.realpath(db_dir)
130+ self.with_auth = with_auth
131+ self.with_keyring = with_keyring
132
133 self.file_ini = os.path.join(config_dir, "desktop-couchdb.ini")
134 self.file_pid = os.path.join(run_dir, "desktop-couchdb.pid")

Subscribers

People subscribed via source and target branches