FedWiki still registered four workflow types that only runs started by an earlier release used: CreateFedWikiSiteWorkflow, SetSiteStatusWorkflow, DeleteFedWikiSiteWorkflow and SwapActiveSiteWorkflow. Their activities adjust the site usage counter by increments, which #165 replaces with a count, so they go first. - A provider may now check something before the Temporal worker starts (WorkerPrecondition). cmd/start.go runs every provider's check after the client connects and exits with status 1 on a refusal, which it logs as a refused start, not a failed worker. - FedWiki's check lists the running runs of the four types over every page of results. It refuses to start while any is open, naming each type with its count, and refuses when the list cannot be read. - The four types, their activities, inputs and workflow-id functions, resolveFullDomain and NewSiteID are deleted. AllocateDomainActivity requires the FQDN the request recorded. - The six recorded histories of the old types and their tests are deleted; the refusal cases they covered that still apply are ported to ApplyFarmSiteStatusActivity and SwapFarmSitesActivity. The eight recorded histories of the request-driven workflows replay unchanged. - The workflows package no longer carries the allowed-domains and support-URL settings it stopped reading; the web handlers keep their own. New tests cover the check's refusals, its singular and plural sentences, the empty FQDN, and a create whose name another workspace already holds. The OpenSpec change metered-usage-recount, which carries the rest of #165, lands with this first section. The full suite passes.
84 lines
2.4 KiB
Go
84 lines
2.4 KiB
Go
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
|
|
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"log/slog"
|
|
"testing"
|
|
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/workflows"
|
|
"go.temporal.io/sdk/client"
|
|
"go.temporal.io/sdk/worker"
|
|
)
|
|
|
|
// plainProvider is a WorkflowProvider with no precondition.
|
|
type plainProvider struct{}
|
|
|
|
func (plainProvider) RegisterWorkflows(worker.Worker, *sql.DB, *slog.Logger) {}
|
|
func (plainProvider) Startup(context.Context, client.Client, string, *sql.DB, *slog.Logger) error {
|
|
return nil
|
|
}
|
|
|
|
// checkedProvider is a WorkflowProvider whose precondition answers err and
|
|
// counts its calls.
|
|
type checkedProvider struct {
|
|
plainProvider
|
|
err error
|
|
calls int
|
|
}
|
|
|
|
func (p *checkedProvider) CheckBeforeWorker(context.Context, client.Client) error {
|
|
p.calls++
|
|
return p.err
|
|
}
|
|
|
|
// A provider whose precondition fails keeps the worker from being built, and
|
|
// the providers after it are not asked.
|
|
func TestNewCheckedWorkerStopsOnAPreconditionError(t *testing.T) {
|
|
refusal := errors.New("runs are open")
|
|
failing := &checkedProvider{err: refusal}
|
|
later := &checkedProvider{}
|
|
cfg := workflows.WorkerConfig{WorkflowProviders: []workflows.WorkflowProvider{plainProvider{}, failing, later}}
|
|
|
|
built := 0
|
|
_, err := newCheckedWorker(context.Background(), nil, cfg,
|
|
func(client.Client, workflows.WorkerConfig) (*workflows.Worker, error) {
|
|
built++
|
|
return nil, nil
|
|
})
|
|
|
|
if !errors.Is(err, refusal) {
|
|
t.Fatalf("err = %v, want the provider's error", err)
|
|
}
|
|
if built != 0 {
|
|
t.Fatalf("NewWorker called %d times, want none", built)
|
|
}
|
|
if later.calls != 0 {
|
|
t.Fatalf("a provider after the failing one was asked %d times", later.calls)
|
|
}
|
|
}
|
|
|
|
// Passing preconditions, and providers with none, build the worker.
|
|
func TestNewCheckedWorkerBuildsTheWorkerWhenEveryPreconditionPasses(t *testing.T) {
|
|
passing := &checkedProvider{}
|
|
cfg := workflows.WorkerConfig{WorkflowProviders: []workflows.WorkflowProvider{plainProvider{}, passing}}
|
|
|
|
built := 0
|
|
_, err := newCheckedWorker(context.Background(), nil, cfg,
|
|
func(client.Client, workflows.WorkerConfig) (*workflows.Worker, error) {
|
|
built++
|
|
return nil, nil
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("err = %v, want nil", err)
|
|
}
|
|
if built != 1 || passing.calls != 1 {
|
|
t.Fatalf("NewWorker called %d times and the precondition %d times, want one each", built, passing.calls)
|
|
}
|
|
}
|