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

Add test framework #48

Merged
merged 7 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 31 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: ci

on:
push:
branches:
- main

pull_request:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- run: bun test
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- run: bun fmt:ci
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.terraform*
.terraform*
node_modules
*.tfstate
*.tfstate.lock.info
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"files.exclude": {
"**/terraform.tfstate": true,
"**/.terraform": true
}
}
34 changes: 5 additions & 29 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,13 @@ To create a new module, clone this repository and run:
./new.sh MOUDLE_NAME
```

Test a module by running an instance of Coder on your local machine:

```shell
coder server --in-memory
```

This will create a new module in the modules directory with the given name and scaffolding.
Edit the files, adding your module's implementation, documentation and screenshots.

## Testing a Module

Create a template and edit it to include your development module:
A suite of test-helpers exists to run `terraform apply` on modules with variables, and test script output against containers.

> [!NOTE]
> The Docker starter template is recommended for quick-iteration!
Reference existing `*.test.ts` files for implementation.

```hcl
module "MOUDLE_NAME" {
source = "/home/user/coder/modules/MOUDLE_NAME"
}
```sh
# Run tests for a specific module!
$ bun test -t '<module>'
```

You can also test your module by specifying the source as a git repository:

```hcl
module "MOUDLE_NAME" {
source = "git::https://github.com/<USERNAME>/<REPO>.git//<FOLDER>?ref=<BRANCH>"
}
```

Build a workspace and your module will be consumed! 🥳

Open a pull-request with your module, a member of the Coder team will
manually test it, and after-merge it will appear on the Registry.
25 changes: 25 additions & 0 deletions aws-region/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { describe, expect, it } from "bun:test";
import {
executeScriptInContainer,
runTerraformApply,
runTerraformInit,
testRequiredVariables,
} from "../test";

describe("aws-region", async () => {
await runTerraformInit(import.meta.dir);

testRequiredVariables(import.meta.dir, {});

it("default output", async () => {
const state = await runTerraformApply(import.meta.dir, {});
expect(state.outputs.value.value).toBe("us-east-1");
});

it("customized default", async () => {
const state = await runTerraformApply(import.meta.dir, {
default: "us-west-2",
});
expect(state.outputs.value.value).toBe("us-west-2");
});
});
202 changes: 101 additions & 101 deletions aws-region/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,45 @@ terraform {
}

variable "display_name" {
default = "AWS Region"
description = "The display name of the parameter."
type = string
default = "AWS Region"
description = "The display name of the parameter."
type = string
}

variable "description" {
default = "The region to deploy workspace infrastructure."
description = "The description of the parameter."
type = string
default = "The region to deploy workspace infrastructure."
description = "The description of the parameter."
type = string
}

variable "default" {
default = "us-east-1"
description = "The default region to use if no region is specified."
type = string
default = "us-east-1"
description = "The default region to use if no region is specified."
type = string
}

variable "mutable" {
default = false
description = "Whether the parameter can be changed after creation."
type = bool
default = false
description = "Whether the parameter can be changed after creation."
type = bool
}

variable "custom_names" {
default = {}
description = "A map of custom display names for region IDs."
type = map(string)
default = {}
description = "A map of custom display names for region IDs."
type = map(string)
}

variable "custom_icons" {
default = {}
description = "A map of custom icons for region IDs."
type = map(string)
default = {}
description = "A map of custom icons for region IDs."
type = map(string)
}

variable "exclude" {
default = []
description = "A list of region IDs to exclude."
type = list(string)
default = []
description = "A list of region IDs to exclude."
type = list(string)
}

locals {
Expand All @@ -57,92 +57,92 @@ locals {
# the provider, which requires a region.
regions = {
"ap-northeast-1" = {
name = "Asia Pacific (Tokyo)"
icon = "/emojis/1f1ef-1f1f5.png"
}
"ap-northeast-2" = {
name = "Asia Pacific (Seoul)"
icon = "/emojis/1f1f0-1f1f7.png"
}
"ap-northeast-3" = {
name = "Asia Pacific (Osaka)"
icon = "/emojis/1f1ef-1f1f5.png"
}
"ap-south-1" = {
name = "Asia Pacific (Mumbai)"
icon = "/emojis/1f1ee-1f1f3.png"
}
"ap-southeast-1" = {
name = "Asia Pacific (Singapore)"
icon = "/emojis/1f1f8-1f1ec.png"
}
"ap-southeast-2" = {
name = "Asia Pacific (Sydney)"
icon = "/emojis/1f1e6-1f1fa.png"
}
"ca-central-1" = {
name = "Canada (Central)"
icon = "/emojis/1f1e8-1f1e6.png"
}
"eu-central-1" = {
name = "EU (Frankfurt)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"eu-north-1" = {
name = "EU (Stockholm)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"eu-west-1" = {
name = "EU (Ireland)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"eu-west-2" = {
name = "EU (London)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"eu-west-3" = {
name = "EU (Paris)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"sa-east-1" = {
name = "South America (São Paulo)"
icon = "/emojis/1f1e7-1f1f7.png"
}
"us-east-1" = {
name = "US East (N. Virginia)"
icon = "/emojis/1f1fa-1f1f8.png"
}
"us-east-2" = {
name = "US East (Ohio)"
icon = "/emojis/1f1fa-1f1f8.png"
}
"us-west-1" = {
name = "US West (N. California)"
icon = "/emojis/1f1fa-1f1f8.png"
}
"us-west-2" = {
name = "US West (Oregon)"
icon = "/emojis/1f1fa-1f1f8.png"
}
name = "Asia Pacific (Tokyo)"
icon = "/emojis/1f1ef-1f1f5.png"
}
"ap-northeast-2" = {
name = "Asia Pacific (Seoul)"
icon = "/emojis/1f1f0-1f1f7.png"
}
"ap-northeast-3" = {
name = "Asia Pacific (Osaka)"
icon = "/emojis/1f1ef-1f1f5.png"
}
"ap-south-1" = {
name = "Asia Pacific (Mumbai)"
icon = "/emojis/1f1ee-1f1f3.png"
}
"ap-southeast-1" = {
name = "Asia Pacific (Singapore)"
icon = "/emojis/1f1f8-1f1ec.png"
}
"ap-southeast-2" = {
name = "Asia Pacific (Sydney)"
icon = "/emojis/1f1e6-1f1fa.png"
}
"ca-central-1" = {
name = "Canada (Central)"
icon = "/emojis/1f1e8-1f1e6.png"
}
"eu-central-1" = {
name = "EU (Frankfurt)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"eu-north-1" = {
name = "EU (Stockholm)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"eu-west-1" = {
name = "EU (Ireland)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"eu-west-2" = {
name = "EU (London)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"eu-west-3" = {
name = "EU (Paris)"
icon = "/emojis/1f1ea-1f1fa.png"
}
"sa-east-1" = {
name = "South America (São Paulo)"
icon = "/emojis/1f1e7-1f1f7.png"
}
"us-east-1" = {
name = "US East (N. Virginia)"
icon = "/emojis/1f1fa-1f1f8.png"
}
"us-east-2" = {
name = "US East (Ohio)"
icon = "/emojis/1f1fa-1f1f8.png"
}
"us-west-1" = {
name = "US West (N. California)"
icon = "/emojis/1f1fa-1f1f8.png"
}
"us-west-2" = {
name = "US West (Oregon)"
icon = "/emojis/1f1fa-1f1f8.png"
}
}
}

data "coder_parameter" "region" {
name = "aws_region"
display_name = var.display_name
description = var.description
default = var.default
mutable = var.mutable
dynamic "option" {
for_each = { for k, v in local.regions : k => v if !(contains(var.exclude, k)) }
content {
name = try(var.custom_names[option.key], option.value.name)
icon = try(var.custom_icons[option.key], option.value.icon)
value = option.key
}
name = "aws_region"
display_name = var.display_name
description = var.description
default = var.default
mutable = var.mutable
dynamic "option" {
for_each = { for k, v in local.regions : k => v if !(contains(var.exclude, k)) }
content {
name = try(var.custom_names[option.key], option.value.name)
icon = try(var.custom_icons[option.key], option.value.icon)
value = option.key
}
}
}

output "value" {
value = data.coder_parameter.region.value
value = data.coder_parameter.region.value
}
25 changes: 25 additions & 0 deletions azure-region/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { describe, expect, it } from "bun:test";
import {
executeScriptInContainer,
runTerraformApply,
runTerraformInit,
testRequiredVariables,
} from "../test";

describe("azure-region", async () => {
await runTerraformInit(import.meta.dir);

testRequiredVariables(import.meta.dir, {});

it("default output", async () => {
const state = await runTerraformApply(import.meta.dir, {});
expect(state.outputs.value.value).toBe("eastus");
});

it("customized default", async () => {
const state = await runTerraformApply(import.meta.dir, {
default: "westus",
});
expect(state.outputs.value.value).toBe("westus");
});
});
Loading
Loading