Migrate duplicated test fixtures
This commit is contained in:
@@ -3,7 +3,6 @@ package app
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -15,6 +14,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/distributor/internal/notify"
|
"gitea.maximumdirect.net/eric/distributor/internal/notify"
|
||||||
"gitea.maximumdirect.net/eric/distributor/internal/state"
|
"gitea.maximumdirect.net/eric/distributor/internal/state"
|
||||||
"gitea.maximumdirect.net/eric/distributor/internal/storage"
|
"gitea.maximumdirect.net/eric/distributor/internal/storage"
|
||||||
|
"gitea.maximumdirect.net/eric/distributor/internal/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRunDryRunPrintsConfigSummary(t *testing.T) {
|
func TestRunDryRunPrintsConfigSummary(t *testing.T) {
|
||||||
@@ -436,61 +436,20 @@ type testFile struct {
|
|||||||
|
|
||||||
func writeSourceBundle(t *testing.T, root, relative string, opts testBundleOptions) bundle.Manifest {
|
func writeSourceBundle(t *testing.T, root, relative string, opts testBundleOptions) bundle.Manifest {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if opts.ID == "" {
|
extraFiles := make([]testutil.SourceFile, 0, len(opts.ExtraFiles))
|
||||||
opts.ID = "weather.daily.brentwood.2026-05-30"
|
for _, file := range opts.ExtraFiles {
|
||||||
|
extraFiles = append(extraFiles, testutil.SourceFile{Path: file.Path, Data: file.Data})
|
||||||
}
|
}
|
||||||
if opts.Created.IsZero() {
|
return testutil.WriteSourceBundle(t, root, relative, testutil.BundleOptions{
|
||||||
opts.Created = time.Date(2026, 5, 30, 11, 10, 0, 0, time.UTC)
|
ID: opts.ID,
|
||||||
}
|
Created: opts.Created,
|
||||||
bundleRoot := filepath.Join(root, filepath.FromSlash(relative))
|
ExtraFiles: extraFiles,
|
||||||
if err := os.MkdirAll(bundleRoot, 0o755); err != nil {
|
})
|
||||||
t.Fatalf("mkdir bundle: %v", err)
|
|
||||||
}
|
|
||||||
files := []struct {
|
|
||||||
path string
|
|
||||||
data string
|
|
||||||
}{
|
|
||||||
{path: "report.md", data: "# Report\nSunny.\n"},
|
|
||||||
{path: "summary.txt", data: "Summary\n"},
|
|
||||||
}
|
|
||||||
for _, extra := range opts.ExtraFiles {
|
|
||||||
files = append(files, struct {
|
|
||||||
path string
|
|
||||||
data string
|
|
||||||
}{path: extra.Path, data: extra.Data})
|
|
||||||
}
|
|
||||||
manifestFiles := make([]bundle.ManifestFile, 0, len(files))
|
|
||||||
for _, file := range files {
|
|
||||||
if err := os.WriteFile(filepath.Join(bundleRoot, filepath.FromSlash(file.path)), []byte(file.data), 0o600); err != nil {
|
|
||||||
t.Fatalf("write source file: %v", err)
|
|
||||||
}
|
|
||||||
manifestFiles = append(manifestFiles, bundle.ManifestFile{
|
|
||||||
Path: file.path,
|
|
||||||
SHA256: bundle.FileDigest([]byte(file.data)),
|
|
||||||
Size: int64(len(file.data)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
manifest := bundle.Manifest{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
ID: opts.ID,
|
|
||||||
Created: opts.Created,
|
|
||||||
Files: manifestFiles,
|
|
||||||
}
|
|
||||||
manifest.Digest = bundle.BundleDigest(manifest.Files)
|
|
||||||
data, err := json.MarshalIndent(manifest, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("marshal manifest: %v", err)
|
|
||||||
}
|
|
||||||
data = append(data, '\n')
|
|
||||||
if err := os.WriteFile(filepath.Join(bundleRoot, "manifest.json"), data, 0o600); err != nil {
|
|
||||||
t.Fatalf("write manifest: %v", err)
|
|
||||||
}
|
|
||||||
return manifest
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeLocalConfig(t *testing.T, sourceRoot, destinationRoot string) string {
|
func writeLocalConfig(t *testing.T, sourceRoot, destinationRoot string) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
return writeLocalConfigWithPolicy(t, sourceRoot, destinationRoot, true, false)
|
return testutil.WriteMinimalLocalConfig(t, sourceRoot, destinationRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeLocalConfigWithPolicy(t *testing.T, sourceRoot, destinationRoot string, publishSource, publishHTML bool) string {
|
func writeLocalConfigWithPolicy(t *testing.T, sourceRoot, destinationRoot string, publishSource, publishHTML bool) string {
|
||||||
@@ -521,20 +480,7 @@ pipelines:
|
|||||||
|
|
||||||
func writeFanoutConfig(t *testing.T, sourceRoot, firstDestination, secondDestination string) string {
|
func writeFanoutConfig(t *testing.T, sourceRoot, firstDestination, secondDestination string) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
return writeConfigFile(t, `
|
return testutil.WriteFanoutLocalConfig(t, sourceRoot, firstDestination, secondDestination)
|
||||||
pipelines:
|
|
||||||
- id: reports
|
|
||||||
source:
|
|
||||||
backend: local
|
|
||||||
path: `+sourceRoot+`
|
|
||||||
destinations:
|
|
||||||
- id: archive-one
|
|
||||||
backend: local
|
|
||||||
path: `+firstDestination+`
|
|
||||||
- id: archive-two
|
|
||||||
backend: local
|
|
||||||
path: `+secondDestination+`
|
|
||||||
`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeConfigFile(t *testing.T, body string) string {
|
func writeConfigFile(t *testing.T, body string) string {
|
||||||
@@ -548,42 +494,12 @@ func writeConfigFile(t *testing.T, body string) string {
|
|||||||
|
|
||||||
func writeDestinationState(t *testing.T, root, relative string, manifest bundle.Manifest) {
|
func writeDestinationState(t *testing.T, root, relative string, manifest bundle.Manifest) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
bundleRoot := filepath.Join(root, filepath.FromSlash(relative))
|
testutil.WriteDestinationState(t, root, relative, manifest, testutil.DestinationStateOptions{})
|
||||||
if err := os.MkdirAll(bundleRoot, 0o755); err != nil {
|
|
||||||
t.Fatalf("mkdir destination: %v", err)
|
|
||||||
}
|
|
||||||
destinationState := state.DistributorState{
|
|
||||||
SchemaVersion: state.SchemaVersion,
|
|
||||||
PipelineID: "reports",
|
|
||||||
DestinationID: "archive",
|
|
||||||
PublishedAt: time.Date(2026, 5, 30, 11, 12, 0, 0, time.UTC),
|
|
||||||
Source: state.SourceState{Manifest: manifest},
|
|
||||||
Outputs: []state.OutputFile{
|
|
||||||
{Path: "report.md", Kind: state.OutputKindSource, SourcePath: "report.md", SHA256: manifest.Files[0].SHA256, Size: manifest.Files[0].Size},
|
|
||||||
{Path: "summary.txt", Kind: state.OutputKindSource, SourcePath: "summary.txt", SHA256: manifest.Files[1].SHA256, Size: manifest.Files[1].Size},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
data, err := json.MarshalIndent(destinationState, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("marshal state: %v", err)
|
|
||||||
}
|
|
||||||
data = append(data, '\n')
|
|
||||||
if err := os.WriteFile(filepath.Join(bundleRoot, storage.StateFileName), data, 0o600); err != nil {
|
|
||||||
t.Fatalf("write state: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func readStateFile(t *testing.T, path string) state.DistributorState {
|
func readStateFile(t *testing.T, path string) state.DistributorState {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
data, err := os.ReadFile(path)
|
return testutil.ReadDestinationState(t, path)
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("read state: %v", err)
|
|
||||||
}
|
|
||||||
destinationState, err := state.Parse(data)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("parse state: %v", err)
|
|
||||||
}
|
|
||||||
return destinationState
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertFile(t *testing.T, path, want string) {
|
func assertFile(t *testing.T, path, want string) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"gitea.maximumdirect.net/eric/distributor/internal/storage"
|
"gitea.maximumdirect.net/eric/distributor/internal/storage"
|
||||||
|
"gitea.maximumdirect.net/eric/distributor/internal/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestExecuteRootHelp(t *testing.T) {
|
func TestExecuteRootHelp(t *testing.T) {
|
||||||
@@ -161,22 +162,8 @@ func TestExecuteInspectArgs(t *testing.T) {
|
|||||||
|
|
||||||
func TestExecuteRunDryRun(t *testing.T) {
|
func TestExecuteRunDryRun(t *testing.T) {
|
||||||
sourceRoot := t.TempDir()
|
sourceRoot := t.TempDir()
|
||||||
writeCLIBundle(t, sourceRoot)
|
testutil.WriteSourceBundle(t, sourceRoot, "", testutil.BundleOptions{})
|
||||||
configPath := filepath.Join(t.TempDir(), "config.yml")
|
configPath := testutil.WriteMinimalLocalConfig(t, sourceRoot, t.TempDir())
|
||||||
err := os.WriteFile(configPath, []byte(`
|
|
||||||
pipelines:
|
|
||||||
- id: reports
|
|
||||||
source:
|
|
||||||
backend: local
|
|
||||||
path: `+sourceRoot+`
|
|
||||||
destinations:
|
|
||||||
- id: archive
|
|
||||||
backend: local
|
|
||||||
path: `+t.TempDir()+`
|
|
||||||
`), 0o600)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("write config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var stdout, stderr bytes.Buffer
|
var stdout, stderr bytes.Buffer
|
||||||
|
|
||||||
@@ -209,22 +196,8 @@ func TestExecuteRunRejectsExtraPositionalArgs(t *testing.T) {
|
|||||||
func TestExecuteRunPublishes(t *testing.T) {
|
func TestExecuteRunPublishes(t *testing.T) {
|
||||||
sourceRoot := t.TempDir()
|
sourceRoot := t.TempDir()
|
||||||
destinationRoot := t.TempDir()
|
destinationRoot := t.TempDir()
|
||||||
writeCLIBundle(t, sourceRoot)
|
testutil.WriteSourceBundle(t, sourceRoot, "", testutil.BundleOptions{})
|
||||||
configPath := filepath.Join(t.TempDir(), "config.yml")
|
configPath := testutil.WriteMinimalLocalConfig(t, sourceRoot, destinationRoot)
|
||||||
err := os.WriteFile(configPath, []byte(`
|
|
||||||
pipelines:
|
|
||||||
- id: reports
|
|
||||||
source:
|
|
||||||
backend: local
|
|
||||||
path: `+sourceRoot+`
|
|
||||||
destinations:
|
|
||||||
- id: archive
|
|
||||||
backend: local
|
|
||||||
path: `+destinationRoot+`
|
|
||||||
`), 0o600)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("write config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var stdout, stderr bytes.Buffer
|
var stdout, stderr bytes.Buffer
|
||||||
|
|
||||||
@@ -250,37 +223,3 @@ func TestUnknownCommandIsUsageError(t *testing.T) {
|
|||||||
t.Fatalf("stderr = %q, want unknown command error", stderr.String())
|
t.Fatalf("stderr = %q, want unknown command error", stderr.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeCLIBundle(t *testing.T, root string) {
|
|
||||||
t.Helper()
|
|
||||||
for _, file := range []struct {
|
|
||||||
path string
|
|
||||||
data string
|
|
||||||
}{
|
|
||||||
{"manifest.json", `{
|
|
||||||
"schema_version": 1,
|
|
||||||
"id": "weather.daily.brentwood.2026-05-30",
|
|
||||||
"digest": "sha256:099b205780d2b050024868399961b05731729a548d5d6329c7b06a6740dd75fe",
|
|
||||||
"created": "2026-05-30T11:10:00Z",
|
|
||||||
"files": [
|
|
||||||
{
|
|
||||||
"path": "report.md",
|
|
||||||
"sha256": "sha256:3640fd37140ee4d2e0e93e78834f232ea67a50e7bc6279203690cc7de1975fa6",
|
|
||||||
"size": 16
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "summary.txt",
|
|
||||||
"sha256": "sha256:3cbb36aca330b3bd113955dfbada0adb7a5f95ad9f678bd61f175406c6a37e95",
|
|
||||||
"size": 8
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
`},
|
|
||||||
{"report.md", "# Report\nSunny.\n"},
|
|
||||||
{"summary.txt", "Summary\n"},
|
|
||||||
} {
|
|
||||||
if err := os.WriteFile(filepath.Join(root, file.path), []byte(file.data), 0o600); err != nil {
|
|
||||||
t.Fatalf("write bundle file: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,42 +3,27 @@ package publish
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"gitea.maximumdirect.net/eric/distributor/internal/bundle"
|
"gitea.maximumdirect.net/eric/distributor/internal/bundle"
|
||||||
"gitea.maximumdirect.net/eric/distributor/internal/config"
|
"gitea.maximumdirect.net/eric/distributor/internal/config"
|
||||||
"gitea.maximumdirect.net/eric/distributor/internal/storage"
|
|
||||||
"gitea.maximumdirect.net/eric/distributor/internal/storage/fake"
|
"gitea.maximumdirect.net/eric/distributor/internal/storage/fake"
|
||||||
|
"gitea.maximumdirect.net/eric/distributor/internal/testutil"
|
||||||
"gitea.maximumdirect.net/eric/distributor/internal/transform"
|
"gitea.maximumdirect.net/eric/distributor/internal/transform"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPlanOutputsRejectsCollision(t *testing.T) {
|
func TestPlanOutputsRejectsCollision(t *testing.T) {
|
||||||
sourceBackend := fake.New()
|
sourceBackend := fake.New()
|
||||||
if _, err := sourceBackend.WriteFile(context.Background(), "report.md", []byte("# Report\n"), storage.WriteOptions{}); err != nil {
|
sourceBundle := testutil.WriteFakeSourceBundle(t, sourceBackend, "", testutil.BundleOptions{
|
||||||
t.Fatalf("WriteFile report.md error = %v", err)
|
Files: []testutil.SourceFile{
|
||||||
}
|
{Path: "report.md", Data: "# Report\n"},
|
||||||
if _, err := sourceBackend.WriteFile(context.Background(), "report.html", []byte("<p>source html</p>\n"), storage.WriteOptions{}); err != nil {
|
{Path: "report.html", Data: "<p>source html</p>\n"},
|
||||||
t.Fatalf("WriteFile report.html error = %v", err)
|
},
|
||||||
}
|
})
|
||||||
reportDigest := bundle.FileDigest([]byte("# Report\n"))
|
|
||||||
htmlDigest := bundle.FileDigest([]byte("<p>source html</p>\n"))
|
|
||||||
files := []bundle.ManifestFile{
|
|
||||||
{Path: "report.md", SHA256: reportDigest, Size: 9},
|
|
||||||
{Path: "report.html", SHA256: htmlDigest, Size: 19},
|
|
||||||
}
|
|
||||||
_, err := PlanOutputs(context.Background(), Request{
|
_, err := PlanOutputs(context.Background(), Request{
|
||||||
SourceBackend: sourceBackend,
|
SourceBackend: sourceBackend,
|
||||||
SourceBundle: bundle.Bundle{
|
SourceBundle: sourceBundle,
|
||||||
Manifest: bundle.Manifest{
|
Publish: config.PublishPolicy{Source: true, HTML: true},
|
||||||
SchemaVersion: 1,
|
Transform: config.Transform{MarkdownToHTML: &config.MarkdownToHTML{Enabled: true, Mode: config.TransformModeSidecar}},
|
||||||
ID: "bundle",
|
|
||||||
Created: time.Date(2026, 5, 30, 11, 10, 0, 0, time.UTC),
|
|
||||||
Digest: bundle.BundleDigest(files),
|
|
||||||
Files: files,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Publish: config.PublishPolicy{Source: true, HTML: true},
|
|
||||||
Transform: config.Transform{MarkdownToHTML: &config.MarkdownToHTML{Enabled: true, Mode: config.TransformModeSidecar}},
|
|
||||||
Transformers: testResolver{transform.MarkdownToHTML: testTransformer{outputs: []transform.Output{{
|
Transformers: testResolver{transform.MarkdownToHTML: testTransformer{outputs: []transform.Output{{
|
||||||
Path: "report.html",
|
Path: "report.html",
|
||||||
SourcePath: "report.md",
|
SourcePath: "report.md",
|
||||||
@@ -55,21 +40,14 @@ func TestPlanOutputsRejectsCollision(t *testing.T) {
|
|||||||
|
|
||||||
func TestPlanOutputsRejectsHTMLWithoutMarkdown(t *testing.T) {
|
func TestPlanOutputsRejectsHTMLWithoutMarkdown(t *testing.T) {
|
||||||
sourceBackend := fake.New()
|
sourceBackend := fake.New()
|
||||||
if _, err := sourceBackend.WriteFile(context.Background(), "summary.txt", []byte("Summary\n"), storage.WriteOptions{}); err != nil {
|
sourceBundle := testutil.WriteFakeSourceBundle(t, sourceBackend, "", testutil.BundleOptions{
|
||||||
t.Fatalf("WriteFile summary.txt error = %v", err)
|
Files: []testutil.SourceFile{{Path: "summary.txt", Data: "Summary\n"}},
|
||||||
}
|
})
|
||||||
files := []bundle.ManifestFile{{Path: "summary.txt", SHA256: bundle.FileDigest([]byte("Summary\n")), Size: 8}}
|
|
||||||
_, err := PlanOutputs(context.Background(), Request{
|
_, err := PlanOutputs(context.Background(), Request{
|
||||||
SourceBackend: sourceBackend,
|
SourceBackend: sourceBackend,
|
||||||
SourceBundle: bundle.Bundle{Manifest: bundle.Manifest{
|
SourceBundle: sourceBundle,
|
||||||
SchemaVersion: 1,
|
Publish: config.PublishPolicy{HTML: true},
|
||||||
ID: "bundle",
|
Transform: config.Transform{MarkdownToHTML: &config.MarkdownToHTML{Enabled: true, Mode: config.TransformModeSidecar}},
|
||||||
Created: time.Date(2026, 5, 30, 11, 10, 0, 0, time.UTC),
|
|
||||||
Digest: bundle.BundleDigest(files),
|
|
||||||
Files: files,
|
|
||||||
}},
|
|
||||||
Publish: config.PublishPolicy{HTML: true},
|
|
||||||
Transform: config.Transform{MarkdownToHTML: &config.MarkdownToHTML{Enabled: true, Mode: config.TransformModeSidecar}},
|
|
||||||
Transformers: testResolver{
|
Transformers: testResolver{
|
||||||
transform.MarkdownToHTML: testTransformer{},
|
transform.MarkdownToHTML: testTransformer{},
|
||||||
},
|
},
|
||||||
@@ -128,24 +106,17 @@ func TestPlanOutputsUsesRegisteredTransformer(t *testing.T) {
|
|||||||
func TestBuildRejectsHTMLWithoutTransform(t *testing.T) {
|
func TestBuildRejectsHTMLWithoutTransform(t *testing.T) {
|
||||||
sourceBackend := fake.New()
|
sourceBackend := fake.New()
|
||||||
destinationBackend := fake.New()
|
destinationBackend := fake.New()
|
||||||
if _, err := sourceBackend.WriteFile(context.Background(), "report.md", []byte("# Report\n"), storage.WriteOptions{}); err != nil {
|
sourceBundle := testutil.WriteFakeSourceBundle(t, sourceBackend, "", testutil.BundleOptions{
|
||||||
t.Fatalf("WriteFile report.md error = %v", err)
|
Files: []testutil.SourceFile{{Path: "report.md", Data: "# Report\n"}},
|
||||||
}
|
})
|
||||||
files := []bundle.ManifestFile{{Path: "report.md", SHA256: bundle.FileDigest([]byte("# Report\n")), Size: 9}}
|
|
||||||
_, err := Build(context.Background(), Request{
|
_, err := Build(context.Background(), Request{
|
||||||
PipelineID: "reports",
|
PipelineID: "reports",
|
||||||
DestinationID: "archive",
|
DestinationID: "archive",
|
||||||
SourceBackend: sourceBackend,
|
SourceBackend: sourceBackend,
|
||||||
DestinationBackend: destinationBackend,
|
DestinationBackend: destinationBackend,
|
||||||
DestinationBundlePath: "",
|
DestinationBundlePath: "",
|
||||||
SourceBundle: bundle.Bundle{Manifest: bundle.Manifest{
|
SourceBundle: sourceBundle,
|
||||||
SchemaVersion: 1,
|
Publish: config.PublishPolicy{HTML: true},
|
||||||
ID: "bundle",
|
|
||||||
Created: time.Date(2026, 5, 30, 11, 10, 0, 0, time.UTC),
|
|
||||||
Digest: bundle.BundleDigest(files),
|
|
||||||
Files: files,
|
|
||||||
}},
|
|
||||||
Publish: config.PublishPolicy{HTML: true},
|
|
||||||
Transfer: config.TransferPolicy{
|
Transfer: config.TransferPolicy{
|
||||||
OnDestinationSame: config.TransferActionSkip,
|
OnDestinationSame: config.TransferActionSkip,
|
||||||
OnDestinationOlder: config.TransferActionReplace,
|
OnDestinationOlder: config.TransferActionReplace,
|
||||||
|
|||||||
Reference in New Issue
Block a user