Skip to content

Commit e6c2e75

Browse files
committed
better marker control on tests, conditional running of tests dependent on extras
1 parent 8de0174 commit e6c2e75

File tree

6 files changed

+126
-47
lines changed

6 files changed

+126
-47
lines changed

pytest.ini

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
[pytest]
2-
addopts = --import-mode=importlib
2+
addopts =
3+
--import-mode=importlib
4+
xfail_strict = true
35
pythonpath = tests
46
testpaths = tests
57
markers =
68
online: marks tests requiring network
7-
geotiff: marks tests requiring geotiff module
9+
requires_fiona: marks tests requiring fiona module
10+
requires_geotiff: marks tests requiring geotiff module
11+
requires_netcdf4: marks tests requiring netcdf4 module
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
from processes import Sleep
1313
from owslib.wps import WPSExecution
1414
from pathlib import Path
15-
from tempfile import TemporaryDirectory
16-
from pywps import dblog
1715

1816
VERSION = "1.0.0"
1917

@@ -27,7 +25,6 @@ def setUp(self) -> None:
2725
# Running processes using the MultiProcessing scheduler and a file-based database
2826
configuration.CONFIG.set('processing', 'mode', 'distributed')
2927

30-
@pytest.mark.xfail(reason="async fails")
3128
def test_async(self):
3229
client = client_for(Service(processes=[Sleep()]))
3330
wps = WPSExecution()
@@ -48,7 +45,6 @@ def test_async(self):
4845

4946
# Parse response to extract the status file path
5047
url = resp.xml.xpath("//@statusLocation")[0]
51-
print(url)
5248

5349
# OWSlib only reads from URLs, not local files. So we need to read the response manually.
5450
p = Path(configuration.get_config_value('server', 'outputpath')) / url.split('/')[-1]

tests/test_execute.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@
2222

2323
from io import StringIO
2424

25+
netCDF4 = None
2526
try:
2627
import netCDF4
2728
except ImportError:
28-
WITH_NC4 = False
29-
else:
30-
WITH_NC4 = True
29+
pass
3130

3231
DATA_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data')
3332

@@ -236,10 +235,9 @@ class ExecuteTest(TestBase):
236235
"""Test for Exeucte request KVP request"""
237236

238237
@pytest.mark.online
239-
@pytest.mark.xfail(reason="test.opendap.org is offline")
238+
@pytest.mark.requires_netcdf4
239+
@pytest.mark.skipif(netCDF4 is None, reason='netCDF4 libraries are required for this test')
240240
def test_dods(self):
241-
if not WITH_NC4:
242-
self.skipTest('netCDF4 not installed')
243241
my_process = create_complex_nc_process()
244242
service = Service(processes=[my_process])
245243

@@ -282,8 +280,11 @@ class FakeRequest():
282280
language = "en-US"
283281

284282
request = FakeRequest()
285-
286283
resp = service.execute('my_opendap_process', request, 'fakeuuid')
284+
285+
if resp.outputs["conventions"].data is None:
286+
pytest.xfail("Network is likely unavailable or test.opendap.org is offline")
287+
287288
self.assertEqual(resp.outputs['conventions'].data, 'CF-1.0')
288289
self.assertEqual(resp.outputs['outdods'].url, href)
289290
self.assertTrue(resp.outputs['outdods'].as_reference)

tests/test_s3storage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
##################################################################
55

66
from basic import TestBase
7-
from pywps.inout.storage.s3 import S3StorageBuilder, S3Storage
7+
from pywps.inout.storage.s3 import S3StorageBuilder
88
from pywps.inout.storage import STORE_TYPE
99
from pywps.inout.basic import ComplexOutput
1010

@@ -41,7 +41,7 @@ def test_write(self, uploadData):
4141
configuration.CONFIG.set('s3', 'prefix', 'wps')
4242
storage = S3StorageBuilder().build()
4343

44-
url = storage.write('Bar Baz', 'out.txt', data_format=FORMATS.TEXT)
44+
storage.write('Bar Baz', 'out.txt', data_format=FORMATS.TEXT)
4545

4646
called_args = uploadData.call_args[0]
4747

tests/validator/test_complexvalidators.py

Lines changed: 110 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,23 @@
2727
import os
2828

2929

30+
netCDF4 = None
3031
try:
31-
import netCDF4 # noqa
32+
import netCDF4
3233
except ImportError:
33-
WITH_NC4 = False
34-
else:
35-
WITH_NC4 = True
34+
pass
35+
36+
geotiff = None
37+
try:
38+
import geotiff
39+
except ImportError:
40+
pass
41+
42+
fiona = None
43+
try:
44+
import fiona
45+
except (ImportError, ModuleNotFoundError):
46+
pass
3647

3748

3849
class ValidateTest(TestBase):
@@ -70,9 +81,10 @@ class data_format(object):
7081
return fake_input
7182

7283
@pytest.mark.online
84+
@pytest.mark.requires_fiona
85+
@pytest.mark.skipif(fiona is None, reason="fiona libraries are required for this test")
7386
def test_gml_validator(self):
74-
"""Test GML validator
75-
"""
87+
"""Test GML validator"""
7688
gml_input = self.get_input('gml/point.gml', 'point.xsd', FORMATS.GML.mime_type)
7789
self.assertTrue(validategml(gml_input, MODE.NONE), 'NONE validation')
7890
self.assertTrue(validategml(gml_input, MODE.SIMPLE), 'SIMPLE validation')
@@ -81,26 +93,39 @@ def test_gml_validator(self):
8193
gml_input.stream.close()
8294

8395
@pytest.mark.online
96+
@pytest.mark.skipif(fiona is not None, reason="fiona libraries must not be installed for this test")
97+
def test_no_gml_validator(self):
98+
"""Test GML validator"""
99+
gml_input = self.get_input('gml/point.gml', 'point.xsd', FORMATS.GML.mime_type)
100+
self.assertTrue(validategml(gml_input, MODE.NONE), 'NONE validation')
101+
self.assertTrue(validategml(gml_input, MODE.SIMPLE), 'SIMPLE validation')
102+
self.assertFalse(validategml(gml_input, MODE.STRICT), 'STRICT validation')
103+
# self.assertTrue(validategml(gml_input, MODE.VERYSTRICT), 'VERYSTRICT validation')
104+
gml_input.stream.close()
105+
106+
@pytest.mark.online
107+
@pytest.mark.requires_fiona
84108
@pytest.mark.xfail(reason="gml verystrict validation fails")
109+
@pytest.mark.skipif(fiona is None, reason="fiona libraries are required for this test")
85110
def test_gml_validator_verystrict(self):
86-
"""Test GML validator
87-
"""
111+
"""Test GML validator"""
88112
gml_input = self.get_input('gml/point.gml', 'point.xsd', FORMATS.GML.mime_type)
89113
self.assertTrue(validategml(gml_input, MODE.VERYSTRICT), 'VERYSTRICT validation')
90114
gml_input.stream.close()
91115

116+
92117
def test_json_validator(self):
93-
"""Test GeoJSON validator
94-
"""
118+
"""Test GeoJSON validator"""
95119
json_input = self.get_input('json/point.geojson', None, FORMATS.JSON.mime_type)
96120
self.assertTrue(validatejson(json_input, MODE.NONE), 'NONE validation')
97121
self.assertTrue(validatejson(json_input, MODE.SIMPLE), 'SIMPLE validation')
98122
self.assertTrue(validatejson(json_input, MODE.STRICT), 'STRICT validation')
99123
json_input.stream.close()
100124

125+
@pytest.mark.requires_fiona
126+
@pytest.mark.skipif(fiona is None, reason="fiona libraries are required for this test")
101127
def test_geojson_validator(self):
102-
"""Test GeoJSON validator
103-
"""
128+
"""Test GeoJSON validator"""
104129
geojson_input = self.get_input('json/point.geojson', 'json/schema/geojson.json',
105130
FORMATS.GEOJSON.mime_type)
106131
self.assertTrue(validategeojson(geojson_input, MODE.NONE), 'NONE validation')
@@ -109,61 +134,114 @@ def test_geojson_validator(self):
109134
self.assertTrue(validategeojson(geojson_input, MODE.VERYSTRICT), 'VERYSTRICT validation')
110135
geojson_input.stream.close()
111136

137+
138+
@pytest.mark.skipif(fiona is not None, reason="fiona libraries must not be installed for this test")
139+
def test_no_geojson_validator(self):
140+
"""Test GeoJSON validator"""
141+
geojson_input = self.get_input('json/point.geojson', 'json/schema/geojson.json',
142+
FORMATS.GEOJSON.mime_type)
143+
self.assertTrue(validategeojson(geojson_input, MODE.NONE), 'NONE validation')
144+
self.assertTrue(validategeojson(geojson_input, MODE.SIMPLE), 'SIMPLE validation')
145+
146+
self.assertFalse(validategeojson(geojson_input, MODE.STRICT), 'STRICT validation')
147+
148+
# FIXME: MODE.VERYSTRICT should fail here
149+
self.assertTrue(validategeojson(geojson_input, MODE.VERYSTRICT), 'VERYSTRICT validation')
150+
151+
geojson_input.stream.close()
152+
153+
@pytest.mark.requires_fiona
154+
@pytest.mark.skipif(fiona is None, reason="fiona libraries are required for this test")
112155
def test_shapefile_validator(self):
113-
"""Test ESRI Shapefile validator
114-
"""
156+
"""Test ESRI Shapefile validator"""
115157
shapefile_input = self.get_input('shp/point.shp.zip', None,
116158
FORMATS.SHP.mime_type)
117159
self.assertTrue(validateshapefile(shapefile_input, MODE.NONE), 'NONE validation')
118160
self.assertTrue(validateshapefile(shapefile_input, MODE.SIMPLE), 'SIMPLE validation')
119161
self.assertTrue(validateshapefile(shapefile_input, MODE.STRICT), 'STRICT validation')
120162
shapefile_input.stream.close()
121163

122-
@pytest.mark.geotiff
164+
@pytest.mark.skipif(fiona is not None, reason="fiona libraries must not be installed for this test")
165+
def test_no_shapefile_validator(self):
166+
"""Test ESRI Shapefile validator"""
167+
shapefile_input = self.get_input('shp/point.shp.zip', None,
168+
FORMATS.SHP.mime_type)
169+
self.assertTrue(validateshapefile(shapefile_input, MODE.NONE), 'NONE validation')
170+
self.assertTrue(validateshapefile(shapefile_input, MODE.SIMPLE), 'SIMPLE validation')
171+
self.assertFalse(validateshapefile(shapefile_input, MODE.STRICT), 'STRICT validation')
172+
shapefile_input.stream.close()
173+
174+
@pytest.mark.skipif(geotiff is not None, reason="geotiff libraries must not be installed for this test")
175+
def test_no_geotiff_validator(self):
176+
"""Test GeoTIFF validator"""
177+
geotiff_input = self.get_input('geotiff/dem.tiff', None,
178+
FORMATS.GEOTIFF.mime_type)
179+
self.assertTrue(validategeotiff(geotiff_input, MODE.NONE), 'NONE validation')
180+
self.assertTrue(validategeotiff(geotiff_input, MODE.SIMPLE), 'SIMPLE validation')
181+
self.assertFalse(validategeotiff(geotiff_input, MODE.STRICT), 'STRICT validation')
182+
geotiff_input.stream.close()
183+
184+
@pytest.mark.requires_geotiff
185+
@pytest.mark.skipif(geotiff is None, reason="geotiff libraries are required for this test")
123186
def test_geotiff_validator(self):
124-
"""Test GeoTIFF validator
125-
"""
187+
"""Test GeoTIFF validator"""
126188
geotiff_input = self.get_input('geotiff/dem.tiff', None,
127189
FORMATS.GEOTIFF.mime_type)
128190
self.assertTrue(validategeotiff(geotiff_input, MODE.NONE), 'NONE validation')
129191
self.assertTrue(validategeotiff(geotiff_input, MODE.SIMPLE), 'SIMPLE validation')
130192
self.assertTrue(validategeotiff(geotiff_input, MODE.STRICT), 'STRICT validation')
131193
geotiff_input.stream.close()
132194

195+
@pytest.mark.requires_netcdf4
196+
@pytest.mark.skipif(netCDF4 is None, reason="NetCDF4 libraries are required for this test")
133197
def test_netcdf_validator(self):
134-
"""Test netCDF validator
135-
"""
198+
"""Test netCDF validator"""
136199
netcdf_input = self.get_input('netcdf/time.nc', None, FORMATS.NETCDF.mime_type)
137200
self.assertTrue(validatenetcdf(netcdf_input, MODE.NONE), 'NONE validation')
138201
self.assertTrue(validatenetcdf(netcdf_input, MODE.SIMPLE), 'SIMPLE validation')
139202
netcdf_input.stream.close()
140-
if WITH_NC4:
141-
self.assertTrue(validatenetcdf(netcdf_input, MODE.STRICT), 'STRICT validation')
142-
netcdf_input.file = 'grub.nc'
143-
self.assertFalse(validatenetcdf(netcdf_input, MODE.STRICT))
144-
else:
145-
self.assertFalse(validatenetcdf(netcdf_input, MODE.STRICT), 'STRICT validation')
203+
204+
self.assertTrue(validatenetcdf(netcdf_input, MODE.STRICT), 'STRICT validation')
205+
netcdf_input.file = 'grub.nc'
206+
self.assertFalse(validatenetcdf(netcdf_input, MODE.STRICT))
207+
208+
@pytest.mark.skipif(netCDF4 is not None, reason="NetCDF4 libraries must not be installed for this test")
209+
def test_no_netcdf_validator(self):
210+
"""Test netCDF validator"""
211+
netcdf_input = self.get_input('netcdf/time.nc', None, FORMATS.NETCDF.mime_type)
212+
self.assertTrue(validatenetcdf(netcdf_input, MODE.NONE), 'NONE validation')
213+
self.assertTrue(validatenetcdf(netcdf_input, MODE.SIMPLE), 'SIMPLE validation')
214+
netcdf_input.stream.close()
215+
216+
self.assertFalse(validatenetcdf(netcdf_input, MODE.STRICT), 'STRICT validation')
146217

147218
@pytest.mark.online
148-
@pytest.mark.xfail(reason="test.opendap.org is offline")
219+
@pytest.mark.requires_netcdf4
220+
@pytest.mark.skipif(netCDF4 is None, reason="NetCDF4 libraries are required for this test")
149221
def test_dods_validator(self):
150222
opendap_input = ComplexInput('dods', 'opendap test', [FORMATS.DODS,])
151223
opendap_input.url = "http://test.opendap.org:80/opendap/netcdf/examples/sresa1b_ncar_ccsm3_0_run1_200001.nc"
152224
self.assertTrue(validatedods(opendap_input, MODE.NONE), 'NONE validation')
153225
self.assertTrue(validatedods(opendap_input, MODE.SIMPLE), 'SIMPLE validation')
154226

155-
if WITH_NC4:
156-
self.assertTrue(validatedods(opendap_input, MODE.STRICT), 'STRICT validation')
157-
opendap_input.url = 'Faulty url'
158-
self.assertFalse(validatedods(opendap_input, MODE.STRICT))
159-
else:
160-
self.assertFalse(validatedods(opendap_input, MODE.STRICT), 'STRICT validation')
227+
self.assertTrue(validatedods(opendap_input, MODE.STRICT), 'STRICT validation')
228+
opendap_input.url = 'Faulty url'
229+
self.assertFalse(validatedods(opendap_input, MODE.STRICT))
161230

231+
@pytest.mark.online
232+
@pytest.mark.skipif(netCDF4 is not None, reason="NetCDF4 libraries must not be installed for this test")
162233
def test_dods_default(self):
163234
opendap_input = ComplexInput('dods', 'opendap test', [FORMATS.DODS,],
164235
default='http://test.opendap.org',
165236
default_type=SOURCE_TYPE.URL,
166237
mode=MODE.SIMPLE)
238+
opendap_input.url = "http://test.opendap.org:80/opendap/netcdf/examples/sresa1b_ncar_ccsm3_0_run1_200001.nc"
239+
self.assertTrue(validatedods(opendap_input, MODE.NONE), 'NONE validation')
240+
self.assertTrue(validatedods(opendap_input, MODE.SIMPLE), 'SIMPLE validation')
241+
242+
with pytest.warns(UserWarning) as record:
243+
self.assertFalse(validatedods(opendap_input, MODE.STRICT), 'STRICT validation')
244+
assert "Complex validation requires netCDF4 support." in record[0].message.args[0]
167245

168246
def test_fail_validator(self):
169247
fake_input = self.get_input('point.xsd', 'point.xsd', FORMATS.SHP.mime_type)

0 commit comments

Comments
 (0)