155 lines
5.4 KiB
PL/PgSQL
155 lines
5.4 KiB
PL/PgSQL
-- Migration: Add Pack Test Results Tracking
|
|
-- Created: 2026-01-20
|
|
-- Description: Add tables and views for tracking pack test execution results
|
|
|
|
-- Pack test execution tracking table
|
|
CREATE TABLE IF NOT EXISTS pack_test_execution (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
pack_id BIGINT NOT NULL REFERENCES pack(id) ON DELETE CASCADE,
|
|
pack_version VARCHAR(50) NOT NULL,
|
|
execution_time TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
trigger_reason VARCHAR(50) NOT NULL, -- 'install', 'update', 'manual', 'validation'
|
|
total_tests INT NOT NULL,
|
|
passed INT NOT NULL,
|
|
failed INT NOT NULL,
|
|
skipped INT NOT NULL,
|
|
pass_rate DECIMAL(5,4) NOT NULL, -- 0.0000 to 1.0000
|
|
duration_ms BIGINT NOT NULL,
|
|
result JSONB NOT NULL, -- Full test result structure
|
|
created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
CONSTRAINT valid_test_counts CHECK (total_tests >= 0 AND passed >= 0 AND failed >= 0 AND skipped >= 0),
|
|
CONSTRAINT valid_pass_rate CHECK (pass_rate >= 0.0 AND pass_rate <= 1.0),
|
|
CONSTRAINT valid_trigger_reason CHECK (trigger_reason IN ('install', 'update', 'manual', 'validation'))
|
|
);
|
|
|
|
-- Indexes for efficient queries
|
|
CREATE INDEX idx_pack_test_execution_pack_id ON pack_test_execution(pack_id);
|
|
CREATE INDEX idx_pack_test_execution_time ON pack_test_execution(execution_time DESC);
|
|
CREATE INDEX idx_pack_test_execution_pass_rate ON pack_test_execution(pass_rate);
|
|
CREATE INDEX idx_pack_test_execution_trigger ON pack_test_execution(trigger_reason);
|
|
|
|
-- Comments for documentation
|
|
COMMENT ON TABLE pack_test_execution IS 'Tracks pack test execution results for validation and auditing';
|
|
COMMENT ON COLUMN pack_test_execution.pack_id IS 'Reference to the pack being tested';
|
|
COMMENT ON COLUMN pack_test_execution.pack_version IS 'Version of the pack at test time';
|
|
COMMENT ON COLUMN pack_test_execution.trigger_reason IS 'What triggered the test: install, update, manual, validation';
|
|
COMMENT ON COLUMN pack_test_execution.pass_rate IS 'Percentage of tests passed (0.0 to 1.0)';
|
|
COMMENT ON COLUMN pack_test_execution.result IS 'Full JSON structure with detailed test results';
|
|
|
|
-- Pack test result summary view (all test executions with pack info)
|
|
CREATE OR REPLACE VIEW pack_test_summary AS
|
|
SELECT
|
|
p.id AS pack_id,
|
|
p.ref AS pack_ref,
|
|
p.label AS pack_label,
|
|
pte.id AS test_execution_id,
|
|
pte.pack_version,
|
|
pte.execution_time AS test_time,
|
|
pte.trigger_reason,
|
|
pte.total_tests,
|
|
pte.passed,
|
|
pte.failed,
|
|
pte.skipped,
|
|
pte.pass_rate,
|
|
pte.duration_ms,
|
|
ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY pte.execution_time DESC) AS rn
|
|
FROM pack p
|
|
LEFT JOIN pack_test_execution pte ON p.id = pte.pack_id
|
|
WHERE pte.id IS NOT NULL;
|
|
|
|
COMMENT ON VIEW pack_test_summary IS 'Summary of all pack test executions with pack details';
|
|
|
|
-- Latest test results per pack view
|
|
CREATE OR REPLACE VIEW pack_latest_test AS
|
|
SELECT
|
|
pack_id,
|
|
pack_ref,
|
|
pack_label,
|
|
test_execution_id,
|
|
pack_version,
|
|
test_time,
|
|
trigger_reason,
|
|
total_tests,
|
|
passed,
|
|
failed,
|
|
skipped,
|
|
pass_rate,
|
|
duration_ms
|
|
FROM pack_test_summary
|
|
WHERE rn = 1;
|
|
|
|
COMMENT ON VIEW pack_latest_test IS 'Latest test results for each pack';
|
|
|
|
-- Function to get pack test statistics
|
|
CREATE OR REPLACE FUNCTION get_pack_test_stats(p_pack_id BIGINT)
|
|
RETURNS TABLE (
|
|
total_executions BIGINT,
|
|
successful_executions BIGINT,
|
|
failed_executions BIGINT,
|
|
avg_pass_rate DECIMAL,
|
|
avg_duration_ms BIGINT,
|
|
last_test_time TIMESTAMPTZ,
|
|
last_test_passed BOOLEAN
|
|
) AS $$
|
|
BEGIN
|
|
RETURN QUERY
|
|
SELECT
|
|
COUNT(*)::BIGINT AS total_executions,
|
|
COUNT(*) FILTER (WHERE passed = total_tests)::BIGINT AS successful_executions,
|
|
COUNT(*) FILTER (WHERE failed > 0)::BIGINT AS failed_executions,
|
|
AVG(pass_rate) AS avg_pass_rate,
|
|
AVG(duration_ms)::BIGINT AS avg_duration_ms,
|
|
MAX(execution_time) AS last_test_time,
|
|
(SELECT failed = 0 FROM pack_test_execution
|
|
WHERE pack_id = p_pack_id
|
|
ORDER BY execution_time DESC
|
|
LIMIT 1) AS last_test_passed
|
|
FROM pack_test_execution
|
|
WHERE pack_id = p_pack_id;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
COMMENT ON FUNCTION get_pack_test_stats IS 'Get statistical summary of test executions for a pack';
|
|
|
|
-- Function to check if pack has recent passing tests
|
|
CREATE OR REPLACE FUNCTION pack_has_passing_tests(
|
|
p_pack_id BIGINT,
|
|
p_hours_ago INT DEFAULT 24
|
|
)
|
|
RETURNS BOOLEAN AS $$
|
|
DECLARE
|
|
v_has_passing_tests BOOLEAN;
|
|
BEGIN
|
|
SELECT EXISTS(
|
|
SELECT 1
|
|
FROM pack_test_execution
|
|
WHERE pack_id = p_pack_id
|
|
AND execution_time > NOW() - (p_hours_ago || ' hours')::INTERVAL
|
|
AND failed = 0
|
|
AND total_tests > 0
|
|
) INTO v_has_passing_tests;
|
|
|
|
RETURN v_has_passing_tests;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
COMMENT ON FUNCTION pack_has_passing_tests IS 'Check if pack has recent passing test executions';
|
|
|
|
-- Add trigger to update pack metadata on test execution
|
|
CREATE OR REPLACE FUNCTION update_pack_test_metadata()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
-- Could update pack table with last_tested timestamp if we add that column
|
|
-- For now, just a placeholder for future functionality
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER trigger_update_pack_test_metadata
|
|
AFTER INSERT ON pack_test_execution
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION update_pack_test_metadata();
|
|
|
|
COMMENT ON TRIGGER trigger_update_pack_test_metadata ON pack_test_execution IS 'Updates pack metadata when tests are executed';
|