mirror of
https://github.com/geoserver/geoserver-cloud.git
synced 2024-10-23 09:14:35 +08:00
Add acceptance tests
This commit is contained in:
parent
cd03d921f7
commit
32f6a9b633
44
.github/workflows/build.yaml
vendored
44
.github/workflows/build.yaml
vendored
@ -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 {}
|
||||
|
4
.github/workflows/pull-request.yaml
vendored
4
.github/workflows/pull-request.yaml
vendored
@ -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
|
||||
|
18
Makefile
18
Makefile
@ -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
3
acceptance_tests/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# ignore all python cache files recursively
|
||||
**/__pycache__/
|
||||
poetry.lock
|
15
acceptance_tests/Dockerfile
Normal file
15
acceptance_tests/Dockerfile
Normal 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"]
|
18
acceptance_tests/README.md
Normal file
18
acceptance_tests/README.md
Normal 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 .
|
||||
```
|
17
acceptance_tests/pyproject.toml
Normal file
17
acceptance_tests/pyproject.toml
Normal 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"
|
12
acceptance_tests/tests/conftest.py
Normal file
12
acceptance_tests/tests/conftest.py
Normal 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)
|
140
acceptance_tests/tests/test_cascaded_stores.py
Normal file
140
acceptance_tests/tests/test_cascaded_stores.py
Normal 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)
|
23
acceptance_tests/tests/test_workspace.py
Normal file
23
acceptance_tests/tests/test_workspace.py
Normal 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
1
ci/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
c2cciutils[checks]==1.6.18
|
95
compose/acceptance.yml
Normal file
95
compose/acceptance.yml
Normal 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
|
@ -8,6 +8,7 @@ volumes:
|
||||
type: none
|
||||
o: bind
|
||||
device: $PWD/../config
|
||||
driver: local
|
||||
|
||||
x-gs-dependencies: &gs-dependencies
|
||||
rabbitmq:
|
||||
|
Loading…
Reference in New Issue
Block a user