Merge lp:~james-w/pkgme-devportal/stormify into lp:pkgme-devportal

Proposed by James Westby
Status: Merged
Merged at revision: 19
Proposed branch: lp:~james-w/pkgme-devportal/stormify
Merge into: lp:pkgme-devportal
Diff against target: 503 lines (+235/-55)
6 files modified
README (+39/-1)
acceptance/tests/__init__.py (+3/-14)
devportalbinary/database.py (+116/-27)
devportalbinary/testing.py (+23/-2)
devportalbinary/tests/test_database.py (+52/-11)
setup.py (+2/-0)
To merge this branch: bzr merge lp:~james-w/pkgme-devportal/stormify
Reviewer Review Type Date Requested Status
pkgme binary committers Pending
Review via email: mp+84529@code.launchpad.net

Description of the change

Hi,

This branch stormifies the code, in order to support postgres as well
as sqlite.

It's not the prettiest thing ever, and the postgres code is under-tested, but
I didn't want to deal with using a postgres fixture.

The unicode() changes are so that postgres types match up, and should be
fine as package names and library file names are (have to be?) ascii.

Thanks,

James

To post a comment you must log in.
Revision history for this message
Jonathan Lange (jml) wrote :
Download full text (9.2 KiB)

On Mon, Dec 5, 2011 at 9:02 PM, James Westby <email address hidden> wrote:
> James Westby has proposed merging lp:~james-w/pkgme-binary/stormify into lp:pkgme-binary.
>
> Requested reviews:
>  pkgme binary committers (pkgme-binary-dev)
>
> For more details, see:
> https://code.launchpad.net/~james-w/pkgme-binary/stormify/+merge/84529
>
> Hi,
>
> This branch stormifies the code, in order to support postgres as well
> as sqlite.
>
> It's not the prettiest thing ever, and the postgres code is under-tested, but
> I didn't want to deal with using a postgres fixture.
>
> The unicode() changes are so that postgres types match up, and should be
> fine as package names and library file names are (have to be?) ascii.
>
> Thanks,
>
> James
>
> --
> https://code.launchpad.net/~james-w/pkgme-binary/stormify/+merge/84529
> Your team pkgme binary committers is requested to review the proposed merge of lp:~james-w/pkgme-binary/stormify into lp:pkgme-binary.
>
> === modified file 'README'
> --- README      2011-11-21 16:19:48 +0000
> +++ README      2011-12-05 21:01:26 +0000
> @@ -6,6 +6,9 @@
...

These changes are much appreciated.

> === modified file 'devportalbinary/database.py'
> --- devportalbinary/database.py 2011-10-25 16:45:08 +0000
> +++ devportalbinary/database.py 2011-12-05 21:01:26 +0000
...
> @@ -201,38 +201,129 @@
>     db.update_source_package(source_package_name, symbols)
>
>
> +class PackageDBSchema(schema.Schema):
> +
> +    class database(schema.Section):
> +        db_type = schema.StringOption(default='sqlite',
> +                help=('The database to use, one of "sqlite", or "postgres"'))
> +        host = schema.StringOption(
> +                help='The database host (for postgres)')
> +        port = schema.StringOption(
> +                help='The database port (for postgres)')
> +        username = schema.StringOption(
> +                help='The database username (for postgres)')
> +        password = schema.StringOption(
> +                help='The database password (for postgres)')
> +        path = schema.StringOption(
> +                help='The path to the database file (for sqlite)')
> +
> +
>  class PackageDatabase(object):
>
> +    SQLITE = 'sqlite'
> +    POSTGRES = 'postgres'
> +
>     ENV_VAR = 'PKGME_LIB_DEPS_DB_PATH'

Why didn't you delete ENV_VAR?

> +    CONF_FILE = '~/.config/pkgme-binary/conf'
>
> -    def __init__(self, sqlite_database):
> -        self._sqlite = sqlite_database
> +    def __init__(self, store):
> +        self._store = store
>
>     @classmethod
> -    def create(cls, sqlite_path=None):
> -        if sqlite_path is None:
> +    def _get_storm_sqlite_connection_string(cls, opts):
> +        if not opts.database_path:
>             try:
> -                sqlite_path = os.environ[cls.ENV_VAR]
> +                opts.database_path = os.environ[cls.ENV_VAR]
>             except KeyError:
>                 raise ValueError(
>                     "Cannot create database, no path given and %s not set"
>                     % (cls.ENV_VAR,))
> -        c = sqlite3.connect(sqlite_path)
> -        c.cursor().execute(
> -            "CREATE TABLE IF NOT EXISTS libdep ("
> -            "source_pac...

Read more...

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

> > +    SQLITE = 'sqlite'
> > +    POSTGRES = 'postgres'
> > +
> >     ENV_VAR = 'PKGME_LIB_DEPS_DB_PATH'
>
> Why didn't you delete ENV_VAR?

It's still used as a fallback. I can delete that code if we want
to just go straight for the config file approach?

> > +    @classmethod
> > +    def get_store_from_config(cls):
> > +        """Create a storm store based on a config file.
> > +
> > +        This method will create a storm store based
> > +        on the information in ``~/.config/pkgme-binary/conf``
> > +
> > +        If that file doesn't exist, or it doesn't contain
> > +        information about setting up a database then this
> > +        method will return None.
> > +        """
>
> Really? It looks like it will always return a tuple.

Good catch, I wrote that docstring before writing any code, and
then changed my approach. I'll fix it up.

> We could probably factor this into using different classes to
> represent the different types of database. Would avoid the 'if' here
> and maybe having to pass around the database type. Probably for a
> later branch though.

I think that would be a good change, I'll defer it for now.

> >     def setUp(self):
> >         super(DatabaseFixture, self).setUp()
> > +        # Set a temporary homedir so that any config on the user's
> > +        # machine isn't picked up and the environment variable is used
> > +        # instead.
> > +        self.useFixture(TempHomeDirFixture())
> >         tempdir = self.useFixture(TempDir())
> >         db_path = os.path.join(tempdir.path, 'test-db')
> > -        self.useFixture(EnvironmentVariableFixture(PackageDatabase.ENV_VAR,
> db_path))
> > -        self.db = PackageDatabase.create(db_path)
> > +        config_file_path = os.path.expanduser(PackageDatabase.CONF_FILE)
> > +        os.makedirs(os.path.dirname(config_file_path))
> > +        with open(config_file_path, 'w') as f:
> > +            f.write('[database]\ndb_type=sqlite\npath=%s\n' % db_path)
> > +        self.db = PackageDatabase.create()
> > +
>
> It's a pity we can't use an in-memory database.

Yeah, this is used for testing across processes so there's
not a lot we can do there I don't think. We should restrict
the number of tests that use it to a minimum though I think.

> This should probably be submitted upstream.

I'll do that.

> As far as I can tell, self.home_dir is unused. Best then to not set it.

Good idead.

> Test coverage is good.
>
> In summary,
> * Delete ENV_VAR
> * Change get_store_from_config's docstring to be correct.

What do you think about dropping support for the env var? I kept it
so that any deployment would keep working across the change, but
we can probably have Tom incorporate this change as he'll want it
for postgres support anyway.

Thanks,

James

Revision history for this message
Jonathan Lange (jml) wrote :

On Tue, Dec 6, 2011 at 4:08 PM, James Westby <email address hidden> wrote:
>
>> > +    SQLITE = 'sqlite'
>> > +    POSTGRES = 'postgres'
>> > +
>> >     ENV_VAR = 'PKGME_LIB_DEPS_DB_PATH'
>>
>> Why didn't you delete ENV_VAR?
>
> It's still used as a fallback. I can delete that code if we want
> to just go straight for the config file approach?
>
...
>> Test coverage is good.
>>
>> In summary,
>>  * Delete ENV_VAR
>>  * Change get_store_from_config's docstring to be correct.
>
> What do you think about dropping support for the env var? I kept it
> so that any deployment would keep working across the change, but
> we can probably have Tom incorporate this change as he'll want it
> for postgres support anyway.
>

Let's leave it in there, and then delete once we've deployed with the
config file.

 approve

jml

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README'
2--- README 2011-11-21 16:19:48 +0000
3+++ README 2011-12-05 21:01:26 +0000
4@@ -6,6 +6,9 @@
5
6 * pkgme
7 * bzr
8+ * storm
9+ * configglue
10+ * launchpadlib (if running fetch-symbol-files)
11
12 Tests
13 -----
14@@ -13,8 +16,43 @@
15 * fixtures
16 * testtools
17
18+Configuration File
19+==================
20+
21+Behaviour can be controlled by a config file at
22+
23+ $HOME/.config/pkgme-binary/conf
24+
25+Currently one section is supported for configuring database access.
26+This can either be sqlite or postgres.
27+
28+SQLite
29+------
30+
31+The file should look something like::
32+
33+ [database]
34+ db_type = sqlite
35+ path = /path/to/file.db
36+
37+Postgres
38+--------
39+
40+The file should look something like::
41+
42+ [database]
43+ db_type = postgres
44+ host = <db host>
45+ port = <db port>
46+ username = <db username>
47+ password = <db password>
48+
49+When using postgres it expects to be able to use a database
50+called "pkgme_binary_dependencies" but tables within this
51+database will be created by the tool itself.
52+
53 Acceptance tests
54-----------------
55+================
56
57 There is an acceptance test suite that is not run as part of the
58 unit tests. You can run these tests with
59
60=== modified file 'acceptance/tests/__init__.py'
61--- acceptance/tests/__init__.py 2011-11-15 17:27:30 +0000
62+++ acceptance/tests/__init__.py 2011-12-05 21:01:26 +0000
63@@ -1,13 +1,13 @@
64 import os
65 import shutil
66
67-from fixtures import EnvironmentVariableFixture, Fixture, MonkeyPatch
68+from fixtures import Fixture, MonkeyPatch
69 from testtools import TestCase
70
71 import pkgme
72 from pkgme.testing import PathExists, TempdirFixture
73
74-from devportalbinary.database import PackageDatabase
75+from devportalbinary.testing import DatabaseFixture
76
77
78 class TestData(Fixture):
79@@ -24,17 +24,6 @@
80 shutil.copytree(source_path, self.path)
81
82
83-class DependencyDatabase(Fixture):
84-
85- def setUp(self):
86- Fixture.setUp(self)
87- tempdir = self.useFixture(TempdirFixture())
88- db_path = os.path.join(tempdir.path, 'db')
89- self.useFixture(
90- EnvironmentVariableFixture(PackageDatabase.ENV_VAR, db_path))
91- self.db = PackageDatabase.create()
92-
93-
94 class AcceptanceTests(TestCase):
95
96 def setUp(self):
97@@ -63,7 +52,7 @@
98
99 def test_gtk(self):
100 """Runs successfully for a basic GTK+ application."""
101- dep_db = self.useFixture(DependencyDatabase())
102+ dep_db = self.useFixture(DatabaseFixture())
103 test_data = self.useFixture(TestData("gtk"))
104 self.run_pkgme(test_data)
105 self.assertThat(
106
107=== modified file 'devportalbinary/database.py'
108--- devportalbinary/database.py 2011-10-25 16:45:08 +0000
109+++ devportalbinary/database.py 2011-12-05 21:01:26 +0000
110@@ -5,22 +5,22 @@
111 from itertools import chain
112 import os
113 import shutil
114-import sqlite3
115 import tempfile
116 from urllib2 import urlopen
117
118 from bzrlib import urlutils
119+from configglue import glue, schema
120 from launchpadlib import (
121 uris,
122 )
123 from launchpadlib.launchpad import Launchpad
124 from pkgme.run_script import run_subprocess
125+from storm.locals import create_database, Store
126
127
128 APPLICATION_NAME = 'pkgme-binary'
129 SERVICE_ROOT = uris.LPNET_SERVICE_ROOT
130
131-
132 def get_lp():
133 return Launchpad.login_anonymously(APPLICATION_NAME, SERVICE_ROOT, tempfile.mkdtemp())
134
135@@ -201,38 +201,129 @@
136 db.update_source_package(source_package_name, symbols)
137
138
139+class PackageDBSchema(schema.Schema):
140+
141+ class database(schema.Section):
142+ db_type = schema.StringOption(default='sqlite',
143+ help=('The database to use, one of "sqlite", or "postgres"'))
144+ host = schema.StringOption(
145+ help='The database host (for postgres)')
146+ port = schema.StringOption(
147+ help='The database port (for postgres)')
148+ username = schema.StringOption(
149+ help='The database username (for postgres)')
150+ password = schema.StringOption(
151+ help='The database password (for postgres)')
152+ path = schema.StringOption(
153+ help='The path to the database file (for sqlite)')
154+
155+
156 class PackageDatabase(object):
157
158+ SQLITE = 'sqlite'
159+ POSTGRES = 'postgres'
160+
161 ENV_VAR = 'PKGME_LIB_DEPS_DB_PATH'
162+ CONF_FILE = '~/.config/pkgme-binary/conf'
163
164- def __init__(self, sqlite_database):
165- self._sqlite = sqlite_database
166+ def __init__(self, store):
167+ self._store = store
168
169 @classmethod
170- def create(cls, sqlite_path=None):
171- if sqlite_path is None:
172+ def _get_storm_sqlite_connection_string(cls, opts):
173+ if not opts.database_path:
174 try:
175- sqlite_path = os.environ[cls.ENV_VAR]
176+ opts.database_path = os.environ[cls.ENV_VAR]
177 except KeyError:
178 raise ValueError(
179 "Cannot create database, no path given and %s not set"
180 % (cls.ENV_VAR,))
181- c = sqlite3.connect(sqlite_path)
182- c.cursor().execute(
183- "CREATE TABLE IF NOT EXISTS libdep ("
184- "source_package_name TEXT, "
185- "library TEXT, "
186- "dependency TEXT, "
187- "CONSTRAINT libdep_uniq UNIQUE (source_package_name, "
188- "library, dependency))")
189- return cls(c)
190+ return '%s:%s' % (opts.database_db_type, opts.database_path)
191+
192+ @classmethod
193+ def _get_storm_postgres_connection_string(cls, opts):
194+ for attr in ('database_host', 'database_port',
195+ 'database_username', 'database_password'):
196+ if not getattr(opts, attr, None):
197+ raise AssertionError(
198+ "You must specify %s for %s" % (
199+ attr, opts.database_db_type))
200+ return '%s://%s:%s@%s:%s/pkgme_binary_dependencies' % (
201+ opts.database_db_type, opts.database_username,
202+ opts.database_password, opts.database_host,
203+ opts.database_port)
204+
205+ @classmethod
206+ def _get_storm_connection_string(cls, opts):
207+ if opts.database_db_type == cls.SQLITE:
208+ return cls._get_storm_sqlite_connection_string(opts)
209+ elif opts.database_db_type == cls.POSTGRES:
210+ return cls._get_storm_postgres_connection_string(opts)
211+ else:
212+ raise AssertionError(
213+ "Unsupported database: %s" % opts.database_db_type)
214+
215+ @classmethod
216+ def get_db_info_from_config(cls):
217+ config_location = os.path.expanduser(cls.CONF_FILE)
218+ config_files = []
219+ if os.path.exists(config_location):
220+ config_files.append(config_location)
221+ theglue = glue.configglue(PackageDBSchema, config_files)
222+ opts = theglue.options
223+ connection_string = cls._get_storm_connection_string(opts)
224+ return connection_string, opts.database_db_type
225+
226+ @classmethod
227+ def get_store_from_config(cls):
228+ """Create a storm store based on a config file.
229+
230+ This method will create a storm store based
231+ on the information in ``~/.config/pkgme-binary/conf``
232+
233+ If that file doesn't exist, or it doesn't contain
234+ information about setting up a database then this
235+ method will return None.
236+ """
237+ connection_string, store_type = cls.get_db_info_from_config()
238+ database = create_database(connection_string)
239+ return Store(database), store_type
240+
241+ @classmethod
242+ def create(cls, store=None, store_type='sqlite'):
243+ if store is None:
244+ store, store_type = cls.get_store_from_config()
245+ if store_type == 'sqlite':
246+ store.execute(
247+ "CREATE TABLE IF NOT EXISTS libdep ("
248+ "source_package_name TEXT, "
249+ "library TEXT, "
250+ "dependency TEXT, "
251+ "CONSTRAINT libdep_uniq UNIQUE (source_package_name, "
252+ "library, dependency))")
253+ elif store_type == 'postgres':
254+ # Postgres only supports IF NOT EXISTS starting from 9.1
255+ exists = store.execute(
256+ "SELECT COUNT(relname) FROM pg_class WHERE "
257+ "relname = 'libdep'").get_one()[0]
258+ if not exists:
259+ store.execute(
260+ "CREATE TABLE libdep ("
261+ "source_package_name TEXT, "
262+ "library TEXT, "
263+ "dependency TEXT, "
264+ "CONSTRAINT libdep_uniq UNIQUE (source_package_name, "
265+ "library, dependency))")
266+ else:
267+ raise AssertionError("Unsupported database type: %s" % store_type)
268+ store.commit()
269+ return cls(store)
270
271 def get_dependencies(self, library_name):
272 """Get the binary packagaes that provide 'library_name'."""
273- c = self._sqlite.cursor()
274- c.execute("SELECT dependency FROM libdep WHERE library = ?",
275- (library_name,))
276- return set([dependency for [dependency] in c])
277+ result = self._store.execute("SELECT dependency FROM libdep WHERE library = ?",
278+ (unicode(library_name),))
279+ return set([dependency for [dependency] in result])
280
281 def insert_new_library(self, source_package_name, library_name, dependency):
282 """Insert a library and its needed dependency into the database.
283@@ -241,9 +332,8 @@
284 :param dependency: A binary package dependency, possibly including
285 version.
286 """
287- c = self._sqlite.cursor()
288- c.execute("INSERT INTO libdep VALUES (?, ?, ?)",
289- (source_package_name, library_name, dependency))
290+ self._store.execute("INSERT INTO libdep VALUES (?, ?, ?)",
291+ (unicode(source_package_name), unicode(library_name), unicode(dependency)))
292
293 def update_source_package(self, source_package_name, symbols):
294 """Update the database with the symbols from 'source_package_name'.
295@@ -254,14 +344,13 @@
296 representation is a list of tuples of library and
297 dependency. e.g. [[(libfoo, foo), ...], ...].
298 """
299- c = self._sqlite.cursor()
300- c.execute("DELETE FROM libdep WHERE source_package_name = ?",
301- (source_package_name,))
302+ self._store.execute("DELETE FROM libdep WHERE source_package_name = ?",
303+ (unicode(source_package_name),))
304 for symbols in symbols:
305 for library, dependency in symbols:
306 self.insert_new_library(
307 source_package_name, library, dependency)
308- self._sqlite.commit()
309+ self._store.commit()
310
311
312 def main(source_package_name):
313
314=== modified file 'devportalbinary/testing.py'
315--- devportalbinary/testing.py 2011-10-24 22:01:46 +0000
316+++ devportalbinary/testing.py 2011-12-05 21:01:26 +0000
317@@ -17,7 +17,28 @@
318
319 def setUp(self):
320 super(DatabaseFixture, self).setUp()
321+ # Set a temporary homedir so that any config on the user's
322+ # machine isn't picked up and the environment variable is used
323+ # instead.
324+ self.useFixture(TempHomeDirFixture())
325 tempdir = self.useFixture(TempDir())
326 db_path = os.path.join(tempdir.path, 'test-db')
327- self.useFixture(EnvironmentVariableFixture(PackageDatabase.ENV_VAR, db_path))
328- self.db = PackageDatabase.create(db_path)
329+ config_file_path = os.path.expanduser(PackageDatabase.CONF_FILE)
330+ os.makedirs(os.path.dirname(config_file_path))
331+ with open(config_file_path, 'w') as f:
332+ f.write('[database]\ndb_type=sqlite\npath=%s\n' % db_path)
333+ self.db = PackageDatabase.create()
334+
335+
336+class TempHomeDirFixture(Fixture):
337+ """Create a temp directory and set it as $HOME.
338+
339+ This provides a known environment for any test that uses
340+ $HOME.
341+ """
342+
343+ def setUp(self):
344+ super(TempHomeDirFixture, self).setUp()
345+ tempdir = self.useFixture(TempDir())
346+ self.path = tempdir.path
347+ self.useFixture(EnvironmentVariableFixture("HOME", self.path))
348
349=== modified file 'devportalbinary/tests/test_database.py'
350--- devportalbinary/tests/test_database.py 2011-10-24 21:48:58 +0000
351+++ devportalbinary/tests/test_database.py 2011-12-05 21:01:26 +0000
352@@ -6,6 +6,7 @@
353 TempDir,
354 )
355 from pkgme.testing import PathExists
356+from storm.locals import create_database, Store
357 from testtools import TestCase
358 from testtools.matchers import (
359 Equals,
360@@ -13,6 +14,7 @@
361 )
362
363 from devportalbinary.database import PackageDatabase
364+from devportalbinary.testing import TempHomeDirFixture
365
366
367 class ResultsIn(Matcher):
368@@ -23,55 +25,62 @@
369
370 def match(self, query):
371 # XXX: Abstraction violation
372- c = self._db._sqlite.cursor()
373- c.execute(query)
374- results = list(c)
375- return Equals(self._rows).match(results)
376+ results = self._db._store.execute(query)
377+ return Equals(self._rows).match(list(results))
378
379
380 class TestDatabase(TestCase):
381
382+ def setUp(self):
383+ super(TestDatabase, self).setUp()
384+ self.home_dir = self.useFixture(TempHomeDirFixture())
385+
386+ def get_package_db(self):
387+ database = create_database('sqlite:')
388+ store = Store(database)
389+ return PackageDatabase.create(store, store_type=PackageDatabase.SQLITE)
390+
391 def test_insert_new_library(self):
392- db = PackageDatabase.create(':memory:')
393+ db = self.get_package_db()
394 db.insert_new_library('foo-src', 'libfoo.so.0', 'foo')
395 self.assertThat(
396 "SELECT source_package_name, library, dependency FROM libdep",
397 ResultsIn(db, [('foo-src', 'libfoo.so.0', 'foo')]))
398
399 def test_double_insert(self):
400- db = PackageDatabase.create(':memory:')
401+ db = self.get_package_db()
402 db.insert_new_library('foo-src', 'libfoo.so.0', 'foo')
403 self.assertRaises(
404 IntegrityError,
405 db.insert_new_library, 'foo-src', 'libfoo.so.0', 'foo')
406
407 def test_differing_dependencies(self):
408- db = PackageDatabase.create(':memory:')
409+ db = self.get_package_db()
410 db.insert_new_library('foo-src', 'libfoo.so.0', 'foo')
411 db.insert_new_library('foo-src', 'libfoo.so.0', 'bar')
412 deps = db.get_dependencies('libfoo.so.0')
413 self.assertEqual(deps, set(['foo', 'bar']))
414
415 def test_get_dependencies(self):
416- db = PackageDatabase.create(':memory:')
417+ db = self.get_package_db()
418 db.insert_new_library('foo-src', 'libfoo.so.0', 'foo')
419 deps = db.get_dependencies('libfoo.so.0')
420 self.assertEqual(deps, set(['foo']))
421
422 def test_unknown_library(self):
423- db = PackageDatabase.create(':memory:')
424+ db = self.get_package_db()
425 deps = db.get_dependencies('libfoo.so.0')
426 self.assertEqual(deps, set())
427
428 def test_update_source_package(self):
429- db = PackageDatabase.create(':memory:')
430+ db = self.get_package_db()
431 db.update_source_package(
432 'foo', [[('libfoo.so.1', 'foo-bin')]])
433 deps = db.get_dependencies('libfoo.so.1')
434 self.assertEqual(deps, set(['foo-bin']))
435
436 def test_update_existing_source_package_no_libraries(self):
437- db = PackageDatabase.create(':memory:')
438+ db = self.get_package_db()
439 db.update_source_package('foo', [[('libfoo.so.1', 'foo-bin')]])
440 # Run again, this time with no symbols, representing that a newer
441 # version of the package no longer exports any libraries.
442@@ -79,7 +88,24 @@
443 deps = db.get_dependencies('libfoo.so.1')
444 self.assertEqual(deps, set())
445
446+ def write_database_config(self, **kwargs):
447+ config_path = os.path.expanduser(PackageDatabase.CONF_FILE)
448+ os.makedirs(os.path.dirname(config_path))
449+ with open(config_path, 'w') as f:
450+ f.write("[database]\n")
451+ for key, value in kwargs.items():
452+ f.write("%s=%s\n" % (key, value))
453+
454+ def test_get_db_info_from_config_sqlite(self):
455+ other_tempdir = self.useFixture(TempDir())
456+ expected_db_path = os.path.join(other_tempdir.path, 'db')
457+ self.write_database_config(db_type='sqlite', path=expected_db_path)
458+ connection_string, store_type = PackageDatabase.get_db_info_from_config()
459+ self.assertEqual('sqlite', store_type)
460+ self.assertEqual('sqlite:%s' % expected_db_path, connection_string)
461+
462 def test_default_create_from_env_var_db(self):
463+ self.useFixture(TempHomeDirFixture())
464 tempdir = self.useFixture(TempDir())
465 db_path = os.path.join(tempdir.path, 'db')
466 self.useFixture(
467@@ -88,6 +114,21 @@
468 self.assertThat(db_path, PathExists())
469
470 def test_default_create_no_env_var_db_set(self):
471+ self.useFixture(TempHomeDirFixture())
472 self.useFixture(
473 EnvironmentVariableFixture(PackageDatabase.ENV_VAR, None))
474 self.assertRaises(ValueError, PackageDatabase.create)
475+
476+ def test_get_db_info_from_config_postgres(self):
477+ expected_username = self.getUniqueString()
478+ expected_password = self.getUniqueString()
479+ expected_host = self.getUniqueString()
480+ expected_port = self.getUniqueString()
481+ self.write_database_config(db_type='postgres',
482+ username=expected_username, password=expected_password,
483+ host=expected_host, port=expected_port)
484+ connection_string, store_type = PackageDatabase.get_db_info_from_config()
485+ self.assertEqual('postgres', store_type)
486+ expected_connection_string = "postgres://%s:%s@%s:%s/pkgme_binary_dependencies" % (
487+ expected_username, expected_password, expected_host, expected_port)
488+ self.assertEqual(expected_connection_string, connection_string)
489
490=== modified file 'setup.py'
491--- setup.py 2011-11-23 12:17:04 +0000
492+++ setup.py 2011-12-05 21:01:26 +0000
493@@ -27,8 +27,10 @@
494 test_suite='devportalbinary.tests',
495 install_requires = [
496 'bzr',
497+ 'configglue',
498 'launchpadlib',
499 'pkgme',
500+ 'storm',
501 ],
502 entry_points = {
503 'console_scripts': [

Subscribers

People subscribed via source and target branches