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

feat: cypress integration tests #42

Merged
merged 13 commits into from
Apr 11, 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
40 changes: 37 additions & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Environment setup
uses: defenseunicorns/uds-common/.github/actions/setup@fc12e3a773580020a1d63e254525eab0f8b99fc8
uses: defenseunicorns/uds-common/.github/actions/setup@5e4414dc25302739063bb58aa96b8afef5be9851 # v0.10.3

- name: Test building the docker image
run: uds run dev-build
Expand All @@ -40,7 +40,7 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Environment setup
uses: defenseunicorns/uds-common/.github/actions/setup@fc12e3a773580020a1d63e254525eab0f8b99fc8
uses: defenseunicorns/uds-common/.github/actions/setup@5e4414dc25302739063bb58aa96b8afef5be9851 # v0.10.3

- name: Test building a zarf package
run: uds run build-zarf-pkg
Expand All @@ -57,7 +57,7 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Environment setup
uses: defenseunicorns/uds-common/.github/actions/setup@fc12e3a773580020a1d63e254525eab0f8b99fc8
uses: defenseunicorns/uds-common/.github/actions/setup@5e4414dc25302739063bb58aa96b8afef5be9851 # v0.10.3

- name: Set up JDK 17
uses: actions/setup-java@v4
Expand All @@ -67,3 +67,37 @@ jobs:

- name: Plugin Unit Tests
run: mvn -B package --file src/plugin/pom.xml

uds_core_base_integration:
runs-on: ubuntu-latest
name: UDS Core + Identity Config smoke test with base realm.json
permissions:
pull-requests: read
contents: read

steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Environment setup
uses: defenseunicorns/uds-common/.github/actions/setup@5e4414dc25302739063bb58aa96b8afef5be9851 # v0.10.3

- name: Test building the docker image
run: uds run uds-core-smoke-test

uds_core_cypress_integration:
runs-on: ubuntu-latest
name: UDS Core + Identity Config cypress integration tests
permissions:
pull-requests: read
contents: read

steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Environment setup
uses: defenseunicorns/uds-common/.github/actions/setup@5e4414dc25302739063bb58aa96b8afef5be9851 # v0.10.3

- name: Test building the docker image
run: uds run uds-core-integration-tests
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ build/
zarf-sbom
tmp/
cacert.b64
csr.conf
ca.crt
ca.pem
ca.cer
test.cer
test.csr
test.pem
*authorized_certs*
uds-core/
./src/authorized_certs.zip
./tls_cacert.yaml
./test.pfx
src/extra-jars/
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ This repo builds the UDS Identity (Keycloak) Config image used by UDS Identity.
| cacert | Get the CA cert value for the Istio Gateway |
| debug-istio-traffic | Debug Istio traffic on keycloak |
| regenerate-test-pki | Generate a PKI cert for testing |
| uds-core-integration-test | Create cluster and deploy uds-core identity using local uds-identity-config image |
| uds-core-registration-integration-test | Web flow registration integration test |

## Customizing UDS Identity Config

Expand Down
44 changes: 44 additions & 0 deletions bundles/uds-bundle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
kind: UDSBundle
metadata:
name: k3d-core-slim-dev
description: A UDS bundle for deploying Istio from UDS Core on a development cluster
version: "dev"

packages:
- name: uds-k3d-dev
repository: ghcr.io/defenseunicorns/packages/uds-k3d
# renovate: datasource=github-tags depName=defenseunicorns/uds-k3d versioning=semver
ref: 0.6.0

- name: init
repository: ghcr.io/defenseunicorns/packages/init
# renovate: datasource=github-tags depName=defenseunicorns/zarf versioning=semver
ref: v0.32.5

- name: keycloak-identity-config
path: ../
ref: dev

- name: core-slim-dev
path: ../uds-core/build/
# renovate: datasource=github-tags depName=defenseunicorns/uds-core versioning=semver
ref: 0.18.0
overrides:
keycloak:
keycloak:
variables:
- name: KEYCLOAK_CONFIG_IMAGE
description: "The keycloak config image to deploy plugin and initial setup configuration"
path: configImage
istio-admin-gateway:
uds-istio-config:
variables:
- name: ADMIN_TLS_CACERT
description: "The CA cert for the tenant gateway (must be base64 encoded)"
path: tls.cacert
istio-tenant-gateway:
uds-istio-config:
variables:
- name: TENANT_TLS_CACERT
description: "The CA cert for the tenant gateway (must be base64 encoded)"
path: tls.cacert
41 changes: 41 additions & 0 deletions docs/INTEGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Integration Testing For UDS Identity Config + UDS Core

[Cypress Web Flow/Integration Testing Docs](https://docs.cypress.io/guides/overview/why-cypress)

## Implemented Tests

| Test Name (link) | Test Description |
|------------------|------------------|
| [Login Existing User](../src/test/cypress/e2e/login.cy.ts) | Login in existing user that is created in the testing [realm.json](../src/test/cypress/realm.json) |
| [Login Nonexistant User / Incorrect creds](../src/test/cypress/e2e/login.cy.ts) | User cannot login / authenticate with incorrect creds or without account |
| [Successfuly CAC Registration](../src/test/cypress/e2e/registration.cy.ts) | New user can successfully register with CAC |
| [CAC User Login](../src/test/cypress/e2e/registration.cy.ts) | New user can successfully login with CAC |
| [Duplicate User Registration](../src/test/cypress/e2e/registration.cy.ts) | User cannot register more than once |
| [Password check for special characters](../src/test/cypress/e2e/registration.cy.ts) | User registration requires password special characters |
| [Password check for length](../src/test/cypress/e2e/registration.cy.ts) | User registration requires password length check |

## Cypress Testing
Using uds-cli task [`uds-core-integration-tests`](../../tasks.yaml).

Task explanation:
- Cleanup an existing uds-core directory ( mainly for local testing )
- Create docker image that uses the new certs as well as a testing realm.json ( has a defined user, no MFA, and no email verification )
- Clone [`uds-core`](https://github.com/defenseunicorns/uds-core) necessary for setting up k3d cluster to test against
- Use that cacert in deploying `uds-core` [istio gateways](https://github.com/defenseunicorns/uds-core/tree/main/src/istio/values)
- Create zarf package that combines uds-core and identity-config
- Setup k3d cluster by utilizing `uds-core` (istio, keycloak, pepr, zarf)
- Deploy zarf package that was created earlier
- Run cypress tests against deployed cluster

## Updating Cypress Certs

Cypress testing requires that a ca.cer be created and put into an authorized_certs.zip, done by using the `regenerate-test-pki` uds task, which is then utilized by the [Dockerfile](../src/Dockerfile). Once a docker image has been created another command is used for pulling that cacert, uds task `cacert`, from the image using it's value to configure uds-core's gateways, `uds-core-gateway-cacert` uds task . Eventually cypress will require a [pfx cert](../src/test/cypress/cypress.config.ts) for its CAC testing.

Our cypress testing utilizes [static certs](../src/test/cypress/certs/) that are created and saved to limit the need for constantly rebuilding and importing those certs.

Follow these steps to update the certs for cypress:
1. Run `uds run regenerate-test-pki` to regenerate the necessary certs and authorized_certs.zip
2. Run `docker build --build-arg CA_ZIP_URL="authorized_certs.zip" -t uds-core-config:keycloak --no-cache src` to create docker image
3. Run `uds run cacert` to extract cacert from docker image for the tls_cacert.yaml file
4. Copy the authorized_certs.zip, test.pfx, and tls_cacert.yaml into the [certs directory](../src/test/cypress/certs/)
- `mv test.pfx tls_cacert.yaml src/authorized_certs.zip src/cypress/certs/`
3 changes: 2 additions & 1 deletion src/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ COPY --chown=nonroot --from=truststore /home/build/authorized_certs.pem .
COPY --chown=nonroot --from=truststore /home/build/truststore.jks .

# The realm.json is loaded into Keycloak on startup only if the realm does not exist
COPY --chown=nonroot realm.json .
ARG REALM_FILE=realm.json
COPY --chown=nonroot ${REALM_FILE} .

# This provides the custom theme for the Keycloak instance
COPY --chown=nonroot theme theme
Expand Down
37 changes: 37 additions & 0 deletions src/csr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[req]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_ext

[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Colorado
localityName = Locality Name (eg, city)
localityName_default = Colorado Springs
organizationName = Organization Name (eg, company)
organizationName_default = Defense Unicorns
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = uds.dev

[req_ext]
subjectAltName = @alt_names

[v3_ext]
subjectAltName = @v3_alt_names
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = digitalSignature
extendedKeyUsage = clientAuth, 2.16.840.1.101.3.6.8
certificatePolicies = @policy_anything

[alt_names]
DNS.0 = *.uds.dev

[v3_alt_names]
otherName.0 = 2.16.840.1.101.3.6.6;UTF8:test@mil

[policy_anything]
policyIdentifier = 2.16.840.1.101.3.2.1.3.12
2 changes: 2 additions & 0 deletions src/test/cypress/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
cypress
13 changes: 13 additions & 0 deletions src/test/cypress/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"arrowParens": "avoid",
"bracketSameLine": true,
"bracketSpacing": true,
"embeddedLanguageFormatting": "auto",
"insertPragma": false,
"printWidth": 100,
"quoteProps": "as-needed",
"requirePragma": false,
"semi": true,
"useTabs": false,
"tabWidth": 2
}
3 changes: 3 additions & 0 deletions src/test/cypress/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Integration Testing For UDS Identity Config + UDS Core

See [docs](../../../docs/INTEGRATION.md)
Binary file added src/test/cypress/certs/authorized_certs.zip
Binary file not shown.
Empty file.
Binary file added src/test/cypress/certs/test.pfx
Binary file not shown.
2 changes: 2 additions & 0 deletions src/test/cypress/certs/tls_cacert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tls:
cacert: "Ci0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEcVRDQ0FwR2dBd0lCQWdJVUE0WlU1ZWVQaGkxQWFLcEZybXAvcjUzV3VtQXdEUVlKS29aSWh2Y05BUUVMCkJRQXdaREVMTUFrR0ExVUVCaE1DVlZNeEdEQVdCZ05WQkFvTUQxVXVVeTRnUjI5MlpYSnViV1Z1ZERFTU1Bb0cKQTFVRUN3d0RSRzlFTVF3d0NnWURWUVFMREFOUVMwa3hIekFkQmdOVkJBTU1Ga1JQUkNCSlJDQkRRUzAxT1NCRwpRVXRGSUZSRlUxUXdIaGNOTWpRd05EQTBNVFF6TXpNMFdoY05Namt3TkRBek1UUXpNek0wV2pCa01Rc3dDUVlEClZRUUdFd0pWVXpFWU1CWUdBMVVFQ2d3UFZTNVRMaUJIYjNabGNtNXRaVzUwTVF3d0NnWURWUVFMREFORWIwUXgKRERBS0JnTlZCQXNNQTFCTFNURWZNQjBHQTFVRUF3d1dSRTlFSUVsRUlFTkJMVFU1SUVaQlMwVWdWRVZUVkRDQwpBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtkejk3dUovZ3RmVDRWbXFzMmZRUDRnCmVtd2lkQjJBd01iQ1ZaYzZMTEhCUi9oWG96Mk8xYTFGT3NwMlhPWldWT1llQTM1WVlMZVpOYjI1OEQ1eXBLdnYKVTI0V2xkWUZId1JFeUVEbmYvNzJZTytFcXJndkdlOFJyMnJhUTlzQ29tQ2w3K1N4TnBVdFdaM2x0OEtYKzFVRwpTV2lIT1phVG93ZFVFY3ZTWHJsNnkzcUZ6Vmw3MFErL0h5SnBzczl6OTBIZnpaMndDYld0aU1FK3BSVmhGenBsCjBaSi9mTzJjUUJUV1NOTnZTenhuTUZOYUExT3FRekp5ZWpueE5DVnRzYmJ1MmdaMk5VS2tQQmJYRmhMZlVLUHMKVStoQjJFVEt5OEFBYXVGVlkxMmtiZWlMTk5jSmJpQjZvRlJHNmNaK1VoSlRoN1pBY0pTRWNCSUVUTHk5RDgwQwpBd0VBQWFOVE1GRXdIUVlEVlIwT0JCWUVGT0RuOVNlSTU4cHU4bDZRUmpOMkZ3TmlTVE1TTUI4R0ExVWRJd1FZCk1CYUFGT0RuOVNlSTU4cHU4bDZRUmpOMkZ3TmlTVE1TTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFIc054NXBCN1UyWVlCb1hQTGxuUm1oYit6RkxHSTBqU3J4cjh1dFpSQTNHN25IaQpONFErY3NYOEFoY1lzbHVhNGNCanZSVnlHVU5ybVlldGczQmFidVlCb1BhS3VHM2lzUDJJZnBUMVNxNUFhTUFDCjlrc2RHcDZKV3RJdlFlQ3lBRGh2YUNYRHo1YWdDaFhsUFQ4T1ZaOEU2QUk4VDhxUXdtYXVCajBnbE5lZHVjb0EKdHpVSVBaWEtYVFJhVURnalhoRFNXWTNCK1kvWVp3S3lrdW40RFl4dkx0bXZ2NVEwZmtjVjVmYnVUbGtRbEJHYwowZWROZEYrOU5TZmIxcmtnSVo0RTVhYU5INDNTcHk5VzNxdkFYVDkwUlhEeDcxK0t4dkNSeTk5eW5ybFVsSDZTCksrdDJNNkgrcVAzc3A5OW44L2FyYzV2S0VKZWlSQVd1UmtMRmo0TT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
30 changes: 30 additions & 0 deletions src/test/cypress/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { defineConfig } from "cypress";

module.exports = defineConfig({
clientCertificates: [
{
url: "https://sso.uds.dev/**",
ca: [],
certs: [
{
pfx: "certs/test.pfx",
passphrase: "certs/pfx_passphrase.txt",
},
],
},
],

e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
retries: 3,
specPattern: "e2e/**/*.cy.ts",
supportFolder: "support/",
supportFile: "support/e2e.ts",
screenshotOnRunFailure: false,
video: false,
},

pageLoadTimeout: 12000,
});
35 changes: 35 additions & 0 deletions src/test/cypress/e2e/login.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { RegistrationFormData } from "../support/types";

describe("Login Flow", () => {
it("Existing User", () => {
// existing user created in test realm.json
const formData: RegistrationFormData = {
firstName: "Testing",
lastName: "User",
username: "testing_user",
password: "testingpassword!!",
};

cy.loginUser(formData.username, formData.password);

// skip the DoD PKI Detected Pop Up
cy.get("input#kc-cancel.btn.btn-light").click();

// Verify Successful Registration and on User Account Page
cy.get("#landingLoggedInUser")
.should("be.visible")
.and("contain", formData.firstName + " " + formData.lastName);
});

it("Invalid User Creds", () => {
const formData: RegistrationFormData = {
username: "testing_user",
password: "PrettyUnicorns!!",
};

cy.loginUser(formData.username, formData.password);

// user doesn't exist or password is incorrect
cy.contains("span", "Invalid username or password.").should("be.visible");
});
});
Loading