Skip to content

Commit

Permalink
feat(testing): Infra/support for external contract tests (#5771)
Browse files Browse the repository at this point in the history
* Getting started with external contract tests "app"

* Build with esbuild and first test

Set limits on cronjob

Run at 11

* Remove entrypoint

* bringing back jest-to-dd script

* switching to using the new NationalRegistry client

* cleaning up and fixing minor issues

* a bit better docs

* Revert "a bit better docs"

This reverts commit ebe542e.

* Revert "cleaning up and fixing minor issues"

This reverts commit 5a4d596.

* Revert "switching to using the new NationalRegistry client"

This reverts commit a0b95b0.

* renaming the spec file to match with the test target

Co-authored-by: Petar Shomov <[email protected]>
  • Loading branch information
sindrig and pshomov authored Jan 7, 2022
1 parent fbb5db8 commit 94e4f1c
Show file tree
Hide file tree
Showing 18 changed files with 302 additions and 11 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ jobs:
- name: Prepare docker build targets
id: build_map
run: |
CHUNKS=$(./scripts/ci/generate-build-chunks.sh docker-express docker-next docker-static docker-cypress)
CHUNKS=$(./scripts/ci/generate-build-chunks.sh docker-express docker-next docker-static docker-cypress docker-jest)
echo "CHUNKS: '$CHUNKS'"
if [[ $CHUNKS != "[]" ]]; then
echo "::set-output name=BUILD_CHUNKS::$CHUNKS"
Expand All @@ -302,7 +302,7 @@ jobs:
env:
BASE: 'origin/main'
run: |
CHUNKS=$(./scripts/ci/generate-build-chunks.sh docker-express docker-next docker-static docker-cypress)
CHUNKS=$(./scripts/ci/generate-build-chunks.sh docker-express docker-next docker-static docker-cypress docker-jest)
echo "CHUNKS: '$CHUNKS'"
if [[ $CHUNKS != "[]" ]]; then
echo "::set-output name=IMAGES::$(echo $CHUNKS | jq '.[] | fromjson | .projects' -r | tr '\n' ',')"
Expand All @@ -311,7 +311,7 @@ jobs:
- name: Gather unaffected docker images
id: unaffected
run: |
UNAFFECTED=$(./scripts/ci/list-unaffected.sh docker-next docker-express docker-static docker-cypress)
UNAFFECTED=$(./scripts/ci/list-unaffected.sh docker-next docker-express docker-static docker-cypress docker-jest)
echo "::set-output name=UNAFFECTED::$UNAFFECTED"
tests:
Expand Down
1 change: 1 addition & 0 deletions apps/external-contracts-tests/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"extends":"../../.eslintrc","rules":{},"ignorePatterns":["!**/*"]}
34 changes: 34 additions & 0 deletions apps/external-contracts-tests/esbuild.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"platform": "node",
"external": [
"fsevents",
"color-string",
"color-convert",
"@nestjs/microservices",
"class-transformer",
"cache-manager",
"@nestjs/websockets/socket-module",
"class-validator",
"class-transformer",
"@nestjs/microservices/microservices-module",
"apollo-server-fastify",
"@elastic/elasticsearch",
"fastify-swagger",
"@nestjs/mongoose",
"@nestjs/typeorm",
"dd-trace",
"express",
"http-errors",
"graphql",
"winston",
"pg",
"source-map-resolve",
"atob",
"logform",
"pg-native",
"form-data",
"bull",
"pseudomap"
],
"keepNames": true
}
31 changes: 31 additions & 0 deletions apps/external-contracts-tests/infra/external-contracts-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { service, ServiceBuilder } from '../../../infra/src/dsl/dsl'
import { Base, NationalRegistry } from '../../../infra/src/dsl/xroad'
import { settings } from '../../../infra/src/dsl/settings'

export const serviceSetup = (): ServiceBuilder<'external-contracts-tests'> => {
return service('external-contracts-tests')
.namespace('external-contracts-tests')
.extraAttributes({
dev: { schedule: '0 11 * * *' },
staging: { schedule: '0 11 * * *' },
prod: { schedule: '0 11 * * *' },
})
.env({})
.secrets({
SOFFIA_SOAP_URL: '/k8s/api/SOFFIA_SOAP_URL',
SOFFIA_HOST_URL: '/k8s/api/SOFFIA_HOST_URL',
SOFFIA_USER: settings.SOFFIA_USER,
SOFFIA_PASS: settings.SOFFIA_PASS,
})
.resources({
limits: {
cpu: '1',
memory: '1024Mi',
},
requests: {
cpu: '500m',
memory: '512Mi',
},
})
.xroad(Base, NationalRegistry)
}
33 changes: 33 additions & 0 deletions apps/external-contracts-tests/jest-to-dd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { StatsD } from 'hot-shots'
import { readFileSync } from 'fs'
import { resolve } from 'path'

// this is not in use yet, but will be part of the next phase in this development

const client = new StatsD({ mock: true })
const jestReport = JSON.parse(
readFileSync(resolve(process.argv[2]), { encoding: 'utf-8' }),
) as {
testResults: {
assertionResults: { fullName: string; status: 'passed' | 'failed' }[]
}[]
}
const testCasesInfo = jestReport.testResults.flatMap(
(testResult) =>
testResult.assertionResults.map((test) => ({
name: test.fullName as string,
status: test.status === 'passed' ? 'success' : 'failure',
})) as { name: string; status: 'success' | 'failure' }[],
)
const successfulTests = testCasesInfo
.filter((tc) => tc.status === 'success')
.map((tc) => tc.name)
const failedTests = testCasesInfo
.filter((tc) => tc.status === 'failure')
.map((tc) => tc.name)

console.log(`Failed test: ${failedTests}`)
console.log(`Successful tests: ${successfulTests}`)

successfulTests.forEach((tc) => client.check(tc, client.CHECKS.OK))
failedTests.forEach((tc) => client.check(tc, client.CHECKS.CRITICAL))
15 changes: 15 additions & 0 deletions apps/external-contracts-tests/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
preset: '../../jest.preset.js',
transform: {
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
'^.+\\.[tj]sx?$': 'ts-jest',
},
globals: {
'ts-jest': {
tsConfig: '<rootDir>/tsconfig.json',
},
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
displayName: 'external-contracts-tests',
modulePathIgnorePatterns: ['<rootDir>/main.spec.ts'],
}
3 changes: 3 additions & 0 deletions apps/external-contracts-tests/main.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as testSuites from './test-suites/'

console.log('Forcing esbuild visit to testSuites:', testSuites)
1 change: 1 addition & 0 deletions apps/external-contracts-tests/test-suites/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './soffia.spec'
25 changes: 25 additions & 0 deletions apps/external-contracts-tests/test-suites/soffia.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// NOTE: To run this locally, you'll need to portforward soffia and set
// the environment variable "SOFFIA_SOAP_URL" to https://localhost:8443
// kubectl port-forward svc/socat-soffia 8443:443 -n socat
import { NationalRegistryApi } from '@island.is/clients/national-registry-v1'

describe('is.island.external.national', () => {
let client: NationalRegistryApi
beforeAll(async () => {
client = await NationalRegistryApi.instantiateClass({
baseSoapUrl: process.env.SOFFIA_SOAP_URL!,
user: process.env.SOFFIA_USER!,
password: process.env.SOFFIA_PASS!,
host: process.env.SOFFIA_HOST_URL!,
})
})
it('should get user correctly', async () => {
const user = await client.getUser('0101302989')
expect(user.Fulltnafn).toEqual('Gervimaður Ameríka')
})
it('throws error if user is not found', async () => {
await expect(client.getUser('0123456789')).rejects.toThrow(
'user with nationalId 0123456789 not found in national Registry',
)
})
})
8 changes: 8 additions & 0 deletions apps/external-contracts-tests/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
}
}
49 changes: 49 additions & 0 deletions charts/islandis/values.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,54 @@ endorsement-system-api:
eks.amazonaws.com/role-arn: 'arn:aws:iam::013313053092:role/endorsement-system-api'
create: true
name: 'endorsement-system-api'
external-contracts-tests:
enabled: true
env:
NODE_OPTIONS: '--max-old-space-size=976'
SERVERSIDE_FEATURES_ON: ''
XROAD_BASE_PATH: 'http://securityserver.dev01.devland.is'
XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.dev01.devland.is/r1/IS-DEV'
XROAD_NATIONAL_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.5fzau3.euw1.cache.amazonaws.com:6379"]'
XROAD_NATIONAL_REGISTRY_SERVICE_PATH: 'IS-DEV/GOV/10001/SKRA-Protected/Einstaklingar-v1'
XROAD_TJODSKRA_API_PATH: '/SKRA-Protected/Einstaklingar-v1'
XROAD_TJODSKRA_MEMBER_CODE: '10001'
XROAD_TLS_BASE_PATH: 'https://securityserver.dev01.devland.is'
XROAD_TLS_BASE_PATH_WITH_ENV: 'https://securityserver.dev01.devland.is/r1/IS-DEV'
grantNamespaces: []
grantNamespacesEnabled: false
healthCheck:
liveness:
initialDelaySeconds: 3
path: '/'
timeoutSeconds: 3
readiness:
initialDelaySeconds: 3
path: '/'
timeoutSeconds: 3
image:
repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/external-contracts-tests'
namespace: 'external-contracts-tests'
replicaCount:
default: 2
max: 3
min: 2
resources:
limits:
cpu: '1'
memory: '1024Mi'
requests:
cpu: '500m'
memory: '512Mi'
schedule: '0 11 * * *'
secrets:
CONFIGCAT_SDK_KEY: '/k8s/configcat/CONFIGCAT_SDK_KEY'
SOFFIA_HOST_URL: '/k8s/api/SOFFIA_HOST_URL'
SOFFIA_PASS: '/k8s/service-portal/SOFFIA_PASS'
SOFFIA_SOAP_URL: '/k8s/api/SOFFIA_SOAP_URL'
SOFFIA_USER: '/k8s/service-portal/SOFFIA_USER'
securityContext:
allowPrivilegeEscalation: false
privileged: false
github-actions-cache:
args:
- '--tls-min-v1.0'
Expand Down Expand Up @@ -807,6 +855,7 @@ namespaces:
- 'air-discount-scheme'
- 'github-actions-cache'
- 'user-notification'
- 'external-contracts-tests'
search-indexer-service:
enabled: true
env:
Expand Down
5 changes: 5 additions & 0 deletions infra/src/uber-charts/islandis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import { serviceSetup as adsApiSetup } from '../../../apps/air-discount-scheme/a
import { serviceSetup as adsWebSetup } from '../../../apps/air-discount-scheme/web/infra/web'
import { serviceSetup as adsBackendSetup } from '../../../apps/air-discount-scheme/backend/infra/backend'

import { serviceSetup as externalContractsTestsSetup } from '../../../apps/external-contracts-tests/infra/external-contracts-tests'

import { EnvironmentServices } from '.././dsl/types/charts'

const endorsement = endorsementServiceSetup({})
Expand Down Expand Up @@ -74,6 +76,8 @@ const adsApi = adsApiSetup({ adsBackend })
const adsWeb = adsWebSetup({ adsApi })
const githubActionsCache = githubActionsCacheSetup()

const externalContractsTests = externalContractsTestsSetup()

export const Services: EnvironmentServices = {
prod: [
appSystemApi,
Expand Down Expand Up @@ -142,6 +146,7 @@ export const Services: EnvironmentServices = {
githubActionsCache,
userNotificationService,
userNotificationWorkerService,
externalContractsTests,
],
}

Expand Down
3 changes: 3 additions & 0 deletions nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,9 @@
"email-service": {
"tags": []
},
"external-contracts-tests": {
"tags": []
},
"feature-flags": {
"tags": []
},
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
"graphql-type-json": "0.3.2",
"handlebars": "4.7.7",
"http-cache-semantics": "4.1.0",
"hot-shots": "9.0.0",
"http-proxy-middleware": "0.19.1",
"hypher": "0.2.5",
"identicon.js": "2.3.3",
Expand Down
10 changes: 10 additions & 0 deletions scripts/ci/90_docker-jest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
set -euxo pipefail

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

# shellcheck disable=SC1091
source "$DIR"/_common.sh

# Building Docker images for jest tests
exec "$DIR"/_docker.sh Dockerfile output-jest
26 changes: 19 additions & 7 deletions scripts/ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,26 @@ ENV NODE_ENV=production

WORKDIR /webapp

# Adding user for running the app
RUN addgroup runners && adduser -D runner -G runners

FROM output-base as output-base-with-pg

RUN npm install -g \
sequelize \
sequelize-cli \
pg
# npx
# logform \
# dd-trace

# Adding user for running the app
RUN addgroup runners && adduser -D runner -G runners
USER runner

FROM output-base as output-express
FROM output-base-with-pg as output-express

COPY --from=builder /build/${APP_DIST_HOME} /webapp/

ENTRYPOINT []
CMD [ "node", "main.js" ]

FROM output-base as output-next
FROM output-base-with-pg as output-next

ENV PORT=4200

Expand Down Expand Up @@ -91,3 +91,15 @@ RUN apk update && \
ADD scripts/dockerfile-assets/nginx/* /etc/nginx/templates
ADD scripts/dockerfile-assets/bash/extract-environment.sh /docker-entrypoint.d
COPY --from=builder /build/${APP_DIST_HOME} /usr/share/nginx/html

FROM output-base as output-jest

RUN echo 'module.exports = {};' > jest.config.js

RUN npm install -g jest

COPY --from=builder /build/${APP_DIST_HOME} /webapp/

USER runner

CMD [ "jest", "main.spec.js" ]
Loading

0 comments on commit 94e4f1c

Please sign in to comment.