gdal/autotest/pyscripts/gdal2tiles/test_option_parser.py

321 строка
11 KiB
Python

#!/usr/bin/env pytest
# -*- coding: utf-8 -*-
###############################################################################
# $Id$
#
# Project: GDAL/OGR Test Suite
# Purpose: gdal2tiles.py testing
# Author: Gregory Bataille <gregory.bataille@gmail.com>
#
###############################################################################
# Copyright (c) 2017, Gregory Bataille <gregory.bataille@gmail.com>
# Copyright (c) 2021, Idan Miara <idan@miara.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
###############################################################################
import os
import tempfile
from unittest import TestCase, mock
import pytest
from osgeo import gdal
from osgeo_utils import gdal2tiles
class AttrDict(dict):
def __init__(self, *args, **kwargs):
super(AttrDict, self).__init__(*args, **kwargs)
self.__dict__ = self
class OptionParserInputOutputTest(TestCase):
def test_vanilla_input_output(self):
_, input_file = tempfile.mkstemp()
output_folder = tempfile.mkdtemp()
parsed_input, parsed_output, options = gdal2tiles.process_args(
[input_file, output_folder]
)
self.assertEqual(parsed_input, input_file)
self.assertEqual(parsed_output, output_folder)
self.assertNotEqual(options, {})
def test_output_folder_is_the_input_file_folder_when_none_passed(self):
_, input_file = tempfile.mkstemp()
_, parsed_output, _ = gdal2tiles.process_args([input_file])
self.assertEqual(parsed_output, os.path.basename(input_file))
def _asserts_exits_with_code_2(self, params):
with self.assertRaises(SystemExit) as cm:
gdal2tiles.process_args(params)
e = cm.exception
self.assertEqual(str(e), "2")
def test_exits_when_0_args_passed(self):
self._asserts_exits_with_code_2([])
def test_exits_when_more_than_2_free_parameters(self):
self._asserts_exits_with_code_2(["input1.tiff", "input2.tiff", "output_folder"])
def test_exits_when_input_file_does_not_exist(self):
self._asserts_exits_with_code_2(["foobar.tiff"])
def test_exits_when_first_param_is_not_a_file(self):
folder = tempfile.gettempdir()
self._asserts_exits_with_code_2([folder])
def mock_GetDriverByName_wo_webp(name, orig_GetDriverByName=gdal.GetDriverByName):
if name == "WEBP":
return None
return orig_GetDriverByName(name)
# pylint:disable=E1101
class OptionParserPostProcessingTest(TestCase):
def setUp(self):
self.DEFAULT_OPTIONS = {
"verbose": True,
"resampling": "near",
"title": "",
"url": "",
"tiledriver": "PNG",
}
self.DEFAULT_ATTRDICT_OPTIONS = AttrDict(self.DEFAULT_OPTIONS)
def _setup_gdal_patch(self, mock_gdal):
mock_gdal.TermProgress_nocb = True
mock_gdal.RegenerateOverview = True
mock_gdal.GetCacheMax = lambda: 1024 * 1024
return mock_gdal
def test_title_is_untouched_if_set(self):
title = "fizzbuzz"
self.DEFAULT_ATTRDICT_OPTIONS["title"] = title
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "bar.tiff", "baz"
)
self.assertEqual(options.title, title)
def test_title_default_to_input_filename_if_not_set(self):
input_file = "foo/bar/fizz/buzz.tiff"
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, input_file, "baz"
)
self.assertEqual(options.title, os.path.basename(input_file))
def test_url_stays_empty_if_not_passed(self):
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
)
self.assertEqual(options.url, "")
def test_url_ends_with_the_output_folder_last_component(self):
output_folder = "foo/bar/fizz"
url = "www.mysite.com/storage"
self.DEFAULT_ATTRDICT_OPTIONS["url"] = url
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", output_folder
)
self.assertEqual(options.url, url + "/fizz/")
# With already present trailing slashes
output_folder = "foo/bar/fizz/"
url = "www.mysite.com/storage/"
self.DEFAULT_ATTRDICT_OPTIONS["url"] = url
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", output_folder
)
self.assertEqual(options.url, url + "fizz/")
@mock.patch("osgeo_utils.gdal2tiles.gdal", spec=AttrDict())
def test_average_resampling_supported_with_latest_gdal(self, mock_gdal):
self._setup_gdal_patch(mock_gdal)
self.DEFAULT_ATTRDICT_OPTIONS["resampling"] = "average"
gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
# No error means it worked as expected
def test_antialias_resampling_supported_with_numpy(self):
gdal2tiles.numpy_available = True
self.DEFAULT_ATTRDICT_OPTIONS["resampling"] = "antialias"
gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
# No error means it worked as expected
def test_antialias_resampling_not_supported_wout_numpy(self):
gdal2tiles.numpy_available = False
if hasattr(gdal2tiles, "numpy"):
del gdal2tiles.numpy
self.DEFAULT_ATTRDICT_OPTIONS["resampling"] = "antialias"
with self.assertRaises(SystemExit):
gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
def test_zoom_option_not_specified(self):
self.DEFAULT_ATTRDICT_OPTIONS["zoom"] = None
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
)
self.assertEqual(options.zoom, [None, None])
def test_zoom_option_single_level(self):
self.DEFAULT_ATTRDICT_OPTIONS["zoom"] = "10"
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
)
self.assertEqual(options.zoom, [10, 10])
def test_zoom_option_two_levels(self):
self.DEFAULT_ATTRDICT_OPTIONS["zoom"] = "14-24"
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
)
self.assertEqual(options.zoom, [14, 24])
def test_zoom_option_two_levels_automatic_max(self):
self.DEFAULT_ATTRDICT_OPTIONS["zoom"] = "14-"
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
)
self.assertEqual(options.zoom, [14, None])
@mock.patch(
"osgeo_utils.gdal2tiles.gdal.GetDriverByName",
side_effect=mock_GetDriverByName_wo_webp,
)
def test_tiledriver_wout_webp(self, mock_GetDriverByName_wo_webp):
self.DEFAULT_ATTRDICT_OPTIONS["tiledriver"] = "WEBP"
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 70
with self.assertRaises(SystemExit):
gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
@mock.patch(
"osgeo_utils.gdal2tiles.gdal.GetDriverByName",
side_effect=mock_GetDriverByName_wo_webp,
)
def test_tiledriver_wout_webp_png_accepted(self, mock_GetDriverByName_wo_webp):
self.DEFAULT_ATTRDICT_OPTIONS["tiledriver"] = "PNG"
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
self.assertEqual(options.tiledriver, "PNG")
def test_tiledriver_webp_quality_option_valid(self):
if gdal.GetDriverByName("WEBP") is None:
pytest.skip()
self.DEFAULT_ATTRDICT_OPTIONS["tiledriver"] = "WEBP"
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 1
self.DEFAULT_ATTRDICT_OPTIONS["webp_lossless"] = False
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
self.assertEqual(options.tiledriver, "WEBP")
self.assertEqual(options.webp_quality, 1)
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 100
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
self.assertEqual(options.tiledriver, "WEBP")
self.assertEqual(options.webp_quality, 100)
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 50
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
self.assertEqual(options.tiledriver, "WEBP")
self.assertEqual(options.webp_quality, 50)
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 10.5
options = gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
self.assertEqual(options.tiledriver, "WEBP")
self.assertEqual(options.webp_quality, 10)
def test_tiledriver_webp_quality_option_invalid(self):
if gdal.GetDriverByName("WEBP") is None:
pytest.skip()
self.DEFAULT_ATTRDICT_OPTIONS["tiledriver"] = "WEBP"
self.DEFAULT_ATTRDICT_OPTIONS["webp_lossless"] = False
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = -20
with self.assertRaises(SystemExit):
gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 0
with self.assertRaises(SystemExit):
gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 140
with self.assertRaises(SystemExit):
gdal2tiles.options_post_processing(
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
)