diff --git a/source/core/coverage/ut_block_helper.pkb b/source/core/coverage/ut_block_helper.pkb
deleted file mode 100644
index f0c2322ab..000000000
--- a/source/core/coverage/ut_block_helper.pkb
+++ /dev/null
@@ -1,89 +0,0 @@
-create or replace package body ut_block_helper is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- type t_proftab_row is record (
- line binary_integer,
- calls number(38,0)
- );
-
- type t_proftab_rows is table of t_proftab_row;
-
- type t_block_row is record(
- line binary_integer
- ,blocks binary_integer
- ,covered_blocks binary_integer);
-
- type t_block_rows is table of t_block_row;
-
- procedure coverage_start(a_run_comment varchar2,a_coverage_id out integer) is
- begin
- a_coverage_id := dbms_plsql_code_coverage.start_coverage(run_comment => a_run_comment);
- end;
-
- procedure coverage_stop is
- begin
- dbms_plsql_code_coverage.stop_coverage();
- end;
-
- function block_results(a_object_owner varchar2, a_object_name varchar2) return t_block_rows is
- c_raw_coverage sys_refcursor;
- l_coverage_rows t_block_rows;
- l_coverage_id integer := ut_coverage_helper.get_coverage_id;
- begin
- open c_raw_coverage for q'[select ccb.line
- ,count(ccb.block) totalblocks
- ,sum(ccb.covered)
- from dbmspcc_units ccu
- left outer join dbmspcc_blocks ccb
- on ccu.run_id = ccb.run_id
- and ccu.object_id = ccb.object_id
- where ccu.run_id = :a_coverage_id
- and ccu.owner = :a_object_owner
- and ccu.name = :a_object_name
- group by ccb.line
- order by 1]' using l_coverage_id,a_object_owner,a_object_name;
-
- fetch c_raw_coverage bulk collect into l_coverage_rows;
- close c_raw_coverage;
-
- return l_coverage_rows;
- end;
-
- function get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return ut_coverage_helper.t_unit_line_calls is
- l_tmp_data t_block_rows;
- l_results ut_coverage_helper.t_unit_line_calls;
-
- begin
- l_tmp_data := block_results(a_object_owner => a_object_owner, a_object_name => a_object_name);
- for i in 1 .. l_tmp_data.count loop
- l_results(l_tmp_data(i).line).blocks := l_tmp_data(i).blocks;
- l_results(l_tmp_data(i).line).covered_blocks := l_tmp_data(i).covered_blocks;
- l_results(l_tmp_data(i).line).partcovered := case
- when (l_tmp_data(i).covered_blocks > 0) and
- (l_tmp_data(i).blocks > l_tmp_data(i).covered_blocks) then
- 1
- else
- 0
- end;
- end loop;
- return l_results;
- end;
-
-
-end;
-/
diff --git a/source/core/coverage/ut_block_helper.pks b/source/core/coverage/ut_block_helper.pks
deleted file mode 100644
index eef041275..000000000
--- a/source/core/coverage/ut_block_helper.pks
+++ /dev/null
@@ -1,26 +0,0 @@
-create or replace package ut_block_helper authid definer is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- procedure coverage_start(a_run_comment in varchar2,a_coverage_id out integer);
-
- procedure coverage_stop;
-
- function get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return ut_coverage_helper.t_unit_line_calls;
-
-end;
-/
diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb
index 4ca1ff056..d09a672be 100644
--- a/source/core/coverage/ut_coverage.pkb
+++ b/source/core/coverage/ut_coverage.pkb
@@ -19,7 +19,84 @@ create or replace package body ut_coverage is
type t_source_lines is table of binary_integer;
- function get_cov_sources_cursor(a_coverage_options in ut_coverage_options,a_sql in varchar2) return sys_refcursor is
+ -- The source query has two important transformations done in it.
+ -- the flag: to_be_skipped ='Y' is set for a line of code that is badly reported by DBMS_PROFILER as executed 0 times.
+ -- This includes lines that are:
+ -- - PACKAGE, PROCEDURE, FUNCTION definition line,
+ -- - BEGIN, END of a block
+ -- Another transformation is adjustment of line number for TRIGGER body.
+ -- DBMS_PROFILER is reporting line numbers for triggers not as defined in DBA_SOURCE, its usign line numbers as defined in DBA_TRIGGERS
+ -- the DBA_TRIGGERS does not contain the trigger specification lines, only lines that define the trigger body.
+ -- the query adjusts the line numbers for triggers by finding first occurrence of begin|declare|compound in the trigger body line.
+ -- The subquery is optimized by:
+ -- - COALESCE function -> it will execute only for TRIGGERS
+ -- - scalar subquery cache -> it will only execute once for one trigger source code.
+ 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_dba_view('dba_source');
+ 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,
+ 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
+ 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,
+ 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
+ from ]'||l_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 ut_coverage_options) return sys_refcursor is
l_cursor sys_refcursor;
l_skip_objects ut_object_names;
l_schema_names ut_varchar2_rows;
@@ -30,7 +107,7 @@ create or replace package body ut_coverage is
--skip all the utplsql framework objects and all the unit test packages that could potentially be reported by coverage.
l_skip_objects := ut_utils.get_utplsql_objects_list() multiset union all coalesce(a_coverage_options.exclude_objects, ut_object_names());
end if;
- l_sql := a_sql;
+ l_sql := get_cov_sources_sql(a_coverage_options);
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;
elsif a_coverage_options.include_objects is not empty then
@@ -41,7 +118,7 @@ create or replace package body ut_coverage is
return l_cursor;
end;
- procedure populate_tmp_table(a_coverage_options in ut_coverage_options,a_sql in varchar2) is
+ procedure populate_tmp_table(a_coverage_options ut_coverage_options) is
pragma autonomous_transaction;
l_cov_sources_crsr sys_refcursor;
l_cov_sources_data ut_coverage_helper.t_coverage_sources_tmp_rows;
@@ -50,7 +127,7 @@ create or replace package body ut_coverage is
if not ut_coverage_helper.is_tmp_table_populated() or ut_coverage_helper.is_develop_mode() then
ut_coverage_helper.cleanup_tmp_table();
- l_cov_sources_crsr := get_cov_sources_cursor(a_coverage_options,a_sql);
+ l_cov_sources_crsr := get_cov_sources_cursor(a_coverage_options);
loop
fetch l_cov_sources_crsr bulk collect into l_cov_sources_data limit 1000;
@@ -70,13 +147,13 @@ create or replace package body ut_coverage is
* Public functions
*/
procedure coverage_start(a_coverage_options ut_coverage_options default null) is
- l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage);
+ l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, 'proftab');
begin
ut_coverage_helper.coverage_start('utPLSQL Code coverage run '||ut_utils.to_string(systimestamp),l_coverage_type);
end;
procedure coverage_start_develop(a_coverage_options ut_coverage_options default null) is
- l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage);
+ l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, 'proftab');
begin
ut_coverage_helper.coverage_start_develop(l_coverage_type);
end;
@@ -101,13 +178,224 @@ create or replace package body ut_coverage is
ut_coverage_helper.coverage_stop_develop();
end;
+ function get_coverage_data_profiler(a_coverage_options ut_coverage_options) return t_coverage is
+ l_line_calls ut_coverage_helper.t_unit_line_calls;
+ l_result t_coverage;
+ l_new_unit t_unit_coverage;
+ line_no binary_integer;
+ l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr;
+ l_source_object ut_coverage_helper.t_tmp_table_object;
+ begin
+
+ --prepare global temp table with sources
+ populate_tmp_table(a_coverage_options);
+
+ l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor();
+ loop
+ fetch l_source_objects_crsr into l_source_object;
+ exit when l_source_objects_crsr%notfound;
+
+ --get coverage data
+ l_line_calls := ut_coverage_helper.get_raw_coverage_data_profiler( l_source_object.owner, l_source_object.name );
+
+ --if there is coverage, we need to filter out the garbage (badly indicated data from dbms_profiler)
+ if l_line_calls.count > 0 then
+ --remove lines that should not be indicted as meaningful
+ for i in 1 .. l_source_object.to_be_skipped_list.count loop
+ if l_source_object.to_be_skipped_list(i) is not null then
+ l_line_calls.delete(l_source_object.to_be_skipped_list(i));
+ end if;
+ end loop;
+ end if;
+
+ --if there are no file mappings or object was actually captured by profiler
+ if a_coverage_options.file_mappings is null or l_line_calls.count > 0 then
+
+ --populate total stats
+ l_result.total_lines := l_result.total_lines + l_source_object.lines_count;
+
+ --populate object level coverage stats
+ if not l_result.objects.exists(l_source_object.full_name) then
+ l_result.objects(l_source_object.full_name) := l_new_unit;
+ l_result.objects(l_source_object.full_name).owner := l_source_object.owner;
+ l_result.objects(l_source_object.full_name).name := l_source_object.name;
+ l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count;
+ end if;
+ --map to results
+ line_no := l_line_calls.first;
+ if line_no is null then
+ l_result.uncovered_lines := l_result.uncovered_lines + l_source_object.lines_count;
+ l_result.objects(l_source_object.full_name).uncovered_lines := l_source_object.lines_count;
+ else
+ loop
+ exit when line_no is null;
+
+ if l_line_calls(line_no).calls > 0 then
+ --total stats
+ l_result.covered_lines := l_result.covered_lines + 1;
+ l_result.executions := l_result.executions + l_line_calls(line_no).calls;
+ --object level stats
+ l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name).covered_lines + 1;
+ l_result.objects(l_source_object.full_name).executions := l_result.objects(l_source_object.full_name).executions + l_line_calls(line_no).calls;
+ elsif l_line_calls(line_no).calls = 0 then
+ l_result.uncovered_lines := l_result.uncovered_lines + 1;
+ l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name).uncovered_lines + 1;
+ end if;
+ l_result.objects(l_source_object.full_name).lines(line_no).executions := l_line_calls(line_no).calls;
+
+ line_no := l_line_calls.next(line_no);
+ end loop;
+ end if;
+ end if;
+
+ end loop;
+
+ close l_source_objects_crsr;
+
+ return l_result;
+ end get_coverage_data_profiler;
+
+ function get_coverage_data_block(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is
+ l_line_calls ut_coverage_helper.t_unit_line_calls;
+ l_result ut_coverage.t_coverage;
+ l_new_unit ut_coverage.t_unit_coverage;
+ line_no binary_integer;
+ l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr;
+ l_source_object ut_coverage_helper.t_tmp_table_object;
+ begin
+ --prepare global temp table with sources
+ populate_tmp_table(a_coverage_options);
+
+ l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor();
+ loop
+ fetch l_source_objects_crsr
+ into l_source_object;
+ exit when l_source_objects_crsr%notfound;
+
+ --get coverage data
+ l_line_calls := ut_coverage_helper.get_raw_coverage_data_block(l_source_object.owner, l_source_object.name);
+
+ --if there is coverage, we need to filter out the garbage (badly indicated data)
+ if l_line_calls.count > 0 then
+ --remove lines that should not be indicted as meaningful
+ for i in 1 .. l_source_object.to_be_skipped_list.count loop
+ if l_source_object.to_be_skipped_list(i) is not null then
+ l_line_calls.delete(l_source_object.to_be_skipped_list(i));
+ end if;
+ end loop;
+ end if;
+
+ --if there are no file mappings or object was actually captured by profiler
+ if a_coverage_options.file_mappings is null or l_line_calls.count > 0 then
+
+ --populate total stats
+ l_result.total_lines := l_result.total_lines + l_source_object.lines_count;
+
+ --populate object level coverage stats
+ if not l_result.objects.exists(l_source_object.full_name) then
+ l_result.objects(l_source_object.full_name) := l_new_unit;
+ l_result.objects(l_source_object.full_name).owner := l_source_object.owner;
+ l_result.objects(l_source_object.full_name).name := l_source_object.name;
+ l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count;
+ end if;
+ --map to results
+ line_no := l_line_calls.first;
+ if line_no is null then
+ l_result.uncovered_lines := l_result.uncovered_lines + l_source_object.lines_count;
+ l_result.objects(l_source_object.full_name).uncovered_lines := l_source_object.lines_count;
+ else
+ loop
+ exit when line_no is null;
+
+ --turn the block coverage into a line coverage format to allow for reading.
+ --whenever the linst is a part covered treat that line as a hit and execution but only part covered
+
+ --total stats
+ --Get total blocks ,blocks covered, blocks not covered this will be used for PCT calc
+ l_result.total_blocks := nvl(l_result.total_blocks, 0) + l_line_calls(line_no).blocks;
+ l_result.covered_blocks := nvl(l_result.covered_blocks, 0) + l_line_calls(line_no).covered_blocks;
+ l_result.uncovered_blocks := nvl(l_result.uncovered_blocks, 0) +
+ (l_line_calls(line_no).blocks - l_line_calls(line_no).covered_blocks);
+
+ --If line is partially covered add as part line cover and covered for line reporter
+ if l_line_calls(line_no).partcovered = 1 then
+ l_result.partcovered_lines := l_result.partcovered_lines + 1;
+ end if;
+
+ if l_line_calls(line_no).covered_blocks > 0 then
+ l_result.covered_lines := l_result.covered_lines + 1;
+ end if;
+
+ -- Use nvl as be default is null and screw the calcs
+ --Increase total blocks
+ l_result.objects(l_source_object.full_name).lines(line_no).no_blocks := l_line_calls(line_no).blocks;
+ l_result.objects(l_source_object.full_name).lines(line_no).covered_blocks := l_line_calls(line_no).covered_blocks;
+ l_result.objects(l_source_object.full_name).total_blocks := nvl(l_result.objects(l_source_object.full_name)
+ .total_blocks
+ ,0) + l_line_calls(line_no).blocks;
+
+ --Total uncovered blocks is a line blocks minus covered blocsk
+ l_result.objects(l_source_object.full_name).uncovered_blocks := nvl(l_result.objects(l_source_object.full_name)
+ .uncovered_blocks
+ ,0) +
+ (l_line_calls(line_no).blocks - l_line_calls(line_no)
+ .covered_blocks);
+
+ --If we have any covered blocks in line
+ if l_line_calls(line_no).covered_blocks > 0 then
+ --If any block is covered then we have a hit on that line
+ l_result.executions := l_result.executions + 1;
+ --object level stats
+ --If its part covered then mark it else treat as full cov
+ if l_line_calls(line_no).partcovered = 1 then
+ l_result.objects(l_source_object.full_name).partcovered_lines := l_result.objects(l_source_object.full_name)
+ .partcovered_lines + 1;
+ end if;
+ l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name)
+ .covered_lines + 1;
+
+ --How many blocks we covered
+ l_result.objects(l_source_object.full_name).covered_blocks := nvl(l_result.objects(l_source_object.full_name)
+ .covered_blocks
+ ,0) + l_line_calls(line_no)
+ .covered_blocks;
+
+ --Object line executions
+ l_result.objects(l_source_object.full_name).executions := nvl(l_result.objects(l_source_object.full_name)
+ .executions
+ ,0) + 1;
+
+ l_result.objects(l_source_object.full_name).lines(line_no).executions := 1;
+
+ --Whenever there is no covered block treat as uncovered (query returns only lines where the blocks are in code so we
+ --dont have a false results here when there is no blocks
+ elsif l_line_calls(line_no).covered_blocks = 0 then
+ l_result.uncovered_lines := l_result.uncovered_lines + 1;
+ l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name)
+ .uncovered_lines + 1;
+ l_result.objects(l_source_object.full_name).lines(line_no).executions := 0;
+ end if;
+ --increase part covered counter (+ 1/0)
+ l_result.objects(l_source_object.full_name).lines(line_no).partcove := l_line_calls(line_no).partcovered;
+ line_no := l_line_calls.next(line_no);
+ end loop;
+ end if;
+ end if;
+
+ end loop;
+
+ close l_source_objects_crsr;
+
+ return l_result;
+ end get_coverage_data_block;
+
function get_coverage_data(a_coverage_options ut_coverage_options) return t_coverage is
begin
- if a_coverage_options.coverage_type = c_block_coverage then
- return ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options);
+ if a_coverage_options.coverage_type = 'block' then
+ return get_coverage_data_block(a_coverage_options => a_coverage_options);
else
- return ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options);
+ return get_coverage_data_profiler(a_coverage_options => a_coverage_options);
end if;
end get_coverage_data;
diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks
index db659c049..8a7df49ed 100644
--- a/source/core/coverage/ut_coverage.pks
+++ b/source/core/coverage/ut_coverage.pks
@@ -15,10 +15,7 @@ create or replace package ut_coverage authid current_user is
See the License for the specific language governing permissions and
limitations under the License.
*/
-
- c_proftab_coverage constant varchar2(32) := 'proftab';
- c_block_coverage constant varchar2(32) := 'block';
-
+
-- total run coverage information
subtype t_full_name is varchar2(4000);
subtype t_object_name is varchar2(250);
@@ -62,8 +59,6 @@ create or replace package ut_coverage authid current_user is
,executions number(38, 0) := 0
,objects tt_program_units);
- procedure populate_tmp_table(a_coverage_options ut_coverage_options, a_sql in varchar2);
-
procedure coverage_start(a_coverage_options ut_coverage_options default null);
/*
diff --git a/source/core/coverage/ut_coverage_block.pkb b/source/core/coverage/ut_coverage_block.pkb
deleted file mode 100644
index a5a9801c8..000000000
--- a/source/core/coverage/ut_coverage_block.pkb
+++ /dev/null
@@ -1,224 +0,0 @@
-create or replace package body ut_coverage_block is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-
- type t_source_lines is table of binary_integer;
-
- -- The source query has two important transformations done in it.
- -- the flag: to_be_skipped ='Y' is set for a line of code that is badly reported by DBMS_PROFILER as executed 0 times.
- -- This includes lines that are:
- -- - PACKAGE, PROCEDURE, FUNCTION definition line,
- -- - BEGIN, END of a block
- -- Another transformation is adjustment of line number for TRIGGER body.
- -- DBMS_PROFILER is reporting line numbers for triggers not as defined in DBA_SOURCE, its usign line numbers as defined in DBA_TRIGGERS
- -- the DBA_TRIGGERS does not contain the trigger specification lines, only lines that define the trigger body.
- -- the query adjusts the line numbers for triggers by finding first occurrence of begin|declare|compound in the trigger body line.
- -- The subquery is optimized by:
- -- - COALESCE function -> it will execute only for TRIGGERS
- -- - scalar subquery cache -> it will only execute once for one trigger source code.
- 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_dba_view('dba_source');
- 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,
- 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
- 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, 'N' as to_be_skipped
- from ]'||l_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;
-
-
- /**
- * Public functions
- */
-
- function get_coverage_data_block(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is
- l_line_calls ut_coverage_helper.t_unit_line_calls;
- l_result ut_coverage.t_coverage;
- l_new_unit ut_coverage.t_unit_coverage;
- line_no binary_integer;
- l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr;
- l_source_object ut_coverage_helper.t_tmp_table_object;
- begin
- --prepare global temp table with sources
- ut_coverage.populate_tmp_table(a_coverage_options,get_cov_sources_sql(a_coverage_options));
-
- l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor();
- loop
- fetch l_source_objects_crsr
- into l_source_object;
- exit when l_source_objects_crsr%notfound;
-
- --get coverage data
- l_line_calls := ut_block_helper.get_raw_coverage_data_block(l_source_object.owner, l_source_object.name);
-
- --if there is coverage, we need to filter out the garbage (badly indicated data)
- if l_line_calls.count > 0 then
- --remove lines that should not be indicted as meaningful
- for i in 1 .. l_source_object.to_be_skipped_list.count loop
- if l_source_object.to_be_skipped_list(i) is not null then
- l_line_calls.delete(l_source_object.to_be_skipped_list(i));
- end if;
- end loop;
- end if;
-
- --if there are no file mappings or object was actually captured by profiler
- if a_coverage_options.file_mappings is null or l_line_calls.count > 0 then
-
- --populate total stats
- l_result.total_lines := l_result.total_lines + l_source_object.lines_count;
-
- --populate object level coverage stats
- if not l_result.objects.exists(l_source_object.full_name) then
- l_result.objects(l_source_object.full_name) := l_new_unit;
- l_result.objects(l_source_object.full_name).owner := l_source_object.owner;
- l_result.objects(l_source_object.full_name).name := l_source_object.name;
- l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count;
- end if;
- --map to results
- line_no := l_line_calls.first;
- if line_no is null then
- l_result.uncovered_lines := l_result.uncovered_lines + l_source_object.lines_count;
- l_result.objects(l_source_object.full_name).uncovered_lines := l_source_object.lines_count;
- else
- loop
- exit when line_no is null;
-
- --turn the block coverage into a line coverage format to allow for reading.
- --whenever the linst is a part covered treat that line as a hit and execution but only part covered
-
- --total stats
- --Get total blocks ,blocks covered, blocks not covered this will be used for PCT calc
- l_result.total_blocks := nvl(l_result.total_blocks, 0) + l_line_calls(line_no).blocks;
- l_result.covered_blocks := nvl(l_result.covered_blocks, 0) + l_line_calls(line_no).covered_blocks;
- l_result.uncovered_blocks := nvl(l_result.uncovered_blocks, 0) +
- (l_line_calls(line_no).blocks - l_line_calls(line_no).covered_blocks);
-
- --If line is partially covered add as part line cover and covered for line reporter
- if l_line_calls(line_no).partcovered = 1 then
- l_result.partcovered_lines := l_result.partcovered_lines + 1;
- end if;
-
- if l_line_calls(line_no).covered_blocks > 0 then
- l_result.covered_lines := l_result.covered_lines + 1;
- end if;
-
- -- Use nvl as be default is null and screw the calcs
- --Increase total blocks
- l_result.objects(l_source_object.full_name).lines(line_no).no_blocks := l_line_calls(line_no).blocks;
- l_result.objects(l_source_object.full_name).lines(line_no).covered_blocks := l_line_calls(line_no).covered_blocks;
- l_result.objects(l_source_object.full_name).total_blocks := nvl(l_result.objects(l_source_object.full_name)
- .total_blocks
- ,0) + l_line_calls(line_no).blocks;
-
- --Total uncovered blocks is a line blocks minus covered blocsk
- l_result.objects(l_source_object.full_name).uncovered_blocks := nvl(l_result.objects(l_source_object.full_name)
- .uncovered_blocks
- ,0) +
- (l_line_calls(line_no).blocks - l_line_calls(line_no)
- .covered_blocks);
-
- --If we have any covered blocks in line
- if l_line_calls(line_no).covered_blocks > 0 then
- --If any block is covered then we have a hit on that line
- l_result.executions := l_result.executions + 1;
- --object level stats
- --If its part covered then mark it else treat as full cov
- if l_line_calls(line_no).partcovered = 1 then
- l_result.objects(l_source_object.full_name).partcovered_lines := l_result.objects(l_source_object.full_name)
- .partcovered_lines + 1;
- end if;
- l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name)
- .covered_lines + 1;
-
- --How many blocks we covered
- l_result.objects(l_source_object.full_name).covered_blocks := nvl(l_result.objects(l_source_object.full_name)
- .covered_blocks
- ,0) + l_line_calls(line_no)
- .covered_blocks;
-
- --Object line executions
- l_result.objects(l_source_object.full_name).executions := nvl(l_result.objects(l_source_object.full_name)
- .executions
- ,0) + 1;
-
- l_result.objects(l_source_object.full_name).lines(line_no).executions := 1;
-
- --Whenever there is no covered block treat as uncovered (query returns only lines where the blocks are in code so we
- --dont have a false results here when there is no blocks
- elsif l_line_calls(line_no).covered_blocks = 0 then
- l_result.uncovered_lines := l_result.uncovered_lines + 1;
- l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name)
- .uncovered_lines + 1;
- l_result.objects(l_source_object.full_name).lines(line_no).executions := 0;
- end if;
- --increase part covered counter (+ 1/0)
- l_result.objects(l_source_object.full_name).lines(line_no).partcove := l_line_calls(line_no).partcovered;
- line_no := l_line_calls.next(line_no);
- end loop;
- end if;
- end if;
-
- end loop;
-
- close l_source_objects_crsr;
-
- return l_result;
- end get_coverage_data_block;
-
-end;
-/
diff --git a/source/core/coverage/ut_coverage_block.pks b/source/core/coverage/ut_coverage_block.pks
deleted file mode 100644
index f0febb021..000000000
--- a/source/core/coverage/ut_coverage_block.pks
+++ /dev/null
@@ -1,22 +0,0 @@
-create or replace package ut_coverage_block authid current_user is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- function get_coverage_data_block(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage;
-
-end;
-/
diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb
index 0f01e64fb..0b7800a27 100644
--- a/source/core/coverage/ut_coverage_helper.pkb
+++ b/source/core/coverage/ut_coverage_helper.pkb
@@ -16,7 +16,7 @@ create or replace package body ut_coverage_helper is
limitations under the License.
*/
-
+ g_coverage_id integer;
g_develop_mode boolean not null := false;
g_is_started boolean not null := false;
@@ -40,25 +40,10 @@ create or replace package body ut_coverage_helper is
g_coverage_type := a_coverage_type;
end;
- procedure set_coverage_status(a_started in boolean) is
- begin
- g_is_started := a_started;
- end;
-
- procedure set_develop_mode(a_develop_mode in boolean) is
- begin
- g_develop_mode := a_develop_mode;
- end;
-
function get_coverage_type return varchar2 is
begin
return g_coverage_type;
end;
-
- function get_coverage_id return integer is
- begin
- return g_coverage_id;
- end;
function is_develop_mode return boolean is
begin
@@ -66,12 +51,16 @@ create or replace package body ut_coverage_helper is
end;
procedure coverage_start_internal(a_run_comment varchar2,a_coverage_type in varchar2) is
+ l_start_block varchar2(32767):= 'call dbms_plsql_code_coverage.start_coverage(run_comment => :a_run_comment)
+ into :g_coverage_id';
begin
set_coverage_type(a_coverage_type);
- if get_coverage_type = ut_coverage.c_block_coverage then
- ut_block_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id );
+ -- Make it dynamic to allow for block coverage.
+ if get_coverage_type = 'block' then
+ execute immediate l_start_block USING IN a_run_comment, OUT g_coverage_id;
+ --g_coverage_id := dbms_plsql_code_coverage.start_coverage(run_comment => a_run_comment);
else
- ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id);
+ dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id);
coverage_pause();
end if;
g_is_started := true;
@@ -94,33 +83,36 @@ create or replace package body ut_coverage_helper is
end;
procedure coverage_pause is
+ l_return_code binary_integer;
begin
if not g_develop_mode then
- if get_coverage_type = ut_coverage.c_block_coverage then
+ if get_coverage_type = 'block' then
null;
else
- ut_proftab_helper.coverage_pause();
+ l_return_code := dbms_profiler.pause_profiler();
end if;
end if;
end;
procedure coverage_resume is
+ l_return_code binary_integer;
begin
- if get_coverage_type = ut_coverage.c_block_coverage then
+ if get_coverage_type = 'block' then
null;
else
- ut_proftab_helper.coverage_resume();
+ l_return_code := dbms_profiler.resume_profiler();
end if;
end;
procedure coverage_stop is
+ l_stop_block varchar2(100) := 'call dbms_plsql_code_coverage.stop_coverage()';
begin
if not g_develop_mode then
g_is_started := false;
- if get_coverage_type = ut_coverage.c_block_coverage then
- ut_block_helper.coverage_stop();
+ if get_coverage_type = 'block' then
+ execute immediate l_stop_block;
else
- ut_proftab_helper.coverage_stop();
+ dbms_profiler.stop_profiler();
end if;
end if;
end;
@@ -129,14 +121,92 @@ create or replace package body ut_coverage_helper is
begin
g_develop_mode := false;
g_is_started := false;
- if get_coverage_type = ut_coverage.c_block_coverage then
- ut_block_helper.coverage_stop();
+ if get_coverage_type = 'block' then
+ null;
else
- ut_proftab_helper.coverage_stop();
+ dbms_profiler.stop_profiler();
end if;
end;
- procedure mock_coverage_id(a_coverage_id integer) is
+ function proftab_results(a_object_owner varchar2, a_object_name varchar2) return t_proftab_rows is
+ c_raw_coverage sys_refcursor;
+ l_coverage_rows t_proftab_rows;
+ begin
+ open c_raw_coverage for q'[select d.line#,
+ case when sum(d.total_occur) = 0 and sum(d.total_time) > 0 then 1 else sum(d.total_occur) end total_occur
+ from plsql_profiler_units u
+ join plsql_profiler_data d
+ on u.runid = d.runid
+ and u.unit_number = d.unit_number
+ where u.runid = :g_coverage_id
+ and u.unit_owner = :a_object_owner
+ and u.unit_name = :a_object_name
+ and u.unit_type not in ('PACKAGE SPEC', 'TYPE SPEC', 'ANONYMOUS BLOCK')
+ group by d.line#]' using g_coverage_id,a_object_owner,a_object_name;
+
+ FETCH c_raw_coverage BULK COLLECT
+ INTO l_coverage_rows;
+ CLOSE c_raw_coverage;
+
+ RETURN l_coverage_rows;
+ end;
+
+ function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls is
+ l_tmp_data t_proftab_rows;
+ l_results t_unit_line_calls;
+ begin
+ l_tmp_data := proftab_results(a_object_owner => a_object_owner, a_object_name => a_object_name);
+
+ for i in 1 .. l_tmp_data.count loop
+ l_results(l_tmp_data(i).line).calls := l_tmp_data(i).calls;
+ end loop;
+ return l_results;
+ end;
+
+ function block_results(a_object_owner varchar2, a_object_name varchar2) return t_block_rows is
+ c_raw_coverage sys_refcursor;
+ l_coverage_rows t_block_rows;
+ begin
+ open c_raw_coverage for q'[select ccb.line
+ ,count(ccb.block) totalblocks
+ ,sum(ccb.covered)
+ from dbmspcc_units ccu
+ left outer join dbmspcc_blocks ccb
+ on ccu.run_id = ccb.run_id
+ and ccu.object_id = ccb.object_id
+ where ccu.run_id = :g_coverage_id
+ and ccu.owner = :a_object_owner
+ and ccu.name = :a_object_name
+ group by ccb.line
+ order by 1]' using g_coverage_id,a_object_owner,a_object_name;
+
+ fetch c_raw_coverage bulk collect into l_coverage_rows;
+ close c_raw_coverage;
+
+ return l_coverage_rows;
+ end;
+
+ function get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls is
+ l_tmp_data t_block_rows;
+ l_results t_unit_line_calls;
+
+ begin
+ l_tmp_data := block_results(a_object_owner => a_object_owner, a_object_name => a_object_name);
+ for i in 1 .. l_tmp_data.count loop
+ l_results(l_tmp_data(i).line).blocks := l_tmp_data(i).blocks;
+ l_results(l_tmp_data(i).line).covered_blocks := l_tmp_data(i).covered_blocks;
+ l_results(l_tmp_data(i).line).partcovered := case
+ when (l_tmp_data(i).covered_blocks > 0) and
+ (l_tmp_data(i).blocks > l_tmp_data(i).covered_blocks) then
+ 1
+ else
+ 0
+ end;
+ end loop;
+ return l_results;
+ end;
+
+ procedure mock_coverage_id(a_coverage_id integer) is
begin
g_develop_mode := true;
g_is_started := true;
diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks
index 6728fd4b3..bf6c60df8 100644
--- a/source/core/coverage/ut_coverage_helper.pks
+++ b/source/core/coverage/ut_coverage_helper.pks
@@ -17,19 +17,12 @@ create or replace package ut_coverage_helper authid definer is
*/
- g_coverage_id integer;
g_coverage_type varchar2(32);
function get_coverage_type return varchar2;
- function get_coverage_id return integer;
-
procedure set_coverage_type(a_coverage_type in varchar2);
- procedure set_coverage_status(a_started in boolean);
-
- procedure set_develop_mode(a_develop_mode in boolean);
-
--table of line calls indexed by line number
--!!! this table is sparse!!!
--type t_unit_line_calls is table of number(38,0) index by binary_integer;
@@ -80,6 +73,10 @@ create or replace package ut_coverage_helper authid definer is
procedure coverage_resume;
+ function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls;
+
+ function get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls;
+
/***
* Allows overwriting of private global variable g_coverage_id
* Used internally, only for unit testing of the framework only
diff --git a/source/core/coverage/ut_coverage_proftab.pkb b/source/core/coverage/ut_coverage_proftab.pkb
deleted file mode 100644
index 1fa550acf..000000000
--- a/source/core/coverage/ut_coverage_proftab.pkb
+++ /dev/null
@@ -1,178 +0,0 @@
-create or replace package body ut_coverage_proftab is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- -- The source query has two important transformations done in it.
- -- the flag: to_be_skipped ='Y' is set for a line of code that is badly reported by DBMS_PROFILER as executed 0 times.
- -- This includes lines that are:
- -- - PACKAGE, PROCEDURE, FUNCTION definition line,
- -- - BEGIN, END of a block
- -- Another transformation is adjustment of line number for TRIGGER body.
- -- DBMS_PROFILER is reporting line numbers for triggers not as defined in DBA_SOURCE, its usign line numbers as defined in DBA_TRIGGERS
- -- the DBA_TRIGGERS does not contain the trigger specification lines, only lines that define the trigger body.
- -- the query adjusts the line numbers for triggers by finding first occurrence of begin|declare|compound in the trigger body line.
- -- The subquery is optimized by:
- -- - COALESCE function -> it will execute only for TRIGGERS
- -- - scalar subquery cache -> it will only execute once for one trigger source code.
- 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_dba_view('dba_source');
- 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,
- 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
- 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,
- 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
- from ]'||l_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;
-
- /**
- * Public functions
- */
- function get_coverage_data_profiler(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is
- l_line_calls ut_coverage_helper.t_unit_line_calls;
- l_result ut_coverage.t_coverage;
- l_new_unit ut_coverage.t_unit_coverage;
- line_no binary_integer;
- l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr;
- l_source_object ut_coverage_helper.t_tmp_table_object;
- begin
-
- --prepare global temp table with sources
- ut_coverage.populate_tmp_table(a_coverage_options,get_cov_sources_sql(a_coverage_options));
-
- l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor();
- loop
- fetch l_source_objects_crsr into l_source_object;
- exit when l_source_objects_crsr%notfound;
-
- --get coverage data
- l_line_calls := ut_proftab_helper.get_raw_coverage_data_profiler( l_source_object.owner, l_source_object.name);
-
- --if there is coverage, we need to filter out the garbage (badly indicated data from dbms_profiler)
- if l_line_calls.count > 0 then
- --remove lines that should not be indicted as meaningful
- for i in 1 .. l_source_object.to_be_skipped_list.count loop
- if l_source_object.to_be_skipped_list(i) is not null then
- l_line_calls.delete(l_source_object.to_be_skipped_list(i));
- end if;
- end loop;
- end if;
-
- --if there are no file mappings or object was actually captured by profiler
- if a_coverage_options.file_mappings is null or l_line_calls.count > 0 then
-
- --populate total stats
- l_result.total_lines := l_result.total_lines + l_source_object.lines_count;
-
- --populate object level coverage stats
- if not l_result.objects.exists(l_source_object.full_name) then
- l_result.objects(l_source_object.full_name) := l_new_unit;
- l_result.objects(l_source_object.full_name).owner := l_source_object.owner;
- l_result.objects(l_source_object.full_name).name := l_source_object.name;
- l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count;
- end if;
- --map to results
- line_no := l_line_calls.first;
- if line_no is null then
- l_result.uncovered_lines := l_result.uncovered_lines + l_source_object.lines_count;
- l_result.objects(l_source_object.full_name).uncovered_lines := l_source_object.lines_count;
- else
- loop
- exit when line_no is null;
-
- if l_line_calls(line_no).calls > 0 then
- --total stats
- l_result.covered_lines := l_result.covered_lines + 1;
- l_result.executions := l_result.executions + l_line_calls(line_no).calls;
- --object level stats
- l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name).covered_lines + 1;
- l_result.objects(l_source_object.full_name).executions := l_result.objects(l_source_object.full_name).executions + l_line_calls(line_no).calls;
- elsif l_line_calls(line_no).calls = 0 then
- l_result.uncovered_lines := l_result.uncovered_lines + 1;
- l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name).uncovered_lines + 1;
- end if;
- l_result.objects(l_source_object.full_name).lines(line_no).executions := l_line_calls(line_no).calls;
-
- line_no := l_line_calls.next(line_no);
- end loop;
- end if;
- end if;
-
- end loop;
-
- close l_source_objects_crsr;
-
- return l_result;
- end get_coverage_data_profiler;
-
-end;
-/
diff --git a/source/core/coverage/ut_coverage_proftab.pks b/source/core/coverage/ut_coverage_proftab.pks
deleted file mode 100644
index 7f0f4ca3b..000000000
--- a/source/core/coverage/ut_coverage_proftab.pks
+++ /dev/null
@@ -1,22 +0,0 @@
-create or replace package ut_coverage_proftab authid current_user is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- function get_coverage_data_profiler(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage;
-
-end;
-/
diff --git a/source/core/coverage/ut_proftab_helper.pkb b/source/core/coverage/ut_proftab_helper.pkb
deleted file mode 100644
index bf40ba531..000000000
--- a/source/core/coverage/ut_proftab_helper.pkb
+++ /dev/null
@@ -1,93 +0,0 @@
-create or replace package body ut_proftab_helper is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- type t_proftab_row is record (
- line binary_integer,
- calls number(38,0)
- );
-
- type t_proftab_rows is table of t_proftab_row;
-
- type t_block_row is record(
- line binary_integer
- ,blocks binary_integer
- ,covered_blocks binary_integer);
-
- type t_block_rows is table of t_block_row;
-
-
- procedure coverage_start(a_run_comment varchar2,a_coverage_id out integer) is
- begin
- dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => a_coverage_id);
- end;
-
- procedure coverage_pause is
- l_return_code binary_integer;
- begin
- l_return_code := dbms_profiler.pause_profiler();
- end;
-
- procedure coverage_resume is
- l_return_code binary_integer;
- begin
- l_return_code := dbms_profiler.resume_profiler();
- end;
-
- procedure coverage_stop is
- begin
- dbms_profiler.stop_profiler();
- end;
-
- function proftab_results(a_object_owner varchar2, a_object_name varchar2) return t_proftab_rows is
- c_raw_coverage sys_refcursor;
- l_coverage_rows t_proftab_rows;
- l_coverage_id integer := ut_coverage_helper.get_coverage_id;
- begin
- open c_raw_coverage for q'[select d.line#,
- case when sum(d.total_occur) = 0 and sum(d.total_time) > 0 then 1 else sum(d.total_occur) end total_occur
- from plsql_profiler_units u
- join plsql_profiler_data d
- on u.runid = d.runid
- and u.unit_number = d.unit_number
- where u.runid = :a_coverage_id
- and u.unit_owner = :a_object_owner
- and u.unit_name = :a_object_name
- and u.unit_type not in ('PACKAGE SPEC', 'TYPE SPEC', 'ANONYMOUS BLOCK')
- group by d.line#]' using l_coverage_id,a_object_owner,a_object_name;
-
- FETCH c_raw_coverage BULK COLLECT
- INTO l_coverage_rows;
- CLOSE c_raw_coverage;
-
- RETURN l_coverage_rows;
- end;
-
- function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return ut_coverage_helper.t_unit_line_calls is
- l_tmp_data t_proftab_rows;
- l_results ut_coverage_helper.t_unit_line_calls;
- begin
- l_tmp_data := proftab_results(a_object_owner => a_object_owner, a_object_name => a_object_name);
-
- for i in 1 .. l_tmp_data.count loop
- l_results(l_tmp_data(i).line).calls := l_tmp_data(i).calls;
- end loop;
- return l_results;
- end;
-
-end;
-/
diff --git a/source/core/coverage/ut_proftab_helper.pks b/source/core/coverage/ut_proftab_helper.pks
deleted file mode 100644
index 53a78dbc5..000000000
--- a/source/core/coverage/ut_proftab_helper.pks
+++ /dev/null
@@ -1,30 +0,0 @@
-create or replace package ut_proftab_helper authid definer is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- procedure coverage_start(a_run_comment in varchar2,a_coverage_id out integer);
-
- procedure coverage_stop;
-
- procedure coverage_pause;
-
- procedure coverage_resume;
-
- function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return ut_coverage_helper.t_unit_line_calls;
-
-end;
-/
diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb
index 5bdf26fb5..ea9f71e9f 100644
--- a/source/core/types/ut_run.tpb
+++ b/source/core/types/ut_run.tpb
@@ -34,7 +34,7 @@ create or replace type body ut_run as
begin
l_coverage_schema_names := coalesce(a_schema_names, get_run_schemes());
l_exclude_objects := coalesce(a_exclude_objects,ut_object_names());
- l_coverage_type := coalesce(a_coverage_type,ut_coverage.c_proftab_coverage);
+ l_coverage_type := coalesce(a_coverage_type,'proftab');
self.run_paths := a_run_paths;
self.self_type := $$plsql_unit;
diff --git a/source/install.sql b/source/install.sql
index 7d5d19664..9a1b2457f 100644
--- a/source/install.sql
+++ b/source/install.sql
@@ -127,18 +127,10 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema
--gathering coverage
@@install_component.sql 'core/coverage/ut_coverage_sources_tmp.sql'
@@install_component.sql 'core/coverage/ut_coverage_helper.pks'
-@@install_component.sql 'core/coverage/ut_block_helper.pks'
-@@install_component.sql 'core/coverage/ut_proftab_helper.pks'
-@@install_component.sql 'core/coverage/ut_coverage.pks'
-@@install_component.sql 'core/coverage/ut_coverage_block.pks'
-@@install_component.sql 'core/coverage/ut_coverage_proftab.pks'
-@@install_component.sql 'core/coverage/ut_coverage_reporter_base.tps'
@@install_component.sql 'core/coverage/ut_coverage_helper.pkb'
-@@install_component.sql 'core/coverage/ut_block_helper.pkb'
-@@install_component.sql 'core/coverage/ut_proftab_helper.pkb'
+@@install_component.sql 'core/coverage/ut_coverage.pks'
@@install_component.sql 'core/coverage/ut_coverage.pkb'
-@@install_component.sql 'core/coverage/ut_coverage_block.pkb'
-@@install_component.sql 'core/coverage/ut_coverage_proftab.pkb'
+@@install_component.sql 'core/coverage/ut_coverage_reporter_base.tps'
@@install_component.sql 'core/coverage/ut_coverage_reporter_base.tpb'
--core type bodies
@@ -259,10 +251,6 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema
@@install_component.sql 'reporters/ut_coverage_html_reporter.tps'
@@install_component.sql 'reporters/ut_coverage_report_html_helper.pks'
@@install_component.sql 'reporters/ut_coverage_report_html_helper.pkb'
-@@install_component.sql 'reporters/ut_block_report_html_helper.pks'
-@@install_component.sql 'reporters/ut_proftab_report_html_helper.pks'
-@@install_component.sql 'reporters/ut_block_report_html_helper.pkb'
-@@install_component.sql 'reporters/ut_proftab_report_html_helper.pkb'
@@install_component.sql 'reporters/ut_coverage_html_reporter.tpb'
@@install_component.sql 'reporters/ut_coverage_sonar_reporter.tps'
@@install_component.sql 'reporters/ut_coverage_sonar_reporter.tpb'
diff --git a/source/reporters/ut_block_report_html_helper.pkb b/source/reporters/ut_block_report_html_helper.pkb
deleted file mode 100644
index f6485f952..000000000
--- a/source/reporters/ut_block_report_html_helper.pkb
+++ /dev/null
@@ -1,226 +0,0 @@
-create or replace package body ut_block_report_html_helper is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a_unit_coverage ut_coverage.t_unit_coverage)
- return clob is
- l_source_code ut_varchar2_list;
- l_result clob;
-
- function build_details_file_content(a_object_id varchar2, a_object_full_name varchar2, a_source_code ut_varchar2_list, a_coverage_unit ut_coverage.t_unit_coverage)
- return clob is
- l_file_part varchar2(32767);
- l_result clob;
- l_coverage_pct number(5, 2);
- l_coverage_block_pct number(5, 2);
- l_hits varchar2(30);
- begin
- dbms_lob.createtemporary(l_result, true);
- l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_unit.covered_blocks, a_coverage_unit.uncovered_blocks);
- l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines);
-
- l_file_part := '
';
- ut_utils.append_to_clob(l_result, l_file_part);
-
- for line_no in 1 .. a_source_code.count loop
- if not a_coverage_unit.lines.exists(line_no) then
- l_file_part := '
-
';
-
- ut_utils.append_to_clob(l_result, l_file_part);
- return l_result;
- end;
-
-end;
-/
diff --git a/source/reporters/ut_block_report_html_helper.pks b/source/reporters/ut_block_report_html_helper.pks
deleted file mode 100644
index 9ec514ffa..000000000
--- a/source/reporters/ut_block_report_html_helper.pks
+++ /dev/null
@@ -1,21 +0,0 @@
-create or replace package ut_block_report_html_helper authid current_user is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null) return clob;
-
-end;
-/
diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb
index 601986374..2deeb6380 100644
--- a/source/reporters/ut_coverage_report_html_helper.pkb
+++ b/source/reporters/ut_coverage_report_html_helper.pkb
@@ -98,20 +98,269 @@ create or replace package body ut_coverage_report_html_helper is
return '' || a_object_full_name || '';
end;
+ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a_unit_coverage ut_coverage.t_unit_coverage, a_coverage_type varchar2)
+ return clob is
+ l_source_code ut_varchar2_list;
+ l_result clob;
+ l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab');
+
+ function build_details_file_content(a_object_id varchar2, a_object_full_name varchar2, a_source_code ut_varchar2_list, a_coverage_unit ut_coverage.t_unit_coverage, a_coverage_type varchar2)
+ return clob is
+ l_file_part varchar2(32767);
+ l_result clob;
+ l_coverage_pct number(5, 2);
+ l_coverage_block_pct number(5, 2);
+ l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab');
+ l_hits varchar2(30);
+ begin
+ dbms_lob.createtemporary(l_result, true);
+
+ if l_coverage_type = 'block' then
+ l_coverage_block_pct := coverage_pct(a_coverage_unit.covered_blocks, a_coverage_unit.uncovered_blocks);
+ end if;
+
+ l_coverage_pct := coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines);
+
+
+ --l_coverage_pct := coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines);
+
+ l_file_part := '
';
+ ut_utils.append_to_clob(l_result, l_file_part);
+
+ for line_no in 1 .. a_source_code.count loop
+ if not a_coverage_unit.lines.exists(line_no) then
+ l_file_part := '
+
';
+
+ ut_utils.append_to_clob(l_result, l_file_part);
return l_result;
end;
diff --git a/source/reporters/ut_coverage_report_html_helper.pks b/source/reporters/ut_coverage_report_html_helper.pks
index 48c96a53d..67faeb6a1 100644
--- a/source/reporters/ut_coverage_report_html_helper.pks
+++ b/source/reporters/ut_coverage_report_html_helper.pks
@@ -17,20 +17,6 @@ create or replace package ut_coverage_report_html_helper authid current_user is
*/
function get_default_html_assets_path return varchar2 deterministic;
- function coverage_pct(a_covered_lines integer, a_uncovered_lines integer) return number;
-
- function coverage_css_class(a_covered_pct number) return varchar2;
-
- function line_status(a_executions in ut_coverage.t_line_executions) return varchar2;
-
- function link_to_source_file(a_object_full_name varchar2) return varchar2;
-
- function object_id(a_object_full_name varchar2) return varchar2;
-
- function executions_per_line(a_executions number, a_lines integer) return integer;
-
- function line_hits_css_class(a_line_hist number) return varchar2;
-
function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null, a_coverage_type varchar2 := null) return clob;
end;
diff --git a/source/reporters/ut_proftab_report_html_helper.pkb b/source/reporters/ut_proftab_report_html_helper.pkb
deleted file mode 100644
index 118d00a1b..000000000
--- a/source/reporters/ut_proftab_report_html_helper.pkb
+++ /dev/null
@@ -1,210 +0,0 @@
-create or replace package body ut_proftab_report_html_helper is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a_unit_coverage ut_coverage.t_unit_coverage)
- return clob is
- l_source_code ut_varchar2_list;
- l_result clob;
-
- function build_details_file_content(a_object_id varchar2, a_object_full_name varchar2, a_source_code ut_varchar2_list, a_coverage_unit ut_coverage.t_unit_coverage)
- return clob is
- l_file_part varchar2(32767);
- l_result clob;
- l_coverage_pct number(5, 2);
- l_coverage_block_pct number(5, 2);
- l_hits varchar2(30);
- begin
- dbms_lob.createtemporary(l_result, true);
-
- l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines);
-
- l_file_part := '
';
- ut_utils.append_to_clob(l_result, l_file_part);
-
- for line_no in 1 .. a_source_code.count loop
- if not a_coverage_unit.lines.exists(line_no) then
- l_file_part := '
-
';
-
- ut_utils.append_to_clob(l_result, l_file_part);
- return l_result;
- end;
-
-end;
-/
diff --git a/source/reporters/ut_proftab_report_html_helper.pks b/source/reporters/ut_proftab_report_html_helper.pks
deleted file mode 100644
index 59316f9bf..000000000
--- a/source/reporters/ut_proftab_report_html_helper.pks
+++ /dev/null
@@ -1,21 +0,0 @@
-create or replace package ut_proftab_report_html_helper authid current_user is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2017 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- function get_index(a_coverage_data ut_coverage.t_coverage, a_assets_path varchar2, a_project_name varchar2 := null, a_command_line varchar2 := null) return clob;
-
-end;
-/