Passed
Push — master ( 34295d...fa6286 )
by Dominik
14:38
created

OSMAlchemyModelTestsSQLite   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 9
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 2
c 2
b 0
f 0
dl 0
loc 9
rs 10
1
#!/usr/bin/env python
2
# ~*~ coding: utf-8 ~*~
3
#-
4
# OSMAlchemy - OpenStreetMap to SQLAlchemy bridge
5
# Copyright (c) 2016 Dominik George <[email protected]>
6
#
7
# Permission is hereby granted, free of charge, to any person obtaining a copy
8
# of this software and associated documentation files (the "Software"), to deal
9
# in the Software without restriction, including without limitation the rights
10
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
# copies of the Software, and to permit persons to whom the Software is
12
# furnished to do so, subject to the following conditions:
13
#
14
# The above copyright notice and this permission notice shall be included in all
15
# copies or substantial portions of the Software.
16
#
17
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
# SOFTWARE.
24
#
25
# Alternatively, you are free to use OSMAlchemy under Simplified BSD, The
26
# MirOS Licence, GPL-2+, LGPL-2.1+, AGPL-3+ or the same terms as Python
27
# itself.
28
29
""" Tests concerning the OSM data model implementation. """
30
31
# Standard unit testing framework
32
import unittest
33
34
# We want to profile test cases
35
import time
36
37
# Helper libraries for different database engines
38
from testing.mysqld import MysqldFactory
39
from testing.postgresql import PostgresqlFactory
40
41
# Module to be tested
42
from osmalchemy import OSMAlchemy
43
44
# SQLAlchemy for working with model and data
45
from sqlalchemy import create_engine
46
from sqlalchemy.ext.declarative import declarative_base
47
from sqlalchemy.orm import sessionmaker
48
49
# Create database engine factories to enable caching
50
Postgresql = PostgresqlFactory(cache_initialized_db=True)
51
Mysqld = MysqldFactory(cache_initialized_db=True)
52
53
# Dictionary to store profiling information about tests
54
profile = {}
55
56
def tearDownModule():
57
    """ Global test suite tear down code """
58
59
    # Purge caches of database engines
60
    Postgresql.clear_cache()
61
    Mysqld.clear_cache()
62
63
    # Print profiling info
64
    print("Database model test times")
65
    print("=========================")
66
    print("")
67
    for suite in profile:
68
        print("%8.3f s\t%s" % (sum([profile[suite][test] for test in profile[suite]]), suite))
69
        for test in profile[suite]:
70
            print("\t%8.3f s\t%s" % (profile[suite][test], test))
71
72
class OSMAlchemyModelTests(object):
73
    """ Incomplete base class for common test routines.
74
75
    Subclassed in engine-dependent test classes.
76
    """
77
78
    def setUp(self):
79
        if not self.__class__.__name__ in profile:
80
            profile[self.__class__.__name__] = {}
81
        profile[self.__class__.__name__][self.id().split(".")[-1]] = time.time()
82
83
        self.base = declarative_base(bind=self.engine)
84
        self.osmalchemy = OSMAlchemy(self.base)
85
        self.base.metadata.create_all()
86
        self.session = sessionmaker(bind=self.engine)()
87
88
    def tearDown(self):
89
        self.session.close()
90
        self.engine.dispose()
91
92
        profile[self.__class__.__name__][self.id().split(".")[-1]] -= time.time()
93
        profile[self.__class__.__name__][self.id().split(".")[-1]] *= -1
94
95
    def test_create_node(self):
96
        # Create node
97
        node = self.osmalchemy.Node()
98
        node.latitude = 51.0
99
        node.longitude = 7.0
100
101
        # Store node
102
        self.session.add(node)
103
        self.session.commit()
104
105
        # Query for node and check
106
        node = self.session.query(self.osmalchemy.Node).filter_by(latitude=51.0).first()
107
        self.assertEqual(node.latitude, 51.0)
108
        self.assertEqual(node.longitude, 7.0)
109
        self.assertEqual(len(node.tags), 0)
110
111
    def test_create_node_with_tags(self):
112
        # Create node and tags
113
        node = self.osmalchemy.Node(51.0, 7.0)
114
        node.tags = {u"name": u"test", u"foo": u"bar"}
115
116
        # Store everything
117
        self.session.add(node)
118
        self.session.commit()
119
120
        # Query for node and check
121
        node = self.session.query(self.osmalchemy.Node).filter_by(latitude=51.0).first()
122
        self.assertEqual(node.latitude, 51.0)
123
        self.assertEqual(node.longitude, 7.0)
124
        self.assertEqual(len(node.tags), 2)
125
        self.assertEqual(node.tags[u"name"], u"test")
126
        self.assertEqual(node.tags[u"foo"], u"bar")
127
128
    def test_create_way_with_nodes(self):
129
        # Create way and nodes
130
        way = self.osmalchemy.Way()
131
        way.nodes = [self.osmalchemy.Node(51.0, 7.0),
132
                     self.osmalchemy.Node(51.1, 7.1),
133
                     self.osmalchemy.Node(51.2, 7.2),
134
                     self.osmalchemy.Node(51.3, 7.3),
135
                     self.osmalchemy.Node(51.4, 7.4)]
136
137
        # Store everything
138
        self.session.add(way)
139
        self.session.commit()
140
141
        # Query for way and check
142
        way = self.session.query(self.osmalchemy.Way).first()
143
        self.assertEqual(len(way.nodes), 5)
144
        self.assertEqual((way.nodes[0].latitude, way.nodes[0].longitude), (51.0, 7.0))
145
        self.assertEqual((way.nodes[1].latitude, way.nodes[1].longitude), (51.1, 7.1))
146
        self.assertEqual((way.nodes[2].latitude, way.nodes[2].longitude), (51.2, 7.2))
147
        self.assertEqual((way.nodes[3].latitude, way.nodes[3].longitude), (51.3, 7.3))
148
        self.assertEqual((way.nodes[4].latitude, way.nodes[4].longitude), (51.4, 7.4))
149
150
    def test_create_way_with_nodes_and_tags(self):
151
        # Create way and nodes
152
        way = self.osmalchemy.Way()
153
        way.nodes = [self.osmalchemy.Node(51.0, 7.0),
154
                     self.osmalchemy.Node(51.1, 7.1),
155
                     self.osmalchemy.Node(51.2, 7.2),
156
                     self.osmalchemy.Node(51.3, 7.3),
157
                     self.osmalchemy.Node(51.4, 7.4)]
158
        way.tags = {u"name": u"Testway", u"foo": u"bar"}
159
160
        # Store everything
161
        self.session.add(way)
162
        self.session.commit()
163
164
        # Query for way and check
165
        way = self.session.query(self.osmalchemy.Way).first()
166
        self.assertEqual(len(way.nodes), 5)
167
        self.assertEqual((way.nodes[0].latitude, way.nodes[0].longitude), (51.0, 7.0))
168
        self.assertEqual((way.nodes[1].latitude, way.nodes[1].longitude), (51.1, 7.1))
169
        self.assertEqual((way.nodes[2].latitude, way.nodes[2].longitude), (51.2, 7.2))
170
        self.assertEqual((way.nodes[3].latitude, way.nodes[3].longitude), (51.3, 7.3))
171
        self.assertEqual((way.nodes[4].latitude, way.nodes[4].longitude), (51.4, 7.4))
172
        self.assertEqual(len(way.tags), 2)
173
        self.assertEqual(way.tags[u"name"], u"Testway")
174
        self.assertEqual(way.tags[u"foo"], u"bar")
175
176
    def test_create_way_with_nodes_and_tags_and_tags_on_node(self):
177
        # Create way and nodes
178
        way = self.osmalchemy.Way()
179
        way.nodes = [self.osmalchemy.Node(51.0, 7.0),
180
                     self.osmalchemy.Node(51.1, 7.1),
181
                     self.osmalchemy.Node(51.2, 7.2),
182
                     self.osmalchemy.Node(51.3, 7.3),
183
                     self.osmalchemy.Node(51.4, 7.4)]
184
        way.tags = {u"name": u"Testway", u"foo": u"bar"}
185
        way.nodes[2].tags = {u"name": u"Testampel", u"foo": u"bar"}
186
187
        # Store everything
188
        self.session.add(way)
189
        self.session.commit()
190
191
        # Query for way and check
192
        way = self.session.query(self.osmalchemy.Way).first()
193
        self.assertEqual(len(way.nodes), 5)
194
        self.assertEqual((way.nodes[0].latitude, way.nodes[0].longitude), (51.0, 7.0))
195
        self.assertEqual((way.nodes[1].latitude, way.nodes[1].longitude), (51.1, 7.1))
196
        self.assertEqual((way.nodes[2].latitude, way.nodes[2].longitude), (51.2, 7.2))
197
        self.assertEqual((way.nodes[3].latitude, way.nodes[3].longitude), (51.3, 7.3))
198
        self.assertEqual((way.nodes[4].latitude, way.nodes[4].longitude), (51.4, 7.4))
199
        self.assertEqual(len(way.tags), 2)
200
        self.assertEqual(way.tags[u"name"], u"Testway")
201
        self.assertEqual(way.tags[u"foo"], u"bar")
202
        self.assertEqual(len(way.nodes[2].tags), 2)
203
        self.assertEqual(way.nodes[2].tags[u"name"], u"Testampel")
204
        self.assertEqual(way.nodes[2].tags[u"foo"], u"bar")
205
206
    def test_create_relation_with_nodes(self):
207
        # Create way and add nodes
208
        relation = self.osmalchemy.Relation()
209
        relation.members = [(self.osmalchemy.Node(51.0, 7.0), u""),
210
                            (self.osmalchemy.Node(51.1, 7.1), u""),
211
                            (self.osmalchemy.Node(51.2, 7.2), u""),
212
                            (self.osmalchemy.Node(51.3, 7.3), u""),
213
                            (self.osmalchemy.Node(51.4, 7.4), u"")]
214
215
        # Store everything
216
        self.session.add(relation)
217
        self.session.commit()
218
219
        # Query for way and check
220
        relation = self.session.query(self.osmalchemy.Relation).first()
221
        self.assertEqual((relation.members[0][0].latitude, relation.members[0][0].longitude),
222
                         (51.0, 7.0))
223
        self.assertEqual((relation.members[1][0].latitude, relation.members[1][0].longitude),
224
                         (51.1, 7.1))
225
        self.assertEqual((relation.members[2][0].latitude, relation.members[2][0].longitude),
226
                         (51.2, 7.2))
227
        self.assertEqual((relation.members[3][0].latitude, relation.members[3][0].longitude),
228
                         (51.3, 7.3))
229
        self.assertEqual((relation.members[4][0].latitude, relation.members[4][0].longitude),
230
                         (51.4, 7.4))
231
232
    def test_create_relation_with_nodes_and_ways(self):
233
        # Create way and add nodes and ways
234
        relation = self.osmalchemy.Relation()
235
        relation.members = [(self.osmalchemy.Node(51.0, 7.0), u''),
236
                            (self.osmalchemy.Way(), u''),
237
                            (self.osmalchemy.Node(51.1, 7.1), u''),
238
                            (self.osmalchemy.Way(), u''),
239
                            (self.osmalchemy.Node(51.2, 7.2), u''),
240
                            (self.osmalchemy.Way(), u''),
241
                            (self.osmalchemy.Node(51.3, 7.3), u''),
242
                            (self.osmalchemy.Way(), u''),
243
                            (self.osmalchemy.Node(51.4, 7.4), u'')]
244
        relation.members[3][0].nodes.append(relation.members[8][0])
245
246
        # Store everything
247
        self.session.add(relation)
248
        self.session.commit()
249
250
        # Query for way and check
251
        relation = self.session.query(self.osmalchemy.Relation).first()
252
        self.assertEqual((relation.members[0][0].latitude, relation.members[0][0].longitude),
253
                         (51.0, 7.0))
254
        self.assertEqual((relation.members[2][0].latitude, relation.members[2][0].longitude),
255
                         (51.1, 7.1))
256
        self.assertEqual((relation.members[4][0].latitude, relation.members[4][0].longitude),
257
                         (51.2, 7.2))
258
        self.assertEqual((relation.members[6][0].latitude, relation.members[6][0].longitude),
259
                         (51.3, 7.3))
260
        self.assertEqual((relation.members[8][0].latitude, relation.members[8][0].longitude),
261
                         (51.4, 7.4))
262
        self.assertIs(relation.members[3][0].nodes[0], relation.members[8][0])
263
264
    def test_create_relation_with_nodes_and_ways_and_tags_everywhere(self):
265
        # Create way and add nodes and ways
266
        relation = self.osmalchemy.Relation()
267
        relation.members = [(self.osmalchemy.Node(51.0, 7.0), u''),
268
                            (self.osmalchemy.Way(), u''),
269
                            (self.osmalchemy.Node(51.1, 7.1), u''),
270
                            (self.osmalchemy.Way(), u''),
271
                            (self.osmalchemy.Node(51.2, 7.2), u''),
272
                            (self.osmalchemy.Way(), u''),
273
                            (self.osmalchemy.Node(51.3, 7.3), u''),
274
                            (self.osmalchemy.Way(), u''),
275
                            (self.osmalchemy.Node(51.4, 7.4), u'')]
276
        relation.tags = {u"name": u"weirdest roads in Paris"}
277
        relation.members[3][0].nodes.append(relation.members[8][0])
278
        relation.members[7][0].tags = {u"foo": u"bar", u"bang": u"baz"}
279
        relation.members[8][0].tags = {u"name": u"Doppelknoten"}
280
281
        # Store everything
282
        self.session.add(relation)
283
        self.session.commit()
284
285
        # Query for way and check
286
        relation = self.session.query(self.osmalchemy.Relation).first()
287
        self.assertEqual((relation.members[0][0].latitude, relation.members[0][0].longitude),
288
                         (51.0, 7.0))
289
        self.assertEqual((relation.members[2][0].latitude, relation.members[2][0].longitude),
290
                         (51.1, 7.1))
291
        self.assertEqual((relation.members[4][0].latitude, relation.members[4][0].longitude),
292
                         (51.2, 7.2))
293
        self.assertEqual((relation.members[6][0].latitude, relation.members[6][0].longitude),
294
                         (51.3, 7.3))
295
        self.assertEqual((relation.members[8][0].latitude, relation.members[8][0].longitude),
296
                         (51.4, 7.4))
297
        self.assertIs(relation.members[3][0].nodes[0], relation.members[8][0])
298
        self.assertEqual(relation.tags[u"name"], u"weirdest roads in Paris")
299
        self.assertEqual(relation.members[7][0].tags[u"foo"], u"bar")
300
        self.assertEqual(relation.members[7][0].tags[u"bang"], u"baz")
301
        self.assertEqual(relation.members[8][0].tags, relation.members[3][0].nodes[0].tags)
302
303
class OSMAlchemyModelTestsSQLite(OSMAlchemyModelTests, unittest.TestCase):
304
    """ Tests run with SQLite """
305
306
    def setUp(self):
307
        self.engine = create_engine("sqlite:///:memory:")
308
        OSMAlchemyModelTests.setUp(self)
309
310
    def tearDown(self):
311
        OSMAlchemyModelTests.tearDown(self)
312
313
class OSMAlchemyModelTestsPostgres(OSMAlchemyModelTests, unittest.TestCase):
314
    """ Tests run with PostgreSQL """
315
316
    def setUp(self):
317
        self.postgresql = Postgresql()
318
        self.engine = create_engine(self.postgresql.url())
319
        OSMAlchemyModelTests.setUp(self)
320
321
    def tearDown(self):
322
        self.postgresql.stop()
323
        OSMAlchemyModelTests.tearDown(self)
324
325
class OSMAlchemyModelTestsMySQL(OSMAlchemyModelTests, unittest.TestCase):
326
    """ Tests run with MySQL """
327
328
    def setUp(self):
329
        self.mysql = Mysqld()
330
        self.engine = create_engine(self.mysql.url() + "?charset=utf8mb4")
331
        OSMAlchemyModelTests.setUp(self)
332
333
    def tearDown(self):
334
        self.mysql.stop()
335
        OSMAlchemyModelTests.tearDown(self)
336
337
# Make runnable as standalone script
338
if __name__ == "__main__":
339
    unittest.main()
340