Files
lijiaoqiao/supply-api/internal/repository/package_integration_test.go

243 lines
6.1 KiB
Go
Raw Normal View History

//go:build integration
// +build integration
package repository
import (
"context"
"os"
"testing"
"github.com/jackc/pgx/v5/pgxpool"
)
// getPackageTestDB 获取测试数据库连接
func getPackageTestDB(t *testing.T) *pgxpool.Pool {
t.Helper()
host := os.Getenv("SUPPLY_API_DB_HOST")
if host == "" {
host = "/var/run/postgresql"
}
port := os.Getenv("SUPPLY_API_DB_PORT")
if port == "" {
port = "5432"
}
user := os.Getenv("SUPPLY_API_DB_USER")
if user == "" {
user = "long"
}
password := os.Getenv("SUPPLY_API_DB_PASSWORD")
dbName := os.Getenv("SUPPLY_API_DB_NAME")
if dbName == "" {
dbName = "supply_test"
}
// 构建 DSN - 如果 host 是路径Unix socket使用 host= 参数
var dsn string
if host[0] == '/' {
dsn = "postgres://" + user + ":" + password + "@/" + dbName + "?host=" + host + "&sslmode=disable"
} else {
dsn = "postgres://" + user + ":" + password + "@" + host + ":" + port + "/" + dbName + "?sslmode=disable"
}
pool, err := pgxpool.New(context.Background(), dsn)
if err != nil {
t.Skipf("跳过集成测试:无法连接数据库: %v", err)
return nil
}
if err := pool.Ping(context.Background()); err != nil {
pool.Close()
t.Skipf("跳过集成测试:无法 ping 数据库: %v", err)
return nil
}
t.Cleanup(func() {
pool.Close()
})
return pool
}
// TestPackageRepository_Create_Integration 集成测试:创建套餐
func TestPackageRepository_Create_Integration(t *testing.T) {
if testing.Short() {
t.Skip("跳过集成测试short mode")
}
pool := getPackageTestDB(t)
if pool == nil {
return
}
// 验证 supply_packages 表存在
var tableName string
err := pool.QueryRow(context.Background(), "SELECT table_name FROM information_schema.tables WHERE table_name = 'supply_packages'").Scan(&tableName)
if err != nil {
t.Skipf("跳过supply_packages 表不存在: %v", err)
}
t.Log("集成测试supply_packages 表存在")
}
// TestPackageRepository_GetByID_Integration 集成测试:获取套餐
func TestPackageRepository_GetByID_Integration(t *testing.T) {
if testing.Short() {
t.Skip("跳过集成测试short mode")
}
pool := getPackageTestDB(t)
if pool == nil {
return
}
var count int
err := pool.QueryRow(context.Background(), "SELECT COUNT(*) FROM supply_packages").Scan(&count)
if err != nil {
t.Logf("集成测试supply_packages 查询结果: %v", err)
} else {
t.Logf("集成测试supply_packages 共有 %d 条记录", count)
}
}
// TestPackageRepository_Update_Integration 集成测试:更新套餐(乐观锁)
func TestPackageRepository_Update_Integration(t *testing.T) {
if testing.Short() {
t.Skip("跳过集成测试short mode")
}
pool := getPackageTestDB(t)
if pool == nil {
return
}
// 验证 version 字段存在(乐观锁)
var columnExists bool
err := pool.QueryRow(context.Background(), `
SELECT EXISTS(
SELECT 1 FROM information_schema.columns
WHERE table_name = 'supply_packages' AND column_name = 'version'
)
`).Scan(&columnExists)
if err != nil || !columnExists {
t.Skip("跳过supply_packages 表缺少 version 字段")
}
t.Log("集成测试supply_packages 包含 version 字段(乐观锁)")
}
// TestPackageRepository_List_Integration 集成测试:列出套餐
func TestPackageRepository_List_Integration(t *testing.T) {
if testing.Short() {
t.Skip("跳过集成测试short mode")
}
pool := getPackageTestDB(t)
if pool == nil {
return
}
// 列出供应商标套餐
rows, err := pool.Query(context.Background(), `
SELECT id, supplier_id, available_quota
FROM supply_packages
LIMIT 10
`)
if err != nil {
t.Logf("集成测试:列出套餐: %v", err)
return
}
defer rows.Close()
count := 0
for rows.Next() {
var id, supplierID int64
var availableQuota int
rows.Scan(&id, &supplierID, &availableQuota)
count++
t.Logf("集成测试:套餐 ID=%d, SupplierID=%d, AvailableQuota=%d", id, supplierID, availableQuota)
}
t.Logf("集成测试:列出 %d 个套餐", count)
}
// TestPackageRepository_UpdateQuota_Integration 集成测试:扣减配额
func TestPackageRepository_UpdateQuota_Integration(t *testing.T) {
if testing.Short() {
t.Skip("跳过集成测试short mode")
}
pool := getPackageTestDB(t)
if pool == nil {
return
}
// 验证 available_quota 字段存在
var columnExists bool
err := pool.QueryRow(context.Background(), `
SELECT EXISTS(
SELECT 1 FROM information_schema.columns
WHERE table_name = 'supply_packages' AND column_name = 'available_quota'
)
`).Scan(&columnExists)
if err != nil || !columnExists {
t.Skip("跳过supply_packages 表缺少 available_quota 字段")
}
t.Log("集成测试supply_packages 包含 available_quota 字段")
}
// TestPackageRepository_GetForUpdate_Integration 集成测试:悲观锁获取
func TestPackageRepository_GetForUpdate_Integration(t *testing.T) {
if testing.Short() {
t.Skip("跳过集成测试short mode")
}
pool := getPackageTestDB(t)
if pool == nil {
return
}
// 测试 FOR UPDATE 锁
tx, err := pool.Begin(context.Background())
if err != nil {
t.Fatalf("开始事务失败: %v", err)
}
defer tx.Rollback(context.Background())
rows, err := tx.Query(context.Background(), "SELECT id FROM supply_packages LIMIT 1 FOR UPDATE")
if err != nil {
t.Logf("集成测试FOR UPDATE 查询: %v", err)
} else {
rows.Close()
t.Log("集成测试FOR UPDATE 锁获取成功")
}
tx.Rollback(context.Background())
}
// TestPackageRepository_OptimisticLock_Integration 集成测试:乐观锁冲突
func TestPackageRepository_OptimisticLock_Integration(t *testing.T) {
if testing.Short() {
t.Skip("跳过集成测试short mode")
}
pool := getPackageTestDB(t)
if pool == nil {
return
}
// 验证 version 字段存在
var versionCol int
err := pool.QueryRow(context.Background(), `
SELECT COUNT(*) FROM information_schema.columns
WHERE table_name = 'supply_packages' AND column_name = 'version'
`).Scan(&versionCol)
if err != nil || versionCol == 0 {
t.Skip("跳过supply_packages 表缺少 version 字段")
}
t.Log("集成测试:乐观锁字段验证通过")
}