Skip to content

Commit

Permalink
Run CITE tests for ogcapi-features 1.0
Browse files Browse the repository at this point in the history
* Add an `ogcapi-features` maven profile to `src/web/app/pom.xml`
* Runs the CITE tests agains all the feature types in the "release" data directory
* The WFS is configured to declare EPSG:4326 and EPSG:3857 for all
  FeatureTypes. Otherwise the tests will try to reproject amongst incompatible
  coordinate systems or boundaries.
  * `tiger:giant_polyon` is disabled. The test suite will try to reproject it even if it declares a single CRS.
  • Loading branch information
groldan committed Nov 8, 2024
1 parent ef583aa commit 514b811
Show file tree
Hide file tree
Showing 279 changed files with 8,106 additions and 166 deletions.
119 changes: 119 additions & 0 deletions .github/workflows/cite.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Run CITE Tests

on:
push:
# branches:
# - main
pull_request:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
build-war:
runs-on: ubuntu-latest
name: Build GeoServer WAR
steps:
- name: Checkout repository (shallow clone)
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '11'
- name: Set up Maven
uses: stCarolas/setup-maven@v5
with:
maven-version: 3.9.8
- name: Maven repository caching
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: gs-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
gs-${{ runner.os }}-maven-
- name: Build geoserver.war
working-directory: build/cite
run: make war

- name: Upload geoserver.war as artifact
uses: actions/upload-artifact@v3
with:
name: geoserver-war
path: build/cite/geoserver/geoserver.war

run-cite-tests:
needs: build-war
runs-on: ubuntu-latest
name: CITE
strategy:
fail-fast: false # Prevents other matrix jobs from being canceled if one fails
matrix:
#suite: [ogcapi-features10, wcs10, wcs11, wfs10, wfs11, wms10, wms11, wms13]
suite: [ogcapi-features10, wms11, wcs11]

steps:
- name: Checkout repository (shallow clone)
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Download geoserver.war artifact
uses: actions/download-artifact@v3
with:
name: geoserver-war
path: build/cite/geoserver/

- name: List geoserver.war contents
run: unzip -l build/cite/geoserver/geoserver.war

- name: Build ogccite/geoserver:${{ matrix.suite }} docker image
working-directory: build/cite
run: make build suite=${{ matrix.suite }}

- name: Pull teamengine and other required images
working-directory: build/cite
run: make pull suite=${{ matrix.suite }}

# optional, used to print out a human readable summary of test failures from the testng results xml
- name: Install xmlstarlet
run: sudo apt-get update && sudo apt-get install -y xmlstarlet

- name: Print services and images used for the ${{ matrix.suite }} test run
working-directory: build/cite
run: make print-docker-compose-services suite=${{ matrix.suite }}

- name: Run the ${{ matrix.suite }} CITE test suite
working-directory: build/cite
run: |
chmod o+w logs
make test suite=${{ matrix.suite }}
- name: Print GeoServer logs
if: always()
working-directory: build/cite
run: make print-logs suite=${{ matrix.suite }} service=geoserver

- name: Print TeamEngine logs
if: always()
working-directory: build/cite
run: make print-logs suite=${{ matrix.suite }} service=teamengine

- name: Shutdown containers
if: always()
working-directory: build/cite
run: make down

- name: Upload logs folder
if: always()
uses: actions/upload-artifact@v3
with:
name: cite-${{ matrix.suite }}-logs
path: build/cite/logs/
167 changes: 148 additions & 19 deletions build/cite/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,163 @@
.DEFAULT_GOAL := help
.PHONY = help
suite =
war_url = "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip"
# `make war` will build the war from ../src/web/app and copy it here
war_url = ./geoserver/geoserver.war

# alternatively you can use one in .war or .zip format from an URL, for example:
# war_url = "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip"
# but it may not have all the required extensions so make sure you know what you're doing


.PHONY: help
help:
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'

clean: ## Will Clean the Environment of previous runs.
.PHONY: clean
clean: down cleanlogs ## Clean the Environment of previous runs.

.PHONY: down
down:
@echo Cleaning up previous runs
docker-compose down --remove-orphans --rmi all -v
docker-compose rm -vfs
@docker compose down --remove-orphans -v
@docker compose rm -vfs

.PHONY: cleanlogs
cleanlogs:
@echo Cleanning the previous logs.
rm -Rf logs/*
@rm -Rf logs/*

.PHONY: build
build: $(suite) ## Build the GeoServer Docker Image for the Environment.
@echo Building the GeoServer Docker Image for the $(suite) test suite
@docker compose -f compose.yml -f ./$(suite)/compose.override.yml \
build --no-cache --build-arg SOURCE_FILE=${war_url} geoserver

.PHONY: version
version: $(suite) ## Print the version of the GeoServer on the current docker.
@echo Getting the GeoServer version.
@docker run -i --rm ogccite/geoserver:$(suite) bash -c \
'cd /usr/local/tomcat/webapps/ && \
if [ -d geoserver ]; then cat geoserver/META-INF/MANIFEST.MF; \
elif [ -f geoserver.war ]; then jar -xf geoserver.war; cat META-INF/MANIFEST.MF; \
fi'

.PHONY: test
test: $(suite) ## Run the Test Suite with teamengine.
ifeq ($(suite), ogcapi-features10)
@$(MAKE) test-rest suite=$(suite)
else
@$(MAKE) test-cli suite=$(suite)
endif

.PHONY: test-cli
test-cli: $(suite)
@echo Running the $(suite) test suite with teamengine CLI
@docker compose -f compose.yml -f ./$(suite)/compose.override.yml \
up --force-recreate --exit-code-from teamengine teamengine

.PHONY: test-rest
test-rest: $(suite)
@echo "Running the $(suite) test suite with the teamengine REST API"
@$(MAKE) start suite=$(suite)
@$(MAKE) run suite=$(suite)
@$(MAKE) validate-testng-results


build: $(suite) ## Will Build the GeoServer Docker Image for the Environment.
@echo Build the GeoServer Docker Image
docker-compose -f docker-compose.yml -f ./$(suite)/docker-compose.override.yml \
build --build-arg GEOSERVER_WEBAPP_SRC=${war_url} geoserver
# Launches the geoserver and teamengine containers
.PHONY: start
start: $(suite)
@echo Starting containers
@docker compose -f compose.yml -f ./$(suite)/compose.override.yml \
up -d --force-recreate

version: $(suite) ## Will give the version of the GeoServer on the current docker.
@echo Getting the GeoServer version.
docker run -i ogccite/geoserver:$(suite) bash -c 'cd /usr/local/tomcat/webapps/ && if [ -f geoserver.war ]; then unzip -q geoserver.war; cat META-INF/MANIFEST.MF; else cat META-INF/MANIFEST.MF; fi'
.PHONY: run
run: $(suite)
@$(MAKE) wait-for url="http://localhost:8090/geoserver/web/wicket/resource/org.geoserver.web.GeoServerBasePage/img/logo.png" timeout=60
@$(MAKE) wait-for url="http://localhost:8080/teamengine/site/logo.png" timeout=60
@docker compose -f compose.yml -f ./$(suite)/compose.override.yml \
exec teamengine /bin/bash -c "/run-test.sh $(suite)"

test: $(suite) | version ## Will running the Suite test with teamengine.
@echo running the Suite test with teamengine
docker-compose -f docker-compose.yml -f ./$(suite)/docker-compose.override.yml \
up --force-recreate --exit-code-from teamengine teamengine
# first prints out a human readable report of test failures, if xmlstarlet is installed,
# and then a summary of passed and failed test counts. This last step will result in a
# non zero exit code if there are test failures.
.PHONY: validate-testng-results
validate-testng-results: $(suite)
@./testng-results-report.sh logs/testng-results.xml
@./testng-results-validate.sh logs/testng-results.xml

webUI: ## Will running the Suite test with teamengine.

.PHONY: webUI
webUI: ## Run the Suite test with teamengine.
@echo running the Suite test with teamengine webUI
docker-compose -f docker-compose.yml -f ./interactive/docker-compose.override.yml \
up --force-recreate --no-deps --exit-code-from teamengine teamengine
@docker compose -f compose.yml -f ./interactive/compose.override.yml \
up --force-recreate --no-deps --exit-code-from teamengine teamengine

.PHONY: pull
pull: $(suite)
@echo starting containers
@docker compose -f compose.yml -f ./$(suite)/compose.override.yml \
pull --ignore-buildable

.PHONY: war
war: build-war copy-war ## Build the geoserver.war file to use for testing and place it in ./geoserver/geoserver.war

.PHONY: build-war
build-war:
@mvn -Pogcapi-features \
clean package -f ../../src/ -DskipTests -T1C -ntp

.PHONY: copy-war
copy-war:
cp ../../src/web/app/target/geoserver.war geoserver/geoserver.war

# Waits for an url to be available (returning HTTP status code 200 or 302)
# Usage: make wait-for url=<URL> timeout=<seconds>
.PHONY: wait-for
wait-for:
@if [ -z "$(url)" ]; then \
echo "Error: url parameter is required. Usage: make wait-for url=<URL> timeout=<seconds>"; \
exit 1; \
fi
@if [ -z "$(timeout)" ]; then \
echo "Error: timeout parameter is required. Usage: make wait-for url=<URL> timeout=<seconds>"; \
exit 1; \
fi
@echo "Waiting for $(url) to be available (timeout: $(timeout) seconds)..."
@start_time=$$(date +%s); \
while true; do \
elapsed_time=$$(( $$(date +%s) - $$start_time )); \
if [ $$elapsed_time -ge $(timeout) ]; then \
echo "Timeout reached: $(url) is not available after $(timeout) seconds"; \
exit 1; \
fi; \
if curl -s -o /dev/null -w "%{http_code}" $(url) | grep -E "^(200|302)$$" > /dev/null; then \
echo "$(url) is available!"; \
break; \
fi; \
echo "Waiting for $(url)..."; \
sleep 5; \
done

# Prints logs for the specified suite and optionally a specific service.
# Usage:
# make print-logs suite=<suite-name> [service=<service-name>]
# If 'service' is not specified, logs for all services in the suite will be shown.
.PHONY: print-logs
print-logs:
@if [ -z "$(suite)" ]; then \
echo "Error: suite variable must be provided. Usage: make print-logs suite=<suite-name> [service=<service-name>]"; \
exit 1; \
fi
@if [ -n "$(service)" ]; then \
docker compose -f compose.yml -f ./$(suite)/compose.override.yml logs $(service); \
else \
docker compose -f compose.yml -f ./$(suite)/compose.override.yml logs; \
fi

# Used in CI/CD to print which services and images are going to be run
# Requires `jq`, comes pre-installed in github actions `ubuntu-latest`
.PHONY: print-docker-compose-services
print-docker-compose-services: $(suite)
@echo Services used in the $(suite) test suite:
@docker compose -f compose.yml -f $(suite)/compose.override.yml config --format=json | jq -r '.services | to_entries | map("\t\(.key):\n \t\timage: \(.value.image)")[]'
1 change: 1 addition & 0 deletions build/cite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ make clean build test suite=<suite test>

### example:
Run the `wms11` suite:

```
make clean build test suite=wms11
```
44 changes: 44 additions & 0 deletions build/cite/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
volumes:
gs_logs:
gs_gwc_cache_dir:

services:
geoserver:
image: ogccite/geoserver:${GEOSERVER_TAG:-latest}
build:
context: .
dockerfile: ./geoserver/Dockerfile
args:
SOURCE_FILE: "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip"
# override as appropriate (e.g. ./wfs11/citewfs-1.1)
GEOSERVER_DATA_DIR_SRC:
ports:
- 8090:8080
env_file:
- ./.env
- ./geoserver/geoserver.env
environment:
JAVA_OPTS: >-
-Xms${HEAP_SIZE_MIN:-1024m}
-Xmx${HEAP_SIZE_MAX:-1024m}
volumes:
- gs_logs:/opt/geoserver_data/logs:rw
- gs_gwc_cache_dir:/opt/geowebcache_data:rw

teamengine:
# see https://github.com/opengeospatial/teamengine-docker
# there's ogccite/teamengine-production and ogccite/teamengine-beta
#image: ogccite/teamengine-production
image: geoserver-docker.osgeo.org/geoserver-cite:${TEAMENGINE_TAG:-teamengine_latest}
hostname: teamengine.local
ports:
- 8080:8080
depends_on:
- geoserver
volumes:
- ./logs:/logs:rw
# old teamengine location
- ./logs:/home/teamengine/te_base/users/teamengine:rw
# location used by new teamengine running tests through REST API
- ./logs:/usr/local/tomcat/te_base/users/ogctest/rest:rw
- ./run-test.sh:/run-test.sh
37 changes: 0 additions & 37 deletions build/cite/docker-compose.yml

This file was deleted.

1 change: 1 addition & 0 deletions build/cite/geoserver/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
geoserver.war
Empty file removed build/cite/geoserver/.placeholder
Empty file.
Loading

0 comments on commit 514b811

Please sign in to comment.