Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 87fa7fc

Browse files
authored
Merge pull request #857 from utPLSQL/feature/add_debug_reporter
Feature/add debug reporter
2 parents 05b5e89 + 0700125 commit 87fa7fc

27 files changed

Lines changed: 534 additions & 71 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ coverage.xml
2727
tfs_test_results.xml
2828
junit_test_results.xml
2929
test_results.xml
30+
*debug*.xml

docs/userguide/reporters.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,46 @@ Details:
120120
# Coverage reporters
121121

122122
utPLSQL comes with a set of build-in coverage reporters. Have a look into the [coverage documentation](coverage.md) to learn more about them.
123+
124+
125+
# Debug reporter
126+
127+
The `ut_debug_reporter` provides a highly verbose output containing thorough details about framework and test execution.
128+
129+
Use this reporter only when you need to investigate framework issues or raise a bug report to utPLSQL team.
130+
131+
Usage of this reporter might have impact on performance of test-suite execution.
132+
133+
Amongst others, reporter provides the following information:
134+
- framework version
135+
- database version
136+
- database OS
137+
- database, instance and session NLS settings
138+
- timing of each event
139+
- time between events logged
140+
- time from start of the run
141+
- stack trace
142+
- information about input parameters for the run including
143+
- run paths
144+
- source file mappings
145+
- test file mappings
146+
- coverage schemas
147+
- coverage exclusions and inclusions
148+
- client character set
149+
- information about every step of the run including
150+
- every suite and context
151+
- every before/after procedure
152+
- every test
153+
- every expectation and it's result
154+
155+
Some of the information in debug log might be redundant.
156+
157+
**Note:**
158+
>Some of the information in debug log may be sensitive. In particular:
159+
> - expectation results and messages (logged even for successful runs)
160+
> - test structure
161+
> - db object names
162+
> - etc.
163+
164+
165+

source/api/ut_runner.pkb

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,21 @@ create or replace package body ut_runner is
9797
l_paths ut_varchar2_list := ut_varchar2_list();
9898
begin
9999
ut_event_manager.initialize();
100+
if a_reporters is not empty then
101+
for i in 1 .. a_reporters.count loop
102+
ut_event_manager.add_listener( a_reporters(i) );
103+
end loop;
104+
else
105+
ut_event_manager.add_listener( ut_documentation_reporter() );
106+
end if;
107+
108+
ut_event_manager.trigger_event(ut_event_manager.gc_initialize);
109+
ut_event_manager.trigger_event(ut_event_manager.gc_debug, ut_run_info());
110+
100111
if a_paths is null or a_paths is empty or a_paths.count = 1 and a_paths(1) is null then
101112
l_paths := ut_varchar2_list(sys_context('userenv', 'current_schema'));
102113
else
103-
for i in 1..a_paths.COUNT loop
114+
for i in 1..a_paths.count loop
104115
l_paths := l_paths multiset union ut_utils.string_to_table(a_string => a_paths(i),a_delimiter => ',');
105116
end loop;
106117
end if;
@@ -110,13 +121,6 @@ create or replace package body ut_runner is
110121
ut_utils.save_dbms_output_to_cache();
111122

112123
ut_console_reporter_base.set_color_enabled(a_color_console);
113-
if a_reporters is null or a_reporters.count = 0 then
114-
ut_event_manager.add_listener(ut_documentation_reporter());
115-
else
116-
for i in 1 .. a_reporters.count loop
117-
ut_event_manager.add_listener(a_reporters(i));
118-
end loop;
119-
end if;
120124

121125
if a_coverage_schemes is not empty then
122126
l_coverage_schema_names := ut_utils.convert_collection(a_coverage_schemes);
@@ -143,8 +147,6 @@ create or replace package body ut_runner is
143147
a_client_character_set
144148
);
145149

146-
ut_event_manager.trigger_event(ut_event_manager.gc_initialize, l_run);
147-
148150
ut_suite_manager.configure_execution_by_path(l_paths, l_run.items);
149151
if a_force_manual_rollback then
150152
l_run.set_rollback_type( a_rollback_type => ut_utils.gc_rollback_manual, a_force => true );

source/core/coverage/ut_coverage.pkb

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ create or replace package body ut_coverage is
131131

132132
if not ut_coverage_helper.is_tmp_table_populated() or is_develop_mode() then
133133
ut_coverage_helper.cleanup_tmp_table();
134-
135-
l_cov_sources_crsr := get_cov_sources_cursor(a_coverage_options,a_sql);
134+
ut_event_manager.trigger_event(ut_event_manager.gc_debug, ut_key_anyvalues().put('a_sql',a_sql) );
135+
l_cov_sources_crsr := get_cov_sources_cursor(a_coverage_options, a_sql);
136136

137137
loop
138138
fetch l_cov_sources_crsr bulk collect into l_cov_sources_data limit 10000;
@@ -209,48 +209,50 @@ create or replace package body ut_coverage is
209209
l_line_no binary_integer;
210210
begin
211211
--prepare global temp table with sources
212+
ut_event_manager.trigger_event('about to populate coverage temp table');
212213
populate_tmp_table(a_coverage_options, get_cov_sources_sql(a_coverage_options));
214+
ut_event_manager.trigger_event('coverage temp table populated');
213215

214216
-- Get raw data for both reporters, order is important as tmp table will skip headers and dont populate
215217
-- tmp table for block again.
216218
l_result_profiler_enrich:= ut_coverage_profiler.get_coverage_data( a_coverage_options, get_coverage_id(gc_proftab_coverage) );
217-
218-
-- If block coverage available we will use it.
219-
$if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then
220-
l_result_block := ut_coverage_block.get_coverage_data( a_coverage_options, get_coverage_id(gc_block_coverage) );
221-
222-
-- Enrich profiler results with some of the block results
223-
l_object := l_result_profiler_enrich.objects.first;
224-
while (l_object is not null)
225-
loop
226-
227-
l_line_no := l_result_profiler_enrich.objects(l_object).lines.first;
228-
229-
-- to avoid no data found check if we got object in profiler
230-
if l_result_block.objects.exists(l_object) then
231-
while (l_line_no is not null)
232-
loop
233-
-- To avoid no data check for object line
234-
if l_result_block.objects(l_object).lines.exists(l_line_no) then
235-
-- enrich line level stats
236-
l_result_profiler_enrich.objects(l_object).lines(l_line_no).partcove := l_result_block.objects(l_object).lines(l_line_no).partcove;
237-
l_result_profiler_enrich.objects(l_object).lines(l_line_no).covered_blocks := l_result_block.objects(l_object).lines(l_line_no).covered_blocks;
238-
l_result_profiler_enrich.objects(l_object).lines(l_line_no).no_blocks := l_result_block.objects(l_object).lines(l_line_no).no_blocks;
239-
-- enrich object level stats
240-
l_result_profiler_enrich.objects(l_object).partcovered_lines := nvl(l_result_profiler_enrich.objects(l_object).partcovered_lines,0) + l_result_block.objects(l_object).lines(l_line_no).partcove;
219+
ut_event_manager.trigger_event('profiler coverage data retrieved');
220+
221+
-- If block coverage available we will use it.
222+
$if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then
223+
l_result_block := ut_coverage_block.get_coverage_data( a_coverage_options, get_coverage_id(gc_block_coverage) );
224+
ut_event_manager.trigger_event('block coverage data retrieved');
225+
226+
-- Enrich profiler results with some of the block results
227+
l_object := l_result_profiler_enrich.objects.first;
228+
while (l_object is not null) loop
229+
230+
l_line_no := l_result_profiler_enrich.objects(l_object).lines.first;
231+
232+
-- to avoid no data found check if we got object in profiler
233+
if l_result_block.objects.exists(l_object) then
234+
while (l_line_no is not null) loop
235+
-- To avoid no data check for object line
236+
if l_result_block.objects(l_object).lines.exists(l_line_no) then
237+
-- enrich line level stats
238+
l_result_profiler_enrich.objects(l_object).lines(l_line_no).partcove := l_result_block.objects(l_object).lines(l_line_no).partcove;
239+
l_result_profiler_enrich.objects(l_object).lines(l_line_no).covered_blocks := l_result_block.objects(l_object).lines(l_line_no).covered_blocks;
240+
l_result_profiler_enrich.objects(l_object).lines(l_line_no).no_blocks := l_result_block.objects(l_object).lines(l_line_no).no_blocks;
241+
-- enrich object level stats
242+
l_result_profiler_enrich.objects(l_object).partcovered_lines := nvl(l_result_profiler_enrich.objects(l_object).partcovered_lines,0) + l_result_block.objects(l_object).lines(l_line_no).partcove;
243+
end if;
244+
--At the end go to next line
245+
l_line_no := l_result_profiler_enrich.objects(l_object).lines.next(l_line_no);
246+
end loop;
247+
--total level stats enrich
248+
l_result_profiler_enrich.partcovered_lines := nvl(l_result_profiler_enrich.partcovered_lines,0) + l_result_profiler_enrich.objects(l_object).partcovered_lines;
249+
-- At the end go to next object
241250
end if;
242-
--At the end go to next line
243-
l_line_no := l_result_profiler_enrich.objects(l_object).lines.next(l_line_no);
244-
end loop;
245-
--total level stats enrich
246-
l_result_profiler_enrich.partcovered_lines := nvl(l_result_profiler_enrich.partcovered_lines,0) + l_result_profiler_enrich.objects(l_object).partcovered_lines;
247-
-- At the end go to next object
248-
end if;
249-
250-
l_object := l_result_profiler_enrich.objects.next(l_object);
251-
252-
end loop;
253-
$end
251+
252+
l_object := l_result_profiler_enrich.objects.next(l_object);
253+
end loop;
254+
ut_event_manager.trigger_event('coverage data combined');
255+
$end
254256

255257
return l_result_profiler_enrich;
256258
end get_coverage_data;

source/core/events/ut_event_item.tps

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,5 @@ create or replace type ut_event_item authid current_user as object (
2121
* The true abstract type is ut_suite_item
2222
*/
2323
self_type varchar2(250 byte)
24-
2524
) not final not instantiable
2625
/

source/core/events/ut_event_manager.pkb

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,30 @@ create or replace package body ut_event_manager as
5757
end if;
5858
end;
5959

60-
procedure trigger_event( a_event_name t_event_name, a_event_object ut_event_item ) is
61-
begin
62-
if a_event_name is not null and g_event_listeners_index.exists(a_event_name)
63-
then
64-
for listener_number in 1 .. g_event_listeners_index(a_event_name).count loop
65-
g_listeners(listener_number).on_event(a_event_name, a_event_object);
60+
procedure trigger_event( a_event_name t_event_name, a_event_object ut_event_item := null ) is
61+
62+
procedure trigger_listener_event(
63+
a_listener_numbers t_listener_numbers,
64+
a_event_name t_event_name,
65+
a_event_object ut_event_item
66+
) is
67+
l_listener_number t_listener_number := a_listener_numbers.first;
68+
begin
69+
while l_listener_number is not null loop
70+
g_listeners(l_listener_number).on_event(a_event_name, a_event_object);
71+
l_listener_number := a_listener_numbers.next(l_listener_number);
6672
end loop;
73+
end;
74+
begin
75+
if a_event_name is not null then
76+
if g_event_listeners_index.exists(gc_all) then
77+
trigger_listener_event( g_event_listeners_index(gc_all), a_event_name, a_event_object );
78+
end if;
79+
if g_event_listeners_index.exists(a_event_name) then
80+
trigger_listener_event( g_event_listeners_index(a_event_name), a_event_name, a_event_object );
81+
end if;
6782
if a_event_name = ut_event_manager.gc_finalize then
68-
dispose_listeners;
83+
dispose_listeners();
6984
end if;
7085
end if;
7186
end;
@@ -78,7 +93,7 @@ create or replace package body ut_event_manager as
7893
procedure add_events( a_event_names ut_varchar2_list, a_listener_pos binary_integer ) is
7994
begin
8095
for i in 1 .. a_event_names.count loop
81-
add_event(a_event_names(i), a_listener_pos);
96+
add_event( a_event_names(i), a_listener_pos );
8297
end loop;
8398
end;
8499

@@ -98,10 +113,9 @@ create or replace package body ut_event_manager as
98113
if a_listener is not null then
99114
l_event_names := a_listener.get_supported_events();
100115
if l_event_names is not empty then
101-
add_events( l_event_names, add_listener(a_listener ) );
116+
add_events( l_event_names, add_listener( a_listener ) );
102117
end if;
103118
end if;
104-
105119
end;
106120

107121
end;

source/core/events/ut_event_manager.pks

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ create or replace package ut_event_manager authid current_user as
1818
/* Constants: Event names */
1919
subtype t_event_name is varchar2(250);
2020

21+
--capture all events
22+
gc_all constant t_event_name := 'all';
23+
24+
gc_debug constant t_event_name := 'debug';
25+
2126
gc_initialize constant t_event_name := 'initialize';
2227

2328
gc_before_run constant t_event_name := 'before_run';
@@ -51,7 +56,7 @@ create or replace package ut_event_manager authid current_user as
5156

5257
gc_finalize constant t_event_name := 'finalize';
5358

54-
procedure trigger_event( a_event_name t_event_name, a_event_object ut_event_item );
59+
procedure trigger_event( a_event_name t_event_name, a_event_object ut_event_item := null );
5560

5661
procedure initialize;
5762

source/core/output_buffers/ut_output_table_buffer.tpb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ create or replace type body ut_output_table_buffer is
8383
l_finished_flags ut_integer_list;
8484
l_already_waited_for number(10,2) := 0;
8585
l_finished boolean := false;
86-
lc_init_wait_sec constant naturaln := coalesce(a_initial_timeout, 15 ); -- 15 seconds
86+
lc_init_wait_sec constant naturaln := coalesce(a_initial_timeout, 60 ); -- 1 minute
8787
lc_max_wait_sec constant naturaln := coalesce(a_timeout_sec, 60 * 60 * 4); -- 4 hours
8888
l_wait_for integer := lc_init_wait_sec;
8989
lc_short_sleep_time constant number(1,1) := 0.1; --sleep for 100 ms between checks

source/core/types/ut_expectation_result.tpb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ create or replace type body ut_expectation_result is
2121
a_description varchar2, a_message clob, a_include_caller_info boolean := true
2222
) return self as result is
2323
begin
24+
self.self_type := $$plsql_unit;
2425
self.status := a_status;
2526
self.description := a_description;
2627
self.message := a_message;

source/core/types/ut_expectation_result.tps

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
create or replace type ut_expectation_result authid current_user as object(
1+
create or replace type ut_expectation_result under ut_event_item(
22
/*
33
utPLSQL - Version 3
44
Copyright 2016 - 2018 utPLSQL Project

0 commit comments

Comments
 (0)