225 lines
7.1 KiB
Go
225 lines
7.1 KiB
Go
package acp
|
|
|
|
import (
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"xworkmate-bridge/internal/gatewayruntime"
|
|
"xworkmate-bridge/internal/shared"
|
|
)
|
|
|
|
func TestApplyProductionGatewayRoutingPreservesGatewayURLPath(t *testing.T) {
|
|
t.Setenv("GATEWAY_RPC_URL", "ws://127.0.0.1:18789/gateway/openclaw")
|
|
server := NewServer()
|
|
|
|
request := applyProductionGatewayRouting(
|
|
server,
|
|
gatewayruntime.ConnectRequest{
|
|
Mode: "openclaw",
|
|
Endpoint: gatewayruntime.Endpoint{
|
|
Host: "xworkmate-bridge.svc.plus",
|
|
Port: 443,
|
|
TLS: true,
|
|
},
|
|
},
|
|
)
|
|
|
|
if request.Endpoint.Host != "127.0.0.1" {
|
|
t.Fatalf("expected gateway host from env, got %#v", request.Endpoint)
|
|
}
|
|
if request.Endpoint.Port != 18789 {
|
|
t.Fatalf("expected gateway port from env, got %#v", request.Endpoint)
|
|
}
|
|
if request.Endpoint.TLS {
|
|
t.Fatalf("expected plaintext local gateway endpoint, got %#v", request.Endpoint)
|
|
}
|
|
if request.Endpoint.Path != "/gateway/openclaw" {
|
|
t.Fatalf("expected gateway URL path to be preserved, got %#v", request.Endpoint)
|
|
}
|
|
}
|
|
|
|
func TestApplyProductionGatewayRoutingDefaultsOpenClawEndpoint(t *testing.T) {
|
|
t.Setenv("GATEWAY_RPC_URL", "")
|
|
t.Setenv("BRIDGE_CONFIG_PATH", filepath.Join(t.TempDir(), "missing-config.yaml"))
|
|
server := NewServer()
|
|
|
|
request := applyProductionGatewayRouting(
|
|
server,
|
|
gatewayruntime.ConnectRequest{Mode: "openclaw"},
|
|
)
|
|
|
|
if request.Endpoint.Host != "127.0.0.1" {
|
|
t.Fatalf("expected built-in gateway host, got %#v", request.Endpoint)
|
|
}
|
|
if request.Endpoint.Port != 18789 {
|
|
t.Fatalf("expected built-in gateway port, got %#v", request.Endpoint)
|
|
}
|
|
if request.Endpoint.TLS {
|
|
t.Fatalf("expected built-in gateway endpoint to use local plaintext, got %#v", request.Endpoint)
|
|
}
|
|
}
|
|
|
|
func TestSystemLogsConnectsProductionGatewayForStatus(t *testing.T) {
|
|
gateway := newAcpFakeOpenClawGateway(t)
|
|
defer gateway.Close()
|
|
|
|
t.Setenv("GATEWAY_RPC_URL", gateway.URL())
|
|
t.Setenv("BRIDGE_AUTH_TOKEN", "bridge-test-token")
|
|
t.Setenv("BRIDGE_CONFIG_PATH", filepath.Join(t.TempDir(), "missing-config.yaml"))
|
|
t.Setenv("XWORKMATE_BRIDGE_OPENCLAW_IDENTITY_PATH", filepath.Join(t.TempDir(), "openclaw-device.json"))
|
|
resetBridgeGatewayIdentityForTest()
|
|
t.Cleanup(resetBridgeGatewayIdentityForTest)
|
|
|
|
server := NewServer()
|
|
|
|
result, rpcErr := server.handleRequest(
|
|
shared.RPCRequest{
|
|
ID: "status",
|
|
Method: "system.logs",
|
|
Params: map[string]any{},
|
|
},
|
|
func(map[string]any) {},
|
|
)
|
|
if rpcErr != nil {
|
|
t.Fatalf("system.logs returned rpc error: %#v", rpcErr)
|
|
}
|
|
if got := result["gatewayStatus"]; got != "connected" {
|
|
t.Fatalf("expected gatewayStatus connected, got %#v", result)
|
|
}
|
|
if got := gateway.ConnectCount(); got != 1 {
|
|
t.Fatalf("expected one gateway connect attempt, got %d", got)
|
|
}
|
|
|
|
result, rpcErr = server.handleRequest(
|
|
shared.RPCRequest{
|
|
ID: "status-again",
|
|
Method: "system.logs",
|
|
Params: map[string]any{},
|
|
},
|
|
func(map[string]any) {},
|
|
)
|
|
if rpcErr != nil {
|
|
t.Fatalf("second system.logs returned rpc error: %#v", rpcErr)
|
|
}
|
|
if got := result["gatewayStatus"]; got != "connected" {
|
|
t.Fatalf("expected second gatewayStatus connected, got %#v", result)
|
|
}
|
|
if got := gateway.ConnectCount(); got != 1 {
|
|
t.Fatalf("expected connected status to reuse gateway session, got %d connect attempts", got)
|
|
}
|
|
}
|
|
|
|
func TestProductionGatewayReconnectsWithSharedTokenAfterDeviceTokenMismatch(t *testing.T) {
|
|
gateway := newAcpFakeOpenClawGateway(t)
|
|
defer gateway.Close()
|
|
gateway.rejectDeviceTokenOnce.Store(true)
|
|
|
|
identityPath := filepath.Join(t.TempDir(), "openclaw-device.json")
|
|
t.Setenv("GATEWAY_RPC_URL", gateway.URL())
|
|
t.Setenv("BRIDGE_AUTH_TOKEN", "bridge-test-token")
|
|
t.Setenv("BRIDGE_CONFIG_PATH", filepath.Join(t.TempDir(), "missing-config.yaml"))
|
|
t.Setenv("XWORKMATE_BRIDGE_OPENCLAW_IDENTITY_PATH", identityPath)
|
|
resetBridgeGatewayIdentityForTest()
|
|
t.Cleanup(resetBridgeGatewayIdentityForTest)
|
|
|
|
_ = newBridgeGatewayIdentity()
|
|
saveBridgeGatewayDeviceToken("stale-device-token")
|
|
server := NewServer()
|
|
|
|
result, rpcErr := server.handleRequest(
|
|
shared.RPCRequest{
|
|
ID: "status",
|
|
Method: "system.logs",
|
|
Params: map[string]any{},
|
|
},
|
|
func(map[string]any) {},
|
|
)
|
|
if rpcErr != nil {
|
|
t.Fatalf("system.logs returned rpc error: %#v", rpcErr)
|
|
}
|
|
if got := result["gatewayStatus"]; got != "connected" {
|
|
t.Fatalf("expected gatewayStatus connected after repair, got %#v", result)
|
|
}
|
|
if got := gateway.ConnectCount(); got != 2 {
|
|
t.Fatalf("expected stale device token retry with shared token, got %d connects", got)
|
|
}
|
|
resetBridgeGatewayIdentityForTest()
|
|
_, token := bridgeGatewayOpenClawCredentials()
|
|
if token != "device-token-1" {
|
|
t.Fatalf("expected repaired device token to be persisted, got %q", token)
|
|
}
|
|
}
|
|
|
|
func TestProductionGatewayReconnectPrefersAIWorkspaceToken(t *testing.T) {
|
|
gateway := newAcpFakeOpenClawGateway(t)
|
|
defer gateway.Close()
|
|
gateway.rejectDeviceTokenOnce.Store(true)
|
|
|
|
t.Setenv("GATEWAY_RPC_URL", gateway.URL())
|
|
t.Setenv("AI_WORKSPACE_AUTH_TOKEN", "ai-workspace-token")
|
|
t.Setenv("BRIDGE_AUTH_TOKEN", "bridge-test-token")
|
|
t.Setenv("BRIDGE_CONFIG_PATH", filepath.Join(t.TempDir(), "missing-config.yaml"))
|
|
t.Setenv("XWORKMATE_BRIDGE_OPENCLAW_IDENTITY_PATH", filepath.Join(t.TempDir(), "openclaw-device.json"))
|
|
resetBridgeGatewayIdentityForTest()
|
|
t.Cleanup(resetBridgeGatewayIdentityForTest)
|
|
|
|
_ = newBridgeGatewayIdentity()
|
|
saveBridgeGatewayDeviceToken("stale-device-token")
|
|
server := NewServer()
|
|
|
|
result, rpcErr := server.handleRequest(
|
|
shared.RPCRequest{
|
|
ID: "status",
|
|
Method: "system.logs",
|
|
Params: map[string]any{},
|
|
},
|
|
func(map[string]any) {},
|
|
)
|
|
if rpcErr != nil {
|
|
t.Fatalf("system.logs returned rpc error: %#v", rpcErr)
|
|
}
|
|
if got := result["gatewayStatus"]; got != "connected" {
|
|
t.Fatalf("expected gatewayStatus connected after AI workspace token repair, got %#v", result)
|
|
}
|
|
if got := gateway.ConnectCount(); got != 2 {
|
|
t.Fatalf("expected stale device token retry with AI workspace token, got %d connects", got)
|
|
}
|
|
}
|
|
|
|
func TestProductionGatewayDoesNotUseInternalServiceTokenFallback(t *testing.T) {
|
|
gateway := newAcpFakeOpenClawGateway(t)
|
|
defer gateway.Close()
|
|
gateway.rejectDeviceTokenOnce.Store(true)
|
|
|
|
t.Setenv("GATEWAY_RPC_URL", gateway.URL())
|
|
t.Setenv("AI_WORKSPACE_AUTH_TOKEN", "")
|
|
t.Setenv("BRIDGE_AUTH_TOKEN", "")
|
|
t.Setenv("INTERNAL_SERVICE_TOKEN", "bridge-test-token")
|
|
t.Setenv("BRIDGE_CONFIG_PATH", filepath.Join(t.TempDir(), "missing-config.yaml"))
|
|
t.Setenv("XWORKMATE_BRIDGE_OPENCLAW_IDENTITY_PATH", filepath.Join(t.TempDir(), "openclaw-device.json"))
|
|
resetBridgeGatewayIdentityForTest()
|
|
t.Cleanup(resetBridgeGatewayIdentityForTest)
|
|
|
|
_ = newBridgeGatewayIdentity()
|
|
saveBridgeGatewayDeviceToken("stale-device-token")
|
|
server := NewServer()
|
|
|
|
result, rpcErr := server.handleRequest(
|
|
shared.RPCRequest{
|
|
ID: "status",
|
|
Method: "system.logs",
|
|
Params: map[string]any{},
|
|
},
|
|
func(map[string]any) {},
|
|
)
|
|
if rpcErr != nil {
|
|
t.Fatalf("system.logs returned rpc error: %#v", rpcErr)
|
|
}
|
|
if got := result["gatewayStatus"]; got != "disconnected" {
|
|
t.Fatalf("expected gatewayStatus disconnected without AI workspace token, got %#v", result)
|
|
}
|
|
if got := gateway.ConnectCount(); got != 1 {
|
|
t.Fatalf("expected no retry with internal token, got %d connects", got)
|
|
}
|
|
}
|