// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package tentacle import ( "encoding/json" "errors" "strings" "sync" "testing" "time" "git.stormux.org/storm/cthulhu/internal/tentaclewire" ) func keyRequest(lease tentaclewire.RemoteLease, sequence uint64, pressed bool) tentaclewire.RemoteKeyRequest { return tentaclewire.RemoteKeyRequest{RemoteOperation: tentaclewire.RemoteOperation{ Lease: lease.Lease, Epoch: lease.Epoch, Sequence: sequence}, Key: tentaclewire.RemoteKey{Name: "Control_R", Pressed: pressed}} } func TestRemoteKeySDKMailboxAndSequence(t *testing.T) { for _, language := range []string{"go", "python"} { t.Run(language, func(t *testing.T) { manager := test_manager(t, DefaultLimits(), nil) session := startSessionSDK(t, manager, language, "keys", "keyboard-inject") lease := speech_fixture_lease(t, session, "controlled", []string{"keyboard-inject"}) request := keyRequest(lease, 1, true) if _, code := remoteCall(t, session, "remote.key", request); code != -32601 { t.Fatal("accepted keys without reader input owner", code) } deliveries := session.EnableRemoteKeys() if session.EnableRemoteKeys() != deliveries { t.Fatal("attachment created another owner mailbox") } if _, code := remoteCall(t, session, "remote.key", request); code != 0 { t.Fatal("valid key was not admitted", code) } first := <-deliveries if first.Key != request.Key || first.Sequence != 1 || first.Lease != lease || first.Context.Err() != nil { t.Fatal("delivery changed key identity, sequence or lifetime") } if _, err := session.RemoteContext(first.Lease, "keyboard-inject"); err != nil { t.Fatal("delivery lost original consent", err) } if _, code := remoteCall(t, session, "remote.key", request); code != -32001 { t.Fatal("replayed key was accepted", code) } request.Sequence++ if _, code := remoteCall(t, session, "remote.heartbeat", request.RemoteOperation); code != 0 { t.Fatal("heartbeat did not share the operation sequence", code) } if _, code := remoteCall(t, session, "remote.key", request); code != -32001 { t.Fatal("key reused heartbeat sequence", code) } request.Sequence++ request.Key.Pressed = false if _, code := remoteCall(t, session, "remote.key", request); code != 0 { t.Fatal("key release was not admitted", code) } second := <-deliveries if second.Key != request.Key || second.Sequence != request.Sequence { t.Fatal("lost release ordering") } firstBytes, _ := json.Marshal(keyRequest(lease, 1, true)) secondBytes, _ := json.Marshal(request) session.mutex.Lock() items, bytes := session.remote.keyItems, session.remote.keyBytes session.mutex.Unlock() if items != 2 || bytes != len(firstBytes)+len(secondBytes) { t.Fatal("in-flight accounting omitted request metadata", items, bytes) } var releases sync.WaitGroup for range 8 { releases.Add(1) go func() { defer releases.Done(); first.Release(); second.Release() }() } releases.Wait() session.mutex.Lock() items, bytes = session.remote.keyItems, session.remote.keyBytes session.mutex.Unlock() if items != 0 || bytes != 0 { t.Fatal("idempotent concurrent release retained capacity", items, bytes) } }) } } func TestRemoteKeySDKPermissionAndParameters(t *testing.T) { for _, language := range []string{"go", "python"} { t.Run(language, func(t *testing.T) { manager := test_manager(t, DefaultLimits(), nil) session := startSessionSDK(t, manager, language, "keys", "keyboard-inject") deliveries := session.EnableRemoteKeys() lease := speech_fixture_lease(t, session, "controller", []string{"remote-present"}) if _, code := remoteCall(t, session, "remote.key", keyRequest(lease, 1, true)); code != -32001 { t.Fatal("controller role injected input", code) } lease = speech_fixture_lease(t, session, "controlled", []string{"output-observe"}) if _, code := remoteCall(t, session, "remote.key", keyRequest(lease, 1, true)); code != -32001 { t.Fatal("output grant allowed input", code) } lease = speech_fixture_lease(t, session, "controlled", []string{"keyboard-inject"}) request := keyRequest(lease, 1, true) for _, foreign := range []tentaclewire.RemoteKeyRequest{ keyRequest(tentaclewire.RemoteLease{Lease: strings.Repeat("f", 32), Epoch: lease.Epoch}, 1, true), keyRequest(tentaclewire.RemoteLease{Lease: lease.Lease, Epoch: lease.Epoch + 1}, 1, true), } { if _, code := remoteCall(t, session, "remote.key", foreign); code != -32001 { t.Fatal("foreign lease/epoch admitted input", code) } } other := startSessionSDK(t, manager, language, "other-keys", "keyboard-inject") other.EnableRemoteKeys() if _, code := remoteCall(t, other, "remote.key", request); code != -32001 { t.Fatal("foreign process used another session's lease", code) } data, _ := json.Marshal(request) for _, raw := range []string{ strings.Replace(string(data), `"pressed":true`, `"pressed":null`, 1), strings.Replace(string(data), `"name":"Control_R"`, `"name":"unknown private value"`, 1), strings.Replace(string(data), `"sequence":1`, `"sequence":1,"origin":"local"`, 1), strings.Replace(string(data), `"sequence":1`, `"sequence":0`, 1), } { if _, code := remoteCall(t, session, "remote.key", json.RawMessage(raw)); code != -32602 { t.Fatal("invalid key parameters were admitted", code) } } if len(deliveries) != 0 { t.Fatal("denied or invalid input reached the owner") } if _, code := remoteCall(t, session, "remote.key", request); code != 0 { t.Fatal("denied requests consumed the live operation sequence", code) } (<-deliveries).Release() }) } } func TestRemoteKeySDKOverflowRetiresInFlightWork(t *testing.T) { for _, language := range []string{"go", "python"} { t.Run(language, func(t *testing.T) { session := startSessionSDK(t, test_manager(t, DefaultLimits(), nil), language, "keys", "keyboard-inject") lease := speech_fixture_lease(t, session, "controlled", []string{"keyboard-inject"}) deliveries := session.EnableRemoteKeys() request := keyRequest(lease, 1, true) if _, code := remoteCall(t, session, "remote.key", request); code != 0 { t.Fatal(code) } inFlight := <-deliveries // Dequeue must not free input capacity. session.mutex.Lock() old := session.remote session.mutex.Unlock() for index := 2; index <= tentaclewire.RemoteKeyQueueSize; index++ { request.Sequence++ if index%32 == 0 { if _, code := remoteCall(t, session, "remote.heartbeat", request.RemoteOperation); code != 0 { t.Fatal(code) } request.Sequence++ } if _, code := remoteCall(t, session, "remote.key", request); code != 0 { t.Fatal("input capacity ended early", index, code) } } request.Sequence++ request.Key.Pressed = false if _, code := remoteCall(t, session, "remote.key", request); code != -32002 { t.Fatal("full queue silently lost a release", code) } if inFlight.Context.Err() == nil { t.Fatal("overflow retained in-flight authority") } if _, err := session.RemoteContext(lease, "keyboard-inject"); !errors.Is(err, ErrPermission) { t.Fatal("overflow retained input consent", err) } inFlight.Release() inFlight.Release() session.mutex.Lock() defer session.mutex.Unlock() if session.remote != nil || old.keyItems != 0 || old.keyBytes != 0 || len(deliveries) != 0 { t.Fatal("overflow retained queued input or accounting") } }) } } func TestRemoteKeySDKRetirementAndReplacement(t *testing.T) { for _, language := range []string{"go", "python"} { for _, reason := range []string{"local", "close", "replace", "expire", "disable", "failure", "policy"} { t.Run(language+"/"+reason, func(t *testing.T) { manager := test_manager(t, DefaultLimits(), nil) policy := NewRemotePolicy() if err := manager.UseRemotePolicy(policy); err != nil { t.Fatal(err) } session := startSessionSDK(t, manager, language, "keys", "keyboard-inject") lease := speech_fixture_lease(t, session, "controlled", []string{"keyboard-inject"}) deliveries := session.EnableRemoteKeys() for sequence := uint64(1); sequence <= 2; sequence++ { if _, code := remoteCall(t, session, "remote.key", keyRequest(lease, sequence, true)); code != 0 { t.Fatal(code) } } inFlight := <-deliveries session.mutex.Lock() old := session.remote session.mutex.Unlock() switch reason { case "local": session.RevokeRemote() case "close": if _, code := remoteCall(t, session, "remote.close", keyRequest(lease, 3, false).RemoteOperation); code != 0 { t.Fatal(code) } case "replace": fresh := speech_fixture_lease(t, session, "controlled", []string{"keyboard-inject"}) if _, code := remoteCall(t, session, "remote.key", keyRequest(fresh, 1, true)); code != 0 { t.Fatal(code) } replacement := <-deliveries inFlight.Release() // Must not release the replacement budget. session.mutex.Lock() count := session.remote.keyItems session.mutex.Unlock() if count != 1 || replacement.Context.Err() != nil { t.Fatal("stale release affected replacement work") } replacement.Release() case "expire", "policy": session.mutex.Lock() if reason == "expire" { session.refresh_remote_locked(time.Millisecond) } else { policy.SetAvailable(false) if inFlight.Context.Err() == nil { session.mutex.Unlock() t.Fatal("policy cancellation waited for a session worker") } policy.SetAvailable(true) } session.mutex.Unlock() var event tentaclewire.SessionEvent if json.Unmarshal(invokeSessionSDK(t, session, "event", nil), &event) != nil || event.Kind != "remote.revoked" || event.Epoch != lease.Epoch { t.Fatal("missing original-epoch retirement notification") } case "disable": session.Disable() case "failure": session.fail(ErrProtocol) } if inFlight.Context.Err() == nil { t.Fatal("retired input survived") } if _, err := session.RemoteContext(lease, "keyboard-inject"); !errors.Is(err, ErrPermission) { t.Fatal("retired input passed delivery-time consent check") } inFlight.Release() inFlight.Release() session.mutex.Lock() defer session.mutex.Unlock() if old.keyItems != 0 || old.keyBytes != 0 || len(deliveries) != 0 { t.Fatal("retirement retained pending input/accounting") } }) } } }