Skip to content

Commit

Permalink
chore: add basic smoke tests with sso, git commit, and file uploads (#…
Browse files Browse the repository at this point in the history
…132)

Fixes #130
  • Loading branch information
marshall007 authored May 24, 2024
1 parent 8ecd5b4 commit 2c34cf9
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 15 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,10 @@ jobs:
uses: defenseunicorns/uds-common/.github/actions/save-logs@859a9b2469c8a6c24c414fe34b127ec5677aea62 # v0.4.3
with:
suffix: ${{ matrix.type }}-${{ matrix.flavor }}-${{ github.run_id }}-${{ github.run_attempt }}

- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: always()
with:
name: playwright-report-${{ matrix.type }}-${{ matrix.flavor }}-${{ github.run_id }}-${{ github.run_attempt }}
path: tests/.playwright/reports/
retention-days: 30
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ test/tf/public-ec2-instance/.terraform
terraform.tfstate
terraform.tfstate.backup
.terraform.lock.hcl

# Tests
node_modules/
.playwright/
6 changes: 6 additions & 0 deletions tasks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ tasks:
- task: create-gl-test-bundle
- task: setup:k3d-test-cluster
- task: deploy:test-bundle
- task: setup:create-doug-user
- task: test:health-check
- task: test:ingress
- task: test:ui
- task: test:git

- name: test-upgrade
description: Test an upgrade from the latest released package to the current branch
Expand All @@ -58,5 +61,8 @@ tasks:
- task: deploy:test-bundle
- task: create-gl-test-bundle
- task: deploy:test-bundle
- task: setup:create-doug-user
- task: test:health-check
- task: test:ingress
- task: test:ui
- task: test:git
92 changes: 77 additions & 15 deletions tasks/test.yaml
Original file line number Diff line number Diff line change
@@ -1,55 +1,59 @@
variables:
- name: GITLAB_TOKEN
default: glpat-NO_DEFAULT_VALUE

tasks:
- name: health-check
actions:
- description: Gitlab Exporter Health Check
- description: GitLab Exporter Health Check
wait:
cluster:
kind: Deployment
name: gitlab-gitlab-exporter
namespace: gitlab
condition: Available

- description: Gitlab Registry Health Check
- description: GitLab Registry Health Check
wait:
cluster:
kind: Deployment
name: gitlab-registry
namespace: gitlab
condition: Available

- description: Gitlab Shell Health Check
- description: GitLab Shell Health Check
wait:
cluster:
kind: Deployment
name: gitlab-gitlab-shell
namespace: gitlab
condition: Available

- description: Gitlab Toolbox Health Check
- description: GitLab Toolbox Health Check
wait:
cluster:
kind: Deployment
name: gitlab-toolbox
namespace: gitlab
condition: Available

- description: Gitlab Sidekiq Health Check
- description: GitLab Sidekiq Health Check
wait:
cluster:
kind: Deployment
name: gitlab-sidekiq-all-in-1-v2
namespace: gitlab
condition: Available

- description: Gitlab Webservice Health Check
- description: GitLab Webservice Health Check
wait:
cluster:
kind: Deployment
name: gitlab-webservice-default
namespace: gitlab
condition: Available

- description: Gitlab Pages Health Check
- description: GitLab Pages Health Check
wait:
cluster:
kind: Deployment
Expand All @@ -58,15 +62,15 @@ tasks:
condition: Available

# StatefulSets don't show conditions themselves so we look for an underlying Pod
- description: Gitlab Gitaly Health Check
- description: GitLab Gitaly Health Check
wait:
cluster:
kind: Pod
name: app=gitaly
namespace: gitlab
condition: Ready

- description: Gitlab Migrations Health Check
- description: GitLab Migrations Health Check
wait:
cluster:
kind: Job
Expand All @@ -76,12 +80,70 @@ tasks:

- name: ingress
actions:
- description: Gitlab UI Health Check
wait:
network:
protocol: https
address: gitlab.uds.dev
code: 200
# `/-/readiness` endpoint returns 503 if any checks fail.
# When `?all=1` is specified, dependent services are also checked.
# https://docs.gitlab.com/ee/administration/monitoring/health_check.html#readiness
- description: GitLab Readiness Check
maxRetries: 30
cmd: |
STATUS=$(curl -s -o /dev/null --write-out '%{http_code}' 'https://gitlab.uds.dev/-/readiness?all=1')
echo "GitLab readiness status: ${STATUS}"
if [ $STATUS != "200" ]; then
sleep 10
exit 1
fi
- name: git
description: GitLab Repository Mirror Checks
actions:
- cmd: |
./uds zarf package create --confirm
dir: tests/data
- task: create-doug-pat
- cmd: |
./uds zarf package mirror-resources \
zarf-package-gitlab-git-tests-${UDS_ARCH}-0.0.1.tar.zst \
--git-url "https://gitlab.uds.dev" \
--git-push-username "doug" \
--git-push-password "${GITLAB_TOKEN}" \
--confirm
dir: tests/data
- name: ui
description: GitLab UI Checks
actions:
- cmd: npm ci
dir: tests
- cmd: npx playwright install --with-deps
dir: tests
- cmd: npx playwright test
dir: tests

- name: create-doug-admin
description: Create "doug" account as admin (must be run *before* first login)
actions:
- cmd: |
./uds zarf tools kubectl exec -n gitlab deployment/gitlab-toolbox -- gitlab-rails runner -e production '\
user = User.new(username: "doug", name: "Doug Unicorn", email: "doug@uds.dev", password: "0123456789!", password_confirmation: "0123456789!"); \
user.assign_personal_namespace!; \
user.skip_confirmation!; \
user.admin = true; \
user.save!; \
puts user.username; puts user.id; \
'
- name: create-doug-pat
description: Create personal access token (PAT) for "doug" account
actions:
- cmd: |
./uds zarf tools kubectl exec -n gitlab deployment/gitlab-toolbox -- gitlab-rails runner -e production '\
user = User.find_by_username("doug"); \
token = user.personal_access_tokens.create(scopes: ["api"], name: "doug", expires_at: 365.days.from_now); \
token.save!; \
puts token.token; \
'
setVariables:
- name: GITLAB_TOKEN
- name: root-password
actions:
Expand Down
26 changes: 26 additions & 0 deletions tests/auth.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { test as setup, expect } from '@playwright/test';
import { authFile } from './playwright.config';

setup('authenticate', async ({ page, context }) => {
await page.goto('/');

await page.getByLabel('Username or email').fill('doug');
await page.getByLabel('Password').fill('unicorn123!@#');
await page.getByRole('button', { name: "Log In" }).click();

await page.waitForURL('/'); // successful redirect

// ensure auth cookies were set
const cookies = await context.cookies();
const keycloakCookie = cookies.find(
(cookie) => cookie.name === "KEYCLOAK_SESSION",
);

expect(keycloakCookie).toBeDefined();
expect(keycloakCookie?.value).not.toBe("");
expect(keycloakCookie?.domain).toContain("sso.");

await page.context().storageState({ path: authFile });

await expect(page).toHaveURL('/');
})
Binary file added tests/data/unicorns.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions tests/data/zarf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
kind: ZarfPackageConfig
metadata:
name: gitlab-git-tests
version: 0.0.1
description: A package with git repos used for testing

components:
- name: git-repos
repos:
# This references a commit that has a .gitlab-ci.yml in it - to update this push a PR and a new commit.
- https://github.com/defenseunicorns/uds-package-gitlab-runner.git
- https://github.com/defenseunicorns/uds-core.git
68 changes: 68 additions & 0 deletions tests/gitlab.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { test, expect } from "@playwright/test";
import path from "path";

function randomProjectName(prefix: string = 'uds-package-test') {
return [ prefix, Math.floor((Math.random() * 10_000)) ].join('-');
}

test('setup a project', async ({ page }) => {
const projectName = randomProjectName();

await page.goto('/projects/new#blank_project');
await page.getByLabel('Project name').fill(projectName);
await page.getByLabel('Initialize repository with a README').setChecked(true);
await page.getByRole('button', { name: 'Create project' }).click();

await expect(page).toHaveURL(`/doug/${projectName}`);

await test.step('create a file', async () => {
await page.goto(`/doug/${projectName}/-/new/main`);

await page.getByTestId('file-name-field').fill('docs/README.md');
await page.getByLabel('Editor content;Press Alt+F1').fill('# Docs', { force: true });
await page.getByTestId('commit-button').click();

await expect(page).toHaveURL(`/doug/${projectName}/-/blob/main/docs/README.md`)
await expect(page.getByRole('heading', { level: 1 })).toContainText('Docs');
});

await test.step('create an issue', async () => {
await page.goto(`/doug/${projectName}/-/issues/new`);

await page.getByTestId('issuable-form-title-field').fill('We should write more tests!');

const descriptionBox = page.getByTestId('issuable-form-description-field');

await descriptionBox.fill(`Why are there no tests???\n\n`);

// upload a file
const fileChooserPromise = page.waitForEvent('filechooser');
await page.getByRole('button', { name: 'Attach a file or image' }).click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(path.join(__dirname, 'data/unicorns.jpeg'));

// check that markdown description box is updated
await expect(descriptionBox).toHaveValue(/uploads\/[a-z0-9]+\/unicorns\.jpeg/);

await page.getByTestId('issuable-create-button').click();

// check that rendered image ends up in issue description
await expect(page.getByRole('img', { name: 'unicorns' }))
.toHaveAttribute('src', /uploads\/[a-z0-9]+\/unicorns\.jpeg/);
});

// regression test for Istio path decoding: https://github.com/defenseunicorns/uds-core/issues/288
await test.step('fetch via API', async () => {
const projectPath = encodeURIComponent(`doug/${projectName}`);

const res = await page.request.get(`/api/v4/projects/${projectPath}`);

expect(res.url()).toContain('%2F');
await expect(res).toBeOK();

const project = await res.json();

expect(project.path).toBe(projectName);
expect(project.namespace.path).toBe('doug');
});
});
Loading

0 comments on commit 2c34cf9

Please sign in to comment.