fix: stabilize direct runtime endpoint tests
This commit is contained in:
@@ -223,12 +223,9 @@ func directRuntimeToolEndpoint(toolName string) (string, bool) {
|
|||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
dynamicMu.RLock()
|
dynamicMu.RLock()
|
||||||
te := dynamicToolEndpoints
|
defer dynamicMu.RUnlock()
|
||||||
dynamicMu.RUnlock()
|
|
||||||
if te == nil {
|
endpoint, ok := dynamicToolEndpoints[toolName]
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
endpoint, ok := te[toolName]
|
|
||||||
return endpoint, ok && strings.TrimSpace(endpoint) != ""
|
return endpoint, ok && strings.TrimSpace(endpoint) != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,24 +249,19 @@ func directRuntimeEndpoint(productID, toolName string) (string, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamicMu.RLock()
|
|
||||||
de := dynamicEndpoints
|
|
||||||
te := dynamicToolEndpoints
|
|
||||||
dynamicMu.RUnlock()
|
|
||||||
|
|
||||||
// Priority 1: product-level endpoint.
|
// Priority 1: product-level endpoint.
|
||||||
// When the caller already knows the productID (e.g. "drive"), the product
|
// When the caller already knows the productID (e.g. "drive"), the product
|
||||||
// endpoint is authoritative. This prevents cross-product tool name
|
// endpoint is authoritative. This prevents cross-product tool name
|
||||||
// collisions (e.g. both "drive" and "doc" register "create_folder") from
|
// collisions (e.g. both "drive" and "doc" register "create_folder") from
|
||||||
// routing the request to the wrong MCP server. See issue #219.
|
// routing the request to the wrong MCP server. See issue #219.
|
||||||
|
dynamicMu.RLock()
|
||||||
for _, candidate := range []string{strings.TrimSpace(productID), normalized} {
|
for _, candidate := range []string{strings.TrimSpace(productID), normalized} {
|
||||||
if candidate == "" {
|
if candidate == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if de != nil {
|
if endpoint, ok := dynamicEndpoints[candidate]; ok {
|
||||||
if endpoint, ok := de[candidate]; ok {
|
dynamicMu.RUnlock()
|
||||||
return endpoint, true
|
return endpoint, true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,11 +269,13 @@ func directRuntimeEndpoint(productID, toolName string) (string, bool) {
|
|||||||
// This path is used when the caller does not know the productID but has a
|
// This path is used when the caller does not know the productID but has a
|
||||||
// tool name, e.g. in helper invocations or plugin routes where only the
|
// tool name, e.g. in helper invocations or plugin routes where only the
|
||||||
// tool name is available.
|
// tool name is available.
|
||||||
if tool := strings.TrimSpace(toolName); tool != "" && te != nil {
|
if tool := strings.TrimSpace(toolName); tool != "" {
|
||||||
if endpoint, ok := te[tool]; ok {
|
if endpoint, ok := dynamicToolEndpoints[tool]; ok {
|
||||||
|
dynamicMu.RUnlock()
|
||||||
return endpoint, true
|
return endpoint, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dynamicMu.RUnlock()
|
||||||
|
|
||||||
// Priority 3: built-in PAT fallback for cold-start paths that run before
|
// Priority 3: built-in PAT fallback for cold-start paths that run before
|
||||||
// discovery/plugin registration has populated the dynamic registry.
|
// discovery/plugin registration has populated the dynamic registry.
|
||||||
@@ -347,12 +341,12 @@ func endpointFromEditionServers(productID string, fn func() []edition.ServerInfo
|
|||||||
// through DINGTALK_<PRODUCT>_MCP_URL instead of requiring discovery.
|
// through DINGTALK_<PRODUCT>_MCP_URL instead of requiring discovery.
|
||||||
func DirectRuntimeProductIDs() map[string]bool {
|
func DirectRuntimeProductIDs() map[string]bool {
|
||||||
dynamicMu.RLock()
|
dynamicMu.RLock()
|
||||||
dp := dynamicProducts
|
defer dynamicMu.RUnlock()
|
||||||
dynamicMu.RUnlock()
|
|
||||||
ids := make(map[string]bool, len(dp)+2)
|
ids := make(map[string]bool, len(dynamicProducts)+2)
|
||||||
ids[defaultPATProductID] = true
|
ids[defaultPATProductID] = true
|
||||||
ids[devappProductID] = true
|
ids[devappProductID] = true
|
||||||
for key := range dp {
|
for key := range dynamicProducts {
|
||||||
ids[key] = true
|
ids[key] = true
|
||||||
}
|
}
|
||||||
return ids
|
return ids
|
||||||
@@ -427,15 +421,14 @@ func AppendDynamicServer(server market.ServerDescriptor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func normalizeDirectRuntimeProductID(productID string) string {
|
func normalizeDirectRuntimeProductID(productID string) string {
|
||||||
dynamicMu.RLock()
|
|
||||||
da := dynamicAliases
|
|
||||||
dynamicMu.RUnlock()
|
|
||||||
trimmed := strings.TrimSpace(productID)
|
trimmed := strings.TrimSpace(productID)
|
||||||
if da != nil {
|
dynamicMu.RLock()
|
||||||
if normalizedID, ok := da[trimmed]; ok && normalizedID != "" {
|
if normalizedID, ok := dynamicAliases[trimmed]; ok && normalizedID != "" {
|
||||||
return normalizedID
|
dynamicMu.RUnlock()
|
||||||
}
|
return normalizedID
|
||||||
}
|
}
|
||||||
|
dynamicMu.RUnlock()
|
||||||
|
|
||||||
if normalizedID, ok := legacyDirectRuntimeAliases[trimmed]; ok {
|
if normalizedID, ok := legacyDirectRuntimeAliases[trimmed]; ok {
|
||||||
return normalizedID
|
return normalizedID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ func TestDirectRuntimeEndpoint_DevappEnvOverridePreservesQuery(t *testing.T) {
|
|||||||
assertEndpoint(t, "devapp", "list_open_dev_apps_by_condition", "https://example.test/server/devapp?key=secret")
|
assertEndpoint(t, "devapp", "list_open_dev_apps_by_condition", "https://example.test/server/devapp?key=secret")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDirectRuntimeEndpoint_DevappDynamicServerWithoutRegistry(t *testing.T) {
|
func TestDirectRuntimeEndpoint_DevappDynamicServerDoesNotOverrideHardcoded(t *testing.T) {
|
||||||
withCleanDynamicRegistry(t)
|
withCleanDynamicRegistry(t)
|
||||||
SetDynamicServers([]market.ServerDescriptor{
|
SetDynamicServers([]market.ServerDescriptor{
|
||||||
{
|
{
|
||||||
@@ -74,10 +74,10 @@ func TestDirectRuntimeEndpoint_DevappDynamicServerWithoutRegistry(t *testing.T)
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
assertEndpoint(t, "devapp", "list_open_dev_apps_by_condition", "https://example.test/server/devapp-supplement")
|
assertEndpoint(t, "devapp", "list_open_dev_apps_by_condition", devappEndpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDirectRuntimeEndpoint_DevappEditionSupplementWithoutRegistry(t *testing.T) {
|
func TestDirectRuntimeEndpoint_DevappEditionSupplementDoesNotOverrideHardcoded(t *testing.T) {
|
||||||
withCleanDynamicRegistry(t)
|
withCleanDynamicRegistry(t)
|
||||||
prev := edition.Get()
|
prev := edition.Get()
|
||||||
edition.Override(&edition.Hooks{
|
edition.Override(&edition.Hooks{
|
||||||
@@ -95,11 +95,10 @@ func TestDirectRuntimeEndpoint_DevappEditionSupplementWithoutRegistry(t *testing
|
|||||||
})
|
})
|
||||||
t.Cleanup(func() { edition.Override(prev) })
|
t.Cleanup(func() { edition.Override(prev) })
|
||||||
|
|
||||||
assertEndpoint(t, "devapp", "list_open_dev_apps_by_condition", "https://example.test/server/devapp-edition-supplement?key=secret")
|
assertEndpoint(t, "devapp", "list_open_dev_apps_by_condition", devappEndpoint)
|
||||||
assertEndpoint(t, "app", "list_open_dev_apps_by_condition", "https://example.test/server/devapp-edition-supplement?key=secret")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDirectRuntimeEndpoint_DevappEditionStaticWithoutRegistry(t *testing.T) {
|
func TestDirectRuntimeEndpoint_DevappEditionStaticDoesNotOverrideHardcoded(t *testing.T) {
|
||||||
withCleanDynamicRegistry(t)
|
withCleanDynamicRegistry(t)
|
||||||
prev := edition.Get()
|
prev := edition.Get()
|
||||||
edition.Override(&edition.Hooks{
|
edition.Override(&edition.Hooks{
|
||||||
@@ -117,7 +116,7 @@ func TestDirectRuntimeEndpoint_DevappEditionStaticWithoutRegistry(t *testing.T)
|
|||||||
})
|
})
|
||||||
t.Cleanup(func() { edition.Override(prev) })
|
t.Cleanup(func() { edition.Override(prev) })
|
||||||
|
|
||||||
assertEndpoint(t, "devapp", "list_open_dev_apps_by_condition", "https://example.test/server/devapp-edition-static")
|
assertEndpoint(t, "devapp", "list_open_dev_apps_by_condition", devappEndpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDirectRuntimeEndpoint_DevappEnvOverrideWinsOverEditionSupplement(t *testing.T) {
|
func TestDirectRuntimeEndpoint_DevappEnvOverrideWinsOverEditionSupplement(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user