Files
wangdefa 7706f59549
CI / test (push) Successful in 32s
Release / release (push) Successful in 52s
发布 0.2.0:模型池自愈、探测修正、任务异步触发与删除加固
2026-07-10 20:25:37 +08:00

161 lines
5.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package oci
import (
"errors"
"fmt"
"testing"
)
// fakeServiceError 模拟 oci-go-sdk 的 common.ServiceError
// Error() 按 SDK 真实格式输出长文以验证截断。
type fakeServiceError struct {
status int
code string
message string
}
func (e fakeServiceError) Error() string {
return fmt.Sprintf(
"Error returned by Compute Service. Http Status Code: %d. Error Code: %s. Message: %s. Troubleshooting Tips: See https://docs.oracle.com/ ...",
e.status, e.code, e.message)
}
func (e fakeServiceError) GetHTTPStatusCode() int { return e.status }
func (e fakeServiceError) GetMessage() string { return e.message }
func (e fakeServiceError) GetCode() string { return e.code }
func (e fakeServiceError) GetOpcRequestID() string { return "req-1" }
func TestCompactError(t *testing.T) {
capacity := fakeServiceError{status: 500, code: "InternalError", message: "Out of host capacity."}
tests := []struct {
name string
err error
want string
}{
{
name: "非 OCI 错误原样返回",
err: errors.New("parse payload: unexpected end of JSON input"),
want: "parse payload: unexpected end of JSON input",
},
{
name: "带操作前缀的 OCI 错误保留前缀并剥掉长文",
err: fmt.Errorf("launch instance: %w", capacity),
want: "launch instance: Out of host capacity.",
},
{
name: "多层包装保留完整前缀链",
err: fmt.Errorf("snatch-1: %w", fmt.Errorf("launch instance: %w", capacity)),
want: "snatch-1: launch instance: Out of host capacity.",
},
{
name: "无前缀时只输出服务端消息",
err: error(capacity),
want: "Out of host capacity.",
},
{
name: "消息中的长 OCID 压缩为类型加尾位",
err: fmt.Errorf("update instance: %w", fakeServiceError{
status: 500, code: "InternalError",
message: "instance ocid1.instance.oc1.phx.anyhqljtp537sbqcr2f5ed2jwkglwyd3g6dfbmgtwdp4xdarxum5q7tdcyla: Out of host capacity.",
}),
want: "update instance: instance ocid1.instance…tdcyla: Out of host capacity.",
},
{
name: "非 OCI 错误里的 OCID 同样压缩",
err: errors.New("get instance ocid1.instance.oc1..aaaaaaaabbbbbbbbccccccccdddddddd failed"),
want: "get instance ocid1.instance…dddddd failed",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := CompactError(tt.err); got != tt.want {
t.Errorf("CompactError() = %q, want %q", got, tt.want)
}
})
}
}
func TestErrorHint(t *testing.T) {
tests := []struct {
name string
err error
want string
}{
{
name: "非 OCI 错误无提示",
err: errors.New("db locked"),
want: "",
},
{
name: "已知错误码给出中文提示",
err: fmt.Errorf("delete vcn: %w", fakeServiceError{409, "IncorrectState", "vcn in use"}),
want: ociErrorHints["IncorrectState"],
},
{
name: "InternalError 但消息为容量不足时归到容量提示",
err: fmt.Errorf("launch: %w", fakeServiceError{500, "InternalError", "Out of host capacity."}),
want: ociErrorHints["OutOfHostCapacity"],
},
{
name: "未知错误码返回空串",
err: fmt.Errorf("x: %w", fakeServiceError{400, "SomethingNew", "boom"}),
want: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ErrorHint(tt.err); got != tt.want {
t.Errorf("ErrorHint() = %q, want %q", got, tt.want)
}
})
}
}
func TestIsOnDemandUnsupported(t *testing.T) {
ft := fakeServiceError{status: 400, code: "InvalidParameter",
message: "Not allowed to call finetune base model ocid1.generativeaimodel.oc1.eu-frankfurt-1.tpel5q, use Endpoint: false"}
tests := []struct {
name string
err error
want bool
}{
{"微调基座 400 命中(含包装链)", fmt.Errorf("genai chat: %w", ft), true},
{"同消息但非 400 不命中", fakeServiceError{status: 500, code: "InternalError", message: ft.message}, false},
{"普通 400 不命中", fakeServiceError{status: 400, code: "InvalidParameter", message: "bad request"}, false},
{"非服务端错误不命中", errors.New("finetune base model"), false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := IsOnDemandUnsupported(tt.err); got != tt.want {
t.Errorf("IsOnDemandUnsupported() = %v, want %v", got, tt.want)
}
})
}
}
func TestIsModelUnavailable(t *testing.T) {
entity404 := fakeServiceError{status: 404, code: "NotFound",
message: "Entity with key ocid1.generativeaimodel.oc1.eu-frankfurt-1.2flsfq not found"}
auth404 := fakeServiceError{status: 404, code: "NotAuthorizedOrNotFound",
message: "Authorization failed or requested resource not found."}
ft400 := fakeServiceError{status: 400, code: "InvalidParameter",
message: "Not allowed to call finetune base model ocid1.generativeaimodel.oc1..x, use Endpoint: false"}
tests := []struct {
name string
err error
want bool
}{
{"实体不存在 404 命中(含包装链)", fmt.Errorf("genai chat: %w", entity404), true},
{"鉴权类 404 不命中(仍属租户级)", auth404, false},
{"微调基座 400 命中", ft400, true},
{"其他 404 消息不命中", fakeServiceError{status: 404, code: "NotFound", message: "route not found"}, false},
{"非服务端错误不命中", errors.New("entity with key x not found"), false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := IsModelUnavailable(tt.err); got != tt.want {
t.Errorf("IsModelUnavailable() = %v, want %v", got, tt.want)
}
})
}
}