Skip to content

Commit f508d06

Browse files
committed
Add missing reset
1 parent 42a6391 commit f508d06

File tree

2 files changed

+245
-0
lines changed

2 files changed

+245
-0
lines changed

e2e/packages/client/reset_db.go

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log/slog"
7+
"strings"
8+
9+
"github.com/jackc/pgx/v5"
10+
)
11+
12+
// ServicePortProvider provides a way to get the mapped port for a service
13+
type ServicePortProvider interface {
14+
GetServicePort(ctx context.Context, serviceName string, internalPort string) (string, error)
15+
}
16+
17+
// DatabaseConfig holds database connection configuration
18+
type DatabaseConfig struct {
19+
User string
20+
Password string
21+
Database string
22+
Host string
23+
Port string
24+
}
25+
26+
// DefaultDatabaseConfig returns the default database configuration
27+
func DefaultDatabaseConfig() DatabaseConfig {
28+
return DatabaseConfig{
29+
User: "infisical",
30+
Password: "infisical",
31+
Database: "infisical",
32+
Host: "localhost",
33+
Port: "5432",
34+
}
35+
}
36+
37+
// ResetDBOptions holds options for resetting the database
38+
type ResetDBOptions struct {
39+
SkipTables map[string]struct{} // Tables to skip when truncating (e.g., migrations)
40+
DBConfig DatabaseConfig
41+
}
42+
43+
// DefaultResetDBOptions returns default options for resetting the database
44+
func DefaultResetDBOptions() ResetDBOptions {
45+
return ResetDBOptions{
46+
SkipTables: map[string]struct{}{
47+
"public.infisical_migrations": {},
48+
"public.infisical_migrations_lock": {},
49+
},
50+
DBConfig: DefaultDatabaseConfig(),
51+
}
52+
}
53+
54+
// ResetDB resets the PostgreSQL database.
55+
// It accepts a port provider to get service ports, and options to configure the reset behavior.
56+
func ResetDB(ctx context.Context, opts ...func(*ResetDBOptions)) error {
57+
options := DefaultResetDBOptions()
58+
for _, opt := range opts {
59+
opt(&options)
60+
}
61+
62+
// Reset PostgreSQL database
63+
if err := resetPostgresDB(ctx, options); err != nil {
64+
return fmt.Errorf("failed to reset PostgreSQL database: %w", err)
65+
}
66+
67+
return nil
68+
}
69+
70+
// resetPostgresDB resets the PostgreSQL database by truncating all tables (except skipped ones)
71+
// and inserting a default super_admin record.
72+
func resetPostgresDB(ctx context.Context, opts ResetDBOptions) error {
73+
// Build connection string using config
74+
connStr := fmt.Sprintf("postgresql://%s:%s@%s:%s/%s",
75+
opts.DBConfig.User,
76+
opts.DBConfig.Password,
77+
opts.DBConfig.Host,
78+
opts.DBConfig.Port,
79+
opts.DBConfig.Database,
80+
)
81+
82+
conn, err := pgx.Connect(ctx, connStr)
83+
if err != nil {
84+
slog.Error("Unable to connect to database", "err", err)
85+
return err
86+
}
87+
defer conn.Close(ctx)
88+
89+
// Get all tables
90+
query := `
91+
SELECT table_schema, table_name
92+
FROM information_schema.tables
93+
WHERE table_type = 'BASE TABLE'
94+
AND table_schema NOT IN ('pg_catalog', 'information_schema')
95+
ORDER BY table_schema, table_name;
96+
`
97+
98+
rows, err := conn.Query(ctx, query)
99+
if err != nil {
100+
slog.Error("Unable to execute query", "query", query, "err", err)
101+
return err
102+
}
103+
defer rows.Close()
104+
105+
tables := make([]string, 0)
106+
for rows.Next() {
107+
var schema, table string
108+
if err := rows.Scan(&schema, &table); err != nil {
109+
slog.Error("Scan failed", "error", err)
110+
return err
111+
}
112+
tables = append(tables, fmt.Sprintf("%s.%s", schema, table))
113+
}
114+
if err := rows.Err(); err != nil {
115+
slog.Error("Row iteration error", "error", err)
116+
return err
117+
}
118+
119+
// Build truncate statements
120+
var builder strings.Builder
121+
for _, table := range tables {
122+
if _, ok := opts.SkipTables[table]; ok {
123+
continue
124+
}
125+
builder.WriteString(fmt.Sprintf("TRUNCATE TABLE %s RESTART IDENTITY CASCADE;\n", table))
126+
}
127+
128+
truncateQuery := builder.String()
129+
if truncateQuery != "" {
130+
_, err = conn.Exec(ctx, truncateQuery)
131+
if err != nil {
132+
slog.Error("Truncate failed", "error", err)
133+
return err
134+
}
135+
slog.Info("Truncate all tables successfully")
136+
}
137+
138+
// Insert default super_admin record
139+
_, err = conn.Exec(ctx,
140+
`INSERT INTO public.super_admin ("id", "fipsEnabled", "initialized", "allowSignUp") VALUES ($1, $2, $3, $4)`,
141+
"00000000-0000-0000-0000-000000000000", true, false, true)
142+
if err != nil {
143+
slog.Error("Failed to insert super_admin", "error", err)
144+
return err
145+
}
146+
147+
return nil
148+
}
149+
150+
// WithSkipTables sets the tables to skip when truncating
151+
func WithSkipTables(tables map[string]struct{}) func(*ResetDBOptions) {
152+
return func(opts *ResetDBOptions) {
153+
opts.SkipTables = tables
154+
}
155+
}
156+
157+
// WithDatabaseConfig sets the database configuration
158+
func WithDatabaseConfig(config DatabaseConfig) func(*ResetDBOptions) {
159+
return func(opts *ResetDBOptions) {
160+
opts.DBConfig = config
161+
}
162+
}

e2e/packages/client/reset_redis.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log/slog"
7+
8+
"github.com/redis/go-redis/v9"
9+
)
10+
11+
// RedisConfig holds Redis connection configuration
12+
type RedisConfig struct {
13+
Host string
14+
Port int
15+
Password string
16+
}
17+
18+
// DefaultRedisConfig returns the default Redis configuration
19+
func DefaultRedisConfig() RedisConfig {
20+
return RedisConfig{
21+
Host: "localhost",
22+
Port: 6379,
23+
Password: "",
24+
}
25+
}
26+
27+
// ResetRedisOptions holds options for resetting Redis
28+
type ResetRedisOptions struct {
29+
RedisConfig RedisConfig
30+
}
31+
32+
// DefaultResetRedisOptions returns default options for resetting Redis
33+
func DefaultResetRedisOptions() ResetRedisOptions {
34+
return ResetRedisOptions{
35+
RedisConfig: DefaultRedisConfig(),
36+
}
37+
}
38+
39+
// ResetRedis resets the Redis database by flushing all keys.
40+
// It accepts a port provider to get service ports, and options to configure the reset behavior.
41+
func ResetRedis(ctx context.Context, opts ...func(*ResetRedisOptions)) error {
42+
options := DefaultResetRedisOptions()
43+
for _, opt := range opts {
44+
opt(&options)
45+
}
46+
47+
return resetRedisDB(ctx, options)
48+
}
49+
50+
// resetRedisDB resets the Redis database by flushing all keys.
51+
func resetRedisDB(ctx context.Context, opts ResetRedisOptions) error {
52+
addr := fmt.Sprintf("%s:%d", opts.RedisConfig.Host, opts.RedisConfig.Port)
53+
rdb := redis.NewClient(&redis.Options{
54+
Addr: addr,
55+
Password: opts.RedisConfig.Password,
56+
})
57+
defer func() {
58+
_ = rdb.Close()
59+
}()
60+
61+
// Test the connection
62+
pong, err := rdb.Ping(ctx).Result()
63+
if err != nil {
64+
return fmt.Errorf("failed to connect to Redis: %w", err)
65+
}
66+
slog.Info("Connected to Redis", "pong", pong)
67+
68+
// Clear all keys in the current database
69+
err = rdb.FlushAll(ctx).Err()
70+
if err != nil {
71+
return fmt.Errorf("failed to flush Redis database: %w", err)
72+
}
73+
slog.Info("All keys cleared successfully from Redis database")
74+
75+
return nil
76+
}
77+
78+
// WithRedisConfig sets the Redis configuration
79+
func WithRedisConfig(config RedisConfig) func(*ResetRedisOptions) {
80+
return func(opts *ResetRedisOptions) {
81+
opts.RedisConfig = config
82+
}
83+
}

0 commit comments

Comments
 (0)