Skip to content

Commit

Permalink
Fixes according to review
Browse files Browse the repository at this point in the history
Signed-off-by: Mykola Morhun <mmorhun@redhat.com>
  • Loading branch information
mmorhun committed Mar 1, 2021
1 parent 45f28d0 commit 11a14b8
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 76 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/e2e-minikube-operator-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
94 changes: 20 additions & 74 deletions test/e2e/e2e-upgrade.test.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)

Expand All @@ -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<string> {
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<boolean> {
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<boolean> {
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

Expand All @@ -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')
Expand All @@ -121,47 +67,47 @@ 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'
} else {
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')
}
61 changes: 61 additions & 0 deletions test/e2e/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -42,6 +45,28 @@ export class E2eHelper {
this.oc = new OpenShiftHelper()
}

async runCliCommand(command: string, args?: string[], printOutput = true): Promise<string> {
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<chetypes.workspace.Workspace[]> {
private async getAllWorkspaces(): Promise<WorkspaceInfo[]> {
Expand Down Expand Up @@ -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<void> {
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<void> {
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 `)
}

}

0 comments on commit 11a14b8

Please sign in to comment.