/* * Tests for the sys.process_updates() function */ BEGIN; -- Delete all registered update types and targets DELETE FROM sys.update_types; DELETE FROM sys.update_targets; -- Create a new update target / type which will be used in tests CREATE SCHEMA test CREATE TABLE test( test_id INT NOT NULL PRIMARY KEY ); INSERT INTO sys.update_targets VALUES ( 1 , 'Test' , 'test' , 'test' ); INSERT INTO sys.update_types VALUES ( 1 , 1 , 'Test 1' , 2 , '' , NULL , NULL ); INSERT INTO sys.update_types VALUES ( 2 , 1 , 'Test 2' , 4 , '' , NULL , NULL ); -- Replace sys.end_tick() with a function that inserts into some table CREATE TABLE end_tick_calls( tick_id BIGINT NOT NULL ); CREATE OR REPLACE FUNCTION sys.end_tick( tick_id BIGINT ) RETURNS VOID LANGUAGE SQL AS 'INSERT INTO end_tick_calls VALUES( $1 );'; -- Create a sys.process_dummy_update() function that inserts into some other table CREATE TABLE process_update_calls( tick_id BIGINT NOT NULL ); CREATE OR REPLACE FUNCTION sys.process_dummy_update( tick_id BIGINT ) RETURNS VOID LANGUAGE SQL AS 'INSERT INTO process_update_calls VALUES( $1 );'; -- Set the general batch size to 1 SELECT sys.uoc_constant( 'game.batchSize' , '(test)' , 'Game updates' , 1 ); -- Insert a few entries in the test table INSERT INTO test.test SELECT * FROM generate_series( 1 , 10 ); -- ***** TESTS BEGIN HERE ***** SELECT plan( 21 ); /* * Case: * Updates have not been processed yet, * * Expected results: * 1) New updates of the first type have been marked for processing, * 2) The quantity of updates marked for processing corresponds to game.batchSize */ UPDATE sys.updates SET update_state = 'FUTURE' , update_last = 1; SELECT diag_test_name( 'sys.process_updates() - General batch size - Return value' ); SELECT ok( sys.process_updates( 1 ) = ROW( TRUE , 'Test 1'::TEXT ) ); SELECT diag_test_name( 'sys.process_updates() - General batch size - Update type' ); SELECT set_eq( $$ SELECT DISTINCT updtype_id FROM sys.updates WHERE update_state = 'PROCESSING'; $$ , $$ VALUES ( 1 ) $$ ); SELECT diag_test_name( 'sys.process_updates() - General batch size - Update count' ); SELECT is( COUNT(*)::INT , 1 ) FROM sys.updates WHERE update_state = 'PROCESSING'; SELECT diag_test_name( 'sys.process_updates() - General batch size - sys.end_tick() not called' ); SELECT is_empty( $$ SELECT * FROM end_tick_calls $$ ); DELETE FROM end_tick_calls; /* * Case: * Updates have not been processed yet, * Update type has a specific batch size, * * Expected results: * 1) New updates have been marked for processing, * 2) The quantity of updates marked for processing corresponds to the specific batch size * 3) sys.end_tick() has not been called */ UPDATE sys.update_types SET updtype_batch_size = 2 WHERE updtype_id = 1; UPDATE sys.updates SET update_state = 'FUTURE' , update_last = 1; SELECT diag_test_name( 'sys.process_updates() - Specific batch size - Return value' ); SELECT ok( sys.process_updates( 1 ) = ROW( TRUE , 'Test 1'::TEXT ) ); SELECT diag_test_name( 'sys.process_updates() - Specific batch size - Update type' ); SELECT set_eq( $$ SELECT DISTINCT updtype_id FROM sys.updates WHERE update_state = 'PROCESSING'; $$ , $$ VALUES ( 1 ) $$ ); SELECT diag_test_name( 'sys.process_updates() - Specific batch size - Update count' ); SELECT is( COUNT(*)::INT , 2 ) FROM sys.updates WHERE update_state = 'PROCESSING'; SELECT diag_test_name( 'sys.process_updates() - Specific batch size - sys.end_tick() not called' ); SELECT is_empty( $$ SELECT * FROM end_tick_calls $$ ); DELETE FROM end_tick_calls; /* * Case: * Some but not all updates of the first type have been processed, * Batch size is greater than the quantity of updates left to process for the type. * * Expected results: * 1) All updates of the first type are marked either for processing or as processed. * 2) sys.end_tick() has not been called */ UPDATE sys.update_types SET updtype_batch_size = 2 WHERE updtype_id = 1; UPDATE sys.updates SET update_state = 'FUTURE' , update_last = 1; UPDATE sys.updates SET update_state = 'PROCESSED' WHERE update_id IN ( SELECT update_id FROM sys.updates WHERE updtype_id = 1 LIMIT 9 ); UPDATE sys.update_types SET updtype_batch_size = 2 WHERE updtype_id = 1; SELECT diag_test_name( 'sys.process_updates() - End of type updates - Return value' ); SELECT ok( sys.process_updates( 1 ) = ROW( TRUE , 'Test 1'::TEXT ) ); SELECT diag_test_name( 'sys.process_updates() - End of type updates - Update type' ); SELECT set_eq( $$ SELECT DISTINCT updtype_id FROM sys.updates WHERE update_state <> 'FUTURE'; $$ , $$ VALUES ( 1 ) $$ ); SELECT diag_test_name( 'sys.process_updates() - End of type updates - Update count' ); SELECT is( COUNT(*)::INT , 10 ) FROM sys.updates WHERE update_state <> 'FUTURE'; SELECT diag_test_name( 'sys.process_updates() - End of type updates - sys.end_tick() not called' ); SELECT is_empty( $$ SELECT * FROM end_tick_calls $$ ); DELETE FROM end_tick_calls; /* * Case: * All updates of the first type have been processed. * No updates of the second type have been processed. * * Expected results: * 1) Some updates from the second type have been marked for processing. * 2) sys.end_tick() has not been called */ UPDATE sys.updates SET update_state = 'FUTURE' , update_last = 1; UPDATE sys.updates SET update_state = 'PROCESSED' WHERE updtype_id = 1; SELECT diag_test_name( 'sys.process_updates() - Update type transition - Return value' ); SELECT ok( sys.process_updates( 1 ) = ROW( TRUE , 'Test 2'::TEXT ) ); SELECT diag_test_name( 'sys.process_updates() - Update type transition - Update type' ); SELECT set_eq( $$ SELECT DISTINCT updtype_id FROM sys.updates WHERE update_state = 'PROCESSING'; $$ , $$ VALUES ( 2 ) $$ ); SELECT diag_test_name( 'sys.process_updates() - Update type transition - Update count' ); SELECT is( COUNT(*)::INT , 1 ) FROM sys.updates WHERE update_state = 'PROCESSING'; SELECT diag_test_name( 'sys.process_updates() - Update type transition - sys.end_tick() not called' ); SELECT is_empty( $$ SELECT * FROM end_tick_calls $$ ); DELETE FROM end_tick_calls; /* * Case: * There no updates to process * Updates are marked as 'PROCESSING' * * Expected results: * 1) _has_more return value is FALSE, * 2) All updates are marked as 'PROCESSED' * 3) sys.end_tick() has been called. */ UPDATE sys.updates SET update_state = 'PROCESSING' , update_last = 1; SELECT diag_test_name( 'sys.process_updates() - No updates left - Return value' ); SELECT ok( sys.process_updates( 1 ) = ROW( FALSE , NULL::TEXT ) ); SELECT diag_test_name( 'sys.process_updates() - No updates left - All updates processed' ); SELECT is_empty( $$ SELECT * FROM sys.updates WHERE update_state <> 'PROCESSED' $$ ); SELECT diag_test_name( 'sys.process_updates() - No updates left - sys.end_tick() called' ); SELECT set_eq( $$ SELECT * FROM end_tick_calls $$ , $$ VALUES ( 1 ) $$ ); DELETE FROM end_tick_calls; /* * Case: * The update type has an in-base processing function * * Expected result: * 1) _process_externally return value is NULL * 2) The processing function has been called. */ UPDATE sys.updates SET update_state = 'FUTURE' , update_last = 1; UPDATE sys.update_types SET updtype_batch_size = NULL , updtype_proc_name = 'process_dummy_update' WHERE updtype_id = 1; SELECT diag_test_name( 'sys.process_updates() - In-base processing - Return value' ); SELECT ok( sys.process_updates( 1 ) = ROW( TRUE , NULL::TEXT ) ); SELECT diag_test_name( 'sys.process_updates() - In-base processing - Processing function called' ); SELECT set_eq( $$ SELECT * FROM process_update_calls $$ , $$ VALUES ( 1 ) $$ ); SELECT * FROM finish( ); ROLLBACK;