108 lines
4.0 KiB
Go
108 lines
4.0 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"yingce/backend/internal/model"
|
|
)
|
|
|
|
func TestAgentMediaAdmissionPersistsOriginAndChargeAuthorization(t *testing.T) {
|
|
s, _, args := agentMediaFixture(t)
|
|
run, state := agentMediaRun(t, s, args, "auto")
|
|
req, _, err := s.prepareCloudAgentMedia(run, &state, agentMediaCall(args))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
req.admission = &taskAdmission{ID: "generation-task", MaxCharge: 1000, AgentRunID: run.ID, GenerationID: "generation", ApprovalID: "approval"}
|
|
req.creationPrepare = &creationTaskPreparation{}
|
|
task, err := s.CreateTask(run.UserID, req)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
order := req.creationPrepare.Order
|
|
if task.AgentRunID != run.ID || task.GenerationID != "generation" || task.ApprovalID != "approval" || order == nil || !order.ChargeLimitSet || task.AuthorizedChargeMicrocredits != order.AmountMicrocredits || order.ChargeLimitMicrocredits != order.AmountMicrocredits {
|
|
t.Fatalf("incomplete generation authorization: task=%+v order=%+v", task, order)
|
|
}
|
|
}
|
|
|
|
func TestAgentMediaRetryRequiresNewGenerationAuthorization(t *testing.T) {
|
|
s, db, _ := agentMediaFixture(t)
|
|
for _, task := range []model.Task{
|
|
{ID: "agent-run-only", AgentRunID: "run"},
|
|
{ID: "generation-only", GenerationID: "generation"},
|
|
{ID: "operation-prefix", Operation: "cloud_agent_media"},
|
|
{ID: "source", InputJSON: `{"metadata":{"source":"cloud_agent"}}`},
|
|
} {
|
|
task.UserID, task.Type, task.Status = "user", "canvas_video", model.TaskStatusFailed
|
|
if task.Operation == "" {
|
|
task.Operation = "image_to_video"
|
|
}
|
|
if task.InputJSON == "" {
|
|
task.InputJSON = `{}`
|
|
}
|
|
if err := db.Create(&task).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := s.RetryTask(task.UserID, task.ID); err == nil || !strings.Contains(err.Error(), "Agent 重试") {
|
|
t.Fatalf("media retry retained old authorization: %v", err)
|
|
}
|
|
stored, err := s.repo.Task(task.ID)
|
|
if err != nil || stored.Status != model.TaskStatusFailed || stored.BillingOrderID != "" {
|
|
t.Fatalf("retry changed old execution: %+v %v", stored, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOrdinaryFailedAndCancelledTasksKeepRetryIdentity(t *testing.T) {
|
|
s, db, _ := agentMediaFixture(t)
|
|
for _, status := range []model.TaskStatus{model.TaskStatusFailed, model.TaskStatusCancelled} {
|
|
task := model.Task{
|
|
ID: "ordinary-" + string(status),
|
|
UserID: "user",
|
|
Type: "canvas_text",
|
|
Operation: "text",
|
|
Status: status,
|
|
InputJSON: `{}`,
|
|
RouteRun: 3,
|
|
}
|
|
if err := db.Create(&task).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
retried, err := s.RetryTask(task.UserID, task.ID)
|
|
if err != nil {
|
|
t.Fatalf("ordinary %s task should remain retryable: %v", status, err)
|
|
}
|
|
if retried.ID != task.ID || retried.Status != model.TaskStatusQueued || retried.RouteRun != 4 || retried.GenerationID != "" || retried.AgentRunID != "" {
|
|
t.Fatalf("retry must reuse task execution identity without inventing an Agent generation: %+v", retried)
|
|
}
|
|
if _, err = s.RetryTask(task.UserID, task.ID); err == nil {
|
|
t.Fatal("queued retry was accepted a second time")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTaskCancellationPersistsFirstSourceAndDiagnostic(t *testing.T) {
|
|
s, db, _ := agentMediaFixture(t)
|
|
task := model.Task{ID: "cancel-child", UserID: "user", AgentRunID: "parent", Status: model.TaskStatusQueued}
|
|
if err := db.Create(&task).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := s.taskLifecycle().cancelTaskWithIntent(context.Background(), "user", task.ID, model.TaskCancellationIntent{Source: model.TaskCancellationParentFailed}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := s.CancelTask(context.Background(), "user", task.ID); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
stored, err := s.repo.Task(task.ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
diagnostic := taskExecutionDiagnostic(stored)
|
|
if stored.CancellationSource != model.TaskCancellationParentFailed || stored.CancellationRequestedAt == nil || diagnostic == nil || diagnostic.Phase != "cancellation" || diagnostic.SubmissionOutcome != "not_submitted" || diagnostic.TaskSubmitted {
|
|
t.Fatalf("cancellation lost facts: %+v %+v", stored, diagnostic)
|
|
}
|
|
}
|