Skip to content

Commit

Permalink
Test scaffolding
Browse files Browse the repository at this point in the history
  • Loading branch information
mraerino committed Jun 30, 2024
1 parent c680b82 commit 9527147
Show file tree
Hide file tree
Showing 10 changed files with 530 additions and 13 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ docs/**/*
docker-compose.yml
LICENSE
README.md
testdata/
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/hashicorp/go-slug v0.15.0
github.com/hashicorp/hcl/v2 v2.20.1
github.com/hashicorp/vault/api v1.13.0
github.com/liamg/memoryfs v1.6.0
github.com/lib/pq v1.10.9
github.com/mattn/go-sqlite3 v1.14.22
github.com/minio/minio-go/v7 v7.0.70
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/liamg/memoryfs v1.6.0 h1:jAFec2HI1PgMTem5gR7UT8zi9u4BfG5jorCRlLH06W8=
github.com/liamg/memoryfs v1.6.0/go.mod h1:z7mfqXFQS8eSeBBsFjYLlxYRMRyiPktytvYCYTb3BSk=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
Expand Down
3 changes: 0 additions & 3 deletions pkg/scaffold/files/tf-preview.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
name: Terraform

on:
workflow_dispatch:
inputs:
workspace_transfer_url:
description: "URL from which to download the workspace"
required: true
type: string

jobs:
plan:
name: Speculative Plan
Expand All @@ -18,7 +16,6 @@ jobs:
TF_HTTP_PASSWORD: ${{ github.token }}
TF_IN_AUTOMATION: "true"
TF_CLI_ARGS: -input=false

# environment variables for providers
# example:
# NETBOX_API_TOKEN: ${{ secrets.NETBOX_API_TOKEN }}
Expand Down
11 changes: 1 addition & 10 deletions pkg/scaffold/files/tf-run.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
name: Terraform

on:
push:
branches: [main]
pull_request:

jobs:
run:
name: Run
Expand All @@ -22,20 +20,16 @@ jobs:
TF_HTTP_PASSWORD: ${{ github.token }}
TF_IN_AUTOMATION: "true"
TF_CLI_ARGS: "-input=false"

# environment variables for providers
# example:
# NETBOX_API_TOKEN: ${{ secrets.NETBOX_API_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4

- uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${TERRAFORM_VERSION}

- run: terraform init

- run: terraform plan -out=tfplan
- name: terraform apply
if: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
Expand All @@ -62,14 +56,12 @@ jobs:
jq -r '.Contents | map(.Key) | sort | reverse | .[5:] | .[]' \
)
for file in ${DELETE_FILES}; do aws s3 rm s3://${S3_BUCKET}/$file; done
- run: terraform show -json tfplan > tfplan.json
env:
TF_CLI_ARGS: ""
- run: terraform show -no-color tfplan > summary.txt
env:
TF_CLI_ARGS: ""

- name: Create status check with details
uses: actions/github-script@v7
with:
Expand Down Expand Up @@ -127,7 +119,6 @@ jobs:
summary,
},
});
- name: Show plan on PR
uses: actions/github-script@v7
if: ${{ github.event_name == 'pull_request' }}
Expand Down Expand Up @@ -179,7 +170,7 @@ jobs:
const codefence = "```"
const body = `
🏗️ Terraform Plan
#### :building_construction: Terraform Plan
${codefence}
${plan.trim("\n")}
${codefence}`
Expand Down
117 changes: 117 additions & 0 deletions pkg/scaffold/scaffold_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package scaffold_test

import (
"io"
"io/fs"
"os"
"path/filepath"
"testing"

"github.com/liamg/memoryfs"
"github.com/nimbolus/terraform-backend/pkg/scaffold"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const expectedBackendConfig = `terraform {
backend "http" {
address = "https://ffddorf-terraform-backend.fly.dev/state/terraform-backend.git/default"
lock_address = "https://ffddorf-terraform-backend.fly.dev/state/terraform-backend.git/default"
unlock_address = "https://ffddorf-terraform-backend.fly.dev/state/terraform-backend.git/default"
username = "github_pat"
}
}
`

func compareFiles(t *testing.T, fs1, fs2 fs.FS, name string) {
file1, err := fs.ReadFile(fs1, name)
require.NoError(t, err)

file2, err := fs.ReadFile(fs2, name)
require.NoError(t, err)

assert.Equal(t, string(file1), string(file2), "in file: %s", name)
}

type confirmer struct{}

var confirmation = []byte{'y', '\n'}

func (c *confirmer) Read(dst []byte) (int, error) {
return copy(dst, confirmation), nil
}

func TestScaffolding(t *testing.T) {
nativeFS := os.DirFS("files")

tests := map[string]struct {
stdin io.Reader
assert func(*testing.T, *memoryfs.FS)
}{
"empty": {
assert: func(t *testing.T, memfs *memoryfs.FS) {
backendOut, err := memfs.ReadFile("backend.tf")
require.NoError(t, err)
assert.Equal(t, expectedBackendConfig, string(backendOut))

subFS, err := memfs.Sub(".github/workflows")
require.NoError(t, err)
compareFiles(t, nativeFS, subFS, "tf-preview.yaml")
compareFiles(t, nativeFS, subFS, "tf-run.yaml")
},
},
"update": {
stdin: &confirmer{},
assert: func(t *testing.T, memfs *memoryfs.FS) {
expectedFS, err := memfs.Sub("expected")
require.NoError(t, err)
compareFiles(t, expectedFS, memfs, "backend.tf")
compareFiles(t, expectedFS, memfs, ".github/workflows/tf-run.yaml")

subFS, err := memfs.Sub(".github/workflows")
require.NoError(t, err)
compareFiles(t, nativeFS, subFS, "tf-preview.yaml")
},
},
}

for name, params := range tests {
t.Run(name, func(t *testing.T) {
memfs := memoryfs.New()

s, err := os.Stat("testdata/" + name)
if err == nil {
require.True(t, s.IsDir(), "testdata for test name needs to be a directory")
testFS := os.DirFS("testdata/" + name)
err := fs.WalkDir(testFS, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if !d.Type().IsRegular() {
return nil
}

contents, err := fs.ReadFile(testFS, path)
if err != nil {
return err
}
if err := memfs.MkdirAll(filepath.Dir(path), 0755); err != nil {
return err
}
return memfs.WriteFile(path, contents, d.Type().Perm())
})
require.NoError(t, err)
}

var stdin io.Reader = os.Stdin
if params.stdin != nil {
stdin = params.stdin
}

cmd := scaffold.NewCommand(memfs, stdin)
require.NoError(t, cmd.Execute())

params.assert(t, memfs)
})
}
}
Loading

0 comments on commit 9527147

Please sign in to comment.