Files
heranran 71c7672545 feat: Skill Hub hardening with session usage tracking and egress governance (#163)
* feat(skill-hub): add Skill Hub catalog, publish flow, and lite materialize pipeline

Introduce Skill Hub for browsing, importing, publishing, and installing skills, with lite instance package materialization and runtime sync support.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skill-hub): remove token-governance hooks from Skill Hub PR

Strip validateManagedRuntimeEnvironmentOverrides, network lock policy sync,
and egress proxy audit wiring that belong to the upcoming token-usage work,
so the Skill Hub branch compiles independently.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skill-hub): update migration number in materialize docs

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skill-hub): make RuntimeAgentClient test stub and hub tests compile-safe

Add ResyncInstanceSkills to the runtime pool handler fake client, and harden
skill hub payload helpers/tests against nil storage/instance repos so go test passes.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat: add Skill Hub hardening with session usage tracking and egress governance

Unify Skill Hub runtime sync improvements with session-token observability,
egress network policy, and admin/instance usage reporting for reopenable PR.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skill-hub): repair CI tests and nested skill install

* fix(ci): restore release deployment configuration

---------

Co-authored-by: heshengran <heshengran@ieisystem.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 12:37:01 +08:00

121 lines
3.8 KiB
Go

package services
import (
"strings"
"testing"
"clawreef/internal/models"
)
func TestValidateManagedRuntimeEnvironmentOverridesRejectsProtectedKeys(t *testing.T) {
err := validateManagedRuntimeEnvironmentOverrides("openclaw", map[string]string{
"OPENAI_BASE_URL": "https://api.openai.com/v1",
})
if err == nil {
t.Fatal("expected protected env override to be rejected")
}
}
func TestApplyProtectedManagedRuntimeEnvRestoresGatewayValues(t *testing.T) {
target := map[string]string{
"OPENAI_BASE_URL": "https://api.openai.com/v1",
"CUSTOM": "value",
}
protected := map[string]string{
"OPENAI_BASE_URL": "http://gateway.example/api/v1/gateway/llm",
}
result := applyProtectedManagedRuntimeEnv(target, protected)
if result["OPENAI_BASE_URL"] != protected["OPENAI_BASE_URL"] {
t.Fatalf("expected protected gateway url, got %q", result["OPENAI_BASE_URL"])
}
if result["CUSTOM"] != "value" {
t.Fatalf("expected custom override to remain")
}
}
func TestValidateManagedRuntimeEnvironmentOverridesAllowsCustomKeys(t *testing.T) {
err := validateManagedRuntimeEnvironmentOverrides("openclaw", map[string]string{
"CUSTOM_FLAG": "1",
})
if err != nil {
t.Fatalf("expected custom override to be allowed, got %v", err)
}
}
func TestNormalizeEnvironmentOverridesRejectsInvalidNames(t *testing.T) {
if _, err := normalizeEnvironmentOverrides(map[string]string{
"1INVALID": "value",
}); err == nil {
t.Fatalf("expected invalid environment variable name to fail validation")
}
}
func TestBuildInstancePodEnvAppliesOverridesAfterDefaults(t *testing.T) {
t.Setenv("CLAWMANAGER_EGRESS_PROXY_URL", "")
t.Setenv("CLAWMANAGER_SYSTEM_NAMESPACE", "")
t.Setenv("K8S_NAMESPACE", "")
raw, err := marshalEnvironmentOverrides(map[string]string{
"SUBFOLDER": "/custom-proxy",
"KASM_SVC_ACCEPT_CUT_TEXT": "-AcceptCutText 1",
"SELKIES_CLIPBOARD_ENABLED": "true|locked",
"SELKIES_CLIPBOARD_IN_ENABLED": "true|locked",
"SELKIES_CLIPBOARD_OUT_ENABLED": "true|locked",
"CUSTOM": "enabled",
})
if err != nil {
t.Fatalf("marshalEnvironmentOverrides returned error: %v", err)
}
instance := &models.Instance{
ID: 42,
Type: "webtop",
EnvironmentOverridesJSON: raw,
}
env, err := buildInstancePodEnv(instance, defaultWebtopDesktopEnv("ClawManager Webtop"), nil, nil)
if err != nil {
t.Fatalf("buildInstancePodEnv returned error: %v", err)
}
if env["SUBFOLDER"] != "/custom-proxy" {
t.Fatalf("expected SUBFOLDER override to win, got %q", env["SUBFOLDER"])
}
if env["KASM_SVC_ACCEPT_CUT_TEXT"] != "-AcceptCutText 1" {
t.Fatalf("expected clipboard policy override to win, got %q", env["KASM_SVC_ACCEPT_CUT_TEXT"])
}
for _, key := range []string{
"SELKIES_CLIPBOARD_ENABLED",
"SELKIES_CLIPBOARD_IN_ENABLED",
"SELKIES_CLIPBOARD_OUT_ENABLED",
} {
if got := env[key]; got != "true|locked" {
t.Fatalf("expected %s override to win, got %q", key, got)
}
}
if env["CUSTOM"] != "enabled" {
t.Fatalf("expected custom environment variable to be merged")
}
if env["TITLE"] != "ClawManager Webtop" {
t.Fatalf("expected default environment variable to remain available")
}
}
func TestValidateManagedRuntimeEnvironmentOverridesSkipsNonManagedTypes(t *testing.T) {
err := validateManagedRuntimeEnvironmentOverrides("ubuntu", map[string]string{
"OPENAI_BASE_URL": "https://api.openai.com/v1",
})
if err != nil {
t.Fatalf("expected non-managed type to skip validation, got %v", err)
}
}
func TestValidateManagedRuntimeEnvironmentOverridesErrorMessage(t *testing.T) {
err := validateManagedRuntimeEnvironmentOverrides("openclaw", map[string]string{
"openai_api_key": "sk-test",
})
if err == nil || !strings.Contains(err.Error(), "OPENAI_API_KEY") {
t.Fatalf("expected normalized key in error, got %v", err)
}
}