Add acceptance tests

This commit is contained in:
Cécile Vuilleumier 2024-09-30 09:49:20 +02:00
parent cd03d921f7
commit 32f6a9b633
No known key found for this signature in database
GPG Key ID: A16CD36473EF733C
13 changed files with 373 additions and 18 deletions

View File

@ -23,25 +23,35 @@ jobs:
uses: actions/checkout@v2
with:
submodules: recursive
- name: Setup Java
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: '21'
cache: 'maven'
# - name: Setup Java
# uses: actions/setup-java@v2
# with:
# distribution: 'temurin'
# java-version: '21'
# cache: 'maven'
- name: Install CI dependencies
run: python3 -m pip install --user --requirement=ci/requirements.txt
- name: Validate source code formatting
run: make lint
# - name: Validate source code formatting
# run: make lint
- name: Build and test
# - name: Build and test
# run: |
# make install test
# - name: Build docker images
# run: |
# make build-image
- name: Run acceptance tests
run: |
make install test
make acceptance-tests
- name: Build docker images
run: |
make build-image
- name: Print docker compose logs
run: (cd compose && c2cciutils-docker-logs)
if: always()
- name: Remove project jars from cached repository
run: |
rm -rf ~/.m2/repository/org/geoserver
find ~/.m2/repository -name "*SNAPSHOT*" -type d | xargs rm -rf {}
# - name: Remove project jars from cached repository
# run: |
# rm -rf ~/.m2/repository/org/geoserver
# find ~/.m2/repository -name "*SNAPSHOT*" -type d | xargs rm -rf {}

View File

@ -47,6 +47,10 @@ jobs:
run: |
make build-image
- name: Run acceptance tests
run: |
make acceptance-tests
- name: Remove project jars from cached repository
run: |
rm -rf ~/.m2/repository/org/geoserver

View File

@ -1,7 +1,13 @@
all: install test build-image
TAG=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout`
TAG=$(shell mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
COSIGN_PASSWORD := $(COSIGN_PASSWORD)
COMPOSE_PGCONFIG_OPTIONS ?= -f compose.yml -f catalog-pgconfig.yml
COMPOSE_DATADIR_OPTIONS ?= -f compose.yml -f catalog-datadir.yml
COMPOSE_ACCEPTANCE_PGCONFIG_OPTIONS ?= $(COMPOSE_PGCONFIG_OPTIONS) -f acceptance.yml
COMPOSE_ACCEPTANCE_DATADIR_OPTIONS ?= $(COMPOSE_DATADIR_OPTIONS) -f acceptance.yml
UID=$(shell id -u)
GID=$(shell id -g)
clean:
./mvnw clean
@ -78,3 +84,13 @@ verify-image:
fi; \
done'
.PHONY: build-acceptance
build-acceptance:
docker build --tag=acceptance:$(TAG) acceptance_tests
.PHONY: acceptance-tests
acceptance-tests:
acceptance-tests: build-acceptance
(cd compose/ && TAG=$(TAG) GS_USER=$(UID):$(GID) docker compose $(COMPOSE_ACCEPTANCE_DATADIR_OPTIONS) up -d)
sleep 30
(cd compose/ && TAG=$(TAG) GS_USER=$(UID):$(GID) docker compose $(COMPOSE_ACCEPTANCE_DATADIR_OPTIONS) exec -T acceptance pytest . -vvv --color=yes)

3
acceptance_tests/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# ignore all python cache files recursively
**/__pycache__/
poetry.lock

View File

@ -0,0 +1,15 @@
FROM ubuntu:24.04 AS base
RUN apt-get update \
&& apt-get upgrade --assume-yes \
&& apt-get install --assume-yes --no-install-recommends \
vim curl jq libmagic1 zip python3-pip libpq-dev python3-dev gcc \
&& rm -rf /var/lib/apt/lists/* \
&& rm /usr/lib/python*/EXTERNALLY-MANAGED
COPY . /acceptance_tests
WORKDIR /acceptance_tests
RUN python3 -m pip install --disable-pip-version-check .
CMD ["sleep", "infinity"]

View File

@ -0,0 +1,18 @@
# GeoServer Cloud acceptance tests
## Requirements
[Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer)
## Installation
```shell
poetry install
```
# Run the tests
First start the docker composition then run:
```shell
GEOSERVER_URL=http://localhost:9090/geoserver/cloud poetry run pytest -vvv .
```

View File

@ -0,0 +1,17 @@
[tool.poetry]
name = "acceptance-tests"
version = "0.1.0"
description = "todo"
authors = ["todo"]
readme = "README.md"
packages = [{ include = "tests" }]
[tool.poetry.dependencies]
python = "^3.10"
pytest = "^8.3.3"
geoservercloud = "^0.2.5"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

View File

@ -0,0 +1,12 @@
import os
import pytest
from geoservercloud import GeoServerCloud
GEOSERVER_URL = os.getenv("GEOSERVER_URL", "http://gateway:8080/geoserver/cloud")
@pytest.fixture(scope="module")
def geoserver():
yield GeoServerCloud(GEOSERVER_URL)

View File

@ -0,0 +1,140 @@
import json
import pytest
from conftest import GEOSERVER_URL
from geoservercloud import GeoServerCloud
WORKSPACE = "test_cascade"
WMS_STORE = "test_cascaded_wms_store"
WMS_URL = "https://wms.geo.admin.ch/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities"
WMS_LAYER = "ch.swisstopo.swissboundaries3d-gemeinde-flaeche.fill"
WMTS_STORE = "test_cascaded_wmts_store"
WMTS_URL = "https://wmts.geo.admin.ch/EPSG/4326/1.0.0/WMTSCapabilities.xml"
WMTS_LAYER = "ch.swisstopo.pixelkarte-grau"
def create_cascaded_wms_store_payload():
return {
"wmsStore": {
"name": WMS_STORE,
"type": "WMS",
"enabled": "true",
"workspace": {"name": WORKSPACE},
"metadata": {"entry": {"@key": "useConnectionPooling", "$": "true"}},
"_default": "false",
"disableOnConnFailure": "false",
"capabilitiesURL": WMS_URL,
"maxConnections": 6,
"readTimeout": 60,
"connectTimeout": 30,
}
}
def delete_wms_store(geoserver):
geoserver.delete_request(
f"/rest/workspaces/{WORKSPACE}/wmsstores/{WMS_STORE}?recurse=true"
)
def delete_wmts_store(geoserver):
geoserver.delete_request(
f"/rest/workspaces/{WORKSPACE}/wmtsstores/{WMTS_STORE}?recurse=true"
)
@pytest.fixture(scope="module")
def geoserver():
geoserver = GeoServerCloud(url=GEOSERVER_URL)
geoserver.create_workspace(WORKSPACE, set_default_workspace=True)
geoserver.publish_workspace(WORKSPACE)
yield geoserver
# geoserver.delete_workspace(WORKSPACE)
def test_cascaded_wms(geoserver):
format = "image/jpeg"
# Create WMS store
payload = create_cascaded_wms_store_payload()
response = geoserver.post_request(
f"/rest/workspaces/{WORKSPACE}/wmsstores", json=payload
)
assert response.status_code == 201
# Publish layer
payload = {
"wmsLayer": {
"name": WMS_LAYER,
}
}
response = geoserver.post_request(
f"/rest/workspaces/{WORKSPACE}/wmsstores/{WMS_STORE}/wmslayers",
json=payload,
)
assert response.status_code == 201
# Perform GetMap request
response = geoserver.get_map(
layers=[WMS_LAYER],
bbox=(2590000, 1196000, 2605000, 1203000),
size=(10, 10),
format=format,
)
assert response.info().get("Content-Type") == format
# Perform GetFeatureInfo request
response = geoserver.get_feature_info(
layers=[WMS_LAYER],
bbox=(2599999.5, 1199999.5, 2600000.5, 1200000.5),
size=(40, 40),
info_format="application/json",
xy=(20, 20),
)
# Due to conflicting formats, the forwarding of GetFeatureInfo requests from map.geo.admin (MapServer)
# through GeoServer is not possible as of 2.25.0.
# See https://sourceforge.net/p/geoserver/mailman/message/30757977/
data = json.loads(response.read().decode("utf-8"))
assert data.get("features") == []
delete_wms_store(geoserver)
def test_cascaded_wmts(geoserver):
format = "image/jpeg"
# Create WMTS store
response = geoserver.create_wmts_store(
WORKSPACE,
WMTS_STORE,
capabilities="https://wmts.geo.admin.ch/EPSG/4326/1.0.0/WMTSCapabilities.xml",
)
assert response.status_code == 201
# Publish layer (GeoServer)
response = geoserver.create_wmts_layer(WORKSPACE, WMTS_STORE, WMTS_LAYER)
assert response.status_code == 201
response = geoserver.get_request(
f"/rest/workspaces/{WORKSPACE}/wmtsstores/{WMTS_STORE}/layers/{WMTS_LAYER}.json"
)
assert response.status_code == 200
# Publish the layer in GWC
response = geoserver.publish_gwc_layer(WORKSPACE, WMTS_LAYER)
assert response.status_code == 200
# Perform GetTile request (GWC)
response = geoserver.get_tile(
layer=f"{WORKSPACE}:{WMTS_LAYER}",
tile_matrix_set="EPSG:4326",
tile_matrix="EPSG:4326:9",
row=122,
column=534,
format=format,
)
assert response.info().get("Content-Type") == format
response = geoserver.delete_request(f"/gwc/rest/layers/{WORKSPACE}:{WMTS_LAYER}")
assert response.status_code == 200
delete_wmts_store(geoserver)

View File

@ -0,0 +1,23 @@
def test_create_get_and_delete_workspace(geoserver):
workspace = "test_create_workspace"
response = geoserver.create_workspace(workspace)
assert response.status_code == 201
response = geoserver.get_request(f"/rest/workspaces/{workspace}.json")
assert response.status_code == 200
response = geoserver.publish_workspace(workspace)
assert response.status_code == 200
response = geoserver.delete_workspace(workspace)
assert response.status_code == 200
def test_update_workspace(geoserver):
workspace = "update_workspace"
response = geoserver.create_workspace(workspace, isolated=True)
assert response.status_code == 201
response = geoserver.get_request(f"/rest/workspaces/{workspace}.json")
assert response.json().get("workspace").get("isolated") == True
response = geoserver.create_workspace(workspace, isolated=False)
assert response.status_code == 200
response = geoserver.get_request(f"/rest/workspaces/{workspace}.json")
assert response.json().get("workspace").get("isolated") == False
geoserver.delete_workspace(workspace)

1
ci/requirements.txt Normal file
View File

@ -0,0 +1 @@
c2cciutils[checks]==1.6.18

95
compose/acceptance.yml Normal file
View File

@ -0,0 +1,95 @@
services:
acceptance:
image: acceptance:${TAG}
depends_on:
init-datadir:
condition: service_completed_successfully
gateway:
condition: service_healthy
discovery:
condition: service_healthy
config:
condition: service_healthy
wms:
condition: service_healthy
# TODO: add wcs and wps
wfs:
condition: service_healthy
gwc:
condition: service_healthy
webui:
condition: service_started
rest:
condition: service_healthy
acl:
condition: service_started
# For github CI
acl:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
gateway:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
discovery:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
config:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
wms:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
healthcheck:
retries: 20
wfs:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
healthcheck:
retries: 20
rest:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
healthcheck:
retries: 20
gwc:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
healthcheck:
retries: 20
webui:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
rabbitmq:
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M

View File

@ -8,6 +8,7 @@ volumes:
type: none
o: bind
device: $PWD/../config
driver: local
x-gs-dependencies: &gs-dependencies
rabbitmq: