2026-05-15 19:26:25 +08:00
package provision
import (
"context"
"database/sql"
2026-05-23 09:18:02 +08:00
"encoding/json"
2026-05-15 19:26:25 +08:00
"fmt"
2026-05-21 21:19:19 +08:00
"strings"
2026-05-15 19:26:25 +08:00
"testing"
_ "modernc.org/sqlite"
"sub2api-cn-relay-manager/internal/host/sub2api"
"sub2api-cn-relay-manager/internal/pack"
"sub2api-cn-relay-manager/internal/store/sqlite"
2026-05-25 07:30:07 +08:00
"sub2api-cn-relay-manager/internal/testutil"
2026-05-15 19:26:25 +08:00
)
func TestRuntimeImportServicePersistsOperationalState ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
2026-05-18 22:22:22 +08:00
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
2026-05-15 19:26:25 +08:00
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" } , { ID : "account_2" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : { OK : true , Status : "passed" } ,
"account_2" : { OK : true , Status : "passed" } ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "deepseek-chat" } } ,
"account_2" : { { ID : "deepseek-chat" } } ,
} ,
gatewayResult : sub2api . GatewayAccessResult { OK : true , StatusCode : 200 , HasExpectedModel : true , Models : [ ] string { "deepseek-chat" } } ,
}
svc := NewRuntimeImportService ( store , host )
result , err := svc . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { " key-1 " , "key-2" , "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-key" ,
} ,
} )
if err != nil {
t . Fatalf ( "RuntimeImportService.Import() error = %v" , err )
}
if result . BatchID <= 0 {
t . Fatalf ( "BatchID = %d, want positive id" , result . BatchID )
}
if result . Report . BatchStatus != BatchStatusSucceeded {
t . Fatalf ( "BatchStatus = %q, want %q" , result . Report . BatchStatus , BatchStatusSucceeded )
}
2026-05-26 07:50:43 +08:00
if len ( result . Report . HostOverlays ) != 0 {
t . Fatalf ( "HostOverlays = %+v, want none for sample provider" , result . Report . HostOverlays )
}
2026-05-15 19:26:25 +08:00
if got := queryCount ( t , store . SQLDB ( ) , "hosts" ) ; got != 1 {
t . Fatalf ( "hosts row count = %d, want 1" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "packs" ) ; got != 1 {
t . Fatalf ( "packs row count = %d, want 1" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "providers" ) ; got != 1 {
t . Fatalf ( "providers row count = %d, want 1" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "import_batches" ) ; got != 1 {
t . Fatalf ( "import_batches row count = %d, want 1" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "import_batch_items" ) ; got != 2 {
t . Fatalf ( "import_batch_items row count = %d, want 2" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "managed_resources" ) ; got != 4 {
t . Fatalf ( "managed_resources row count = %d, want 4" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "probe_results" ) ; got != 2 {
t . Fatalf ( "probe_results row count = %d, want 2" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "access_closure_records" ) ; got != 1 {
t . Fatalf ( "access_closure_records row count = %d, want 1" , got )
}
2026-05-29 14:43:34 +08:00
if got := queryCount ( t , store . SQLDB ( ) , "provider_accounts" ) ; got != 2 {
t . Fatalf ( "provider_accounts row count = %d, want 2" , got )
}
2026-05-15 19:26:25 +08:00
var batchStatus string
var accessStatus string
if err := store . SQLDB ( ) . QueryRowContext ( context . Background ( ) , "SELECT batch_status, access_status FROM import_batches WHERE id = ?" , result . BatchID ) . Scan ( & batchStatus , & accessStatus ) ; err != nil {
t . Fatalf ( "query import batch state: %v" , err )
}
if batchStatus != BatchStatusSucceeded {
t . Fatalf ( "persisted batch_status = %q, want %q" , batchStatus , BatchStatusSucceeded )
}
if accessStatus != AccessStatusSelfServiceReady {
t . Fatalf ( "persisted access_status = %q, want %q" , accessStatus , AccessStatusSelfServiceReady )
}
var fingerprint string
var accountStatus string
if err := store . SQLDB ( ) . QueryRowContext ( context . Background ( ) , "SELECT key_fingerprint, account_status FROM import_batch_items ORDER BY id LIMIT 1" ) . Scan ( & fingerprint , & accountStatus ) ; err != nil {
t . Fatalf ( "query import batch item: %v" , err )
}
if fingerprint == "key-1" || fingerprint == "key-2" || len ( fingerprint ) < 10 {
t . Fatalf ( "key_fingerprint = %q, want hashed fingerprint instead of raw key" , fingerprint )
}
if accountStatus != "passed" {
t . Fatalf ( "account_status = %q, want passed" , accountStatus )
}
2026-05-29 14:43:34 +08:00
var inventoryStatus string
var inventoryShadowGroup string
if err := store . SQLDB ( ) . QueryRowContext ( context . Background ( ) , "SELECT account_status, shadow_group_id FROM provider_accounts WHERE host_account_id = ? ORDER BY id LIMIT 1" , "account_1" ) . Scan ( & inventoryStatus , & inventoryShadowGroup ) ; err != nil {
t . Fatalf ( "query provider account inventory: %v" , err )
}
if inventoryStatus != sqlite . ProviderAccountStatusActive {
t . Fatalf ( "provider_accounts.account_status = %q, want %q" , inventoryStatus , sqlite . ProviderAccountStatusActive )
}
if inventoryShadowGroup == "" {
t . Fatal ( "provider_accounts.shadow_group_id = empty, want group id" )
}
2026-05-15 19:26:25 +08:00
}
2026-05-26 07:50:43 +08:00
func TestRuntimeImportServiceIncludesMatchingHostOverlaysInReport ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
host := & fakeHostAdapter {
hostVersion : "0.1.129" ,
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" } } ,
testResults : map [ string ] sub2api . ProbeResult { "account_1" : { OK : true , Status : "passed" } } ,
models : map [ string ] [ ] sub2api . AccountModel { "account_1" : { { ID : "kimi-k2.6" } } } ,
gatewayResult : sub2api . GatewayAccessResult { OK : true , StatusCode : 200 , HasExpectedModel : true , Models : [ ] string { "kimi-k2.6" } , CompletionOK : true , CompletionStatus : 200 } ,
}
provider := sampleProviderManifest ( )
provider . ProviderID = "kimi-a7m"
provider . DefaultModels = [ ] string { "kimi-k2.6" }
provider . SmokeTestModel = "kimi-k2.6"
provider . ChannelTemplate . ModelMapping = map [ string ] string { "kimi-k2.6" : "kimi-k2.6" }
provider . HostOverlays = [ ] pack . HostOverlay { {
OverlayID : "sub2api-stock-v0129-kimi-a7m" ,
DisplayName : "sub2api stock v0.1.129 Kimi A7M overlay" ,
TargetHost : "sub2api" ,
MinHostVersion : "0.1.129" ,
MaxHostVersion : "0.1.129" ,
Reason : "stock host still routes chat traffic into unsupported Responses path" ,
} }
result , err := NewRuntimeImportService ( store , host ) . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : provider ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSubscription ,
Subscriptions : [ ] SubscriptionTarget { { UserID : "crm-user" , DurationDays : 30 } } ,
} ,
} )
if err != nil {
t . Fatalf ( "RuntimeImportService.Import() error = %v" , err )
}
if len ( result . Report . HostOverlays ) != 1 || result . Report . HostOverlays [ 0 ] . OverlayID != "sub2api-stock-v0129-kimi-a7m" {
t . Fatalf ( "HostOverlays = %+v, want matching overlay" , result . Report . HostOverlays )
}
}
2026-05-15 19:26:25 +08:00
func TestRuntimeImportServicePersistsFailedBatchAfterStrictRollback ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
2026-05-18 22:22:22 +08:00
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
2026-05-15 19:26:25 +08:00
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" } , { ID : "account_2" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : { OK : true , Status : "passed" } ,
"account_2" : { OK : false , Status : "failed" , Message : "bad key" } ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "deepseek-chat" } } ,
"account_2" : { { ID : "deepseek-chat" } } ,
} ,
}
svc := NewRuntimeImportService ( store , host )
result , err := svc . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModeStrict ,
Keys : [ ] string { "key-1" , "key-2" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-key" ,
} ,
} )
if err == nil {
t . Fatal ( "RuntimeImportService.Import() error = nil, want strict failure" )
}
if result . BatchID <= 0 {
t . Fatalf ( "BatchID = %d, want positive id" , result . BatchID )
}
var batchStatus string
var accessStatus string
if err := store . SQLDB ( ) . QueryRowContext ( context . Background ( ) , "SELECT batch_status, access_status FROM import_batches WHERE id = ?" , result . BatchID ) . Scan ( & batchStatus , & accessStatus ) ; err != nil {
t . Fatalf ( "query failed import batch state: %v" , err )
}
if batchStatus != BatchStatusFailed {
t . Fatalf ( "persisted batch_status = %q, want %q" , batchStatus , BatchStatusFailed )
}
if accessStatus != AccessStatusBroken {
t . Fatalf ( "persisted access_status = %q, want %q" , accessStatus , AccessStatusBroken )
}
if got := queryCount ( t , store . SQLDB ( ) , "managed_resources" ) ; got != 0 {
t . Fatalf ( "managed_resources row count = %d, want 0 after strict rollback" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "probe_results" ) ; got != 2 {
t . Fatalf ( "probe_results row count = %d, want 2" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "access_closure_records" ) ; got != 1 {
t . Fatalf ( "access_closure_records row count = %d, want 1" , got )
}
}
2026-05-21 21:19:19 +08:00
func TestRuntimeImportServicePersistsWarningAccountStatusForAdvisoryProbeFailure ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : {
OK : false ,
Status : "failed" ,
Message : "账号本身可正常使用,但当前测试接口仅支持 Responses API 路径。请直接通过实际 API 调用验证。" ,
} ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "deepseek-chat" } } ,
2026-05-22 12:33:12 +08:00
} ,
gatewayResult : sub2api . GatewayAccessResult {
OK : true ,
StatusCode : 200 ,
HasExpectedModel : true ,
Models : [ ] string { "deepseek-chat" } ,
CompletionOK : true ,
CompletionStatus : 200 ,
} ,
}
svc := NewRuntimeImportService ( store , host )
result , err := svc . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-key" ,
} ,
} )
if err != nil {
t . Fatalf ( "RuntimeImportService.Import() error = %v" , err )
}
if result . Report . BatchStatus != BatchStatusSucceeded {
t . Fatalf ( "BatchStatus = %q, want %q" , result . Report . BatchStatus , BatchStatusSucceeded )
}
var accountStatus string
var summary string
if err := store . SQLDB ( ) . QueryRowContext ( context . Background ( ) , "SELECT account_status, probe_summary_json FROM import_batch_items WHERE batch_id = ? ORDER BY id LIMIT 1" , result . BatchID ) . Scan ( & accountStatus , & summary ) ; err != nil {
t . Fatalf ( "query import batch item: %v" , err )
}
if accountStatus != AccountStatusWarning {
t . Fatalf ( "account_status = %q, want %q" , accountStatus , AccountStatusWarning )
}
if ! strings . Contains ( summary , "\"probe_advisory\":true" ) {
t . Fatalf ( "probe_summary_json = %s, want probe_advisory=true" , summary )
}
}
func TestRuntimeImportServicePersistsWarningAccountStatusForForbiddenProbeRace ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : {
OK : false ,
Status : "failed" ,
Message : "API returned 403: Forbidden" ,
} ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "deepseek-chat" } } ,
2026-05-21 21:19:19 +08:00
} ,
gatewayResult : sub2api . GatewayAccessResult {
OK : true ,
StatusCode : 200 ,
HasExpectedModel : true ,
Models : [ ] string { "deepseek-chat" } ,
CompletionOK : true ,
CompletionStatus : 200 ,
} ,
}
svc := NewRuntimeImportService ( store , host )
result , err := svc . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-key" ,
} ,
} )
if err != nil {
t . Fatalf ( "RuntimeImportService.Import() error = %v" , err )
}
if result . Report . BatchStatus != BatchStatusSucceeded {
t . Fatalf ( "BatchStatus = %q, want %q" , result . Report . BatchStatus , BatchStatusSucceeded )
}
var accountStatus string
var summary string
if err := store . SQLDB ( ) . QueryRowContext ( context . Background ( ) , "SELECT account_status, probe_summary_json FROM import_batch_items WHERE batch_id = ? ORDER BY id LIMIT 1" , result . BatchID ) . Scan ( & accountStatus , & summary ) ; err != nil {
t . Fatalf ( "query import batch item: %v" , err )
}
if accountStatus != AccountStatusWarning {
t . Fatalf ( "account_status = %q, want %q" , accountStatus , AccountStatusWarning )
}
if ! strings . Contains ( summary , "\"probe_advisory\":true" ) {
t . Fatalf ( "probe_summary_json = %s, want probe_advisory=true" , summary )
}
}
2026-05-18 22:22:22 +08:00
func TestRuntimeImportServicePersistsPartialManagedResourcesOnAccessFailure ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : { OK : true , Status : "passed" } ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "deepseek-chat" } } ,
} ,
assignErr : fmt . Errorf ( "group is not a subscription type" ) ,
}
svc := NewRuntimeImportService ( store , host )
result , err := svc . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSubscription ,
ProbeAPIKey : "user-key" ,
Subscriptions : [ ] SubscriptionTarget { { UserID : "1" , DurationDays : 30 } } ,
} ,
} )
if err == nil {
t . Fatal ( "RuntimeImportService.Import() error = nil, want partial failure" )
}
if result . BatchID <= 0 {
t . Fatalf ( "BatchID = %d, want positive id" , result . BatchID )
}
if got := queryCount ( t , store . SQLDB ( ) , "managed_resources" ) ; got != 4 {
t . Fatalf ( "managed_resources row count = %d, want 4 persisted resources on partial failure" , got )
}
var batchStatus string
if err := store . SQLDB ( ) . QueryRowContext ( context . Background ( ) , "SELECT batch_status FROM import_batches WHERE id = ?" , result . BatchID ) . Scan ( & batchStatus ) ; err != nil {
t . Fatalf ( "query import batch status: %v" , err )
}
if batchStatus != BatchStatusPartial {
t . Fatalf ( "persisted batch_status = %q, want %q" , batchStatus , BatchStatusPartial )
}
}
2026-05-23 09:18:02 +08:00
func TestRuntimeImportServicePersistsSelfServiceProbeKeyInAccessClosure ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" , Name : "deepseek-01" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : { OK : true , Status : "passed" } ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "deepseek-chat" } } ,
} ,
gatewayResult : sub2api . GatewayAccessResult { OK : true , StatusCode : 200 , HasExpectedModel : true , Models : [ ] string { "deepseek-chat" } , CompletionOK : true , CompletionStatus : 200 } ,
}
result , err := NewRuntimeImportService ( store , host ) . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-probe-key" ,
} ,
} )
if err != nil {
t . Fatalf ( "RuntimeImportService.Import() error = %v" , err )
}
closures , err := store . AccessClosures ( ) . GetByBatchID ( context . Background ( ) , result . BatchID )
if err != nil {
t . Fatalf ( "AccessClosures().GetByBatchID() error = %v" , err )
}
if len ( closures ) != 1 {
t . Fatalf ( "access closures = %d, want 1" , len ( closures ) )
}
var payload map [ string ] any
if err := json . Unmarshal ( [ ] byte ( closures [ 0 ] . DetailsJSON ) , & payload ) ; err != nil {
t . Fatalf ( "decode access closure details: %v" , err )
}
if got , _ := payload [ "probe_api_key" ] . ( string ) ; got != "user-probe-key" {
t . Fatalf ( "probe_api_key = %q, want user-probe-key" , got )
}
2026-05-23 17:06:52 +08:00
if got , _ := payload [ "requested_probe_api_key" ] . ( string ) ; got != "user-probe-key" {
t . Fatalf ( "requested_probe_api_key = %q, want user-probe-key" , got )
}
if got , _ := payload [ "effective_probe_key_source" ] . ( string ) ; got != "requested_probe_api_key" {
t . Fatalf ( "effective_probe_key_source = %q, want requested_probe_api_key" , got )
}
if got , _ := payload [ "effective_probe_key_fingerprint" ] . ( string ) ; got != fingerprintSecret ( "user-probe-key" ) {
t . Fatalf ( "effective_probe_key_fingerprint = %q, want hashed user-probe-key" , got )
}
2026-05-23 09:18:02 +08:00
}
func TestRuntimeImportServicePersistsSubscriptionMetadataInAccessClosure ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" , Name : "deepseek-01" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : { OK : true , Status : "passed" } ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "deepseek-chat" } } ,
} ,
gatewayResult : sub2api . GatewayAccessResult { OK : true , StatusCode : 200 , HasExpectedModel : true , Models : [ ] string { "deepseek-chat" } , CompletionOK : true , CompletionStatus : 200 } ,
}
result , err := NewRuntimeImportService ( store , host ) . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSubscription ,
Subscriptions : [ ] SubscriptionTarget { { UserID : "user-42" , DurationDays : 30 } } ,
} ,
} )
if err != nil {
t . Fatalf ( "RuntimeImportService.Import() error = %v" , err )
}
closures , err := store . AccessClosures ( ) . GetByBatchID ( context . Background ( ) , result . BatchID )
if err != nil {
t . Fatalf ( "AccessClosures().GetByBatchID() error = %v" , err )
}
if len ( closures ) != 1 {
t . Fatalf ( "access closures = %d, want 1" , len ( closures ) )
}
var payload map [ string ] any
if err := json . Unmarshal ( [ ] byte ( closures [ 0 ] . DetailsJSON ) , & payload ) ; err != nil {
t . Fatalf ( "decode access closure details: %v" , err )
}
users , _ := payload [ "subscription_users" ] . ( [ ] any )
if len ( users ) != 1 || users [ 0 ] != "user-42" {
t . Fatalf ( "subscription_users = %#v, want [user-42]" , users )
}
if got , _ := payload [ "subscription_days" ] . ( float64 ) ; int ( got ) != 30 {
t . Fatalf ( "subscription_days = %v, want 30" , got )
}
2026-05-23 17:06:52 +08:00
if _ , ok := payload [ "probe_api_key" ] ; ok {
t . Fatalf ( "probe_api_key should be omitted for subscription closure, got %#v" , payload [ "probe_api_key" ] )
}
if got , _ := payload [ "effective_probe_key_source" ] . ( string ) ; got != "managed_subscription" {
t . Fatalf ( "effective_probe_key_source = %q, want managed_subscription" , got )
}
if got , _ := payload [ "effective_probe_key_fingerprint" ] . ( string ) ; got != fingerprintSecret ( "managed-subscription-key" ) {
t . Fatalf ( "effective_probe_key_fingerprint = %q, want managed-subscription-key fingerprint" , got )
}
2026-05-23 09:18:02 +08:00
}
2026-05-18 22:22:22 +08:00
func TestRuntimeImportServiceRepeatedImportReusesManagedResources ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" , Name : "key-1" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : { OK : true , Status : "passed" } ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "deepseek-chat" } } ,
} ,
gatewayResult : sub2api . GatewayAccessResult { OK : true , StatusCode : 200 , HasExpectedModel : true , Models : [ ] string { "deepseek-chat" } } ,
}
svc := NewRuntimeImportService ( store , host )
request := RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-key" ,
} ,
}
first , err := svc . Import ( context . Background ( ) , request )
if err != nil {
t . Fatalf ( "first Import() error = %v" , err )
}
second , err := svc . Import ( context . Background ( ) , request )
if err != nil {
t . Fatalf ( "second Import() error = %v" , err )
}
if second . BatchID <= first . BatchID {
t . Fatalf ( "second BatchID = %d, want > first BatchID %d" , second . BatchID , first . BatchID )
}
if got := queryCount ( t , store . SQLDB ( ) , "managed_resources" ) ; got != 3 {
t . Fatalf ( "managed_resources row count = %d, want 3 after reused import" , got )
}
if got := queryCount ( t , store . SQLDB ( ) , "import_batches" ) ; got != 2 {
t . Fatalf ( "import_batches row count = %d, want 2" , got )
}
}
2026-05-23 10:55:57 +08:00
func TestRuntimeImportServiceResolvesHostByBaseURL ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : { OK : true , Status : "passed" } ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "deepseek-chat" } } ,
} ,
gatewayResult : sub2api . GatewayAccessResult {
OK : true ,
StatusCode : 200 ,
HasExpectedModel : true ,
Models : [ ] string { "deepseek-chat" } ,
CompletionOK : true ,
CompletionStatus : 200 ,
} ,
}
result , err := NewRuntimeImportService ( store , host ) . Import ( context . Background ( ) , RuntimeImportRequest {
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-key" ,
} ,
} )
if err != nil {
t . Fatalf ( "RuntimeImportService.Import() error = %v" , err )
}
if result . BatchID <= 0 {
t . Fatalf ( "BatchID = %d, want positive id" , result . BatchID )
}
}
func TestRuntimeImportServiceRejectsUnregisteredHostBaseURL ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
_ , err := NewRuntimeImportService ( store , & fakeHostAdapter { } ) . Import ( context . Background ( ) , RuntimeImportRequest {
HostBaseURL : "https://missing.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-key" ,
} ,
} )
if err == nil || ! strings . Contains ( err . Error ( ) , ` host_id is required for unregistered host_base_url "https://missing.example.com" ` ) {
t . Fatalf ( "RuntimeImportService.Import() error = %v, want unregistered host_base_url error" , err )
}
}
func TestRuntimeImportServiceRejectsHostBaseURLMismatch ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
_ , err := NewRuntimeImportService ( store , & fakeHostAdapter { } ) . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://other.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : sampleProviderManifest ( ) ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-key" ,
} ,
} )
if err == nil || err . Error ( ) != ` host "host-1" base_url mismatch: registered=https://sub2api.example.com runtime=https://other.example.com ` {
t . Fatalf ( "RuntimeImportService.Import() error = %v, want base_url mismatch" , err )
}
}
2026-05-21 09:18:17 +08:00
func TestRuntimeImportServiceImportReconcilesExistingChannelConfiguration ( t * testing . T ) {
store := openProvisionTestStore ( t )
defer closeProvisionTestStore ( t , store )
seedProvisionHost ( t , store , "host-1" , "https://sub2api.example.com" )
host := & fakeHostAdapter {
batchAccounts : [ ] sub2api . AccountRef { { ID : "account_1" , Name : "minimax-01" } } ,
testResults : map [ string ] sub2api . ProbeResult {
"account_1" : { OK : true , Status : "passed" } ,
} ,
models : map [ string ] [ ] sub2api . AccountModel {
"account_1" : { { ID : "MiniMax-M2.7-highspeed" } } ,
} ,
gatewayResult : sub2api . GatewayAccessResult { OK : true , StatusCode : 200 , HasExpectedModel : true , Models : [ ] string { "MiniMax-M2.5-highspeed" , "MiniMax-M2.7-highspeed" } } ,
managedSnapshot : sub2api . ManagedResourceSnapshot {
Groups : [ ] sub2api . NamedResource { { ID : "group_existing" , Name : "MiniMax 默认分组-self-service" } } ,
Channels : [ ] sub2api . NamedResource { { ID : "channel_existing" , Name : "MiniMax 默认渠道-self-service" } } ,
Plans : [ ] sub2api . NamedResource { { ID : "plan_existing" , Name : "MiniMax 默认套餐-self-service" } } ,
} ,
}
provider := sampleProviderManifest ( )
provider . ProviderID = "minimax"
provider . DisplayName = "MiniMax OpenAI Compatible"
provider . BaseURL = "https://v2.aicodee.com/v1"
provider . DefaultModels = [ ] string { "MiniMax-M2.5-highspeed" , "MiniMax-M2.7-highspeed" }
provider . SmokeTestModel = "MiniMax-M2.7-highspeed"
provider . GroupTemplate . Name = "MiniMax 默认分组"
provider . ChannelTemplate = pack . ChannelTemplate {
Name : "MiniMax 默认渠道" ,
ModelMapping : map [ string ] string { "MiniMax-M2.5-highspeed" : "MiniMax-M2.5-highspeed" , "MiniMax-M2.7-highspeed" : "MiniMax-M2.7-highspeed" } ,
}
provider . PlanTemplate . Name = "MiniMax 默认套餐"
svc := NewRuntimeImportService ( store , host )
result , err := svc . Import ( context . Background ( ) , RuntimeImportRequest {
HostID : "host-1" ,
HostBaseURL : "https://sub2api.example.com" ,
Pack : pack . LoadedPack {
Manifest : pack . Manifest { PackID : "openai-cn-pack" , Version : "1.0.0" , TargetHost : "sub2api" , MinHostVersion : "0.1.126" , MaxHostVersion : "0.2.x" } ,
Checksum : "checksum-1" ,
} ,
Provider : provider ,
Mode : ImportModePartial ,
Keys : [ ] string { "key-1" } ,
Access : AccessRequest {
Mode : AccessModeSelfService ,
ProbeAPIKey : "user-key" ,
} ,
} )
if err != nil {
t . Fatalf ( "RuntimeImportService.Import() error = %v" , err )
}
if result . Report . Channel . ID != "channel_existing" {
t . Fatalf ( "Channel.ID = %q, want reused channel_existing" , result . Report . Channel . ID )
}
if host . createChannelCalls != 0 {
t . Fatalf ( "CreateChannel() calls = %d, want 0 when channel already exists" , host . createChannelCalls )
}
if host . updateChannelCalls != 1 {
t . Fatalf ( "UpdateChannel() calls = %d, want 1" , host . updateChannelCalls )
}
if host . updateChannelID != "channel_existing" {
t . Fatalf ( "UpdateChannel() id = %q, want channel_existing" , host . updateChannelID )
}
if len ( host . updateChannelReq . ModelPricing ) != 1 {
t . Fatalf ( "UpdateChannel().ModelPricing len = %d, want 1" , len ( host . updateChannelReq . ModelPricing ) )
}
if got := host . updateChannelReq . ModelPricing [ 0 ] . Models ; len ( got ) != 2 || got [ 0 ] != "MiniMax-M2.5-highspeed" || got [ 1 ] != "MiniMax-M2.7-highspeed" {
t . Fatalf ( "UpdateChannel().ModelPricing[0].Models = %v, want minimax default models" , got )
}
if host . updateChannelReq . ModelPricing [ 0 ] . BillingMode != "token" {
t . Fatalf ( "UpdateChannel().ModelPricing[0].BillingMode = %q, want token" , host . updateChannelReq . ModelPricing [ 0 ] . BillingMode )
}
}
2026-05-15 19:26:25 +08:00
func openProvisionTestStore ( t * testing . T ) * sqlite . DB {
t . Helper ( )
2026-05-25 07:30:07 +08:00
return testutil . OpenSQLiteStore ( t , testutil . SQLiteTestDSN ( t , "state.db" , true ) )
2026-05-15 19:26:25 +08:00
}
func closeProvisionTestStore ( t * testing . T , store * sqlite . DB ) {
t . Helper ( )
2026-05-25 07:30:07 +08:00
testutil . CloseSQLiteStore ( t , store )
2026-05-15 19:26:25 +08:00
}
2026-05-18 22:22:22 +08:00
func seedProvisionHost ( t * testing . T , store * sqlite . DB , hostID , baseURL string ) int64 {
t . Helper ( )
id , err := store . Hosts ( ) . Create ( context . Background ( ) , sqlite . Host {
HostID : hostID ,
BaseURL : baseURL ,
HostVersion : "0.1.126" ,
AuthType : "apikey" ,
AuthToken : "test-host-token" ,
} )
if err != nil {
t . Fatalf ( "Hosts().Create() error = %v" , err )
}
return id
}
2026-05-15 19:26:25 +08:00
func queryCount ( t * testing . T , db * sql . DB , table string ) int {
t . Helper ( )
var count int
if err := db . QueryRowContext ( context . Background ( ) , "SELECT COUNT(*) FROM " + table ) . Scan ( & count ) ; err != nil {
t . Fatalf ( "count rows for %s: %v" , table , err )
}
return count
}