Co-authored-by: shangguanxuan.sgx <shangguanxuan.sgx@alibaba-inc.com>
111 lines
3.5 KiB
Go
111 lines
3.5 KiB
Go
// Copyright 2026 Alibaba Group
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package auth
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestDeriveAgentID_Format(t *testing.T) {
|
|
id := deriveAgentID("machine-abc", "claudecode")
|
|
if !strings.HasPrefix(id, "dwsa_") {
|
|
t.Fatalf("want dwsa_ prefix, got %q", id)
|
|
}
|
|
if len(id) != len("dwsa_")+12 {
|
|
t.Fatalf("want 12 base62 chars after prefix, got %q (len %d)", id, len(id))
|
|
}
|
|
}
|
|
|
|
func TestDeriveAgentID_Deterministic(t *testing.T) {
|
|
a := deriveAgentID("seed", "claudecode")
|
|
b := deriveAgentID("seed", "claudecode")
|
|
if a != b {
|
|
t.Fatalf("derivation must be deterministic: %q != %q", a, b)
|
|
}
|
|
}
|
|
|
|
func TestDeriveAgentID_DistinctByChannelAndMachine(t *testing.T) {
|
|
m1c1 := deriveAgentID("machine1", "claudecode")
|
|
m1c2 := deriveAgentID("machine1", "cursor")
|
|
m2c1 := deriveAgentID("machine2", "claudecode")
|
|
if m1c1 == m1c2 {
|
|
t.Errorf("same machine, different channel must differ: %q", m1c1)
|
|
}
|
|
if m1c1 == m2c1 {
|
|
t.Errorf("different machine, same channel must differ: %q", m1c1)
|
|
}
|
|
}
|
|
|
|
func TestResolveAgentID_IdempotentAndPersisted(t *testing.T) {
|
|
dir := t.TempDir()
|
|
id := EnsureExists(dir)
|
|
|
|
first := id.ResolveAgentID(dir, "claudecode", "sig:CLAUDECODE")
|
|
second := id.ResolveAgentID(dir, "claudecode", "sig:CLAUDECODE")
|
|
if first != second {
|
|
t.Fatalf("ResolveAgentID must be idempotent: %q != %q", first, second)
|
|
}
|
|
|
|
// Reload from disk — the channel entry must have persisted.
|
|
reloaded := Load(dir)
|
|
if reloaded == nil {
|
|
t.Fatal("expected identity to persist")
|
|
}
|
|
e, ok := reloaded.Agents["claudecode"]
|
|
if !ok || e.AgentID != first {
|
|
t.Fatalf("persisted agentId mismatch: %+v", reloaded.Agents)
|
|
}
|
|
if e.Detect != "sig:CLAUDECODE" {
|
|
t.Errorf("want detect signal recorded, got %q", e.Detect)
|
|
}
|
|
}
|
|
|
|
func TestResolveAgentID_EmptyAgentCodeReturnsEmpty(t *testing.T) {
|
|
dir := t.TempDir()
|
|
id := EnsureExists(dir)
|
|
got := id.ResolveAgentID(dir, "", "fallback")
|
|
if got != "" {
|
|
t.Fatalf("empty agent_code must not derive an instance id, got %q", got)
|
|
}
|
|
}
|
|
|
|
// A v1 file ({agentId, source}) must migrate: machineId backfilled from the
|
|
// legacy agentId, and per-channel derivation keyed off that stable seed.
|
|
func TestLoad_MigratesV1(t *testing.T) {
|
|
dir := t.TempDir()
|
|
v1 := `{"agentId":"504ddd36-3acf-45f6-9c1f-82f99260a419","source":"dws"}`
|
|
if err := os.WriteFile(filepath.Join(dir, identityFile), []byte(v1), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
id := Load(dir)
|
|
if id == nil {
|
|
t.Fatal("v1 file should load")
|
|
}
|
|
if id.MachineID != "504ddd36-3acf-45f6-9c1f-82f99260a419" {
|
|
t.Fatalf("machineId must backfill from legacy agentId, got %q", id.MachineID)
|
|
}
|
|
if id.machineSeed() != id.MachineID {
|
|
t.Fatalf("seed should be machineId, got %q", id.machineSeed())
|
|
}
|
|
// Derivation is stable against the migrated seed.
|
|
want := deriveAgentID(id.MachineID, "claudecode")
|
|
if got := id.ResolveAgentID(dir, "claudecode", "sig:CLAUDECODE"); got != want {
|
|
t.Fatalf("post-migration derivation mismatch: %q != %q", got, want)
|
|
}
|
|
}
|