mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-30 17:13:08 +08:00
167682c39b
Add /v1/messages handler with Anthropic-to-OpenAI translation, upstream failover, and probe endpoints. Replace shell-based functional test scripts with pkg/aiproxy/ft and climc test commands; consolidate documentation.
214 lines
5.7 KiB
Go
214 lines
5.7 KiB
Go
// Copyright 2019 Yunion
|
|
//
|
|
// 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 ft
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/pkg/errors"
|
|
|
|
"yunion.io/x/onecloud/pkg/mcclient"
|
|
apmodules "yunion.io/x/onecloud/pkg/mcclient/modules/aiproxy"
|
|
)
|
|
|
|
type providerConfigSnapshot struct {
|
|
providerKey string
|
|
config *jsonutils.JSONDict
|
|
}
|
|
|
|
// ResourceTracker records resources created during a test run for automatic cleanup.
|
|
type ResourceTracker struct {
|
|
KeepResources bool
|
|
|
|
createdRouting string
|
|
createdVirtualKey string
|
|
createdAiKey string
|
|
createdAiModel string
|
|
createdProvider string
|
|
|
|
providerConfigRestore *providerConfigSnapshot
|
|
}
|
|
|
|
func NewResourceTracker(keepResources bool) *ResourceTracker {
|
|
return &ResourceTracker{KeepResources: keepResources}
|
|
}
|
|
|
|
func envKeepResources(explicit bool) bool {
|
|
if explicit {
|
|
return true
|
|
}
|
|
return envTruthy("AIPROXY_TEST_KEEP_RESOURCES", "AIPROXY_FT_KEEP_RESOURCES")
|
|
}
|
|
|
|
func (t *ResourceTracker) hasCreated() bool {
|
|
if t == nil {
|
|
return false
|
|
}
|
|
return t.createdRouting != "" ||
|
|
t.createdVirtualKey != "" ||
|
|
t.createdAiKey != "" ||
|
|
t.createdAiModel != "" ||
|
|
t.createdProvider != "" ||
|
|
t.providerConfigRestore != nil
|
|
}
|
|
|
|
func (t *ResourceTracker) Cleanup(session *mcclient.ClientSession) {
|
|
if t == nil {
|
|
return
|
|
}
|
|
if t.KeepResources {
|
|
if t.hasCreated() {
|
|
fmt.Println()
|
|
fmt.Println("Keeping test resources (--keep-resources / AIPROXY_TEST_KEEP_RESOURCES=1)")
|
|
t.printKeepHint()
|
|
}
|
|
return
|
|
}
|
|
if !t.hasCreated() {
|
|
return
|
|
}
|
|
|
|
fmt.Println()
|
|
Step("cleanup test resources")
|
|
|
|
if t.createdRouting != "" {
|
|
t.deleteRouting(session, t.createdRouting)
|
|
}
|
|
if t.createdVirtualKey != "" {
|
|
t.deleteVirtualKey(session, t.createdVirtualKey)
|
|
}
|
|
if t.createdAiKey != "" {
|
|
t.deleteAiKey(session, t.createdAiKey)
|
|
}
|
|
if t.createdAiModel != "" {
|
|
t.deleteAiModel(session, t.createdAiModel)
|
|
}
|
|
if t.providerConfigRestore != nil {
|
|
t.restoreProviderConfig(session)
|
|
}
|
|
if t.createdProvider != "" {
|
|
t.deleteProvider(session, t.createdProvider)
|
|
}
|
|
}
|
|
|
|
func (t *ResourceTracker) printKeepHint() {
|
|
if t.createdRouting != "" {
|
|
fmt.Printf(" climc ai-routing-delete %s\n", t.createdRouting)
|
|
}
|
|
if t.createdVirtualKey != "" {
|
|
fmt.Printf(" climc ai-virtual-key-delete %s\n", t.createdVirtualKey)
|
|
}
|
|
if t.createdAiKey != "" {
|
|
fmt.Printf(" climc ai-key-delete %s\n", t.createdAiKey)
|
|
}
|
|
if t.createdAiModel != "" {
|
|
fmt.Printf(" climc ai-model-delete %s\n", t.createdAiModel)
|
|
}
|
|
if t.createdProvider != "" {
|
|
fmt.Printf(" climc ai-provider-delete %s\n", t.createdProvider)
|
|
}
|
|
}
|
|
|
|
func (t *ResourceTracker) deleteRouting(session *mcclient.ClientSession, name string) {
|
|
if _, err := apmodules.AiRoutings.Delete(session, name, nil); err != nil {
|
|
fmt.Printf("WARN: delete ai_routing %s: %v\n", name, err)
|
|
return
|
|
}
|
|
fmt.Printf("deleted ai_routing %s\n", name)
|
|
}
|
|
|
|
func (t *ResourceTracker) deleteVirtualKey(session *mcclient.ClientSession, name string) {
|
|
if _, err := apmodules.AiVirtualKeys.Delete(session, name, nil); err != nil {
|
|
fmt.Printf("WARN: delete ai_virtual_key %s: %v\n", name, err)
|
|
return
|
|
}
|
|
fmt.Printf("deleted ai_virtual_key %s\n", name)
|
|
}
|
|
|
|
func (t *ResourceTracker) deleteAiKey(session *mcclient.ClientSession, name string) {
|
|
if _, err := apmodules.AiKeys.Delete(session, name, nil); err != nil {
|
|
fmt.Printf("WARN: delete ai_key %s: %v\n", name, err)
|
|
return
|
|
}
|
|
fmt.Printf("deleted ai_key %s\n", name)
|
|
}
|
|
|
|
func (t *ResourceTracker) deleteAiModel(session *mcclient.ClientSession, name string) {
|
|
if _, err := apmodules.AiModels.Delete(session, name, nil); err != nil {
|
|
fmt.Printf("WARN: delete ai_model %s: %v\n", name, err)
|
|
return
|
|
}
|
|
fmt.Printf("deleted ai_model %s\n", name)
|
|
}
|
|
|
|
func (t *ResourceTracker) deleteProvider(session *mcclient.ClientSession, name string) {
|
|
if _, err := apmodules.AiProviders.Delete(session, name, nil); err != nil {
|
|
fmt.Printf("WARN: delete ai_provider %s: %v\n", name, err)
|
|
return
|
|
}
|
|
fmt.Printf("deleted ai_provider %s\n", name)
|
|
}
|
|
|
|
func (t *ResourceTracker) restoreProviderConfig(session *mcclient.ClientSession) {
|
|
snap := t.providerConfigRestore
|
|
if snap == nil {
|
|
return
|
|
}
|
|
params := jsonutils.NewDict()
|
|
if snap.config != nil {
|
|
params.Set("config", snap.config)
|
|
} else {
|
|
params.Set("config", jsonutils.NewDict())
|
|
}
|
|
if _, err := apmodules.AiProviders.Update(session, snap.providerKey, params); err != nil {
|
|
fmt.Printf("WARN: restore ai_provider %s config: %v\n", snap.providerKey, err)
|
|
return
|
|
}
|
|
fmt.Printf("restored ai_provider %s config\n", snap.providerKey)
|
|
}
|
|
|
|
func cloneJSONDict(obj jsonutils.JSONObject) *jsonutils.JSONDict {
|
|
if obj == nil {
|
|
return nil
|
|
}
|
|
if d, ok := obj.(*jsonutils.JSONDict); ok {
|
|
out := jsonutils.NewDict()
|
|
out.Update(d)
|
|
return out
|
|
}
|
|
parsed, err := jsonutils.Parse([]byte(obj.String()))
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
if d, ok := parsed.(*jsonutils.JSONDict); ok {
|
|
return d
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func snapshotProviderConfig(session *mcclient.ClientSession, providerKey string) (*providerConfigSnapshot, error) {
|
|
obj, err := apmodules.AiProviders.Get(session, providerKey, nil)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "ai_provider %s not found", providerKey)
|
|
}
|
|
snap := &providerConfigSnapshot{providerKey: providerKey}
|
|
if obj.Contains("config") {
|
|
cfg, _ := obj.Get("config")
|
|
snap.config = cloneJSONDict(cfg)
|
|
}
|
|
return snap, nil
|
|
}
|