/[thuban]/branches/WIP-pyshapelib-bramz/test/test_load.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/test/test_load.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1931 - (hide annotations)
Tue Nov 11 13:24:45 2003 UTC (21 years, 3 months ago) by bh
Original Path: trunk/thuban/test/test_load.py
File MIME type: text/x-python
File size: 29225 byte(s)
(TestSingleLayer.test_leak): New. test for the
resource leak in load_session

1 bh 765 # Copyright (c) 2002, 2003 by Intevation GmbH
2 bh 292 # Authors:
3     # Bernhard Herzog <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8     """
9     Test loading a thuban session from a file
10 bh 1247
11     The tests in this file (test_load.py) are always be the tests for the
12     current version of the thuban file format. Tests for older versions can
13     be found in the version specific test modules, e.g. test_load_0_2 for
14     files created by Thuban 0.2.
15    
16     Maintenance of the test cases:
17    
18     When during a development period the file format is changed with respect
19     to the last released version for the first, the tests here should be
20 bh 1257 copied to the version specific test file. The round-trip tests which
21     save the session again and compare the XML files should not be copied
22     over as they only make sense here to make sure th that the files checked
23     here are actually ones that may have been written by the current thuban
24     version.
25 bh 292 """
26    
27     __version__ = "$Revision$"
28     # $Source$
29     # $Id$
30    
31     import os
32     import unittest
33    
34     import support
35     support.initthuban()
36    
37 bh 1646 import postgissupport
38 bh 1257 from xmlsupport import sax_eventlist
39 bh 1268
40     import dbflib
41    
42 bh 1257 from Thuban.Model.save import save_session
43 bh 1646 from Thuban.Model.load import load_session, parse_color, LoadError, \
44     LoadCancelled
45 jonathan 1350 from Thuban.Model.color import Transparent
46 jonathan 684 from Thuban.Model.classification import ClassGroupProperties, ClassGroupRange,\
47     ClassGroupSingleton, ClassGroupDefault
48 bh 1646 from Thuban.Model.postgisdb import ConnectionError
49 jonathan 684
50 bh 292 def filenames_equal(name1, name2):
51     """Return true if the filenames name1 and name2 are equal.
52    
53     On systems where it is available, simply use os.path.samefile,
54     otherwise return whether the normalized versions of the filenames
55     according to os.path.normpath are equal.
56     """
57     if hasattr(os.path, "samefile"):
58     return os.path.samefile(name1, name2)
59     return os.path.normpath(name1) == os.path.normpath(name2)
60    
61    
62 bh 957
63     class LoadSessionTest(support.FileLoadTestCase):
64    
65     """Base class for .thuban file loading tests
66    
67     Basically the same as the FileLoadTestCase, except that all tests
68     use the '.thuban' extension by default and that setUp and tearDown
69     handle sessions.
70     """
71    
72     file_extension = ".thuban"
73    
74     def setUp(self):
75     """Create the test files"""
76     support.FileLoadTestCase.setUp(self)
77     self.session = None
78    
79     def tearDown(self):
80     if self.session is not None:
81     self.session.Destroy()
82     self.session = None
83    
84 bh 1268
85 bh 1846 dtd = "http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
86 bh 1268 thubanids = [((dtd, n), (None, "id")) for n in
87     ["fileshapesource", "filetable", "jointable",
88     "derivedshapesource"]]
89     thubanidrefs = [((dtd, n), (None, m)) for n, m in
90     [("layer", "shapestore"),
91     ("jointable", "left"),
92     ("jointable", "right"),
93     ("derivedshapesource", "table"),
94     ("derivedshapesource", "shapesource")]]
95 bh 1683 filenames = [((dtd, n), (None, m)) for n, m in
96     [("fileshapesource", "filename"),
97     ("rasterlayer", "filename"),
98     ("filetable", "filename")]]
99 bh 1268 del n, m, dtd
100    
101 bh 1257 def check_format(self):
102     """Check whether the file we loaded from matches the one that
103     would be written. Call this from each test case after loading
104     the session
105     """
106     filename = self.temp_file_name(self.id() + ".roundtrip.thuban")
107     save_session(self.session, filename)
108 bh 1268 el1 = sax_eventlist(filename = filename, ids = self.thubanids,
109 bh 1683 idrefs = self.thubanidrefs,
110     filenames = self.filenames)
111 bh 1268 el2 = sax_eventlist(filename = self.filename(), ids = self.thubanids,
112 bh 1683 idrefs = self.thubanidrefs,
113     filenames = self.filenames)
114 bh 1268 if 0:
115     for a, b in zip(el1, el2):
116     print a != b and "***************" or ""
117     print a
118     print b
119     self.assertEquals(el1, el2,
120     "loaded file not equivalent to the saved file")
121 bh 957
122 bh 1257
123 bh 957 class ClassificationTest(LoadSessionTest):
124    
125     """
126     Base class for tests that do some detailed checking of classifications
127     """
128    
129     def TestLayers(self, layers, expected):
130     TITLE = 0
131     NUM_GROUPS = 1
132     CLASSES = 2
133     GROUP_TYPE = 0
134     GROUP_DATA = 1
135     GROUP_LABEL = 2
136     GROUP_PROPS = 3
137    
138     eq = self.assertEquals
139    
140     eq(len(layers), len(expected))
141    
142     for layer, data in zip(layers, expected):
143     eq(layer.Title(), data[TITLE])
144    
145     clazz = layer.GetClassification()
146     eq(clazz.GetNumGroups(), data[NUM_GROUPS])
147     eq(clazz.GetNumGroups() + 1, len(data[CLASSES]))
148    
149     i = 0
150     for group in clazz:
151     props = ClassGroupProperties()
152     props.SetLineColor(
153     parse_color(data[CLASSES][i][GROUP_PROPS][0]))
154     props.SetLineWidth(data[CLASSES][i][GROUP_PROPS][1])
155     props.SetFill(
156     parse_color(data[CLASSES][i][GROUP_PROPS][2]))
157    
158     if data[CLASSES][i][GROUP_TYPE] == "default":
159     g = ClassGroupDefault(props, data[CLASSES][i][GROUP_LABEL])
160     elif data[CLASSES][i][GROUP_TYPE] == "range":
161 jonathan 1357 g = ClassGroupRange((data[CLASSES][i][GROUP_DATA][0],
162     data[CLASSES][i][GROUP_DATA][1]),
163 bh 957 props, data[CLASSES][i][GROUP_LABEL])
164     elif data[CLASSES][i][GROUP_TYPE] == "single":
165     g = ClassGroupSingleton(data[CLASSES][i][GROUP_DATA],
166     props, data[CLASSES][i][GROUP_LABEL])
167    
168     eq(group, g)
169    
170     i += 1
171    
172    
173    
174     class TestSingleLayer(LoadSessionTest):
175    
176 bh 1846 # Note: The use of &amp; and non-ascii characters is deliberate. We
177     # want to test whether the loading code handles that correctly.
178 bh 957 file_contents = '''\
179 bh 292 <?xml version="1.0" encoding="UTF-8"?>
180 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
181     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
182 bh 1848 title="Stra\xc3\x9fen &amp; Landmarken">
183 bh 1268 <fileshapesource filetype="shapefile" id="D1"
184     filename="../../Data/iceland/political.shp"/>
185 bh 1848 <map title="\xc3\x9cbersicht">
186 bh 1846 <projection epsg="32627" name="WGS 84 / UTM zone 27N">
187     <parameter value="datum=WGS84"/>
188     <parameter value="ellps=WGS84"/>
189 bh 1268 <parameter value="proj=utm"/>
190 bh 1846 <parameter value="units=m"/>
191     <parameter value="zone=27"/>
192 bh 1268 </projection>
193     <layer shapestore="D1" visible="true"
194 bh 1848 stroke="#000000" title="K\xc3\xbcste" stroke_width="1"
195 bh 1268 fill="None"/>
196     </map>
197 bh 292 </session>
198     '''
199    
200 bh 957 def test(self):
201     """Load a session with a single map with a single layer"""
202     eq = self.assertEquals
203     session = load_session(self.filename())
204     self.session = session
205    
206     # Check the title
207 bh 1848 eq(session.Title(), "Stra\xdfen & Landmarken")
208 bh 957
209     # the session has one map.
210     maps = session.Maps()
211     eq(len(maps), 1)
212    
213     # Check the map's attributes
214     map = maps[0]
215 bh 1848 eq(map.Title(), "\xdcbersicht")
216 bh 1846 proj = map.GetProjection()
217     eq(proj.GetName(), "WGS 84 / UTM zone 27N")
218     eq(proj.EPSGCode(), "32627")
219     params = proj.GetAllParameters()
220     params.sort()
221     eq(params, ["datum=WGS84", "ellps=WGS84", "proj=utm", "units=m",
222     "zone=27"])
223 bh 957
224     # the map has a single layer
225     layers = map.Layers()
226     eq(len(layers), 1)
227    
228     # Check the layer attributes
229     layer = layers[0]
230 bh 1848 eq(layer.Title(), "K\xfcste")
231 bh 1219 self.failUnless(filenames_equal(layer.ShapeStore().FileName(),
232 bh 957 os.path.join(self.temp_dir(),
233     os.pardir, os.pardir,
234     "Data", "iceland",
235     "political.shp")))
236 jonathan 1347 eq(layer.GetClassification().GetDefaultFill(), Transparent)
237 bh 957 eq(layer.GetClassification().GetDefaultLineColor().hex(), "#000000")
238     eq(layer.Visible(), True)
239    
240 bh 1257 self.check_format()
241    
242 bh 957 self.session.Destroy()
243     self.session = None
244    
245 bh 1931 def test_leak(self):
246     """Test load_session for resource leaks
247 bh 957
248 bh 1931 The load_session function had a resource leak in that it created
249     cyclic references. The objects would have been eventually
250     collected by the garbage collector but too late. One symptom is
251     that when layers are removed so that the last normal reference
252     owned indirectly by the session to a shape store goes away, the
253     shape store is not actually removed from the session even though
254     the session only keeps weak references because there are still
255     references owned by the cyclic garbage.
256     """
257     session = load_session(self.filename())
258     self.session = session
259    
260     # sanity check
261     self.assertEquals(len(session.ShapeStores()), 1)
262    
263     # remove the map. The shapestore should go away too
264     session.RemoveMap(session.Maps()[0])
265     self.assertEquals(len(session.ShapeStores()), 0)
266    
267    
268 bh 957 class TestLayerVisibility(LoadSessionTest):
269    
270     file_contents = '''\
271 jonathan 690 <?xml version="1.0" encoding="UTF-8"?>
272 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
273     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
274 bh 1268 title="single map&amp;layer">
275     <fileshapesource filetype="shapefile" id="D1"
276     filename="../../Data/iceland/political.shp"/>
277     <map title="Test Map">
278     <projection name="Unknown">
279     <parameter value="zone=26"/>
280     <parameter value="proj=utm"/>
281     <parameter value="ellps=clrk66"/>
282     </projection>
283     <layer shapestore="D1" visible="false" stroke="#000000"
284     title="My Layer" stroke_width="1" fill="None"/>
285 bh 957 </map>
286     </session>
287     '''
288    
289     def test(self):
290     """Test that the visible flag is correctly loaded for a layer."""
291     eq = self.assertEquals
292     session = load_session(self.filename())
293     self.session = session
294     maps = session.Maps()
295     eq(len(maps), 1)
296     map = maps[0]
297     layers = map.Layers()
298     eq(len(layers), 1)
299     layer = layers[0]
300    
301     eq(layer.Visible(), False)
302    
303 bh 1257 self.check_format()
304 bh 957
305    
306     class TestClassification(ClassificationTest):
307    
308     file_contents = '''\
309     <?xml version="1.0" encoding="UTF-8"?>
310     <!DOCTYPE session SYSTEM "thuban.dtd">
311     <session title="single map&amp;layer">
312     <map title="Test Map">
313     <projection>
314     <parameter value="zone=26"/>
315     <parameter value="proj=utm"/>
316     <parameter value="ellps=clrk66"/>
317     </projection>
318     <layer title="My Layer" stroke_width="1" fill="None"
319     filename="../../Data/iceland/political.shp"
320 jonathan 690 stroke="#000000">
321     <classification field="POPYREG" field_type="string">
322     <clnull>
323     <cldata stroke="#000000" stroke_width="1" fill="None"/>
324     </clnull>
325     <clpoint value="1">
326     <cldata stroke="#000000" stroke_width="2" fill="None"/>
327     </clpoint>
328     <clpoint value="1">
329     <cldata stroke="#000000" stroke_width="10" fill="None"/>
330     </clpoint>
331 bh 1417 <clpoint value="\xc3\xa4\xc3\xb6\xc3\xbc"
332     label="\xc3\x9cml\xc3\xa4uts">
333     <cldata fill="None" stroke="#000000" stroke_width="1"/>
334     </clpoint>
335 jonathan 690 </classification>
336     </layer>
337     <layer title="My Layer 2" stroke_width="1" fill="None"
338     filename="../../Data/iceland/political.shp"
339     stroke="#000000">
340     <classification field="AREA" field_type="double">
341     <clnull>
342     <cldata stroke="#000000" stroke_width="2" fill="None"/>
343     </clnull>
344     <clrange min="0" max="1">
345 jonathan 692 <cldata stroke="#111111" stroke_width="1" fill="None"/>
346 jonathan 690 </clrange>
347     <clpoint value=".5">
348 jonathan 692 <cldata stroke="#000000" stroke_width="1" fill="#111111"/>
349 jonathan 690 </clpoint>
350     <clrange min="-1" max="0">
351     <cldata stroke="#000000" stroke_width="1" fill="None"/>
352     </clrange>
353     <clpoint value="-.5">
354     <cldata stroke="#000000" stroke_width="1" fill="None"/>
355     </clpoint>
356     </classification>
357     </layer>
358     </map>
359     </session>
360     '''
361 bh 292
362 bh 957 def test(self):
363 bh 1247 """Load a Thuban session with a map and classified layers."""
364 bh 957 session = load_session(self.filename())
365     self.session = session
366    
367     map = self.session.Maps()[0] # only one map in the sample
368    
369 bh 1417 expected = [("My Layer", 3,
370 bh 957 [("default", (), "",
371     ("#000000", 1, "None")),
372     ("single", "1", "",
373     ("#000000", 2, "None")),
374     ("single", "1", "",
375 bh 1417 ("#000000", 10, "None")),
376     ("single", "\xe4\xf6\xfc", "\xdcml\xe4uts",
377     ("#000000", 1, "None"))]),
378 bh 957 ("My Layer 2", 4,
379     [("default", (), "",
380     ("#000000", 2, "None")),
381     ("range", (0, 1), "",
382     ("#111111", 1, "None")),
383     ("single", .5, "",
384     ("#000000", 1, "#111111")),
385     ("range", (-1, 0), "",
386     ("#000000", 1, "None")),
387     ("single", -.5, "",
388     ("#000000", 1, "None"))])]
389    
390     self.TestLayers(map.Layers(), expected)
391    
392    
393     class TestLabels(ClassificationTest):
394    
395     file_contents = '''\
396 jonathan 690 <?xml version="1.0" encoding="UTF-8"?>
397 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
398     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
399 bh 1268 title="single map&amp;layer">
400     <fileshapesource filetype="shapefile" id="D1"
401     filename="../../Data/iceland/political.shp"/>
402     <map title="Test Map">
403     <projection name="Unknown">
404     <parameter value="zone=26"/>
405     <parameter value="proj=utm"/>
406     <parameter value="ellps=clrk66"/>
407     </projection>
408     <layer shapestore="D1" visible="true" stroke="#000000"
409     title="My Layer" stroke_width="1" fill="None">
410 jonathan 690 <classification field="POPYREG" field_type="string">
411     <clnull label="hallo">
412     <cldata stroke="#000000" stroke_width="1" fill="None"/>
413     </clnull>
414     <clpoint label="welt" value="1">
415     <cldata stroke="#000000" stroke_width="2" fill="None"/>
416     </clpoint>
417     </classification>
418     </layer>
419     </map>
420     </session>
421     '''
422    
423 bh 957 def test(self):
424     """Load a session and test for reading the group labels."""
425     eq = self.assertEquals
426     session = load_session(self.filename())
427     self.session = session
428    
429     map = self.session.Maps()[0] # only one map in the sample
430    
431     expected = [("My Layer", 1,
432     [("default", (), "hallo",
433     ("#000000", 1, "None")),
434     ("single", "1", "welt",
435     ("#000000", 2, "None"))])]
436    
437     self.TestLayers(map.Layers(), expected)
438 bh 1257 self.check_format()
439 bh 957
440    
441     class TestLayerProjection(LoadSessionTest):
442    
443     file_contents = '''\
444 jonathan 746 <?xml version="1.0" encoding="UTF-8"?>
445 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
446     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
447 bh 1268 title="single map&amp;layer">
448     <fileshapesource filetype="shapefile" id="D2"
449     filename="../../Data/iceland/roads-line.shp"/>
450     <fileshapesource filetype="shapefile" id="D4"
451     filename="../../Data/iceland/political.shp"/>
452     <map title="Test Map">
453     <projection name="Unknown">
454     <parameter value="zone=26"/>
455     <parameter value="proj=utm"/>
456     <parameter value="ellps=clrk66"/>
457     </projection>
458     <layer shapestore="D4" visible="true" stroke="#000000"
459     title="My Layer" stroke_width="1" fill="None">
460     <projection name="hello">
461     <parameter value="zone=13"/>
462     <parameter value="proj=tmerc"/>
463     <parameter value="ellps=clrk66"/>
464     </projection>
465 jonathan 746 <classification field="POPYREG" field_type="string">
466     <clnull label="hallo">
467     <cldata stroke="#000000" stroke_width="1" fill="None"/>
468     </clnull>
469     <clpoint label="welt" value="1">
470     <cldata stroke="#000000" stroke_width="2" fill="None"/>
471     </clpoint>
472     </classification>
473     </layer>
474 bh 1268 <layer shapestore="D2" visible="true" stroke="#000000"
475     title="My Layer" stroke_width="1" fill="None">
476     <projection name="Unknown">
477     <parameter value="proj=lcc"/>
478 bh 1687 <parameter value="lat_1=10"/>
479     <parameter value="lat_2=20"/>
480 bh 1268 <parameter value="ellps=clrk66"/>
481     </projection>
482 jonathan 746 </layer>
483     </map>
484     </session>
485     '''
486    
487 bh 957 def test(self):
488     """Test loading layers with projections"""
489 bh 292 eq = self.assertEquals
490 jonathan 746 neq = self.assertNotEqual
491    
492 bh 957 session = load_session(self.filename())
493 jonathan 746 self.session = session
494    
495     map = self.session.Maps()[0] # only one map in the sample
496    
497     layers = map.Layers() # two layers in the sample
498    
499     # test layer with a named projection
500     proj = layers[0].GetProjection()
501     neq(proj, None)
502     eq(proj.GetName(), "hello")
503     eq(proj.GetParameter("proj"), "tmerc")
504     eq(proj.GetParameter("zone"), "13")
505     eq(proj.GetParameter("ellps"), "clrk66")
506    
507     # test layer with an unnamed projection
508     proj = layers[1].GetProjection()
509     neq(proj, None)
510     eq(proj.GetName(), "Unknown")
511     eq(proj.GetParameter("proj"), "lcc")
512 bh 1687 eq(proj.GetParameter("lat_1"), "10")
513     eq(proj.GetParameter("lat_2"), "20")
514 jonathan 746 eq(proj.GetParameter("ellps"), "clrk66")
515    
516 bh 1257 self.check_format()
517 bh 957
518 bh 1257
519 bh 957 class TestRasterLayer(LoadSessionTest):
520    
521     file_contents = '''\
522     <?xml version="1.0" encoding="UTF-8"?>
523 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
524     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
525 bh 1268 title="single map&amp;layer">
526     <map title="Test Map">
527     <rasterlayer visible="false" filename="../../Data/iceland/island.tif"
528     title="My RasterLayer"/>
529 bh 957 </map>
530     </session>
531     '''
532    
533     def test(self):
534 jonathan 947 eq = self.assertEquals
535     neq = self.assertNotEqual
536    
537 bh 957 session = load_session(self.filename())
538 jonathan 947 self.session = session
539    
540     map = self.session.Maps()[0] # only one map in the sample
541    
542     layer = map.Layers()[0] # one layer in the sample
543    
544     eq(layer.Title(), "My RasterLayer")
545     self.failIf(layer.Visible())
546     self.failUnless(filenames_equal(layer.GetImageFilename(),
547     os.path.join(self.temp_dir(),
548     os.pardir, os.pardir,
549     "Data", "iceland",
550     "island.tif")))
551 bh 1257 self.check_format()
552 jonathan 947
553 bh 1268
554     class TestJoinedTable(LoadSessionTest):
555    
556     file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
557 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
558     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd" title="A Joined Table session">
559 bh 1282 <fileshapesource filetype="shapefile" id="D137227612"
560     filename="../../Data/iceland/roads-line.shp"/>
561     <filetable filetype="DBF" filename="load_joinedtable.dbf" id="D136171140"
562     title="Some Title"/>
563 bh 1375 <jointable id="D136169900" title="Joined"
564     right="D136171140" left="D137227612"
565     leftcolumn="RDLNTYPE" rightcolumn="RDTYPE"
566     jointype="LEFT OUTER"/>
567 bh 1282 <derivedshapesource table="D136169900" shapesource="D137227612"
568     id="D136170932"/>
569 bh 1268 <map title="Test Map">
570 bh 1282 <layer shapestore="D136170932" visible="true" stroke="#000000"
571     title="My Layer" stroke_width="1" fill="None"/>
572 bh 1268 </map>
573 bh 1282 </session>
574     '''
575 bh 1268
576     def setUp(self):
577     """Extend inherited method to create the dbffile for the join"""
578     LoadSessionTest.setUp(self)
579     dbffile = self.temp_file_name("load_joinedtable.dbf")
580     dbf = dbflib.create(dbffile)
581     dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
582     dbf.add_field("TEXT", dbflib.FTString, 10, 0)
583     dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
584     dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
585     dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
586     dbf.close()
587    
588     def test(self):
589     """Test loading a session containing a joined table"""
590     session = load_session(self.filename())
591     self.session = session
592    
593     tables = session.Tables()
594     self.assertEquals(len(tables), 3)
595     # FIXME: The tests shouldn't assume a certain order of the tables
596     self.assertEquals(tables[0].Title(), "Some Title")
597     self.assertEquals(tables[1].Title(), "Joined")
598 bh 1375 self.assertEquals(tables[1].JoinType(), "LEFT OUTER")
599 bh 1282 self.check_format()
600 bh 1268
601    
602 bh 1646
603     class TestPostGISLayer(LoadSessionTest):
604    
605     file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
606 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
607     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
608 bh 1646 title="unnamed session">
609     <dbconnection port="%(port)s" host="%(host)s" user="%(user)s"
610     dbtype="postgis" id="D142684948" dbname="%(dbname)s"/>
611     <dbshapesource tablename="landmarks" id="D143149420" dbconn="D142684948"/>
612     <map title="unnamed map">
613     <layer shapestore="D143149420" visible="true" stroke="#000000"
614     title="landmarks" stroke_width="1" fill="None"/>
615     </map>
616     </session>
617     '''
618    
619     def setUp(self):
620     """Extend the inherited method to start the postgis server
621    
622     Furthermore, patch the file contents with the real postgis db
623     information
624     """
625     postgissupport.skip_if_no_postgis()
626     self.server = postgissupport.get_test_server()
627     self.postgisdb = self.server.get_default_static_data_db()
628    
629     self.file_contents = self.__class__.file_contents % {
630     "dbname": self.postgisdb.dbname,
631     "user": self.server.user_name,
632     "port": self.server.port,
633     "host": self.server.host}
634     LoadSessionTest.setUp(self)
635    
636     def test(self):
637     """Test loading a session containing a postgis shapestore"""
638     session = load_session(self.filename())
639     self.session = session
640     connections = session.DBConnections()
641     self.assertEquals(len(connections), 1)
642     conn = connections[0]
643     for attr, value in [("host", self.server.host),
644     ("port", str(self.server.port)),
645     ("user", self.server.user_name),
646     ("dbname", self.postgisdb.dbname)]:
647     self.assertEquals(getattr(conn, attr), value)
648     layer = session.Maps()[0].Layers()[0]
649     self.failUnless(layer.ShapeStore().DBConnection() is conn)
650    
651    
652     class TestPostGISLayerPassword(LoadSessionTest):
653    
654     file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
655 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
656     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
657 bh 1646 title="unnamed session">
658     <dbconnection port="%(port)s" host="%(host)s" user="%(user)s"
659     dbtype="postgis" id="D142684948" dbname="%(dbname)s"/>
660     <dbshapesource tablename="landmarks" id="D143149420" dbconn="D142684948"/>
661     <map title="unnamed map">
662     <layer shapestore="D143149420" visible="true" stroke="#000000"
663     title="landmarks" stroke_width="1" fill="None"/>
664     </map>
665     </session>
666     '''
667    
668     def setUp(self):
669     """Extend the inherited method to start the postgis server
670    
671     Furthermore, patch the file contents with the real postgis db
672     information
673     """
674     postgissupport.skip_if_no_postgis()
675     self.server = postgissupport.get_test_server()
676     self.postgisdb = self.server.get_default_static_data_db()
677    
678     self.file_contents = self.__class__.file_contents % {
679     "dbname": self.postgisdb.dbname,
680     "user": self.server.user_name,
681     "port": self.server.port,
682     "host": self.server.host}
683     LoadSessionTest.setUp(self)
684    
685     self.db_connection_callback_called = False
686     self.server.require_authentication(True)
687    
688     def tearDown(self):
689     """Extend the inherited method to switch off postgresql authentication
690     """
691     self.server.require_authentication(False)
692     LoadSessionTest.tearDown(self)
693    
694     def db_connection_callback(self, params, message):
695     """Implementation of Thuban.Model.hooks.query_db_connection_parameters
696     """
697     self.assertEquals(params,
698     {"dbname": self.postgisdb.dbname,
699     "user": self.server.user_name,
700     "port": str(self.server.port),
701     "host": self.server.host})
702     self.db_connection_callback_called = True
703     params = params.copy()
704     params["password"] = self.server.user_password
705     return params
706    
707     def test_with_callback(self):
708     """Test loading a session with postgis, authentication and a callback
709     """
710     session = load_session(self.filename(),
711     db_connection_callback = self.db_connection_callback)
712     self.session = session
713     connections = session.DBConnections()
714     self.assertEquals(len(connections), 1)
715     conn = connections[0]
716     for attr, value in [("host", self.server.host),
717     ("port", str(self.server.port)),
718     ("user", self.server.user_name),
719     ("dbname", self.postgisdb.dbname)]:
720     self.assertEquals(getattr(conn, attr), value)
721     layer = session.Maps()[0].Layers()[0]
722     self.failUnless(layer.ShapeStore().DBConnection() is conn)
723     self.failUnless(self.db_connection_callback_called)
724    
725     def test_without_callback(self):
726     """Test loading a session with postgis, authentication and no callback
727     """
728     # A password is required and there's no callback, so we should
729     # get a ConnectionError
730     self.assertRaises(ConnectionError, load_session, self.filename())
731    
732     def test_cancel(self):
733     """Test loading a session with postgis and cancelling authentication
734     """
735     def cancel(*args):
736     self.db_connection_callback_called = True
737     return None
738    
739     # If the user cancels, i.e. if the callbakc returns None, a
740     # LoadCancelled exception is raised.
741     self.assertRaises(LoadCancelled,
742     load_session, self.filename(), cancel)
743     self.failUnless(self.db_connection_callback_called)
744    
745    
746 bh 1268 class TestLoadError(LoadSessionTest):
747    
748     file_contents = '''\
749     <?xml version="1.0" encoding="UTF-8"?>
750 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
751     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
752 bh 1268 title="single map&amp;layer">
753     <fileshapesource id="D1" filename="../../Data/iceland/political.shp"/>
754     <map title="Test Map">
755     <projection name="Unknown">
756     <parameter value="zone=26"/>
757     <parameter value="proj=utm"/>
758     <parameter value="ellps=clrk66"/>
759     </projection>
760     <layer shapestore="D1" visible="true"
761     stroke="#000000" title="My Layer" stroke_width="1"
762     fill="None"/>
763     </map>
764     </session>
765     '''
766    
767     def test(self):
768     """Test loading a session missing a required attribute"""
769     # Don't use assertRaises to make sure that if a session is
770     # actually returned it gets destroyed properly.
771     try:
772     self.session = load_session(self.filename())
773     except LoadError, value:
774 bh 1642 # Check the actual messge in value to make sure the
775     # LoadError really was about the missing attribute
776     self.assertEquals(str(value),
777     "Element "
778 bh 1846 "(u'http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd',"
779 bh 1642 " u'fileshapesource') requires an attribute 'filetype'")
780 bh 1268 else:
781     self.fail("Missing filetype attribute doesn't raise LoadError")
782    
783 bh 292 if __name__ == "__main__":
784 bh 1683 support.run_tests()

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26