Merge lp:~jml/pkgme-devportal/remove-package-database into lp:pkgme-devportal

Proposed by Jonathan Lange
Status: Merged
Merged at revision: 146
Proposed branch: lp:~jml/pkgme-devportal/remove-package-database
Merge into: lp:pkgme-devportal
Prerequisite: lp:~jml/pkgme-devportal/remove-database-code
Diff against target: 451 lines (+7/-363)
4 files modified
devportalbinary/database.py (+0/-122)
devportalbinary/testing.py (+3/-139)
devportalbinary/tests/test_database.py (+2/-102)
setup.py (+2/-0)
To merge this branch: bzr merge lp:~jml/pkgme-devportal/remove-package-database
Reviewer Review Type Date Requested Status
pkgme binary committers Pending
Review via email: mp+134102@code.launchpad.net

Commit message

Remove PackageDatabase and a bunch of test code.

Description of the change

Slowly killing things.

To post a comment you must log in.
178. By Jonathan Lange

More things that we don't need.

179. By Jonathan Lange

Merge changes from trunk.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'devportalbinary/database.py'
--- devportalbinary/database.py 2012-11-13 14:35:23 +0000
+++ devportalbinary/database.py 2012-11-13 14:35:23 +0000
@@ -1,135 +1,13 @@
1# Copyright 2011 Canonical Ltd. This software is licensed under the1# Copyright 2011 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4from storm.expr import And, Column, Select, Table
5from storm.locals import create_database, Store
6from storm.uri import URI as StormURI
7
8from .configuration import (4from .configuration import (
9 CONF_FILE_ENV_VAR,
10 get_config_file_path,
11 load_configuration,5 load_configuration,
12 )6 )
137
14from libdep_service_client.client import Client8from libdep_service_client.client import Client
159
1610
17class URI(StormURI):
18 """A stand-in for Storm's URI class.
19
20 This class implements the same interface as `storm.uri.URI`, except
21 that the constructor has a different signature. Storm's version takes
22 a string and parses it, this version can be used when you already
23 have a parsed version and just need to create the object.
24 """
25
26 # XXX: Only used by PackageDatabase, which is flagged for deletion.
27
28 def __init__(self, scheme=None, host=None, port=None, username=None,
29 password=None, database=None, options=None):
30 self.scheme = scheme
31 self.host = host
32 self.port = port
33 self.username = username
34 self.password = password
35 self.database = database
36 self.options = options
37 if self.options is None:
38 self.options = dict()
39
40
41class PackageDatabase(object):
42
43 # XXX: No longer used within pkgme-devportal
44
45 SQLITE = 'sqlite'
46 POSTGRES = 'postgres'
47
48 def __init__(self, store):
49 self._store = store
50
51 @classmethod
52 def _get_storm_sqlite_connection_uri(cls, opts):
53 raise ValueError(
54 "SQLite is no longer supported, you must migrate to postgresql.")
55
56 @classmethod
57 def _get_storm_postgres_connection_uri(cls, opts):
58 if not getattr(opts, 'database_db_name', None):
59 raise ValueError(
60 "Can't create database, no connection info available. "
61 "You must specify %s. Looked in %s. "
62 "Perhaps %s is set incorrectly?" % (
63 'db_name', get_config_file_path(), CONF_FILE_ENV_VAR))
64 return URI(scheme=opts.database_db_type,
65 username=opts.database_username,
66 password=opts.database_password,
67 host=opts.database_host,
68 port=opts.database_port,
69 database=opts.database_db_name)
70
71 @classmethod
72 def _get_storm_connection_uri(cls, opts):
73 if opts.database_db_type == cls.POSTGRES:
74 return cls._get_storm_postgres_connection_uri(opts)
75 elif opts.database_db_type == cls.SQLITE:
76 return cls._get_storm_sqlite_connection_uri(opts)
77 else:
78 raise AssertionError(
79 "Unsupported database: %s" % opts.database_db_type)
80
81 @classmethod
82 def get_db_info_from_config(cls, opts):
83 return cls._get_storm_connection_uri(opts)
84
85 @classmethod
86 def get_store_from_config(cls, opts):
87 """Create a storm store based on a config file.
88
89 This method will create a storm store based
90 on the information in ``~/.config/pkgme-binary/conf``
91
92 :return: a tuple of (store, store_type), where store_type
93 is one of cls.SQLITE or cls.POSTGRES, indicating what
94 is at the other end of the store.
95 """
96 connection_info = cls.get_db_info_from_config(opts)
97 database = create_database(connection_info)
98 return Store(database)
99
100 @classmethod
101 def from_options(cls, options):
102 return cls(cls.get_store_from_config(options))
103
104 def _get_query(self, library_names, arch):
105 return Select(
106 [Column('library'), Column('dependency')],
107 And(Column('architecture') == arch,
108 Column('library').is_in(map(unicode, library_names))),
109 Table('libdep'))
110
111 def get_multiple_dependencies(self, library_names, arch):
112 """Get the binary packages that provide libraries.
113
114 :return: (deps, missing), where ``deps`` is a dict mapping library
115 names to sets of packages that provide them, and ``missing`` is a
116 set of library names for which no dependencies could be found.
117 """
118 arch = unicode(arch)
119 result = self._store.execute(self._get_query(library_names, arch))
120 found = {}
121 for row in result:
122 [lib, dependency] = row
123 if lib in found:
124 found[lib].add(dependency)
125 else:
126 found[lib] = set([dependency])
127 return found
128
129 def close(self):
130 self._store.close()
131
132
133class LibdepServiceClient(object):11class LibdepServiceClient(object):
134 """Implements the read part of PackageDatabase's interface."""12 """Implements the read part of PackageDatabase's interface."""
13513
13614
=== modified file 'devportalbinary/testing.py'
--- devportalbinary/testing.py 2012-11-13 11:12:08 +0000
+++ devportalbinary/testing.py 2012-11-13 14:35:23 +0000
@@ -1,7 +1,6 @@
1# Copyright 2011-2012 Canonical Ltd. This software is licensed under the1# Copyright 2011-2012 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4from contextlib import closing
5import json4import json
6import os5import os
7import random6import random
@@ -21,11 +20,6 @@
21 Fixture,20 Fixture,
22 TempDir,21 TempDir,
23 )22 )
24from postgresfixture import ClusterFixture
25from storm.locals import create_database, Store
26from testresources import (
27 FixtureResource as _FixtureResource,
28 )
29from testtools import TestCase23from testtools import TestCase
30from treeshape import (24from treeshape import (
31 from_rough_spec,25 from_rough_spec,
@@ -33,11 +27,7 @@
33 )27 )
3428
35from devportalbinary.binary import MetadataBackend29from devportalbinary.binary import MetadataBackend
36from devportalbinary.database import (30from devportalbinary.database import LibdepServiceClient
37 LibdepServiceClient,
38 PackageDatabase,
39 URI,
40 )
4131
42from devportalbinary.configuration import CONF_FILE_ENV_VAR32from devportalbinary.configuration import CONF_FILE_ENV_VAR
4333
@@ -90,133 +80,6 @@
90 im.size[0], im.size[1], im.format))80 im.size[0], im.size[1], im.format))
9181
9282
93def get_db_schema_file_path(name):
94 return os.path.join(os.path.dirname(
95 os.path.abspath(__file__)), 'db', name)
96
97
98def get_db_schema_queries(filenames):
99 for filename in filenames:
100 path = get_db_schema_file_path(filename)
101 with open(path) as f:
102 yield f.read()
103
104
105class PostgresDatabaseFixture(Fixture):
106
107 def __init__(self):
108 super(PostgresDatabaseFixture, self).__init__()
109 self.db_name = "libdep"
110
111 def drop_db(self):
112 # stub suggests that dropping all tables would be quicker than
113 # dropping the db when the number of tables is small.
114 # select quote_ident(table_schema) || '.' ||
115 # quote_ident(table_name) from information_schema.tables
116 # WHERE table_schema = 'public';
117 self.cluster.dropdb(self.db_name)
118
119 def create_db(self):
120 self.cluster.createdb(self.db_name)
121 queries = [
122 'postgres_schema.sql',
123 'patch-00001.sql',
124 'patch-00002.sql',
125 ]
126 for patch in get_db_schema_queries(queries):
127 self._execute(patch)
128
129 def _execute(self, query):
130 with closing(self.cluster.connect(self.db_name)) as conn:
131 cur = conn.cursor()
132 cur.execute(query)
133 conn.commit()
134
135 def close_connection(self):
136 self.conn.close()
137
138 def open_connection(self):
139 db = create_database(URI(scheme='postgres',
140 host=self.cluster.datadir, database=self.db_name))
141 self.conn = Store(db)
142 self.addCleanup(self.close_connection)
143
144 def reset(self):
145 self.close_connection()
146 self.drop_db()
147 self.create_db()
148 self.open_connection()
149
150 def setUp(self):
151 super(PostgresDatabaseFixture, self).setUp()
152 self.tempdir = self.useFixture(TempDir())
153 self.cluster = self.useFixture(ClusterFixture(self.tempdir.path))
154 self.create_db()
155 self.open_connection()
156
157
158class FixtureResource(_FixtureResource):
159 """The built in FixtureResource doesn't get properly dirtied."""
160 # XXX: workaround for bug 1023423
161
162 def _get_dirty(self):
163 return True
164
165 def _set_dirty(self, new_val):
166 pass
167
168 _dirty = property(_get_dirty, _set_dirty)
169
170
171class PostgresDatabaseResource(FixtureResource):
172
173 def __init__(self):
174 fixture = PostgresDatabaseFixture()
175 super(PostgresDatabaseResource, self).__init__(fixture)
176
177 def reset(self, resource, result=None):
178 resource.reset()
179 return resource
180
181
182postgres_db_resource = PostgresDatabaseResource()
183
184
185class DatabaseConfig(Fixture):
186
187 def __init__(self, db_fixture):
188 super(DatabaseConfig, self).__init__()
189 self.db_fixture = db_fixture
190
191 def setUp(self):
192 super(DatabaseConfig, self).setUp()
193 self.useFixture(
194 ConfigSettings(
195 ('database', {'db_type': 'postgres',
196 'host': self.db_fixture.cluster.datadir,
197 'db_name': self.db_fixture.db_name,
198 })))
199
200
201class DatabaseFixture(Fixture):
202 """Create a temporary database and make it the default.
203
204 Don't use this twice within a test, otherwise you'll get confused.
205 """
206
207 def setUp(self):
208 super(DatabaseFixture, self).setUp()
209 pg_db = self.useFixture(PostgresDatabaseFixture())
210 self.useFixture(DatabaseConfig(pg_db))
211 self.db = PackageDatabase(pg_db.conn)
212 self.addCleanup(self.db.close)
213
214
215def ConfigFileFixture(location):
216 """Use a different configuration file."""
217 return EnvironmentVariableFixture(CONF_FILE_ENV_VAR, location)
218
219
220class ConfigSettings(Fixture):83class ConfigSettings(Fixture):
221 """Use a configuration file with different settings."""84 """Use a configuration file with different settings."""
22285
@@ -239,7 +102,8 @@
239 tempdir = self.useFixture(TempDir())102 tempdir = self.useFixture(TempDir())
240 config_file_path = os.path.join(tempdir.path, 'test.cfg')103 config_file_path = os.path.join(tempdir.path, 'test.cfg')
241 write_config_file(config_file_path, self._settings)104 write_config_file(config_file_path, self._settings)
242 self.useFixture(ConfigFileFixture(config_file_path))105 self.useFixture(
106 EnvironmentVariableFixture(CONF_FILE_ENV_VAR, config_file_path))
243107
244108
245class LibdepFixture(Fixture):109class LibdepFixture(Fixture):
246110
=== modified file 'devportalbinary/tests/test_database.py'
--- devportalbinary/tests/test_database.py 2012-11-13 14:35:23 +0000
+++ devportalbinary/tests/test_database.py 2012-11-13 14:35:23 +0000
@@ -1,112 +1,12 @@
1import os
21
3from fixtures import TempDir
4from testresources import ResourcedTestCase
5from testtools import TestCase2from testtools import TestCase
6from testtools.matchers import (
7 Equals,
8 Matcher,
9 )
103
11from devportalbinary.database import (4from devportalbinary.database import LibdepServiceClient
12 get_dependency_database,5from devportalbinary.testing import get_libdep_service_client
13 LibdepServiceClient,
14 load_configuration,
15 PackageDatabase,
16 )
17from devportalbinary.testing import (
18 ConfigFileFixture,
19 ConfigSettings,
20 get_libdep_service_client,
21 postgres_db_resource,
22 )
236
24from libdep_service_client.client import Client7from libdep_service_client.client import Client
258
269
27class ResultsIn(Matcher):
28
29 def __init__(self, db, rows):
30 self._db = db
31 self._rows = rows
32
33 def match(self, query):
34 # XXX: Abstraction violation
35 results = self._db._store.execute(query)
36 return Equals(self._rows).match(list(results))
37
38
39class TestDatabase(TestCase, ResourcedTestCase):
40
41 resources = [
42 ('db_fixture', postgres_db_resource),
43 ]
44
45 def get_package_db(self):
46 db = PackageDatabase(self.db_fixture.conn)
47 self.addCleanup(db.close)
48 return db
49
50 def test_unknown_library(self):
51 db = self.get_package_db()
52 deps = db.get_multiple_dependencies(['libfoo.so.0'], 'i386')
53 self.assertEqual(deps, {})
54
55 def test_close(self):
56 # Test that we can close the package db.
57 db = PackageDatabase(self.db_fixture.conn)
58 db.close()
59
60 def test_close_twice(self):
61 # Test that we can close the package db twice with no exception.
62 db = PackageDatabase(self.db_fixture.conn)
63 db.close()
64 db.close()
65
66
67class TestDatabaseConfiguration(TestCase):
68
69 def use_database_config(self, **db_settings):
70 return self.useFixture(ConfigSettings(('database', db_settings)))
71
72 def test_get_db_info_from_config_sqlite(self):
73 other_tempdir = self.useFixture(TempDir())
74 expected_db_path = os.path.join(other_tempdir.path, 'db')
75 self.use_database_config(db_type='sqlite', path=expected_db_path)
76 options = load_configuration()
77 self.assertRaises(ValueError, PackageDatabase.get_db_info_from_config,
78 options)
79
80 def test_remote_service(self):
81 base_url = 'http://example.com/libdep-service/'
82 self.use_database_config(db_type='libdep-service', base_url=base_url)
83 db = get_dependency_database()
84 self.assertIsInstance(db, LibdepServiceClient)
85 self.assertEqual(base_url, db._client.base_url)
86
87 def test_get_db_info_from_config_postgres(self):
88 expected_username = self.getUniqueString()
89 expected_password = self.getUniqueString()
90 expected_host = self.getUniqueString()
91 expected_port = self.getUniqueInteger()
92 expected_db_name = self.getUniqueString()
93
94 self.use_database_config(
95 db_type='postgres',
96 username=expected_username,
97 password=expected_password,
98 host=expected_host,
99 port=expected_port,
100 db_name=expected_db_name)
101 options = load_configuration()
102 uri = PackageDatabase.get_db_info_from_config(options)
103 self.assertEqual(expected_db_name, uri.database)
104 self.assertEqual(expected_port, uri.port)
105 self.assertEqual(expected_host, uri.host)
106 self.assertEqual(expected_password, uri.password)
107 self.assertEqual(expected_username, uri.username)
108
109
110class TestLibdepServiceClient(TestCase):10class TestLibdepServiceClient(TestCase):
11111
112 TEST_DATA = [('libfoo', {'i386': {'libfoo': 'libfoo-bin'}})]12 TEST_DATA = [('libfoo', {'i386': {'libfoo': 'libfoo-bin'}})]
11313
=== modified file 'setup.py'
--- setup.py 2012-11-13 14:35:23 +0000
+++ setup.py 2012-11-13 14:35:23 +0000
@@ -18,6 +18,8 @@
18 )18 )
19from setuptools import setup, find_packages19from setuptools import setup, find_packages
2020
21# XXX: Need to do a trawl to see if we are depending on things that we are no
22# longer using.
2123
22__version__ = get_version('devportalbinary/__init__.py')24__version__ = get_version('devportalbinary/__init__.py')
2325

Subscribers

People subscribed via source and target branches