From 287590b098b7d53d6ea59b5cef63b512e6e1e9bd Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 11 Mar 2018 12:11:41 +0000 Subject: [PATCH 01/37] 12.2 Stable : Adding a types required to support block coverage Updated html reporter Changed name of get raw data coverage for profiler to allow execution of block one. Get coverage data have now logical block to allow run type of proftab or block coverage (block will be added in next iteration). Signed-off-by: lwasylow --- source/api/ut.pkb | 56 +-- source/api/ut.pks | 24 +- source/api/ut_runner.pkb | 5 +- source/api/ut_runner.pks | 2 +- source/core/coverage/ut_coverage.pkb | 30 +- source/core/coverage/ut_coverage.pks | 51 ++- source/core/coverage/ut_coverage_helper.pkb | 35 +- source/core/coverage/ut_coverage_helper.pks | 2 +- source/core/types/ut_coverage_options.tps | 3 +- source/core/types/ut_run.tpb | 12 +- source/core/types/ut_run.tps | 3 +- .../ut_coverage_cobertura_reporter.tpb | 2 +- .../reporters/ut_coverage_html_reporter.tpb | 2 +- .../ut_coverage_report_html_helper.pkb | 359 ++++++++++++------ .../ut_coverage_report_html_helper.pks | 2 +- .../reporters/ut_coverage_sonar_reporter.tpb | 2 +- source/reporters/ut_coveralls_reporter.tpb | 2 +- 17 files changed, 384 insertions(+), 208 deletions(-) diff --git a/source/api/ut.pkb b/source/api/ut.pkb index 7ac52ba0c..12cbac451 100644 --- a/source/api/ut.pkb +++ b/source/api/ut.pkb @@ -96,14 +96,14 @@ create or replace package body ut is procedure run_autonomous( a_paths ut_varchar2_list, a_reporter ut_reporter_base, a_color_console integer, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings, a_test_file_mappings ut_file_mappings, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings, a_test_file_mappings ut_file_mappings, a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list ) is pragma autonomous_transaction; begin ut_runner.run( a_paths, ut_reporters(coalesce(a_reporter,ut_documentation_reporter())), - ut_utils.int_to_boolean(a_color_console), a_coverage_schemes, + ut_utils.int_to_boolean(a_color_console), a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects ); rollback; @@ -111,14 +111,14 @@ create or replace package body ut is procedure run_autonomous( a_paths ut_varchar2_list, a_reporter ut_reporter_base, a_color_console integer, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list ) is pragma autonomous_transaction; begin ut_runner.run( a_paths, ut_reporters(coalesce(a_reporter,ut_documentation_reporter())), - ut_utils.int_to_boolean(a_color_console), a_coverage_schemes, + ut_utils.int_to_boolean(a_color_console), a_coverage_schemes,a_coverage_type, ut_file_mapper.build_file_mappings(a_source_files), ut_file_mapper.build_file_mappings(a_test_files), a_include_objects, a_exclude_objects @@ -128,7 +128,7 @@ create or replace package body ut is function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); @@ -138,7 +138,7 @@ create or replace package body ut is begin run_autonomous( l_paths, l_reporter, a_color_console, - a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects + a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -153,7 +153,7 @@ create or replace package body ut is function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); @@ -162,7 +162,7 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + l_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then @@ -178,7 +178,7 @@ create or replace package body ut is function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); @@ -186,7 +186,7 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - a_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then @@ -202,7 +202,7 @@ create or replace package body ut is function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); @@ -210,7 +210,7 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - a_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + a_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then @@ -226,7 +226,7 @@ create or replace package body ut is function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); @@ -235,7 +235,7 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + l_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then @@ -251,7 +251,7 @@ create or replace package body ut is function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); @@ -260,7 +260,7 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + l_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then @@ -276,13 +276,13 @@ create or replace package body ut is procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); begin run_autonomous( - a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then @@ -292,13 +292,13 @@ create or replace package body ut is procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); begin run_autonomous( - a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes, a_source_files, a_test_files, + a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then @@ -308,50 +308,50 @@ create or replace package body ut is procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is begin ut.run( ut_varchar2_list(sys_context('userenv', 'current_schema')), a_reporter, a_color_console, - a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects + a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects ); end; procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is begin ut.run( ut_varchar2_list(sys_context('userenv', 'current_schema')), a_reporter, a_color_console, - a_coverage_schemes, a_source_files, a_test_files, a_include_objects, a_exclude_objects + a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, a_include_objects, a_exclude_objects ); end; procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); begin ut.run( - l_paths, a_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + l_paths, a_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects ); end; procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); begin ut.run( - l_paths, a_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + l_paths, a_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, a_include_objects, a_exclude_objects ); end; diff --git a/source/api/ut.pks b/source/api/ut.pks index ad6ea9757..f479f12fd 100644 --- a/source/api/ut.pks +++ b/source/api/ut.pks @@ -49,73 +49,73 @@ create or replace package ut authid current_user as function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index 6953baba8..b1d059a5c 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -66,7 +66,7 @@ create or replace package body ut_runner is procedure run( a_paths ut_varchar2_list, a_reporters ut_reporters, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2 := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false ) is l_items_to_run ut_run; @@ -88,7 +88,8 @@ create or replace package body ut_runner is to_ut_object_list(a_exclude_objects), to_ut_object_list(a_include_objects), set(a_source_file_mappings), - set(a_test_file_mappings) + set(a_test_file_mappings), + a_coverage_type ); l_items_to_run.do_execute(l_listener); diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index 582f63073..65341b9e0 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -57,7 +57,7 @@ create or replace package ut_runner authid current_user is */ procedure run( a_paths ut_varchar2_list, a_reporters ut_reporters, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2 := null , a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false ); diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index 5bc372341..dd85cede5 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -16,8 +16,19 @@ create or replace package body ut_coverage is limitations under the License. */ + type t_source_lines is table of binary_integer; + procedure set_coverage_type(a_coverage_type in varchar2) is + begin + g_coverage_type := a_coverage_type; + end; + + function get_coverage_type return varchar2 is + begin + return g_coverage_type; + end; + -- 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: @@ -175,7 +186,7 @@ create or replace package body ut_coverage is ut_coverage_helper.coverage_stop_develop(); end; - function get_coverage_data(a_coverage_options ut_coverage_options) return t_coverage is + 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; @@ -193,7 +204,7 @@ create or replace package body ut_coverage is exit when l_source_objects_crsr%notfound; --get coverage data - l_line_calls := ut_coverage_helper.get_raw_coverage_data( l_source_object.owner, l_source_object.name ); + 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 @@ -238,7 +249,7 @@ create or replace package body ut_coverage is 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) := l_line_calls(line_no); + l_result.objects(l_source_object.full_name).lines(line_no).executions := l_line_calls(line_no); line_no := l_line_calls.next(line_no); end loop; @@ -250,7 +261,18 @@ create or replace package body ut_coverage is close l_source_objects_crsr; return l_result; - end get_coverage_data; + end get_coverage_data_profiler; + function get_coverage_data(a_coverage_options ut_coverage_options) return t_coverage is + begin + + if get_coverage_type = 'block' then + null; + --return get_coverage_data_block(a_coverage_options => a_coverage_options); + else + return get_coverage_data_profiler(a_coverage_options => a_coverage_options); + end if; + end get_coverage_data; + end; / diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks index 68f49d86a..10b5c9d85 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -17,35 +17,52 @@ create or replace package ut_coverage authid current_user is */ -- total run coverage information - subtype t_full_name is varchar2(4000); + subtype t_full_name is varchar2(4000); subtype t_object_name is varchar2(250); - subtype t_line_executions is binary_integer; + --subtype t_line_executions is binary_integer; + + type t_line_executions is record( + executions binary_integer + ,partcove binary_integer + ,no_blocks binary_integer + ,covered_blocks binary_integer); -- line coverage information indexed by line no. + --type tt_lines is table of t_line_executions index by binary_integer; type tt_lines is table of t_line_executions index by binary_integer; --unit coverage information record - type t_unit_coverage is record ( - owner varchar2(128), - name varchar2(128), - covered_lines binary_integer := 0, - uncovered_lines binary_integer := 0, - total_lines binary_integer := 0, - executions number(38,0) := 0, - lines tt_lines - ); + type t_unit_coverage is record( + owner varchar2(128) + ,name varchar2(128) + ,covered_lines binary_integer := 0 + ,uncovered_lines binary_integer := 0 + ,partcovered_lines binary_integer := 0 + ,total_blocks binary_integer default null + ,covered_blocks binary_integer default null + ,uncovered_blocks binary_integer default null + ,total_lines binary_integer := 0 + ,executions number(38, 0) := 0 + ,lines tt_lines); -- coverage information indexed by full object name (schema.object) type tt_program_units is table of t_unit_coverage index by t_full_name; -- total run coverage information type t_coverage is record( - covered_lines binary_integer := 0, - uncovered_lines binary_integer := 0, - total_lines binary_integer := 0, - executions number(38,0) := 0, - objects tt_program_units - ); + covered_lines binary_integer := 0 + ,uncovered_lines binary_integer := 0 + ,partcovered_lines binary_integer := 0 + ,total_lines binary_integer default null + ,total_blocks binary_integer default null + ,covered_blocks binary_integer default null + ,uncovered_blocks binary_integer default null + ,executions number(38, 0) := 0 + ,objects tt_program_units); + + g_coverage_type varchar2(32); + function get_coverage_type return varchar2; + procedure coverage_start; /* diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index b4bd79705..a5e6a0628 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -27,9 +27,14 @@ create or replace package body ut_coverage_helper is procedure coverage_start_internal(a_run_comment varchar2) is begin - dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id); + -- Make it dynamic to allow for block coverage. + if ut_coverage.get_coverage_type = 'block' then + null; + else + dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id); + coverage_pause(); + end if; g_is_started := true; - coverage_pause(); end; procedure coverage_start(a_run_comment varchar2) is @@ -52,21 +57,33 @@ create or replace package body ut_coverage_helper is l_return_code binary_integer; begin if not g_develop_mode then - l_return_code := dbms_profiler.pause_profiler(); + if ut_coverage.get_coverage_type = 'block' then + null; + else + l_return_code := dbms_profiler.pause_profiler(); + end if; end if; end; procedure coverage_resume is l_return_code binary_integer; begin - l_return_code := dbms_profiler.resume_profiler(); + if ut_coverage.get_coverage_type = 'block' then + null; + else + l_return_code := dbms_profiler.resume_profiler(); + end if; end; procedure coverage_stop is begin if not g_develop_mode then g_is_started := false; - dbms_profiler.stop_profiler(); + if ut_coverage.get_coverage_type = 'block' then + null; + else + dbms_profiler.stop_profiler(); + end if; end if; end; @@ -74,10 +91,14 @@ create or replace package body ut_coverage_helper is begin g_develop_mode := false; g_is_started := false; - dbms_profiler.stop_profiler(); + if ut_coverage.get_coverage_type = 'block' then + null; + else + dbms_profiler.stop_profiler(); + end if; end; - function get_raw_coverage_data(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls is + function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls is type coverage_row is record ( line binary_integer, calls number(38,0) diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index 3bd76a3c5..1b6ab13eb 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -58,7 +58,7 @@ create or replace package ut_coverage_helper authid definer is procedure coverage_resume; - function get_raw_coverage_data(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls; + function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls; /*** * Allows overwriting of private global variable g_coverage_id diff --git a/source/core/types/ut_coverage_options.tps b/source/core/types/ut_coverage_options.tps index 61caffe1b..1710ca1ef 100644 --- a/source/core/types/ut_coverage_options.tps +++ b/source/core/types/ut_coverage_options.tps @@ -19,6 +19,7 @@ create or replace type ut_coverage_options as object ( schema_names ut_varchar2_rows, exclude_objects ut_object_names, include_objects ut_object_names, - file_mappings ut_file_mappings + file_mappings ut_file_mappings, + coverage_type varchar2(32) ) / diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb index dac651bb1..ea9f71e9f 100644 --- a/source/core/types/ut_run.tpb +++ b/source/core/types/ut_run.tpb @@ -15,7 +15,7 @@ create or replace type body ut_run as See the License for the specific language governing permissions and limitations under the License. */ - + constructor function ut_run( self in out nocopy ut_run, a_items ut_suite_items, @@ -24,15 +24,18 @@ create or replace type body ut_run as a_exclude_objects ut_object_names := null, a_include_objects ut_object_names := null, a_project_file_mappings ut_file_mappings := null, - a_test_file_mappings ut_file_mappings := null + a_test_file_mappings ut_file_mappings := null, + a_coverage_type varchar2 := null ) return self as result is l_coverage_schema_names ut_varchar2_rows; l_coverage_options ut_coverage_options; l_exclude_objects ut_object_names; + l_coverage_type varchar2(32); 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,'proftab'); + self.run_paths := a_run_paths; self.self_type := $$plsql_unit; self.items := a_items; @@ -42,7 +45,8 @@ create or replace type body ut_run as l_coverage_schema_names, l_exclude_objects multiset union all ut_suite_manager.get_schema_ut_packages(l_coverage_schema_names), a_include_objects, - a_project_file_mappings + a_project_file_mappings, + l_coverage_type ); return; end; diff --git a/source/core/types/ut_run.tps b/source/core/types/ut_run.tps index d072b545a..01b926d7e 100644 --- a/source/core/types/ut_run.tps +++ b/source/core/types/ut_run.tps @@ -31,7 +31,8 @@ create or replace type ut_run under ut_suite_item ( a_exclude_objects ut_object_names := null, a_include_objects ut_object_names := null, a_project_file_mappings ut_file_mappings := null, - a_test_file_mappings ut_file_mappings := null + a_test_file_mappings ut_file_mappings := null, + a_coverage_type varchar2 := null ) return self as result, overriding member procedure mark_as_skipped(self in out nocopy ut_run, a_listener in out nocopy ut_event_listener_base), overriding member function do_execute(self in out nocopy ut_run, a_listener in out nocopy ut_event_listener_base) return boolean, diff --git a/source/reporters/ut_coverage_cobertura_reporter.tpb b/source/reporters/ut_coverage_cobertura_reporter.tpb index edd783ca6..4fec0d9b5 100644 --- a/source/reporters/ut_coverage_cobertura_reporter.tpb +++ b/source/reporters/ut_coverage_cobertura_reporter.tpb @@ -43,7 +43,7 @@ create or replace type body ut_coverage_cobertura_reporter is end loop; else while l_line_no is not null loop - if a_unit_coverage.lines(l_line_no) = 0 then + if a_unit_coverage.lines(l_line_no).executions = 0 then l_file_part := ''||chr(10); else l_file_part := ''||chr(10); diff --git a/source/reporters/ut_coverage_html_reporter.tpb b/source/reporters/ut_coverage_html_reporter.tpb index 4ebb0b2fd..504e34f19 100644 --- a/source/reporters/ut_coverage_html_reporter.tpb +++ b/source/reporters/ut_coverage_html_reporter.tpb @@ -36,7 +36,7 @@ create or replace type body ut_coverage_html_reporter is l_coverage_data := ut_coverage.get_coverage_data(a_run.coverage_options); - self.print_clob( ut_coverage_report_html_helper.get_index( l_coverage_data, self.assets_path, self.project_name ) ); + self.print_clob( ut_coverage_report_html_helper.get_index( a_coverage_data => l_coverage_data,a_assets_path => self.assets_path, a_project_name=> self.project_name, a_coverage_type => a_run.coverage_options.coverage_type ) ); end; diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb index 8a70b9085..2deeb6380 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -2,13 +2,13 @@ create or replace package body ut_coverage_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. @@ -16,18 +16,18 @@ create or replace package body ut_coverage_report_html_helper is limitations under the License. */ - gc_green_coverage_pct constant integer := 90; - gc_yellow_coverage_pct constant integer := 80; - - gc_green_css constant varchar2(10) := 'green'; - gc_yellow_css constant varchar2(10) := 'yellow'; - gc_red_css constant varchar2(10) := 'red'; + gc_green_coverage_pct constant integer := 90; + gc_yellow_coverage_pct constant integer := 80; - gc_missed constant varchar2(7) := 'missed'; - gc_skipped constant varchar2(7) := 'skipped'; - gc_disabled constant varchar2(7) := 'never'; - gc_covered constant varchar2(7) := 'covered'; + gc_green_css constant varchar2(10) := 'green'; + gc_yellow_css constant varchar2(10) := 'yellow'; + gc_red_css constant varchar2(10) := 'red'; + gc_missed constant varchar2(7) := 'missed'; + gc_skipped constant varchar2(7) := 'skipped'; + gc_disabled constant varchar2(7) := 'never'; + gc_covered constant varchar2(7) := 'covered'; + gc_partcovered constant varchar2(7) := 'partcov'; function get_default_html_assets_path return varchar2 deterministic is c_assets_path constant varchar2(200) := 'https://utplsql.github.io/utPLSQL-coverage-html/assets/'; @@ -42,18 +42,22 @@ create or replace package body ut_coverage_report_html_helper is l_result := gc_green_css; elsif a_covered_pct > gc_yellow_coverage_pct then l_result := gc_yellow_css; - else + else l_result := gc_red_css; end if; return l_result; end; - function line_status(a_executions binary_integer) return varchar2 is + function line_status(a_executions in ut_coverage.t_line_executions) return varchar2 is l_result varchar2(10); begin - if a_executions > 0 then - l_result := gc_covered; - elsif a_executions = 0 then + if a_executions.executions > 0 then + if NVL(a_executions.partcove,0) = 0 then + l_result := gc_covered; + else + l_result := gc_partcovered; + end if; + elsif a_executions.executions = 0 then l_result := gc_missed; else l_result := gc_disabled; @@ -63,130 +67,217 @@ create or replace package body ut_coverage_report_html_helper is function executions_per_line(a_executions number, a_lines integer) return integer is begin - return nvl(a_executions/nullif(a_lines,0),0); + return nvl(a_executions / nullif(a_lines, 0), 0); end; function line_hits_css_class(a_line_hist number) return varchar2 is l_result varchar2(10); begin if a_line_hist > 1 then - l_result := gc_green_css; + l_result := gc_green_css; elsif a_line_hist = 1 then - l_result := gc_yellow_css; - else - l_result := gc_red_css; + l_result := gc_yellow_css; + else + l_result := gc_red_css; end if; return l_result; end; function coverage_pct(a_covered_lines integer, a_uncovered_lines integer) return number is begin - return round(nvl(a_covered_lines/nullif(a_covered_lines+a_uncovered_lines,0),0)*100,2); + return ROUND(nvl(a_covered_lines / nullif(a_covered_lines + a_uncovered_lines, 0), 0) * 100, 2); end; function object_id(a_object_full_name varchar2) return varchar2 is begin - return rawtohex( utl_raw.CAST_TO_RAW(dbms_obfuscation_toolkit.md5(input_string=>a_object_full_name)) ); + return rawtohex(utl_raw.cast_to_raw(dbms_obfuscation_toolkit.md5(input_string => a_object_full_name))); end; function link_to_source_file(a_object_full_name varchar2) return varchar2 is begin - return ''||a_object_full_name||''; + 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) return clob is + 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; - - 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_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); - l_coverage_pct := coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines); - l_file_part := - '

'||dbms_xmlgen.convert(a_object_full_name)||'

' || - '

'||l_coverage_pct||' % covered

' || - '
'||(a_coverage_unit.covered_lines+a_coverage_unit.uncovered_lines)||' relevant lines. ' || - ''||a_coverage_unit.covered_lines||' lines covered and ' || - ''||a_coverage_unit.uncovered_lines||' lines missed
' || - '
    '; + + 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 := '

    ' || + dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || + '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || case + when l_coverage_type = 'block' then + '(including ' || a_coverage_unit.partcovered_lines || + ' lines partially covered ' + end || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'|| + case when l_coverage_type = 'block' then + '

    ' || l_coverage_block_pct || ' % blocks covered

    '|| + '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| + ''||a_coverage_unit.covered_blocks||' blocks covered and '|| + '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' + end ||'
      '; 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 :=' -
    1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || '
    2. '; + l_file_part := ' +
    3. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    4. '; else - l_file_part :=' -
    5. '; - if a_coverage_unit.lines(line_no) > 0 then + l_hits := case when l_coverage_type = 'block' then + to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| + to_char(a_coverage_unit.lines(line_no).no_blocks) + else + to_char(a_coverage_unit.lines(line_no).executions) + end; + + l_file_part := ' +
    6. '; + if a_coverage_unit.lines(line_no).executions > 0 then + l_file_part := l_file_part || ' - '||(a_coverage_unit.lines(line_no))||''; + ' || dbms_xmlgen.convert(l_hits) || + ''; end if; l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || '
    7. '; + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + ''; end if; ut_utils.append_to_clob(l_result, l_file_part); end loop; - + l_file_part := '
    '; ut_utils.append_to_clob(l_result, l_file_part); return l_result; end; begin l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result,true); - l_result := build_details_file_content(a_object_id, a_unit.identity, l_source_code, a_unit_coverage); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ,l_coverage_type); return l_result; end; - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage, a_coverage_type varchar2) return clob is l_file_part varchar2(32767); l_title varchar2(100) := 'All files'; - l_coverage_pct number(5,2); + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); l_result clob; l_id varchar2(50) := object_id(a_title); l_unit_coverage ut_coverage.t_unit_coverage; l_unit ut_coverage.t_object_name; + l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); begin - dbms_lob.createtemporary(l_result,true); + if l_coverage_type = 'block' then + l_coverage_block_pct := coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); + end if; + l_coverage_pct := coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - l_file_part := - '
    ' || - '

    '||l_title||'' || - ' ('||l_coverage_pct||'%' || - ' covered at ' || - ''|| - executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines)||' hits/line)

    ' || - '' || - '
    '||a_coverage.objects.count||' files in total. ' || - ''||(a_coverage.uncovered_lines + a_coverage.covered_lines)||' relevant lines. ' || - ''||a_coverage.covered_lines||' lines covered and ' || - ''||a_coverage.uncovered_lines||' lines missed
    ' || - '' || - '' || - '' || - ''; + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
    ' || '

    ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + case when l_coverage_type = 'block' then + ', ' || + l_coverage_block_pct || '%' || ' executed blocks covered)' + else + ' at ' || + '' || + executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' hits/line)' + end || + '

    ' || '' || '
    ' || + a_coverage.objects.count || ' files in total.
    ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered' || case + when l_coverage_type = 'block' then + ' (inlcluding ' || a_coverage.partcovered_lines || + ' lines partially covered' + else + null + end || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + case when l_coverage_type = 'block' then + '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| + ''||a_coverage.covered_blocks||' blocks covered and '|| + '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' + end || + '
    File% coveredLinesRelevant LinesLines coveredLines missedAvg. Hits / Line
    ' || '' || + '' || + ''; ut_utils.append_to_clob(l_result, l_file_part); l_unit := a_coverage.objects.first; loop exit when l_unit is null; l_unit_coverage := a_coverage.objects(l_unit); + + if l_coverage_type = 'block' then + l_coverage_block_pct := coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); + end if; + l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - l_file_part := - chr(10)|| - '' || - '' || - '' || - '' || - '' || - '' || - '' || - '' || - ''; + + + --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' + else + (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || '' + end || '' || + case + when l_coverage_type = 'block' then + ''; ut_utils.append_to_clob(l_result, l_file_part); l_unit := a_coverage.objects.next(l_unit); end loop; @@ -198,59 +289,77 @@ create or replace package body ut_coverage_report_html_helper is /* * public definitions */ - 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 is - - l_file_part varchar2(32767); - l_result clob; - l_title varchar2(250); - l_coverage_pct number(5,2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; + 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 is + + l_file_part varchar2(32767); + l_result clob; + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); begin - l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + if l_coverage_type = 'block' then + l_coverage_pct := coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); + else + l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + end if; + + --l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + l_time_str := ut_utils.to_string(sysdate); - l_using := case when a_command_line is not null then '
    using '||dbms_xmlgen.convert(a_command_line) end; - dbms_lob.createtemporary(l_result,true); - - l_title := case when a_project_name is null then 'Code coverage' else dbms_xmlgen.convert(a_project_name) ||' code coverage' end; + l_using := case + when a_command_line is not null then + '
    using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; --TODO - build main file containing total run data and per schema data - l_file_part := - '' || - ''||l_title||'' || - '' || - '' || - '' || - '' || - '' || - '' || - '
    loading
    ' || - ''; + 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 e25e308a0..67faeb6a1 100644 --- a/source/reporters/ut_coverage_report_html_helper.pks +++ b/source/reporters/ut_coverage_report_html_helper.pks @@ -17,7 +17,7 @@ create or replace package ut_coverage_report_html_helper authid current_user is */ function get_default_html_assets_path return varchar2 deterministic; - 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; + 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_coverage_sonar_reporter.tpb b/source/reporters/ut_coverage_sonar_reporter.tpb index 48b04ffdd..596115d17 100644 --- a/source/reporters/ut_coverage_sonar_reporter.tpb +++ b/source/reporters/ut_coverage_sonar_reporter.tpb @@ -42,7 +42,7 @@ create or replace type body ut_coverage_sonar_reporter is end loop; else while l_line_no is not null loop - if a_unit_coverage.lines(l_line_no) = 0 then + if a_unit_coverage.lines(l_line_no).executions = 0 then l_file_part := ''||chr(10); else l_file_part := ''||chr(10); diff --git a/source/reporters/ut_coveralls_reporter.tpb b/source/reporters/ut_coveralls_reporter.tpb index c13084415..f19d1f3ce 100644 --- a/source/reporters/ut_coveralls_reporter.tpb +++ b/source/reporters/ut_coveralls_reporter.tpb @@ -48,7 +48,7 @@ create or replace type body ut_coveralls_reporter is else for line_no in 1 .. l_last_line_no loop if a_unit_coverage.lines.exists(line_no) then - l_file_part := to_char(a_unit_coverage.lines(line_no)); + l_file_part := to_char(a_unit_coverage.lines(line_no).executions); else l_file_part := c_null; end if; From 68768f8391c263f3fc2fcb3220a1db1e292e2c1c Mon Sep 17 00:00:00 2001 From: lwasylow Date: Tue, 13 Mar 2018 13:08:28 +0000 Subject: [PATCH 02/37] 12.2 Stable : Add block coverage --- source/core/coverage/dbms_plssqlcode.sql | 5 + source/core/coverage/ut_coverage.pkb | 155 +++++++++++++++++- source/core/coverage/ut_coverage.pks | 4 +- source/core/coverage/ut_coverage_helper.pkb | 44 ++++- source/core/coverage/ut_coverage_helper.pks | 12 +- .../coverage/ut_coverage_reporter_base.tpb | 2 +- source/install.sql | 6 + 7 files changed, 212 insertions(+), 16 deletions(-) create mode 100644 source/core/coverage/dbms_plssqlcode.sql diff --git a/source/core/coverage/dbms_plssqlcode.sql b/source/core/coverage/dbms_plssqlcode.sql new file mode 100644 index 000000000..18e7b5580 --- /dev/null +++ b/source/core/coverage/dbms_plssqlcode.sql @@ -0,0 +1,5 @@ +begin + DBMS_PLSQL_CODE_COVERAGE.create_coverage_tables( + force_it => TRUE); +end; +/ diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index dd85cede5..517677511 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -156,13 +156,17 @@ create or replace package body ut_coverage is /** * Public functions */ - procedure coverage_start is + procedure coverage_start(a_coverage_options ut_coverage_options default null) is + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, 'proftab'); begin + set_coverage_type(a_coverage_type => l_coverage_type); ut_coverage_helper.coverage_start('utPLSQL Code coverage run '||ut_utils.to_string(systimestamp)); end; - procedure coverage_start_develop is + procedure coverage_start_develop(a_coverage_options ut_coverage_options default null) is + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, 'proftab'); begin + set_coverage_type(a_coverage_type => l_coverage_type); ut_coverage_helper.coverage_start_develop(); end; @@ -238,18 +242,18 @@ create or replace package body ut_coverage is loop exit when line_no is null; - if l_line_calls(line_no) > 0 then + 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); + 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); - elsif l_line_calls(line_no) = 0 then + 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); + 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; @@ -263,12 +267,145 @@ create or replace package body ut_coverage is 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 get_coverage_type = 'block' then - null; - --return get_coverage_data_block(a_coverage_options => a_coverage_options); + return get_coverage_data_block(a_coverage_options => a_coverage_options); else return get_coverage_data_profiler(a_coverage_options => a_coverage_options); end if; diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks index 10b5c9d85..7f5f5507c 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -63,12 +63,12 @@ create or replace package ut_coverage authid current_user is function get_coverage_type return varchar2; - procedure coverage_start; + procedure coverage_start(a_coverage_options ut_coverage_options default null); /* * Start coverage in develop mode, where all internal calls to utPLSQL itself are also included */ - procedure coverage_start_develop; + procedure coverage_start_develop(a_coverage_options ut_coverage_options default null); procedure coverage_stop; diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index a5e6a0628..9d4a18737 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -29,7 +29,7 @@ create or replace package body ut_coverage_helper is begin -- Make it dynamic to allow for block coverage. if ut_coverage.get_coverage_type = 'block' then - null; + g_coverage_id := dbms_plsql_code_coverage.start_coverage(run_comment => a_run_comment); else dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id); coverage_pause(); @@ -80,7 +80,7 @@ create or replace package body ut_coverage_helper is if not g_develop_mode then g_is_started := false; if ut_coverage.get_coverage_type = 'block' then - null; + dbms_plsql_code_coverage.stop_coverage; else dbms_profiler.stop_profiler(); end if; @@ -126,7 +126,45 @@ create or replace package body ut_coverage_helper is and u.unit_type not in ('PACKAGE SPEC', 'TYPE SPEC', 'ANONYMOUS BLOCK') group by d.line#; for i in 1 .. l_tmp_data.count loop - l_results(l_tmp_data(i).line) := l_tmp_data(i).calls; + l_results(l_tmp_data(i).line).calls := l_tmp_data(i).calls; + end loop; + return l_results; + end; + + function get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls is + type coverage_row is record( + line binary_integer + ,blocks binary_integer + ,covered_blocks binary_integer); + type coverage_rows is table of coverage_row; + l_tmp_data coverage_rows; + l_results t_unit_line_calls; + + begin + select ccb.line + ,count(ccb.block) totalblocks + ,sum(ccb.covered) as coveredblocks bulk collect + into l_tmp_data + 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.owner = a_object_owner + and ccu.name = a_object_name + and ccu.run_id = g_coverage_id + group by ccb.line + order by 1; + + 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; diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index 1b6ab13eb..9688d5894 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -18,7 +18,15 @@ create or replace package ut_coverage_helper authid definer is --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; + --type t_unit_line_calls is table of number(38,0) index by binary_integer; + + type t_unit_line_call is record( + blocks binary_integer default 0 + ,covered_blocks binary_integer default 0 + ,partcovered binary_integer default 0 + ,calls binary_integer default 0); + + type t_unit_line_calls is table of t_unit_line_call index by binary_integer; type t_coverage_sources_tmp_row is record ( full_name ut_coverage_sources_tmp.full_name%type, @@ -60,6 +68,8 @@ create or replace package ut_coverage_helper authid definer is 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_reporter_base.tpb b/source/core/coverage/ut_coverage_reporter_base.tpb index cf8135ba5..7cde025e2 100644 --- a/source/core/coverage/ut_coverage_reporter_base.tpb +++ b/source/core/coverage/ut_coverage_reporter_base.tpb @@ -19,7 +19,7 @@ create or replace type body ut_coverage_reporter_base is overriding final member procedure before_calling_run(self in out nocopy ut_coverage_reporter_base, a_run ut_run) as begin (self as ut_output_reporter_base).before_calling_run(a_run); - ut_coverage.coverage_start(); + ut_coverage.coverage_start(a_coverage_options => a_run.coverage_options); end; overriding final member procedure before_calling_before_all(self in out nocopy ut_coverage_reporter_base, a_suite in ut_logical_suite) is diff --git a/source/install.sql b/source/install.sql index 69be9317c..9a1b2457f 100644 --- a/source/install.sql +++ b/source/install.sql @@ -114,6 +114,12 @@ alter session set current_schema = &&ut3_owner; prompt Installing PLSQL profiler objects into &&ut3_owner schema @@core/coverage/proftab.sql +prompt Installing PLSQL profiler objects into &&ut3_owner schema +@@core/coverage/proftab.sql + +prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema +@@core/coverage/dbms_plssqlcode.sql + @@install_component.sql 'core/ut_file_mapper.pks' @@install_component.sql 'core/ut_file_mapper.pkb' From 76bf86973995bb760a473c8b34c74b94d7d15a16 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Tue, 13 Mar 2018 20:35:42 +0000 Subject: [PATCH 03/37] 12.2 Stable : Moved get raw coverage into dynamic cursors to minimize impact on compilation --- source/core/coverage/ut_coverage_helper.pkb | 97 +++++++++++++-------- 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index 9d4a18737..e5b62ca20 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -20,15 +20,33 @@ create or replace package body ut_coverage_helper is g_develop_mode boolean not null := false; g_is_started boolean not null := false; + + 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; + function is_develop_mode return boolean is begin return g_develop_mode; end; procedure coverage_start_internal(a_run_comment varchar2) is + --l_start_block varchar2(32767):= 'call dbms_plsql_code_coverage.start_coverage(run_comment => :a_run_comment) + -- into :g_coverage_id'; begin -- Make it dynamic to allow for block coverage. if ut_coverage.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 dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id); @@ -98,63 +116,70 @@ create or replace package body ut_coverage_helper is end if; end; - function get_raw_coverage_data_profiler(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls is - type coverage_row is record ( - line binary_integer, - calls number(38,0) - ); - type coverage_rows is table of coverage_row; - l_tmp_data coverage_rows; - l_results t_unit_line_calls; + 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 - select d.line#, - -- This transformation addresses two issues: - -- 1. dbms_profiler shows multiple unit_number for single code unit; - -- to address this, we take a sum od all units by name - -- 2. some lines show 0 total_occur while they were executed (time > 0) - -- in this case we show 1 to indicate that there was execution even if we don't know how many there were + 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 - bulk collect into l_tmp_data 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 - --exclude specification + 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#; + 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 get_raw_coverage_data_block(a_object_owner varchar2, a_object_name varchar2) return t_unit_line_calls is - type coverage_row is record( - line binary_integer - ,blocks binary_integer - ,covered_blocks binary_integer); - type coverage_rows is table of coverage_row; - l_tmp_data coverage_rows; - l_results t_unit_line_calls; - + 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 - select ccb.line + open c_raw_coverage for q'[select ccb.line ,count(ccb.block) totalblocks - ,sum(ccb.covered) as coveredblocks bulk collect - into l_tmp_data + ,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.owner = a_object_owner - and ccu.name = a_object_name - and ccu.run_id = g_coverage_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; + 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; From 1f4f5f0dff19087b107226a7331cc8b03e79314a Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 14 Mar 2018 07:29:20 +0000 Subject: [PATCH 04/37] Tests 12.2 Coverage: Added Some more tests for test block coverage. --- test/core/reporters/test_block_coverage.pkb | 161 ++++++++++++++++++++ test/core/reporters/test_block_coverage.pks | 22 +++ test/core/reporters/test_coverage.pkb | 74 +++++++++ test/core/reporters/test_coverage.pks | 15 +- test/install_tests.sql | 2 + 5 files changed, 271 insertions(+), 3 deletions(-) create mode 100644 test/core/reporters/test_block_coverage.pkb create mode 100644 test/core/reporters/test_block_coverage.pks diff --git a/test/core/reporters/test_block_coverage.pkb b/test/core/reporters/test_block_coverage.pkb new file mode 100644 index 000000000..4e8237ff0 --- /dev/null +++ b/test/core/reporters/test_block_coverage.pkb @@ -0,0 +1,161 @@ +create or replace package body test_block_coverage is + + g_run_id integer; + + function get_mock_run_id return integer is + v_result integer; + begin + select nvl(min(run_id),0) - 1 into v_result + from ut3.dbmspcc_runs; + return v_result; + end; + + procedure create_dummy_coverage_package is + pragma autonomous_transaction; + begin + execute immediate q'[create or replace package UT3.DUMMY_COVERAGE is + procedure do_stuff(i_input in number); + end;]'; + execute immediate q'[create or replace package body UT3.DUMMY_COVERAGE is + procedure do_stuff(i_input in number) is + begin + if i_input = 2 then + dbms_output.put_line('should not get here'); + else + dbms_output.put_line('should get here'); + end if; + end; + end;]'; + end; + + procedure create_dummy_coverage_test is + pragma autonomous_transaction; + begin + execute immediate q'[create or replace package UT3.TEST_DUMMY_COVERAGE is + --%suite(dummy coverage test) + --%suitepath(coverage_testing) + + --%test + procedure test_do_stuff; + end;]'; + execute immediate q'[create or replace package body UT3.TEST_DUMMY_COVERAGE is + procedure test_do_stuff is + begin + dummy_coverage.do_stuff(1); + ut.expect(1).to_equal(1); + end; + end;]'; + end; + + procedure mock_coverage_data(a_run_id integer) is + c_unit_id constant integer := 1; + begin + insert into ut3.dbmspcc_runs ( run_id, run_owner, run_timestamp, run_comment) + values(a_run_id, user, sysdate, 'unit testing utPLSQL'); + + insert into ut3.dbmspcc_units ( run_id, object_id, type, owner, name,last_ddl_time) + values(a_run_id, c_unit_id, 'PACKAGE BODY', 'UT3', 'DUMMY_COVERAGE',sysdate); + + insert into ut3.dbmspcc_blocks ( run_id, object_id, line,block,col,covered,not_feasible) + select a_run_id, c_unit_id,4,1,1,1,0 from dual union all + select a_run_id, c_unit_id,5,2,0 ,1,0 from dual union all + select a_run_id, c_unit_id,7,3,1,1,0 from dual; + end; + + procedure setup_dummy_coverage is + pragma autonomous_transaction; + begin + create_dummy_coverage_package(); + create_dummy_coverage_test(); + g_run_id := get_mock_run_id(); + ut3.ut_coverage_helper.mock_coverage_id(g_run_id); + mock_coverage_data(g_run_id); + commit; + end; + + procedure cleanup_dummy_coverage is + pragma autonomous_transaction; + begin + begin execute immediate q'[drop package ut3.test_dummy_coverage]'; exception when others then null; end; + begin execute immediate q'[drop package ut3.dummy_coverage]'; exception when others then null; end; + delete from ut3.dbmspcc_blocks where run_id = g_run_id; + delete from ut3.dbmspcc_units where run_id = g_run_id; + delete from ut3.dbmspcc_runs where run_id = g_run_id; + commit; + end; + + procedure coverage_for_object is + l_expected clob; + l_actual clob; + l_results ut3.ut_varchar2_list; + begin + --Arrange + l_expected := '%%'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_sonar_reporter( ), + a_coverage_type => 'block', + a_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage' ) + ) + ); + --Assert + l_actual := ut3.ut_utils.table_to_clob(l_results); + ut.expect(l_actual).to_be_like(l_expected); + end; + + procedure coverage_for_schema is + l_expected clob; + l_actual clob; + l_results ut3.ut_varchar2_list; + begin + --Arrange + l_expected := ''; + l_expected := '%'||l_expected||'%'||l_expected||'%'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_sonar_reporter( ), + a_coverage_type => 'block', + a_coverage_schemes => ut3.ut_varchar2_list( 'ut3' ) + ) + ); + --Assert + l_actual := ut3.ut_utils.table_to_clob(l_results); + ut.expect(l_actual).to_be_like(l_expected); + end; + + procedure coverage_for_file is + l_expected clob; + l_actual clob; + l_results ut3.ut_varchar2_list; + l_file_path varchar2(100); + begin + --Arrange + l_file_path := lower('test/ut3.dummy_coverage.pkb'); + l_expected := '%%'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_sonar_reporter( ), + a_coverage_type => 'block', + a_source_files => ut3.ut_varchar2_list( l_file_path ), + a_test_files => ut3.ut_varchar2_list( ) + ) + ); + --Assert + l_actual := ut3.ut_utils.table_to_clob(l_results); + ut.expect(l_actual).to_be_like(l_expected); + end; + +end; +/ diff --git a/test/core/reporters/test_block_coverage.pks b/test/core/reporters/test_block_coverage.pks new file mode 100644 index 000000000..8f65a6ca8 --- /dev/null +++ b/test/core/reporters/test_block_coverage.pks @@ -0,0 +1,22 @@ +create or replace package test_block_coverage is + + --%suite + --%suitepath(utplsql.core.reporters) + + --%beforeall + procedure setup_dummy_coverage; + + --%afterall + procedure cleanup_dummy_coverage; + + --%test(Coverage is gathered for specified object - block coverage type) + procedure coverage_for_object; + + --%test(Coverage is gathered for specified schema - block coverage type) + procedure coverage_for_schema; + + --%test(Coverage is gathered for specified file - block coverage type) + procedure coverage_for_file; + +end; +/ diff --git a/test/core/reporters/test_coverage.pkb b/test/core/reporters/test_coverage.pkb index 978c4b8bb..ca8b704d9 100644 --- a/test/core/reporters/test_coverage.pkb +++ b/test/core/reporters/test_coverage.pkb @@ -192,6 +192,80 @@ create or replace package body test_coverage is ut.expect(l_actual).to_be_like(l_expected); end; + procedure coverage_for_object_proftab is + l_expected clob; + l_actual clob; + l_results ut3.ut_varchar2_list; + begin + --Arrange + l_expected := '%%'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_sonar_reporter( ), + a_coverage_type => 'proftab', + a_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage' ) + ) + ); + --Assert + l_actual := ut3.ut_utils.table_to_clob(l_results); + ut.expect(l_actual).to_be_like(l_expected); + end; + + procedure coverage_for_schema_proftab is + l_expected clob; + l_actual clob; + l_results ut3.ut_varchar2_list; + begin + --Arrange + l_expected := ''; + l_expected := '%'||l_expected||'%'||l_expected||'%'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_sonar_reporter( ), + a_coverage_type => 'proftab', + a_coverage_schemes => ut3.ut_varchar2_list( 'ut3' ) + ) + ); + --Assert + l_actual := ut3.ut_utils.table_to_clob(l_results); + ut.expect(l_actual).to_be_like(l_expected); + end; + + procedure coverage_for_file_proftab is + l_expected clob; + l_actual clob; + l_results ut3.ut_varchar2_list; + l_file_path varchar2(100); + begin + --Arrange + l_file_path := lower('test/ut3.dummy_coverage.pkb'); + l_expected := '%%'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_sonar_reporter( ), + a_coverage_type => 'proftab', + a_source_files => ut3.ut_varchar2_list( l_file_path ), + a_test_files => ut3.ut_varchar2_list( ) + ) + ); + --Assert + l_actual := ut3.ut_utils.table_to_clob(l_results); + ut.expect(l_actual).to_be_like(l_expected); + end; + + procedure coverage_tmp_data_refresh is l_actual clob; l_results ut3.ut_varchar2_list; diff --git a/test/core/reporters/test_coverage.pks b/test/core/reporters/test_coverage.pks index bd6948ee2..61984a8ec 100644 --- a/test/core/reporters/test_coverage.pks +++ b/test/core/reporters/test_coverage.pks @@ -10,15 +10,24 @@ create or replace package test_coverage is procedure cleanup_dummy_coverage; - --%test(Coverage is gathered for specified object) + --%test(Coverage is gathered for specified object - default coverage type) procedure coverage_for_object; - --%test(Coverage is gathered for specified schema) + --%test(Coverage is gathered for specified schema - default coverage type) procedure coverage_for_schema; - --%test(Coverage is gathered for specified file) + --%test(Coverage is gathered for specified file - default coverage type) procedure coverage_for_file; + --%test(Coverage is gathered for specified object - explicit proftab coverage) + procedure coverage_for_object_proftab; + + --%test(Coverage is gathered for specified schema - explicit proftab coverag) + procedure coverage_for_schema_proftab; + + --%test(Coverage is gathered for specified file - explicit proftab coverag) + procedure coverage_for_file_proftab; + --%test(Coverage data is not cached between runs - issue #562 ) --%aftertest(setup_dummy_coverage) procedure coverage_tmp_data_refresh; diff --git a/test/install_tests.sql b/test/install_tests.sql index eca77b215..042d842e7 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -25,6 +25,7 @@ whenever oserror exit failure rollback @@core/test_output_buffer.pks @@core/test_suite_manager.pks @@core/reporters/test_coverage.pks +@@core/reporters/test_block_coverage.pks @@core/reporters/test_coverage/test_coverage_sonar_reporter.pks @@core/reporters/test_coverage/test_coveralls_reporter.pks @@core/reporters/test_coverage/test_cov_cobertura_reporter.pks @@ -56,6 +57,7 @@ whenever oserror exit failure rollback @@core/test_output_buffer.pkb @@core/test_suite_manager.pkb @@core/reporters/test_coverage.pkb +@@core/reporters/test_block_coverage.pkb @@core/reporters/test_coverage/test_coverage_sonar_reporter.pkb @@core/reporters/test_coverage/test_coveralls_reporter.pkb @@core/reporters/test_coverage/test_cov_cobertura_reporter.pkb From 90858ebb8ac790e9e113d8e6fa0a69e42df545de Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 14 Mar 2018 19:26:51 +0000 Subject: [PATCH 05/37] Added 12.2 coverage Fixes to cycle dependancies --- source/core/coverage/ut_coverage.pkb | 18 ++---------- source/core/coverage/ut_coverage.pks | 4 --- source/core/coverage/ut_coverage_helper.pkb | 31 ++++++++++++++------- source/core/coverage/ut_coverage_helper.pks | 11 ++++++-- 4 files changed, 33 insertions(+), 31 deletions(-) diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index 517677511..d09a672be 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -19,16 +19,6 @@ create or replace package body ut_coverage is type t_source_lines is table of binary_integer; - procedure set_coverage_type(a_coverage_type in varchar2) is - begin - g_coverage_type := a_coverage_type; - end; - - function get_coverage_type return varchar2 is - begin - return g_coverage_type; - end; - -- 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: @@ -159,15 +149,13 @@ create or replace package body ut_coverage is procedure coverage_start(a_coverage_options ut_coverage_options default null) is l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, 'proftab'); begin - set_coverage_type(a_coverage_type => l_coverage_type); - ut_coverage_helper.coverage_start('utPLSQL Code coverage run '||ut_utils.to_string(systimestamp)); + 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, 'proftab'); begin - set_coverage_type(a_coverage_type => l_coverage_type); - ut_coverage_helper.coverage_start_develop(); + ut_coverage_helper.coverage_start_develop(l_coverage_type); end; procedure coverage_pause is @@ -404,7 +392,7 @@ create or replace package body ut_coverage is function get_coverage_data(a_coverage_options ut_coverage_options) return t_coverage is begin - if get_coverage_type = 'block' then + if a_coverage_options.coverage_type = 'block' then return get_coverage_data_block(a_coverage_options => a_coverage_options); else return get_coverage_data_profiler(a_coverage_options => a_coverage_options); diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks index 7f5f5507c..8a7df49ed 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -58,10 +58,6 @@ create or replace package ut_coverage authid current_user is ,uncovered_blocks binary_integer default null ,executions number(38, 0) := 0 ,objects tt_program_units); - - g_coverage_type varchar2(32); - - function get_coverage_type return varchar2; procedure coverage_start(a_coverage_options ut_coverage_options default null); diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index e5b62ca20..5b0469e85 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -35,17 +35,28 @@ create or replace package body ut_coverage_helper is type t_block_rows is table of t_block_row; + procedure set_coverage_type(a_coverage_type in varchar2) is + begin + g_coverage_type := a_coverage_type; + end; + + function get_coverage_type return varchar2 is + begin + return g_coverage_type; + end; + function is_develop_mode return boolean is begin return g_develop_mode; end; - procedure coverage_start_internal(a_run_comment varchar2) is + 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); -- Make it dynamic to allow for block coverage. - if ut_coverage.get_coverage_type = 'block' then + 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 @@ -55,19 +66,19 @@ create or replace package body ut_coverage_helper is g_is_started := true; end; - procedure coverage_start(a_run_comment varchar2) is + procedure coverage_start(a_run_comment varchar2,a_coverage_type in varchar2) is begin if not g_is_started then g_develop_mode := false; - coverage_start_internal(a_run_comment); + coverage_start_internal(a_run_comment,a_coverage_type); end if; end; - procedure coverage_start_develop is + procedure coverage_start_develop(a_coverage_type in varchar2) is begin if not g_is_started then g_develop_mode := true; - coverage_start_internal('utPLSQL Code coverage run in development MODE '||ut_utils.to_string(systimestamp)); + coverage_start_internal('utPLSQL Code coverage run in development MODE '||ut_utils.to_string(systimestamp),a_coverage_type); end if; end; @@ -75,7 +86,7 @@ create or replace package body ut_coverage_helper is l_return_code binary_integer; begin if not g_develop_mode then - if ut_coverage.get_coverage_type = 'block' then + if get_coverage_type = 'block' then null; else l_return_code := dbms_profiler.pause_profiler(); @@ -86,7 +97,7 @@ create or replace package body ut_coverage_helper is procedure coverage_resume is l_return_code binary_integer; begin - if ut_coverage.get_coverage_type = 'block' then + if get_coverage_type = 'block' then null; else l_return_code := dbms_profiler.resume_profiler(); @@ -97,7 +108,7 @@ create or replace package body ut_coverage_helper is begin if not g_develop_mode then g_is_started := false; - if ut_coverage.get_coverage_type = 'block' then + if get_coverage_type = 'block' then dbms_plsql_code_coverage.stop_coverage; else dbms_profiler.stop_profiler(); @@ -109,7 +120,7 @@ create or replace package body ut_coverage_helper is begin g_develop_mode := false; g_is_started := false; - if ut_coverage.get_coverage_type = 'block' then + if get_coverage_type = 'block' then null; else dbms_profiler.stop_profiler(); diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index 9688d5894..bf6c60df8 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -16,6 +16,13 @@ create or replace package ut_coverage_helper authid definer is limitations under the License. */ + + g_coverage_type varchar2(32); + + function get_coverage_type return varchar2; + + procedure set_coverage_type(a_coverage_type in varchar2); + --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; @@ -51,12 +58,12 @@ create or replace package ut_coverage_helper authid definer is function is_develop_mode return boolean; - procedure coverage_start(a_run_comment varchar2); + procedure coverage_start(a_run_comment in varchar2,a_coverage_type in varchar2); /* * Start coverage in develop mode, where all internal calls to utPLSQL itself are also included */ - procedure coverage_start_develop; + procedure coverage_start_develop(a_coverage_type in varchar2); procedure coverage_stop; From d77cf9a99d2161aa805f75d65fa1e8a26092dd1e Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 14 Mar 2018 19:27:26 +0000 Subject: [PATCH 06/37] Test 12.2 coverage Added test to cover for block coverage in regression --- .../test_cov_cobertura_rptr_blk.pkb | 45 +++++++++++++++++++ .../test_cov_cobertura_rptr_blk.pks | 10 +++++ .../test_coverage_sonar_rprt_blk.pkb | 34 ++++++++++++++ .../test_coverage_sonar_rprt_blk.pks | 10 +++++ .../test_coveralls_reporter_block.pkb | 31 +++++++++++++ .../test_coveralls_reporter_block.pks | 10 +++++ .../test_html_block_reporter.pkb | 29 ++++++++++++ .../test_html_block_reporter.pks | 10 +++++ .../test_html_proftab_reporter.pkb | 30 +++++++++++++ .../test_html_proftab_reporter.pks | 10 +++++ test/install_tests.sql | 10 +++++ 11 files changed, 229 insertions(+) create mode 100644 test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb create mode 100644 test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks create mode 100644 test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb create mode 100644 test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks create mode 100644 test/core/reporters/test_coverage/test_coveralls_reporter_block.pkb create mode 100644 test/core/reporters/test_coverage/test_coveralls_reporter_block.pks create mode 100644 test/core/reporters/test_coverage/test_html_block_reporter.pkb create mode 100644 test/core/reporters/test_coverage/test_html_block_reporter.pks create mode 100644 test/core/reporters/test_coverage/test_html_proftab_reporter.pkb create mode 100644 test/core/reporters/test_coverage/test_html_proftab_reporter.pks diff --git a/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb b/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb new file mode 100644 index 000000000..913c0060a --- /dev/null +++ b/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb @@ -0,0 +1,45 @@ +create or replace package body test_cov_cobertura_rptr_blk is + + procedure report_on_file is + l_results ut3.ut_varchar2_list; + l_expected clob; + l_actual clob; + begin + --Arrange + l_expected := + ' + + +test/ut3.dummy_coverage.pkb + + + + + + + + + + + + +'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_cobertura_reporter( ), + a_coverage_type => 'block', + a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), + a_test_files => ut3.ut_varchar2_list( ) + ) + ); + l_actual := ut3.ut_utils.table_to_clob(l_results); + --Assert + ut.expect(l_actual).to_be_like(l_expected); + end; + +end; +/ diff --git a/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks b/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks new file mode 100644 index 000000000..248c6b803 --- /dev/null +++ b/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks @@ -0,0 +1,10 @@ +create or replace package test_cov_cobertura_rptr_blk is + + --%suite(ut_test_cov_cobertura_rptr_blk) + --%suitepath(utplsql.core.reporters.test_block_coverage) + + --%test(reports on a project file mapped to database object in block coverage) + procedure report_on_file; + +end test_cov_cobertura_rptr_blk; +/ diff --git a/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb b/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb new file mode 100644 index 000000000..1f4d0d7d6 --- /dev/null +++ b/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb @@ -0,0 +1,34 @@ +create or replace package body test_coverage_sonar_rprt_blk is + + procedure report_on_file is + l_results ut3.ut_varchar2_list; + l_expected clob; + l_actual clob; + begin + --Arrange + l_expected := ' + + + + + +'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_sonar_reporter( ), + a_coverage_type => 'block', + a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), + a_test_files => ut3.ut_varchar2_list( ) + ) + ); + l_actual := ut3.ut_utils.table_to_clob(l_results); + --Assert + ut.expect(l_actual).to_equal(l_expected); + end; + +end; +/ diff --git a/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks b/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks new file mode 100644 index 000000000..b30e76dbe --- /dev/null +++ b/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks @@ -0,0 +1,10 @@ +create or replace package test_coverage_sonar_rprt_blk is + + --%suite(ut_test_coverage_sonar_rprt_blk) + --%suitepath(utplsql.core.reporters.test_block_coverage) + + --%test(reports on a project file mapped to database object in block coverage) + procedure report_on_file; + +end; +/ diff --git a/test/core/reporters/test_coverage/test_coveralls_reporter_block.pkb b/test/core/reporters/test_coverage/test_coveralls_reporter_block.pkb new file mode 100644 index 000000000..56a5499de --- /dev/null +++ b/test/core/reporters/test_coverage/test_coveralls_reporter_block.pkb @@ -0,0 +1,31 @@ +create or replace package body test_coveralls_reporter_block is + + procedure report_on_file is + l_results ut3.ut_varchar2_list; + l_expected clob; + l_actual clob; + begin + --Arrange + l_expected := '{"source_files":[ +{ "name": "test/ut3.dummy_coverage.pkb", +"coverage": [null,null,null,1,1,null,1]}]} + '; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coveralls_reporter( ), + a_coverage_type => 'block', + a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), + a_test_files => ut3.ut_varchar2_list( ) + ) + ); + l_actual := ut3.ut_utils.table_to_clob(l_results); + --Assert + ut.expect(l_actual).to_equal(l_expected); + end; + +end; +/ diff --git a/test/core/reporters/test_coverage/test_coveralls_reporter_block.pks b/test/core/reporters/test_coverage/test_coveralls_reporter_block.pks new file mode 100644 index 000000000..92b0a7517 --- /dev/null +++ b/test/core/reporters/test_coverage/test_coveralls_reporter_block.pks @@ -0,0 +1,10 @@ +create or replace package test_coveralls_reporter_block is + + --%suite(ut_coveralls_reporter_block) + --%suitepath(utplsql.core.reporters.test_block_coverage) + + --%test(reports on a project file mapped to database object in block coverage) + procedure report_on_file; + +end; +/ diff --git a/test/core/reporters/test_coverage/test_html_block_reporter.pkb b/test/core/reporters/test_coverage/test_html_block_reporter.pkb new file mode 100644 index 000000000..7dbf931c1 --- /dev/null +++ b/test/core/reporters/test_coverage/test_html_block_reporter.pkb @@ -0,0 +1,29 @@ +create or replace package body test_html_block_reporter is + + procedure report_on_file is + l_results ut3.ut_varchar2_list; + l_expected varchar2(32767); + l_actual clob; + begin + --Arrange + l_expected := '%

    UT3.DUMMY_COVERAGE

    %100 % blocks covered
    3 blocks in total.3 blocks covered and 0 blocks missed.
    %'; + --l_expected := '%

    UT3.DUMMY_COVERAGE

    100 % lines covered

    3 relevant lines. 3 lines covered (including 0 lines partially covered ) and 0 lines missed

    100 % blocks covered

    3 blocks in total.3 blocks covered and 0 blocks missed.
    %'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_html_reporter(), + a_coverage_type => 'block', + a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), + a_test_files => ut3.ut_varchar2_list( ) + ) + ); + l_actual := ut3.ut_utils.table_to_clob(l_results); + --Assert + ut.expect(l_actual).to_be_like(l_expected); + end; + +end test_html_block_reporter; +/ diff --git a/test/core/reporters/test_coverage/test_html_block_reporter.pks b/test/core/reporters/test_coverage/test_html_block_reporter.pks new file mode 100644 index 000000000..e6848c0da --- /dev/null +++ b/test/core/reporters/test_coverage/test_html_block_reporter.pks @@ -0,0 +1,10 @@ +create or replace package test_html_block_reporter is + + --%suite(ut_html_block_reporter) + --%suitepath(utplsql.core.reporters.test_block_coverage) + + --%test(reports on a project file mapped to database object in block coverage) + procedure report_on_file; + +end test_html_block_reporter; +/ diff --git a/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb b/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb new file mode 100644 index 000000000..4016dbb9c --- /dev/null +++ b/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb @@ -0,0 +1,30 @@ +create or replace package body test_html_proftab_reporter is + + procedure report_on_file is + l_results ut3.ut_varchar2_list; + l_expected varchar2(32767); + l_actual clob; + begin + --Arrange + l_expected := '%

    UT3.DUMMY_COVERAGE

    %3 relevant lines. 2 lines covered ) and 1 lines missed%'; + + --l_expected := '%

    UT3.DUMMY_COVERAGE

    66% lines covered

    3 relevant lines. 2 lines covered ) and 1 lines missed
    %'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_html_reporter(), + a_coverage_type => 'proftab', + a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), + a_test_files => ut3.ut_varchar2_list( ) + ) + ); + l_actual := ut3.ut_utils.table_to_clob(l_results); + --Assert + ut.expect(l_actual).to_be_like(l_expected); + end; + +end test_html_proftab_reporter; +/ diff --git a/test/core/reporters/test_coverage/test_html_proftab_reporter.pks b/test/core/reporters/test_coverage/test_html_proftab_reporter.pks new file mode 100644 index 000000000..d091510c6 --- /dev/null +++ b/test/core/reporters/test_coverage/test_html_proftab_reporter.pks @@ -0,0 +1,10 @@ +create or replace package test_html_proftab_reporter is + + --%suite(ut_html_proftab_reporter) + --%suitepath(utplsql.core.reporters.test_coverage) + + --%test(reports on a project file mapped to database object in profiler coverage) + procedure report_on_file; + +end test_html_proftab_reporter; +/ diff --git a/test/install_tests.sql b/test/install_tests.sql index 042d842e7..f0c96ae1e 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -29,6 +29,11 @@ whenever oserror exit failure rollback @@core/reporters/test_coverage/test_coverage_sonar_reporter.pks @@core/reporters/test_coverage/test_coveralls_reporter.pks @@core/reporters/test_coverage/test_cov_cobertura_reporter.pks +@@core/reporters/test_coverage/test_html_proftab_reporter.pks +@@core/reporters/test_coverage/test_html_block_reporter.pks +@@core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks +@@core/reporters/test_coverage/test_coveralls_reporter_block.pks +@@core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks @@core/reporters/test_xunit_reporter.pks @@core/expectations.pks @@core/expectations/scalar_data/binary/test_be_greater_or_equal.pks @@ -61,6 +66,11 @@ whenever oserror exit failure rollback @@core/reporters/test_coverage/test_coverage_sonar_reporter.pkb @@core/reporters/test_coverage/test_coveralls_reporter.pkb @@core/reporters/test_coverage/test_cov_cobertura_reporter.pkb +@@core/reporters/test_coverage/test_html_proftab_reporter.pkb +@@core/reporters/test_coverage/test_html_block_reporter.pkb +@@core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb +@@core/reporters/test_coverage/test_coveralls_reporter_block.pkb +@@core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb @@core/reporters/test_xunit_reporter.pkb @@core/expectations.pkb @@core/expectations/scalar_data/binary/test_be_greater_or_equal.pkb From 4f83357cc9121697d7e132ba4f59c46eda538463 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 14 Mar 2018 20:27:49 +0000 Subject: [PATCH 07/37] Added 12.2 Coverage Update block to be called from dynamic sql to avoid a compilation issues. Updated documentation --- docs/userguide/coverage.md | 18 +++++++++++++++++- source/core/coverage/ut_coverage_helper.pkb | 11 ++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/docs/userguide/coverage.md b/docs/userguide/coverage.md index b3d2553e8..666e34052 100644 --- a/docs/userguide/coverage.md +++ b/docs/userguide/coverage.md @@ -29,7 +29,7 @@ If you have `execute` privilege on the code that are tested, but do not have `cr If you have `execute` privilege only on the unit tests, but do not have `execute` privilege on the code that is tested, the code will not be reported by coverage - as if it did not exist in the database. If the code that is testes is complied as NATIVE, the code coverage will not be reported as well. -## Running unite tests with coverage +## Running unit tests with coverage Using code coverage functionality is as easy as using any other [reporter](reporters.md) for utPLSQL project. All you need to do is run your tests from your preferred SQL tool and save the outcomes of reporter to a file. All you need to do, is pass the constructor of the reporter to your `ut.run` @@ -40,6 +40,8 @@ begin end; / ``` + + Executes all unit tests in current schema, gather information about code coverage and output the html text into DBMS_OUTPUT. The `ut_coverage_html_reporter` will produce a interactive HTML report. You may see a sample of code coverage for utPLSQL project [here](https://utplsql.github.io/utPLSQL-coverage-html/) @@ -52,6 +54,20 @@ The report allow to navigate to every source and inspect line by line coverage. ![Coverage Details page](../images/coverage_html_details.png) +#### Oracle 12.2 block coverage. +In Oracle 12.2 new functionality was released which supports native [block coverage](https://docs.oracle.com/en/database/oracle/oracle-database/12.2/arpls/DBMS_PLSQL_CODE_COVERAGE.html#GUID-55A9E502-9EC2-4118-B292-DC79E6DC465E). +This has been enabled in utPLSQL code coverage as a separate option. It can be invoked by passing a argument a_coverage_type with value 'block'. By default profiler option is enabled ('proftab'). + +Example: +```sql +begin + ut.run(ut_coverage_html_reporter(),a_coverage_type => 'block'); +end; +/ +``` + +In this mode html reporter will show additionally number of lines that been partially covered and highlight them in orange. Number of blocks in code, blocks covered and missed. + ## Coverage reporting options By default the database schema/schemes containing the tests that were executed during the run, are fully reported by coverage reporter. All valid unit tests are excluded from the report regardless if they were invoked or not. This way the coverage report is not affected by presence of tests and contains only the tested code. diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index 5b0469e85..0b7800a27 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -51,14 +51,14 @@ 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'; + 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); -- 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); + 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 dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id); coverage_pause(); @@ -105,11 +105,12 @@ create or replace package body ut_coverage_helper is 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 = 'block' then - dbms_plsql_code_coverage.stop_coverage; + execute immediate l_stop_block; else dbms_profiler.stop_profiler(); end if; From ac40332d66cf4dd47d8d235f3e8b90e324873030 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 14 Mar 2018 20:43:52 +0000 Subject: [PATCH 08/37] Added 12.2 Coverage Amended install script to not fail when block coverage not present --- source/core/coverage/dbms_plssqlcode.sql | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/core/coverage/dbms_plssqlcode.sql b/source/core/coverage/dbms_plssqlcode.sql index 18e7b5580..2370da385 100644 --- a/source/core/coverage/dbms_plssqlcode.sql +++ b/source/core/coverage/dbms_plssqlcode.sql @@ -1,5 +1,11 @@ +declare + e_not_exists exception; + pragma exception_init(e_not_exists,-6576); + l_install_call varchar2(500) := 'call dbms_plsql_code_coverage.create_coverage_tables(force_it => :forceit)'; begin - DBMS_PLSQL_CODE_COVERAGE.create_coverage_tables( - force_it => TRUE); + execute immediate l_install_call using in true; +exception + when e_not_exists then + dbms_output.put_line('dbms_plsql_code_coverage doesnt exists in your database. Please upgrade.'); end; / From 9d7f16c5d5f1f378c3286cee4c8585e93d44cf7e Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Thu, 15 Mar 2018 00:45:01 +0000 Subject: [PATCH 09/37] Added conditional install of tests for 12.2 only - when block coverage is available. --- source/core/coverage/dbms_plssqlcode.sql | 13 +++++------ test/install_above_12_1.sql | 28 ++++++++++++++++++++++++ test/install_tests.sql | 24 +++++++++++--------- 3 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 test/install_above_12_1.sql diff --git a/source/core/coverage/dbms_plssqlcode.sql b/source/core/coverage/dbms_plssqlcode.sql index 2370da385..e3aa2ec9a 100644 --- a/source/core/coverage/dbms_plssqlcode.sql +++ b/source/core/coverage/dbms_plssqlcode.sql @@ -1,11 +1,8 @@ -declare - e_not_exists exception; - pragma exception_init(e_not_exists,-6576); - l_install_call varchar2(500) := 'call dbms_plsql_code_coverage.create_coverage_tables(force_it => :forceit)'; begin - execute immediate l_install_call using in true; -exception - when e_not_exists then - dbms_output.put_line('dbms_plsql_code_coverage doesnt exists in your database. Please upgrade.'); + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + dbms_plsql_code_coverage.create_coverage_tables(force_it => true); + $else + null; + $end end; / diff --git a/test/install_above_12_1.sql b/test/install_above_12_1.sql new file mode 100644 index 000000000..fe20cf816 --- /dev/null +++ b/test/install_above_12_1.sql @@ -0,0 +1,28 @@ +set termout off +set echo off +spool dummy.sql +prompt whenever sqlerror exit failure rollback +spool off + + +def FILE_NAME = '&&1' +column SCRIPT_NAME new_value SCRIPT_NAME noprint + +VAR V_FILE_NAME VARCHAR2(1000); +begin + if dbms_db_version.version = 12 and dbms_db_version.release >= 2 + or dbms_db_version.version > 12 + then + :V_FILE_NAME := '&&FILE_NAME'; + else + :V_FILE_NAME := 'dummy.sql'; + end if; +end; +/ +set verify off +select :V_FILE_NAME as SCRIPT_NAME from dual; +set termout on + + +@@&&SCRIPT_NAME + diff --git a/test/install_tests.sql b/test/install_tests.sql index f0c96ae1e..249db7e83 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -25,15 +25,17 @@ whenever oserror exit failure rollback @@core/test_output_buffer.pks @@core/test_suite_manager.pks @@core/reporters/test_coverage.pks -@@core/reporters/test_block_coverage.pks +set define on +@@install_above_12_1.sql 'core/reporters/test_block_coverage.pks' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_html_block_reporter.pks' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_coveralls_reporter_block.pks' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks' +set define off @@core/reporters/test_coverage/test_coverage_sonar_reporter.pks @@core/reporters/test_coverage/test_coveralls_reporter.pks @@core/reporters/test_coverage/test_cov_cobertura_reporter.pks @@core/reporters/test_coverage/test_html_proftab_reporter.pks -@@core/reporters/test_coverage/test_html_block_reporter.pks -@@core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks -@@core/reporters/test_coverage/test_coveralls_reporter_block.pks -@@core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks @@core/reporters/test_xunit_reporter.pks @@core/expectations.pks @@core/expectations/scalar_data/binary/test_be_greater_or_equal.pks @@ -62,15 +64,17 @@ whenever oserror exit failure rollback @@core/test_output_buffer.pkb @@core/test_suite_manager.pkb @@core/reporters/test_coverage.pkb -@@core/reporters/test_block_coverage.pkb @@core/reporters/test_coverage/test_coverage_sonar_reporter.pkb @@core/reporters/test_coverage/test_coveralls_reporter.pkb @@core/reporters/test_coverage/test_cov_cobertura_reporter.pkb @@core/reporters/test_coverage/test_html_proftab_reporter.pkb -@@core/reporters/test_coverage/test_html_block_reporter.pkb -@@core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb -@@core/reporters/test_coverage/test_coveralls_reporter_block.pkb -@@core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb +set define on +@@install_above_12_1.sql 'core/reporters/test_block_coverage.pkb' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_html_block_reporter.pkb' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_coveralls_reporter_block.pkb' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb' +set define off @@core/reporters/test_xunit_reporter.pkb @@core/expectations.pkb @@core/expectations/scalar_data/binary/test_be_greater_or_equal.pkb From 20541b551979932e35b9093d97f00e8a6057d561 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 18 Mar 2018 20:30:43 +0000 Subject: [PATCH 10/37] Refactoring coverage: split block and proftab for better visibility. --- source/core/coverage/ut_block_helper.pkb | 89 ++++++ source/core/coverage/ut_block_helper.pks | 26 ++ source/core/coverage/ut_coverage.pkb | 302 +------------------ source/core/coverage/ut_coverage.pks | 7 +- source/core/coverage/ut_coverage_block.pkb | 224 ++++++++++++++ source/core/coverage/ut_coverage_block.pks | 22 ++ source/core/coverage/ut_coverage_helper.pkb | 130 ++------ source/core/coverage/ut_coverage_helper.pks | 11 +- source/core/coverage/ut_coverage_proftab.pkb | 178 +++++++++++ source/core/coverage/ut_coverage_proftab.pks | 22 ++ source/core/coverage/ut_proftab_helper.pkb | 93 ++++++ source/core/coverage/ut_proftab_helper.pks | 30 ++ source/install.sql | 12 +- 13 files changed, 744 insertions(+), 402 deletions(-) create mode 100644 source/core/coverage/ut_block_helper.pkb create mode 100644 source/core/coverage/ut_block_helper.pks create mode 100644 source/core/coverage/ut_coverage_block.pkb create mode 100644 source/core/coverage/ut_coverage_block.pks create mode 100644 source/core/coverage/ut_coverage_proftab.pkb create mode 100644 source/core/coverage/ut_coverage_proftab.pks create mode 100644 source/core/coverage/ut_proftab_helper.pkb create mode 100644 source/core/coverage/ut_proftab_helper.pks diff --git a/source/core/coverage/ut_block_helper.pkb b/source/core/coverage/ut_block_helper.pkb new file mode 100644 index 000000000..f0c2322ab --- /dev/null +++ b/source/core/coverage/ut_block_helper.pkb @@ -0,0 +1,89 @@ +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 new file mode 100644 index 000000000..eef041275 --- /dev/null +++ b/source/core/coverage/ut_block_helper.pks @@ -0,0 +1,26 @@ +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 d09a672be..f10e80621 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -19,84 +19,7 @@ create or replace package body ut_coverage is 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, - 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 + function get_cov_sources_cursor(a_coverage_options in ut_coverage_options,a_sql in varchar2) return sys_refcursor is l_cursor sys_refcursor; l_skip_objects ut_object_names; l_schema_names ut_varchar2_rows; @@ -107,7 +30,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 := get_cov_sources_sql(a_coverage_options); + l_sql := a_sql; 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 @@ -118,7 +41,7 @@ create or replace package body ut_coverage is return l_cursor; end; - procedure populate_tmp_table(a_coverage_options ut_coverage_options) is + procedure populate_tmp_table(a_coverage_options in ut_coverage_options,a_sql in varchar2) is pragma autonomous_transaction; l_cov_sources_crsr sys_refcursor; l_cov_sources_data ut_coverage_helper.t_coverage_sources_tmp_rows; @@ -127,7 +50,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); + l_cov_sources_crsr := get_cov_sources_cursor(a_coverage_options,a_sql); loop fetch l_cov_sources_crsr bulk collect into l_cov_sources_data limit 1000; @@ -178,224 +101,13 @@ 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 = 'block' then - return get_coverage_data_block(a_coverage_options => a_coverage_options); + if a_coverage_options.coverage_type = c_block_coverage then + return ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); else - return get_coverage_data_profiler(a_coverage_options => a_coverage_options); + return ut_coverage_proftab.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 8a7df49ed..db659c049 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -15,7 +15,10 @@ 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); @@ -59,6 +62,8 @@ 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 new file mode 100644 index 000000000..a5a9801c8 --- /dev/null +++ b/source/core/coverage/ut_coverage_block.pkb @@ -0,0 +1,224 @@ +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 new file mode 100644 index 000000000..f0febb021 --- /dev/null +++ b/source/core/coverage/ut_coverage_block.pks @@ -0,0 +1,22 @@ +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 0b7800a27..0f01e64fb 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,10 +40,25 @@ 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 @@ -51,16 +66,12 @@ 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); - -- 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); + 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 ); else - dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id); + ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id); coverage_pause(); end if; g_is_started := true; @@ -83,36 +94,33 @@ 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 = 'block' then + if get_coverage_type = ut_coverage.c_block_coverage then null; else - l_return_code := dbms_profiler.pause_profiler(); + ut_proftab_helper.coverage_pause(); end if; end if; end; procedure coverage_resume is - l_return_code binary_integer; begin - if get_coverage_type = 'block' then + if get_coverage_type = ut_coverage.c_block_coverage then null; else - l_return_code := dbms_profiler.resume_profiler(); + ut_proftab_helper.coverage_resume(); 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 = 'block' then - execute immediate l_stop_block; + if get_coverage_type = ut_coverage.c_block_coverage then + ut_block_helper.coverage_stop(); else - dbms_profiler.stop_profiler(); + ut_proftab_helper.coverage_stop(); end if; end if; end; @@ -121,92 +129,14 @@ create or replace package body ut_coverage_helper is begin g_develop_mode := false; g_is_started := false; - if get_coverage_type = 'block' then - null; + if get_coverage_type = ut_coverage.c_block_coverage then + ut_block_helper.coverage_stop(); else - dbms_profiler.stop_profiler(); + ut_proftab_helper.coverage_stop(); end if; 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; - 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 + 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 bf6c60df8..6728fd4b3 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -17,12 +17,19 @@ 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; @@ -73,10 +80,6 @@ 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 new file mode 100644 index 000000000..1fa550acf --- /dev/null +++ b/source/core/coverage/ut_coverage_proftab.pkb @@ -0,0 +1,178 @@ +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 new file mode 100644 index 000000000..7f0f4ca3b --- /dev/null +++ b/source/core/coverage/ut_coverage_proftab.pks @@ -0,0 +1,22 @@ +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 new file mode 100644 index 000000000..bf40ba531 --- /dev/null +++ b/source/core/coverage/ut_proftab_helper.pkb @@ -0,0 +1,93 @@ +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 new file mode 100644 index 000000000..53a78dbc5 --- /dev/null +++ b/source/core/coverage/ut_proftab_helper.pks @@ -0,0 +1,30 @@ +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/install.sql b/source/install.sql index 9a1b2457f..2a88197e8 100644 --- a/source/install.sql +++ b/source/install.sql @@ -127,10 +127,18 @@ 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_coverage_helper.pkb' +@@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.pkb' +@@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.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.tpb' --core type bodies From ab7eb93916f274bed0e9e0aa99074295224793ff Mon Sep 17 00:00:00 2001 From: lwasylow Date: Fri, 23 Mar 2018 08:27:37 +0000 Subject: [PATCH 11/37] Coverage Refactoring: Moved HTML reporters stable version Introduced constant for easier maintain. Signed-off-by: lwasylow --- source/core/coverage/ut_coverage.pkb | 4 +- source/core/types/ut_run.tpb | 2 +- source/install.sql | 4 + .../reporters/ut_block_report_html_helper.pkb | 226 +++++++++++++++ .../reporters/ut_block_report_html_helper.pks | 21 ++ .../ut_coverage_report_html_helper.pkb | 259 +----------------- .../ut_coverage_report_html_helper.pks | 14 + .../ut_proftab_report_html_helper.pkb | 210 ++++++++++++++ .../ut_proftab_report_html_helper.pks | 21 ++ 9 files changed, 504 insertions(+), 257 deletions(-) create mode 100644 source/reporters/ut_block_report_html_helper.pkb create mode 100644 source/reporters/ut_block_report_html_helper.pks create mode 100644 source/reporters/ut_proftab_report_html_helper.pkb create mode 100644 source/reporters/ut_proftab_report_html_helper.pks diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index f10e80621..4ca1ff056 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -70,13 +70,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, 'proftab'); + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage); 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, 'proftab'); + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage); begin ut_coverage_helper.coverage_start_develop(l_coverage_type); end; diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb index ea9f71e9f..5bdf26fb5 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,'proftab'); + l_coverage_type := coalesce(a_coverage_type,ut_coverage.c_proftab_coverage); self.run_paths := a_run_paths; self.self_type := $$plsql_unit; diff --git a/source/install.sql b/source/install.sql index 2a88197e8..7d5d19664 100644 --- a/source/install.sql +++ b/source/install.sql @@ -259,6 +259,10 @@ 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 new file mode 100644 index 000000000..f6485f952 --- /dev/null +++ b/source/reporters/ut_block_report_html_helper.pkb @@ -0,0 +1,226 @@ +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 := '

    ' || + dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || + '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || + '(including ' || a_coverage_unit.partcovered_lines || + ' lines partially covered ' + || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'||'

    ' || l_coverage_block_pct || ' % blocks covered

    '|| + '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| + ''||a_coverage_unit.covered_blocks||' blocks covered and '|| + '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' + ||'
      '; + 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 := ' +
    1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    2. '; + else + l_hits := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| + to_char(a_coverage_unit.lines(line_no).no_blocks); + + l_file_part := ' +
    3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ); + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + begin + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
    ' || '

    ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + ', ' || + l_coverage_block_pct || '%' || ' executed blocks covered)' + ||'

    ' || '' || '
    ' || + a_coverage.objects.count || ' files in total.
    ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered' || + ' (inlcluding ' || a_coverage.partcovered_lines || + ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| + ''||a_coverage.covered_blocks||' blocks covered and '|| + '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' + ||'
    File% coveredLinesRelevant LinesLines coveredLines missed' + ||case when l_coverage_type = 'block' then + '% blocks covered' + else + 'Avg. Hits / Line' + end ||'
    '||link_to_source_file(dbms_xmlgen.convert(l_unit))||''||l_coverage_pct||' %'||l_unit_coverage.total_lines||''||(l_unit_coverage.covered_lines+l_unit_coverage.uncovered_lines)||''||l_unit_coverage.covered_lines||''||l_unit_coverage.uncovered_lines||''||executions_per_line(l_unit_coverage.executions, l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)||'
    ' || link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || case + when l_coverage_type = 'block' then + (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || + '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || + '' || + l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' + else + '' || to_char(executions_per_line(l_unit_coverage.executions + ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) + end || '
    ' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + + --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' + ||'% blocks covered' ||'
    ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || + (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || + '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || + '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' + || '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + + /* + * public definitions + */ + 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 is + + l_file_part varchar2(32767); + l_result clob; + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
    using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || '' || l_title || + '' || '' || + '' || + '' || + '' || '' || '' || + '
    loading
    ' || + ''; + + 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 new file mode 100644 index 000000000..9ec514ffa --- /dev/null +++ b/source/reporters/ut_block_report_html_helper.pks @@ -0,0 +1,21 @@ +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 2deeb6380..601986374 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -98,269 +98,20 @@ 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 := '

    ' || - dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || - '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || case - when l_coverage_type = 'block' then - '(including ' || a_coverage_unit.partcovered_lines || - ' lines partially covered ' - end || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'|| - case when l_coverage_type = 'block' then - '

    ' || l_coverage_block_pct || ' % blocks covered

    '|| - '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| - ''||a_coverage_unit.covered_blocks||' blocks covered and '|| - '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' - end ||'
      '; - 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 := ' -
    1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    2. '; - else - l_hits := case when l_coverage_type = 'block' then - to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| - to_char(a_coverage_unit.lines(line_no).no_blocks) - else - to_char(a_coverage_unit.lines(line_no).executions) - end; - - l_file_part := ' -
    3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ,l_coverage_type); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage, a_coverage_type varchar2) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); - begin - if l_coverage_type = 'block' then - l_coverage_block_pct := coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); - end if; - - l_coverage_pct := coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
    ' || '

    ' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - case when l_coverage_type = 'block' then - ', ' || - l_coverage_block_pct || '%' || ' executed blocks covered)' - else - ' at ' || - '' || - executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' hits/line)' - end || - '

    ' || '' || '
    ' || - a_coverage.objects.count || ' files in total.
    ' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered' || case - when l_coverage_type = 'block' then - ' (inlcluding ' || a_coverage.partcovered_lines || - ' lines partially covered' - else - null - end || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - case when l_coverage_type = 'block' then - '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| - ''||a_coverage.covered_blocks||' blocks covered and '|| - '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' - end || - '' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - - if l_coverage_type = 'block' then - l_coverage_block_pct := coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); - end if; - - l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - - --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' - else - (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || '' - end || '' || - case - when l_coverage_type = 'block' then - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' - ||case when l_coverage_type = 'block' then - '% blocks covered' - else - 'Avg. Hits / Line' - end ||'
    ' || link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || case - when l_coverage_type = 'block' then - (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || - '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || - '' || - l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' - else - '' || to_char(executions_per_line(l_unit_coverage.executions - ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) - end || '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - /* * public definitions */ 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 is - - l_file_part varchar2(32767); l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); + l_coverage_type varchar2(32) := coalesce(a_coverage_type, ut_coverage.c_proftab_coverage); begin - if l_coverage_type = 'block' then - l_coverage_pct := coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); + if l_coverage_type = ut_coverage.c_block_coverage then + l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); else - l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + l_result := ut_proftab_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); end if; - - --l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); - - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
    using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || '' || l_title || - '' || '' || - '' || - '' || - '' || '' || '' || - '
    loading
    ' || - ''; - - 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 67faeb6a1..48c96a53d 100644 --- a/source/reporters/ut_coverage_report_html_helper.pks +++ b/source/reporters/ut_coverage_report_html_helper.pks @@ -17,6 +17,20 @@ 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 new file mode 100644 index 000000000..118d00a1b --- /dev/null +++ b/source/reporters/ut_proftab_report_html_helper.pkb @@ -0,0 +1,210 @@ +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 := '

    ' || + dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || + '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'||'
      '; + 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 := ' +
    1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    2. '; + else + l_hits := to_char(a_coverage_unit.lines(line_no).executions); + + l_file_part := ' +
    3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ); + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
    ' || '

    ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + ' at ' || + '' || + ut_coverage_report_html_helper.executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' hits/line)

    ' || '' || '
    ' || + a_coverage.objects.count || ' files in total.
    ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered'|| ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + '' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' + ||'Avg. Hits / Line
    ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || + (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || + l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' || to_char(ut_coverage_report_html_helper.executions_per_line(l_unit_coverage.executions + ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) + || '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + + /* + * public definitions + */ + 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 is + + l_file_part varchar2(32767); + l_result clob; + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
    using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || '' || l_title || + '' || '' || + '' || + '' || + '' || '' || '' || + '
    loading
    ' || + ''; + + 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 new file mode 100644 index 000000000..59316f9bf --- /dev/null +++ b/source/reporters/ut_proftab_report_html_helper.pks @@ -0,0 +1,21 @@ +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; +/ From 2560f5b7c12c8562010ff92e3bcb24588e16ca81 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 25 Mar 2018 18:04:26 +0100 Subject: [PATCH 12/37] Revert "Feature/12cblockcoverage" --- source/core/coverage/ut_block_helper.pkb | 89 ----- source/core/coverage/ut_block_helper.pks | 26 -- source/core/coverage/ut_coverage.pkb | 306 +++++++++++++++++- source/core/coverage/ut_coverage.pks | 7 +- source/core/coverage/ut_coverage_block.pkb | 224 ------------- source/core/coverage/ut_coverage_block.pks | 22 -- source/core/coverage/ut_coverage_helper.pkb | 130 ++++++-- source/core/coverage/ut_coverage_helper.pks | 11 +- source/core/coverage/ut_coverage_proftab.pkb | 178 ---------- source/core/coverage/ut_coverage_proftab.pks | 22 -- source/core/coverage/ut_proftab_helper.pkb | 93 ------ source/core/coverage/ut_proftab_helper.pks | 30 -- source/core/types/ut_run.tpb | 2 +- source/install.sql | 16 +- .../reporters/ut_block_report_html_helper.pkb | 226 ------------- .../reporters/ut_block_report_html_helper.pks | 21 -- .../ut_coverage_report_html_helper.pkb | 259 ++++++++++++++- .../ut_coverage_report_html_helper.pks | 14 - .../ut_proftab_report_html_helper.pkb | 210 ------------ .../ut_proftab_report_html_helper.pks | 21 -- 20 files changed, 659 insertions(+), 1248 deletions(-) delete mode 100644 source/core/coverage/ut_block_helper.pkb delete mode 100644 source/core/coverage/ut_block_helper.pks delete mode 100644 source/core/coverage/ut_coverage_block.pkb delete mode 100644 source/core/coverage/ut_coverage_block.pks delete mode 100644 source/core/coverage/ut_coverage_proftab.pkb delete mode 100644 source/core/coverage/ut_coverage_proftab.pks delete mode 100644 source/core/coverage/ut_proftab_helper.pkb delete mode 100644 source/core/coverage/ut_proftab_helper.pks delete mode 100644 source/reporters/ut_block_report_html_helper.pkb delete mode 100644 source/reporters/ut_block_report_html_helper.pks delete mode 100644 source/reporters/ut_proftab_report_html_helper.pkb delete mode 100644 source/reporters/ut_proftab_report_html_helper.pks 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 := '

    ' || - dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || - '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || - '(including ' || a_coverage_unit.partcovered_lines || - ' lines partially covered ' - || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'||'

    ' || l_coverage_block_pct || ' % blocks covered

    '|| - '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| - ''||a_coverage_unit.covered_blocks||' blocks covered and '|| - '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' - ||'
      '; - 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 := ' -
    1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    2. '; - else - l_hits := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| - to_char(a_coverage_unit.lines(line_no).no_blocks); - - l_file_part := ' -
    3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - begin - l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
    ' || '

    ' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - ', ' || - l_coverage_block_pct || '%' || ' executed blocks covered)' - ||'

    ' || '' || '
    ' || - a_coverage.objects.count || ' files in total.
    ' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered' || - ' (inlcluding ' || a_coverage.partcovered_lines || - ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| - ''||a_coverage.covered_blocks||' blocks covered and '|| - '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' - ||'' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - - --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' - ||'% blocks covered' ||'
    ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || - (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || - '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || - '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' - || '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - - /* - * public definitions - */ - 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 is - - l_file_part varchar2(32767); - l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
    using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || '' || l_title || - '' || '' || - '' || - '' || - '' || '' || '' || - '
    loading
    ' || - ''; - - 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 := '

    ' || + dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || + '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || case + when l_coverage_type = 'block' then + '(including ' || a_coverage_unit.partcovered_lines || + ' lines partially covered ' + end || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'|| + case when l_coverage_type = 'block' then + '

    ' || l_coverage_block_pct || ' % blocks covered

    '|| + '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| + ''||a_coverage_unit.covered_blocks||' blocks covered and '|| + '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' + end ||'
      '; + 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 := ' +
    1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    2. '; + else + l_hits := case when l_coverage_type = 'block' then + to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| + to_char(a_coverage_unit.lines(line_no).no_blocks) + else + to_char(a_coverage_unit.lines(line_no).executions) + end; + + l_file_part := ' +
    3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ,l_coverage_type); + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage, a_coverage_type varchar2) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); + begin + if l_coverage_type = 'block' then + l_coverage_block_pct := coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); + end if; + + l_coverage_pct := coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
    ' || '

    ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + case when l_coverage_type = 'block' then + ', ' || + l_coverage_block_pct || '%' || ' executed blocks covered)' + else + ' at ' || + '' || + executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' hits/line)' + end || + '

    ' || '' || '
    ' || + a_coverage.objects.count || ' files in total.
    ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered' || case + when l_coverage_type = 'block' then + ' (inlcluding ' || a_coverage.partcovered_lines || + ' lines partially covered' + else + null + end || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + case when l_coverage_type = 'block' then + '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| + ''||a_coverage.covered_blocks||' blocks covered and '|| + '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' + end || + '' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + + if l_coverage_type = 'block' then + l_coverage_block_pct := coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); + end if; + + l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + + --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' + else + (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || '' + end || '' || + case + when l_coverage_type = 'block' then + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' + ||case when l_coverage_type = 'block' then + '% blocks covered' + else + 'Avg. Hits / Line' + end ||'
    ' || link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || case + when l_coverage_type = 'block' then + (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || + '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || + '' || + l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' + else + '' || to_char(executions_per_line(l_unit_coverage.executions + ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) + end || '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + /* * public definitions */ 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 is + + l_file_part varchar2(32767); l_result clob; - l_coverage_type varchar2(32) := coalesce(a_coverage_type, ut_coverage.c_proftab_coverage); + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); begin - if l_coverage_type = ut_coverage.c_block_coverage then - l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + if l_coverage_type = 'block' then + l_coverage_pct := coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); else - l_result := ut_proftab_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); end if; - + + --l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
    using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || '' || l_title || + '' || '' || + '' || + '' || + '' || '' || '' || + '
    loading
    ' || + ''; + + 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 := '

    ' || - dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || - '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'||'
      '; - 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 := ' -
    1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    2. '; - else - l_hits := to_char(a_coverage_unit.lines(line_no).executions); - - l_file_part := ' -
    3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
    ' || '

    ' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - ' at ' || - '' || - ut_coverage_report_html_helper.executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' hits/line)

    ' || '' || '
    ' || - a_coverage.objects.count || ' files in total.
    ' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered'|| ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - '' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' - ||'Avg. Hits / Line
    ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || - (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || - l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' || to_char(ut_coverage_report_html_helper.executions_per_line(l_unit_coverage.executions - ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) - || '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - - /* - * public definitions - */ - 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 is - - l_file_part varchar2(32767); - l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); - - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
    using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || '' || l_title || - '' || '' || - '' || - '' || - '' || '' || '' || - '
    loading
    ' || - ''; - - 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; -/ From 82358489d65055758229e31feecff9fc78cc69ad Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 25 Mar 2018 20:08:11 +0100 Subject: [PATCH 13/37] Refactor Coverage: Split block and profiler Added conditional blocks for version less than 12.2 Split html reporter --- source/core/coverage/ut_block_helper.pkb | 89 +++++ source/core/coverage/ut_block_helper.pks | 26 ++ source/core/coverage/ut_coverage.pkb | 310 +----------------- source/core/coverage/ut_coverage.pks | 7 +- source/core/coverage/ut_coverage_block.pkb | 224 +++++++++++++ source/core/coverage/ut_coverage_block.pks | 22 ++ source/core/coverage/ut_coverage_helper.pkb | 142 +++----- source/core/coverage/ut_coverage_helper.pks | 11 +- source/core/coverage/ut_coverage_proftab.pkb | 178 ++++++++++ source/core/coverage/ut_coverage_proftab.pks | 22 ++ source/core/coverage/ut_proftab_helper.pkb | 93 ++++++ source/core/coverage/ut_proftab_helper.pks | 30 ++ source/dummy.sql | 1 + source/install.sql | 16 +- source/install_above_12_1.sql | 27 ++ .../reporters/ut_block_report_html_helper.pkb | 226 +++++++++++++ .../reporters/ut_block_report_html_helper.pks | 21 ++ .../ut_coverage_report_html_helper.pkb | 263 +-------------- .../ut_coverage_report_html_helper.pks | 14 + .../ut_proftab_report_html_helper.pkb | 210 ++++++++++++ .../ut_proftab_report_html_helper.pks | 21 ++ test/install_and_run_tests.sh | 2 + 22 files changed, 1297 insertions(+), 658 deletions(-) create mode 100644 source/core/coverage/ut_block_helper.pkb create mode 100644 source/core/coverage/ut_block_helper.pks create mode 100644 source/core/coverage/ut_coverage_block.pkb create mode 100644 source/core/coverage/ut_coverage_block.pks create mode 100644 source/core/coverage/ut_coverage_proftab.pkb create mode 100644 source/core/coverage/ut_coverage_proftab.pks create mode 100644 source/core/coverage/ut_proftab_helper.pkb create mode 100644 source/core/coverage/ut_proftab_helper.pks create mode 100644 source/dummy.sql create mode 100644 source/install_above_12_1.sql create mode 100644 source/reporters/ut_block_report_html_helper.pkb create mode 100644 source/reporters/ut_block_report_html_helper.pks create mode 100644 source/reporters/ut_proftab_report_html_helper.pkb create mode 100644 source/reporters/ut_proftab_report_html_helper.pks diff --git a/source/core/coverage/ut_block_helper.pkb b/source/core/coverage/ut_block_helper.pkb new file mode 100644 index 000000000..f0c2322ab --- /dev/null +++ b/source/core/coverage/ut_block_helper.pkb @@ -0,0 +1,89 @@ +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 new file mode 100644 index 000000000..eef041275 --- /dev/null +++ b/source/core/coverage/ut_block_helper.pks @@ -0,0 +1,26 @@ +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 d09a672be..fd0cc3b9a 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -19,84 +19,7 @@ create or replace package body ut_coverage is 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, - 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 + function get_cov_sources_cursor(a_coverage_options in ut_coverage_options,a_sql in varchar2) return sys_refcursor is l_cursor sys_refcursor; l_skip_objects ut_object_names; l_schema_names ut_varchar2_rows; @@ -107,7 +30,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 := get_cov_sources_sql(a_coverage_options); + l_sql := a_sql; 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 @@ -118,7 +41,7 @@ create or replace package body ut_coverage is return l_cursor; end; - procedure populate_tmp_table(a_coverage_options ut_coverage_options) is + procedure populate_tmp_table(a_coverage_options in ut_coverage_options,a_sql in varchar2) is pragma autonomous_transaction; l_cov_sources_crsr sys_refcursor; l_cov_sources_data ut_coverage_helper.t_coverage_sources_tmp_rows; @@ -127,7 +50,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); + l_cov_sources_crsr := get_cov_sources_cursor(a_coverage_options,a_sql); loop fetch l_cov_sources_crsr bulk collect into l_cov_sources_data limit 1000; @@ -147,13 +70,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, 'proftab'); + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage); 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, 'proftab'); + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage); begin ut_coverage_helper.coverage_start_develop(l_coverage_type); end; @@ -178,224 +101,17 @@ 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 = 'block' then - return get_coverage_data_block(a_coverage_options => a_coverage_options); + if a_coverage_options.coverage_type = c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + return ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); + $else + return null; + $end else - return get_coverage_data_profiler(a_coverage_options => a_coverage_options); + return ut_coverage_proftab.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 8a7df49ed..db659c049 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -15,7 +15,10 @@ 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); @@ -59,6 +62,8 @@ 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 new file mode 100644 index 000000000..a5a9801c8 --- /dev/null +++ b/source/core/coverage/ut_coverage_block.pkb @@ -0,0 +1,224 @@ +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 new file mode 100644 index 000000000..f0febb021 --- /dev/null +++ b/source/core/coverage/ut_coverage_block.pks @@ -0,0 +1,22 @@ +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 0b7800a27..e8cb198b3 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,10 +40,25 @@ 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 @@ -51,16 +66,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); - -- 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); + if get_coverage_type = ut_coverage.c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_block_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id ); + $else + null; + $end else - dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id); + ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id); coverage_pause(); end if; g_is_started := true; @@ -83,36 +98,37 @@ 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 = 'block' then + if get_coverage_type = ut_coverage.c_block_coverage then null; else - l_return_code := dbms_profiler.pause_profiler(); + ut_proftab_helper.coverage_pause(); end if; end if; end; procedure coverage_resume is - l_return_code binary_integer; begin - if get_coverage_type = 'block' then + if get_coverage_type = ut_coverage.c_block_coverage then null; else - l_return_code := dbms_profiler.resume_profiler(); + ut_proftab_helper.coverage_resume(); 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 = 'block' then - execute immediate l_stop_block; + if get_coverage_type = ut_coverage.c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_block_helper.coverage_stop(); + $else + null; + $end else - dbms_profiler.stop_profiler(); + ut_proftab_helper.coverage_stop(); end if; end if; end; @@ -121,92 +137,18 @@ create or replace package body ut_coverage_helper is begin g_develop_mode := false; g_is_started := false; - if get_coverage_type = 'block' then - null; + if get_coverage_type = ut_coverage.c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_block_helper.coverage_stop(); + $else + null; + $end else - dbms_profiler.stop_profiler(); + ut_proftab_helper.coverage_stop(); end if; 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; - 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 + 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 bf6c60df8..6728fd4b3 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -17,12 +17,19 @@ 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; @@ -73,10 +80,6 @@ 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 new file mode 100644 index 000000000..1fa550acf --- /dev/null +++ b/source/core/coverage/ut_coverage_proftab.pkb @@ -0,0 +1,178 @@ +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 new file mode 100644 index 000000000..7f0f4ca3b --- /dev/null +++ b/source/core/coverage/ut_coverage_proftab.pks @@ -0,0 +1,22 @@ +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 new file mode 100644 index 000000000..bf40ba531 --- /dev/null +++ b/source/core/coverage/ut_proftab_helper.pkb @@ -0,0 +1,93 @@ +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 new file mode 100644 index 000000000..53a78dbc5 --- /dev/null +++ b/source/core/coverage/ut_proftab_helper.pks @@ -0,0 +1,30 @@ +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/dummy.sql b/source/dummy.sql new file mode 100644 index 000000000..36d9f8778 --- /dev/null +++ b/source/dummy.sql @@ -0,0 +1 @@ +whenever sqlerror exit failure rollback diff --git a/source/install.sql b/source/install.sql index 9a1b2457f..275b34aff 100644 --- a/source/install.sql +++ b/source/install.sql @@ -127,10 +127,18 @@ 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_coverage_helper.pkb' +@@install_above_12_1.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.pkb' +@@install_above_12_1.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_above_12_1.sql 'core/coverage/ut_block_helper.pkb' +@@install_component.sql 'core/coverage/ut_proftab_helper.pkb' +@@install_component.sql 'core/coverage/ut_coverage.pkb' +@@install_above_12_1.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.tpb' --core type bodies @@ -250,7 +258,11 @@ 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_above_12_1.sql 'reporters/ut_block_report_html_helper.pks' +@@install_component.sql 'reporters/ut_proftab_report_html_helper.pks' +@@install_above_12_1.sql 'reporters/ut_block_report_html_helper.pkb' @@install_component.sql 'reporters/ut_coverage_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/install_above_12_1.sql b/source/install_above_12_1.sql new file mode 100644 index 000000000..69e47ce9a --- /dev/null +++ b/source/install_above_12_1.sql @@ -0,0 +1,27 @@ +def FILE_NAME = '&&1' +column SCRIPT_NAME new_value SCRIPT_NAME noprint + +VAR V_FILE_NAME VARCHAR2(1000); +begin + if dbms_db_version.version = 12 and dbms_db_version.release >= 2 + or dbms_db_version.version > 12 + then + :V_FILE_NAME := '&&FILE_NAME'; + else + :V_FILE_NAME := 'dummy.sql'; + end if; +end; +/ + +set verify off +select :V_FILE_NAME as SCRIPT_NAME from dual; +set termout on + +set heading off +set feedback off +exec dbms_output.put_line('Installing component '||upper(regexp_substr('&&1','\/(\w*)\.',1,1,'i',1))); +@@&&SCRIPT_NAME +exec dbms_output.put_line('&&line_separator'); + + + diff --git a/source/reporters/ut_block_report_html_helper.pkb b/source/reporters/ut_block_report_html_helper.pkb new file mode 100644 index 000000000..f6485f952 --- /dev/null +++ b/source/reporters/ut_block_report_html_helper.pkb @@ -0,0 +1,226 @@ +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 := '

    ' || + dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || + '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || + '(including ' || a_coverage_unit.partcovered_lines || + ' lines partially covered ' + || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'||'

    ' || l_coverage_block_pct || ' % blocks covered

    '|| + '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| + ''||a_coverage_unit.covered_blocks||' blocks covered and '|| + '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' + ||'
      '; + 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 := ' +
    1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    2. '; + else + l_hits := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| + to_char(a_coverage_unit.lines(line_no).no_blocks); + + l_file_part := ' +
    3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ); + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + begin + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
    ' || '

    ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + ', ' || + l_coverage_block_pct || '%' || ' executed blocks covered)' + ||'

    ' || '' || '
    ' || + a_coverage.objects.count || ' files in total.
    ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered' || + ' (inlcluding ' || a_coverage.partcovered_lines || + ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| + ''||a_coverage.covered_blocks||' blocks covered and '|| + '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' + ||'' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + + --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' + ||'% blocks covered' ||'
    ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || + (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || + '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || + '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' + || '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + + /* + * public definitions + */ + 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 is + + l_file_part varchar2(32767); + l_result clob; + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
    using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || '' || l_title || + '' || '' || + '' || + '' || + '' || '' || '' || + '
    loading
    ' || + ''; + + 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 new file mode 100644 index 000000000..9ec514ffa --- /dev/null +++ b/source/reporters/ut_block_report_html_helper.pks @@ -0,0 +1,21 @@ +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 2deeb6380..b18369b8f 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -98,269 +98,24 @@ 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 := '

    ' || - dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || - '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || case - when l_coverage_type = 'block' then - '(including ' || a_coverage_unit.partcovered_lines || - ' lines partially covered ' - end || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'|| - case when l_coverage_type = 'block' then - '

    ' || l_coverage_block_pct || ' % blocks covered

    '|| - '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| - ''||a_coverage_unit.covered_blocks||' blocks covered and '|| - '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' - end ||'
      '; - 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 := ' -
    1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    2. '; - else - l_hits := case when l_coverage_type = 'block' then - to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| - to_char(a_coverage_unit.lines(line_no).no_blocks) - else - to_char(a_coverage_unit.lines(line_no).executions) - end; - - l_file_part := ' -
    3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ,l_coverage_type); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage, a_coverage_type varchar2) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); - begin - if l_coverage_type = 'block' then - l_coverage_block_pct := coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); - end if; - - l_coverage_pct := coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
    ' || '

    ' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - case when l_coverage_type = 'block' then - ', ' || - l_coverage_block_pct || '%' || ' executed blocks covered)' - else - ' at ' || - '' || - executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' hits/line)' - end || - '

    ' || '' || '
    ' || - a_coverage.objects.count || ' files in total.
    ' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered' || case - when l_coverage_type = 'block' then - ' (inlcluding ' || a_coverage.partcovered_lines || - ' lines partially covered' - else - null - end || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - case when l_coverage_type = 'block' then - '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| - ''||a_coverage.covered_blocks||' blocks covered and '|| - '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' - end || - '' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - - if l_coverage_type = 'block' then - l_coverage_block_pct := coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); - end if; - - l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - - --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' - else - (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || '' - end || '' || - case - when l_coverage_type = 'block' then - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' - ||case when l_coverage_type = 'block' then - '% blocks covered' - else - 'Avg. Hits / Line' - end ||'
    ' || link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || case - when l_coverage_type = 'block' then - (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || - '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || - '' || - l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' - else - '' || to_char(executions_per_line(l_unit_coverage.executions - ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) - end || '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - /* * public definitions */ 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 is - - l_file_part varchar2(32767); l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); + l_coverage_type varchar2(32) := coalesce(a_coverage_type, ut_coverage.c_proftab_coverage); begin - if l_coverage_type = 'block' then - l_coverage_pct := coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); + if l_coverage_type = ut_coverage.c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + $else + l_result := null; + $end else - l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + l_result := ut_proftab_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); end if; - - --l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); - - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
    using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || '' || l_title || - '' || '' || - '' || - '' || - '' || '' || '' || - '
    loading
    ' || - ''; - - 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 67faeb6a1..48c96a53d 100644 --- a/source/reporters/ut_coverage_report_html_helper.pks +++ b/source/reporters/ut_coverage_report_html_helper.pks @@ -17,6 +17,20 @@ 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 new file mode 100644 index 000000000..118d00a1b --- /dev/null +++ b/source/reporters/ut_proftab_report_html_helper.pkb @@ -0,0 +1,210 @@ +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 := '

    ' || + dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || + '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'||'
      '; + 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 := ' +
    1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    2. '; + else + l_hits := to_char(a_coverage_unit.lines(line_no).executions); + + l_file_part := ' +
    3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ); + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
    ' || '

    ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + ' at ' || + '' || + ut_coverage_report_html_helper.executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' hits/line)

    ' || '' || '
    ' || + a_coverage.objects.count || ' files in total.
    ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered'|| ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + '' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' + ||'Avg. Hits / Line
    ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || + (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || + l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' || to_char(ut_coverage_report_html_helper.executions_per_line(l_unit_coverage.executions + ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) + || '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + + /* + * public definitions + */ + 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 is + + l_file_part varchar2(32767); + l_result clob; + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
    using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || '' || l_title || + '' || '' || + '' || + '' || + '' || '' || '' || + '
    loading
    ' || + ''; + + 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 new file mode 100644 index 000000000..59316f9bf --- /dev/null +++ b/source/reporters/ut_proftab_report_html_helper.pks @@ -0,0 +1,21 @@ +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; +/ diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh index b96602f15..4892393d7 100644 --- a/test/install_and_run_tests.sh +++ b/test/install_and_run_tests.sh @@ -5,6 +5,8 @@ set -ev #goto git root directory git rev-parse && cd "$(git rev-parse --show-cdup)" +. development/env.sh + cd test "$SQLCLI" ${UT3_TESTER}/${UT3_TESTER_PASSWORD}@//${CONNECTION_STR} @install_tests.sql From 78fdab5a6a58126d1c3f3a97816e2a77b72e0e4c Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 25 Mar 2018 20:08:11 +0100 Subject: [PATCH 14/37] Refactor Coverage: Split block and profiler Added conditional blocks for version less than 12.2 Split html reporter --- source/core/coverage/ut_block_helper.pkb | 89 +++++ source/core/coverage/ut_block_helper.pks | 26 ++ source/core/coverage/ut_coverage.pkb | 310 +----------------- source/core/coverage/ut_coverage.pks | 7 +- source/core/coverage/ut_coverage_block.pkb | 224 +++++++++++++ source/core/coverage/ut_coverage_block.pks | 22 ++ source/core/coverage/ut_coverage_helper.pkb | 142 +++----- source/core/coverage/ut_coverage_helper.pks | 11 +- source/core/coverage/ut_coverage_proftab.pkb | 178 ++++++++++ source/core/coverage/ut_coverage_proftab.pks | 22 ++ source/core/coverage/ut_proftab_helper.pkb | 93 ++++++ source/core/coverage/ut_proftab_helper.pks | 30 ++ source/dummy.sql | 1 + source/install.sql | 16 +- source/install_above_12_1.sql | 27 ++ .../reporters/ut_block_report_html_helper.pkb | 226 +++++++++++++ .../reporters/ut_block_report_html_helper.pks | 21 ++ .../ut_coverage_report_html_helper.pkb | 263 +-------------- .../ut_coverage_report_html_helper.pks | 14 + .../ut_proftab_report_html_helper.pkb | 210 ++++++++++++ .../ut_proftab_report_html_helper.pks | 21 ++ 21 files changed, 1295 insertions(+), 658 deletions(-) create mode 100644 source/core/coverage/ut_block_helper.pkb create mode 100644 source/core/coverage/ut_block_helper.pks create mode 100644 source/core/coverage/ut_coverage_block.pkb create mode 100644 source/core/coverage/ut_coverage_block.pks create mode 100644 source/core/coverage/ut_coverage_proftab.pkb create mode 100644 source/core/coverage/ut_coverage_proftab.pks create mode 100644 source/core/coverage/ut_proftab_helper.pkb create mode 100644 source/core/coverage/ut_proftab_helper.pks create mode 100644 source/dummy.sql create mode 100644 source/install_above_12_1.sql create mode 100644 source/reporters/ut_block_report_html_helper.pkb create mode 100644 source/reporters/ut_block_report_html_helper.pks create mode 100644 source/reporters/ut_proftab_report_html_helper.pkb create mode 100644 source/reporters/ut_proftab_report_html_helper.pks diff --git a/source/core/coverage/ut_block_helper.pkb b/source/core/coverage/ut_block_helper.pkb new file mode 100644 index 000000000..f0c2322ab --- /dev/null +++ b/source/core/coverage/ut_block_helper.pkb @@ -0,0 +1,89 @@ +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 new file mode 100644 index 000000000..eef041275 --- /dev/null +++ b/source/core/coverage/ut_block_helper.pks @@ -0,0 +1,26 @@ +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 d09a672be..fd0cc3b9a 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -19,84 +19,7 @@ create or replace package body ut_coverage is 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, - 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 + function get_cov_sources_cursor(a_coverage_options in ut_coverage_options,a_sql in varchar2) return sys_refcursor is l_cursor sys_refcursor; l_skip_objects ut_object_names; l_schema_names ut_varchar2_rows; @@ -107,7 +30,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 := get_cov_sources_sql(a_coverage_options); + l_sql := a_sql; 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 @@ -118,7 +41,7 @@ create or replace package body ut_coverage is return l_cursor; end; - procedure populate_tmp_table(a_coverage_options ut_coverage_options) is + procedure populate_tmp_table(a_coverage_options in ut_coverage_options,a_sql in varchar2) is pragma autonomous_transaction; l_cov_sources_crsr sys_refcursor; l_cov_sources_data ut_coverage_helper.t_coverage_sources_tmp_rows; @@ -127,7 +50,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); + l_cov_sources_crsr := get_cov_sources_cursor(a_coverage_options,a_sql); loop fetch l_cov_sources_crsr bulk collect into l_cov_sources_data limit 1000; @@ -147,13 +70,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, 'proftab'); + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage); 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, 'proftab'); + l_coverage_type varchar2(10) := coalesce(a_coverage_options.coverage_type, c_proftab_coverage); begin ut_coverage_helper.coverage_start_develop(l_coverage_type); end; @@ -178,224 +101,17 @@ 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 = 'block' then - return get_coverage_data_block(a_coverage_options => a_coverage_options); + if a_coverage_options.coverage_type = c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + return ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); + $else + return null; + $end else - return get_coverage_data_profiler(a_coverage_options => a_coverage_options); + return ut_coverage_proftab.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 8a7df49ed..db659c049 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -15,7 +15,10 @@ 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); @@ -59,6 +62,8 @@ 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 new file mode 100644 index 000000000..a5a9801c8 --- /dev/null +++ b/source/core/coverage/ut_coverage_block.pkb @@ -0,0 +1,224 @@ +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 new file mode 100644 index 000000000..f0febb021 --- /dev/null +++ b/source/core/coverage/ut_coverage_block.pks @@ -0,0 +1,22 @@ +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 0b7800a27..e8cb198b3 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,10 +40,25 @@ 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 @@ -51,16 +66,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); - -- 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); + if get_coverage_type = ut_coverage.c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_block_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id ); + $else + null; + $end else - dbms_profiler.start_profiler(run_comment => a_run_comment, run_number => g_coverage_id); + ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id); coverage_pause(); end if; g_is_started := true; @@ -83,36 +98,37 @@ 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 = 'block' then + if get_coverage_type = ut_coverage.c_block_coverage then null; else - l_return_code := dbms_profiler.pause_profiler(); + ut_proftab_helper.coverage_pause(); end if; end if; end; procedure coverage_resume is - l_return_code binary_integer; begin - if get_coverage_type = 'block' then + if get_coverage_type = ut_coverage.c_block_coverage then null; else - l_return_code := dbms_profiler.resume_profiler(); + ut_proftab_helper.coverage_resume(); 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 = 'block' then - execute immediate l_stop_block; + if get_coverage_type = ut_coverage.c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_block_helper.coverage_stop(); + $else + null; + $end else - dbms_profiler.stop_profiler(); + ut_proftab_helper.coverage_stop(); end if; end if; end; @@ -121,92 +137,18 @@ create or replace package body ut_coverage_helper is begin g_develop_mode := false; g_is_started := false; - if get_coverage_type = 'block' then - null; + if get_coverage_type = ut_coverage.c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_block_helper.coverage_stop(); + $else + null; + $end else - dbms_profiler.stop_profiler(); + ut_proftab_helper.coverage_stop(); end if; 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; - 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 + 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 bf6c60df8..6728fd4b3 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -17,12 +17,19 @@ 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; @@ -73,10 +80,6 @@ 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 new file mode 100644 index 000000000..1fa550acf --- /dev/null +++ b/source/core/coverage/ut_coverage_proftab.pkb @@ -0,0 +1,178 @@ +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 new file mode 100644 index 000000000..7f0f4ca3b --- /dev/null +++ b/source/core/coverage/ut_coverage_proftab.pks @@ -0,0 +1,22 @@ +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 new file mode 100644 index 000000000..bf40ba531 --- /dev/null +++ b/source/core/coverage/ut_proftab_helper.pkb @@ -0,0 +1,93 @@ +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 new file mode 100644 index 000000000..53a78dbc5 --- /dev/null +++ b/source/core/coverage/ut_proftab_helper.pks @@ -0,0 +1,30 @@ +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/dummy.sql b/source/dummy.sql new file mode 100644 index 000000000..36d9f8778 --- /dev/null +++ b/source/dummy.sql @@ -0,0 +1 @@ +whenever sqlerror exit failure rollback diff --git a/source/install.sql b/source/install.sql index 9a1b2457f..275b34aff 100644 --- a/source/install.sql +++ b/source/install.sql @@ -127,10 +127,18 @@ 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_coverage_helper.pkb' +@@install_above_12_1.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.pkb' +@@install_above_12_1.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_above_12_1.sql 'core/coverage/ut_block_helper.pkb' +@@install_component.sql 'core/coverage/ut_proftab_helper.pkb' +@@install_component.sql 'core/coverage/ut_coverage.pkb' +@@install_above_12_1.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.tpb' --core type bodies @@ -250,7 +258,11 @@ 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_above_12_1.sql 'reporters/ut_block_report_html_helper.pks' +@@install_component.sql 'reporters/ut_proftab_report_html_helper.pks' +@@install_above_12_1.sql 'reporters/ut_block_report_html_helper.pkb' @@install_component.sql 'reporters/ut_coverage_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/install_above_12_1.sql b/source/install_above_12_1.sql new file mode 100644 index 000000000..69e47ce9a --- /dev/null +++ b/source/install_above_12_1.sql @@ -0,0 +1,27 @@ +def FILE_NAME = '&&1' +column SCRIPT_NAME new_value SCRIPT_NAME noprint + +VAR V_FILE_NAME VARCHAR2(1000); +begin + if dbms_db_version.version = 12 and dbms_db_version.release >= 2 + or dbms_db_version.version > 12 + then + :V_FILE_NAME := '&&FILE_NAME'; + else + :V_FILE_NAME := 'dummy.sql'; + end if; +end; +/ + +set verify off +select :V_FILE_NAME as SCRIPT_NAME from dual; +set termout on + +set heading off +set feedback off +exec dbms_output.put_line('Installing component '||upper(regexp_substr('&&1','\/(\w*)\.',1,1,'i',1))); +@@&&SCRIPT_NAME +exec dbms_output.put_line('&&line_separator'); + + + diff --git a/source/reporters/ut_block_report_html_helper.pkb b/source/reporters/ut_block_report_html_helper.pkb new file mode 100644 index 000000000..f6485f952 --- /dev/null +++ b/source/reporters/ut_block_report_html_helper.pkb @@ -0,0 +1,226 @@ +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 := '

    ' || + dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || + '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || + '(including ' || a_coverage_unit.partcovered_lines || + ' lines partially covered ' + || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'||'

    ' || l_coverage_block_pct || ' % blocks covered

    '|| + '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| + ''||a_coverage_unit.covered_blocks||' blocks covered and '|| + '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' + ||'
      '; + 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 := ' +
    1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    2. '; + else + l_hits := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| + to_char(a_coverage_unit.lines(line_no).no_blocks); + + l_file_part := ' +
    3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ); + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + begin + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
    ' || '

    ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + ', ' || + l_coverage_block_pct || '%' || ' executed blocks covered)' + ||'

    ' || '' || '
    ' || + a_coverage.objects.count || ' files in total.
    ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered' || + ' (inlcluding ' || a_coverage.partcovered_lines || + ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| + ''||a_coverage.covered_blocks||' blocks covered and '|| + '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' + ||'' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + + --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' + ||'% blocks covered' ||'
    ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || + (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || + '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || + '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' + || '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + + /* + * public definitions + */ + 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 is + + l_file_part varchar2(32767); + l_result clob; + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
    using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || '' || l_title || + '' || '' || + '' || + '' || + '' || '' || '' || + '
    loading
    ' || + ''; + + 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 new file mode 100644 index 000000000..9ec514ffa --- /dev/null +++ b/source/reporters/ut_block_report_html_helper.pks @@ -0,0 +1,21 @@ +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 2deeb6380..b18369b8f 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -98,269 +98,24 @@ 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 := '

    ' || - dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || - '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || case - when l_coverage_type = 'block' then - '(including ' || a_coverage_unit.partcovered_lines || - ' lines partially covered ' - end || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'|| - case when l_coverage_type = 'block' then - '

    ' || l_coverage_block_pct || ' % blocks covered

    '|| - '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| - ''||a_coverage_unit.covered_blocks||' blocks covered and '|| - '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' - end ||'
      '; - 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 := ' -
    1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    2. '; - else - l_hits := case when l_coverage_type = 'block' then - to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| - to_char(a_coverage_unit.lines(line_no).no_blocks) - else - to_char(a_coverage_unit.lines(line_no).executions) - end; - - l_file_part := ' -
    3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
    4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ,l_coverage_type); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage, a_coverage_type varchar2) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); - begin - if l_coverage_type = 'block' then - l_coverage_block_pct := coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); - end if; - - l_coverage_pct := coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
    ' || '

    ' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - case when l_coverage_type = 'block' then - ', ' || - l_coverage_block_pct || '%' || ' executed blocks covered)' - else - ' at ' || - '' || - executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' hits/line)' - end || - '

    ' || '' || '
    ' || - a_coverage.objects.count || ' files in total.
    ' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered' || case - when l_coverage_type = 'block' then - ' (inlcluding ' || a_coverage.partcovered_lines || - ' lines partially covered' - else - null - end || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - case when l_coverage_type = 'block' then - '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| - ''||a_coverage.covered_blocks||' blocks covered and '|| - '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' - end || - '' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - - if l_coverage_type = 'block' then - l_coverage_block_pct := coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); - end if; - - l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - - --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' - else - (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || '' - end || '' || - case - when l_coverage_type = 'block' then - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' - ||case when l_coverage_type = 'block' then - '% blocks covered' - else - 'Avg. Hits / Line' - end ||'
    ' || link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || case - when l_coverage_type = 'block' then - (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || - '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || - '' || - l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' - else - '' || to_char(executions_per_line(l_unit_coverage.executions - ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) - end || '
    '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - /* * public definitions */ 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 is - - l_file_part varchar2(32767); l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - l_coverage_type varchar2(32) := coalesce(a_coverage_type, 'proftab'); + l_coverage_type varchar2(32) := coalesce(a_coverage_type, ut_coverage.c_proftab_coverage); begin - if l_coverage_type = 'block' then - l_coverage_pct := coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); + if l_coverage_type = ut_coverage.c_block_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + $else + l_result := null; + $end else - l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + l_result := ut_proftab_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); end if; - - --l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); - - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
    using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || '' || l_title || - '' || '' || - '' || - '' || - '' || '' || '' || - '
    loading
    ' || - ''; - - 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 67faeb6a1..48c96a53d 100644 --- a/source/reporters/ut_coverage_report_html_helper.pks +++ b/source/reporters/ut_coverage_report_html_helper.pks @@ -17,6 +17,20 @@ 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 new file mode 100644 index 000000000..118d00a1b --- /dev/null +++ b/source/reporters/ut_proftab_report_html_helper.pkb @@ -0,0 +1,210 @@ +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 := '

    ' || + dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || + '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'||'
      '; + 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 := ' +
    1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    2. '; + else + l_hits := to_char(a_coverage_unit.lines(line_no).executions); + + l_file_part := ' +
    3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ); + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
    ' || '

    ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + ' at ' || + '' || + ut_coverage_report_html_helper.executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' hits/line)

    ' || '' || '
    ' || + a_coverage.objects.count || ' files in total.
    ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered'|| ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + '' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' + ||'Avg. Hits / Line
    ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || + (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || + l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' || to_char(ut_coverage_report_html_helper.executions_per_line(l_unit_coverage.executions + ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) + || '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + + /* + * public definitions + */ + 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 is + + l_file_part varchar2(32767); + l_result clob; + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
    using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || '' || l_title || + '' || '' || + '' || + '' || + '' || '' || '' || + '
    loading
    ' || + ''; + + 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 new file mode 100644 index 000000000..59316f9bf --- /dev/null +++ b/source/reporters/ut_proftab_report_html_helper.pks @@ -0,0 +1,21 @@ +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; +/ From 466e126ab3e16d36b6d58223ab4032a28c2965d6 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 25 Mar 2018 20:23:42 +0100 Subject: [PATCH 15/37] Update test local --- test/install_and_run_tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh index 4892393d7..444346bb2 100644 --- a/test/install_and_run_tests.sh +++ b/test/install_and_run_tests.sh @@ -5,7 +5,6 @@ set -ev #goto git root directory git rev-parse && cd "$(git rev-parse --show-cdup)" -. development/env.sh cd test From 0f1d789bcdadb9c1f1b876d209ad3cb1c9401efb Mon Sep 17 00:00:00 2001 From: lwasylow Date: Tue, 3 Apr 2018 23:23:24 +0100 Subject: [PATCH 16/37] 12.2 coverage Fixes to order of new attribute. Rename package to more meaningful name Introduce an raise an error for non existing coverage type Update tests --- source/api/ut.pkb | 106 +++++++++--------- source/api/ut.pks | 48 ++++---- source/api/ut_runner.pkb | 4 +- source/api/ut_runner.pks | 5 +- ...elper.pkb => ut_block_coverage_helper.pkb} | 2 +- ...elper.pks => ut_block_coverage_helper.pks} | 2 +- source/core/coverage/ut_coverage_block.pkb | 2 +- source/core/coverage/ut_coverage_helper.pkb | 8 +- source/core/ut_utils.pks | 5 + source/install.sql | 4 +- test/install_below_12_2.sql | 28 +++++ test/install_tests.sql | 4 + 12 files changed, 128 insertions(+), 90 deletions(-) rename source/core/coverage/{ut_block_helper.pkb => ut_block_coverage_helper.pkb} (98%) rename source/core/coverage/{ut_block_helper.pks => ut_block_coverage_helper.pks} (92%) create mode 100644 test/install_below_12_2.sql diff --git a/source/api/ut.pkb b/source/api/ut.pkb index 071a422bd..b085c53aa 100644 --- a/source/api/ut.pkb +++ b/source/api/ut.pkb @@ -106,40 +106,40 @@ create or replace package body ut is procedure run_autonomous( a_paths ut_varchar2_list, a_reporter ut_reporter_base, a_color_console integer, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings, a_test_file_mappings ut_file_mappings, - a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings, a_test_file_mappings ut_file_mappings, + a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list, a_coverage_type varchar2:=null ) is pragma autonomous_transaction; begin ut_runner.run( a_paths, ut_reporters(coalesce(a_reporter,ut_documentation_reporter())), - ut_utils.int_to_boolean(a_color_console), a_coverage_schemes,a_coverage_type, - a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects + ut_utils.int_to_boolean(a_color_console), a_coverage_schemes, a_source_file_mappings, + a_test_file_mappings, a_include_objects, a_exclude_objects, false, a_coverage_type ); rollback; end; procedure run_autonomous( a_paths ut_varchar2_list, a_reporter ut_reporter_base, a_color_console integer, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list, a_coverage_type varchar2:=null ) is pragma autonomous_transaction; begin ut_runner.run( a_paths, ut_reporters(coalesce(a_reporter,ut_documentation_reporter())), - ut_utils.int_to_boolean(a_color_console), a_coverage_schemes,a_coverage_type, + ut_utils.int_to_boolean(a_color_console), a_coverage_schemes, ut_file_mapper.build_file_mappings(a_source_files), ut_file_mapper.build_file_mappings(a_test_files), - a_include_objects, a_exclude_objects + a_include_objects, a_exclude_objects, false, a_coverage_type ); rollback; end; function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(sys_context('userenv', 'current_schema')); @@ -148,7 +148,7 @@ create or replace package body ut is begin run_autonomous( l_paths, l_reporter, a_color_console, - a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects + a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects,a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -165,8 +165,8 @@ create or replace package body ut is function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(sys_context('userenv', 'current_schema')); @@ -174,8 +174,8 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - l_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -192,16 +192,16 @@ create or replace package body ut is function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_lines sys_refcursor; l_line varchar2(4000); begin run_autonomous( - a_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects + a_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -218,16 +218,16 @@ create or replace package body ut is function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_lines sys_refcursor; l_line varchar2(4000); begin run_autonomous( - a_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + a_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -244,8 +244,8 @@ create or replace package body ut is function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null,a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); @@ -253,8 +253,8 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - l_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects + l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_include_objects, a_exclude_objects,a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -271,8 +271,8 @@ create or replace package body ut is function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); @@ -280,8 +280,8 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - l_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -298,14 +298,14 @@ create or replace package body ut is procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); begin run_autonomous( - a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects + a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then treat(l_reporter as ut_output_reporter_base).lines_to_dbms_output(); @@ -315,14 +315,14 @@ create or replace package body ut is procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null,a_coverage_type varchar2:=null ) is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); begin run_autonomous( - a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects,a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then treat(l_reporter as ut_output_reporter_base).lines_to_dbms_output(); @@ -332,51 +332,51 @@ create or replace package body ut is procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is begin ut.run( ut_varchar2_list(sys_context('userenv', 'current_schema')), a_reporter, a_color_console, - a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects + a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects, a_coverage_type ); end; procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is begin ut.run( ut_varchar2_list(sys_context('userenv', 'current_schema')), a_reporter, a_color_console, - a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, a_include_objects, a_exclude_objects + a_coverage_schemes, a_source_files, a_test_files, a_include_objects, a_exclude_objects, a_coverage_type ); end; procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); begin ut.run( - l_paths, a_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects + l_paths, a_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_include_objects, a_exclude_objects, a_coverage_type ); end; procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); begin ut.run( - l_paths, a_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + l_paths, a_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects ,a_coverage_type ); end; diff --git a/source/api/ut.pks b/source/api/ut.pks index f479f12fd..1d55951d0 100644 --- a/source/api/ut.pks +++ b/source/api/ut.pks @@ -49,74 +49,74 @@ create or replace package ut authid current_user as function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); /** diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index 5476f84fc..7e6bd3250 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -66,8 +66,8 @@ create or replace package body ut_runner is procedure run( a_paths ut_varchar2_list, a_reporters ut_reporters, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2 := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false,a_coverage_type varchar2 := null ) is l_items_to_run ut_run; l_listener ut_event_listener; diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index 65341b9e0..882b520f3 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -57,8 +57,9 @@ create or replace package ut_runner authid current_user is */ procedure run( a_paths ut_varchar2_list, a_reporters ut_reporters, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2 := null , a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, + a_fail_on_errors boolean default false, a_coverage_type varchar2 := null ); /** diff --git a/source/core/coverage/ut_block_helper.pkb b/source/core/coverage/ut_block_coverage_helper.pkb similarity index 98% rename from source/core/coverage/ut_block_helper.pkb rename to source/core/coverage/ut_block_coverage_helper.pkb index f0c2322ab..346b47e27 100644 --- a/source/core/coverage/ut_block_helper.pkb +++ b/source/core/coverage/ut_block_coverage_helper.pkb @@ -1,4 +1,4 @@ -create or replace package body ut_block_helper is +create or replace package body ut_block_coverage_helper is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project diff --git a/source/core/coverage/ut_block_helper.pks b/source/core/coverage/ut_block_coverage_helper.pks similarity index 92% rename from source/core/coverage/ut_block_helper.pks rename to source/core/coverage/ut_block_coverage_helper.pks index eef041275..1b41c0ca3 100644 --- a/source/core/coverage/ut_block_helper.pks +++ b/source/core/coverage/ut_block_coverage_helper.pks @@ -1,4 +1,4 @@ -create or replace package ut_block_helper authid definer is +create or replace package ut_block_coverage_helper authid definer is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project diff --git a/source/core/coverage/ut_coverage_block.pkb b/source/core/coverage/ut_coverage_block.pkb index a5a9801c8..cda04cb58 100644 --- a/source/core/coverage/ut_coverage_block.pkb +++ b/source/core/coverage/ut_coverage_block.pkb @@ -104,7 +104,7 @@ create or replace package body ut_coverage_block is 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); + l_line_calls := ut_block_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 diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index e8cb198b3..d2d296aea 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -70,9 +70,9 @@ create or replace package body ut_coverage_helper is set_coverage_type(a_coverage_type); if get_coverage_type = ut_coverage.c_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id ); + ut_block_coverage_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id ); $else - null; + raise_application_error(ut_utils.gc_invalid_coverage_type,'Invalid coverage type requested. Please validate your Oracle install'); $end else ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id); @@ -123,7 +123,7 @@ create or replace package body ut_coverage_helper is g_is_started := false; if get_coverage_type = ut_coverage.c_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_helper.coverage_stop(); + ut_block_coverage_helper.coverage_stop(); $else null; $end @@ -139,7 +139,7 @@ create or replace package body ut_coverage_helper is g_is_started := false; if get_coverage_type = ut_coverage.c_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_helper.coverage_stop(); + ut_block_coverage_helper.coverage_stop(); $else null; $end diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 1bcf0b611..7931164a1 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -90,6 +90,11 @@ create or replace package ut_utils authid definer is gc_invalid_version_no constant pls_integer := -20214; pragma exception_init(ex_invalid_version_no, -20214); + -- Invalid coverage type + ex_invalid_coverage_type exception; + gc_invalid_coverage_type constant pls_integer := -20215; + pragma exception_init(ex_invalid_coverage_type, -20215); + gc_max_storage_varchar2_len constant integer := 4000; gc_max_output_string_length constant integer := 4000; gc_max_input_string_length constant integer := gc_max_output_string_length - 2; --we need to remove 2 chars for quotes around string diff --git a/source/install.sql b/source/install.sql index 275b34aff..6eb9f0b22 100644 --- a/source/install.sql +++ b/source/install.sql @@ -127,14 +127,14 @@ 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_above_12_1.sql 'core/coverage/ut_block_helper.pks' +@@install_above_12_1.sql 'core/coverage/ut_block_coverage_helper.pks' @@install_component.sql 'core/coverage/ut_proftab_helper.pks' @@install_component.sql 'core/coverage/ut_coverage.pks' @@install_above_12_1.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_above_12_1.sql 'core/coverage/ut_block_helper.pkb' +@@install_above_12_1.sql 'core/coverage/ut_block_coverage_helper.pkb' @@install_component.sql 'core/coverage/ut_proftab_helper.pkb' @@install_component.sql 'core/coverage/ut_coverage.pkb' @@install_above_12_1.sql 'core/coverage/ut_coverage_block.pkb' diff --git a/test/install_below_12_2.sql b/test/install_below_12_2.sql new file mode 100644 index 000000000..669ae75fc --- /dev/null +++ b/test/install_below_12_2.sql @@ -0,0 +1,28 @@ +set termout off +set echo off +spool dummy.sql +prompt whenever sqlerror exit failure rollback +spool off + + +def FILE_NAME = '&&1' +column SCRIPT_NAME new_value SCRIPT_NAME noprint + +VAR V_FILE_NAME VARCHAR2(1000); +begin + if dbms_db_version.version = 12 and dbms_db_version.release < 2 + or dbms_db_version.version < 12 + then + :V_FILE_NAME := '&&FILE_NAME'; + else + :V_FILE_NAME := 'dummy.sql'; + end if; +end; +/ +set verify off +select :V_FILE_NAME as SCRIPT_NAME from dual; +set termout on + + +@@&&SCRIPT_NAME + diff --git a/test/install_tests.sql b/test/install_tests.sql index 29a5176eb..142f26f27 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -27,6 +27,10 @@ whenever oserror exit failure rollback @@core/test_suite_manager.pks @@core/reporters/test_coverage.pks set define on +@@install_below_12_2.sql 'core/reporters/test_not_existing_block.pks' +@@install_below_12_2.sql 'core/reporters/test_not_existing_block.pkb' +set define off +set define on @@install_above_12_1.sql 'core/reporters/test_block_coverage.pks' @@install_above_12_1.sql 'core/reporters/test_coverage/test_html_block_reporter.pks' @@install_above_12_1.sql 'core/reporters/test_coverage/test_coveralls_reporter_block.pks' From 35e5e1376557817cec7cd1236406ed512f736703 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Tue, 3 Apr 2018 23:23:24 +0100 Subject: [PATCH 17/37] 12.2 coverage Fixes to order of new attribute. Rename package to more meaningful name Introduce an raise an error for non existing coverage type Update tests --- source/api/ut.pkb | 106 ++++++------- source/api/ut.pks | 48 +++--- source/api/ut_runner.pkb | 4 +- source/api/ut_runner.pks | 5 +- ...elper.pkb => ut_block_coverage_helper.pkb} | 2 +- ...elper.pks => ut_block_coverage_helper.pks} | 2 +- source/core/coverage/ut_coverage_block.pkb | 2 +- source/core/coverage/ut_coverage_helper.pkb | 8 +- source/core/ut_utils.pks | 5 + source/install.sql | 4 +- .../reporters/test_not_existing_block.pkb | 145 ++++++++++++++++++ .../reporters/test_not_existing_block.pks | 18 +++ test/install_below_12_2.sql | 28 ++++ test/install_tests.sql | 4 + 14 files changed, 291 insertions(+), 90 deletions(-) rename source/core/coverage/{ut_block_helper.pkb => ut_block_coverage_helper.pkb} (98%) rename source/core/coverage/{ut_block_helper.pks => ut_block_coverage_helper.pks} (92%) create mode 100644 test/core/reporters/test_not_existing_block.pkb create mode 100644 test/core/reporters/test_not_existing_block.pks create mode 100644 test/install_below_12_2.sql diff --git a/source/api/ut.pkb b/source/api/ut.pkb index 071a422bd..b085c53aa 100644 --- a/source/api/ut.pkb +++ b/source/api/ut.pkb @@ -106,40 +106,40 @@ create or replace package body ut is procedure run_autonomous( a_paths ut_varchar2_list, a_reporter ut_reporter_base, a_color_console integer, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings, a_test_file_mappings ut_file_mappings, - a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings, a_test_file_mappings ut_file_mappings, + a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list, a_coverage_type varchar2:=null ) is pragma autonomous_transaction; begin ut_runner.run( a_paths, ut_reporters(coalesce(a_reporter,ut_documentation_reporter())), - ut_utils.int_to_boolean(a_color_console), a_coverage_schemes,a_coverage_type, - a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects + ut_utils.int_to_boolean(a_color_console), a_coverage_schemes, a_source_file_mappings, + a_test_file_mappings, a_include_objects, a_exclude_objects, false, a_coverage_type ); rollback; end; procedure run_autonomous( a_paths ut_varchar2_list, a_reporter ut_reporter_base, a_color_console integer, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list, a_coverage_type varchar2:=null ) is pragma autonomous_transaction; begin ut_runner.run( a_paths, ut_reporters(coalesce(a_reporter,ut_documentation_reporter())), - ut_utils.int_to_boolean(a_color_console), a_coverage_schemes,a_coverage_type, + ut_utils.int_to_boolean(a_color_console), a_coverage_schemes, ut_file_mapper.build_file_mappings(a_source_files), ut_file_mapper.build_file_mappings(a_test_files), - a_include_objects, a_exclude_objects + a_include_objects, a_exclude_objects, false, a_coverage_type ); rollback; end; function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(sys_context('userenv', 'current_schema')); @@ -148,7 +148,7 @@ create or replace package body ut is begin run_autonomous( l_paths, l_reporter, a_color_console, - a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects + a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects,a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -165,8 +165,8 @@ create or replace package body ut is function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(sys_context('userenv', 'current_schema')); @@ -174,8 +174,8 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - l_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -192,16 +192,16 @@ create or replace package body ut is function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_lines sys_refcursor; l_line varchar2(4000); begin run_autonomous( - a_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects + a_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -218,16 +218,16 @@ create or replace package body ut is function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_lines sys_refcursor; l_line varchar2(4000); begin run_autonomous( - a_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + a_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -244,8 +244,8 @@ create or replace package body ut is function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null,a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); @@ -253,8 +253,8 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - l_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects + l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_include_objects, a_exclude_objects,a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -271,8 +271,8 @@ create or replace package body ut is function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); @@ -280,8 +280,8 @@ create or replace package body ut is l_line varchar2(4000); begin run_autonomous( - l_paths, l_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -298,14 +298,14 @@ create or replace package body ut is procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); begin run_autonomous( - a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects + a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_include_objects, a_exclude_objects, a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then treat(l_reporter as ut_output_reporter_base).lines_to_dbms_output(); @@ -315,14 +315,14 @@ create or replace package body ut is procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null,a_coverage_type varchar2:=null ) is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); begin run_autonomous( - a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects,a_coverage_type ); if l_reporter is of (ut_output_reporter_base) then treat(l_reporter as ut_output_reporter_base).lines_to_dbms_output(); @@ -332,51 +332,51 @@ create or replace package body ut is procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is begin ut.run( ut_varchar2_list(sys_context('userenv', 'current_schema')), a_reporter, a_color_console, - a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects + a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects, a_coverage_type ); end; procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is begin ut.run( ut_varchar2_list(sys_context('userenv', 'current_schema')), a_reporter, a_color_console, - a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, a_include_objects, a_exclude_objects + a_coverage_schemes, a_source_files, a_test_files, a_include_objects, a_exclude_objects, a_coverage_type ); end; procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); begin ut.run( - l_paths, a_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects + l_paths, a_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, + a_include_objects, a_exclude_objects, a_coverage_type ); end; procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) is l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); begin ut.run( - l_paths, a_reporter, a_color_console, a_coverage_schemes,a_coverage_type, a_source_files, a_test_files, - a_include_objects, a_exclude_objects + l_paths, a_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, + a_include_objects, a_exclude_objects ,a_coverage_type ); end; diff --git a/source/api/ut.pks b/source/api/ut.pks index f479f12fd..1d55951d0 100644 --- a/source/api/ut.pks +++ b/source/api/ut.pks @@ -49,74 +49,74 @@ create or replace package ut authid current_user as function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ) return ut_varchar2_rows pipelined; procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2:=null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null + a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null ); /** diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index 5476f84fc..7e6bd3250 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -66,8 +66,8 @@ create or replace package body ut_runner is procedure run( a_paths ut_varchar2_list, a_reporters ut_reporters, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2 := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false,a_coverage_type varchar2 := null ) is l_items_to_run ut_run; l_listener ut_event_listener; diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index 65341b9e0..882b520f3 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -57,8 +57,9 @@ create or replace package ut_runner authid current_user is */ procedure run( a_paths ut_varchar2_list, a_reporters ut_reporters, a_color_console boolean := false, - a_coverage_schemes ut_varchar2_list := null,a_coverage_type varchar2 := null , a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false + a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, + a_fail_on_errors boolean default false, a_coverage_type varchar2 := null ); /** diff --git a/source/core/coverage/ut_block_helper.pkb b/source/core/coverage/ut_block_coverage_helper.pkb similarity index 98% rename from source/core/coverage/ut_block_helper.pkb rename to source/core/coverage/ut_block_coverage_helper.pkb index f0c2322ab..346b47e27 100644 --- a/source/core/coverage/ut_block_helper.pkb +++ b/source/core/coverage/ut_block_coverage_helper.pkb @@ -1,4 +1,4 @@ -create or replace package body ut_block_helper is +create or replace package body ut_block_coverage_helper is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project diff --git a/source/core/coverage/ut_block_helper.pks b/source/core/coverage/ut_block_coverage_helper.pks similarity index 92% rename from source/core/coverage/ut_block_helper.pks rename to source/core/coverage/ut_block_coverage_helper.pks index eef041275..1b41c0ca3 100644 --- a/source/core/coverage/ut_block_helper.pks +++ b/source/core/coverage/ut_block_coverage_helper.pks @@ -1,4 +1,4 @@ -create or replace package ut_block_helper authid definer is +create or replace package ut_block_coverage_helper authid definer is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project diff --git a/source/core/coverage/ut_coverage_block.pkb b/source/core/coverage/ut_coverage_block.pkb index a5a9801c8..cda04cb58 100644 --- a/source/core/coverage/ut_coverage_block.pkb +++ b/source/core/coverage/ut_coverage_block.pkb @@ -104,7 +104,7 @@ create or replace package body ut_coverage_block is 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); + l_line_calls := ut_block_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 diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index e8cb198b3..d2d296aea 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -70,9 +70,9 @@ create or replace package body ut_coverage_helper is set_coverage_type(a_coverage_type); if get_coverage_type = ut_coverage.c_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id ); + ut_block_coverage_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id ); $else - null; + raise_application_error(ut_utils.gc_invalid_coverage_type,'Invalid coverage type requested. Please validate your Oracle install'); $end else ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id); @@ -123,7 +123,7 @@ create or replace package body ut_coverage_helper is g_is_started := false; if get_coverage_type = ut_coverage.c_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_helper.coverage_stop(); + ut_block_coverage_helper.coverage_stop(); $else null; $end @@ -139,7 +139,7 @@ create or replace package body ut_coverage_helper is g_is_started := false; if get_coverage_type = ut_coverage.c_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_helper.coverage_stop(); + ut_block_coverage_helper.coverage_stop(); $else null; $end diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 1bcf0b611..7931164a1 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -90,6 +90,11 @@ create or replace package ut_utils authid definer is gc_invalid_version_no constant pls_integer := -20214; pragma exception_init(ex_invalid_version_no, -20214); + -- Invalid coverage type + ex_invalid_coverage_type exception; + gc_invalid_coverage_type constant pls_integer := -20215; + pragma exception_init(ex_invalid_coverage_type, -20215); + gc_max_storage_varchar2_len constant integer := 4000; gc_max_output_string_length constant integer := 4000; gc_max_input_string_length constant integer := gc_max_output_string_length - 2; --we need to remove 2 chars for quotes around string diff --git a/source/install.sql b/source/install.sql index 275b34aff..6eb9f0b22 100644 --- a/source/install.sql +++ b/source/install.sql @@ -127,14 +127,14 @@ 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_above_12_1.sql 'core/coverage/ut_block_helper.pks' +@@install_above_12_1.sql 'core/coverage/ut_block_coverage_helper.pks' @@install_component.sql 'core/coverage/ut_proftab_helper.pks' @@install_component.sql 'core/coverage/ut_coverage.pks' @@install_above_12_1.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_above_12_1.sql 'core/coverage/ut_block_helper.pkb' +@@install_above_12_1.sql 'core/coverage/ut_block_coverage_helper.pkb' @@install_component.sql 'core/coverage/ut_proftab_helper.pkb' @@install_component.sql 'core/coverage/ut_coverage.pkb' @@install_above_12_1.sql 'core/coverage/ut_coverage_block.pkb' diff --git a/test/core/reporters/test_not_existing_block.pkb b/test/core/reporters/test_not_existing_block.pkb new file mode 100644 index 000000000..348bc065c --- /dev/null +++ b/test/core/reporters/test_not_existing_block.pkb @@ -0,0 +1,145 @@ +create or replace package body test_coverage is + + g_run_id integer; + + function get_mock_run_id return integer is + v_result integer; + begin + select nvl(min(runid),0) - 1 into v_result + from ut3.plsql_profiler_runs; + return v_result; + end; + + procedure create_dummy_coverage_package is + pragma autonomous_transaction; + begin + execute immediate q'[create or replace package UT3.DUMMY_COVERAGE is + procedure do_stuff; + end;]'; + execute immediate q'[create or replace package body UT3.DUMMY_COVERAGE is + procedure do_stuff is + begin + if 1 = 2 then + dbms_output.put_line('should not get here'); + else + dbms_output.put_line('should get here'); + end if; + end; + end;]'; + end; + + procedure create_dummy_coverage_test is + pragma autonomous_transaction; + begin + execute immediate q'[create or replace package UT3.TEST_DUMMY_COVERAGE is + --%suite(dummy coverage test) + --%suitepath(coverage_testing) + + --%test + procedure test_do_stuff; + end;]'; + execute immediate q'[create or replace package body UT3.TEST_DUMMY_COVERAGE is + procedure test_do_stuff is + begin + dummy_coverage.do_stuff; + end; + end;]'; + end; + + procedure create_dummy_coverage_test_1 is + pragma autonomous_transaction; + begin + execute immediate q'[create or replace package UT3.DUMMY_COVERAGE_1 is + procedure do_stuff; + end;]'; + execute immediate q'[create or replace package body UT3.DUMMY_COVERAGE_1 is + procedure do_stuff is + begin + if 1 = 2 then + dbms_output.put_line('should not get here'); + else + dbms_output.put_line('should get here'); + end if; + end; + end;]'; + execute immediate q'[create or replace package UT3.TEST_DUMMY_COVERAGE_1 is + --%suite(dummy coverage test 1) + --%suitepath(coverage_testing) + + --%test + procedure test_do_stuff; + end;]'; + execute immediate q'[create or replace package body UT3.TEST_DUMMY_COVERAGE_1 is + procedure test_do_stuff is + begin + dummy_coverage_1.do_stuff; + end; + end;]'; + end; + + procedure drop_dummy_coverage_test_1 is + pragma autonomous_transaction; + begin + execute immediate q'[drop package UT3.DUMMY_COVERAGE_1]'; + execute immediate q'[drop package UT3.TEST_DUMMY_COVERAGE_1]'; + end; + + + procedure mock_coverage_data(a_run_id integer) is + c_unit_id constant integer := 1; + begin + insert into ut3.plsql_profiler_runs ( runid, run_owner, run_date, run_comment) + values(a_run_id, user, sysdate, 'unit testing utPLSQL'); + + insert into ut3.plsql_profiler_units ( runid, unit_number, unit_type, unit_owner, unit_name) + values(a_run_id, c_unit_id, 'PACKAGE BODY', 'UT3', 'DUMMY_COVERAGE'); + + insert into ut3.plsql_profiler_data ( runid, unit_number, line#, total_occur, total_time) + select a_run_id, c_unit_id, 4, 1, 1 from dual union all + select a_run_id, c_unit_id, 5, 0, 0 from dual union all + select a_run_id, c_unit_id, 7, 1, 1 from dual; + end; + + procedure setup_dummy_coverage is + pragma autonomous_transaction; + begin + create_dummy_coverage_package(); + create_dummy_coverage_test(); + g_run_id := get_mock_run_id(); + ut3.ut_coverage_helper.mock_coverage_id(g_run_id); + mock_coverage_data(g_run_id); + commit; + end; + + procedure cleanup_dummy_coverage is + pragma autonomous_transaction; + begin + begin execute immediate q'[drop package ut3.test_dummy_coverage]'; exception when others then null; end; + begin execute immediate q'[drop package ut3.dummy_coverage]'; exception when others then null; end; + delete from ut3.plsql_profiler_data where runid = g_run_id; + delete from ut3.plsql_profiler_units where runid = g_run_id; + delete from ut3.plsql_profiler_runs where runid = g_run_id; + commit; + end; + + procedure invalid_coverage_type is + l_expected clob; + l_actual clob; + l_results ut3.ut_varchar2_list; + begin + --Arrange + l_expected := '%%'; + --Act + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_sonar_reporter( ), + a_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage' ) + ) + ); + end; + +end; +/ diff --git a/test/core/reporters/test_not_existing_block.pks b/test/core/reporters/test_not_existing_block.pks new file mode 100644 index 000000000..161c03058 --- /dev/null +++ b/test/core/reporters/test_not_existing_block.pks @@ -0,0 +1,18 @@ +create or replace package test_coverage is + + --%suite + --%suitepath(utplsql.core.reporters) + + --%beforeall + procedure setup_dummy_coverage; + + --%afterall + procedure cleanup_dummy_coverage; + + + --%test(Coverage is requested for invalid type of coverage) + --%throws(-20215) + procedure invalid_coverage_type; + +end; +/ diff --git a/test/install_below_12_2.sql b/test/install_below_12_2.sql new file mode 100644 index 000000000..669ae75fc --- /dev/null +++ b/test/install_below_12_2.sql @@ -0,0 +1,28 @@ +set termout off +set echo off +spool dummy.sql +prompt whenever sqlerror exit failure rollback +spool off + + +def FILE_NAME = '&&1' +column SCRIPT_NAME new_value SCRIPT_NAME noprint + +VAR V_FILE_NAME VARCHAR2(1000); +begin + if dbms_db_version.version = 12 and dbms_db_version.release < 2 + or dbms_db_version.version < 12 + then + :V_FILE_NAME := '&&FILE_NAME'; + else + :V_FILE_NAME := 'dummy.sql'; + end if; +end; +/ +set verify off +select :V_FILE_NAME as SCRIPT_NAME from dual; +set termout on + + +@@&&SCRIPT_NAME + diff --git a/test/install_tests.sql b/test/install_tests.sql index 29a5176eb..142f26f27 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -27,6 +27,10 @@ whenever oserror exit failure rollback @@core/test_suite_manager.pks @@core/reporters/test_coverage.pks set define on +@@install_below_12_2.sql 'core/reporters/test_not_existing_block.pks' +@@install_below_12_2.sql 'core/reporters/test_not_existing_block.pkb' +set define off +set define on @@install_above_12_1.sql 'core/reporters/test_block_coverage.pks' @@install_above_12_1.sql 'core/reporters/test_coverage/test_html_block_reporter.pks' @@install_above_12_1.sql 'core/reporters/test_coverage/test_coveralls_reporter_block.pks' From c0ca9d39650906bbce07cbc4f00b8328e6aad40b Mon Sep 17 00:00:00 2001 From: lwasylow Date: Tue, 3 Apr 2018 23:56:12 +0100 Subject: [PATCH 18/37] Fixing error in package name --- test/core/reporters/test_not_existing_block.pkb | 2 +- test/core/reporters/test_not_existing_block.pks | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/reporters/test_not_existing_block.pkb b/test/core/reporters/test_not_existing_block.pkb index 348bc065c..449b8eccf 100644 --- a/test/core/reporters/test_not_existing_block.pkb +++ b/test/core/reporters/test_not_existing_block.pkb @@ -1,4 +1,4 @@ -create or replace package body test_coverage is +create or replace package body test_not_existing_block is g_run_id integer; diff --git a/test/core/reporters/test_not_existing_block.pks b/test/core/reporters/test_not_existing_block.pks index 161c03058..3b734c062 100644 --- a/test/core/reporters/test_not_existing_block.pks +++ b/test/core/reporters/test_not_existing_block.pks @@ -1,4 +1,4 @@ -create or replace package test_coverage is +create or replace package test_not_existing_block is --%suite --%suitepath(utplsql.core.reporters) From f151a6e43ab7ed03ebc644537eb49e3eb6462f7e Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 4 Apr 2018 20:48:45 +0100 Subject: [PATCH 19/37] Update test --- test/core/reporters/test_not_existing_block.pkb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/core/reporters/test_not_existing_block.pkb b/test/core/reporters/test_not_existing_block.pkb index 449b8eccf..5c053a6b2 100644 --- a/test/core/reporters/test_not_existing_block.pkb +++ b/test/core/reporters/test_not_existing_block.pkb @@ -136,6 +136,7 @@ create or replace package body test_not_existing_block is ut3.ut.run( a_path => 'ut3.test_dummy_coverage', a_reporter=> ut3.ut_coverage_sonar_reporter( ), + a_coverage_type => 'block', a_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage' ) ) ); From 28f765317b1fbb799573cc2900de1ac339ad0088 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sat, 7 Apr 2018 17:20:40 +0100 Subject: [PATCH 20/37] Statement Coverage First Commit --- .../coverage/ut_block_coverage_helper.pkb | 8 +- source/core/coverage/ut_coverage.pkb | 5 +- source/core/coverage/ut_coverage.pks | 3 +- source/core/coverage/ut_coverage_block.pkb | 3 +- source/core/coverage/ut_coverage_extended.pkb | 173 ++++++++++++++ source/core/coverage/ut_coverage_extended.pks | 22 ++ source/core/coverage/ut_coverage_helper.pkb | 32 ++- source/core/coverage/ut_coverage_helper.pks | 9 +- source/core/coverage/ut_coverage_proftab.pkb | 3 +- source/core/coverage/ut_proftab_helper.pkb | 2 +- source/install.sql | 4 + .../reporters/ut_coverage_html_reporter.tpb | 1 - .../ut_coverage_report_html_helper.pkb | 6 +- .../ut_extended_report_html_helper.pkb | 226 ++++++++++++++++++ .../ut_extended_report_html_helper.pks | 21 ++ 15 files changed, 496 insertions(+), 22 deletions(-) create mode 100644 source/core/coverage/ut_coverage_extended.pkb create mode 100644 source/core/coverage/ut_coverage_extended.pks create mode 100644 source/reporters/ut_extended_report_html_helper.pkb create mode 100644 source/reporters/ut_extended_report_html_helper.pks diff --git a/source/core/coverage/ut_block_coverage_helper.pkb b/source/core/coverage/ut_block_coverage_helper.pkb index 346b47e27..d6fbabdbb 100644 --- a/source/core/coverage/ut_block_coverage_helper.pkb +++ b/source/core/coverage/ut_block_coverage_helper.pkb @@ -43,8 +43,9 @@ create or replace package body ut_block_coverage_helper is 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; + l_coverage_id integer := ut_coverage_helper.get_coverage_id(ut_coverage.c_block_coverage); begin + open c_raw_coverage for q'[select ccb.line ,count(ccb.block) totalblocks ,sum(ccb.covered) @@ -57,10 +58,10 @@ create or replace package body ut_block_coverage_helper is 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; @@ -70,6 +71,7 @@ create or replace package body ut_block_coverage_helper is 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; diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index fd0cc3b9a..d0503eb50 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -106,10 +106,13 @@ create or replace package body ut_coverage is if a_coverage_options.coverage_type = c_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - return ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); + return ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); $else return null; $end + elsif a_coverage_options.coverage_type = c_extended_coverage then + --Collect data for block and proftab and pass to extended for modifications. + return ut_coverage_extended.get_extended_coverage(a_coverage_options => a_coverage_options); else return ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); end if; diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks index db659c049..2d80edaef 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -18,7 +18,8 @@ create or replace package ut_coverage authid current_user is c_proftab_coverage constant varchar2(32) := 'proftab'; c_block_coverage constant varchar2(32) := 'block'; - + c_extended_coverage constant varchar2(32) := 'extended'; + -- total run coverage information subtype t_full_name is varchar2(4000); subtype t_object_name is varchar2(250); diff --git a/source/core/coverage/ut_coverage_block.pkb b/source/core/coverage/ut_coverage_block.pkb index cda04cb58..95d1331e0 100644 --- a/source/core/coverage/ut_coverage_block.pkb +++ b/source/core/coverage/ut_coverage_block.pkb @@ -105,7 +105,6 @@ create or replace package body ut_coverage_block is --get coverage data l_line_calls := ut_block_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 @@ -120,7 +119,7 @@ create or replace package body ut_coverage_block is 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; + l_result.total_lines := nvl(l_result.total_lines,0) + l_source_object.lines_count; --populate object level coverage stats if not l_result.objects.exists(l_source_object.full_name) then diff --git a/source/core/coverage/ut_coverage_extended.pkb b/source/core/coverage/ut_coverage_extended.pkb new file mode 100644 index 000000000..cf5820e78 --- /dev/null +++ b/source/core/coverage/ut_coverage_extended.pkb @@ -0,0 +1,173 @@ +create or replace package body ut_coverage_extended 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_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 extend coverage + P - profiler line result, C - coverage line result, X-result + Dla ka?dej linii:X=greatest(P,nvl(C,0)) + Czyli: + If P is null - line is irrelevant + If P or X > 0 - line is covered + */ + + + function get_extended_coverage(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is + l_result ut_coverage.t_coverage; + l_result_block ut_coverage.t_coverage; + l_result_profiler ut_coverage.t_coverage; + l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr; + l_source_object ut_coverage_helper.t_tmp_table_object; + l_new_unit ut_coverage.t_unit_coverage; + line_no binary_integer; + begin + l_result_block := ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); + l_result_profiler:= ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); + + + 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; + --check if we have a hits in any of reporters + if l_result_block.total_lines > 0 or l_result_profiler.total_lines > 0 then + --update total stats + l_result.total_lines := nvl(l_result.total_lines,0) + l_source_object.lines_count; + l_result.total_blocks := l_result_block.total_blocks; + l_result.uncovered_blocks := l_result_block.uncovered_blocks; + l_result.covered_blocks := l_result_block.covered_blocks; + l_result.partcovered_lines := l_result_block.partcovered_lines; + + --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; + l_result.objects(l_source_object.full_name).total_blocks := l_result_block.objects(l_source_object.full_name).total_blocks; + l_result.objects(l_source_object.full_name).uncovered_blocks := l_result_block.objects(l_source_object.full_name).uncovered_blocks; + l_result.objects(l_source_object.full_name).covered_blocks := l_result_block.objects(l_source_object.full_name).covered_blocks; + l_result.objects(l_source_object.full_name).partcovered_lines := l_result_block.objects(l_source_object.full_name).partcovered_lines; + end if; + + line_no := coalesce(l_result_block.objects(l_source_object.full_name).lines.first, + l_result_profiler.objects(l_source_object.full_name).lines.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; + -- object level stats + + -- Failing on non existing data for block objects.Check if exists and then use it + l_result.objects(l_source_object.full_name).lines(line_no).executions := greatest(l_result_block.objects(l_source_object.full_name).lines(line_no).executions, + l_result_profiler.objects(l_source_object.full_name).lines(line_no).executions); + l_result.objects(l_source_object.full_name).lines(line_no).no_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(line_no).no_blocks,0); + l_result.objects(l_source_object.full_name).lines(line_no).covered_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(line_no).covered_blocks,0); + l_result.objects(l_source_object.full_name).lines(line_no).partcove := l_result_block.objects(l_source_object.full_name).lines(line_no).partcove; + -- total level stats + + -- Recalculate total lines + if l_result.objects(l_source_object.full_name).lines(line_no).executions > 0 then + -- total level stats + l_result.executions := l_result.executions + l_result.objects(l_source_object.full_name).lines(line_no).executions; + l_result.covered_lines := l_result.covered_lines + 1; + -- object level stats + l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name) + .uncovered_lines + 1; + elsif l_result.objects(l_source_object.full_name).lines(line_no).executions = 0 then + -- total level stats + l_result.uncovered_lines := l_result.uncovered_lines + 1; + -- object level stats + l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name) + .uncovered_lines + 1; + end if; + + line_no := coalesce(l_result_block.objects(l_source_object.full_name).lines.next(line_no), + l_result_profiler.objects(l_source_object.full_name).lines.next(line_no)); + + end loop; + end if; + end if; + + end loop; + close l_source_objects_crsr; + return l_result; + + end get_extended_coverage; + +end; +/ diff --git a/source/core/coverage/ut_coverage_extended.pks b/source/core/coverage/ut_coverage_extended.pks new file mode 100644 index 000000000..67bc93ce5 --- /dev/null +++ b/source/core/coverage/ut_coverage_extended.pks @@ -0,0 +1,22 @@ +create or replace package ut_coverage_extended 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_extended_coverage(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 d2d296aea..542991e74 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -55,9 +55,9 @@ create or replace package body ut_coverage_helper is return g_coverage_type; end; - function get_coverage_id return integer is + function get_coverage_id(a_coverage_type in varchar2) return integer is begin - return g_coverage_id; + return g_coverage_id(a_coverage_type); end; function is_develop_mode return boolean is @@ -70,12 +70,20 @@ create or replace package body ut_coverage_helper is set_coverage_type(a_coverage_type); if get_coverage_type = ut_coverage.c_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_coverage_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id ); + ut_block_coverage_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id(ut_coverage.c_block_coverage) ); + $else + raise_application_error(ut_utils.gc_invalid_coverage_type,'Invalid coverage type requested. Please validate your Oracle install'); + $end + elsif get_coverage_type = ut_coverage.c_extended_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_block_coverage_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id(ut_coverage.c_block_coverage) ); + ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id(ut_coverage.c_proftab_coverage)); + coverage_pause(); $else raise_application_error(ut_utils.gc_invalid_coverage_type,'Invalid coverage type requested. Please validate your Oracle install'); $end else - ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id); + ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id(ut_coverage.c_proftab_coverage)); coverage_pause(); end if; g_is_started := true; @@ -127,6 +135,13 @@ create or replace package body ut_coverage_helper is $else null; $end + elsif get_coverage_type = ut_coverage.c_extended_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_proftab_helper.coverage_stop(); + ut_block_coverage_helper.coverage_stop(); + $else + null; + $end else ut_proftab_helper.coverage_stop(); end if; @@ -143,6 +158,13 @@ create or replace package body ut_coverage_helper is $else null; $end + elsif get_coverage_type = ut_coverage.c_extended_coverage then + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_proftab_helper.coverage_stop(); + ut_block_coverage_helper.coverage_stop(); + $else + null; + $end else ut_proftab_helper.coverage_stop(); end if; @@ -152,7 +174,7 @@ create or replace package body ut_coverage_helper is begin g_develop_mode := true; g_is_started := true; - g_coverage_id := a_coverage_id; + g_coverage_id(g_coverage_type) := a_coverage_id; end; procedure insert_into_tmp_table(a_data t_coverage_sources_tmp_rows) is diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index 6728fd4b3..16a6faed9 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -16,13 +16,14 @@ create or replace package ut_coverage_helper authid definer is limitations under the License. */ - - g_coverage_id integer; + type g_coverage_arr is table of integer index by varchar2(30); + g_coverage_id g_coverage_arr; + --g_coverage_id integer; g_coverage_type varchar2(32); - + function get_coverage_type return varchar2; - function get_coverage_id return integer; + function get_coverage_id(a_coverage_type in varchar2) return integer; procedure set_coverage_type(a_coverage_type in varchar2); diff --git a/source/core/coverage/ut_coverage_proftab.pkb b/source/core/coverage/ut_coverage_proftab.pkb index 1fa550acf..f07024744 100644 --- a/source/core/coverage/ut_coverage_proftab.pkb +++ b/source/core/coverage/ut_coverage_proftab.pkb @@ -131,8 +131,7 @@ create or replace package body ut_coverage_proftab is 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; - + l_result.total_lines := nvl(l_result.total_lines,0) + 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; diff --git a/source/core/coverage/ut_proftab_helper.pkb b/source/core/coverage/ut_proftab_helper.pkb index bf40ba531..b572383ce 100644 --- a/source/core/coverage/ut_proftab_helper.pkb +++ b/source/core/coverage/ut_proftab_helper.pkb @@ -56,7 +56,7 @@ create or replace package body ut_proftab_helper 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; - l_coverage_id integer := ut_coverage_helper.get_coverage_id; + l_coverage_id integer := ut_coverage_helper.get_coverage_id(ut_coverage.c_proftab_coverage); 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 diff --git a/source/install.sql b/source/install.sql index 6eb9f0b22..657608916 100644 --- a/source/install.sql +++ b/source/install.sql @@ -128,6 +128,7 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema @@install_component.sql 'core/coverage/ut_coverage_sources_tmp.sql' @@install_component.sql 'core/coverage/ut_coverage_helper.pks' @@install_above_12_1.sql 'core/coverage/ut_block_coverage_helper.pks' +@@install_above_12_1.sql 'core/coverage/ut_coverage_extended.pks' @@install_component.sql 'core/coverage/ut_proftab_helper.pks' @@install_component.sql 'core/coverage/ut_coverage.pks' @@install_above_12_1.sql 'core/coverage/ut_coverage_block.pks' @@ -135,6 +136,7 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema @@install_component.sql 'core/coverage/ut_coverage_reporter_base.tps' @@install_component.sql 'core/coverage/ut_coverage_helper.pkb' @@install_above_12_1.sql 'core/coverage/ut_block_coverage_helper.pkb' +@@install_above_12_1.sql 'core/coverage/ut_coverage_extended.pkb' @@install_component.sql 'core/coverage/ut_proftab_helper.pkb' @@install_component.sql 'core/coverage/ut_coverage.pkb' @@install_above_12_1.sql 'core/coverage/ut_coverage_block.pkb' @@ -259,8 +261,10 @@ 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_above_12_1.sql 'reporters/ut_block_report_html_helper.pks' +@@install_above_12_1.sql 'reporters/ut_extended_report_html_helper.pks' @@install_component.sql 'reporters/ut_proftab_report_html_helper.pks' @@install_above_12_1.sql 'reporters/ut_block_report_html_helper.pkb' +@@install_above_12_1.sql 'reporters/ut_extended_report_html_helper.pkb' @@install_component.sql 'reporters/ut_coverage_report_html_helper.pkb' @@install_component.sql 'reporters/ut_proftab_report_html_helper.pkb' @@install_component.sql 'reporters/ut_coverage_html_reporter.tpb' diff --git a/source/reporters/ut_coverage_html_reporter.tpb b/source/reporters/ut_coverage_html_reporter.tpb index 504e34f19..2c5e2b15a 100644 --- a/source/reporters/ut_coverage_html_reporter.tpb +++ b/source/reporters/ut_coverage_html_reporter.tpb @@ -33,7 +33,6 @@ create or replace type body ut_coverage_html_reporter is l_coverage_data ut_coverage.t_coverage; begin ut_coverage.coverage_stop(); - l_coverage_data := ut_coverage.get_coverage_data(a_run.coverage_options); self.print_clob( ut_coverage_report_html_helper.get_index( a_coverage_data => l_coverage_data,a_assets_path => self.assets_path, a_project_name=> self.project_name, a_coverage_type => a_run.coverage_options.coverage_type ) ); diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb index b18369b8f..837b04063 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -105,13 +105,15 @@ create or replace package body ut_coverage_report_html_helper is return clob is l_result clob; l_coverage_type varchar2(32) := coalesce(a_coverage_type, ut_coverage.c_proftab_coverage); - begin + begin if l_coverage_type = ut_coverage.c_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); $else l_result := null; $end + elsif l_coverage_type = ut_coverage.c_extended_coverage then + l_result := ut_extended_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); else l_result := ut_proftab_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); end if; diff --git a/source/reporters/ut_extended_report_html_helper.pkb b/source/reporters/ut_extended_report_html_helper.pkb new file mode 100644 index 000000000..73262236e --- /dev/null +++ b/source/reporters/ut_extended_report_html_helper.pkb @@ -0,0 +1,226 @@ +create or replace package body ut_extended_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 := '

    ' || + dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || + '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || + ' lines covered ' || + '(including ' || a_coverage_unit.partcovered_lines || + ' lines partially covered ' + || ') and ' || a_coverage_unit.uncovered_lines || + ' lines missed'||'

    ' || l_coverage_block_pct || ' % blocks covered

    '|| + '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| + ''||a_coverage_unit.covered_blocks||' blocks covered and '|| + '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' + ||'
      '; + 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 := ' +
    1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    2. '; + else + l_hits := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| + to_char(a_coverage_unit.lines(line_no).no_blocks); + + l_file_part := ' +
    3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
    4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ); + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + begin + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
    ' || '

    ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + ', ' || + l_coverage_block_pct || '%' || ' executed blocks covered)' + ||'

    ' || '' || '
    ' || + a_coverage.objects.count || ' files in total.
    ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered' || + ' (inlcluding ' || a_coverage.partcovered_lines || + ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + '
    '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| + ''||a_coverage.covered_blocks||' blocks covered and '|| + '' || a_coverage.uncovered_blocks || ' blocks missed.
    ' + ||'' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + + --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
    File% coveredLinesRelevant LinesLines coveredLines missed' + ||'% blocks covered' ||'
    ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || + (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || + '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || + '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' + || '
    '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + + /* + * public definitions + */ + 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 is + + l_file_part varchar2(32767); + l_result clob; + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + begin + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
    using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || '' || l_title || + '' || '' || + '' || + '' || + '' || '' || '' || + '
    loading
    ' || + ''; + + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + +end; +/ diff --git a/source/reporters/ut_extended_report_html_helper.pks b/source/reporters/ut_extended_report_html_helper.pks new file mode 100644 index 000000000..dc6076f1d --- /dev/null +++ b/source/reporters/ut_extended_report_html_helper.pks @@ -0,0 +1,21 @@ +create or replace package ut_extended_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; +/ From d8b8e8759c530a7567f9433e6981ed9c14d8fd29 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sat, 7 Apr 2018 21:16:59 +0100 Subject: [PATCH 21/37] Updated coverage with statement level information --- source/core/coverage/ut_coverage.pkb | 1 - source/core/coverage/ut_coverage_extended.pkb | 56 +++++++++++-------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index 4266b3d08..e6722186b 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -102,7 +102,6 @@ create or replace package body ut_coverage is end; function get_coverage_data(a_coverage_options ut_coverage_options) return t_coverage is - l_line_no binary_integer; begin if a_coverage_options.coverage_type = gc_block_coverage then diff --git a/source/core/coverage/ut_coverage_extended.pkb b/source/core/coverage/ut_coverage_extended.pkb index 97b58f539..43ce62ba4 100644 --- a/source/core/coverage/ut_coverage_extended.pkb +++ b/source/core/coverage/ut_coverage_extended.pkb @@ -104,24 +104,24 @@ create or replace package body ut_coverage_extended is if l_result_block.total_lines > 0 or l_result_profiler.total_lines > 0 then --update total stats l_result.total_lines := nvl(l_result.total_lines,0) + l_source_object.lines_count; - l_result.total_blocks := l_result_block.total_blocks; - l_result.uncovered_blocks := l_result_block.uncovered_blocks; - l_result.covered_blocks := l_result_block.covered_blocks; - l_result.partcovered_lines := l_result_block.partcovered_lines; + l_result.total_blocks := nvl(l_result_block.total_blocks,0); + l_result.uncovered_blocks := nvl(l_result_block.uncovered_blocks,0); + l_result.covered_blocks := nvl(l_result_block.covered_blocks,0); + l_result.partcovered_lines := nvl(l_result_block.partcovered_lines,0); --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).name := l_source_object.name; l_result.objects(l_source_object.full_name).total_lines := l_source_object.lines_count; - l_result.objects(l_source_object.full_name).total_blocks := l_result_block.objects(l_source_object.full_name).total_blocks; - l_result.objects(l_source_object.full_name).uncovered_blocks := l_result_block.objects(l_source_object.full_name).uncovered_blocks; - l_result.objects(l_source_object.full_name).covered_blocks := l_result_block.objects(l_source_object.full_name).covered_blocks; - l_result.objects(l_source_object.full_name).partcovered_lines := l_result_block.objects(l_source_object.full_name).partcovered_lines; + l_result.objects(l_source_object.full_name).total_blocks := nvl(l_result_block.objects(l_source_object.full_name).total_blocks,0); + l_result.objects(l_source_object.full_name).uncovered_blocks := nvl(l_result_block.objects(l_source_object.full_name).uncovered_blocks,0); + l_result.objects(l_source_object.full_name).covered_blocks := nvl(l_result_block.objects(l_source_object.full_name).covered_blocks,0); + l_result.objects(l_source_object.full_name).partcovered_lines := nvl(l_result_block.objects(l_source_object.full_name).partcovered_lines,0); end if; - l_line_no := coalesce(l_result_block.objects(l_source_object.full_name).lines.first, + l_line_no := least(l_result_block.objects(l_source_object.full_name).lines.first, l_result_profiler.objects(l_source_object.full_name).lines.first); if l_line_no is null then @@ -130,15 +130,27 @@ create or replace package body ut_coverage_extended is else loop exit when l_line_no is null; - -- object level stats - - -- Failing on non existing data for block objects.Check if exists and then use it - l_result.objects(l_source_object.full_name).lines(l_line_no).executions := greatest(l_result_block.objects(l_source_object.full_name).lines(l_line_no).executions, - l_result_profiler.objects(l_source_object.full_name).lines(l_line_no).executions); - l_result.objects(l_source_object.full_name).lines(l_line_no).no_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(l_line_no).no_blocks,0); - l_result.objects(l_source_object.full_name).lines(l_line_no).covered_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(l_line_no).covered_blocks,0); - l_result.objects(l_source_object.full_name).lines(l_line_no).partcove := l_result_block.objects(l_source_object.full_name).lines(l_line_no).partcove; - -- total level stats + + -- Set executions to zero at beginning, specific coverage will overwrite if exists. + l_result.objects(l_source_object.full_name).lines(l_line_no).executions := 0; + l_result.objects(l_source_object.full_name).lines(l_line_no).no_blocks := 0; + l_result.objects(l_source_object.full_name).lines(l_line_no).covered_blocks := 0; + l_result.objects(l_source_object.full_name).lines(l_line_no).partcove := 0; + + -- we need to check if given index exists for that coverage type or we get no data found + if l_result_block.objects(l_source_object.full_name).lines.exists(l_line_no) then + l_result.objects(l_source_object.full_name).lines(l_line_no).no_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(l_line_no).no_blocks,0); + l_result.objects(l_source_object.full_name).lines(l_line_no).covered_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(l_line_no).covered_blocks,0); + l_result.objects(l_source_object.full_name).lines(l_line_no).partcove := NVL(l_result_block.objects(l_source_object.full_name).lines(l_line_no).partcove,0); + --We capture block executions here, since block coverage do not capture more than 1 + --if profiler executions exists we will use that number as profiler shows hits correctly + + l_result.objects(l_source_object.full_name).lines(l_line_no).executions := l_result_block.objects(l_source_object.full_name).lines(l_line_no).executions; + end if; + + if l_result_profiler.objects(l_source_object.full_name).lines.exists(l_line_no) then + l_result.objects(l_source_object.full_name).lines(l_line_no).executions := l_result_profiler.objects(l_source_object.full_name).lines(l_line_no).executions; + end if; -- Recalculate total lines if l_result.objects(l_source_object.full_name).lines(l_line_no).executions > 0 then @@ -146,8 +158,8 @@ create or replace package body ut_coverage_extended is l_result.executions := l_result.executions + l_result.objects(l_source_object.full_name).lines(l_line_no).executions; l_result.covered_lines := l_result.covered_lines + 1; -- object level stats - l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name) - .uncovered_lines + 1; + l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name) + .covered_lines + 1; elsif l_result.objects(l_source_object.full_name).lines(l_line_no).executions = 0 then -- total level stats l_result.uncovered_lines := l_result.uncovered_lines + 1; @@ -156,7 +168,7 @@ create or replace package body ut_coverage_extended is .uncovered_lines + 1; end if; - l_line_no := coalesce(l_result_block.objects(l_source_object.full_name).lines.next(l_line_no), + l_line_no := least(l_result_block.objects(l_source_object.full_name).lines.next(l_line_no), l_result_profiler.objects(l_source_object.full_name).lines.next(l_line_no)); end loop; From 49b1b847bcfe1a2da83f7290bad7cb4fb0134a3c Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 8 Apr 2018 17:37:31 +0100 Subject: [PATCH 22/37] Move get_cov_sql function into common package to remove code duplication --- source/core/coverage/ut_coverage.pkb | 72 ++++++++++++++++ source/core/coverage/ut_coverage.pks | 2 + source/core/coverage/ut_coverage_block.pkb | 65 +-------------- source/core/coverage/ut_coverage_extended.pkb | 64 +-------------- source/core/coverage/ut_coverage_proftab.pkb | 82 +------------------ .../ut_extended_report_html_helper.pkb | 65 ++++++--------- .../ut_proftab_report_html_helper.pkb | 4 +- 7 files changed, 108 insertions(+), 246 deletions(-) diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index e6722186b..0f38c8a1c 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -19,6 +19,78 @@ create or replace package body ut_coverage is type t_source_lines is table of binary_integer; + function get_cov_sources_sql(a_coverage_options ut_coverage_options, a_skipped_lines varchar2 default 'Y') 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, ]'; + if a_skipped_lines = 'Y' then + 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 ]'; + else + l_result := l_result || q'['N' as to_be_skipped ]'; + end if; + + l_result := l_result ||' 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 in ut_coverage_options,a_sql in varchar2) return sys_refcursor is l_cursor sys_refcursor; l_skip_objects ut_object_names; diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks index 4f207b8b5..2dff5ddc1 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -63,6 +63,8 @@ create or replace package ut_coverage authid current_user is ,executions number(38, 0) := 0 ,objects tt_program_units); + function get_cov_sources_sql(a_coverage_options ut_coverage_options, a_skipped_lines varchar2 default 'Y') return varchar2; + 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 index b92ca4e1a..a2631bf12 100644 --- a/source/core/coverage/ut_coverage_block.pkb +++ b/source/core/coverage/ut_coverage_block.pkb @@ -19,69 +19,6 @@ create or replace package body ut_coverage_block is 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 */ @@ -95,7 +32,7 @@ create or replace package body ut_coverage_block is 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)); + ut_coverage.populate_tmp_table(a_coverage_options,ut_coverage.get_cov_sources_sql(a_coverage_options,'N')); l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor(); loop diff --git a/source/core/coverage/ut_coverage_extended.pkb b/source/core/coverage/ut_coverage_extended.pkb index 43ce62ba4..142a07988 100644 --- a/source/core/coverage/ut_coverage_extended.pkb +++ b/source/core/coverage/ut_coverage_extended.pkb @@ -16,69 +16,9 @@ create or replace package body ut_coverage_extended is limitations under the License. */ - 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 extend coverage - P - profiler line result, C - coverage line result, X-result - Dla ka?dej linii:X=greatest(P,nvl(C,0)) - Czyli: - If P is null - line is irrelevant - If P or X > 0 - line is covered - */ - + */ function get_extended_coverage(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is l_result ut_coverage.t_coverage; @@ -93,7 +33,7 @@ create or replace package body ut_coverage_extended is l_result_profiler:= ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); - ut_coverage.populate_tmp_table(a_coverage_options,get_cov_sources_sql(a_coverage_options)); + ut_coverage.populate_tmp_table(a_coverage_options,ut_coverage.get_cov_sources_sql(a_coverage_options,'N')); l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor(); loop diff --git a/source/core/coverage/ut_coverage_proftab.pkb b/source/core/coverage/ut_coverage_proftab.pkb index 91237be7d..59436995c 100644 --- a/source/core/coverage/ut_coverage_proftab.pkb +++ b/source/core/coverage/ut_coverage_proftab.pkb @@ -15,85 +15,7 @@ create or replace package body ut_coverage_proftab is 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 */ @@ -107,7 +29,7 @@ create or replace package body ut_coverage_proftab is begin --prepare global temp table with sources - ut_coverage.populate_tmp_table(a_coverage_options,get_cov_sources_sql(a_coverage_options)); + ut_coverage.populate_tmp_table(a_coverage_options,ut_coverage.get_cov_sources_sql(a_coverage_options,'Y')); l_source_objects_crsr := ut_coverage_helper.get_tmp_table_objects_cursor(); loop diff --git a/source/reporters/ut_extended_report_html_helper.pkb b/source/reporters/ut_extended_report_html_helper.pkb index 73262236e..2ec1da88d 100644 --- a/source/reporters/ut_extended_report_html_helper.pkb +++ b/source/reporters/ut_extended_report_html_helper.pkb @@ -20,7 +20,7 @@ create or replace package body ut_extended_report_html_helper is 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); @@ -30,24 +30,19 @@ create or replace package body ut_extended_report_html_helper is 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 := '

    ' || + + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines); + + l_file_part := '

    ' || dbms_xmlgen.convert(a_object_full_name) || '

    ' || '

    ' || l_coverage_pct || ' % lines covered

    ' || '
    ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || + ' lines covered '|| '(including ' || a_coverage_unit.partcovered_lines || ' lines partially covered ' || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'||'

    ' || l_coverage_block_pct || ' % blocks covered

    '|| - '
    '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| - ''||a_coverage_unit.covered_blocks||' blocks covered and '|| - '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
    ' - ||'
      '; + ' lines missed'||'

      '; ut_utils.append_to_clob(l_result, l_file_part); for line_no in 1 .. a_source_code.count loop @@ -57,8 +52,7 @@ create or replace package body ut_extended_report_html_helper is ' || (dbms_xmlgen.convert(a_source_code(line_no))) || ''; else - l_hits := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| - to_char(a_coverage_unit.lines(line_no).no_blocks); + l_hits := to_char(a_coverage_unit.lines(line_no).executions); l_file_part := '
    1. ' || '

      ' || l_title || '' || ' (' || l_coverage_pct || '%' || ' lines covered'|| - ', ' || - l_coverage_block_pct || '%' || ' executed blocks covered)' - ||'

      ' || '' || '
      ' || + ' at ' || + '' || + ut_coverage_report_html_helper.executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' hits/line)' || '' || '
      ' || a_coverage.objects.count || ' files in total.
      ' || '' || (a_coverage.uncovered_lines + a_coverage.covered_lines) || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered' || + ' lines covered'|| ' (inlcluding ' || a_coverage.partcovered_lines || - ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - '
      '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| - ''||a_coverage.covered_blocks||' blocks covered and '|| - '' || a_coverage.uncovered_blocks || ' blocks missed.
      ' - ||'' || '' || + ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + '
      ' || '' || '' || + ||'Avg. Hits / Line ' || ''; ut_utils.append_to_clob(l_result, l_file_part); l_unit := a_coverage.objects.first; loop exit when l_unit is null; l_unit_coverage := a_coverage.objects(l_unit); - l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - - --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || '' || '' || - ''; + ' %' || '' || '' || '' || + ''; ut_utils.append_to_clob(l_result, l_file_part); l_unit := a_coverage.objects.next(l_unit); end loop; @@ -166,7 +154,8 @@ create or replace package body ut_extended_report_html_helper is l_using varchar2(1000); l_unit ut_coverage.t_full_name; begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); + l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + l_time_str := ut_utils.to_string(sysdate); l_using := case when a_command_line is not null then diff --git a/source/reporters/ut_proftab_report_html_helper.pkb b/source/reporters/ut_proftab_report_html_helper.pkb index 118d00a1b..5e6156d22 100644 --- a/source/reporters/ut_proftab_report_html_helper.pkb +++ b/source/reporters/ut_proftab_report_html_helper.pkb @@ -38,7 +38,7 @@ create or replace package body ut_proftab_report_html_helper is ut_coverage_report_html_helper.coverage_css_class(l_coverage_pct) || '">' || l_coverage_pct || ' % lines covered' || '
      ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || ') and ' || a_coverage_unit.uncovered_lines || + ' lines covered ' || ' and ' || a_coverage_unit.uncovered_lines || ' lines missed'||'
        '; ut_utils.append_to_clob(l_result, l_file_part); @@ -107,7 +107,7 @@ create or replace package body ut_proftab_report_html_helper is a_coverage.objects.count || ' files in total.
        ' || '' || (a_coverage.uncovered_lines + a_coverage.covered_lines) || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered'|| ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| + ' lines covered'|| ' and ' || a_coverage.uncovered_lines || ' lines missed.'|| '
      File% coveredLinesRelevant LinesLines coveredLines missed' - ||'% blocks covered' ||'
      ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || + + l_file_part := chr(10) || '
      ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || - (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || - '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || - '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' - || '
      ' || l_unit_coverage.total_lines || '' || + (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || + l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' || to_char(ut_coverage_report_html_helper.executions_per_line(l_unit_coverage.executions + ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) + || '
      ' || '' || '' || From ab7eb248ed2c56310cc27aab6a98f3b2cee2de1a Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 8 Apr 2018 19:03:21 +0100 Subject: [PATCH 23/37] Refactor Coverage to now enrich profile for partially covered lines using block coverage. --- source/core/coverage/ut_coverage_extended.pkb | 122 +++++------------- 1 file changed, 29 insertions(+), 93 deletions(-) diff --git a/source/core/coverage/ut_coverage_extended.pkb b/source/core/coverage/ut_coverage_extended.pkb index 142a07988..f9d2234e5 100644 --- a/source/core/coverage/ut_coverage_extended.pkb +++ b/source/core/coverage/ut_coverage_extended.pkb @@ -21,103 +21,39 @@ create or replace package body ut_coverage_extended is */ function get_extended_coverage(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is - l_result ut_coverage.t_coverage; - l_result_block ut_coverage.t_coverage; - l_result_profiler ut_coverage.t_coverage; - l_source_objects_crsr ut_coverage_helper.t_tmp_table_objects_crsr; - l_source_object ut_coverage_helper.t_tmp_table_object; - l_new_unit ut_coverage.t_unit_coverage; - l_line_no binary_integer; + l_result_block ut_coverage.t_coverage; + l_result_profiler_enrich ut_coverage.t_coverage; + l_object ut_coverage.t_full_name; + l_line_no binary_integer; begin + ut_coverage_helper.cleanup_tmp_table(); l_result_block := ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); - l_result_profiler:= ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); + ut_coverage_helper.cleanup_tmp_table(); + l_result_profiler_enrich:= ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); - - ut_coverage.populate_tmp_table(a_coverage_options,ut_coverage.get_cov_sources_sql(a_coverage_options,'N')); - - 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; - --check if we have a hits in any of reporters - if l_result_block.total_lines > 0 or l_result_profiler.total_lines > 0 then - --update total stats - l_result.total_lines := nvl(l_result.total_lines,0) + l_source_object.lines_count; - l_result.total_blocks := nvl(l_result_block.total_blocks,0); - l_result.uncovered_blocks := nvl(l_result_block.uncovered_blocks,0); - l_result.covered_blocks := nvl(l_result_block.covered_blocks,0); - l_result.partcovered_lines := nvl(l_result_block.partcovered_lines,0); - - --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; - l_result.objects(l_source_object.full_name).total_blocks := nvl(l_result_block.objects(l_source_object.full_name).total_blocks,0); - l_result.objects(l_source_object.full_name).uncovered_blocks := nvl(l_result_block.objects(l_source_object.full_name).uncovered_blocks,0); - l_result.objects(l_source_object.full_name).covered_blocks := nvl(l_result_block.objects(l_source_object.full_name).covered_blocks,0); - l_result.objects(l_source_object.full_name).partcovered_lines := nvl(l_result_block.objects(l_source_object.full_name).partcovered_lines,0); + -- Enrich profiler results with some of the block results + l_object := l_result_profiler_enrich.objects.first; + while (l_object is not null) + loop + l_line_no := l_result_profiler_enrich.objects(l_object).lines.first; + while (l_line_no is not null) + loop + if l_result_block.objects(l_object).lines.exists(l_line_no) then + -- enrich line level stats + l_result_profiler_enrich.objects(l_object).lines(l_line_no).partcove := l_result_block.objects(l_object).lines(l_line_no).partcove; + -- enrich object level stats + l_result_profiler_enrich.objects(l_object).partcovered_lines := nvl(l_result_profiler_enrich.objects(l_object).partcovered_lines,0) + l_result_block.objects(l_object).lines(l_line_no).partcove; end if; - - l_line_no := least(l_result_block.objects(l_source_object.full_name).lines.first, - l_result_profiler.objects(l_source_object.full_name).lines.first); - - if l_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 l_line_no is null; - - -- Set executions to zero at beginning, specific coverage will overwrite if exists. - l_result.objects(l_source_object.full_name).lines(l_line_no).executions := 0; - l_result.objects(l_source_object.full_name).lines(l_line_no).no_blocks := 0; - l_result.objects(l_source_object.full_name).lines(l_line_no).covered_blocks := 0; - l_result.objects(l_source_object.full_name).lines(l_line_no).partcove := 0; - - -- we need to check if given index exists for that coverage type or we get no data found - if l_result_block.objects(l_source_object.full_name).lines.exists(l_line_no) then - l_result.objects(l_source_object.full_name).lines(l_line_no).no_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(l_line_no).no_blocks,0); - l_result.objects(l_source_object.full_name).lines(l_line_no).covered_blocks := NVL(l_result_block.objects(l_source_object.full_name).lines(l_line_no).covered_blocks,0); - l_result.objects(l_source_object.full_name).lines(l_line_no).partcove := NVL(l_result_block.objects(l_source_object.full_name).lines(l_line_no).partcove,0); - --We capture block executions here, since block coverage do not capture more than 1 - --if profiler executions exists we will use that number as profiler shows hits correctly - - l_result.objects(l_source_object.full_name).lines(l_line_no).executions := l_result_block.objects(l_source_object.full_name).lines(l_line_no).executions; - end if; - - if l_result_profiler.objects(l_source_object.full_name).lines.exists(l_line_no) then - l_result.objects(l_source_object.full_name).lines(l_line_no).executions := l_result_profiler.objects(l_source_object.full_name).lines(l_line_no).executions; - end if; - - -- Recalculate total lines - if l_result.objects(l_source_object.full_name).lines(l_line_no).executions > 0 then - -- total level stats - l_result.executions := l_result.executions + l_result.objects(l_source_object.full_name).lines(l_line_no).executions; - l_result.covered_lines := l_result.covered_lines + 1; - -- object level stats - l_result.objects(l_source_object.full_name).covered_lines := l_result.objects(l_source_object.full_name) - .covered_lines + 1; - elsif l_result.objects(l_source_object.full_name).lines(l_line_no).executions = 0 then - -- total level stats - l_result.uncovered_lines := l_result.uncovered_lines + 1; - -- object level stats - l_result.objects(l_source_object.full_name).uncovered_lines := l_result.objects(l_source_object.full_name) - .uncovered_lines + 1; - end if; - - l_line_no := least(l_result_block.objects(l_source_object.full_name).lines.next(l_line_no), - l_result_profiler.objects(l_source_object.full_name).lines.next(l_line_no)); - - end loop; - end if; - end if; - - end loop; - close l_source_objects_crsr; - return l_result; + --At the end go to next line + l_line_no := l_result_profiler_enrich.objects(l_object).lines.next(l_line_no); + end loop; + --total level stats enrich + l_result_profiler_enrich.partcovered_lines := nvl(l_result_profiler_enrich.partcovered_lines,0) + l_result_profiler_enrich.objects(l_object).partcovered_lines; + -- At the end go to next object + l_object := l_result_profiler_enrich.objects.next(l_object); + end loop; + + return l_result_profiler_enrich; end get_extended_coverage; From 36279faf01b010a194b30c3386ae83c3f0de8ec2 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Tue, 10 Apr 2018 20:19:50 +0100 Subject: [PATCH 24/37] Update tests and fixed typo in original coverage reporter --- source/core/coverage/ut_coverage_helper.pkb | 7 +++++ source/core/coverage/ut_coverage_helper.pks | 3 +- .../test_html_extended_reporter.pkb | 28 +++++++++++++++++++ .../test_html_extended_reporter.pks | 10 +++++++ .../test_html_proftab_reporter.pkb | 2 +- test/install_tests.sql | 4 +++ 6 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 test/core/reporters/test_coverage/test_html_extended_reporter.pkb create mode 100644 test/core/reporters/test_coverage/test_html_extended_reporter.pks diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index fe1e0dc2c..ababcf9e6 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -177,6 +177,13 @@ create or replace package body ut_coverage_helper is g_coverage_id(g_coverage_type) := a_coverage_id; end; + procedure mock_coverage_id(a_coverage_id g_coverage_arr) is + begin + g_develop_mode := true; + g_is_started := true; + g_coverage_id := a_coverage_id; + end; + procedure insert_into_tmp_table(a_data t_coverage_sources_tmp_rows) is begin forall i in 1 .. a_data.count diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index 16a6faed9..29fbadfaa 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -18,7 +18,6 @@ create or replace package ut_coverage_helper authid definer is type g_coverage_arr is table of integer index by varchar2(30); g_coverage_id g_coverage_arr; - --g_coverage_id integer; g_coverage_type varchar2(32); function get_coverage_type return varchar2; @@ -86,6 +85,8 @@ create or replace package ut_coverage_helper authid definer is * Used internally, only for unit testing of the framework only */ procedure mock_coverage_id(a_coverage_id integer); + + procedure mock_coverage_id(a_coverage_id g_coverage_arr); procedure insert_into_tmp_table(a_data t_coverage_sources_tmp_rows); diff --git a/test/core/reporters/test_coverage/test_html_extended_reporter.pkb b/test/core/reporters/test_coverage/test_html_extended_reporter.pkb new file mode 100644 index 000000000..30843fe14 --- /dev/null +++ b/test/core/reporters/test_coverage/test_html_extended_reporter.pkb @@ -0,0 +1,28 @@ +create or replace package body test_html_extended_reporter is + + procedure report_on_file is + l_results ut3.ut_varchar2_list; + l_expected varchar2(32767); + l_actual clob; + begin + --Arrange + l_expected := '%

      UT3.DUMMY_COVERAGE

      %4 relevant lines. 3 lines covered (including 1 lines partially covered ) and 1 lines missed%'; + + select * + bulk collect into l_results + from table( + ut3.ut.run( + a_path => 'ut3.test_dummy_coverage', + a_reporter=> ut3.ut_coverage_html_reporter(), + a_coverage_type => 'extended', + a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), + a_test_files => ut3.ut_varchar2_list( ) + ) + ); + l_actual := ut3.ut_utils.table_to_clob(l_results); + --Assert + ut.expect(l_actual).to_be_like(l_expected); + end; + +end test_html_extended_reporter; +/ diff --git a/test/core/reporters/test_coverage/test_html_extended_reporter.pks b/test/core/reporters/test_coverage/test_html_extended_reporter.pks new file mode 100644 index 000000000..cefa71d66 --- /dev/null +++ b/test/core/reporters/test_coverage/test_html_extended_reporter.pks @@ -0,0 +1,10 @@ +create or replace package test_html_extended_reporter is + + --%suite(ut_html_extended_reporter) + --%suitepath(utplsql.core.reporters.test_extended_coverage) + + --%test(reports on a project file mapped to database object in extended profiler coverage) + procedure report_on_file; + +end test_html_extended_reporter; +/ diff --git a/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb b/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb index 4016dbb9c..307ad27dd 100644 --- a/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb +++ b/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb @@ -6,7 +6,7 @@ create or replace package body test_html_proftab_reporter is l_actual clob; begin --Arrange - l_expected := '%

      UT3.DUMMY_COVERAGE

      %3 relevant lines. 2 lines covered ) and 1 lines missed%'; + l_expected := '%

      UT3.DUMMY_COVERAGE

      %3 relevant lines. 2 lines covered and 1 lines missed%'; --l_expected := '%

      UT3.DUMMY_COVERAGE

      66% lines covered

      3 relevant lines. 2 lines covered ) and 1 lines missed
      %'; --Act diff --git a/test/install_tests.sql b/test/install_tests.sql index 64de65310..541c564cc 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -36,6 +36,8 @@ set define on @@install_above_12_1.sql 'core/reporters/test_coverage/test_coveralls_reporter_block.pks' @@install_above_12_1.sql 'core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks' @@install_above_12_1.sql 'core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks' +@@install_above_12_1.sql 'core/reporters/test_extended_coverage.pks' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_html_extended_reporter.pks' set define off @@core/reporters/test_coverage/test_coverage_sonar_reporter.pks @@core/reporters/test_coverage/test_coveralls_reporter.pks @@ -81,6 +83,8 @@ set define on @@install_above_12_1.sql 'core/reporters/test_coverage/test_coveralls_reporter_block.pkb' @@install_above_12_1.sql 'core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb' @@install_above_12_1.sql 'core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb' +@@install_above_12_1.sql 'core/reporters/test_extended_coverage.pkb' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_html_extended_reporter.pkb' set define off @@core/reporters/test_xunit_reporter.pkb @@core/reporters/test_tfs_junit_reporter.pkb From 57f7a4ff325151f57cf679e1c84841013655ebbf Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 11 Apr 2018 18:35:09 +0100 Subject: [PATCH 25/37] Updated coverage --- source/core/coverage/ut_coverage_extended.pkb | 9 +++++---- source/core/coverage/ut_coverage_helper.pks | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/core/coverage/ut_coverage_extended.pkb b/source/core/coverage/ut_coverage_extended.pkb index f9d2234e5..7a05a836a 100644 --- a/source/core/coverage/ut_coverage_extended.pkb +++ b/source/core/coverage/ut_coverage_extended.pkb @@ -26,11 +26,12 @@ create or replace package body ut_coverage_extended is l_object ut_coverage.t_full_name; l_line_no binary_integer; begin - ut_coverage_helper.cleanup_tmp_table(); - l_result_block := ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); - ut_coverage_helper.cleanup_tmp_table(); + -- Get raw data for both reporters, order is important as tmp table will skip headers and dont populate + -- tmp table for block again. l_result_profiler_enrich:= ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); - + + l_result_block := ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); + -- Enrich profiler results with some of the block results l_object := l_result_profiler_enrich.objects.first; while (l_object is not null) diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index 29fbadfaa..3fe0294fe 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -17,6 +17,7 @@ create or replace package ut_coverage_helper authid definer is */ type g_coverage_arr is table of integer index by varchar2(30); + g_coverage_id g_coverage_arr; g_coverage_type varchar2(32); From c9cb0045563b47b616ca9bdd7896ba61f8e93441 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 11 Apr 2018 19:22:32 +0100 Subject: [PATCH 26/37] Fixes to conditional compilation --- source/core/coverage/ut_coverage.pkb | 7 +++++-- source/reporters/ut_coverage_report_html_helper.pkb | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index 97e516af4..1ae00ad9c 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -181,8 +181,11 @@ create or replace package body ut_coverage is return null; $end elsif a_coverage_options.coverage_type = gc_extended_coverage then - --Collect data for block and proftab and pass to extended for modifications. - return ut_coverage_extended.get_extended_coverage(a_coverage_options => a_coverage_options); + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + return ut_coverage_extended.get_extended_coverage(a_coverage_options => a_coverage_options); + $else + return null; + $end else return ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); end if; diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb index 2f2fd20e3..7fb1660c5 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -108,12 +108,16 @@ create or replace package body ut_coverage_report_html_helper is begin if l_coverage_type = ut_coverage.gc_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); $else l_result := null; $end elsif l_coverage_type = ut_coverage.gc_extended_coverage then - l_result := ut_extended_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + l_result := ut_extended_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + $else + l_result := null; + $end else l_result := ut_proftab_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); end if; From a862b95c4791396b5f5c083f440b706d8967a0d4 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 11 Apr 2018 21:34:16 +0100 Subject: [PATCH 27/37] Fixes to new asso array during mock coverage id. --- source/core/coverage/ut_coverage_helper.pkb | 4 ++-- source/core/coverage/ut_coverage_helper.pks | 2 +- test/core/reporters/test_block_coverage.pkb | 2 +- test/core/reporters/test_coverage.pkb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index ababcf9e6..3513c0b3a 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -170,11 +170,11 @@ create or replace package body ut_coverage_helper is end if; end; - procedure mock_coverage_id(a_coverage_id integer) is + procedure mock_coverage_id(a_coverage_id integer,a_coverage_type in varchar2) is begin g_develop_mode := true; g_is_started := true; - g_coverage_id(g_coverage_type) := a_coverage_id; + g_coverage_id(a_coverage_type) := a_coverage_id; end; procedure mock_coverage_id(a_coverage_id g_coverage_arr) is diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index 3fe0294fe..6ec553df0 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -85,7 +85,7 @@ create or replace package ut_coverage_helper authid definer is * Allows overwriting of private global variable g_coverage_id * Used internally, only for unit testing of the framework only */ - procedure mock_coverage_id(a_coverage_id integer); + procedure mock_coverage_id(a_coverage_id integer,a_coverage_type in varchar2); procedure mock_coverage_id(a_coverage_id g_coverage_arr); diff --git a/test/core/reporters/test_block_coverage.pkb b/test/core/reporters/test_block_coverage.pkb index 4e8237ff0..2f5f28a90 100644 --- a/test/core/reporters/test_block_coverage.pkb +++ b/test/core/reporters/test_block_coverage.pkb @@ -68,7 +68,7 @@ create or replace package body test_block_coverage is create_dummy_coverage_package(); create_dummy_coverage_test(); g_run_id := get_mock_run_id(); - ut3.ut_coverage_helper.mock_coverage_id(g_run_id); + ut3.ut_coverage_helper.mock_coverage_id(g_run_id,ut3.ut_coverage.gc_block_coverage); mock_coverage_data(g_run_id); commit; end; diff --git a/test/core/reporters/test_coverage.pkb b/test/core/reporters/test_coverage.pkb index 368fa56b4..43346c430 100644 --- a/test/core/reporters/test_coverage.pkb +++ b/test/core/reporters/test_coverage.pkb @@ -106,7 +106,7 @@ create or replace package body test_coverage is create_dummy_coverage_package(); create_dummy_coverage_test(); g_run_id := get_mock_run_id(); - ut3.ut_coverage_helper.mock_coverage_id(g_run_id); + ut3.ut_coverage_helper.mock_coverage_id(g_run_id,ut3.ut_coverage.gc_proftab_coverage); mock_coverage_data(g_run_id); commit; end; From 45617955dd2ecd5735a9195a15cefb512072efcc Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 11 Apr 2018 22:07:34 +0100 Subject: [PATCH 28/37] Update test --- test/core/reporters/test_not_existing_block.pkb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/core/reporters/test_not_existing_block.pkb b/test/core/reporters/test_not_existing_block.pkb index 5c053a6b2..a958edd1f 100644 --- a/test/core/reporters/test_not_existing_block.pkb +++ b/test/core/reporters/test_not_existing_block.pkb @@ -106,7 +106,7 @@ create or replace package body test_not_existing_block is create_dummy_coverage_package(); create_dummy_coverage_test(); g_run_id := get_mock_run_id(); - ut3.ut_coverage_helper.mock_coverage_id(g_run_id); + ut3.ut_coverage_helper.mock_coverage_id(g_run_id,ut3.ut_coverage.gc_block_coverage); mock_coverage_data(g_run_id); commit; end; @@ -116,9 +116,9 @@ create or replace package body test_not_existing_block is begin begin execute immediate q'[drop package ut3.test_dummy_coverage]'; exception when others then null; end; begin execute immediate q'[drop package ut3.dummy_coverage]'; exception when others then null; end; - delete from ut3.plsql_profiler_data where runid = g_run_id; - delete from ut3.plsql_profiler_units where runid = g_run_id; - delete from ut3.plsql_profiler_runs where runid = g_run_id; + delete from ut3.dbmspcc_blocks where run_id = g_run_id; + delete from ut3.dbmspcc_units where run_id = g_run_id; + delete from ut3.dbmspcc_runs where run_id = g_run_id; commit; end; From 0556fbe54d4140ebe51f5bfc6b870ae63fa6f8cf Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 11 Apr 2018 22:07:34 +0100 Subject: [PATCH 29/37] Update test --- test/core/reporters/test_not_existing_block.pkb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/reporters/test_not_existing_block.pkb b/test/core/reporters/test_not_existing_block.pkb index 5c053a6b2..f14979896 100644 --- a/test/core/reporters/test_not_existing_block.pkb +++ b/test/core/reporters/test_not_existing_block.pkb @@ -106,7 +106,7 @@ create or replace package body test_not_existing_block is create_dummy_coverage_package(); create_dummy_coverage_test(); g_run_id := get_mock_run_id(); - ut3.ut_coverage_helper.mock_coverage_id(g_run_id); + ut3.ut_coverage_helper.mock_coverage_id(g_run_id,ut3.ut_coverage.gc_block_coverage); mock_coverage_data(g_run_id); commit; end; From d19f9412b9a655501301c8d257a9c456ab7cd0ab Mon Sep 17 00:00:00 2001 From: lwasylow Date: Wed, 11 Apr 2018 23:25:17 +0100 Subject: [PATCH 30/37] Update test/core/reporters/test_extended_coverage.pkb --- test/core/reporters/test_extended_coverage.pkb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/reporters/test_extended_coverage.pkb b/test/core/reporters/test_extended_coverage.pkb index 450f22a9e..4151ed0db 100644 --- a/test/core/reporters/test_extended_coverage.pkb +++ b/test/core/reporters/test_extended_coverage.pkb @@ -95,8 +95,8 @@ create or replace package body test_extended_coverage is g_run_id(ut3.ut_coverage.gc_block_coverage) := get_mock_block_run_id(); g_run_id(ut3.ut_coverage.gc_proftab_coverage) := get_mock_proftab_run_id(); ut3.ut_coverage_helper.mock_coverage_id(g_run_id); - mock_block_coverage_data(g_run_id(ut3.ut_coverage.gc_proftab_coverage)); - mock_profiler_coverage_data(g_run_id(ut3.ut_coverage.gc_block_coverage)); + mock_block_coverage_data(g_run_id(ut3.ut_coverage.gc_block_coverage)); + mock_profiler_coverage_data(g_run_id(ut3.ut_coverage.gc_proftab_coverage)); commit; end; From e2e1437a38aea3a82070ed83367bd88090817d84 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Thu, 12 Apr 2018 00:22:26 +0100 Subject: [PATCH 31/37] Updated html reporter to show a information about the partially covered lines by displaying a covered not covered blocks. --- docs/userguide/coverage.md | 20 ++++++++++++ source/core/coverage/ut_coverage_extended.pkb | 2 ++ .../ut_extended_report_html_helper.pkb | 31 ++++++++++++++++--- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/docs/userguide/coverage.md b/docs/userguide/coverage.md index 95e7e66ab..20fcbc9cb 100644 --- a/docs/userguide/coverage.md +++ b/docs/userguide/coverage.md @@ -67,6 +67,26 @@ end; In this mode html reporter will show additionally number of lines that been partially covered and highlight them in orange. Number of blocks in code, blocks covered and missed. +#### Oracle 12.2 extended coverage with profiler and block coverage +Using data collected from profiler and block coverage running parallel we are able to enrich information about coverage. +For every line recorded by profiler if we have a partially covered same line in block coverage we will display that information +presenting line as partially covered and displaying number of block and how many blocks been covered in that line. + +Example: +```sql +begin + ut.run(ut_coverage_html_reporter(),a_coverage_type => 'extended'); +end; +/ +``` + +Sample output: +![Package Coverage Summary](../images/extended_coverage_html_summary.png) + +![Line Coverage Details](../images/extended_coverage_html_line.png) + + + ### Coverage reporting options There are two distinct ways to gather code coverage: diff --git a/source/core/coverage/ut_coverage_extended.pkb b/source/core/coverage/ut_coverage_extended.pkb index 7a05a836a..6e31c8e73 100644 --- a/source/core/coverage/ut_coverage_extended.pkb +++ b/source/core/coverage/ut_coverage_extended.pkb @@ -42,6 +42,8 @@ create or replace package body ut_coverage_extended is if l_result_block.objects(l_object).lines.exists(l_line_no) then -- enrich line level stats l_result_profiler_enrich.objects(l_object).lines(l_line_no).partcove := l_result_block.objects(l_object).lines(l_line_no).partcove; + l_result_profiler_enrich.objects(l_object).lines(l_line_no).covered_blocks := l_result_block.objects(l_object).lines(l_line_no).covered_blocks; + l_result_profiler_enrich.objects(l_object).lines(l_line_no).no_blocks := l_result_block.objects(l_object).lines(l_line_no).no_blocks; -- enrich object level stats l_result_profiler_enrich.objects(l_object).partcovered_lines := nvl(l_result_profiler_enrich.objects(l_object).partcovered_lines,0) + l_result_block.objects(l_object).lines(l_line_no).partcove; end if; diff --git a/source/reporters/ut_extended_report_html_helper.pkb b/source/reporters/ut_extended_report_html_helper.pkb index 2ec1da88d..c83f71c3b 100644 --- a/source/reporters/ut_extended_report_html_helper.pkb +++ b/source/reporters/ut_extended_report_html_helper.pkb @@ -28,6 +28,7 @@ create or replace package body ut_extended_report_html_helper is l_coverage_pct number(5, 2); l_coverage_block_pct number(5, 2); l_hits varchar2(30); + l_blocks varchar2(30); begin dbms_lob.createtemporary(l_result, true); @@ -52,14 +53,36 @@ create or replace package body ut_extended_report_html_helper is ' || (dbms_xmlgen.convert(a_source_code(line_no))) || ''; else - l_hits := to_char(a_coverage_unit.lines(line_no).executions); - + l_hits := to_char(a_coverage_unit.lines(line_no).executions); + if nvl(a_coverage_unit.lines(line_no).covered_blocks,0) < nvl(a_coverage_unit.lines(line_no).no_blocks,0) + and nvl(a_coverage_unit.lines(line_no).partcove,0) = 1 then + l_blocks := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| + to_char(a_coverage_unit.lines(line_no).no_blocks); + else + l_blocks := null; + end if; + l_file_part := '
    2. '; + dbms_xmlgen.convert(l_hits)|| '"'|| + case + when l_blocks is not null + then ' data-blocks="'||dbms_xmlgen.convert(l_blocks)||'"' + else + null + end + ||' data-linenumber="' || (line_no) || '">'; if a_coverage_unit.lines(line_no).executions > 0 then - l_file_part := l_file_part || ' + l_file_part := l_file_part || + case when l_blocks is not null + then ' + ' ||dbms_xmlgen.convert(l_blocks) || + '' + else + null + end + || ' ' || dbms_xmlgen.convert(l_hits) || ''; end if; From a112e36c50c2a838a43b2293ac0805e18a2e64a7 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sat, 14 Apr 2018 20:01:55 +0100 Subject: [PATCH 32/37] Added support for block coverage in sonar and cobertura reporters. Cleanup of object names. --- source/core/coverage/ut_coverage.pkb | 6 ++-- source/core/coverage/ut_coverage_block.pkb | 6 ++-- source/core/coverage/ut_coverage_block.pks | 2 +- source/core/coverage/ut_coverage_extended.pkb | 8 +++--- source/core/coverage/ut_coverage_extended.pks | 2 +- source/core/coverage/ut_coverage_helper.pkb | 28 +++++++++---------- ...elper.pkb => ut_coverage_helper_block.pkb} | 4 +-- ...elper.pks => ut_coverage_helper_block.pks} | 4 +-- ...er.pkb => ut_coverage_helper_profiler.pkb} | 4 +-- ...er.pks => ut_coverage_helper_profiler.pks} | 4 +-- ...e_proftab.pkb => ut_coverage_profiler.pkb} | 8 +++--- ...e_proftab.pks => ut_coverage_profiler.pks} | 4 +-- source/install.sql | 12 ++++---- .../ut_coverage_cobertura_reporter.tpb | 12 +++++++- .../reporters/ut_coverage_sonar_reporter.tpb | 7 ++++- test/core/reporters/test_block_coverage.pkb | 13 +++++---- .../test_cov_cobertura_rptr_blk.pkb | 2 +- .../test_coverage_sonar_rprt_blk.pkb | 6 ++-- .../test_html_block_reporter.pkb | 2 +- .../core/reporters/test_extended_coverage.pkb | 10 +++---- test/core/reporters/test_xunit_reporter.pkb | 2 +- 21 files changed, 81 insertions(+), 65 deletions(-) rename source/core/coverage/{ut_block_coverage_helper.pkb => ut_coverage_helper_block.pkb} (94%) rename source/core/coverage/{ut_block_coverage_helper.pks => ut_coverage_helper_block.pks} (78%) rename source/core/coverage/{ut_proftab_helper.pkb => ut_coverage_helper_profiler.pkb} (93%) rename source/core/coverage/{ut_proftab_helper.pks => ut_coverage_helper_profiler.pks} (79%) rename source/core/coverage/{ut_coverage_proftab.pkb => ut_coverage_profiler.pkb} (92%) rename source/core/coverage/{ut_coverage_proftab.pks => ut_coverage_profiler.pks} (77%) diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index 1ae00ad9c..f3531995d 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -176,18 +176,18 @@ create or replace package body ut_coverage is if a_coverage_options.coverage_type = gc_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - return ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); + return ut_coverage_block.get_coverage_data(a_coverage_options => a_coverage_options); $else return null; $end elsif a_coverage_options.coverage_type = gc_extended_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - return ut_coverage_extended.get_extended_coverage(a_coverage_options => a_coverage_options); + return ut_coverage_extended.get_coverage_data(a_coverage_options => a_coverage_options); $else return null; $end else - return ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); + return ut_coverage_profiler.get_coverage_data(a_coverage_options => a_coverage_options); end if; end get_coverage_data; diff --git a/source/core/coverage/ut_coverage_block.pkb b/source/core/coverage/ut_coverage_block.pkb index a2631bf12..c405fd262 100644 --- a/source/core/coverage/ut_coverage_block.pkb +++ b/source/core/coverage/ut_coverage_block.pkb @@ -23,7 +23,7 @@ create or replace package body ut_coverage_block is * Public functions */ - function get_coverage_data_block(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is + function get_coverage_data(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; @@ -41,7 +41,7 @@ create or replace package body ut_coverage_block is exit when l_source_objects_crsr%notfound; --get coverage data - l_line_calls := ut_block_coverage_helper.get_raw_coverage_data_block(l_source_object.owner, l_source_object.name); + l_line_calls := ut_coverage_helper_block.get_raw_coverage_data(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 @@ -154,7 +154,7 @@ create or replace package body ut_coverage_block is close l_source_objects_crsr; return l_result; - end get_coverage_data_block; + end get_coverage_data; end; / diff --git a/source/core/coverage/ut_coverage_block.pks b/source/core/coverage/ut_coverage_block.pks index f0febb021..00c5e9e28 100644 --- a/source/core/coverage/ut_coverage_block.pks +++ b/source/core/coverage/ut_coverage_block.pks @@ -16,7 +16,7 @@ create or replace package ut_coverage_block authid current_user is limitations under the License. */ - function get_coverage_data_block(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage; + function get_coverage_data(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage; end; / diff --git a/source/core/coverage/ut_coverage_extended.pkb b/source/core/coverage/ut_coverage_extended.pkb index 6e31c8e73..469756af4 100644 --- a/source/core/coverage/ut_coverage_extended.pkb +++ b/source/core/coverage/ut_coverage_extended.pkb @@ -20,7 +20,7 @@ create or replace package body ut_coverage_extended is * Public functions */ - function get_extended_coverage(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is + function get_coverage_data(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is l_result_block ut_coverage.t_coverage; l_result_profiler_enrich ut_coverage.t_coverage; l_object ut_coverage.t_full_name; @@ -28,9 +28,9 @@ create or replace package body ut_coverage_extended is begin -- Get raw data for both reporters, order is important as tmp table will skip headers and dont populate -- tmp table for block again. - l_result_profiler_enrich:= ut_coverage_proftab.get_coverage_data_profiler(a_coverage_options => a_coverage_options); + l_result_profiler_enrich:= ut_coverage_profiler.get_coverage_data(a_coverage_options => a_coverage_options); - l_result_block := ut_coverage_block.get_coverage_data_block(a_coverage_options => a_coverage_options); + l_result_block := ut_coverage_block.get_coverage_data(a_coverage_options => a_coverage_options); -- Enrich profiler results with some of the block results l_object := l_result_profiler_enrich.objects.first; @@ -58,7 +58,7 @@ create or replace package body ut_coverage_extended is return l_result_profiler_enrich; - end get_extended_coverage; + end get_coverage_data; end; / diff --git a/source/core/coverage/ut_coverage_extended.pks b/source/core/coverage/ut_coverage_extended.pks index 67bc93ce5..01d57fb7c 100644 --- a/source/core/coverage/ut_coverage_extended.pks +++ b/source/core/coverage/ut_coverage_extended.pks @@ -16,7 +16,7 @@ create or replace package ut_coverage_extended authid current_user is limitations under the License. */ - function get_extended_coverage(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage; + function get_coverage_data(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 3513c0b3a..aa7e7b6f5 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -70,20 +70,20 @@ create or replace package body ut_coverage_helper is set_coverage_type(a_coverage_type); if get_coverage_type = ut_coverage.gc_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_coverage_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id(ut_coverage.gc_block_coverage) ); + ut_coverage_helper_block.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id(ut_coverage.gc_block_coverage) ); $else raise_application_error(ut_utils.gc_invalid_coverage_type,'Invalid coverage type requested. Please validate your Oracle install'); $end elsif get_coverage_type = ut_coverage.gc_extended_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_coverage_helper.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id(ut_coverage.gc_block_coverage) ); - ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id(ut_coverage.gc_proftab_coverage)); + ut_coverage_helper_block.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id(ut_coverage.gc_block_coverage) ); + ut_coverage_helper_profiler.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id(ut_coverage.gc_proftab_coverage)); coverage_pause(); $else raise_application_error(ut_utils.gc_invalid_coverage_type,'Invalid coverage type requested. Please validate your Oracle install'); $end else - ut_proftab_helper.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id(ut_coverage.gc_proftab_coverage)); + ut_coverage_helper_profiler.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id(ut_coverage.gc_proftab_coverage)); coverage_pause(); end if; g_is_started := true; @@ -111,7 +111,7 @@ create or replace package body ut_coverage_helper is if get_coverage_type = ut_coverage.gc_block_coverage then null; else - ut_proftab_helper.coverage_pause(); + ut_coverage_helper_profiler.coverage_pause(); end if; end if; end; @@ -121,7 +121,7 @@ create or replace package body ut_coverage_helper is if get_coverage_type = ut_coverage.gc_block_coverage then null; else - ut_proftab_helper.coverage_resume(); + ut_coverage_helper_profiler.coverage_resume(); end if; end; @@ -131,19 +131,19 @@ create or replace package body ut_coverage_helper is g_is_started := false; if get_coverage_type = ut_coverage.gc_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_coverage_helper.coverage_stop(); + ut_coverage_helper_block.coverage_stop(); $else null; $end elsif get_coverage_type = ut_coverage.gc_extended_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_proftab_helper.coverage_stop(); - ut_block_coverage_helper.coverage_stop(); + ut_coverage_helper_profiler.coverage_stop(); + ut_coverage_helper_block.coverage_stop(); $else null; $end else - ut_proftab_helper.coverage_stop(); + ut_coverage_helper_profiler.coverage_stop(); end if; end if; end; @@ -154,19 +154,19 @@ create or replace package body ut_coverage_helper is g_is_started := false; if get_coverage_type = ut_coverage.gc_block_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_block_coverage_helper.coverage_stop(); + ut_coverage_helper_block.coverage_stop(); $else null; $end elsif get_coverage_type = ut_coverage.gc_extended_coverage then $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_proftab_helper.coverage_stop(); - ut_block_coverage_helper.coverage_stop(); + ut_coverage_helper_profiler.coverage_stop(); + ut_coverage_helper_block.coverage_stop(); $else null; $end else - ut_proftab_helper.coverage_stop(); + ut_coverage_helper_profiler.coverage_stop(); end if; end; diff --git a/source/core/coverage/ut_block_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper_block.pkb similarity index 94% rename from source/core/coverage/ut_block_coverage_helper.pkb rename to source/core/coverage/ut_coverage_helper_block.pkb index 119234b97..8d652099d 100644 --- a/source/core/coverage/ut_block_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper_block.pkb @@ -1,4 +1,4 @@ -create or replace package body ut_block_coverage_helper is +create or replace package body ut_coverage_helper_block is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project @@ -65,7 +65,7 @@ create or replace package body ut_block_coverage_helper is 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 + function get_raw_coverage_data(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; diff --git a/source/core/coverage/ut_block_coverage_helper.pks b/source/core/coverage/ut_coverage_helper_block.pks similarity index 78% rename from source/core/coverage/ut_block_coverage_helper.pks rename to source/core/coverage/ut_coverage_helper_block.pks index 1b41c0ca3..041db26f7 100644 --- a/source/core/coverage/ut_block_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper_block.pks @@ -1,4 +1,4 @@ -create or replace package ut_block_coverage_helper authid definer is +create or replace package ut_coverage_helper_block authid definer is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project @@ -20,7 +20,7 @@ create or replace package ut_block_coverage_helper authid definer is 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; + function get_raw_coverage_data(a_object_owner varchar2, a_object_name varchar2) return ut_coverage_helper.t_unit_line_calls; end; / diff --git a/source/core/coverage/ut_proftab_helper.pkb b/source/core/coverage/ut_coverage_helper_profiler.pkb similarity index 93% rename from source/core/coverage/ut_proftab_helper.pkb rename to source/core/coverage/ut_coverage_helper_profiler.pkb index 47316de82..eb993d9f9 100644 --- a/source/core/coverage/ut_proftab_helper.pkb +++ b/source/core/coverage/ut_coverage_helper_profiler.pkb @@ -1,4 +1,4 @@ -create or replace package body ut_proftab_helper is +create or replace package body ut_coverage_helper_profiler is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project @@ -77,7 +77,7 @@ create or replace package body ut_proftab_helper is 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 + function get_raw_coverage_data(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 diff --git a/source/core/coverage/ut_proftab_helper.pks b/source/core/coverage/ut_coverage_helper_profiler.pks similarity index 79% rename from source/core/coverage/ut_proftab_helper.pks rename to source/core/coverage/ut_coverage_helper_profiler.pks index 53a78dbc5..cfe08df87 100644 --- a/source/core/coverage/ut_proftab_helper.pks +++ b/source/core/coverage/ut_coverage_helper_profiler.pks @@ -1,4 +1,4 @@ -create or replace package ut_proftab_helper authid definer is +create or replace package ut_coverage_helper_profiler authid definer is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project @@ -24,7 +24,7 @@ create or replace package ut_proftab_helper authid definer is 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; + function get_raw_coverage_data(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_proftab.pkb b/source/core/coverage/ut_coverage_profiler.pkb similarity index 92% rename from source/core/coverage/ut_coverage_proftab.pkb rename to source/core/coverage/ut_coverage_profiler.pkb index 59436995c..64c8cf2d0 100644 --- a/source/core/coverage/ut_coverage_proftab.pkb +++ b/source/core/coverage/ut_coverage_profiler.pkb @@ -1,4 +1,4 @@ -create or replace package body ut_coverage_proftab is +create or replace package body ut_coverage_profiler is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project @@ -19,7 +19,7 @@ create or replace package body ut_coverage_proftab is /** * Public functions */ - function get_coverage_data_profiler(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is + function get_coverage_data(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; @@ -37,7 +37,7 @@ create or replace package body ut_coverage_proftab is 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); + l_line_calls := ut_coverage_helper_profiler.get_raw_coverage_data( 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 @@ -93,7 +93,7 @@ create or replace package body ut_coverage_proftab is close l_source_objects_crsr; return l_result; - end get_coverage_data_profiler; + end get_coverage_data; end; / diff --git a/source/core/coverage/ut_coverage_proftab.pks b/source/core/coverage/ut_coverage_profiler.pks similarity index 77% rename from source/core/coverage/ut_coverage_proftab.pks rename to source/core/coverage/ut_coverage_profiler.pks index 7f0f4ca3b..a86d31486 100644 --- a/source/core/coverage/ut_coverage_proftab.pks +++ b/source/core/coverage/ut_coverage_profiler.pks @@ -1,4 +1,4 @@ -create or replace package ut_coverage_proftab authid current_user is +create or replace package ut_coverage_profiler authid current_user is /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project @@ -16,7 +16,7 @@ create or replace package ut_coverage_proftab authid current_user is limitations under the License. */ - function get_coverage_data_profiler(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage; + function get_coverage_data(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage; end; / diff --git a/source/install.sql b/source/install.sql index eaf0f0415..bcbe71aea 100644 --- a/source/install.sql +++ b/source/install.sql @@ -127,20 +127,20 @@ 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_above_12_1.sql 'core/coverage/ut_block_coverage_helper.pks' +@@install_above_12_1.sql 'core/coverage/ut_coverage_helper_block.pks' @@install_above_12_1.sql 'core/coverage/ut_coverage_extended.pks' -@@install_component.sql 'core/coverage/ut_proftab_helper.pks' +@@install_component.sql 'core/coverage/ut_coverage_helper_profiler.pks' @@install_component.sql 'core/coverage/ut_coverage.pks' @@install_above_12_1.sql 'core/coverage/ut_coverage_block.pks' -@@install_component.sql 'core/coverage/ut_coverage_proftab.pks' +@@install_component.sql 'core/coverage/ut_coverage_profiler.pks' @@install_component.sql 'core/coverage/ut_coverage_reporter_base.tps' @@install_component.sql 'core/coverage/ut_coverage_helper.pkb' -@@install_above_12_1.sql 'core/coverage/ut_block_coverage_helper.pkb' +@@install_above_12_1.sql 'core/coverage/ut_coverage_helper_block.pkb' @@install_above_12_1.sql 'core/coverage/ut_coverage_extended.pkb' -@@install_component.sql 'core/coverage/ut_proftab_helper.pkb' +@@install_component.sql 'core/coverage/ut_coverage_helper_profiler.pkb' @@install_component.sql 'core/coverage/ut_coverage.pkb' @@install_above_12_1.sql 'core/coverage/ut_coverage_block.pkb' -@@install_component.sql 'core/coverage/ut_coverage_proftab.pkb' +@@install_component.sql 'core/coverage/ut_coverage_profiler.pkb' @@install_component.sql 'core/coverage/ut_coverage_reporter_base.tpb' --core type bodies diff --git a/source/reporters/ut_coverage_cobertura_reporter.tpb b/source/reporters/ut_coverage_cobertura_reporter.tpb index 4fec0d9b5..82d085604 100644 --- a/source/reporters/ut_coverage_cobertura_reporter.tpb +++ b/source/reporters/ut_coverage_cobertura_reporter.tpb @@ -33,6 +33,7 @@ create or replace type body ut_coverage_cobertura_reporter is l_file_part varchar2(32767); l_result clob; l_line_no binary_integer; + l_pct integer; begin dbms_lob.createtemporary(l_result, true); l_line_no := a_unit_coverage.lines.first; @@ -46,7 +47,16 @@ create or replace type body ut_coverage_cobertura_reporter is if a_unit_coverage.lines(l_line_no).executions = 0 then l_file_part := ''||chr(10); else - l_file_part := ''||chr(10); + l_file_part := ''||chr(10); end if; ut_utils.append_to_clob(l_result, l_file_part); l_line_no := a_unit_coverage.lines.next(l_line_no); diff --git a/source/reporters/ut_coverage_sonar_reporter.tpb b/source/reporters/ut_coverage_sonar_reporter.tpb index 596115d17..a82097061 100644 --- a/source/reporters/ut_coverage_sonar_reporter.tpb +++ b/source/reporters/ut_coverage_sonar_reporter.tpb @@ -45,7 +45,12 @@ create or replace type body ut_coverage_sonar_reporter is if a_unit_coverage.lines(l_line_no).executions = 0 then l_file_part := ''||chr(10); else - l_file_part := ''||chr(10); + l_file_part := ''||chr(10); end if; ut_utils.append_to_clob(l_result, l_file_part); l_line_no := a_unit_coverage.lines.next(l_line_no); diff --git a/test/core/reporters/test_block_coverage.pkb b/test/core/reporters/test_block_coverage.pkb index 2f5f28a90..417066633 100644 --- a/test/core/reporters/test_block_coverage.pkb +++ b/test/core/reporters/test_block_coverage.pkb @@ -58,8 +58,9 @@ create or replace package body test_block_coverage is insert into ut3.dbmspcc_blocks ( run_id, object_id, line,block,col,covered,not_feasible) select a_run_id, c_unit_id,4,1,1,1,0 from dual union all - select a_run_id, c_unit_id,5,2,0 ,1,0 from dual union all - select a_run_id, c_unit_id,7,3,1,1,0 from dual; + select a_run_id, c_unit_id,4,2,2,0,0 from dual union all + select a_run_id, c_unit_id,5,3,0,1,0 from dual union all + select a_run_id, c_unit_id,7,4,1,1,0 from dual; end; procedure setup_dummy_coverage is @@ -90,7 +91,7 @@ create or replace package body test_block_coverage is l_results ut3.ut_varchar2_list; begin --Arrange - l_expected := '%%'; + l_expected := '%%%'; --Act select * bulk collect into l_results @@ -113,8 +114,7 @@ create or replace package body test_block_coverage is l_results ut3.ut_varchar2_list; begin --Arrange - l_expected := ''; - l_expected := '%'||l_expected||'%'||l_expected||'%'; + l_expected := '%%%'; --Act select * bulk collect into l_results @@ -129,6 +129,7 @@ create or replace package body test_block_coverage is --Assert l_actual := ut3.ut_utils.table_to_clob(l_results); ut.expect(l_actual).to_be_like(l_expected); + ut.expect(l_actual).to_be_like('%%%'); end; procedure coverage_for_file is @@ -139,7 +140,7 @@ create or replace package body test_block_coverage is begin --Arrange l_file_path := lower('test/ut3.dummy_coverage.pkb'); - l_expected := '%%'; + l_expected := '%%%'; --Act select * bulk collect into l_results diff --git a/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb b/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb index 913c0060a..ededfdceb 100644 --- a/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb +++ b/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb @@ -16,7 +16,7 @@ create or replace package body test_cov_cobertura_rptr_blk is - + diff --git a/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb b/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb index 1f4d0d7d6..7f7c259a6 100644 --- a/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb +++ b/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb @@ -8,9 +8,9 @@ create or replace package body test_coverage_sonar_rprt_blk is --Arrange l_expected := ' - - - + + + '; --Act diff --git a/test/core/reporters/test_coverage/test_html_block_reporter.pkb b/test/core/reporters/test_coverage/test_html_block_reporter.pkb index 7dbf931c1..fcc99e043 100644 --- a/test/core/reporters/test_coverage/test_html_block_reporter.pkb +++ b/test/core/reporters/test_coverage/test_html_block_reporter.pkb @@ -6,7 +6,7 @@ create or replace package body test_html_block_reporter is l_actual clob; begin --Arrange - l_expected := '%

      UT3.DUMMY_COVERAGE

      %100 % blocks covered
      3 blocks in total.3 blocks covered and 0 blocks missed.
      %'; + l_expected := '%

      UT3.DUMMY_COVERAGE

      %75 % blocks covered
      4 blocks in total.3 blocks covered and 1 blocks missed.
      %'; --l_expected := '%

      UT3.DUMMY_COVERAGE

      100 % lines covered

      3 relevant lines. 3 lines covered (including 0 lines partially covered ) and 0 lines missed

      100 % blocks covered

      3 blocks in total.3 blocks covered and 0 blocks missed.
      %'; --Act select * diff --git a/test/core/reporters/test_extended_coverage.pkb b/test/core/reporters/test_extended_coverage.pkb index 4151ed0db..441ee61bb 100644 --- a/test/core/reporters/test_extended_coverage.pkb +++ b/test/core/reporters/test_extended_coverage.pkb @@ -67,7 +67,7 @@ create or replace package body test_extended_coverage is insert into ut3.dbmspcc_blocks ( run_id, object_id, line,block,col,covered,not_feasible) select a_run_id, c_unit_id,4,1,1,1,0 from dual union all select a_run_id, c_unit_id,4,2,2,0,0 from dual union all - select a_run_id, c_unit_id,5,3,0 ,1,0 from dual union all + select a_run_id, c_unit_id,5,3,0,1,0 from dual union all select a_run_id, c_unit_id,7,4,1,1,0 from dual; end; @@ -120,7 +120,7 @@ create or replace package body test_extended_coverage is l_results ut3.ut_varchar2_list; begin --Arrange - l_expected := '%%'; + l_expected := '%%%'; --Act select * bulk collect into l_results @@ -143,8 +143,7 @@ create or replace package body test_extended_coverage is l_results ut3.ut_varchar2_list; begin --Arrange - l_expected := ''; - l_expected := '%'||l_expected||'%'||l_expected||'%'; + l_expected := '%%%'; --Act select * bulk collect into l_results @@ -159,6 +158,7 @@ create or replace package body test_extended_coverage is --Assert l_actual := ut3.ut_utils.table_to_clob(l_results); ut.expect(l_actual).to_be_like(l_expected); + ut.expect(l_actual).to_be_like('%%%'); end; procedure coverage_for_file is @@ -169,7 +169,7 @@ create or replace package body test_extended_coverage is begin --Arrange l_file_path := lower('test/ut3.dummy_coverage.pkb'); - l_expected := '%%'; + l_expected := '%%%'; --Act select * bulk collect into l_results diff --git a/test/core/reporters/test_xunit_reporter.pkb b/test/core/reporters/test_xunit_reporter.pkb index fde0591d2..f75c53ce4 100644 --- a/test/core/reporters/test_xunit_reporter.pkb +++ b/test/core/reporters/test_xunit_reporter.pkb @@ -106,7 +106,7 @@ create or replace package body test_xunit_reporter as from table(ut3.ut.run('check_xunit_reporting', ut3.ut_xunit_reporter())); l_actual := ut3.ut_utils.table_to_clob(l_results); --Assert - ut.expect(l_actual).to_match('time="[0-9]*\.[0-9]{6}"'); + ut.expect(l_actual).to_match('time="[0-9]*\.[0-9]{3,6}"'); --Cleanup execute immediate 'alter session set NLS_NUMERIC_CHARACTERS='''||l_nls_numeric_characters||''''; end; From f0e265331154b725cb3667fef87049a9a917ff54 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 15 Apr 2018 14:16:08 +0100 Subject: [PATCH 33/37] Clean-up and removal of unnecessary reporters --- source/api/ut.pkb | 56 ++--- source/api/ut.pks | 24 +- source/api/ut_runner.pkb | 5 +- source/api/ut_runner.pks | 2 +- source/core/coverage/ut_coverage.pkb | 68 ++++-- source/core/coverage/ut_coverage_extended.pkb | 64 ----- source/core/coverage/ut_coverage_extended.pks | 22 -- source/core/coverage/ut_coverage_helper.pkb | 95 ++------ source/core/coverage/ut_coverage_helper.pks | 10 +- source/core/types/ut_coverage_options.tps | 5 +- source/core/types/ut_run.tpb | 11 +- source/core/types/ut_run.tps | 5 +- source/core/ut_utils.pks | 5 - source/install.sql | 4 - .../reporters/ut_block_report_html_helper.pkb | 226 ------------------ .../reporters/ut_block_report_html_helper.pks | 21 -- .../reporters/ut_coverage_html_reporter.tpb | 2 +- .../ut_coverage_report_html_helper.pkb | 25 +- .../ut_coverage_report_html_helper.pks | 2 +- test/core/reporters/test_block_coverage.pkb | 162 ------------- test/core/reporters/test_block_coverage.pks | 22 -- test/core/reporters/test_coverage.pkb | 74 ------ test/core/reporters/test_coverage.pks | 9 - .../test_cov_cobertura_rptr_blk.pkb | 45 ---- .../test_cov_cobertura_rptr_blk.pks | 10 - .../test_coverage_sonar_rprt_blk.pkb | 34 --- .../test_coverage_sonar_rprt_blk.pks | 10 - .../test_coveralls_reporter_block.pkb | 31 --- .../test_coveralls_reporter_block.pks | 10 - .../test_html_block_reporter.pkb | 29 --- .../test_html_block_reporter.pks | 10 - .../test_html_extended_reporter.pkb | 1 - .../test_html_proftab_reporter.pkb | 1 - .../core/reporters/test_extended_coverage.pkb | 3 - .../reporters/test_not_existing_block.pkb | 146 ----------- .../reporters/test_not_existing_block.pks | 18 -- test/install_tests.sql | 26 +- 37 files changed, 142 insertions(+), 1151 deletions(-) delete mode 100644 source/core/coverage/ut_coverage_extended.pkb delete mode 100644 source/core/coverage/ut_coverage_extended.pks delete mode 100644 source/reporters/ut_block_report_html_helper.pkb delete mode 100644 source/reporters/ut_block_report_html_helper.pks delete mode 100644 test/core/reporters/test_block_coverage.pkb delete mode 100644 test/core/reporters/test_block_coverage.pks delete mode 100644 test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb delete mode 100644 test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks delete mode 100644 test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb delete mode 100644 test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks delete mode 100644 test/core/reporters/test_coverage/test_coveralls_reporter_block.pkb delete mode 100644 test/core/reporters/test_coverage/test_coveralls_reporter_block.pks delete mode 100644 test/core/reporters/test_coverage/test_html_block_reporter.pkb delete mode 100644 test/core/reporters/test_coverage/test_html_block_reporter.pks delete mode 100644 test/core/reporters/test_not_existing_block.pkb delete mode 100644 test/core/reporters/test_not_existing_block.pks diff --git a/source/api/ut.pkb b/source/api/ut.pkb index b085c53aa..4225629b8 100644 --- a/source/api/ut.pkb +++ b/source/api/ut.pkb @@ -107,14 +107,14 @@ create or replace package body ut is procedure run_autonomous( a_paths ut_varchar2_list, a_reporter ut_reporter_base, a_color_console integer, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings, a_test_file_mappings ut_file_mappings, - a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list ) is pragma autonomous_transaction; begin ut_runner.run( a_paths, ut_reporters(coalesce(a_reporter,ut_documentation_reporter())), ut_utils.int_to_boolean(a_color_console), a_coverage_schemes, a_source_file_mappings, - a_test_file_mappings, a_include_objects, a_exclude_objects, false, a_coverage_type + a_test_file_mappings, a_include_objects, a_exclude_objects, false ); rollback; end; @@ -122,7 +122,7 @@ create or replace package body ut is procedure run_autonomous( a_paths ut_varchar2_list, a_reporter ut_reporter_base, a_color_console integer, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list, a_exclude_objects ut_varchar2_list ) is pragma autonomous_transaction; begin @@ -131,7 +131,7 @@ create or replace package body ut is ut_utils.int_to_boolean(a_color_console), a_coverage_schemes, ut_file_mapper.build_file_mappings(a_source_files), ut_file_mapper.build_file_mappings(a_test_files), - a_include_objects, a_exclude_objects, false, a_coverage_type + a_include_objects, a_exclude_objects, false ); rollback; end; @@ -139,7 +139,7 @@ create or replace package body ut is function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(sys_context('userenv', 'current_schema')); @@ -148,7 +148,7 @@ create or replace package body ut is begin run_autonomous( l_paths, l_reporter, a_color_console, - a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects,a_coverage_type + a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -166,7 +166,7 @@ create or replace package body ut is function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(sys_context('userenv', 'current_schema')); @@ -175,7 +175,7 @@ create or replace package body ut is begin run_autonomous( l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, - a_include_objects, a_exclude_objects, a_coverage_type + a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -193,7 +193,7 @@ create or replace package body ut is function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_lines sys_refcursor; @@ -201,7 +201,7 @@ create or replace package body ut is begin run_autonomous( a_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects, a_coverage_type + a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -219,7 +219,7 @@ create or replace package body ut is function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_lines sys_refcursor; @@ -227,7 +227,7 @@ create or replace package body ut is begin run_autonomous( a_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, - a_include_objects, a_exclude_objects, a_coverage_type + a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -245,7 +245,7 @@ create or replace package body ut is function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null,a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); @@ -254,7 +254,7 @@ create or replace package body ut is begin run_autonomous( l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects,a_coverage_type + a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -272,7 +272,7 @@ create or replace package body ut is function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); @@ -281,7 +281,7 @@ create or replace package body ut is begin run_autonomous( l_paths, l_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, - a_include_objects, a_exclude_objects, a_coverage_type + a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); @@ -299,13 +299,13 @@ create or replace package body ut is procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); begin run_autonomous( a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects, a_coverage_type + a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then treat(l_reporter as ut_output_reporter_base).lines_to_dbms_output(); @@ -316,13 +316,13 @@ create or replace package body ut is procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null,a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is l_reporter ut_reporter_base := coalesce(a_reporter, ut_documentation_reporter()); begin run_autonomous( a_paths, l_reporter, ut_utils.boolean_to_int(a_color_console), a_coverage_schemes, a_source_files, a_test_files, - a_include_objects, a_exclude_objects,a_coverage_type + a_include_objects, a_exclude_objects ); if l_reporter is of (ut_output_reporter_base) then treat(l_reporter as ut_output_reporter_base).lines_to_dbms_output(); @@ -333,50 +333,50 @@ create or replace package body ut is procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is begin ut.run( ut_varchar2_list(sys_context('userenv', 'current_schema')), a_reporter, a_color_console, - a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects, a_coverage_type + a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, a_include_objects, a_exclude_objects ); end; procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is begin ut.run( ut_varchar2_list(sys_context('userenv', 'current_schema')), a_reporter, a_color_console, - a_coverage_schemes, a_source_files, a_test_files, a_include_objects, a_exclude_objects, a_coverage_type + a_coverage_schemes, a_source_files, a_test_files, a_include_objects, a_exclude_objects ); end; procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); begin ut.run( l_paths, a_reporter, a_color_console, a_coverage_schemes, a_source_file_mappings, a_test_file_mappings, - a_include_objects, a_exclude_objects, a_coverage_type + a_include_objects, a_exclude_objects ); end; procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) is l_paths ut_varchar2_list := ut_varchar2_list(coalesce(a_path, sys_context('userenv', 'current_schema'))); begin ut.run( l_paths, a_reporter, a_color_console, a_coverage_schemes, a_source_files, a_test_files, - a_include_objects, a_exclude_objects ,a_coverage_type + a_include_objects, a_exclude_objects ); end; diff --git a/source/api/ut.pks b/source/api/ut.pks index 1d55951d0..ad6ea9757 100644 --- a/source/api/ut.pks +++ b/source/api/ut.pks @@ -50,73 +50,73 @@ create or replace package ut authid current_user as function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; function run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console integer := 0, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ) return ut_varchar2_rows pipelined; procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_paths ut_varchar2_list, a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); procedure run( a_path varchar2, a_reporter ut_reporter_base := null, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_files ut_varchar2_list, a_test_files ut_varchar2_list, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_coverage_type varchar2:=null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null ); /** diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index 3a504440d..fbdb97e1f 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -76,7 +76,7 @@ create or replace package body ut_runner is procedure run( a_paths ut_varchar2_list, a_reporters ut_reporters, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, - a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false,a_coverage_type varchar2 := null + a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean default false ) is l_items_to_run ut_run; l_listener ut_event_listener; @@ -116,8 +116,7 @@ create or replace package body ut_runner is l_exclude_object_names, l_include_object_names, set(a_source_file_mappings), - set(a_test_file_mappings), - a_coverage_type + set(a_test_file_mappings) ); l_items_to_run.do_execute(l_listener); diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index 8f92c7992..ae83b2e60 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -59,7 +59,7 @@ create or replace package ut_runner authid current_user is a_paths ut_varchar2_list, a_reporters ut_reporters, a_color_console boolean := false, a_coverage_schemes ut_varchar2_list := null, a_source_file_mappings ut_file_mappings := null, a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_fail_on_errors boolean default false, a_coverage_type varchar2 := null + a_fail_on_errors boolean default false ); /** diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index f3531995d..b56c82ccd 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -140,15 +140,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, gc_proftab_coverage); begin - ut_coverage_helper.coverage_start('utPLSQL Code coverage run '||ut_utils.to_string(systimestamp),l_coverage_type); + ut_coverage_helper.coverage_start('utPLSQL Code coverage run '||ut_utils.to_string(systimestamp)); 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, gc_proftab_coverage); begin - ut_coverage_helper.coverage_start_develop(l_coverage_type); + ut_coverage_helper.coverage_start_develop; end; procedure coverage_pause is @@ -172,23 +170,53 @@ create or replace package body ut_coverage is end; function get_coverage_data(a_coverage_options ut_coverage_options) return t_coverage is + l_result_block ut_coverage.t_coverage; + l_result_profiler_enrich ut_coverage.t_coverage; + l_object ut_coverage.t_full_name; + l_line_no binary_integer; begin - - if a_coverage_options.coverage_type = gc_block_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - return ut_coverage_block.get_coverage_data(a_coverage_options => a_coverage_options); - $else - return null; - $end - elsif a_coverage_options.coverage_type = gc_extended_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - return ut_coverage_extended.get_coverage_data(a_coverage_options => a_coverage_options); - $else - return null; - $end - else - return ut_coverage_profiler.get_coverage_data(a_coverage_options => a_coverage_options); - end if; + -- Get raw data for both reporters, order is important as tmp table will skip headers and dont populate + -- tmp table for block again. + l_result_profiler_enrich:= ut_coverage_profiler.get_coverage_data(a_coverage_options => a_coverage_options); + + -- If block coverage available we will use it. + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + l_result_block := ut_coverage_block.get_coverage_data(a_coverage_options => a_coverage_options); + + -- Enrich profiler results with some of the block results + l_object := l_result_profiler_enrich.objects.first; + while (l_object is not null) + loop + + l_line_no := l_result_profiler_enrich.objects(l_object).lines.first; + + -- to avoid no data found check if we got object in profiler + if l_result_block.objects.exists(l_object) then + while (l_line_no is not null) + loop + -- To avoid no data check for object line + if l_result_block.objects(l_object).lines.exists(l_line_no) then + -- enrich line level stats + l_result_profiler_enrich.objects(l_object).lines(l_line_no).partcove := l_result_block.objects(l_object).lines(l_line_no).partcove; + l_result_profiler_enrich.objects(l_object).lines(l_line_no).covered_blocks := l_result_block.objects(l_object).lines(l_line_no).covered_blocks; + l_result_profiler_enrich.objects(l_object).lines(l_line_no).no_blocks := l_result_block.objects(l_object).lines(l_line_no).no_blocks; + -- enrich object level stats + l_result_profiler_enrich.objects(l_object).partcovered_lines := nvl(l_result_profiler_enrich.objects(l_object).partcovered_lines,0) + l_result_block.objects(l_object).lines(l_line_no).partcove; + end if; + --At the end go to next line + l_line_no := l_result_profiler_enrich.objects(l_object).lines.next(l_line_no); + end loop; + --total level stats enrich + l_result_profiler_enrich.partcovered_lines := nvl(l_result_profiler_enrich.partcovered_lines,0) + l_result_profiler_enrich.objects(l_object).partcovered_lines; + -- At the end go to next object + end if; + + l_object := l_result_profiler_enrich.objects.next(l_object); + + end loop; + $end + + return l_result_profiler_enrich; end get_coverage_data; end; diff --git a/source/core/coverage/ut_coverage_extended.pkb b/source/core/coverage/ut_coverage_extended.pkb deleted file mode 100644 index 469756af4..000000000 --- a/source/core/coverage/ut_coverage_extended.pkb +++ /dev/null @@ -1,64 +0,0 @@ -create or replace package body ut_coverage_extended 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. - */ - - /** - * Public functions - */ - - function get_coverage_data(a_coverage_options ut_coverage_options) return ut_coverage.t_coverage is - l_result_block ut_coverage.t_coverage; - l_result_profiler_enrich ut_coverage.t_coverage; - l_object ut_coverage.t_full_name; - l_line_no binary_integer; - begin - -- Get raw data for both reporters, order is important as tmp table will skip headers and dont populate - -- tmp table for block again. - l_result_profiler_enrich:= ut_coverage_profiler.get_coverage_data(a_coverage_options => a_coverage_options); - - l_result_block := ut_coverage_block.get_coverage_data(a_coverage_options => a_coverage_options); - - -- Enrich profiler results with some of the block results - l_object := l_result_profiler_enrich.objects.first; - while (l_object is not null) - loop - l_line_no := l_result_profiler_enrich.objects(l_object).lines.first; - while (l_line_no is not null) - loop - if l_result_block.objects(l_object).lines.exists(l_line_no) then - -- enrich line level stats - l_result_profiler_enrich.objects(l_object).lines(l_line_no).partcove := l_result_block.objects(l_object).lines(l_line_no).partcove; - l_result_profiler_enrich.objects(l_object).lines(l_line_no).covered_blocks := l_result_block.objects(l_object).lines(l_line_no).covered_blocks; - l_result_profiler_enrich.objects(l_object).lines(l_line_no).no_blocks := l_result_block.objects(l_object).lines(l_line_no).no_blocks; - -- enrich object level stats - l_result_profiler_enrich.objects(l_object).partcovered_lines := nvl(l_result_profiler_enrich.objects(l_object).partcovered_lines,0) + l_result_block.objects(l_object).lines(l_line_no).partcove; - end if; - --At the end go to next line - l_line_no := l_result_profiler_enrich.objects(l_object).lines.next(l_line_no); - end loop; - --total level stats enrich - l_result_profiler_enrich.partcovered_lines := nvl(l_result_profiler_enrich.partcovered_lines,0) + l_result_profiler_enrich.objects(l_object).partcovered_lines; - -- At the end go to next object - l_object := l_result_profiler_enrich.objects.next(l_object); - end loop; - - return l_result_profiler_enrich; - - end get_coverage_data; - -end; -/ diff --git a/source/core/coverage/ut_coverage_extended.pks b/source/core/coverage/ut_coverage_extended.pks deleted file mode 100644 index 01d57fb7c..000000000 --- a/source/core/coverage/ut_coverage_extended.pks +++ /dev/null @@ -1,22 +0,0 @@ -create or replace package ut_coverage_extended 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(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 aa7e7b6f5..41f5108d5 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -35,11 +35,6 @@ create or replace package body ut_coverage_helper is type t_block_rows is table of t_block_row; - procedure set_coverage_type(a_coverage_type in varchar2) is - begin - g_coverage_type := a_coverage_type; - end; - procedure set_coverage_status(a_started in boolean) is begin g_is_started := a_started; @@ -49,11 +44,6 @@ create or replace package body ut_coverage_helper 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(a_coverage_type in varchar2) return integer is begin @@ -65,86 +55,58 @@ create or replace package body ut_coverage_helper is return g_develop_mode; end; - procedure coverage_start_internal(a_run_comment varchar2,a_coverage_type in varchar2) is - begin - set_coverage_type(a_coverage_type); - if get_coverage_type = ut_coverage.gc_block_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_coverage_helper_block.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id(ut_coverage.gc_block_coverage) ); - $else - raise_application_error(ut_utils.gc_invalid_coverage_type,'Invalid coverage type requested. Please validate your Oracle install'); - $end - elsif get_coverage_type = ut_coverage.gc_extended_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + procedure coverage_start_internal(a_run_comment varchar2) is + begin + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then ut_coverage_helper_block.coverage_start(a_run_comment => a_run_comment ,a_coverage_id => g_coverage_id(ut_coverage.gc_block_coverage) ); ut_coverage_helper_profiler.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id(ut_coverage.gc_proftab_coverage)); coverage_pause(); - $else - raise_application_error(ut_utils.gc_invalid_coverage_type,'Invalid coverage type requested. Please validate your Oracle install'); - $end - else + $else ut_coverage_helper_profiler.coverage_start(a_run_comment => a_run_comment, a_coverage_id => g_coverage_id(ut_coverage.gc_proftab_coverage)); coverage_pause(); - end if; + $end + g_is_started := true; end; - procedure coverage_start(a_run_comment varchar2,a_coverage_type in varchar2) is + procedure coverage_start(a_run_comment varchar2) is begin if not g_is_started then g_develop_mode := false; - coverage_start_internal(a_run_comment,a_coverage_type); + coverage_start_internal(a_run_comment); end if; end; - procedure coverage_start_develop(a_coverage_type in varchar2) is + procedure coverage_start_develop is begin if not g_is_started then g_develop_mode := true; - coverage_start_internal('utPLSQL Code coverage run in development MODE '||ut_utils.to_string(systimestamp),a_coverage_type); + coverage_start_internal('utPLSQL Code coverage run in development MODE '||ut_utils.to_string(systimestamp)); end if; end; procedure coverage_pause is begin if not g_develop_mode then - if get_coverage_type = ut_coverage.gc_block_coverage then - null; - else - ut_coverage_helper_profiler.coverage_pause(); - end if; + ut_coverage_helper_profiler.coverage_pause(); end if; end; procedure coverage_resume is begin - if get_coverage_type = ut_coverage.gc_block_coverage then - null; - else - ut_coverage_helper_profiler.coverage_resume(); - end if; + ut_coverage_helper_profiler.coverage_resume(); end; procedure coverage_stop is begin if not g_develop_mode then g_is_started := false; - if get_coverage_type = ut_coverage.gc_block_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_coverage_helper_block.coverage_stop(); - $else - null; - $end - elsif get_coverage_type = ut_coverage.gc_extended_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_coverage_helper_profiler.coverage_stop(); - ut_coverage_helper_block.coverage_stop(); - $else - null; - $end - else - ut_coverage_helper_profiler.coverage_stop(); - end if; + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_coverage_helper_profiler.coverage_stop(); + ut_coverage_helper_block.coverage_stop(); + $else + ut_coverage_helper_profiler.coverage_stop(); + $end end if; end; @@ -152,22 +114,13 @@ create or replace package body ut_coverage_helper is begin g_develop_mode := false; g_is_started := false; - if get_coverage_type = ut_coverage.gc_block_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_coverage_helper_block.coverage_stop(); - $else - null; - $end - elsif get_coverage_type = ut_coverage.gc_extended_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - ut_coverage_helper_profiler.coverage_stop(); - ut_coverage_helper_block.coverage_stop(); - $else - null; - $end - else + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + ut_coverage_helper_profiler.coverage_stop(); + ut_coverage_helper_block.coverage_stop(); + $else ut_coverage_helper_profiler.coverage_stop(); - end if; + $end + end; procedure mock_coverage_id(a_coverage_id integer,a_coverage_type in varchar2) is diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index 6ec553df0..ee7c33846 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -19,14 +19,10 @@ create or replace package ut_coverage_helper authid definer is type g_coverage_arr is table of integer index by varchar2(30); g_coverage_id g_coverage_arr; - g_coverage_type varchar2(32); - - function get_coverage_type return varchar2; + function get_coverage_id(a_coverage_type in varchar2) 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); @@ -66,12 +62,12 @@ create or replace package ut_coverage_helper authid definer is function is_develop_mode return boolean; - procedure coverage_start(a_run_comment in varchar2,a_coverage_type in varchar2); + procedure coverage_start(a_run_comment in varchar2); /* * Start coverage in develop mode, where all internal calls to utPLSQL itself are also included */ - procedure coverage_start_develop(a_coverage_type in varchar2); + procedure coverage_start_develop; procedure coverage_stop; diff --git a/source/core/types/ut_coverage_options.tps b/source/core/types/ut_coverage_options.tps index 1710ca1ef..876457f8e 100644 --- a/source/core/types/ut_coverage_options.tps +++ b/source/core/types/ut_coverage_options.tps @@ -1,4 +1,4 @@ -create or replace type ut_coverage_options as object ( +create or replace type ut_coverage_options force as object ( /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project @@ -19,7 +19,6 @@ create or replace type ut_coverage_options as object ( schema_names ut_varchar2_rows, exclude_objects ut_object_names, include_objects ut_object_names, - file_mappings ut_file_mappings, - coverage_type varchar2(32) + file_mappings ut_file_mappings ) / diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb index ae35e3ab6..c7b2056cf 100644 --- a/source/core/types/ut_run.tpb +++ b/source/core/types/ut_run.tpb @@ -24,16 +24,12 @@ create or replace type body ut_run as a_exclude_objects ut_object_names := null, a_include_objects ut_object_names := null, a_project_file_mappings ut_file_mappings := null, - a_test_file_mappings ut_file_mappings := null, - a_coverage_type varchar2 := null + a_test_file_mappings ut_file_mappings := null ) return self as result is l_coverage_schema_names ut_varchar2_rows; l_coverage_options ut_coverage_options; l_exclude_objects ut_object_names; - l_coverage_type varchar2(32); - begin - l_coverage_type := coalesce(a_coverage_type,'proftab'); - + begin self.run_paths := a_run_paths; self.self_type := $$plsql_unit; self.items := a_items; @@ -43,8 +39,7 @@ create or replace type body ut_run as a_schema_names, a_exclude_objects, a_include_objects, - a_project_file_mappings, - l_coverage_type + a_project_file_mappings ); return; end; diff --git a/source/core/types/ut_run.tps b/source/core/types/ut_run.tps index 1c5df6250..02d77a93f 100644 --- a/source/core/types/ut_run.tps +++ b/source/core/types/ut_run.tps @@ -1,4 +1,4 @@ -create or replace type ut_run under ut_suite_item ( +create or replace type ut_run force under ut_suite_item ( /* utPLSQL - Version 3 Copyright 2016 - 2017 utPLSQL Project @@ -31,8 +31,7 @@ create or replace type ut_run under ut_suite_item ( a_exclude_objects ut_object_names := null, a_include_objects ut_object_names := null, a_project_file_mappings ut_file_mappings := null, - a_test_file_mappings ut_file_mappings := null, - a_coverage_type varchar2 := null + a_test_file_mappings ut_file_mappings := null ) return self as result, overriding member procedure mark_as_skipped(self in out nocopy ut_run, a_listener in out nocopy ut_event_listener_base), overriding member function do_execute(self in out nocopy ut_run, a_listener in out nocopy ut_event_listener_base) return boolean, diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index a0735aced..9c42dacc5 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -90,11 +90,6 @@ create or replace package ut_utils authid definer is gc_invalid_version_no constant pls_integer := -20214; pragma exception_init(ex_invalid_version_no, -20214); - -- Invalid coverage type - ex_invalid_coverage_type exception; - gc_invalid_coverage_type constant pls_integer := -20215; - pragma exception_init(ex_invalid_coverage_type, -20215); - gc_max_storage_varchar2_len constant integer := 4000; gc_max_output_string_length constant integer := 4000; gc_max_input_string_length constant integer := gc_max_output_string_length - 2; --we need to remove 2 chars for quotes around string diff --git a/source/install.sql b/source/install.sql index bcbe71aea..0a4cc3bc8 100644 --- a/source/install.sql +++ b/source/install.sql @@ -128,7 +128,6 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema @@install_component.sql 'core/coverage/ut_coverage_sources_tmp.sql' @@install_component.sql 'core/coverage/ut_coverage_helper.pks' @@install_above_12_1.sql 'core/coverage/ut_coverage_helper_block.pks' -@@install_above_12_1.sql 'core/coverage/ut_coverage_extended.pks' @@install_component.sql 'core/coverage/ut_coverage_helper_profiler.pks' @@install_component.sql 'core/coverage/ut_coverage.pks' @@install_above_12_1.sql 'core/coverage/ut_coverage_block.pks' @@ -136,7 +135,6 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema @@install_component.sql 'core/coverage/ut_coverage_reporter_base.tps' @@install_component.sql 'core/coverage/ut_coverage_helper.pkb' @@install_above_12_1.sql 'core/coverage/ut_coverage_helper_block.pkb' -@@install_above_12_1.sql 'core/coverage/ut_coverage_extended.pkb' @@install_component.sql 'core/coverage/ut_coverage_helper_profiler.pkb' @@install_component.sql 'core/coverage/ut_coverage.pkb' @@install_above_12_1.sql 'core/coverage/ut_coverage_block.pkb' @@ -262,10 +260,8 @@ 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_above_12_1.sql 'reporters/ut_block_report_html_helper.pks' @@install_above_12_1.sql 'reporters/ut_extended_report_html_helper.pks' @@install_component.sql 'reporters/ut_proftab_report_html_helper.pks' -@@install_above_12_1.sql 'reporters/ut_block_report_html_helper.pkb' @@install_above_12_1.sql 'reporters/ut_extended_report_html_helper.pkb' @@install_component.sql 'reporters/ut_coverage_report_html_helper.pkb' @@install_component.sql 'reporters/ut_proftab_report_html_helper.pkb' 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 := '

      ' || - dbms_xmlgen.convert(a_object_full_name) || '

      ' || '

      ' || l_coverage_pct || ' % lines covered

      ' || - '
      ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || - '(including ' || a_coverage_unit.partcovered_lines || - ' lines partially covered ' - || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'||'

      ' || l_coverage_block_pct || ' % blocks covered

      '|| - '
      '|| TO_CHAR(a_coverage_unit.covered_blocks + a_coverage_unit.uncovered_blocks)||' blocks in total.'|| - ''||a_coverage_unit.covered_blocks||' blocks covered and '|| - '' || a_coverage_unit.uncovered_blocks || ' blocks missed.
      ' - ||'
        '; - 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 := ' -
      1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
      2. '; - else - l_hits := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| - to_char(a_coverage_unit.lines(line_no).no_blocks); - - l_file_part := ' -
      3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
      4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
      '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - begin - l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_blocks, a_coverage.uncovered_blocks); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
      ' || '

      ' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - ', ' || - l_coverage_block_pct || '%' || ' executed blocks covered)' - ||'

      ' || '' || '
      ' || - a_coverage.objects.count || ' files in total.
      ' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered' || - ' (inlcluding ' || a_coverage.partcovered_lines || - ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - '
      '|| TO_CHAR(a_coverage.covered_blocks + a_coverage.uncovered_blocks)||' exectuted blocks in total. '|| - ''||a_coverage.covered_blocks||' blocks covered and '|| - '' || a_coverage.uncovered_blocks || ' blocks missed.
      ' - ||'
    3. File% coveredLinesRelevant LinesLines coveredLines missed' ||'Avg. Hits / Line
      ' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - l_coverage_block_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_blocks, l_unit_coverage.uncovered_blocks); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - - --l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
      File% coveredLinesRelevant LinesLines coveredLines missed' - ||'% blocks covered' ||'
      ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || - (l_unit_coverage.covered_lines + l_unit_coverage.partcovered_lines + l_unit_coverage.uncovered_lines) || - '' || l_unit_coverage.covered_lines || ' (' || l_unit_coverage.partcovered_lines || ')' || - '' || l_unit_coverage.uncovered_lines || '' ||to_char(l_coverage_block_pct)||'%' - || '
      '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - - /* - * public definitions - */ - 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 is - - l_file_part varchar2(32767); - l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_blocks, a_coverage_data.uncovered_blocks); - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
      using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || '' || l_title || - '' || '' || - '' || - '' || - '' || '' || '' || - '
      loading
      ' || - ''; - - 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_html_reporter.tpb b/source/reporters/ut_coverage_html_reporter.tpb index 2c5e2b15a..d1a9dd473 100644 --- a/source/reporters/ut_coverage_html_reporter.tpb +++ b/source/reporters/ut_coverage_html_reporter.tpb @@ -35,7 +35,7 @@ create or replace type body ut_coverage_html_reporter is ut_coverage.coverage_stop(); l_coverage_data := ut_coverage.get_coverage_data(a_run.coverage_options); - self.print_clob( ut_coverage_report_html_helper.get_index( a_coverage_data => l_coverage_data,a_assets_path => self.assets_path, a_project_name=> self.project_name, a_coverage_type => a_run.coverage_options.coverage_type ) ); + self.print_clob( ut_coverage_report_html_helper.get_index( a_coverage_data => l_coverage_data,a_assets_path => self.assets_path, a_project_name=> self.project_name )); end; diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb index 7fb1660c5..5c3174137 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -101,27 +101,16 @@ create or replace package body ut_coverage_report_html_helper is /* * public definitions */ - 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) + 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 is l_result clob; - l_coverage_type varchar2(32) := coalesce(a_coverage_type, ut_coverage.gc_proftab_coverage); - begin - if l_coverage_type = ut_coverage.gc_block_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - l_result := ut_block_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); - $else - l_result := null; - $end - elsif l_coverage_type = ut_coverage.gc_extended_coverage then - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - l_result := ut_extended_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); - $else - l_result := null; - $end - else +begin + $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then + l_result := ut_extended_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); + $else l_result := ut_proftab_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); - end if; - + $end + 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..e718f9fed 100644 --- a/source/reporters/ut_coverage_report_html_helper.pks +++ b/source/reporters/ut_coverage_report_html_helper.pks @@ -31,7 +31,7 @@ create or replace package ut_coverage_report_html_helper authid current_user is 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; + 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/test/core/reporters/test_block_coverage.pkb b/test/core/reporters/test_block_coverage.pkb deleted file mode 100644 index 417066633..000000000 --- a/test/core/reporters/test_block_coverage.pkb +++ /dev/null @@ -1,162 +0,0 @@ -create or replace package body test_block_coverage is - - g_run_id integer; - - function get_mock_run_id return integer is - v_result integer; - begin - select nvl(min(run_id),0) - 1 into v_result - from ut3.dbmspcc_runs; - return v_result; - end; - - procedure create_dummy_coverage_package is - pragma autonomous_transaction; - begin - execute immediate q'[create or replace package UT3.DUMMY_COVERAGE is - procedure do_stuff(i_input in number); - end;]'; - execute immediate q'[create or replace package body UT3.DUMMY_COVERAGE is - procedure do_stuff(i_input in number) is - begin - if i_input = 2 then - dbms_output.put_line('should not get here'); - else - dbms_output.put_line('should get here'); - end if; - end; - end;]'; - end; - - procedure create_dummy_coverage_test is - pragma autonomous_transaction; - begin - execute immediate q'[create or replace package UT3.TEST_DUMMY_COVERAGE is - --%suite(dummy coverage test) - --%suitepath(coverage_testing) - - --%test - procedure test_do_stuff; - end;]'; - execute immediate q'[create or replace package body UT3.TEST_DUMMY_COVERAGE is - procedure test_do_stuff is - begin - dummy_coverage.do_stuff(1); - ut.expect(1).to_equal(1); - end; - end;]'; - end; - - procedure mock_coverage_data(a_run_id integer) is - c_unit_id constant integer := 1; - begin - insert into ut3.dbmspcc_runs ( run_id, run_owner, run_timestamp, run_comment) - values(a_run_id, user, sysdate, 'unit testing utPLSQL'); - - insert into ut3.dbmspcc_units ( run_id, object_id, type, owner, name,last_ddl_time) - values(a_run_id, c_unit_id, 'PACKAGE BODY', 'UT3', 'DUMMY_COVERAGE',sysdate); - - insert into ut3.dbmspcc_blocks ( run_id, object_id, line,block,col,covered,not_feasible) - select a_run_id, c_unit_id,4,1,1,1,0 from dual union all - select a_run_id, c_unit_id,4,2,2,0,0 from dual union all - select a_run_id, c_unit_id,5,3,0,1,0 from dual union all - select a_run_id, c_unit_id,7,4,1,1,0 from dual; - end; - - procedure setup_dummy_coverage is - pragma autonomous_transaction; - begin - create_dummy_coverage_package(); - create_dummy_coverage_test(); - g_run_id := get_mock_run_id(); - ut3.ut_coverage_helper.mock_coverage_id(g_run_id,ut3.ut_coverage.gc_block_coverage); - mock_coverage_data(g_run_id); - commit; - end; - - procedure cleanup_dummy_coverage is - pragma autonomous_transaction; - begin - begin execute immediate q'[drop package ut3.test_dummy_coverage]'; exception when others then null; end; - begin execute immediate q'[drop package ut3.dummy_coverage]'; exception when others then null; end; - delete from ut3.dbmspcc_blocks where run_id = g_run_id; - delete from ut3.dbmspcc_units where run_id = g_run_id; - delete from ut3.dbmspcc_runs where run_id = g_run_id; - commit; - end; - - procedure coverage_for_object is - l_expected clob; - l_actual clob; - l_results ut3.ut_varchar2_list; - begin - --Arrange - l_expected := '%%%'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'block', - a_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage' ) - ) - ); - --Assert - l_actual := ut3.ut_utils.table_to_clob(l_results); - ut.expect(l_actual).to_be_like(l_expected); - end; - - procedure coverage_for_schema is - l_expected clob; - l_actual clob; - l_results ut3.ut_varchar2_list; - begin - --Arrange - l_expected := '%%%'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'block', - a_coverage_schemes => ut3.ut_varchar2_list( 'ut3' ) - ) - ); - --Assert - l_actual := ut3.ut_utils.table_to_clob(l_results); - ut.expect(l_actual).to_be_like(l_expected); - ut.expect(l_actual).to_be_like('%%%'); - end; - - procedure coverage_for_file is - l_expected clob; - l_actual clob; - l_results ut3.ut_varchar2_list; - l_file_path varchar2(100); - begin - --Arrange - l_file_path := lower('test/ut3.dummy_coverage.pkb'); - l_expected := '%%%'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'block', - a_source_files => ut3.ut_varchar2_list( l_file_path ), - a_test_files => ut3.ut_varchar2_list( ) - ) - ); - --Assert - l_actual := ut3.ut_utils.table_to_clob(l_results); - ut.expect(l_actual).to_be_like(l_expected); - end; - -end; -/ diff --git a/test/core/reporters/test_block_coverage.pks b/test/core/reporters/test_block_coverage.pks deleted file mode 100644 index 8f65a6ca8..000000000 --- a/test/core/reporters/test_block_coverage.pks +++ /dev/null @@ -1,22 +0,0 @@ -create or replace package test_block_coverage is - - --%suite - --%suitepath(utplsql.core.reporters) - - --%beforeall - procedure setup_dummy_coverage; - - --%afterall - procedure cleanup_dummy_coverage; - - --%test(Coverage is gathered for specified object - block coverage type) - procedure coverage_for_object; - - --%test(Coverage is gathered for specified schema - block coverage type) - procedure coverage_for_schema; - - --%test(Coverage is gathered for specified file - block coverage type) - procedure coverage_for_file; - -end; -/ diff --git a/test/core/reporters/test_coverage.pkb b/test/core/reporters/test_coverage.pkb index 43346c430..7a759ec43 100644 --- a/test/core/reporters/test_coverage.pkb +++ b/test/core/reporters/test_coverage.pkb @@ -214,80 +214,6 @@ create or replace package body test_coverage is ut.expect(l_actual).to_be_like(l_expected); end; - procedure coverage_for_object_proftab is - l_expected clob; - l_actual clob; - l_results ut3.ut_varchar2_list; - begin - --Arrange - l_expected := '%%'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'proftab', - a_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage' ) - ) - ); - --Assert - l_actual := ut3.ut_utils.table_to_clob(l_results); - ut.expect(l_actual).to_be_like(l_expected); - end; - - procedure coverage_for_schema_proftab is - l_expected clob; - l_actual clob; - l_results ut3.ut_varchar2_list; - begin - --Arrange - l_expected := ''; - l_expected := '%'||l_expected||'%'||l_expected||'%'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'proftab', - a_coverage_schemes => ut3.ut_varchar2_list( 'ut3' ) - ) - ); - --Assert - l_actual := ut3.ut_utils.table_to_clob(l_results); - ut.expect(l_actual).to_be_like(l_expected); - end; - - procedure coverage_for_file_proftab is - l_expected clob; - l_actual clob; - l_results ut3.ut_varchar2_list; - l_file_path varchar2(100); - begin - --Arrange - l_file_path := lower('test/ut3.dummy_coverage.pkb'); - l_expected := '%%'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'proftab', - a_source_files => ut3.ut_varchar2_list( l_file_path ), - a_test_files => ut3.ut_varchar2_list( ) - ) - ); - --Assert - l_actual := ut3.ut_utils.table_to_clob(l_results); - ut.expect(l_actual).to_be_like(l_expected); - end; - - procedure coverage_tmp_data_refresh is l_actual clob; l_results ut3.ut_varchar2_list; diff --git a/test/core/reporters/test_coverage.pks b/test/core/reporters/test_coverage.pks index 5b2ed54e9..d507fa0ee 100644 --- a/test/core/reporters/test_coverage.pks +++ b/test/core/reporters/test_coverage.pks @@ -21,15 +21,6 @@ create or replace package test_coverage is --%test(Coverage is gathered for specified file - default coverage type) procedure coverage_for_file; - - --%test(Coverage is gathered for specified object - explicit proftab coverage) - procedure coverage_for_object_proftab; - - --%test(Coverage is gathered for specified schema - explicit proftab coverag) - procedure coverage_for_schema_proftab; - - --%test(Coverage is gathered for specified file - explicit proftab coverag) - procedure coverage_for_file_proftab; --%test(Coverage data is not cached between runs - issue #562 ) --%aftertest(setup_dummy_coverage) diff --git a/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb b/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb deleted file mode 100644 index ededfdceb..000000000 --- a/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb +++ /dev/null @@ -1,45 +0,0 @@ -create or replace package body test_cov_cobertura_rptr_blk is - - procedure report_on_file is - l_results ut3.ut_varchar2_list; - l_expected clob; - l_actual clob; - begin - --Arrange - l_expected := - ' - - -test/ut3.dummy_coverage.pkb - - - - - - - - - - - - -'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_cobertura_reporter( ), - a_coverage_type => 'block', - a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), - a_test_files => ut3.ut_varchar2_list( ) - ) - ); - l_actual := ut3.ut_utils.table_to_clob(l_results); - --Assert - ut.expect(l_actual).to_be_like(l_expected); - end; - -end; -/ diff --git a/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks b/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks deleted file mode 100644 index 248c6b803..000000000 --- a/test/core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks +++ /dev/null @@ -1,10 +0,0 @@ -create or replace package test_cov_cobertura_rptr_blk is - - --%suite(ut_test_cov_cobertura_rptr_blk) - --%suitepath(utplsql.core.reporters.test_block_coverage) - - --%test(reports on a project file mapped to database object in block coverage) - procedure report_on_file; - -end test_cov_cobertura_rptr_blk; -/ diff --git a/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb b/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb deleted file mode 100644 index 7f7c259a6..000000000 --- a/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb +++ /dev/null @@ -1,34 +0,0 @@ -create or replace package body test_coverage_sonar_rprt_blk is - - procedure report_on_file is - l_results ut3.ut_varchar2_list; - l_expected clob; - l_actual clob; - begin - --Arrange - l_expected := ' - - - - - -'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'block', - a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), - a_test_files => ut3.ut_varchar2_list( ) - ) - ); - l_actual := ut3.ut_utils.table_to_clob(l_results); - --Assert - ut.expect(l_actual).to_equal(l_expected); - end; - -end; -/ diff --git a/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks b/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks deleted file mode 100644 index b30e76dbe..000000000 --- a/test/core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks +++ /dev/null @@ -1,10 +0,0 @@ -create or replace package test_coverage_sonar_rprt_blk is - - --%suite(ut_test_coverage_sonar_rprt_blk) - --%suitepath(utplsql.core.reporters.test_block_coverage) - - --%test(reports on a project file mapped to database object in block coverage) - procedure report_on_file; - -end; -/ diff --git a/test/core/reporters/test_coverage/test_coveralls_reporter_block.pkb b/test/core/reporters/test_coverage/test_coveralls_reporter_block.pkb deleted file mode 100644 index 56a5499de..000000000 --- a/test/core/reporters/test_coverage/test_coveralls_reporter_block.pkb +++ /dev/null @@ -1,31 +0,0 @@ -create or replace package body test_coveralls_reporter_block is - - procedure report_on_file is - l_results ut3.ut_varchar2_list; - l_expected clob; - l_actual clob; - begin - --Arrange - l_expected := '{"source_files":[ -{ "name": "test/ut3.dummy_coverage.pkb", -"coverage": [null,null,null,1,1,null,1]}]} - '; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coveralls_reporter( ), - a_coverage_type => 'block', - a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), - a_test_files => ut3.ut_varchar2_list( ) - ) - ); - l_actual := ut3.ut_utils.table_to_clob(l_results); - --Assert - ut.expect(l_actual).to_equal(l_expected); - end; - -end; -/ diff --git a/test/core/reporters/test_coverage/test_coveralls_reporter_block.pks b/test/core/reporters/test_coverage/test_coveralls_reporter_block.pks deleted file mode 100644 index 92b0a7517..000000000 --- a/test/core/reporters/test_coverage/test_coveralls_reporter_block.pks +++ /dev/null @@ -1,10 +0,0 @@ -create or replace package test_coveralls_reporter_block is - - --%suite(ut_coveralls_reporter_block) - --%suitepath(utplsql.core.reporters.test_block_coverage) - - --%test(reports on a project file mapped to database object in block coverage) - procedure report_on_file; - -end; -/ diff --git a/test/core/reporters/test_coverage/test_html_block_reporter.pkb b/test/core/reporters/test_coverage/test_html_block_reporter.pkb deleted file mode 100644 index fcc99e043..000000000 --- a/test/core/reporters/test_coverage/test_html_block_reporter.pkb +++ /dev/null @@ -1,29 +0,0 @@ -create or replace package body test_html_block_reporter is - - procedure report_on_file is - l_results ut3.ut_varchar2_list; - l_expected varchar2(32767); - l_actual clob; - begin - --Arrange - l_expected := '%

      UT3.DUMMY_COVERAGE

      %75 % blocks covered
      4 blocks in total.3 blocks covered and 1 blocks missed.
      %'; - --l_expected := '%

      UT3.DUMMY_COVERAGE

      100 % lines covered

      3 relevant lines. 3 lines covered (including 0 lines partially covered ) and 0 lines missed

      100 % blocks covered

      3 blocks in total.3 blocks covered and 0 blocks missed.
      %'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_html_reporter(), - a_coverage_type => 'block', - a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), - a_test_files => ut3.ut_varchar2_list( ) - ) - ); - l_actual := ut3.ut_utils.table_to_clob(l_results); - --Assert - ut.expect(l_actual).to_be_like(l_expected); - end; - -end test_html_block_reporter; -/ diff --git a/test/core/reporters/test_coverage/test_html_block_reporter.pks b/test/core/reporters/test_coverage/test_html_block_reporter.pks deleted file mode 100644 index e6848c0da..000000000 --- a/test/core/reporters/test_coverage/test_html_block_reporter.pks +++ /dev/null @@ -1,10 +0,0 @@ -create or replace package test_html_block_reporter is - - --%suite(ut_html_block_reporter) - --%suitepath(utplsql.core.reporters.test_block_coverage) - - --%test(reports on a project file mapped to database object in block coverage) - procedure report_on_file; - -end test_html_block_reporter; -/ diff --git a/test/core/reporters/test_coverage/test_html_extended_reporter.pkb b/test/core/reporters/test_coverage/test_html_extended_reporter.pkb index 30843fe14..cd71a6c8c 100644 --- a/test/core/reporters/test_coverage/test_html_extended_reporter.pkb +++ b/test/core/reporters/test_coverage/test_html_extended_reporter.pkb @@ -14,7 +14,6 @@ create or replace package body test_html_extended_reporter is ut3.ut.run( a_path => 'ut3.test_dummy_coverage', a_reporter=> ut3.ut_coverage_html_reporter(), - a_coverage_type => 'extended', a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), a_test_files => ut3.ut_varchar2_list( ) ) diff --git a/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb b/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb index 307ad27dd..80e6a9ded 100644 --- a/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb +++ b/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb @@ -16,7 +16,6 @@ create or replace package body test_html_proftab_reporter is ut3.ut.run( a_path => 'ut3.test_dummy_coverage', a_reporter=> ut3.ut_coverage_html_reporter(), - a_coverage_type => 'proftab', a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), a_test_files => ut3.ut_varchar2_list( ) ) diff --git a/test/core/reporters/test_extended_coverage.pkb b/test/core/reporters/test_extended_coverage.pkb index 441ee61bb..7a7668b6c 100644 --- a/test/core/reporters/test_extended_coverage.pkb +++ b/test/core/reporters/test_extended_coverage.pkb @@ -128,7 +128,6 @@ create or replace package body test_extended_coverage is ut3.ut.run( a_path => 'ut3.test_dummy_coverage', a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'extended', a_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage' ) ) ); @@ -151,7 +150,6 @@ create or replace package body test_extended_coverage is ut3.ut.run( a_path => 'ut3.test_dummy_coverage', a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'extended', a_coverage_schemes => ut3.ut_varchar2_list( 'ut3' ) ) ); @@ -177,7 +175,6 @@ create or replace package body test_extended_coverage is ut3.ut.run( a_path => 'ut3.test_dummy_coverage', a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'extended', a_source_files => ut3.ut_varchar2_list( l_file_path ), a_test_files => ut3.ut_varchar2_list( ) ) diff --git a/test/core/reporters/test_not_existing_block.pkb b/test/core/reporters/test_not_existing_block.pkb deleted file mode 100644 index f14979896..000000000 --- a/test/core/reporters/test_not_existing_block.pkb +++ /dev/null @@ -1,146 +0,0 @@ -create or replace package body test_not_existing_block is - - g_run_id integer; - - function get_mock_run_id return integer is - v_result integer; - begin - select nvl(min(runid),0) - 1 into v_result - from ut3.plsql_profiler_runs; - return v_result; - end; - - procedure create_dummy_coverage_package is - pragma autonomous_transaction; - begin - execute immediate q'[create or replace package UT3.DUMMY_COVERAGE is - procedure do_stuff; - end;]'; - execute immediate q'[create or replace package body UT3.DUMMY_COVERAGE is - procedure do_stuff is - begin - if 1 = 2 then - dbms_output.put_line('should not get here'); - else - dbms_output.put_line('should get here'); - end if; - end; - end;]'; - end; - - procedure create_dummy_coverage_test is - pragma autonomous_transaction; - begin - execute immediate q'[create or replace package UT3.TEST_DUMMY_COVERAGE is - --%suite(dummy coverage test) - --%suitepath(coverage_testing) - - --%test - procedure test_do_stuff; - end;]'; - execute immediate q'[create or replace package body UT3.TEST_DUMMY_COVERAGE is - procedure test_do_stuff is - begin - dummy_coverage.do_stuff; - end; - end;]'; - end; - - procedure create_dummy_coverage_test_1 is - pragma autonomous_transaction; - begin - execute immediate q'[create or replace package UT3.DUMMY_COVERAGE_1 is - procedure do_stuff; - end;]'; - execute immediate q'[create or replace package body UT3.DUMMY_COVERAGE_1 is - procedure do_stuff is - begin - if 1 = 2 then - dbms_output.put_line('should not get here'); - else - dbms_output.put_line('should get here'); - end if; - end; - end;]'; - execute immediate q'[create or replace package UT3.TEST_DUMMY_COVERAGE_1 is - --%suite(dummy coverage test 1) - --%suitepath(coverage_testing) - - --%test - procedure test_do_stuff; - end;]'; - execute immediate q'[create or replace package body UT3.TEST_DUMMY_COVERAGE_1 is - procedure test_do_stuff is - begin - dummy_coverage_1.do_stuff; - end; - end;]'; - end; - - procedure drop_dummy_coverage_test_1 is - pragma autonomous_transaction; - begin - execute immediate q'[drop package UT3.DUMMY_COVERAGE_1]'; - execute immediate q'[drop package UT3.TEST_DUMMY_COVERAGE_1]'; - end; - - - procedure mock_coverage_data(a_run_id integer) is - c_unit_id constant integer := 1; - begin - insert into ut3.plsql_profiler_runs ( runid, run_owner, run_date, run_comment) - values(a_run_id, user, sysdate, 'unit testing utPLSQL'); - - insert into ut3.plsql_profiler_units ( runid, unit_number, unit_type, unit_owner, unit_name) - values(a_run_id, c_unit_id, 'PACKAGE BODY', 'UT3', 'DUMMY_COVERAGE'); - - insert into ut3.plsql_profiler_data ( runid, unit_number, line#, total_occur, total_time) - select a_run_id, c_unit_id, 4, 1, 1 from dual union all - select a_run_id, c_unit_id, 5, 0, 0 from dual union all - select a_run_id, c_unit_id, 7, 1, 1 from dual; - end; - - procedure setup_dummy_coverage is - pragma autonomous_transaction; - begin - create_dummy_coverage_package(); - create_dummy_coverage_test(); - g_run_id := get_mock_run_id(); - ut3.ut_coverage_helper.mock_coverage_id(g_run_id,ut3.ut_coverage.gc_block_coverage); - mock_coverage_data(g_run_id); - commit; - end; - - procedure cleanup_dummy_coverage is - pragma autonomous_transaction; - begin - begin execute immediate q'[drop package ut3.test_dummy_coverage]'; exception when others then null; end; - begin execute immediate q'[drop package ut3.dummy_coverage]'; exception when others then null; end; - delete from ut3.plsql_profiler_data where runid = g_run_id; - delete from ut3.plsql_profiler_units where runid = g_run_id; - delete from ut3.plsql_profiler_runs where runid = g_run_id; - commit; - end; - - procedure invalid_coverage_type is - l_expected clob; - l_actual clob; - l_results ut3.ut_varchar2_list; - begin - --Arrange - l_expected := '%%'; - --Act - select * - bulk collect into l_results - from table( - ut3.ut.run( - a_path => 'ut3.test_dummy_coverage', - a_reporter=> ut3.ut_coverage_sonar_reporter( ), - a_coverage_type => 'block', - a_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage' ) - ) - ); - end; - -end; -/ diff --git a/test/core/reporters/test_not_existing_block.pks b/test/core/reporters/test_not_existing_block.pks deleted file mode 100644 index 3b734c062..000000000 --- a/test/core/reporters/test_not_existing_block.pks +++ /dev/null @@ -1,18 +0,0 @@ -create or replace package test_not_existing_block is - - --%suite - --%suitepath(utplsql.core.reporters) - - --%beforeall - procedure setup_dummy_coverage; - - --%afterall - procedure cleanup_dummy_coverage; - - - --%test(Coverage is requested for invalid type of coverage) - --%throws(-20215) - procedure invalid_coverage_type; - -end; -/ diff --git a/test/install_tests.sql b/test/install_tests.sql index e14eb0c3b..85b222747 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -28,22 +28,15 @@ whenever oserror exit failure rollback @@core/test_suite_manager.pks @@core/reporters/test_coverage.pks set define on -@@install_below_12_2.sql 'core/reporters/test_not_existing_block.pks' -@@install_below_12_2.sql 'core/reporters/test_not_existing_block.pkb' -set define off -set define on -@@install_above_12_1.sql 'core/reporters/test_block_coverage.pks' -@@install_above_12_1.sql 'core/reporters/test_coverage/test_html_block_reporter.pks' -@@install_above_12_1.sql 'core/reporters/test_coverage/test_coveralls_reporter_block.pks' -@@install_above_12_1.sql 'core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pks' -@@install_above_12_1.sql 'core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pks' @@install_above_12_1.sql 'core/reporters/test_extended_coverage.pks' @@install_above_12_1.sql 'core/reporters/test_coverage/test_html_extended_reporter.pks' set define off @@core/reporters/test_coverage/test_coverage_sonar_reporter.pks @@core/reporters/test_coverage/test_coveralls_reporter.pks @@core/reporters/test_coverage/test_cov_cobertura_reporter.pks -@@core/reporters/test_coverage/test_html_proftab_reporter.pks +set define on +@@install_below_12_2.sql 'core/reporters/test_coverage/test_html_proftab_reporter.pks' +set define off @@core/reporters/test_xunit_reporter.pks @@core/reporters/test_tfs_junit_reporter.pks @@core/expectations.pks @@ -75,18 +68,15 @@ set define off @@core/test_file_mapper.pkb @@core/test_suite_manager.pkb @@core/reporters/test_coverage.pkb +set define on +@@install_above_12_1.sql 'core/reporters/test_extended_coverage.pkb' +@@install_above_12_1.sql 'core/reporters/test_coverage/test_html_extended_reporter.pkb' +set define off @@core/reporters/test_coverage/test_coverage_sonar_reporter.pkb @@core/reporters/test_coverage/test_coveralls_reporter.pkb @@core/reporters/test_coverage/test_cov_cobertura_reporter.pkb -@@core/reporters/test_coverage/test_html_proftab_reporter.pkb set define on -@@install_above_12_1.sql 'core/reporters/test_block_coverage.pkb' -@@install_above_12_1.sql 'core/reporters/test_coverage/test_html_block_reporter.pkb' -@@install_above_12_1.sql 'core/reporters/test_coverage/test_coveralls_reporter_block.pkb' -@@install_above_12_1.sql 'core/reporters/test_coverage/test_coverage_sonar_rprt_blk.pkb' -@@install_above_12_1.sql 'core/reporters/test_coverage/test_cov_cobertura_rptr_blk.pkb' -@@install_above_12_1.sql 'core/reporters/test_extended_coverage.pkb' -@@install_above_12_1.sql 'core/reporters/test_coverage/test_html_extended_reporter.pkb' +@@install_below_12_2.sql 'core/reporters/test_coverage/test_html_proftab_reporter.pks' set define off @@core/reporters/test_xunit_reporter.pkb @@core/reporters/test_tfs_junit_reporter.pkb From 4458dfff327da741cf882fb3d98899d3c6b41de0 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 15 Apr 2018 14:43:42 +0100 Subject: [PATCH 34/37] Unify reporters --- source/install.sql | 4 - .../ut_coverage_report_html_helper.pkb | 243 +++++++++++++++++- .../ut_extended_report_html_helper.pkb | 238 ----------------- .../ut_extended_report_html_helper.pks | 21 -- .../ut_proftab_report_html_helper.pkb | 210 --------------- .../ut_proftab_report_html_helper.pks | 21 -- 6 files changed, 237 insertions(+), 500 deletions(-) delete mode 100644 source/reporters/ut_extended_report_html_helper.pkb delete mode 100644 source/reporters/ut_extended_report_html_helper.pks delete mode 100644 source/reporters/ut_proftab_report_html_helper.pkb delete mode 100644 source/reporters/ut_proftab_report_html_helper.pks diff --git a/source/install.sql b/source/install.sql index 0a4cc3bc8..85411f9d9 100644 --- a/source/install.sql +++ b/source/install.sql @@ -260,11 +260,7 @@ 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_above_12_1.sql 'reporters/ut_extended_report_html_helper.pks' -@@install_component.sql 'reporters/ut_proftab_report_html_helper.pks' -@@install_above_12_1.sql 'reporters/ut_extended_report_html_helper.pkb' @@install_component.sql 'reporters/ut_coverage_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_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb index 5c3174137..132971c34 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -98,19 +98,250 @@ 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) + return clob is + l_source_code ut_varchar2_list; + l_result clob; + + function get_block_file_attributes(a_coverage_unit ut_coverage.t_unit_coverage) return varchar2 is + l_result varchar2(32767); + begin + if (a_coverage_unit.partcovered_lines is not null) OR (a_coverage_unit.partcovered_lines > 0) then + l_result := ' (including '|| a_coverage_unit.partcovered_lines ||' lines partially covered )'; + else + l_result := null; + end if; + return l_result; + end; + + function get_common_file_attributes(a_coverage_unit ut_coverage.t_unit_coverage) return varchar2 is + l_attributes varchar2(32767); + begin + l_attributes := '
      ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) + ||' relevant lines. ' || '' || a_coverage_unit.covered_lines + ||' lines covered' + || get_block_file_attributes(a_coverage_unit) + || ' and ' || a_coverage_unit.uncovered_lines ||' lines missed'; + return l_attributes; + end; + + 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); + l_blocks varchar2(30); + begin + dbms_lob.createtemporary(l_result, true); + + l_coverage_pct := coverage_pct(a_coverage_unit.covered_lines, a_coverage_unit.uncovered_lines); + + l_file_part := '

      ' || + dbms_xmlgen.convert(a_object_full_name) || '

      ' + || l_coverage_pct || ' % lines covered

      ' + ||get_common_file_attributes(a_coverage_unit) ||'
        '; + 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 := ' +
      1. + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
      2. '; + else + l_hits := to_char(a_coverage_unit.lines(line_no).executions); + if nvl(a_coverage_unit.lines(line_no).covered_blocks,0) < nvl(a_coverage_unit.lines(line_no).no_blocks,0) + and nvl(a_coverage_unit.lines(line_no).partcove,0) = 1 then + l_blocks := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| + to_char(a_coverage_unit.lines(line_no).no_blocks); + else + l_blocks := null; + end if; + + l_file_part := ' +
      3. '; + if a_coverage_unit.lines(line_no).executions > 0 then + + l_file_part := l_file_part || + case when l_blocks is not null + then ' + ' ||dbms_xmlgen.convert(l_blocks) || + '' + else + null + end + || ' + ' || dbms_xmlgen.convert(l_hits) || + ''; + end if; + l_file_part := l_file_part || ' + ' || (dbms_xmlgen.convert(a_source_code(line_no))) || + '
      4. '; + end if; + ut_utils.append_to_clob(l_result, l_file_part); + end loop; + + l_file_part := '
      '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + begin + l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); + dbms_lob.createtemporary(l_result, true); + l_result := build_details_file_content(a_object_id + ,a_unit.identity + ,l_source_code + ,a_unit_coverage + ); + return l_result; + end; + + function get_block_list_attributes(a_coverage_unit ut_coverage.t_coverage) return varchar2 is + l_result varchar2(32767); + begin + if (a_coverage_unit.partcovered_lines is not null) OR (a_coverage_unit.partcovered_lines > 0) then + l_result := ' (including '|| a_coverage_unit.partcovered_lines ||' lines partially covered )'; + else + l_result := null; + end if; + return l_result; + end; + + function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is + l_file_part varchar2(32767); + l_title varchar2(100) := 'All files'; + l_coverage_pct number(5, 2); + l_coverage_block_pct number(5, 2); + l_result clob; + l_id varchar2(50) := object_id(a_title); + l_unit_coverage ut_coverage.t_unit_coverage; + l_unit ut_coverage.t_object_name; + begin + l_coverage_pct := coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); + + dbms_lob.createtemporary(l_result, true); + + l_file_part := '
      ' || '

      ' || l_title || + '' || ' (' || + l_coverage_pct || '%' || ' lines covered'|| + ' at ' || + '' || + executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' hits/line)

      ' || '' || '
      ' || + a_coverage.objects.count || ' files in total.
      ' || '' || + (a_coverage.uncovered_lines + a_coverage.covered_lines) + || ' relevant lines. ' || '' || a_coverage.covered_lines || + ' lines covered'|| get_block_list_attributes(a_coverage) + ||' and ' || a_coverage.uncovered_lines || ' lines missed.'|| + '' || '' || + '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.first; + loop + exit when l_unit is null; + l_unit_coverage := a_coverage.objects(l_unit); + l_coverage_pct := coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); + + l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || + ''; + ut_utils.append_to_clob(l_result, l_file_part); + l_unit := a_coverage.objects.next(l_unit); + end loop; + l_file_part := '
      File% coveredLinesRelevant LinesLines coveredLines missed' + ||'Avg. Hits / Line
      ' || link_to_source_file(dbms_xmlgen.convert(l_unit)) || + '' || l_coverage_pct || + ' %' || l_unit_coverage.total_lines || '' || + (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || + l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' || to_char(executions_per_line(l_unit_coverage.executions + ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) + || '
      '; + ut_utils.append_to_clob(l_result, l_file_part); + return l_result; + end; + /* * public definitions */ 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 is + + l_file_part varchar2(32767); l_result clob; -begin - $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then - l_result := ut_extended_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); - $else - l_result := ut_proftab_report_html_helper.get_index(a_coverage_data => a_coverage_data, a_assets_path => a_assets_path,a_project_name=>a_project_name,a_command_line=> a_command_line); - $end + l_title varchar2(250); + l_coverage_pct number(5, 2); + l_time_str varchar2(50); + l_using varchar2(1000); + l_unit ut_coverage.t_full_name; + begin + l_coverage_pct := coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); + l_time_str := ut_utils.to_string(sysdate); + l_using := case + when a_command_line is not null then + '
      using ' || dbms_xmlgen.convert(a_command_line) + end; + dbms_lob.createtemporary(l_result, true); + + l_title := case + when a_project_name is null then + 'Code coverage' + else + dbms_xmlgen.convert(a_project_name) || ' code coverage' + end; + --TODO - build main file containing total run data and per schema data + l_file_part := '' || '' || l_title || + '' || '' || + '' || + '' || + '' || '' || '' || + '
      loading
      ' || + ''; + + ut_utils.append_to_clob(l_result, l_file_part); return l_result; end; diff --git a/source/reporters/ut_extended_report_html_helper.pkb b/source/reporters/ut_extended_report_html_helper.pkb deleted file mode 100644 index c83f71c3b..000000000 --- a/source/reporters/ut_extended_report_html_helper.pkb +++ /dev/null @@ -1,238 +0,0 @@ -create or replace package body ut_extended_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); - l_blocks 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 := '

      ' || - dbms_xmlgen.convert(a_object_full_name) || '

      ' || '

      ' || l_coverage_pct || ' % lines covered

      ' || - '
      ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered '|| - '(including ' || a_coverage_unit.partcovered_lines || - ' lines partially covered ' - || ') and ' || a_coverage_unit.uncovered_lines || - ' lines missed'||'
        '; - 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 := ' -
      1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
      2. '; - else - l_hits := to_char(a_coverage_unit.lines(line_no).executions); - if nvl(a_coverage_unit.lines(line_no).covered_blocks,0) < nvl(a_coverage_unit.lines(line_no).no_blocks,0) - and nvl(a_coverage_unit.lines(line_no).partcove,0) = 1 then - l_blocks := to_char(a_coverage_unit.lines(line_no).covered_blocks) || chr(47)|| - to_char(a_coverage_unit.lines(line_no).no_blocks); - else - l_blocks := null; - end if; - - l_file_part := ' -
      3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || - case when l_blocks is not null - then ' - ' ||dbms_xmlgen.convert(l_blocks) || - '' - else - null - end - || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
      4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
      '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
      ' || '

      ' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - ' at ' || - '' || - ut_coverage_report_html_helper.executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' hits/line)

      ' || '' || '
      ' || - a_coverage.objects.count || ' files in total.
      ' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered'|| - ' (inlcluding ' || a_coverage.partcovered_lines || - ' lines partially covered' || ') and ' || a_coverage.uncovered_lines || ' lines missed.'|| - '' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
      File% coveredLinesRelevant LinesLines coveredLines missed' - ||'Avg. Hits / Line
      ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || - (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || - l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' || to_char(ut_coverage_report_html_helper.executions_per_line(l_unit_coverage.executions - ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) - || '
      '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - - /* - * public definitions - */ - 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 is - - l_file_part varchar2(32767); - l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); - - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
      using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || '' || l_title || - '' || '' || - '' || - '' || - '' || '' || '' || - '
      loading
      ' || - ''; - - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - -end; -/ diff --git a/source/reporters/ut_extended_report_html_helper.pks b/source/reporters/ut_extended_report_html_helper.pks deleted file mode 100644 index dc6076f1d..000000000 --- a/source/reporters/ut_extended_report_html_helper.pks +++ /dev/null @@ -1,21 +0,0 @@ -create or replace package ut_extended_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_proftab_report_html_helper.pkb b/source/reporters/ut_proftab_report_html_helper.pkb deleted file mode 100644 index 5e6156d22..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 := '

      ' || - dbms_xmlgen.convert(a_object_full_name) || '

      ' || '

      ' || l_coverage_pct || ' % lines covered

      ' || - '
      ' ||(a_coverage_unit.covered_lines + a_coverage_unit.uncovered_lines) - || ' relevant lines. ' || '' || a_coverage_unit.covered_lines || - ' lines covered ' || ' and ' || a_coverage_unit.uncovered_lines || - ' lines missed'||'
        '; - 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 := ' -
      1. - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
      2. '; - else - l_hits := to_char(a_coverage_unit.lines(line_no).executions); - - l_file_part := ' -
      3. '; - if a_coverage_unit.lines(line_no).executions > 0 then - - l_file_part := l_file_part || ' - ' || dbms_xmlgen.convert(l_hits) || - ''; - end if; - l_file_part := l_file_part || ' - ' || (dbms_xmlgen.convert(a_source_code(line_no))) || - '
      4. '; - end if; - ut_utils.append_to_clob(l_result, l_file_part); - end loop; - - l_file_part := '
      '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - begin - l_source_code := ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name); - dbms_lob.createtemporary(l_result, true); - l_result := build_details_file_content(a_object_id - ,a_unit.identity - ,l_source_code - ,a_unit_coverage - ); - return l_result; - end; - - function file_list(a_title varchar2, a_coverage ut_coverage.t_coverage) return clob is - l_file_part varchar2(32767); - l_title varchar2(100) := 'All files'; - l_coverage_pct number(5, 2); - l_coverage_block_pct number(5, 2); - l_result clob; - l_id varchar2(50) := ut_coverage_report_html_helper.object_id(a_title); - l_unit_coverage ut_coverage.t_unit_coverage; - l_unit ut_coverage.t_object_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage.covered_lines, a_coverage.uncovered_lines); - - dbms_lob.createtemporary(l_result, true); - - l_file_part := '
      ' || '

      ' || l_title || - '' || ' (' || - l_coverage_pct || '%' || ' lines covered'|| - ' at ' || - '' || - ut_coverage_report_html_helper.executions_per_line(a_coverage.executions, a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' hits/line)

      ' || '' || '
      ' || - a_coverage.objects.count || ' files in total.
      ' || '' || - (a_coverage.uncovered_lines + a_coverage.covered_lines) - || ' relevant lines. ' || '' || a_coverage.covered_lines || - ' lines covered'|| ' and ' || a_coverage.uncovered_lines || ' lines missed.'|| - '' || '' || - '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.first; - loop - exit when l_unit is null; - l_unit_coverage := a_coverage.objects(l_unit); - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(l_unit_coverage.covered_lines, l_unit_coverage.uncovered_lines); - - l_file_part := chr(10) || '' || '' || '' || '' || '' || '' || - ''; - ut_utils.append_to_clob(l_result, l_file_part); - l_unit := a_coverage.objects.next(l_unit); - end loop; - l_file_part := '
      File% coveredLinesRelevant LinesLines coveredLines missed' - ||'Avg. Hits / Line
      ' || ut_coverage_report_html_helper.link_to_source_file(dbms_xmlgen.convert(l_unit)) || - '' || l_coverage_pct || - ' %' || l_unit_coverage.total_lines || '' || - (l_unit_coverage.covered_lines + l_unit_coverage.uncovered_lines) || '' || - l_unit_coverage.covered_lines || '' || l_unit_coverage.uncovered_lines || '' || to_char(ut_coverage_report_html_helper.executions_per_line(l_unit_coverage.executions - ,l_unit_coverage.uncovered_lines + l_unit_coverage.covered_lines)) - || '
      '; - ut_utils.append_to_clob(l_result, l_file_part); - return l_result; - end; - - /* - * public definitions - */ - 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 is - - l_file_part varchar2(32767); - l_result clob; - l_title varchar2(250); - l_coverage_pct number(5, 2); - l_time_str varchar2(50); - l_using varchar2(1000); - l_unit ut_coverage.t_full_name; - begin - l_coverage_pct := ut_coverage_report_html_helper.coverage_pct(a_coverage_data.covered_lines, a_coverage_data.uncovered_lines); - - l_time_str := ut_utils.to_string(sysdate); - l_using := case - when a_command_line is not null then - '
      using ' || dbms_xmlgen.convert(a_command_line) - end; - dbms_lob.createtemporary(l_result, true); - - l_title := case - when a_project_name is null then - 'Code coverage' - else - dbms_xmlgen.convert(a_project_name) || ' code coverage' - end; - --TODO - build main file containing total run data and per schema data - l_file_part := '' || '' || l_title || - '' || '' || - '' || - '' || - '' || '' || '' || - '
      loading
      ' || - ''; - - 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; -/ From 20274211fc96e9afbeecbb9e0871b3456803cc1b Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 15 Apr 2018 15:46:33 +0100 Subject: [PATCH 35/37] Update test --- test/install_tests.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/install_tests.sql b/test/install_tests.sql index 85b222747..73ae288ff 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -76,7 +76,7 @@ set define off @@core/reporters/test_coverage/test_coveralls_reporter.pkb @@core/reporters/test_coverage/test_cov_cobertura_reporter.pkb set define on -@@install_below_12_2.sql 'core/reporters/test_coverage/test_html_proftab_reporter.pks' +@@install_below_12_2.sql 'core/reporters/test_coverage/test_html_proftab_reporter.pkb' set define off @@core/reporters/test_xunit_reporter.pkb @@core/reporters/test_tfs_junit_reporter.pkb From 924eb9bba70ab65c6bc91e2f7f443af3312dd9ec Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 15 Apr 2018 17:39:23 +0100 Subject: [PATCH 36/37] Update issue with part covered being zero. --- source/reporters/ut_coverage_report_html_helper.pkb | 4 ++-- .../reporters/test_coverage/test_html_proftab_reporter.pkb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb index 132971c34..4ea8c6eb1 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -109,7 +109,7 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a function get_block_file_attributes(a_coverage_unit ut_coverage.t_unit_coverage) return varchar2 is l_result varchar2(32767); begin - if (a_coverage_unit.partcovered_lines is not null) OR (a_coverage_unit.partcovered_lines > 0) then + if (a_coverage_unit.partcovered_lines is not null) AND (a_coverage_unit.partcovered_lines > 0) then l_result := ' (including '|| a_coverage_unit.partcovered_lines ||' lines partially covered )'; else l_result := null; @@ -212,7 +212,7 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a function get_block_list_attributes(a_coverage_unit ut_coverage.t_coverage) return varchar2 is l_result varchar2(32767); begin - if (a_coverage_unit.partcovered_lines is not null) OR (a_coverage_unit.partcovered_lines > 0) then + if (a_coverage_unit.partcovered_lines is not null) AND (a_coverage_unit.partcovered_lines > 0) then l_result := ' (including '|| a_coverage_unit.partcovered_lines ||' lines partially covered )'; else l_result := null; diff --git a/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb b/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb index 80e6a9ded..7167dc6f6 100644 --- a/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb +++ b/test/core/reporters/test_coverage/test_html_proftab_reporter.pkb @@ -6,7 +6,7 @@ create or replace package body test_html_proftab_reporter is l_actual clob; begin --Arrange - l_expected := '%

      UT3.DUMMY_COVERAGE

      %3 relevant lines. 2 lines covered and 1 lines missed%'; + l_expected := '%

      UT3.DUMMY_COVERAGE

      %3 relevant lines. 2 lines covered and 1 lines missed%'; --l_expected := '%

      UT3.DUMMY_COVERAGE

      66% lines covered

      3 relevant lines. 2 lines covered ) and 1 lines missed
      %'; --Act From a111c6d7ca75f3138639994d6581fbab6a962033 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 15 Apr 2018 18:31:49 +0100 Subject: [PATCH 37/37] Update for test with timestamp --- test/core/reporters/test_tfs_junit_reporter.pkb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/reporters/test_tfs_junit_reporter.pkb b/test/core/reporters/test_tfs_junit_reporter.pkb index f7ea923ff..267ba6ab0 100644 --- a/test/core/reporters/test_tfs_junit_reporter.pkb +++ b/test/core/reporters/test_tfs_junit_reporter.pkb @@ -141,7 +141,7 @@ create or replace package body test_tfs_junit_reporter as from table(ut3.ut.run('check_junit_reporting', ut3.ut_tfs_junit_reporter())); l_actual := ut3.ut_utils.table_to_clob(l_results); --Assert - ut.expect(l_actual).to_match('time="[0-9]*\.[0-9]{6}"'); + ut.expect(l_actual).to_match('time="[0-9]*\.[0-9]{3,6}"'); --Cleanup execute immediate 'alter session set NLS_NUMERIC_CHARACTERS='''||l_nls_numeric_characters||''''; end;