Skip to content

Commit

Permalink
fix(core): fix to dependency logic in dev command
Browse files Browse the repository at this point in the history
Before this fix, if a service was deployed with hot reloading via the
dev command, and a test spec had a runtime dependency on that service,
the service would initially be deployed without hot reloading enabled.

This would result in subsequent hot reloads for that service failing.

Also added a test case checking for this behavior.
  • Loading branch information
thsig committed Feb 21, 2020
1 parent fc5523a commit ef20e92
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 44 deletions.
112 changes: 69 additions & 43 deletions garden-service/src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,49 +133,14 @@ export class DevCommand extends Command<DevCommandArgs, DevCommandOpts> {
}
}

const initialTasks = flatten(
await Bluebird.map(modules, async (module) => {
// Build the module (in case there are no tests, tasks or services here that need to be run)
const buildTasks = await BuildTask.factory({
garden,
log,
module,
force: false,
})

// Run all tests in module
const testTasks = skipTests
? []
: await getTestTasks({
garden,
graph,
log,
module,
force: false,
forceBuild: false,
})

// Deploy all enabled services in module
const services = await graph.getServices({ names: module.serviceNames, includeDisabled: true })
const deployTasks = services
.filter((s) => !s.disabled)
.map(
(service) =>
new DeployTask({
garden,
log,
graph,
service,
force: false,
forceBuild: false,
fromWatch: false,
hotReloadServiceNames,
})
)

return [...buildTasks, ...testTasks, ...deployTasks]
})
)
const initialTasks = await getDevCommandInitialTasks({
garden,
log,
graph,
modules,
hotReloadServiceNames,
skipTests,
})

const results = await processModules({
garden,
Expand All @@ -202,6 +167,67 @@ export class DevCommand extends Command<DevCommandArgs, DevCommandOpts> {
}
}

export async function getDevCommandInitialTasks({
garden,
log,
graph,
modules,
hotReloadServiceNames,
skipTests,
}: {
garden: Garden
log: LogEntry
graph: ConfigGraph
modules: Module[]
hotReloadServiceNames: string[]
skipTests: boolean
}) {
return flatten(
await Bluebird.map(modules, async (module) => {
// Build the module (in case there are no tests, tasks or services here that need to be run)
const buildTasks = await BuildTask.factory({
garden,
log,
module,
force: false,
})

// Run all tests in module
const testTasks = skipTests
? []
: await getTestTasks({
garden,
graph,
log,
module,
hotReloadServiceNames,
force: false,
forceBuild: false,
})

// Deploy all enabled services in module
const services = await graph.getServices({ names: module.serviceNames, includeDisabled: true })
const deployTasks = services
.filter((s) => !s.disabled)
.map(
(service) =>
new DeployTask({
garden,
log,
graph,
service,
force: false,
forceBuild: false,
fromWatch: false,
hotReloadServiceNames,
})
)

return [...buildTasks, ...testTasks, ...deployTasks]
})
)
}

export async function getDevCommandWatchTasks({
garden,
log,
Expand Down
2 changes: 2 additions & 0 deletions garden-service/test/data/test-project-a/module-a/garden.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ tests:
command: [echo, OK]
- name: integration
command: [echo, OK]
dependencies:
- service-a
tasks:
- name: task-a
command: [echo, OK]
43 changes: 42 additions & 1 deletion garden-service/test/unit/src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import Bluebird from "bluebird"
import { flattenDeep } from "lodash"
import pEvent from "p-event"
import { expect } from "chai"
import { DevCommand, DevCommandArgs, DevCommandOpts, getDevCommandWatchTasks } from "../../../../src/commands/dev"
import {
DevCommand,
DevCommandArgs,
DevCommandOpts,
getDevCommandWatchTasks,
getDevCommandInitialTasks,
} from "../../../../src/commands/dev"
import { makeTestGardenA, withDefaultGlobalOpts, TestGarden } from "../../../helpers"
import { ParameterValues } from "../../../../src/commands/base"
import { GlobalOptions } from "../../../../src/cli/cli"
import { BaseTask } from "../../../../src/tasks/base"

describe("DevCommand", () => {
const command = new DevCommand()
Expand Down Expand Up @@ -106,6 +115,38 @@ describe("DevCommand", () => {
return promise
})

it("should initially deploy services with hot reloading when requested", async () => {
const garden = await makeTestGardenA()
const log = garden.log
const graph = await garden.getConfigGraph(log)
const modules = await graph.getModules()

const initialTasks = await getDevCommandInitialTasks({
garden,
log,
graph,
modules,
// Note: service-a is a runtime dependency of module-a's integration test spec, so in this test case
// we're implicitly verifying that tests with runtime dependencies on services being deployed with
// hot reloading don't request non-hot-reload-enabled deploys for those same services.
hotReloadServiceNames: ["service-a"],
skipTests: false,
})

const withDeps = async (task: BaseTask) => {
const deps = await task.getDependencies()
return [task, await Bluebird.map(deps, async (dep) => await withDeps(dep))]
}

const initialTasksWithDeps: BaseTask[] = flattenDeep(await Bluebird.map(initialTasks, withDeps))
const deployTasksForServiceA = initialTasksWithDeps.filter((t) => t.getKey() === "deploy.service-a")

expect(deployTasksForServiceA.length).to.be.greaterThan(0)
for (const deployTask of deployTasksForServiceA) {
expect(deployTask!["hotReloadServiceNames"]).to.eql(["service-a"])
}
})

it("should skip disabled services", async () => {
const garden = await makeTestGardenA()

Expand Down
2 changes: 2 additions & 0 deletions garden-service/test/unit/src/commands/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ describe("TestCommand", () => {
expect(Object.keys(taskResultOutputs(result!)).sort()).to.eql([
"build.module-a",
"build.module-b",
"deploy.service-a",
"get-service-status.service-a",
"stage-build.module-a",
"stage-build.module-b",
"test.module-a.integration",
Expand Down
1 change: 1 addition & 0 deletions garden-service/test/unit/src/config/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ describe("loadConfig", () => {
{
name: "integration",
command: ["echo", "OK"],
dependencies: ["service-a"],
},
],
},
Expand Down

0 comments on commit ef20e92

Please sign in to comment.