-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy path26_drop_create_loop.sql
More file actions
197 lines (164 loc) · 6.14 KB
/
Copy path26_drop_create_loop.sql
File metadata and controls
197 lines (164 loc) · 6.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
-- Test: Worker Restart After Drop
-- Tests that:
-- 1. After DROP EXTENSION CASCADE, worker waits for extension recreation
-- 2. Worker detects recreated extension and reinitializes
-- 3. System becomes operational again without PostgreSQL restart
-- 4. Multiple drop-recreate cycles work correctly
-- This test verifies the worker's ability to handle multiple create-drop-create cycles
-- Phase 1: Initial state - extension should exist
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_durable') THEN
RAISE EXCEPTION 'TEST FAILED: Extension should exist at test start';
END IF;
RAISE NOTICE 'PASS: Initial extension exists';
END $$;
-- Phase 2: First extension drop-create cycle
DROP EXTENSION IF EXISTS pg_durable CASCADE;
CREATE EXTENSION pg_durable;
-- Wait for worker to initialize duroxide-pg tables
DO $$
DECLARE
table_count INT;
attempts INT := 0;
BEGIN
RAISE NOTICE 'Drop-create cycle 1';
LOOP
SELECT COUNT(*) INTO table_count
FROM pg_tables
WHERE schemaname = 'duroxide'
AND tablename IN ('executions', 'instances', 'history', 'orchestrator_queue', 'worker_queue');
EXIT WHEN table_count = 5 OR attempts > 150;
PERFORM pg_sleep(0.1);
attempts := attempts + 1;
END LOOP;
IF table_count != 5 THEN
RAISE EXCEPTION 'TEST FAILED (cycle 1): Worker did not initialize duroxide-pg, found % of 5 expected tables', table_count;
END IF;
RAISE NOTICE 'PASS: Worker initialized duroxide-pg after cycle 1';
END $$;
-- Give the worker additional time to fully complete initialization
-- This avoids race conditions with migration conflicts when client connects
SELECT pg_sleep(1);
-- Verify operational with a simple durable function
CREATE TEMP TABLE _cycle1_state (instance_id TEXT);
INSERT INTO _cycle1_state
SELECT df.start('SELECT 1 as cycle1_test', 'test-worker-restart-cycle1');
DO $$
DECLARE
inst_id TEXT;
status TEXT;
attempts INT := 0;
BEGIN
SELECT instance_id INTO inst_id FROM _cycle1_state;
LOOP
SELECT s INTO status FROM df.status(inst_id) s;
EXIT WHEN lower(status) IN ('completed', 'failed', 'canceled') OR attempts > 300;
PERFORM pg_sleep(0.1);
attempts := attempts + 1;
END LOOP;
IF lower(status) != 'completed' THEN
RAISE EXCEPTION 'TEST FAILED (cycle 1): Worker not operational, status = %', status;
END IF;
RAISE NOTICE 'PASS: Worker operational after cycle 1';
END $$;
DROP TABLE _cycle1_state;
-- Phase 3: Second extension drop-create cycle
DROP EXTENSION IF EXISTS pg_durable CASCADE;
CREATE EXTENSION pg_durable;
-- Wait for worker to initialize duroxide-pg tables
DO $$
DECLARE
table_count INT;
attempts INT := 0;
BEGIN
RAISE NOTICE 'Drop-create cycle 2';
LOOP
SELECT COUNT(*) INTO table_count
FROM pg_tables
WHERE schemaname = 'duroxide'
AND tablename IN ('executions', 'instances', 'history', 'orchestrator_queue', 'worker_queue');
EXIT WHEN table_count = 5 OR attempts > 150;
PERFORM pg_sleep(0.1);
attempts := attempts + 1;
END LOOP;
IF table_count != 5 THEN
RAISE EXCEPTION 'TEST FAILED (cycle 2): Worker did not initialize duroxide-pg, found % of 5 expected tables', table_count;
END IF;
RAISE NOTICE 'PASS: Worker initialized duroxide-pg after cycle 2';
END $$;
-- Give the worker additional time to fully complete initialization
SELECT pg_sleep(1);
-- Verify operational again
CREATE TEMP TABLE _cycle2_state (instance_id TEXT);
INSERT INTO _cycle2_state
SELECT df.start('SELECT 2 as cycle2_test', 'test-worker-restart-cycle2');
DO $$
DECLARE
inst_id TEXT;
status TEXT;
attempts INT := 0;
BEGIN
SELECT instance_id INTO inst_id FROM _cycle2_state;
LOOP
SELECT s INTO status FROM df.status(inst_id) s;
EXIT WHEN lower(status) IN ('completed', 'failed', 'canceled') OR attempts > 300;
PERFORM pg_sleep(0.1);
attempts := attempts + 1;
END LOOP;
IF lower(status) != 'completed' THEN
RAISE EXCEPTION 'TEST FAILED (cycle 2): Worker not operational, status = %', status;
END IF;
RAISE NOTICE 'PASS: Worker operational after cycle 2';
END $$;
DROP TABLE _cycle2_state;
-- Phase 4: Third extension drop-create cycle (to really prove it can handle multiple cycles)
DROP EXTENSION IF EXISTS pg_durable CASCADE;
CREATE EXTENSION pg_durable;
-- Wait for worker to initialize duroxide-pg tables
DO $$
DECLARE
table_count INT;
attempts INT := 0;
BEGIN
RAISE NOTICE 'Drop-create cycle 3';
LOOP
SELECT COUNT(*) INTO table_count
FROM pg_tables
WHERE schemaname = 'duroxide'
AND tablename IN ('executions', 'instances', 'history', 'orchestrator_queue', 'worker_queue');
EXIT WHEN table_count = 5 OR attempts > 150;
PERFORM pg_sleep(0.1);
attempts := attempts + 1;
END LOOP;
IF table_count != 5 THEN
RAISE EXCEPTION 'TEST FAILED (cycle 3): Worker did not initialize duroxide-pg, found % of 5 expected tables', table_count;
END IF;
RAISE NOTICE 'PASS: Worker initialized duroxide-pg after cycle 3';
END $$;
-- Give the worker additional time to fully complete initialization
SELECT pg_sleep(1);
-- Verify operational one more time
CREATE TEMP TABLE _cycle3_state (instance_id TEXT);
INSERT INTO _cycle3_state
SELECT df.start('SELECT 3 as cycle3_test', 'test-worker-restart-cycle3');
DO $$
DECLARE
inst_id TEXT;
status TEXT;
attempts INT := 0;
BEGIN
SELECT instance_id INTO inst_id FROM _cycle3_state;
LOOP
SELECT s INTO status FROM df.status(inst_id) s;
EXIT WHEN lower(status) IN ('completed', 'failed', 'canceled') OR attempts > 300;
PERFORM pg_sleep(0.1);
attempts := attempts + 1;
END LOOP;
IF lower(status) != 'completed' THEN
RAISE EXCEPTION 'TEST FAILED (cycle 3): Worker not operational, status = %', status;
END IF;
RAISE NOTICE 'PASS: Worker operational after cycle 3';
END $$;
DROP TABLE _cycle3_state;
SELECT 'TEST PASSED: Worker restart after multiple drop-create cycles verified' AS result;