diff --git a/.ci/oci_chectl_olm.sh b/.ci/oci_chectl_olm.sh new file mode 100755 index 000000000..1a4295200 --- /dev/null +++ b/.ci/oci_chectl_olm.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# +# Copyright (c) 2012-2020 Red Hat, Inc. +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Red Hat, Inc. - initial API and implementation + +set -e -x + +# Stop execution on any error +trap "catchFinish" EXIT SIGINT + +# Catch_Finish is executed after finish script. +catchFinish() { + result=$? + if [ "$result" != "0" ]; then + echo "Failed on running tests. Please check logs or contact QE team (e-mail:codereadyqe-workspaces-qe@redhat.com, Slack: #che-qe-internal, Eclipse mattermost: 'Eclipse Che QE'" + echo "Logs should be availabe on /tmp/artifacts/che-logs" + getCheClusterLogs + exit 1 + fi + + exit $result +} + +# Setup all necessary environments needed by e2e and Openshift CI +init() { + export SCRIPT=$(readlink -f "$0") + export SCRIPT_DIR=$(dirname "$SCRIPT") + + # Env necessary for openshift CI to put che logs inside + export ARTIFACTS_DIR="/tmp/artifacts" + + # SUGGESTED NAMESPACE + export NAMESPACE="eclipse-che" + + # Environment to define the project absolute path. + if [[ ${WORKSPACE} ]] && [[ -d ${WORKSPACE} ]]; then + export CHECTL_REPO=${WORKSPACE}; + else + export CHECTL_REPO=$(dirname "$SCRIPT_DIR"); + fi +} + +# Function to get all logs and events from Che deployments +getCheClusterLogs() { + mkdir -p ${ARTIFACTS_DIR}/che-logs + ${CHECTL_REPO}/bin/run server:logs --directory=${ARTIFACTS_DIR}/che-logs +} + +run() { + # Before to start to run the e2e tests we need to install all deps with yarn + yarn --cwd ${CHECTL_REPO} + export PLATFORM=openshift + export INSTALLER=olm + export XDG_CONFIG_HOME=/tmp/chectl/config + export XDG_CACHE_HOME=/tmp/chectl/cache + export XDG_DATA_HOME=/tmp/chectl/data + echo "[INFO] Running e2e tests on ${PLATFORM} platform." + yarn test --coverage=false --forceExit --testRegex=${CHECTL_REPO}/test/e2e/e2e.test.ts +} + +init +run diff --git a/.ci/cico_chectl_openshift.sh b/.ci/oci_chectl_operator.sh similarity index 97% rename from .ci/cico_chectl_openshift.sh rename to .ci/oci_chectl_operator.sh index c2359be7c..c4257bfe8 100755 --- a/.ci/cico_chectl_openshift.sh +++ b/.ci/oci_chectl_operator.sh @@ -34,7 +34,9 @@ init() { # Env necessary for openshift CI to put che logs inside export ARTIFACTS_DIR="/tmp/artifacts" - export NAMESPACE="che" + + # SUGGESTED NAMESPACE + export NAMESPACE="eclipse-che" # Environment to define the project absolute path. if [[ ${WORKSPACE} ]] && [[ -d ${WORKSPACE} ]]; then diff --git a/.github/workflows/e2e-minikube-helm.yml b/.github/workflows/e2e-minikube-helm.yml index b37648a3e..2a51c3006 100644 --- a/.github/workflows/e2e-minikube-helm.yml +++ b/.github/workflows/e2e-minikube-helm.yml @@ -8,11 +8,11 @@ # # Contributors: # Red Hat, Inc. - initial API and implementation -name: chectl e2e tests +name: Minikube E2E on: pull_request jobs: minikube-e2e-helm: - name: Minikube Helm + name: Helm installer runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/e2e-minikube-olm.yml b/.github/workflows/e2e-minikube-olm.yml new file mode 100644 index 000000000..c8b3ba038 --- /dev/null +++ b/.github/workflows/e2e-minikube-olm.yml @@ -0,0 +1,31 @@ +# +# Copyright (c) 2012-2020 Red Hat, Inc. +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Red Hat, Inc. - initial API and implementation +name: Minikube E2E +on: pull_request +jobs: + minikube-e2e-helm: + name: OLM installer + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v1 + - name: Install minikube kubernetes cluster + run: minikube start --memory=6000 + - name: Install chectl dependencies + run: yarn + - name: Run olm e2e tests minikube + run: | + export PLATFORM=minikube + export INSTALLER=olm + minikube addons enable olm + minikube addons enable ingress + + sleep 60 + yarn test --coverage=false --forceExit --testRegex=test/e2e/e2e.test.ts diff --git a/.github/workflows/e2e-minikube-operator.yml b/.github/workflows/e2e-minikube-operator.yml index 3f9152afc..4f55a9aac 100644 --- a/.github/workflows/e2e-minikube-operator.yml +++ b/.github/workflows/e2e-minikube-operator.yml @@ -8,11 +8,11 @@ # # Contributors: # Red Hat, Inc. - initial API and implementation -name: chectl e2e tests +name: Minikube E2E on: pull_request jobs: minikube-e2e: - name: Minikube Operator + name: Operator installer runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/e2e-minishift-operator.yml b/.github/workflows/e2e-minishift-operator.yml index 683f12663..c60efc00e 100644 --- a/.github/workflows/e2e-minishift-operator.yml +++ b/.github/workflows/e2e-minishift-operator.yml @@ -8,11 +8,11 @@ # # Contributors: # Red Hat, Inc. - initial API and implementation -name: chectl e2e tests +name: Minishift E2E on: pull_request jobs: minishift-e2e: - name: Minishift Operator + name: Operator installer runs-on: macos-latest steps: - uses: actions/checkout@v1 @@ -63,14 +63,14 @@ jobs: sleep 30 eval $(minishift oc-env) oc login -u system:admin --insecure-skip-tls-verify=true - oc create namespace che + oc create namespace eclipse-che oc project default oc delete secret router-certs cat domain.crt domain.key > minishift.crt oc create secret tls router-certs --key=domain.key --cert=minishift.crt sleep 5s # oc rollout latest router - oc create secret generic self-signed-certificate --from-file=ca.crt -n=che + oc create secret generic self-signed-certificate --from-file=ca.crt -n=eclipse-che # RUN THE TESTS export PLATFORM=minishift export INSTALLER=operator diff --git a/test/e2e/e2e.test.ts b/test/e2e/e2e.test.ts index 35aa4b2da..98eb4c677 100644 --- a/test/e2e/e2e.test.ts +++ b/test/e2e/e2e.test.ts @@ -13,6 +13,7 @@ import { expect, test } from '@oclif/test' import * as execa from 'execa' +import { DEFAULT_OLM_SUGGESTED_NAMESPACE } from '../../src/constants' import { isKubernetesPlatformFamily } from '../../src/util' import { E2eHelper } from './util' @@ -22,6 +23,8 @@ jest.setTimeout(1000000) const binChectl = `${process.cwd()}/bin/run` +const NAMESPACE = DEFAULT_OLM_SUGGESTED_NAMESPACE + const PLATFORM = process.env.PLATFORM || '' const INSTALLER = process.env.INSTALLER || '' @@ -32,27 +35,36 @@ const PLATFORM_MINIKUBE = 'minikube' const INSTALLER_OPERATOR = 'operator' const INSTALLER_HELM = 'helm' +const INSTALLER_OLM = 'olm' function getDeployCommand(): string { let command: string switch (PLATFORM) { - case PLATFORM_OPENSHIFT: - case PLATFORM_CRC: - case PLATFORM_MINISHIFT: - if (INSTALLER !== INSTALLER_OPERATOR) { - throw new Error(`Unknown installer ${INSTALLER}`) - } - command = `${binChectl} server:deploy --platform=${PLATFORM} --installer=${INSTALLER} --che-operator-cr-patch-yaml=test/e2e/resources/cr-patch.yaml` - break - case PLATFORM_MINIKUBE: - if (!(INSTALLER === INSTALLER_OPERATOR || INSTALLER === INSTALLER_HELM)) { - throw new Error(`Unknown installer ${INSTALLER}`) - } - const patchOption = INSTALLER === INSTALLER_HELM ? '--helm-patch-yaml=test/e2e/resources/helm-patch.yaml' : '--che-operator-cr-patch-yaml=test/e2e/resources/cr-patch.yaml' - command = `${binChectl} server:deploy --platform=${PLATFORM} --installer=${INSTALLER} ${patchOption} --multiuser --skip-cluster-availability-check` - break - default: - throw new Error(`Unknown platform: ${PLATFORM}`) + case PLATFORM_OPENSHIFT: + if (!(INSTALLER === INSTALLER_OPERATOR || INSTALLER === INSTALLER_OLM)) { + throw new Error(`Unknown installer ${INSTALLER}`) + } + command = `${binChectl} server:deploy --platform=${PLATFORM} --installer=${INSTALLER} --chenamespace=${NAMESPACE} --che-operator-cr-patch-yaml=test/e2e/resources/cr-patch.yaml` + break + + case PLATFORM_CRC: + case PLATFORM_MINISHIFT: + if (INSTALLER !== INSTALLER_OPERATOR) { + throw new Error(`Unknown installer ${INSTALLER}`) + } + command = `${binChectl} server:deploy --platform=${PLATFORM} --installer=${INSTALLER} --chenamespace=${NAMESPACE} --che-operator-cr-patch-yaml=test/e2e/resources/cr-patch.yaml` + break + + case PLATFORM_MINIKUBE: + if (!(INSTALLER === INSTALLER_OPERATOR || INSTALLER === INSTALLER_HELM || INSTALLER === INSTALLER_OLM)) { + throw new Error(`Unknown installer ${INSTALLER}`) + } + const patchOption = INSTALLER === INSTALLER_HELM ? '--helm-patch-yaml=test/e2e/resources/helm-patch.yaml' : '--che-operator-cr-patch-yaml=test/e2e/resources/cr-patch.yaml' + command = `${binChectl} server:deploy --platform=${PLATFORM} --installer=${INSTALLER} --chenamespace=${NAMESPACE} ${patchOption} --multiuser --skip-cluster-availability-check` + break + + default: + throw new Error(`Unknown platform: ${PLATFORM}`) } return command } @@ -82,13 +94,13 @@ describe('Eclipse Che server authentication', () => { let cheApiEndpoint: string if (isKubernetesPlatformFamily(PLATFORM)) { const ingressName = INSTALLER === INSTALLER_HELM ? 'che-ingress' : 'che' - cheApiEndpoint = await helper.K8SHostname(ingressName) + '/api' + cheApiEndpoint = await helper.K8SHostname(ingressName, NAMESPACE) + '/api' } else { - cheApiEndpoint = await helper.OCHostname('che') + '/api' + cheApiEndpoint = await helper.OCHostname('che', NAMESPACE) + '/api' } const command = `${binChectl} auth:login` - const args = [cheApiEndpoint, '-u', 'admin', '-p', 'admin'] + const args = [cheApiEndpoint, '-u', 'admin', '-p', 'admin', '-n', `${NAMESPACE}`] const { exitCode, stdout, stderr } = await execa(command, args, { timeout: 30000, shell: true }) @@ -102,7 +114,7 @@ describe('Eclipse Che server authentication', () => { }) it('Should show current login session', async () => { - const command = `${binChectl} auth:get` + const command = `${binChectl} auth:get -n ${NAMESPACE}` const { exitCode, stdout, stderr } = await execa(command, { timeout: 30000, shell: true }) @@ -118,7 +130,7 @@ describe('Eclipse Che server authentication', () => { describe('Export CA certificate', () => { it('Export CA certificate', async () => { - const command = `${binChectl} cacert:export` + const command = `${binChectl} cacert:export -n ${NAMESPACE}` const { exitCode, stdout, stderr } = await execa(command, { timeout: 30000, shell: true }) @@ -136,7 +148,7 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele it('Testing workspace:create command', async () => { console.log('>>> Testing workspace:create command') - const { exitCode, stdout, stderr, } = await execa(binChectl, ['workspace:create', '--devfile=test/e2e/resources/devfile-example.yaml'], { timeout: 30000, shell: true }) + const { exitCode, stdout, stderr, } = await execa(binChectl, ['workspace:create', '--devfile=test/e2e/resources/devfile-example.yaml', `-n ${NAMESPACE}`], { timeout: 30000, shell: true }) console.log(`stdout: ${stdout}`) console.log(`stderr: ${stderr}`) @@ -149,7 +161,7 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele console.log('>>> Testing workspace:start command') const workspaceId = await helper.getWorkspaceId() - const { exitCode, stdout, stderr, } = await execa(binChectl, ['workspace:start', workspaceId], { timeout: 30000, shell: true }) + const { exitCode, stdout, stderr, } = await execa(binChectl, ['workspace:start', workspaceId, `-n ${NAMESPACE}`], { timeout: 30000, shell: true }) console.log(`stdout: ${stdout}`) console.log(`stderr: ${stderr}`) @@ -166,7 +178,7 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele it('Testing workspace:inject command', async () => { console.log('>>> Testing workspace:inject command') - const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:inject', '--kubeconfig'], { timeout: 60000, shell: true }) + const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:inject', '--kubeconfig', `-n ${NAMESPACE}`], { timeout: 60000, shell: true }) console.log(`stdout: ${stdout}`) console.log(`stderr: ${stderr}`) @@ -178,16 +190,29 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele test .stdout({ print: true }) .stderr({ print: true }) - .command(['workspace:list']) - .it('List workspaces') + .it('List workspaces', async () => { + console.log('>>> Testing workspace:list command') + const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:list', `--chenamespace=${NAMESPACE}`], { timeout: 30000, shell: true }) + + console.log(`stdout: ${stdout}`) + console.log(`stderr: ${stderr}`) + expect(exitCode).equal(0) + }) }) describe('Get Eclipse Che server status', () => { test .stdout({ print: true }) .stderr({ print: true }) - .command(['server:status']) - .it('Get Che Server status') + .it('Get Che Server status', async () => { + console.log('>>> Testing server:status command') + + const { exitCode, stdout, stderr } = await execa(binChectl, ['server:status', `--chenamespace=${NAMESPACE}`], { timeout: 30000, shell: true }) + + console.log(`stdout: ${stdout}`) + console.log(`stderr: ${stderr}`) + expect(exitCode).equal(0) + }) }) describe('Stop Workspace', () => { @@ -195,7 +220,7 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele console.log('>>> Testing workspace:stop command') const workspaceId = await helper.getWorkspaceId() - const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:stop', workspaceId], { timeout: 30000, shell: true }) + const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:stop', workspaceId, `-n ${NAMESPACE}`], { timeout: 30000, shell: true }) console.log(`stdout: ${stdout}`) console.log(`stderr: ${stderr}`) @@ -212,7 +237,7 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele console.log('>>> Testing workspace:delete command') const workspaceId = await helper.getWorkspaceId() - const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:delete', workspaceId], { timeout: 30000, shell: true }) + const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:delete', workspaceId, `-n ${NAMESPACE}`], { timeout: 30000, shell: true }) console.log(`stdout: ${stdout}`) console.log(`stderr: ${stderr}`) @@ -224,7 +249,7 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele it('server:stop command coverage', async () => { console.log('>>> Testing server:stop command') - const { exitCode, stdout, stderr } = await execa(binChectl, ['server:stop'], { shell: true }) + const { exitCode, stdout, stderr } = await execa(binChectl, ['server:stop', `-n ${NAMESPACE}`], { shell: true }) console.log(`stdout: ${stdout}`) console.log(`stderr: ${stderr}`) @@ -236,7 +261,7 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele test .stdout({ print: true }) .stderr({ print: true }) - .command(['server:delete', '--yes', '--delete-namespace']) + .command(['server:delete', '--yes', '--delete-namespace', '-n', `${NAMESPACE}`]) .exit(0) .it(`deletes Eclipse Che resources on ${PLATFORM} platform successfully`) }) diff --git a/test/e2e/util.ts b/test/e2e/util.ts index 59e3626fd..6b21925c9 100644 --- a/test/e2e/util.ts +++ b/test/e2e/util.ts @@ -84,10 +84,10 @@ export class E2eHelper { } //Return a route from Openshift adding protocol - async OCHostname(ingressName: string): Promise { - if (await this.oc.routeExist(ingressName, 'che')) { - const protocol = await this.oc.getRouteProtocol(ingressName, 'che') - const hostname = await this.oc.getRouteHost(ingressName, 'che') + async OCHostname(ingressName: string, namespace: string): Promise { + if (await this.oc.routeExist(ingressName, namespace)) { + const protocol = await this.oc.getRouteProtocol(ingressName, namespace) + const hostname = await this.oc.getRouteHost(ingressName, namespace) return `${protocol}://${hostname}` } @@ -95,8 +95,7 @@ export class E2eHelper { } // Return ingress and protocol from minikube platform - async K8SHostname(ingressName: string): Promise { - const namespace = 'che' + async K8SHostname(ingressName: string, namespace: string): Promise { if (await this.kubeHelper.ingressExist(ingressName, namespace)) { const protocol = await this.kubeHelper.getIngressProtocol(ingressName, namespace) const hostname = await this.kubeHelper.getIngressHost(ingressName, namespace)