1*eeb7e5b3SAdam Hornáčekcreate or replace package ut_utils authid definer is 2*eeb7e5b3SAdam Hornáček /* 3*eeb7e5b3SAdam Hornáček utPLSQL - Version 3 4*eeb7e5b3SAdam Hornáček Copyright 2016 - 2017 utPLSQL Project 5*eeb7e5b3SAdam Hornáček 6*eeb7e5b3SAdam Hornáček Licensed under the Apache License, Version 2.0 (the "License"): 7*eeb7e5b3SAdam Hornáček you may not use this file except in compliance with the License. 8*eeb7e5b3SAdam Hornáček You may obtain a copy of the License at 9*eeb7e5b3SAdam Hornáček 10*eeb7e5b3SAdam Hornáček http://www.apache.org/licenses/LICENSE-2.0 11*eeb7e5b3SAdam Hornáček 12*eeb7e5b3SAdam Hornáček Unless required by applicable law or agreed to in writing, software 13*eeb7e5b3SAdam Hornáček distributed under the License is distributed on an "AS IS" BASIS, 14*eeb7e5b3SAdam Hornáček WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15*eeb7e5b3SAdam Hornáček See the License for the specific language governing permissions and 16*eeb7e5b3SAdam Hornáček limitations under the License. 17*eeb7e5b3SAdam Hornáček */ 18*eeb7e5b3SAdam Hornáček 19*eeb7e5b3SAdam Hornáček /** 20*eeb7e5b3SAdam Hornáček * Common utilities and constants used throughout utPLSQL framework 21*eeb7e5b3SAdam Hornáček * 22*eeb7e5b3SAdam Hornáček */ 23*eeb7e5b3SAdam Hornáček 24*eeb7e5b3SAdam Hornáček gc_version constant varchar2(50) := 'v3.0.4.1461-develop'; 25*eeb7e5b3SAdam Hornáček 26*eeb7e5b3SAdam Hornáček /* Constants: Event names */ 27*eeb7e5b3SAdam Hornáček gc_run constant varchar2(12) := 'run'; 28*eeb7e5b3SAdam Hornáček gc_suite constant varchar2(12) := 'suite'; 29*eeb7e5b3SAdam Hornáček gc_before_all constant varchar2(12) := 'before_all'; 30*eeb7e5b3SAdam Hornáček gc_before_each constant varchar2(12) := 'before_each'; 31*eeb7e5b3SAdam Hornáček gc_before_test constant varchar2(12) := 'before_test'; 32*eeb7e5b3SAdam Hornáček gc_test constant varchar2(12) := 'test'; 33*eeb7e5b3SAdam Hornáček gc_test_execute constant varchar2(12) := 'test_execute'; 34*eeb7e5b3SAdam Hornáček gc_after_test constant varchar2(10) := 'after_test'; 35*eeb7e5b3SAdam Hornáček gc_after_each constant varchar2(12) := 'after_each'; 36*eeb7e5b3SAdam Hornáček gc_after_all constant varchar2(12) := 'after_all'; 37*eeb7e5b3SAdam Hornáček 38*eeb7e5b3SAdam Hornáček /* Constants: Test Results */ 39*eeb7e5b3SAdam Hornáček tr_disabled constant number(1) := 0; -- test/suite was disabled 40*eeb7e5b3SAdam Hornáček tr_success constant number(1) := 1; -- test passed 41*eeb7e5b3SAdam Hornáček tr_failure constant number(1) := 2; -- one or more expectations failed 42*eeb7e5b3SAdam Hornáček tr_error constant number(1) := 3; -- exception was raised 43*eeb7e5b3SAdam Hornáček 44*eeb7e5b3SAdam Hornáček tr_disabled_char constant varchar2(8) := 'Disabled'; -- test/suite was disabled 45*eeb7e5b3SAdam Hornáček tr_success_char constant varchar2(7) := 'Success'; -- test passed 46*eeb7e5b3SAdam Hornáček tr_failure_char constant varchar2(7) := 'Failure'; -- one or more expectations failed 47*eeb7e5b3SAdam Hornáček tr_error_char constant varchar2(5) := 'Error'; -- exception was raised 48*eeb7e5b3SAdam Hornáček 49*eeb7e5b3SAdam Hornáček /* 50*eeb7e5b3SAdam Hornáček Constants: Rollback type for ut_test_object 51*eeb7e5b3SAdam Hornáček */ 52*eeb7e5b3SAdam Hornáček gc_rollback_auto constant number(1) := 0; -- rollback after each test and suite 53*eeb7e5b3SAdam Hornáček gc_rollback_manual constant number(1) := 1; -- leave transaction control manual 54*eeb7e5b3SAdam Hornáček --gc_rollback_on_error constant number(1) := 2; -- rollback tests only on error 55*eeb7e5b3SAdam Hornáček 56*eeb7e5b3SAdam Hornáček ex_unsupported_rollback_type exception; 57*eeb7e5b3SAdam Hornáček gc_unsupported_rollback_type constant pls_integer := -20200; 58*eeb7e5b3SAdam Hornáček pragma exception_init(ex_unsupported_rollback_type, -20200); 59*eeb7e5b3SAdam Hornáček 60*eeb7e5b3SAdam Hornáček ex_path_list_is_empty exception; 61*eeb7e5b3SAdam Hornáček gc_path_list_is_empty constant pls_integer := -20201; 62*eeb7e5b3SAdam Hornáček pragma exception_init(ex_path_list_is_empty, -20201); 63*eeb7e5b3SAdam Hornáček 64*eeb7e5b3SAdam Hornáček ex_invalid_path_format exception; 65*eeb7e5b3SAdam Hornáček gc_invalid_path_format constant pls_integer := -20202; 66*eeb7e5b3SAdam Hornáček pragma exception_init(ex_invalid_path_format, -20202); 67*eeb7e5b3SAdam Hornáček 68*eeb7e5b3SAdam Hornáček ex_suite_package_not_found exception; 69*eeb7e5b3SAdam Hornáček gc_suite_package_not_found constant pls_integer := -20204; 70*eeb7e5b3SAdam Hornáček pragma exception_init(ex_suite_package_not_found, -20204); 71*eeb7e5b3SAdam Hornáček 72*eeb7e5b3SAdam Hornáček -- Reporting event time not supported 73*eeb7e5b3SAdam Hornáček ex_invalid_rep_event_time exception; 74*eeb7e5b3SAdam Hornáček gc_invalid_rep_event_time constant pls_integer := -20210; 75*eeb7e5b3SAdam Hornáček pragma exception_init(ex_invalid_rep_event_time, -20210); 76*eeb7e5b3SAdam Hornáček 77*eeb7e5b3SAdam Hornáček -- Reporting event name not supported 78*eeb7e5b3SAdam Hornáček ex_invalid_rep_event_name exception; 79*eeb7e5b3SAdam Hornáček gc_invalid_rep_event_name constant pls_integer := -20211; 80*eeb7e5b3SAdam Hornáček pragma exception_init(ex_invalid_rep_event_name, -20211); 81*eeb7e5b3SAdam Hornáček 82*eeb7e5b3SAdam Hornáček -- Any of tests failed 83*eeb7e5b3SAdam Hornáček ex_some_tests_failed exception; 84*eeb7e5b3SAdam Hornáček gc_some_tests_failed constant pls_integer := -20213; 85*eeb7e5b3SAdam Hornáček pragma exception_init(ex_some_tests_failed, -20213); 86*eeb7e5b3SAdam Hornáček 87*eeb7e5b3SAdam Hornáček -- Any of tests failed 88*eeb7e5b3SAdam Hornáček ex_invalid_version_no exception; 89*eeb7e5b3SAdam Hornáček gc_invalid_version_no constant pls_integer := -20214; 90*eeb7e5b3SAdam Hornáček pragma exception_init(ex_invalid_version_no, -20214); 91*eeb7e5b3SAdam Hornáček 92*eeb7e5b3SAdam Hornáček gc_max_storage_varchar2_len constant integer := 4000; 93*eeb7e5b3SAdam Hornáček gc_max_output_string_length constant integer := 4000; 94*eeb7e5b3SAdam Hornáček gc_max_input_string_length constant integer := gc_max_output_string_length - 2; --we need to remove 2 chars for quotes around string 95*eeb7e5b3SAdam Hornáček gc_more_data_string constant varchar2(5) := '[...]'; 96*eeb7e5b3SAdam Hornáček gc_overflow_substr_len constant integer := gc_max_input_string_length - length(gc_more_data_string); 97*eeb7e5b3SAdam Hornáček gc_number_format constant varchar2(100) := 'TM9'; 98*eeb7e5b3SAdam Hornáček gc_date_format constant varchar2(100) := 'yyyy-mm-dd"T"hh24:mi:ss'; 99*eeb7e5b3SAdam Hornáček gc_timestamp_format constant varchar2(100) := 'yyyy-mm-dd"T"hh24:mi:ssxff'; 100*eeb7e5b3SAdam Hornáček gc_timestamp_tz_format constant varchar2(100) := 'yyyy-mm-dd"T"hh24:mi:ssxff tzh:tzm'; 101*eeb7e5b3SAdam Hornáček gc_null_string constant varchar2(4) := 'NULL'; 102*eeb7e5b3SAdam Hornáček 103*eeb7e5b3SAdam Hornáček type t_version is record( 104*eeb7e5b3SAdam Hornáček major natural, 105*eeb7e5b3SAdam Hornáček minor natural, 106*eeb7e5b3SAdam Hornáček bugfix natural, 107*eeb7e5b3SAdam Hornáček build natural 108*eeb7e5b3SAdam Hornáček ); 109*eeb7e5b3SAdam Hornáček 110*eeb7e5b3SAdam Hornáček 111*eeb7e5b3SAdam Hornáček /** 112*eeb7e5b3SAdam Hornáček * Converts test results into strings 113*eeb7e5b3SAdam Hornáček * 114*eeb7e5b3SAdam Hornáček * @param a_test_result numeric representation of test result 115*eeb7e5b3SAdam Hornáček * 116*eeb7e5b3SAdam Hornáček * @return a string representation of a test_result. 117*eeb7e5b3SAdam Hornáček */ 118*eeb7e5b3SAdam Hornáček function test_result_to_char(a_test_result integer) return varchar2; 119*eeb7e5b3SAdam Hornáček 120*eeb7e5b3SAdam Hornáček function to_test_result(a_test boolean) return integer; 121*eeb7e5b3SAdam Hornáček 122*eeb7e5b3SAdam Hornáček /** 123*eeb7e5b3SAdam Hornáček * Generates a unique name for a savepoint 124*eeb7e5b3SAdam Hornáček * Uses sys_guid, as timestamp gives only miliseconds on Windows and is not unique 125*eeb7e5b3SAdam Hornáček * Issue: #506 for details on the implementation approach 126*eeb7e5b3SAdam Hornáček */ 127*eeb7e5b3SAdam Hornáček function gen_savepoint_name return varchar2; 128*eeb7e5b3SAdam Hornáček 129*eeb7e5b3SAdam Hornáček procedure debug_log(a_message varchar2); 130*eeb7e5b3SAdam Hornáček 131*eeb7e5b3SAdam Hornáček procedure debug_log(a_message clob); 132*eeb7e5b3SAdam Hornáček 133*eeb7e5b3SAdam Hornáček function to_string(a_value varchar2, a_qoute_char varchar2 := '''') return varchar2; 134*eeb7e5b3SAdam Hornáček 135*eeb7e5b3SAdam Hornáček function to_string(a_value clob, a_qoute_char varchar2 := '''') return varchar2; 136*eeb7e5b3SAdam Hornáček 137*eeb7e5b3SAdam Hornáček function to_string(a_value blob, a_qoute_char varchar2 := '''') return varchar2; 138*eeb7e5b3SAdam Hornáček 139*eeb7e5b3SAdam Hornáček function to_string(a_value boolean) return varchar2; 140*eeb7e5b3SAdam Hornáček 141*eeb7e5b3SAdam Hornáček function to_string(a_value number) return varchar2; 142*eeb7e5b3SAdam Hornáček 143*eeb7e5b3SAdam Hornáček function to_string(a_value date) return varchar2; 144*eeb7e5b3SAdam Hornáček 145*eeb7e5b3SAdam Hornáček function to_string(a_value timestamp_unconstrained) return varchar2; 146*eeb7e5b3SAdam Hornáček 147*eeb7e5b3SAdam Hornáček function to_string(a_value timestamp_tz_unconstrained) return varchar2; 148*eeb7e5b3SAdam Hornáček 149*eeb7e5b3SAdam Hornáček function to_string(a_value timestamp_ltz_unconstrained) return varchar2; 150*eeb7e5b3SAdam Hornáček 151*eeb7e5b3SAdam Hornáček function to_string(a_value yminterval_unconstrained) return varchar2; 152*eeb7e5b3SAdam Hornáček 153*eeb7e5b3SAdam Hornáček function to_string(a_value dsinterval_unconstrained) return varchar2; 154*eeb7e5b3SAdam Hornáček 155*eeb7e5b3SAdam Hornáček function boolean_to_int(a_value boolean) return integer; 156*eeb7e5b3SAdam Hornáček 157*eeb7e5b3SAdam Hornáček function int_to_boolean(a_value integer) return boolean; 158*eeb7e5b3SAdam Hornáček 159*eeb7e5b3SAdam Hornáček /** 160*eeb7e5b3SAdam Hornáček * Validates passed value against supported rollback types 161*eeb7e5b3SAdam Hornáček */ 162*eeb7e5b3SAdam Hornáček procedure validate_rollback_type(a_rollback_type number); 163*eeb7e5b3SAdam Hornáček 164*eeb7e5b3SAdam Hornáček 165*eeb7e5b3SAdam Hornáček /** 166*eeb7e5b3SAdam Hornáček * 167*eeb7e5b3SAdam Hornáček * Splits a given string into table of string by delimiter. 168*eeb7e5b3SAdam Hornáček * The delimiter gets removed. 169*eeb7e5b3SAdam Hornáček * If null passed as any of the parameters, empty table is returned. 170*eeb7e5b3SAdam Hornáček * If no occurence of a_delimiter found in a_text then text is returned as a single row of the table. 171*eeb7e5b3SAdam Hornáček * If no text between delimiters found then an empty row is returned, example: 172*eeb7e5b3SAdam Hornáček * string_to_table( 'a,,b', ',' ) gives table ut_varchar2_list( 'a', null, 'b' ); 173*eeb7e5b3SAdam Hornáček * 174*eeb7e5b3SAdam Hornáček * @param a_string the text to be split. 175*eeb7e5b3SAdam Hornáček * @param a_delimiter the delimiter character or string 176*eeb7e5b3SAdam Hornáček * @param a_skip_leading_delimiter determines if the leading delimiter should be ignored, used by clob_to_table 177*eeb7e5b3SAdam Hornáček * 178*eeb7e5b3SAdam Hornáček * @return table of varchar2 values 179*eeb7e5b3SAdam Hornáček */ 180*eeb7e5b3SAdam Hornáček function string_to_table(a_string varchar2, a_delimiter varchar2:= chr(10), a_skip_leading_delimiter varchar2 := 'N') return ut_varchar2_list; 181*eeb7e5b3SAdam Hornáček 182*eeb7e5b3SAdam Hornáček /** 183*eeb7e5b3SAdam Hornáček * Splits a given string into table of string by delimiter. 184*eeb7e5b3SAdam Hornáček * Default value of a_max_amount is 8191 because of code can contains multibyte character. 185*eeb7e5b3SAdam Hornáček * The delimiter gets removed. 186*eeb7e5b3SAdam Hornáček * If null passed as any of the parameters, empty table is returned. 187*eeb7e5b3SAdam Hornáček * If split text is longer than a_max_amount it gets split into pieces of a_max_amount. 188*eeb7e5b3SAdam Hornáček * If no text between delimiters found then an empty row is returned, example: 189*eeb7e5b3SAdam Hornáček * string_to_table( 'a,,b', ',' ) gives table ut_varchar2_list( 'a', null, 'b' ); 190*eeb7e5b3SAdam Hornáček * 191*eeb7e5b3SAdam Hornáček * @param a_clob the text to be split. 192*eeb7e5b3SAdam Hornáček * @param a_delimiter the delimiter character or string (default chr(10) ) 193*eeb7e5b3SAdam Hornáček * @param a_max_amount the maximum length of returned string (default 8191) 194*eeb7e5b3SAdam Hornáček * @return table of varchar2 values 195*eeb7e5b3SAdam Hornáček */ 196*eeb7e5b3SAdam Hornáček function clob_to_table(a_clob clob, a_max_amount integer := 8191, a_delimiter varchar2:= chr(10)) return ut_varchar2_list; 197*eeb7e5b3SAdam Hornáček 198*eeb7e5b3SAdam Hornáček function table_to_clob(a_text_table ut_varchar2_list, a_delimiter varchar2:= chr(10)) return clob; 199*eeb7e5b3SAdam Hornáček 200*eeb7e5b3SAdam Hornáček /** 201*eeb7e5b3SAdam Hornáček * Returns time difference in seconds (with miliseconds) between given timestamps 202*eeb7e5b3SAdam Hornáček */ 203*eeb7e5b3SAdam Hornáček function time_diff(a_start_time timestamp with time zone, a_end_time timestamp with time zone) return number; 204*eeb7e5b3SAdam Hornáček 205*eeb7e5b3SAdam Hornáček /** 206*eeb7e5b3SAdam Hornáček * Returns a text indented with spaces except the first line. 207*eeb7e5b3SAdam Hornáček */ 208*eeb7e5b3SAdam Hornáček function indent_lines(a_text varchar2, a_indent_size integer := 4, a_include_first_line boolean := false) return varchar2; 209*eeb7e5b3SAdam Hornáček 210*eeb7e5b3SAdam Hornáček 211*eeb7e5b3SAdam Hornáček /** 212*eeb7e5b3SAdam Hornáček * Returns a list of object that are part of utPLSQL framework 213*eeb7e5b3SAdam Hornáček */ 214*eeb7e5b3SAdam Hornáček function get_utplsql_objects_list return ut_object_names; 215*eeb7e5b3SAdam Hornáček 216*eeb7e5b3SAdam Hornáček /** 217*eeb7e5b3SAdam Hornáček * Append a line to the end of ut_varchar2_lst 218*eeb7e5b3SAdam Hornáček */ 219*eeb7e5b3SAdam Hornáček procedure append_to_varchar2_list(a_list in out nocopy ut_varchar2_list, a_line varchar2); 220*eeb7e5b3SAdam Hornáček 221*eeb7e5b3SAdam Hornáček procedure append_to_clob(a_src_clob in out nocopy clob, a_new_data clob); 222*eeb7e5b3SAdam Hornáček procedure append_to_clob(a_src_clob in out nocopy clob, a_new_data varchar2); 223*eeb7e5b3SAdam Hornáček 224*eeb7e5b3SAdam Hornáček function convert_collection(a_collection ut_varchar2_list) return ut_varchar2_rows; 225*eeb7e5b3SAdam Hornáček 226*eeb7e5b3SAdam Hornáček /** 227*eeb7e5b3SAdam Hornáček * Set session's action and module using dbms_application_info 228*eeb7e5b3SAdam Hornáček */ 229*eeb7e5b3SAdam Hornáček procedure set_action(a_text in varchar2); 230*eeb7e5b3SAdam Hornáček 231*eeb7e5b3SAdam Hornáček /** 232*eeb7e5b3SAdam Hornáček * Set session's client info using dbms_application_info 233*eeb7e5b3SAdam Hornáček */ 234*eeb7e5b3SAdam Hornáček procedure set_client_info(a_text in varchar2); 235*eeb7e5b3SAdam Hornáček 236*eeb7e5b3SAdam Hornáček function to_xpath(a_list varchar2, a_ancestors varchar2 := '/*/') return varchar2; 237*eeb7e5b3SAdam Hornáček 238*eeb7e5b3SAdam Hornáček function to_xpath(a_list ut_varchar2_list, a_ancestors varchar2 := '/*/') return varchar2; 239*eeb7e5b3SAdam Hornáček 240*eeb7e5b3SAdam Hornáček procedure cleanup_temp_tables; 241*eeb7e5b3SAdam Hornáček 242*eeb7e5b3SAdam Hornáček /** 243*eeb7e5b3SAdam Hornáček * Converts version string into version record 244*eeb7e5b3SAdam Hornáček * 245*eeb7e5b3SAdam Hornáček * @param a_version_no string representation of version in format vX.X.X.X where X is a positive integer 246*eeb7e5b3SAdam Hornáček * @return t_version record with up to four positive numbers containing version 247*eeb7e5b3SAdam Hornáček * @throws 20214 if passed version string is not matching version pattern 248*eeb7e5b3SAdam Hornáček */ 249*eeb7e5b3SAdam Hornáček function to_version(a_version_no varchar2) return t_version; 250*eeb7e5b3SAdam Hornáček 251*eeb7e5b3SAdam Hornáček 252*eeb7e5b3SAdam Hornáček /** 253*eeb7e5b3SAdam Hornáček * Saves data from dbms_output buffer into a global temporary table (cache) 254*eeb7e5b3SAdam Hornáček * used to store dbms_output buffer captured before the run 255*eeb7e5b3SAdam Hornáček * 256*eeb7e5b3SAdam Hornáček */ 257*eeb7e5b3SAdam Hornáček procedure save_dbms_output_to_cache; 258*eeb7e5b3SAdam Hornáček 259*eeb7e5b3SAdam Hornáček /** 260*eeb7e5b3SAdam Hornáček * Reads data from global temporary table (cache) abd puts it back into dbms_output 261*eeb7e5b3SAdam Hornáček * used to recover dbms_output buffer data after a run is complete 262*eeb7e5b3SAdam Hornáček * 263*eeb7e5b3SAdam Hornáček */ 264*eeb7e5b3SAdam Hornáček procedure read_cache_to_dbms_output; 265*eeb7e5b3SAdam Hornáček 266*eeb7e5b3SAdam Hornáček 267*eeb7e5b3SAdam Hornáček /** 268*eeb7e5b3SAdam Hornáček * Function is used to reference to utPLSQL owned objects in dynamic sql statements executed from packages with invoker rights 269*eeb7e5b3SAdam Hornáček * 270*eeb7e5b3SAdam Hornáček * @return the name of the utPSQL schema owner 271*eeb7e5b3SAdam Hornáček */ 272*eeb7e5b3SAdam Hornáček function ut_owner return varchar2; 273*eeb7e5b3SAdam Hornáček 274*eeb7e5b3SAdam Hornáček 275*eeb7e5b3SAdam Hornáček /** 276*eeb7e5b3SAdam Hornáček * Used in dynamic sql select statements to maintain balance between 277*eeb7e5b3SAdam Hornáček * number of hard-parses and optimiser accurancy for cardinality of collections 278*eeb7e5b3SAdam Hornáček * 279*eeb7e5b3SAdam Hornáček * 280*eeb7e5b3SAdam Hornáček * @return 3, for inputs of: 1-9; 33 for input of 10 - 99; 333 for (100 - 999) 281*eeb7e5b3SAdam Hornáček */ 282*eeb7e5b3SAdam Hornáček function scale_cardinality(a_cardinality natural) return natural; 283*eeb7e5b3SAdam Hornáček 284*eeb7e5b3SAdam Hornáčekend ut_utils; 285*eeb7e5b3SAdam Hornáček/ 286*eeb7e5b3SAdam Hornáček 287*eeb7e5b3SAdam Hornáčekcreate or replace package body ut_suite_builder is 288*eeb7e5b3SAdam Hornáček /* 289*eeb7e5b3SAdam Hornáček utPLSQL - Version 3 290*eeb7e5b3SAdam Hornáček Copyright 2016 - 2017 utPLSQL Project 291*eeb7e5b3SAdam Hornáček 292*eeb7e5b3SAdam Hornáček Licensed under the Apache License, Version 2.0 (the "License"): 293*eeb7e5b3SAdam Hornáček you may not use this file except in compliance with the License. 294*eeb7e5b3SAdam Hornáček You may obtain a copy of the License at 295*eeb7e5b3SAdam Hornáček 296*eeb7e5b3SAdam Hornáček http://www.apache.org/licenses/LICENSE-2.0 297*eeb7e5b3SAdam Hornáček 298*eeb7e5b3SAdam Hornáček Unless required by applicable law or agreed to in writing, software 299*eeb7e5b3SAdam Hornáček distributed under the License is distributed on an "AS IS" BASIS, 300*eeb7e5b3SAdam Hornáček WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 301*eeb7e5b3SAdam Hornáček See the License for the specific language governing permissions and 302*eeb7e5b3SAdam Hornáček limitations under the License. 303*eeb7e5b3SAdam Hornáček */ 304*eeb7e5b3SAdam Hornáček 305*eeb7e5b3SAdam Hornáček ------------------ 306*eeb7e5b3SAdam Hornáček 307*eeb7e5b3SAdam Hornáček function create_suite(a_object ut_annotated_object) return ut_logical_suite is 308*eeb7e5b3SAdam Hornáček l_is_suite boolean := false; 309*eeb7e5b3SAdam Hornáček l_is_test boolean := false; 310*eeb7e5b3SAdam Hornáček l_suite_disabled boolean := false; 311*eeb7e5b3SAdam Hornáček l_test_disabled boolean := false; 312*eeb7e5b3SAdam Hornáček l_suite_items ut_suite_items := ut_suite_items(); 313*eeb7e5b3SAdam Hornáček l_suite_name varchar2(4000); 314*eeb7e5b3SAdam Hornáček 315*eeb7e5b3SAdam Hornáček l_default_setup_proc varchar2(250 char); 316*eeb7e5b3SAdam Hornáček l_default_teardown_proc varchar2(250 char); 317*eeb7e5b3SAdam Hornáček l_suite_setup_proc varchar2(250 char); 318*eeb7e5b3SAdam Hornáček l_suite_teardown_proc varchar2(250 char); 319*eeb7e5b3SAdam Hornáček l_suite_path varchar2(4000 char); 320*eeb7e5b3SAdam Hornáček 321*eeb7e5b3SAdam Hornáček l_proc_name varchar2(250 char); 322*eeb7e5b3SAdam Hornáček 323*eeb7e5b3SAdam Hornáček l_suite ut_logical_suite; 324*eeb7e5b3SAdam Hornáček l_test ut_test; 325*eeb7e5b3SAdam Hornáček 326*eeb7e5b3SAdam Hornáček l_suite_rollback integer; 327*eeb7e5b3SAdam Hornáček 328*eeb7e5b3SAdam Hornáček l_beforetest_procedure varchar2(250 char); 329*eeb7e5b3SAdam Hornáček l_aftertest_procedure varchar2(250 char); 330*eeb7e5b3SAdam Hornáček l_rollback_type integer; 331*eeb7e5b3SAdam Hornáček l_displayname varchar2(4000); 332*eeb7e5b3SAdam Hornáček function is_last_annotation_for_proc(a_annotations ut_annotations, a_index binary_integer) return boolean is 333*eeb7e5b3SAdam Hornáček begin 334*eeb7e5b3SAdam Hornáček return a_index = a_annotations.count or a_annotations(a_index).subobject_name != nvl(a_annotations(a_index+1).subobject_name, ' '); 335*eeb7e5b3SAdam Hornáček end; 336*eeb7e5b3SAdam Hornáček begin 337*eeb7e5b3SAdam Hornáček l_suite_rollback := ut_utils.gc_rollback_auto; 338*eeb7e5b3SAdam Hornáček for i in 1 .. a_object.annotations.count loop 339*eeb7e5b3SAdam Hornáček 340*eeb7e5b3SAdam Hornáček if a_object.annotations(i).subobject_name is null then 341*eeb7e5b3SAdam Hornáček 342*eeb7e5b3SAdam Hornáček if a_object.annotations(i).name in ('suite','displayname') then 343*eeb7e5b3SAdam Hornáček l_suite_name := a_object.annotations(i).text; 344*eeb7e5b3SAdam Hornáček if a_object.annotations(i).name = 'suite' then 345*eeb7e5b3SAdam Hornáček l_is_suite := true; 346*eeb7e5b3SAdam Hornáček end if; 347*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'disabled' then 348*eeb7e5b3SAdam Hornáček l_suite_disabled := true; 349*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'suitepath' and a_object.annotations(i).text is not null then 350*eeb7e5b3SAdam Hornáček l_suite_path := a_object.annotations(i).text || '.' || lower(a_object.object_name); 351*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'rollback' then 352*eeb7e5b3SAdam Hornáček if lower(a_object.annotations(i).text) = 'manual' then 353*eeb7e5b3SAdam Hornáček l_suite_rollback := ut_utils.gc_rollback_manual; 354*eeb7e5b3SAdam Hornáček else 355*eeb7e5b3SAdam Hornáček l_suite_rollback := ut_utils.gc_rollback_auto; 356*eeb7e5b3SAdam Hornáček end if; 357*eeb7e5b3SAdam Hornáček end if; 358*eeb7e5b3SAdam Hornáček 359*eeb7e5b3SAdam Hornáček elsif l_is_suite then 360*eeb7e5b3SAdam Hornáček 361*eeb7e5b3SAdam Hornáček l_proc_name := a_object.annotations(i).subobject_name; 362*eeb7e5b3SAdam Hornáček 363*eeb7e5b3SAdam Hornáček if a_object.annotations(i).name = 'beforeeach' and l_default_setup_proc is null then 364*eeb7e5b3SAdam Hornáček l_default_setup_proc := l_proc_name; 365*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'aftereach' and l_default_teardown_proc is null then 366*eeb7e5b3SAdam Hornáček l_default_teardown_proc := l_proc_name; 367*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'beforeall' and l_suite_setup_proc is null then 368*eeb7e5b3SAdam Hornáček l_suite_setup_proc := l_proc_name; 369*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'afterall' and l_suite_teardown_proc is null then 370*eeb7e5b3SAdam Hornáček l_suite_teardown_proc := l_proc_name; 371*eeb7e5b3SAdam Hornáček 372*eeb7e5b3SAdam Hornáček 373*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'disabled' then 374*eeb7e5b3SAdam Hornáček l_test_disabled := true; 375*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'beforetest' then 376*eeb7e5b3SAdam Hornáček l_beforetest_procedure := a_object.annotations(i).text; 377*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'aftertest' then 378*eeb7e5b3SAdam Hornáček l_aftertest_procedure := a_object.annotations(i).text; 379*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name in ('displayname','test') then 380*eeb7e5b3SAdam Hornáček l_displayname := a_object.annotations(i).text; 381*eeb7e5b3SAdam Hornáček if a_object.annotations(i).name = 'test' then 382*eeb7e5b3SAdam Hornáček l_is_test := true; 383*eeb7e5b3SAdam Hornáček end if; 384*eeb7e5b3SAdam Hornáček elsif a_object.annotations(i).name = 'rollback' then 385*eeb7e5b3SAdam Hornáček if lower(a_object.annotations(i).text) = 'manual' then 386*eeb7e5b3SAdam Hornáček l_rollback_type := ut_utils.gc_rollback_manual; 387*eeb7e5b3SAdam Hornáček elsif lower(a_object.annotations(i).text) = 'auto' then 388*eeb7e5b3SAdam Hornáček l_rollback_type := ut_utils.gc_rollback_auto; 389*eeb7e5b3SAdam Hornáček end if; 390*eeb7e5b3SAdam Hornáček end if; 391*eeb7e5b3SAdam Hornáček 392*eeb7e5b3SAdam Hornáček if l_is_test and is_last_annotation_for_proc(a_object.annotations, i) then 393*eeb7e5b3SAdam Hornáček l_suite_items.extend; 394*eeb7e5b3SAdam Hornáček l_suite_items(l_suite_items.last) := 395*eeb7e5b3SAdam Hornáček ut_test(a_object_owner => a_object.object_owner 396*eeb7e5b3SAdam Hornáček ,a_object_name => a_object.object_name 397*eeb7e5b3SAdam Hornáček ,a_name => l_proc_name 398*eeb7e5b3SAdam Hornáček ,a_description => l_displayname 399*eeb7e5b3SAdam Hornáček ,a_rollback_type => coalesce(l_rollback_type, l_suite_rollback) 400*eeb7e5b3SAdam Hornáček ,a_disabled_flag => l_test_disabled 401*eeb7e5b3SAdam Hornáček ,a_before_test_proc_name => l_beforetest_procedure 402*eeb7e5b3SAdam Hornáček ,a_after_test_proc_name => l_aftertest_procedure); 403*eeb7e5b3SAdam Hornáček 404*eeb7e5b3SAdam Hornáček l_is_test := false; 405*eeb7e5b3SAdam Hornáček l_test_disabled := false; 406*eeb7e5b3SAdam Hornáček l_aftertest_procedure := null; 407*eeb7e5b3SAdam Hornáček l_beforetest_procedure := null; 408*eeb7e5b3SAdam Hornáček l_rollback_type := null; 409*eeb7e5b3SAdam Hornáček end if; 410*eeb7e5b3SAdam Hornáček 411*eeb7e5b3SAdam Hornáček end if; 412*eeb7e5b3SAdam Hornáček end loop; 413*eeb7e5b3SAdam Hornáček 414*eeb7e5b3SAdam Hornáček if l_is_suite then 415*eeb7e5b3SAdam Hornáček l_suite := ut_suite ( 416*eeb7e5b3SAdam Hornáček a_object_owner => a_object.object_owner, 417*eeb7e5b3SAdam Hornáček a_object_name => a_object.object_name, 418*eeb7e5b3SAdam Hornáček a_name => a_object.object_name, --this could be different for sub-suite (context) 419*eeb7e5b3SAdam Hornáček a_path => l_suite_path, --a patch for this suite (excluding the package name of current suite) 420*eeb7e5b3SAdam Hornáček a_description => l_suite_name, 421*eeb7e5b3SAdam Hornáček a_rollback_type => l_suite_rollback, 422*eeb7e5b3SAdam Hornáček a_disabled_flag => l_suite_disabled, 423*eeb7e5b3SAdam Hornáček a_before_all_proc_name => l_suite_setup_proc, 424*eeb7e5b3SAdam Hornáček a_after_all_proc_name => l_suite_teardown_proc 425*eeb7e5b3SAdam Hornáček ); 426*eeb7e5b3SAdam Hornáček for i in 1 .. l_suite_items.count loop 427*eeb7e5b3SAdam Hornáček l_test := treat(l_suite_items(i) as ut_test); 428*eeb7e5b3SAdam Hornáček l_test.set_beforeeach(l_default_setup_proc); 429*eeb7e5b3SAdam Hornáček l_test.set_aftereach(l_default_teardown_proc); 430*eeb7e5b3SAdam Hornáček l_test.path := l_suite.path || '.' || l_test.name; 431*eeb7e5b3SAdam Hornáček l_suite.add_item(l_test); 432*eeb7e5b3SAdam Hornáček end loop; 433*eeb7e5b3SAdam Hornáček end if; 434*eeb7e5b3SAdam Hornáček 435*eeb7e5b3SAdam Hornáček return l_suite; 436*eeb7e5b3SAdam Hornáček 437*eeb7e5b3SAdam Hornáček end create_suite; 438*eeb7e5b3SAdam Hornáček 439*eeb7e5b3SAdam Hornáček function build_suites_hierarchy(a_suites_by_path tt_schema_suites) return tt_schema_suites is 440*eeb7e5b3SAdam Hornáček l_result tt_schema_suites; 441*eeb7e5b3SAdam Hornáček l_suite_path varchar2(4000 char); 442*eeb7e5b3SAdam Hornáček l_parent_path varchar2(4000 char); 443*eeb7e5b3SAdam Hornáček l_name varchar2(4000 char); 444*eeb7e5b3SAdam Hornáček l_suites_by_path tt_schema_suites; 445*eeb7e5b3SAdam Hornáček begin 446*eeb7e5b3SAdam Hornáček l_suites_by_path := a_suites_by_path; 447*eeb7e5b3SAdam Hornáček --were iterating in reverse order of the index by path table 448*eeb7e5b3SAdam Hornáček -- so the first paths will be the leafs of hierarchy and next will their parents 449*eeb7e5b3SAdam Hornáček l_suite_path := l_suites_by_path.last; 450*eeb7e5b3SAdam Hornáček ut_utils.debug_log('Input suites to process = '||l_suites_by_path.count); 451*eeb7e5b3SAdam Hornáček 452*eeb7e5b3SAdam Hornáček while l_suite_path is not null loop 453*eeb7e5b3SAdam Hornáček l_parent_path := substr( l_suite_path, 1, instr(l_suite_path,'.',-1)-1); 454*eeb7e5b3SAdam Hornáček ut_utils.debug_log('Processing l_suite_path = "'||l_suite_path||'", l_parent_path = "'||l_parent_path||'"'); 455*eeb7e5b3SAdam Hornáček --no parent => I'm a root element 456*eeb7e5b3SAdam Hornáček if l_parent_path is null then 457*eeb7e5b3SAdam Hornáček ut_utils.debug_log(' suite "'||l_suite_path||'" is a root element - adding to return list.'); 458*eeb7e5b3SAdam Hornáček l_result(l_suite_path) := l_suites_by_path(l_suite_path); 459*eeb7e5b3SAdam Hornáček -- not a root suite - need to add it to a parent suite 460*eeb7e5b3SAdam Hornáček else 461*eeb7e5b3SAdam Hornáček --parent does not exist and needs to be added 462*eeb7e5b3SAdam Hornáček if not l_suites_by_path.exists(l_parent_path) then 463*eeb7e5b3SAdam Hornáček l_name := substr( l_parent_path, instr(l_parent_path,'.',-1)+1); 464*eeb7e5b3SAdam Hornáček ut_utils.debug_log(' Parent suite "'||l_parent_path||'" not found in the list - Adding suite "'||l_name||'"'); 465*eeb7e5b3SAdam Hornáček l_suites_by_path(l_parent_path) := 466*eeb7e5b3SAdam Hornáček ut_logical_suite( 467*eeb7e5b3SAdam Hornáček a_object_owner => l_suites_by_path(l_suite_path).object_owner, 468*eeb7e5b3SAdam Hornáček a_object_name => l_name, a_name => l_name, a_path => l_parent_path 469*eeb7e5b3SAdam Hornáček ); 470*eeb7e5b3SAdam Hornáček else 471*eeb7e5b3SAdam Hornáček ut_utils.debug_log(' Parent suite "'||l_parent_path||'" found in list of suites'); 472*eeb7e5b3SAdam Hornáček end if; 473*eeb7e5b3SAdam Hornáček ut_utils.debug_log(' adding suite "'||l_suite_path||'" to "'||l_parent_path||'" items'); 474*eeb7e5b3SAdam Hornáček l_suites_by_path(l_parent_path).add_item( l_suites_by_path(l_suite_path) ); 475*eeb7e5b3SAdam Hornáček end if; 476*eeb7e5b3SAdam Hornáček l_suite_path := l_suites_by_path.prior(l_suite_path); 477*eeb7e5b3SAdam Hornáček end loop; 478*eeb7e5b3SAdam Hornáček ut_utils.debug_log(l_result.count||' root suites created.'); 479*eeb7e5b3SAdam Hornáček return l_result; 480*eeb7e5b3SAdam Hornáček end; 481*eeb7e5b3SAdam Hornáček 482*eeb7e5b3SAdam Hornáček function build_suites(a_annotated_objects sys_refcursor) return t_schema_suites_info is 483*eeb7e5b3SAdam Hornáček l_suite ut_logical_suite; 484*eeb7e5b3SAdam Hornáček l_annotated_objects ut_annotated_objects; 485*eeb7e5b3SAdam Hornáček l_all_suites tt_schema_suites; 486*eeb7e5b3SAdam Hornáček l_result t_schema_suites_info; 487*eeb7e5b3SAdam Hornáček begin 488*eeb7e5b3SAdam Hornáček fetch a_annotated_objects bulk collect into l_annotated_objects; 489*eeb7e5b3SAdam Hornáček close a_annotated_objects; 490*eeb7e5b3SAdam Hornáček 491*eeb7e5b3SAdam Hornáček for i in 1 .. l_annotated_objects.count loop 492*eeb7e5b3SAdam Hornáček l_suite := create_suite(l_annotated_objects(i)); 493*eeb7e5b3SAdam Hornáček if l_suite is not null then 494*eeb7e5b3SAdam Hornáček l_all_suites(l_suite.path) := l_suite; 495*eeb7e5b3SAdam Hornáček l_result.suite_paths(l_suite.object_name) := l_suite.path; 496*eeb7e5b3SAdam Hornáček end if; 497*eeb7e5b3SAdam Hornáček end loop; 498*eeb7e5b3SAdam Hornáček 499*eeb7e5b3SAdam Hornáček --build hierarchical structure of the suite 500*eeb7e5b3SAdam Hornáček -- Restructure single-dimension list into hierarchy of suites by the value of %suitepath attribute value 501*eeb7e5b3SAdam Hornáček l_result.schema_suites := build_suites_hierarchy(l_all_suites); 502*eeb7e5b3SAdam Hornáček 503*eeb7e5b3SAdam Hornáček return l_result; 504*eeb7e5b3SAdam Hornáček end; 505*eeb7e5b3SAdam Hornáček 506*eeb7e5b3SAdam Hornáček function build_schema_suites(a_owner_name varchar2) return t_schema_suites_info is 507*eeb7e5b3SAdam Hornáček l_annotations_cursor sys_refcursor; 508*eeb7e5b3SAdam Hornáček begin 509*eeb7e5b3SAdam Hornáček -- form the single-dimension list of suites constructed from parsed packages 510*eeb7e5b3SAdam Hornáček open l_annotations_cursor for 511*eeb7e5b3SAdam Hornáček q'[select value(x) 512*eeb7e5b3SAdam Hornáček from table( 513*eeb7e5b3SAdam Hornáček ]'||ut_utils.ut_owner||q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE') 514*eeb7e5b3SAdam Hornáček )x ]' 515*eeb7e5b3SAdam Hornáček using a_owner_name; 516*eeb7e5b3SAdam Hornáček 517*eeb7e5b3SAdam Hornáček return build_suites(l_annotations_cursor); 518*eeb7e5b3SAdam Hornáček end; 519*eeb7e5b3SAdam Hornáček 520*eeb7e5b3SAdam Hornáčekend ut_suite_builder; 521*eeb7e5b3SAdam Hornáček/ 522*eeb7e5b3SAdam Hornáček/*http://example.com.*/ 523*eeb7e5b3SAdam Hornáček/* comment /* comment */ 524*eeb7e5b3SAdam Hornáčekcomment 525*eeb7e5b3SAdam Hornáček*/ 526