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

Skip to content

Commit 58706b9

Browse files
committed
Simple auto/manual transaction control implementation
1 parent edfae1a commit 58706b9

8 files changed

Lines changed: 112 additions & 17 deletions

File tree

source/types/ut_test.tpb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
create or replace type body ut_test is
22

3-
constructor function ut_test(a_object_name varchar2, a_test_procedure varchar2, a_test_name in varchar2 default null, a_owner_name varchar2 default null, a_setup_procedure varchar2 default null, a_teardown_procedure varchar2 default null)
3+
constructor function ut_test(a_object_name varchar2, a_test_procedure varchar2, a_test_name in varchar2 default null, a_owner_name varchar2 default null, a_setup_procedure varchar2 default null, a_teardown_procedure varchar2 default null, a_rollback_type integer default null)
44
return self as result is
55
begin
66
self.name := a_test_name;
@@ -21,6 +21,16 @@ create or replace type body ut_test is
2121
,procedure_name => trim(a_teardown_procedure)
2222
,owner_name => trim(a_owner_name));
2323
end if;
24+
25+
if a_rollback_type is not null then
26+
if a_rollback_type in (ut_utils.gc_rollback_auto, ut_utils.gc_rollback_on_error, ut_utils.gc_rollback_manual) then
27+
self.rollback_type := a_rollback_type;
28+
else
29+
raise_application_error(-20200,'Rollback type is not supported');
30+
end if;
31+
else
32+
self.rollback_type := ut_utils.gc_rollback_auto;
33+
end if;
2434
return;
2535
end ut_test;
2636

@@ -37,15 +47,22 @@ create or replace type body ut_test is
3747
end;
3848
overriding member function execute(self in out nocopy ut_test, a_reporter ut_reporter) return ut_reporter is
3949
l_reporter ut_reporter := a_reporter;
50+
l_savepoint varchar2(30);
4051
begin
4152
l_reporter.before_test(self);
53+
54+
if self.rollback_type = ut_utils.gc_rollback_auto then
55+
l_savepoint := ut_utils.gen_savepoint_name;
56+
execute immediate 'savepoint '||l_savepoint;
57+
end if;
4258

4359
begin
4460
ut_utils.debug_log('ut_test.execute');
4561

4662
self.start_time := current_timestamp;
4763

4864
if self.is_valid() then
65+
4966
if self.setup is not null then
5067
l_reporter.before_test_setup(self);
5168
self.setup.execute;
@@ -54,7 +71,6 @@ create or replace type body ut_test is
5471

5572
l_reporter.before_test_execute(self);
5673
begin
57-
5874
self.test.execute;
5975
exception
6076
when others then
@@ -72,6 +88,8 @@ create or replace type body ut_test is
7288
self.teardown.execute;
7389
l_reporter.after_test_teardown(self);
7490
end if;
91+
92+
7593
end if;
7694

7795
exception
@@ -85,6 +103,10 @@ create or replace type body ut_test is
85103
ut_assert.report_error(sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_stack);
86104
ut_assert.report_error(sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_backtrace);
87105
end;
106+
107+
if self.rollback_type = ut_utils.gc_rollback_auto then
108+
execute immediate 'rollback to '||l_savepoint;
109+
end if;
88110

89111
self.end_time := current_timestamp;
90112

source/types/ut_test.tps

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ create or replace type ut_test force under ut_test_object
44
test ut_executable,
55
teardown ut_executable,
66

7-
constructor function ut_test(a_object_name varchar2, a_test_procedure varchar2, a_test_name in varchar2 default null, a_owner_name varchar2 default null, a_setup_procedure varchar2 default null, a_teardown_procedure varchar2 default null)
7+
constructor function ut_test(a_object_name varchar2, a_test_procedure varchar2, a_test_name in varchar2 default null, a_owner_name varchar2 default null, a_setup_procedure varchar2 default null, a_teardown_procedure varchar2 default null, a_rollback_type integer default null)
88
return self as result,
99

1010
member function is_valid return boolean,

source/types/ut_test_object.tps

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ create or replace type ut_test_object force under ut_composite_object
33
start_time timestamp with time zone,
44
end_time timestamp with time zone,
55
object_name varchar2(4000),
6+
rollback_type integer(1), -- ut_tils:gc_rollback_% constants
67
not instantiable member procedure execute(self in out nocopy ut_test_object, a_reporter ut_reporter),
78
not instantiable member function execute(self in out nocopy ut_test_object, a_reporter ut_reporter)
89
return ut_reporter,

source/types/ut_test_suite.tpb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
create or replace type body ut_test_suite is
22

3-
constructor function ut_test_suite(a_suite_name varchar2, a_object_name varchar2 default null, a_items ut_objects_list default ut_objects_list())
3+
constructor function ut_test_suite(a_suite_name varchar2, a_object_name varchar2 default null, a_items ut_objects_list default ut_objects_list(), a_rollback_type number default null)
44
return self as result is
55
begin
66
self.name := a_suite_name;
77
self.object_type := 2;
88
self.items := a_items;
99
self.object_name := lower(trim(a_object_name));
10+
11+
if a_rollback_type is not null then
12+
if a_rollback_type in (ut_utils.gc_rollback_auto, ut_utils.gc_rollback_on_error, ut_utils.gc_rollback_manual) then
13+
self.rollback_type := a_rollback_type;
14+
else
15+
raise_application_error(-20200,'Rollback type is not supported');
16+
end if;
17+
else
18+
self.rollback_type := ut_utils.gc_rollback_auto;
19+
end if;
20+
1021
return;
1122
end ut_test_suite;
1223

@@ -43,6 +54,7 @@ create or replace type body ut_test_suite is
4354
return ut_reporter is
4455
l_reporter ut_reporter := a_reporter;
4556
l_test_object ut_test_object;
57+
l_savepoint varchar2(30);
4658
begin
4759
l_reporter.before_suite(self);
4860

@@ -51,6 +63,11 @@ create or replace type body ut_test_suite is
5163
self.start_time := current_timestamp;
5264

5365
if self.is_valid() then
66+
67+
if self.rollback_type = ut_utils.gc_rollback_auto then
68+
l_savepoint := ut_utils.gen_savepoint_name;
69+
execute immediate 'savepoint '||l_savepoint;
70+
end if;
5471

5572
if self.setup is not null then
5673
l_reporter.before_suite_setup(self);
@@ -75,6 +92,10 @@ create or replace type body ut_test_suite is
7592
end if;
7693

7794
self.calc_execution_result;
95+
96+
if self.rollback_type = ut_utils.gc_rollback_auto then
97+
execute immediate 'rollback to '||l_savepoint;
98+
end if;
7899
else
79100
self.result := ut_utils.tr_error;
80101
end if;

source/types/ut_test_suite.tps

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ create or replace type ut_test_suite force under ut_test_object
44
setup ut_executable,
55
teardown ut_executable,
66

7-
constructor function ut_test_suite(a_suite_name varchar2, a_object_name varchar2 default null, a_items ut_objects_list default ut_objects_list())
7+
constructor function ut_test_suite(a_suite_name varchar2, a_object_name varchar2 default null, a_items ut_objects_list default ut_objects_list(), a_rollback_type number default null)
88
return self as result,
99

1010
member procedure set_suite_setup(self in out nocopy ut_test_suite, a_object_name in varchar2, a_proc_name in varchar2, a_owner_name varchar2 default null),

source/ut_suite_manager.pkb

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ create or replace package body ut_suite_manager is
2323
l_owner_name varchar2(32 char);
2424
l_object_name varchar2(32 char);
2525
l_suite ut_test_suite;
26+
27+
l_suite_rollback integer;
28+
l_suite_rollback_annotation varchar2(4000);
2629

2730
begin
2831
l_owner_name := a_owner_name;
@@ -41,8 +44,24 @@ create or replace package body ut_suite_manager is
4144
else
4245
l_suite_package := lower(l_object_name);
4346
end if;
47+
48+
if l_annotation_data.package_annotations.exists('rollback') then
49+
l_suite_rollback_annotation := ut_annotations.get_annotation_param(l_annotation_data.package_annotations('rollback'), 1);
50+
l_suite_rollback := case lower(l_suite_rollback_annotation)
51+
when 'manual' then
52+
ut_utils.gc_rollback_manual
53+
when 'auto' then
54+
ut_utils.gc_rollback_auto
55+
--when 'on-error' then
56+
-- ut_utils.gc_rollback_on_error
57+
else
58+
ut_utils.gc_rollback_auto
59+
end;
60+
else
61+
l_suite_rollback := ut_utils.gc_rollback_auto;
62+
end if;
4463

45-
l_suite := ut_test_suite(l_suite_name, l_suite_package);
64+
l_suite := ut_test_suite(l_suite_name, l_suite_package, a_rollback_type => l_suite_rollback);
4665

4766
l_proc_name := l_annotation_data.procedure_annotations.first;
4867
while (l_default_setup_proc is null or l_default_teardown_proc is null or l_suite_setup_proc is null or
@@ -76,32 +95,49 @@ create or replace package body ut_suite_manager is
7695

7796
l_proc_name := l_annotation_data.procedure_annotations.first;
7897
while l_proc_name is not null loop
79-
declare
80-
l_setup_procedure varchar2(30 char);
81-
l_teardown_procedure varchar2(30 char);
82-
begin
83-
l_proc_annotations := l_annotation_data.procedure_annotations(l_proc_name);
84-
85-
if l_proc_annotations.exists('test') then
98+
99+
l_proc_annotations := l_annotation_data.procedure_annotations(l_proc_name);
100+
if l_proc_annotations.exists('test') then
101+
declare
102+
l_setup_procedure varchar2(30 char);
103+
l_teardown_procedure varchar2(30 char);
104+
l_rollback_annotation varchar2(4000);
105+
l_rollback_type integer := ut_utils.gc_rollback_auto;
106+
begin
86107
if l_proc_annotations.exists('testsetup') then
87108
l_setup_procedure := ut_annotations.get_annotation_param(l_proc_annotations('testsetup'), 1);
88109
end if;
89110

90111
if l_proc_annotations.exists('testteardown') then
91112
l_teardown_procedure := ut_annotations.get_annotation_param(l_proc_annotations('testteardown'), 1);
92113
end if;
114+
115+
if l_proc_annotations.exists('rollback') then
116+
l_rollback_annotation := ut_annotations.get_annotation_param(l_proc_annotations('rollback'), 1);
117+
l_rollback_type := case lower(l_rollback_annotation)
118+
when 'manual' then
119+
ut_utils.gc_rollback_manual
120+
when 'auto' then
121+
ut_utils.gc_rollback_auto
122+
--when 'on-error' then
123+
-- ut_utils.gc_rollback_on_error
124+
else
125+
l_suite_rollback
126+
end;
127+
end if;
93128

94129
l_test := ut_test(a_object_name => l_object_name
95130
,a_test_procedure => l_proc_name
96131
,a_test_name => ut_annotations.get_annotation_param(l_proc_annotations('test'), 1)
97132
,a_owner_name => l_owner_name
98133
,a_setup_procedure => nvl(l_setup_procedure, l_default_setup_proc)
99-
,a_teardown_procedure => nvl(l_teardown_procedure, l_default_teardown_proc));
134+
,a_teardown_procedure => nvl(l_teardown_procedure, l_default_teardown_proc)
135+
,a_rollback_type => l_rollback_type);
100136

101137
l_suite.add_item(l_test);
102-
end if;
103-
104-
end;
138+
end;
139+
end if;
140+
105141
l_proc_name := l_annotation_data.procedure_annotations.next(l_proc_name);
106142
end loop;
107143
end if;

source/ut_utils.pkb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ create or replace package body ut_utils is
1818
else tr_failure
1919
end;
2020
end;
21+
22+
function gen_savepoint_name return varchar2 is
23+
begin
24+
return 'ut_'||to_char(systimestamp,'yymmddhh24mmssff');
25+
end;
2126

2227
procedure debug_log(a_message varchar2) is
2328
begin

source/ut_utils.pks

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ create or replace package ut_utils is
1818
tr_success_char constant varchar2(7) := 'Success'; -- test passed
1919
tr_failure_char constant varchar2(7) := 'Failure'; -- one or more asserts failed
2020
tr_error_char constant varchar2(5) := 'Error'; -- exception was raised
21+
22+
/*
23+
Constants: Rollback type for ut_test_object
24+
*/
25+
gc_rollback_auto constant number(1) := 0; -- rollback after each test and suite
26+
gc_rollback_manual constant number(1) := 1; -- leave transaction control manual
27+
--gc_rollback_on_error constant number(1) := 2; -- rollback tests only on error
28+
2129

2230
gc_max_sring_length constant integer := 4000;
2331
gc_more_data_string constant varchar2(5) := '[...]';
@@ -39,6 +47,8 @@ create or replace package ut_utils is
3947
function test_result_to_char(a_test_result integer) return varchar2;
4048

4149
function to_test_result(a_test boolean) return integer;
50+
51+
function gen_savepoint_name return varchar2;
4252

4353
procedure debug_log(a_message varchar2);
4454

0 commit comments

Comments
 (0)