-- Copyright (c) Microsoft Corporation. -- Licensed under the PostgreSQL License. -- Merged from: 01_simple_sql, 02_sequence, 04_parallel_join, 07_sleep, 16_scenario_join3, 17_race -- Tests: simple SQL execution, sequential steps, parallel join, sleep/timer, -- three-way parallel join, race/first-wins execution SET SESSION AUTHORIZATION df_e2e_user; -- === Test: 01_simple_sql === CREATE TEMP TABLE _test_state (instance_id TEXT, variant TEXT); -- Variant A: Auto-wrapped SQL (plain string) INSERT INTO _test_state SELECT df.start('SELECT 42 as answer', 'test-simple-auto'), 'auto'; -- Variant B: Explicit df.sql() function INSERT INTO _test_state SELECT df.start(df.sql('SELECT 42 as answer'), 'test-simple-func'), 'func'; DO $$ DECLARE rec RECORD; status TEXT; result TEXT; BEGIN FOR rec IN SELECT instance_id, variant FROM _test_state LOOP RAISE NOTICE 'Testing % variant: %', rec.variant, rec.instance_id; SELECT df.await_instance(rec.instance_id) INTO status; IF status != 'completed' THEN RAISE EXCEPTION 'TEST FAILED [%]: expected completed, got %', rec.variant, status; END IF; SELECT r INTO result FROM df.result(rec.instance_id) r; IF result NOT LIKE '%42%' THEN RAISE EXCEPTION 'TEST FAILED [%]: result should contain 42, got %', rec.variant, result; END IF; RAISE NOTICE 'PASSED: simple_sql [%]', rec.variant; END LOOP; RAISE NOTICE 'TEST PASSED: simple_sql (both variants)'; END $$; DROP TABLE _test_state; -- === Test: 02_sequence === DROP TABLE IF EXISTS test_sequence_log; CREATE TABLE test_sequence_log (id SERIAL, step INT, variant TEXT, ts TIMESTAMP DEFAULT now()); CREATE TEMP TABLE _test_state (instance_id TEXT, variant TEXT); -- Variant A: Using ~> operator INSERT INTO _test_state SELECT df.start( 'INSERT INTO test_sequence_log (step, variant) VALUES (1, ''op'')' ~> 'INSERT INTO test_sequence_log (step, variant) VALUES (2, ''op'')' ~> 'INSERT INTO test_sequence_log (step, variant) VALUES (3, ''op'')', 'test-sequence-op' ), 'operator'; -- Variant B: Using df.seq() function INSERT INTO _test_state SELECT df.start( df.seq( df.seq( 'INSERT INTO test_sequence_log (step, variant) VALUES (1, ''fn'')', 'INSERT INTO test_sequence_log (step, variant) VALUES (2, ''fn'')' ), 'INSERT INTO test_sequence_log (step, variant) VALUES (3, ''fn'')' ), 'test-sequence-fn' ), 'function'; DO $$ DECLARE rec RECORD; status TEXT; steps INT[]; BEGIN FOR rec IN SELECT instance_id, variant FROM _test_state LOOP RAISE NOTICE 'Testing % variant: %', rec.variant, rec.instance_id; SELECT df.await_instance(rec.instance_id) INTO status; IF status != 'completed' THEN RAISE EXCEPTION 'TEST FAILED [%]: status = %', rec.variant, status; END IF; IF rec.variant = 'operator' THEN SELECT array_agg(step ORDER BY id) INTO steps FROM test_sequence_log WHERE variant = 'op'; ELSE SELECT array_agg(step ORDER BY id) INTO steps FROM test_sequence_log WHERE variant = 'fn'; END IF; IF steps != ARRAY[1,2,3] THEN RAISE EXCEPTION 'TEST FAILED [%]: expected [1,2,3], got %', rec.variant, steps; END IF; RAISE NOTICE 'PASSED: sequence [%]', rec.variant; END LOOP; RAISE NOTICE 'TEST PASSED: sequence (both variants)'; END $$; DROP TABLE _test_state; DROP TABLE test_sequence_log; -- === Test: 04_parallel_join === DROP TABLE IF EXISTS test_parallel_log; CREATE TABLE test_parallel_log (id SERIAL, branch TEXT, variant TEXT); CREATE TEMP TABLE _test_state (instance_id TEXT, variant TEXT); -- Test A: df.join() function INSERT INTO _test_state SELECT df.start( df.join( 'INSERT INTO test_parallel_log (branch, variant) VALUES (''A'', ''func'')', 'INSERT INTO test_parallel_log (branch, variant) VALUES (''B'', ''func'')' ), 'test-parallel-func' ), 'func'; -- Test B: & operator INSERT INTO _test_state SELECT df.start( 'INSERT INTO test_parallel_log (branch, variant) VALUES (''A'', ''op'')' & 'INSERT INTO test_parallel_log (branch, variant) VALUES (''B'', ''op'')', 'test-parallel-op' ), 'op'; DO $$ DECLARE rec RECORD; status TEXT; cnt INT; BEGIN FOR rec IN SELECT instance_id, variant FROM _test_state LOOP SELECT df.await_instance(rec.instance_id) INTO status; IF status != 'completed' THEN RAISE EXCEPTION 'TEST FAILED [%]: status = %', rec.variant, status; END IF; SELECT COUNT(DISTINCT branch) INTO cnt FROM test_parallel_log WHERE variant = rec.variant; IF cnt != 2 THEN RAISE EXCEPTION 'TEST FAILED [%]: expected 2 branches, got %', rec.variant, cnt; END IF; END LOOP; RAISE NOTICE 'PASSED: parallel_join [func + & operator]'; END $$; DROP TABLE _test_state; DROP TABLE test_parallel_log; -- === Test: 07_sleep === DROP TABLE IF EXISTS test_sleep_log; CREATE TABLE test_sleep_log (id SERIAL, ts TIMESTAMP DEFAULT now()); INSERT INTO test_sleep_log DEFAULT VALUES; CREATE TEMP TABLE _test_state (instance_id TEXT); INSERT INTO _test_state SELECT df.start( df.sleep(2) ~> 'INSERT INTO test_sleep_log DEFAULT VALUES', 'test-sleep' ); DO $$ DECLARE inst_id TEXT; status TEXT; cnt INT; time_diff INTERVAL; BEGIN SELECT instance_id INTO inst_id FROM _test_state; RAISE NOTICE 'Testing instance: %', inst_id; SELECT df.await_instance(inst_id, 50) INTO status; IF status != 'completed' THEN RAISE EXCEPTION 'TEST FAILED: status = %', status; END IF; SELECT COUNT(*) INTO cnt FROM test_sleep_log; IF cnt != 2 THEN RAISE EXCEPTION 'TEST FAILED: expected 2 log entries, got %', cnt; END IF; SELECT MAX(ts) - MIN(ts) INTO time_diff FROM test_sleep_log; IF time_diff < interval '1.5 seconds' THEN RAISE EXCEPTION 'TEST FAILED: sleep should be at least 2s, got %', time_diff; END IF; RAISE NOTICE 'TEST PASSED: sleep'; END $$; DROP TABLE _test_state; DROP TABLE test_sleep_log; -- === Test: 16_scenario_join3 === DROP TABLE IF EXISTS test_join3_log; CREATE TABLE test_join3_log (id SERIAL, branch TEXT, ts TIMESTAMP DEFAULT now()); CREATE TEMP TABLE _test_state (instance_id TEXT); INSERT INTO _test_state SELECT df.start( df.join3( 'INSERT INTO test_join3_log (branch) VALUES (''A'')', 'INSERT INTO test_join3_log (branch) VALUES (''B'')', 'INSERT INTO test_join3_log (branch) VALUES (''C'')' ), 'scenario-join3' ); DO $$ DECLARE inst_id TEXT; inst_status TEXT; branch_count INT; BEGIN SELECT instance_id INTO inst_id FROM _test_state; RAISE NOTICE 'Testing join3: %', inst_id; SELECT df.await_instance(inst_id) INTO inst_status; IF inst_status != 'completed' THEN RAISE EXCEPTION 'TEST FAILED: join3 status = %', inst_status; END IF; SELECT COUNT(DISTINCT branch) INTO branch_count FROM test_join3_log; IF branch_count != 3 THEN RAISE EXCEPTION 'TEST FAILED: expected 3 branches, got %', branch_count; END IF; RAISE NOTICE 'TEST PASSED: scenario_join3'; END $$; DROP TABLE _test_state; DROP TABLE test_join3_log; -- === Test: 17_race === DROP TABLE IF EXISTS test_race_log; CREATE TABLE test_race_log (id SERIAL, branch TEXT, variant TEXT, ts TIMESTAMP DEFAULT now()); CREATE TEMP TABLE _test_state (instance_id TEXT, variant TEXT); -- Test A: df.race() function - fast vs slow INSERT INTO _test_state SELECT df.start( df.race( 'INSERT INTO test_race_log (branch, variant) VALUES (''fast'', ''func'') RETURNING ''fast''', df.sleep(10) ~> 'INSERT INTO test_race_log (branch, variant) VALUES (''slow'', ''func'') RETURNING ''slow''' ), 'test-race-func' ), 'func'; -- Test B: | operator - fast vs slow INSERT INTO _test_state SELECT df.start( 'INSERT INTO test_race_log (branch, variant) VALUES (''fast'', ''op'') RETURNING ''fast''' | (df.sleep(10) ~> 'INSERT INTO test_race_log (branch, variant) VALUES (''slow'', ''op'') RETURNING ''slow'''), 'test-race-op' ), 'op'; DO $$ DECLARE rec RECORD; status TEXT; cnt INT; BEGIN FOR rec IN SELECT instance_id, variant FROM _test_state LOOP SELECT df.await_instance(rec.instance_id) INTO status; IF status != 'completed' THEN RAISE EXCEPTION 'TEST FAILED [%]: status = %', rec.variant, status; END IF; SELECT COUNT(*) INTO cnt FROM test_race_log WHERE variant = rec.variant AND branch = 'fast'; IF cnt < 1 THEN RAISE EXCEPTION 'TEST FAILED [%]: fast branch should have completed', rec.variant; END IF; END LOOP; RAISE NOTICE 'PASSED: race [func + | operator]'; END $$; DROP TABLE _test_state; DROP TABLE test_race_log; RESET SESSION AUTHORIZATION; SELECT 'TEST PASSED' AS result;