Changeset 34 for trunk/epic

Show
Ignore:
Timestamp:
06/08/09 21:47:59 (3 years ago)
Author:
fumanchu
Message:

Fixed to work on PG 8.1.

Location:
trunk/epic
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/epic/epic.sql

    r33 r34  
    177177*/ 
    178178 
    179 CREATE OR REPLACE FUNCTION assert_test_schema() RETURNS boolean AS $$ 
     179CREATE OR REPLACE FUNCTION _epic_init() RETURNS boolean AS $$ 
     180DECLARE 
     181  t        text; 
    180182BEGIN 
    181183  SET client_min_messages = warning; 
     184   
     185  BEGIN 
     186    RAISE EXCEPTION 'ignore me'; 
     187  EXCEPTION WHEN OTHERS THEN 
     188    BEGIN 
     189      t := SQLSTATE; 
     190      t := SQLERRM; 
     191    EXCEPTION WHEN undefined_column THEN 
     192      -- PG 8.0 did not have SQLSTATE, SQLERRM available. Epic relies 
     193      -- on the ability to distinguish one error from another. 
     194      RAISE EXCEPTION 'Epic requires at least PostgreSQL version 8.1'; 
     195    END; 
     196  END; 
    182197   
    183198  BEGIN 
     
    189204  BEGIN 
    190205    CREATE TABLE test.results (name text PRIMARY KEY, module text, 
    191                                result text, errcode text, errmsg text); 
     206                               result text, errcode text, errmsg text, 
     207                               runtime timestamp with time zone default now()); 
    192208  EXCEPTION WHEN duplicate_table THEN 
    193209    NULL; 
     
    198214$$ LANGUAGE plpgsql; 
    199215 
    200 SELECT * FROM assert_test_schema(); 
    201 DROP FUNCTION assert_test_schema(); 
     216SELECT * FROM _epic_init(); 
     217DROP FUNCTION _epic_init(); 
    202218 
    203219 
     
    208224  ON pg_proc.pronamespace::oid = pg_namespace.oid::oid 
    209225  WHERE pg_namespace.nspname = 'test' 
    210     AND pg_proc.proname LIKE E'test\_%'; 
     226    AND pg_proc.proname LIKE 'test_%'; 
    211227 
    212228 
     
    219235  IF result ~* '^[[:space:]]*(SELECT|EXECUTE)[[:space:]]' THEN 
    220236    return result; 
    221   ELSIF result ~* E'^[[:space:]]*(VALUES)[[:space:]]*\\(' THEN 
     237  ELSIF result ~* '^[[:space:]]*(VALUES)[[:space:]]*\\(' THEN 
    222238    return result; 
    223239  ELSE 
     
    348364  rec      record; 
    349365  seen     int := 0; 
     366  msg      text; 
    350367BEGIN 
    351368  FOR rec IN 
     
    360377   
    361378  IF seen = 0 THEN 
    362     RAISE EXCEPTION '% has no attributes.', quote_literal(tablename); 
     379    msg := quote_literal(tablename); 
     380    RAISE EXCEPTION '% has no attributes.', msg; 
    363381  END IF; 
    364382END; 
     
    391409  output_record   test.results%ROWTYPE; 
    392410  splitpoint      int; 
    393   old_search_path text; 
    394411BEGIN 
    395412  SELECT module INTO modulename FROM test.testnames WHERE name = testname; 
     
    399416    -- Allow test.* functions to be referenced without a schema name during this transaction. 
    400417    PERFORM set_config('search_path', 'test, ' || current_setting('search_path'), true); 
    401     EXECUTE 'SELECT * FROM test.' || testname || '();'; 
     418    EXECUTE 'SELECT * FROM test.' || testname || '();' INTO output_record; 
     419    RETURN output_record; 
    402420  EXCEPTION WHEN OTHERS THEN 
    403421    IF SQLSTATE = 'P0001' AND SQLERRM LIKE '[%]%' THEN 
     
    406424        VALUES (testname, modulename, substr(SQLERRM, 1, splitpoint), 
    407425                CASE WHEN SQLERRM LIKE '[FAIL]%' THEN SQLSTATE ELSE '' END, 
    408                 btrim(substr(SQLERRM, splitpoint + 1))) 
    409         RETURNING * INTO output_record; 
     426                btrim(substr(SQLERRM, splitpoint + 1))); 
     427      SELECT INTO output_record * FROM test.results WHERE name = testname; 
    410428      RETURN output_record; 
    411429    ELSE 
    412430      INSERT INTO test.results (name, module, result, errcode, errmsg) 
    413         VALUES (testname, modulename, '[FAIL]', SQLSTATE, SQLERRM) 
    414         RETURNING * INTO output_record; 
     431        VALUES (testname, modulename, '[FAIL]', SQLSTATE, SQLERRM); 
     432      SELECT INTO output_record * FROM test.results WHERE name = testname; 
    415433      RETURN output_record; 
    416434    END IF; 
     
    425443-- Runs all tests in the given module, stores in test.results, and returns results. 
    426444DECLARE 
    427   testname        pg_proc.proname%TYPE; 
     445  testname        record; 
    428446  output_record   test.results%ROWTYPE; 
    429447BEGIN 
     
    440458-- Runs all known test functions, stores in test.results, and returns results. 
    441459DECLARE 
    442   testname pg_proc.proname%TYPE; 
    443   modulename text; 
     460  testname record; 
     461  modulename record; 
    444462  output_record test.results%ROWTYPE; 
    445463BEGIN 
    446464  FOR modulename in SELECT DISTINCT module FROM test.testnames ORDER BY module ASC 
    447465  LOOP 
    448     FOR testname IN SELECT name FROM test.testnames WHERE module = modulename ORDER BY name ASC 
     466    FOR testname IN SELECT name FROM test.testnames WHERE module = modulename.module ORDER BY name ASC 
    449467    LOOP 
    450       SELECT INTO output_record * FROM test.run_test(testname); 
     468      SELECT INTO output_record * FROM test.run_test(testname.name); 
    451469      RETURN NEXT output_record; 
    452470    END LOOP; 
    453471  END LOOP; 
     472  RETURN; 
    454473END; 
    455474$$ LANGUAGE plpgsql; 
     
    541560    RAISE EXCEPTION 'Call: ''%'' did not return void. Got ''%'' instead.', call, retval; 
    542561  END IF; 
     562  RETURN; 
    543563END; 
    544564$$ LANGUAGE plpgsql; 
     
    557577    RAISE EXCEPTION '%', msg; 
    558578  END IF; 
     579  RETURN; 
    559580END; 
    560581$$ LANGUAGE plpgsql IMMUTABLE; 
     
    572593    RAISE EXCEPTION '% != %', elem_1, elem_2; 
    573594  END IF; 
     595  RETURN; 
    574596END; 
    575597$$ LANGUAGE plpgsql IMMUTABLE; 
     
    585607    RAISE EXCEPTION '% = %', elem_1, elem_2; 
    586608  END IF; 
     609  RETURN; 
    587610END; 
    588611$$ LANGUAGE plpgsql IMMUTABLE; 
     
    601624    RAISE EXCEPTION '% not < %', elem_1, elem_2; 
    602625  END IF; 
     626  RETURN; 
    603627END; 
    604628$$ LANGUAGE plpgsql IMMUTABLE; 
     
    617641    RAISE EXCEPTION '% not <= %', elem_1, elem_2; 
    618642  END IF; 
     643  RETURN; 
    619644END; 
    620645$$ LANGUAGE plpgsql IMMUTABLE; 
     
    633658    RAISE EXCEPTION '% not > %', elem_1, elem_2; 
    634659  END IF; 
     660  RETURN; 
    635661END; 
    636662$$ LANGUAGE plpgsql IMMUTABLE; 
     
    649675    RAISE EXCEPTION '% not >= %', elem_1, elem_2; 
    650676  END IF; 
     677  RETURN; 
    651678END; 
    652679$$ LANGUAGE plpgsql IMMUTABLE; 
     
    667694-- errm = '' and state = ''. The resultant error will tell you the 
    668695-- SQLSTATE and SQLERRM that were raised. 
     696DECLARE 
     697  msg       text; 
    669698BEGIN 
    670699  BEGIN 
     
    674703      IF ((state IS NOT NULL AND SQLSTATE != state) OR 
    675704          (errm IS NOT NULL AND SQLERRM != errm)) THEN 
    676         RAISE EXCEPTION 'Call: ''%'' raised ''(%) %'' instead of ''(%) %''.', call, SQLSTATE, SQLERRM, state, errm; 
     705        msg = 'Call: ''' || call || ''' raised ''(' || SQLSTATE || ') ' || SQLERRM || ''' instead of ''(' || state || ') ' || errm || '''.'; 
     706        RAISE EXCEPTION '%', msg; 
    677707      END IF; 
    678708      RETURN; 
    679709  END; 
    680   RAISE EXCEPTION 'Call: % did not raise an error.', quote_literal(call); 
     710  msg := 'Call: ' || quote_literal(call) || ' did not raise an error.'; 
     711  RAISE EXCEPTION '%', msg; 
    681712END; 
    682713$$ LANGUAGE plpgsql; 
     
    713744  s       text; 
    714745  e       text; 
     746  msg     text; 
    715747BEGIN 
    716748  s := test.statement(call_1); 
     
    726758    RAISE EXCEPTION 'Record: % from: % not found in: %', rec, call_2, call_1; 
    727759  END LOOP; 
     760  RETURN; 
    728761END; 
    729762$$ LANGUAGE plpgsql; 
     
    753786  found_1       boolean; 
    754787  lower_bound   int; 
    755   base_type      text; 
     788  base_type     text; 
     789  msg           text; 
    756790BEGIN 
    757791  -- Dump the call output into a temp table 
     
    826860    DROP TABLE _test_assert_column_base; 
    827861    EXECUTE 'DROP TABLE _test_assert_column_expected'; 
    828     RAISE EXCEPTION '%', SQLERRM; 
    829   END TRY; 
     862    msg := SQLERRM; 
     863    RAISE EXCEPTION '%', msg; 
     864  END; 
    830865   
    831866  CLOSE curs_base; 
     
    833868  DROP TABLE _test_assert_column_base; 
    834869  EXECUTE 'DROP TABLE _test_assert_column_expected'; 
     870  RETURN; 
    835871END; 
    836872$$ LANGUAGE plpgsql; 
     
    856892    'SELECT ' || columns || ' FROM ' || call_2 
    857893    ); 
     894  RETURN; 
    858895END; 
    859896$$ LANGUAGE plpgsql; 
     
    864901DECLARE 
    865902  result      bool; 
    866   failed      text[]; 
     903  failed      text[] DEFAULT '{}'::text[]; 
    867904  failed_len  int; 
    868905BEGIN 
     
    885922    END IF; 
    886923  END IF; 
     924  RETURN; 
    887925END; 
    888926$$ LANGUAGE plpgsql; 
     
    897935    PERFORM test.fail('The call "' || call || '" is not empty.'); 
    898936  END IF; 
     937  RETURN; 
    899938END; 
    900939$$ LANGUAGE plpgsql; 
     
    929968    END IF; 
    930969  END IF; 
     970  RETURN; 
    931971END; 
    932972$$ LANGUAGE plpgsql; 
     
    941981    PERFORM test.fail('The call "' || call || '" is empty.'); 
    942982  END IF; 
     983  RETURN; 
    943984END; 
    944985$$ LANGUAGE plpgsql; 
     
    957998  IF number IS NULL THEN v_number := 1000000; END IF; 
    958999  -- Mustn't use now() here since that value is fixed for the entire transaction. 
    959   start := clock_timestamp(); 
     1000  -- Also, clock_timestamp isn't available until 8.2 so we use timeofday instead. 
     1001  start := timeofday()::timestamp; 
    9601002  FOR i IN 1..v_number 
    9611003  LOOP 
     
    9651007  -- overhead outweighs assignment overhead if we accumulated the time inside the loop; 
    9661008  -- therefore I chose "outside" since it makes the whole run faster. ;) 
    967   RETURN (clock_timestamp() - start); 
     1009  RETURN (timeofday()::timestamp - start); 
    9681010END; 
    9691011$$ LANGUAGE plpgsql; 
  • trunk/epic/test/test_asserts.sql

    r32 r34  
    9090 
    9191 
     92CREATE OR REPLACE FUNCTION test._return_void() RETURNS VOID AS $$ 
     93BEGIN 
     94  RETURN; 
     95END; 
     96$$ LANGUAGE plpgsql; 
     97 
    9298CREATE OR REPLACE FUNCTION test.test_assert_void() RETURNS VOID AS $$ 
    9399-- Assert the correct operation of test.assert_void 
     
    97103BEGIN 
    98104  -- assert_void() MUST return VOID if the given call returns VOID. 
    99   SELECT INTO retval * FROM test.assert_void('pg_sleep(0.1)'); 
     105  SELECT INTO retval * FROM test.assert_void('test._return_void()'); 
    100106  IF retval != '' THEN 
    101107    RAISE EXCEPTION 'assert_void did not itself return void. Got ''%'' instead.', retval; 
  • trunk/epic/test/test_timing.sql

    r25 r34  
    11-- Tests for the timing functions which Epic provides. 
    22-- To run, execute epic.sql, then this script, then test.run_module('test_timing'). 
     3 
     4CREATE OR REPLACE FUNCTION test._sleep(s double precision) RETURNS VOID AS $$ 
     5-- sleep function for Postgres 8.1 
     6DECLARE 
     7  start    timestamp with time zone; 
     8BEGIN 
     9  start := timeofday()::timestamp; 
     10  LOOP 
     11    EXIT WHEN (timeofday()::timestamp - start) > (s || ' second')::interval; 
     12  END LOOP; 
     13END; 
     14$$ LANGUAGE plpgsql; 
    315 
    416CREATE OR REPLACE FUNCTION test.test_timing() RETURNS VOID AS $$ 
     
    820BEGIN 
    921  -- Shame we have to use 0.01 but some platforms don't have finer resolution. 
    10   t := test.timing('SELECT pg_sleep(0.01)', 100); 
     22  t := test.timing('SELECT test._sleep(0.01)', 100); 
    1123   
    1224  -- Let's assume that sleep(0.01) * 100 should never run *under* 1s