package worker import ( "context" "database/sql" "fmt" "os" "testing" _ "github.com/lib/pq" ) func setupMaterializerDB(t *testing.T) (*sql.DB, string, func()) { dsn := os.Getenv("TEST_DATABASE_URL") if dsn == "" { t.Skip("TEST_DATABASE_URL not set") } db, err := sql.Open("postgres", dsn) if err != nil { t.Fatal(err) } if err := db.Ping(); err != nil { t.Skipf("DB ping failed: %v", err) } schema := "statistic_test_mat_" + sanitizeName(t.Name()) db.Exec("CREATE SCHEMA IF NOT EXISTS " + schema) // refresh_log 表(MV DDL 不需要建,因为只测 RefreshOne 对 refresh_log 的写) db.Exec(fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s.refresh_log ( id BIGSERIAL PRIMARY KEY, mv_name VARCHAR(128) NOT NULL, started_at TIMESTAMPTZ NOT NULL, finished_at TIMESTAMPTZ, row_count BIGINT, status VARCHAR(16) NOT NULL, error_message TEXT )`, schema)) cleanup := func() { db.Exec("DROP SCHEMA IF EXISTS " + schema + " CASCADE") db.Close() } return db, schema, cleanup } func TestMaterializer_RefreshOne_LogsToRefreshLog(t *testing.T) { db, schema, cleanup := setupMaterializerDB(t) defer cleanup() m := NewMaterializer(db, schema) // 用一个不存在的 MV 名(期望失败但 refresh_log 仍写入) err := m.RefreshOne(context.Background(), "mv_does_not_exist") if err == nil { t.Fatal("expected error for non-existent MV") } // 验证 refresh_log 有 failed 记录 var status string if err := db.QueryRow( "SELECT status FROM "+schema+`.refresh_log WHERE mv_name='mv_does_not_exist' ORDER BY id DESC LIMIT 1`, ).Scan(&status); err != nil { t.Fatal(err) } if status != "failed" { t.Fatalf("expected status=failed, got %s", status) } }