完善生图5.0的功能

This commit is contained in:
andy committed 2026-08-25 14:06:04 +08:00
1 parent 88a4268d40
commit 678d213f40
31 files changed
+3281 -107

No files matched your search

@@ -1,10 +1,13 @@
package orchestration
import (
"bytes"
"context"
"encoding/json"
"errors"
"log"
"reflect"
"strings"
"testing"
"time"
@@ -233,6 +236,30 @@ func TestCreationCoordinatorUsesAtomicChargeAndActivationWhenStoreSupportsIt(t *
}
}
func TestCreationCoordinatorMapsAtomicInsufficientBalanceBeforeDispatch(t *testing.T) {
creator := &creationStoreStub{}
quoter := &quoterStub{quote: &billing.Quote{AmountFen: 39, Currency: "CNY"}}
state := &atomicCreationStateStub{err: errors.New("charge and activate: BILLING_INSUFFICIENT_BALANCE")}
coordinator := NewCreationCoordinator(platformBuilderStub{}, creator, quoter, &chargeLedgerStub{}, state)
_, _, err := coordinator.CreatePlatform(context.Background(), identity.Session{User: identity.User{ID: "account", OrganizationID: "org"}}, CreationInput{Capability: "image.generate", Body: map[string]any{"prompt": "fresh"}})
if billing.HTTPStatus(err) != 402 || state.failed.Status != jobs.StatusFailed {
t.Fatalf("error=%v status=%d failed=%#v", err, billing.HTTPStatus(err), state.failed)
}
}
func TestCreationCoordinatorReturnsActionableErrorWithoutBillingOrganization(t *testing.T) {
creator := &creationStoreStub{}
quoter := &quoterStub{quote: &billing.Quote{AmountFen: 39, Currency: "CNY"}}
state := &creationStateStub{}
coordinator := NewCreationCoordinator(platformBuilderStub{}, creator, quoter, &chargeLedgerStub{}, state)
_, _, err := coordinator.CreatePlatform(context.Background(), identity.Session{User: identity.User{ID: "account", Role: "user"}}, CreationInput{Capability: "image.generate", Body: map[string]any{"prompt": "fresh"}})
if billing.HTTPStatus(err) != 409 || state.failed.Status != jobs.StatusFailed {
t.Fatalf("error=%v status=%d failed=%#v", err, billing.HTTPStatus(err), state.failed)
}
}
func TestCreationCoordinatorRetryRebuildsAnyOwnedImageJobWithFreshQuote(t *testing.T) {
creator := &creationStoreStub{}
quoter := &quoterStub{quote: &billing.Quote{AmountFen: 41, Currency: "CNY"}}
@@ -266,7 +293,7 @@ func TestSafeBillingErrorMapsPostgresWalletFailures(t *testing.T) {
}{
{name: "insufficient", err: errors.New("charge and activate: BILLING_INSUFFICIENT_BALANCE"), want: 402},
{name: "idempotency", err: errors.New("charge and activate: BILLING_IDEMPOTENCY_PAYLOAD_MISMATCH"), want: 409},
{name: "unknown", err: errors.New("database unavailable"), want: 500},
{name: "unknown", err: errors.New("database unavailable"), want: 503},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
@@ -274,13 +301,40 @@ func TestSafeBillingErrorMapsPostgresWalletFailures(t *testing.T) {
if status := billing.HTTPStatus(got); status != test.want {
t.Fatalf("status = %d, want %d (error %v)", status, test.want, got)
}
if test.want == 500 && got.Error() != "charge generation job" {
if test.want == 503 && got.Error() == test.err.Error() {
t.Fatalf("unknown error leaked: %v", got)
}
})
}
}
func TestGenerationBillingFailureLogKeepsOnlySafeClassification(t *testing.T) {
var output bytes.Buffer
previousWriter, previousFlags := log.Writer(), log.Flags()
log.SetOutput(&output)
log.SetFlags(0)
defer func() {
log.SetOutput(previousWriter)
log.SetFlags(previousFlags)
}()
logGenerationBillingFailure(
"job-safe-log",
"charge",
&billingSQLStateTestError{code: "42501", message: "database password leaked"},
billing.ErrProviderUnavailable,
)
got := output.String()
for _, expected := range []string{"jobId=job-safe-log", "phase=charge", "status=503", `code="42501"`, "errorClass=database"} {
if !strings.Contains(got, expected) {
t.Fatalf("safe log %q missing %q", got, expected)
}
}
if strings.Contains(got, "password") || strings.Contains(got, "leaked") {
t.Fatalf("safe log leaked raw error: %q", got)
}
}
func TestCreationCoordinatorPublicCreationNeverQuotesOrCharges(t *testing.T) {
creator := &creationStoreStub{}
quoter := &quoterStub{}
@@ -457,12 +511,21 @@ type creationStateStub struct {
type atomicCreationStateStub struct {
creationStateStub
charged json.RawMessage
err error
calls int
}
type billingSQLStateTestError struct {
code string
message string
}
func (e *billingSQLStateTestError) Error() string { return e.message }
func (e *billingSQLStateTestError) SQLState() string { return e.code }
func (s *atomicCreationStateStub) ChargeAndActivateCreation(_ context.Context, _ billing.ChargeRequest, _ json.RawMessage) (json.RawMessage, error) {
s.calls++
return append(json.RawMessage(nil), s.charged...), nil
return append(json.RawMessage(nil), s.charged...), s.err
}
func (s *creationStateStub) WriteBilling(_ context.Context, _ string, _ json.RawMessage) error {