Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Java e2e tests #16

Merged
merged 5 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions .github/workflows/java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Copyright 2024 New Relic, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
name: Java Agent CI

on:
workflow_dispatch: # run test job only
pull_request: # run check modified files / test jobs
release: # run check modified files / test / publish jobs
types:
- published

# only allow one instance of this workflow to be running per PR or branch, cancels any that are already running
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
K8S_OPERATOR_IMAGE_TAG: edge

permissions:
contents: read

jobs:
check-modified-files:
name: Check whether any Java-related files were modified, skip the test job if not
uses: ./.github/workflows/check-modified-files.yml
secrets: inherit
permissions:
contents: read
with:
agent-language: java

test:
name: Run Java init container tests
runs-on: ubuntu-latest
needs: check-modified-files
# run only if files were modified or the workflow was manually invoked
if: needs.check-modified-files.outputs.files-changed == 'true' || github.event_name == 'workflow_dispatch'

steps:
# For some reason, Harden Runner causes setup-minikube to not work correctly
# - name: Harden Runner
# uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
# with:
# #disable-sudo: true
# egress-policy: audit

- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # 4.1.1
with:
persist-credentials: false
fetch-depth: 0

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # 3.3.0

- name: Start minikube
uses: medyagh/setup-minikube@317d92317e473a10540357f1f4b2878b80ee7b95 # 0.0.16

- name: Deploy cert-manager to minikube
run: |
helm repo add jetstack https://charts.jetstack.io --force-update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.14.5 --set installCRDs=true
echo "waiting for cert-manager pods to be ready..."
sleep 5
kubectl wait --for=condition=Ready -n cert-manager --all pods --timeout=60s
- name: Deploy New Relic k8s-agents-operator to minikube
run: |
helm repo add k8s-agents-operator https://newrelic.github.io/k8s-agents-operator
helm upgrade --install k8s-agents-operator k8s-agents-operator/k8s-agents-operator \
--namespace=default \
--set=licenseKey=${{ secrets.NEW_RELIC_LICENSE_KEY }} \
--set=controllerManager.manager.image.tag=${{ env.K8S_OPERATOR_IMAGE_TAG }}
sleep 5
kubectl wait --for=condition=Ready -n default --all pods --timeout=60s
- name: Build init container for e2e test
# When the init container image is built without specifying the agent version via a build arg, the current agent version published to download.newrelic.com will be used.
run: |
minikube image build -t e2e/newrelic-java-init:e2e src/java/
- name: Build test app container
run: |
minikube image build -t e2e/test-app-java:e2e tests/java/
- name: Run e2e-test
uses: newrelic/newrelic-integration-e2e-action@a97ced80a4841c8c6261d1f9dca6706b1d89acb1 # 1.11.0
with:
retry_seconds: 60
retry_attempts: 5
agent_enabled: false
spec_path: tests/java/test-specs.yml
account_id: ${{ secrets.NEW_RELIC_ACCOUNT_ID }}
api_key: ${{ secrets.NEW_RELIC_API_KEY }}
license_key: ${{ secrets.NEW_RELIC_LICENSE_KEY }}
# set the region to Staging if using a staging license key. Also set NEW_RELIC_HOST in tests/chart/templates/deployment.yaml
#region: Staging

publish:
runs-on: ubuntu-latest
needs: test
# only publish on a java release
if: (github.event_name == 'release' && endsWith(github.ref, '_java'))

steps:
- name: Harden Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
with:
disable-sudo: true
egress-policy: audit

- name: Extract Agent Version from release tag
id: version
run: |
agent_version=${{ github.ref_name }} # Use tag name
agent_version=${agent_version##v} # Remove v prefix
agent_version=${agent_version%%_java} # Remove language suffix
echo "agent_version=${agent_version}" | tee -a "$GITHUB_OUTPUT"
- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # 4.1.1
with:
persist-credentials: false
fetch-depth: 0

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # 3.3.0

- name: Generate Docker metadata (tags and labels)
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # 5.5.1
with:
images: newrelic/newrelic-java-init
tags: |
type=raw,value=${{ steps.version.outputs.agent_version }}
type=raw,value=latest
- name: Login to Docker Hub Container Registry
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # 3.1.0
with:
username: ${{ github.repository_owner }}
password: ${{ secrets.DOCKER_TOKEN }}

- name: Build and publish Java Agent init container image
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # 5.3.0
with:
push: true
context: src/java/
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@

# VS Code
**/.vscode/

# IntelliJ IDEA
.idea/

*.DS_Store
17 changes: 13 additions & 4 deletions src/java/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
# To build one auto-instrumentation image for Java, please:
# - Download the newrelic `newrelic-agent-$version.jar` to `/newrelic-agent.jar`. This is required as when instrumenting the pod,
# one init container will be created to copy the jar to your app's container.
# - Grant the necessary access to the jar. `chmod -R go+r //newrelic-agent.jar`
# - Download the newrelic java agent jar file to `/newrelic-agent.jar` using the java-agent-download.sh.
# This is required as when instrumenting the pod, one init container will be created to copy the jar to your app's container.
# - Grant the necessary access to the jar. `chmod -R go+r /newrelic-agent.jar`
FROM busybox
ARG version
ADD https://download.newrelic.com/newrelic/java-agent/newrelic-agent/$version/newrelic-agent-$version.jar /newrelic-agent.jar

# Copy shell script to image
COPY java-agent-download.sh /
# Set executable permissions on shell script
RUN chmod +x /java-agent-download.sh
# Execute shell script to download agent, passing the version build arg to it
RUN /java-agent-download.sh $version
# Remove script from image when it's no longer needed
RUN rm /java-agent-download.sh
# Set executable permissions on Java agent jar file
RUN chmod -R go+r /newrelic-agent.jar
22 changes: 22 additions & 0 deletions src/java/java-agent-download.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh
:'Shell script to download the New Relic Java agent.
This script takes an optional agent `version` argument (e.g. java-agent-download.sh 8.12.0).
If no input argument is provided, then the current Java agent version will be downloaded,
otherwise the agent version specified by the input argument will be downloaded.'

# If the input arg is empty...
if [ -z "$1" ]
then
# Download current Java agent version if no argument is provided
wget https://download.newrelic.com/newrelic/java-agent/newrelic-agent/current/newrelic-agent.jar
else
# Download the Java agent version specified by the provided input argument
wget https://download.newrelic.com/newrelic/java-agent/newrelic-agent/$1/newrelic-agent-$1.jar
fi

# If the Java agent jar file exists...
if [ -e newrelic*.jar ]
then
# Rename the Java agent jar file to newrelic-agent.jar
mv newrelic*.jar newrelic-agent.jar
fi
29 changes: 29 additions & 0 deletions tests/java/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# BUILD STAGE
FROM eclipse-temurin:17-jdk-jammy as build

# Install git
RUN apt update
RUN apt install -y git

# Clone and build SpringBoot PetClinic Java service
RUN git clone https://github.com/spring-projects/spring-petclinic
# Checkout a specific commit to pin the PetClinic service to a known working version. Comment this out to get latest version.
RUN cd ./spring-petclinic && git checkout 923e2b7aa331b8194a6579da99fb6388f15d7f3e
# Build SpringBoot PetClinic Java service
RUN cd ./spring-petclinic && ./mvnw -Dmaven.test.skip=true clean package

# PRODUCTION STAGE
FROM eclipse-temurin:17-jre-jammy as production

# Create work directory
WORKDIR /petclinic-app

# Copy PetClinic jar from build stage to work directory
COPY --from=build /spring-petclinic/target/spring-petclinic*.jar .

# SpringBoot listens on port 8080 by default
# To change it set the -Dserver.port=8083 system propery in the following CMD step
# Alternatively, change the SERVER_PORT and port mapping in docker-compose.yml
EXPOSE 8080

CMD java -jar spring-petclinic*.jar
23 changes: 23 additions & 0 deletions tests/java/chart/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
6 changes: 6 additions & 0 deletions tests/java/chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v2
name: test-app-java
description: A Helm chart for Kubernetes
type: application
version: 1.0.0
appVersion: "1.0.0"
53 changes: 53 additions & 0 deletions tests/java/chart/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-app-java
spec:
selector:
matchLabels:
app: test-app-java
replicas: 1
template:
metadata:
labels:
app: test-app-java
annotations:
instrumentation.newrelic.com/inject-java: "true"
spec:
containers:
- name: test-app-java
image: e2e/test-app-java:e2e
imagePullPolicy: Never
ports:
- containerPort: 8080
env:
- name: NEW_RELIC_APP_NAME
value: k8s-e2e-test-app-java
- name: NEW_RELIC_LABELS # labels used by the e2e Github action
value: "testKey:{{ .Values.scenarioTag | default "NOTSET" }}"
- name: NEW_RELIC_SYNC_STARTUP
value: "true"
- name: NEW_RELIC_SEND_DATA_ON_EXIT
value: "true"
- name: NEW_RELIC_SEND_DATA_ON_EXIT_THRESHOLD
value: "0"
# for testing, comment out if not needed
#- name: NEW_RELIC_LOG_LEVEL
# value: finest
# set the host to staging if using a staging license key
#- name: NEW_RELIC_HOST
# value: staging-collector.newrelic.com

---
apiVersion: v1
kind: Service
metadata:
name: test-app-java-service
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
selector:
app: test-app-java
11 changes: 11 additions & 0 deletions tests/java/chart/templates/instrumentation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
apiVersion: newrelic.com/v1alpha1
kind: Instrumentation
metadata:
labels:
app.kubernetes.io/name: instrumentation
app.kubernetes.io/created-by: newrelic-agent-operator
name: newrelic-instrumentation
spec:
java:
image: e2e/newrelic-java-init:e2e
1 change: 1 addition & 0 deletions tests/java/chart/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
scenarioTag: ""
15 changes: 15 additions & 0 deletions tests/java/test-specs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
description: End-to-end tests for java initcontainer
custom_test_key: tags.testKey
scenarios:
- description: This scenario will verify that a transaction is reported by the test app after a curl request
before:
- helm install test-java ./chart/ --set=scenarioTag="${SCENARIO_TAG}" -n default
- sleep 120
- kubectl wait --for=condition=Ready -n default --all pods
- curl --fail-with-body $(minikube service test-app-java-service --url -n default)
tests:
nrqls:
- query: SELECT latest(duration) AS duration FROM Transaction WHERE appName = 'k8s-e2e-test-app-java'
expected_results:
- key: "duration"
lowerBoundedValue: 0.0
Loading