Skip to content

Commit fee6576

Browse files
committed
Fixed some of the clunky coverage options behavior.
Moved logic spread across `ut_runner.run`, `ut_run` into one place. Added replace of '\' with '/' when matching files to objects and simplified regex for file mapping. Significant updates to coverage documentation.
1 parent cbe31e5 commit fee6576

11 files changed

Lines changed: 449 additions & 164 deletions

File tree

docs/userguide/coverage.md

Lines changed: 306 additions & 55 deletions
Large diffs are not rendered by default.

source/api/ut_runner.pkb

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,23 @@ create or replace package body ut_runner is
2020
/**
2121
* Private functions
2222
*/
23-
function to_ut_object_list(a_names ut_varchar2_list) return ut_object_names is
24-
l_result ut_object_names;
23+
function to_ut_object_list(a_names ut_varchar2_list, a_schema_names ut_varchar2_rows) return ut_object_names is
24+
l_result ut_object_names;
25+
l_object_name ut_object_name;
2526
begin
26-
if a_names is not null then
27+
if a_names is not empty then
2728
l_result := ut_object_names();
2829
for i in 1 .. a_names.count loop
29-
l_result.extend;
30-
l_result(l_result.last) := ut_object_name(a_names(i));
30+
l_object_name := ut_object_name(a_names(i));
31+
if l_object_name.owner is null then
32+
for i in 1 .. cardinality(a_schema_names) loop
33+
l_result.extend;
34+
l_result(l_result.last) := ut_object_name(a_schema_names(i)||'.'||l_object_name.name);
35+
end loop;
36+
else
37+
l_result.extend;
38+
l_result(l_result.last) := l_object_name;
39+
end if;
3140
end loop;
3241
end if;
3342
return l_result;
@@ -71,6 +80,9 @@ create or replace package body ut_runner is
7180
) is
7281
l_items_to_run ut_run;
7382
l_listener ut_event_listener;
83+
l_coverage_schema_names ut_varchar2_rows;
84+
l_exclude_object_names ut_object_names := ut_object_names();
85+
l_include_object_names ut_object_names;
7486
begin
7587
begin
7688
ut_expectation_processor.reset_invalidation_exception();
@@ -82,12 +94,27 @@ create or replace package body ut_runner is
8294
else
8395
l_listener := ut_event_listener(a_reporters);
8496
end if;
97+
98+
if a_coverage_schemes is not empty then
99+
l_coverage_schema_names := ut_utils.convert_collection(a_coverage_schemes);
100+
else
101+
l_coverage_schema_names := ut_suite_manager.get_schema_names(a_paths);
102+
end if;
103+
104+
if a_exclude_objects is not empty then
105+
l_exclude_object_names := to_ut_object_list(a_exclude_objects, l_coverage_schema_names);
106+
end if;
107+
108+
l_exclude_object_names := l_exclude_object_names multiset union all ut_suite_manager.get_schema_ut_packages(l_coverage_schema_names);
109+
110+
l_include_object_names := to_ut_object_list(a_include_objects, l_coverage_schema_names);
111+
85112
l_items_to_run := ut_run(
86113
ut_suite_manager.configure_execution_by_path(a_paths),
87114
a_paths,
88-
ut_utils.convert_collection(a_coverage_schemes),
89-
to_ut_object_list(a_exclude_objects),
90-
to_ut_object_list(a_include_objects),
115+
l_coverage_schema_names,
116+
l_exclude_object_names,
117+
l_include_object_names,
91118
set(a_source_file_mappings),
92119
set(a_test_file_mappings)
93120
);
@@ -144,38 +171,35 @@ create or replace package body ut_runner is
144171
return;
145172
end;
146173

147-
function get_reporters_list return tt_reporters_info pipelined
148-
AS
174+
function get_reporters_list return tt_reporters_info pipelined is
149175
l_cursor sys_refcursor;
150176
l_owner varchar2(128) := ut_utils.ut_owner();
151177
l_results tt_reporters_info;
152178
c_bulk_limit constant integer := 10;
153-
begin
154-
open l_cursor for 'SELECT
155-
owner || ''.'' || type_name,
156-
CASE
157-
WHEN sys_connect_by_path(owner
158-
|| ''.''
159-
|| type_name,'','') LIKE ''%' || l_owner || '''
160-
|| ''.UT_OUTPUT_REPORTER_BASE%'' THEN ''Y''
161-
ELSE ''N''
162-
END
163-
is_output_reporter
164-
FROM dba_types t
165-
WHERE instantiable = ''YES''
166-
CONNECT BY supertype_name = PRIOR type_name AND supertype_owner = PRIOR owner
167-
START WITH type_name = ''UT_REPORTER_BASE'' AND owner = '''|| l_owner || '''';
168-
loop
169-
fetch l_cursor bulk collect into l_results limit c_bulk_limit;
170-
for i in 1 .. l_results.count loop
171-
pipe row (l_results(i));
172-
end loop;
173-
exit when l_cursor%notfound;
179+
begin
180+
open l_cursor for 'SELECT
181+
owner || ''.'' || type_name,
182+
CASE
183+
WHEN sys_connect_by_path(owner
184+
|| ''.''
185+
|| type_name,'','') LIKE ''%' || l_owner || '''
186+
|| ''.UT_OUTPUT_REPORTER_BASE%'' THEN ''Y''
187+
ELSE ''N''
188+
END
189+
is_output_reporter
190+
FROM dba_types t
191+
WHERE instantiable = ''YES''
192+
CONNECT BY supertype_name = PRIOR type_name AND supertype_owner = PRIOR owner
193+
START WITH type_name = ''UT_REPORTER_BASE'' AND owner = '''|| l_owner || '''';
194+
loop
195+
fetch l_cursor bulk collect into l_results limit c_bulk_limit;
196+
for i in 1 .. l_results.count loop
197+
pipe row (l_results(i));
174198
end loop;
175-
close l_cursor;
176-
end;
177-
178-
199+
exit when l_cursor%notfound;
200+
end loop;
201+
close l_cursor;
202+
end;
179203

180204
end ut_runner;
181205
/

source/core/coverage/ut_coverage.pkb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,8 @@ create or replace package body ut_coverage is
9898
function get_cov_sources_cursor(a_coverage_options ut_coverage_options) return sys_refcursor is
9999
l_cursor sys_refcursor;
100100
l_skip_objects ut_object_names;
101-
l_schema_names ut_varchar2_rows;
102101
l_sql varchar2(32767);
103102
begin
104-
l_schema_names := coalesce(a_coverage_options.schema_names, ut_varchar2_rows(sys_context('USERENV','CURRENT_SCHEMA')));
105103
if not ut_coverage_helper.is_develop_mode() then
106104
--skip all the utplsql framework objects and all the unit test packages that could potentially be reported by coverage.
107105
l_skip_objects := ut_utils.get_utplsql_objects_list() multiset union all coalesce(a_coverage_options.exclude_objects, ut_object_names());
@@ -112,7 +110,7 @@ create or replace package body ut_coverage is
112110
elsif a_coverage_options.include_objects is not empty then
113111
open l_cursor for l_sql using a_coverage_options.include_objects, l_skip_objects;
114112
else
115-
open l_cursor for l_sql using l_schema_names, l_skip_objects;
113+
open l_cursor for l_sql using a_coverage_options.schema_names, l_skip_objects;
116114
end if;
117115
return l_cursor;
118116
end;

source/core/types/ut_object_name.tpb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ create or replace type body ut_object_name as
2424

2525
constructor function ut_object_name(self in out nocopy ut_object_name, a_unit_name varchar2) return self as result is
2626
begin
27-
self.owner := upper(regexp_substr(a_unit_name,'[^\.]+', 1, 1));
28-
self.name := upper(regexp_substr(a_unit_name,'[^\.]+', 1, 2));
27+
if instr(a_unit_name,'.') > 0 then
28+
self.owner := upper(regexp_substr(a_unit_name,'[^\.]+', 1, 1));
29+
self.name := upper(regexp_substr(a_unit_name,'[^\.]+', 1, 2));
30+
else
31+
self.name := upper(a_unit_name);
32+
end if;
2933
return;
3034
end;
3135

source/core/types/ut_run.tpb

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,14 @@ create or replace type body ut_run as
3030
l_coverage_options ut_coverage_options;
3131
l_exclude_objects ut_object_names;
3232
begin
33-
l_coverage_schema_names := coalesce(a_schema_names, get_run_schemes());
34-
l_exclude_objects := coalesce(a_exclude_objects,ut_object_names());
35-
3633
self.run_paths := a_run_paths;
3734
self.self_type := $$plsql_unit;
3835
self.items := a_items;
3936
self.results_count := ut_results_counter();
4037
self.test_file_mappings := coalesce(a_test_file_mappings, ut_file_mappings());
4138
self.coverage_options := ut_coverage_options(
42-
l_coverage_schema_names,
43-
l_exclude_objects multiset union all ut_suite_manager.get_schema_ut_packages(l_coverage_schema_names),
39+
a_schema_names,
40+
a_exclude_objects,
4441
a_include_objects,
4542
a_project_file_mappings
4643
);
@@ -110,42 +107,6 @@ create or replace type body ut_run as
110107
a_listener.fire_after_event(ut_utils.gc_run, self);
111108
end;
112109

113-
member function get_run_schemes return ut_varchar2_rows is
114-
l_schema varchar2(128);
115-
c_current_schema constant varchar2(128) := sys_context('USERENV','CURRENT_SCHEMA');
116-
l_path varchar2(32767);
117-
l_schemes ut_varchar2_rows;
118-
begin
119-
if run_paths is not null then
120-
l_schemes := ut_varchar2_rows();
121-
for i in 1 .. self.run_paths.count loop
122-
l_path := self.run_paths(i);
123-
if regexp_like(l_path, '^([A-Za-z0-9$#_]+)?:') then
124-
l_schema := regexp_substr(l_path, '^([A-Za-z0-9$#_]+)?:',subexpression => 1);
125-
if l_schema is not null then
126-
l_schema := sys.dbms_assert.schema_name(upper(l_schema));
127-
else
128-
l_schema := c_current_schema;
129-
end if;
130-
else
131-
begin
132-
l_schema := sys.dbms_assert.schema_name(upper(regexp_substr(l_path, '^[A-Za-z0-9$#_]+')));
133-
exception
134-
when sys.dbms_assert.invalid_schema_name then
135-
l_schema := c_current_schema;
136-
end;
137-
138-
end if;
139-
l_schemes.extend;
140-
l_schemes(l_schemes.last) := l_schema;
141-
end loop;
142-
else
143-
l_schemes := ut_varchar2_rows(c_current_schema);
144-
end if;
145-
return l_schemes;
146-
147-
end;
148-
149110
overriding member function get_error_stack_traces return ut_varchar2_list is
150111
begin
151112
return ut_varchar2_list();

source/core/types/ut_run.tps

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ create or replace type ut_run under ut_suite_item (
3737
overriding member function do_execute(self in out nocopy ut_run, a_listener in out nocopy ut_event_listener_base) return boolean,
3838
overriding member procedure calc_execution_result(self in out nocopy ut_run),
3939
overriding member procedure mark_as_errored(self in out nocopy ut_run, a_listener in out nocopy ut_event_listener_base, a_error_stack_trace varchar2),
40-
member function get_run_schemes return ut_varchar2_rows,
4140
overriding member function get_error_stack_traces return ut_varchar2_list,
4241
overriding member function get_serveroutputs return clob
4342
)

source/core/ut_file_mapper.pks

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ create or replace package ut_file_mapper authid current_user is
1616
limitations under the License.
1717
*/
1818

19-
gc_file_mapping_regex constant varchar2(100) := '.*/((\w+)\.)?(\w+)\.(\w{3})$';
19+
gc_file_mapping_regex constant varchar2(100) := '/((\w+)\.)?(\w+)\.(\w{3})$';
2020
gc_regex_owner_subexpression constant positive := 2;
2121
gc_regex_name_subexpression constant positive := 3;
2222
gc_regex_type_subexpression constant positive := 4;

source/core/ut_suite_manager.pkb

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,41 @@ create or replace package body ut_suite_manager is
129129
return l_schema_ut_packages;
130130
end;
131131

132-
procedure resolve_schema_names(a_paths in out nocopy ut_varchar2_list) is
132+
procedure validate_paths(a_paths in ut_varchar2_list) is
133+
l_path varchar2(32767);
134+
begin
135+
if a_paths is null or a_paths.count = 0 then
136+
raise_application_error(ut_utils.gc_path_list_is_empty, 'Path list is empty');
137+
else
138+
for i in 1 .. a_paths.count loop
139+
l_path := a_paths(i);
140+
if l_path is null or not (regexp_like(l_path, '^[A-Za-z0-9$#_]+(\.[A-Za-z0-9$#_]+){0,2}$') or regexp_like(l_path, '^([A-Za-z0-9$#_]+)?:[A-Za-z0-9$#_]+(\.[A-Za-z0-9$#_]+)*$')) then
141+
raise_application_error(ut_utils.gc_invalid_path_format, 'Invalid path format: ' || nvl(l_path, 'NULL'));
142+
end if;
143+
end loop;
144+
end if;
145+
end;
146+
147+
function clean_paths(a_paths ut_varchar2_list) return ut_varchar2_list is
148+
l_paths_temp ut_varchar2_list := ut_varchar2_list();
149+
begin
150+
l_paths_temp.extend(a_paths.count);
151+
for i in 1 .. a_paths.count loop
152+
l_paths_temp(i) := trim(lower(a_paths(i)));
153+
end loop;
154+
return l_paths_temp;
155+
end;
156+
157+
function resolve_schema_names(a_paths in out nocopy ut_varchar2_list) return ut_varchar2_rows is
133158
l_schema varchar2(4000);
134159
l_object varchar2(4000);
160+
l_schema_names ut_varchar2_rows := ut_varchar2_rows();
135161
c_current_schema constant all_tables.owner%type := sys_context('USERENV','CURRENT_SCHEMA');
136162
begin
163+
a_paths := set( clean_paths(a_paths) );
164+
165+
validate_paths(a_paths);
166+
137167
for i in 1 .. a_paths.count loop
138168
--if path is suite-path
139169
if regexp_like(a_paths(i), '^([A-Za-z0-9$#_]+)?:') then
@@ -144,7 +174,7 @@ create or replace package body ut_suite_manager is
144174
l_schema := sys.dbms_assert.schema_name(upper(l_schema));
145175
else
146176
a_paths(i) := c_current_schema || a_paths(i);
147-
l_schema := c_current_schema;
177+
l_schema := c_current_schema;
148178
end if;
149179
else
150180
-- get schema name / object.[procedure] name
@@ -163,32 +193,23 @@ create or replace package body ut_suite_manager is
163193
end if;
164194
end;
165195
end if;
196+
l_schema_names.extend;
197+
l_schema_names(l_schema_names.last) := l_schema;
166198
end loop;
199+
return l_schema_names;
167200
end;
168201

169-
procedure validate_paths(a_paths in ut_varchar2_list) is
170-
l_path varchar2(32767);
202+
procedure resolve_schema_names(a_paths in out nocopy ut_varchar2_list) is
203+
l_schema_names ut_varchar2_rows;
171204
begin
172-
if a_paths is null or a_paths.count = 0 then
173-
raise_application_error(ut_utils.gc_path_list_is_empty, 'Path list is empty');
174-
else
175-
for i in 1 .. a_paths.count loop
176-
l_path := a_paths(i);
177-
if l_path is null or not (regexp_like(l_path, '^[A-Za-z0-9$#_]+(\.[A-Za-z0-9$#_]+){0,2}$') or regexp_like(l_path, '^([A-Za-z0-9$#_]+)?:[A-Za-z0-9$#_]+(\.[A-Za-z0-9$#_]+)*$')) then
178-
raise_application_error(ut_utils.gc_invalid_path_format, 'Invalid path format: ' || nvl(l_path, 'NULL'));
179-
end if;
180-
end loop;
181-
end if;
205+
l_schema_names := resolve_schema_names(a_paths);
182206
end;
183207

184-
function clean_paths(a_paths ut_varchar2_list) return ut_varchar2_list is
185-
l_paths_temp ut_varchar2_list := ut_varchar2_list();
208+
function get_schema_names(a_paths ut_varchar2_list) return ut_varchar2_rows is
209+
l_paths ut_varchar2_list;
186210
begin
187-
l_paths_temp.extend(a_paths.count);
188-
for i in 1 .. a_paths.count loop
189-
l_paths_temp(i) := trim(lower(a_paths(i)));
190-
end loop;
191-
return l_paths_temp;
211+
l_paths := a_paths;
212+
return resolve_schema_names(l_paths);
192213
end;
193214

194215
procedure filter_suite_by_path(a_suite in out nocopy ut_suite_item, a_path varchar2) is
@@ -265,7 +286,7 @@ create or replace package body ut_suite_manager is
265286
end;
266287

267288
function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items is
268-
l_paths ut_varchar2_list;
289+
l_paths ut_varchar2_list := a_paths;
269290
l_path varchar2(32767);
270291
l_schema varchar2(4000);
271292
l_suites_info t_schema_suites_info;
@@ -274,10 +295,6 @@ create or replace package body ut_suite_manager is
274295
l_objects_to_run ut_suite_items;
275296
l_schema_paths t_schema_paths;
276297
begin
277-
l_paths := set( clean_paths(a_paths) );
278-
279-
validate_paths(l_paths);
280-
281298
--resolve schema names from paths and group paths by schema name
282299
resolve_schema_names(l_paths);
283300

source/core/ut_suite_manager.pks

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,11 @@ create or replace package ut_suite_manager authid current_user is
3939
*/
4040
function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items;
4141

42+
/**
43+
* Cleanup paths by removing leading/trailing whitespace and making paths lowercase
44+
* Get list of schema names from execution paths.
45+
*/
46+
function get_schema_names(a_paths ut_varchar2_list) return ut_varchar2_rows;
47+
4248
end ut_suite_manager;
4349
/

0 commit comments

Comments
 (0)