-- Copyright (c) Microsoft Corporation. -- Licensed under the PostgreSQL License. -- Regression test for issue #168: -- df.instance_executions() can return no rows for completed instances. -- -- A completed instance always has at least one execution row in the duroxide -- store (the instance and its first execution are created in the same -- transaction). Previously, instance_executions() swallowed any -- runtime/provider/lookup error into an empty rowset, making "no execution -- history yet" indistinguishable from "the lookup failed". -- -- This test guards the contract: -- * a completed instance exposes >= 1 execution row, and -- * an invalid limit_count is rejected with an explicit error rather than -- being silently masked by an empty rowset. SET SESSION AUTHORIZATION df_e2e_user; CREATE TEMP TABLE _test_state (instance_id TEXT); INSERT INTO _test_state SELECT df.start('SELECT 42', 'test-instance-executions-168'); DO $$ DECLARE inst_id TEXT; status TEXT; exec_count INT; top_exec_id BIGINT; top_status TEXT; BEGIN SELECT instance_id INTO inst_id FROM _test_state; RAISE NOTICE 'Testing instance: %', inst_id; SELECT df.await_instance(inst_id) INTO status; IF lower(status) != 'completed' THEN RAISE EXCEPTION 'TEST FAILED: expected completed, got %', status; END IF; -- Core assertion (issue #168): a completed instance must expose >= 1 execution. SELECT count(*) INTO exec_count FROM df.instance_executions(inst_id, 1); IF exec_count < 1 THEN RAISE EXCEPTION 'TEST FAILED: instance_executions(inst_id, 1) returned % rows for a completed instance, expected >= 1', exec_count; END IF; -- The returned execution should have a valid id and a non-empty status. -- We deliberately do NOT assert status = 'completed': df.status() / -- await_instance track the pg_durable df.instances table, while -- instance_executions reports duroxide's per-execution status. The two are -- updated independently and can briefly diverge under concurrent -- background-worker load. Issue #168 is about empty rows, not the exact -- status string, so asserting row presence + a well-formed status is the -- correct, race-free check. SELECT e.execution_id, e.status INTO top_exec_id, top_status FROM df.instance_executions(inst_id, 1) e; IF top_exec_id < 1 THEN RAISE EXCEPTION 'TEST FAILED: execution_id should be >= 1, got %', top_exec_id; END IF; IF top_status IS NULL OR length(trim(top_status)) = 0 THEN RAISE EXCEPTION 'TEST FAILED: execution status should be non-empty, got %', coalesce(top_status, ''); END IF; -- The default limit should also return the execution history. SELECT count(*) INTO exec_count FROM df.instance_executions(inst_id); IF exec_count < 1 THEN RAISE EXCEPTION 'TEST FAILED: instance_executions(inst_id) (default limit) returned % rows, expected >= 1', exec_count; END IF; RAISE NOTICE 'TEST PASSED: instance_executions returns execution history for a completed instance'; END $$; -- limit_count < 1 must raise an explicit error, not silently return empty rows. DO $$ DECLARE inst_id TEXT; got_error BOOLEAN := false; BEGIN SELECT instance_id INTO inst_id FROM _test_state; BEGIN PERFORM * FROM df.instance_executions(inst_id, 0); EXCEPTION WHEN OTHERS THEN got_error := true; END; IF NOT got_error THEN RAISE EXCEPTION 'TEST FAILED: instance_executions(inst_id, 0) should raise an error for limit_count < 1'; END IF; RAISE NOTICE 'TEST PASSED: instance_executions rejects limit_count < 1'; END $$; DROP TABLE _test_state; RESET SESSION AUTHORIZATION; SELECT 'TEST PASSED' AS result;