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

PP-11224: Add Dockerfile, config, and unit test workflow #2

Merged
merged 7 commits into from
Jul 21, 2023
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
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,13 @@ updates:
- dependencies
- govuk-pay
- github_actions
- package-ecosystem: npm
directory: "/tests/node_service"
schedule:
interval: daily
time: "03:00"
open-pull-requests-limit: 0
labels:
- dependencies
- govuk-pay
- javascript
22 changes: 22 additions & 0 deletions .github/workflows/post-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Post Merge

on:
push:
branches:
- main
paths-ignore:
- '.github/**'

permissions:
contents: read

jobs:
tests:
uses: ./.github/workflows/run-tests.yml

tag-release:
needs:
- tests
permissions:
contents: write
uses: alphagov/pay-ci/.github/workflows/_create-alpha-release-tag.yml@master
32 changes: 32 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Build and test

on:
workflow_call:
pull_request:

permissions:
contents: read

jobs:
detect-secrets:
runs-on: ubuntu-latest
steps:
- name: Git checkout
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
- name: Detect secrets
uses: alphagov/pay-ci/actions/detect-secrets@master

build-and-test:
name: Container Build Tests
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
- name: Docker build
run: |
docker build -t pay-adot:github-tests .
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we tag the build with the SHA (like we do on the telegraf tests)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's needed, we're not actually putting this image anywhere so the tag is completely ephemeral anyway

- name: Run tests
working-directory: tests/
run: ./test.sh


5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM amazon/aws-otel-collector:v0.30.0

COPY config.yml /etc/ecs/govuk-pay-adot-sidecar-config.yaml

CMD ["--config=/etc/ecs/govuk-pay-adot-sidecar-config.yaml"]
38 changes: 38 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
receivers:
prometheus:
config:
global:
scrape_interval: 15s
scrape_timeout: 10s
scrape_configs:
- job_name: "adot-sidecar-scrape-application"
static_configs:
- targets: [ "127.0.0.1:$APPLICATION_PORT" ]
honor_labels: true
honor_timestamps: true

processors:

exporters:
prometheusremotewrite:
endpoint: $PROMETHEUS_ENDPOINT_URL
resource_to_telemetry_conversion:
enabled: false
auth:
authenticator: sigv4auth
logging:
loglevel: info

extensions:
sigv4auth:
region: $AWS_REGION
service: aps
assume_role:
arn: $PROMETHEUS_WRITE_ASSUME_ROLE_ARN

service:
extensions: [sigv4auth]
pipelines:
metrics/application:
receivers: [prometheus]
exporters: [logging, prometheusremotewrite]
39 changes: 39 additions & 0 deletions tests/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: "3"
services:
test-app:
build: node_service/
expose:
- 3000
ports:
- 3000:3000
healthcheck:
test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://localhost:3000/metrics"]
interval: 1s
timeout: 10s
retries: 30

adot-sidecar:
build: ../.
volumes:
- "./test-config.yml:/etc/ecs/govuk-pay-adot-sidecar-config.yaml"
depends_on:
- prometheus
- test-app
environment:
- APPLICATION_PORT=3000
- PROMETHEUS_REMOTE_WRITE_URL=http://prometheus:9090/api/v1/write

prometheus:
image: prom/prometheus:v2.45.0
expose:
- 9090
ports:
- 9090:9090
command:
- --web.enable-remote-write-receiver
- --config.file=/etc/prometheus/prometheus.yml
healthcheck:
test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://localhost:9090/-/ready"]
interval: 5s
timeout: 10s
retries: 30
1 change: 1 addition & 0 deletions tests/node_service/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
16 changes: 16 additions & 0 deletions tests/node_service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM node:20-alpine

RUN apk add --no-cache tini

WORKDIR /app

COPY package*.json ./
RUN npm ci --no-progress --omit=dev

COPY ./index.mjs index.mjs

EXPOSE 3000

ENTRYPOINT ["/sbin/tini", "--"]

CMD ["node", "index.mjs"]
67 changes: 67 additions & 0 deletions tests/node_service/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import promClient from 'prom-client'
import express from 'express'

promClient.collectDefaultMetrics({ timeout: 10000 })
promClient.register.metrics().then(str => console.log('Metrics registered'))

function defaultLabels() {
return {
ecsClusterName: "local-test",
ecsServiceName: "test-node-app",
awsAccountName: "local",
}
}

try {
promClient.register.setDefaultLabels(defaultLabels());
} catch (ex) {
const labels = {}
console.log(`Failed to get labels ${ex}`)
}

const counters = {
index: new promClient.Counter({
name: 'page_count_index',
help: 'Count of hits to the index page',
}),
foo: new promClient.Counter({
name: 'page_count_foo',
help: 'Count of hits to the foo page',
}),
metrics: new promClient.Counter({
name: 'page_count_metrics',
help: 'Count of hits to the metrics page',
}),

}

const app = express()
const port = 3000

app.get('/', (req, res) => {
counters.index.inc()
console.log('GET /')
res.send('Hello World!')
})

app.get('/foo', (req, res) => {
counters.foo.inc()
console.log('GET /foo')
res.send('Foo woo hoo')
})

app.get('/metrics', async (req, res) => {
counters.metrics.inc()
console.log('GET /metrics')
try {
res.set('Content-Type', promClient.register.contentType)
const metrics = await promClient.register.metrics()
res.end(metrics)
} catch (ex) {
res.status(500).end(ex)
}
})

app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
Loading