Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(terraform): run tests for multiple tf versions #4381

Merged
merged 24 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
766f751
test(terraform): run tests for multiple tf versions
stefreak Jan 31, 2023
39b4834
improvement: remove terraform lock files from git tree
stefreak Jan 31, 2023
2fafeaa
ci(circleci): re-enable plugins tests
stefreak May 23, 2023
f271e37
chore(terraform): fix hash for terraform 0.13.3 darwin amd64
Walther May 23, 2023
b5e923f
chore: terraform-plugin: 0.13 config updates for test projects
Walther May 23, 2023
08f0ef2
chore: terraform-plugin: test updates for 0.13 config
Walther May 23, 2023
fa8bea7
chore: terraform-plugin: fix provider tests
Walther May 26, 2023
5906145
chore: terraform-plugin: fix some action tests
Walther May 26, 2023
cf13e96
chore: terraform-plugin: fix 'sets the workspace before destroying' test
Walther May 26, 2023
ba05d09
chore: terraform-plugin: fix rest of the skipped tests
Walther May 26, 2023
19f7a62
chore: conftest plugin: temporarily disable tests, fix in another pr
Walther May 26, 2023
5829c64
chore: conftest plugin: temporarily disable tests, fix in another pr
Walther May 26, 2023
d0afe5f
chore: jib plugin: temporarily disable tests, fix in another pr
Walther May 29, 2023
f6a1bbc
chore: conftest test: fix import
Walther May 29, 2023
66e68ee
chore: jib plugin: temporarily disable tests, fix in another pr
Walther May 29, 2023
eda2521
chore: terraform-plugin common tests: init before workspace commands
Walther May 29, 2023
d997004
chore: terraform-plugin: lockfile for both test projects
Walther May 29, 2023
fee8a39
Merge branch 'main' into test-terraform-latest
Walther May 29, 2023
033c4ab
chore: update unzipper
Walther May 29, 2023
a2b8371
refactor: improve log message methods for testing purposes
Walther May 31, 2023
4334ce9
chore: return the separate getRootLogMessages and getLogMessages
Walther May 31, 2023
7b8aa63
chore: disable terraform-plugin tests
Walther Jun 1, 2023
ca03c12
chore: terraform-plugin: remove lockfile
Walther Jun 1, 2023
ddbdf80
chore: terraform-plugin tests: restore test-project-module
Walther Jun 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1026,10 +1026,9 @@ workflows:
requires: [build]
kindNodeImage: kindest/node:v1.26.3@sha256:61b92f38dff6ccc29969e7aa154d34e38b89443af1a2c14e6cfbd2df6419c66f

# TODO-0.13: fix and re-enable
# - test-plugins:
# requires: [build]
# kindNodeImage: kindest/node:v1.21.14@sha256:27ef72ea623ee879a25fe6f9982690a3e370c68286f4356bf643467c552a3888
- test-plugins:
requires: [build]
kindNodeImage: kindest/node:v1.21.14@sha256:27ef72ea623ee879a25fe6f9982690a3e370c68286f4356bf643467c552a3888

# This is only for edge release (Overrides version to edge-bonsai)
- build-dist:
Expand Down
6 changes: 3 additions & 3 deletions core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
"typescript-memoize": "^1.1.1",
"uniqid": "^5.4.0",
"unixify": "^1.0.0",
"unzipper": "^0.10.11",
"unzipper": "^0.10.14",
"username": "^5.1.0",
"uuid": "^9.0.0",
"which": "^3.0.0",
Expand Down Expand Up @@ -204,7 +204,7 @@
"@types/touch": "^3.1.2",
"@types/tough-cookie": "^4.0.2",
"@types/uniqid": "^5.3.2",
"@types/unzipper": "^0.10.5",
"@types/unzipper": "^0.10.6",
"@types/uuid": "^9.0.1",
"@types/which": "^1.3.2",
"@types/wrap-ansi": "^3.0.0",
Expand Down Expand Up @@ -266,4 +266,4 @@
]
},
"gitHead": "b0647221a4d2ff06952bae58000b104215aed922"
}
}
13 changes: 7 additions & 6 deletions core/src/logger/log-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,7 @@ export abstract class Log<C extends BaseContext = LogContext> implements LogConf
private getMsgWithDuration(params: CreateLogEntryParams) {
// If params.showDuration is set, it takes precedence over this.duration (since it's set at the call site for the
// log line in question).
const showDuration = params.showDuration !== undefined
? params.showDuration
: this.showDuration
const showDuration = params.showDuration !== undefined ? params.showDuration : this.showDuration
if (showDuration && params.msg) {
const msg = hasAnsi(params.msg) ? params.msg : chalk.green(params.msg)
return msg + " " + chalk.white(renderDuration(this.getDuration(1)))
Expand Down Expand Up @@ -401,7 +399,10 @@ export abstract class Log<C extends BaseContext = LogContext> implements LogConf
return this.entries.slice(-1)[0]
}

getChildLogEntries() {
/**
* Get the log entries for this particular log context.
*/
getLogEntries() {
return this.entries
}

Expand All @@ -413,13 +414,13 @@ export abstract class Log<C extends BaseContext = LogContext> implements LogConf
}

/**
* Dumps child entries as a string, optionally filtering the entries with `filter`.
* Dumps log entries for this particular log context as a string, optionally filtering the entries with `filter`.
* For example, to dump all the logs of level info or higher:
*
* log.toString((entry) => entry.level <= LogLevel.info)
*/
toString(filter?: (log: LogEntry) => boolean) {
return this.getChildLogEntries()
return this.getLogEntries()
.filter((entry) => (filter ? filter(entry) : true))
.map((entry) => entry.msg)
.join("\n")
Expand Down
15 changes: 13 additions & 2 deletions core/src/util/testing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,23 @@ export interface EventLogEntry<N extends EventName = any> {
}

/**
* Retrieves all the child log entries from the given LogEntry and returns a list of all the messages,
* Retrieves the log entries from the given log context and returns a list of all the messages,
* stripped of ANSI characters. Useful to check if a particular message was logged.
*/
export function getLogMessages(log: Log, filter?: (log: LogEntry) => boolean) {
return log
.getChildLogEntries()
.getLogEntries()
.filter((entry) => (filter ? filter(entry) : true))
.map((entry) => stripAnsi(entry.msg || ""))
}

/**
* Retrieves all the entries from the root log and returns a list of all the messages,
* stripped of ANSI characters. Useful to check if a particular message was logged.
*/
export function getRootLogMessages(log: Log, filter?: (log: LogEntry) => boolean) {
return log
.getAllLogEntries()
.filter((entry) => (filter ? filter(entry) : true))
.map((entry) => stripAnsi(entry.msg || ""))
}
Expand Down
10 changes: 3 additions & 7 deletions core/test/unit/src/commands/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ async function makeGarden({ tmpDir, plugin }: { tmpDir: tmp.DirectoryResult; plu
// Returns all entries that match the logMsg as string, sorted by service name.
function getLogOutput(garden: TestGarden, msg: string, extraFilter: (e: LogEntry) => boolean = () => true) {
const entries = garden.log
.getChildLogEntries()
.getLogEntries()
.filter(extraFilter)
.filter((e) => e.msg?.includes(msg))!
return entries.map((e) => formatForTerminal(e, garden.log.root).trim())
Expand Down Expand Up @@ -267,9 +267,7 @@ describe("LogsCommand", () => {

const out = getLogOutput(garden, logMsg)

expect(stripAnsi(out[0])).to.eql(
`test-service-a → ${timestamp.toISOString()} → Yes, this is log`
)
expect(stripAnsi(out[0])).to.eql(`test-service-a → ${timestamp.toISOString()} → Yes, this is log`)
})
it("should set the '--tail' and since flag", async () => {
const garden = await makeGarden({ tmpDir, plugin: makeTestPlugin() })
Expand Down Expand Up @@ -375,9 +373,7 @@ describe("LogsCommand", () => {
expect(stripAnsi(out[0])).to.eql(`a-short → [container=short] ${logMsg}`)
expect(stripAnsi(out[1])).to.eql(`b-not-short → [container=not-short] ${logMsg}`)
expect(stripAnsi(out[2])).to.eql(`a-short → [container=short] ${logMsg}`)
expect(stripAnsi(out[3])).to.eql(
`d-very-very-long → [container=very-very-long] ${logMsg}`
)
expect(stripAnsi(out[3])).to.eql(`d-very-very-long → [container=very-very-long] ${logMsg}`)
expect(stripAnsi(out[4])).to.eql(`a-short → [container=short] ${logMsg}`)
})
})
Expand Down
2 changes: 1 addition & 1 deletion plugins/conftest-container/test/conftest-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { defaultDotIgnoreFile } from "@garden-io/core/build/src/util/fs"
import { defaultDockerfileName } from "@garden-io/core/build/src/plugins/container/config"
import { DEFAULT_BUILD_TIMEOUT_SEC, GardenApiVersion } from "@garden-io/core/build/src/constants"

describe("conftest-container provider", () => {
describe.skip("conftest-container provider", () => {
const projectRoot = join(__dirname, "test-project")

const projectConfig: ProjectConfig = {
Expand Down
2 changes: 1 addition & 1 deletion plugins/conftest-kubernetes/test/conftest-kubernetes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { makeTestGarden } from "@garden-io/sdk/testing"

import { TestTask } from "@garden-io/core/build/src/tasks/test"

describe("conftest-kubernetes provider", () => {
describe.skip("conftest-kubernetes provider", () => {
const projectRoot = join(__dirname, "test-project")

it("should add a conftest module for each helm module, and add runtime dependencies as necessary", async () => {
Expand Down
4 changes: 2 additions & 2 deletions plugins/conftest/test/conftest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import { makeTestGarden } from "@garden-io/sdk/testing"

import { TestTask } from "@garden-io/core/build/src/tasks/test"
import { defaultDotIgnoreFile } from "@garden-io/core/build/src/util/fs"
import { GardenApiVersion } from "@garden-io/core/src/constants"
import { GardenApiVersion } from "@garden-io/core/build/src/constants"

describe("conftest provider", () => {
describe.skip("conftest provider", () => {
const projectRoot = join(__dirname, "test-project")

const projectConfig: ProjectConfig = {
Expand Down
4 changes: 2 additions & 2 deletions plugins/jib/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import { JibBuildAction } from "../util"
import { Resolved } from "@garden-io/core/build/src/actions/types"
import { ResolvedConfigGraph } from "@garden-io/core/build/src/graph/config-graph"
import { createActionLog } from "@garden-io/core/build/src/logger/log-entry"
import { GardenApiVersion } from "@garden-io/core/src/constants"
import { GardenApiVersion } from "@garden-io/core/build/src/constants"

describe("jib-container", function () {
describe.skip("jib-container", function () {
// eslint-disable-next-line no-invalid-this
this.timeout(180 * 1000) // initial jib build can take a long time

Expand Down
2 changes: 1 addition & 1 deletion plugins/jib/test/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { expectError } from "@garden-io/sdk/testing"
import { expect } from "chai"
import { detectProjectType, getBuildFlags } from "../util"

describe("util", () => {
describe.skip("util", () => {
Walther marked this conversation as resolved.
Show resolved Hide resolved
describe("detectProjectType", () => {
it("returns gradle if module files include a gradle config", () => {
const module: any = {
Expand Down
2 changes: 1 addition & 1 deletion plugins/terraform/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const terraformCliSpecs: { [version: string]: PluginToolSpec } = {
platform: "darwin",
architecture: "amd64",
url: "https://releases.hashicorp.com/terraform/0.13.3/terraform_0.13.3_darwin_amd64.zip",
sha256: "ccbfd3af8732a47b6bd32c419e1a52e41eb8a39ff7437afffbef438b5c0f92c3",
sha256: "4a613dc18ff8cfac525a59cc0e78216fa0a9ecd63e6ac45603561ceb72f6d772",
extract: {
format: "zip",
targetPath: "terraform",
Expand Down
1 change: 1 addition & 0 deletions plugins/terraform/test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test-project/**/*.lock.hcl
178 changes: 92 additions & 86 deletions plugins/terraform/test/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,109 +13,115 @@ import { makeTestGarden, TestGarden } from "@garden-io/sdk/testing"
import { Log, PluginContext } from "@garden-io/sdk/types"
import { getWorkspaces, setWorkspace } from "../common"
import { expect } from "chai"
import { terraform } from "../cli"

describe("Terraform common", () => {
const testRoot = join(__dirname, "test-project")

let root: string
let terraformDirPath: string
let stateDirPath: string
let testFilePath: string

let garden: TestGarden
let log: Log
let ctx: PluginContext
let provider: TerraformProvider

async function reset() {
if (terraformDirPath && (await pathExists(terraformDirPath))) {
await remove(terraformDirPath)
import { defaultTerraformVersion, terraform } from "../cli"

for (const terraformVersion of ["0.13.3", defaultTerraformVersion]) {
describe(`Terraform common with version ${terraformVersion}`, () => {
const testRoot = join(__dirname, "test-project")

let root: string
let terraformDirPath: string
let stateDirPath: string
let testFilePath: string

let garden: TestGarden
let log: Log
let ctx: PluginContext
let provider: TerraformProvider

async function reset() {
if (terraformDirPath && (await pathExists(terraformDirPath))) {
await remove(terraformDirPath)
}
if (testFilePath && (await pathExists(testFilePath))) {
await remove(testFilePath)
}
if (stateDirPath && (await pathExists(stateDirPath))) {
await remove(stateDirPath)
}
}
if (testFilePath && (await pathExists(testFilePath))) {
await remove(testFilePath)
}
if (stateDirPath && (await pathExists(stateDirPath))) {
await remove(stateDirPath)
}
}

before(async () => {
garden = await makeTestGarden(testRoot, {
plugins: [gardenPlugin()],
environmentString: "prod",
forceRefresh: true,
before(async () => {
garden = await makeTestGarden(testRoot, {
plugins: [gardenPlugin()],
environmentString: "prod",
forceRefresh: true,
variableOverrides: { "tf-version": terraformVersion },
})
log = garden.log
provider = (await garden.resolveProvider(log, "terraform")) as TerraformProvider
ctx = await garden.getPluginContext({ provider, events: undefined, templateContext: undefined })
root = join(garden.projectRoot, "tf")
terraformDirPath = join(root, ".terraform")
stateDirPath = join(root, "terraform.tfstate.d")
testFilePath = join(root, "test.log")
})
log = garden.log
provider = (await garden.resolveProvider(log, "terraform")) as TerraformProvider
ctx = await garden.getPluginContext({ provider, events: undefined, templateContext: undefined })
root = join(garden.projectRoot, "tf")
terraformDirPath = join(root, ".terraform")
stateDirPath = join(root, "terraform.tfstate.d")
testFilePath = join(root, "test.log")
})

beforeEach(async () => {
await reset()
})

after(async () => {
await reset()
})

describe("getWorkspaces", () => {
it("returns just the default workspace if none other exists", async () => {
const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("default")
expect(workspaces).to.eql(["default"])
beforeEach(async () => {
await reset()
})

it("returns all workspaces and which is selected", async () => {
await terraform(ctx, provider).exec({ args: ["workspace", "new", "foo"], cwd: root, log })
await terraform(ctx, provider).exec({ args: ["workspace", "new", "bar"], cwd: root, log })
after(async () => {
await reset()
})

const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("bar")
expect(workspaces).to.eql(["default", "bar", "foo"])
describe("getWorkspaces", () => {
it("returns just the default workspace if none other exists", async () => {
const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("default")
expect(workspaces).to.eql(["default"])
})

it("returns all workspaces and which is selected", async () => {
await terraform(ctx, provider).exec({ args: ["init"], cwd: root, log })
await terraform(ctx, provider).exec({ args: ["workspace", "new", "foo"], cwd: root, log })
await terraform(ctx, provider).exec({ args: ["workspace", "new", "bar"], cwd: root, log })

const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("bar")
expect(workspaces).to.eql(["default", "bar", "foo"])
})
})
})

describe("setWorkspace", () => {
it("does nothing if no workspace is set", async () => {
await terraform(ctx, provider).exec({ args: ["workspace", "new", "foo"], cwd: root, log })
describe("setWorkspace", () => {
it("does nothing if no workspace is set", async () => {
await terraform(ctx, provider).exec({ args: ["init"], cwd: root, log })
await terraform(ctx, provider).exec({ args: ["workspace", "new", "foo"], cwd: root, log })

await setWorkspace({ ctx, provider, log, root, workspace: null })
await setWorkspace({ ctx, provider, log, root, workspace: null })

const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("foo")
expect(workspaces).to.eql(["default", "foo"])
})
const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("foo")
expect(workspaces).to.eql(["default", "foo"])
})

it("does nothing if already on requested workspace", async () => {
await setWorkspace({ ctx, provider, log, root, workspace: "default" })
it("does nothing if already on requested workspace", async () => {
await setWorkspace({ ctx, provider, log, root, workspace: "default" })

const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("default")
expect(workspaces).to.eql(["default"])
})
const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("default")
expect(workspaces).to.eql(["default"])
})

it("selects the given workspace if it already exists", async () => {
await terraform(ctx, provider).exec({ args: ["workspace", "new", "foo"], cwd: root, log })
await terraform(ctx, provider).exec({ args: ["workspace", "select", "default"], cwd: root, log })
it("selects the given workspace if it already exists", async () => {
await terraform(ctx, provider).exec({ args: ["init"], cwd: root, log })
await terraform(ctx, provider).exec({ args: ["workspace", "new", "foo"], cwd: root, log })
await terraform(ctx, provider).exec({ args: ["workspace", "select", "default"], cwd: root, log })

await setWorkspace({ ctx, provider, log, root, workspace: "foo" })
await setWorkspace({ ctx, provider, log, root, workspace: "foo" })

const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("foo")
expect(workspaces).to.eql(["default", "foo"])
})
const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("foo")
expect(workspaces).to.eql(["default", "foo"])
})

it("creates a new workspace if it doesn't already exist", async () => {
await setWorkspace({ ctx, provider, log, root, workspace: "foo" })
it("creates a new workspace if it doesn't already exist", async () => {
await setWorkspace({ ctx, provider, log, root, workspace: "foo" })

const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("foo")
expect(workspaces).to.eql(["default", "foo"])
const { workspaces, selected } = await getWorkspaces({ ctx, provider, log, root })
expect(selected).to.equal("foo")
expect(workspaces).to.eql(["default", "foo"])
})
})
})
})
}
Loading