mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
chore(testutil): extract testutil.CreateZip and testutil.CreateTar helpers (#15540)
Extracts `testutil.CreateTar` and `testutil.CreateZip` test helpers.
This commit is contained in:
@ -9,6 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/provisionersdk/proto"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
@ -380,7 +381,7 @@ func TestParse(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
session := configure(ctx, t, api, &proto.Config{
|
||||
TemplateSourceArchive: makeTar(t, testCase.Files),
|
||||
TemplateSourceArchive: testutil.CreateTar(t, testCase.Files),
|
||||
})
|
||||
|
||||
err := session.Send(&proto.Request{Type: &proto.Request_Parse{Parse: &proto.ParseRequest{}}})
|
||||
|
@ -3,8 +3,6 @@
|
||||
package terraform_test
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@ -28,6 +26,7 @@ import (
|
||||
"github.com/coder/coder/v2/provisioner/terraform"
|
||||
"github.com/coder/coder/v2/provisionersdk"
|
||||
"github.com/coder/coder/v2/provisionersdk/proto"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
)
|
||||
|
||||
type provisionerServeOptions struct {
|
||||
@ -78,39 +77,6 @@ func setupProvisioner(t *testing.T, opts *provisionerServeOptions) (context.Cont
|
||||
return ctx, api
|
||||
}
|
||||
|
||||
func makeTar(t *testing.T, files map[string]string) []byte {
|
||||
t.Helper()
|
||||
var buffer bytes.Buffer
|
||||
writer := tar.NewWriter(&buffer)
|
||||
|
||||
addedDirs := make(map[string]bool)
|
||||
for name, content := range files {
|
||||
// Add parent directories if they don't exist
|
||||
dir := filepath.Dir(name)
|
||||
if dir != "." && !addedDirs[dir] {
|
||||
err := writer.WriteHeader(&tar.Header{
|
||||
Name: dir + "/", // Directory names must end with /
|
||||
Mode: 0o755,
|
||||
Typeflag: tar.TypeDir,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
addedDirs[dir] = true
|
||||
}
|
||||
|
||||
err := writer.WriteHeader(&tar.Header{
|
||||
Name: name,
|
||||
Size: int64(len(content)),
|
||||
Mode: 0o644,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, err = writer.Write([]byte(content))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
err := writer.Flush()
|
||||
require.NoError(t, err)
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
func configure(ctx context.Context, t *testing.T, client proto.DRPCProvisionerClient, config *proto.Config) proto.DRPCProvisioner_SessionClient {
|
||||
t.Helper()
|
||||
sess, err := client.Session(ctx)
|
||||
@ -200,7 +166,7 @@ func TestProvision_Cancel(t *testing.T) {
|
||||
binaryPath: binPath,
|
||||
})
|
||||
sess := configure(ctx, t, api, &proto.Config{
|
||||
TemplateSourceArchive: makeTar(t, nil),
|
||||
TemplateSourceArchive: testutil.CreateTar(t, nil),
|
||||
})
|
||||
|
||||
err = sendPlan(sess, proto.WorkspaceTransition_START)
|
||||
@ -271,7 +237,7 @@ func TestProvision_CancelTimeout(t *testing.T) {
|
||||
})
|
||||
|
||||
sess := configure(ctx, t, api, &proto.Config{
|
||||
TemplateSourceArchive: makeTar(t, nil),
|
||||
TemplateSourceArchive: testutil.CreateTar(t, nil),
|
||||
})
|
||||
|
||||
// provisioner requires plan before apply, so test cancel with plan.
|
||||
@ -360,7 +326,7 @@ func TestProvision_TextFileBusy(t *testing.T) {
|
||||
})
|
||||
|
||||
sess := configure(ctx, t, api, &proto.Config{
|
||||
TemplateSourceArchive: makeTar(t, nil),
|
||||
TemplateSourceArchive: testutil.CreateTar(t, nil),
|
||||
})
|
||||
|
||||
err = sendPlan(sess, proto.WorkspaceTransition_START)
|
||||
@ -811,7 +777,7 @@ func TestProvision(t *testing.T) {
|
||||
|
||||
ctx, api := setupProvisioner(t, nil)
|
||||
sess := configure(ctx, t, api, &proto.Config{
|
||||
TemplateSourceArchive: makeTar(t, testCase.Files),
|
||||
TemplateSourceArchive: testutil.CreateTar(t, testCase.Files),
|
||||
})
|
||||
|
||||
planRequest := &proto.Request{Type: &proto.Request_Plan{Plan: &proto.PlanRequest{
|
||||
@ -925,7 +891,7 @@ func TestProvision_ExtraEnv(t *testing.T) {
|
||||
|
||||
ctx, api := setupProvisioner(t, nil)
|
||||
sess := configure(ctx, t, api, &proto.Config{
|
||||
TemplateSourceArchive: makeTar(t, map[string]string{"main.tf": `resource "null_resource" "A" {}`}),
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{"main.tf": `resource "null_resource" "A" {}`}),
|
||||
})
|
||||
|
||||
err := sendPlan(sess, proto.WorkspaceTransition_START)
|
||||
@ -975,7 +941,7 @@ func TestProvision_SafeEnv(t *testing.T) {
|
||||
|
||||
ctx, api := setupProvisioner(t, nil)
|
||||
sess := configure(ctx, t, api, &proto.Config{
|
||||
TemplateSourceArchive: makeTar(t, map[string]string{"main.tf": echoResource}),
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{"main.tf": echoResource}),
|
||||
})
|
||||
|
||||
err := sendPlan(sess, proto.WorkspaceTransition_START)
|
||||
@ -997,7 +963,7 @@ func TestProvision_MalformedModules(t *testing.T) {
|
||||
|
||||
ctx, api := setupProvisioner(t, nil)
|
||||
sess := configure(ctx, t, api, &proto.Config{
|
||||
TemplateSourceArchive: makeTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"main.tf": `module "hello" { source = "./module" }`,
|
||||
"module/module.tf": `resource "null_`,
|
||||
}),
|
||||
|
@ -1,8 +1,6 @@
|
||||
package tfparse_test
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"log"
|
||||
@ -11,7 +9,6 @@ import (
|
||||
"cdr.dev/slog"
|
||||
"cdr.dev/slog/sloggers/sloghuman"
|
||||
"cdr.dev/slog/sloggers/slogtest"
|
||||
"github.com/coder/coder/v2/archive"
|
||||
"github.com/coder/coder/v2/provisioner/terraform/tfparse"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
|
||||
@ -363,7 +360,7 @@ func Test_WorkspaceTagDefaultsFromFile(t *testing.T) {
|
||||
t.Run(tc.name+"/tar", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
tar := createTar(t, tc.files)
|
||||
tar := testutil.CreateTar(t, tc.files)
|
||||
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
||||
tmpDir := t.TempDir()
|
||||
tfparse.WriteArchive(tar, "application/x-tar", tmpDir)
|
||||
@ -381,7 +378,7 @@ func Test_WorkspaceTagDefaultsFromFile(t *testing.T) {
|
||||
t.Run(tc.name+"/zip", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
zip := createZip(t, tc.files)
|
||||
zip := testutil.CreateZip(t, tc.files)
|
||||
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
|
||||
tmpDir := t.TempDir()
|
||||
tfparse.WriteArchive(zip, "application/zip", tmpDir)
|
||||
@ -399,36 +396,6 @@ func Test_WorkspaceTagDefaultsFromFile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func createTar(t testing.TB, files map[string]string) []byte {
|
||||
var buffer bytes.Buffer
|
||||
writer := tar.NewWriter(&buffer)
|
||||
for path, content := range files {
|
||||
err := writer.WriteHeader(&tar.Header{
|
||||
Name: path,
|
||||
Size: int64(len(content)),
|
||||
Uid: 65534, // nobody
|
||||
Gid: 65534, // nogroup
|
||||
Mode: 0o666, // -rw-rw-rw-
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = writer.Write([]byte(content))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
err := writer.Flush()
|
||||
require.NoError(t, err)
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
func createZip(t testing.TB, files map[string]string) []byte {
|
||||
ta := createTar(t, files)
|
||||
tr := tar.NewReader(bytes.NewReader(ta))
|
||||
za, err := archive.CreateZipFromTar(tr, int64(len(ta)))
|
||||
require.NoError(t, err)
|
||||
return za
|
||||
}
|
||||
|
||||
// Last run results:
|
||||
// goos: linux
|
||||
// goarch: amd64
|
||||
@ -460,8 +427,8 @@ func BenchmarkWorkspaceTagDefaultsFromFile(b *testing.B) {
|
||||
}
|
||||
}`,
|
||||
}
|
||||
tarFile := createTar(b, files)
|
||||
zipFile := createZip(b, files)
|
||||
tarFile := testutil.CreateTar(b, files)
|
||||
zipFile := testutil.CreateZip(b, files)
|
||||
logger := discardLogger(b)
|
||||
b.ResetTimer()
|
||||
b.Run("Tar", func(b *testing.B) {
|
||||
|
@ -34,7 +34,7 @@ func TestTimingsFromProvision(t *testing.T) {
|
||||
binaryPath: fakeBin,
|
||||
})
|
||||
sess := configure(ctx, t, api, &proto.Config{
|
||||
TemplateSourceArchive: makeTar(t, nil),
|
||||
TemplateSourceArchive: testutil.CreateTar(t, nil),
|
||||
})
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, testutil.WaitLong)
|
||||
|
@ -1,8 +1,6 @@
|
||||
package provisionerd_test
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -97,7 +95,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
err := stream.Send(&proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_TemplateImport_{
|
||||
@ -150,7 +148,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
acq = newAcquireOne(t, &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"../../../etc/passwd": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_TemplateImport_{
|
||||
@ -194,7 +192,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
err := stream.Send(&proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_TemplateImport_{
|
||||
@ -243,7 +241,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
acq = newAcquireOne(t, &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
provisionersdk.ReadmeFile: "# A cool template 😎\n",
|
||||
}),
|
||||
@ -325,7 +323,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
acq = newAcquireOne(t, &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_TemplateDryRun_{
|
||||
@ -396,7 +394,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
acq = newAcquireOne(t, &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
@ -459,7 +457,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
acq = newAcquireOne(t, &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
@ -549,7 +547,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
acq = newAcquireOne(t, &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
@ -645,7 +643,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
err := stream.Send(&proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
@ -725,7 +723,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
err := stream.Send(&proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
@ -819,7 +817,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
job := &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
@ -916,7 +914,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
job := &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
@ -1010,7 +1008,7 @@ func TestProvisionerd(t *testing.T) {
|
||||
err := stream.Send(&proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: testutil.CreateTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
@ -1078,26 +1076,6 @@ func TestProvisionerd(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// Creates an in-memory tar of the files provided.
|
||||
func createTar(t *testing.T, files map[string]string) []byte {
|
||||
var buffer bytes.Buffer
|
||||
writer := tar.NewWriter(&buffer)
|
||||
for path, content := range files {
|
||||
err := writer.WriteHeader(&tar.Header{
|
||||
Name: path,
|
||||
Size: int64(len(content)),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = writer.Write([]byte(content))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
err := writer.Flush()
|
||||
require.NoError(t, err)
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
// Creates a provisionerd implementation with the provided dialer and provisioners.
|
||||
func createProvisionerd(t *testing.T, dialer provisionerd.Dialer, connector provisionerd.LocalProvisioners) *provisionerd.Server {
|
||||
server := provisionerd.New(dialer, &provisionerd.Options{
|
||||
|
61
testutil/archive.go
Normal file
61
testutil/archive.go
Normal file
@ -0,0 +1,61 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/archive"
|
||||
)
|
||||
|
||||
// Creates an in-memory tar of the files provided.
|
||||
// Files in the archive are written with nobody
|
||||
// owner/group, and -rw-rw-rw- permissions.
|
||||
func CreateTar(t testing.TB, files map[string]string) []byte {
|
||||
var buffer bytes.Buffer
|
||||
writer := tar.NewWriter(&buffer)
|
||||
// Keep track of directories previously added.
|
||||
addedDirs := make(map[string]bool)
|
||||
for path, content := range files {
|
||||
// Add parent directories if they don't exist
|
||||
dir := filepath.Dir(path)
|
||||
if dir != "." && !addedDirs[dir] {
|
||||
err := writer.WriteHeader(&tar.Header{
|
||||
Name: dir + "/", // Directory names must end with /
|
||||
Mode: 0o755,
|
||||
Typeflag: tar.TypeDir,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
addedDirs[dir] = true
|
||||
}
|
||||
|
||||
err := writer.WriteHeader(&tar.Header{
|
||||
Name: path,
|
||||
Size: int64(len(content)),
|
||||
Uid: 65534, // nobody
|
||||
Gid: 65534, // nogroup
|
||||
Mode: 0o666, // -rw-rw-rw-
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = writer.Write([]byte(content))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
err := writer.Flush()
|
||||
require.NoError(t, err)
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
// Creates an in-memory zip of the files provided.
|
||||
// Uses archive.CreateZipFromTar under the hood.
|
||||
func CreateZip(t testing.TB, files map[string]string) []byte {
|
||||
ta := CreateTar(t, files)
|
||||
tr := tar.NewReader(bytes.NewReader(ta))
|
||||
za, err := archive.CreateZipFromTar(tr, int64(len(ta)))
|
||||
require.NoError(t, err)
|
||||
return za
|
||||
}
|
Reference in New Issue
Block a user