8000 Feature/improve coverage source query by jgebal · Pull Request #981 · utPLSQL/utPLSQL · GitHub
[go: up one dir, main page]

Skip to content

Feature/improve coverage source query #981

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 18, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Trying different approach to coverage gathering.
  • Loading branch information
jgebal committed Jul 16, 2019
commit abba642181ff9a94f48a913947e18acc3af934c5
167 changes: 125 additions & 42 deletions source/core/coverage/ut_coverage.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -36,32 +36,39 @@ create or replace package body ut_coverage is
end;

function get_cov_sources_sql(a_coverage_options ut_coverage_options) return varchar2 is
l_result varchar2(32767);
l_full_name varchar2(100);
l_view_name varchar2(200) := ut_metadata.get_source_view_name();
l_result varchar2(32767);
l_full_name varchar2(32767);
l_mappings varchar2(32767);
l_filters varchar2(32767);
l_mappings_cardinality integer := 0;
begin
if a_coverage_options.file_mappings is not null and a_coverage_options.file_mappings.count > 0 then
l_full_name := 'f.file_name';
else
l_full_name := 'lower(s.owner||''.''||s.name)';
end if;
l_result := '
select full_name, owner, name, line, to_be_skipped, text
from (
select '||l_full_name||q'[ as full_name,
l_result := q'[
with sources as (
select /*+ cardinality(f {mappings_cardinality}) */
{l_full_name} as full_name, s.owner, s.name, s.line, s.text
from {sources_view} s {file_mappings}
where s.type in ('PACKAGE BODY', 'TYPE BODY', 'PROCEDURE', 'FUNCTION')
{filters}
),
trigger_sources as (
select /*+ cardinality(f {mappings_cardinality}) */
{l_full_name} as full_name,
s.owner,
s.name,
s.line -
coalesce(
case when type!='TRIGGER' then 0 end,
(select min(t.line) - 1
from ]'||l_view_name||q'[ t
s.line
- (select min(t.line) - 1
from {sources_view} t
where t.owner = s.owner and t.type = s.type and t.name = s.name
and regexp_like( t.text, '[A-Za-z0-9$#_]*(begin|declare|compound).*','i'))
) as line,
s.text, ]';
l_result := l_result ||
q'[case
and regexp_like( t.text, '[A-Za-z0-9$#_]*(begin|declare|compound).*', 'i' )
) as line,
s.text
from {sources_view} s {file_mappings}
where s.type = 'TRIGGER'
{filters}
),
coverage_sources as (
select full_name, owner, name, line, text,
case
when
-- to avoid execution of regexp_like on every line
-- first do a rough check for existence of search pattern keyword
Expand All @@ -76,31 +83,107 @@ create or replace package body ut_coverage is
'^([\t ]*(((not)?\s*(overriding|final|instantiable)[\t ]*)*(static|constructor|member)?[\t ]*(procedure|function)|package([\t ]+body)|begin|end([\t ]+\S+)*[ \t]*;))', 'i'
)
then 'Y'
end as to_be_skipped ]';
end as to_be_skipped
from (
select * from sources
union all
select * from trigger_sources
) s
)
select full_name, owner, name, line, to_be_skipped, text
from coverage_sources s
--Exclude calls to utPLSQL framework, Unit Test packages and objects from a_exclude_list parameter of coverage reporter
where (s.owner, s.name) not in ( select el.owner, el.name from table(:l_skipped_objects) el )
and line > 0
]';

l_result := l_result ||' from '||l_view_name||q'[ s]';

if a_coverage_options.file_mappings is not empty then
l_result := l_result || '
l_mappings_cardinality := ut_utils.scale_cardinality(cardinality(a_coverage_options.file_mappings));
l_full_name := 'f.file_name';
l_mappings := '
join table(:file_mappings) f
on s.name = f.object_name
and s.type = f.object_type
and s.owner = f.object_owner
where 1 = 1';
elsif a_coverage_options.include_objects is not empty then
l_result := l_result || '
where (s.owner, s.name) in (select il.owner, il.name from table(:include_objects) il)';
and s.owner = f.object_owner';
else
l_result := l_result || '
where s.owner in (select upper(t.column_value) from table(:l_schema_names) t)';
l_full_name := q'[lower(s.owner||'.'||s.name)]';
l_filters := case
when a_coverage_options.include_objects is not empty then '
and (s.owner, s.name) in (select il.owner, il.name from table(:include_objects) il)'
else '
and s.owner in (select upper(t.column_value) from table(:l_schema_names) t)'
end;
end if;
l_result := l_result || q'[
and s.type not in ('PACKAGE', 'TYPE', 'JAVA SOURCE')
--Exclude calls to utPLSQL framework, Unit Test packages and objects from a_exclude_list parameter of coverage reporter
and (s.owner, s.name) not in (select el.owner, el.name from table(:l_skipped_objects) el)
)
where line > 0]';

l_result := replace(l_result, '{sources_view}', ut_metadata.get_source_view_name());
l_result := replace(l_result, '{l_full_name}', l_full_name);
l_result := replace(l_result, '{file_mappings}', l_mappings);
l_result := replace(l_result, '{filters}', l_filters);
l_result := replace(l_result, '{mappings_cardinality}', l_mappings_cardinality);

return l_result;

-- if a_coverage_options.file_mappings is not null and a_coverage_options.file_mappings.count > 0 then
-- l_full_name := 'f.file_name';
-- else
-- l_full_name := 'lower(s.owner||''.''||s.name)';
-- end if;
-- l_result := '
-- select full_name, owner, name, line, to_be_skipped, text
-- from (
-- select '||l_full_name||q'[ as full_name,
-- s.owner,
-- s.name,
-- s.line -
-- coalesce(
-- case when type!='TRIGGER' then 0 end,
-- (select min(t.line) - 1
-- from ]'||ut_metadata.get_source_view_name()||q'[ t
-- where t.owner = s.owner and t.type = s.type and t.name = s.name
-- and regexp_like( t.text, '[A-Za-z0-9$#_]*(begin|declare|compound).*','i'))
-- ) as line,
-- s.text, ]';
-- l_result := l_result ||
-- q'[case
-- when
-- -- to avoid execution of regexp_like on every line
-- -- first do a rough check for existence of search pattern keyword
-- (lower(s.text) like '%procedure%'
-- or lower(s.text) like '%function%'
-- or lower(s.text) like '%begin%'
-- or lower(s.text) like '%end%'
-- or lower(s.text) like '%package%'
-- ) and
-- regexp_like(
-- s.text,
-- '^([\t ]*(((not)?\s*(overriding|final|instantiable)[\t ]*)*(static|constructor|member)?[\t ]*(procedure|function)|package([\t ]+body)|begin|end([\t ]+\S+)*[ \t]*;))', 'i'
-- )
-- then 'Y'
-- end as to_be_skipped ]';
--
-- l_result := l_result ||' from '||ut_metadata.get_source_view_name()||q'[ s]';
--
-- if a_coverage_options.file_mappings is not empty then
-- l_result := l_result || '
-- join table(:file_mappings) f
-- on s.name = f.object_name
-- and s.type = f.object_type
-- and s.owner = f.object_owner
-- where 1 = 1';
-- elsif a_coverage_options.include_objects is not empty then
-- l_result := l_result || '
-- where (s.owner, s.name) in (select il.owner, il.name from table(:include_objects) il)';
-- else
-- l_result := l_result || '
-- where s.owner in (select upper(t.column_value) from table(:l_schema_names) t)';
-- end if;
-- l_result := l_result || q'[
-- and s.type not in ('PACKAGE', 'TYPE', 'JAVA SOURCE')
-- --Exclude calls to utPLSQL framework, Unit Test packages and objects from a_exclude_list parameter of coverage reporter
-- and (s.owner, s.name) not in (select el.owner, el.name from table(:l_skipped_objects) el)
-- )
-- where line > 0]';
-- return l_result;
end;

function get_cov_sources_cursor(a_coverage_options in ut_coverage_options,a_sql in varchar2) return sys_refcursor is
Expand All @@ -120,11 +203,11 @@ create or replace package body ut_coverage is
raise_application_error(-20542, 'Possible SQL injection detected. a_sql parameter does not match valid pattern "' || l_valid_pattern || '".');
end if;
if a_coverage_options.file_mappings is not empty then
open l_cursor for l_sql using a_coverage_options.file_mappings, l_skip_objects;
open l_cursor for l_sql using a_coverage_options.file_mappings, a_coverage_options.file_mappings, l_skip_objects;
elsif a_coverage_options.include_objects is not empty then
open l_cursor for l_sql using a_coverage_options.include_objects, l_skip_objects;
open l_cursor for l_sql using a_coverage_options.include_objects, a_coverage_options.include_objects, l_skip_objects;
else
open l_cursor for l_sql using a_coverage_options.schema_names, l_skip_objects;
open l_cursor for l_sql using a_coverage_options.schema_names, a_coverage_options.schema_names, l_skip_objects;
end if;
return l_cursor;
end;
Expand Down
0