Ctrl K
ComunidadGuías…

internal/config/cmdinfo_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package config

import "testing"

func TestParseCmd_ModelPath(t *testing.T) {
	cases := []struct {
		name string
		cmd  string
		want string
	}{
		{"llama -m", "llama-server -m /models/a.gguf -c 4096", "/models/a.gguf"},
		{"long form", "tts-server --model /models/b.gguf", "/models/b.gguf"},
		{"equals form", "llama-server --model=/models/c.gguf", "/models/c.gguf"},
		{"sd diffusion model", "sd-server --diffusion-model /models/d.gguf --max-vram 20", "/models/d.gguf"},
		{"first flag wins", "sd-server --diffusion-model /models/d.gguf --model /models/clip.gguf", "/models/d.gguf"},
		{"ttscpp model-path", "tts-server --model-path /models/Kokoro_no_espeak_Q8.gguf --port 9000", "/models/Kokoro_no_espeak_Q8.gguf"},
		{"vllm serve gguf", "vllm serve /models/q.gguf --port 9000 --quantization gguf", "/models/q.gguf"},
		{"vllm serve HF folder", "vllm serve /models/meta/Llama-3-8B --port 9000", "/models/meta/Llama-3-8B"},
		{"serve with no positional", "ollama serve --port 9000", ""},
		{"no model flag", "some-upstream --serve 8080", ""},
		{"flag with no value", "llama-server -c 4096 -m", ""},
		{"unparseable", "", ""},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			if got := ParseCmd(tc.cmd).ModelPath; got != tc.want {
				t.Errorf("ModelPath = %q, want %q", got, tc.want)
			}
		})
	}
}

func TestCmdInfo_HasIsTokenExact(t *testing.T) {
	info := ParseCmd("llama-server -m /models/a.gguf --slot-save-path /kv --model-draft /models/d.gguf")
	if !info.Has("--slot-save-path") {
		t.Error("expected --slot-save-path detected")
	}
	// A raw strings.Contains(cmd, "--model") would match --model-draft; the token
	// scan must not.
	if info.Has("--model") {
		t.Error("--model-draft must not register as --model")
	}
	if info.Has("--codec") {
		t.Error("absent flag reported present")
	}
	if !ParseCmd("sd-server --lora-model-dir=/loras").Has("--lora-model-dir") {
		t.Error("--flag=value form should count as present")
	}
}

// The emitter renders one flag per line, so a value can sit on the line after
// its flag. The old sniffs tested for the contiguous substring
// "--spec-type draft-mtp" and silently went blind whenever that happened.
func TestCmdInfo_ValueAcrossLineBreak(t *testing.T) {
	cmd := "llama-server\n-m /models/a.gguf\n--spec-type\ndraft-mtp\n"
	info := ParseCmd(cmd)
	if !info.HasValue("draft-mtp", "--spec-type") {
		t.Errorf("line-wrapped --spec-type draft-mtp not detected, argv=%q", info.Argv)
	}
	if info.HasValue("draft-dflash", "--spec-type") {
		t.Error("draft-dflash falsely detected")
	}
}

func TestCmdInfo_ValuesRepeatable(t *testing.T) {
	info := ParseCmd("llama-server --spec-type draft-mtp --spec-type draft-dflash")
	got := info.Values("--spec-type")
	if len(got) != 2 || got[0] != "draft-mtp" || got[1] != "draft-dflash" {
		t.Errorf("Values = %q, want both spec types in order", got)
	}
	if !info.HasValue("draft-dflash", "--spec-type") {
		t.Error("second occurrence must be visible")
	}
}

func TestCmdInfo_ValueAndInt(t *testing.T) {
	info := ParseCmd("llama-server -c 32768 --port 9001 -ngl abc")
	if n, ok := info.Int("-c", "--ctx-size"); !ok || n != 32768 {
		t.Errorf("Int(-c) = %d,%v want 32768,true", n, ok)
	}
	if v, ok := info.Value("--port", "-port"); !ok || v != "9001" {
		t.Errorf("Value(--port) = %q,%v want 9001,true", v, ok)
	}
	if _, ok := info.Int("-ngl"); ok {
		t.Error("non-numeric value must not parse as int")
	}
	if _, ok := info.Value("--missing"); ok {
		t.Error("absent flag must report ok=false")
	}
}

func TestParseCmd_Memoized(t *testing.T) {
	cmd := "llama-server -m /models/memo.gguf -c 8192"
	if a, b := ParseCmd(cmd), ParseCmd(cmd); a != b {
		t.Error("repeat parse of the same command should return the cached CmdInfo")
	}
}

func TestParseCmd_UnparseableIsSafe(t *testing.T) {
	info := ParseCmd("") // SanitizeCommand rejects an empty command
	if info == nil {
		t.Fatal("ParseCmd must never return nil")
	}
	if info.Argv != nil {
		t.Errorf("expected nil argv for unparseable command, got %q", info.Argv)
	}
	if info.Has("-m") {
		t.Error("nil argv must not match any flag")
	}
	if _, ok := info.Int("-c"); ok {
		t.Error("nil argv must not yield ints")
	}
}