I have an app that does CRUD basically. I am able to run my unit tests locally but on the CI(GitHub Action) it's failing. I am getting the error because of PostgreSQL. Here you can see the error. I couldn't be able to fix that. You can access the whole repository on this LINK. You can see my ci.yaml file below;
name: CI
on:
pull_request:
push:
branches: [develop, main]
concurrency:
group: ci-${{ github.ref }}-group
cancel-in-progress: true
jobs:
default:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- name: Set up JDK
uses: actions/setup-java#v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Update dependency graph
uses: advanced-security/maven-dependency-submission-action#571e99aab1055c2e71a1e2309b9691de18d6b7d6
- name: Build Jar file
run: ./project-dev build-jar
- name: Save Jar file
uses: actions/upload-artifact#v3
with:
name: demo-0.0.1-SNAPSHOT
path: target/demo-0.0.1-SNAPSHOT.jar
retention-days: 1
Can someone help me to run my unit tests on the CI, please?
You need to make sure that the database runs.
Your program expects a Posgres DB named school_management to be available under localhost:5432.
However, such a database isn't available in your script.
For setting up the database, you could use the an existing action like this one :
steps:
- uses: harmon758/postgresql-action#v1
with:
postgresql version: '11'
postgresql db: school_management
postgresql user: learning
postgresql password: sa123456
Alternatively, you could use PosgreSQL service containers as described here:
# Service containers to run with `container-job`
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: sa123456
POSTGRES_USER: learning
POSTGRES_DB: school_management
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
However this makes it run using a different hostname so you have to change your spring.datasource.url to jdbc:postgresql://localhost:5432/school_management or similar.
Integrated in your workflow, it could look like the following:
name: CI
on:
pull_request:
push:
branches: [develop, main]
concurrency:
group: ci-${{ github.ref }}-group
cancel-in-progress: true
jobs:
default:
runs-on: ubuntu-latest
# Service containers to run with `container-job`
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: sa123456
POSTGRES_USER: learning
POSTGRES_DB: school_management
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout#v3
- name: Set up JDK
uses: actions/setup-java#v3
with:
java-version: '17'
distribution: 'temurin'
# override spring.datasource.url
- name: Setup config
run: |
mkdir config
echo 'spring.datasource.url=jdbc:postgresql://postgres:5432/school_management' > config/application.properties
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Update dependency graph
uses: advanced-security/maven-dependency-submission-action#571e99aab1055c2e71a1e2309b9691de18d6b7d6
- name: Build Jar file
run: ./project-dev build-jar
- name: Save Jar file
uses: actions/upload-artifact#v3
with:
name: demo-0.0.1-SNAPSHOT
path: target/demo-0.0.1-SNAPSHOT.jar
retention-days: 1
Another possibility is to use an embedded database like H2 for tests.
With this, you don't have to setup any database.
Looking at your logs line 1351
org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
Your tests are trying to connect to a local Postgres instance that is not available. Also looking at your tests you have both unit and integration tests. Whereas an integration test needs to load the application context meaning that your running application inside of the pipeline will not be able to connect to Postgres. Hence, all of your integration tests will fail that utilize Postgres.
However, your other tests are passing, line 2085:
2023-02-14 12:13:39.378 INFO 1740 --- [ main] o.s.j.d.e.EmbeddedDatabaseFactory : Starting embedded database: url='jdbc:h2:mem:d00124ab-b172-4fd1-bf29-b4836ae2f938;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
these are working since your application is connecting correctly to the h2 database that you have.
the StudentRepositoryTest are working since you have the following annotation in your class #DataJpaTest which will boot up this integration test and connect to the in-memory database.
I think the test that is failing is the following DemoApplicationTests:
#SpringBootTest
class DemoApplicationTests {
#Test
void contextLoads() {
}
}
Since this test load the application context (the whole application) and will automatically try to connect with postgres.
So to fix the issue just delete the file. or a better solution which I would recommend (which is a bit more advanced) is to use something called testcontainers and actually run a postgres database inside of a container.
The reason why am suggesting the latter solution is normally once you want to run an integration test you try to have the exact solution that your application runs on production. Hence, an h2 database might have edge cases that does not match postgres database
Related
I have a Spring Boot application with MSSQL database. I would like to run github action and run tests for pull requests and merges to master. However I have problem with connecting to database from GA tests. My application uses YAML configuration and I have separate config file for CI tests.
Here is workflow:
name: Java CI with Maven
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
services:
mssql:
image: mcr.microsoft.com/mssql/server:2019-latest
env:
SA_PASSWORD: myPassword
ACCEPT_EULA: 'Y'
DBNAME: test
ports:
- 1433:1433
steps:
- uses: actions/checkout#v3
- name: Set up JDK 11
uses: actions/setup-java#v3
with:
java-version: '11'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -ntp -U clean test -P junit-ci
And junit-ci config file:
spring:
datasource:
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://mssql:1433;database=test;
username: sa
password: myPassword
And here is error:
[main] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization.
com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host mssql, port 1433 has failed. Error: "mssql. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:234)
at com.microsoft.sqlserver.jdbc.SQLServerException.ConvertConnectExceptionToSQLServerException(SQLServerException.java:285)
at com.microsoft.sqlserver.jdbc.SocketFinder.findSocket(IOBuffer.java:2434)
Suggest to use Testcontainers instead. This way it is the testcontainers Java library which takes care of starting a database to use it for Integration Testing. It is sooo much easier than the path you are currently on. IMHO.
Your GitHub Action YAML then becomes simpler. It will just be pure Maven actions. You also make your test code less dependent on GitHub Actions as your CI system.
Using Testcontainers has other advantages: Your test can have full control over the database (or the container in which it runs). For example you can have a test where you kill the container during the test, thereby similating the effect on your application on a database which suddenly is lost.
Btw: Strictly speaking, what you are attempting is not Unit Tests, but Integration Tests. Maven makes a distinction. It is advisable to make this distinction. Integration Tests are often quite heavy. By using Testcontainers approach the database container will only be started when you tell Maven to execute Integration Tests. In your example, the database container is always started, regardless if it is needed.
I'm currently on my final phase of my bachelor thesis, implementing a web application. Now I need to host it on Azure. I've an application.war with Angular Frontend in it and a services.war with the Java REST Calls. Both are packed through Maven.
When I deploy it from Github with GitHub Actions to Azure, I get the following Error:
"Deployment Failed with Error: Error: More than one package matched with specified pattern: *.war. Please restrain the search pattern."
Do you have a tutorial or can help me how to setup the yml-file to deploy the application.war to ROOT and services.war to /services/...
on:
push:
branches:
- master
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Set up Java version
uses: actions/setup-java#v1
with:
java-version: '11'
- name: Build with Maven
run: mvn clean install
- name: Upload artifact for deployment job
uses: actions/upload-artifact#v2
with:
name: java-app
path: '${{ github.workspace }}/**/target/*.war'
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: 'Production'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact#v2
with:
name: java-app
- name: Deploy to Azure Web App
id: deploy-to-webapp
uses: azure/webapps-deploy#v2
with:
app-name: 'app-name'
slot-name: 'Production'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE }}
package: '*.war'
Thank you very much!
Janick
If you check this Deploy Angular app to Azure App Service running Linux from GitHub, you will understand how to deploy an Angular single page application, from GitHub to Azure App Service.
In order to deploy to App Service using GitHub Actions we need a workflow file. A workflow is defined by a YAML (.yml) file in the /.github/workflows/ path in your repository. This definition contains the various steps and parameters that make up the workflow.
Build and deploy a Java app to Azure using an Azure publish profile. The publish-profile input references the AZURE_WEBAPP_PUBLISH_PROFILE secret that you created earlier.
name: Java CI with Maven
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Set up JDK 1.8
uses: actions/setup-java#v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn -B package --file pom.xml
working-directory: my-app-path
- name: Azure WebApp
uses: Azure/webapps-deploy#v2
with:
app-name: my-app-name
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: my/target/*.war
For more information check this Deploy to App Service using GitHub Actions document from Microsoft. Also read this Create Azure Web App and deploy using GitHub Actions document from GitHub and check the example templates.
I created a job Maven Project in Jenkins for the purpose to Compile and execute all my automatic tests, but when i build the job i got this error :
i got the same message error for all the scenarios
should i create a pipeline in place of project maven ?
i recupare my project with the link ssh GitLab and im working behind a proxy
Thnaks(y)
Here is a docker-compose file that will open 7 instances of FF and 1 instance on chrome. I use it with azure pipeline but you can integrate it with jenkins. You'll will have to add a jenkins task that runs docker-compose
To try on command line , just install docker desktop ( i use it with mac) and run below command
docker-compose -f /path/of/file up
version: "3"
services:
selenium-hub:
image: selenium/hub:3.141.59-20210607
container_name: selenium-hub
ports:
- "65299:4444"
chrome:
image: selenium/node-chrome:3.141.59-20210607
depends_on:
- selenium-hub
environment:
- HUB_HOST=selenium-hub
- HUB_PORT=4444
firefox:
image: selenium/node-firefox:3.141.59-20210607
depends_on:
- selenium-hub
environment:
- HUB_HOST=selenium-hub
- HUB_PORT=4444
deploy:
mode: replicated
replicas: 7
For using docker-compose with azure pipeline , I am using the below.
Make sure you have dockerRegistryEndpoint setup (in below ex: Dockerhub) . I use this to run my cucumber tests and integrate third party cucumber report (PublishCucumberReport#1)in pipeline
trigger:
- master
resources:
- repo: self
variables:
tag: '$(Build.BuildId)'
stages:
- stage: Build
displayName: Build and Push image
jobs:
- job: Build
displayName: Build and Push
pool:
vmImage: 'ubuntu-latest'
steps:
- task: DockerCompose#0
displayName: open browser instances
inputs:
containerregistrytype: 'Container Registry'
dockerRegistryEndpoint: Dockerhub
dockerComposeFile: '**/docker-compose.yml'
action: 'Run a Docker Compose command'
dockerComposeCommand: 'up -d'
detached: true
- task: Maven#3
inputs:
mavenPomFile: 'pom.xml'
mavenOptions: '-Xmx3072m'
jdkArchitectureOption: 'x64'
publishJUnitResults: true
testResultsFiles: '**/target/cucumber.html'
goals: 'clean verify -P acceptanceTests -e -X'
- task: PublishPipelineArtifact#1
displayName: Publish cucumber report
inputs:
pathToPublish: $(System.DefaultWorkingDirectory)/s/target/cucumber-report/
artifactName: 'cucumber.html'
- task: PublishCucumberReport#1
inputs:
jsonDir: ./target/cucumber-report/
outputPath: ./target/
For documentation , refer - https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/build/docker-compose?view=azure-devops
My own app dockerized on my MacOS M1 Silicon host machine, fails with standard_init_linux.go:190: exec user process caused "exec format error" when launched on Kubernetes cluster, with runs on Linux server.
I have my app with this Dockerfile:
FROM openjdk:11-jre-slim as jdkbase
FROM jdkbase
COPY app/target/dependency-jars /run/dependency-jars
COPY app/target/resources /run/resources
ADD app/target/app-1.0.3.jar /run/app-1.0.3.jar
CMD java -jar run/app-1.0.3.jar
,this docker-compose.yaml:
version: "3.8"
services:
myapp:
build:
context: .
dockerfile: myapp/Dockerfile
hostname: myapphost
and this pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: myapp-container
image: my.private.repo/app_dir/myapp:1.0.3
imagePullSecrets:
- name: st-creds
I've spent several hours trying to figure it out how to solve it, trying to use diff. variants of Entrypoints and cmds, but non of this was a working option.
The final solution was to build app for certain architecture, adding platform (platform: linux/amd64) to the compose file:
version: "3.8"
services:
myapp:
platform: linux/amd64
build:
context: .
dockerfile: myapp/Dockerfile
hostname: myapphost
and also to change base image in the Dockerfile to any java image, which works with amd64, for example, to amd64/openjdk:11-slim, like this:
FROM amd64/openjdk:11-slim as jdkbase
FROM jdkbase
COPY app/target/dependency-jars /run/dependency-jars
COPY app/target/resources /run/resources
ADD app/target/app-1.0.3.jar /run/app-1.0.3.jar
CMD java -jar run/app-1.0.3.jar
Hope this'll save time to anyone else who is new to Docker as me
I have been following this tutorial trying to set up a database using flyway migration scripts. The only difference with the tutorial is that I have been trying to use it in a Spring Boot application. For some reason, when I run "docker-compose up" I always get the the following logging in my terminal.
flyway_1 | Flyway Community Edition 7.5.3 by Redgate flyway_1 |
Database: jdbc:postgresql://postgres:5432/db-name (PostgreSQL 12.2)
flyway_1 | Successfully validated 0 migrations (execution time
00:00.041s) flyway_1 | WARNING: No migrations found. Are your
locations set up correctly? flyway_1 | Current version of schema
"public": << Empty Schema >> flyway_1 | Schema "public" is up to
date. No migration necessary.
However, I have a migration script under src/main/resources/db/migration. I am not sure why it is not able to find it, as it seems that is where flyway is supposed to look for them by default.
Here is my docker-compose.yml file
version: '3'
services:
flyway:
image: flyway/flyway:7.5.3
command: -configFiles=/flyway/conf/flyway.config -locations=filesystem:/flyway/sql -connectRetries=60 migrate
volumes:
- ${PWD}/src/main/java/resources/db/migration
- ${PWD}/docker-flyway.config:/flyway/conf/flyway.config
depends_on:
- postgres
postgres:
image: postgres:12.2
restart: always
ports:
- "5432:5432"
environment:
- POSTGRES_USER=example-username
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=db-name
And here is my docker-flyway.config file.
flyway.url=jdbc:postgresql://postgres:5432/db-name
flyway.user=example-username
flyway.password=pass
flyway.baselineOnMigrate=false
The Flyway files need to have the .sql extension. Mentioned here: https://flywaydb.org/documentation/concepts/migrations#naming
I realized that I had one of the volume mappings written incorrectly in my docker-compose.yml file. I don't exactly understand the mapping itself, but after copying what was in this post it ran the migration script properly.