first commit
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"browser.local/platform/domain"
|
||||
"browser.local/platform/repo"
|
||||
)
|
||||
|
||||
func TestCoreServiceRegistersNewRunControlSession(t *testing.T) {
|
||||
svc := newTestCoreService()
|
||||
|
||||
result, err := svc.RegisterRunHello(validRunControlHello())
|
||||
if err != nil {
|
||||
t.Fatalf("register hello: %v", err)
|
||||
}
|
||||
if !result.Accepted || result.SessionToken == "" || result.HeartbeatIntervalSeconds <= 0 {
|
||||
t.Fatalf("expected accepted hello response, got %+v", result)
|
||||
}
|
||||
|
||||
endpoint, err := svc.GetRunEndpoint("run-local")
|
||||
if err != nil {
|
||||
t.Fatalf("get registered endpoint: %v", err)
|
||||
}
|
||||
if endpoint.Status != domain.RunEndpointStatusOnline || !endpoint.LastHeartbeatAt.Equal(fixedTime) {
|
||||
t.Fatalf("expected online endpoint with heartbeat time, got %+v", endpoint)
|
||||
}
|
||||
if len(endpoint.Capabilities) != 2 || endpoint.Capacity.MaxJobs != 4 {
|
||||
t.Fatalf("expected capabilities and capacity, got %+v", endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreServiceReRegistersExistingRunEndpoint(t *testing.T) {
|
||||
svc := newTestCoreService()
|
||||
first, err := svc.RegisterRunHello(validRunControlHello())
|
||||
if err != nil {
|
||||
t.Fatalf("register first hello: %v", err)
|
||||
}
|
||||
|
||||
hello := validRunControlHello()
|
||||
hello.DisplayName = "Local Run Updated"
|
||||
hello.Version = "0.2.0"
|
||||
hello.CapabilityReport.Capabilities = []string{"control.hello", "control.heartbeat", "jobs.claim"}
|
||||
hello.CapabilityReport.Fingerprint = "cap-v2"
|
||||
second, err := svc.RegisterRunHello(hello)
|
||||
if err != nil {
|
||||
t.Fatalf("register second hello: %v", err)
|
||||
}
|
||||
if second.SessionToken == first.SessionToken {
|
||||
t.Fatalf("expected re-registration to issue a new token, got %q", second.SessionToken)
|
||||
}
|
||||
|
||||
endpoint, err := svc.GetRunEndpoint("run-local")
|
||||
if err != nil {
|
||||
t.Fatalf("get re-registered endpoint: %v", err)
|
||||
}
|
||||
if endpoint.DisplayName != "Local Run Updated" || endpoint.Version != "0.2.0" || len(endpoint.Capabilities) != 3 {
|
||||
t.Fatalf("expected endpoint metadata update, got %+v", endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreServiceAcceptsRunHeartbeat(t *testing.T) {
|
||||
svc := newTestCoreService()
|
||||
hello, err := svc.RegisterRunHello(validRunControlHello())
|
||||
if err != nil {
|
||||
t.Fatalf("register hello: %v", err)
|
||||
}
|
||||
|
||||
result, err := svc.AcceptRunHeartbeat(domain.RunControlHeartbeat{
|
||||
RunEndpointID: "run-local",
|
||||
SessionToken: hello.SessionToken,
|
||||
Version: "0.1.1",
|
||||
Status: domain.RunEndpointStatusDegraded,
|
||||
CapabilityFingerprint: "cap-v1",
|
||||
Capacity: domain.RunCapacity{MaxJobs: 4, RunningJobs: 2, QueuedJobs: 1},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("accept heartbeat: %v", err)
|
||||
}
|
||||
if !result.Accepted || result.RefreshCapabilities {
|
||||
t.Fatalf("expected accepted heartbeat without refresh, got %+v", result)
|
||||
}
|
||||
|
||||
endpoint, err := svc.GetRunEndpoint("run-local")
|
||||
if err != nil {
|
||||
t.Fatalf("get heartbeat endpoint: %v", err)
|
||||
}
|
||||
if endpoint.Status != domain.RunEndpointStatusDegraded || endpoint.Version != "0.1.1" || endpoint.Capacity.RunningJobs != 2 {
|
||||
t.Fatalf("expected heartbeat metadata update, got %+v", endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreServiceRejectsInvalidRunHeartbeatToken(t *testing.T) {
|
||||
svc := newTestCoreService()
|
||||
if _, err := svc.RegisterRunHello(validRunControlHello()); err != nil {
|
||||
t.Fatalf("register hello: %v", err)
|
||||
}
|
||||
|
||||
_, err := svc.AcceptRunHeartbeat(domain.RunControlHeartbeat{
|
||||
RunEndpointID: "run-local",
|
||||
SessionToken: "stale-token",
|
||||
Version: "0.1.1",
|
||||
Status: domain.RunEndpointStatusOnline,
|
||||
CapabilityFingerprint: "cap-v1",
|
||||
Capacity: domain.RunCapacity{MaxJobs: 4, RunningJobs: 3},
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "sessionToken is invalid") {
|
||||
t.Fatalf("expected invalid token rejection, got %v", err)
|
||||
}
|
||||
|
||||
endpoint, err := svc.GetRunEndpoint("run-local")
|
||||
if err != nil {
|
||||
t.Fatalf("get endpoint after rejected heartbeat: %v", err)
|
||||
}
|
||||
if endpoint.Capacity.RunningJobs != 0 || endpoint.Version != "0.1.0" {
|
||||
t.Fatalf("heartbeat with invalid token must not update endpoint, got %+v", endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreServiceRejectsInvalidRunControlHello(t *testing.T) {
|
||||
svc := newTestCoreService()
|
||||
invalid := validRunControlHello()
|
||||
invalid.RegistrationToken = ""
|
||||
invalid.Capacity.RunningJobs = 8
|
||||
|
||||
_, err := svc.RegisterRunHello(invalid)
|
||||
if err == nil || !strings.Contains(err.Error(), "registrationToken") || !strings.Contains(err.Error(), "runningJobs") {
|
||||
t.Fatalf("expected validation errors, got %v", err)
|
||||
}
|
||||
if _, err := svc.GetRunEndpoint("run-local"); !errors.Is(err, repo.ErrNotFound) {
|
||||
t.Fatalf("invalid hello must not create endpoint, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreServiceRequestsCapabilityRefreshOnFingerprintDrift(t *testing.T) {
|
||||
svc := newTestCoreService()
|
||||
hello, err := svc.RegisterRunHello(validRunControlHello())
|
||||
if err != nil {
|
||||
t.Fatalf("register hello: %v", err)
|
||||
}
|
||||
|
||||
result, err := svc.AcceptRunHeartbeat(domain.RunControlHeartbeat{
|
||||
RunEndpointID: "run-local",
|
||||
SessionToken: hello.SessionToken,
|
||||
Version: "0.1.0",
|
||||
Status: domain.RunEndpointStatusOnline,
|
||||
CapabilityFingerprint: "cap-v2",
|
||||
Capacity: domain.RunCapacity{MaxJobs: 4},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("accept drift heartbeat: %v", err)
|
||||
}
|
||||
if !result.RefreshCapabilities {
|
||||
t.Fatalf("expected capability refresh request, got %+v", result)
|
||||
}
|
||||
|
||||
result, err = svc.AcceptRunHeartbeat(domain.RunControlHeartbeat{
|
||||
RunEndpointID: "run-local",
|
||||
SessionToken: hello.SessionToken,
|
||||
Version: "0.1.0",
|
||||
Status: domain.RunEndpointStatusOnline,
|
||||
CapabilityFingerprint: "cap-v2",
|
||||
Capacity: domain.RunCapacity{MaxJobs: 4},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("accept stable heartbeat: %v", err)
|
||||
}
|
||||
if result.RefreshCapabilities {
|
||||
t.Fatalf("expected refreshed fingerprint to become known, got %+v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func validRunControlHello() domain.RunControlHello {
|
||||
return domain.RunControlHello{
|
||||
RegistrationToken: "registration-token",
|
||||
RunEndpointID: "run-local",
|
||||
DisplayName: "Local Run",
|
||||
Version: "0.1.0",
|
||||
Status: domain.RunEndpointStatusOnline,
|
||||
Platform: "darwin/arm64",
|
||||
CapabilityReport: domain.RunCapabilityReport{
|
||||
Capabilities: []string{"control.hello", "control.heartbeat"},
|
||||
Fingerprint: "cap-v1",
|
||||
},
|
||||
Capacity: domain.RunCapacity{MaxJobs: 4},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user