diff --git a/test/python_tests/datasource_test.py b/test/python_tests/datasource_test.py index 011b07cbd..78624aaa6 100644 --- a/test/python_tests/datasource_test.py +++ b/test/python_tests/datasource_test.py @@ -7,7 +7,7 @@ import mapnik -from .utilities import execution_path, run_all +from .utilities import execution_path, run_all, datasources_available PYTHON3 = sys.version_info[0] == 3 if PYTHON3: @@ -164,9 +164,10 @@ def rle_encode(l): return ["%d:%s" % (len(list(group)), name) for name, group in groupby(l)] - m = mapnik.Map(256, 256) - try: - mapnik.load_map(m, '../data/good_maps/agg_poly_gamma_map.xml') + xmlfile = '../data/good_maps/agg_poly_gamma_map.xml' + if datasources_available(xmlfile): + m = mapnik.Map(256, 256) + mapnik.load_map(m, xmlfile) m.zoom_all() join_field = 'NAME' fg = [] # feature grid @@ -182,10 +183,6 @@ def rle_encode(l): hit_list = '|'.join(rle_encode(fg)) eq_(hit_list[:16], '730:|2:Greenland') eq_(hit_list[-12:], '1:Chile|812:') - except RuntimeError as e: - # only test datasources that we have installed - if not 'Could not create datasource' in str(e): - raise RuntimeError(str(e)) if __name__ == '__main__': diff --git a/test/python_tests/layer_modification_test.py b/test/python_tests/layer_modification_test.py index a4af1861f..dc5a943d4 100644 --- a/test/python_tests/layer_modification_test.py +++ b/test/python_tests/layer_modification_test.py @@ -33,9 +33,9 @@ def test_adding_datasource_to_layer(): ''' - m = mapnik.Map(256, 256) + if 'shape' in mapnik.DatasourceCache.plugin_names(): + m = mapnik.Map(256, 256) - try: mapnik.load_map_from_string(m, map_string) # validate it loaded fine @@ -73,10 +73,7 @@ def test_adding_datasource_to_layer(): eq_(m.layers[ 0].srs, '+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs') eq_(lyr.srs, '+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs') - except RuntimeError as e: - # only test datasources that we have installed - if not 'Could not create datasource' in str(e): - raise RuntimeError(e) + if __name__ == "__main__": setup() diff --git a/test/python_tests/load_map_test.py b/test/python_tests/load_map_test.py index 6e330edab..deab3acc1 100644 --- a/test/python_tests/load_map_test.py +++ b/test/python_tests/load_map_test.py @@ -7,7 +7,7 @@ import mapnik -from .utilities import execution_path, run_all +from .utilities import execution_path, run_all, datasources_available default_logging_severity = mapnik.logger.get_severity() @@ -55,46 +55,52 @@ def test_can_parse_xml_with_deprecated_properties(): failures = [] for filename in files_with_deprecated_props: - try: - m = mapnik.Map(512, 512) - strict = True - mapnik.load_map(m, filename, strict) - base_path = os.path.dirname(filename) - mapnik.load_map_from_string( - m, - open( - filename, - 'rb').read(), - strict, - base_path) - except RuntimeError as e: - # only test datasources that we have installed - if not 'Could not create datasource' in str(e) \ - and not 'could not connect' in str(e): - failures.append( - 'Failed to load valid map %s (%s)' % - (filename, e)) + if datasources_available(filename): + try: + m = mapnik.Map(512, 512) + strict = True + mapnik.load_map(m, filename, strict) + base_path = os.path.dirname(filename) + mapnik.load_map_from_string( + m, + open( + filename, + 'rb').read(), + strict, + base_path) + except RuntimeError as e: + if not 'could not connect' in str(e): + failures.append( + 'Failed to load valid map %s (%s)' % + (filename, e)) eq_(len(failures), 0, '\n' + '\n'.join(failures)) mapnik.logger.set_severity(default_logging_severity) def test_good_files(): - good_files = glob.glob("../data/good_maps/*.xml") - good_files.extend(glob.glob("../visual_tests/styles/*.xml")) + all_files = glob.glob("../data/good_maps/*.xml") + all_files.extend(glob.glob("../visual_tests/styles/*.xml")) + + good_files = list() + for xmlfile in all_files: + missing_plugins = set() + have_inputs = datasources_available(xmlfile, missing_plugins) + if have_inputs: + good_files.append(xmlfile) + else: + print 'Notice: skipping load_map_test for %s due to unavailable input plugins: %s' % (os.path.basename(xmlfile), list(missing_plugins)) failures = [] + strict = True for filename in good_files: try: m = mapnik.Map(512, 512) - strict = True mapnik.load_map(m, filename, strict) base_path = os.path.dirname(filename) with open(filename, 'rb') as f: mapnik.load_map_from_string(m, f.read(), strict, base_path) except RuntimeError as e: - # only test datasources that we have installed - if not 'Could not create datasource' in str(e) \ - and not 'could not connect' in str(e): + if not 'could not connect' in str(e): failures.append( 'Failed to load valid map %s (%s)' % (filename, e)) diff --git a/test/python_tests/object_test.py b/test/python_tests/object_test.py index 583a523dc..79b8072f6 100644 --- a/test/python_tests/object_test.py +++ b/test/python_tests/object_test.py @@ -377,9 +377,9 @@ # # ''' -# m = mapnik.Map(600, 300) -# eq_(m.base, '') -# try: +# if 'shape' in mapnik.DatasourceCache.plugin_names(): +# m = mapnik.Map(600, 300) +# eq_(m.base, '') # mapnik.load_map_from_string(m, map_string) # eq_(m.base, './') # mapnik.load_map_from_string(m, map_string, False, "") # this "" will have no effect @@ -394,10 +394,6 @@ # m.base = 'foo' # mapnik.load_map_from_string(m, map_string, True, ".") # eq_(m.base, '.') -# except RuntimeError, e: -# # only test datasources that we have installed -# if not 'Could not create datasource' in str(e): -# raise RuntimeError(e) # # Color initialization # @raises(Exception) # Boost.Python.ArgumentError diff --git a/test/python_tests/raster_symbolizer_test.py b/test/python_tests/raster_symbolizer_test.py index caebaab23..896305872 100644 --- a/test/python_tests/raster_symbolizer_test.py +++ b/test/python_tests/raster_symbolizer_test.py @@ -6,7 +6,7 @@ import mapnik -from .utilities import execution_path, get_unique_colors, run_all +from .utilities import execution_path, get_unique_colors, run_all, datasources_available def setup(): @@ -106,28 +106,23 @@ def test_dataraster_query_point(): def test_load_save_map(): - map = mapnik.Map(256, 256) + m = mapnik.Map(256, 256) in_map = "../data/good_maps/raster_symbolizer.xml" - try: - mapnik.load_map(map, in_map) - - out_map = mapnik.save_map_to_string(map) + if datasources_available(in_map): + mapnik.load_map(m, in_map) + out_map = mapnik.save_map_to_string(m) assert 'RasterSymbolizer' in out_map assert 'RasterColorizer' in out_map assert 'stop' in out_map - except RuntimeError as e: - # only test datasources that we have installed - if not 'Could not create datasource' in str(e): - raise RuntimeError(str(e)) def test_raster_with_alpha_blends_correctly_with_background(): WIDTH = 500 HEIGHT = 500 - map = mapnik.Map(WIDTH, HEIGHT) + m = mapnik.Map(WIDTH, HEIGHT) WHITE = mapnik.Color(255, 255, 255) - map.background = WHITE + m.background = WHITE style = mapnik.Style() rule = mapnik.Rule() @@ -137,20 +132,20 @@ def test_raster_with_alpha_blends_correctly_with_background(): rule.symbols.append(symbolizer) style.rules.append(rule) - map.append_style('raster_style', style) + m.append_style('raster_style', style) map_layer = mapnik.Layer('test_layer') filepath = '../data/raster/white-alpha.png' if 'gdal' in mapnik.DatasourceCache.plugin_names(): map_layer.datasource = mapnik.Gdal(file=filepath) map_layer.styles.append('raster_style') - map.layers.append(map_layer) + m.layers.append(map_layer) - map.zoom_all() + m.zoom_all() mim = mapnik.Image(WIDTH, HEIGHT) - mapnik.render(map, mim) + mapnik.render(m, mim) mim.tostring() # All white is expected eq_(get_unique_colors(mim), ['rgba(254,254,254,255)']) diff --git a/test/python_tests/render_test.py b/test/python_tests/render_test.py index 42f63f260..889559aab 100644 --- a/test/python_tests/render_test.py +++ b/test/python_tests/render_test.py @@ -9,7 +9,7 @@ import mapnik -from .utilities import execution_path, run_all +from .utilities import execution_path, run_all, datasources_available PYTHON3 = sys.version_info[0] == 3 @@ -126,18 +126,15 @@ def get_paired_images(w, h, mapfile): def test_render_from_serialization(): - try: - im, im2 = get_paired_images( - 100, 100, '../data/good_maps/building_symbolizer.xml') + xmlfile = '../data/good_maps/building_symbolizer.xml' + if datasources_available(xmlfile): + im, im2 = get_paired_images(100, 100, xmlfile) eq_(im.tostring('png32'), im2.tostring('png32')) - im, im2 = get_paired_images( - 100, 100, '../data/good_maps/polygon_symbolizer.xml') + xmlfile = '../data/good_maps/polygon_symbolizer.xml' + if datasources_available(xmlfile): + im, im2 = get_paired_images(100, 100, xmlfile) eq_(im.tostring('png32'), im2.tostring('png32')) - except RuntimeError as e: - # only test datasources that we have installed - if not 'Could not create datasource' in str(e): - raise RuntimeError(e) def test_render_points(): diff --git a/test/python_tests/save_map_test.py b/test/python_tests/save_map_test.py index 8e7afd21e..a53b8ca81 100644 --- a/test/python_tests/save_map_test.py +++ b/test/python_tests/save_map_test.py @@ -8,7 +8,7 @@ import mapnik -from .utilities import execution_path, run_all +from .utilities import execution_path, run_all, datasources_available default_logging_severity = mapnik.logger.get_severity() @@ -27,17 +27,16 @@ def teardown(): mapnik.logger.set_severity(default_logging_severity) -def compare_map(xml): +def compare_map(xmlfile): + missing_plugins = set() + have_inputs = datasources_available(xmlfile, missing_plugins) + if not have_inputs: + print 'Notice: skipping saved map comparison for %s due to unavailable input plugins: %s' % (os.path.basename(xmlfile), list(missing_plugins)) + return False + m = mapnik.Map(256, 256) - absolute_base = os.path.abspath(os.path.dirname(xml)) - try: - mapnik.load_map(m, xml, False, absolute_base) - except RuntimeError as e: - # only test datasources that we have installed - if not 'Could not create datasource' in str(e) \ - and not 'could not connect' in str(e): - raise RuntimeError(str(e)) - return + absolute_base = os.path.abspath(os.path.dirname(xmlfile)) + mapnik.load_map(m, xmlfile, False, absolute_base) (handle, test_map) = tempfile.mkstemp( suffix='.xml', prefix='mapnik-temp-map1-') os.close(handle) @@ -60,7 +59,7 @@ def compare_map(xml): except AssertionError as e: raise AssertionError( 'serialized map "%s" not the same after being reloaded, \ncompare with command:\n\n$%s' % - (xml, diff)) + (xmlfile, diff)) if os.path.exists(test_map): os.remove(test_map) @@ -72,9 +71,6 @@ def compare_map(xml): def test_compare_map(): good_maps = glob.glob("../data/good_maps/*.xml") good_maps = [os.path.normpath(p) for p in good_maps] - # remove one map that round trips CDATA differently, but this is okay - ignorable = os.path.join('..', 'data', 'good_maps', 'empty_parameter2.xml') - good_maps.remove(ignorable) for m in good_maps: compare_map(m) diff --git a/test/python_tests/shapeindex_test.py b/test/python_tests/shapeindex_test.py index 53aa04d51..ab9129512 100644 --- a/test/python_tests/shapeindex_test.py +++ b/test/python_tests/shapeindex_test.py @@ -19,41 +19,42 @@ def setup(): def test_shapeindex(): - # first copy shapefiles to tmp directory - source_dir = '../data/shp/' - working_dir = '/tmp/mapnik-shp-tmp/' - if os.path.exists(working_dir): - shutil.rmtree(working_dir) - shutil.copytree(source_dir, working_dir) - matches = [] - for root, dirnames, filenames in os.walk('%s' % source_dir): - for filename in fnmatch.filter(filenames, '*.shp'): - matches.append(os.path.join(root, filename)) - for shp in matches: - source_file = os.path.join( - source_dir, os.path.relpath( - shp, source_dir)) - dest_file = os.path.join(working_dir, os.path.relpath(shp, source_dir)) - ds = mapnik.Shapefile(file=source_file) - count = 0 - fs = ds.featureset() - try: - while (fs.next()): - count = count + 1 - except StopIteration: - pass - stdin, stderr = Popen( - 'shapeindex %s' % - dest_file, shell=True, stdout=PIPE, stderr=PIPE).communicate() - ds2 = mapnik.Shapefile(file=dest_file) - count2 = 0 - fs = ds.featureset() - try: - while (fs.next()): - count2 = count2 + 1 - except StopIteration: - pass - eq_(count, count2) + if 'shape' in mapnik.DatasourceCache.plugin_names(): + # first copy shapefiles to tmp directory + source_dir = '../data/shp/' + working_dir = '/tmp/mapnik-shp-tmp/' + if os.path.exists(working_dir): + shutil.rmtree(working_dir) + shutil.copytree(source_dir, working_dir) + matches = [] + for root, dirnames, filenames in os.walk('%s' % source_dir): + for filename in fnmatch.filter(filenames, '*.shp'): + matches.append(os.path.join(root, filename)) + for shp in matches: + source_file = os.path.join( + source_dir, os.path.relpath( + shp, source_dir)) + dest_file = os.path.join(working_dir, os.path.relpath(shp, source_dir)) + ds = mapnik.Shapefile(file=source_file) + count = 0 + fs = ds.featureset() + try: + while (fs.next()): + count = count + 1 + except StopIteration: + pass + stdin, stderr = Popen( + 'shapeindex %s' % + dest_file, shell=True, stdout=PIPE, stderr=PIPE).communicate() + ds2 = mapnik.Shapefile(file=dest_file) + count2 = 0 + fs = ds.featureset() + try: + while (fs.next()): + count2 = count2 + 1 + except StopIteration: + pass + eq_(count, count2) if __name__ == "__main__": setup() diff --git a/test/python_tests/utilities.py b/test/python_tests/utilities.py index 9bfc9aec6..56454a8b3 100644 --- a/test/python_tests/utilities.py +++ b/test/python_tests/utilities.py @@ -4,6 +4,7 @@ import os import sys import traceback +from xml.etree import ElementTree from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin from nose.tools import assert_almost_equal @@ -139,3 +140,33 @@ def assert_box2d_almost_equal(a, b, msg=None): assert_almost_equal(a.maxx, b.maxx, msg=msg) assert_almost_equal(a.miny, b.miny, msg=msg) assert_almost_equal(a.maxy, b.maxy, msg=msg) + +def datasources_available(map_file, missing_datasources=None): + ''' + datasources_available + + Determine whether the map file contains only available data source types. + + @param map_file: path of XML map file + @type map_file: string + + @param missing_datasources: collection of data source type names. if there + are unavailable data sources, and a collection + reference is provided, it will be populated with + the names of the unavailable data sources + @type missing_datasources: collection reference + + @return: True if all referenced data source types are available, + otherwise False + ''' + have_inputs = True + map_xml = ElementTree.parse(map_file) + data_source_type_params = map_xml.findall(".//Datasource/Parameter[@name=\"type\"]") + if data_source_type_params is not None and len(data_source_type_params) > 0: + for p in data_source_type_params: + dstype = p.text + if dstype not in mapnik.DatasourceCache.plugin_names(): + have_inputs = False + if missing_datasources is not None: + missing_datasources.add(dstype) + return have_inputs