From 42965c4069a985180ab68f9bb80e4f8ce8e53d2d Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Tue, 10 Nov 2020 09:10:00 +0200 Subject: [PATCH] feat: Improve error check while deploying Eclipse Che (#973) * Improve error check * Fix test Signed-off-by: Anatolii Bazko --- .github/workflows/e2e-minikube-helm.yml | 28 ++++ .github/workflows/e2e-minikube-operator.yml | 28 ++++ .../{e2e.yml => e2e-minishift-operator.yml} | 33 +--- README.md | 10 +- package.json | 8 +- src/api/kube.ts | 18 +-- src/commands/auth/login.ts | 2 +- src/commands/server/deploy.ts | 18 ++- src/tasks/kube.ts | 92 +++++++----- test/e2e/e2e.test.ts | 141 ++++++++---------- test/e2e/util.ts | 2 +- 11 files changed, 213 insertions(+), 167 deletions(-) create mode 100644 .github/workflows/e2e-minikube-helm.yml create mode 100644 .github/workflows/e2e-minikube-operator.yml rename .github/workflows/{e2e.yml => e2e-minishift-operator.yml} (74%) diff --git a/.github/workflows/e2e-minikube-helm.yml b/.github/workflows/e2e-minikube-helm.yml new file mode 100644 index 000000000..b37648a3e --- /dev/null +++ b/.github/workflows/e2e-minikube-helm.yml @@ -0,0 +1,28 @@ +# +# 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: chectl e2e tests +on: pull_request +jobs: + minikube-e2e-helm: + name: Minikube Helm + 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 e2e tests minikube + run: | + export PLATFORM=minikube + export INSTALLER=helm + minikube addons enable ingress + 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 new file mode 100644 index 000000000..3f9152afc --- /dev/null +++ b/.github/workflows/e2e-minikube-operator.yml @@ -0,0 +1,28 @@ +# +# 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: chectl e2e tests +on: pull_request +jobs: + minikube-e2e: + name: Minikube Operator + 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 e2e tests minikube + run: | + export PLATFORM=minikube + export INSTALLER=operator + minikube addons enable ingress + yarn test --coverage=false --forceExit --testRegex=test/e2e/e2e.test.ts diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e-minishift-operator.yml similarity index 74% rename from .github/workflows/e2e.yml rename to .github/workflows/e2e-minishift-operator.yml index 6b0fa10b5..683f12663 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e-minishift-operator.yml @@ -11,36 +11,6 @@ name: chectl e2e tests on: pull_request jobs: - minikube-e2e: - name: Minikube Operator - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Install minikube kubernetes cluster - run: minikube start --memory=6000 - - name: Install chectl dependencies - run: yarn - - name: Run e2e tests minikube - run: | - export PLATFORM=minikube - export INSTALLER=operator - minikube addons enable ingress - yarn test --coverage=false --forceExit --testRegex=test/e2e/e2e.test.ts - minikube-e2e-helm: - name: Minikube Helm - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Install minikube kubernetes cluster - run: minikube start --memory=6000 - - name: Install chectl dependencies - run: yarn - - name: Run e2e tests minikube - run: | - export PLATFORM=minikube - export INSTALLER=helm - minikube addons enable ingress - yarn test --coverage=false --forceExit --testRegex=test/e2e/e2e.test.ts minishift-e2e: name: Minishift Operator runs-on: macos-latest @@ -98,7 +68,8 @@ jobs: oc delete secret router-certs cat domain.crt domain.key > minishift.crt oc create secret tls router-certs --key=domain.key --cert=minishift.crt - oc rollout latest router + sleep 5s + # oc rollout latest router oc create secret generic self-signed-certificate --from-file=ca.crt -n=che # RUN THE TESTS export PLATFORM=minishift diff --git a/README.md b/README.md index 634d32224..4bac0ccd3 100644 --- a/README.md +++ b/README.md @@ -516,11 +516,17 @@ OPTIONS --helm-patch-yaml=helm-patch-yaml Path to yaml file with Helm Chart values patch. The file format is identical to values.yaml from the chart. + --k8spoddownloadimagetimeout=k8spoddownloadimagetimeout + [default: 600000] Waiting time for Pod downloading image (in milliseconds) + + --k8spoderrorrechecktimeout=k8spoderrorrechecktimeout + [default: 15000] Waiting time for Pod rechecking error (in milliseconds) + --k8spodreadytimeout=k8spodreadytimeout - [default: 130000] Waiting time for Pod Ready Kubernetes (in milliseconds) + [default: 600000] Waiting time for Pod Ready condition (in milliseconds) --k8spodwaittimeout=k8spodwaittimeout - [default: 300000] Waiting time for Pod Wait Timeout Kubernetes (in milliseconds) + [default: 600000] Waiting time for Pod scheduled condition (in milliseconds) --olm-channel=olm-channel Olm channel to install Eclipse Che, f.e. stable. diff --git a/package.json b/package.json index bbe9e9322..3c11c293d 100644 --- a/package.json +++ b/package.json @@ -140,10 +140,10 @@ "test": "jest", "posttest": "tslint -p test -t stylish", "test-watch": "jest --watchAll", - "e2e-minikube": "jest ./test/e2e/minikube.test.ts --testRegex='/test/(e2e)/.*.test.ts'", - "e2e-minishift": "jest ./test/e2e/minishift.test.ts --testRegex='/test/(e2e)/.*.test.ts'", - "e2e-openshift": "jest ./test/e2e/openshift.test.ts --testRegex='/test/(e2e)/.*.test.ts'", - "prepack": "rm -rf lib && rm -rf tsconfig.tsbuildinfo && tsc -b && oclif-dev manifest && oclif-dev readme", + "e2e-minikube-helm": "export PLATFORM=minikube && export INSTALLER=helm && yarn jest ./test/e2e/e2e.test.ts --testRegex='/test/(e2e)/.*.test.ts'", + "e2e-minikube-operator": "export PLATFORM=minikube && export INSTALLER=operator && yarn jest ./test/e2e/e2e.test.ts --testRegex='/test/(e2e)/.*.test.ts'", + "e2e-minishift": "export PLATFORM=minishift && export INSTALLER=operator && yarn jest ./test/e2e/e2e.test.ts --testRegex='/test/(e2e)/.*.test.ts'", + "e2e-openshift": "export PLATFORM=openshift && export INSTALLER=operator && yarn jest ./test/e2e/e2e.test.ts --testRegex='/test/(e2e)/.*.test.ts'", "prepack": "rm -rf lib && rm -rf tsconfig.tsbuildinfo && tsc -b && oclif-dev manifest && oclif-dev readme", "pack-binaries": "oclif-dev pack", "postpack": "rm -f oclif.manifest.json", "format": "tsfmt -r --useTsfmt tsfmt.json", diff --git a/src/api/kube.ts b/src/api/kube.ts index b7c18a785..ee52ff2f2 100644 --- a/src/api/kube.ts +++ b/src/api/kube.ts @@ -28,6 +28,8 @@ import { CatalogSource, ClusterServiceVersion, ClusterServiceVersionList, Instal import { IdentityProvider, OAuth } from './typings/openshift' const AWAIT_TIMEOUT_S = 30 +export const DEFAULT_K8S_POD_TIMEOUT = 600000 +export const DEFAULT_K8S_POD_ERROR_RECHECK_TIMEOUT = 15000 export class KubeHelper { public static readonly KUBE_CONFIG = KubeHelper.initializeKubeConfig() @@ -42,19 +44,15 @@ export class KubeHelper { logHelper = new Log(KubeHelper.KUBE_CONFIG) podWaitTimeout: number + podDownloadImageTimeout: number podReadyTimeout: number + podErrorRecheckTimeout: number constructor(flags?: any) { - if (flags && flags.k8spodwaittimeout) { - this.podWaitTimeout = parseInt(flags.k8spodwaittimeout, 10) - } else { - this.podWaitTimeout = 300000 - } - if (flags && flags.k8spodreadytimeout) { - this.podReadyTimeout = parseInt(flags.k8spodreadytimeout, 10) - } else { - this.podReadyTimeout = 130000 - } + this.podWaitTimeout = (flags && flags.k8spodwaittimeout) ? parseInt(flags.k8spodwaittimeout, 10) : DEFAULT_K8S_POD_TIMEOUT + this.podReadyTimeout = (flags && flags.k8spodreadytimeout) ? parseInt(flags.k8spodreadytimeout, 10) : DEFAULT_K8S_POD_TIMEOUT + this.podDownloadImageTimeout = (flags && flags.k8spoddownloadimagetimeout) ? parseInt(flags.k8spoddownloadimagetimeout, 10) : DEFAULT_K8S_POD_TIMEOUT + this.podErrorRecheckTimeout = (flags && flags.spoderrorrechecktimeout) ? parseInt(flags.spoderrorrechecktimeout, 10) : DEFAULT_K8S_POD_ERROR_RECHECK_TIMEOUT } async createNamespace(namespaceName: string, labels: any): Promise { diff --git a/src/commands/auth/login.ts b/src/commands/auth/login.ts index 6f79a40d9..30252a8c0 100644 --- a/src/commands/auth/login.ts +++ b/src/commands/auth/login.ts @@ -151,7 +151,7 @@ export default class Login extends Command { try { const username = await loginManager.setLoginContext(cheApiEndpoint, loginData) - cli.info(`Succesfully logged into ${cheApiEndpoint} as ${username}`) + cli.info(`Successfully logged into ${cheApiEndpoint} as ${username}`) } catch (error) { cli.error(error) } diff --git a/src/commands/server/deploy.ts b/src/commands/server/deploy.ts index b661f8d38..99fc08c89 100644 --- a/src/commands/server/deploy.ts +++ b/src/commands/server/deploy.ts @@ -17,7 +17,7 @@ import * as notifier from 'node-notifier' import * as os from 'os' import * as path from 'path' -import { KubeHelper } from '../../api/kube' +import { DEFAULT_K8S_POD_ERROR_RECHECK_TIMEOUT, DEFAULT_K8S_POD_TIMEOUT, KubeHelper } from '../../api/kube' import { cheDeployment, cheNamespace, cheOperatorCRPatchYaml, cheOperatorCRYaml, CHE_OPERATOR_CR_PATCH_YAML_KEY, CHE_OPERATOR_CR_YAML_KEY, devWorkspaceControllerNamespace, listrRenderer, skipKubeHealthzCheck as skipK8sHealthCheck } from '../../common-flags' import { DEFAULT_CHE_OPERATOR_IMAGE, DEFAULT_DEV_WORKSPACE_CONTROLLER_IMAGE, DEFAULT_OLM_SUGGESTED_NAMESPACE, DOCS_LINK_INSTALL_RUNNING_CHE_LOCALLY } from '../../constants' import { CheTasks } from '../../tasks/che' @@ -64,12 +64,20 @@ export default class Deploy extends Command { env: 'CHE_SERVER_BOOT_TIMEOUT' }), k8spodwaittimeout: string({ - description: 'Waiting time for Pod Wait Timeout Kubernetes (in milliseconds)', - default: '300000' + description: 'Waiting time for Pod scheduled condition (in milliseconds)', + default: `${DEFAULT_K8S_POD_TIMEOUT}` + }), + k8spoddownloadimagetimeout: string({ + description: 'Waiting time for Pod downloading image (in milliseconds)', + default: `${DEFAULT_K8S_POD_TIMEOUT}` }), k8spodreadytimeout: string({ - description: 'Waiting time for Pod Ready Kubernetes (in milliseconds)', - default: '130000' + description: 'Waiting time for Pod Ready condition (in milliseconds)', + default: `${DEFAULT_K8S_POD_TIMEOUT}` + }), + k8spoderrorrechecktimeout: string({ + description: 'Waiting time for Pod rechecking error (in milliseconds)', + default: `${DEFAULT_K8S_POD_ERROR_RECHECK_TIMEOUT}` }), multiuser: flags.boolean({ char: 'm', diff --git a/src/tasks/kube.ts b/src/tasks/kube.ts index 61521c588..2b49af0e9 100644 --- a/src/tasks/kube.ts +++ b/src/tasks/kube.ts @@ -14,8 +14,9 @@ import * as Listr from 'listr' import { KubeHelper } from '../api/kube' export class KubeTasks { - kubeHelper: KubeHelper - constructor(flags?: any) { + private readonly interval = 500 + private readonly kubeHelper: KubeHelper + constructor(flags: any) { this.kubeHelper = new KubeHelper(flags) } @@ -24,21 +25,31 @@ export class KubeTasks { { title: 'Scheduling', task: async (_ctx: any, task: any) => { - // any way use 5 minutes (600*500=5*60*1000 ms) timeout - for (let i = 1; i <= 600; i++) { + const taskTitle = task.title + const iterations = this.kubeHelper.podWaitTimeout / this.interval + for (let i = 1; i <= iterations; i++) { + // check 'PodScheduled' condition const failedCondition = await this.getFailedPodCondition(namespace, selector, 'PodScheduled') if (failedCondition) { - task.title = `${task.title}...failed` - throw new Error(`Failed to schedule a pod, reason: ${failedCondition.reason}, message: ${failedCondition.message}`) + task.title = `${taskTitle}...failed, rechecking...` + + // for instance we need some time for pvc provisioning... + await cli.wait(this.kubeHelper.podErrorRecheckTimeout) + + const failedCondition = await this.getFailedPodCondition(namespace, selector, 'PodScheduled') + if (failedCondition) { + task.title = `${taskTitle}...failed` + throw new Error(`Failed to schedule a pod, reason: ${failedCondition.reason}, message: ${failedCondition.message}. Consider increasing error recheck timeout with --k8spoderrorrechecktimeout flag.`) + } } const allScheduled = await this.isPodConditionStatusPassed(namespace, selector, 'PodScheduled') if (allScheduled) { - task.title = `${task.title}...done.` + task.title = `${taskTitle}...done` return } - await cli.wait(500) + await cli.wait(this.interval) } throw new Error(`Failed to schedule a pod: ${await this.getTimeOutErrorMessage(namespace, selector)}`) @@ -47,22 +58,29 @@ export class KubeTasks { { title: 'Downloading images', task: async (_ctx: any, task: any) => { - // any way use 5 minutes (600*500=5*60*1000 ms) timeout - for (let i = 1; i <= 600; i++) { + const taskTitle = task.title + const iterations = this.kubeHelper.podDownloadImageTimeout / this.interval + for (let i = 1; i <= iterations; i++) { const failedState = await this.getFailedWaitingState(namespace, selector, 'Pending') if (failedState) { - task.title = `${task.title}...failed` - throw new Error(`Failed to download image, reason: ${failedState.reason}, message: ${failedState.message}`) + task.title = `${taskTitle}...failed, rechecking...` + await cli.wait(this.kubeHelper.podErrorRecheckTimeout) + + const failedState = await this.getFailedWaitingState(namespace, selector, 'Pending') + if (failedState) { + task.title = `${taskTitle}...failed` + throw new Error(`Failed to download image, reason: ${failedState.reason}, message: ${failedState.message}.`) + } } const pods = await this.kubeHelper.getPodListByLabel(namespace, selector) const allRunning = !pods.some(value => !value.status || value.status.phase !== 'Running') if (pods.length && allRunning) { - task.title = `${task.title}...done.` + task.title = `${taskTitle}...done` return } - await cli.wait(500) + await cli.wait(this.interval) } throw new Error(`Failed to download image: ${await this.getTimeOutErrorMessage(namespace, selector)}`) @@ -71,27 +89,38 @@ export class KubeTasks { { title: 'Starting', task: async (_ctx: any, task: any) => { - // any way use 5 minutes (600*500=5*60*1000 ms) timeout - for (let i = 1; i <= 600; i++) { + const taskTitle = task.title + const iterations = this.kubeHelper.podReadyTimeout / this.interval + for (let i = 1; i <= iterations; i++) { const failedState = await this.getFailedWaitingState(namespace, selector, 'Running') if (failedState) { - task.title = `${task.title}...failed` - throw new Error(`Failed to start a pod, reason: ${failedState.reason}, message: ${failedState.message}`) + task.title = `${taskTitle}...failed, rechecking...` + await cli.wait(this.kubeHelper.podErrorRecheckTimeout) + + const failedState = await this.getFailedWaitingState(namespace, selector, 'Running') + if (failedState) { + task.title = `${taskTitle}...failed` + throw new Error(`Failed to start a pod, reason: ${failedState.reason}, message: ${failedState.message}`) + } } const terminatedState = await this.kubeHelper.getPodLastTerminatedState(namespace, selector) if (terminatedState) { - task.title = `${task.title}...failed` - throw new Error(`Failed to start a pod, reason: ${terminatedState.reason}, message: ${terminatedState.message}`) + task.title = `${taskTitle}...failed` + let errorMsg = `Failed to start a pod, reason: ${terminatedState.reason}` + terminatedState.message && (errorMsg += `, message: ${terminatedState.message}`) + terminatedState.exitCode && (errorMsg += `, exitCode: ${terminatedState.exitCode}`) + terminatedState.signal && (errorMsg += `, signal: ${terminatedState.signal}`) + throw new Error(errorMsg) } const allStarted = await this.isPodConditionStatusPassed(namespace, selector, 'Ready') if (allStarted) { - task.title = `${task.title}...done.` + task.title = `${taskTitle}...done` return } - await cli.wait(500) + await cli.wait(this.interval) } throw new Error(`Failed to start a pod: ${await this.getTimeOutErrorMessage(namespace, selector)}`) @@ -102,14 +131,7 @@ export class KubeTasks { private async getFailedPodCondition(namespace: string, selector: string, conditionType: string): Promise { const status = await this.kubeHelper.getPodCondition(namespace, selector, conditionType) - const failedPod = status.find(s => s.status === 'False' && s.message && s.reason) - if (failedPod) { - // wait 10 sec, check again and only then fail - await cli.wait(10000) - - const condition = await this.kubeHelper.getPodCondition(namespace, selector, conditionType) - return condition.find(s => s.status === 'False' && s.message && s.reason) - } + return status.find(s => s.status === 'False' && s.message && s.reason) } private async isPodConditionStatusPassed(namespace: string, selector: string, conditionType: string): Promise { @@ -124,13 +146,7 @@ export class KubeTasks { private async getFailedWaitingState(namespace: string, selector: string, state: string): Promise { const waitingState = await this.kubeHelper.getPodWaitingState(namespace, selector, state) if (waitingState && waitingState.reason && waitingState.message) { - // wait 10 sec, check again and only then fail - await cli.wait(10000) - - const waitingState = await this.kubeHelper.getPodWaitingState(namespace, selector, state) - if (waitingState && waitingState.reason && waitingState.message) { - return waitingState - } + return waitingState } } @@ -140,7 +156,7 @@ export class KubeTasks { private async getTimeOutErrorMessage(namespace: string, selector: string): Promise { const pods = await this.kubeHelper.getPodListByLabel(namespace, selector) if (!pods.length) { - return 'Timeout: there no pods.' + throw new Error(`Timeout: there are no pods in the namespace: ${namespace}, selector: ${selector}. Check Eclipse Che logs for details. Consider increasing error recheck timeout with --k8spoderrorrechecktimeout flag.`) } let errorMessage = 'Timeout:' diff --git a/test/e2e/e2e.test.ts b/test/e2e/e2e.test.ts index 68b058e32..7395b33b3 100644 --- a/test/e2e/e2e.test.ts +++ b/test/e2e/e2e.test.ts @@ -36,28 +36,28 @@ const INSTALLER_HELM = 'helm' 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(`Unknow platform: ${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}`) } return command } -describe('Eclipse Che deploy test suite', () => { +describe('Eclipse Che deploy deployemnt', () => { describe(`server:deploy using ${INSTALLER} installer and self signed certificates`, () => { it(`server:deploy using ${INSTALLER} installer and self signed certificates`, async () => { const command = getDeployCommand() @@ -70,11 +70,14 @@ describe('Eclipse Che deploy test suite', () => { if (exitCode !== 0) { console.log(stderr) } + + // sleep after deploying + await execa('sleep 15s', { shell: true }) }) }) }) -describe('Che server authentication', () => { +describe('Eclipse Che server authentication', () => { it('Should login in to Che server with username and password', async () => { let cheApiEndpoint: string if (isKubernetesPlatformFamily(PLATFORM)) { @@ -90,7 +93,7 @@ describe('Che server authentication', () => { const { exitCode, stdout, stderr } = await execa(command, args, { timeout: 30000, shell: true }) expect(exitCode).equal(0) - expect(stdout).to.contain('Succesfully logged into') + expect(stdout).to.contain('Successfully logged into') console.log(stdout) if (exitCode !== 0) { @@ -129,49 +132,45 @@ describe('Export CA certificate', () => { }) describe('Workspace creation, list, start, inject, delete. Support stop and delete commands for Eclipse Che server', () => { - describe('Create Workspace', () => { - test - .stdout({ print: true }) - .stderr({ print: true }) - .command(['workspace:create', '--devfile=test/e2e/resources/devfile-example.yaml']) - .exit(0) - .it('Create a workspace and wait to be started') + describe('Create workspace', () => { + 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 }) + + console.log(`stdout: ${stdout}`) + console.log(`stderr: ${stderr}`) + expect(exitCode).equal(0) + }) }) describe('Start Workspace', () => { - it('Start a workspace using execa library', async () => { - const workspaceId = await helper.getWorkspaceId() - const command = `${binChectl} workspace:start ${workspaceId}` + it('Testing workspace:start command', async () => { + console.log('>>> Testing workspace:start command') - const { exitCode, stdout, stderr } = await execa(command, { timeout: 30000, shell: true }) + const workspaceId = await helper.getWorkspaceId() + const { exitCode, stdout, stderr, } = await execa(binChectl, ['workspace:start', workspaceId], { timeout: 30000, shell: true }) + console.log(`stdout: ${stdout}`) + console.log(`stderr: ${stderr}`) expect(exitCode).equal(0) - console.log(stdout) // Sleep time to wait to workspace to be running - await helper.SleepTests(200000) - if (exitCode !== 0) { - console.log(stderr) - } - + await helper.sleep(200000) const workspaceStatus = await helper.getWorkspaceStatus() - expect(workspaceStatus).to.contain('RUNNING') }) }) describe('Inject kubeconfig to workspaces', () => { - it('Inject kubeconfig to workspaces', async () => { - const command = `${binChectl} workspace:inject --kubeconfig` + it('Testing workspace:inject command', async () => { + console.log('>>> Testing workspace:inject command') - const { exitCode, stdout, stderr } = await execa(command, { timeout: 30000, shell: true }) + const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:inject', '--kubeconfig'], { timeout: 30000, shell: true }) + console.log(`stdout: ${stdout}`) + console.log(`stderr: ${stderr}`) expect(exitCode).equal(0) - console.log(stdout) - - if (exitCode !== 0) { - console.log(stderr) - } }) }) @@ -183,7 +182,7 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele .it('List workspaces') }) - describe('Server Status', () => { + describe('Get Eclipse Che server status', () => { test .stdout({ print: true }) .stderr({ print: true }) @@ -192,19 +191,16 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele }) describe('Stop Workspace', () => { - it('Stop a workspace using execa library', async () => { + it('Testing workspace:stop command', async () => { + console.log('>>> Testing workspace:stop command') + const workspaceId = await helper.getWorkspaceId() - const command = `${binChectl} workspace:stop ${workspaceId}` + const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:stop', workspaceId], { timeout: 30000, shell: true }) - const { exitCode, stdout, stderr } = await execa(command, { timeout: 30000, shell: true }) + console.log(`stdout: ${stdout}`) + console.log(`stderr: ${stderr}`) expect(exitCode).equal(0) - console.log(stdout) - - if (exitCode !== 0) { - console.log(stderr) - } - const workspaceStatus = await helper.getWorkspaceStatus() // The status could be STOPPING or STOPPED expect(workspaceStatus).to.contain('STOP') @@ -212,38 +208,33 @@ describe('Workspace creation, list, start, inject, delete. Support stop and dele }) describe('Delete Workspace', () => { - it('Delete a workspace using execa library', async () => { + it('Testing workspace:delete command', async () => { + console.log('>>> Testing workspace:delete command') + const workspaceId = await helper.getWorkspaceId() - const command = `${binChectl} workspace:delete ${workspaceId}` + const { exitCode, stdout, stderr } = await execa(binChectl, ['workspace:delete', workspaceId], { timeout: 30000, shell: true }) - const { exitCode, stdout, stderr } = await execa(command, { timeout: 30000, shell: true }) + console.log(`stdout: ${stdout}`) + console.log(`stderr: ${stderr}`) expect(exitCode).equal(0) - - console.log(stdout) - - if (exitCode !== 0) { - console.log(stderr) - } }) }) - describe('Stop Eclipse Che Server', () => { + describe('Stop Eclipse Che server', () => { it('server:stop command coverage', async () => { - const command = `${binChectl} server:stop --skip-kubernetes-health-check` - const { exitCode, stdout, stderr } = await execa(command, { shell: true }) + console.log('>>> Testing server:stop command') - expect(exitCode).equal(0) - console.log(stdout) + const { exitCode, stdout, stderr } = await execa(binChectl, ['server:stop'], { shell: true }) - if (exitCode !== 0) { - console.log(stderr) - } + console.log(`stdout: ${stdout}`) + console.log(`stderr: ${stderr}`) + expect(exitCode).equal(0) }) }) - describe('Delete Eclipse Che Server', () => { + describe('Delete Eclipse Che server', () => { test - .stdout() + .stdout({ print: true }) .stderr({ print: true }) .command(['server:delete', '--yes', '--delete-namespace']) .exit(0) diff --git a/test/e2e/util.ts b/test/e2e/util.ts index 5ed77b7b3..59e3626fd 100644 --- a/test/e2e/util.ts +++ b/test/e2e/util.ts @@ -107,7 +107,7 @@ export class E2eHelper { } // Utility to wait a time - SleepTests(ms: number): Promise { + sleep(ms: number): Promise { // tslint:disable-next-line no-string-based-set-timeout return new Promise(resolve => setTimeout(resolve, ms)) }