Skip to content

Commit

Permalink
feat(commands): skip-dependants opt for test cmd
Browse files Browse the repository at this point in the history
The current behavior of the test command when called with a list of
module names is to run all tests in those modules, and all tests in
modules with dependencies on those modules.

This is not the desired behavior in all cases, so here we add a
`--skip-dependants` option to the test command. When used, only tests in
the requested modules will be run.
  • Loading branch information
thsig committed Apr 26, 2021
1 parent de678d8 commit 6a7d6c5
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 12 deletions.
36 changes: 25 additions & 11 deletions core/src/commands/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,23 @@ import { getTestTasks } from "../tasks/test"
import { printHeader } from "../logger/util"
import { startServer } from "../server/server"
import { StringsParameter, BooleanParameter } from "../cli/params"
import { deline } from "../util/string"

export const testArgs = {
modules: new StringsParameter({
help:
"The name(s) of the module(s) to test (skip to test all modules). " +
"Use comma as a separator to specify multiple modules.",
help: deline`
The name(s) of the module(s) to test (skip to test all modules).
Use comma as a separator to specify multiple modules.
`,
}),
}

export const testOpts = {
"name": new StringsParameter({
help:
"Only run tests with the specfied name (e.g. unit or integ). " +
"Accepts glob patterns (e.g. integ* would run both 'integ' and 'integration')",
help: deline`
Only run tests with the specfied name (e.g. unit or integ).
Accepts glob patterns (e.g. integ* would run both 'integ' and 'integration').
`,
alias: "n",
}),
"force": new BooleanParameter({
Expand All @@ -51,6 +54,12 @@ export const testOpts = {
alias: "w",
cliOnly: true,
}),
"skip-dependants": new BooleanParameter({
help: deline`
When using the modules argument, only run tests for those modules (and skip tests in other modules with
dependencies on those modules).
`,
}),
}

type Args = typeof testArgs
Expand Down Expand Up @@ -115,11 +124,16 @@ export class TestCommand extends Command<Args, Opts> {
}

const graph = await garden.getConfigGraph(log)

const modules: GardenModule[] = args.modules
? graph.withDependantModules(graph.getModules({ names: args.modules }))
: // All modules are included in this case, so there's no need to compute dependants.
graph.getModules()
const skipDependants = opts["skip-dependants"]
let modules: GardenModule[]

if (args.modules) {
modules = skipDependants
? graph.getModules({ names: args.modules })
: graph.withDependantModules(graph.getModules({ names: args.modules }))
} else {
modules = graph.getModules()
}

const filterNames = opts.name || []
const force = opts.force
Expand Down
90 changes: 90 additions & 0 deletions core/test/unit/src/commands/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { expect } from "chai"
import { TestCommand } from "../../../../src/commands/test"
import isSubset = require("is-subset")
import { makeTestGardenA, taskResultOutputs, withDefaultGlobalOpts } from "../../../helpers"
import { ModuleConfig } from "../../../../src/config/module"

describe("TestCommand", () => {
const command = new TestCommand()
Expand All @@ -30,6 +31,7 @@ describe("TestCommand", () => {
"force": true,
"force-build": true,
"watch": false,
"skip-dependants": false,
}),
})

Expand Down Expand Up @@ -160,6 +162,7 @@ describe("TestCommand", () => {
"force": true,
"force-build": true,
"watch": false,
"skip-dependants": false,
}),
})

Expand Down Expand Up @@ -192,6 +195,7 @@ describe("TestCommand", () => {
"force": true,
"force-build": true,
"watch": false,
"skip-dependants": false,
}),
})

Expand Down Expand Up @@ -248,6 +252,7 @@ describe("TestCommand", () => {
"force": true,
"force-build": false,
"watch": false,
"skip-dependants": false,
}),
})

Expand Down Expand Up @@ -284,6 +289,7 @@ describe("TestCommand", () => {
"force": true,
"force-build": false,
"watch": false,
"skip-dependants": false,
}),
})

Expand All @@ -303,4 +309,88 @@ describe("TestCommand", () => {
"test.module-b.unit",
])
})

it("should skip dependant modules if --skip-dependants is passed", async () => {
const garden = await makeTestGardenA()
const log = garden.log

const moduleConfigs: ModuleConfig[] = [
{
apiVersion: "garden.io/v0",
kind: "Module",
name: "module-a",
include: [],
build: { dependencies: [] },
path: garden.projectRoot,
serviceConfigs: [],
disabled: false,
allowPublish: false,
spec: {
services: [{ name: "service-a" }],
tests: [
{ name: "unit", command: ["echo", "OK"] },
{ name: "integration", command: ["echo", "OK"], dependencies: ["service-a"] },
],
tasks: [],
build: { command: ["echo", "A"], dependencies: [] },
},
testConfigs: [],
type: "test",
taskConfigs: [],
},
{
apiVersion: "garden.io/v0",
kind: "Module",
name: "module-b",
include: [],
build: { dependencies: [] },
path: garden.projectRoot,
serviceConfigs: [],
disabled: false,
allowPublish: false,
spec: {
services: [{ name: "service-b" }],
tests: [
{ name: "unit", command: ["echo", "OK"] },
{ name: "integration", command: ["echo", "OK"], dependencies: ["service-a"] }, // <--- depends on service-a
],
tasks: [],
build: { command: ["echo", "A"], dependencies: [] },
},
testConfigs: [],
type: "test",
taskConfigs: [],
},
]

garden.setModuleConfigs(moduleConfigs)

const { result, errors } = await command.action({
garden,
log,
headerLog: log,
footerLog: log,
args: { modules: ["module-a"] },
opts: withDefaultGlobalOpts({
"name": undefined,
"force": true,
"force-build": false,
"watch": false,
"skip-dependants": true, // <----
}),
})

if (errors) {
throw errors[0]
}

expect(Object.keys(taskResultOutputs(result!)).sort()).to.eql([
"build.module-a",
"deploy.service-a",
"get-service-status.service-a",
"stage-build.module-a",
"test.module-a.integration",
"test.module-a.unit",
])
})
})
3 changes: 2 additions & 1 deletion docs/reference/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -3262,10 +3262,11 @@ Examples:

| Argument | Alias | Type | Description |
| -------- | ----- | ---- | ----------- |
| `--name` | `-n` | array:string | Only run tests with the specfied name (e.g. unit or integ). Accepts glob patterns (e.g. integ* would run both &#x27;integ&#x27; and &#x27;integration&#x27;)
| `--name` | `-n` | array:string | Only run tests with the specfied name (e.g. unit or integ). Accepts glob patterns (e.g. integ* would run both &#x27;integ&#x27; and &#x27;integration&#x27;).
| `--force` | `-f` | boolean | Force re-test of module(s).
| `--force-build` | | boolean | Force rebuild of module(s).
| `--watch` | `-w` | boolean | Watch for changes in module(s) and auto-test.
| `--skip-dependants` | | boolean | When using the modules argument, only run tests for those modules (and skip tests in other modules with dependencies on those modules).

#### Outputs

Expand Down

0 comments on commit 6a7d6c5

Please sign in to comment.