From 11a14b84ba9914e326b3f912acdbc0285553df01 Mon Sep 17 00:00:00 2001 From: Mykola Morhun Date: Mon, 1 Mar 2021 11:29:47 +0200 Subject: [PATCH] Fixes according to review Signed-off-by: Mykola Morhun --- .../e2e-minikube-operator-update.yml | 4 +- test/e2e/e2e-upgrade.test.ts | 94 ++++--------------- test/e2e/util.ts | 61 ++++++++++++ 3 files changed, 83 insertions(+), 76 deletions(-) diff --git a/.github/workflows/e2e-minikube-operator-update.yml b/.github/workflows/e2e-minikube-operator-update.yml index 10757907f..8b38c9301 100644 --- a/.github/workflows/e2e-minikube-operator-update.yml +++ b/.github/workflows/e2e-minikube-operator-update.yml @@ -8,11 +8,11 @@ # # Contributors: # Red Hat, Inc. - initial API and implementation -name: Minikube E2E Che update +name: Minikube on: pull_request jobs: minikube-e2e-update: - name: Operator installer update + name: e2e update tests runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v1 diff --git a/test/e2e/e2e-upgrade.test.ts b/test/e2e/e2e-upgrade.test.ts index b84d40a8a..c5ec589de 100644 --- a/test/e2e/e2e-upgrade.test.ts +++ b/test/e2e/e2e-upgrade.test.ts @@ -1,5 +1,5 @@ /********************************************************************* - * Copyright (c) 2020 Red Hat, Inc. + * Copyright (c) 2021 Red Hat, Inc. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -11,15 +11,12 @@ // tslint:disable: no-console import { expect } from '@oclif/test' -import * as execa from 'execa' import { CheGithubClient } from '../../src/api/github-client' -import { KubeHelper } from '../../src/api/kube' import { isKubernetesPlatformFamily } from '../../src/util' -import { DEVFILE_URL, E2eHelper } from './util' +import { DEVFILE_URL, E2eHelper, NAMESPACE, NIGHTLY } from './util' -const kube = new KubeHelper() const helper = new E2eHelper() jest.setTimeout(1000000) @@ -28,62 +25,11 @@ const binChectl = `${process.cwd()}/bin/run` const PLATFORM = process.env.PLATFORM || 'minikube' const INSTALLER = 'operator' -const NAMESPACE = 'eclipse-che' - -const NIGHTLY = 'nightly' const UPDATE_CHE_TIMEOUT_MS = 5 * 60 * 1000 const WORKSPACE_START_TIMEOUT_MS = 5 * 60 * 1000 const CHE_VERSION_TIMEOUT_MS = 50 * 1000 -async function runCommand(command: string, args?: string[]): Promise { - console.log(`Running command: ${command} ${args ? args.join(' ') : ''}`) - const { exitCode, stdout, stderr } = await execa(command, args, { shell: true }) - console.log(stdout) - if (exitCode !== 0) { - console.log(stderr) - } - - expect(exitCode).equal(0) - - return stdout -} - -async function waitForVersionInCheCR(version: string, timeoutMs: number): Promise { - const delayMs = 5 * 1000 - - let totalTimeMs = 0 - while (totalTimeMs < timeoutMs) { - const cheCR = await kube.getCheCluster(NAMESPACE) - if (cheCR.status.cheVersion === version) { - return true - } - await helper.sleep(delayMs) - totalTimeMs += delayMs - } - return false -} - -async function waitForCheServerImageTag(tag: string, timeoutMs: number): Promise { - const delayMs = 5 * 1000 - const chePodNameRegExp = new RegExp('che-[0-9a-f]+-.*') - - let totalTimeMs = 0 - while (totalTimeMs < timeoutMs) { - const pods = (await kube.listNamespacedPod(NAMESPACE)).items - const pod = pods.find((pod => pod.metadata && pod.metadata.name && pod.metadata.name.match(chePodNameRegExp))) - if (pod && pod.status && pod.status.containerStatuses && pod.status.containerStatuses[0].image) { - const imageTag = pod.status.containerStatuses[0].image.split(':')[1] - if (imageTag === tag) { - return true - } - } - await helper.sleep(delayMs) - totalTimeMs += delayMs - } - return false -} - describe('Test Che upgrade', () => { let cheVersion: string @@ -95,24 +41,24 @@ describe('Test Che upgrade', () => { cheVersion = latestStableCheTag.name const deployCommand = `${binChectl} server:deploy --platform=${PLATFORM} --installer=${INSTALLER} --version=${cheVersion} --chenamespace=${NAMESPACE} --telemetry=off --che-operator-cr-patch-yaml=test/e2e/resources/cr-patch.yaml` - await runCommand(deployCommand) + await helper.runCliCommand(deployCommand) - expect(await waitForVersionInCheCR(cheVersion, CHE_VERSION_TIMEOUT_MS)).equal(true) + await helper.waitForVersionInCheCR(cheVersion, CHE_VERSION_TIMEOUT_MS) }) it('Prepare test workspace', async () => { - await loginTest() + await runLoginTest() // Create - await runCommand(binChectl, ['workspace:create', `--devfile=${DEVFILE_URL}`, '--telemetry=off', `-n ${NAMESPACE}`]) + await helper.runCliCommand(binChectl, ['workspace:create', `--devfile=${DEVFILE_URL}`, '--telemetry=off', `-n ${NAMESPACE}`]) const workspaceId = await helper.getWorkspaceId() // Start - await runCommand(binChectl, ['workspace:start', workspaceId, `-n ${NAMESPACE}`, '--telemetry=off']) - expect(await helper.waitWorkspaceStatus('RUNNING', WORKSPACE_START_TIMEOUT_MS)).to.equal(true) + await helper.runCliCommand(binChectl, ['workspace:start', workspaceId, `-n ${NAMESPACE}`, '--telemetry=off']) + await helper.waitWorkspaceStatus('RUNNING', WORKSPACE_START_TIMEOUT_MS) // Stop - await runCommand(binChectl, ['workspace:stop', workspaceId, `-n ${NAMESPACE}`, '--telemetry=off']) + await helper.runCliCommand(binChectl, ['workspace:stop', workspaceId, `-n ${NAMESPACE}`, '--telemetry=off']) const workspaceStatus = await helper.getWorkspaceStatus() // The status could be STOPPING or STOPPED expect(workspaceStatus).to.contain('STOP') @@ -121,40 +67,40 @@ describe('Test Che upgrade', () => { describe('Test Che update', () => { it('Update Che to nightly version', async () => { - await runCommand(binChectl, ['server:update', '-y', `-n ${NAMESPACE}`, '--telemetry=off']) - expect(await waitForCheServerImageTag(NIGHTLY, UPDATE_CHE_TIMEOUT_MS)).equal(true) + await helper.runCliCommand(binChectl, ['server:update', '-y', `-n ${NAMESPACE}`, '--telemetry=off']) + await helper.waitForCheServerImageTag(NIGHTLY, UPDATE_CHE_TIMEOUT_MS) }) it('Check updated Che version', async () => { - expect(await waitForVersionInCheCR(NIGHTLY, CHE_VERSION_TIMEOUT_MS)).equal(true) + await helper.waitForVersionInCheCR(NIGHTLY, CHE_VERSION_TIMEOUT_MS) }) }) describe('Test updated Che', () => { it('Start existing workspace after update', async () => { // Relogin - await loginTest() + await runLoginTest() const workspaceId = await helper.getWorkspaceId() - await runCommand(binChectl, ['workspace:start', workspaceId, `-n ${NAMESPACE}`, '--telemetry=off']) - expect(await helper.waitWorkspaceStatus('RUNNING', WORKSPACE_START_TIMEOUT_MS)).to.equal(true) + await helper.runCliCommand(binChectl, ['workspace:start', workspaceId, `-n ${NAMESPACE}`, '--telemetry=off']) + await helper.waitWorkspaceStatus('RUNNING', WORKSPACE_START_TIMEOUT_MS) }) }) describe('Test Che downgrade', () => { it('Downgrade Che', async () => { - await runCommand(binChectl, ['server:update', '-y', `--version=${cheVersion}`, `-n ${NAMESPACE}`, '--telemetry=off']) - expect(await waitForCheServerImageTag(cheVersion, UPDATE_CHE_TIMEOUT_MS)).equal(true) + await helper.runCliCommand(binChectl, ['server:update', '-y', `--version=${cheVersion}`, `-n ${NAMESPACE}`, '--telemetry=off']) + await helper.waitForCheServerImageTag(cheVersion, UPDATE_CHE_TIMEOUT_MS) }) it('Check downgraded Che version', async () => { - expect(await waitForVersionInCheCR(cheVersion, CHE_VERSION_TIMEOUT_MS)).equal(true) + await helper.waitForVersionInCheCR(cheVersion, CHE_VERSION_TIMEOUT_MS) }) }) }) -async function loginTest() { +async function runLoginTest() { let cheApiEndpoint: string if (isKubernetesPlatformFamily(PLATFORM)) { cheApiEndpoint = await helper.K8SHostname('che', NAMESPACE) + '/api' @@ -162,6 +108,6 @@ async function loginTest() { cheApiEndpoint = await helper.OCHostname('che', NAMESPACE) + '/api' } - const stdout = await runCommand(binChectl, ['auth:login', cheApiEndpoint, '-u', 'admin', '-p', 'admin', '-n', `${NAMESPACE}`, '--telemetry=off']) + const stdout = await helper.runCliCommand(binChectl, ['auth:login', cheApiEndpoint, '-u', 'admin', '-p', 'admin', '-n', `${NAMESPACE}`, '--telemetry=off']) expect(stdout).to.contain('Successfully logged into') } diff --git a/test/e2e/util.ts b/test/e2e/util.ts index 983af8b73..649ebb74b 100644 --- a/test/e2e/util.ts +++ b/test/e2e/util.ts @@ -27,6 +27,9 @@ const binChectl = `${process.cwd()}/bin/run` export const DEVFILE_URL = 'https://raw.githubusercontent.com/eclipse/che-devfile-registry/master/devfiles/quarkus/devfile.yaml' +export const NAMESPACE = 'eclipse-che' +export const NIGHTLY = 'nightly' + //Utilities to help e2e tests export class E2eHelper { protected kubeHelper: KubeHelper @@ -42,6 +45,28 @@ export class E2eHelper { this.oc = new OpenShiftHelper() } + async runCliCommand(command: string, args?: string[], printOutput = true): Promise { + if (printOutput) { + // tslint:disable-next-line: no-console + console.log(`Running command: ${command} ${args ? args.join(' ') : ''}`) + } + + const { exitCode, stdout, stderr } = await execa(command, args, { shell: true }) + + if (printOutput) { + // tslint:disable-next-line: no-console + console.log(stdout) + if (exitCode !== 0) { + // tslint:disable-next-line: no-console + console.log(stderr) + } + } + + expect(exitCode).toEqual(0) + + return stdout + } + // Return an array with all user workspaces // async getAllWorkspaces(isOpenshiftPlatformFamily: string): Promise { private async getAllWorkspaces(): Promise { @@ -128,4 +153,40 @@ export class E2eHelper { // tslint:disable-next-line no-string-based-set-timeout return new Promise(resolve => setTimeout(resolve, ms)) } + + async waitForVersionInCheCR(version: string, timeoutMs: number): Promise { + const delayMs = 5 * 1000 + + let totalTimeMs = 0 + while (totalTimeMs < timeoutMs) { + const cheCR = await this.kubeHelper.getCheCluster(NAMESPACE) + if (cheCR && cheCR.status && cheCR.status.cheVersion === version) { + return + } + await this.sleep(delayMs) + totalTimeMs += delayMs + } + throw new Error(`Che CR version ${version} has not appeared in ${timeoutMs / 1000}s`) + } + + async waitForCheServerImageTag(tag: string, timeoutMs: number): Promise { + const delayMs = 5 * 1000 + const chePodNameRegExp = new RegExp('che-[0-9a-f]+-.*') + + let totalTimeMs = 0 + while (totalTimeMs < timeoutMs) { + const pods = (await this.kubeHelper.listNamespacedPod(NAMESPACE)).items + const pod = pods.find((pod => pod.metadata && pod.metadata.name && pod.metadata.name.match(chePodNameRegExp))) + if (pod && pod.status && pod.status.containerStatuses && pod.status.containerStatuses[0].image) { + const imageTag = pod.status.containerStatuses[0].image.split(':')[1] + if (imageTag === tag) { + return + } + } + await this.sleep(delayMs) + totalTimeMs += delayMs + } + throw new Error(`Che server image tag ${tag} has not appeared in ${timeoutMs / 1000}s `) + } + }