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

Skip to content

Commit 8fc2ea6

Browse files
committed
Further optimizations to suite parsing.
Changed functions to procedures to avoid copying of large memmory segments.
1 parent 248bf8c commit 8fc2ea6

5 files changed

Lines changed: 136 additions & 85 deletions

File tree

source/api/ut_runner.pkb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ create or replace package body ut_runner is
128128
l_include_object_names := to_ut_object_list(a_include_objects, l_coverage_schema_names);
129129

130130
l_run := ut_run(
131-
ut_suite_manager.configure_execution_by_path(l_paths),
131+
null,
132132
l_paths,
133133
l_coverage_schema_names,
134134
l_exclude_object_names,
@@ -137,6 +137,7 @@ create or replace package body ut_runner is
137137
set(a_test_file_mappings),
138138
a_client_character_set
139139
);
140+
ut_suite_manager.configure_execution_by_path(l_paths, l_run.items);
140141
l_run.do_execute();
141142

142143
finish_run(l_run);

source/core/annotations/ut_annotation_parser.pkb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ create or replace package body ut_annotation_parser as
155155
-- position index is shifted by 1 because gc_annot_comment_pattern contains ^ as first sign
156156
-- but after instr index already points to the char on that line
157157
l_comment_pos := l_comment_pos-1;
158-
l_comment_line := regexp_count(substr(a_source,1,l_comment_pos),chr(10),1,'m')+1;
158+
l_comment_line := length(substr(a_source,1,l_comment_pos))-length(replace(substr(a_source,1,l_comment_pos),chr(10)))+1;
159159
l_comments(l_comment_line) := trim(regexp_substr(srcstr => a_source
160160
,pattern => gc_annot_comment_pattern
161161
,occurrence => 1

source/core/ut_suite_cache_manager.pkb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,11 @@ create or replace package body ut_suite_cache_manager is
138138
procedure remove_from_cache(a_schema_name varchar2, a_objects ut_varchar2_rows) is
139139
pragma autonomous_transaction;
140140
begin
141-
delete
142-
from ut_suite_cache_package i
141+
delete from ut_suite_cache i
142+
where i.object_owner = a_schema_name
143+
and i.object_name in ( select column_value from table (a_objects) );
144+
145+
delete from ut_suite_cache_package i
143146
where i.object_owner = a_schema_name
144147
and i.object_name in ( select column_value from table (a_objects) );
145148

source/core/ut_suite_manager.pkb

Lines changed: 119 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ create or replace package body ut_suite_manager is
2929
type tt_cached_suites is table of t_cached_suite;
3030
type t_cached_suites_cursor is ref cursor return t_cached_suite;
3131

32+
type t_item_levels is table of ut_suite_items index by binary_integer;
3233
------------------
3334

3435
procedure validate_paths(a_paths in ut_varchar2_list) is
@@ -167,48 +168,30 @@ create or replace package body ut_suite_manager is
167168
end loop;
168169
end;
169170

170-
procedure reconstruct_from_cache(
171-
a_suites out nocopy ut_suite_items,
172-
a_suite_data_cursor sys_refcursor
173-
) is
174-
type t_item_levels is table of ut_suite_items index by binary_integer;
175-
c_bulk_limit constant pls_integer := 1000;
176-
l_items_at_level t_item_levels;
177-
l_rows tt_cached_suites;
178-
l_test ut_test;
179-
l_logical_suite ut_logical_suite;
180-
l_level pls_integer;
181-
l_prev_level pls_integer;
182-
l_idx integer;
171+
function get_logical_suite(
172+
l_rows tt_cached_suites,
173+
l_idx pls_integer,
174+
l_level pls_integer,
175+
l_prev_level pls_integer,
176+
l_items_at_level t_item_levels
177+
) return ut_logical_suite is
183178
begin
184-
a_suites := ut_suite_items();
185-
loop
186-
fetch a_suite_data_cursor bulk collect into l_rows limit c_bulk_limit;
187-
exit when l_rows.count = 0;
188-
189-
l_idx := l_rows.first;
190-
loop
191-
l_test := null;
192-
l_logical_suite := null;
193-
case l_rows(l_idx).self_type
194-
when 'UT_TEST' then
195-
l_test :=
196-
ut_test(
179+
return
180+
case l_rows(l_idx).self_type
181+
when 'UT_SUITE' then
182+
case when l_prev_level > l_level then
183+
ut_suite(
197184
self_type => l_rows(l_idx).self_type,
198185
object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name),
199186
name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path,
200187
rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag,
201188
line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time,
202189
start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings,
203190
results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(),
204-
before_each_list => sort_by_seq_no(l_rows(l_idx).before_each_list), before_test_list => sort_by_seq_no(l_rows(l_idx).before_test_list),
205-
item => l_rows(l_idx).item,
206-
after_test_list => sort_by_seq_no(l_rows(l_idx).after_test_list), after_each_list => sort_by_seq_no(l_rows(l_idx).after_each_list),
207-
all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(),
208-
parent_error_stack_trace => null, expected_error_codes => l_rows(l_idx).expected_error_codes
209-
);
210-
when 'UT_SUITE' then
211-
l_logical_suite :=
191+
items => l_items_at_level(l_prev_level),
192+
before_all_list => sort_by_seq_no(l_rows(l_idx).before_all_list), after_all_list => sort_by_seq_no(l_rows(l_idx).after_all_list)
193+
)
194+
else
212195
ut_suite(
213196
self_type => l_rows(l_idx).self_type,
214197
object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name),
@@ -219,9 +202,22 @@ create or replace package body ut_suite_manager is
219202
results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(),
220203
items => ut_suite_items(),
221204
before_all_list => sort_by_seq_no(l_rows(l_idx).before_all_list), after_all_list => sort_by_seq_no(l_rows(l_idx).after_all_list)
222-
);
223-
when 'UT_SUITE_CONTEXT' then
224-
l_logical_suite :=
205+
)
206+
end
207+
when 'UT_SUITE_CONTEXT' then
208+
case when l_prev_level > l_level then
209+
ut_suite_context(
210+
self_type => l_rows(l_idx).self_type,
211+
object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name),
212+
name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path,
213+
rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag,
214+
line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time,
215+
start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings,
216+
results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(),
217+
items => l_items_at_level(l_prev_level),
218+
before_all_list => sort_by_seq_no(l_rows(l_idx).before_all_list), after_all_list => sort_by_seq_no(l_rows(l_idx).after_all_list)
219+
)
220+
else
225221
ut_suite_context(
226222
self_type => l_rows(l_idx).self_type,
227223
object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name),
@@ -232,9 +228,21 @@ create or replace package body ut_suite_manager is
232228
results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(),
233229
items => ut_suite_items(),
234230
before_all_list => sort_by_seq_no(l_rows(l_idx).before_all_list), after_all_list => sort_by_seq_no(l_rows(l_idx).after_all_list)
235-
);
236-
when 'UT_LOGICAL_SUITE' then
237-
l_logical_suite :=
231+
)
232+
end
233+
when 'UT_LOGICAL_SUITE' then
234+
case when l_prev_level > l_level then
235+
ut_logical_suite(
236+
self_type => l_rows(l_idx).self_type,
237+
object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name),
238+
name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path,
239+
rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag,
240+
line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time,
241+
start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings,
242+
results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(),
243+
items => l_items_at_level(l_prev_level)
244+
)
245+
else
238246
ut_logical_suite(
239247
self_type => l_rows(l_idx).self_type,
240248
object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name),
@@ -244,32 +252,62 @@ create or replace package body ut_suite_manager is
244252
start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings,
245253
results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(),
246254
items => ut_suite_items()
247-
);
248-
end case;
255+
)
256+
end
257+
end;
258+
end;
259+
260+
procedure reconstruct_from_cache(
261+
a_suites in out nocopy ut_suite_items,
262+
a_suite_data_cursor sys_refcursor
263+
) is
264+
c_bulk_limit constant pls_integer := 1000;
265+
l_items_at_level t_item_levels;
266+
l_rows tt_cached_suites;
267+
l_logical_suite ut_logical_suite;
268+
l_level pls_integer;
269+
l_prev_level pls_integer;
270+
l_idx integer;
271+
begin
272+
loop
273+
fetch a_suite_data_cursor bulk collect into l_rows limit c_bulk_limit;
274+
exit when l_rows.count = 0;
249275

276+
l_idx := l_rows.first;
277+
loop
250278
l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1;
251-
252279
if l_level > 1 then
253-
if l_prev_level > l_level then
254-
l_logical_suite.items := l_items_at_level(l_prev_level);
255-
l_items_at_level(l_prev_level).delete;
256-
end if;
257280
if not l_items_at_level.exists(l_level) then
258281
l_items_at_level(l_level) := ut_suite_items();
259282
end if;
260283
l_items_at_level(l_level).extend;
261-
if l_test is not null then
262-
l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_test;
284+
if l_rows(l_idx).self_type = 'UT_TEST' then
285+
l_items_at_level(l_level)(l_items_at_level(l_level).last) :=
286+
ut_test(
287+
self_type => l_rows(l_idx).self_type,
288+
object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name),
289+
name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path,
290+
rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag,
291+
line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time,
292+
start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings,
293+
results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(),
294+
before_each_list => sort_by_seq_no(l_rows(l_idx).before_each_list), before_test_list => sort_by_seq_no(l_rows(l_idx).before_test_list),
295+
item => l_rows(l_idx).item,
296+
after_test_list => sort_by_seq_no(l_rows(l_idx).after_test_list), after_each_list => sort_by_seq_no(l_rows(l_idx).after_each_list),
297+
all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(),
298+
parent_error_stack_trace => null, expected_error_codes => l_rows(l_idx).expected_error_codes
299+
);
263300
else
264-
l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_logical_suite;
265-
end if;
301+
pragma inline(get_logical_suite, 'YES');
302+
l_items_at_level(l_level)(l_items_at_level(l_level).last) := get_logical_suite(l_rows, l_idx, l_level,l_prev_level, l_items_at_level );
303+
end if;
266304
else
267-
if l_prev_level > l_level then
268-
l_logical_suite.items := l_items_at_level(l_prev_level);
269-
l_items_at_level(l_prev_level).delete;
270-
end if;
271305
a_suites.extend;
272-
a_suites(a_suites.last) := l_logical_suite;
306+
pragma inline(get_logical_suite, 'YES');
307+
a_suites(a_suites.last) := get_logical_suite(l_rows, l_idx, l_level,l_prev_level, l_items_at_level );
308+
end if;
309+
if l_prev_level > l_level then
310+
l_items_at_level(l_prev_level).delete;
273311
end if;
274312
l_prev_level := l_level;
275313
l_idx := l_rows.next(l_idx);
@@ -483,18 +521,18 @@ create or replace package body ut_suite_manager is
483521

484522
end;
485523

486-
function get_suites_for_path(
524+
procedure add_suites_for_path(
487525
a_owner_name varchar2,
488526
a_path varchar2 := null,
489527
a_object_name varchar2 := null,
490-
a_procedure_name varchar2 := null
491-
) return ut_suite_items is
492-
l_suites ut_suite_items;
528+
a_procedure_name varchar2 := null,
529+
a_suites in out nocopy ut_suite_items
530+
) is
493531
begin
494532
refresh_cache(a_owner_name);
495533

496534
reconstruct_from_cache(
497-
l_suites,
535+
a_suites,
498536
get_cached_suite_data(
499537
a_owner_name,
500538
a_path,
@@ -503,9 +541,8 @@ create or replace package body ut_suite_manager is
503541
can_skip_all_objects_scan(a_owner_name)
504542
)
505543
);
506-
return l_suites;
507544

508-
end get_suites_for_path;
545+
end;
509546

510547
-----------------------------------------------
511548
-----------------------------------------------
@@ -519,7 +556,7 @@ create or replace package body ut_suite_manager is
519556
a_procedure_name varchar2 := null,
520557
a_skip_all_objects boolean := false
521558
) return ut_suite_items is
522-
l_suites ut_suite_items;
559+
l_suites ut_suite_items := ut_suite_items();
523560
begin
524561
build_and_cache_suites(a_owner_name, a_annotated_objects);
525562

@@ -578,58 +615,59 @@ create or replace package body ut_suite_manager is
578615
end;
579616

580617
function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items is
618+
l_suites ut_suite_items := ut_suite_items();
619+
begin
620+
configure_execution_by_path(a_paths, l_suites );
621+
return l_suites;
622+
end;
623+
624+
procedure configure_execution_by_path(a_paths in ut_varchar2_list, a_suites out nocopy ut_suite_items) is
581625
l_paths ut_varchar2_list := a_paths;
582626
l_path_items t_path_items;
583627
l_path_item t_path_item;
584628
l_schema varchar2(4000);
585-
l_suites ut_suite_items;
629+
l_suites_count pls_integer := 0;
586630
l_index varchar2(4000 char);
587-
l_objects_to_run ut_suite_items;
588631
l_schema_paths t_schema_paths;
589632
begin
633+
a_suites := ut_suite_items();
590634
--resolve schema names from paths and group paths by schema name
591635
resolve_schema_names(l_paths);
592636

593637
l_schema_paths := group_paths_by_schema(l_paths);
594638

595-
l_objects_to_run := ut_suite_items();
596-
597639
l_schema := l_schema_paths.first;
598640
while l_schema is not null loop
599641
l_path_items := l_schema_paths(l_schema);
600642
for i in 1 .. l_path_items.count loop
601643
l_path_item := l_path_items(i);
602-
l_suites := get_suites_for_path(
644+
add_suites_for_path(
603645
upper(l_schema),
604646
l_path_item.suite_path,
605647
l_path_item.object_name,
606-
l_path_item.procedure_name
648+
l_path_item.procedure_name,
649+
a_suites
607650
);
608-
if l_suites.count = 0 then
651+
if a_suites.count = l_suites_count then
609652
if l_path_item.suite_path is not null then
610653
raise_application_error(ut_utils.gc_suite_package_not_found,'No suite packages found for path '||l_schema||':'||l_path_item.suite_path|| '.');
611654
elsif l_path_item.procedure_name is not null then
612655
raise_application_error(ut_utils.gc_suite_package_not_found,'Suite test '||l_schema||'.'||l_path_item.object_name|| '.'||l_path_item.procedure_name||' does not exist');
613-
else
656+
elsif l_path_item.object_name is not null then
614657
raise_application_error(ut_utils.gc_suite_package_not_found,'Suite package '||l_schema||'.'||l_path_item.object_name|| ' does not exist');
615658
end if;
616659
end if;
617-
l_index := l_suites.first;
618-
while l_index is not null loop
619-
l_objects_to_run.extend;
620-
l_objects_to_run(l_objects_to_run.count) := l_suites(l_index);
621-
l_index := l_suites.next(l_index);
622-
end loop;
660+
l_index := a_suites.first;
661+
l_suites_count := a_suites.count;
623662
end loop;
624663
l_schema := l_schema_paths.next(l_schema);
625664
end loop;
626665

627666
--propagate rollback type to suite items after organizing suites into hierarchy
628-
for i in 1 .. l_objects_to_run.count loop
629-
l_objects_to_run(i).set_rollback_type( l_objects_to_run(i).get_rollback_type() );
667+
for i in 1 .. a_suites.count loop
668+
a_suites(i).set_rollback_type( a_suites(i).get_rollback_type() );
630669
end loop;
631670

632-
return l_objects_to_run;
633671
end configure_execution_by_path;
634672

635673
function get_suites_info(a_owner_name varchar2) return tt_suite_items pipelined is

source/core/ut_suite_manager.pks

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

42+
/**
43+
* Builds a hierarchical suites based on given suite-paths
44+
*
45+
* @param a_paths list of suite-paths or procedure names or package names or schema names
46+
* @param a_suites returned array containing root suites-ready to be executed
47+
*
48+
*/
49+
procedure configure_execution_by_path(a_paths in ut_varchar2_list, a_suites out nocopy ut_suite_items);
50+
4251
/**
4352
* Cleanup paths by removing leading/trailing whitespace and making paths lowercase
4453
* Get list of schema names from execution paths.

0 commit comments

Comments
 (0)