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

CLD-5698 - Add e2e smoketests #23590

Merged
merged 11 commits into from Jun 12, 2023
Merged
24 changes: 24 additions & 0 deletions .github/workflows/docker-push-mirrored.yml
@@ -0,0 +1,24 @@
---
name: Push mirrored docker images
on:
push:
branches:
- master
paths:
- server/scripts/mirror-docker-images.*

jobs:
build-docker:
name: cd/Push mirrored docker images
runs-on: ubuntu-22.04
steps:
- name: cd/Login to Docker Hub
uses: docker/login-action@3da7dc6e2b31f99ef2cb9fb4c50fb0971e0d0139 # v2.1.0
with:
username: ${{ secrets.DOCKERHUB_DEV_USERNAME }}
password: ${{ secrets.DOCKERHUB_DEV_TOKEN }}
- name: cd/Run image upload script
env:
IMAGES_FILE: server/scripts/mirror-docker-images.json
DRY_RUN: no
run: ./server/scripts/mirror-docker-images.sh
78 changes: 70 additions & 8 deletions .github/workflows/e2e-tests-ci.yml
@@ -1,51 +1,76 @@
name: mattermost-e2e-tests
name: E2E Tests
on:
pull_request:
push:
branches:
- master
- mono-repo*
# For PRs, this workflow gets triggered from the Argo Events platform.
# Check the following repo for details: https://github.com/mattermost/delivery-platform
workflow_dispatch:
inputs:
commit_sha:
type: string
required: false

defaults:
run:
shell: bash

jobs:
update-initial-status:
runs-on: ubuntu-22.04
steps:
- uses: mattermost/actions/delivery/update-commit-status@main
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha || github.sha }}
context: ci/e2e-tests
description: E2E tests for mattermost server app
status: pending

cypress-check:
runs-on: ubuntu-22.04
needs:
- update-initial-status
defaults:
run:
working-directory: e2e-tests/cypress
steps:
- name: ci/checkout-repo
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
with:
ref: ${{ inputs.commit_sha || github.sha }}
- name: ci/setup-node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
id: setup_node
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: 'e2e-tests/cypress/package-lock.json'
cache-dependency-path: "e2e-tests/cypress/package-lock.json"
- name: ci/cypress/npm-install
run: |
npm ci
- name: ci/cypress/npm-check
run: |
npm run check

playwright-check:
runs-on: ubuntu-22.04
needs:
- update-initial-status
defaults:
run:
working-directory: e2e-tests/playwright
steps:
- name: ci/checkout-repo
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
with:
ref: ${{ inputs.commit_sha || github.sha }}
- name: ci/setup-node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0
id: setup_node
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: 'e2e-tests/playwright/package-lock.json'
cache-dependency-path: "e2e-tests/playwright/package-lock.json"
- name: ci/get-webapp-node-modules
working-directory: webapp
# requires build of client and types
Expand All @@ -57,3 +82,40 @@ jobs:
- name: ci/playwright/npm-check
run: |
npm run check

smoketests:
runs-on: ubuntu-22.04
needs:
- cypress-check
- playwright-check
defaults:
run:
working-directory: e2e-tests
steps:
- name: ci/checkout-repo
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
with:
ref: ${{ inputs.commit_sha || github.sha }}
- name: ci/e2e-smoketests
run: |
make
# Assert that the run contained 0 failures
CYPRESS_FAILURES=$(find cypress/results -name '*.json' | xargs -l jq -r '.stats.failures' | jq -s add)
echo "Cypress run completed with $CYPRESS_FAILURES failures"
[ "$CYPRESS_FAILURES" = "0" ]

update-final-status:
runs-on: ubuntu-22.04
if: always()
needs:
- smoketests
steps:
- uses: mattermost/actions/delivery/update-commit-status@main
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha || github.sha }}
context: ci/e2e-tests
description: E2E tests for mattermost server app
status: ${{ job.status }}
82 changes: 82 additions & 0 deletions e2e-tests/.ci/.e2erc
@@ -0,0 +1,82 @@
# Utility variables
# NB: these assume you `source` them from the directory this file is in
export MME2E_DC_SERVER="docker-compose -p mmserver -f $(readlink -e ../../server/build/gitlab-dc.postgres.yml) -f $(readlink -e ./server.override.yml)"
export MME2E_DC_DASHBOARD="docker-compose -p mmdashboard -f $(readlink -e ./dashboard/docker/docker-compose.yml) -f $(readlink -e ./dashboard.override.yml)"
export MME2E_UID=$(id -u)

# Default the optional variables that are used in the docker-compose file
export SERVER_IMAGE_DEFAULT="mattermostdevelopment/mm-ee-test:$(git rev-parse --short=7 HEAD)"
export SERVER_IMAGE=${SERVER_IMAGE:-$SERVER_IMAGE_DEFAULT}

# Function definitions
mme2e_log () { echo "[$(date -Is)]" "$@"; }
mme2e_get_current_shopt_arg () {
# This function lets you get the current value of shell options, e.g. pipefail or allexport, in the form
# of arguments to pass to the 'set' shell function, in order to restore its value later
SHOPT_ARG=${1:?}
case $(set -o | sed -n -E "s/^${SHOPT_ARG}[[:space:]]+(o..?)$/\1/p") in
on) echo -n "-o ${SHOPT_ARG}";;
off) echo -n "+o ${SHOPT_ARG}";;
*) exit 1;;
esac
}
mme2e_load_env_file () {
# This loads the ./env file. Variables are automatically exported
[ -f ./env ] || return 0
MME2E_PREVIOUS_ALLEXPORT=$(mme2e_get_current_shopt_arg allexport)
set -o allexport
mme2e_log "Loading env file"
. ./env
set ${MME2E_PREVIOUS_ALLEXPORT}
}
mme2e_generate_envfile_from_var_names () {
# Read var names from stdin, one per line
while read VARIABLE; do
[ -z "${!VARIABLE:-}" ] || echo "${VARIABLE}=${!VARIABLE}";
done
}
mme2e_wait_command_success () {
COMMAND=${1?}
RETRY_MESSAGE=${2?}
RETRIES_LEFT=${3:-1}
RETRIES_INTERVAL=${4:-10}
MME2E_PREVIOUS_PIPEFAIL=$(mme2e_get_current_shopt_arg pipefail)
set -o pipefail
until bash -c "${COMMAND}"; do
RETRIES_LEFT=$((RETRIES_LEFT - 1))
[ "$RETRIES_LEFT" -le "0" ] && break
mme2e_log "${RETRY_MESSAGE} ($RETRIES_LEFT retries left, sleeping $RETRIES_INTERVAL seconds)"
sleep $RETRIES_INTERVAL
done
set ${MME2E_PREVIOUS_PIPEFAIL}
if [ "$RETRIES_LEFT" = "0" ]; then
exit 1
fi
}
mme2e_wait_service_healthy () {
SERVICE_NAME=${1?}
RETRIES_LEFT=${2:-1}
RETRIES_INTERVAL=${3:-10}
mme2e_wait_command_success "${MME2E_DC_SERVER} ps ${SERVICE_NAME} | grep -q '\(healthy\)'" "Waiting for ${SERVICE_NAME} container to be healthy" "$RETRIES_LEFT" "$RETRIES_INTERVAL"
}
mme2e_wait_image () {
IMAGE_NAME=${1?}
RETRIES_LEFT=${2:-1}
RETRIES_INTERVAL=${3:-10}
mme2e_wait_command_success "docker pull $IMAGE_NAME" "Waiting for docker image ${IMAGE_NAME} to be available" "$RETRIES_LEFT" "$RETRIES_INTERVAL"
}
mme2e_legacy_setup () {
# These functions are needed until every pipeline depending on the `server/build/gitlab-dc.*.yml` files is adapted to not use external docker networking anymore
# After that is fixed, this function and the external network in the docker-compose files may be removed
export COMPOSE_PROJECT_NAME=mmserver_legacy
docker network inspect ${COMPOSE_PROJECT_NAME} >/dev/null 2>&1 || docker network create ${COMPOSE_PROJECT_NAME}
}

# Utility alias, for interactive shell usage. Can be reversed with 'unalias docker-compose' in your shell
# NB: this won't work in the script
alias docker-compose-mmserver="${MME2E_DC_SERVER}"
alias docker-compose-mmdashboard="${MME2E_DC_DASHBOARD}"

# Call prerequisite utility functions
mme2e_load_env_file
mme2e_legacy_setup # Temporary
1 change: 1 addition & 0 deletions e2e-tests/.ci/.env.cypress
@@ -0,0 +1 @@
# NB: this file is just a placeholder required by docker-compose. It's supposed to be modified by the CI pipeline and should remain empty in git
1 change: 1 addition & 0 deletions e2e-tests/.ci/.env.dashboard
@@ -0,0 +1 @@
# NB: this file is just a placeholder required by docker-compose. It's supposed to be modified by the CI pipeline and should remain empty in git
1 change: 1 addition & 0 deletions e2e-tests/.ci/.env.server
@@ -0,0 +1 @@
# NB: this file is just a placeholder required by docker-compose. It's supposed to be modified by the CI pipeline and should remain empty in git
5 changes: 5 additions & 0 deletions e2e-tests/.ci/.gitignore
@@ -0,0 +1,5 @@
dashboard
env
!.env.cypress
!.env.server
!.env.dashboard
21 changes: 21 additions & 0 deletions e2e-tests/.ci/dashboard.entrypoint.sh
@@ -0,0 +1,21 @@
#!/bin/bash
set -e -u -o pipefail

npm install

# Run migrations. This is also a way to wait for the database to be up
MIGRATION_ATTEMPTS_LEFT=10
MIGRATION_ATTEMPTS_INTERVAL=10
until npm run migrate:latest; do
MIGRATION_ATTEMPTS_LEFT=$((MIGRATION_ATTEMPTS_LEFT - 1))
[ "$MIGRATION_ATTEMPTS_LEFT" -gt 0 ] || break
echo "Migration script failed, sleeping $MIGRATION_ATTEMPTS_INTERVAL"
sleep $MIGRATION_ATTEMPTS_INTERVAL
done
[ "$MIGRATION_ATTEMPTS_LEFT" -gt 0 ] || {
echo "Migration script failed, exhausted attempts. Giving up."
exit 1
}

# Launch the dashboard
exec npm run dev
24 changes: 24 additions & 0 deletions e2e-tests/.ci/dashboard.override.yml
@@ -0,0 +1,24 @@
---
version: '3.1'

services:
dashboard:
image: node:16.17.0
environment:
PG_URI: postgres://mmuser:mostest@db:5432/automation_dashboard_db
JWT_SECRET: s8gGBA3ujKRohSw1L8HLOY7Jjnu2ZYv8 # Generated with e.g. `dd if=/dev/urandom count=24 bs=1 2>/dev/null | base64 -w0`
JWT_USER: cypress-test
JWT_ROLE: integration
JWT_ALG: HS256
JWT_EXPIRES_IN: 365d
ALLOWED_USER: cypress-test
ALLOWED_ROLE: integration
user: "${MME2E_UID}"
volumes:
- "../:/app"
- "../../dashboard.entrypoint.sh:/usr/local/bin/dashboard.entrypoint.sh:ro"
- "../../.env.dashboard:/var/local/.env.dashboard:rw"
working_dir: /app
entrypoint: /usr/local/bin/dashboard.entrypoint.sh
ports:
- 4000:4000
33 changes: 33 additions & 0 deletions e2e-tests/.ci/dashboard.start.sh
@@ -0,0 +1,33 @@
#!/bin/bash
set -e -u -o pipefail
cd $(dirname $0)
. .e2erc

MME2E_DASHBOARD_REF_DEFAULT="origin/main"
MME2E_DASHBOARD_REF=${MME2E_DASHBOARD_REF:-$MME2E_DASHBOARD_REF_DEFAULT}

mme2e_log "Cloning the automation-dashboard project"
if [ ! -d dashboard ]; then
git clone https://github.com/saturninoabril/automation-dashboard.git dashboard
. .e2erc # Must reinitialize some variables that depend on the dashboard repo being checked out
fi
git -C dashboard fetch
git -C dashboard checkout $MME2E_DASHBOARD_REF

mme2e_log "Starting the dashboard"
${MME2E_DC_DASHBOARD} up -d db dashboard

mme2e_log "Generating the dashboard's local URL"
MME2E_DC_DASHBOARD_NETWORK=$(${MME2E_DC_DASHBOARD} ps -q dashboard | xargs -l docker inspect | jq -r '.[0].NetworkSettings.Networks | (keys|.[0])')
MME2E_DC_DASHBOARD_GATEWAY=$(docker network inspect $MME2E_DC_DASHBOARD_NETWORK | jq -r '.[0].IPAM.Config[0].Gateway')
AUTOMATION_DASHBOARD_URL="http://${MME2E_DC_DASHBOARD_GATEWAY}:4000/api"

mme2e_log "Generating a signed JWT token for accessing the dashboard"
${MME2E_DC_DASHBOARD} exec -T -u $MME2E_UID dashboard npm i
AUTOMATION_DASHBOARD_TOKEN=$(${MME2E_DC_DASHBOARD} exec -T -u $MME2E_UID dashboard node script/sign.js | awk '{ print $2; }') # The token secret is specified in the dashboard.override.yml file

mme2e_log "Generating the .env.dashboard file, to point Cypress to the dashboard URL"
mme2e_generate_envfile_from_var_names >.env.dashboard <<EOF
AUTOMATION_DASHBOARD_URL
AUTOMATION_DASHBOARD_TOKEN
EOF
11 changes: 11 additions & 0 deletions e2e-tests/.ci/dashboard.stop.sh
@@ -0,0 +1,11 @@
#!/bin/bash
set -e -u -o pipefail
cd $(dirname $0)
. .e2erc

if [ -d dashboard ]; then
mme2e_log "Stopping the dashboard containers"
${MME2E_DC_DASHBOARD} down
else
mme2e_log "Not stopping the dashboard containers: dashboard repo not checked out locally, skipping"
fi