- NewSchemaCommand / NewMCPCommand / newCatalogCommand no longer accept a DiscoveryCatalogLoader they always discarded; schema's no-discovery property is now structural, retiring the panic-loader test guard along with the trivial root.go wrappers and the unused buildMCPCommandFn seam. - Delete the lazy sync.Once / atomic counter around the retired MCP pin: runtimeMCPMetadata only existed so a diagnostic counter could observe a loader that always returns the constant empty pin. Assembly now calls emptyPinnedMCPMetadata directly and SchemaMetadataLoadCounts loses the dead MCPMetadata field (the policy bans keep the retired names from reappearing).
360 lines
17 KiB
Go
360 lines
17 KiB
Go
// Copyright 2026 Alibaba Group
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
package cli
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd/contract"
|
|
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd/contractfinal"
|
|
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd/runtimeannotate"
|
|
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/testseam"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/pflag"
|
|
)
|
|
|
|
func TestCrossPlatformCoverageRuntimeSchemaLoaderAndAnnotationEdges(t *testing.T) {
|
|
if got := emptyPinnedMCPMetadata(); got.Tools == nil || len(got.Tools) != 0 {
|
|
t.Fatalf("empty pinned metadata = %#v", got)
|
|
}
|
|
|
|
cmd := &cobra.Command{Use: "run", Short: "short", Long: "long"}
|
|
AnnotateRuntimeToolMetadata(cmd, " title ", " description ", " source ")
|
|
if cmd.Annotations[runtimeSchemaTitleAnnotation] != "title" {
|
|
t.Fatalf("annotations = %#v", cmd.Annotations)
|
|
}
|
|
AnnotateRuntimePositionals(cmd, contract.RuntimeSchemaPositional{Name: " ", Index: -1})
|
|
if _, ok := cmd.Annotations[runtimeSchemaArgsAnnotation]; ok {
|
|
t.Fatal("invalid positional should not be annotated")
|
|
}
|
|
if runtimeCommandTitle(nil) != "" || runtimeCommandDescription(nil) != "" {
|
|
t.Fatal("nil command text should be empty")
|
|
}
|
|
cmd.Annotations[runtimeSchemaTitleAnnotation] = " annotated title "
|
|
cmd.Annotations[runtimeSchemaDescAnnotation] = " annotated description "
|
|
if runtimeCommandTitle(cmd) != "annotated title" || runtimeCommandDescription(cmd) != "annotated description" {
|
|
t.Fatalf("annotated text = %q / %q", runtimeCommandTitle(cmd), runtimeCommandDescription(cmd))
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageCollectRuntimeSchemaEntriesErrorsAndOrdering(t *testing.T) {
|
|
testseam.Swap(t, &bindValidateParameterBindings, func() error { return errors.New("bindings failed") })
|
|
if _, err := collectRuntimeSchemaEntries(&cobra.Command{Use: "dws"}); err == nil || !strings.Contains(err.Error(), "bindings failed") {
|
|
t.Fatalf("validation error = %v", err)
|
|
}
|
|
|
|
testseam.Swap(t, &bindValidateParameterBindings, func() error { return nil })
|
|
prevGroups := reviewedRuntimeSchemaExclusionGroups
|
|
t.Cleanup(func() { reviewedRuntimeSchemaExclusionGroups = prevGroups })
|
|
reviewedRuntimeSchemaExclusionGroups = []runtimeSchemaExclusionGroup{{
|
|
ID: "", Reason: "x", Reviewed: true, Commands: []string{"x"},
|
|
}}
|
|
if _, err := collectRuntimeSchemaEntries(&cobra.Command{Use: "dws"}); err == nil {
|
|
t.Fatal("invalid reviewed exclusions should fail identity collection")
|
|
}
|
|
reviewedRuntimeSchemaExclusionGroups = prevGroups
|
|
|
|
if _, err := collectRuntimeSchemaEntriesFromBound(BoundCommandRegistry{Commands: []BoundCommandSpec{{
|
|
CommandSpec: CommandSpec{CanonicalPath: "invalid", Visibility: SchemaVisibilityPublic},
|
|
}}}); err == nil {
|
|
t.Fatal("invalid canonical path should fail")
|
|
}
|
|
leaf := &cobra.Command{Use: "run", Run: func(*cobra.Command, []string) {}}
|
|
entries, err := collectRuntimeSchemaEntriesFromBound(BoundCommandRegistry{Commands: []BoundCommandSpec{
|
|
{CommandSpec: CommandSpec{CanonicalPath: "sample.run", PrimaryCLIPath: "z run", Visibility: SchemaVisibilityPublic}, PrimaryCommand: leaf},
|
|
{CommandSpec: CommandSpec{CanonicalPath: "sample.run", PrimaryCLIPath: "a run", Visibility: SchemaVisibilityPublic}, PrimaryCommand: leaf},
|
|
}})
|
|
if err != nil || len(entries) != 2 || entries[0].CLIPath != "a run" {
|
|
t.Fatalf("ordered entries = %#v, err = %v", entries, err)
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageRuntimeSchemaMetadataLookupEdges(t *testing.T) {
|
|
if _, ok := pinnedMCPMetadataForEntryFrom(runtimeSchemaEntry{}, agentMetadata{}, embeddedMCPMetadata{Tools: map[string]embeddedMCPToolMetadata{}}); ok {
|
|
t.Fatal("empty lookup unexpectedly matched")
|
|
}
|
|
|
|
leaf := &cobra.Command{Use: "reply"}
|
|
contractfinal.RegisterRuntimeContractFinal(leaf, contract.ContractFinalPayload{
|
|
Identity: &contract.ToolIdentitySpec{
|
|
ProductID: "sample", Name: "run", CanonicalPath: "sample.run",
|
|
CLIPath: "sample run", PrimaryCLIPath: "sample run",
|
|
},
|
|
|
|
Interface: &contract.InterfaceSpec{
|
|
Mode: contract.InterfaceModeMCP,
|
|
Availability: contract.InterfaceAvailable,
|
|
Ref: &contract.InterfaceRefSpec{ProductID: "chat", RPCName: "send_personal_message"},
|
|
},
|
|
})
|
|
t.Cleanup(func() { ClearRuntimeContractFinalForTest(leaf) })
|
|
mcp := embeddedMCPMetadata{Tools: map[string]embeddedMCPToolMetadata{
|
|
"chat.send_personal_message": {
|
|
Parameters: map[string]embeddedMCPParamMeta{
|
|
"clawType": {Type: "string"},
|
|
},
|
|
},
|
|
}}
|
|
got, ok := pinnedMCPMetadataForEntryFrom(runtimeSchemaEntry{Command: leaf, ProductID: "chat", ToolName: "reply_personal_message"}, agentMetadata{}, mcp)
|
|
if !ok || got.Parameters["clawType"].Type != "string" {
|
|
t.Fatalf("ContractFinal Interface.Ref MCP remap = %#v ok=%v", got, ok)
|
|
}
|
|
if got.InterfaceRef == nil || got.InterfaceRef.RPCName != "send_personal_message" {
|
|
t.Fatalf("InterfaceRef = %#v", got.InterfaceRef)
|
|
}
|
|
|
|
for _, test := range []struct {
|
|
value any
|
|
want int
|
|
}{
|
|
{value: map[string]any{"tool_count": 1}, want: 1},
|
|
{value: map[string]any{"tool_count": int64(2)}, want: 2},
|
|
{value: map[string]any{"tool_count": float64(3)}, want: 3},
|
|
{value: map[string]any{"tools": []any{1, 2, 3, 4}}, want: 4},
|
|
{value: map[string]any{}, want: 0},
|
|
} {
|
|
if got := schemaProductToolCount(test.value.(map[string]any)); got != test.want {
|
|
t.Fatalf("tool count = %d, want %d", got, test.want)
|
|
}
|
|
}
|
|
|
|
originalResolver := resolveRuntimeSchemaField
|
|
t.Cleanup(func() { resolveRuntimeSchemaField = originalResolver })
|
|
for _, field := range []string{"title", "description"} {
|
|
resolveRuntimeSchemaField = func(got string, candidates ...runtimeSchemaFieldCandidate) (runtimeSchemaFieldCandidate, error) {
|
|
if got == field {
|
|
return runtimeSchemaFieldCandidate{}, errors.New("forced " + field)
|
|
}
|
|
return resolveRuntimeSchemaCandidate(got, candidates...)
|
|
}
|
|
_, _, _, _, err := runtimeToolTextMetadataFromMetadata(runtimeSchemaEntry{Title: "title", Description: "description", MetadataSource: "native"}, runtimeSchemaMetadataSources{})
|
|
if err == nil || !strings.Contains(err.Error(), field) {
|
|
t.Fatalf("%s error = %v", field, err)
|
|
}
|
|
}
|
|
resolveRuntimeSchemaField = func(field string, candidates ...runtimeSchemaFieldCandidate) (runtimeSchemaFieldCandidate, error) {
|
|
return runtimeSchemaStringCandidate("selected", "mcp_metadata"), nil
|
|
}
|
|
_, _, source, _, err := runtimeToolTextMetadataFromMetadata(runtimeSchemaEntry{}, runtimeSchemaMetadataSources{})
|
|
if err != nil || source != ProvenanceEmbeddedMCPMetadata {
|
|
t.Fatalf("MCP metadata source = %q, err = %v", source, err)
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageRuntimeSchemaCandidateAndProvenanceEdges(t *testing.T) {
|
|
left := runtimeSchemaStringCandidateAtPriority("same", true, "same", 1, "z")
|
|
right := runtimeSchemaStringCandidateAtPriority("same", true, "same", 1, "a")
|
|
winner, err := resolveRuntimeSchemaCandidate("ordering", left, right)
|
|
if err != nil || winner.Precedence != "a" {
|
|
t.Fatalf("precedence tie ordering winner = %#v, err = %v", winner, err)
|
|
}
|
|
if got := runtimeSchemaFieldProvenance(runtimeSchemaFieldCandidate{}); !reflect.DeepEqual(got, contract.FieldProvenance{}) {
|
|
t.Fatalf("absent provenance = %#v", got)
|
|
}
|
|
bad := runtimeSchemaCandidate(func() {}, true, "custom")
|
|
bad.Compared = []runtimeSchemaFieldCandidate{bad}
|
|
provenance := runtimeSchemaFieldProvenance(bad)
|
|
if string(provenance.Value) != "null" || string(provenance.Candidates[0].Value) != "null" {
|
|
t.Fatalf("invalid value provenance = %#v", provenance)
|
|
}
|
|
if rank, precedence := runtimeSchemaSourcePriority("custom"); rank != runtimeSchemaRankDerived || precedence != "source_order" {
|
|
t.Fatalf("custom source = %d/%q", rank, precedence)
|
|
}
|
|
|
|
flags := pflag.NewFlagSet("annotations", pflag.ContinueOnError)
|
|
flags.Bool("enabled", false, "")
|
|
flag := flags.Lookup("enabled")
|
|
setFlagAnnotation(flag, runtimeSchemaFlagRequiredAnnotation, "not-bool")
|
|
if candidate := runtimeSchemaAnnotatedBoolCandidate(flag, runtimeSchemaFlagRequiredAnnotation, "native_annotation"); candidate.Present {
|
|
t.Fatalf("invalid bool candidate = %#v", candidate)
|
|
}
|
|
|
|
originalResolver := resolveRuntimeSchemaField
|
|
t.Cleanup(func() { resolveRuntimeSchemaField = originalResolver })
|
|
resolveRuntimeSchemaField = func(string, ...runtimeSchemaFieldCandidate) (runtimeSchemaFieldCandidate, error) {
|
|
return runtimeSchemaFieldCandidate{}, errors.New("required failed")
|
|
}
|
|
if _, err := resolveRequiredProjection(false); err == nil {
|
|
t.Fatal("required resolver error was not returned")
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageRuntimeCommandParameterErrorEdges(t *testing.T) {
|
|
cmd := &cobra.Command{Use: "run"}
|
|
cmd.Flags().String("value", "", "value")
|
|
flag := cmd.Flags().Lookup("value")
|
|
|
|
if specs, err := runtimeCommandParameterSpecs(nil, "sample.run", nil, RuntimeSchemaConstraints{}); err != nil || specs != nil {
|
|
t.Fatalf("nil command specs = %#v, err = %v", specs, err)
|
|
}
|
|
testseam.Swap(t, &schemaParameterBindingData, func() (schemaParameterBindingSnapshot, error) {
|
|
return schemaParameterBindingSnapshot{}, errors.New("load failed")
|
|
})
|
|
if _, err := runtimeCommandParameterSpecs(cmd, "sample.run", nil, RuntimeSchemaConstraints{}); err == nil || !strings.Contains(err.Error(), "load failed") {
|
|
t.Fatalf("binding load error = %v", err)
|
|
}
|
|
testseam.Swap(t, &schemaParameterBindingData, func() (schemaParameterBindingSnapshot, error) {
|
|
return schemaParameterBindingSnapshot{Bindings: map[string]map[string]string{}, MappingExclusions: map[string]string{}}, nil
|
|
})
|
|
if _, _, err := runtimeSchemaParameterMappingCandidates(schemaParameterBindingSnapshot{
|
|
Bindings: map[string]map[string]string{},
|
|
MappingExclusions: map[string]string{"sample.run --value": " "},
|
|
}, "sample.run", "value"); err == nil {
|
|
t.Fatal("empty mapping exclusion reason should fail")
|
|
}
|
|
testseam.Swap(t, &schemaParameterBindingData, func() (schemaParameterBindingSnapshot, error) {
|
|
return schemaParameterBindingSnapshot{
|
|
Bindings: map[string]map[string]string{},
|
|
MappingExclusions: map[string]string{"sample.run --value": " "},
|
|
}, nil
|
|
})
|
|
if _, err := runtimeCommandParameterSpecs(cmd, "sample.run", nil, RuntimeSchemaConstraints{}); err == nil || !strings.Contains(err.Error(), "mapping exclusion") {
|
|
t.Fatalf("mapping exclusion error = %v", err)
|
|
}
|
|
testseam.Swap(t, &schemaParameterBindingData, func() (schemaParameterBindingSnapshot, error) {
|
|
return schemaParameterBindingSnapshot{Bindings: map[string]map[string]string{}, MappingExclusions: map[string]string{}}, nil
|
|
})
|
|
|
|
realResolver := resolveRuntimeSchemaField
|
|
for _, target := range []string{"property", "interface_type", "description", "required", "required_when", "format", "enum", "example"} {
|
|
testseam.Swap(t, &resolveRuntimeSchemaField, func(field string, candidates ...runtimeSchemaFieldCandidate) (runtimeSchemaFieldCandidate, error) {
|
|
if field == target {
|
|
return runtimeSchemaFieldCandidate{}, errors.New("forced " + target)
|
|
}
|
|
return resolveRuntimeSchemaCandidate(field, candidates...)
|
|
})
|
|
if _, err := runtimeCommandParameterSpecs(cmd, "sample.run", nil, RuntimeSchemaConstraints{}); err == nil || !strings.Contains(err.Error(), target) {
|
|
t.Fatalf("%s resolution error = %v", target, err)
|
|
}
|
|
}
|
|
resolveRuntimeSchemaField = realResolver
|
|
|
|
if specs, err := runtimeCommandParameterSpecs(&cobra.Command{Use: "empty"}, "sample.empty", nil, RuntimeSchemaConstraints{}); err != nil || specs != nil {
|
|
t.Fatalf("empty specs = %#v, err = %v", specs, err)
|
|
}
|
|
if payload, err := runtimeCommandParameters(nil, "", nil, RuntimeSchemaConstraints{}); err != nil || payload != nil {
|
|
t.Fatalf("empty payload = %#v, err = %v", payload, err)
|
|
}
|
|
testseam.Swap(t, &runtimeCommandParameterSpecsForPayload, func(*cobra.Command, string, map[string]embeddedMCPParamMeta, RuntimeSchemaConstraints) ([]ParameterSpec, error) {
|
|
return []ParameterSpec{{Name: "bad", Example: json.RawMessage("{")}}, nil
|
|
})
|
|
if _, err := runtimeCommandParameters(cmd, "sample.run", nil, RuntimeSchemaConstraints{}); err == nil || !strings.Contains(err.Error(), "serialize Schema parameter") {
|
|
t.Fatalf("payload serialization error = %v", err)
|
|
}
|
|
|
|
setFlagAnnotation(flag, runtimeSchemaFlagRequiredAnnotation, "true")
|
|
if required, present := runtimeFlagRequiredState(flag); !required || !present {
|
|
t.Fatalf("required annotation = %v/%v", required, present)
|
|
}
|
|
|
|
// Fixture MCP-shaped maps still participate when explicitly injected.
|
|
testseam.Swap(t, &schemaParameterBindingData, func() (schemaParameterBindingSnapshot, error) {
|
|
return schemaParameterBindingSnapshot{
|
|
Bindings: map[string]map[string]string{"sample.run": {"value": "clawType"}},
|
|
}, nil
|
|
})
|
|
requiredTrue := true
|
|
specs, err := runtimeCommandParameterSpecs(cmd, "sample.run", map[string]embeddedMCPParamMeta{
|
|
"clawType": {
|
|
Type: "string",
|
|
Description: "fixture description",
|
|
Required: &requiredTrue,
|
|
Default: "fixture-default",
|
|
},
|
|
}, RuntimeSchemaConstraints{})
|
|
if err != nil {
|
|
t.Fatalf("fixture pinned parameter specs error = %v", err)
|
|
}
|
|
if len(specs) != 1 || specs[0].Property != "clawType" || specs[0].InterfaceDescription != "fixture description" {
|
|
t.Fatalf("fixture pinned parameter specs = %#v", specs)
|
|
}
|
|
if len(specs[0].InterfaceDefault) == 0 {
|
|
t.Fatalf("fixture interface_default missing: %#v", specs[0])
|
|
}
|
|
if prov := specs[0].FieldProvenance["required"]; prov.Source == "" {
|
|
t.Fatalf("fixture required provenance missing: %#v", specs[0].FieldProvenance)
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageRuntimeSchemaPureHelperEdges(t *testing.T) {
|
|
if runtimeCommandFlag(nil, "x") != nil || runtimeCommandFlag(&cobra.Command{Use: "run"}, " ") != nil {
|
|
t.Fatal("invalid command flag lookup should be nil")
|
|
}
|
|
visitRuntimeCommandFlags(nil, nil, nil)
|
|
|
|
cmd := &cobra.Command{Use: "run", Annotations: map[string]string{
|
|
runtimeSchemaRulesAnnotation: "{",
|
|
runtimeSchemaArgsAnnotation: "{",
|
|
}}
|
|
if got := runtimeCommandConstraints(cmd); !runtimeSchemaConstraintsEmpty(got) {
|
|
t.Fatalf("invalid constraints = %#v", got)
|
|
}
|
|
if got := runtimeCommandPositionals(cmd); got != nil {
|
|
t.Fatalf("invalid positionals = %#v", got)
|
|
}
|
|
cmd.Annotations[runtimeSchemaArgsAnnotation] = `[{"name":"second","index":2},{"name":"first","index":1}]`
|
|
if got := runtimeCommandPositionals(cmd); len(got) != 2 || got[0].Name != "first" {
|
|
t.Fatalf("sorted positionals = %#v", got)
|
|
}
|
|
groups := runtimeannotate.NormalizeConstraints(runtimeannotate.RuntimeSchemaConstraints{
|
|
RequireOneOf: [][]string{{" "}, {" ", "one", "one"}, {"one"}, {"one"}},
|
|
}).RequireOneOf
|
|
if !reflect.DeepEqual(groups, [][]string{{"one"}}) {
|
|
t.Fatalf("normalized groups = %#v", groups)
|
|
}
|
|
if meta, ok := lookupPinnedMCPParam(map[string]embeddedMCPParamMeta{"flag": {Type: "string"}}, "property", "flag"); !ok || meta.Type != "string" {
|
|
t.Fatalf("flag fallback metadata = %#v/%v", meta, ok)
|
|
}
|
|
if isGenericPayloadFlag(nil) {
|
|
t.Fatal("nil flag cannot be a generic payload")
|
|
}
|
|
flags := pflag.NewFlagSet("payload", pflag.ContinueOnError)
|
|
flags.String("params", "", "Additional JSON object payload merged after --json")
|
|
if !isGenericPayloadFlag(flags.Lookup("params")) {
|
|
t.Fatal("params payload flag was not recognized")
|
|
}
|
|
|
|
invalidRequired := &pflag.Flag{Name: "x", Usage: "required", Annotations: map[string][]string{runtimeSchemaFlagRequiredAnnotation: {"bad"}}}
|
|
if required, present := runtimeFlagRequiredState(invalidRequired); !required || !present {
|
|
t.Fatalf("usage required fallback = %v/%v", required, present)
|
|
}
|
|
if usageImpliesRequired("") || usageImpliesRequired("required when enabled") {
|
|
t.Fatal("empty or conditional usage should not be unconditionally required")
|
|
}
|
|
if required, present := runtimeFlagRequiredState(&pflag.Flag{Name: "optional", Usage: "optional"}); required || present {
|
|
t.Fatalf("optional required state = %v/%v", required, present)
|
|
}
|
|
if lowerCamelFlagName("---") != "---" || lowerCamelFlagName("one") != "one" || lowerCamelFlagName("one-two") != "oneTwo" {
|
|
t.Fatal("lower camel conversion failed")
|
|
}
|
|
if inferredRuntimeFlagFormat(nil) != "" {
|
|
t.Fatal("nil flag format should be empty")
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageSchemaCompactProjectionEdges(t *testing.T) {
|
|
if stripSchemaPayloadCompact(nil) != nil {
|
|
t.Fatal("nil compact payload should stay nil")
|
|
}
|
|
if got := stripSchemaParametersCompact("raw"); got != "raw" {
|
|
t.Fatalf("raw parameters = %#v", got)
|
|
}
|
|
parameters := map[string]any{
|
|
"raw": "value",
|
|
"typed": map[string]any{"type": "string", "property": "remote"},
|
|
}
|
|
got := stripSchemaParametersCompact(parameters).(map[string]any)
|
|
if got["raw"] != "value" || got["typed"].(map[string]any)["property"] != nil {
|
|
t.Fatalf("compact parameters = %#v", got)
|
|
}
|
|
value := stripSchemaValueCompact(map[string]any{"required": false, "property": "remote"}).(map[string]any)
|
|
if _, exists := value["property"]; exists {
|
|
t.Fatalf("compact parameter value = %#v", value)
|
|
}
|
|
}
|