Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions pkg/agent/config_compat_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package agent

import (
"testing"
)

func TestGetConfigManager(t *testing.T) {
// GetConfigManager should return a non-nil *ConfigManager singleton
cm := GetConfigManager()
if cm == nil {
t.Fatal("GetConfigManager() returned nil")
}

// Calling again should return the same singleton
cm2 := GetConfigManager()
if cm != cm2 {
t.Error("GetConfigManager() did not return the same singleton on second call")
}
}

func TestGetBaseURLEnvKeyForProvider(t *testing.T) {
tests := []struct {
provider string
wantNon bool // expect non-empty result
}{
{"ollama", true},
{"llamacpp", true},
{"localai", true},
{"vllm", true},
{"lm-studio", true},
{"nonexistent-provider", false},
}

for _, tt := range tests {
t.Run(tt.provider, func(t *testing.T) {
got := getBaseURLEnvKeyForProvider(tt.provider)
if tt.wantNon && got == "" {
t.Errorf("getBaseURLEnvKeyForProvider(%q) = empty, want non-empty", tt.provider)
}
if !tt.wantNon && got != "" {
t.Errorf("getBaseURLEnvKeyForProvider(%q) = %q, want empty", tt.provider, got)
}
})
}
}

func TestGetEnvKeyForProvider(t *testing.T) {
tests := []struct {
provider string
wantNon bool
}{
{"claude", true},
{"openai", true},
{"gemini", true},
{"nonexistent-provider", false},
}

for _, tt := range tests {
t.Run(tt.provider, func(t *testing.T) {
got := getEnvKeyForProvider(tt.provider)
if tt.wantNon && got == "" {
t.Errorf("getEnvKeyForProvider(%q) = empty, want non-empty", tt.provider)
}
if !tt.wantNon && got != "" {
t.Errorf("getEnvKeyForProvider(%q) = %q, want empty", tt.provider, got)
}
})
}
}

func TestGetModelEnvKeyForProvider(t *testing.T) {
tests := []struct {
provider string
wantNon bool
}{
{"ollama", true},
{"openai", true},
{"nonexistent-provider", false},
}

for _, tt := range tests {
t.Run(tt.provider, func(t *testing.T) {
got := getModelEnvKeyForProvider(tt.provider)
if tt.wantNon && got == "" {
t.Errorf("getModelEnvKeyForProvider(%q) = empty, want non-empty", tt.provider)
}
if !tt.wantNon && got != "" {
t.Errorf("getModelEnvKeyForProvider(%q) = %q, want empty", tt.provider, got)
}
})
}
}

func TestIsolateConfigManager(t *testing.T) {
// isolateConfigManager should return a non-nil *ConfigManager for test isolation
cm := isolateConfigManager(t)
if cm == nil {
t.Fatal("isolateConfigManager(t) returned nil")
}
}
62 changes: 62 additions & 0 deletions pkg/agent/kagent_compat_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package agent

import (
"testing"

"k8s.io/apimachinery/pkg/runtime/schema"
)

func TestKagentGVRsNonEmpty(t *testing.T) {
// All kagent GVR delegations should resolve to non-empty GroupVersionResource
gvrs := map[string]schema.GroupVersionResource{
"agentGVR": agentGVR,
"modelConfigGVR": modelConfigGVR,
"modelProviderConfigGVR": modelProviderConfigGVR,
"toolServerGVR": toolServerGVR,
"remoteMCPServerGVR": remoteMCPServerGVR,
"memoryGVR": memoryGVR,
}

for name, gvr := range gvrs {
t.Run(name, func(t *testing.T) {
if gvr.Group == "" {
t.Errorf("%s has empty Group", name)
}
if gvr.Version == "" {
t.Errorf("%s has empty Version", name)
}
if gvr.Resource == "" {
t.Errorf("%s has empty Resource", name)
}
})
}
}

func TestKagentTypeAliases(t *testing.T) {
// Verify type aliases compile and can hold zero values
var agent kagentCRDAgent
if agent.Name != "" {
t.Error("zero-value kagentCRDAgent should have empty Name")
}

var tool kagentCRDTool
_ = tool

var model kagentCRDModel
_ = model

var memory kagentCRDMemory
_ = memory

var iAgent kagentiAgent
_ = iAgent

var build kagentiBuild
_ = build

var card kagentiCard
_ = card

var iTool kagentiTool
_ = iTool
}
31 changes: 31 additions & 0 deletions pkg/agent/procgroup_compat_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//go:build !windows

package agent

import (
"os/exec"
"testing"
)

func TestConfigureProcessGroup(t *testing.T) {
// configureProcessGroup should not panic on a valid Cmd
cmd := exec.Command("echo", "test")
configureProcessGroup(cmd)

// Verify SysProcAttr was set (on Unix, this sets Setpgid)
if cmd.SysProcAttr == nil {
t.Error("configureProcessGroup did not set SysProcAttr")
}
if !cmd.SysProcAttr.Setpgid {
t.Error("configureProcessGroup did not set Setpgid=true")
}
}

func TestConfigureProcessGroupNilFields(t *testing.T) {
// Should handle a freshly created Cmd without panicking
cmd := &exec.Cmd{Path: "/bin/echo"}
configureProcessGroup(cmd)
if cmd.SysProcAttr == nil {
t.Error("configureProcessGroup did not set SysProcAttr on bare Cmd")
}
}
Comment on lines +5 to +31
97 changes: 97 additions & 0 deletions pkg/agent/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package agent

import (
"testing"
)

func TestProviderTypeAliases(t *testing.T) {
// Verify the capability constants are correctly re-exported
if CapabilityChat == 0 {
t.Error("CapabilityChat should be non-zero")
}
if CapabilityToolExec == 0 {
t.Error("CapabilityToolExec should be non-zero")
}
if CapabilityChat == CapabilityToolExec {
t.Error("CapabilityChat and CapabilityToolExec should be distinct")
}
}

func TestCapabilityHasCapability(t *testing.T) {
both := CapabilityChat | CapabilityToolExec
if !both.HasCapability(CapabilityChat) {
t.Error("combined capability should include CapabilityChat")
}
if !both.HasCapability(CapabilityToolExec) {
t.Error("combined capability should include CapabilityToolExec")
}
if CapabilityChat.HasCapability(CapabilityToolExec) {
t.Error("CapabilityChat alone should not include CapabilityToolExec")
}
}

func TestMaxStderrBytes(t *testing.T) {
// maxStderrBytes should be 1MB
if maxStderrBytes != 1<<20 {
t.Errorf("maxStderrBytes = %d, want %d (1MB)", maxStderrBytes, 1<<20)
}
}

func TestMixedModeConfigZeroValue(t *testing.T) {
// MixedModeConfig should be usable with zero values
var cfg MixedModeConfig
if cfg.Enabled {
t.Error("zero-value MixedModeConfig should have Enabled=false")
}
if cfg.ThinkingAgent != "" {
t.Error("zero-value MixedModeConfig should have empty ThinkingAgent")
}
if cfg.ExecutionAgent != "" {
t.Error("zero-value MixedModeConfig should have empty ExecutionAgent")
}
}

func TestMixedModeConfigFields(t *testing.T) {
cfg := MixedModeConfig{
ThinkingAgent: "claude",
ExecutionAgent: "codex",
Enabled: true,
}
if cfg.ThinkingAgent != "claude" {
t.Errorf("ThinkingAgent = %q, want %q", cfg.ThinkingAgent, "claude")
}
if cfg.ExecutionAgent != "codex" {
t.Errorf("ExecutionAgent = %q, want %q", cfg.ExecutionAgent, "codex")
}
if !cfg.Enabled {
t.Error("Enabled should be true")
}
}

func TestChatRequestZeroValue(t *testing.T) {
// ChatRequest type alias should compile and instantiate
var req ChatRequest
if req.SessionID != "" {
t.Error("zero-value ChatRequest should have empty SessionID")
}
if req.Prompt != "" {
t.Error("zero-value ChatRequest should have empty Prompt")
}
if req.History != nil {
t.Error("zero-value ChatRequest should have nil History")
}
}

func TestChatResponseZeroValue(t *testing.T) {
// ChatResponse type alias should compile and instantiate
var resp ChatResponse
if resp.Content != "" {
t.Error("zero-value ChatResponse should have empty Content")
}
if resp.Done {
t.Error("zero-value ChatResponse should have Done=false")
}
if resp.ExitCode != 0 {
t.Error("zero-value ChatResponse should have ExitCode=0")
}
}
Loading
Loading