mirror of
https://github.com/hhftechnology/middleware-manager.git
synced 2026-07-17 03:48:24 +00:00
Replace direct defers that ignored returned errors with explicit defer func() { _ = ... }() and use blank-assignment for Setenv/RemoveAll/Close to satisfy error-checking and ensure closures run. Convert several if-else chains to switch for clarity (status filter, test server path matching), switch strings.Replace to strings.ReplaceAll, and normalize some error/log message casing. These changes are minor refactors across handlers, services, database and tests to improve lint compliance and readability.
127 lines
3.7 KiB
Go
127 lines
3.7 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func newTestDB(t *testing.T) *DB {
|
|
t.Helper()
|
|
dbPath := filepath.Join(t.TempDir(), "test.db")
|
|
db, err := InitDB(dbPath)
|
|
if err != nil {
|
|
t.Fatalf("failed to init temp db: %v", err)
|
|
}
|
|
return db
|
|
}
|
|
|
|
func mustExec(t *testing.T, db *DB, query string, args ...interface{}) {
|
|
t.Helper()
|
|
if _, err := db.Exec(query, args...); err != nil {
|
|
t.Fatalf("exec failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestWithTransactionCommitAndRollback(t *testing.T) {
|
|
db := newTestDB(t)
|
|
defer func() { _ = db.Close() }()
|
|
|
|
mustExec(t, db, `CREATE TABLE items (id INTEGER PRIMARY KEY, name TEXT)`)
|
|
|
|
if err := db.WithTransaction(func(tx *sql.Tx) error {
|
|
_, err := tx.Exec("INSERT INTO items (name) VALUES (?)", "ok")
|
|
return err
|
|
}); err != nil {
|
|
t.Fatalf("commit transaction failed: %v", err)
|
|
}
|
|
|
|
var count int
|
|
if err := db.QueryRow("SELECT COUNT(*) FROM items").Scan(&count); err != nil {
|
|
t.Fatalf("count query failed: %v", err)
|
|
}
|
|
if count != 1 {
|
|
t.Fatalf("expected 1 row after commit, got %d", count)
|
|
}
|
|
|
|
// Force a rollback by returning an error from the TxFn.
|
|
_ = db.WithTransaction(func(tx *sql.Tx) error {
|
|
if _, err := tx.Exec("INSERT INTO items (name) VALUES (?)", "rollback"); err != nil {
|
|
return err
|
|
}
|
|
return errors.New("boom")
|
|
})
|
|
|
|
if err := db.QueryRow("SELECT COUNT(*) FROM items").Scan(&count); err != nil {
|
|
t.Fatalf("count query failed: %v", err)
|
|
}
|
|
if count != 1 {
|
|
t.Fatalf("expected rollback to keep 1 row, got %d", count)
|
|
}
|
|
}
|
|
|
|
func TestWithTimeoutTransaction(t *testing.T) {
|
|
db := newTestDB(t)
|
|
defer func() { _ = db.Close() }()
|
|
|
|
err := db.WithTimeoutTransaction(context.Background(), 10*time.Millisecond, func(tx *sql.Tx) error {
|
|
time.Sleep(50 * time.Millisecond)
|
|
_, execErr := tx.Exec("SELECT 1")
|
|
return execErr
|
|
})
|
|
|
|
if err == nil || !strings.Contains(err.Error(), "transaction timed out") {
|
|
t.Fatalf("expected timeout error, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCleanupDuplicateServices(t *testing.T) {
|
|
db := newTestDB(t)
|
|
defer func() { _ = db.Close() }()
|
|
|
|
// Seed duplicate services and a relationship.
|
|
mustExec(t, db, `INSERT INTO services (id, name, type, config) VALUES (?, ?, ?, ?)`,
|
|
"svc@file", "svc", "loadBalancer", "{}")
|
|
mustExec(t, db, `INSERT INTO services (id, name, type, config) VALUES (?, ?, ?, ?)`,
|
|
"svc", "svc", "loadBalancer", "{}")
|
|
mustExec(t, db, `INSERT INTO services (id, name, type, config) VALUES (?, ?, ?, ?)`,
|
|
"other", "other", "loadBalancer", "{}")
|
|
|
|
mustExec(t, db, `INSERT INTO resources (id, host, service_id, org_id, site_id, status) VALUES (?, ?, ?, ?, ?, ?)`,
|
|
"res1", "example.com", "svc@file", "org", "site", "active")
|
|
mustExec(t, db, `INSERT INTO resource_services (resource_id, service_id) VALUES (?, ?)`,
|
|
"res1", "svc@file")
|
|
|
|
if err := db.CleanupDuplicateServices(DefaultCleanupOptions()); err != nil {
|
|
t.Fatalf("cleanup failed: %v", err)
|
|
}
|
|
|
|
// Only the unsuffixed service should remain.
|
|
var count int
|
|
if err := db.QueryRow(`SELECT COUNT(*) FROM services WHERE id LIKE 'svc%'`).Scan(&count); err != nil {
|
|
t.Fatalf("count query failed: %v", err)
|
|
}
|
|
if count != 1 {
|
|
t.Fatalf("expected 1 svc* row after cleanup, got %d", count)
|
|
}
|
|
|
|
var remainingID string
|
|
if err := db.QueryRow(`SELECT id FROM services WHERE id LIKE 'svc%'`).Scan(&remainingID); err != nil {
|
|
t.Fatalf("select failed: %v", err)
|
|
}
|
|
if remainingID != "svc" {
|
|
t.Fatalf("expected svc to remain, got %s", remainingID)
|
|
}
|
|
|
|
// Relationship to deleted service should be gone.
|
|
if err := db.QueryRow(`SELECT COUNT(*) FROM resource_services`).Scan(&count); err != nil {
|
|
t.Fatalf("resource_services count failed: %v", err)
|
|
}
|
|
if count != 0 {
|
|
t.Fatalf("expected relationships cleaned up, got %d", count)
|
|
}
|
|
}
|