Newer
Older
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# MapServer REST API is a python wrapper around MapServer which #
# allows to manipulate a mapfile in a RESTFul way. It has been #
# developped to match as close as possible the way the GeoServer #
# REST API acts. #
# #
# Copyright (C) 2011-2013 Neogeo Technologies. #
# #
# This file is part of MapServer Rest API. #
# #
# MapServer Rest API is free software: you can redistribute it #
# and/or modify it under the terms of the GNU General Public License #
# as published by the Free Software Foundation, either version 3 of #
# the License, or (at your option) any later version. #
# #
# MapServer Rest API is distributed in the hope that it will be #
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty #
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
import utils
from utils import APIRequest
import sys
Wannes Rombouts
committed
import random
Wannes Rombouts
committed
def _test_workspaces(target, map_name, delete=True):
# GET workspaces.
wss = APIRequest("GET", target + "/maps/" + map_name + "/workspaces")["workspaces"]
assert len(wss) == 1
assert wss[0]["name"] == "default"
# GET workspaceName
ws = APIRequest("GET", wss[0]["href"])["workspace"]
assert ws["name"] == wss[0]["name"]
Wannes Rombouts
committed
#
# Test DataStores.
#
# GET dataStores
dss = APIRequest("GET", ws["dataStores"]["href"])["dataStores"]
# POST a datastore and GET it
name, title = "testDS1", "test datastore 1"
_, r = APIRequest("POST", ws["dataStores"]["href"], {"dataStore":{"name":name, "title":title}},
get_response=True)
Wannes Rombouts
committed
ds_link = r.getheader("Location").rsplit(".", 1)[0]
ds = APIRequest("GET", ds_link)["dataStore"]
assert ds["name"] == name
assert ds["title"] == title
# PUT a datastore
ds["title"] = title.upper()
del ds["href"]
APIRequest("PUT", ds_link, {"dataStore":ds})
ds = APIRequest("GET", ds_link)["dataStore"]
assert ds["title"] == title.upper()
# GET featuretypes
fts = APIRequest("GET", ds["href"])["featureTypes"]
assert len(fts) == 0
# PUT file, and check if datastore is updated.
APIRequest("PUT", ds_link + "/file.shp", open("./files/timezones_shp.zip", "rb"),
encode=None, content_type="application/zip")
ds = APIRequest("GET", ds_link)["dataStore"]
Wannes Rombouts
committed
assert ds["connectionParameters"]["url"] == "file:workspaces/%s/datastores/%s/timezones.shp" % (ws["name"], ds["name"])
Wannes Rombouts
committed
# POST a featuretype and GET it
Wannes Rombouts
committed
name, title = "timezones", "test feature type 1"
_, r = APIRequest("POST", ds["href"], {"featureType":{"name":name, "title":title}},
get_response=True)
Wannes Rombouts
committed
ft_link = r.getheader("Location").rsplit(".", 1)[0]
ft = APIRequest("GET", ft_link)["featureType"]
assert ft["name"] == name
Wannes Rombouts
committed
assert ft["title"] == title
# PUT a featuretype
ft["title"] = title.upper()
APIRequest("PUT", ft_link, {"featureType":ft})
ft = APIRequest("GET", ft_link)["featureType"]
assert ft["title"] == title.upper()
# DELETE stuff
Wannes Rombouts
committed
if delete:
Wannes Rombouts
committed
Wannes Rombouts
committed
APIRequest("DELETE", ft_link)
fts = APIRequest("GET", ds_link + "/featuretypes")["featureTypes"]
assert len(fts) == 0
APIRequest("DELETE", ds_link)
dss = APIRequest("GET", ws["dataStores"]["href"])["dataStores"]
assert len(dss) == 0
Wannes Rombouts
committed
#
# Test CoverageStores.
#
# GET coverageStores
css = APIRequest("GET", ws["coverageStores"]["href"])["coverageStores"]
assert len(css) == 0
# POST a coverageStore and GET it
name, title = "testCS1", "test coverageStore 1"
_, r = APIRequest("POST", ws["coverageStores"]["href"], {"coverageStore":{"name":name, "title":title}},
get_response=True)
Wannes Rombouts
committed
cs_link = r.getheader("Location").rsplit(".", 1)[0]
Wannes Rombouts
committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
cs = APIRequest("GET", cs_link)["coverageStore"]
assert cs["name"] == name
assert cs["title"] == title
# PUT a coverageStore
cs["title"] = title.upper()
del cs["href"]
APIRequest("PUT", cs_link, {"coverageStore":cs})
cs = APIRequest("GET", cs_link)["coverageStore"]
assert cs["title"] == title.upper()
# GET coverages
fts = APIRequest("GET", cs["href"])["coverages"]
assert len(fts) == 0
# PUT file, and check if coverageStore is updated.
APIRequest("PUT", cs_link + "/file.tif", open("./files/HYP_LR.zip", "rb"),
encode=None, content_type="application/zip")
cs = APIRequest("GET", cs_link)["coverageStore"]
assert cs["connectionParameters"]["url"] == "file:workspaces/%s/coveragestores/%s/HYP_LR/HYP_LR.tif" % (ws["name"], cs["name"])
# POST a coverage and GET it
name, title = "HYP_LR", "test coverage 1"
_, r = APIRequest("POST", cs["href"], {"coverage":{"name":name, "title":title}},
get_response=True)
Wannes Rombouts
committed
c_link = r.getheader("Location").rsplit(".", 1)[0]
Wannes Rombouts
committed
Wannes Rombouts
committed
ft = APIRequest("GET", c_link)["coverage"]
Wannes Rombouts
committed
assert ft["name"] == name
assert ft["title"] == title
# PUT a coverage
ft["title"] = title.upper()
Wannes Rombouts
committed
APIRequest("PUT", c_link, {"coverage":ft})
Wannes Rombouts
committed
Wannes Rombouts
committed
ft = APIRequest("GET", c_link)["coverage"]
Wannes Rombouts
committed
assert ft["title"] == title.upper()
# DELETE stuff
Wannes Rombouts
committed
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
if delete:
APIRequest("DELETE", c_link)
fts = APIRequest("GET", cs_link + "/coverages")["coverages"]
assert len(fts) == 0
APIRequest("DELETE", cs_link)
css = APIRequest("GET", ws["coverageStores"]["href"])["coverageStores"]
assert len(css) == 0
return ws
def _test_styles(target, map_name):
# Lets DELETE all the styles.
styles = APIRequest("GET", target + "/maps/" + map_name + "/styles")["styles"]
for style in styles:
if style["name"].startswith("__test_"):
APIRequest("DELETE", style["href"])
styles = APIRequest("GET", target + "/maps/" + map_name + "/styles")["styles"]
assert len([style for style in styles if style["name"].startswith("__test_")]) == 0
# Lets POST a style and GET it.
name = "__test_awesome_style_name"
data = open("./files/style.sld").read()
noise = "".join(map(str, random.sample(xrange(10000000), 60)))
# We add some noise, so we can check PUT later.
styles = APIRequest("POST", target + "/maps/" + map_name + "/styles?name=" + name,
encode=None, content_type="application/vnd.ogc.sld+xml", data=data+noise)
styles = APIRequest("GET", target + "/maps/" + map_name + "/styles")["styles"]
assert len(styles) == 1
assert styles[0]["name"] == name
st_link = styles[0]["href"].rsplit(".", 1)[0]
style = APIRequest("GET", st_link)
content = APIRequest("GET", style["href"], encode=None, decode=None)
assert content == data+noise
# Use PUT to remove the noise in the file.
styles = APIRequest("PUT", style["href"], encode=None, content_type="application/vnd.ogc.sld+xml", data=data)
content = APIRequest("GET", style["href"], encode=None, decode=None)
assert content == data
def _test_layers(target, map_name):
# We need to setup something to work with first.
# GET workspaces.
wss = APIRequest("GET", target + "/maps/" + map_name + "/workspaces")["workspaces"]
ws = APIRequest("GET", wss[0]["href"])["workspace"]
# DataStores.
name, title = "testDS1", "test datastore 1"
_, r = APIRequest("POST", ws["dataStores"]["href"], {"dataStore":{"name":name, "title":title}},
get_response=True)
ds_link = r.getheader("Location").rsplit(".", 1)[0]
# PUT file
APIRequest("PUT", ds_link + "/file.shp", open("./files/timezones_shp.zip", "rb"),
encode=None, content_type="application/zip")
ds = APIRequest("GET", ds_link)["dataStore"]
# POST a featuretype
name, title = "timezones", "test feature type 1"
_, r = APIRequest("POST", ds["href"], {"featureType":{"name":name, "title":title}},
get_response=True)
ft_link = r.getheader("Location").rsplit(".", 1)[0]
# CoverageStores.
name, title = "testCS1", "test coverageStore 1"
_, r = APIRequest("POST", ws["coverageStores"]["href"], {"coverageStore":{"name":name, "title":title}},
get_response=True)
cs_link = r.getheader("Location").rsplit(".", 1)[0]
# PUT file
APIRequest("PUT", cs_link + "/file.tif", open("./files/HYP_LR.zip", "rb"),
encode=None, content_type="application/zip")
cs = APIRequest("GET", cs_link)["coverageStore"]
# POST a coverage
name, title = "HYP_LR", "test coverage 1"
_, r = APIRequest("POST", cs["href"], {"coverage":{"name":name, "title":title}},
get_response=True)
c_link = r.getheader("Location").rsplit(".", 1)[0]
#
# OK, now the actual layer tests.
#
layers = APIRequest("GET", target + "/maps/" + map_name + "/layers")["layers"]
assert len(layers) == 0
# A first layer for featuretype
name = "FTlayerTest"
_, r = APIRequest("POST", target + "/maps/" + map_name + "/layers",
{"layer":{"name":name, "resource":{"href":ft_link}}},
get_response=True)
ftl_link = r.getheader("Location").rsplit(".", 1)[0]
# Check GET.
ftl = APIRequest("GET", ftl_link)["layer"]
assert ftl["name"] == name
assert ftl["type"] == "POLYGON"
# check GET fields
fields = APIRequest("GET", ftl_link + "/fields")["fields"]
assert len(fields) == 15
# check GET layerstyles
styles = APIRequest("GET", ftl_link + "/styles")["styles"]
assert len(styles) == 1
APIRequest("POST", ftl_link + "/styles", {"style":{"resource":{"href":styles[0]["href"]}}})
# A second layer for coverage
name = "ClayerTest"
_, r = APIRequest("POST", target + "/maps/" + map_name + "/layers",
{"layer":{"name":name, "resource":{"href":c_link}}},
get_response=True)
cl_link = r.getheader("Location").rsplit(".", 1)[0]
Wannes Rombouts
committed
# Check GET.
cl = APIRequest("GET", cl_link)["layer"]
assert cl["name"] == name
assert cl["type"] == "RASTER"
Wannes Rombouts
committed
# Check GET.
layers = APIRequest("GET", target + "/maps/" + map_name + "/layers")["layers"]
assert len(layers) == 2
# check GET fields
fields = APIRequest("GET", cl_link + "/fields")["fields"]
Wannes Rombouts
committed
assert len(fields) == 0
# check GET layerstyles
fields = APIRequest("GET", cl_link + "/styles")["styles"]
Wannes Rombouts
committed
assert len(fields) == 0
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# Now lets try layer groups.
layers = APIRequest("GET", target + "/maps/" + map_name + "/layergroups")["layerGroups"]
assert len(layers) == 0
# POST an empty group
name = "test_group"
_, r = APIRequest("POST", target + "/maps/" + map_name + "/layergroups", {"layerGroup":{"name":name}}, get_response=True)
g_link = r.getheader("Location").rsplit(".", 1)[0]
# GET it.
group = APIRequest("GET", g_link)["layerGroup"]
assert group["name"] == name
assert len(group["layers"]) == 0
# PUT some new layers in it.
group["layers"] = [x["name"] for x in group["layers"]] + [ftl["name"]]
del group["bounds"]
APIRequest("PUT", g_link, {"layerGroup":group})
# GET it.
group = APIRequest("GET", g_link)["layerGroup"]
assert len(group["layers"]) == 1
# PUT some new layers in it.
group["layers"] = [x["name"] for x in group["layers"]] + [cl["name"]]
del group["bounds"]
APIRequest("PUT", g_link, {"layerGroup":group})
# GET it.
group = APIRequest("GET", g_link)["layerGroup"]
assert len(group["layers"]) == 2
Wannes Rombouts
committed
def test_scenario():
# utils.default_encoding = "xml"
Wannes Rombouts
committed
target = "http://localhost:8080"
map_name = "tests"
# Clean the test file, now we are sure it is empty.
Wannes Rombouts
committed
APIRequest("DELETE", target + "/maps/" + map_name)
APIRequest("POST", target + "/maps", {"mapfile":{"name":map_name}})
Wannes Rombouts
committed
# _test_workspaces(target, map_name)
# _test_styles(target, map_name)
Wannes Rombouts
committed
_test_layers(target, map_name)