package publish import ( "context" "fmt" "io" "testing" "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/testutil" ) func TestExecuteCleansUpAfterWriteFailure(t *testing.T) { sourceBackend := fake.New() destinationBackend := &failingBackend{Backend: fake.New(), failPath: "summary.txt"} sourceBundle := testutil.WriteFakeSourceBundle(t, sourceBackend, "", testutil.BundleOptions{}) req := Request{ PipelineID: "reports", DestinationID: "archive", SourceBundle: sourceBundle, SourceBackend: sourceBackend, DestinationBackend: destinationBackend, DestinationBundlePath: "", Publish: config.PublishPolicy{Source: true}, Transfer: config.TransferPolicy{OnDestinationSame: config.TransferActionSkip, OnDestinationOlder: config.TransferActionReplace, OnDestinationNewer: config.TransferActionSkip, OnConflict: config.TransferActionFail}, DistributorVersion: "test", } plan, err := Build(context.Background(), req) if err != nil { t.Fatalf("Build() error = %v", err) } err = Execute(context.Background(), req, plan) if err == nil { t.Fatal("Execute() error = nil, want error") } found, err := destinationBackend.HasAny(context.Background(), "") if err != nil { t.Fatalf("HasAny() error = %v", err) } if found { t.Fatal("destination has content after failed execution") } } type failingBackend struct { *fake.Backend failPath string } func (b *failingBackend) WriteFile(ctx context.Context, path string, data []byte, opts storage.WriteOptions) (storage.Entry, error) { if path == b.failPath { return storage.Entry{}, fmt.Errorf("injected write failure") } return b.Backend.WriteFile(ctx, path, data, opts) } func (b *failingBackend) WriteFrom(ctx context.Context, path string, r io.Reader, opts storage.WriteOptions) (storage.Entry, error) { if path == b.failPath { return storage.Entry{}, fmt.Errorf("injected write failure") } return b.Backend.WriteFrom(ctx, path, r, opts) }