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

Skip to content

Commit a6de86f

Browse files
committed
Added reporting of procedures that caused broke savepoints.
1 parent 934890b commit a6de86f

10 files changed

Lines changed: 84 additions & 53 deletions

source/core/types/ut_executable.tpb

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ create or replace type body ut_executable is
6666
end do_execute;
6767

6868
member function do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item, a_listener in out nocopy ut_event_listener_base) return boolean is
69-
l_statement varchar2(4000);
70-
l_status number;
71-
l_cursor_number number;
72-
l_owner varchar2(200) := self.owner_name;
73-
l_object_name varchar2(200) := self.object_name;
74-
l_procedure_name varchar2(200) := self.procedure_name;
69+
l_statement varchar2(4000);
70+
l_status number;
71+
l_cursor_number number;
72+
l_owner varchar2(200) := self.owner_name;
73+
l_object_name varchar2(200) := self.object_name;
74+
l_procedure_name varchar2(200) := self.procedure_name;
7575

7676
l_completed_without_errors boolean := true;
77-
77+
l_start_transaction_id varchar2(250);
7878
procedure save_dbms_output is
7979
l_status number;
8080
l_line varchar2(32767);
@@ -94,6 +94,7 @@ create or replace type body ut_executable is
9494
end save_dbms_output;
9595
begin
9696
if self.is_defined() then
97+
l_start_transaction_id := dbms_transaction.local_transaction_id(true);
9798
--listener - before call to executable
9899
a_listener.fire_before_event(self.associated_event_name, a_item);
99100

@@ -135,9 +136,14 @@ create or replace type body ut_executable is
135136

136137
l_completed_without_errors := (self.error_stack||self.error_backtrace) is null;
137138

138-
a_listener.fire_after_event(self.associated_event_name, a_item);
139139
--listener - after call to executable
140+
a_listener.fire_after_event(self.associated_event_name, a_item);
141+
142+
if l_start_transaction_id != dbms_transaction.local_transaction_id(true) then
143+
a_item.add_transaction_invalidator(self.form_name());
144+
end if;
140145
end if;
146+
141147
return l_completed_without_errors;
142148
end do_execute;
143149

source/core/types/ut_logical_suite.tpb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,19 @@ create or replace type body ut_logical_suite as
115115
return null;
116116
end;
117117

118+
overriding member function get_transaction_invalidators return ut_varchar2_list is
119+
l_result ut_varchar2_list;
120+
l_child_results ut_varchar2_list;
121+
begin
122+
l_result := self.transaction_invalidators;
123+
for i in 1 .. self.items.count loop
124+
l_child_results := self.items(i).get_transaction_invalidators();
125+
for j in 1 .. l_child_results.count loop
126+
l_result.extend; l_result(l_result.last) := l_child_results(j);
127+
end loop;
128+
end loop;
129+
return l_result;
130+
end;
131+
118132
end;
119133
/

source/core/types/ut_logical_suite.tps

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ create or replace type ut_logical_suite under ut_suite_item (
3333
overriding member function do_execute(self in out nocopy ut_logical_suite, a_listener in out nocopy ut_event_listener_base) return boolean,
3434
overriding member procedure calc_execution_result(self in out nocopy ut_logical_suite),
3535
overriding member procedure mark_as_errored(self in out nocopy ut_logical_suite, a_listener in out nocopy ut_event_listener_base, a_error_stack_trace varchar2),
36-
overriding member function get_error_stack_traces return ut_varchar2_list,
37-
overriding member function get_serveroutputs return clob
36+
overriding member function get_error_stack_traces return ut_varchar2_list,
37+
overriding member function get_serveroutputs return clob,
38+
overriding member function get_transaction_invalidators return ut_varchar2_list
3839
) not final
3940
/

source/core/types/ut_results_counter.tpb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,12 @@ create or replace type body ut_results_counter as
2525
return;
2626
end;
2727

28-
constructor function ut_results_counter(self in out nocopy ut_results_counter, a_status integer) return self as result is
28+
member procedure set_counter_values(self in out nocopy ut_results_counter, a_status integer) is
2929
begin
3030
self.disabled_count := case when a_status = ut_utils.tr_disabled then 1 else 0 end;
3131
self.success_count := case when a_status = ut_utils.tr_success then 1 else 0 end;
3232
self.failure_count := case when a_status = ut_utils.tr_failure then 1 else 0 end;
3333
self.errored_count := case when a_status = ut_utils.tr_error then 1 else 0 end;
34-
self.warnings_count := 0;
35-
return;
3634
end;
3735

3836
member procedure sum_counter_values(self in out nocopy ut_results_counter, a_item ut_results_counter) is

source/core/types/ut_results_counter.tps

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ create or replace type ut_results_counter as object(
2121
errored_count integer,
2222
warnings_count integer,
2323
constructor function ut_results_counter(self in out nocopy ut_results_counter) return self as result,
24-
constructor function ut_results_counter(self in out nocopy ut_results_counter, a_status integer) return self as result,
24+
member procedure set_counter_values(self in out nocopy ut_results_counter, a_status integer),
2525
member procedure sum_counter_values(self in out nocopy ut_results_counter, a_item ut_results_counter),
2626
member procedure increase_warning_count(self in out nocopy ut_results_counter),
2727
member function total_count return integer,

source/core/types/ut_suite_item.tpb

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ create or replace type body ut_suite_item as
22
/*
33
utPLSQL - Version X.X.X.X
44
Copyright 2016 - 2017 utPLSQL Project
5-
5+
66
Licensed under the Apache License, Version 2.0 (the "License"):
77
you may not use this file except in compliance with the License.
88
You may obtain a copy of the License at
9-
9+
1010
http://www.apache.org/licenses/LICENSE-2.0
11-
11+
1212
Unless required by applicable law or agreed to in writing, software
1313
distributed under the License is distributed on an "AS IS" BASIS,
1414
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,6 +27,7 @@ create or replace type body ut_suite_item as
2727
self.disabled_flag := ut_utils.boolean_to_int(a_disabled_flag);
2828
self.results_count := ut_results_counter();
2929
self.warnings := ut_varchar2_list();
30+
self.transaction_invalidators := ut_varchar2_list();
3031
end;
3132

3233
member procedure set_disabled_flag(self in out nocopy ut_suite_item, a_disabled_flag boolean) is
@@ -64,11 +65,13 @@ create or replace type body ut_suite_item as
6465
end if;
6566
exception
6667
when ex_savepoint_not_exists then
67-
put_warning('Unable to perform automatic rollback after ' || case self_type when 'UT_TEST' then 'test' when
68-
'UT_LOGICAL_SUITE' then 'test suite' when 'UT_SUITE' then 'test suite'
69-
end || ': ' || self.path || '
70-
An implicit or explicit commit/rollback occurred.
71-
Use the %rollback(manual) annotation or remove commits/rollback/ddl statements that are causing the issue.');
68+
put_warning(
69+
'Unable to perform automatic rollback after test'
70+
|| case when self_type like '%SUITE' then ' suite' end || '. '
71+
||'An implicit or explicit commit/rollback occurred in procedures:'||chr(10)
72+
||lower(ut_utils.indent_lines(ut_utils.table_to_clob(self.get_transaction_invalidators()), 2, true))||chr(10)
73+
||'Use the "--%rollback(manual)" annotation or remove commit/rollback/ddl statements that are causing the issue.'
74+
);
7275
end;
7376

7477
member function execution_time return number is
@@ -83,5 +86,16 @@ Use the %rollback(manual) annotation or remove commits/rollback/ddl statements t
8386
self.results_count.increase_warning_count;
8487
end;
8588

89+
member function get_transaction_invalidators return ut_varchar2_list is
90+
begin
91+
return transaction_invalidators;
92+
end;
93+
94+
final member procedure add_transaction_invalidator(a_object_name varchar2) is
95+
begin
96+
transaction_invalidators.extend();
97+
transaction_invalidators(transaction_invalidators.last) := a_object_name;
98+
end;
99+
86100
end;
87101
/

source/core/types/ut_suite_item.tps

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@ create or replace type ut_suite_item force under ut_suite_item_base (
1717
*/
1818

1919
results_count ut_results_counter,
20+
transaction_invalidators ut_varchar2_list,
2021
member procedure init(
2122
self in out nocopy ut_suite_item, a_object_owner varchar2, a_object_name varchar2, a_name varchar2,
2223
a_description varchar2, a_path varchar2, a_rollback_type integer, a_disabled_flag boolean),
2324
member procedure set_disabled_flag(self in out nocopy ut_suite_item, a_disabled_flag boolean),
2425
member function get_disabled_flag return boolean,
2526
member function create_savepoint_if_needed return varchar2,
2627
member procedure rollback_to_savepoint(self in out nocopy ut_suite_item, a_savepoint varchar2),
28+
member function get_transaction_invalidators return ut_varchar2_list,
29+
final member procedure add_transaction_invalidator(a_object_name varchar2),
2730
/*
2831
Returns execution time in seconds (with miliseconds)
2932
*/

source/core/types/ut_test.tpb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ create or replace type body ut_test as
5858
if self.get_disabled_flag() then
5959
self.result := ut_utils.tr_disabled;
6060
ut_utils.debug_log('ut_test.execute - disabled');
61-
self.results_count := ut_results_counter(self.result);
61+
self.results_count.set_counter_values(self.result);
6262
self.end_time := self.start_time;
6363
else
6464
if self.is_valid() then
@@ -100,7 +100,7 @@ create or replace type body ut_test as
100100
end if;
101101
--expectation results need to be part of test results
102102
self.results := ut_expectation_processor.get_expectations_results();
103-
self.results_count := ut_results_counter(self.result);
103+
self.results_count.set_counter_values(self.result);
104104
end;
105105

106106
overriding member procedure mark_as_errored(self in out nocopy ut_test, a_listener in out nocopy ut_event_listener_base, a_error_stack_trace varchar2) is

source/reporters/ut_documentation_reporter.tpb

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ create or replace type body ut_documentation_reporter is
8888
l_warning_index pls_integer := 0;
8989
-- make all warning indexes uniformly indented
9090
c_warnings_lpad constant integer := length(to_char(a_run.results_count.warnings_count));
91-
91+
9292
procedure print_failure_for_expectation(a_expectation ut_expectation_result) is
9393
l_lines ut_varchar2_list;
9494
begin
@@ -144,14 +144,17 @@ create or replace type body ut_documentation_reporter is
144144
end if;
145145
end;
146146

147-
procedure print_item_warnings(a_item in ut_logical_suite) is
148-
l_suite ut_logical_suite;
147+
procedure print_item_warnings(a_item in ut_suite_item) is
148+
l_items ut_suite_items;
149149
begin
150-
for i in 1 .. a_item.items.count loop
151-
if a_item.items(i) is of(ut_logical_suite) then
152-
print_item_warnings(treat(a_item.items(i) as ut_logical_suite));
153-
end if;
154-
end loop;
150+
if a_item is of (ut_logical_suite) then
151+
l_items := treat(a_item as ut_logical_suite).items;
152+
for i in 1 .. l_items.count loop
153+
if l_items(i) is of(ut_suite_item) then
154+
print_item_warnings(l_items(i));
155+
end if;
156+
end loop;
157+
end if;
155158

156159
if a_item.warnings is not null and a_item.warnings.count > 0 then
157160
for i in 1 .. a_item.warnings.count loop
@@ -166,14 +169,13 @@ create or replace type body ut_documentation_reporter is
166169
end;
167170

168171
procedure print_warnings(a_run in ut_run) is
169-
l_suite ut_logical_suite;
170172
begin
171173
if a_run.results_count.warnings_count > 0 then
172174
self.print_text(' ');
173175
self.print_text('Warnings:');
174176
self.print_text(' ');
175177
for i in 1 .. a_run.items.count loop
176-
print_item_warnings(treat(a_run.items(i) as ut_logical_suite));
178+
print_item_warnings(treat(a_run.items(i) as ut_suite_item));
177179
end loop;
178180
end if;
179181
end;
@@ -182,7 +184,7 @@ create or replace type body ut_documentation_reporter is
182184
print_failures_details(a_run);
183185
print_warnings(a_run);
184186
self.print_text('Finished in ' || a_run.execution_time || ' seconds');
185-
187+
186188
l_summary_text :=
187189
a_run.results_count.total_count || ' tests, '
188190
|| a_run.results_count.failure_count || ' failed, ' || a_run.results_count.errored_count || ' errored, '

tests/ut_test/ut_test.ReportWarningOnRollbackFailed.sql

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
create or replace package ut_output_test_rollback
22
as
33
--%suite
4-
4+
55
--%test
66
procedure tt;
7-
7+
88
end;
99
/
1010

@@ -20,29 +20,22 @@ end;
2020
/
2121

2222
declare
23-
l_output_data dbms_output.chararr;
24-
l_num_lines integer := 100000;
25-
l_output clob;
23+
l_lines ut_varchar2_list;
24+
l_results clob;
2625
begin
2726
--act
28-
ut.run('ut_output_test_rollback');
27+
select * bulk collect into l_lines from table(ut.run('ut_output_test_rollback'));
28+
29+
l_results := ut_utils.table_to_clob(l_lines);
2930

3031
--assert
31-
dbms_output.get_lines( l_output_data, l_num_lines);
32-
dbms_lob.createtemporary(l_output,true);
33-
for i in 1 .. l_num_lines loop
34-
dbms_lob.append(l_output,l_output_data(i));
35-
end loop;
36-
37-
if l_output like '%Warnings:%Unable to perform automatic rollback after test suite: ut_output_test_rollback%
32+
if l_results like '%Warnings:%Unable to perform automatic rollback after test suite: ut_output_test_rollback%
3833
An implicit or explicit commit/rollback occurred.%
3934
Use the %rollback(manual) annotation or remove commits/rollback/ddl statements that are causing the issue.%0 disabled, 1 warning(s)%' then
4035
:test_result := ut_utils.tr_success;
41-
end if;
42-
43-
if :test_result != ut_utils.tr_success or :test_result is null then
44-
for i in 1 .. l_num_lines loop
45-
dbms_output.put_line(l_output_data(i));
36+
else
37+
for i in 1 .. l_lines.count loop
38+
dbms_output.put_line(l_lines(i));
4639
end loop;
4740
dbms_output.put_line('Failed: Wrong output');
4841
end if;

0 commit comments

Comments
 (0)