extend BDD API tests to query via Python frameworks

A new config option ENGINE allows to choose between php and any of the
supported Python engines.
This commit is contained in:
Sarah Hoffmann
2022-12-06 11:20:50 +01:00
parent d7bc846c3c
commit 7219ee6532
6 changed files with 83 additions and 11 deletions

View File

@@ -28,6 +28,7 @@ userconfig = {
'SERVER_MODULE_PATH' : None,
'TOKENIZER' : None, # Test with a custom tokenizer
'STYLE' : 'extratags',
'API_ENGINE': 'php',
'PHPCOV' : False, # set to output directory to enable code coverage
}

View File

@@ -5,9 +5,13 @@
# Copyright (C) 2022 by the Nominatim developer community.
# For a full list of authors see the git log.
from pathlib import Path
import importlib
import sys
import tempfile
from asgi_lifespan import LifespanManager
import httpx
import psycopg2
import psycopg2.extras
@@ -49,6 +53,12 @@ class NominatimEnvironment:
self.api_db_done = False
self.website_dir = None
self.api_engine = None
if config['API_ENGINE'] != 'php':
if not hasattr(self, f"create_api_request_func_{config['API_ENGINE']}"):
raise RuntimeError(f"Unknown API engine '{config['API_ENGINE']}'")
self.api_engine = getattr(self, f"create_api_request_func_{config['API_ENGINE']}")()
def connect_database(self, dbname):
""" Return a connection to the database with the given name.
Uses configured host, user and port.
@@ -323,3 +333,49 @@ class NominatimEnvironment:
WHERE class='place' and type='houses'
and osm_type='W'
and ST_GeometryType(geometry) = 'ST_LineString'""")
def create_api_request_func_starlette(self):
import nominatim.server.starlette.server
async def _request(endpoint, params, project_dir, environ):
app = nominatim.server.starlette.server.get_application(project_dir, environ)
async with LifespanManager(app):
async with httpx.AsyncClient(app=app, base_url="http://nominatim.test") as client:
response = await client.get(f"/{endpoint}", params=params)
return response.text, response.status_code
return _request
def create_api_request_func_sanic(self):
import nominatim.server.sanic.server
async def _request(endpoint, params, project_dir, environ):
app = nominatim.server.sanic.server.get_application(project_dir, environ)
_, response = await app.asgi_client.get(f"/{endpoint}", params=params)
return response.text, response.status_code
return _request
def create_api_request_func_falcon(self):
import nominatim.server.falcon.server
import falcon.testing
async def _request(endpoint, params, project_dir, environ):
app = nominatim.server.falcon.server.get_application(project_dir, environ)
async with falcon.testing.ASGIConductor(app) as conductor:
response = await conductor.get(f"/{endpoint}", params=params)
return response.text, response.status_code
return _request

View File

@@ -9,10 +9,12 @@
Queries may either be run directly via PHP using the query script
or via the HTTP interface using php-cgi.
"""
from pathlib import Path
import json
import os
import re
import logging
import asyncio
from urllib.parse import urlencode
from utils import run_script
@@ -72,6 +74,16 @@ def send_api_query(endpoint, params, fmt, context):
for h in context.table.headings:
params[h] = context.table[0][h]
if context.nominatim.api_engine is None:
return send_api_query_php(endpoint, params, context)
return asyncio.run(context.nominatim.api_engine(endpoint, params,
Path(context.nominatim.website_dir.name),
context.nominatim.test_env))
def send_api_query_php(endpoint, params, context):
env = dict(BASE_SERVER_ENV)
env['QUERY_STRING'] = urlencode(params)