Skip to content

Commit

Permalink
fix(cli): return error in garden run task if task fails (#1669)
Browse files Browse the repository at this point in the history
* fix: return an error if the test fails

* fix: create common helper

Co-authored-by: Mitchell Friedman <[email protected]>
Co-authored-by: Jon Edvald <[email protected]>
  • Loading branch information
3 people authored Mar 10, 2020
1 parent b293fe2 commit f5cf81c
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 34 deletions.
34 changes: 25 additions & 9 deletions garden-service/src/commands/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@
*/

import Joi = require("@hapi/joi")
import chalk from "chalk"
import dedent = require("dedent")
import inquirer = require("inquirer")
import stripAnsi from "strip-ansi"
import { GardenError, RuntimeError, InternalError, ParameterError } from "../exceptions"
import { TaskResults } from "../task-graph"
import { LoggerType } from "../logger/logger"
import { ProcessResults } from "../process"

import { GlobalOptions } from "../cli/cli"
import { joi } from "../config/common"
import { GardenError, InternalError, ParameterError, RuntimeError } from "../exceptions"
import { Garden } from "../garden"
import { LogEntry } from "../logger/log-entry"
import { LoggerType } from "../logger/logger"
import { printFooter } from "../logger/util"
import { GlobalOptions } from "../cli/cli"
import { joi } from "../config/common"
import inquirer = require("inquirer")
import dedent = require("dedent")
import chalk from "chalk"
import { ProcessResults } from "../process"
import { TaskResults } from "../task-graph"
import { RunResult } from "../types/plugin/base"

export interface ParameterConstructor<T> {
help: string
Expand Down Expand Up @@ -370,6 +372,20 @@ export abstract class Command<T extends Parameters = {}, U extends Parameters =
}
}

export async function handleActionResult(action: string, result: RunResult): Promise<CommandResult<RunResult>> {
if (!result.success) {
return {
errors: [
new RuntimeError(`${action} failed!`, {
result,
}),
],
}
}

return { result }
}

export async function handleTaskResults(
log: LogEntry,
taskType: string,
Expand Down
19 changes: 14 additions & 5 deletions garden-service/src/commands/run/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@
*/

import chalk from "chalk"
import { RunResult } from "../../types/plugin/base"
import { BooleanParameter, Command, CommandParams, StringParameter, CommandResult, StringsParameter } from "../base"
import { printRuntimeContext } from "./run"

import { printHeader } from "../../logger/util"
import { prepareRuntimeContext } from "../../runtime-context"
import { BuildTask } from "../../tasks/build"
import { RunResult } from "../../types/plugin/base"
import { dedent, deline } from "../../util/string"
import { prepareRuntimeContext } from "../../runtime-context"
import {
BooleanParameter,
Command,
CommandParams,
CommandResult,
handleActionResult,
StringParameter,
StringsParameter,
} from "../base"
import { printRuntimeContext } from "./run"

const runArgs = {
module: new StringParameter({
Expand Down Expand Up @@ -118,6 +127,6 @@ export class RunModuleCommand extends Command<Args, Opts> {
timeout: opts.interactive ? 999999 : undefined,
})

return { result }
return handleActionResult(`Module ${module.name}`, result)
}
}
15 changes: 8 additions & 7 deletions garden-service/src/commands/run/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
*/

import chalk from "chalk"
import { RunResult } from "../../types/plugin/base"
import { BooleanParameter, Command, CommandParams, CommandResult, StringParameter } from "../base"
import { printRuntimeContext } from "./run"
import dedent = require("dedent")

import { CommandError } from "../../exceptions"
import { printHeader } from "../../logger/util"
import { DeployTask } from "../../tasks/deploy"
import { getServiceStatuses, getRunTaskResults } from "../../tasks/base"
import { prepareRuntimeContext } from "../../runtime-context"
import { getRunTaskResults, getServiceStatuses } from "../../tasks/base"
import { DeployTask } from "../../tasks/deploy"
import { RunResult } from "../../types/plugin/base"
import { deline } from "../../util/string"
import { CommandError } from "../../exceptions"
import { BooleanParameter, Command, CommandParams, CommandResult, handleActionResult, StringParameter } from "../base"
import { printRuntimeContext } from "./run"

const runArgs = {
service: new StringParameter({
Expand Down Expand Up @@ -110,6 +111,6 @@ export class RunServiceCommand extends Command<Args, Opts> {
timeout: 999999,
})

return { result }
return handleActionResult(`Service ${service.name} in module ${module.name}`, result)
}
}
19 changes: 10 additions & 9 deletions garden-service/src/commands/run/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
*/

import chalk from "chalk"
import { ParameterError, CommandError } from "../../exceptions"
import { RunResult } from "../../types/plugin/base"
import { findByName, getNames } from "../../util/util"
import { BooleanParameter, Command, CommandParams, CommandResult, StringParameter } from "../base"
import { printRuntimeContext } from "./run"
import { prepareRuntimeContext } from "../../runtime-context"

import { CommandError, ParameterError } from "../../exceptions"
import { printHeader } from "../../logger/util"
import { TestTask } from "../../tasks/test"
import { prepareRuntimeContext } from "../../runtime-context"
import { getRunTaskResults, getServiceStatuses } from "../../tasks/base"
import { dedent, deline } from "../../util/string"
import { TestTask } from "../../tasks/test"
import { RunResult } from "../../types/plugin/base"
import { testFromConfig } from "../../types/test"
import { dedent, deline } from "../../util/string"
import { findByName, getNames } from "../../util/util"
import { BooleanParameter, Command, CommandParams, CommandResult, handleActionResult, StringParameter } from "../base"
import { printRuntimeContext } from "./run"

const runArgs = {
module: new StringParameter({
Expand Down Expand Up @@ -137,6 +138,6 @@ export class RunTestCommand extends Command<Args, Opts> {
testVersion: testTask.version,
})

return { result }
return handleActionResult(`Test ${test.name} in module ${module.name}`, result)
}
}
7 changes: 7 additions & 0 deletions garden-service/test/data/test-project-fails/garden.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: Project
name: test-project-failing-test
environments:
- name: local
providers:
- name: test-plugin
environments: [local]
9 changes: 9 additions & 0 deletions garden-service/test/data/test-project-fails/module/garden.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
kind: Module
name: module
type: test
tests:
- name: unit
command: [exit, "10"]
tasks:
- name: task
command: [exit, "10"]
5 changes: 5 additions & 0 deletions garden-service/test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ async function runModule(params: RunModuleParams): Promise<RunResult> {
}

export const projectRootA = getDataDir("test-project-a")
export const projectTestFailsRoot = getDataDir("test-project-fails")

const testModuleTestSchema = () => containerTestSchema().keys({ command: joi.array().items(joi.string()) })

Expand Down Expand Up @@ -351,6 +352,10 @@ export const makeTestGardenA = async (extraPlugins: RegisterPluginParam[] = [])
return makeTestGarden(projectRootA, { plugins: extraPlugins })
}

export const makeTestGardenTasksFails = async (extraPlugins: RegisterPluginParam[] = []) => {
return makeTestGarden(projectTestFailsRoot, { plugins: extraPlugins })
}

export function stubAction<T extends keyof PluginActionHandlers>(
garden: Garden,
pluginName: string,
Expand Down
7 changes: 4 additions & 3 deletions garden-service/test/unit/src/commands/run/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { expect } from "chai"
import td from "testdouble"

import { RunModuleCommand } from "../../../../../src/commands/run/module"
import { Garden } from "../../../../../src/garden"
import { RunResult } from "../../../../../src/types/plugin/base"
import { makeTestGardenA, testModuleVersion, testNow, withDefaultGlobalOpts } from "../../../../helpers"
import { expect } from "chai"
import { Garden } from "../../../../../src/garden"
import td from "testdouble"

describe("RunModuleCommand", () => {
// TODO: test optional flags
Expand Down
18 changes: 17 additions & 1 deletion garden-service/test/unit/src/commands/run/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import stripAnsi from "strip-ansi"
import { expect } from "chai"
import { omit } from "lodash"
import { makeTestGardenA, withDefaultGlobalOpts, expectError } from "../../../../helpers"
import { makeTestGardenA, makeTestGardenTasksFails, withDefaultGlobalOpts, expectError } from "../../../../helpers"
import { RunTestCommand } from "../../../../../src/commands/run/test"

describe("RunTestCommand", () => {
Expand Down Expand Up @@ -39,6 +39,22 @@ describe("RunTestCommand", () => {
expect(omit(result, ["completedAt", "startedAt", "version"])).to.eql(expected)
})

it("should return an error if the test fails", async () => {
const garden = await makeTestGardenTasksFails()
const log = garden.log

const result = await cmd.action({
garden,
log,
headerLog: log,
footerLog: log,
args: { test: "unit", module: "module" },
opts: withDefaultGlobalOpts({ "force": false, "force-build": false, "interactive": true }),
})

expect(result.errors).to.have.lengthOf(1)
})

it("should throw if the test is disabled", async () => {
const garden = await makeTestGardenA()
const log = garden.log
Expand Down

0 comments on commit f5cf81c

Please sign in to comment.