package opensandboxbackend import ( "context" "testing" runnerv1 "gitea.dev/actionslib/runner/v1" opensandbox "github.com/alibaba/OpenSandbox/sdks/sandbox/go" "git.ddupan.top/panxiao81/gitea-dynamic-runner/internal/taskassignment" "git.ddupan.top/panxiao81/gitea-dynamic-runner/internal/taskidentity" "git.ddupan.top/panxiao81/gitea-dynamic-runner/internal/taskworker" ) type fakeLifecycle struct { items []opensandbox.SandboxInfo created opensandbox.CreateSandboxRequest deleted string } func (f *fakeLifecycle) ListSandboxes(context.Context, opensandbox.ListOptions) (*opensandbox.ListSandboxesResponse, error) { return &opensandbox.ListSandboxesResponse{Items: f.items}, nil } func (f *fakeLifecycle) CreateSandbox(_ context.Context, request opensandbox.CreateSandboxRequest) (*opensandbox.SandboxInfo, error) { f.created = request return &opensandbox.SandboxInfo{ID: "sandbox-42", Status: opensandbox.SandboxStatus{State: opensandbox.StatePending}, Metadata: request.Metadata}, nil } func (f *fakeLifecycle) GetSandbox(_ context.Context, id string) (*opensandbox.SandboxInfo, error) { for _, item := range f.items { if item.ID == id { return &item, nil } } return &opensandbox.SandboxInfo{ID: id, Metadata: map[string]string{"ci.ddupan.top/spiffe-id": assignment().Identity.SPIFFEID}}, nil } func (f *fakeLifecycle) DeleteSandbox(_ context.Context, id string) error { f.deleted = id; return nil } func backend(lifecycle Lifecycle) Backend { return Backend{Lifecycle: lifecycle, Config: Config{ Pool: "ci-vm", Timeout: 14400, Entrypoint: []string{"/usr/local/bin/gitea-task-executor"}, Env: map[string]string{"SPIFFE_ENDPOINT_SOCKET": "unix:///run/spire/agent-sockets/spire-agent.sock"}, }} } func assignment() taskassignment.Assignment { return taskassignment.Assignment{ ID: "gitea-task-42", Backend: taskassignment.BackendVM, Task: &runnerv1.Task{Id: 42}, Identity: taskidentity.Identity{Repository: "owner/repo", Task: "publish", SPIFFEID: "spiffe://ddupan.top/ci/owner/repo/publish"}, } } func TestFindRecoversSandboxByMetadata(t *testing.T) { lifecycle := &fakeLifecycle{items: []opensandbox.SandboxInfo{{ID: "sandbox-42", Status: opensandbox.SandboxStatus{State: opensandbox.StateRunning}}}} executor, err := backend(lifecycle).Find(context.Background(), assignment().ID) if err != nil || executor.Name != "sandbox-42" || executor.Phase != taskworker.PhaseRunning { t.Fatalf("executor=%#v err=%v", executor, err) } } func TestCreateUsesPoolAndPersistsRecoveryMetadata(t *testing.T) { lifecycle := &fakeLifecycle{} metadata := taskworker.BackendMetadata(assignment()) executor, err := backend(lifecycle).Create(context.Background(), assignment(), taskworker.LaunchSpec{ Metadata: metadata, Environment: map[string]string{ "CI_SPIFFE_ID": assignment().Identity.SPIFFEID, "CI_RUNNER_CAPABILITY": "capability", }, }) if err != nil { t.Fatal(err) } if lifecycle.created.Extensions["poolRef"] != "ci-vm" || lifecycle.created.Metadata[assignmentMetadata] != assignment().ID || lifecycle.created.Env["CI_SPIFFE_ID"] != assignment().Identity.SPIFFEID || executor.Name != "sandbox-42" { t.Fatalf("request=%#v executor=%#v", lifecycle.created, executor) } if lifecycle.created.Env["CI_RUNNER_CAPABILITY"] != "capability" { t.Fatalf("environment = %#v", lifecycle.created.Env) } } func TestBindIdentityVerifiesPersistedMetadata(t *testing.T) { lifecycle := &fakeLifecycle{} if err := backend(lifecycle).BindIdentity(context.Background(), &taskworker.Executor{Name: "sandbox-42"}, assignment().Identity); err != nil { t.Fatal(err) } }