CLD-5699 Preliminary fixes (#25040)

* Rework some of PR24647
* Store MM_LICENSE to .env.server file
* Remove legacy network setup
* Fixes, generate docker-compose and env files in one place
* Simplify templating mechanism for server.yml
* Fix race condition for dashboard start
* Fix websockets for local debugging
* Fix: make webhook-interaction work again
* Simplify and fix dashboard&cloud configuration, formatting fix

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Mario Vitale 2023-11-07 10:45:43 +01:00 committed by GitHub
parent b0bf5d0765
commit 42b3ef0238
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 540 additions and 606 deletions

View File

@ -2,6 +2,9 @@
# Utility variables
# NB: these assume you `source` them from the directory this file is in
# Set up base docker compose file and export
export MME2E_DC_SERVER="docker compose -p mmserver -f ./server.yml"
export MME2E_DC_DASHBOARD="docker compose -p mmdashboard -f ./dashboard/docker/docker-compose.yml -f ./dashboard.override.yml"
export MME2E_UID=$(id -u)
export MME2E_OSTYPE=$(docker version -f '{{ .Client.Os }}')
export MME2E_ARCHTYPE=$(docker version -f '{{ .Client.Arch }}')
@ -10,8 +13,11 @@ export NODE_VERSION_REQUIRED=$(cat ../../.nvmrc)
# Default values for optional variables
export SERVER_IMAGE_DEFAULT="mattermostdevelopment/mm-ee-test:$(git rev-parse --short=7 HEAD)"
export BROWSER_DEFAULT="chrome"
export SERVER_DEFAULT="self-hosted"
export TEST_DEFAULT="cypress"
export ENABLED_DOCKER_SERVICES_DEFAULT="postgres inbucket"
# OS specific defaults overrides
case $MME2E_OSTYPE in
# OS specific defaults overrides
darwin )
BROWSER_DEFAULT="electron" ;;
* )
@ -20,6 +26,9 @@ esac
# Populate the optional variables that are used in the docker-compose file
export SERVER_IMAGE=${SERVER_IMAGE:-$SERVER_IMAGE_DEFAULT}
export BROWSER=${BROWSER:-$BROWSER_DEFAULT}
export SERVER=${SERVER:-$SERVER_DEFAULT}
export TEST=${TEST:-$TEST_DEFAULT}
export ENABLED_DOCKER_SERVICES=${ENABLED_DOCKER_SERVICES:-$ENABLED_DOCKER_SERVICES_DEFAULT}
# Function definitions
mme2e_log () { echo "[$(date +%Y-%m-%dT%H:%M:%S%Z)]" "$@"; }
@ -30,16 +39,16 @@ mme2e_get_current_shopt_arg () {
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;;
*) return 1;;
esac
}
mme2e_load_env_file () {
# This loads the ./.env file. Variables are automatically exported
[ -f ./.env ] || return 0
# 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
mme2e_log "Loading env file"
. ./env
# shellcheck disable=SC2086
set ${MME2E_PREVIOUS_ALLEXPORT}
}
@ -65,14 +74,15 @@ mme2e_wait_command_success () {
# shellcheck disable=SC2086
set ${MME2E_PREVIOUS_PIPEFAIL}
if [ "$RETRIES_LEFT" = "0" ]; then
exit 1
return 1
fi
}
mme2e_wait_service_healthy () {
DC_COMMAND="${DC_COMMAND:-$MME2E_DC_SERVER}"
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_command_success "${DC_COMMAND} ps ${SERVICE_NAME} | grep -q '\(healthy\)'" "Waiting for ${SERVICE_NAME} container to be healthy" "$RETRIES_LEFT" "$RETRIES_INTERVAL"
}
mme2e_wait_image () {
IMAGE_NAME=${1?}
@ -80,20 +90,16 @@ mme2e_wait_image () {
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
case $MME2E_OSTYPE in
windows )
# https://learn.microsoft.com/en-us/virtualization/windowscontainers/container-networking/network-drivers-topologies
DOCKER_NETWORK_DRIVER="nat" ;;
* )
DOCKER_NETWORK_DRIVER="bridge" ;;
esac
docker network inspect ${COMPOSE_PROJECT_NAME} >/dev/null 2>&1 || docker network create --driver=${DOCKER_NETWORK_DRIVER} ${COMPOSE_PROJECT_NAME}
mme2e_is_token_in_list() {
local TOKEN=$1
local LIST=$2
grep -qE "(^| )$TOKEN( |$)" <<<"$LIST"
}
# 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

View File

@ -1,22 +0,0 @@
# shellcheck disable=SC2148
# Set up base docker compose file and export
DC_FILE="docker-compose.server.override.yml"
if [ ! -f docker-compose.server.override.yml ]; then
echo "No './.ci/docker-compose.server.override.yml' found. You may need to run 'make generate-docker-compose'"
exit 1
fi
if [ "$TEST" = "cypress" ]; then
MME2E_DC_SERVER="docker compose -p mmserver -f ./$DC_FILE -f ./docker-compose.cypress.yml"
elif [ "$TEST" = "playwright" ]; then
MME2E_DC_SERVER="docker compose -p mmserver -f ./$DC_FILE -f ./docker-compose.playwright.yml"
else
MME2E_DC_SERVER="docker compose -p mmserver -f ./$DC_FILE"
fi
export MME2E_DC_SERVER=$MME2E_DC_SERVER
alias docker-compose-mmserver='${MME2E_DC_SERVER}'
export MME2E_DC_DASHBOARD="docker compose -p mmdashboard -f ./dashboard/docker/docker-compose.yml -f ./dashboard.override.yml"
alias docker-compose-mmdashboard='${MME2E_DC_DASHBOARD}'

View File

@ -1 +0,0 @@
# 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

View File

@ -1 +0,0 @@
# 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

View File

@ -1 +0,0 @@
# 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

View File

@ -1 +0,0 @@
# 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

View File

@ -1,6 +1,4 @@
dashboard
.env
!.env.cypress
!.env.server
!.env.server.cloud
!.env.dashboard
server.yml
env
.env.*

View File

@ -13,10 +13,14 @@ services:
JWT_EXPIRES_IN: 365d
ALLOWED_USER: cypress-test
ALLOWED_ROLE: integration
healthcheck:
test: ["CMD", "curl", "-s", "-o/dev/null", "127.0.0.1:4000"]
interval: 10s
timeout: 15s
retries: 12
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:

View File

@ -2,7 +2,6 @@
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
. .e2erc_setup
MME2E_DASHBOARD_REF_DEFAULT="origin/main"
MME2E_DASHBOARD_REF=${MME2E_DASHBOARD_REF:-$MME2E_DASHBOARD_REF_DEFAULT}
@ -12,7 +11,6 @@ if [ ! -d dashboard ]; then
git clone https://github.com/saturninoabril/automation-dashboard.git dashboard
# Must reinitialize some variables that depend on the dashboard repo being checked out
. .e2erc
. .e2erc_setup
fi
git -C dashboard fetch
git -C dashboard checkout "$MME2E_DASHBOARD_REF"
@ -20,6 +18,11 @@ git -C dashboard checkout "$MME2E_DASHBOARD_REF"
mme2e_log "Starting the dashboard"
${MME2E_DC_DASHBOARD} up -d db dashboard
if ! DC_COMMAND="${MME2E_DC_DASHBOARD}" mme2e_wait_service_healthy dashboard 60 10; then
mme2e_log "Dashboard container not healthy, retry attempts exhausted. Giving up." >&2
exit 1
fi
mme2e_log "Generating the dashboard's local URL"
case $MME2E_OSTYPE in
darwin)
@ -36,7 +39,7 @@ esac
AUTOMATION_DASHBOARD_URL="http://${AUTOMATION_DASHBOARD_IP}:4000/api"
mme2e_log "Generating a signed JWT token for accessing the dashboard"
${MME2E_DC_DASHBOARD} exec -T dashboard bash -c "rm -rf node_modules && npm install --cache /tmp/empty-cache"
# Not running 'npm install'. We assume it has been run by the dashboard container's entrypoint
# shellcheck disable=SC2034
AUTOMATION_DASHBOARD_TOKEN=$(${MME2E_DC_DASHBOARD} exec -T dashboard node script/sign.js | awk '{ print $2; }') # The token secret is specified in the dashboard.override.yml file

View File

@ -2,11 +2,11 @@
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
. .e2erc_setup
if [ -d dashboard ]; then
mme2e_log "Stopping the dashboard containers"
${MME2E_DC_DASHBOARD} down
else
# Base docker-compose file is found in the dashboard repo, we can't run docker commands without it
mme2e_log "Not stopping the dashboard containers: dashboard repo not checked out locally, skipping"
fi

View File

@ -1,61 +0,0 @@
# Image hashes in this file are for amd64 systems
version: "2.4"
services:
cypress:
image: "cypress/browsers:node-18.16.1-chrome-114.0.5735.133-1-ff-114.0.2-edge-114.0.1823.51-1"
### Temporarily disabling this image, until both the amd64 and arm64 version are mirrored
# image: "mattermostdevelopment/mirrored-cypress-browsers-public:node-18.16.1-chrome-114.0.5735.133-1-ff-114.0.2-edge-114.0.1823.51-1"
entrypoint: ["/bin/bash", "-c"]
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
env_file:
- "../../e2e-tests/.ci/.env.dashboard"
- "../../e2e-tests/.ci/.env.cypress"
environment:
REPO: "mattermost"
# Cypress configuration
HEADLESS: "true"
CYPRESS_baseUrl: "http://server:8065"
CYPRESS_dbConnection: "postgres://mmuser:mostest@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10"
CYPRESS_smtpUrl: "http://inbucket:9001"
CYPRESS_webhookBaseUrl: "http://webhook-interactions:3000"
CYPRESS_chromeWebSecurity: "false"
CYPRESS_firstTest: "true"
CYPRESS_resetBeforeTest: "true"
CYPRESS_allowedUntrustedInternalConnections: "localhost webhook-interactions"
TM4J_ENABLE: "false"
# disable shared memory X11 affecting Cypress v4 and Chrome
# https://github.com/cypress-io/cypress-docker-images/issues/270
QT_X11_NO_MITSHM: "1"
_X11_NO_MITSHM: "1"
_MITSHM: "0"
# avoid too many progress messages
# https://github.com/cypress-io/cypress/issues/1243
CI: "1"
# Ensure we're independent from the global node environment
PATH: /cypress/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ulimits:
nofile:
soft: 8096
hard: 1048576
working_dir: /cypress
volumes:
- "../../e2e-tests/cypress/:/cypress"
webhook-interactions:
image: mattermostdevelopment/mirrored-node:${NODE_VERSION_REQUIRED}
command: sh -c "npm install --legacy-peer-deps && exec node webhook_serve.js"
environment:
NODE_PATH: /usr/local/lib/node_modules/
healthcheck:
test: ["CMD", "curl", "-s", "-o/dev/null", "127.0.0.1:3000"]
interval: 10s
timeout: 15s
retries: 12
working_dir: /cypress
volumes:
- "../../e2e-tests/cypress/:/cypress:ro"
networks:
default:
aliases:
- webhook-interactions

View File

@ -1,32 +0,0 @@
# Image hashes in this file are for amd64 systems
version: "2.4"
services:
playwright:
image: mcr.microsoft.com/playwright:v1.38.1-jammy
entrypoint: ["/bin/bash", "-c"]
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
env_file:
- "./.env.playwright"
environment:
CI: "true"
NODE_OPTIONS: --no-experimental-fetch
PW_BASE_URL: http://server:8065
PW_ADMIN_USERNAME: sysadmin
PW_ADMIN_PASSWORD: Sys@dmin-sample1
PW_ADMIN_EMAIL: sysadmin@sample.mattermost.com
PW_ENSURE_PLUGINS_INSTALLED: ""
PW_HA_CLUSTER_ENABLED: "false"
PW_RESET_BEFORE_TEST: "false"
PW_HEADLESS: "true"
PW_SLOWMO: 0
PW_WORKERS: 2
PW_SNAPSHOT_ENABLE: "false"
PW_PERCY_ENABLE: "false"
ulimits:
nofile:
soft: 8096
hard: 1048576
working_dir: /mattermost
volumes:
- "../../:/mattermost"

View File

@ -1,242 +0,0 @@
#!/bin/bash
# SC2034: <variable> appears unused.
# https://www.shellcheck.net/wiki/SC2034
# shellcheck disable=SC2034
# Note: Variables are dynamically used depending on usage input (ENABLED_DOCKER_SERVICES)
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
# File to be used for overriding docker compose
CONFIG_FILE="docker-compose.server.override.yml"
# Check if ENABLED_DOCKER_SERVICES is set or not
if [ -n "${ENABLED_DOCKER_SERVICES-}" ] && [ -n "$ENABLED_DOCKER_SERVICES" ]; then
mme2e_log "ENABLED_DOCKER_SERVICES: $ENABLED_DOCKER_SERVICES"
else
# If not set, then remove the override file if it exists and exit
mme2e_log "ENABLED_DOCKER_SERVICES is empty or unset."
if [ -f $CONFIG_FILE ]; then
rm -f $CONFIG_FILE
mme2e_log "$CONFIG_FILE removed."
else
mme2e_log "No override to docker compose."
fi
exit 0
fi
# Define list of valid services
validServices=("postgres:5432" "minio:9000" "inbucket:9001" "openldap:389" "elasticsearch:9200" "keycloak:8080")
# Read the enabled docker services and split them into an array
enabled_docker_services="$ENABLED_DOCKER_SERVICES"
read -ra docker_services <<<"$enabled_docker_services"
# Initialize variables for required services
postgres_found=false
inbucket_found=false
# Get service and post of valid services
services=()
for service in "${docker_services[@]}"; do
port=""
for svcPort in "${validServices[@]}"; do
svc=${svcPort%%:*}
if [ "$service" == "$svc" ]; then
port=${svcPort#*:}
# Find the required services
if [ "$service" == "$svc" ]; then
if [ "$service" == "postgres" ]; then
postgres_found=true
elif [ "$service" == "inbucket" ]; then
inbucket_found=true
fi
fi
break
fi
done
if [ -z "$port" ]; then
mme2e_log "Unknown service $svc"
exit 1
fi
services+=("$service:$port")
done
# Check if the required services such as postgres and inbucket are found
# Do not continue if any of the required services are not found.
if [ "$postgres_found" != true ] || [ "$inbucket_found" != true ]; then
mme2e_log "When overriding docker compose via ENABLED_DOCKER_SERVICES, postgres and inbucket are both required."
exit 1
fi
# Define each service values
postgres='
postgres:
image: mattermostdevelopment/mirrored-postgres:12
restart: always
environment:
POSTGRES_USER: mmuser
POSTGRES_PASSWORD: mostest
POSTGRES_DB: mattermost_test
command: postgres -c "config_file=/etc/postgresql/postgresql.conf"
volumes:
- ../../server/build/docker/postgres.conf:/etc/postgresql/postgresql.conf
healthcheck:
test: ["CMD", "pg_isready", "-h", "localhost"]
interval: 10s
timeout: 15s
retries: 12
networks:
default:
aliases:
- postgres'
inbucket='
inbucket:
restart: "no"
container_name: mattermost-inbucket
ports:
- "9001:9001"
- "10025:10025"
- "10110:10110"
extends:
file: ../../server/build/gitlab-dc.common.yml
service: inbucket'
minio='
minio:
restart: "no"
container_name: mattermost-minio
ports:
- "9000:9000"
extends:
file: ../../server/build/gitlab-dc.common.yml
service: minio'
openldap='
openldap:
restart: "no"
container_name: mattermost-openldap
ports:
- "389:389"
- "636:636"
extends:
file: ../../server/build/gitlab-dc.common.yml
service: openldap'
elasticsearch='
elasticsearch:
restart: "no"
container_name: mattermost-elasticsearch
ports:
- "9200:9200"
- "9300:9300"
extends:
file: ../../server/build/gitlab-dc.common.yml
service: elasticsearch'
elasticsearch_arm64='
elasticsearch:
image: mattermostdevelopment/mattermost-elasticsearch:7.17.10
platform: linux/arm64/v8
restart: "no"
container_name: mattermost-elasticsearch
ports:
- "9200:9200"
- "9300:9300"
extends:
file: ../../server/build/gitlab-dc.common.yml
service: elasticsearch'
keycloak='
keycloak:
restart: "no"
container_name: mattermost-keycloak
ports:
- "8484:8080"
extends:
file: ../../server/build/gitlab-dc.common.yml
service: keycloak'
# Function to get the service value based on the key
get_service_val_by_key() {
local key="$1"
if [ "$MME2E_ARCHTYPE" = "arm64" ] && [ "$key" = "elasticsearch" ]; then
# Use arm64 version of elasticsearch
key="elasticsearch_arm64"
fi
# Use variable indirection to retrieve the value
local service_val="${!key}"
echo "$service_val"
}
# Generate the docker compose override file
cat <<EOL >"$CONFIG_FILE"
# Image hashes in this file are for amd64 systems
# NB: May include paths relative to the "server/build" directory, which contains the original compose file that this yaml is overriding
version: "2.4"
services:
server:
image: \${SERVER_IMAGE}
restart: always
env_file:
- "./.env.server"
- "./.env.server.cloud"
environment:
MM_LICENSE: \${MM_LICENSE}
MM_SERVICESETTINGS_SITEURL: http://server:8065
MM_SERVICESETTINGS_ENABLELOCALMODE: "true"
MM_PLUGINSETTINGS_ENABLED: "true"
MM_PLUGINSETTINGS_ENABLEUPLOADS: "true"
MM_PLUGINSETTINGS_AUTOMATICPREPACKAGEDPLUGINS: "true"
MM_TEAMSETTINGS_ENABLEOPENSERVER: "true"
MM_SQLSETTINGS_DATASOURCE: "postgres://mmuser:mostest@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10&binary_parameters=yes"
MM_SQLSETTINGS_DRIVERNAME: "postgres"
MM_EMAILSETTINGS_SMTPSERVER: "inbucket"
MM_CLUSTERSETTINGS_READONLYCONFIG: "false"
MM_SERVICESETTINGS_ENABLEONBOARDINGFLOW: "false"
MM_FEATUREFLAGS_ONBOARDINGTOURTIPS: "false"
MM_SERVICEENVIRONMENT: "test"
ports:
- "8065:8065"
depends_on:
$(for service in "${docker_services[@]}"; do
echo " $service:"
echo " condition: service_healthy"
done)
$(for service in "${docker_services[@]}"; do
service_val=$(get_service_val_by_key "$service")
if [ -n "$service_val" ]; then
echo "$service_val"
fi
done)
start_dependencies:
image: mattermost/mattermost-wait-for-dep:latest
depends_on:
$(for service in "${docker_services[@]}"; do
echo " - $service"
done)
command: $(
IFS=' '
echo "${services[*]}"
)
networks:
default:
networks:
default:
name: \${COMPOSE_PROJECT_NAME}
external: true
EOL
mme2e_log "Configuration generated in $CONFIG_FILE"

View File

@ -1,25 +0,0 @@
#!/bin/bash
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
if [ "$SERVER" != "cloud" ]; then
mme2e_log "Not applicable to SERVER='$SERVER'. For cloud only."
exit 0
fi
mme2e_log "Loading .env.server.cloud"
. .env.server.cloud
# Check if CWS_URL is set or not
if [ -n "${CWS_URL-}" ] && [ -n "$CWS_URL" ]; then
mme2e_log "CWS_URL is set."
else
mme2e_log "Environment variable CWS_URL is empty or unset. It must be set to delete test cloud customer."
exit 1
fi
mme2e_log "Deleting customer $MM_CUSTOMER_ID."
curl -X DELETE "${CWS_URL}/api/v1/internal/tests/customers/$MM_CUSTOMER_ID/payment-customer"
mme2e_log "Test cloud customer deleted, MM_CUSTOMER_ID: $MM_CUSTOMER_ID."

View File

@ -4,17 +4,16 @@ cd "$(dirname "$0")"
. .e2erc
if [ "$SERVER" != "cloud" ]; then
mme2e_log "Not applicable to SERVER='$SERVER'. For cloud only."
mme2e_log "Skipping cloud instance initialization: operation supported only for cloud server, but running with SERVER='$SERVER'"
exit 0
fi
# Check if CWS_URL is set or not
if [ -n "${CWS_URL-}" ] && [ -n "$CWS_URL" ]; then
mme2e_log "CWS_URL is set."
else
mme2e_log "Environment variable CWS_URL is empty or unset. It must be set to create test cloud customer."
exit 1
fi
mme2e_log "Initializing cloud tests"
# Assert that required variables are set
MME2E_ENVCHECK_MSG="variable required for initializing cloud tests, but is empty or unset."
: "${CWS_URL:?$MME2E_ENVCHECK_MSG}"
: "${MM_LICENSE:?$MME2E_ENVCHECK_MSG}"
response=$(curl -X POST "${CWS_URL}/api/v1/internal/tests/create-customer?sku=cloud-enterprise&is_paid=true")
MM_CUSTOMER_ID=$(echo "$response" | jq -r .customer_id)
@ -27,7 +26,7 @@ export MM_CLOUD_INSTALLATION_ID=$MM_CLOUD_INSTALLATION_ID
export MM_CLOUDSETTINGS_CWSURL=$CWS_URL
export MM_CLOUDSETTINGS_CWSAPIURL=$CWS_URL
mme2e_generate_envfile_from_var_names >.env.server.cloud <<EOF
mme2e_generate_envfile_from_var_names >.env.cloud <<EOF
MM_CLOUDSETTINGS_CWSURL
MM_CLOUDSETTINGS_CWSAPIURL
MM_CLOUD_API_KEY

View File

@ -0,0 +1,24 @@
#!/bin/bash
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
if [ "$SERVER" != "cloud" ]; then
mme2e_log "Skipping cloud instance teardown: operation supported only for cloud server, but running with SERVER='$SERVER'"
exit 0
fi
mme2e_log "Tearing down cloud tests"
mme2e_log "Loading .env.cloud"
. .env.cloud
# Assert that required variables are set
MME2E_ENVCHECK_MSG="variable required for tearing down cloud tests, but is empty or unset."
: "${CWS_URL:?$MME2E_ENVCHECK_MSG}"
: "${MM_CUSTOMER_ID:?$MME2E_ENVCHECK_MSG}"
mme2e_log "Deleting customer $MM_CUSTOMER_ID."
curl -X DELETE "${CWS_URL}/api/v1/internal/tests/customers/$MM_CUSTOMER_ID/payment-customer"
mme2e_log "Test cloud customer deleted, MM_CUSTOMER_ID: $MM_CUSTOMER_ID."

376
e2e-tests/.ci/server.generate.sh Executable file
View File

@ -0,0 +1,376 @@
#!/bin/bash
# SC2034: <variable> appears unused.
# https://www.shellcheck.net/wiki/SC2034
# shellcheck disable=SC2034
# Note: Variables are dynamically used depending on usage input (ENABLED_DOCKER_SERVICES)
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
enable_docker_service() {
local SERVICE_TO_ENABLE="$1"
if ! mme2e_is_token_in_list "$SERVICE_TO_ENABLE" "$ENABLED_DOCKER_SERVICES"; then
ENABLED_DOCKER_SERVICES="$ENABLED_DOCKER_SERVICES $SERVICE_TO_ENABLE"
fi
}
assert_docker_services_validity() {
local SERVICES_TO_CHECK="$*"
local SERVICES_VALID="postgres minio inbucket openldap elasticsearch keycloak cypress webhook-interactions playwright"
local SERVICES_REQUIRED="postgres inbucket"
for SERVICE_NAME in $SERVICES_TO_CHECK; do
if ! mme2e_is_token_in_list "$SERVICE_NAME" "$SERVICES_VALID"; then
mme2e_log "Error, requested invalid service: $SERVICE_NAME" >&2
mme2e_log "Valid services are: $SERVICES_VALID" >&2
mme2e_log "Aborting" >&2
exit 1
fi
SERVICES_REQUIRED="${SERVICES_REQUIRED/$SERVICE_NAME/}"
done
if [ -n "${SERVICES_REQUIRED/ /}" ]; then
mme2e_log "Missing required services: $SERVICES_REQUIRED" >&2
mme2e_log "Aborting" >&2
exit 2
fi
}
generate_docker_compose_file() {
# Generating the server docker-compose file
local DC_FILE="server.yml"
mme2e_log "Generating docker-compose file in: $DC_FILE"
# Generate the docker compose override file
cat <<EOL >"$DC_FILE"
# Image hashes in this file are for amd64 systems
# NB: May include paths relative to the "server/build" directory, which contains the original compose file that this yaml is overriding
version: "2.4"
services:
server:
image: \${SERVER_IMAGE}
restart: always
env_file:
- "./.env.server"
environment:
MM_SERVICESETTINGS_ALLOWCORSFROM: "*"
MM_SERVICESETTINGS_ENABLELOCALMODE: "true"
MM_PLUGINSETTINGS_ENABLED: "true"
MM_PLUGINSETTINGS_ENABLEUPLOADS: "true"
MM_PLUGINSETTINGS_AUTOMATICPREPACKAGEDPLUGINS: "true"
MM_TEAMSETTINGS_ENABLEOPENSERVER: "true"
MM_SQLSETTINGS_DATASOURCE: "postgres://mmuser:mostest@localhost:5432/mattermost_test?sslmode=disable&connect_timeout=10&binary_parameters=yes"
MM_SQLSETTINGS_DRIVERNAME: "postgres"
MM_EMAILSETTINGS_SMTPSERVER: "inbucket"
MM_CLUSTERSETTINGS_READONLYCONFIG: "false"
MM_SERVICESETTINGS_ENABLEONBOARDINGFLOW: "false"
MM_FEATUREFLAGS_ONBOARDINGTOURTIPS: "false"
MM_SERVICEENVIRONMENT: "test"
network_mode: host
depends_on:
$(for service in $ENABLED_DOCKER_SERVICES; do
# The server container will start only if all other dependent services are healthy
# Skip creating the dependency for containers that don't need a healthcheck
if grep -qE "^(cypress|webhook-interactions|playwright)" <<<"$service"; then
continue
fi
echo " $service:"
echo " condition: service_healthy"
done)
$(if mme2e_is_token_in_list "postgres" "$ENABLED_DOCKER_SERVICES"; then
echo '
postgres:
image: mattermostdevelopment/mirrored-postgres:12
restart: always
environment:
POSTGRES_USER: mmuser
POSTGRES_PASSWORD: mostest
POSTGRES_DB: mattermost_test
command: postgres -c "config_file=/etc/postgresql/postgresql.conf"
volumes:
- ../../server/build/docker/postgres.conf:/etc/postgresql/postgresql.conf
network_mode: host
healthcheck:
test: ["CMD", "pg_isready", "-h", "localhost"]
interval: 10s
timeout: 15s
retries: 12'
fi)
$(if mme2e_is_token_in_list "inbucket" "$ENABLED_DOCKER_SERVICES"; then
echo '
inbucket:
restart: "no"
network_mode: host
extends:
file: ../../server/build/gitlab-dc.common.yml
service: inbucket'
fi)
$(if mme2e_is_token_in_list "minio" "$ENABLED_DOCKER_SERVICES"; then
echo '
minio:
restart: "no"
network_mode: host
extends:
file: ../../server/build/gitlab-dc.common.yml
service: minio'
fi)
$(if mme2e_is_token_in_list "openldap" "$ENABLED_DOCKER_SERVICES"; then
echo '
openldap:
restart: "no"
network_mode: host
extends:
file: ../../server/build/gitlab-dc.common.yml
service: openldap'
fi)
$(if mme2e_is_token_in_list "elasticsearch" "$ENABLED_DOCKER_SERVICES"; then
if [ "$MME2E_ARCHTYPE" = "arm64" ]; then
echo '
elasticsearch:
image: mattermostdevelopment/mattermost-elasticsearch:7.17.10
platform: linux/arm64/v8
restart: "no"
network_mode: host
extends:
file: ../../server/build/gitlab-dc.common.yml
service: elasticsearch'
else
echo '
elasticsearch:
restart: "no"
network_mode: host
extends:
file: ../../server/build/gitlab-dc.common.yml
service: elasticsearch'
fi
fi)
$(if mme2e_is_token_in_list "keycloak" "$ENABLED_DOCKER_SERVICES"; then
echo '
keycloak:
restart: "no"
network_mode: host
extends:
file: ../../server/build/gitlab-dc.common.yml
service: keycloak'
fi)
$(if mme2e_is_token_in_list "cypress" "$ENABLED_DOCKER_SERVICES"; then
echo '
cypress:
image: "cypress/browsers:node-18.16.1-chrome-114.0.5735.133-1-ff-114.0.2-edge-114.0.1823.51-1"
### Temporarily disabling this image, until both the amd64 and arm64 version are mirrored
# image: "mattermostdevelopment/mirrored-cypress-browsers-public:node-18.16.1-chrome-114.0.5735.133-1-ff-114.0.2-edge-114.0.1823.51-1"
entrypoint: ["/bin/bash", "-c"]
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
env_file:
- "../../e2e-tests/.ci/.env.cypress"
environment:
REPO: "mattermost"
# Cypress configuration
HEADLESS: "true"
CYPRESS_baseUrl: "http://localhost:8065"
CYPRESS_dbConnection: "postgres://mmuser:mostest@localhost:5432/mattermost_test?sslmode=disable&connect_timeout=10"
CYPRESS_smtpUrl: "http://localhost:9001"
CYPRESS_webhookBaseUrl: "http://localhost:3000"
CYPRESS_chromeWebSecurity: "false"
CYPRESS_firstTest: "true"
CYPRESS_resetBeforeTest: "true"
CYPRESS_allowedUntrustedInternalConnections: "localhost webhook-interactions"
TM4J_ENABLE: "false"
# disable shared memory X11 affecting Cypress v4 and Chrome
# https://github.com/cypress-io/cypress-docker-images/issues/270
QT_X11_NO_MITSHM: "1"
_X11_NO_MITSHM: "1"
_MITSHM: "0"
# avoid too many progress messages
# https://github.com/cypress-io/cypress/issues/1243
CI: "1"
# Ensure we are independent from the global node environment
PATH: /cypress/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ulimits:
nofile:
soft: 8096
hard: 1048576
working_dir: /cypress
network_mode: host
volumes:
- "../../e2e-tests/cypress/:/cypress"'
fi)
$(if mme2e_is_token_in_list "webhook-interactions" "$ENABLED_DOCKER_SERVICES"; then
# shellcheck disable=SC2016
echo '
webhook-interactions:
image: mattermostdevelopment/mirrored-node:${NODE_VERSION_REQUIRED}
command: sh -c "npm install --global --legacy-peer-deps && exec node webhook_serve.js"
healthcheck:
test: ["CMD", "curl", "-s", "-o/dev/null", "127.0.0.1:3000"]
interval: 10s
timeout: 15s
retries: 12
working_dir: /cypress
network_mode: host
restart: on-failure
volumes:
- "../../e2e-tests/cypress/:/cypress:ro"'
fi)
$(if mme2e_is_token_in_list "playwright" "$ENABLED_DOCKER_SERVICES"; then
echo '
playwright:
image: mcr.microsoft.com/playwright:v1.38.1-jammy
entrypoint: ["/bin/bash", "-c"]
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
env_file:
- "./.env.playwright"
environment:
CI: "true"
NODE_OPTIONS: --no-experimental-fetch
PW_BASE_URL: http://localhost:8065
PW_ADMIN_USERNAME: sysadmin
PW_ADMIN_PASSWORD: Sys@dmin-sample1
PW_ADMIN_EMAIL: sysadmin@sample.mattermost.com
PW_ENSURE_PLUGINS_INSTALLED: ""
PW_HA_CLUSTER_ENABLED: "false"
PW_RESET_BEFORE_TEST: "false"
PW_HEADLESS: "true"
PW_SLOWMO: 0
PW_WORKERS: 2
PW_SNAPSHOT_ENABLE: "false"
PW_PERCY_ENABLE: "false"
ulimits:
nofile:
soft: 8096
hard: 1048576
working_dir: /mattermost
network_mode: host
volumes:
- "../../:/mattermost"'
fi)
EOL
mme2e_log "docker-compose file generated."
}
generate_env_files() {
# Generate .env.server
mme2e_log "Generating .env.server"
mme2e_generate_envfile_from_var_names >.env.server <<-EOF
MM_LICENSE
EOF
# Setting SERVER-specific variables
case "$SERVER" in
cloud)
echo "MM_NOTIFY_ADMIN_COOL_OFF_DAYS=0.00000001" >>.env.server
echo 'MM_FEATUREFLAGS_ANNUALSUBSCRIPTION="true"' >>.env.server
# Load .env.cloud into .env.server
# We assume the file exist at this point. The actual check for that should be done before calling this function
cat >>.env.server <.env.cloud
;;
esac
# Setting MM_ENV-injected variables
# shellcheck disable=SC2086
envarr=$(echo ${MM_ENV:-} | tr "," "\n")
for env in $envarr; do
echo "$env" >>.env.server
done
# Generating TEST-specific env files
BRANCH_DEFAULT=$(git branch --show-current)
BUILD_ID_DEFAULT=$(date +%s)
export BRANCH=${BRANCH:-$BRANCH_DEFAULT}
export BUILD_ID=${BUILD_ID:-$BUILD_ID_DEFAULT}
export CI_BASE_URL="${CI_BASE_URL:-localhost}"
case "$TEST" in
cypress)
mme2e_log "Cypress: Generating .env.cypress"
mme2e_generate_envfile_from_var_names >.env.cypress <<-EOF
BRANCH
BUILD_ID
CI_BASE_URL
BROWSER
AUTOMATION_DASHBOARD_URL
AUTOMATION_DASHBOARD_TOKEN
EOF
# Adding service-specific cypress variables
for SERVICE in $ENABLED_DOCKER_SERVICES; do
case $SERVICE in
openldap)
echo "CYPRESS_ldapServer=localhost" >>.env.cypress
echo "CYPRESS_runLDAPSync=true" >>.env.cypress
;;
minio)
echo "CYPRESS_minioS3Endpoint=localhost:9000" >>.env.cypress
;;
keycloak)
echo "CYPRESS_keycloakBaseUrl=http://localhost:8484" >>.env.cypress
;;
elasticsearch)
echo "CYPRESS_elasticsearchConnectionURL=http://localhost:9200" >>.env.cypress
;;
esac
done
# Adding SERVER-specific cypress variables
case "$SERVER" in
cloud)
echo "CYPRESS_serverEdition=Cloud" >>.env.cypress
;;
*)
echo "CYPRESS_serverEdition=E20" >>.env.cypress
;;
esac
# If the dashboard is running, load .env.dashboard into .env.cypress
if DC_COMMAND="$MME2E_DC_DASHBOARD" mme2e_wait_service_healthy dashboard 1; then
mme2e_log "Detected a running automation dashboard: loading its access variables into the Cypress container"
cat >>.env.cypress <.env.dashboard
fi
;;
playwright)
mme2e_log "Playwright: Generating .env.playwright"
mme2e_generate_envfile_from_var_names >.env.playwright <<-EOF
BRANCH
BUILD_ID
EOF
;;
none)
mme2e_log "Requested TEST=$TEST. Skipping generation of test-specific env files."
;;
esac
}
# Perform SERVER-specific checks/customizations
case "$SERVER" in
cloud)
if ! [ -f .env.cloud ]; then
mme2e_log "Error: when using SERVER=$SERVER, the .env.cloud file is expected to exist, before generating the docker-compose file. Aborting." >&2
exit 1
fi
;;
esac
# Perform TEST-specific checks/customizations
case $TEST in
cypress)
enable_docker_service cypress
enable_docker_service webhook-interactions
;;
playwright)
enable_docker_service playwright
;;
esac
mme2e_log "Generating docker-compose file using the following parameters..."
mme2e_log "TEST: ${TEST}"
mme2e_log "SERVER: ${SERVER}"
mme2e_log "ENABLED_DOCKER_SERVICES: ${ENABLED_DOCKER_SERVICES}"
assert_docker_services_validity "$ENABLED_DOCKER_SERVICES"
generate_docker_compose_file
generate_env_files

View File

@ -2,33 +2,31 @@
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
. .e2erc_setup
if [ "$TEST" != "cypress" ]; then
mme2e_log "Not applicable to TEST='$TEST'. For cypress only."
exit 0
if [ "$TEST" = "cypress" ]; then
mme2e_log "Prepare Cypress: install dependencies"
${MME2E_DC_SERVER} exec -T -u 0 -- cypress bash -c "id $MME2E_UID || useradd -u $MME2E_UID -m nodeci" # Works around the node image's assumption that the app files are owned by user 1000
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress npm i
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress cypress install
mme2e_log "Prepare Cypress: populating fixtures"
${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-gitlab/releases/download/v1.3.0/com.github.manland.mattermost-plugin-gitlab-1.3.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/com.github.manland.mattermost-plugin-gitlab-1.3.0.tar.gz >/dev/null
${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.9.0/com.mattermost.demo-plugin-0.9.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/com.mattermost.demo-plugin-0.9.0.tar.gz >/dev/null
${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.8.0/com.mattermost.demo-plugin-0.8.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/com.mattermost.demo-plugin-0.8.0.tar.gz >/dev/null
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/keycloak.crt >/dev/null <../../server/build/docker/keycloak/keycloak.crt
fi
# Install cypress dependencies
mme2e_log "Prepare Cypress: install dependencies"
${MME2E_DC_SERVER} exec -T -u 0 -- cypress bash -c "id $MME2E_UID || useradd -u $MME2E_UID -m nodeci" # Works around the node image's assumption that the app files are owned by user 1000
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress npm i
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress cypress install
# Populate cypress fixtures
mme2e_log "Prepare Cypress: populating fixtures"
${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-gitlab/releases/download/v1.3.0/com.github.manland.mattermost-plugin-gitlab-1.3.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/com.github.manland.mattermost-plugin-gitlab-1.3.0.tar.gz >/dev/null
${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.9.0/com.mattermost.demo-plugin-0.9.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/com.mattermost.demo-plugin-0.9.0.tar.gz >/dev/null
${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.8.0/com.mattermost.demo-plugin-0.8.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/com.mattermost.demo-plugin-0.8.0.tar.gz >/dev/null
${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.8.0/com.mattermost.demo-plugin-0.8.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/com.mattermost.demo-plugin-0.8.0.tar.gz >/dev/null
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/keycloak.crt >/dev/null <../../server/build/docker/keycloak/keycloak.crt
if [[ $ENABLED_DOCKER_SERVICES == *"openldap"* ]]; then
${MME2E_DC_SERVER} exec -T -- openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest' <../../server/tests/test-data.ldif
fi
if [[ $ENABLED_DOCKER_SERVICES == *"minio"* ]]; then
${MME2E_DC_SERVER} exec -T -- minio sh -c 'mkdir -p /data/mattermost-test'
fi
# Run service-specific initialization steps
for SERVICE in $ENABLED_DOCKER_SERVICES; do
case "$SERVICE" in
openldap)
mme2e_log "Configuring the $SERVICE container"
${MME2E_DC_SERVER} exec -T -- openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest' <../../server/tests/test-data.ldif
;;
minio)
mme2e_log "Configuring the $SERVICE container"
${MME2E_DC_SERVER} exec -T -- minio sh -c 'mkdir -p /data/mattermost-test'
;;
esac
done
mme2e_log "Mattermost is running and ready for E2E testing"

View File

@ -2,7 +2,6 @@
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
. .e2erc_setup
# Set required variables
TEST_FILTER_DEFAULT='--stage=@prod --group=@smoke'

View File

@ -2,7 +2,6 @@
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
. .e2erc_setup
# Initialize Playwright report directory
mme2e_log "Prepare Playwright: clean and initialize report and logs directory"

View File

@ -0,0 +1,22 @@
#!/bin/bash
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
case $TEST in
cypress)
./server.run_cypress.sh
;;
playwright)
./server.run_playwright.sh
;;
none)
mme2e_log "Running with TEST=$TEST. No tests to run."
exit 0
;;
*)
mme2e_log "Error, unsupported value for TEST: $TEST" >&2
mme2e_log "Aborting" >&2
exit 1
;;
esac

View File

@ -2,89 +2,17 @@
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
. .e2erc_setup
if [ "$TEST" != "cypress" ] && [ "$TEST" != "playwright" ] && [ "$TEST" != "server" ]; then
mme2e_log "Invalid TEST='$TEST', expected: 'cypress', 'playwright' or 'server'"
exit 1
fi
BRANCH_DEFAULT=$(git branch --show-current)
export BRANCH=${BRANCH:-$BRANCH_DEFAULT}
BUILD_ID_DEFAULT=$(date +%s)
export BUILD_ID=${BUILD_ID:-$BUILD_ID_DEFAULT}
export CI_BASE_URL="${CI_BASE_URL:-localhost}"
export SITE_URL="${SITE_URL:-http://server:8065}"
# Cleanup old containers, if any
mme2e_log "Stopping leftover E2E containers, if any are running"
${MME2E_DC_SERVER} down -v --remove-orphans
# Generate .env.server
mme2e_log "Generating .env.server"
if [ "$SERVER" = "cloud" ]; then
export "MM_NOTIFY_ADMIN_COOL_OFF_DAYS=0.00000001"
export 'MM_FEATUREFLAGS_ANNUALSUBSCRIPTION="true"'
fi
mme2e_generate_envfile_from_var_names >.env.server <<EOF
MM_ELASTICSEARCHSETTINGS_CONNECTIONURL
MM_LDAPSETTINGS_LDAPSERVER
MM_NOTIFY_ADMIN_COOL_OFF_DAYS
MM_FEATUREFLAGS_ANNUALSUBSCRIPTION
EOF
# shellcheck disable=SC2086
envarr=$(echo ${MM_ENV:-} | tr "," "\n")
for env in $envarr; do
echo "$env" >>.env.server
done
if [ "$TEST" = "cypress" ]; then
# Generate .env.cypress
mme2e_log "Cypress: Generating .env.cypress"
mme2e_generate_envfile_from_var_names >.env.cypress <<EOF
BRANCH
BUILD_ID
CI_BASE_URL
BROWSER
AUTOMATION_DASHBOARD_URL
AUTOMATION_DASHBOARD_TOKEN
EOF
# Additional variables to .env.cypress
if [[ $ENABLED_DOCKER_SERVICES == *"openldap"* ]]; then
echo "CYPRESS_ldapServer=openldap" >>.env.cypress
echo "CYPRESS_runLDAPSync=true" >>.env.cypress
fi
if [[ $ENABLED_DOCKER_SERVICES == *"minio"* ]]; then
echo "CYPRESS_minioS3Endpoint=minio:9000" >>.env.cypress
fi
if [[ $ENABLED_DOCKER_SERVICES == *"keycloak"* ]]; then
echo "CYPRESS_keycloakBaseUrl=http://keycloak:8484" >>.env.cypress
fi
if [[ $ENABLED_DOCKER_SERVICES == *"elasticsearch"* ]]; then
echo "CYPRESS_elasticsearchConnectionURL=http://elasticsearch:9200" >>.env.cypress
fi
if [ "$SERVER" = "cloud" ]; then
echo "CYPRESS_serverEdition=Cloud" >>.env.cypress
else
echo "CYPRESS_serverEdition=E20" >>.env.cypress
fi
elif [ "$TEST" = "playwright" ]; then
# Generate .env.playwright
mme2e_log "Playwright: Generating .env.playwright"
mme2e_generate_envfile_from_var_names >.env.playwright <<EOF
BRANCH
BUILD_ID
EOF
else
mme2e_log "Preparing server setup only"
fi
# Wait for the required server image
mme2e_log "Waiting for server image to be available"
mme2e_wait_image "$SERVER_IMAGE" 30 60

View File

@ -2,7 +2,6 @@
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
. .e2erc_setup
mme2e_log "Stopping E2E containers"
${MME2E_DC_SERVER} down -v --remove-orphans

View File

@ -9,6 +9,3 @@
# node
*.lock
# dev/ci
.ci/docker-compose.server.override.yml

View File

@ -3,38 +3,25 @@
export
SHELL := /bin/bash
TEST ?= cypress
SERVER ?= self-hosted
ENABLED_DOCKER_SERVICES ?= postgres inbucket
define log_message
@echo "[$(shell date '+%Y-%m-%dT%H:%M:%S%Z')]$1"
endef
.PHONY: all run stop
.PHONY: all run stop clean
all: run
run: info generate-docker-compose create-cloud-customer start-server-test prepare-server run-test delete-cloud-customer
stop: stop-server stop-dashboard clean-env-placeholders
run: cloud-init generate-server start-server prepare-server run-test cloud-teardown
stop: stop-server stop-dashboard clean
clean:
rm -fv .ci/server.yml
rm -fv .ci/.env*
.PHONY: info generate-docker-compose start-server-test run-test start-server prepare-server stop-server restart-server
generate-docker-compose:
bash ./.ci/docker_compose_generator.sh
start-server-test:
.PHONY: generate-server start-server prepare-server run-test stop-server restart-server
generate-server:
bash ./.ci/server.generate.sh
start-server: generate-server
bash ./.ci/server.start.sh
prepare-server:
bash ./.ci/server.prepare.sh
run-test:
@if [ "$(TEST)" = "cypress" ]; then bash ./.ci/server.run_cypress.sh; \
elif [ "$(TEST)" = "playwright" ]; then bash ./.ci/server.run_playwright.sh; \
else $(call log_message, "TEST: $(TEST)"); fi
info:
$(call log_message, "TEST: $(TEST)")
$(call log_message, "SERVER: $(SERVER)")
$(call log_message, "ENABLED_DOCKER_SERVICES: $(ENABLED_DOCKER_SERVICES)")
start-server: generate-docker-compose
TEST=server bash ./.ci/server.start.sh
stop-server:
bash ./.ci/server.run_test.sh
stop-server: generate-server
bash ./.ci/server.stop.sh
restart-server: stop-server start-server
@ -44,33 +31,19 @@ start-dashboard:
stop-dashboard:
bash ./.ci/dashboard.stop.sh
.PHONY: print-env-placeholders clean-env-placeholders
print-env-placeholders:
find .ci -maxdepth 1 -name '.env.*' | xargs --verbose -l cat
clean-env-placeholders:
git reset .ci/.env.{cypress,server,server.cloud,dashboard}
git checkout .ci/.env.{cypress,server,server.cloud,dashboard}
.PHONY: cloud-init cloud-teardown
cloud-init: requirecmd-jq requirecmd-curl
bash ./.ci/server.cloud_init.sh
cloud-teardown:
bash ./.ci/server.cloud_teardown.sh
.PHONY: create-cloud-customer delete-cloud-customer
create-cloud-customer:
@if [ "$(SERVER)" = "cloud" ]; then bash ./.ci/server.cloud_customer_create.sh; fi
delete-cloud-customer:
@if [ "$(SERVER)" = "cloud" ]; then bash ./.ci/server.cloud_customer_delete.sh; fi
.PHONY: prettier fmt-ci
# Install with https://webinstall.dev/shellcheck/
HAVE_SHELLCHECK ?= $(shell command -v shellcheck >/dev/null 2>&1 && echo yes)
# Install with https://webinstall.dev/shfmt/
HAVE_SHFMT ?= $(shell command -v shfmt >/dev/null 2>&1 && echo yes)
prettier:
# formats yaml files
.PHONY: fmt-node fmt-shell fmt
requirecmd-%:
@which "$(*)" >/dev/null || { echo "Error, missing required CLI tool: $(*). Aborting." >&2; exit 1; }
fmt-node: requirecmd-npx
# Formats yaml files
npx prettier ./.ci "!./.ci/dashboard" --write --cache
fmt-ci: prettier
ifeq ($(HAVE_SHFMT),yes)
shfmt -w -s -i 2 ./.ci/*.sh
endif
ifeq ($(HAVE_SHELLCHECK),yes)
shellcheck ./.ci/*.sh ./.ci/.e2erc*
endif
fmt-shell: requirecmd-shfmt requirecmd-shellcheck
shfmt -w -s -i 2 ./.ci/*.sh # Install with https://webinstall.dev/shellcheck/
shellcheck ./.ci/*.sh ./.ci/.e2erc* # Install with https://webinstall.dev/shfmt/
fmt: fmt-node fmt-shell

View File

@ -16,42 +16,35 @@ Instructions, tl;dr: create a local branch with your E2E test changes, then open
Instructions, detailed:
1. (optional, undefined variables are set to sane defaults) Create the `.ci/env` file, and populate it with the variables you need out of the following list:
* The following variables will be passed over to the server container: `MM_LICENSE` (no enterprise features will be available if this is unset), and the exploded `MM_ENV` (a comma-separated list of env var specifications)
* `TEST` either `cypress` (default) or `playwright`.
* `SERVER` either `self-hosted` (default) or `cloud`.
* The `ENABLED_DOCKER_SERVICES` is by default set to `postgres` and `inbucket` for smoke tests purpose, and for lightweight and faster start up time. Depending on the test requirement being worked on, you may want to override as needed, as such:
* Cypress full tests require full services with `postgres`, `inbucket`, `minio`, `openldap`, `elasticsearch` and `keycloak`.
* Cypress smoke tests require `postgres` and `inbucket` only.
* Playwright full tests require `postgres` and `inbucket` only.
* The following variables will be passed over to the cypress container: `BRANCH`, `BUILD_ID`, `CI_BASE_URL`, `BROWSER`, `AUTOMATION_DASHBOARD_URL` and `AUTOMATION_DASHBOARD_TOKEN`
* `SERVER`: either `self-hosted` (default) or `cloud`.
* `CWS_URL` (mandatory when `SERVER=cloud`, only used in such caase): when spinning up a cloud-like test server that communicates with a test instance of customer web server.
* `TEST`: either `cypress` (default), `playwright`, or `none` (to avoid creating the cypress/playwright sidecar containers, e.g. if you only want to launch a server instance)
* `ENABLED_DOCKER_SERVICES`: a space-separated list of services to start alongside the server. Default to `postgres inbucket`, for smoke tests purposes and for lightweight and faster start up time. Depending on the test requirement being worked on, you may want to override as needed, as such:
- Cypress full tests require all services to be running: `postgres inbucket minio openldap elasticsearch keycloak`.
- Cypress smoke tests require only the following: `postgres inbucket`.
- Playwright full tests require only the folliwing: `postgres inbucket`.
* The following variables, which will be passed over to the server container: `MM_LICENSE` (no enterprise features will be available if this is unset; required when `SERVER=cloud`), and the exploded `MM_ENV` (a comma-separated list of env var specifications)
* The following variables, which will be passed over to the cypress container: `BRANCH`, `BUILD_ID`, `CI_BASE_URL`, `BROWSER`, `AUTOMATION_DASHBOARD_URL` and `AUTOMATION_DASHBOARD_TOKEN`
* The `SERVER_IMAGE` variable can also be set, if you want to select a custom mattermost-server image. If not specified, the value of the `SERVER_IMAGE_DEFAULT` variable defined in file `.ci/.e2erc` is used.
* The `TEST_FILTER` variable can also be set, to customize which tests you want cypress to run. If not specified, only the smoke tests will run. Please check the `e2e-tests/cypress/run_tests.js` file for details about its format.
* Set `CWS_URL` when spinning up a cloud-like test server that communicates with a test instance of customer web server.
2. (optional) `make start-dashboard`: start the automation-dashboard in the background
* This also sets the `AUTOMATION_DASHBOARD_URL` and `AUTOMATION_DASHBOARD_TOKEN` variables for the cypress container
* Note that if you run the dashboard locally, but also specify other `AUTOMATION_DASHBOARD_*` variables in your `.ci/env` file, the latter variables will take precedence.
* The dashboard is used for orchestrating specs with parallel test run and is typically used in CI.
* Only Cypress is currently using the dashboard; Playwright is not.
3. Run the following commands to run with cypress:
* `TEST=cypress make`: start and prepare the server, then run the cypress tests against self-hosted test server.
* `TEST=cypress SERVER=cloud make`: create test customer for cloud, start and prepare the server, run the cypress tests against cloud-like test server, then delete the test customer. When anticipating a licensed test server, make sure the loaded license via `MM_LICENSE` is for cloud.
* When anticipating a licensed test server, make sure the loaded license via `MM_LICENSE` does match either for self-hosted or cloud.
* `CWS_URL` is required to be set for cloud test.
* You can track the progress of the run in the `http://localhost:4000/cycles` dashboard, if you launched it locally.
4. Run the following commands to run with playwright:
* `TEST=playwright make`: start and prepare the server, then run the playwright tests against self-hosted test server.
* `TEST=playwright SERVER=cloud `: generate test customer for cloud, start and prepare the server, run the playwright tests against cloud-like test server, then delete the initially generated test customer.
* When anticipating a licensed test server, make sure the loaded license via `MM_LICENSE` does match either for self-hosted or cloud.
* `CWS_URL` is required to be set for cloud test.
5. `TEST=server make`: starts local server.
6. `make stop`: tears down the server (and the dashboard, if running), then cleans up the env placeholder files.
3. `make`: start and prepare the server, then run the Cypress smoke tests
* You can track the progress of the run in the `http://localhost:4000/cycles` dashboard, if you launched it locally
* When running with `SERVER=cloud`, this will automatically create a cloud customer against the specified `CWS_URL` service, and delete that user after the run is complete.
* If you want to run the Playwright tests instead of the Cypress ones, you can run `TEST=playwright make`
* If you just want to run a local server instance, without any further testing, you can run `TEST=none make`
4. `make stop`: tears down the server (and the dashboard, if running)
* `make clean` will also remove any generated environment or docker-compose files, in addition to stopping the containers.
Notes:
- Setting a variable in `.ci/env` is functionally equivalent to exporting variables in your current shell's environment, before invoking the makefile.
- The `.ci/.env.*` files are auto generated by the pipeline scripts, and aren't meant to be modified manually. The only file you should edit to control the containers' environment is `.ci/env`, as specified in the instructions above.
- Aside from some exceptions (e.g. `TEST_FILTER`), most of the variables in `.ci/env` must be set before the `make start-server` command is run. Modifying that file afterwards has no effect, because the containers' env files are generated in that step.
- Aside from some exceptions (e.g. `TEST_FILTER`), most of the variables in `.ci/env` must be set before the `make generate-server` command is run. Modifying that file afterwards has no effect, because the containers' env files are generated in that step.
- If you restart the dashboard at any point, you must also restart the server containers, so that it picks up the new IP of the dashboard from the newly generated `.env.dashboard` file
- If you started the dashboard locally in the past, but want to point to another dashboard later, you can run `make clean-env-placeholders` to remove references to the local dashboard (you'll likely need to restart the server)
- If new variables need to be passed to any of the containers:
* If their value is fixed (e.g. a static server configuration), these may be simply added to the `docker_compose_generator.sh` file, to the appropriate container.
* If you need to introduce variables that you want to control from `.ci/env`: you need to update the scripts under the `.ci/` dir, and configure them to write the new variables' values over to the appropriate `.env.*` file. In particular, avoid defining variables that depend on other variables within the docker-compose override files: this is to ensure uniformity in their availability, and simplifies the question of what container has access to which variable considerably.

View File

@ -4,6 +4,7 @@
"requires": true,
"packages": {
"": {
"name": "cypress",
"devDependencies": {
"@babel/eslint-parser": "7.22.15",
"@babel/eslint-plugin": "7.22.10",

View File

@ -1,4 +1,5 @@
{
"name": "cypress",
"devDependencies": {
"@babel/eslint-parser": "7.22.15",
"@babel/eslint-plugin": "7.22.10",