Skip to content

Commit 6cde594

Browse files
authored
Merge pull request #3943 from mapfish/test-cluster-mode-GSMFP-33
Add custer mode test in the CI
2 parents 46fdcf5 + 4ab4fc3 commit 6cde594

9 files changed

Lines changed: 153 additions & 8 deletions

File tree

.github/workflows/main.yaml

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,32 @@ jobs:
133133
if-no-files-found: ignore
134134
if: always()
135135

136-
- run: make acceptance-tests-up
137-
- run: make acceptance-tests-run
138-
- run: make acceptance-tests-down
136+
- name: Start the acceptance tests composition
137+
run: make acceptance-tests-up
138+
- name: Run the acceptance tests
139+
run: make acceptance-tests-run
140+
timeout-minutes: 6 # Add a timeout to catch performance regressions
139141
- run: c2cciutils-docker-logs || true
140142
if: always()
143+
- name: Stop the acceptance tests composition
144+
run: make acceptance-tests-down
145+
146+
- name: Start the acceptance tests composition (cluster)
147+
run: make acceptance-tests-up
148+
env:
149+
DOCKER_COMPOSE_ARGS: --file=docker-compose-cluster.yaml
150+
- name: Run the acceptance tests (cluster)
151+
run: make acceptance-tests-run
152+
timeout-minutes: 6 # Add a timeout to catch performance regressions
153+
env:
154+
DOCKER_COMPOSE_ARGS: --file=docker-compose-cluster.yaml
155+
MAPFISH_PRINT_TESTS_CLUSTER_MODE: 'true'
156+
- run: c2cciutils-docker-logs || true
157+
if: always()
158+
- name: Stop the acceptance tests composition (cluster)
159+
run: make acceptance-tests-down
160+
env:
161+
DOCKER_COMPOSE_ARGS: --file=docker-compose-cluster.yaml
141162

142163
- uses: actions/upload-artifact@v6
143164
with:

Makefile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
GIT_HEAD_ARG = --build-arg=GIT_HEAD=$(shell git rev-parse HEAD)
22
export DOCKER_BUILDKIT = 1
33

4+
# Set it to `--file=docker-compose-cluster.yaml` to run the acceptance tests in cluster mode
5+
DOCKER_COMPOSE_ARGS ?=
6+
47
.PHONY: clean
58
clean:
69
rm -rf .env examples/geoserver-data/logs/
@@ -50,11 +53,11 @@ tests: build-builder
5053
acceptance-tests-up: build .env
5154
# Required to avoid root ownership of reports folder
5255
mkdir -p examples/build/reports/ || true
53-
docker compose up --detach
56+
docker compose $(DOCKER_COMPOSE_ARGS) up --detach
5457

5558
.PHONY: acceptance-tests-run
5659
acceptance-tests-run: .env
57-
docker compose exec -T tests gradle \
60+
docker compose $(DOCKER_COMPOSE_ARGS) exec -T tests gradle \
5861
--exclude-task=:core:spotbugsMain --exclude-task=:core:checkstyleMain \
5962
--exclude-task=:core:spotbugsTest --exclude-task=:core:checkstyleTest --exclude-task=:core:testCLI \
6063
:examples:integrationTest
@@ -63,7 +66,7 @@ acceptance-tests-run: .env
6366

6467
.PHONY: acceptance-tests-down
6568
acceptance-tests-down: .env
66-
docker compose down || true
69+
docker compose $(DOCKER_COMPOSE_ARGS) down || true
6770

6871
.PHONY: dist
6972
dist: build-builder

core/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ CMD ["/usr/local/tomcat/bin/docker-start-print"]
5050
FROM runner AS tester
5151

5252
COPY extraConfigFor/acceptanceTests/mapfish-spring-application-context-override.xml /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/
53+
COPY extraConfigFor/acceptanceTests/mapfish-spring-application-context-override-db.xml /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/
54+
RUN chmod go+rw /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/mapfish-spring-application-context-override*.xml
5355

5456
FROM runner AS watcher
5557

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:security="http://www.springframework.org/schema/security"
5+
xmlns="http://www.springframework.org/schema/beans"
6+
xsi:schemaLocation="
7+
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
8+
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
9+
10+
<!-- Use hibernate instead of the registry to store the job queue. configure the data source as well -->
11+
<bean id="jobQueue" class="org.mapfish.print.servlet.job.impl.hibernate.HibernateJobQueue"/>
12+
<bean id="mfDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
13+
<property name="driverClass" value="org.postgresql.Driver"/>
14+
<property name="jdbcUrl" value="jdbc:postgresql://${db.host}:${db.port:5432}/${db.name}"/>
15+
<property name="user" value="${db.username}"/>
16+
<property name="password" value="${db.password}"/>
17+
<property name="minPoolSize" value="1"/>
18+
<property name="numHelperThreads" value="1"/>
19+
<property name="maxIdleTime" value="30"/>
20+
</bean>
21+
22+
<!-- Force the job manager the support clustering, by not taking submitted jobs automatically as its own.
23+
This mode requires the hibernate job queue, the registry job queue is unsupported.
24+
oldFileCleanUp should be turned off if hibernate is used for print job results (see below) -->
25+
<bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
26+
<property name="ignoreResourceNotFound" value="true"/>
27+
<property name="properties">
28+
<props>
29+
<prop key="jobManager.clustered">true</prop>
30+
<prop key="jobManager.oldFileCleanUp">false</prop>
31+
</props>
32+
</property>
33+
</bean>
34+
35+
<!-- Use hibernate to read and write print job results -->
36+
<bean id="printJobPrototype" class="org.mapfish.print.servlet.job.impl.hibernate.HibernatePrintJob"
37+
scope="prototype"/>
38+
<bean id="fileReportLoader" class="org.mapfish.print.servlet.job.impl.hibernate.HibernateReportLoader"/>
39+
<bean id="accounting" class="org.mapfish.print.servlet.job.HibernateAccounting" lazy-init="false"/>
40+
41+
<bean name="bcryptEncoder"
42+
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
43+
44+
<security:authentication-manager alias="authenticationManager">
45+
<security:authentication-provider>
46+
<security:password-encoder ref="bcryptEncoder"/>
47+
<security:user-service>
48+
<!-- password is jimi -->
49+
<security:user name="jimi"
50+
password="$2a$10$OeKmMfVmL2IbF/3skK8l2.Gl3EqvvGhb.Pxr/K0dN7.ttPRHsOzVW"
51+
authorities="ROLE_USER, ROLE_ADMIN"/>
52+
<!-- password is bob -->
53+
<security:user name="bob"
54+
password="$2a$10$D5gwUewQQSpjfZPTcj9rpuTTfmxAqNEyJ19pzC7Z9.fHSCl3jtDj."
55+
authorities="ROLE_USER"/>
56+
</security:user-service>
57+
</security:authentication-provider>
58+
</security:authentication-manager>
59+
</beans>

core/src/main/java/org/mapfish/print/config/access/RoleAccessAssertion.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ public AccessAssertion setRequiredRoles(final Collection<String> assertionRequir
5656
public void assertAccess(final String resourceDescription, final Object protectedResource) {
5757
final SecurityContext context = SecurityContextHolder.getContext();
5858

59-
if (context == null || context.getAuthentication() == null) {
59+
if (context == null) {
60+
throw new AuthenticationCredentialsNotFoundException("Unable to get the security context");
61+
}
62+
if (context.getAuthentication() == null) {
6063
throw new AuthenticationCredentialsNotFoundException(
6164
resourceDescription + " requires an authenticated user");
6265
} else if (this.requiredRoles.isEmpty()) {

core/src/main/resources/mapfish-spring-application-context-override-db.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<bean id="jobQueue" class="org.mapfish.print.servlet.job.impl.hibernate.HibernateJobQueue"/>
77
<bean id="mfDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
88
<property name="driverClass" value="org.postgresql.Driver"/>
9-
<property name="jdbcUrl" value="jdbc:postgresql://${db.host}:${db.port}/${db.name}"/>
9+
<property name="jdbcUrl" value="jdbc:postgresql://${db.host}:${db.port:5432}/${db.name}"/>
1010
<property name="user" value="${db.username}"/>
1111
<property name="password" value="${db.password}"/>
1212
<property name="minPoolSize" value="1"/>

docker-compose-cluster.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
services:
2+
db:
3+
image: postgres:15.15
4+
environment:
5+
POSTGRES_DB: print
6+
POSTGRES_USER: print
7+
POSTGRES_PASSWORD: print
8+
9+
geoserver:
10+
image: camptocamp/geoserver:16
11+
volumes:
12+
- ./examples/geoserver-data/:/mnt/geoserver_datadir
13+
- ./core/src/test/resources/map-data/:/mnt/geoserver_datadir/www/map-data
14+
15+
print:
16+
image: mapfish_print_tester
17+
user: ${USER_ID}
18+
volumes:
19+
- ./examples/src/test/resources/examples:/usr/local/tomcat/webapps/ROOT/print-apps:ro
20+
ports:
21+
- 8080:8080
22+
environment:
23+
PRINT_YAML_MAX_ALIASES: '200'
24+
LOG_LEVEL: DEBUG
25+
JASPER_LOG_LEVEL: DEBUG
26+
CATALINA_OPTS: '-Ddb.host=db -Ddb.username=print -Ddb.password=print -Ddb.name=print'
27+
JAVA_OPTS: '-Dmapfish.image.plugins=true'
28+
29+
tests:
30+
image: mapfish_print_builder
31+
user: ${USER_ID}
32+
command: tail --follow /dev/null
33+
volumes:
34+
- ./examples/src:/src/examples/src:ro
35+
- ./examples/src/test/resources/examples:/src/examples/src/test/resources/examples
36+
- ./examples/build/reports:/src/examples/build/reports
37+
- ./examples/build/resources:/src/examples/build/resources
38+
environment:
39+
PRINT_YAML_MAX_ALIASES: '200'
40+
GRADLE_USER_HOME: /home/gradle/.gradle

examples/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,18 @@ We can optionally have a mask image that will be used to mask the tested image.
4444
This mask image will be loaded from the `src/test/resources/examples/<tested_application>/expected_output/mask-requestData<postfix>.png` file.
4545
This image should be grayscale with only full black and full white pixel values.
4646
If we create the mask image with Gimp, we can't create indexed image with tow colors because in the Java code we get the values 1 instead of 0 for the black pixel.
47+
48+
## Acceptance tests run by CI
49+
50+
To run the acceptance tests, in the CI run:
51+
52+
- `make acceptance-tests-up` to start the test server.
53+
- `make acceptance-tests-run` to run the tests.
54+
- `make acceptance-tests-down` to stop the test server.
55+
56+
The CI does also the tests in cluster mode with a single instance but with a PostgreSQL database used to store the state.
57+
To do so, in the CI use the `DOCKER_COMPOSE_ARGS` environment variable to specify the docker-compose file to use:
58+
59+
- `DOCKER_COMPOSE_ARGS=--file=docker-compose-cluster.yaml make acceptance-tests-up`
60+
- `DOCKER_COMPOSE_ARGS=--file=docker-compose-cluster.yaml make acceptance-tests-run`
61+
- `DOCKER_COMPOSE_ARGS=--file=docker-compose-cluster.yaml make acceptance-tests-down`

examples/src/test/java/org/mapfish/print/PrintApiTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.json.JSONObject;
1616
import org.junit.jupiter.api.Test;
1717
import org.junit.jupiter.api.Timeout;
18+
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
1819
import org.junit.jupiter.api.extension.ExtendWith;
1920
import org.mapfish.print.servlet.MapPrinterServlet;
2021
import org.springframework.http.HttpMethod;
@@ -486,6 +487,7 @@ private void assertRequiresAuth(String path) throws IOException, URISyntaxExcept
486487
}
487488

488489
@Test
490+
@EnabledIfEnvironmentVariable(named = "MAPFISH_PRINT_TESTS_CLUSTER_MODE", matches = "true")
489491
public void testSecuredTemplate_CreateMap() throws Exception {
490492
ClientHttpRequest request =
491493
getPrintRequest(

0 commit comments

Comments
 (0)