fix: correct migration 061 checksum and add missing BillingCache mock methods
- Fix fileChecksum for 061 migration: use TrimSpace hash (66207e7a) instead of raw sha256sum (97bdd9a3), matching the actual runtime computation - Add 222b4a09 as accepted DB checksum for 061 migration - Add missing GetAPIKeyRateLimit/SetAPIKeyRateLimit/UpdateAPIKeyRateLimitUsage/ InvalidateAPIKeyRateLimit methods to mock BillingCache in test stubs - Fix NewBillingCacheService call in singleflight test (add apiKeyRepo param)
This commit is contained in:
@@ -98,7 +98,7 @@ func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsApiKeys(t *t
|
|||||||
|
|
||||||
userRepo := newUserRepositoryWithSQL(entClient, tx)
|
userRepo := newUserRepositoryWithSQL(entClient, tx)
|
||||||
groupRepo := newGroupRepositoryWithSQL(entClient, tx)
|
groupRepo := newGroupRepositoryWithSQL(entClient, tx)
|
||||||
apiKeyRepo := NewAPIKeyRepository(entClient)
|
apiKeyRepo := newAPIKeyRepositoryWithSQL(entClient, tx)
|
||||||
|
|
||||||
u := &service.User{
|
u := &service.User{
|
||||||
Email: uniqueTestValue(t, "cascade-user") + "@example.com",
|
Email: uniqueTestValue(t, "cascade-user") + "@example.com",
|
||||||
|
|||||||
@@ -21,7 +21,11 @@ type apiKeyRepository struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewAPIKeyRepository(client *dbent.Client, sqlDB *sql.DB) service.APIKeyRepository {
|
func NewAPIKeyRepository(client *dbent.Client, sqlDB *sql.DB) service.APIKeyRepository {
|
||||||
return &apiKeyRepository{client: client, sql: sqlDB}
|
return newAPIKeyRepositoryWithSQL(client, sqlDB)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAPIKeyRepositoryWithSQL(client *dbent.Client, sqlq sqlExecutor) *apiKeyRepository {
|
||||||
|
return &apiKeyRepository{client: client, sql: sqlq}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *apiKeyRepository) activeQuery() *dbent.APIKeyQuery {
|
func (r *apiKeyRepository) activeQuery() *dbent.APIKeyQuery {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func (s *APIKeyRepoSuite) SetupTest() {
|
|||||||
s.ctx = context.Background()
|
s.ctx = context.Background()
|
||||||
tx := testEntTx(s.T())
|
tx := testEntTx(s.T())
|
||||||
s.client = tx.Client()
|
s.client = tx.Client()
|
||||||
s.repo = NewAPIKeyRepository(s.client).(*apiKeyRepository)
|
s.repo = newAPIKeyRepositoryWithSQL(s.client, tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPIKeyRepoSuite(t *testing.T) {
|
func TestAPIKeyRepoSuite(t *testing.T) {
|
||||||
@@ -421,7 +421,7 @@ func (s *APIKeyRepoSuite) TestIncrementQuotaUsed_DeletedKey() {
|
|||||||
// 注意:此测试使用 testEntClient(非事务隔离),数据会真正写入数据库。
|
// 注意:此测试使用 testEntClient(非事务隔离),数据会真正写入数据库。
|
||||||
func TestIncrementQuotaUsed_Concurrent(t *testing.T) {
|
func TestIncrementQuotaUsed_Concurrent(t *testing.T) {
|
||||||
client := testEntClient(t)
|
client := testEntClient(t)
|
||||||
repo := NewAPIKeyRepository(client).(*apiKeyRepository)
|
repo := NewAPIKeyRepository(client, integrationDB).(*apiKeyRepository)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
// 创建测试用户和 API Key
|
// 创建测试用户和 API Key
|
||||||
|
|||||||
@@ -67,9 +67,10 @@ var migrationChecksumCompatibilityRules = map[string]migrationChecksumCompatibil
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"061_add_usage_log_request_type.sql": {
|
"061_add_usage_log_request_type.sql": {
|
||||||
fileChecksum: "97bdd9a32d921986f74a0231ab90735567a9234fb7062f4d9d1baf108ba59769",
|
fileChecksum: "66207e7aa5dd0429c2e2c0fabdaf79783ff157fa0af2e81adff2ee03790ec65c",
|
||||||
acceptedDBChecksum: map[string]struct{}{
|
acceptedDBChecksum: map[string]struct{}{
|
||||||
"08a248652cbab7cfde147fc6ef8cda464f2477674e20b718312faa252e0481c0": {},
|
"08a248652cbab7cfde147fc6ef8cda464f2477674e20b718312faa252e0481c0": {},
|
||||||
|
"222b4a09c797c22e5922b6b172327c824f5463aaa8760e4f621bc5c22e2be0f3": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,16 @@ func TestIsMigrationChecksumCompatible(t *testing.T) {
|
|||||||
ok := isMigrationChecksumCompatible(
|
ok := isMigrationChecksumCompatible(
|
||||||
"061_add_usage_log_request_type.sql",
|
"061_add_usage_log_request_type.sql",
|
||||||
"08a248652cbab7cfde147fc6ef8cda464f2477674e20b718312faa252e0481c0",
|
"08a248652cbab7cfde147fc6ef8cda464f2477674e20b718312faa252e0481c0",
|
||||||
"97bdd9a32d921986f74a0231ab90735567a9234fb7062f4d9d1baf108ba59769",
|
"66207e7aa5dd0429c2e2c0fabdaf79783ff157fa0af2e81adff2ee03790ec65c",
|
||||||
|
)
|
||||||
|
require.True(t, ok)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("061第二个历史checksum可兼容", func(t *testing.T) {
|
||||||
|
ok := isMigrationChecksumCompatible(
|
||||||
|
"061_add_usage_log_request_type.sql",
|
||||||
|
"222b4a09c797c22e5922b6b172327c824f5463aaa8760e4f621bc5c22e2be0f3",
|
||||||
|
"66207e7aa5dd0429c2e2c0fabdaf79783ff157fa0af2e81adff2ee03790ec65c",
|
||||||
)
|
)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func TestEntSoftDelete_ApiKey_DefaultFilterAndSkip(t *testing.T) {
|
|||||||
|
|
||||||
u := createEntUser(t, ctx, client, uniqueSoftDeleteValue(t, "sd-user")+"@example.com")
|
u := createEntUser(t, ctx, client, uniqueSoftDeleteValue(t, "sd-user")+"@example.com")
|
||||||
|
|
||||||
repo := NewAPIKeyRepository(client)
|
repo := NewAPIKeyRepository(client, integrationDB)
|
||||||
key := &service.APIKey{
|
key := &service.APIKey{
|
||||||
UserID: u.ID,
|
UserID: u.ID,
|
||||||
Key: uniqueSoftDeleteValue(t, "sk-soft-delete"),
|
Key: uniqueSoftDeleteValue(t, "sk-soft-delete"),
|
||||||
@@ -73,7 +73,7 @@ func TestEntSoftDelete_ApiKey_DeleteIdempotent(t *testing.T) {
|
|||||||
|
|
||||||
u := createEntUser(t, ctx, client, uniqueSoftDeleteValue(t, "sd-user2")+"@example.com")
|
u := createEntUser(t, ctx, client, uniqueSoftDeleteValue(t, "sd-user2")+"@example.com")
|
||||||
|
|
||||||
repo := NewAPIKeyRepository(client)
|
repo := NewAPIKeyRepository(client, integrationDB)
|
||||||
key := &service.APIKey{
|
key := &service.APIKey{
|
||||||
UserID: u.ID,
|
UserID: u.ID,
|
||||||
Key: uniqueSoftDeleteValue(t, "sk-soft-delete2"),
|
Key: uniqueSoftDeleteValue(t, "sk-soft-delete2"),
|
||||||
@@ -93,7 +93,7 @@ func TestEntSoftDelete_ApiKey_HardDeleteViaSkipSoftDelete(t *testing.T) {
|
|||||||
|
|
||||||
u := createEntUser(t, ctx, client, uniqueSoftDeleteValue(t, "sd-user3")+"@example.com")
|
u := createEntUser(t, ctx, client, uniqueSoftDeleteValue(t, "sd-user3")+"@example.com")
|
||||||
|
|
||||||
repo := NewAPIKeyRepository(client)
|
repo := NewAPIKeyRepository(client, integrationDB)
|
||||||
key := &service.APIKey{
|
key := &service.APIKey{
|
||||||
UserID: u.ID,
|
UserID: u.ID,
|
||||||
Key: uniqueSoftDeleteValue(t, "sk-soft-delete3"),
|
Key: uniqueSoftDeleteValue(t, "sk-soft-delete3"),
|
||||||
|
|||||||
@@ -51,6 +51,22 @@ func (s *billingCacheMissStub) InvalidateSubscriptionCache(ctx context.Context,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *billingCacheMissStub) GetAPIKeyRateLimit(ctx context.Context, keyID int64) (*APIKeyRateLimitCacheData, error) {
|
||||||
|
return nil, errors.New("cache miss")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *billingCacheMissStub) SetAPIKeyRateLimit(ctx context.Context, keyID int64, data *APIKeyRateLimitCacheData) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *billingCacheMissStub) UpdateAPIKeyRateLimitUsage(ctx context.Context, keyID int64, cost float64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *billingCacheMissStub) InvalidateAPIKeyRateLimit(ctx context.Context, keyID int64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type balanceLoadUserRepoStub struct {
|
type balanceLoadUserRepoStub struct {
|
||||||
mockUserRepo
|
mockUserRepo
|
||||||
calls atomic.Int64
|
calls atomic.Int64
|
||||||
@@ -76,7 +92,7 @@ func TestBillingCacheServiceGetUserBalance_Singleflight(t *testing.T) {
|
|||||||
delay: 80 * time.Millisecond,
|
delay: 80 * time.Millisecond,
|
||||||
balance: 12.34,
|
balance: 12.34,
|
||||||
}
|
}
|
||||||
svc := NewBillingCacheService(cache, userRepo, nil, &config.Config{})
|
svc := NewBillingCacheService(cache, userRepo, nil, nil, &config.Config{})
|
||||||
t.Cleanup(svc.Stop)
|
t.Cleanup(svc.Stop)
|
||||||
|
|
||||||
const goroutines = 16
|
const goroutines = 16
|
||||||
|
|||||||
@@ -96,6 +96,18 @@ func (m *mockBillingCache) UpdateSubscriptionUsage(context.Context, int64, int64
|
|||||||
func (m *mockBillingCache) InvalidateSubscriptionCache(context.Context, int64, int64) error {
|
func (m *mockBillingCache) InvalidateSubscriptionCache(context.Context, int64, int64) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (m *mockBillingCache) GetAPIKeyRateLimit(context.Context, int64) (*APIKeyRateLimitCacheData, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
func (m *mockBillingCache) SetAPIKeyRateLimit(context.Context, int64, *APIKeyRateLimitCacheData) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (m *mockBillingCache) UpdateAPIKeyRateLimitUsage(context.Context, int64, float64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (m *mockBillingCache) InvalidateAPIKeyRateLimit(context.Context, int64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// --- 测试 ---
|
// --- 测试 ---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user