From 922630f70f0be3946eb7081465e2d1b9adc21aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20G=C4=99bal?= Date: Sun, 22 Jul 2018 11:02:34 +0100 Subject: [PATCH 001/115] Update VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d95827c3d..66cfae52b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.1.2 +v3.1.3 From d4ff93db37cbae60f7cba0e53437e51c78142918 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sun, 22 Jul 2018 10:26:57 +0000 Subject: [PATCH 002/115] Updated project version after build [skip ci] --- VERSION | 2 +- sonar-project.properties | 2 +- source/core/ut_utils.pks | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 66cfae52b..ed4f9d9f8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.1.3 +v3.1.3-develop diff --git a/sonar-project.properties b/sonar-project.properties index a2139b3fe..a1fabbede 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,7 +2,7 @@ sonar.projectKey=utPLSQL # this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1. sonar.projectName=utPLSQL -sonar.projectVersion=v3.1.2 +sonar.projectVersion=v3.1.3-develop # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. # Since SonarQube 4.2, this property is optional if sonar.modules is set. diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 847c57fd8..c76f21384 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.2.2130'; + gc_version constant varchar2(50) := 'v3.1.3.2137-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From d568b1f6e127224cf3d50e30ffcffb2b6b8666ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20G=C4=99bal?= Date: Mon, 23 Jul 2018 16:16:28 +0100 Subject: [PATCH 003/115] Update annotations.md --- docs/userguide/annotations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/userguide/annotations.md b/docs/userguide/annotations.md index 3b8f0a9dd..54b5fae8c 100644 --- a/docs/userguide/annotations.md +++ b/docs/userguide/annotations.md @@ -1089,7 +1089,7 @@ create or replace package test_rooms_management is --%context(remove_rooms_by_name) - --%description(Remove rooms by name) + --%displayname(Remove rooms by name) --%test(Removes a room without content in it) procedure remove_empty_room; @@ -1102,7 +1102,7 @@ create or replace package test_rooms_management is --%context(add_rooms_content) - --%description(Add content to a room) + --%displayname(Add content to a room) --%test(Fails when room name is not valid) --%throws(no_data_found) From 56abea00a1923d4fb9715e6f1f26fe08367e379b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20G=C4=99bal?= Date: Mon, 23 Jul 2018 16:27:55 +0100 Subject: [PATCH 004/115] Update annotations.md Fixing description of the `displayname` annotation. --- docs/userguide/annotations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/userguide/annotations.md b/docs/userguide/annotations.md index 54b5fae8c..d9c731b34 100644 --- a/docs/userguide/annotations.md +++ b/docs/userguide/annotations.md @@ -19,7 +19,7 @@ We strongly recommend putting package level annotations at the very top of packa | --- | --- | --- | | `--%suite()` | Package | Mandatory. Marks package as a test suite. Optional suite description can be provided (see `displayname`). | | `--%suitepath()` | Package | Similar to java package. The annotation allows logical grouping of suites into hierarchies. | -| `--%displayname()` | Package/procedure | Human-readable and meaningful description of a suite/test. `%displayname(Name of the suite/test)`. The annotation is provided for flexibility and convenience only. It has exactly the same meaning as `` in `test` and `suite` annotations. If description is provided using both `suite`/`test` and `displayname`, then the one defined as last takes precedence. | +| `--%displayname()` | Package/procedure | Human-readable and meaningful description of a context/suite/test. Provides description to a `context` when used within `context`. When used with `test` or `suite` annotation, overrides the `` provided with `suite`/`test`. | | `--%test()` | Procedure | Denotes that the annotated procedure is a unit test procedure. Optional test description can by provided (see `displayname`). | | `--%throws([,...])`| Procedure | Denotes that the annotated test procedure must throw one of the exceptions provided. Supported forms of exceptions are: numeric literals, numeric contant names, exception constant names, predefined Oracle exception names. | | `--%beforeall` | Procedure | Denotes that the annotated procedure should be executed once before all elements of the suite. | From 392a949516ffcd4c69cfd4577dacac76272cc6eb Mon Sep 17 00:00:00 2001 From: Travis CI Date: Mon, 23 Jul 2018 16:08:43 +0000 Subject: [PATCH 005/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index c76f21384..857013723 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2137-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2140-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 89a2839cc30cee6cab51b309fa6a42084640aa94 Mon Sep 17 00:00:00 2001 From: Pazus Date: Tue, 24 Jul 2018 09:28:09 +0300 Subject: [PATCH 006/115] Introduced tests on Oracle database 18c --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 5da14e7a9..e152e13ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,6 +52,7 @@ env: - ORACLE_VERSION="${DOCKER_TAG_11G:-11g-r2-xe}" CONNECTION_STR='127.0.0.1:1521/XE' DOCKER_OPTIONS='--shm-size=1g' - ORACLE_VERSION="${DOCKER_TAG_12C:-12c-r1-se2}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" - ORACLE_VERSION="${DOCKER_TAG_12C2:-12c-r2-se2}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" + - ORACLE_VERSION="${DOCKER_TAG_18:-18c-se2}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" cache: pip: true From 7e78473f15e106ff3638b694c97fe85835f68df8 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 24 Jul 2018 22:42:24 +0100 Subject: [PATCH 007/115] Disabling tests that cant execute on 18c. --- test/api/test_ut_run.pks | 9 +++++++++ test/core/test_ut_executable.pks | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/test/api/test_ut_run.pks b/test/api/test_ut_run.pks index cd4a78ff3..eb03ac4b6 100644 --- a/test/api/test_ut_run.pks +++ b/test/api/test_ut_run.pks @@ -79,10 +79,19 @@ create or replace package test_ut_run is --%test(Executes successfully an empty suite) procedure run_func_empty_suite; + $if dbms_db_version.version > 12 $then + --%disabled --%test(ut.run - raises after completing all tests if a test fails with ORA-04068 or ORA-04061) --%beforetest(create_test_suite) --%aftertest(drop_test_suite) procedure raise_in_invalid_state; + $else + --%test(ut.run - raises after completing all tests if a test fails with ORA-04068 or ORA-04061) + --%beforetest(create_test_suite) + --%aftertest(drop_test_suite) + procedure raise_in_invalid_state; + $end + procedure create_test_suite; procedure drop_test_suite; diff --git a/test/core/test_ut_executable.pks b/test/core/test_ut_executable.pks index 51641ecbf..bb28debc7 100644 --- a/test/core/test_ut_executable.pks +++ b/test/core/test_ut_executable.pks @@ -14,10 +14,18 @@ create or replace package test_ut_executable is --%test(Executes a procedure raising exception, saves dbms_output and exception stack trace) procedure exec_failing_proc; + $if dbms_db_version.version > 12 $then + --%disabled --%test(Sets state invalid flag when package-state invalidated and saves exception stack trace) --%beforetest(create_state_dependant_pkg) --%aftertest(drop_state_dependant_pkg) procedure exec_invalid_state_proc; + $else + --%test(Sets state invalid flag when package-state invalidated and saves exception stack trace) + --%beforetest(create_state_dependant_pkg) + --%aftertest(drop_state_dependant_pkg) + procedure exec_invalid_state_proc; + $end procedure create_state_dependant_pkg; procedure drop_state_dependant_pkg; From 952c9a820f88faf99534f8739d079a9cb5491187 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Wed, 25 Jul 2018 01:14:21 +0100 Subject: [PATCH 008/115] Permanently disabling tests that cant execute on 18c. --- test/api/test_ut_run.pks | 10 +--------- test/core/test_ut_executable.pks | 10 +--------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/test/api/test_ut_run.pks b/test/api/test_ut_run.pks index eb03ac4b6..dcbb71c58 100644 --- a/test/api/test_ut_run.pks +++ b/test/api/test_ut_run.pks @@ -79,19 +79,11 @@ create or replace package test_ut_run is --%test(Executes successfully an empty suite) procedure run_func_empty_suite; - $if dbms_db_version.version > 12 $then - --%disabled + --%disabled(Makes session wait for lock on 18.1 due to library cache pin wait) --%test(ut.run - raises after completing all tests if a test fails with ORA-04068 or ORA-04061) --%beforetest(create_test_suite) --%aftertest(drop_test_suite) procedure raise_in_invalid_state; - $else - --%test(ut.run - raises after completing all tests if a test fails with ORA-04068 or ORA-04061) - --%beforetest(create_test_suite) - --%aftertest(drop_test_suite) - procedure raise_in_invalid_state; - $end - procedure create_test_suite; procedure drop_test_suite; diff --git a/test/core/test_ut_executable.pks b/test/core/test_ut_executable.pks index bb28debc7..7c1f8d297 100644 --- a/test/core/test_ut_executable.pks +++ b/test/core/test_ut_executable.pks @@ -14,19 +14,11 @@ create or replace package test_ut_executable is --%test(Executes a procedure raising exception, saves dbms_output and exception stack trace) procedure exec_failing_proc; - $if dbms_db_version.version > 12 $then - --%disabled + --%disabled(Makes session wait for lock on 18.1 due to library cache pin wait) --%test(Sets state invalid flag when package-state invalidated and saves exception stack trace) --%beforetest(create_state_dependant_pkg) --%aftertest(drop_state_dependant_pkg) procedure exec_invalid_state_proc; - $else - --%test(Sets state invalid flag when package-state invalidated and saves exception stack trace) - --%beforetest(create_state_dependant_pkg) - --%aftertest(drop_state_dependant_pkg) - procedure exec_invalid_state_proc; - $end - procedure create_state_dependant_pkg; procedure drop_state_dependant_pkg; From 55ecb5c7542a0e4d4a9820d26b8da056aa02a03e Mon Sep 17 00:00:00 2001 From: Pazus Date: Fri, 27 Jul 2018 08:32:05 +0300 Subject: [PATCH 009/115] Updated sqlcl version used for tests to version 18.2 --- .travis/download.sh | 4 ++-- .travis/install_sqlcl.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis/download.sh b/.travis/download.sh index 096496aa0..d7f0b7d0f 100644 --- a/.travis/download.sh +++ b/.travis/download.sh @@ -60,8 +60,8 @@ fi if [ "$PRODUCT" == "sqlcl" ]; then agreementUrl="http://www.oracle.com/technetwork/developer-tools/sqlcl/downloads/index.html" - downloadUrl="http://download.oracle.com/otn/java/sqldeveloper/sqlcl-4.2.0.17.073.1038-no-jre.zip" - outputFile=sqlcl-4.2.0.17.073.1038-no-jre.zip + downloadUrl="http://download.oracle.com/otn/java/sqldeveloper/sqlcl-18.2.0.zip" + outputFile=sqlcl-18.2.0.zip downloadFile $agreementUrl $downloadUrl $outputFile exit 0 fi diff --git a/.travis/install_sqlcl.sh b/.travis/install_sqlcl.sh index e3f144540..9db262c5d 100644 --- a/.travis/install_sqlcl.sh +++ b/.travis/install_sqlcl.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -SQLCL_FILE=sqlcl-4.2.0.17.073.1038-no-jre.zip +SQLCL_FILE=sqlcl-18.2.0.zip cd .travis # Download if not present on cache dir. From 105f3242c988d6198d5b4a6f5e29566d46e62608 Mon Sep 17 00:00:00 2001 From: Pazus Date: Fri, 27 Jul 2018 08:55:00 +0300 Subject: [PATCH 010/115] updated documentation. In other places we say something like "12.2 and above" so no need to change --- CONTRIBUTING.md | 1 + docs/userguide/install.md | 8 ++++++++ readme.md | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21cc1a49f..0e82a4ce4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -175,6 +175,7 @@ We are using private docker images to test utPLSQL for our Travis CI builds. The * 11g XE R2 * 12c SE R1 * 12c SE R2 +* 18c SE These images are based on the slimmed versions [official dockerfiles released by Oracle](https://github.com/utPLSQL/docker-scripts), but due to licensing restrictions, we can't make the images public. You can build your own and use it locally, or push to a private docker repository. diff --git a/docs/userguide/install.md b/docs/userguide/install.md index 0b9bec462..0bd713464 100644 --- a/docs/userguide/install.md +++ b/docs/userguide/install.md @@ -49,6 +49,14 @@ foreach ($i in $urlList) { } ``` +# Supported database versions + +The utPLSQL may be installed on any supported version of Oracle Database [see](http://www.oracle.com/us/support/library/lifetime-support-technology-069183.pdf) +* 11g R2 +* 12c +* 12c R2 +* 18c + # Headless installation To install the utPLSQL into a new database schema and grant it to public, execute the script `install_headless.sql` as SYSDBA. diff --git a/readme.md b/readme.md index 16e68d5a0..5dbec9166 100644 --- a/readme.md +++ b/readme.md @@ -192,7 +192,7 @@ If you have a great feature in mind, that you would like to see in utPLSQL v3 pl | Auto Compilation of Tests | Yes | No (Let us know if you use this) | | Assertion Library | 30 assertions2 | 26 matchers (13 + 13 negated) | | Extendable assertions | No | Yes - custom matchers | -| PLSQL Record Assertions | generated code through **utRecEq** Package | [possible on Oracle 12c](https://oracle-base.com/articles/12c/using-the-table-operator-with-locally-defined-types-in-plsql-12cr1) using [cursor matchers](docs/userguide/expectations.md#comparing-cursors)| +| PLSQL Record Assertions | generated code through **utRecEq** Package | [possible on Oracle 12c+](https://oracle-base.com/articles/12c/using-the-table-operator-with-locally-defined-types-in-plsql-12cr1) using [cursor matchers](docs/userguide/expectations.md#comparing-cursors)| | Test Skeleton Generation | Yes | No (Let us know if you use this) | | **Test Execution3** | | | | Single Test Package Execution | Yes | Yes | From 870b04d988dc68a84fcbdabe96f705d42540cc5c Mon Sep 17 00:00:00 2001 From: Pazus Date: Fri, 27 Jul 2018 08:59:56 +0300 Subject: [PATCH 011/115] change link to direct to the DB life support page --- docs/userguide/install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/userguide/install.md b/docs/userguide/install.md index 0bd713464..ef0bef2bd 100644 --- a/docs/userguide/install.md +++ b/docs/userguide/install.md @@ -51,7 +51,7 @@ foreach ($i in $urlList) { # Supported database versions -The utPLSQL may be installed on any supported version of Oracle Database [see](http://www.oracle.com/us/support/library/lifetime-support-technology-069183.pdf) +The utPLSQL may be installed on any supported version of Oracle Database [see](http://www.oracle.com/us/support/library/lifetime-support-technology-069183.pdf#page=6) * 11g R2 * 12c * 12c R2 From fef260b05fb5ce37eaed349120f26cea22490bbe Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 27 Jul 2018 08:38:31 +0100 Subject: [PATCH 012/115] Resolved issue with running package state invalidation test on 18c. --- test/api/test_ut_run.pkb | 68 ++++++++++++++++---------------- test/api/test_ut_run.pks | 2 +- test/core/test_ut_executable.pkb | 58 --------------------------- test/core/test_ut_executable.pks | 8 ---- 4 files changed, 35 insertions(+), 101 deletions(-) diff --git a/test/api/test_ut_run.pkb b/test/api/test_ut_run.pkb index 807f38696..704627ac9 100644 --- a/test/api/test_ut_run.pkb +++ b/test/api/test_ut_run.pkb @@ -514,11 +514,27 @@ create or replace package body test_ut_run is end; procedure create_test_suite is + l_service_name varchar2(100); pragma autonomous_transaction; begin + select global_name into l_service_name from global_name; + execute immediate + 'create public database link db_loopback connect to ut3_tester identified by ut3 + using ''(DESCRIPTION= + (ADDRESS=(PROTOCOL=TCP) + (HOST='||sys_context('userenv','SERVER_HOST')||') + (PORT=1521) + ) + (CONNECT_DATA=(SERVICE_NAME='||l_service_name||')))'''; execute immediate q'[ create or replace package stateful_package as + function get_state return varchar2; + end; + ]'; + execute immediate q'[ + create or replace package body stateful_package as g_state varchar2(1) := 'A'; + function get_state return varchar2 is begin return g_state; end; end; ]'; execute immediate q'[ @@ -527,11 +543,11 @@ create or replace package body test_ut_run is --%suitepath(test_state) --%test - --%beforetest(acquire_state,recompile_in_background) + --%beforetest(acquire_state_via_db_link,rebuild_stateful_package) procedure failing_stateful_test; - procedure recompile_in_background; - procedure acquire_state; + procedure rebuild_stateful_package; + procedure acquire_state_via_db_link; end; ]'; @@ -540,39 +556,23 @@ create or replace package body test_ut_run is procedure failing_stateful_test is begin - ut3.ut.expect(stateful_package.g_state).to_equal('abc'); + ut3.ut.expect(stateful_package.get_state@db_loopback).to_equal('abc'); end; - procedure recompile_in_background is - l_job_name varchar2(30) := 'recreate_stateful_package'; - l_cnt integer := 1; + procedure rebuild_stateful_package is pragma autonomous_transaction; begin - dbms_scheduler.create_job( - job_name => l_job_name, - job_type => 'PLSQL_BLOCK', - job_action => q'/ - begin - execute immediate q'[ - create or replace package stateful_package as - g_state varchar2(3) := 'abc'; - end;]'; - end;/', - start_date => localtimestamp, - enabled => TRUE, - auto_drop => TRUE, - comments => 'one-time job' - ); - dbms_lock.sleep(1); - while l_cnt > 0 loop - select count(1) into l_cnt - from dba_scheduler_running_jobs srj - where srj.job_name = l_job_name; - end loop; + execute immediate q'[ + create or replace package body stateful_package as + g_state varchar2(3) := 'abc'; + function get_state return varchar2 is begin return g_state; end; + end; + ]'; end; - procedure acquire_state is + + procedure acquire_state_via_db_link is begin - dbms_output.put_line('stateful_package.g_state='||stateful_package.g_state); + dbms_output.put_line('stateful_package.get_state@db_loopback='||stateful_package.get_state@db_loopback); end; end; }'; @@ -589,10 +589,9 @@ create or replace package body test_ut_run is failing_stateful_test [% sec] (FAILED - 1)% Failures:% 1) failing_stateful_test - ORA-04061: existing state of package "UT3_TESTER.STATEFUL_PACKAGE" has been invalidated - ORA-04065: not executed, altered or dropped package "UT3_TESTER.STATEFUL_PACKAGE" - ORA-06508: PL/SQL: could not find program unit being called: "UT3_TESTER.STATEFUL_PACKAGE" - ORA-06512: at "UT3_TESTER.TEST_STATEFUL", line 5% + ORA-04068: existing state of packages (DB_LOOPBACK) has been discarded + ORA-04061: existing state of package body "UT3_TESTER.STATEFUL_PACKAGE" has been invalidated + ORA-04065: not executed, altered or dropped package body "UT3_TESTER.STATEFUL_PACKAGE"% ORA-06512: at line 6% 1 tests, 0 failed, 1 errored, 0 disabled, 0 warning(s)%'; @@ -613,6 +612,7 @@ Failures:% begin execute immediate 'drop package stateful_package'; execute immediate 'drop package test_stateful'; + begin execute immediate 'drop public database link db_loopback'; exception when others then null; end; end; procedure run_in_invalid_state is diff --git a/test/api/test_ut_run.pks b/test/api/test_ut_run.pks index dcbb71c58..cfc06c80d 100644 --- a/test/api/test_ut_run.pks +++ b/test/api/test_ut_run.pks @@ -79,7 +79,7 @@ create or replace package test_ut_run is --%test(Executes successfully an empty suite) procedure run_func_empty_suite; - --%disabled(Makes session wait for lock on 18.1 due to library cache pin wait) + --disabled(Makes session wait for lock on 18.1 due to library cache pin wait) --%test(ut.run - raises after completing all tests if a test fails with ORA-04068 or ORA-04061) --%beforetest(create_test_suite) --%aftertest(drop_test_suite) diff --git a/test/core/test_ut_executable.pkb b/test/core/test_ut_executable.pkb index b5f372c32..2d4cde518 100644 --- a/test/core/test_ut_executable.pkb +++ b/test/core/test_ut_executable.pkb @@ -50,32 +50,6 @@ create or replace package body test_ut_executable is ut.expect(l_executable.get_error_stack_trace()).to_be_like('ORA-06501: PL/SQL: program error%'); end; - procedure create_state_dependant_pkg is - pragma autonomous_transaction; - begin - execute immediate q'[ - create or replace package stateful_package as - g_state varchar2(1) := 'A'; - end; - ]'; - execute immediate q'[ - create or replace package state_dependant_pkg as - procedure run; - end; - ]'; - execute immediate q'[ - create or replace package body state_dependant_pkg as - procedure run is - x varchar2(30); - begin - if stateful_package.g_state = 'A' then - dbms_output.put_line('stateful_package.g_state = "A"'); - end if; - end; - end; - ]'; - end; - procedure modify_stateful_package is l_job_name varchar2(30) := 'recreate_stateful_package'; l_cnt integer := 1; @@ -104,38 +78,6 @@ create or replace package body test_ut_executable is end loop; end; - procedure drop_state_dependant_pkg is - pragma autonomous_transaction; - begin - execute immediate 'drop package state_dependant_pkg'; - execute immediate 'drop package stateful_package'; - end; - - - procedure exec_invalid_state_proc is - l_executable ut3.ut_executable; - l_test ut3.ut_test; - l_result boolean; - begin - --Arrange - l_test := ut3.ut_test(a_object_name => 'state_dependant_pkg',a_name => 'state_dependant_pkg'); - l_executable := ut3.ut_executable_test( user, 'state_dependant_pkg', 'run', ut3.ut_utils.gc_test_execute ); - l_result := l_executable.do_execute(l_test); - ut.expect(l_result).to_be_true; - - modify_stateful_package; - - l_test := ut3.ut_test(a_object_name => 'state_dependant_pkg',a_name => 'state_dependant_pkg'); - l_executable := ut3.ut_executable_test( user, 'state_dependant_pkg', 'run', ut3.ut_utils.gc_test_execute ); - --Act - l_result := l_executable.do_execute(l_test); - --Assert - ut.expect(l_result).to_be_false; - ut.expect(l_executable.serveroutput).to_be_null; - ut.expect(l_executable.get_error_stack_trace()).to_be_like('ORA-04061: existing state of package "UT3_TESTER.STATEFUL_PACKAGE" has been invalidated%'); - ut.expect(ut3.ut_expectation_processor.invalidation_exception_found()).to_be_true; - end; - procedure form_name is begin ut.expect(ut3.ut_executable_test( user, 'package', 'proc', null ).form_name()).to_equal(user||'.package.proc'); diff --git a/test/core/test_ut_executable.pks b/test/core/test_ut_executable.pks index 7c1f8d297..4c11e5142 100644 --- a/test/core/test_ut_executable.pks +++ b/test/core/test_ut_executable.pks @@ -14,14 +14,6 @@ create or replace package test_ut_executable is --%test(Executes a procedure raising exception, saves dbms_output and exception stack trace) procedure exec_failing_proc; - --%disabled(Makes session wait for lock on 18.1 due to library cache pin wait) - --%test(Sets state invalid flag when package-state invalidated and saves exception stack trace) - --%beforetest(create_state_dependant_pkg) - --%aftertest(drop_state_dependant_pkg) - procedure exec_invalid_state_proc; - procedure create_state_dependant_pkg; - procedure drop_state_dependant_pkg; - --%endcontext --%context(form_name) From c15f4c25b8a647e6e062be66ddc198713966bded Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 27 Jul 2018 09:33:59 +0100 Subject: [PATCH 013/115] Improved performance of tests by changing runtime plsql_optimize_level=0 --- test/core.pkb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/core.pkb b/test/core.pkb index 69a21b69e..7ace9f7ce 100644 --- a/test/core.pkb +++ b/test/core.pkb @@ -3,6 +3,9 @@ create or replace package body core is procedure global_setup is begin ut3.ut_coverage.set_develop_mode(true); + --improve performance of test execution by disabling all compiler optimizations + execute_autonomous('ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=0'); + execute_autonomous( q'[create or replace package ut_transaction_control as function count_rows(a_val varchar2) return number; From 88a355972b961aca459c29195b5f0d5fe4c5dfd6 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Fri, 27 Jul 2018 09:33:43 +0000 Subject: [PATCH 014/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 857013723..2c7f764cd 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2140-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2156-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From b28c568cb47e2ea81452ed3515efd12329f4955c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20G=C4=99bal?= Date: Fri, 27 Jul 2018 11:34:09 +0100 Subject: [PATCH 015/115] Resolves #737 --- source/check_sys_grants.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/check_sys_grants.sql b/source/check_sys_grants.sql index 863727f00..a762cb06c 100644 --- a/source/check_sys_grants.sql +++ b/source/check_sys_grants.sql @@ -18,7 +18,7 @@ begin select column_value as privilege from table(l_expected_grants) minus - select privilege + select replace(privilege,' ANY ') privilege from user_sys_privs ); if l_missing_grants is not null then From 4888784f8654d7f812f5d52f17c85ad625d1a345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20G=C4=99bal?= Date: Fri, 27 Jul 2018 12:58:19 +0100 Subject: [PATCH 016/115] Update check_sys_grants.sql --- source/check_sys_grants.sql | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/check_sys_grants.sql b/source/check_sys_grants.sql index a762cb06c..e16869e54 100644 --- a/source/check_sys_grants.sql +++ b/source/check_sys_grants.sql @@ -18,8 +18,11 @@ begin select column_value as privilege from table(l_expected_grants) minus - select replace(privilege,' ANY ') privilege + (select privilege from user_sys_privs + union all + select replace(privilege,' ANY ') privilege + from user_sys_privs) ); if l_missing_grants is not null then raise_application_error( From d309c901bbcae04f99ce86a2a787a54ad4d7d092 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 27 Jul 2018 18:19:44 +0100 Subject: [PATCH 017/115] Updated Copyright notice to 2018 Resolves #736 --- mkdocs.yml | 2 +- source/api/ut.pkb | 2 +- source/api/ut.pks | 2 +- source/api/ut_runner.pkb | 2 +- source/api/ut_runner.pks | 2 +- source/core/annotations/ut_annotated_object.tps | 2 +- source/core/annotations/ut_annotated_objects.tps | 2 +- source/core/annotations/ut_annotation.tps | 2 +- source/core/annotations/ut_annotation_cache.sql | 2 +- source/core/annotations/ut_annotation_cache_info.sql | 2 +- source/core/annotations/ut_annotation_cache_manager.pkb | 2 +- source/core/annotations/ut_annotation_cache_manager.pks | 2 +- source/core/annotations/ut_annotation_cache_seq.sql | 2 +- source/core/annotations/ut_annotation_manager.pkb | 2 +- source/core/annotations/ut_annotation_manager.pks | 2 +- source/core/annotations/ut_annotation_obj_cache_info.tps | 2 +- source/core/annotations/ut_annotation_objs_cache_info.tps | 2 +- source/core/annotations/ut_annotation_parser.pkb | 2 +- source/core/annotations/ut_annotation_parser.pks | 2 +- source/core/annotations/ut_annotations.tps | 2 +- source/core/coverage/ut_coverage.pkb | 2 +- source/core/coverage/ut_coverage.pks | 2 +- source/core/coverage/ut_coverage_block.pkb | 2 +- source/core/coverage/ut_coverage_block.pks | 2 +- source/core/coverage/ut_coverage_helper.pkb | 2 +- source/core/coverage/ut_coverage_helper.pks | 2 +- source/core/coverage/ut_coverage_helper_block.pkb | 2 +- source/core/coverage/ut_coverage_helper_block.pks | 2 +- source/core/coverage/ut_coverage_helper_profiler.pkb | 2 +- source/core/coverage/ut_coverage_helper_profiler.pks | 2 +- source/core/coverage/ut_coverage_profiler.pkb | 2 +- source/core/coverage/ut_coverage_profiler.pks | 2 +- source/core/coverage/ut_coverage_reporter_base.tpb | 2 +- source/core/coverage/ut_coverage_reporter_base.tps | 2 +- source/core/coverage/ut_coverage_sources_tmp.sql | 4 ++-- source/core/events/ut_event_item.tps | 2 +- source/core/events/ut_event_listener.tps | 2 +- source/core/events/ut_event_manager.pkb | 2 +- source/core/events/ut_event_manager.pks | 2 +- source/core/output_buffers/ut_output_buffer_base.tps | 2 +- source/core/output_buffers/ut_output_buffer_info_tmp.sql | 4 ++-- source/core/output_buffers/ut_output_buffer_tmp.sql | 4 ++-- source/core/output_buffers/ut_output_table_buffer.tpb | 2 +- source/core/output_buffers/ut_output_table_buffer.tps | 2 +- source/core/types/ut_console_reporter_base.tpb | 2 +- source/core/types/ut_console_reporter_base.tps | 2 +- source/core/types/ut_coverage_options.tps | 2 +- source/core/types/ut_executable.tpb | 2 +- source/core/types/ut_executable.tps | 2 +- source/core/types/ut_executable_test.tps | 2 +- source/core/types/ut_executables.tps | 2 +- source/core/types/ut_expectation_result.tpb | 2 +- source/core/types/ut_expectation_result.tps | 2 +- source/core/types/ut_expectation_results.tps | 2 +- source/core/types/ut_file_mapping.tpb | 2 +- source/core/types/ut_file_mapping.tps | 2 +- source/core/types/ut_file_mappings.tps | 2 +- source/core/types/ut_integer_list.tps | 2 +- source/core/types/ut_key_value_pair.tps | 2 +- source/core/types/ut_key_value_pairs.tps | 2 +- source/core/types/ut_logical_suite.tpb | 2 +- source/core/types/ut_logical_suite.tps | 2 +- source/core/types/ut_object_name.tpb | 2 +- source/core/types/ut_object_name.tps | 2 +- source/core/types/ut_object_names.tps | 2 +- source/core/types/ut_output_reporter_base.tpb | 2 +- source/core/types/ut_output_reporter_base.tps | 2 +- source/core/types/ut_reporter_base.tpb | 2 +- source/core/types/ut_reporter_base.tps | 2 +- source/core/types/ut_reporters.tps | 2 +- source/core/types/ut_results_counter.tpb | 2 +- source/core/types/ut_results_counter.tps | 2 +- source/core/types/ut_run.tpb | 2 +- source/core/types/ut_run.tps | 2 +- source/core/types/ut_suite.tpb | 2 +- source/core/types/ut_suite.tps | 2 +- source/core/types/ut_suite_context.tpb | 2 +- source/core/types/ut_suite_context.tps | 2 +- source/core/types/ut_suite_item.tpb | 2 +- source/core/types/ut_suite_item.tps | 2 +- source/core/types/ut_suite_items.tps | 2 +- source/core/types/ut_test.tpb | 2 +- source/core/types/ut_test.tps | 2 +- source/core/types/ut_varchar2_list.tps | 2 +- source/core/types/ut_varchar2_rows.tps | 2 +- source/core/ut_dbms_output_cache.sql | 2 +- source/core/ut_expectation_processor.pkb | 2 +- source/core/ut_expectation_processor.pks | 2 +- source/core/ut_file_mapper.pkb | 2 +- source/core/ut_file_mapper.pks | 2 +- source/core/ut_metadata.pkb | 2 +- source/core/ut_metadata.pks | 2 +- source/core/ut_suite_builder.pkb | 2 +- source/core/ut_suite_builder.pks | 2 +- source/core/ut_suite_manager.pkb | 2 +- source/core/ut_suite_manager.pks | 2 +- source/core/ut_utils.pkb | 2 +- source/core/ut_utils.pks | 2 +- source/create_synonyms_and_grants_for_public.sql | 2 +- source/create_user_grants.sql | 2 +- source/create_user_synonyms.sql | 2 +- source/create_utplsql_owner.sql | 2 +- source/define_ut3_owner_param.sql | 2 +- source/expectations/data_values/ut_compound_data_diff_tmp.sql | 2 +- source/expectations/data_values/ut_compound_data_helper.pkb | 2 +- source/expectations/data_values/ut_compound_data_helper.pks | 2 +- source/expectations/data_values/ut_compound_data_tmp.sql | 2 +- source/expectations/data_values/ut_compound_data_value.tpb | 2 +- source/expectations/data_values/ut_compound_data_value.tps | 2 +- source/expectations/data_values/ut_data_value.tpb | 2 +- source/expectations/data_values/ut_data_value.tps | 2 +- source/expectations/data_values/ut_data_value_anydata.tpb | 2 +- source/expectations/data_values/ut_data_value_anydata.tps | 2 +- source/expectations/data_values/ut_data_value_blob.tpb | 2 +- source/expectations/data_values/ut_data_value_blob.tps | 2 +- source/expectations/data_values/ut_data_value_boolean.tpb | 2 +- source/expectations/data_values/ut_data_value_boolean.tps | 2 +- source/expectations/data_values/ut_data_value_clob.tpb | 2 +- source/expectations/data_values/ut_data_value_clob.tps | 2 +- source/expectations/data_values/ut_data_value_collection.tpb | 2 +- source/expectations/data_values/ut_data_value_collection.tps | 2 +- source/expectations/data_values/ut_data_value_date.tpb | 2 +- source/expectations/data_values/ut_data_value_date.tps | 2 +- source/expectations/data_values/ut_data_value_dsinterval.tpb | 2 +- source/expectations/data_values/ut_data_value_dsinterval.tps | 2 +- source/expectations/data_values/ut_data_value_number.tpb | 2 +- source/expectations/data_values/ut_data_value_number.tps | 2 +- source/expectations/data_values/ut_data_value_object.tpb | 2 +- source/expectations/data_values/ut_data_value_object.tps | 2 +- source/expectations/data_values/ut_data_value_refcursor.tpb | 2 +- source/expectations/data_values/ut_data_value_refcursor.tps | 2 +- source/expectations/data_values/ut_data_value_timestamp.tpb | 2 +- source/expectations/data_values/ut_data_value_timestamp.tps | 2 +- .../expectations/data_values/ut_data_value_timestamp_ltz.tpb | 2 +- .../expectations/data_values/ut_data_value_timestamp_ltz.tps | 2 +- .../expectations/data_values/ut_data_value_timestamp_tz.tpb | 2 +- .../expectations/data_values/ut_data_value_timestamp_tz.tps | 2 +- source/expectations/data_values/ut_data_value_varchar2.tpb | 2 +- source/expectations/data_values/ut_data_value_varchar2.tps | 2 +- source/expectations/data_values/ut_data_value_xmltype.tpb | 2 +- source/expectations/data_values/ut_data_value_xmltype.tps | 2 +- source/expectations/data_values/ut_data_value_yminterval.tpb | 2 +- source/expectations/data_values/ut_data_value_yminterval.tps | 2 +- source/expectations/data_values/ut_key_anyval_pair.tps | 2 +- source/expectations/data_values/ut_key_anyval_pairs.tps | 2 +- source/expectations/matchers/ut_be_between.tpb | 2 +- source/expectations/matchers/ut_be_between.tps | 2 +- source/expectations/matchers/ut_be_empty.tpb | 2 +- source/expectations/matchers/ut_be_empty.tps | 2 +- source/expectations/matchers/ut_be_false.tpb | 2 +- source/expectations/matchers/ut_be_false.tps | 2 +- source/expectations/matchers/ut_be_greater_or_equal.tpb | 2 +- source/expectations/matchers/ut_be_greater_or_equal.tps | 2 +- source/expectations/matchers/ut_be_greater_than.tpb | 2 +- source/expectations/matchers/ut_be_greater_than.tps | 2 +- source/expectations/matchers/ut_be_less_or_equal.tpb | 2 +- source/expectations/matchers/ut_be_less_or_equal.tps | 2 +- source/expectations/matchers/ut_be_less_than.tpb | 2 +- source/expectations/matchers/ut_be_less_than.tps | 2 +- source/expectations/matchers/ut_be_like.tpb | 2 +- source/expectations/matchers/ut_be_like.tps | 2 +- source/expectations/matchers/ut_be_not_null.tpb | 2 +- source/expectations/matchers/ut_be_not_null.tps | 2 +- source/expectations/matchers/ut_be_null.tpb | 2 +- source/expectations/matchers/ut_be_null.tps | 2 +- source/expectations/matchers/ut_be_true.tpb | 2 +- source/expectations/matchers/ut_be_true.tps | 2 +- source/expectations/matchers/ut_comparison_matcher.tpb | 2 +- source/expectations/matchers/ut_comparison_matcher.tps | 2 +- source/expectations/matchers/ut_equal.tpb | 2 +- source/expectations/matchers/ut_equal.tps | 2 +- source/expectations/matchers/ut_have_count.tpb | 2 +- source/expectations/matchers/ut_have_count.tps | 2 +- source/expectations/matchers/ut_match.tpb | 2 +- source/expectations/matchers/ut_match.tps | 2 +- source/expectations/matchers/ut_matcher.tpb | 2 +- source/expectations/matchers/ut_matcher.tps | 2 +- source/expectations/ut_expectation.tpb | 2 +- source/expectations/ut_expectation.tps | 2 +- source/expectations/ut_expectation_compound.tpb | 2 +- source/expectations/ut_expectation_compound.tps | 2 +- source/install.sql | 2 +- source/install_component.sql | 2 +- source/install_headless.sql | 2 +- source/reporters/ut_ansiconsole_helper.pkb | 2 +- source/reporters/ut_ansiconsole_helper.pks | 2 +- source/reporters/ut_coverage_cobertura_reporter.tpb | 2 +- source/reporters/ut_coverage_cobertura_reporter.tps | 2 +- source/reporters/ut_coverage_html_reporter.tpb | 2 +- source/reporters/ut_coverage_html_reporter.tps | 2 +- source/reporters/ut_coverage_report_html_helper.pkb | 2 +- source/reporters/ut_coverage_report_html_helper.pks | 2 +- source/reporters/ut_coverage_sonar_reporter.tpb | 2 +- source/reporters/ut_coverage_sonar_reporter.tps | 2 +- source/reporters/ut_coveralls_reporter.tpb | 2 +- source/reporters/ut_coveralls_reporter.tps | 2 +- source/reporters/ut_documentation_reporter.tpb | 2 +- source/reporters/ut_documentation_reporter.tps | 2 +- source/reporters/ut_junit_reporter.tpb | 2 +- source/reporters/ut_junit_reporter.tps | 2 +- source/reporters/ut_sonar_test_reporter.tpb | 2 +- source/reporters/ut_sonar_test_reporter.tps | 2 +- source/reporters/ut_teamcity_reporter.tpb | 2 +- source/reporters/ut_teamcity_reporter.tps | 2 +- source/reporters/ut_teamcity_reporter_helper.pkb | 2 +- source/reporters/ut_teamcity_reporter_helper.pks | 2 +- source/reporters/ut_tfs_junit_reporter.tpb | 2 +- source/reporters/ut_tfs_junit_reporter.tps | 2 +- source/reporters/ut_xunit_reporter.tpb | 2 +- source/reporters/ut_xunit_reporter.tps | 2 +- source/uninstall.sql | 2 +- source/uninstall_all.sql | 2 +- 212 files changed, 215 insertions(+), 215 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 6811fe245..3aeae4d95 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,7 +3,7 @@ site_name: utPLSQL site_description: utPLSQL Documenation Powerful Unit Testing Framework for Oracle PL/SQL -copyright: Copyright © 2016 - 2017 utPLSQL Team +copyright: Copyright © 2016 - 2018 utPLSQL Team repo_url: https://github.com/utPLSQL/utPLSQL theme: mkdocs use_directory_urls: false diff --git a/source/api/ut.pkb b/source/api/ut.pkb index 6fd4eab08..bd241ce13 100644 --- a/source/api/ut.pkb +++ b/source/api/ut.pkb @@ -2,7 +2,7 @@ create or replace package body ut is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/api/ut.pks b/source/api/ut.pks index a90957fd2..59c709a33 100644 --- a/source/api/ut.pks +++ b/source/api/ut.pks @@ -2,7 +2,7 @@ create or replace package ut authid current_user as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index ec02af30e..c04fa5112 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -2,7 +2,7 @@ create or replace package body ut_runner is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index b796aab9b..45b8cb642 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -2,7 +2,7 @@ create or replace package ut_runner authid current_user is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotated_object.tps b/source/core/annotations/ut_annotated_object.tps index 5aa89f6dd..4bf141a3f 100644 --- a/source/core/annotations/ut_annotated_object.tps +++ b/source/core/annotations/ut_annotated_object.tps @@ -1,7 +1,7 @@ create type ut_annotated_object as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotated_objects.tps b/source/core/annotations/ut_annotated_objects.tps index 53c816902..b7c01fe7a 100644 --- a/source/core/annotations/ut_annotated_objects.tps +++ b/source/core/annotations/ut_annotated_objects.tps @@ -1,7 +1,7 @@ create type ut_annotated_objects as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotation.tps b/source/core/annotations/ut_annotation.tps index b334fb415..35af758c7 100644 --- a/source/core/annotations/ut_annotation.tps +++ b/source/core/annotations/ut_annotation.tps @@ -1,7 +1,7 @@ create type ut_annotation as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotation_cache.sql b/source/core/annotations/ut_annotation_cache.sql index bcabc5735..f9c9295cb 100644 --- a/source/core/annotations/ut_annotation_cache.sql +++ b/source/core/annotations/ut_annotation_cache.sql @@ -1,7 +1,7 @@ create table ut_annotation_cache ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 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 diff --git a/source/core/annotations/ut_annotation_cache_info.sql b/source/core/annotations/ut_annotation_cache_info.sql index dfd623a4f..48f8a606c 100644 --- a/source/core/annotations/ut_annotation_cache_info.sql +++ b/source/core/annotations/ut_annotation_cache_info.sql @@ -1,7 +1,7 @@ create table ut_annotation_cache_info ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 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 diff --git a/source/core/annotations/ut_annotation_cache_manager.pkb b/source/core/annotations/ut_annotation_cache_manager.pkb index a9b4f81ee..a05914e37 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pkb +++ b/source/core/annotations/ut_annotation_cache_manager.pkb @@ -1,7 +1,7 @@ create or replace package body ut_annotation_cache_manager as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotation_cache_manager.pks b/source/core/annotations/ut_annotation_cache_manager.pks index 344581aa1..d37212d69 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pks +++ b/source/core/annotations/ut_annotation_cache_manager.pks @@ -1,7 +1,7 @@ create or replace package ut_annotation_cache_manager authid definer as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotation_cache_seq.sql b/source/core/annotations/ut_annotation_cache_seq.sql index 88fb0582b..028225ddb 100644 --- a/source/core/annotations/ut_annotation_cache_seq.sql +++ b/source/core/annotations/ut_annotation_cache_seq.sql @@ -1,7 +1,7 @@ create sequence ut_annotation_cache_seq /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 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 diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb index c3dfb5151..e44e5dd10 100644 --- a/source/core/annotations/ut_annotation_manager.pkb +++ b/source/core/annotations/ut_annotation_manager.pkb @@ -1,7 +1,7 @@ create or replace package body ut_annotation_manager as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotation_manager.pks b/source/core/annotations/ut_annotation_manager.pks index a52209b6f..a2925c388 100644 --- a/source/core/annotations/ut_annotation_manager.pks +++ b/source/core/annotations/ut_annotation_manager.pks @@ -1,7 +1,7 @@ create or replace package ut_annotation_manager authid current_user as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotation_obj_cache_info.tps b/source/core/annotations/ut_annotation_obj_cache_info.tps index 0005bf45b..2be2ac184 100644 --- a/source/core/annotations/ut_annotation_obj_cache_info.tps +++ b/source/core/annotations/ut_annotation_obj_cache_info.tps @@ -1,7 +1,7 @@ create type ut_annotation_obj_cache_info as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotation_objs_cache_info.tps b/source/core/annotations/ut_annotation_objs_cache_info.tps index e02f0895b..9773a045e 100644 --- a/source/core/annotations/ut_annotation_objs_cache_info.tps +++ b/source/core/annotations/ut_annotation_objs_cache_info.tps @@ -1,7 +1,7 @@ create type ut_annotation_objs_cache_info as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotation_parser.pkb b/source/core/annotations/ut_annotation_parser.pkb index 84efbaa91..2467c6262 100644 --- a/source/core/annotations/ut_annotation_parser.pkb +++ b/source/core/annotations/ut_annotation_parser.pkb @@ -1,7 +1,7 @@ create or replace package body ut_annotation_parser as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotation_parser.pks b/source/core/annotations/ut_annotation_parser.pks index 979e26399..a396e877e 100644 --- a/source/core/annotations/ut_annotation_parser.pks +++ b/source/core/annotations/ut_annotation_parser.pks @@ -1,7 +1,7 @@ create or replace package ut_annotation_parser authid current_user as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/annotations/ut_annotations.tps b/source/core/annotations/ut_annotations.tps index 563450200..4238f9512 100644 --- a/source/core/annotations/ut_annotations.tps +++ b/source/core/annotations/ut_annotations.tps @@ -1,7 +1,7 @@ create type ut_annotations /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index bb06a80b7..64d625d84 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -1,7 +1,7 @@ create or replace package body ut_coverage is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks index 26890e600..b291f4b26 100644 --- a/source/core/coverage/ut_coverage.pks +++ b/source/core/coverage/ut_coverage.pks @@ -1,7 +1,7 @@ create or replace package ut_coverage authid current_user is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_block.pkb b/source/core/coverage/ut_coverage_block.pkb index 3d830822e..7da62ff80 100644 --- a/source/core/coverage/ut_coverage_block.pkb +++ b/source/core/coverage/ut_coverage_block.pkb @@ -1,7 +1,7 @@ create or replace package body ut_coverage_block is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_block.pks b/source/core/coverage/ut_coverage_block.pks index 3eba99b12..fdce622a5 100644 --- a/source/core/coverage/ut_coverage_block.pks +++ b/source/core/coverage/ut_coverage_block.pks @@ -1,7 +1,7 @@ create or replace package ut_coverage_block authid current_user is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb index 0f10d4b03..cfa3e413c 100644 --- a/source/core/coverage/ut_coverage_helper.pkb +++ b/source/core/coverage/ut_coverage_helper.pkb @@ -1,7 +1,7 @@ create or replace package body ut_coverage_helper is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks index c36ae43b2..014e7b471 100644 --- a/source/core/coverage/ut_coverage_helper.pks +++ b/source/core/coverage/ut_coverage_helper.pks @@ -1,7 +1,7 @@ create or replace package ut_coverage_helper authid definer is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_helper_block.pkb b/source/core/coverage/ut_coverage_helper_block.pkb index 3db3d84c7..865576b3e 100644 --- a/source/core/coverage/ut_coverage_helper_block.pkb +++ b/source/core/coverage/ut_coverage_helper_block.pkb @@ -1,7 +1,7 @@ create or replace package body ut_coverage_helper_block is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_helper_block.pks b/source/core/coverage/ut_coverage_helper_block.pks index fa2c55904..0b71b7067 100644 --- a/source/core/coverage/ut_coverage_helper_block.pks +++ b/source/core/coverage/ut_coverage_helper_block.pks @@ -1,7 +1,7 @@ create or replace package ut_coverage_helper_block authid current_user is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_helper_profiler.pkb b/source/core/coverage/ut_coverage_helper_profiler.pkb index 965d1ab54..340a28ca3 100644 --- a/source/core/coverage/ut_coverage_helper_profiler.pkb +++ b/source/core/coverage/ut_coverage_helper_profiler.pkb @@ -1,7 +1,7 @@ create or replace package body ut_coverage_helper_profiler is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_helper_profiler.pks b/source/core/coverage/ut_coverage_helper_profiler.pks index 89117aada..db91326eb 100644 --- a/source/core/coverage/ut_coverage_helper_profiler.pks +++ b/source/core/coverage/ut_coverage_helper_profiler.pks @@ -1,7 +1,7 @@ create or replace package ut_coverage_helper_profiler authid definer is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_profiler.pkb b/source/core/coverage/ut_coverage_profiler.pkb index 2ff528f3c..e4c9ab0af 100644 --- a/source/core/coverage/ut_coverage_profiler.pkb +++ b/source/core/coverage/ut_coverage_profiler.pkb @@ -1,7 +1,7 @@ create or replace package body ut_coverage_profiler is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_profiler.pks b/source/core/coverage/ut_coverage_profiler.pks index 6bfb6a8f7..4e4b8d9c0 100644 --- a/source/core/coverage/ut_coverage_profiler.pks +++ b/source/core/coverage/ut_coverage_profiler.pks @@ -1,7 +1,7 @@ create or replace package ut_coverage_profiler authid current_user is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_reporter_base.tpb b/source/core/coverage/ut_coverage_reporter_base.tpb index b675c07f1..9e339347f 100644 --- a/source/core/coverage/ut_coverage_reporter_base.tpb +++ b/source/core/coverage/ut_coverage_reporter_base.tpb @@ -1,7 +1,7 @@ create or replace type body ut_coverage_reporter_base is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_reporter_base.tps b/source/core/coverage/ut_coverage_reporter_base.tps index 087f4edff..76206dd95 100644 --- a/source/core/coverage/ut_coverage_reporter_base.tps +++ b/source/core/coverage/ut_coverage_reporter_base.tps @@ -1,7 +1,7 @@ create or replace type ut_coverage_reporter_base under ut_output_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/coverage/ut_coverage_sources_tmp.sql b/source/core/coverage/ut_coverage_sources_tmp.sql index aaf97ef01..bcc661a22 100644 --- a/source/core/coverage/ut_coverage_sources_tmp.sql +++ b/source/core/coverage/ut_coverage_sources_tmp.sql @@ -1,7 +1,7 @@ create global temporary table ut_coverage_sources_tmp$( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 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 @@ -39,7 +39,7 @@ begin v_view_source := ' ut_coverage_sources_tmp as /* utPLSQL - Version 3 -Copyright 2016 - 2017 utPLSQL Project +Copyright 2016 - 2018 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 diff --git a/source/core/events/ut_event_item.tps b/source/core/events/ut_event_item.tps index caa0423dd..398cc2ac0 100644 --- a/source/core/events/ut_event_item.tps +++ b/source/core/events/ut_event_item.tps @@ -1,7 +1,7 @@ create or replace type ut_event_item authid current_user as object ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/events/ut_event_listener.tps b/source/core/events/ut_event_listener.tps index 56511c8d0..fd6ae0486 100644 --- a/source/core/events/ut_event_listener.tps +++ b/source/core/events/ut_event_listener.tps @@ -1,7 +1,7 @@ create or replace type ut_event_listener authid current_user as object ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/events/ut_event_manager.pkb b/source/core/events/ut_event_manager.pkb index cb556050a..7ae0ad0b3 100644 --- a/source/core/events/ut_event_manager.pkb +++ b/source/core/events/ut_event_manager.pkb @@ -1,7 +1,7 @@ create or replace package body ut_event_manager as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/events/ut_event_manager.pks b/source/core/events/ut_event_manager.pks index 4e690082c..fa0da4a00 100644 --- a/source/core/events/ut_event_manager.pks +++ b/source/core/events/ut_event_manager.pks @@ -1,7 +1,7 @@ create or replace package ut_event_manager authid current_user as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/output_buffers/ut_output_buffer_base.tps b/source/core/output_buffers/ut_output_buffer_base.tps index 320b4ed5c..f1d71c502 100644 --- a/source/core/output_buffers/ut_output_buffer_base.tps +++ b/source/core/output_buffers/ut_output_buffer_base.tps @@ -1,7 +1,7 @@ create or replace type ut_output_buffer_base authid definer as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/output_buffers/ut_output_buffer_info_tmp.sql b/source/core/output_buffers/ut_output_buffer_info_tmp.sql index 0cfe58ed2..5880022f5 100644 --- a/source/core/output_buffers/ut_output_buffer_info_tmp.sql +++ b/source/core/output_buffers/ut_output_buffer_info_tmp.sql @@ -1,7 +1,7 @@ create table ut_output_buffer_info_tmp$( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 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 @@ -40,7 +40,7 @@ begin v_view_source := ' ut_output_buffer_info_tmp as /* utPLSQL - Version 3 -Copyright 2016 - 2017 utPLSQL Project +Copyright 2016 - 2018 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 diff --git a/source/core/output_buffers/ut_output_buffer_tmp.sql b/source/core/output_buffers/ut_output_buffer_tmp.sql index 8d0def8a8..e8127e237 100644 --- a/source/core/output_buffers/ut_output_buffer_tmp.sql +++ b/source/core/output_buffers/ut_output_buffer_tmp.sql @@ -1,7 +1,7 @@ create table ut_output_buffer_tmp$( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 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 @@ -44,7 +44,7 @@ begin v_view_source := ' ut_output_buffer_tmp as /* utPLSQL - Version 3 -Copyright 2016 - 2017 utPLSQL Project +Copyright 2016 - 2018 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 diff --git a/source/core/output_buffers/ut_output_table_buffer.tpb b/source/core/output_buffers/ut_output_table_buffer.tpb index 5384afd45..0cc68b76b 100644 --- a/source/core/output_buffers/ut_output_table_buffer.tpb +++ b/source/core/output_buffers/ut_output_table_buffer.tpb @@ -1,7 +1,7 @@ create or replace type body ut_output_table_buffer is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/output_buffers/ut_output_table_buffer.tps b/source/core/output_buffers/ut_output_table_buffer.tps index f052b0744..96628de77 100644 --- a/source/core/output_buffers/ut_output_table_buffer.tps +++ b/source/core/output_buffers/ut_output_table_buffer.tps @@ -1,7 +1,7 @@ create or replace type ut_output_table_buffer under ut_output_buffer_base ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_console_reporter_base.tpb b/source/core/types/ut_console_reporter_base.tpb index a6ac8a6ce..70513223c 100644 --- a/source/core/types/ut_console_reporter_base.tpb +++ b/source/core/types/ut_console_reporter_base.tpb @@ -1,7 +1,7 @@ create or replace type body ut_console_reporter_base is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_console_reporter_base.tps b/source/core/types/ut_console_reporter_base.tps index 23882596a..b74b08033 100644 --- a/source/core/types/ut_console_reporter_base.tps +++ b/source/core/types/ut_console_reporter_base.tps @@ -1,7 +1,7 @@ create or replace type ut_console_reporter_base under ut_output_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_coverage_options.tps b/source/core/types/ut_coverage_options.tps index 876457f8e..737ea1abb 100644 --- a/source/core/types/ut_coverage_options.tps +++ b/source/core/types/ut_coverage_options.tps @@ -1,7 +1,7 @@ create or replace type ut_coverage_options force as object ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_executable.tpb b/source/core/types/ut_executable.tpb index b31322331..b41e75388 100644 --- a/source/core/types/ut_executable.tpb +++ b/source/core/types/ut_executable.tpb @@ -1,7 +1,7 @@ create or replace type body ut_executable is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_executable.tps b/source/core/types/ut_executable.tps index 976ccf396..5fa4f3566 100644 --- a/source/core/types/ut_executable.tps +++ b/source/core/types/ut_executable.tps @@ -1,7 +1,7 @@ create or replace type ut_executable under ut_event_item( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_executable_test.tps b/source/core/types/ut_executable_test.tps index a4963a2b9..b11676c0c 100644 --- a/source/core/types/ut_executable_test.tps +++ b/source/core/types/ut_executable_test.tps @@ -1,7 +1,7 @@ create or replace type ut_executable_test authid current_user under ut_executable ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_executables.tps b/source/core/types/ut_executables.tps index f74d3f7ca..a06e6c067 100644 --- a/source/core/types/ut_executables.tps +++ b/source/core/types/ut_executables.tps @@ -1,7 +1,7 @@ create or replace type ut_executables as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_expectation_result.tpb b/source/core/types/ut_expectation_result.tpb index 6e3a0d4c0..6714d48b6 100644 --- a/source/core/types/ut_expectation_result.tpb +++ b/source/core/types/ut_expectation_result.tpb @@ -1,7 +1,7 @@ create or replace type body ut_expectation_result is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_expectation_result.tps b/source/core/types/ut_expectation_result.tps index 5c994bf00..af819504d 100644 --- a/source/core/types/ut_expectation_result.tps +++ b/source/core/types/ut_expectation_result.tps @@ -1,7 +1,7 @@ create or replace type ut_expectation_result authid current_user as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_expectation_results.tps b/source/core/types/ut_expectation_results.tps index 49d21c57c..942f9b398 100644 --- a/source/core/types/ut_expectation_results.tps +++ b/source/core/types/ut_expectation_results.tps @@ -1,7 +1,7 @@ create or replace type ut_expectation_results as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_file_mapping.tpb b/source/core/types/ut_file_mapping.tpb index d0fa58031..c5a82c09d 100644 --- a/source/core/types/ut_file_mapping.tpb +++ b/source/core/types/ut_file_mapping.tpb @@ -1,7 +1,7 @@ create or replace type body ut_file_mapping as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_file_mapping.tps b/source/core/types/ut_file_mapping.tps index f8643c12a..e046808d4 100644 --- a/source/core/types/ut_file_mapping.tps +++ b/source/core/types/ut_file_mapping.tps @@ -1,7 +1,7 @@ create or replace type ut_file_mapping as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_file_mappings.tps b/source/core/types/ut_file_mappings.tps index b5b891386..6ff2604b3 100644 --- a/source/core/types/ut_file_mappings.tps +++ b/source/core/types/ut_file_mappings.tps @@ -1,7 +1,7 @@ create or replace type ut_file_mappings as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_integer_list.tps b/source/core/types/ut_integer_list.tps index c2ba251d8..c1fc4de91 100644 --- a/source/core/types/ut_integer_list.tps +++ b/source/core/types/ut_integer_list.tps @@ -1,7 +1,7 @@ create or replace type ut_integer_list as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_key_value_pair.tps b/source/core/types/ut_key_value_pair.tps index a23df4a7b..ae1b9aba7 100644 --- a/source/core/types/ut_key_value_pair.tps +++ b/source/core/types/ut_key_value_pair.tps @@ -1,7 +1,7 @@ create or replace type ut_key_value_pair force as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_key_value_pairs.tps b/source/core/types/ut_key_value_pairs.tps index 45e208518..c9bab9ec2 100644 --- a/source/core/types/ut_key_value_pairs.tps +++ b/source/core/types/ut_key_value_pairs.tps @@ -1,7 +1,7 @@ create or replace type ut_key_value_pairs as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_logical_suite.tpb b/source/core/types/ut_logical_suite.tpb index 17cadd449..0443bf105 100644 --- a/source/core/types/ut_logical_suite.tpb +++ b/source/core/types/ut_logical_suite.tpb @@ -1,7 +1,7 @@ create or replace type body ut_logical_suite as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_logical_suite.tps b/source/core/types/ut_logical_suite.tps index e9f260035..85bb80870 100644 --- a/source/core/types/ut_logical_suite.tps +++ b/source/core/types/ut_logical_suite.tps @@ -1,7 +1,7 @@ create or replace type ut_logical_suite under ut_suite_item ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_object_name.tpb b/source/core/types/ut_object_name.tpb index c02710405..299b6e269 100644 --- a/source/core/types/ut_object_name.tpb +++ b/source/core/types/ut_object_name.tpb @@ -1,7 +1,7 @@ create or replace type body ut_object_name as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_object_name.tps b/source/core/types/ut_object_name.tps index 521985c23..12afa69dd 100644 --- a/source/core/types/ut_object_name.tps +++ b/source/core/types/ut_object_name.tps @@ -1,7 +1,7 @@ create or replace type ut_object_name as object ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_object_names.tps b/source/core/types/ut_object_names.tps index 80c5a67ee..f46580172 100644 --- a/source/core/types/ut_object_names.tps +++ b/source/core/types/ut_object_names.tps @@ -1,7 +1,7 @@ create or replace type ut_object_names as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_output_reporter_base.tpb b/source/core/types/ut_output_reporter_base.tpb index d83f72792..32e8b225b 100644 --- a/source/core/types/ut_output_reporter_base.tpb +++ b/source/core/types/ut_output_reporter_base.tpb @@ -1,7 +1,7 @@ create or replace type body ut_output_reporter_base is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_output_reporter_base.tps b/source/core/types/ut_output_reporter_base.tps index 776711fad..a0a9f63f6 100644 --- a/source/core/types/ut_output_reporter_base.tps +++ b/source/core/types/ut_output_reporter_base.tps @@ -1,7 +1,7 @@ create or replace type ut_output_reporter_base under ut_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_reporter_base.tpb b/source/core/types/ut_reporter_base.tpb index d86118bdd..487b7685e 100644 --- a/source/core/types/ut_reporter_base.tpb +++ b/source/core/types/ut_reporter_base.tpb @@ -1,7 +1,7 @@ create or replace type body ut_reporter_base is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_reporter_base.tps b/source/core/types/ut_reporter_base.tps index 2b5f8d853..9543486f1 100644 --- a/source/core/types/ut_reporter_base.tps +++ b/source/core/types/ut_reporter_base.tps @@ -1,7 +1,7 @@ create or replace type ut_reporter_base under ut_event_listener ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_reporters.tps b/source/core/types/ut_reporters.tps index 08425b8f4..7df85c2f3 100644 --- a/source/core/types/ut_reporters.tps +++ b/source/core/types/ut_reporters.tps @@ -1,7 +1,7 @@ create or replace type ut_reporters as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_results_counter.tpb b/source/core/types/ut_results_counter.tpb index 04db4ad64..2378bf640 100644 --- a/source/core/types/ut_results_counter.tpb +++ b/source/core/types/ut_results_counter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_results_counter as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_results_counter.tps b/source/core/types/ut_results_counter.tps index 5bedb9072..c3ed97d71 100644 --- a/source/core/types/ut_results_counter.tps +++ b/source/core/types/ut_results_counter.tps @@ -1,7 +1,7 @@ create or replace type ut_results_counter as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb index a282bcfdb..0db9f38c0 100644 --- a/source/core/types/ut_run.tpb +++ b/source/core/types/ut_run.tpb @@ -1,7 +1,7 @@ create or replace type body ut_run as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_run.tps b/source/core/types/ut_run.tps index 0f1c71ca7..5dc8e0399 100644 --- a/source/core/types/ut_run.tps +++ b/source/core/types/ut_run.tps @@ -1,7 +1,7 @@ create or replace type ut_run under ut_suite_item ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_suite.tpb b/source/core/types/ut_suite.tpb index 1c5663dd9..9d9a60e8d 100644 --- a/source/core/types/ut_suite.tpb +++ b/source/core/types/ut_suite.tpb @@ -1,7 +1,7 @@ create or replace type body ut_suite as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_suite.tps b/source/core/types/ut_suite.tps index 866eefc80..f56d95c08 100644 --- a/source/core/types/ut_suite.tps +++ b/source/core/types/ut_suite.tps @@ -1,7 +1,7 @@ create or replace type ut_suite under ut_logical_suite ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_suite_context.tpb b/source/core/types/ut_suite_context.tpb index d09fb824f..a4add114b 100644 --- a/source/core/types/ut_suite_context.tpb +++ b/source/core/types/ut_suite_context.tpb @@ -1,7 +1,7 @@ create or replace type body ut_suite_context as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_suite_context.tps b/source/core/types/ut_suite_context.tps index ea7d6d31c..345c12a65 100644 --- a/source/core/types/ut_suite_context.tps +++ b/source/core/types/ut_suite_context.tps @@ -1,7 +1,7 @@ create or replace type ut_suite_context under ut_suite ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_suite_item.tpb b/source/core/types/ut_suite_item.tpb index b63ed9931..a3319a4d8 100644 --- a/source/core/types/ut_suite_item.tpb +++ b/source/core/types/ut_suite_item.tpb @@ -1,7 +1,7 @@ create or replace type body ut_suite_item as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_suite_item.tps b/source/core/types/ut_suite_item.tps index 5973f9bd9..52b6a2a19 100644 --- a/source/core/types/ut_suite_item.tps +++ b/source/core/types/ut_suite_item.tps @@ -1,7 +1,7 @@ create or replace type ut_suite_item force under ut_event_item ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_suite_items.tps b/source/core/types/ut_suite_items.tps index 9d4c3ab4d..ff5709ca8 100644 --- a/source/core/types/ut_suite_items.tps +++ b/source/core/types/ut_suite_items.tps @@ -1,7 +1,7 @@ create or replace type ut_suite_items as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_test.tpb b/source/core/types/ut_test.tpb index 88250fac2..f6495ecd6 100644 --- a/source/core/types/ut_test.tpb +++ b/source/core/types/ut_test.tpb @@ -1,7 +1,7 @@ create or replace type body ut_test as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_test.tps b/source/core/types/ut_test.tps index e8ecd3cb4..d26e220b9 100644 --- a/source/core/types/ut_test.tps +++ b/source/core/types/ut_test.tps @@ -1,7 +1,7 @@ create or replace type ut_test under ut_suite_item ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_varchar2_list.tps b/source/core/types/ut_varchar2_list.tps index 062852f29..f324a2842 100644 --- a/source/core/types/ut_varchar2_list.tps +++ b/source/core/types/ut_varchar2_list.tps @@ -1,7 +1,7 @@ create or replace type ut_varchar2_list as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/types/ut_varchar2_rows.tps b/source/core/types/ut_varchar2_rows.tps index 7149f6930..ba8962378 100644 --- a/source/core/types/ut_varchar2_rows.tps +++ b/source/core/types/ut_varchar2_rows.tps @@ -1,7 +1,7 @@ create or replace type ut_varchar2_rows as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_dbms_output_cache.sql b/source/core/ut_dbms_output_cache.sql index 91aba0ba5..2102ab4ee 100644 --- a/source/core/ut_dbms_output_cache.sql +++ b/source/core/ut_dbms_output_cache.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 -Copyright 2016 - 2017 utPLSQL Project +Copyright 2016 - 2018 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 diff --git a/source/core/ut_expectation_processor.pkb b/source/core/ut_expectation_processor.pkb index d1c9d6cc5..45dfb7dee 100644 --- a/source/core/ut_expectation_processor.pkb +++ b/source/core/ut_expectation_processor.pkb @@ -1,7 +1,7 @@ create or replace package body ut_expectation_processor as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_expectation_processor.pks b/source/core/ut_expectation_processor.pks index 9f7705761..f5d13ccb6 100644 --- a/source/core/ut_expectation_processor.pks +++ b/source/core/ut_expectation_processor.pks @@ -1,7 +1,7 @@ create or replace package ut_expectation_processor authid current_user as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_file_mapper.pkb b/source/core/ut_file_mapper.pkb index 7125efa09..35233b57b 100644 --- a/source/core/ut_file_mapper.pkb +++ b/source/core/ut_file_mapper.pkb @@ -1,7 +1,7 @@ create or replace package body ut_file_mapper is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_file_mapper.pks b/source/core/ut_file_mapper.pks index f16913e98..5402ef6e8 100644 --- a/source/core/ut_file_mapper.pks +++ b/source/core/ut_file_mapper.pks @@ -1,7 +1,7 @@ create or replace package ut_file_mapper authid current_user is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_metadata.pkb b/source/core/ut_metadata.pkb index 631f152df..30b0da64e 100644 --- a/source/core/ut_metadata.pkb +++ b/source/core/ut_metadata.pkb @@ -1,7 +1,7 @@ create or replace package body ut_metadata as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_metadata.pks b/source/core/ut_metadata.pks index 380047e11..121524a0b 100644 --- a/source/core/ut_metadata.pks +++ b/source/core/ut_metadata.pks @@ -1,7 +1,7 @@ create or replace package ut_metadata authid current_user as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index 3a9593906..8558b4331 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -1,7 +1,7 @@ create or replace package body ut_suite_builder is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_suite_builder.pks b/source/core/ut_suite_builder.pks index 43ea29c85..2ae40f4d3 100644 --- a/source/core/ut_suite_builder.pks +++ b/source/core/ut_suite_builder.pks @@ -1,7 +1,7 @@ create or replace package ut_suite_builder authid current_user is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index dccd745d2..ca438813d 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -1,7 +1,7 @@ create or replace package body ut_suite_manager is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_suite_manager.pks b/source/core/ut_suite_manager.pks index f35ddb4b3..3fde7f6b5 100644 --- a/source/core/ut_suite_manager.pks +++ b/source/core/ut_suite_manager.pks @@ -1,7 +1,7 @@ create or replace package ut_suite_manager authid current_user is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_utils.pkb b/source/core/ut_utils.pkb index 7130ff6c5..2528c04e7 100644 --- a/source/core/ut_utils.pkb +++ b/source/core/ut_utils.pkb @@ -1,7 +1,7 @@ create or replace package body ut_utils is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 2c7f764cd..b5dbf1d89 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -1,7 +1,7 @@ create or replace package ut_utils authid definer is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql index e2cc450f5..17452ec0c 100644 --- a/source/create_synonyms_and_grants_for_public.sql +++ b/source/create_synonyms_and_grants_for_public.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/create_user_grants.sql b/source/create_user_grants.sql index 112317027..bae0364be 100644 --- a/source/create_user_grants.sql +++ b/source/create_user_grants.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/create_user_synonyms.sql b/source/create_user_synonyms.sql index b16b0683c..9a087f61a 100644 --- a/source/create_user_synonyms.sql +++ b/source/create_user_synonyms.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/create_utplsql_owner.sql b/source/create_utplsql_owner.sql index 368206d60..6bdda5611 100644 --- a/source/create_utplsql_owner.sql +++ b/source/create_utplsql_owner.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/define_ut3_owner_param.sql b/source/define_ut3_owner_param.sql index 7d4cd0287..a889ead05 100644 --- a/source/define_ut3_owner_param.sql +++ b/source/define_ut3_owner_param.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_compound_data_diff_tmp.sql b/source/expectations/data_values/ut_compound_data_diff_tmp.sql index 27f95907b..a7959d4aa 100644 --- a/source/expectations/data_values/ut_compound_data_diff_tmp.sql +++ b/source/expectations/data_values/ut_compound_data_diff_tmp.sql @@ -1,7 +1,7 @@ create global temporary table ut_compound_data_diff_tmp( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 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 diff --git a/source/expectations/data_values/ut_compound_data_helper.pkb b/source/expectations/data_values/ut_compound_data_helper.pkb index bde359738..ee01819d6 100644 --- a/source/expectations/data_values/ut_compound_data_helper.pkb +++ b/source/expectations/data_values/ut_compound_data_helper.pkb @@ -1,7 +1,7 @@ create or replace package body ut_compound_data_helper is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_compound_data_helper.pks b/source/expectations/data_values/ut_compound_data_helper.pks index da2863667..ab3693920 100644 --- a/source/expectations/data_values/ut_compound_data_helper.pks +++ b/source/expectations/data_values/ut_compound_data_helper.pks @@ -1,7 +1,7 @@ create or replace package ut_compound_data_helper authid definer is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_compound_data_tmp.sql b/source/expectations/data_values/ut_compound_data_tmp.sql index 827ab9066..a4c6516af 100644 --- a/source/expectations/data_values/ut_compound_data_tmp.sql +++ b/source/expectations/data_values/ut_compound_data_tmp.sql @@ -1,7 +1,7 @@ create global temporary table ut_compound_data_tmp( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 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 diff --git a/source/expectations/data_values/ut_compound_data_value.tpb b/source/expectations/data_values/ut_compound_data_value.tpb index 2d7f5ff65..113c5153e 100644 --- a/source/expectations/data_values/ut_compound_data_value.tpb +++ b/source/expectations/data_values/ut_compound_data_value.tpb @@ -1,7 +1,7 @@ create or replace type body ut_compound_data_value as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_compound_data_value.tps b/source/expectations/data_values/ut_compound_data_value.tps index f95fa478c..bf942c92e 100644 --- a/source/expectations/data_values/ut_compound_data_value.tps +++ b/source/expectations/data_values/ut_compound_data_value.tps @@ -1,7 +1,7 @@ create or replace type ut_compound_data_value force under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value.tpb b/source/expectations/data_values/ut_data_value.tpb index db7d29763..4237ba040 100644 --- a/source/expectations/data_values/ut_data_value.tpb +++ b/source/expectations/data_values/ut_data_value.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value.tps b/source/expectations/data_values/ut_data_value.tps index e9ad68bba..793a25942 100644 --- a/source/expectations/data_values/ut_data_value.tps +++ b/source/expectations/data_values/ut_data_value.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value force authid current_user as object ( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_anydata.tpb b/source/expectations/data_values/ut_data_value_anydata.tpb index be91c2d4a..7d5322cca 100644 --- a/source/expectations/data_values/ut_data_value_anydata.tpb +++ b/source/expectations/data_values/ut_data_value_anydata.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_anydata as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_anydata.tps b/source/expectations/data_values/ut_data_value_anydata.tps index 91d66c7bd..caabe36b6 100644 --- a/source/expectations/data_values/ut_data_value_anydata.tps +++ b/source/expectations/data_values/ut_data_value_anydata.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_anydata under ut_compound_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_blob.tpb b/source/expectations/data_values/ut_data_value_blob.tpb index 0f7f1d758..c597af023 100644 --- a/source/expectations/data_values/ut_data_value_blob.tpb +++ b/source/expectations/data_values/ut_data_value_blob.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_blob as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_blob.tps b/source/expectations/data_values/ut_data_value_blob.tps index 8ebfffc3e..ed6aa2afe 100644 --- a/source/expectations/data_values/ut_data_value_blob.tps +++ b/source/expectations/data_values/ut_data_value_blob.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_blob under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_boolean.tpb b/source/expectations/data_values/ut_data_value_boolean.tpb index 2443ed2d1..bc8c1e2f9 100644 --- a/source/expectations/data_values/ut_data_value_boolean.tpb +++ b/source/expectations/data_values/ut_data_value_boolean.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_boolean as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_boolean.tps b/source/expectations/data_values/ut_data_value_boolean.tps index eef4f88cd..62b413e10 100644 --- a/source/expectations/data_values/ut_data_value_boolean.tps +++ b/source/expectations/data_values/ut_data_value_boolean.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_boolean under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_clob.tpb b/source/expectations/data_values/ut_data_value_clob.tpb index 289a3a73c..7b7c7ffd8 100644 --- a/source/expectations/data_values/ut_data_value_clob.tpb +++ b/source/expectations/data_values/ut_data_value_clob.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_clob as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_clob.tps b/source/expectations/data_values/ut_data_value_clob.tps index d72e05926..4212efb3c 100644 --- a/source/expectations/data_values/ut_data_value_clob.tps +++ b/source/expectations/data_values/ut_data_value_clob.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_clob under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_collection.tpb b/source/expectations/data_values/ut_data_value_collection.tpb index fa91a1fb4..15298c801 100644 --- a/source/expectations/data_values/ut_data_value_collection.tpb +++ b/source/expectations/data_values/ut_data_value_collection.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_collection as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_collection.tps b/source/expectations/data_values/ut_data_value_collection.tps index e375e27d0..7c5d5285c 100644 --- a/source/expectations/data_values/ut_data_value_collection.tps +++ b/source/expectations/data_values/ut_data_value_collection.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_collection under ut_data_value_anydata( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_date.tpb b/source/expectations/data_values/ut_data_value_date.tpb index 3c1e51622..727f624d4 100644 --- a/source/expectations/data_values/ut_data_value_date.tpb +++ b/source/expectations/data_values/ut_data_value_date.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_date as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_date.tps b/source/expectations/data_values/ut_data_value_date.tps index 93068f7ee..e1c358789 100644 --- a/source/expectations/data_values/ut_data_value_date.tps +++ b/source/expectations/data_values/ut_data_value_date.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_date under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_dsinterval.tpb b/source/expectations/data_values/ut_data_value_dsinterval.tpb index 78789da54..6b49a5d1c 100644 --- a/source/expectations/data_values/ut_data_value_dsinterval.tpb +++ b/source/expectations/data_values/ut_data_value_dsinterval.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_dsinterval as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_dsinterval.tps b/source/expectations/data_values/ut_data_value_dsinterval.tps index 13fbb133a..2d3ad48f0 100644 --- a/source/expectations/data_values/ut_data_value_dsinterval.tps +++ b/source/expectations/data_values/ut_data_value_dsinterval.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_dsinterval under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_number.tpb b/source/expectations/data_values/ut_data_value_number.tpb index 42a364f7c..cbd524f42 100644 --- a/source/expectations/data_values/ut_data_value_number.tpb +++ b/source/expectations/data_values/ut_data_value_number.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_number as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_number.tps b/source/expectations/data_values/ut_data_value_number.tps index db144ded1..674dd89fe 100644 --- a/source/expectations/data_values/ut_data_value_number.tps +++ b/source/expectations/data_values/ut_data_value_number.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_number under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_object.tpb b/source/expectations/data_values/ut_data_value_object.tpb index c3c26f4bc..89e49abc1 100644 --- a/source/expectations/data_values/ut_data_value_object.tpb +++ b/source/expectations/data_values/ut_data_value_object.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_object as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_object.tps b/source/expectations/data_values/ut_data_value_object.tps index 3cc6ee051..cf1dc631d 100644 --- a/source/expectations/data_values/ut_data_value_object.tps +++ b/source/expectations/data_values/ut_data_value_object.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_object under ut_data_value_anydata( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_refcursor.tpb b/source/expectations/data_values/ut_data_value_refcursor.tpb index 701b01d3c..1c7619be0 100644 --- a/source/expectations/data_values/ut_data_value_refcursor.tpb +++ b/source/expectations/data_values/ut_data_value_refcursor.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_refcursor as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_refcursor.tps b/source/expectations/data_values/ut_data_value_refcursor.tps index 27f4a4d7c..02ded0b39 100644 --- a/source/expectations/data_values/ut_data_value_refcursor.tps +++ b/source/expectations/data_values/ut_data_value_refcursor.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_refcursor under ut_compound_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_timestamp.tpb b/source/expectations/data_values/ut_data_value_timestamp.tpb index f03045943..7b9d15e41 100644 --- a/source/expectations/data_values/ut_data_value_timestamp.tpb +++ b/source/expectations/data_values/ut_data_value_timestamp.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_timestamp as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_timestamp.tps b/source/expectations/data_values/ut_data_value_timestamp.tps index 52b7edf16..e32f855a6 100644 --- a/source/expectations/data_values/ut_data_value_timestamp.tps +++ b/source/expectations/data_values/ut_data_value_timestamp.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_timestamp under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb b/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb index e780748d9..8abbfce12 100644 --- a/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb +++ b/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_timestamp_ltz as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_timestamp_ltz.tps b/source/expectations/data_values/ut_data_value_timestamp_ltz.tps index f13c9771c..869197c98 100644 --- a/source/expectations/data_values/ut_data_value_timestamp_ltz.tps +++ b/source/expectations/data_values/ut_data_value_timestamp_ltz.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_timestamp_ltz under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_timestamp_tz.tpb b/source/expectations/data_values/ut_data_value_timestamp_tz.tpb index 4ce44d39e..a61d60e33 100644 --- a/source/expectations/data_values/ut_data_value_timestamp_tz.tpb +++ b/source/expectations/data_values/ut_data_value_timestamp_tz.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_timestamp_tz as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_timestamp_tz.tps b/source/expectations/data_values/ut_data_value_timestamp_tz.tps index 83a7bc3cc..55aa3a803 100644 --- a/source/expectations/data_values/ut_data_value_timestamp_tz.tps +++ b/source/expectations/data_values/ut_data_value_timestamp_tz.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_timestamp_tz under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_varchar2.tpb b/source/expectations/data_values/ut_data_value_varchar2.tpb index 7b0d8a862..4f80ee161 100644 --- a/source/expectations/data_values/ut_data_value_varchar2.tpb +++ b/source/expectations/data_values/ut_data_value_varchar2.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_varchar2 as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_varchar2.tps b/source/expectations/data_values/ut_data_value_varchar2.tps index 5687a27c9..ce5954a09 100644 --- a/source/expectations/data_values/ut_data_value_varchar2.tps +++ b/source/expectations/data_values/ut_data_value_varchar2.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_varchar2 under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_xmltype.tpb b/source/expectations/data_values/ut_data_value_xmltype.tpb index 237a7e592..ecefb664d 100644 --- a/source/expectations/data_values/ut_data_value_xmltype.tpb +++ b/source/expectations/data_values/ut_data_value_xmltype.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_xmltype as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_xmltype.tps b/source/expectations/data_values/ut_data_value_xmltype.tps index 2bc4ae985..42c54ae05 100644 --- a/source/expectations/data_values/ut_data_value_xmltype.tps +++ b/source/expectations/data_values/ut_data_value_xmltype.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_xmltype under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_yminterval.tpb b/source/expectations/data_values/ut_data_value_yminterval.tpb index 8b37f6bfd..38f3cf857 100644 --- a/source/expectations/data_values/ut_data_value_yminterval.tpb +++ b/source/expectations/data_values/ut_data_value_yminterval.tpb @@ -1,7 +1,7 @@ create or replace type body ut_data_value_yminterval as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_data_value_yminterval.tps b/source/expectations/data_values/ut_data_value_yminterval.tps index b0b9b0773..efc9e0e48 100644 --- a/source/expectations/data_values/ut_data_value_yminterval.tps +++ b/source/expectations/data_values/ut_data_value_yminterval.tps @@ -1,7 +1,7 @@ create or replace type ut_data_value_yminterval under ut_data_value( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_key_anyval_pair.tps b/source/expectations/data_values/ut_key_anyval_pair.tps index 8fb4831c0..e0701ef28 100644 --- a/source/expectations/data_values/ut_key_anyval_pair.tps +++ b/source/expectations/data_values/ut_key_anyval_pair.tps @@ -1,7 +1,7 @@ create or replace type ut_key_anyval_pair force as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/data_values/ut_key_anyval_pairs.tps b/source/expectations/data_values/ut_key_anyval_pairs.tps index ccf4ce047..40748c5a5 100644 --- a/source/expectations/data_values/ut_key_anyval_pairs.tps +++ b/source/expectations/data_values/ut_key_anyval_pairs.tps @@ -1,7 +1,7 @@ create or replace type ut_key_anyval_pairs as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_between.tpb b/source/expectations/matchers/ut_be_between.tpb index 19e4ea8c2..f4bf24aab 100644 --- a/source/expectations/matchers/ut_be_between.tpb +++ b/source/expectations/matchers/ut_be_between.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_between is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_between.tps b/source/expectations/matchers/ut_be_between.tps index ae49fcfec..79c4ec2fe 100644 --- a/source/expectations/matchers/ut_be_between.tps +++ b/source/expectations/matchers/ut_be_between.tps @@ -1,7 +1,7 @@ create or replace type ut_be_between under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_empty.tpb b/source/expectations/matchers/ut_be_empty.tpb index 7bf9bdd84..82ad95d5a 100644 --- a/source/expectations/matchers/ut_be_empty.tpb +++ b/source/expectations/matchers/ut_be_empty.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_empty as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_empty.tps b/source/expectations/matchers/ut_be_empty.tps index 4908d3b8f..0acb80e55 100644 --- a/source/expectations/matchers/ut_be_empty.tps +++ b/source/expectations/matchers/ut_be_empty.tps @@ -1,7 +1,7 @@ create or replace type ut_be_empty under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_false.tpb b/source/expectations/matchers/ut_be_false.tpb index 73e5477d8..6e2f3ba1f 100644 --- a/source/expectations/matchers/ut_be_false.tpb +++ b/source/expectations/matchers/ut_be_false.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_false as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_false.tps b/source/expectations/matchers/ut_be_false.tps index 09e9ead6f..06bb290d4 100644 --- a/source/expectations/matchers/ut_be_false.tps +++ b/source/expectations/matchers/ut_be_false.tps @@ -1,7 +1,7 @@ create or replace type ut_be_false under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_greater_or_equal.tpb b/source/expectations/matchers/ut_be_greater_or_equal.tpb index 69f0196fe..978d821e1 100644 --- a/source/expectations/matchers/ut_be_greater_or_equal.tpb +++ b/source/expectations/matchers/ut_be_greater_or_equal.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_greater_or_equal AS /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_greater_or_equal.tps b/source/expectations/matchers/ut_be_greater_or_equal.tps index d6f93940f..b97589bb0 100644 --- a/source/expectations/matchers/ut_be_greater_or_equal.tps +++ b/source/expectations/matchers/ut_be_greater_or_equal.tps @@ -1,7 +1,7 @@ create or replace type ut_be_greater_or_equal under ut_comparison_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_greater_than.tpb b/source/expectations/matchers/ut_be_greater_than.tpb index 56046e1c6..b7b52af9a 100644 --- a/source/expectations/matchers/ut_be_greater_than.tpb +++ b/source/expectations/matchers/ut_be_greater_than.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_greater_than AS /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_greater_than.tps b/source/expectations/matchers/ut_be_greater_than.tps index 830f9ef93..9963a6277 100644 --- a/source/expectations/matchers/ut_be_greater_than.tps +++ b/source/expectations/matchers/ut_be_greater_than.tps @@ -1,7 +1,7 @@ create or replace type ut_be_greater_than under ut_comparison_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_less_or_equal.tpb b/source/expectations/matchers/ut_be_less_or_equal.tpb index 67eb6095b..6f6b7febd 100644 --- a/source/expectations/matchers/ut_be_less_or_equal.tpb +++ b/source/expectations/matchers/ut_be_less_or_equal.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_less_or_equal AS /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_less_or_equal.tps b/source/expectations/matchers/ut_be_less_or_equal.tps index 4f6bef34b..a9fe9492b 100644 --- a/source/expectations/matchers/ut_be_less_or_equal.tps +++ b/source/expectations/matchers/ut_be_less_or_equal.tps @@ -1,7 +1,7 @@ create or replace type ut_be_less_or_equal under ut_comparison_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_less_than.tpb b/source/expectations/matchers/ut_be_less_than.tpb index ea759e601..7d3e06d62 100644 --- a/source/expectations/matchers/ut_be_less_than.tpb +++ b/source/expectations/matchers/ut_be_less_than.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_less_than as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_less_than.tps b/source/expectations/matchers/ut_be_less_than.tps index e9d290d91..f6ae1f0e4 100644 --- a/source/expectations/matchers/ut_be_less_than.tps +++ b/source/expectations/matchers/ut_be_less_than.tps @@ -1,7 +1,7 @@ create or replace type ut_be_less_than under ut_comparison_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_like.tpb b/source/expectations/matchers/ut_be_like.tpb index d673d7194..315f43d6c 100644 --- a/source/expectations/matchers/ut_be_like.tpb +++ b/source/expectations/matchers/ut_be_like.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_like as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_like.tps b/source/expectations/matchers/ut_be_like.tps index 78f262d60..1e8430e32 100644 --- a/source/expectations/matchers/ut_be_like.tps +++ b/source/expectations/matchers/ut_be_like.tps @@ -1,7 +1,7 @@ create or replace type ut_be_like under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_not_null.tpb b/source/expectations/matchers/ut_be_not_null.tpb index c2adbb259..595a94b75 100644 --- a/source/expectations/matchers/ut_be_not_null.tpb +++ b/source/expectations/matchers/ut_be_not_null.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_not_null as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_not_null.tps b/source/expectations/matchers/ut_be_not_null.tps index aba8a9b69..42e899701 100644 --- a/source/expectations/matchers/ut_be_not_null.tps +++ b/source/expectations/matchers/ut_be_not_null.tps @@ -1,7 +1,7 @@ create or replace type ut_be_not_null under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_null.tpb b/source/expectations/matchers/ut_be_null.tpb index 96219807e..82a4391d6 100644 --- a/source/expectations/matchers/ut_be_null.tpb +++ b/source/expectations/matchers/ut_be_null.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_null as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_null.tps b/source/expectations/matchers/ut_be_null.tps index 2870a0253..ef30feea1 100644 --- a/source/expectations/matchers/ut_be_null.tps +++ b/source/expectations/matchers/ut_be_null.tps @@ -1,7 +1,7 @@ create or replace type ut_be_null under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_true.tpb b/source/expectations/matchers/ut_be_true.tpb index 6b99fe35b..3c83002e0 100644 --- a/source/expectations/matchers/ut_be_true.tpb +++ b/source/expectations/matchers/ut_be_true.tpb @@ -1,7 +1,7 @@ create or replace type body ut_be_true as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_be_true.tps b/source/expectations/matchers/ut_be_true.tps index adf362884..f73c7700b 100644 --- a/source/expectations/matchers/ut_be_true.tps +++ b/source/expectations/matchers/ut_be_true.tps @@ -1,7 +1,7 @@ create or replace type ut_be_true under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_comparison_matcher.tpb b/source/expectations/matchers/ut_comparison_matcher.tpb index b1baf2f5d..6eec4c11a 100644 --- a/source/expectations/matchers/ut_comparison_matcher.tpb +++ b/source/expectations/matchers/ut_comparison_matcher.tpb @@ -1,7 +1,7 @@ create or replace type body ut_comparison_matcher as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_comparison_matcher.tps b/source/expectations/matchers/ut_comparison_matcher.tps index 108b516a1..d66ad8b56 100644 --- a/source/expectations/matchers/ut_comparison_matcher.tps +++ b/source/expectations/matchers/ut_comparison_matcher.tps @@ -1,7 +1,7 @@ create or replace type ut_comparison_matcher under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_equal.tpb b/source/expectations/matchers/ut_equal.tpb index 3a163e9c9..611b1cd1c 100644 --- a/source/expectations/matchers/ut_equal.tpb +++ b/source/expectations/matchers/ut_equal.tpb @@ -1,7 +1,7 @@ create or replace type body ut_equal as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_equal.tps b/source/expectations/matchers/ut_equal.tps index 01b1d2e1e..9968dba7f 100644 --- a/source/expectations/matchers/ut_equal.tps +++ b/source/expectations/matchers/ut_equal.tps @@ -1,7 +1,7 @@ create or replace type ut_equal under ut_comparison_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_have_count.tpb b/source/expectations/matchers/ut_have_count.tpb index aad54f0ce..de2d64d1c 100644 --- a/source/expectations/matchers/ut_have_count.tpb +++ b/source/expectations/matchers/ut_have_count.tpb @@ -1,7 +1,7 @@ create or replace type body ut_have_count as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_have_count.tps b/source/expectations/matchers/ut_have_count.tps index e7f59e374..dc4511d72 100644 --- a/source/expectations/matchers/ut_have_count.tps +++ b/source/expectations/matchers/ut_have_count.tps @@ -1,7 +1,7 @@ create or replace type ut_have_count under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_match.tpb b/source/expectations/matchers/ut_match.tpb index 719368875..f85af4aac 100644 --- a/source/expectations/matchers/ut_match.tpb +++ b/source/expectations/matchers/ut_match.tpb @@ -1,7 +1,7 @@ create or replace type body ut_match as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_match.tps b/source/expectations/matchers/ut_match.tps index f43b2e296..ca9fcd34c 100644 --- a/source/expectations/matchers/ut_match.tps +++ b/source/expectations/matchers/ut_match.tps @@ -1,7 +1,7 @@ create or replace type ut_match under ut_matcher( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_matcher.tpb b/source/expectations/matchers/ut_matcher.tpb index d0c4d6c0a..78b05a827 100644 --- a/source/expectations/matchers/ut_matcher.tpb +++ b/source/expectations/matchers/ut_matcher.tpb @@ -1,7 +1,7 @@ create or replace type body ut_matcher as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/matchers/ut_matcher.tps b/source/expectations/matchers/ut_matcher.tps index a9d336b77..7aefb8ad9 100644 --- a/source/expectations/matchers/ut_matcher.tps +++ b/source/expectations/matchers/ut_matcher.tps @@ -1,7 +1,7 @@ create or replace type ut_matcher authid current_user as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/ut_expectation.tpb b/source/expectations/ut_expectation.tpb index 6d668b6b8..26e0c1092 100644 --- a/source/expectations/ut_expectation.tpb +++ b/source/expectations/ut_expectation.tpb @@ -1,7 +1,7 @@ create or replace type body ut_expectation as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/ut_expectation.tps b/source/expectations/ut_expectation.tps index 218fc51b0..d27a18377 100644 --- a/source/expectations/ut_expectation.tps +++ b/source/expectations/ut_expectation.tps @@ -1,7 +1,7 @@ create or replace type ut_expectation authid current_user as object( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/ut_expectation_compound.tpb b/source/expectations/ut_expectation_compound.tpb index dea146bd2..c620ec39c 100644 --- a/source/expectations/ut_expectation_compound.tpb +++ b/source/expectations/ut_expectation_compound.tpb @@ -1,7 +1,7 @@ create or replace type body ut_expectation_compound as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/expectations/ut_expectation_compound.tps b/source/expectations/ut_expectation_compound.tps index 967706a21..529b8875d 100644 --- a/source/expectations/ut_expectation_compound.tps +++ b/source/expectations/ut_expectation_compound.tps @@ -1,7 +1,7 @@ create or replace type ut_expectation_compound under ut_expectation( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/install.sql b/source/install.sql index 07227c316..902b45aba 100644 --- a/source/install.sql +++ b/source/install.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/install_component.sql b/source/install_component.sql index 5a9fc7e56..16c4cd8a0 100644 --- a/source/install_component.sql +++ b/source/install_component.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/install_headless.sql b/source/install_headless.sql index 1b73cb953..8acc080fa 100644 --- a/source/install_headless.sql +++ b/source/install_headless.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_ansiconsole_helper.pkb b/source/reporters/ut_ansiconsole_helper.pkb index 290dc9caa..ceb0cf53f 100644 --- a/source/reporters/ut_ansiconsole_helper.pkb +++ b/source/reporters/ut_ansiconsole_helper.pkb @@ -1,7 +1,7 @@ create or replace package body ut_ansiconsole_helper as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_ansiconsole_helper.pks b/source/reporters/ut_ansiconsole_helper.pks index 718cac061..29d746c7b 100644 --- a/source/reporters/ut_ansiconsole_helper.pks +++ b/source/reporters/ut_ansiconsole_helper.pks @@ -1,7 +1,7 @@ create or replace package ut_ansiconsole_helper as /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coverage_cobertura_reporter.tpb b/source/reporters/ut_coverage_cobertura_reporter.tpb index cce2224df..0d702dbbd 100644 --- a/source/reporters/ut_coverage_cobertura_reporter.tpb +++ b/source/reporters/ut_coverage_cobertura_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_coverage_cobertura_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coverage_cobertura_reporter.tps b/source/reporters/ut_coverage_cobertura_reporter.tps index 9b50a3922..6bfd60892 100644 --- a/source/reporters/ut_coverage_cobertura_reporter.tps +++ b/source/reporters/ut_coverage_cobertura_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_coverage_cobertura_reporter under ut_coverage_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coverage_html_reporter.tpb b/source/reporters/ut_coverage_html_reporter.tpb index 08069ff65..a6b5b4517 100644 --- a/source/reporters/ut_coverage_html_reporter.tpb +++ b/source/reporters/ut_coverage_html_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_coverage_html_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coverage_html_reporter.tps b/source/reporters/ut_coverage_html_reporter.tps index fccfb0e43..11984ac58 100644 --- a/source/reporters/ut_coverage_html_reporter.tps +++ b/source/reporters/ut_coverage_html_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_coverage_html_reporter under ut_coverage_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb index 6b310e1f8..725a232f2 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -1,7 +1,7 @@ create or replace package body ut_coverage_report_html_helper is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coverage_report_html_helper.pks b/source/reporters/ut_coverage_report_html_helper.pks index 8970a235e..d140588ad 100644 --- a/source/reporters/ut_coverage_report_html_helper.pks +++ b/source/reporters/ut_coverage_report_html_helper.pks @@ -1,7 +1,7 @@ create or replace package ut_coverage_report_html_helper authid current_user is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coverage_sonar_reporter.tpb b/source/reporters/ut_coverage_sonar_reporter.tpb index 29d3d351d..249736f92 100644 --- a/source/reporters/ut_coverage_sonar_reporter.tpb +++ b/source/reporters/ut_coverage_sonar_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_coverage_sonar_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coverage_sonar_reporter.tps b/source/reporters/ut_coverage_sonar_reporter.tps index a013ad2fa..af52f1675 100644 --- a/source/reporters/ut_coverage_sonar_reporter.tps +++ b/source/reporters/ut_coverage_sonar_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_coverage_sonar_reporter under ut_coverage_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coveralls_reporter.tpb b/source/reporters/ut_coveralls_reporter.tpb index 96df05483..3681147f3 100644 --- a/source/reporters/ut_coveralls_reporter.tpb +++ b/source/reporters/ut_coveralls_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_coveralls_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_coveralls_reporter.tps b/source/reporters/ut_coveralls_reporter.tps index d62ec5058..b5c1e1f28 100644 --- a/source/reporters/ut_coveralls_reporter.tps +++ b/source/reporters/ut_coveralls_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_coveralls_reporter under ut_coverage_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_documentation_reporter.tpb b/source/reporters/ut_documentation_reporter.tpb index 90a06634e..73ac3bf1a 100644 --- a/source/reporters/ut_documentation_reporter.tpb +++ b/source/reporters/ut_documentation_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_documentation_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_documentation_reporter.tps b/source/reporters/ut_documentation_reporter.tps index 6048eb970..717ab3cd7 100644 --- a/source/reporters/ut_documentation_reporter.tps +++ b/source/reporters/ut_documentation_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_documentation_reporter under ut_console_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_junit_reporter.tpb b/source/reporters/ut_junit_reporter.tpb index 204a39fb4..63d256aab 100644 --- a/source/reporters/ut_junit_reporter.tpb +++ b/source/reporters/ut_junit_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_junit_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_junit_reporter.tps b/source/reporters/ut_junit_reporter.tps index c0c23a693..051358c59 100644 --- a/source/reporters/ut_junit_reporter.tps +++ b/source/reporters/ut_junit_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_junit_reporter force under ut_output_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_sonar_test_reporter.tpb b/source/reporters/ut_sonar_test_reporter.tpb index a410480ae..547ccf9d3 100644 --- a/source/reporters/ut_sonar_test_reporter.tpb +++ b/source/reporters/ut_sonar_test_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_sonar_test_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_sonar_test_reporter.tps b/source/reporters/ut_sonar_test_reporter.tps index f174d5abe..353edbf0d 100644 --- a/source/reporters/ut_sonar_test_reporter.tps +++ b/source/reporters/ut_sonar_test_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_sonar_test_reporter under ut_output_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_teamcity_reporter.tpb b/source/reporters/ut_teamcity_reporter.tpb index 951daba2f..086775254 100644 --- a/source/reporters/ut_teamcity_reporter.tpb +++ b/source/reporters/ut_teamcity_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_teamcity_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_teamcity_reporter.tps b/source/reporters/ut_teamcity_reporter.tps index 71e0be8a1..7f61e2b6e 100644 --- a/source/reporters/ut_teamcity_reporter.tps +++ b/source/reporters/ut_teamcity_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_teamcity_reporter under ut_output_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_teamcity_reporter_helper.pkb b/source/reporters/ut_teamcity_reporter_helper.pkb index 9a5369a64..d3a76e20b 100644 --- a/source/reporters/ut_teamcity_reporter_helper.pkb +++ b/source/reporters/ut_teamcity_reporter_helper.pkb @@ -1,7 +1,7 @@ create or replace package body ut_teamcity_reporter_helper is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_teamcity_reporter_helper.pks b/source/reporters/ut_teamcity_reporter_helper.pks index 8bc12763e..6bab87367 100644 --- a/source/reporters/ut_teamcity_reporter_helper.pks +++ b/source/reporters/ut_teamcity_reporter_helper.pks @@ -1,7 +1,7 @@ create or replace package ut_teamcity_reporter_helper is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_tfs_junit_reporter.tpb b/source/reporters/ut_tfs_junit_reporter.tpb index dbcd558a6..d3edd1208 100644 --- a/source/reporters/ut_tfs_junit_reporter.tpb +++ b/source/reporters/ut_tfs_junit_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_tfs_junit_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_tfs_junit_reporter.tps b/source/reporters/ut_tfs_junit_reporter.tps index 669f79960..9e7a90e0a 100644 --- a/source/reporters/ut_tfs_junit_reporter.tps +++ b/source/reporters/ut_tfs_junit_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_tfs_junit_reporter under ut_output_reporter_base( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_xunit_reporter.tpb b/source/reporters/ut_xunit_reporter.tpb index 04eb48e02..e2deb22ce 100644 --- a/source/reporters/ut_xunit_reporter.tpb +++ b/source/reporters/ut_xunit_reporter.tpb @@ -1,7 +1,7 @@ create or replace type body ut_xunit_reporter is /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/reporters/ut_xunit_reporter.tps b/source/reporters/ut_xunit_reporter.tps index d004f218c..81fa19e5b 100644 --- a/source/reporters/ut_xunit_reporter.tps +++ b/source/reporters/ut_xunit_reporter.tps @@ -1,7 +1,7 @@ create or replace type ut_xunit_reporter under ut_junit_reporter( /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/uninstall.sql b/source/uninstall.sql index 0991d9245..7b927e91d 100644 --- a/source/uninstall.sql +++ b/source/uninstall.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. diff --git a/source/uninstall_all.sql b/source/uninstall_all.sql index 21b567d0e..8d2bf0222 100644 --- a/source/uninstall_all.sql +++ b/source/uninstall_all.sql @@ -1,6 +1,6 @@ /* utPLSQL - Version 3 - Copyright 2016 - 2017 utPLSQL Project + Copyright 2016 - 2018 utPLSQL Project Licensed under the Apache License, Version 2.0 (the "License"): you may not use this file except in compliance with the License. From 3aa44773d72607c9266ca61ca8bccb346a5047f7 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Fri, 27 Jul 2018 18:21:22 +0000 Subject: [PATCH 018/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 2c7f764cd..e182ae374 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2156-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2167-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 37d27b97f925cebebaa686d99bad31e3ce5d4290 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Fri, 27 Jul 2018 20:37:27 +0000 Subject: [PATCH 019/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 96ca11754..14783f526 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2167-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2171-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 8feae1c6a544d821ccab4a03f5455a4a7e63e704 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 29 Jul 2018 16:27:32 +0100 Subject: [PATCH 020/115] Adding timing to docker operations. --- .travis/start_db.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis/start_db.sh b/.travis/start_db.sh index 2f71c07bd..29433a8ff 100644 --- a/.travis/start_db.sh +++ b/.travis/start_db.sh @@ -10,6 +10,6 @@ else mkdir -p $HOME/.docker && cp $CACHE_DIR/.docker/config.json $HOME/.docker/ fi -docker pull $DOCKHER_HUB_REPO:$ORACLE_VERSION +time docker pull $DOCKHER_HUB_REPO:$ORACLE_VERSION docker run -d --name $ORACLE_VERSION $DOCKER_OPTIONS -p 1521:1521 $DOCKHER_HUB_REPO:$ORACLE_VERSION -docker logs -f $ORACLE_VERSION | grep -m 1 "DATABASE IS READY TO USE!" --line-buffered \ No newline at end of file +time docker logs -f $ORACLE_VERSION | grep -m 1 "DATABASE IS READY TO USE!" --line-buffered \ No newline at end of file From 81694a53cdbff0625d4f6af2625fb6e1f17760b7 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 29 Jul 2018 16:31:08 +0100 Subject: [PATCH 021/115] Moved filesystem stats into `start_db.sh` --- .travis.yml | 2 -- .travis/start_db.sh | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e152e13ee..5b82e811a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -80,9 +80,7 @@ install: - bash .travis/install_sqlcl.sh - sudo mkdir -p /dev/pdbs - sudo chmod -R 777 /dev/pdbs - - df -h - if [[ ! $TRAVIS_TAG ]]; then bash .travis/start_db.sh; fi - - df -h before_script: - if [[ ! $TRAVIS_TAG ]]; then bash .travis/install.sh; fi diff --git a/.travis/start_db.sh b/.travis/start_db.sh index 29433a8ff..e42656987 100644 --- a/.travis/start_db.sh +++ b/.travis/start_db.sh @@ -10,6 +10,9 @@ else mkdir -p $HOME/.docker && cp $CACHE_DIR/.docker/config.json $HOME/.docker/ fi +df -h time docker pull $DOCKHER_HUB_REPO:$ORACLE_VERSION +df -h docker run -d --name $ORACLE_VERSION $DOCKER_OPTIONS -p 1521:1521 $DOCKHER_HUB_REPO:$ORACLE_VERSION -time docker logs -f $ORACLE_VERSION | grep -m 1 "DATABASE IS READY TO USE!" --line-buffered \ No newline at end of file +time docker logs -f $ORACLE_VERSION | grep -m 1 "DATABASE IS READY TO USE!" --line-buffered +df -h From 110bfa743b06a31353d9157ec9686355420cb8ea Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 29 Jul 2018 16:37:19 +0100 Subject: [PATCH 022/115] Disabling maven wagon-http --- .travis/maven_cfg.sh | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/.travis/maven_cfg.sh b/.travis/maven_cfg.sh index ef2348099..65dbc9c8f 100644 --- a/.travis/maven_cfg.sh +++ b/.travis/maven_cfg.sh @@ -2,17 +2,20 @@ set -ev cp .travis/settings.xml $MAVEN_CFG/settings.xml -cd $(dirname $(readlink -f $0)) - -# Download wagon-http recommended by Oracle. -# On maven latest version this is not needed, but travis doesn't have it. -if [ ! -f $CACHE_DIR/wagon-http-2.8-shaded.jar ]; then - curl -L -O "http://central.maven.org/maven2/org/apache/maven/wagon/wagon-http/2.8/wagon-http-2.8-shaded.jar" - mv wagon-http-2.8-shaded.jar $CACHE_DIR/ - sudo cp $CACHE_DIR/wagon-http-2.8-shaded.jar $MAVEN_HOME/lib/ext/ -else - echo "Using cached wagon-http..." - sudo cp $CACHE_DIR/wagon-http-2.8-shaded.jar $MAVEN_HOME/lib/ext/ -fi - -mvn dependency:copy-dependencies -DoutputDirectory=../utPLSQL-cli/lib \ No newline at end of file +############################################ +# disabling all the below to check if it's still needed with maven 3.5.2 on Travis +############################################ +#cd $(dirname $(readlink -f $0)) +# +## Download wagon-http recommended by Oracle. +## On maven latest version this is not needed, but travis doesn't have it. +#if [ ! -f $CACHE_DIR/wagon-http-2.8-shaded.jar ]; then +# curl -L -O "http://central.maven.org/maven2/org/apache/maven/wagon/wagon-http/2.8/wagon-http-2.8-shaded.jar" +# mv wagon-http-2.8-shaded.jar $CACHE_DIR/ +# sudo cp $CACHE_DIR/wagon-http-2.8-shaded.jar $MAVEN_HOME/lib/ext/ +#else +# echo "Using cached wagon-http..." +# sudo cp $CACHE_DIR/wagon-http-2.8-shaded.jar $MAVEN_HOME/lib/ext/ +#fi +# +#mvn dependency:copy-dependencies -DoutputDirectory=../utPLSQL-cli/lib \ No newline at end of file From 3021a69d187aa5f6da2473b1c1c2304b20b0115f Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 29 Jul 2018 16:41:53 +0100 Subject: [PATCH 023/115] Removing unneeded (duplicate) warnings on install. --- .travis/install.sh | 1 - .travis/install_utplsql_release.sh | 1 - 2 files changed, 2 deletions(-) diff --git a/.travis/install.sh b/.travis/install.sh index bb99a0e2d..a979f6b2d 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -7,7 +7,6 @@ set -ev set feedback off set verify off -alter session set plsql_warnings = 'ENABLE:ALL', 'DISABLE:(5004,5018,6000,6001,6003,6009,6010,7206)'; @install_headless.sql $UT3_OWNER $UT3_OWNER_PASSWORD SQL diff --git a/.travis/install_utplsql_release.sh b/.travis/install_utplsql_release.sh index f551ff9b5..169634500 100644 --- a/.travis/install_utplsql_release.sh +++ b/.travis/install_utplsql_release.sh @@ -37,7 +37,6 @@ end; SQL "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA < Date: Sun, 29 Jul 2018 16:42:49 +0100 Subject: [PATCH 024/115] Adding `plsql_optimize_level=0` to improve install performance. --- .travis/install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis/install.sh b/.travis/install.sh index a979f6b2d..fb4de5e73 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -7,6 +7,7 @@ set -ev set feedback off set verify off +alter session set plsql_optimize_level=0; @install_headless.sql $UT3_OWNER $UT3_OWNER_PASSWORD SQL From 8a23068808c1bfbde483cf4ac06b0e36b84e5223 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 29 Jul 2018 16:43:27 +0100 Subject: [PATCH 025/115] Adding `plsql_optimize_level=0` to further improve install performance and check impact on test performance. --- .travis/install.sh | 1 + .travis/install_utplsql_release.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis/install.sh b/.travis/install.sh index fb4de5e73..2bd530c9c 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -39,6 +39,7 @@ set feedback off set verify off alter session set plsql_warnings = 'ENABLE:ALL', 'DISABLE:(5004,5018,6000,6001,6003,6009,6010,7206)'; +alter session set plsql_optimize_level=0; @install.sql $UT3_OWNER SQL diff --git a/.travis/install_utplsql_release.sh b/.travis/install_utplsql_release.sh index 169634500..889e098da 100644 --- a/.travis/install_utplsql_release.sh +++ b/.travis/install_utplsql_release.sh @@ -37,6 +37,7 @@ end; SQL "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA < Date: Sun, 29 Jul 2018 17:04:28 +0100 Subject: [PATCH 026/115] Revert "Disabling maven wagon-http" This reverts commit 110bfa7 --- .travis/maven_cfg.sh | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/.travis/maven_cfg.sh b/.travis/maven_cfg.sh index 65dbc9c8f..ef2348099 100644 --- a/.travis/maven_cfg.sh +++ b/.travis/maven_cfg.sh @@ -2,20 +2,17 @@ set -ev cp .travis/settings.xml $MAVEN_CFG/settings.xml -############################################ -# disabling all the below to check if it's still needed with maven 3.5.2 on Travis -############################################ -#cd $(dirname $(readlink -f $0)) -# -## Download wagon-http recommended by Oracle. -## On maven latest version this is not needed, but travis doesn't have it. -#if [ ! -f $CACHE_DIR/wagon-http-2.8-shaded.jar ]; then -# curl -L -O "http://central.maven.org/maven2/org/apache/maven/wagon/wagon-http/2.8/wagon-http-2.8-shaded.jar" -# mv wagon-http-2.8-shaded.jar $CACHE_DIR/ -# sudo cp $CACHE_DIR/wagon-http-2.8-shaded.jar $MAVEN_HOME/lib/ext/ -#else -# echo "Using cached wagon-http..." -# sudo cp $CACHE_DIR/wagon-http-2.8-shaded.jar $MAVEN_HOME/lib/ext/ -#fi -# -#mvn dependency:copy-dependencies -DoutputDirectory=../utPLSQL-cli/lib \ No newline at end of file +cd $(dirname $(readlink -f $0)) + +# Download wagon-http recommended by Oracle. +# On maven latest version this is not needed, but travis doesn't have it. +if [ ! -f $CACHE_DIR/wagon-http-2.8-shaded.jar ]; then + curl -L -O "http://central.maven.org/maven2/org/apache/maven/wagon/wagon-http/2.8/wagon-http-2.8-shaded.jar" + mv wagon-http-2.8-shaded.jar $CACHE_DIR/ + sudo cp $CACHE_DIR/wagon-http-2.8-shaded.jar $MAVEN_HOME/lib/ext/ +else + echo "Using cached wagon-http..." + sudo cp $CACHE_DIR/wagon-http-2.8-shaded.jar $MAVEN_HOME/lib/ext/ +fi + +mvn dependency:copy-dependencies -DoutputDirectory=../utPLSQL-cli/lib \ No newline at end of file From 385450200ecfe2546f808539e00bf683e5e3023e Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 29 Jul 2018 17:27:39 +0100 Subject: [PATCH 027/115] Adding `plsql_optimize_level=0` to tests installation. Adding timing for tests installation and execution. --- test/install_and_run_tests.sh | 4 ++-- test/install_tests.sql | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh index 2c6f78ae1..a1e5e0849 100644 --- a/test/install_and_run_tests.sh +++ b/test/install_and_run_tests.sh @@ -8,11 +8,11 @@ git rev-parse && cd "$(git rev-parse --show-cdup)" cd test -"$SQLCLI" ${UT3_TESTER}/${UT3_TESTER_PASSWORD}@//${CONNECTION_STR} @install_tests.sql +time "$SQLCLI" ${UT3_TESTER}/${UT3_TESTER_PASSWORD}@//${CONNECTION_STR} @install_tests.sql cd .. -utPLSQL-cli/bin/utplsql run ${UT3_TESTER}/${UT3_TESTER_PASSWORD}@${CONNECTION_STR} \ +time utPLSQL-cli/bin/utplsql run ${UT3_TESTER}/${UT3_TESTER_PASSWORD}@${CONNECTION_STR} \ -source_path=source -owner=ut3 \ -test_path=test -c \ -f=ut_documentation_reporter -o=test_results.log -s \ diff --git a/test/install_tests.sql b/test/install_tests.sql index e0a5d6d9f..3e90b1590 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -2,6 +2,7 @@ set define off whenever sqlerror exit failure rollback whenever oserror exit failure rollback +alter session set plsql_optimize_level=0; --Install helpers @@helpers/ut_test_table.sql @@helpers/ut_example_tests.pks From 69d504f3121703c534228e7670f7f47eb65094a8 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 29 Jul 2018 18:44:06 +0100 Subject: [PATCH 028/115] Reworking install script to run some actions only on the first JOB (11g - fastest): - testing of code uninstall process - checking code style validity --- .travis/install.sh | 96 ++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 55 deletions(-) diff --git a/.travis/install.sh b/.travis/install.sh index 2bd530c9c..2f1bdf743 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -2,61 +2,65 @@ cd source set -ev + #install core of utplsql -"$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL +time "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL set feedback off set verify off +alter session set plsql_warnings = 'ENABLE:ALL', 'DISABLE:(5004,5018,6000,6001,6003,6009,6010,7206)'; alter session set plsql_optimize_level=0; @install_headless.sql $UT3_OWNER $UT3_OWNER_PASSWORD SQL -#uninstall core of utplsql -"$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL -set feedback off -set verify off - -@uninstall_all.sql $UT3_OWNER -declare - v_leftover_objects_count integer; -begin - select sum(cnt) - into v_leftover_objects_count - from (select count(1) cnt from dba_objects where owner = '$UT3_OWNER' - union all - select count(1) cnt from dba_synonyms where table_owner = '$UT3_OWNER' - ); - if v_leftover_objects_count > 0 then - raise_application_error(-20000, 'Not all objects were successfully uninstalled - leftover objects count='||v_leftover_objects_count); - end if; -end; -/ +if [ "$TRAVIS_JOB_ID" == "1" ]; then + + #check code-style for errors + time "$SQLCLI" $UT3_OWNER/$UT3_OWNER_PASSWORD@//$CONNECTION_STR @../development/utplsql_style_check.sql + + #test install/uninstall process + time "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL + set feedback off + set verify off + + @uninstall_all.sql $UT3_OWNER + declare + v_leftover_objects_count integer; + begin + select sum(cnt) + into v_leftover_objects_count + from (select count(1) cnt from dba_objects where owner = '$UT3_OWNER' + union all + select count(1) cnt from dba_synonyms where table_owner = '$UT3_OWNER' + ); + if v_leftover_objects_count > 0 then + raise_application_error(-20000, 'Not all objects were successfully uninstalled - leftover objects count='||v_leftover_objects_count); + end if; + end; + / SQL -#reinstall core of utplsql -"$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL -set feedback off -set verify off + time "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL + set feedback off + set verify off -alter session set plsql_warnings = 'ENABLE:ALL', 'DISABLE:(5004,5018,6000,6001,6003,6009,6010,7206)'; -alter session set plsql_optimize_level=0; -@install.sql $UT3_OWNER + alter session set plsql_optimize_level=0; + @install.sql $UT3_OWNER SQL +fi + #additional privileges to run scripted tests -"$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL +time "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL set feedback on --needed for Mystats script to work grant select any dictionary to $UT3_OWNER; --Needed for testing a coverage outside ut3_owner. grant create any procedure, drop any procedure, execute any procedure to $UT3_OWNER; - -conn $UT3_OWNER/$UT3_OWNER_PASSWORD@//$CONNECTION_STR -@../development/utplsql_style_check.sql SQL -#Create additional users -"$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL +#Create user that will own the tests +time "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL set feedback off @create_utplsql_owner.sql $UT3_TESTER $UT3_TESTER_PASSWORD $UT3_TABLESPACE @@ -71,29 +75,11 @@ grant create job to $UT3_TESTER; exit SQL -#additional privileges to run tests -"$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL -set feedback on ---needed for Mystats script to work -grant select any dictionary to $UT3_OWNER; ---Needed for testing a coverage outside ut3_owner. -grant create any procedure, drop any procedure, execute any procedure to $UT3_OWNER; - -exit -SQL - -#Create additional users -"$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL +#Create additional UT3$USER# to test for special characters +time "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL set feedback off @create_utplsql_owner.sql $UT3_USER $UT3_USER_PASSWORD $UT3_TABLESPACE - -exit -SQL - -#Grant UT3 framework to UT3$USER# -"$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL -set feedback off +--Grant UT3 framework to UT3$USER# @create_user_grants.sql $UT3_OWNER $UT3_USER - exit SQL From 591c14b707f03bf579f02ce5ddfca7f17623c5b3 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 29 Jul 2018 18:58:34 +0100 Subject: [PATCH 029/115] Reworking install script to run some actions only on the first JOB (11g - fastest): - testing of code uninstall process - checking code style validity --- .travis/install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis/install.sh b/.travis/install.sh index 2f1bdf743..7b799eaa0 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -13,7 +13,8 @@ alter session set plsql_optimize_level=0; @install_headless.sql $UT3_OWNER $UT3_OWNER_PASSWORD SQL -if [ "$TRAVIS_JOB_ID" == "1" ]; then +#Run this step only on first job slave (11.2 - at it's fastest) +if [[ "${TRAVIS_JOB_NUMBER}" =~ \.1$ ]]; then #check code-style for errors time "$SQLCLI" $UT3_OWNER/$UT3_OWNER_PASSWORD@//$CONNECTION_STR @../development/utplsql_style_check.sql From f590d7790bead1eeed6e32ce333698170b4edeba Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sun, 29 Jul 2018 19:04:08 +0000 Subject: [PATCH 030/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 14783f526..6725cb90b 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2171-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2195-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From c850b38cb6316123818ca68015e510d27948992e Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sat, 11 Aug 2018 17:27:09 +0100 Subject: [PATCH 031/115] Resolves issues with teamcity reporter: - the `[` and `]` were not escaped - the `"` was escaped though not needed - If total length of message inside the square brackets exceeds 4000 characters it's causing teamcity to report success for a test failed Resolves #747 --- source/reporters/ut_teamcity_reporter_helper.pkb | 4 ++-- test/core/reporters.pkb | 2 +- test/core/reporters/test_teamcity_reporter.pkb | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/reporters/ut_teamcity_reporter_helper.pkb b/source/reporters/ut_teamcity_reporter_helper.pkb index d3a76e20b..c4ae3aa86 100644 --- a/source/reporters/ut_teamcity_reporter_helper.pkb +++ b/source/reporters/ut_teamcity_reporter_helper.pkb @@ -21,7 +21,7 @@ create or replace package body ut_teamcity_reporter_helper is function escape_value(a_value in varchar2) return varchar2 is begin - return translate(regexp_replace(a_value, '(''|"|[|]|' || chr(13) || '|' || chr(10) || ')', '|\1'),chr(13)||chr(10),'nr'); + return translate(regexp_replace(a_value, q'/(\'|\||\[|\]|/' || chr(13) || '|' || chr(10) || ')', '|\1'),chr(13)||chr(10),'rn'); end; function message(a_command in varchar2, a_props t_props default cast(null as t_props)) return varchar2 is @@ -35,7 +35,7 @@ create or replace package body ut_teamcity_reporter_helper is l_index := a_props.first; while l_index is not null loop if a_props(l_index) is not null then - l_value := escape_value(a_props(l_index)); + l_value := substr(escape_value(a_props(l_index)),1,2000); l_message := l_message || ' ' || l_index || '=''' || l_value || ''''; end if; l_index := a_props.next(l_index); diff --git a/test/core/reporters.pkb b/test/core/reporters.pkb index 8eb2a4992..9388ddb1b 100644 --- a/test/core/reporters.pkb +++ b/test/core/reporters.pkb @@ -76,7 +76,7 @@ as is begin dbms_output.put_line(''); - ut3.ut.expect(1,'Fails as values are different').to_equal(2); + ut3.ut.expect('number [1] ','Fails as values are different').to_equal('number [2] '); end; procedure erroring_test diff --git a/test/core/reporters/test_teamcity_reporter.pkb b/test/core/reporters/test_teamcity_reporter.pkb index e3c05003f..9d796ee13 100644 --- a/test/core/reporters/test_teamcity_reporter.pkb +++ b/test/core/reporters/test_teamcity_reporter.pkb @@ -22,14 +22,14 @@ create or replace package body test_teamcity_reporter as -%##teamcity[testFailed timestamp='%' message='Fails as values are different' name='ut3_tester.test_reporters.failing_test'] +%##teamcity[testFailed timestamp='%' details='Actual: |'number |[1|] |' (varchar2) was expected to equal: |'number |[2|] |' (varchar2) ' message='Fails as values are different' name='ut3_tester.test_reporters.failing_test'] %##teamcity[testFinished timestamp='%' duration='%' name='ut3_tester.test_reporters.failing_test'] %##teamcity[testStarted timestamp='%' captureStandardOutput='true' name='ut3_tester.test_reporters.erroring_test'] -%##teamcity[testStdErr timestamp='%' name='ut3_tester.test_reporters.erroring_test' out='Test exception:|rORA-06512: at |"UT3_TESTER.TEST_REPORTERS|", line %|rORA-06512: at %|r|r'] -%##teamcity[testFailed timestamp='%' details='Test exception:|rORA-06512: at |"UT3_TESTER.TEST_REPORTERS|", line %|rORA-06512: at %|r|r' message='Error occured' name='ut3_tester.test_reporters.erroring_test'] +%##teamcity[testStdErr timestamp='%' name='ut3_tester.test_reporters.erroring_test' out='Test exception:|nORA-06512: at "UT3_TESTER.TEST_REPORTERS", line %|nORA-06512: at %|n|n'] +%##teamcity[testFailed timestamp='%' details='Test exception:|nORA-06512: at "UT3_TESTER.TEST_REPORTERS", line %|nORA-06512: at %|n|n' message='Error occured' name='ut3_tester.test_reporters.erroring_test'] %##teamcity[testFinished timestamp='%' duration='%' name='ut3_tester.test_reporters.erroring_test'] %##teamcity[testStarted timestamp='%' captureStandardOutput='true' name='ut3_tester.test_reporters.disabled_test'] %##teamcity[testIgnored timestamp='%' name='ut3_tester.test_reporters.disabled_test'] From 9ae7d55469cb1601c6e1eaa04986a3989f92b152 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sat, 11 Aug 2018 20:09:56 +0100 Subject: [PATCH 032/115] Ficing build issue with mkdocs --- mkdocs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 3aeae4d95..7bffe0c71 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,14 +2,14 @@ # http://www.mkdocs.org/user-guide/configuration/ site_name: utPLSQL -site_description: utPLSQL Documenation Powerful Unit Testing Framework for Oracle PL/SQL +site_description: utPLSQL Ultimate Unit Testing Framework for Oracle PL/SQL copyright: Copyright © 2016 - 2018 utPLSQL Team repo_url: https://github.com/utPLSQL/utPLSQL theme: mkdocs use_directory_urls: false strict: true -pages: +nav: - Home: index.md - User Guide: - Installation: userguide/install.md From cd742e7a089e5eed1652cc31ffa5e564a09d3d36 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sat, 11 Aug 2018 23:35:18 +0100 Subject: [PATCH 033/115] Fixed issue with context generating a separate tag in sonar test-results. --- source/reporters/ut_sonar_test_reporter.tpb | 11 +++++++-- test/core/reporters.pkb | 7 +++++- .../reporters/test_documentation_reporter.pkb | 1 + .../reporters/test_documentation_reporter.pks | 10 ++++++++ test/core/reporters/test_junit_reporter.pkb | 24 ++++++++++--------- .../core/reporters/test_teamcity_reporter.pkb | 20 ++++++++-------- test/install_tests.sql | 2 ++ 7 files changed, 51 insertions(+), 24 deletions(-) create mode 100644 test/core/reporters/test_documentation_reporter.pkb create mode 100644 test/core/reporters/test_documentation_reporter.pks diff --git a/source/reporters/ut_sonar_test_reporter.tpb b/source/reporters/ut_sonar_test_reporter.tpb index 547ccf9d3..92b0e55cc 100644 --- a/source/reporters/ut_sonar_test_reporter.tpb +++ b/source/reporters/ut_sonar_test_reporter.tpb @@ -69,19 +69,26 @@ create or replace type body ut_sonar_test_reporter is procedure print_suite_results(a_suite ut_logical_suite, a_file_mappings ut_file_mappings) is begin + + if a_suite is of(ut_suite) and not a_suite is of(ut_suite_context) then + self.print_text(''); + end if; + for i in 1 .. a_suite.items.count loop if a_suite.items(i) is of(ut_logical_suite) then print_suite_results(treat(a_suite.items(i) as ut_logical_suite), a_file_mappings); end if; end loop; - if a_suite is of(ut_suite) then - self.print_text(''); + if a_suite is of(ut_suite) then for i in 1 .. a_suite.items.count loop if a_suite.items(i) is of(ut_test) then print_test_results(treat(a_suite.items(i) as ut_test)); end if; end loop; + end if; + + if a_suite is of(ut_suite) and not a_suite is of(ut_suite_context) then self.print_text(''); end if; end; diff --git a/test/core/reporters.pkb b/test/core/reporters.pkb index 8eb2a4992..614a832ba 100644 --- a/test/core/reporters.pkb +++ b/test/core/reporters.pkb @@ -6,7 +6,7 @@ create or replace package body reporters is execute immediate q'[create or replace package test_reporters as --%suite(A suite for testing different outcomes from reporters) - --%suitepath(utplsqlorg.helpers.tests.test.test_reporters) + --%suitepath(org.utplsql.tests.helpers) --%beforeall procedure beforeall; @@ -14,11 +14,16 @@ as --%beforeeach procedure beforeeach; + --%context(some_context) + --%displayname(A description of some context) + --%test --%beforetest(beforetest) --%aftertest(aftertest) procedure passing_test; + --%endcontext + procedure beforetest; procedure aftertest; diff --git a/test/core/reporters/test_documentation_reporter.pkb b/test/core/reporters/test_documentation_reporter.pkb new file mode 100644 index 000000000..36c29dbcb --- /dev/null +++ b/test/core/reporters/test_documentation_reporter.pkb @@ -0,0 +1 @@ +create or replace package body test_documentation_reporter as procedure report_produces_expected_out is l_results ut3.ut_varchar2_list; l_actual clob; l_expected varchar2(32767):=q'[%org utplsql tests helpers A suite for testing different outcomes from reporters A description of some context passing_test [% sec] a test with failing assertion [% sec] (FAILED - 1) a test raising unhandled exception [% sec] (FAILED - 2) a disabled test [0 sec] (DISABLED) % Failures: % 1) failing_test "Fails as values are different" Actual: 1 (number) was expected to equal: 2 (number)% at "UT3_TESTER.TEST_REPORTERS.FAILING_TEST", line 36 ut3.ut.expect(1,'Fails as values are different').to_equal(2); % % 2) erroring_test ORA-06502: PL/SQL: numeric or value error: character to number conversion error ORA-06512: at "UT3_TESTER.TEST_REPORTERS", line 44 ORA-06512: at "UT3_TESTER.TEST_REPORTERS", line 44 ORA-06512: at line 6 Finished in % seconds 4 tests, 1 failed, 1 errored, 1 disabled, 0 warning(s)%]'; begin select * bulk collect into l_results from table( ut3.ut.run( 'test_reporters', ut3.ut_documentation_reporter() ) ); l_actual := ut3.ut_utils.table_to_clob(l_results); ut.expect(l_actual).to_be_like(l_expected); end; procedure check_encoding_included is begin reporters.check_xml_encoding_included(ut3.ut_sonar_test_reporter(), 'UTF-8'); end; end; / \ No newline at end of file diff --git a/test/core/reporters/test_documentation_reporter.pks b/test/core/reporters/test_documentation_reporter.pks new file mode 100644 index 000000000..09835abdc --- /dev/null +++ b/test/core/reporters/test_documentation_reporter.pks @@ -0,0 +1,10 @@ +create or replace package test_documentation_reporter as + + --%suite(ut_documentation_reporter) + --%suitepath(utplsql.core.reporters) + + --%test(Report produces expected output) + procedure report_produces_expected_out; + +end; +/ diff --git a/test/core/reporters/test_junit_reporter.pkb b/test/core/reporters/test_junit_reporter.pkb index 29beaaa55..6cd67b8a3 100644 --- a/test/core/reporters/test_junit_reporter.pkb +++ b/test/core/reporters/test_junit_reporter.pkb @@ -247,32 +247,35 @@ create or replace package body test_junit_reporter as l_actual clob; l_expected varchar2(32767):=q'[ - - - - - - - + + + + + + + % - + + + + %Fails as values are different% % - + %ORA-06502:% % - + @@ -285,7 +288,6 @@ create or replace package body test_junit_reporter as - ]'; begin diff --git a/test/core/reporters/test_teamcity_reporter.pkb b/test/core/reporters/test_teamcity_reporter.pkb index e3c05003f..009085927 100644 --- a/test/core/reporters/test_teamcity_reporter.pkb +++ b/test/core/reporters/test_teamcity_reporter.pkb @@ -5,12 +5,12 @@ create or replace package body test_teamcity_reporter as l_output clob; l_expected varchar2(32767); begin - l_expected := q'{%##teamcity[testSuiteStarted timestamp='%' name='utplsqlorg'] -%##teamcity[testSuiteStarted timestamp='%' name='utplsqlorg.helpers'] -%##teamcity[testSuiteStarted timestamp='%' name='utplsqlorg.helpers.tests'] -%##teamcity[testSuiteStarted timestamp='%' name='utplsqlorg.helpers.tests.test'] -%##teamcity[testSuiteStarted timestamp='%' name='utplsqlorg.helpers.tests.test.test_reporters'] + l_expected := q'{%##teamcity[testSuiteStarted timestamp='%' name='org'] +%##teamcity[testSuiteStarted timestamp='%' name='org.utplsql'] +%##teamcity[testSuiteStarted timestamp='%' name='org.utplsql.tests'] +%##teamcity[testSuiteStarted timestamp='%' name='org.utplsql.tests.helpers'] %##teamcity[testSuiteStarted timestamp='%' name='A suite for testing different outcomes from reporters'] +%##teamcity[testSuiteStarted timestamp='%' name='A description of some context'] %##teamcity[testStarted timestamp='%' captureStandardOutput='true' name='ut3_tester.test_reporters.passing_test'] @@ -18,6 +18,7 @@ create or replace package body test_teamcity_reporter as %##teamcity[testFinished timestamp='%' duration='%' name='ut3_tester.test_reporters.passing_test'] +%##teamcity[testSuiteFinished timestamp='%' name='A description of some context'] %##teamcity[testStarted timestamp='%' captureStandardOutput='true' name='ut3_tester.test_reporters.failing_test'] @@ -34,11 +35,10 @@ create or replace package body test_teamcity_reporter as %##teamcity[testStarted timestamp='%' captureStandardOutput='true' name='ut3_tester.test_reporters.disabled_test'] %##teamcity[testIgnored timestamp='%' name='ut3_tester.test_reporters.disabled_test'] %##teamcity[testSuiteFinished timestamp='%' name='A suite for testing different outcomes from reporters'] -%##teamcity[testSuiteFinished timestamp='%' name='utplsqlorg.helpers.tests.test.test_reporters'] -%##teamcity[testSuiteFinished timestamp='%' name='utplsqlorg.helpers.tests.test'] -%##teamcity[testSuiteFinished timestamp='%' name='utplsqlorg.helpers.tests'] -%##teamcity[testSuiteFinished timestamp='%' name='utplsqlorg.helpers'] -%##teamcity[testSuiteFinished timestamp='%' name='utplsqlorg']}'; +%##teamcity[testSuiteFinished timestamp='%' name='org.utplsql.tests.helpers'] +%##teamcity[testSuiteFinished timestamp='%' name='org.utplsql.tests'] +%##teamcity[testSuiteFinished timestamp='%' name='org.utplsql'] +%##teamcity[testSuiteFinished timestamp='%' name='org']}'; --act select * bulk collect into l_output_data diff --git a/test/install_tests.sql b/test/install_tests.sql index 3e90b1590..2aa60692c 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -45,6 +45,7 @@ set define on @@install_below_12_2.sql 'core/reporters/test_coverage/test_html_proftab_reporter.pks' set define off @@core/reporters/test_tfs_junit_reporter.pks +@@core/reporters/test_documentation_reporter.pks @@core/reporters/test_sonar_test_reporter.pks @@core/reporters/test_teamcity_reporter.pks @@core/expectations.pks @@ -93,6 +94,7 @@ set define on @@install_below_12_2.sql 'core/reporters/test_coverage/test_html_proftab_reporter.pkb' set define off @@core/reporters/test_tfs_junit_reporter.pkb +@@core/reporters/test_documentation_reporter.pkb @@core/reporters/test_sonar_test_reporter.pkb @@core/reporters/test_teamcity_reporter.pkb @@core/expectations.pkb From 3c5cd620f95bf4dd906b8567073432589e897b4b Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 12 Aug 2018 00:50:07 +0100 Subject: [PATCH 034/115] Fixed regression with nested suites reporting for sonar test execution. Fixed issue with test on documentation reporter on 11g-12.1. --- source/reporters/ut_sonar_test_reporter.tpb | 14 ++++++++++---- .../core/reporters/test_documentation_reporter.pkb | 2 +- test/install_and_run_tests.sh | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source/reporters/ut_sonar_test_reporter.tpb b/source/reporters/ut_sonar_test_reporter.tpb index 92b0e55cc..913ae8b50 100644 --- a/source/reporters/ut_sonar_test_reporter.tpb +++ b/source/reporters/ut_sonar_test_reporter.tpb @@ -70,13 +70,19 @@ create or replace type body ut_sonar_test_reporter is procedure print_suite_results(a_suite ut_logical_suite, a_file_mappings ut_file_mappings) is begin - if a_suite is of(ut_suite) and not a_suite is of(ut_suite_context) then + for i in 1 .. a_suite.items.count loop + if a_suite.items(i) is of(ut_logical_suite) and a_suite.items(i) is not of(ut_suite_context) then + print_suite_results(treat(a_suite.items(i) as ut_logical_suite), a_file_mappings); + end if; + end loop; + + if a_suite is of(ut_suite) and a_suite is not of(ut_suite_context) then self.print_text(''); end if; for i in 1 .. a_suite.items.count loop - if a_suite.items(i) is of(ut_logical_suite) then - print_suite_results(treat(a_suite.items(i) as ut_logical_suite), a_file_mappings); + if a_suite.items(i) is of(ut_suite_context) then + print_suite_results(treat(a_suite.items(i) as ut_suite_context), a_file_mappings); end if; end loop; @@ -88,7 +94,7 @@ create or replace type body ut_sonar_test_reporter is end loop; end if; - if a_suite is of(ut_suite) and not a_suite is of(ut_suite_context) then + if a_suite is of(ut_suite) and a_suite is not of(ut_suite_context) then self.print_text(''); end if; end; diff --git a/test/core/reporters/test_documentation_reporter.pkb b/test/core/reporters/test_documentation_reporter.pkb index 36c29dbcb..bdd612273 100644 --- a/test/core/reporters/test_documentation_reporter.pkb +++ b/test/core/reporters/test_documentation_reporter.pkb @@ -1 +1 @@ -create or replace package body test_documentation_reporter as procedure report_produces_expected_out is l_results ut3.ut_varchar2_list; l_actual clob; l_expected varchar2(32767):=q'[%org utplsql tests helpers A suite for testing different outcomes from reporters A description of some context passing_test [% sec] a test with failing assertion [% sec] (FAILED - 1) a test raising unhandled exception [% sec] (FAILED - 2) a disabled test [0 sec] (DISABLED) % Failures: % 1) failing_test "Fails as values are different" Actual: 1 (number) was expected to equal: 2 (number)% at "UT3_TESTER.TEST_REPORTERS.FAILING_TEST", line 36 ut3.ut.expect(1,'Fails as values are different').to_equal(2); % % 2) erroring_test ORA-06502: PL/SQL: numeric or value error: character to number conversion error ORA-06512: at "UT3_TESTER.TEST_REPORTERS", line 44 ORA-06512: at "UT3_TESTER.TEST_REPORTERS", line 44 ORA-06512: at line 6 Finished in % seconds 4 tests, 1 failed, 1 errored, 1 disabled, 0 warning(s)%]'; begin select * bulk collect into l_results from table( ut3.ut.run( 'test_reporters', ut3.ut_documentation_reporter() ) ); l_actual := ut3.ut_utils.table_to_clob(l_results); ut.expect(l_actual).to_be_like(l_expected); end; procedure check_encoding_included is begin reporters.check_xml_encoding_included(ut3.ut_sonar_test_reporter(), 'UTF-8'); end; end; / \ No newline at end of file +create or replace package body test_documentation_reporter as procedure report_produces_expected_out is l_results ut3.ut_varchar2_list; l_actual clob; l_expected varchar2(32767):=q'[%org utplsql tests helpers A suite for testing different outcomes from reporters A description of some context passing_test [% sec] a test with failing assertion [% sec] (FAILED - 1) a test raising unhandled exception [% sec] (FAILED - 2) a disabled test [0 sec] (DISABLED) % Failures: % 1) failing_test "Fails as values are different" Actual: 1 (number) was expected to equal: 2 (number)% at "UT3_TESTER.TEST_REPORTERS%", line 36 ut3.ut.expect(1,'Fails as values are different').to_equal(2); % % 2) erroring_test ORA-06502: PL/SQL: numeric or value error: character to number conversion error ORA-06512: at "UT3_TESTER.TEST_REPORTERS", line 44% ORA-06512: at line 6 Finished in % seconds 4 tests, 1 failed, 1 errored, 1 disabled, 0 warning(s)%]'; begin select * bulk collect into l_results from table( ut3.ut.run( 'test_reporters', ut3.ut_documentation_reporter() ) ); l_actual := ut3.ut_utils.table_to_clob(l_results); ut.expect(l_actual).to_be_like(l_expected); end; procedure check_encoding_included is begin reporters.check_xml_encoding_included(ut3.ut_sonar_test_reporter(), 'UTF-8'); end; end; / \ No newline at end of file diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh index a1e5e0849..1ffe2b787 100644 --- a/test/install_and_run_tests.sh +++ b/test/install_and_run_tests.sh @@ -13,7 +13,7 @@ time "$SQLCLI" ${UT3_TESTER}/${UT3_TESTER_PASSWORD}@//${CONNECTION_STR} @install cd .. time utPLSQL-cli/bin/utplsql run ${UT3_TESTER}/${UT3_TESTER_PASSWORD}@${CONNECTION_STR} \ --source_path=source -owner=ut3 \ +-source_path=source -owner=ut3 -p=test_documentation_reporter \ -test_path=test -c \ -f=ut_documentation_reporter -o=test_results.log -s \ -f=ut_coverage_sonar_reporter -o=coverage.xml \ From fff402ff35eba1ef1097158c92e37366193f830b Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Mon, 13 Aug 2018 23:35:08 +0100 Subject: [PATCH 035/115] Added explicit tests for trimmed output on teamcity report --- .../reporters/ut_teamcity_reporter_helper.pkb | 6 +- .../core/reporters/test_teamcity_reporter.pkb | 79 +++++++++++++++++++ .../core/reporters/test_teamcity_reporter.pks | 12 +++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/source/reporters/ut_teamcity_reporter_helper.pkb b/source/reporters/ut_teamcity_reporter_helper.pkb index c4ae3aa86..f5167fbb8 100644 --- a/source/reporters/ut_teamcity_reporter_helper.pkb +++ b/source/reporters/ut_teamcity_reporter_helper.pkb @@ -28,6 +28,7 @@ create or replace package body ut_teamcity_reporter_helper is l_message varchar2(32767); l_index t_prop_index; l_value varchar2(32767); + l_max_len binary_integer := 2000; begin l_message := '##teamcity[' || a_command || ' timestamp=''' || regexp_replace(to_char(systimestamp, 'YYYY-MM-DD"T"HH24:MI:ss.FF3TZHTZM'), '(\.\d{3})\d+(\+)', '\1\2') || ''''; @@ -35,7 +36,10 @@ create or replace package body ut_teamcity_reporter_helper is l_index := a_props.first; while l_index is not null loop if a_props(l_index) is not null then - l_value := substr(escape_value(a_props(l_index)),1,2000); + l_value := escape_value(a_props(l_index)); + if length(l_value) > l_max_len then + l_value := substr(l_value,1,l_max_len-7)||escape_value('[...]'); + end if; l_message := l_message || ' ' || l_index || '=''' || l_value || ''''; end if; l_index := a_props.next(l_index); diff --git a/test/core/reporters/test_teamcity_reporter.pkb b/test/core/reporters/test_teamcity_reporter.pkb index 9d796ee13..0110d57e8 100644 --- a/test/core/reporters/test_teamcity_reporter.pkb +++ b/test/core/reporters/test_teamcity_reporter.pkb @@ -1,5 +1,39 @@ create or replace package body test_teamcity_reporter as + procedure create_a_test_package is + pragma autonomous_transaction; + begin + execute immediate q'[create or replace package check_escape_special_chars is + --%suite(A suite with 'quote') + + --%test(A test with 'quote') + procedure test_do_stuff; + + end;]'; + execute immediate q'[create or replace package body check_escape_special_chars is + procedure test_do_stuff is + begin + ut3.ut.expect(' [ ' || chr(13) || chr(10) || ' ] ' ).to_be_null; + end; + + end;]'; + + execute immediate q'[create or replace package check_trims_long_output is + --%suite + + --%test + procedure long_output; + end;]'; + execute immediate q'[create or replace package body check_trims_long_output is + procedure long_output is + begin + ut3.ut.expect(rpad('aVarchar',4000,'a')).to_be_null; + end; + end;]'; + + end; + + procedure report_produces_expected_out is l_output_data ut3.ut_varchar2_list; l_output clob; @@ -48,5 +82,50 @@ create or replace package body test_teamcity_reporter as ut.expect(ut3.ut_utils.table_to_clob(l_output_data)).to_be_like(l_expected); end; + procedure escape_special_chars is + l_output_data ut3.ut_varchar2_list; + l_output clob; + l_expected varchar2(32767); + begin + l_expected := q'{%##teamcity[testSuiteStarted timestamp='%' name='A suite with |'quote|''] +%##teamcity[testStarted timestamp='%' captureStandardOutput='true' name='ut3_tester.check_escape_special_chars.test_do_stuff'] +%##teamcity[testFailed timestamp='%' details='Actual: (varchar2)|n |' |[ |r|n |] |'|nwas expected to be null' name='ut3_tester.check_escape_special_chars.test_do_stuff'] +%##teamcity[testFinished timestamp='%' duration='%' name='ut3_tester.check_escape_special_chars.test_do_stuff'] +%##teamcity[testSuiteFinished timestamp='%' name='A suite with |'quote|'']}'; + --act + select * + bulk collect into l_output_data + from table(ut3.ut.run('check_escape_special_chars',ut3.ut_teamcity_reporter())); + + --assert + ut.expect(ut3.ut_utils.table_to_clob(l_output_data)).to_be_like(l_expected); + end; + + procedure trims_long_output is + l_output_data ut3.ut_varchar2_list; + l_output clob; + l_expected varchar2(32767); + begin + l_expected := q'{%##teamcity[testSuiteStarted timestamp='%' name='check_trims_long_output'] +%##teamcity[testStarted timestamp='%' captureStandardOutput='true' name='ut3_tester.check_trims_long_output.long_output'] +%##teamcity[testFailed timestamp='%' details='Actual: (varchar2)|n |'aVarcharaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|[...|]' name='ut3_tester.check_trims_long_output.long_output'] +%##teamcity[testFinished timestamp='%' duration='%' name='ut3_tester.check_trims_long_output.long_output'] +%##teamcity[testSuiteFinished timestamp='%' name='check_trims_long_output']}'; + --act + select * + bulk collect into l_output_data + from table(ut3.ut.run('check_trims_long_output',ut3.ut_teamcity_reporter())); + + --assert + ut.expect(ut3.ut_utils.table_to_clob(l_output_data)).to_be_like(l_expected); + end; + + procedure remove_test_package is + pragma autonomous_transaction; + begin + execute immediate 'drop package check_escape_special_chars'; + execute immediate 'drop package check_trims_long_output'; + end; + end; / diff --git a/test/core/reporters/test_teamcity_reporter.pks b/test/core/reporters/test_teamcity_reporter.pks index 277044417..ef474b225 100644 --- a/test/core/reporters/test_teamcity_reporter.pks +++ b/test/core/reporters/test_teamcity_reporter.pks @@ -3,8 +3,20 @@ create or replace package test_teamcity_reporter as --%suite(ut_teamcity_reporter) --%suitepath(utplsql.core.reporters) + --%beforeall + procedure create_a_test_package; + --%test(Report produces expected output) procedure report_produces_expected_out; + --%test(Escapes special characters) + procedure escape_special_chars; + + --%test(Trims output so it fits into 4000 chars) + procedure trims_long_output; + + --%afterall + procedure remove_test_package; + end; / From 2c3df8bc6a6d33c7a0ab5980149d7dae865ec641 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Mon, 13 Aug 2018 23:36:09 +0100 Subject: [PATCH 036/115] Removing suitepath committed by accident. --- test/install_and_run_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh index 1ffe2b787..a1e5e0849 100644 --- a/test/install_and_run_tests.sh +++ b/test/install_and_run_tests.sh @@ -13,7 +13,7 @@ time "$SQLCLI" ${UT3_TESTER}/${UT3_TESTER_PASSWORD}@//${CONNECTION_STR} @install cd .. time utPLSQL-cli/bin/utplsql run ${UT3_TESTER}/${UT3_TESTER_PASSWORD}@${CONNECTION_STR} \ --source_path=source -owner=ut3 -p=test_documentation_reporter \ +-source_path=source -owner=ut3 \ -test_path=test -c \ -f=ut_documentation_reporter -o=test_results.log -s \ -f=ut_coverage_sonar_reporter -o=coverage.xml \ From 8b509c71a3c8a62cd417c62b3444d13b4c4501e7 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Thu, 16 Aug 2018 21:29:43 +0000 Subject: [PATCH 037/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 6725cb90b..8a186e48c 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2195-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2212-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 97b83fac42b2e1226d0f7924da16a8449fe93022 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Thu, 16 Aug 2018 23:43:55 +0100 Subject: [PATCH 038/115] Fixed failing unit test after merging. --- test/core/reporters/test_documentation_reporter.pkb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/reporters/test_documentation_reporter.pkb b/test/core/reporters/test_documentation_reporter.pkb index bdd612273..7045aa7ca 100644 --- a/test/core/reporters/test_documentation_reporter.pkb +++ b/test/core/reporters/test_documentation_reporter.pkb @@ -1 +1 @@ -create or replace package body test_documentation_reporter as procedure report_produces_expected_out is l_results ut3.ut_varchar2_list; l_actual clob; l_expected varchar2(32767):=q'[%org utplsql tests helpers A suite for testing different outcomes from reporters A description of some context passing_test [% sec] a test with failing assertion [% sec] (FAILED - 1) a test raising unhandled exception [% sec] (FAILED - 2) a disabled test [0 sec] (DISABLED) % Failures: % 1) failing_test "Fails as values are different" Actual: 1 (number) was expected to equal: 2 (number)% at "UT3_TESTER.TEST_REPORTERS%", line 36 ut3.ut.expect(1,'Fails as values are different').to_equal(2); % % 2) erroring_test ORA-06502: PL/SQL: numeric or value error: character to number conversion error ORA-06512: at "UT3_TESTER.TEST_REPORTERS", line 44% ORA-06512: at line 6 Finished in % seconds 4 tests, 1 failed, 1 errored, 1 disabled, 0 warning(s)%]'; begin select * bulk collect into l_results from table( ut3.ut.run( 'test_reporters', ut3.ut_documentation_reporter() ) ); l_actual := ut3.ut_utils.table_to_clob(l_results); ut.expect(l_actual).to_be_like(l_expected); end; procedure check_encoding_included is begin reporters.check_xml_encoding_included(ut3.ut_sonar_test_reporter(), 'UTF-8'); end; end; / \ No newline at end of file +create or replace package body test_documentation_reporter as procedure report_produces_expected_out is l_results ut3.ut_varchar2_list; l_actual clob; l_expected varchar2(32767):=q'[%org utplsql tests helpers A suite for testing different outcomes from reporters A description of some context passing_test [% sec] a test with failing assertion [% sec] (FAILED - 1) a test raising unhandled exception [% sec] (FAILED - 2) a disabled test [0 sec] (DISABLED) % Failures: % 1) failing_test "Fails as values are different" Actual: 'number [1] ' (varchar2) was expected to equal: 'number [2] ' (varchar2)% at "UT3_TESTER.TEST_REPORTERS%", line 36 ut3.ut.expect('number [1] ','Fails as values are different').to_equal('number [2] '); % % 2) erroring_test ORA-06502: PL/SQL: numeric or value error: character to number conversion error ORA-06512: at "UT3_TESTER.TEST_REPORTERS", line 44% ORA-06512: at line 6 Finished in % seconds 4 tests, 1 failed, 1 errored, 1 disabled, 0 warning(s)%]'; begin select * bulk collect into l_results from table( ut3.ut.run( 'test_reporters', ut3.ut_documentation_reporter() ) ); l_actual := ut3.ut_utils.table_to_clob(l_results); ut.expect(l_actual).to_be_like(l_expected); end; procedure check_encoding_included is begin reporters.check_xml_encoding_included(ut3.ut_sonar_test_reporter(), 'UTF-8'); end; end; / \ No newline at end of file From b21704f748e7a065952f885a628d555d63207051 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sat, 18 Aug 2018 12:54:40 +0000 Subject: [PATCH 039/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 8a186e48c..d6a4a82e5 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2212-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2217-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 28ed15ca8cb8a46923f7bac899a3aad313392a44 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 18 Sep 2018 23:08:47 +0100 Subject: [PATCH 040/115] Switching to small Oracle Docker Images. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5b82e811a..9dd9d8ef8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,10 +49,10 @@ env: - MAVEN_HOME=/usr/local/maven - MAVEN_CFG=$HOME/.m2 matrix: - - ORACLE_VERSION="${DOCKER_TAG_11G:-11g-r2-xe}" CONNECTION_STR='127.0.0.1:1521/XE' DOCKER_OPTIONS='--shm-size=1g' - - ORACLE_VERSION="${DOCKER_TAG_12C:-12c-r1-se2}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" - - ORACLE_VERSION="${DOCKER_TAG_12C2:-12c-r2-se2}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" - - ORACLE_VERSION="${DOCKER_TAG_18:-18c-se2}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" + - ORACLE_VERSION="${DOCKER_TAG_11G:-11g-r2-xe}" CONNECTION_STR='127.0.0.1:1521/XE' DOCKER_OPTIONS='--shm-size=1g' + - ORACLE_VERSION="${DOCKER_TAG_12C:-12c-r1-se2-small}" CONNECTION_STR='127.0.0.1:1521/ORCL' + - ORACLE_VERSION="${DOCKER_TAG_12C2:-12c-r2-se2-small}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" + - ORACLE_VERSION="${DOCKER_TAG_18:-18c-se2-small}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" cache: pip: true From 7e15d7087f778c4aa25d9bd164cd8a93a9c0164c Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Thu, 20 Sep 2018 23:47:57 +0100 Subject: [PATCH 041/115] Fixing test performance issue found - implicit data-type conversion to CLOB is causing significant test slowness on 18c. --- test/core/expectations/test_matchers.pkb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/core/expectations/test_matchers.pkb b/test/core/expectations/test_matchers.pkb index e66f7c750..1a15986b9 100644 --- a/test/core/expectations/test_matchers.pkb +++ b/test/core/expectations/test_matchers.pkb @@ -192,8 +192,8 @@ create or replace package body test_matchers is begin exec_match('varchar2(100)', '''Stephen''', '^Ste(v|ph)en$', '', ut3.ut_utils.gc_success); exec_match('varchar2(100)', '''sTEPHEN''', '^Ste(v|ph)en$', 'i', ut3.ut_utils.gc_success); - exec_match('clob', 'rpad('', '',32767)||''Stephen''', 'Ste(v|ph)en$', '', ut3.ut_utils.gc_success); - exec_match('clob', 'rpad('', '',32767)||''sTEPHEN''', 'Ste(v|ph)en$', 'i', ut3.ut_utils.gc_success); + exec_match('clob', 'to_clob(rpad('', '',32767)||''Stephen'')', 'Ste(v|ph)en$', '', ut3.ut_utils.gc_success); + exec_match('clob', 'to_clob(rpad('', '',32767)||''sTEPHEN'')', 'Ste(v|ph)en$', 'i', ut3.ut_utils.gc_success); exec_match('varchar2(100)', '''Stephen''', '^Steven$', '', ut3.ut_utils.gc_failure); exec_match('varchar2(100)', '''sTEPHEN''', '^Steven$', 'i', ut3.ut_utils.gc_failure); @@ -202,8 +202,8 @@ create or replace package body test_matchers is exec_match('varchar2(100)', '''Stephen''', '^Ste(v|ph)en$', '', ut3.ut_utils.gc_failure, 'not_'); exec_match('varchar2(100)', '''sTEPHEN''', '^Ste(v|ph)en$', 'i', ut3.ut_utils.gc_failure, 'not_'); - exec_match('clob', 'rpad('', '',32767)||''Stephen''', 'Ste(v|ph)en$', '', ut3.ut_utils.gc_failure, 'not_'); - exec_match('clob', 'rpad('', '',32767)||''sTEPHEN''', 'Ste(v|ph)en$', 'i', ut3.ut_utils.gc_failure, 'not_'); + exec_match('clob', 'to_clob(rpad('', '',32767)||''Stephen'')', 'Ste(v|ph)en$', '', ut3.ut_utils.gc_failure, 'not_'); + exec_match('clob', 'to_clob(rpad('', '',32767)||''sTEPHEN'')', 'Ste(v|ph)en$', 'i', ut3.ut_utils.gc_failure, 'not_'); exec_match('varchar2(100)', '''Stephen''', '^Steven$', '', ut3.ut_utils.gc_success, 'not_'); exec_match('varchar2(100)', '''sTEPHEN''', '^Steven$', 'i', ut3.ut_utils.gc_success, 'not_'); @@ -217,23 +217,23 @@ create or replace package body test_matchers is begin exec_be_like('varchar2(100)', '''Stephen_King''', 'Ste__en%', '', ut3.ut_utils.gc_success); exec_be_like('varchar2(100)', '''Stephen_King''', 'Ste__en\_K%', '\', ut3.ut_utils.gc_success); - exec_be_like('clob', 'rpad(''a'',32767,''a'')||''Stephen_King''', 'a%Ste__en%', '', ut3.ut_utils.gc_success); - exec_be_like('clob', 'rpad(''a'',32767,''a'')||''Stephen_King''', 'a%Ste__en\_K%', '\', ut3.ut_utils.gc_success); + exec_be_like('clob', 'to_clob(rpad(''a'',32767,''a'')||''Stephen_King'')', 'a%Ste__en%', '', ut3.ut_utils.gc_success); + exec_be_like('clob', 'to_clob(rpad(''a'',32767,''a'')||''Stephen_King'')', 'a%Ste__en\_K%', '\', ut3.ut_utils.gc_success); exec_be_like('varchar2(100)', '''Stephen_King''', 'Ste_en%', '', ut3.ut_utils.gc_failure); exec_be_like('varchar2(100)', '''Stephen_King''', 'Stephe\__%', '\', ut3.ut_utils.gc_failure); - exec_be_like('clob', 'rpad(''a'',32767,''a'')||''Stephen_King''', 'a%Ste_en%', '', ut3.ut_utils.gc_failure); - exec_be_like('clob', 'rpad(''a'',32767,''a'')||''Stephen_King''', 'a%Stephe\__%', '\', ut3.ut_utils.gc_failure); + exec_be_like('clob', 'to_clob(rpad(''a'',32767,''a'')||''Stephen_King'')', 'a%Ste_en%', '', ut3.ut_utils.gc_failure); + exec_be_like('clob', 'to_clob(rpad(''a'',32767,''a'')||''Stephen_King'')', 'a%Stephe\__%', '\', ut3.ut_utils.gc_failure); exec_be_like('varchar2(100)', '''Stephen_King''', 'Ste__en%', '', ut3.ut_utils.gc_failure, 'not_'); exec_be_like('varchar2(100)', '''Stephen_King''', 'Ste__en\_K%', '\', ut3.ut_utils.gc_failure, 'not_'); - exec_be_like('clob', 'rpad(''a'',32767,''a'')||''Stephen_King''', 'a%Ste__en%', '', ut3.ut_utils.gc_failure, 'not_'); - exec_be_like('clob', 'rpad(''a'',32767,''a'')||''Stephen_King''', 'a%Ste__en\_K%', '\', ut3.ut_utils.gc_failure, 'not_'); + exec_be_like('clob', 'to_clob(rpad(''a'',32767,''a'')||''Stephen_King'')', 'a%Ste__en%', '', ut3.ut_utils.gc_failure, 'not_'); + exec_be_like('clob', 'to_clob(rpad(''a'',32767,''a'')||''Stephen_King'')', 'a%Ste__en\_K%', '\', ut3.ut_utils.gc_failure, 'not_'); exec_be_like('varchar2(100)', '''Stephen_King''', 'Ste_en%', '', ut3.ut_utils.gc_success, 'not_'); exec_be_like('varchar2(100)', '''Stephen_King''', 'Stephe\__%', '\', ut3.ut_utils.gc_success, 'not_'); - exec_be_like('clob', 'rpad(''a'',32767,''a'')||''Stephen_King''', 'a%Ste_en%', '', ut3.ut_utils.gc_success, 'not_'); - exec_be_like('clob', 'rpad(''a'',32767,''a'')||''Stephen_King''', 'a%Stephe\__%', '\', ut3.ut_utils.gc_success, 'not_'); + exec_be_like('clob', 'to_clob(rpad(''a'',32767,''a'')||''Stephen_King'')', 'a%Ste_en%', '', ut3.ut_utils.gc_success, 'not_'); + exec_be_like('clob', 'to_clob(rpad(''a'',32767,''a'')||''Stephen_King'')', 'a%Stephe\__%', '\', ut3.ut_utils.gc_success, 'not_'); --Fails for unsupported data-type exec_be_like('number', '12345', '123%', '', ut3.ut_utils.gc_failure); From 4ec7f138cbd3323b6da7f868e395af0068a58be8 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 21 Sep 2018 01:26:42 +0100 Subject: [PATCH 042/115] Trying sonar exclusions from command-line --- .travis/run_sonar_scanner.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/run_sonar_scanner.sh b/.travis/run_sonar_scanner.sh index 5cad42e29..6d1ed9782 100755 --- a/.travis/run_sonar_scanner.sh +++ b/.travis/run_sonar_scanner.sh @@ -53,4 +53,4 @@ else fi #Execute Sonar scanner -sonar-scanner \ No newline at end of file +sonar-scanner -Dsonar.exclusions=** \ No newline at end of file From a24c9aa51473d1fc9d36db64f98e96311c71745c Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 21 Sep 2018 01:59:12 +0100 Subject: [PATCH 043/115] Trying to cache sonar scanner plugins --- .travis.yml | 4 ++++ .travis/run_sonar_scanner.sh | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9dd9d8ef8..4ba2389fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,10 +58,14 @@ cache: pip: true directories: - $CACHE_DIR + - /home/travis/.sonar/cache - node_modules - $MAVEN_CFG before_install: + #cache to be used between stages. Based on https://github.com/travis-ci/docs-travis-ci-com/issues/1329 + #delete all files in cache that are older than 5 days + - mkdir -p $CACHE_DIR/stages_cache; find $CACHE_DIR/stages_cache/ -mtime +5 -exec rm {} \; #The update_project_version.sh is done before deployment to validate that the change of project files does not break installation - bash .travis/update_project_version.sh #Allow for sonar to blame issues diff --git a/.travis/run_sonar_scanner.sh b/.travis/run_sonar_scanner.sh index 6d1ed9782..5cad42e29 100755 --- a/.travis/run_sonar_scanner.sh +++ b/.travis/run_sonar_scanner.sh @@ -53,4 +53,4 @@ else fi #Execute Sonar scanner -sonar-scanner -Dsonar.exclusions=** \ No newline at end of file +sonar-scanner \ No newline at end of file From 4cb3aca66bc1a6d7475214b30b66be16846474bb Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 21 Sep 2018 08:48:31 +0100 Subject: [PATCH 044/115] Switching to non-PDB images. --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4ba2389fb..a6aecb53c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,9 +50,9 @@ env: - MAVEN_CFG=$HOME/.m2 matrix: - ORACLE_VERSION="${DOCKER_TAG_11G:-11g-r2-xe}" CONNECTION_STR='127.0.0.1:1521/XE' DOCKER_OPTIONS='--shm-size=1g' - - ORACLE_VERSION="${DOCKER_TAG_12C:-12c-r1-se2-small}" CONNECTION_STR='127.0.0.1:1521/ORCL' - - ORACLE_VERSION="${DOCKER_TAG_12C2:-12c-r2-se2-small}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" - - ORACLE_VERSION="${DOCKER_TAG_18:-18c-se2-small}" CONNECTION_STR='127.0.0.1:1521/ORCLPDB1' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" + - ORACLE_VERSION="${DOCKER_TAG_12C:-12c-r1-se2-small}" CONNECTION_STR='127.0.0.1:1521/ORCLCDB' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" + - ORACLE_VERSION="${DOCKER_TAG_12C2:-12c-r2-se2-small}" CONNECTION_STR='127.0.0.1:1521/ORCLCDB' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" + - ORACLE_VERSION="${DOCKER_TAG_18:-18c-se2-small}" CONNECTION_STR='127.0.0.1:1521/ORCLCDB' DOCKER_OPTIONS="-v /dev/pdbs:/opt/oracle/oradata/pdbs" cache: pip: true From df6bd422c7a7d9818b2c81ed379f2244273e7f79 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Mon, 24 Sep 2018 20:14:07 +0000 Subject: [PATCH 045/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index d6a4a82e5..4ea6ed0f7 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2217-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2238-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From af524990b10e66b4ceba0ff1e5f7f162a8369b7b Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 25 Sep 2018 00:11:28 +0100 Subject: [PATCH 046/115] Extended the proftab column size for 12.2 long names Resolves #716 --- source/core/coverage/proftab.sql | 8 +++---- .../test_html_extended_reporter.pkb | 4 ++-- .../core/reporters/test_extended_coverage.pkb | 22 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/source/core/coverage/proftab.sql b/source/core/coverage/proftab.sql index ad0caa458..62c69dc9a 100644 --- a/source/core/coverage/proftab.sql +++ b/source/core/coverage/proftab.sql @@ -12,7 +12,7 @@ begin -- from plsql_profiler_runnumber related_run number, -- runid of related run (for client/ -- server correlation) - run_owner varchar2(32), -- user who started run + run_owner varchar2(128), -- user who started run run_date date, -- start time of run run_comment varchar2(2047), -- user provided comment for this run run_total_time number, -- elapsed time for this run @@ -39,9 +39,9 @@ begin ( runid number references plsql_profiler_runs, unit_number number, -- internally generated library unit # - unit_type varchar2(32), -- library unit type - unit_owner varchar2(32), -- library unit owner name - unit_name varchar2(32), -- library unit name + unit_type varchar2(128), -- library unit type + unit_owner varchar2(128), -- library unit owner name + unit_name varchar2(128), -- library unit name -- timestamp on library unit, can be used to detect changes to -- unit between runs unit_timestamp date, 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 b1f6fa4bd..19e1fe807 100644 --- a/test/core/reporters/test_coverage/test_html_extended_reporter.pkb +++ b/test/core/reporters/test_coverage/test_html_extended_reporter.pkb @@ -7,7 +7,7 @@ create or replace package body test_html_extended_reporter is l_charset varchar2(100) := 'ISO-8859-1'; begin --Arrange - l_expected := '%%

UT3.DUMMY_COVERAGE

%4 relevant lines. 3 lines covered (including 1 lines partially covered ) and 1 lines missed%'; + l_expected := '%%

UT3.DUMMY_COVERAGE_PACKAGE_WITH_AN_AMAZINGLY_LONG_NAME_THAT_YOU_WOULD_NOT_THINK_OF_IN_REAL_LIFE_PROJECT_BECAUSE_ITS_SIMPLY_TOO_LONG

%4 relevant lines. 3 lines covered (including 1 lines partially covered ) and 1 lines missed%'; select * bulk collect into l_results @@ -15,7 +15,7 @@ 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_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage.pkb' ), + a_source_files => ut3.ut_varchar2_list( 'test/ut3.dummy_coverage_package_with_an_amazingly_long_name_that_you_would_not_think_of_in_real_life_project_because_its_simply_too_long.pkb' ), a_test_files => ut3.ut_varchar2_list( ), a_client_character_set => l_charset ) diff --git a/test/core/reporters/test_extended_coverage.pkb b/test/core/reporters/test_extended_coverage.pkb index 7ae0606e2..a3719e503 100644 --- a/test/core/reporters/test_extended_coverage.pkb +++ b/test/core/reporters/test_extended_coverage.pkb @@ -21,10 +21,10 @@ create or replace package body test_extended_coverage is procedure create_dummy_coverage_package is pragma autonomous_transaction; begin - execute immediate q'[create or replace package UT3.DUMMY_COVERAGE is + execute immediate q'[create or replace package UT3.DUMMY_COVERAGE_PACKAGE_WITH_AN_AMAZINGLY_LONG_NAME_THAT_YOU_WOULD_NOT_THINK_OF_IN_REAL_LIFE_PROJECT_BECAUSE_ITS_SIMPLY_TOO_LONG is procedure do_stuff(i_input in number); end;]'; - execute immediate q'[create or replace package body UT3.DUMMY_COVERAGE is + execute immediate q'[create or replace package body UT3.DUMMY_COVERAGE_PACKAGE_WITH_AN_AMAZINGLY_LONG_NAME_THAT_YOU_WOULD_NOT_THINK_OF_IN_REAL_LIFE_PROJECT_BECAUSE_ITS_SIMPLY_TOO_LONG is procedure do_stuff(i_input in number) is begin if i_input = 2 then @@ -49,7 +49,7 @@ create or replace package body test_extended_coverage is execute immediate q'[create or replace package body UT3.TEST_DUMMY_COVERAGE is procedure test_do_stuff is begin - dummy_coverage.do_stuff(1); + dummy_coverage_package_with_an_amazingly_long_name_that_you_would_not_think_of_in_real_life_project_because_its_simply_too_long.do_stuff(1); ut.expect(1).to_equal(1); end; end;]'; @@ -62,7 +62,7 @@ create or replace package body test_extended_coverage is values(a_run_id, user, sysdate, 'unit testing utPLSQL'); insert into 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); + values(a_run_id, c_unit_id, 'PACKAGE BODY', 'UT3', 'DUMMY_COVERAGE_PACKAGE_WITH_AN_AMAZINGLY_LONG_NAME_THAT_YOU_WOULD_NOT_THINK_OF_IN_REAL_LIFE_PROJECT_BECAUSE_ITS_SIMPLY_TOO_LONG',sysdate); insert into 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 @@ -78,7 +78,7 @@ create or replace package body test_extended_coverage is 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'); + values(a_run_id, c_unit_id, 'PACKAGE BODY', 'UT3', 'DUMMY_COVERAGE_PACKAGE_WITH_AN_AMAZINGLY_LONG_NAME_THAT_YOU_WOULD_NOT_THINK_OF_IN_REAL_LIFE_PROJECT_BECAUSE_ITS_SIMPLY_TOO_LONG'); 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 @@ -104,7 +104,7 @@ create or replace package body test_extended_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; + begin execute immediate q'[drop package ut3.dummy_coverage_package_with_an_amazingly_long_name_that_you_would_not_think_of_in_real_life_project_because_its_simply_too_long]'; exception when others then null; end; delete from dbmspcc_blocks where run_id = g_run_id(ut3.ut_coverage.gc_block_coverage); delete from dbmspcc_units where run_id = g_run_id(ut3.ut_coverage.gc_block_coverage); delete from dbmspcc_runs where run_id = g_run_id(ut3.ut_coverage.gc_block_coverage); @@ -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 @@ -128,7 +128,7 @@ 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_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage' ) + a_include_objects => ut3.ut_varchar2_list( 'ut3.dummy_coverage_package_with_an_amazingly_long_name_that_you_would_not_think_of_in_real_life_project_because_its_simply_too_long' ) ) ); --Assert @@ -142,7 +142,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 @@ -163,10 +163,10 @@ create or replace package body test_extended_coverage is l_expected clob; l_actual clob; l_results ut3.ut_varchar2_list; - l_file_path varchar2(100); + l_file_path varchar2(250); begin --Arrange - l_file_path := lower('test/ut3.dummy_coverage.pkb'); + l_file_path := lower('test/ut3.dummy_coverage_package_with_an_amazingly_long_name_that_you_would_not_think_of_in_real_life_project_because_its_simply_too_long.pkb'); l_expected := '%%%'; --Act select * From a966451e2c3983e3fc82f6f4102701f46455f86b Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 25 Sep 2018 00:36:08 +0100 Subject: [PATCH 047/115] Added cardinality to SQL on xmltable to avoid excessive estimates. Resolves #752 --- .../data_values/ut_compound_data_helper.pkb | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/source/expectations/data_values/ut_compound_data_helper.pkb b/source/expectations/data_values/ut_compound_data_helper.pkb index ee01819d6..19a534ebc 100644 --- a/source/expectations/data_values/ut_compound_data_helper.pkb +++ b/source/expectations/data_values/ut_compound_data_helper.pkb @@ -95,37 +95,39 @@ create or replace package body ut_compound_data_helper is with expected_cols as ( select :a_expected as item_data from dual ), actual_cols as ( select :a_actual as item_data from dual ), - expected_cols_info as ( - select e.*, + expected_cols_info as ( + select /*+ cardinality(e 100) */ + e.*, replace(expected_type,'VARCHAR2','CHAR') expected_type_compare from ( - SELECT rownum expected_pos, - xt.name expected_name, - xt.type expected_type - FROM (select ]'||l_column_filter||q'[ from expected_cols ucd) x, - XMLTABLE('/ROW/*' - PASSING x.item_data - COLUMNS - name VARCHAR2(4000) PATH '@xml_valid_name', - type VARCHAR2(4000) PATH '/' - ) xt - ) e + select rownum expected_pos, + xt.name expected_name, + xt.type expected_type + from (select ]'||l_column_filter||q'[ from expected_cols ucd) x, + xmltable( + '/ROW/*' + passing x.item_data + columns + name varchar2(4000) PATH '@xml_valid_name', + type varchar2(4000) PATH '/' + ) xt + ) e ), actual_cols_info as ( - select a.*, + select /*+ cardinality(a 100) */ + a.*, replace(actual_type,'VARCHAR2','CHAR') actual_type_compare - from ( - SELECT rownum actual_pos, - xt.name actual_name, - xt.type actual_type - FROM (select ]'||l_column_filter||q'[ from actual_cols ucd) x, - XMLTABLE('/ROW/*' - PASSING x.item_data - COLUMNS - name VARCHAR2(4000) PATH '@xml_valid_name', - type VARCHAR2(4000) PATH '/' - ) xt - ) a + from (select rownum actual_pos, + xt.name actual_name, + xt.type actual_type + from (select ]'||l_column_filter||q'[ from actual_cols ucd) x, + xmltable('/ROW/*' + passing x.item_data + columns + name varchar2(4000) path '@xml_valid_name', + type varchar2(4000) path '/' + ) xt + ) a ), joined_cols as ( select e.*, a.*, @@ -134,7 +136,8 @@ create or replace package body ut_compound_data_helper is from expected_cols_info e full outer join actual_cols_info a on e.expected_name = a.actual_name ) - select case + select /*+ cardinality(joined_cols 100)*/ + case when expected_pos is null and actual_pos is not null then '+' when expected_pos is not null and actual_pos is null then '-' when expected_type_compare != actual_type_compare then 't' From eb0dab742764d52731a9eb932ee00d29e736aad2 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 25 Sep 2018 12:07:27 +0100 Subject: [PATCH 048/115] Additional cardinality hint. --- .../expectations/data_values/ut_compound_data_helper.pkb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/expectations/data_values/ut_compound_data_helper.pkb b/source/expectations/data_values/ut_compound_data_helper.pkb index 19a534ebc..92d9fb399 100644 --- a/source/expectations/data_values/ut_compound_data_helper.pkb +++ b/source/expectations/data_values/ut_compound_data_helper.pkb @@ -91,6 +91,7 @@ create or replace package body ut_compound_data_helper is l_results tt_column_diffs; begin l_column_filter := get_columns_row_filter(a_exclude_xpath, a_include_xpath); + --CARDINALITY hints added to address issue: https://github.com/utPLSQL/utPLSQL/issues/752 l_sql := q'[ with expected_cols as ( select :a_expected as item_data from dual ), @@ -100,7 +101,8 @@ create or replace package body ut_compound_data_helper is e.*, replace(expected_type,'VARCHAR2','CHAR') expected_type_compare from ( - select rownum expected_pos, + select /*+ cardinality(xt 100) */ + rownum expected_pos, xt.name expected_name, xt.type expected_type from (select ]'||l_column_filter||q'[ from expected_cols ucd) x, @@ -117,7 +119,8 @@ create or replace package body ut_compound_data_helper is select /*+ cardinality(a 100) */ a.*, replace(actual_type,'VARCHAR2','CHAR') actual_type_compare - from (select rownum actual_pos, + from (select /*+ cardinality(xt 100) */ + rownum actual_pos, xt.name actual_name, xt.type actual_type from (select ]'||l_column_filter||q'[ from actual_cols ucd) x, From ad6059f5a4e4eb24b7d75db0fdba3255751fb90b Mon Sep 17 00:00:00 2001 From: Travis CI Date: Tue, 25 Sep 2018 13:18:49 +0000 Subject: [PATCH 049/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 4ea6ed0f7..ae2f6710f 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2238-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2245-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 0f592e6572e31da1be19435b88752eedd78f6ff4 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 25 Sep 2018 23:44:54 +0100 Subject: [PATCH 050/115] Cleanup of cardinality hints. --- .../data_values/ut_compound_data_helper.pkb | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/source/expectations/data_values/ut_compound_data_helper.pkb b/source/expectations/data_values/ut_compound_data_helper.pkb index 92d9fb399..e6665bd10 100644 --- a/source/expectations/data_values/ut_compound_data_helper.pkb +++ b/source/expectations/data_values/ut_compound_data_helper.pkb @@ -97,11 +97,10 @@ create or replace package body ut_compound_data_helper is expected_cols as ( select :a_expected as item_data from dual ), actual_cols as ( select :a_actual as item_data from dual ), expected_cols_info as ( - select /*+ cardinality(e 100) */ - e.*, + select e.*, replace(expected_type,'VARCHAR2','CHAR') expected_type_compare from ( - select /*+ cardinality(xt 100) */ + select /*+ CARDINALITY(xt 100) */ rownum expected_pos, xt.name expected_name, xt.type expected_type @@ -116,10 +115,9 @@ create or replace package body ut_compound_data_helper is ) e ), actual_cols_info as ( - select /*+ cardinality(a 100) */ - a.*, + select a.*, replace(actual_type,'VARCHAR2','CHAR') actual_type_compare - from (select /*+ cardinality(xt 100) */ + from (select /*+ CARDINALITY(xt 100) */ rownum actual_pos, xt.name actual_name, xt.type actual_type @@ -139,8 +137,7 @@ create or replace package body ut_compound_data_helper is from expected_cols_info e full outer join actual_cols_info a on e.expected_name = a.actual_name ) - select /*+ cardinality(joined_cols 100)*/ - case + select case when expected_pos is null and actual_pos is not null then '+' when expected_pos is not null and actual_pos is null then '-' when expected_type_compare != actual_type_compare then 't' From a6e4e6aafb338b969a2c413f29858fd5e8af3488 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Wed, 26 Sep 2018 00:43:00 +0000 Subject: [PATCH 051/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index ae2f6710f..a96253c58 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2245-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2251-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From ab64302b86165d79237fd416e92e1168221f85ea Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 19 Oct 2018 17:57:26 +0200 Subject: [PATCH 052/115] Change CLI version to 3.1.0. It is a requirement to test the current develp branch --- development/template.env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/template.env.sh b/development/template.env.sh index 1e90aaed3..94004c89d 100755 --- a/development/template.env.sh +++ b/development/template.env.sh @@ -4,7 +4,7 @@ export SQLCLI=sql # For sqlcl client #export SQLCLI=sqlplus # For sqlplus client export CONNECTION_STR=127.0.0.1:1521/xe # Adjust the connect string export ORACLE_PWD=oracle # Adjust your local SYS password -export UTPLSQL_CLI_VERSION="3.0.4" +export UTPLSQL_CLI_VERSION="3.1.0" export SELFTESTING_BRANCH=develop export UTPLSQL_DIR="utPLSQL_latest_release" From 9c3b1fffcb0cce5d275661a2833a3f715b075e28 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 19 Oct 2018 17:58:12 +0200 Subject: [PATCH 053/115] ignore temporary files created by actions described in CONTRIBUTING.md --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index 13452754f..197d0f5e9 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,13 @@ utPLSQL_latest_release/ utPLSQL-cli/ development/env.sh *.log + +# exclusions based on artifacts created via actions documented in CONTRIBUTING.md +test/dummy.sql +coverage.html_assets/ +coverage.html +coverage.json +coverage.xml +tfs_test_results.xml +junit_test_results.xml +test_results.xml From 766837e38efa11595da836d498f73ed47db360d3 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 19 Oct 2018 19:00:38 +0100 Subject: [PATCH 054/115] Fixing test dependency on NLS settings. Fixing test dependency on global_names (for DB links) Fixing missing privs. Resolves #765 --- .../create_synonyms_and_grants_for_public.sql | 4 +- source/create_user_grants.sql | 4 +- test/api/test_ut_run.pkb | 2 +- .../test_annot_throws_exception.pkb | 40 +++++++++---------- ....pkb => test_before_after_annotations.pkb} | 4 +- ....pks => test_before_after_annotations.pks} | 0 test/core/reporters/test_junit_reporter.pkb | 2 +- .../reporters/test_tfs_junit_reporter.pkb | 2 +- test/install_tests.sql | 4 +- 9 files changed, 31 insertions(+), 31 deletions(-) rename test/core/annotations/{test_before_after_test_annotation.pkb => test_before_after_annotations.pkb} (98%) rename test/core/annotations/{test_before_after_test_annotation.pks => test_before_after_annotations.pks} (100%) diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql index 17452ec0c..1ac5bb9ea 100644 --- a/source/create_synonyms_and_grants_for_public.sql +++ b/source/create_synonyms_and_grants_for_public.sql @@ -76,8 +76,8 @@ grant execute on &&ut3_owner..ut_file_mapping to public; grant execute on &&ut3_owner..ut_file_mapper to public; grant execute on &&ut3_owner..ut_key_value_pairs to public; grant execute on &&ut3_owner..ut_key_value_pair to public; -grant select, insert, delete on &&ut3_owner..ut_compound_data_tmp to public; -grant select, insert, delete on &&ut3_owner..ut_compound_data_diff_tmp to public; +grant select, insert, update, delete on &&ut3_owner..ut_compound_data_tmp to public; +grant select, insert, update, delete on &&ut3_owner..ut_compound_data_diff_tmp to public; grant execute on &&ut3_owner..ut_sonar_test_reporter to public; grant execute on &&ut3_owner..ut_annotations to public; grant execute on &&ut3_owner..ut_annotation to public; diff --git a/source/create_user_grants.sql b/source/create_user_grants.sql index bae0364be..07d9097f3 100644 --- a/source/create_user_grants.sql +++ b/source/create_user_grants.sql @@ -96,8 +96,8 @@ grant execute on &&ut3_owner..ut_file_mapping to &ut3_user; grant execute on &&ut3_owner..ut_file_mapper to &ut3_user; grant execute on &&ut3_owner..ut_key_value_pairs to &ut3_user; grant execute on &&ut3_owner..ut_key_value_pair to &ut3_user; -grant select, insert, delete on &&ut3_owner..ut_compound_data_tmp to &ut3_user; -grant select, insert, delete on &&ut3_owner..ut_compound_data_diff_tmp to &ut3_user; +grant select, insert, update, delete on &&ut3_owner..ut_compound_data_tmp to &ut3_user; +grant select, insert, update, delete on &&ut3_owner..ut_compound_data_diff_tmp to &ut3_user; grant execute on &&ut3_owner..ut_sonar_test_reporter to &ut3_user; grant execute on &&ut3_owner..ut_annotations to &ut3_user; grant execute on &&ut3_owner..ut_annotation to &ut3_user; diff --git a/test/api/test_ut_run.pkb b/test/api/test_ut_run.pkb index 704627ac9..dae7e175a 100644 --- a/test/api/test_ut_run.pkb +++ b/test/api/test_ut_run.pkb @@ -589,7 +589,7 @@ create or replace package body test_ut_run is failing_stateful_test [% sec] (FAILED - 1)% Failures:% 1) failing_stateful_test - ORA-04068: existing state of packages (DB_LOOPBACK) has been discarded + ORA-04068: existing state of packages (DB_LOOPBACK%) has been discarded ORA-04061: existing state of package body "UT3_TESTER.STATEFUL_PACKAGE" has been invalidated ORA-04065: not executed, altered or dropped package body "UT3_TESTER.STATEFUL_PACKAGE"% ORA-06512: at line 6% diff --git a/test/core/annotations/test_annot_throws_exception.pkb b/test/core/annotations/test_annot_throws_exception.pkb index 2c8c3be2c..1ad4f19a5 100644 --- a/test/core/annotations/test_annot_throws_exception.pkb +++ b/test/core/annotations/test_annot_throws_exception.pkb @@ -240,43 +240,43 @@ is procedure throws_same_annotated_except is begin - ut.expect(g_tests_results).to_match('^\s*Throws same annotated exception \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Throws same annotated exception \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('raised_same_exception'); end; procedure throws_one_of_annotated_excpt is begin - ut.expect(g_tests_results).to_match('^\s*Throws one of the listed exceptions \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Throws one of the listed exceptions \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('raised_one_listed_exception'); end; procedure throws_with_leading_zero is begin - ut.expect(g_tests_results).to_match('^\s*Leading zero is ignored in exception list \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Leading zero is ignored in exception list \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('leading_0_exception_no'); end; procedure throws_diff_annotated_except is begin - ut.expect(g_tests_results).to_match('^\s*Throws diff exception \[[\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Throws diff exception \[[,\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); ut.expect(g_tests_results).to_match('raised_diff_exception\s+Actual: -20143 was expected to equal: -20144\s+ORA-20143: Test error\s+ORA-06512: at "UT3_TESTER.ANNOTATED_PACKAGE_WITH_THROWS"'); end; procedure throws_empty is begin - ut.expect(g_tests_results).to_match('^\s*Throws empty \[[\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Throws empty \[[,\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); ut.expect(g_tests_results).to_match('empty_throws\s*ORA-20143: Test error\s*ORA-06512: at "UT3_TESTER.ANNOTATED_PACKAGE_WITH_THROWS"'); end; procedure bad_paramters_with_except is begin - ut.expect(g_tests_results).to_match('^\s*Ignores annotation and fails when exception was thrown \[[\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Ignores annotation and fails when exception was thrown \[[,\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); ut.expect(g_tests_results).to_match('bad_paramters_with_except\s*ORA-20143: Test error\s*ORA-06512: at "UT3_TESTER.ANNOTATED_PACKAGE_WITH_THROWS"'); end; procedure bad_paramters_without_except is begin - ut.expect(g_tests_results).to_match('^\s*Ignores annotation and succeeds when no exception thrown \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Ignores annotation and succeeds when no exception thrown \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('bad_paramters_without_except'); end; @@ -288,79 +288,79 @@ is procedure nothing_thrown is begin - ut.expect(g_tests_results).to_match('^\s*Gives failure when a exception is expected and nothing is thrown \[[\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Gives failure when a exception is expected and nothing is thrown \[[,\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); ut.expect(g_tests_results).to_match('nothing_thrown\s*Expected one of exceptions \(-20459, -20136, -20145\) but nothing was raised.'); end; procedure single_exc_const_pkg is begin - ut.expect(g_tests_results).to_match('^\s*Single exception defined as a constant number in package \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Single exception defined as a constant number in package \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('single_exc_const_pkg'); end; procedure list_of_exc_constant is begin - ut.expect(g_tests_results).to_match('^\s*Gives success when one of annotated exception using constant is thrown \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Gives success when one of annotated exception using constant is thrown \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('list_of_exc_constant'); end; procedure fail_not_match_exc is begin - ut.expect(g_tests_results).to_match('^\s*Gives failure when the raised exception is different that the annotated one using variable \[[\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Gives failure when the raised exception is different that the annotated one using variable \[[,\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); ut.expect(g_tests_results).to_match('fail_not_match_exc\s+Actual: -1403 was expected to equal: -20204\s+ORA-01403: no data found\s+ORA-06512: at "UT3_TESTER.ANNOTATED_PACKAGE_WITH_THROWS"'); end; procedure mixed_exc_list is begin - ut.expect(g_tests_results).to_match('^\s*Success when one of exception from mixed list of number and constant is thrown \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Success when one of exception from mixed list of number and constant is thrown \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('mixed_exc_list'); end; procedure mixed_list_notexi is begin - ut.expect(g_tests_results).to_match('^\s*Success when match exception even if other variable on list dont exists \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Success when match exception even if other variable on list dont exists \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('mixed_list_notexi'); end; procedure named_exc_pragma is begin - ut.expect(g_tests_results).to_match('^\s*Success resolve and match named exception defined in pragma exception init \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Success resolve and match named exception defined in pragma exception init \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('mixed_list_notexi'); end; procedure named_exc_ora is begin - ut.expect(g_tests_results).to_match('^\s*Success resolve and match oracle named exception \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Success resolve and match oracle named exception \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('named_exc_ora'); end; procedure named_exc_ora_dup_ind is begin - ut.expect(g_tests_results).to_match('^\s*Success resolve and match oracle named exception dup val index \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Success resolve and match oracle named exception dup val index \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('named_exc_ora_dup_ind'); end; procedure nodata_exc_ora is begin - ut.expect(g_tests_results).to_match('^\s*Success map no data 100 to -1403 \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Success map no data 100 to -1403 \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('nodata_exc_ora'); end; procedure defined_varchar_exc is begin - ut.expect(g_tests_results).to_match('^\s*Success for exception defined as varchar \[[\.0-9]+ sec\]\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Success for exception defined as varchar \[[,\.0-9]+ sec\]\s*$','m'); ut.expect(g_tests_results).not_to_match('defined_varchar_exc'); end; procedure non_existing_const is begin - ut.expect(g_tests_results).to_match('^\s*Non existing constant exception \[[\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Non existing constant exception \[[,\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); ut.expect(g_tests_results).to_match('non_existing_const\s*ORA-20143: Test error\s*ORA-06512: at "UT3_TESTER.ANNOTATED_PACKAGE_WITH_THROWS"'); end; procedure bad_exc_const is begin - ut.expect(g_tests_results).to_match('^\s*Bad exception constant \[[\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); + ut.expect(g_tests_results).to_match('^\s*Bad exception constant \[[,\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m'); ut.expect(g_tests_results).to_match('bad_exc_const\s*ORA-20143: Test error\s*ORA-06512: at "UT3_TESTER.ANNOTATED_PACKAGE_WITH_THROWS"'); end; diff --git a/test/core/annotations/test_before_after_test_annotation.pkb b/test/core/annotations/test_before_after_annotations.pkb similarity index 98% rename from test/core/annotations/test_before_after_test_annotation.pkb rename to test/core/annotations/test_before_after_annotations.pkb index 06871a335..0aa9f5c39 100644 --- a/test/core/annotations/test_before_after_test_annotation.pkb +++ b/test/core/annotations/test_before_after_annotations.pkb @@ -277,7 +277,7 @@ create or replace package body test_before_after_annotations is ut.expect(l_actual).to_be_empty; ut.expect(g_tests_results).to_match( - '^\s*Stops execution at first non-existing Beforetest procedure and marks test as errored \[[\.0-9]+ sec\] \(FAILED - 1\)\s*$' + '^\s*Stops execution at first non-existing Beforetest procedure and marks test as errored \[[,\.0-9]+ sec\] \(FAILED - 1\)\s*$' ,'m' ); ut.expect(g_tests_results).to_match( @@ -297,7 +297,7 @@ create or replace package body test_before_after_annotations is ut.expect(l_actual).to_be_empty; ut.expect(g_tests_results).to_match( - '^\s*Stops execution at first non-existing Beforetest procedure and marks test as errored \[[\.0-9]+ sec\] \(FAILED - 1\)\s*$' + '^\s*Stops execution at first non-existing Beforetest procedure and marks test as errored \[[,\.0-9]+ sec\] \(FAILED - 1\)\s*$' ,'m' ); ut.expect(g_tests_results).to_match( diff --git a/test/core/annotations/test_before_after_test_annotation.pks b/test/core/annotations/test_before_after_annotations.pks similarity index 100% rename from test/core/annotations/test_before_after_test_annotation.pks rename to test/core/annotations/test_before_after_annotations.pks diff --git a/test/core/reporters/test_junit_reporter.pkb b/test/core/reporters/test_junit_reporter.pkb index 6cd67b8a3..e0a7ea00d 100644 --- a/test/core/reporters/test_junit_reporter.pkb +++ b/test/core/reporters/test_junit_reporter.pkb @@ -166,7 +166,7 @@ create or replace package body test_junit_reporter as l_nls_numeric_characters varchar2(30); begin --Arrange - select nsp.value into l_nls_numeric_characters + select replace(nsp.value,'''','''''') into l_nls_numeric_characters from nls_session_parameters nsp where parameter = 'NLS_NUMERIC_CHARACTERS'; execute immediate q'[alter session set NLS_NUMERIC_CHARACTERS=', ']'; diff --git a/test/core/reporters/test_tfs_junit_reporter.pkb b/test/core/reporters/test_tfs_junit_reporter.pkb index bd09b8682..122c665e3 100644 --- a/test/core/reporters/test_tfs_junit_reporter.pkb +++ b/test/core/reporters/test_tfs_junit_reporter.pkb @@ -149,7 +149,7 @@ create or replace package body test_tfs_junit_reporter as l_nls_numeric_characters varchar2(30); begin --Arrange - select nsp.value into l_nls_numeric_characters + select replace(nsp.value,'''','''''') into l_nls_numeric_characters from nls_session_parameters nsp where parameter = 'NLS_NUMERIC_CHARACTERS'; execute immediate q'[alter session set NLS_NUMERIC_CHARACTERS=', ']'; diff --git a/test/install_tests.sql b/test/install_tests.sql index 2aa60692c..2f1292b74 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -23,7 +23,7 @@ alter session set plsql_optimize_level=0; @@core/test_ut_test.pks @@core/annotations/test_annotation_parser.pks @@core/annotations/test_annotation_manager.pks -@@core/annotations/test_before_after_test_annotation.pks +@@core/annotations/test_before_after_annotations.pks @@core/expectations/test_expectation_processor.pks @@core/expectations/test_matchers.pks @@core/test_output_buffer.pks @@ -74,7 +74,7 @@ set define off @@core/annotations/test_annotation_manager.pkb @@core/expectations/test_expectation_processor.pkb @@core/expectations/test_matchers.pkb -@@core/annotations/test_before_after_test_annotation.pkb +@@core/annotations/test_before_after_annotations.pkb @@core/test_output_buffer.pkb @@core/test_file_mapper.pkb @@core/test_suite_manager.pkb From aa4e3d53f9eae584491710cdadc085bd55b4e2a1 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 19 Oct 2018 19:07:08 +0100 Subject: [PATCH 055/115] Adding fix to avoid running sonar-scanner on external pull-requests. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a6aecb53c..58aa254e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -95,7 +95,7 @@ before_script: script: - if [[ ! $TRAVIS_TAG ]]; then bash test/install_and_run_tests.sh; fi - if [[ ! $TRAVIS_TAG ]]; then bash .travis/validate_report_files.sh; fi - - if [[ ! $TRAVIS_TAG ]] && [ "${TRAVIS_REPO_SLUG}" = "${UTPLSQL_REPO}" ]; then bash .travis/run_sonar_scanner.sh; fi + - if [[ ! $TRAVIS_TAG ]] && [ "${TRAVIS_REPO_SLUG}" = "${UTPLSQL_REPO}" ] && [ "${TRAVIS_PULL_REQUEST_SLUG}" = "${TRAVIS_REPO_SLUG}" ]; then bash .travis/run_sonar_scanner.sh; fi - if [[ ! $TRAVIS_TAG ]]; then bash .travis/coveralls_uploader.sh; fi notifications: From f818af4873e229f5fcd57142368740b0061ef383 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Fri, 19 Oct 2018 20:03:12 +0000 Subject: [PATCH 056/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index a96253c58..a4388c523 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2251-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2276-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From db19e3089f4c605a09567ac2d96c2cf3e5b59caa Mon Sep 17 00:00:00 2001 From: Travis CI Date: Fri, 19 Oct 2018 23:12:12 +0000 Subject: [PATCH 057/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index a4388c523..fbf9a73ae 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2276-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2278-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From e5df0e20cfe4e17ebc87fc8fb56550065723d4bb Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sat, 20 Oct 2018 22:20:05 +0100 Subject: [PATCH 058/115] fix to unordered. Due to missing duplicate_no in populated table the data results been skewed. --- .../data_values/ut_compound_data_helper.pkb | 5 +-- .../data_values/ut_compound_data_value.tpb | 23 +++++++++---- .../expectations/test_expectations_cursor.pkb | 34 ++++++++++++++++++- .../expectations/test_expectations_cursor.pks | 5 ++- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/source/expectations/data_values/ut_compound_data_helper.pkb b/source/expectations/data_values/ut_compound_data_helper.pkb index e6665bd10..c6a38e35c 100644 --- a/source/expectations/data_values/ut_compound_data_helper.pkb +++ b/source/expectations/data_values/ut_compound_data_helper.pkb @@ -373,8 +373,7 @@ create or replace package body ut_compound_data_helper is /** * Since its unordered search we cannot select max rows from diffs as we miss some comparision records * We will restrict output on higher level of select - */ - + */ execute immediate q'[with diff_info as (select item_hash,duplicate_no from ut_compound_data_diff_tmp ucdc where diff_id = :diff_guid) select duplicate_no, @@ -403,6 +402,7 @@ create or replace package body ut_compound_data_helper is diff_info i where ucd.data_id = :self_guid and ucd.item_hash = i.item_hash + and ucd.duplicate_no = i.duplicate_no ) r, table( xmlsequence( extract(r.item_data,'/*') ) ) ucd ) ucd @@ -417,6 +417,7 @@ create or replace package body ut_compound_data_helper is diff_info i where ucd.data_id = :other_guid and ucd.item_hash = i.item_hash + and ucd.duplicate_no = i.duplicate_no ) r, table( xmlsequence( extract(r.item_data,'/*') ) ) ucd ) ucd diff --git a/source/expectations/data_values/ut_compound_data_value.tpb b/source/expectations/data_values/ut_compound_data_value.tpb index 113c5153e..de81830dd 100644 --- a/source/expectations/data_values/ut_compound_data_value.tpb +++ b/source/expectations/data_values/ut_compound_data_value.tpb @@ -234,6 +234,13 @@ create or replace type body ut_compound_data_value as **/ execute immediate 'merge into ' || l_ut_owner || '.ut_compound_data_tmp tgt using ( + select ucd_out.item_hash, + ucd_out.pk_hash, + ucd_out.item_no, + ucd_out.data_id, + row_number() over (partition by ucd_out.pk_hash,ucd_out.item_hash,ucd_out.data_id order by 1,2) duplicate_no + from + ( select '||l_ut_owner ||'.ut_compound_data_helper.get_hash(ucd.item_data.getclobval()) item_hash, pk_hash, ucd.item_no, ucd.data_id from @@ -242,17 +249,19 @@ create or replace type body ut_compound_data_value as from ' || l_ut_owner || q'[.ut_compound_data_tmp ucd where data_id = :self_guid or data_id = :other_guid ) ucd + )ucd_out ) src on (tgt.item_no = src.item_no and tgt.data_id = src.data_id) when matched then update set tgt.item_hash = src.item_hash, - tgt.pk_hash = src.pk_hash ]' + tgt.pk_hash = src.pk_hash, + tgt.duplicate_no = src.duplicate_no]' using a_exclude_xpath, a_include_xpath,a_join_by_xpath,self.data_id, l_other.data_id; /* Peform minus on two sets two get diffrences that will be used later on to print results */ execute immediate 'insert into ' || l_ut_owner || '.ut_compound_data_diff_tmp ( diff_id,item_hash,pk_hash,duplicate_no) with source_data as - ( select t.data_id,t.item_hash,row_number() over (partition by t.pk_hash,t.item_hash,t.data_id order by 1,2) duplicate_no, + ( select t.data_id,t.item_hash,t.duplicate_no, pk_hash from ' || l_ut_owner || '.ut_compound_data_tmp t where data_id = :self_guid or data_id = :other_guid @@ -260,21 +269,21 @@ create or replace type body ut_compound_data_value as select distinct :diff_id,tmp.item_hash,tmp.pk_hash,tmp.duplicate_no from( ( - select t.item_hash,t. duplicate_no,t.pk_hash + select t.item_hash,t.duplicate_no,t.pk_hash from source_data t where t.data_id = :self_guid minus - select t.item_hash,t. duplicate_no,t.pk_hash + select t.item_hash,t.duplicate_no,t.pk_hash from source_data t where t.data_id = :other_guid ) union all ( - select t.item_hash,t. duplicate_no,t.pk_hash + select t.item_hash,t.duplicate_no,t.pk_hash from source_data t where t.data_id = :other_guid minus - select t.item_hash,t. duplicate_no,t.pk_hash + select t.item_hash,t.duplicate_no,t.pk_hash from source_data t where t.data_id = :self_guid ))tmp' @@ -282,7 +291,7 @@ create or replace type body ut_compound_data_value as l_diff_id, self.data_id, l_other.data_id, l_other.data_id,self.data_id; - --result is OK only if both are same + --result is OK only if both are same if sql%rowcount = 0 and self.elements_count = l_other.elements_count then l_result := 0; else diff --git a/test/core/expectations/test_expectations_cursor.pkb b/test/core/expectations/test_expectations_cursor.pkb index d18cef5fb..fb75b2da8 100644 --- a/test/core/expectations/test_expectations_cursor.pkb +++ b/test/core/expectations/test_expectations_cursor.pkb @@ -1986,6 +1986,38 @@ Diff:% ut.expect(l_actual_message).to_be_like(l_expected_message); end; - + + procedure unordered_fix_764 is + l_actual sys_refcursor; + l_expected sys_refcursor; + l_expected_message varchar2(32767); + l_actual_message varchar2(32767); + begin + open l_expected for + select 'Table' as name from dual + union all + select 'Desk' as name from dual + union all + select 'Table' as name from dual; + + open l_actual for + select 'Desk' as name from dual + union all + select 'Table' as name from dual; + + --Assert + ut3.ut.expect( l_actual ).to_equal( l_expected ).unordered(); + + --Assert + l_expected_message := q'[%Actual: refcursor [ count = 2 ] was expected to equal: refcursor [ count = 3 ] +%Diff: +%Rows: [ 1 differences ] +%Missing: Table%]'; + l_actual_message := ut3.ut_expectation_processor.get_failed_expectations()(1).message; + --Assert + ut.expect(l_actual_message).to_be_like(l_expected_message); + + end; + end; / diff --git a/test/core/expectations/test_expectations_cursor.pks b/test/core/expectations/test_expectations_cursor.pks index a1cff85d9..88d59e1a3 100644 --- a/test/core/expectations/test_expectations_cursor.pks +++ b/test/core/expectations/test_expectations_cursor.pks @@ -315,6 +315,9 @@ create or replace package test_expectations_cursor is --%test(Trying to join on collection element inside record ) procedure compare_rec_coll_as_join; - + + --%test( Unordered fix for issues with duplicate no : #764 ) + procedure unordered_fix_764; + end; / From 44713a53c5dabf6299175b025b3529eec54af5fd Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sat, 20 Oct 2018 22:41:01 +0100 Subject: [PATCH 059/115] Moving uninstall tests to child job no 2 - (12.1) as it is now fastest build. --- .travis/install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis/install.sh b/.travis/install.sh index 7b799eaa0..528b44f20 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -13,8 +13,8 @@ alter session set plsql_optimize_level=0; @install_headless.sql $UT3_OWNER $UT3_OWNER_PASSWORD SQL -#Run this step only on first job slave (11.2 - at it's fastest) -if [[ "${TRAVIS_JOB_NUMBER}" =~ \.1$ ]]; then +#Run this step only on second child job (12.1 - at it's fastest) +if [[ "${TRAVIS_JOB_NUMBER}" =~ \.2$ ]]; then #check code-style for errors time "$SQLCLI" $UT3_OWNER/$UT3_OWNER_PASSWORD@//$CONNECTION_STR @../development/utplsql_style_check.sql From 306674aa0303ebc398d2eea287da1320233258a9 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sat, 20 Oct 2018 23:27:34 +0000 Subject: [PATCH 060/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index fbf9a73ae..a42cda124 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2278-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2284-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 19290a4e8cd320510f4e4365fee02844cbbc2d12 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 21 Oct 2018 01:54:35 +0100 Subject: [PATCH 061/115] Disabling compilation with PLSQL compiler warnings. --- .travis/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/install.sh b/.travis/install.sh index 528b44f20..e37cfa35f 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -8,7 +8,7 @@ time "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL set feedback off set verify off -alter session set plsql_warnings = 'ENABLE:ALL', 'DISABLE:(5004,5018,6000,6001,6003,6009,6010,7206)'; +--alter session set plsql_warnings = 'ENABLE:ALL', 'DISABLE:(5004,5018,6000,6001,6003,6009,6010,7206)'; alter session set plsql_optimize_level=0; @install_headless.sql $UT3_OWNER $UT3_OWNER_PASSWORD SQL From 013cba3b91e6f56b0963b393fe83ecd8a4711176 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sun, 21 Oct 2018 01:24:18 +0000 Subject: [PATCH 062/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index a42cda124..5623efa9b 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2284-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2297-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From b05dbd7427959e8e5a5b30475b740a2e13da15da Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sat, 27 Oct 2018 15:13:59 +0100 Subject: [PATCH 063/115] Fix to issue #770 when the merge statement is run via current user which can result in error due to missing privs to internal function --- .../data_values/ut_compound_data_helper.pkb | 53 +++++++++++++++++++ .../data_values/ut_compound_data_helper.pks | 3 ++ .../data_values/ut_compound_data_value.tpb | 47 ++-------------- 3 files changed, 59 insertions(+), 44 deletions(-) diff --git a/source/expectations/data_values/ut_compound_data_helper.pkb b/source/expectations/data_values/ut_compound_data_helper.pkb index c6a38e35c..0fba5b0e7 100644 --- a/source/expectations/data_values/ut_compound_data_helper.pkb +++ b/source/expectations/data_values/ut_compound_data_helper.pkb @@ -541,5 +541,58 @@ create or replace package body ut_compound_data_helper is return l_no_missing_keys; end; + procedure update_row_and_pk_hash(a_self_data_id in raw, a_other_data_id in raw, a_exclude_xpath varchar2, + a_include_xpath varchar2, a_join_by_xpath varchar2) is + l_ut_owner varchar2(250) := ut_utils.ut_owner; + l_column_filter varchar2(32767); + l_pk_hash_sql varchar2(32767); + + function get_column_pk_hash(a_join_by_xpath varchar2) return varchar2 is + l_column varchar2(32767); + begin + /* due to possibility of key being to columns we cannot use xmlextractvalue + usage of xmlagg is possible however it greatly complicates code and performance is impacted. + xpath to be looked at or regex + */ + if a_join_by_xpath is not null then + l_column := l_ut_owner ||'.ut_compound_data_helper.get_hash(extract(ucd.item_data,:join_by_xpath).GetClobVal()) pk_hash'; + else + l_column := ':join_by_xpath pk_hash'; + end if; + return l_column; + end; + + begin + l_column_filter := ut_compound_data_helper.get_columns_filter(a_exclude_xpath, a_include_xpath); + l_pk_hash_sql := get_column_pk_hash(a_join_by_xpath); + + execute immediate 'merge into ' || l_ut_owner || '.ut_compound_data_tmp tgt + using ( + select ucd_out.item_hash, + ucd_out.pk_hash, + ucd_out.item_no, + ucd_out.data_id, + row_number() over (partition by ucd_out.pk_hash,ucd_out.item_hash,ucd_out.data_id order by 1,2) duplicate_no + from + ( + select '||l_ut_owner ||'.ut_compound_data_helper.get_hash(ucd.item_data.getclobval()) item_hash, + pk_hash, ucd.item_no, ucd.data_id + from + ( + select '||l_column_filter||','||l_pk_hash_sql||', item_no, data_id + from ' || l_ut_owner || q'[.ut_compound_data_tmp ucd + where data_id = :self_guid or data_id = :other_guid + ) ucd + )ucd_out + ) src + on (tgt.item_no = src.item_no and tgt.data_id = src.data_id) + when matched then update + set tgt.item_hash = src.item_hash, + tgt.pk_hash = src.pk_hash, + tgt.duplicate_no = src.duplicate_no]' + using a_exclude_xpath, a_include_xpath,a_join_by_xpath,a_self_data_id, a_other_data_id; + + end; + end; / diff --git a/source/expectations/data_values/ut_compound_data_helper.pks b/source/expectations/data_values/ut_compound_data_helper.pks index ab3693920..a18c20952 100644 --- a/source/expectations/data_values/ut_compound_data_helper.pks +++ b/source/expectations/data_values/ut_compound_data_helper.pks @@ -81,5 +81,8 @@ create or replace package ut_compound_data_helper authid definer is function is_pk_exists(a_expected_cursor xmltype, a_actual_cursor xmltype, a_exclude_xpath varchar2, a_include_xpath varchar2,a_join_by_xpath varchar2) return tt_missing_pk; + procedure update_row_and_pk_hash(a_self_data_id in raw, a_other_data_id in raw, a_exclude_xpath varchar2, + a_include_xpath varchar2, a_join_by_xpath varchar2); + end; / diff --git a/source/expectations/data_values/ut_compound_data_value.tpb b/source/expectations/data_values/ut_compound_data_value.tpb index de81830dd..e5a766890 100644 --- a/source/expectations/data_values/ut_compound_data_value.tpb +++ b/source/expectations/data_values/ut_compound_data_value.tpb @@ -197,27 +197,11 @@ create or replace type body ut_compound_data_value as member function compare_implementation(a_other ut_data_value, a_exclude_xpath varchar2, a_include_xpath varchar2, a_join_by_xpath varchar2, a_unordered boolean ) return integer is l_other ut_compound_data_value; l_ut_owner varchar2(250) := ut_utils.ut_owner; - l_column_filter varchar2(32767); l_diff_id ut_compound_data_helper.t_hash; l_result integer; l_row_diffs ut_compound_data_helper.tt_row_diffs; c_max_rows constant integer := 20; - function get_column_pk_hash(a_join_by_xpath varchar2) return varchar2 is - l_column varchar2(32767); - begin - /* due to possibility of key being to columns we cannot use xmlextractvalue - usage of xmlagg is possible however it greatly complicates code and performance is impacted. - xpath to be looked at or regex - */ - if a_join_by_xpath is not null then - l_column := l_ut_owner ||'.ut_compound_data_helper.get_hash(extract(ucd.item_data,:join_by_xpath).GetClobVal()) pk_hash'; - else - l_column := ':join_by_xpath pk_hash'; - end if; - return l_column; - end; - begin if not a_other is of (ut_compound_data_value) then raise value_error; @@ -226,37 +210,12 @@ create or replace type body ut_compound_data_value as l_other := treat(a_other as ut_compound_data_value); l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id); - l_column_filter := ut_compound_data_helper.get_columns_filter(a_exclude_xpath, a_include_xpath); - + /** * Due to incompatibility issues in XML between 11 and 12.2 and 12.1 versions we will prepopulate pk_hash upfront to * avoid optimizer incorrectly rewrite and causing NULL error or ORA-600 - **/ - execute immediate 'merge into ' || l_ut_owner || '.ut_compound_data_tmp tgt - using ( - select ucd_out.item_hash, - ucd_out.pk_hash, - ucd_out.item_no, - ucd_out.data_id, - row_number() over (partition by ucd_out.pk_hash,ucd_out.item_hash,ucd_out.data_id order by 1,2) duplicate_no - from - ( - select '||l_ut_owner ||'.ut_compound_data_helper.get_hash(ucd.item_data.getclobval()) item_hash, - pk_hash, ucd.item_no, ucd.data_id - from - ( - select '||l_column_filter||','||get_column_pk_hash(a_join_by_xpath)||', item_no, data_id - from ' || l_ut_owner || q'[.ut_compound_data_tmp ucd - where data_id = :self_guid or data_id = :other_guid - ) ucd - )ucd_out - ) src - on (tgt.item_no = src.item_no and tgt.data_id = src.data_id) - when matched then update - set tgt.item_hash = src.item_hash, - tgt.pk_hash = src.pk_hash, - tgt.duplicate_no = src.duplicate_no]' - using a_exclude_xpath, a_include_xpath,a_join_by_xpath,self.data_id, l_other.data_id; + **/ + ut_compound_data_helper.update_row_and_pk_hash(self.data_id, l_other.data_id, a_exclude_xpath,a_include_xpath,a_join_by_xpath); /* Peform minus on two sets two get diffrences that will be used later on to print results */ execute immediate 'insert into ' || l_ut_owner || '.ut_compound_data_diff_tmp ( diff_id,item_hash,pk_hash,duplicate_no) From 94234573bad50053c8e486acd36f8d084f4d5c63 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 28 Oct 2018 07:48:16 +0000 Subject: [PATCH 064/115] Added test for min user test --- test/install__min_usr_tests.sql | 39 ++++++++++++++++++++++ test/install_and_run_tests.sh | 30 ++++++++++++++++- test/min_grant_user/min_grant_user_exp.pkb | 19 +++++++++++ test/min_grant_user/min_grant_user_exp.pks | 9 +++++ 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 test/install__min_usr_tests.sql create mode 100644 test/min_grant_user/min_grant_user_exp.pkb create mode 100644 test/min_grant_user/min_grant_user_exp.pks diff --git a/test/install__min_usr_tests.sql b/test/install__min_usr_tests.sql new file mode 100644 index 000000000..fa788f8f9 --- /dev/null +++ b/test/install__min_usr_tests.sql @@ -0,0 +1,39 @@ +set define off +whenever sqlerror exit failure rollback +whenever oserror exit failure rollback + +alter session set plsql_optimize_level=0; + +--Install tests +@@min_grant_user/min_grant_user_exp.pks +@@min_grant_user/min_grant_user_exp.pkb + +set linesize 200 +set define on +set verify off +column text format a100 +column error_count noprint new_value error_count + +prompt Validating installation + +set heading on +select type, name, sequence, line, position, text, count(1) over() error_count + from all_errors + where owner = USER + and name not like 'BIN$%' --not recycled + and name != 'UT_WITH_INVALID_BODY' + -- errors only. ignore warnings + and attribute = 'ERROR' + order by name, type, sequence +/ + +begin + if to_number('&&error_count') > 0 then + raise_application_error(-20000, 'Not all sources were successfully installed.'); + else + dbms_output.put_line('Installation completed successfully'); + end if; +end; +/ + +exit; diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh index a1e5e0849..04d70fb39 100644 --- a/test/install_and_run_tests.sh +++ b/test/install_and_run_tests.sh @@ -1,10 +1,35 @@ #!/bin/bash set -ev +check_result() +{ + RC1=$1 + RC2=$2 + + if [ "$RC1" != "0" ] || [ "$RC2" != "0" ]; then + return 1 + fi + return 0 +} #goto git root directory git rev-parse && cd "$(git rev-parse --show-cdup)" +cd test + +time "$SQLCLI" ${UT3_USER}/${UT3_USER_PASSWORD}@//${CONNECTION_STR} @install__min_usr_tests.sql + +cd .. + +time utPLSQL-cli/bin/utplsql run ${UT3_USER}/${UT3_USER_PASSWORD}@${CONNECTION_STR} \ +-source_path=source -owner=ut3 \ +-test_path=test -c \ +-f=ut_documentation_reporter -o=min_test_results.log -s \ +-scc + +status_line_regex="^[0-9]+ tests, ([0-9]+) failed, ([0-9]+) errored.*" + +RC1=$(cat min_test_results.log | grep -E "${status_line_regex}" | sed -re "s/${status_line_regex}/\1\2/") cd test @@ -29,6 +54,9 @@ status_line_regex="^[0-9]+ tests, ([0-9]+) failed, ([0-9]+) errored.*" #cat coverage.xml #cat test_results.xml -RC=$(cat test_results.log | grep -E "${status_line_regex}" | sed -re "s/${status_line_regex}/\1\2/") +RC2=$(cat test_results.log | grep -E "${status_line_regex}" | sed -re "s/${status_line_regex}/\1\2/") + +check_result $RC1 $RC2 +RC=$? exit $RC diff --git a/test/min_grant_user/min_grant_user_exp.pkb b/test/min_grant_user/min_grant_user_exp.pkb new file mode 100644 index 000000000..1a8089c0b --- /dev/null +++ b/test/min_grant_user/min_grant_user_exp.pkb @@ -0,0 +1,19 @@ +create or replace package body min_grant_user_exp is + + procedure test_join_by_cursor is + l_actual SYS_REFCURSOR; + l_expected SYS_REFCURSOR; + begin + --Arrange + open l_actual for select owner, object_name,object_type from all_objects where owner = user + order by 1,2,3 asc; + open l_expected for select owner, object_name,object_type from all_objects where owner = user + order by 1,2,3 desc; + + --Act + ut3.ut.expect(l_actual).to_equal(l_expected).join_by('OWNER'); + + end; + +end; +/ diff --git a/test/min_grant_user/min_grant_user_exp.pks b/test/min_grant_user/min_grant_user_exp.pks new file mode 100644 index 000000000..467d62ce0 --- /dev/null +++ b/test/min_grant_user/min_grant_user_exp.pks @@ -0,0 +1,9 @@ +create or replace package min_grant_user_exp is + + --%suite(minimum grant user tests) + + --%test(execute join by test) + procedure test_join_by_cursor; + +end; +/ From 4b3fe8afa42febfce52769e4bb5b6d9eb20180f0 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 28 Oct 2018 07:57:51 +0000 Subject: [PATCH 065/115] Update sqlcl download --- .travis/download.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/download.sh b/.travis/download.sh index d7f0b7d0f..a071fafeb 100644 --- a/.travis/download.sh +++ b/.travis/download.sh @@ -60,7 +60,7 @@ fi if [ "$PRODUCT" == "sqlcl" ]; then agreementUrl="http://www.oracle.com/technetwork/developer-tools/sqlcl/downloads/index.html" - downloadUrl="http://download.oracle.com/otn/java/sqldeveloper/sqlcl-18.2.0.zip" + downloadUrl="http://download.oracle.com/otn/java/sqldeveloper/sqlcl-18.3.0.259.2029.zip" outputFile=sqlcl-18.2.0.zip downloadFile $agreementUrl $downloadUrl $outputFile exit 0 From 40314b6045acbd3e5f71c83b502796b3c15da018 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Sun, 28 Oct 2018 08:03:23 +0000 Subject: [PATCH 066/115] Revert "Update sqlcl download" This reverts commit 4b3fe8afa42febfce52769e4bb5b6d9eb20180f0. --- .travis/download.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/download.sh b/.travis/download.sh index a071fafeb..d7f0b7d0f 100644 --- a/.travis/download.sh +++ b/.travis/download.sh @@ -60,7 +60,7 @@ fi if [ "$PRODUCT" == "sqlcl" ]; then agreementUrl="http://www.oracle.com/technetwork/developer-tools/sqlcl/downloads/index.html" - downloadUrl="http://download.oracle.com/otn/java/sqldeveloper/sqlcl-18.3.0.259.2029.zip" + downloadUrl="http://download.oracle.com/otn/java/sqldeveloper/sqlcl-18.2.0.zip" outputFile=sqlcl-18.2.0.zip downloadFile $agreementUrl $downloadUrl $outputFile exit 0 From 2a6c82c513dfe08681d401873762af8d40582976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20G=C4=99bal?= Date: Sun, 28 Oct 2018 08:01:14 +0000 Subject: [PATCH 067/115] Fix sqlcl download --- .travis/download.js | 4 +++- .travis/download.sh | 7 ++++--- .travis/install_sqlcl.sh | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.travis/download.js b/.travis/download.js index bc981cdf4..339001c57 100644 --- a/.travis/download.js +++ b/.travis/download.js @@ -17,6 +17,7 @@ var paramUsername = casper.cli.get(0); var paramPassword = casper.cli.get(1); var agreementUrl = casper.cli.get(2); var downloadUrl = casper.cli.get(3); +var downloaded = false; casper.start(); // TODO: Error handling. @@ -41,10 +42,11 @@ casper.thenOpen(downloadUrl).waitForUrl(/signon\.jsp$/, function (re) { }); casper.on("resource.received", function (resource) { - if (resource.url.indexOf("AuthParam") !== -1) { + if (resource.url.indexOf("AuthParam") !== -1 && !downloaded) { // this.echo("DownloadUrl:"); // Print the download url. this.echo(resource.url); + downloaded = true; // TODO: Try to download file from here. this.download is not working because of cross site request. } }); diff --git a/.travis/download.sh b/.travis/download.sh index d7f0b7d0f..fdbcdef7c 100644 --- a/.travis/download.sh +++ b/.travis/download.sh @@ -12,8 +12,9 @@ PRODUCT="" # Then download the file using curl. downloadFile() { downloadUrl=$(exec casperjs download.js $ORACLE_OTN_USER $ORACLE_OTN_PASSWORD $1 $2) + downloadUrl=${downloadUrl%$'\r'} echo "DownloadURL: $downloadUrl" - curl $downloadUrl -o $3 + curl -o $3 -L "$downloadUrl" } ############################# @@ -60,8 +61,8 @@ fi if [ "$PRODUCT" == "sqlcl" ]; then agreementUrl="http://www.oracle.com/technetwork/developer-tools/sqlcl/downloads/index.html" - downloadUrl="http://download.oracle.com/otn/java/sqldeveloper/sqlcl-18.2.0.zip" - outputFile=sqlcl-18.2.0.zip + downloadUrl="https://download.oracle.com/otn/java/sqldeveloper/sqlcl-18.3.0.259.2029.zip" + outputFile=sqlcl-18.3.0.259.2029.zip downloadFile $agreementUrl $downloadUrl $outputFile exit 0 fi diff --git a/.travis/install_sqlcl.sh b/.travis/install_sqlcl.sh index 9db262c5d..9743ddac2 100644 --- a/.travis/install_sqlcl.sh +++ b/.travis/install_sqlcl.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -SQLCL_FILE=sqlcl-18.2.0.zip +SQLCL_FILE=sqlcl-18.3.0.259.2029.zip cd .travis # Download if not present on cache dir. From 899ddcffd57b5bb66448ea8306933dafae543cc2 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Thu, 1 Nov 2018 01:18:58 +0000 Subject: [PATCH 068/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 5623efa9b..60f189a66 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2297-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2321-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 72851ff5699583671415a890d17317fe9e258ab8 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Thu, 1 Nov 2018 18:46:01 +0000 Subject: [PATCH 069/115] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 899ddcffd57b5bb66448ea8306933dafae543cc2 Author: Travis CI Date: Thu Nov 1 01:18:58 2018 +0000 Updated project version after build [skip ci] commit df9dac7b2f4b5323db7a54865bc8f0be42ca34a8 Merge: 013cba3b 2a6c82c5 Author: Jacek Gębal Date: Thu Nov 1 01:05:42 2018 +0000 Merge pull request #772 from utPLSQL/bugfix/fix_travis_sqlcl_download_vini Fix sqlcl download commit 2a6c82c513dfe08681d401873762af8d40582976 Author: Jacek Gębal Date: Sun Oct 28 08:01:14 2018 +0000 Fix sqlcl download --- .travis/download.js | 4 +++- .travis/download.sh | 7 ++++--- .travis/install_sqlcl.sh | 2 +- source/core/ut_utils.pks | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.travis/download.js b/.travis/download.js index bc981cdf4..339001c57 100644 --- a/.travis/download.js +++ b/.travis/download.js @@ -17,6 +17,7 @@ var paramUsername = casper.cli.get(0); var paramPassword = casper.cli.get(1); var agreementUrl = casper.cli.get(2); var downloadUrl = casper.cli.get(3); +var downloaded = false; casper.start(); // TODO: Error handling. @@ -41,10 +42,11 @@ casper.thenOpen(downloadUrl).waitForUrl(/signon\.jsp$/, function (re) { }); casper.on("resource.received", function (resource) { - if (resource.url.indexOf("AuthParam") !== -1) { + if (resource.url.indexOf("AuthParam") !== -1 && !downloaded) { // this.echo("DownloadUrl:"); // Print the download url. this.echo(resource.url); + downloaded = true; // TODO: Try to download file from here. this.download is not working because of cross site request. } }); diff --git a/.travis/download.sh b/.travis/download.sh index d7f0b7d0f..fdbcdef7c 100644 --- a/.travis/download.sh +++ b/.travis/download.sh @@ -12,8 +12,9 @@ PRODUCT="" # Then download the file using curl. downloadFile() { downloadUrl=$(exec casperjs download.js $ORACLE_OTN_USER $ORACLE_OTN_PASSWORD $1 $2) + downloadUrl=${downloadUrl%$'\r'} echo "DownloadURL: $downloadUrl" - curl $downloadUrl -o $3 + curl -o $3 -L "$downloadUrl" } ############################# @@ -60,8 +61,8 @@ fi if [ "$PRODUCT" == "sqlcl" ]; then agreementUrl="http://www.oracle.com/technetwork/developer-tools/sqlcl/downloads/index.html" - downloadUrl="http://download.oracle.com/otn/java/sqldeveloper/sqlcl-18.2.0.zip" - outputFile=sqlcl-18.2.0.zip + downloadUrl="https://download.oracle.com/otn/java/sqldeveloper/sqlcl-18.3.0.259.2029.zip" + outputFile=sqlcl-18.3.0.259.2029.zip downloadFile $agreementUrl $downloadUrl $outputFile exit 0 fi diff --git a/.travis/install_sqlcl.sh b/.travis/install_sqlcl.sh index 9db262c5d..9743ddac2 100644 --- a/.travis/install_sqlcl.sh +++ b/.travis/install_sqlcl.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -SQLCL_FILE=sqlcl-18.2.0.zip +SQLCL_FILE=sqlcl-18.3.0.259.2029.zip cd .travis # Download if not present on cache dir. diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 5623efa9b..60f189a66 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2297-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2321-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 5f25daf8241da361a2f34e9adf1362ed2d9c1aad Mon Sep 17 00:00:00 2001 From: lwasylow Date: Thu, 1 Nov 2018 19:10:40 +0000 Subject: [PATCH 070/115] Update run test shell. --- test/install_and_run_tests.sh | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh index 04d70fb39..79dfda65e 100644 --- a/test/install_and_run_tests.sh +++ b/test/install_and_run_tests.sh @@ -1,17 +1,6 @@ #!/bin/bash set -ev -check_result() -{ - RC1=$1 - RC2=$2 - - if [ "$RC1" != "0" ] || [ "$RC2" != "0" ]; then - return 1 - fi - return 0 -} - #goto git root directory git rev-parse && cd "$(git rev-parse --show-cdup)" @@ -29,7 +18,11 @@ time utPLSQL-cli/bin/utplsql run ${UT3_USER}/${UT3_USER_PASSWORD}@${CONNECTION_S status_line_regex="^[0-9]+ tests, ([0-9]+) failed, ([0-9]+) errored.*" -RC1=$(cat min_test_results.log | grep -E "${status_line_regex}" | sed -re "s/${status_line_regex}/\1\2/") +RC=$(cat min_test_results.log | grep -E "${status_line_regex}" | sed -re "s/${status_line_regex}/\1\2/") + +if [ "$RC" == "1" ] then + exit 1 +fi cd test @@ -54,9 +47,7 @@ status_line_regex="^[0-9]+ tests, ([0-9]+) failed, ([0-9]+) errored.*" #cat coverage.xml #cat test_results.xml -RC2=$(cat test_results.log | grep -E "${status_line_regex}" | sed -re "s/${status_line_regex}/\1\2/") - -check_result $RC1 $RC2 -RC=$? +RC=$(cat test_results.log | grep -E "${status_line_regex}" | sed -re "s/${status_line_regex}/\1\2/") exit $RC + From 2df635485077cb5e26af37a2b1e5f812348781d3 Mon Sep 17 00:00:00 2001 From: lwasylow Date: Thu, 1 Nov 2018 19:18:25 +0000 Subject: [PATCH 071/115] Update shell --- test/install_and_run_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh index 79dfda65e..b8aba77e2 100644 --- a/test/install_and_run_tests.sh +++ b/test/install_and_run_tests.sh @@ -20,7 +20,7 @@ status_line_regex="^[0-9]+ tests, ([0-9]+) failed, ([0-9]+) errored.*" RC=$(cat min_test_results.log | grep -E "${status_line_regex}" | sed -re "s/${status_line_regex}/\1\2/") -if [ "$RC" == "1" ] then +if [ "$RC" == "1" ]; then exit 1 fi From e41d6f9471ffa99e609e7c4f05a1e163e4948cfe Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 30 Oct 2018 23:47:28 +0000 Subject: [PATCH 072/115] Interim commit with lots of dirty code - got to a place where I get the infamous ORA-00600 `ORA-00600: internal error code, arguments: [pfrobj.c: invalid RTTI for Object], [], [], [], [], [], [], [], [], [], [], []`` --- .../core/annotations/ut_annotated_object.tps | 1 + .../ut_annotation_cache_manager.pkb | 19 +- .../ut_annotation_cache_manager.pks | 2 +- .../annotations/ut_annotation_manager.pkb | 54 +- .../annotations/ut_annotation_manager.pks | 3 +- source/core/types/ut_logical_suite.tpb | 2 +- source/core/types/ut_logical_suites.tps | 19 + source/core/types/ut_suite.tpb | 4 +- source/core/types/ut_suite.tps | 2 +- source/core/types/ut_suite_context.tpb | 4 +- source/core/types/ut_suite_context.tps | 2 +- source/core/types/ut_suite_item.tpb | 12 +- source/core/types/ut_suite_item.tps | 19 +- source/core/types/ut_test.tpb | 8 +- source/core/types/ut_test.tps | 2 +- source/core/ut_expectation_processor.pkb | 4 +- source/core/ut_expectation_processor.pks | 2 +- source/core/ut_suite_builder.pkb | 619 ++++++++++++++---- source/core/ut_suite_builder.pks | 32 +- source/core/ut_suite_cache.sql | 89 +++ source/core/ut_suite_cache_manager.pkb | 284 ++++++++ source/core/ut_suite_cache_manager.pks | 32 + source/core/ut_suite_cache_schema.sql | 20 + source/core/ut_suite_manager.pkb | 147 ++++- source/install.sql | 5 + source/uninstall_objects.sql | 4 + .../expectations/test_expectations_cursor.pkb | 25 +- test/core/test_suite_builder.pkb | 57 +- test/core/test_suite_builder.pks | 14 +- test/core/test_ut_executable.pkb | 12 +- test/core/test_ut_suite.pkb | 28 +- test/core/test_ut_test.pkb | 30 +- 32 files changed, 1270 insertions(+), 287 deletions(-) create mode 100644 source/core/types/ut_logical_suites.tps create mode 100644 source/core/ut_suite_cache.sql create mode 100644 source/core/ut_suite_cache_manager.pkb create mode 100644 source/core/ut_suite_cache_manager.pks create mode 100644 source/core/ut_suite_cache_schema.sql diff --git a/source/core/annotations/ut_annotated_object.tps b/source/core/annotations/ut_annotated_object.tps index 4bf141a3f..e78a2a282 100644 --- a/source/core/annotations/ut_annotated_object.tps +++ b/source/core/annotations/ut_annotated_object.tps @@ -18,6 +18,7 @@ create type ut_annotated_object as object( object_owner varchar2(250), object_name varchar2(250), object_type varchar2(50), + parse_time date, annotations ut_annotations ) / diff --git a/source/core/annotations/ut_annotation_cache_manager.pkb b/source/core/annotations/ut_annotation_cache_manager.pkb index a05914e37..e9d60730b 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pkb +++ b/source/core/annotations/ut_annotation_cache_manager.pkb @@ -37,17 +37,10 @@ create or replace package body ut_annotation_cache_manager as where cache_id = l_cache_id; if a_object.annotations is not null and a_object.annotations.count > 0 then --- begin insert into ut_annotation_cache (cache_id, annotation_position, annotation_name, annotation_text, subobject_name) select l_cache_id, a.position, a.name, a.text, a.subobject_name from table(a_object.annotations) a; - --TODO - duplicate annotations found?? - should not happen, getting standalone annotations need to happen after procedure annotations were parsed --- exception --- when others then --- dbms_output.put_line(xmltype(anydata.convertCollection(a_object.annotations)).getclobval); --- raise; --- end; end if; commit; end; @@ -81,12 +74,12 @@ create or replace package body ut_annotation_cache_manager as commit; end; - function get_annotations_for_objects(a_cached_objects ut_annotation_objs_cache_info) return sys_refcursor is + function get_annotations_for_objects(a_cached_objects ut_annotation_objs_cache_info, a_parse_date date) return sys_refcursor is l_results sys_refcursor; begin - open l_results for + open l_results for q'[ select ut_annotated_object( - o.object_owner, o.object_name, o.object_type, + i.object_owner, i.object_name, i.object_type, i.parse_time, cast( collect( ut_annotation( @@ -95,11 +88,13 @@ create or replace package body ut_annotation_cache_manager as ) as ut_annotations ) ) - from table(a_cached_objects) o + from table(:a_cached_objects) o join ut_annotation_cache_info i on o.object_owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type join ut_annotation_cache c on i.cache_id = c.cache_id - group by o.object_owner, o.object_name, o.object_type; + where ]'|| case when a_parse_date is null then ':a_parse_date is null' else 'i.parse_time > :a_parse_date' end ||q'[ + group by i.object_owner, i.object_name, i.object_type, i.parse_time]' + using a_cached_objects, a_parse_date; return l_results; end; diff --git a/source/core/annotations/ut_annotation_cache_manager.pks b/source/core/annotations/ut_annotation_cache_manager.pks index d37212d69..7663fdc33 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pks +++ b/source/core/annotations/ut_annotation_cache_manager.pks @@ -32,7 +32,7 @@ create or replace package ut_annotation_cache_manager authid definer as * * @param a_cached_objects a `ut_annotation_objs_cache_info` list with information about objects to get from cache */ - function get_annotations_for_objects(a_cached_objects ut_annotation_objs_cache_info) return sys_refcursor; + function get_annotations_for_objects(a_cached_objects ut_annotation_objs_cache_info, a_parse_date date) return sys_refcursor; /** * Removes cached information about annotations for objects on the list and updates parse_time in cache info table. diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb index e44e5dd10..7c299b766 100644 --- a/source/core/annotations/ut_annotation_manager.pkb +++ b/source/core/annotations/ut_annotation_manager.pkb @@ -19,11 +19,12 @@ create or replace package body ut_annotation_manager as ------------------------------ --private definitions - function get_annotation_objs_info_cur(a_object_owner varchar2, a_object_type varchar2) return sys_refcursor is - l_result sys_refcursor; + function get_annotation_objs_info(a_object_owner varchar2, a_object_type varchar2, a_parse_date date := null) return ut_annotation_objs_cache_info is + l_rows sys_refcursor; l_ut_owner varchar2(250) := ut_utils.ut_owner; l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); - l_cursor_text long; + l_cursor_text varchar2(32767); + l_result ut_annotation_objs_cache_info; begin l_cursor_text := q'[select ]'||l_ut_owner||q'[.ut_annotation_obj_cache_info( @@ -34,10 +35,20 @@ create or replace package body ut_annotation_manager as ) from ]'||l_objects_view||q'[ o left join ]'||l_ut_owner||q'[.ut_annotation_cache_info i - on o.owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type + on o.owner = i.object_owner + and o.object_name = i.object_name + and o.object_type = i.object_type where o.owner = :a_object_owner - and o.object_type = :a_object_type]'; - open l_result for l_cursor_text using a_object_owner, a_object_type; + and o.object_type = :a_object_type + and ]' + || case + when a_parse_date is null + then ':a_parse_date is null' + else 'o.last_ddl_time > :a_parse_date' + end; + open l_rows for l_cursor_text using a_object_owner, a_object_type, a_parse_date; + fetch l_rows bulk collect into l_result limit 1000000; + close l_rows; return l_result; end; @@ -103,6 +114,7 @@ create or replace package body ut_annotation_manager as l_names dbms_preprocessor.source_lines_t; l_name varchar2(250); l_object_lines dbms_preprocessor.source_lines_t; + l_parse_time date := sysdate; pragma autonomous_transaction; begin ut_annotation_cache_manager.cleanup_cache(a_schema_objects); @@ -112,7 +124,7 @@ create or replace package body ut_annotation_manager as if l_names(i) != l_name then l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines); ut_annotation_cache_manager.update_cache( - ut_annotated_object(a_object_owner, l_name, a_object_type, l_annotations) + ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations) ); l_object_lines.delete; end if; @@ -126,7 +138,7 @@ create or replace package body ut_annotation_manager as if a_sources_cursor%rowcount > 0 then l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines); ut_annotation_cache_manager.update_cache( - ut_annotated_object(a_object_owner, l_name, a_object_type, l_annotations) + ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations) ); l_object_lines.delete; end if; @@ -140,7 +152,8 @@ create or replace package body ut_annotation_manager as l_objects_to_parse ut_annotation_objs_cache_info := ut_annotation_objs_cache_info(); begin --get list of objects in cache - select count( 1)into l_objects_in_cache_count from table(a_info_rows) x where x.needs_refresh = 'N'; + select count(1) into l_objects_in_cache_count + from table(a_info_rows) x where x.needs_refresh = 'N'; --if cache is empty and there are objects to parse if l_objects_in_cache_count = 0 and a_info_rows.count > 0 then @@ -173,30 +186,26 @@ create or replace package body ut_annotation_manager as --public definitions ------------------------------------------------------------ procedure rebuild_annotation_cache(a_object_owner varchar2, a_object_type varchar2) is - l_info_cursor sys_refcursor; - l_info_rows ut_annotation_objs_cache_info; begin - l_info_cursor := get_annotation_objs_info_cur(a_object_owner, a_object_type); - fetch l_info_cursor bulk collect into l_info_rows; - close l_info_cursor; - rebuild_annotation_cache(a_object_owner, a_object_type, l_info_rows); + rebuild_annotation_cache( + a_object_owner, + a_object_type, + get_annotation_objs_info(a_object_owner, a_object_type, null) + ); end; - function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2) return ut_annotated_objects pipelined is - l_info_cursor sys_refcursor; + function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_parse_date date := null) return ut_annotated_objects pipelined is l_info_rows ut_annotation_objs_cache_info; l_cursor sys_refcursor; l_results ut_annotated_objects; c_object_fetch_limit constant integer := 10; begin - - l_info_cursor := get_annotation_objs_info_cur(a_object_owner, a_object_type); - fetch l_info_cursor bulk collect into l_info_rows; - close l_info_cursor; + + l_info_rows := get_annotation_objs_info(a_object_owner, a_object_type, a_parse_date); rebuild_annotation_cache(a_object_owner, a_object_type, l_info_rows); --pipe annotations from cache - l_cursor := ut_annotation_cache_manager.get_annotations_for_objects(l_info_rows); + l_cursor := ut_annotation_cache_manager.get_annotations_for_objects(l_info_rows, a_parse_date); loop fetch l_cursor bulk collect into l_results limit c_object_fetch_limit; for i in 1 .. l_results.count loop @@ -205,7 +214,6 @@ create or replace package body ut_annotation_manager as exit when l_cursor%notfound; end loop; close l_cursor; - end; procedure purge_cache(a_object_owner varchar2, a_object_type varchar2) is diff --git a/source/core/annotations/ut_annotation_manager.pks b/source/core/annotations/ut_annotation_manager.pks index a2925c388..f0468ccd5 100644 --- a/source/core/annotations/ut_annotation_manager.pks +++ b/source/core/annotations/ut_annotation_manager.pks @@ -27,9 +27,10 @@ create or replace package ut_annotation_manager authid current_user as * * @param a_object_owner owner of objects to get annotations for * @param a_object_type type of objects to get annotations for + * @param a_parse_date date when object was last parsed * @return array containing annotated objects along with annotations for each object (nested) */ - function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2) return ut_annotated_objects pipelined; + function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_parse_date date := null) return ut_annotated_objects pipelined; /** * Rebuilds annotation cache for a specified schema and object type. diff --git a/source/core/types/ut_logical_suite.tpb b/source/core/types/ut_logical_suite.tpb index 0443bf105..1acfc776c 100644 --- a/source/core/types/ut_logical_suite.tpb +++ b/source/core/types/ut_logical_suite.tpb @@ -21,7 +21,7 @@ create or replace type body ut_logical_suite as ) return self as result is begin self.self_type := $$plsql_unit; - self.init(a_object_owner, a_object_name, a_name); + self.init(a_object_owner, a_object_name, a_name, 0); self.path := a_path; self.disabled_flag := ut_utils.boolean_to_int(false); self.items := ut_suite_items(); diff --git a/source/core/types/ut_logical_suites.tps b/source/core/types/ut_logical_suites.tps new file mode 100644 index 000000000..560f245d0 --- /dev/null +++ b/source/core/types/ut_logical_suites.tps @@ -0,0 +1,19 @@ +create or replace type ut_logical_suites as + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + table of ut_logical_suite +/ diff --git a/source/core/types/ut_suite.tpb b/source/core/types/ut_suite.tpb index 9d9a60e8d..b92804fb0 100644 --- a/source/core/types/ut_suite.tpb +++ b/source/core/types/ut_suite.tpb @@ -17,11 +17,11 @@ create or replace type body ut_suite as */ constructor function ut_suite ( - self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2 + self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2, a_line_no integer ) return self as result is begin self.self_type := $$plsql_unit; - self.init(a_object_owner, a_object_name, a_object_name); + self.init(a_object_owner, a_object_name, a_object_name, a_line_no); self.items := ut_suite_items(); before_all_list := ut_executables(); after_all_list := ut_executables(); diff --git a/source/core/types/ut_suite.tps b/source/core/types/ut_suite.tps index f56d95c08..7057e4911 100644 --- a/source/core/types/ut_suite.tps +++ b/source/core/types/ut_suite.tps @@ -27,7 +27,7 @@ create or replace type ut_suite under ut_logical_suite ( */ after_all_list ut_executables, constructor function ut_suite ( - self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2 + self in out nocopy ut_suite, a_object_owner varchar2, a_object_name varchar2, a_line_no integer ) return self as result, overriding member function do_execute(self in out nocopy ut_suite) return boolean, overriding member function get_error_stack_traces(self ut_suite) return ut_varchar2_list, diff --git a/source/core/types/ut_suite_context.tpb b/source/core/types/ut_suite_context.tpb index a4add114b..c8255f374 100644 --- a/source/core/types/ut_suite_context.tpb +++ b/source/core/types/ut_suite_context.tpb @@ -17,11 +17,11 @@ create or replace type body ut_suite_context as */ constructor function ut_suite_context ( - self in out nocopy ut_suite_context, a_object_owner varchar2, a_object_name varchar2, a_context_name varchar2 := null + self in out nocopy ut_suite_context, a_object_owner varchar2, a_object_name varchar2, a_context_name varchar2 := null, a_line_no integer ) return self as result is begin self.self_type := $$plsql_unit; - self.init(a_object_owner, a_object_name, a_context_name); + self.init(a_object_owner, a_object_name, a_context_name, a_line_no); self.items := ut_suite_items(); before_all_list := ut_executables(); after_all_list := ut_executables(); diff --git a/source/core/types/ut_suite_context.tps b/source/core/types/ut_suite_context.tps index 345c12a65..ce4510c39 100644 --- a/source/core/types/ut_suite_context.tps +++ b/source/core/types/ut_suite_context.tps @@ -16,7 +16,7 @@ create or replace type ut_suite_context under ut_suite ( limitations under the License. */ constructor function ut_suite_context ( - self in out nocopy ut_suite_context, a_object_owner varchar2, a_object_name varchar2, a_context_name varchar2 := null + self in out nocopy ut_suite_context, a_object_owner varchar2, a_object_name varchar2, a_context_name varchar2 := null, a_line_no integer ) return self as result ) / diff --git a/source/core/types/ut_suite_item.tpb b/source/core/types/ut_suite_item.tpb index a3319a4d8..4788a9a3c 100644 --- a/source/core/types/ut_suite_item.tpb +++ b/source/core/types/ut_suite_item.tpb @@ -16,22 +16,18 @@ create or replace type body ut_suite_item as limitations under the License. */ - member procedure init(self in out nocopy ut_suite_item, a_object_owner varchar2, a_object_name varchar2, a_name varchar2) is + member procedure init(self in out nocopy ut_suite_item, a_object_owner varchar2, a_object_name varchar2, a_name varchar2, a_line_no integer) is begin self.object_owner := a_object_owner; self.object_name := lower(trim(a_object_name)); self.name := lower(trim(a_name)); self.results_count := ut_results_counter(); - self.warnings := ut_varchar2_list(); + self.warnings := ut_varchar2_rows(); + self.line_no := a_line_no; self.transaction_invalidators := ut_varchar2_list(); self.disabled_flag := ut_utils.boolean_to_int(false); end; - member procedure set_disabled_flag(self in out nocopy ut_suite_item, a_disabled_flag boolean) is - begin - self.disabled_flag := ut_utils.boolean_to_int(a_disabled_flag); - end; - member function get_disabled_flag return boolean is begin return ut_utils.int_to_boolean(self.disabled_flag); @@ -47,7 +43,7 @@ create or replace type body ut_suite_item as return nvl(self.rollback_type, ut_utils.gc_rollback_default); end; -final member procedure do_execute(self in out nocopy ut_suite_item) is + final member procedure do_execute(self in out nocopy ut_suite_item) is l_completed_without_errors boolean; begin l_completed_without_errors := self.do_execute(); diff --git a/source/core/types/ut_suite_item.tps b/source/core/types/ut_suite_item.tps index 52b6a2a19..0f08263c4 100644 --- a/source/core/types/ut_suite_item.tps +++ b/source/core/types/ut_suite_item.tps @@ -19,15 +19,15 @@ create or replace type ut_suite_item force under ut_event_item ( /** * owner of the database object (package) */ - object_owner varchar2(4000 byte), + object_owner varchar2(250 byte), /** * name of the database object (package) */ - object_name varchar2(4000 byte), + object_name varchar2(250 byte), /** * Name of the object (suite, sub-suite, test) */ - name varchar2(4000 byte), + name varchar2(250 byte), /** * Description fo the suite item (as given by the annotation) */ @@ -45,15 +45,22 @@ create or replace type ut_suite_item force under ut_event_item ( * Indicates if the test is to be disabled by execution */ disabled_flag integer(1), + /** + * Line no where annotation identifying this item is placed in package + */ + line_no integer, + /** + * Time when the suite item was last parsed from package source + */ + parse_time date, --execution result fields start_time timestamp with time zone, end_time timestamp with time zone, result integer(1), - warnings ut_varchar2_list, + warnings ut_varchar2_rows, results_count ut_results_counter, transaction_invalidators ut_varchar2_list, - member procedure init(self in out nocopy ut_suite_item, a_object_owner varchar2, a_object_name varchar2, a_name varchar2), - member procedure set_disabled_flag(self in out nocopy ut_suite_item, a_disabled_flag boolean), + member procedure init(self in out nocopy ut_suite_item, a_object_owner varchar2, a_object_name varchar2, a_name varchar2, a_line_no integer), member function get_disabled_flag return boolean, not instantiable member procedure mark_as_skipped(self in out nocopy ut_suite_item), member procedure set_rollback_type(self in out nocopy ut_suite_item, a_rollback_type integer), diff --git a/source/core/types/ut_test.tpb b/source/core/types/ut_test.tpb index f6495ecd6..ed9692e14 100644 --- a/source/core/types/ut_test.tpb +++ b/source/core/types/ut_test.tpb @@ -18,11 +18,11 @@ create or replace type body ut_test as constructor function ut_test( self in out nocopy ut_test, a_object_owner varchar2 := null, a_object_name varchar2, a_name varchar2, - a_expected_error_codes ut_integer_list := null + a_line_no integer, a_expected_error_codes ut_integer_list := null ) return self as result is begin self.self_type := $$plsql_unit; - self.init(a_object_owner, a_object_name, a_name); + self.init(a_object_owner, a_object_name, a_name, a_line_no); self.item := ut_executable_test(a_object_owner, a_object_name, a_name, ut_utils.gc_test_execute); self.before_each_list := ut_executables(); self.before_test_list := ut_executables(); @@ -97,7 +97,7 @@ create or replace type body ut_test as end; overriding member procedure calc_execution_result(self in out nocopy ut_test) is - l_warnings ut_varchar2_list; + l_warnings ut_varchar2_rows; begin if self.get_error_stack_traces().count = 0 then self.result := ut_expectation_processor.get_status(); @@ -107,7 +107,7 @@ create or replace type body ut_test as --expectation results need to be part of test results self.all_expectations := ut_expectation_processor.get_all_expectations(); self.failed_expectations := ut_expectation_processor.get_failed_expectations(); - l_warnings := coalesce( ut_expectation_processor.get_warnings(), ut_varchar2_list() ); + l_warnings := coalesce( ut_expectation_processor.get_warnings(), ut_varchar2_rows() ); self.warnings := self.warnings multiset union all l_warnings; self.results_count.increase_warning_count( cardinality(l_warnings) ); self.results_count.set_counter_values(self.result); diff --git a/source/core/types/ut_test.tps b/source/core/types/ut_test.tps index d26e220b9..752ef3ef7 100644 --- a/source/core/types/ut_test.tps +++ b/source/core/types/ut_test.tps @@ -57,7 +57,7 @@ create or replace type ut_test under ut_suite_item ( expected_error_codes ut_integer_list, constructor function ut_test( self in out nocopy ut_test, a_object_owner varchar2 := null, a_object_name varchar2, a_name varchar2, - a_expected_error_codes ut_integer_list := null + a_line_no integer, a_expected_error_codes ut_integer_list := null ) return self as result, overriding member procedure mark_as_skipped(self in out nocopy ut_test), overriding member function do_execute(self in out nocopy ut_test) return boolean, diff --git a/source/core/ut_expectation_processor.pkb b/source/core/ut_expectation_processor.pkb index 45dfb7dee..170846125 100644 --- a/source/core/ut_expectation_processor.pkb +++ b/source/core/ut_expectation_processor.pkb @@ -22,7 +22,7 @@ create or replace package body ut_expectation_processor as g_expectations_called ut_expectation_results := ut_expectation_results(); - g_warnings ut_varchar2_list := ut_varchar2_list(); + g_warnings ut_varchar2_rows := ut_varchar2_rows(); g_nulls_are_equal boolean_not_null := gc_default_nulls_are_equal; @@ -176,7 +176,7 @@ create or replace package body ut_expectation_processor as ); end; - function get_warnings return ut_varchar2_list is + function get_warnings return ut_varchar2_rows is begin return g_warnings; end; diff --git a/source/core/ut_expectation_processor.pks b/source/core/ut_expectation_processor.pks index f5d13ccb6..f58de2441 100644 --- a/source/core/ut_expectation_processor.pks +++ b/source/core/ut_expectation_processor.pks @@ -52,7 +52,7 @@ create or replace package ut_expectation_processor authid current_user as procedure add_depreciation_warning(a_deprecated_syntax varchar2, a_new_syntax varchar2); - function get_warnings return ut_varchar2_list; + function get_warnings return ut_varchar2_rows; function invalidation_exception_found return boolean; procedure set_invalidation_exception; diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index 8558b4331..ce269280a 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -59,7 +59,7 @@ create or replace package body ut_suite_builder is ); gc_placeholder constant varchar2(3) := '\\%'; - + gc_integer_exception constant varchar2(1) := 'I'; gc_named_exception constant varchar2(1) := 'N'; @@ -73,7 +73,7 @@ create or replace package body ut_suite_builder is text t_annotation_text, procedure_name t_object_name ); - + type tt_annotations_by_line is table of t_annotation index by t_annotation_position; --list of annotation texts for a given annotation indexed by annotation position: @@ -84,17 +84,18 @@ create or replace package body ut_suite_builder is -- procedure some_test ... -- when you'd like to have two beforetest procedures executed in a single test type tt_annotation_texts is table of t_annotation_text index by t_annotation_position; - + type tt_annotations_by_name is table of tt_annotation_texts index by t_annotation_name; type tt_annotations_by_proc is table of tt_annotations_by_name index by t_object_name; type t_annotations_info is record ( - owner t_object_name, - name t_object_name, - by_line tt_annotations_by_line, - by_proc tt_annotations_by_proc, - by_name tt_annotations_by_name + owner t_object_name, + name t_object_name, + parse_time date, + by_line tt_annotations_by_line, + by_proc tt_annotations_by_proc, + by_name tt_annotations_by_name ); procedure delete_annotations_range( @@ -430,37 +431,39 @@ create or replace package body ut_suite_builder is a_suite in out nocopy ut_suite, a_tests in out nocopy tt_tests, a_procedure_name t_object_name, - a_proc_annotations tt_annotations_by_name + a_annotations t_annotations_info ) is l_test ut_test; l_annotation_texts tt_annotation_texts; l_annotation_pos binary_integer; + l_proc_annotations tt_annotations_by_name := a_annotations.by_proc(a_procedure_name); begin - if not a_proc_annotations.exists(gc_test) then + if not l_proc_annotations.exists(gc_test) then return; end if; - warning_on_duplicate_annot(a_suite, a_proc_annotations, gc_test, a_procedure_name); - warning_on_duplicate_annot(a_suite, a_proc_annotations, gc_displayname, a_procedure_name); - warning_on_duplicate_annot(a_suite, a_proc_annotations, gc_rollback, a_procedure_name); + warning_on_duplicate_annot( a_suite, l_proc_annotations, gc_test, a_procedure_name); + warning_on_duplicate_annot( a_suite, l_proc_annotations, gc_displayname, a_procedure_name); + warning_on_duplicate_annot( a_suite, l_proc_annotations, gc_rollback, a_procedure_name); warning_bad_annot_combination( - a_suite, a_procedure_name, a_proc_annotations, gc_test, + a_suite, a_procedure_name, l_proc_annotations, gc_test, ut_varchar2_list(gc_beforeeach, gc_aftereach, gc_beforeall, gc_afterall) ); - - l_test := ut_test(a_suite.object_owner, a_suite.object_name, a_procedure_name); - if a_proc_annotations.exists(gc_displayname) then - l_annotation_texts := a_proc_annotations(gc_displayname); + l_test := ut_test(a_suite.object_owner, a_suite.object_name, a_procedure_name, l_proc_annotations( gc_test).first); + l_test.parse_time := a_annotations.parse_time; + + if l_proc_annotations.exists( gc_displayname) then + l_annotation_texts := l_proc_annotations( gc_displayname); --take the last definition if more than one was provided l_test.description := l_annotation_texts(l_annotation_texts.first); --TODO if more than one - warning else - l_test.description := a_proc_annotations(gc_test)(a_proc_annotations(gc_test).first); + l_test.description := l_proc_annotations(gc_test)(l_proc_annotations(gc_test).first); end if; l_test.path := a_suite.path ||'.'||a_procedure_name; - if a_proc_annotations.exists(gc_rollback) then - l_annotation_texts := a_proc_annotations(gc_rollback); + if l_proc_annotations.exists(gc_rollback) then + l_annotation_texts := l_proc_annotations(gc_rollback); l_test.rollback_type := get_rollback_type(l_annotation_texts(l_annotation_texts.first)); if l_test.rollback_type is null then add_annotation_ignored_warning( @@ -470,22 +473,22 @@ create or replace package body ut_suite_builder is end if; end if; - if a_proc_annotations.exists(gc_beforetest) then + if l_proc_annotations.exists( gc_beforetest) then l_test.before_test_list := convert_list( - add_executables( l_test.object_owner, l_test.object_name, a_proc_annotations( gc_beforetest ), gc_beforetest ) + add_executables( l_test.object_owner, l_test.object_name, l_proc_annotations( gc_beforetest ), gc_beforetest ) ); end if; - if a_proc_annotations.exists(gc_aftertest) then + if l_proc_annotations.exists( gc_aftertest) then l_test.after_test_list := convert_list( - add_executables( l_test.object_owner, l_test.object_name, a_proc_annotations( gc_aftertest ), gc_aftertest ) + add_executables( l_test.object_owner, l_test.object_name, l_proc_annotations( gc_aftertest ), gc_aftertest ) ); end if; - if a_proc_annotations.exists(gc_throws) then - add_to_throws_numbers_list(a_suite, l_test.expected_error_codes, a_procedure_name, a_proc_annotations(gc_throws)); + if l_proc_annotations.exists( gc_throws) then + add_to_throws_numbers_list(a_suite, l_test.expected_error_codes, a_procedure_name, l_proc_annotations( gc_throws)); end if; - l_test.disabled_flag := ut_utils.boolean_to_int(a_proc_annotations.exists(gc_disabled)); + l_test.disabled_flag := ut_utils.boolean_to_int( l_proc_annotations.exists( gc_disabled)); - a_tests(a_proc_annotations(gc_test).first) := l_test; + a_tests( l_proc_annotations( gc_test).first) := l_test; end; procedure update_before_after_each( @@ -512,13 +515,37 @@ create or replace package body ut_suite_builder is end if; end; + procedure update_before_after_each( + a_suite_items in out nocopy ut_suite_items, + a_before_each_list tt_executables, + a_after_each_list tt_executables + ) is + l_test ut_test; + l_context ut_logical_suite; + begin + if a_suite_items is not null then + for i in 1 .. a_suite_items.count loop + if a_suite_items(i) is of (ut_test) then + l_test := treat( a_suite_items(i) as ut_test); + l_test.before_each_list := coalesce(convert_list(a_before_each_list),ut_executables()) multiset union all l_test.before_each_list; + l_test.after_each_list := l_test.after_each_list multiset union all coalesce(convert_list(a_after_each_list),ut_executables()); + a_suite_items(i) := l_test; + elsif a_suite_items(i) is of (ut_logical_suite) then + l_context := treat(a_suite_items(i) as ut_logical_suite); + update_before_after_each(l_context.items, a_before_each_list, a_after_each_list); + a_suite_items(i) := l_context; + end if; + end loop; + end if; + end; + procedure process_before_after_annot( a_list in out nocopy tt_executables, a_annotation_name t_annotation_name, a_procedure_name t_object_name, a_proc_annotations tt_annotations_by_name, a_suite in out nocopy ut_suite - ) is + ) is begin if a_proc_annotations.exists(a_annotation_name) and not a_proc_annotations.exists(gc_test) then a_list( a_proc_annotations(a_annotation_name).first ) := ut_executables(ut_executable(a_suite.object_owner, a_suite.object_name, a_procedure_name, a_annotation_name)); @@ -528,7 +555,7 @@ create or replace package body ut_suite_builder is end; procedure add_annotated_procedures( - a_proc_annotations tt_annotations_by_proc, + a_proc_annotations t_annotations_info, a_suite in out nocopy ut_suite, a_before_each_list in out nocopy tt_executables, a_after_each_list in out nocopy tt_executables, @@ -538,18 +565,42 @@ create or replace package body ut_suite_builder is l_procedure_name t_object_name; l_tests tt_tests; begin - l_procedure_name := a_proc_annotations.first; + l_procedure_name := a_proc_annotations.by_proc.first; while l_procedure_name is not null loop - add_test( a_suite, l_tests, l_procedure_name, a_proc_annotations(l_procedure_name) ); - process_before_after_annot(a_before_each_list, gc_beforeeach, l_procedure_name, a_proc_annotations(l_procedure_name), a_suite); - process_before_after_annot(a_after_each_list, gc_aftereach, l_procedure_name, a_proc_annotations(l_procedure_name), a_suite); - process_before_after_annot(a_before_all_list, gc_beforeall, l_procedure_name, a_proc_annotations(l_procedure_name), a_suite); - process_before_after_annot(a_after_all_list, gc_afterall, l_procedure_name, a_proc_annotations(l_procedure_name), a_suite); - l_procedure_name := a_proc_annotations.next( l_procedure_name ); + add_test( a_suite, l_tests, l_procedure_name, a_proc_annotations ); + process_before_after_annot(a_before_each_list, gc_beforeeach, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); + process_before_after_annot(a_after_each_list, gc_aftereach, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); + process_before_after_annot(a_before_all_list, gc_beforeall, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); + process_before_after_annot(a_after_all_list, gc_afterall, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); + l_procedure_name := a_proc_annotations.by_proc.next( l_procedure_name ); end loop; a_suite.items := a_suite.items multiset union all convert_list(l_tests); end; + function get_annotated_procedures( + a_proc_annotations t_annotations_info, + a_suite in out nocopy ut_suite, + a_before_each_list in out nocopy tt_executables, + a_after_each_list in out nocopy tt_executables, + a_before_all_list in out nocopy tt_executables, + a_after_all_list in out nocopy tt_executables + ) return ut_suite_items is + l_procedure_name t_object_name; + l_tests tt_tests; + + begin + l_procedure_name := a_proc_annotations.by_proc.first; + while l_procedure_name is not null loop + add_test( a_suite, l_tests, l_procedure_name, a_proc_annotations ); + process_before_after_annot(a_before_each_list, gc_beforeeach, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); + process_before_after_annot(a_after_each_list, gc_aftereach, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); + process_before_after_annot(a_before_all_list, gc_beforeall, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); + process_before_after_annot(a_after_all_list, gc_afterall, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); + l_procedure_name := a_proc_annotations.by_proc.next( l_procedure_name ); + end loop; + return convert_list(l_tests); + end; + procedure build_suitepath( a_suite in out nocopy ut_suite, a_annotations t_annotations_info @@ -630,7 +681,7 @@ create or replace package body ut_suite_builder is a_suite.disabled_flag := ut_utils.boolean_to_int(a_annotations.by_name.exists(gc_disabled)); --process procedure annotations for suite - add_annotated_procedures(a_annotations.by_proc, a_suite, l_before_each_list, l_after_each_list, l_before_all_list, l_after_all_list); + add_annotated_procedures(a_annotations, a_suite, l_before_each_list, l_after_each_list, l_before_all_list, l_after_all_list); a_suite.set_rollback_type(l_rollback_type); update_before_after_each(a_suite, l_before_each_list, l_after_each_list); @@ -638,6 +689,112 @@ create or replace package body ut_suite_builder is a_suite.after_all_list := convert_list(l_after_all_list); end; + function get_suite_items( + a_suite in out nocopy ut_suite, + a_annotations t_annotations_info + ) return ut_suite_items is + l_before_each_list tt_executables; + l_after_each_list tt_executables; + l_before_all_list tt_executables; + l_after_all_list tt_executables; + l_rollback_type ut_utils.t_rollback_type; + l_annotation_text t_annotation_text; + l_results ut_suite_items := ut_suite_items(); + begin + if a_annotations.by_name.exists(gc_displayname) then + l_annotation_text := trim(a_annotations.by_name(gc_displayname)(a_annotations.by_name(gc_displayname).first)); + if l_annotation_text is not null then + a_suite.description := l_annotation_text; + else + add_annotation_ignored_warning( + a_suite, gc_displayname, '%%% annotation requires a non-empty parameter value.', + a_annotations.by_name(gc_displayname).first + ); + end if; + warning_on_duplicate_annot(a_suite, a_annotations.by_name, gc_displayname); + end if; + + if a_annotations.by_name.exists(gc_rollback) then + l_rollback_type := get_rollback_type(a_annotations.by_name(gc_rollback)(a_annotations.by_name(gc_rollback).first)); + if l_rollback_type is null then + add_annotation_ignored_warning( + a_suite, gc_rollback, '%%% annotation requires one of values as parameter: "auto" or "manual".', + a_annotations.by_name(gc_rollback).first + ); + end if; + warning_on_duplicate_annot(a_suite, a_annotations.by_name, gc_rollback); + end if; + if a_annotations.by_name.exists(gc_beforeall) then + l_before_all_list := add_executables( a_suite.object_owner, a_suite.object_name, a_annotations.by_name(gc_beforeall), gc_beforeall ); + end if; + if a_annotations.by_name.exists(gc_afterall) then + l_after_all_list := add_executables( a_suite.object_owner, a_suite.object_name, a_annotations.by_name(gc_afterall), gc_afterall ); + end if; + + if a_annotations.by_name.exists(gc_beforeeach) then + l_before_each_list := add_executables( a_suite.object_owner, a_suite.object_name, a_annotations.by_name(gc_beforeeach), gc_beforeeach ); + end if; + if a_annotations.by_name.exists(gc_aftereach) then + l_after_each_list := add_executables( a_suite.object_owner, a_suite.object_name, a_annotations.by_name(gc_aftereach), gc_aftereach ); + end if; + + a_suite.disabled_flag := ut_utils.boolean_to_int(a_annotations.by_name.exists(gc_disabled)); + + --process procedure annotations for suite + l_results := get_annotated_procedures(a_annotations, a_suite, l_before_each_list, l_after_each_list, l_before_all_list, l_after_all_list); + + a_suite.set_rollback_type(l_rollback_type); + update_before_after_each(l_results, l_before_each_list, l_after_each_list); + a_suite.before_all_list := convert_list(l_before_all_list); + a_suite.after_all_list := convert_list(l_after_all_list); + return l_results; + end; + + function get_endcontext_position( + a_context_ann_pos t_annotation_position, + a_package_annotations in out nocopy tt_annotations_by_name + ) return t_annotation_position is + l_result t_annotation_position; + begin + if a_package_annotations.exists(gc_endcontext) then + l_result := a_package_annotations(gc_endcontext).first; + while l_result <= a_context_ann_pos loop + l_result := a_package_annotations(gc_endcontext).next(l_result); + end loop; + end if; + return l_result; + end; + + function get_annotations_in_context( + a_annotations t_annotations_info, + a_context_pos t_annotation_position, + a_end_context_pos t_annotation_position + ) return t_annotations_info is + l_result t_annotations_info; + l_position t_annotation_position; + l_procedure_name t_object_name; + l_annotation_name t_annotation_name; + l_annotation_text t_annotation_text; + begin + l_position := a_context_pos; + l_result.owner := a_annotations.owner; + l_result.name := a_annotations.name; + l_result.parse_time := a_annotations.parse_time; + while l_position is not null and l_position <= a_end_context_pos loop + l_result.by_line(l_position) := a_annotations.by_line(l_position); + l_procedure_name := l_result.by_line(l_position).procedure_name; + l_annotation_name := l_result.by_line(l_position).name; + l_annotation_text := l_result.by_line(l_position).text; + if l_procedure_name is not null then + l_result.by_proc(l_procedure_name)(l_annotation_name)(l_position) := l_annotation_text; + else + l_result.by_name(l_annotation_name)(l_position) := l_annotation_text; + end if; + l_position := a_annotations.by_line.next(l_position); + end loop; + return l_result; + end; + procedure add_suite_contexts( a_suite in out nocopy ut_suite, @@ -649,54 +806,70 @@ create or replace package body ut_suite_builder is l_ctx_annotations t_annotations_info; l_context ut_suite_context; l_context_no binary_integer := 1; + type tt_context_names is table of boolean index by t_object_name; + l_context_names tt_context_names; + begin + if not a_annotations.by_name.exists(gc_context) then + return; + end if; - function get_endcontext_position( - a_context_ann_pos t_annotation_position, - a_package_annotations in out nocopy tt_annotations_by_name - ) return t_annotation_position is - l_result t_annotation_position; - begin - if a_package_annotations.exists(gc_endcontext) then - l_result := a_package_annotations(gc_endcontext).first; - while l_result <= a_context_ann_pos loop - l_result := a_package_annotations(gc_endcontext).next(l_result); - end loop; + l_context_pos := a_annotations.by_name( gc_context).first; + + while l_context_pos is not null loop + l_end_context_pos := get_endcontext_position(l_context_pos, a_annotations.by_name ); + if l_end_context_pos is null then + exit; end if; - return l_result; - end; - function get_annotations_in_context( - a_annotations t_annotations_info, - a_context_pos t_annotation_position, - a_end_context_pos t_annotation_position - ) return t_annotations_info is - l_result t_annotations_info; - l_position t_annotation_position; - l_procedure_name t_object_name; - l_annotation_name t_annotation_name; - l_annotation_text t_annotation_text; - begin - l_position := a_context_pos; - l_result.owner := a_annotations.owner; - l_result.name := a_annotations.name; - while l_position is not null and l_position <= a_end_context_pos loop - l_result.by_line(l_position) := a_annotations.by_line(l_position); - l_procedure_name := l_result.by_line(l_position).procedure_name; - l_annotation_name := l_result.by_line(l_position).name; - l_annotation_text := l_result.by_line(l_position).text; - if l_procedure_name is not null then - l_result.by_proc(l_procedure_name)(l_annotation_name)(l_position) := l_annotation_text; - else - l_result.by_name(l_annotation_name)(l_position) := l_annotation_text; - end if; - l_position := a_annotations.by_line.next(l_position); - end loop; - return l_result; - end; + --create a sub-set of annotations to process as sub-suite (context) + l_ctx_annotations := get_annotations_in_context( a_annotations, l_context_pos, l_end_context_pos); + + l_context_name := coalesce( + l_ctx_annotations.by_line( l_context_pos ).text + , gc_context||'_'||l_context_no + ); + if l_context_names.exists(l_context_name) then + add_annotation_ignored_warning( a_suite, 'context', 'Context name must be unique in a suite. Context and all of it''s content ignored.', l_context_pos ); + else + l_context_names(l_context_name) := true; + l_context := ut_suite_context(a_suite.object_owner, a_suite.object_name, l_context_name, l_context_pos ); + + l_context.path := a_suite.path||'.'||l_context_name; + l_context.description := l_ctx_annotations.by_line( l_context_pos ).text; + + warning_on_duplicate_annot( l_context, l_ctx_annotations.by_name, gc_context ); + + populate_suite_contents( l_context, l_ctx_annotations ); + + a_suite.add_item(l_context); + end if; + -- remove annotations within context after processing them + delete_annotations_range(a_annotations, l_context_pos, l_end_context_pos); + + exit when not a_annotations.by_name.exists( gc_context); + + l_context_pos := a_annotations.by_name( gc_context).next( l_context_pos); + l_context_no := l_context_no + 1; + end loop; + end; + + function get_suite_contexts_items( + a_suite in out nocopy ut_suite, + a_annotations in out nocopy t_annotations_info + ) return ut_suite_items is + l_context_pos t_annotation_position; + l_end_context_pos t_annotation_position; + l_context_name t_object_name; + l_ctx_annotations t_annotations_info; + l_context ut_suite_context; + l_context_no binary_integer := 1; + type tt_context_names is table of boolean index by t_object_name; + l_context_names tt_context_names; + l_results ut_suite_items := ut_suite_items(); begin if not a_annotations.by_name.exists(gc_context) then - return; + return l_results; end if; l_context_pos := a_annotations.by_name( gc_context).first; @@ -714,18 +887,23 @@ create or replace package body ut_suite_builder is l_ctx_annotations.by_line( l_context_pos ).text , gc_context||'_'||l_context_no ); + if l_context_names.exists(l_context_name) then + add_annotation_ignored_warning( a_suite, 'context', 'Context name must be unique in a suite. Context and all of it''s content ignored.', l_context_pos ); + else + l_context_names(l_context_name) := true; - l_context := ut_suite_context(a_suite.object_owner, a_suite.object_name, l_context_name ); - - l_context.path := a_suite.path||'.'||l_context_name; - l_context.description := l_ctx_annotations.by_line( l_context_pos ).text; - - warning_on_duplicate_annot( l_context, l_ctx_annotations.by_name, gc_context ); + l_context := ut_suite_context(a_suite.object_owner, a_suite.object_name, l_context_name, l_context_pos ); - populate_suite_contents( l_context, l_ctx_annotations ); + l_context.path := a_suite.path||'.'||l_context_name; + l_context.description := l_ctx_annotations.by_line( l_context_pos ).text; + l_context.parse_time := a_annotations.parse_time; - a_suite.add_item(l_context); + warning_on_duplicate_annot( l_context, l_ctx_annotations.by_name, gc_context ); + l_results := l_results multiset union all get_suite_items( l_context, l_ctx_annotations ); + l_results.extend; + l_results(l_results.last) := l_context; + end if; -- remove annotations within context after processing them delete_annotations_range(a_annotations, l_context_pos, l_end_context_pos); @@ -734,6 +912,7 @@ create or replace package body ut_suite_builder is l_context_pos := a_annotations.by_name( gc_context).next( l_context_pos); l_context_no := l_context_no + 1; end loop; + return l_results; end; procedure warning_on_incomplete_context( @@ -794,9 +973,9 @@ create or replace package body ut_suite_builder is if l_annotations.by_name.exists( gc_suite) then --create an incomplete suite - l_suite := ut_suite(l_annotations.owner, l_annotations.name); - l_annotation_pos := l_annotations.by_name( gc_suite).first; - l_suite.description := l_annotations.by_name( gc_suite)( l_annotation_pos); + l_annotation_pos := l_annotations.by_name(gc_suite).first; + l_suite := ut_suite(l_annotations.owner, l_annotations.name, l_annotation_pos); + l_suite.description := l_annotations.by_name(gc_suite)(l_annotation_pos); warning_on_unknown_annotations(l_suite, l_annotations.by_line); warning_on_duplicate_annot( l_suite, l_annotations.by_name, gc_suite ); @@ -813,7 +992,54 @@ create or replace package body ut_suite_builder is return l_suite; end; - function build_suites_hierarchy(a_suites_by_path tt_schema_suites) return tt_schema_suites is + function build_parent_suites_for_path(a_suite ut_suite) return ut_suite_items is + l_results ut_suite_items := ut_suite_items(); + l_path varchar2(200); + l_name varchar2(200); + begin + l_path := a_suite.path; + loop + l_path := substr( l_path, 1, instr(l_path,'.',-1)-1); + exit when l_path is null; + l_name := substr( l_path, instr(l_path,'.',-1)+1); + l_results.extend; + l_results(l_results.last) := + ut_logical_suite( + a_object_owner => a_suite.object_owner, + a_object_name => l_name, a_name => l_name, a_path => l_path + ); + l_results(l_results.last).parse_time := a_suite.parse_time; + end loop; + return l_results; + end; + function create_suite_items( a_annotations t_annotations_info ) return ut_suite_items is + l_annotations t_annotations_info := a_annotations; + l_annotation_pos t_annotation_position; + l_suite ut_suite; + l_results ut_suite_items; + begin + if l_annotations.by_name.exists(gc_suite) then + l_annotation_pos := l_annotations.by_name(gc_suite).first; + l_suite := ut_suite(l_annotations.owner, l_annotations.name, l_annotation_pos); + l_suite.description := l_annotations.by_name( gc_suite)( l_annotation_pos); + l_suite.parse_time := l_annotations.parse_time; + warning_on_unknown_annotations(l_suite, l_annotations.by_line); + + warning_on_duplicate_annot( l_suite, l_annotations.by_name, gc_suite ); + + build_suitepath( l_suite, l_annotations ); + l_results := get_suite_contexts_items( l_suite, l_annotations ) multiset union all get_suite_items( l_suite, l_annotations ); + + --by this time all contexts were consumed and l_annotations should not have any context/endcontext annotation in it. + warning_on_incomplete_context( l_suite, l_annotations.by_name ); + l_results.extend; + l_results(l_results.last) := l_suite; + l_results := l_results multiset union all build_parent_suites_for_path(l_suite); + end if; + return l_results; + end; + + function build_suites_hierarchy( a_suites_by_path tt_schema_suites ) return tt_schema_suites is l_result tt_schema_suites; l_suite_path varchar2(4000 char); l_parent_path varchar2(4000 char); @@ -856,49 +1082,53 @@ create or replace package body ut_suite_builder is return l_result; end; + function convert_package_annotations(a_object ut_annotated_object) return t_annotations_info is + l_result t_annotations_info; + l_annotation t_annotation; + l_annotation_no binary_integer; + l_annotation_pos binary_integer; + begin + l_result.owner := a_object.object_owner; + l_result.name := lower(trim(a_object.object_name)); + l_result.parse_time := a_object.parse_time; + l_annotation_no := a_object.annotations.first; + while l_annotation_no is not null loop + l_annotation_pos := a_object.annotations(l_annotation_no).position; + l_annotation.name := a_object.annotations(l_annotation_no).name; + l_annotation.text := a_object.annotations(l_annotation_no).text; + l_annotation.procedure_name := lower(trim(a_object.annotations(l_annotation_no).subobject_name)); + l_result.by_line( l_annotation_pos) := l_annotation; + if l_annotation.procedure_name is null then + l_result.by_name( l_annotation.name)( l_annotation_pos) := l_annotation.text; + else + l_result.by_proc(l_annotation.procedure_name)(l_annotation.name)(l_annotation_pos) := l_annotation.text; + end if; + l_annotation_no := a_object.annotations.next(l_annotation_no); + end loop; + return l_result; + end; + + function build_suites(a_annotated_objects sys_refcursor) return t_schema_suites_info is l_suite ut_logical_suite; l_annotated_objects ut_annotated_objects; l_all_suites tt_schema_suites; l_result t_schema_suites_info; - - function convert_package_annotations(a_object ut_annotated_object) return t_annotations_info is - l_result t_annotations_info; - l_annotation t_annotation; - l_annotation_no binary_integer; - l_annotation_pos binary_integer; - begin - l_result.owner := a_object.object_owner; - l_result.name := lower(trim(a_object.object_name)); - l_annotation_no := a_object.annotations.first; - while l_annotation_no is not null loop - l_annotation_pos := a_object.annotations(l_annotation_no).position; - l_annotation.name := a_object.annotations(l_annotation_no).name; - l_annotation.text := a_object.annotations(l_annotation_no).text; - l_annotation.procedure_name := lower(trim(a_object.annotations(l_annotation_no).subobject_name)); - l_result.by_line( l_annotation_pos) := l_annotation; - if l_annotation.procedure_name is null then - l_result.by_name( l_annotation.name)( l_annotation_pos) := l_annotation.text; - else - l_result.by_proc(l_annotation.procedure_name)(l_annotation.name)(l_annotation_pos) := l_annotation.text; + begin + loop + fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; + + for i in 1 .. l_annotated_objects.count loop + l_suite := create_suite(convert_package_annotations(l_annotated_objects(i))); + ut_suite_cache_manager.save_cache( create_suite_items(convert_package_annotations(l_annotated_objects(i))) ); + if l_suite is not null then + l_all_suites(l_suite.path) := l_suite; + l_result.suite_paths(l_suite.object_name) := l_suite.path; end if; - l_annotation_no := a_object.annotations.next(l_annotation_no); end loop; - return l_result; - end; - - begin - fetch a_annotated_objects bulk collect into l_annotated_objects; - close a_annotated_objects; - - for i in 1 .. l_annotated_objects.count loop - l_suite := create_suite(convert_package_annotations(l_annotated_objects(i))); - if l_suite is not null then - l_all_suites(l_suite.path) := l_suite; - l_result.suite_paths(l_suite.object_name) := l_suite.path; - end if; + exit when a_annotated_objects%notfound; end loop; - + close a_annotated_objects; --build hierarchical structure of the suite -- Restructure single-dimension list into hierarchy of suites by the value of %suitepath attribute value l_result.schema_suites := build_suites_hierarchy(l_all_suites); @@ -906,7 +1136,77 @@ create or replace package body ut_suite_builder is return l_result; end; - function build_schema_suites(a_owner_name varchar2) return t_schema_suites_info is + procedure refresh_suite_cache(a_annotated_objects sys_refcursor) is + l_suite ut_logical_suite; + l_annotated_objects ut_annotated_objects; + l_all_suites tt_schema_suites; + l_result t_schema_suites_info; + begin + loop + fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; + + for i in 1 .. l_annotated_objects.count loop + ut_suite_cache_manager.save_cache( create_suite_items(convert_package_annotations(l_annotated_objects(i))) ); + end loop; + exit when a_annotated_objects%notfound; + end loop; + close a_annotated_objects; + end; + + procedure reconstruct_from_cache( + a_suites in out nocopy ut_suite_items, + a_suite_data_cursor sys_refcursor + ) is + type t_item_levels is table of ut_suite_items index by binary_integer; + l_items_at_level t_item_levels; + l_tests ut_suite_items; + l_logical_suites ut_logical_suites; + l_levels ut_integer_list; + l_cursor_idx integer; + l_prev_level integer; + begin + a_suites := ut_suite_items(); + loop + if l_cursor_idx is null then + fetch a_suite_data_cursor bulk collect into l_tests, l_logical_suites, l_levels limit 1000; + l_cursor_idx := l_levels.first; + end if; + exit when l_cursor_idx is null; + if l_levels(l_cursor_idx) > 1 then + if l_prev_level > l_levels(l_cursor_idx) then + l_logical_suites(l_cursor_idx).items := l_items_at_level(l_prev_level); + l_items_at_level(l_prev_level).delete; + end if; + if not l_items_at_level.exists((l_levels(l_cursor_idx))) then + l_items_at_level(l_levels(l_cursor_idx)) := ut_suite_items(); + end if; + l_items_at_level(l_levels(l_cursor_idx)).extend; + if l_tests(l_cursor_idx) is not null then + l_items_at_level(l_levels(l_cursor_idx))(l_items_at_level(l_levels(l_cursor_idx)).last) + := l_tests(l_cursor_idx); + else + l_items_at_level(l_levels(l_cursor_idx))(l_items_at_level(l_levels(l_cursor_idx)).last) + := l_logical_suites(l_cursor_idx); + end if; + else + if l_prev_level > l_levels(l_cursor_idx) then + l_logical_suites(l_cursor_idx).items := l_items_at_level(l_prev_level); + l_items_at_level(l_prev_level).delete; + end if; + a_suites.extend; + if l_tests(l_cursor_idx) is not null then + a_suites(a_suites.last) := l_tests(l_cursor_idx); + else + a_suites(a_suites.last) := l_logical_suites(l_cursor_idx); + end if; + end if; + l_prev_level := l_levels(l_cursor_idx); + l_cursor_idx := l_levels.next(l_cursor_idx); + end loop; + close a_suite_data_cursor; + end; + + function build_schema_suites_old(a_owner_name varchar2) return t_schema_suites_info is l_annotations_cursor sys_refcursor; begin -- form the single-dimension list of suites constructed from parsed packages @@ -920,5 +1220,66 @@ create or replace package body ut_suite_builder is return build_suites(l_annotations_cursor); end; + function get_build_suites(a_owner_name varchar2) return ut_suite_items is + l_suites t_schema_suites_info; + l_results ut_suite_items := ut_suite_items(); + l_index varchar2(4000); + begin + l_suites := build_schema_suites_old(a_owner_name); + l_index := l_suites.schema_suites.first; + while l_index is not null loop + l_results.extend; + l_results(l_results.last) := l_suites.schema_suites(l_index); + l_index := l_suites.schema_suites.next(l_index); + end loop; + return l_results; + end; + + + procedure refresh_suite_cache(a_owner_name varchar2) is + l_annotations_cursor sys_refcursor; + begin + open l_annotations_cursor for + q'[select value(x) + from table( + ]'||ut_utils.ut_owner||q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE') + )x ]' + using a_owner_name; + refresh_suite_cache(l_annotations_cursor); + end; + + function build_schema_suites(a_owner_name varchar2) return ut_suite_items is + l_suites ut_suite_items; + begin + refresh_suite_cache(a_owner_name); + reconstruct_from_cache(l_suites, ut_suite_cache_manager.cached_suite_by_schema(a_owner_name)); + for i in 1 .. l_suites.count loop + l_suites(i).set_rollback_type(l_suites(i).get_rollback_type); + end loop; + return l_suites; + end; + + function build_schema_suites(a_owner_name varchar2,a_object_name varchar2,a_procedure_name varchar2) return ut_suite_items is + l_suites ut_suite_items; + begin + refresh_suite_cache(a_owner_name); + reconstruct_from_cache(l_suites, ut_suite_cache_manager.cached_suite_by_package(a_owner_name, a_object_name, a_procedure_name)); + for i in 1 .. l_suites.count loop + l_suites(i).set_rollback_type(l_suites(i).get_rollback_type); + end loop; + return l_suites; + end; + + function build_schema_suites(a_owner_name varchar2,a_path varchar2) return ut_suite_items is + l_suites ut_suite_items; + begin + refresh_suite_cache(a_owner_name); + reconstruct_from_cache(l_suites, ut_suite_cache_manager.cached_suite_by_path(a_owner_name, a_path)); + for i in 1 .. l_suites.count loop + l_suites(i).set_rollback_type(l_suites(i).get_rollback_type); + end loop; + return l_suites; + end; + end ut_suite_builder; / diff --git a/source/core/ut_suite_builder.pks b/source/core/ut_suite_builder.pks index 2ae40f4d3..0f4d97c76 100644 --- a/source/core/ut_suite_builder.pks +++ b/source/core/ut_suite_builder.pks @@ -20,10 +20,10 @@ create or replace package ut_suite_builder authid current_user is * Responsible for converting annotations into unit test suites */ - --table of ut_suites indexed by object name ( suite_paths('object_name') = ut_logical_suite + --table of ut_suites indexed by suite path - tt_schema_suites('suite.path') gives ut_logical_suite type tt_schema_suites is table of ut_logical_suite index by varchar2(4000 char); - --table of suite paths indexed by object name ( suite_paths('object_name') = 'suitepath.to.object' + --table of suite paths indexed by object name - t_object_suite_path('object_name') = 'suitepath.to.object' type t_object_suite_path is table of varchar2(4000) index by varchar2(4000 char); type t_schema_suites_info is record ( @@ -34,11 +34,32 @@ create or replace package ut_suite_builder authid current_user is /** * Builds set of hierarchical suites for a given schema * - * @param a_owner_name name of the schema to builds suites for + * @param a_owner_name name of the schema to builds suite for * @return list of suites organized into hierarchy * */ - function build_schema_suites(a_owner_name varchar2) return t_schema_suites_info; + function build_schema_suites(a_owner_name varchar2) return ut_suite_items; + + /** + * Builds set of hierarchical suites for a given schema + * + * @param a_owner_name name of the schema to builds suite for + * @param a_object_name object name to build suite for + * @param a_object_name procedure name to build suite for (can be null) + * @return list of suites organized into hierarchy + * + */ + function build_schema_suites(a_owner_name varchar2, a_object_name varchar2,a_procedure_name varchar2) return ut_suite_items; + + /** + * Builds set of hierarchical suites for a given schema + * + * @param a_owner_name name of the schema to builds suite for + * @param a_path suite path to build suite for + * @return list of suites organized into hierarchy + * + */ + function build_schema_suites(a_owner_name varchar2,a_path varchar2) return ut_suite_items; /** * Builds set of hierarchical suites for given annotations @@ -49,5 +70,8 @@ create or replace package ut_suite_builder authid current_user is */ function build_suites(a_annotated_objects sys_refcursor) return t_schema_suites_info; + function get_build_suites(a_owner_name varchar2) return ut_suite_items; + function build_schema_suites_old(a_owner_name varchar2) return t_schema_suites_info; + end ut_suite_builder; / diff --git a/source/core/ut_suite_cache.sql b/source/core/ut_suite_cache.sql new file mode 100644 index 000000000..183f4cf35 --- /dev/null +++ b/source/core/ut_suite_cache.sql @@ -0,0 +1,89 @@ +create or replace type ut_suite_contexts as table of ut_suite_context +/ +create or replace type ut_tests as table of ut_test +/ + +create table ut_suite_cache ( + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + self_type, + path, + object_owner, + object_name, + name, + line_no, + parse_time, + description, + rollback_type, + disabled_flag, + warnings, + before_all_list, + after_all_list, + before_each_list, + before_test_list, + after_each_list, + after_test_list, + expected_error_codes, + item +) + nested table warnings store as ut_suite_cache_warnings + nested table before_all_list store as ut_suite_cache_before_all + nested table after_all_list store as ut_suite_cache_after_all + nested table before_each_list store as ut_suite_cache_before_each + nested table after_each_list store as ut_suite_cache_after_each + nested table before_test_list store as ut_suite_cache_before_test + nested table after_test_list store as ut_suite_cache_after_test + nested table expected_error_codes store as ut_suite_cache_trhows + as + select + c.self_type, + c.path, + c.object_owner, + c.object_name, + c.name, + c.line_no, + c.parse_time, + c.description, + c.rollback_type, + c.disabled_flag, + c.warnings, + c.before_all_list, + c.after_all_list, + t.before_each_list, + t.before_test_list, + t.after_each_list, + t.after_test_list, + t.expected_error_codes, + t.item + from table(ut_suite_contexts(ut_suite_context(user,'package_name','ctx_name',1))) c + cross join table(ut_tests(ut_test(user,'package_name','test_name',1))) t + where rownum < 0 +/ + +alter table ut_suite_cache modify (object_owner not null, path not null, self_type not null, object_name not null, name not null, parse_time not null) +/ +alter table ut_suite_cache add constraint ut_suite_cache_pk primary key (object_owner, path) +/ +create unique index ut_suite_cache_uk on ut_suite_cache(object_owner, object_name, line_no) +/ +create index ut_suite_cache_nu1 on ut_suite_cache(object_owner, object_name) +/ +alter table ut_suite_cache add constraint ut_suite_cache_schema_fk foreign key (object_owner) references ut_suite_cache_schema(object_owner) +/ + +drop type ut_tests +/ + +drop type ut_suite_contexts +/ diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb new file mode 100644 index 000000000..a51ee14a7 --- /dev/null +++ b/source/core/ut_suite_cache_manager.pkb @@ -0,0 +1,284 @@ +create or replace package body ut_suite_cache_manager is + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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_suite_by(a_schema_name varchar2, a_path varchar2 := null, a_object_name varchar2 := null, a_procedure_name varchar2 := null) return sys_refcursor is + l_result sys_refcursor; + begin + open l_result for + select + case self_type + when 'UT_TEST' + then ut_test( + self_type => self_type, + object_owner => object_owner, object_name => object_name, name => name, + description => description, path => path, rollback_type => rollback_type, + disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, + start_time => null, end_time => null, result => null, warnings => warnings, + results_count => ut_results_counter(), transaction_invalidators => null, + before_each_list => before_each_list, before_test_list => before_test_list, + item => item, after_test_list => after_test_list, after_each_list => after_each_list, + all_expectations => null, failed_expectations => null, + parent_error_stack_trace => null, expected_error_codes => expected_error_codes + ) + end as test_item, + case self_type + when 'UT_SUITE' + then ut_suite( + self_type => self_type, + object_owner => object_owner, object_name => object_name, name => name, + description => description, path => path, rollback_type => rollback_type, + disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, + start_time => null, end_time => null, result => null, warnings => warnings, + results_count => ut_results_counter(), transaction_invalidators => null, + items => ut_suite_items(), + before_all_list => before_all_list, after_all_list => after_all_list + ) + when 'UT_SUITE_CONTEXT' + then ut_suite_context( + self_type => self_type, + object_owner => object_owner, object_name => object_name, name => name, + description => description, path => path, rollback_type => rollback_type, + disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, + start_time => null, end_time => null, result => null, warnings => warnings, + results_count => ut_results_counter(), transaction_invalidators => null, + items => ut_suite_items(), + before_all_list => before_all_list, after_all_list => after_all_list + ) + when 'UT_LOGICAL_SUITE' + then ut_logical_suite( + self_type => self_type, + object_owner => object_owner, object_name => object_name, name => name, + description => description, path => path, rollback_type => rollback_type, + disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, + start_time => null, end_time => null, result => null, warnings => warnings, + results_count => ut_results_counter(), transaction_invalidators => null, + items => ut_suite_items() + ) + end as logical_suite, + length(path) - length( replace(path, '.') )+1 as path_level + from ut_suite_cache x + where ( a_path like path ||'.'||'%' + or ( path like a_path || '%' + and object_name = nvl(lower(a_object_name), object_name) + and name = nvl(lower(a_procedure_name), name) + ) + ) + and object_owner = upper(a_schema_name) + order by path desc, object_name, line_no; + + return l_result; + end; + +-- function get_suite_by(a_schema_name varchar2, a_path varchar2 := null, a_object_name varchar2 := null, a_procedure_name varchar2 := null) return sys_refcursor is +-- l_filter varchar2(1000); +-- l_result sys_refcursor; +-- l_owner varchar2(250) := ut_utils.ut_owner(); +-- begin +-- if a_object_name is not null then +-- l_filter := ' object_name = lower(:a_object_name)'; +-- if a_procedure_name is not null then +-- l_filter := l_filter || ' and name = lower(:a_procedure_name)'; +-- else +-- l_filter := l_filter || ' and :a_procedure_name is null'; +-- end if; +-- else +-- l_filter := ' :a_object_name is null and :a_procedure_name is null'; +-- end if; +-- open l_result for q'[ +-- select +-- case self_type +-- when 'UT_TEST' +-- then ]'||l_owner||q'[.ut_test( +-- self_type => self_type, +-- object_owner => object_owner, object_name => object_name, name => name, +-- description => description, path => path, rollback_type => rollback_type, +-- disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, +-- start_time => null, end_time => null, result => null, warnings => warnings, +-- results_count => ut_results_counter(), transaction_invalidators => null, +-- before_each_list => before_each_list, before_test_list => before_test_list, +-- item => item, after_test_list => after_test_list, after_each_list => after_each_list, +-- all_expectations => null, failed_expectations => null, +-- parent_error_stack_trace => null, expected_error_codes => expected_error_codes +-- ) +-- end as test_item, +-- case self_type +-- when 'UT_SUITE' +-- then ]'||l_owner||q'[.ut_suite( +-- self_type => self_type, +-- object_owner => object_owner, object_name => object_name, name => name, +-- description => description, path => path, rollback_type => rollback_type, +-- disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, +-- start_time => null, end_time => null, result => null, warnings => warnings, +-- results_count => ]'||l_owner||q'[.ut_results_counter(), transaction_invalidators => null, +-- items => ut_suite_items(), +-- before_all_list => before_all_list, after_all_list => after_all_list +-- ) +-- when 'UT_SUITE_CONTEXT' +-- then ]'||l_owner||q'[.ut_suite_context( +-- self_type => self_type, +-- object_owner => object_owner, object_name => object_name, name => name, +-- description => description, path => path, rollback_type => rollback_type, +-- disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, +-- start_time => null, end_time => null, result => null, warnings => warnings, +-- results_count => ]'||l_owner||q'[.ut_results_counter(), transaction_invalidators => null, +-- items => ut_suite_items(), +-- before_all_list => before_all_list, after_all_list => after_all_list +-- ) +-- when 'UT_LOGICAL_SUITE' +-- then ]'||l_owner||q'[.ut_logical_suite( +-- self_type => self_type, +-- object_owner => object_owner, object_name => object_name, name => name, +-- description => description, path => path, rollback_type => rollback_type, +-- disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, +-- start_time => null, end_time => null, result => null, warnings => warnings, +-- results_count => ]'||l_owner||q'[.ut_results_counter(), transaction_invalidators => null, +-- items => ut_suite_items() +-- ) +-- end as logical_suite, +-- length(path) - length( replace(path, '.') )+1 as path_level +-- from ]'||l_owner||q'[.ut_suite_cache x +-- where ( :a_path like path ||'.'||'%' +-- or path like :a_path ||'%' and ]'||l_filter||q'[ ) +-- and object_owner = upper(:a_schema_name) +-- order by path desc, object_name, line_no]' +-- using a_path, a_path, a_object_name, a_procedure_name, a_schema_name; +-- +-- return l_result; +-- end; +-- + function cached_suite_by_path(a_schema_name varchar2, a_path varchar2) return sys_refcursor is + begin + return get_suite_by(a_schema_name, a_path); + end; + + function cached_suite_by_package(a_schema_name varchar2, a_object_name varchar2, a_procedure_name varchar2) return sys_refcursor is + l_path varchar2(4000); + begin + select min(path) into l_path + from ut_suite_cache + where object_owner = upper(a_schema_name) + and object_name = lower(a_object_name) + and name = nvl(lower(a_procedure_name),name); + + return get_suite_by(a_schema_name, l_path, a_object_name, a_procedure_name ); + end; + + function cached_suite_by_schema(a_schema_name varchar2) return sys_refcursor is + begin + return get_suite_by(a_schema_name); + end; + + procedure save_cache(a_suite_items ut_suite_items) is + pragma autonomous_transaction; + l_annotation_parse_time date; + l_suite_parse_time date; + begin + if a_suite_items.count = 0 then + return; + end if; + if a_suite_items(1).self_type != 'UT_LOGICAL_SUITE' then + select min(parse_time) + into l_suite_parse_time from ut_suite_cache t + where t.object_name = a_suite_items(1).object_name + and t.object_owner = a_suite_items(1).object_owner + and rownum = 1; + end if; + + l_annotation_parse_time := a_suite_items(1).parse_time; + + if l_annotation_parse_time > l_suite_parse_time or l_suite_parse_time is null then + + merge into ut_suite_cache_schema t + using(select object_owner, max(parse_time) parse_time from table(a_suite_items) group by object_owner) s + on (s.object_owner = t.object_owner) + when matched then update + set t.parse_time = s.parse_time + where s.parse_time > t.parse_time + when not matched then + insert (object_owner, parse_time) + values (s.object_owner, s.parse_time); + + delete from ut_suite_cache t + where (t.object_name, t.object_owner) + in (select s.object_name, s.object_owner from table(a_suite_items) s where s.self_type != 'UT_LOGICAL_SUITE'); + + merge into ut_suite_cache t + using ( + select self_type, path, object_owner, object_name, name, + line_no, parse_time, description, + rollback_type, disabled_flag, warnings + from table(a_suite_items) x where x.self_type = 'UT_LOGICAL_SUITE' + ) s + on (t.object_name = s.object_name and t.object_owner = s.object_owner) + when not matched then + insert ( + self_type, path, object_owner, object_name, name, + line_no, parse_time, description, + rollback_type, disabled_flag, warnings + ) + values ( + s.self_type, s.path, s.object_owner, s.object_name, s.name, + s.line_no, s.parse_time, s.description, + s.rollback_type, s.disabled_flag, s.warnings + ); + + + insert into ut_suite_cache t + ( + self_type, path, object_owner, object_name, name, + line_no, parse_time, description, + rollback_type, disabled_flag, warnings, + before_all_list, after_all_list, + before_each_list, after_each_list, + before_test_list, after_test_list, + expected_error_codes, item + ) + with + suite_items as ( select value(x) item from table(a_suite_items) x ), + suites as ( + select treat(item as ut_suite) i from suite_items s + where s.item.self_type in ('UT_SUITE','UT_SUITE_CONTEXT') + ), + tests as ( + select treat(item as ut_test) t from suite_items s + where s.item.self_type in ('UT_TEST') + ) + select s.i.self_type as self_type, s.i.path as path, + s.i.object_owner as object_owner, s.i.object_name as object_name, s.i.name as name, + s.i.line_no as line_no, s.i.parse_time as parse_time, s.i.description as description, + s.i.rollback_type as rollback_type, s.i.disabled_flag as disabled_flag, s.i.warnings as warnings, + s.i.before_all_list as before_all_list, s.i.after_all_list as after_all_list, + null before_each_list, null after_each_list, + null before_test_list, null after_test_list, + null expected_error_codes, null item + from suites s + union all + select s.t.self_type as self_type, s.t.path as path, + s.t.object_owner as object_owner, s.t.object_name as object_name, s.t.name as name, + s.t.line_no as line_no, s.t.parse_time as parse_time, s.t.description as description, + s.t.rollback_type as rollback_type, s.t.disabled_flag as disabled_flag, s.t.warnings as warnings, + null before_all_list, null after_all_list, + s.t.before_each_list as before_each_list, s.t.after_each_list as after_each_list, + s.t.before_test_list as before_test_list, s.t.after_test_list as after_test_list, + s.t.expected_error_codes as expected_error_codes, s.t.item as item + from tests s; + end if; + commit; + end; +end ut_suite_cache_manager; +/ diff --git a/source/core/ut_suite_cache_manager.pks b/source/core/ut_suite_cache_manager.pks new file mode 100644 index 000000000..1b2d1f2f6 --- /dev/null +++ b/source/core/ut_suite_cache_manager.pks @@ -0,0 +1,32 @@ +create or replace package ut_suite_cache_manager authid definer is + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + + /** + * Responsible for storing and retrieving suite data from cache + */ + + procedure save_cache(a_suite_items ut_suite_items); + + function cached_suite_by_path(a_schema_name varchar2, a_path varchar2) return sys_refcursor; + + function cached_suite_by_package(a_schema_name varchar2, a_object_name varchar2, a_procedure_name varchar2) return sys_refcursor; + + function cached_suite_by_schema(a_schema_name varchar2) return sys_refcursor; + +end ut_suite_cache_manager; +/ diff --git a/source/core/ut_suite_cache_schema.sql b/source/core/ut_suite_cache_schema.sql new file mode 100644 index 000000000..890c72e0b --- /dev/null +++ b/source/core/ut_suite_cache_schema.sql @@ -0,0 +1,20 @@ +create table ut_suite_cache_schema ( + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + object_owner varchar2(250) not null, + parse_time date not null, + constraint ut_suite_cache_schema_pk primary key(object_owner) +) organization index +/ + diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index ca438813d..dd9ffb5de 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -33,7 +33,15 @@ create or replace package body ut_suite_manager is g_schema_suites tt_schema_suites_list; - type t_schema_paths is table of ut_varchar2_list index by varchar2(4000 char); +-- type t_schema_paths is table of ut_varchar2_list index by varchar2(4000 char); + + type t_path_item is record ( + object_name varchar2(250), + procedure_name varchar2(250), + suite_path varchar2(4000) + ); + type t_path_items is table of t_path_item; + type t_schema_paths is table of t_path_items index by varchar2(250 char); ------------------ @@ -88,7 +96,7 @@ create or replace package body ut_suite_manager is l_result.suite_paths := g_schema_suites(a_schema_name).suite_paths; else ut_utils.debug_log('Rescanning schema ' || a_schema_name); - l_result := ut_suite_builder.build_schema_suites(a_schema_name); + l_result := ut_suite_builder.build_schema_suites_old(a_schema_name); update_cache(a_schema_name, l_result, get_schema_info(a_schema_name).obj_cnt ); end if; @@ -144,7 +152,7 @@ create or replace package body ut_suite_manager is end if; end; - function clean_paths(a_paths ut_varchar2_list) return ut_varchar2_list is + function trim_and_lower_paths( a_paths ut_varchar2_list) return ut_varchar2_list is l_paths_temp ut_varchar2_list := ut_varchar2_list(); begin l_paths_temp.extend(a_paths.count); @@ -160,7 +168,7 @@ create or replace package body ut_suite_manager is l_schema_names ut_varchar2_rows := ut_varchar2_rows(); c_current_schema constant all_tables.owner%type := sys_context('USERENV','CURRENT_SCHEMA'); begin - a_paths := set( clean_paths(a_paths) ); + a_paths := set( trim_and_lower_paths( a_paths) ); validate_paths(a_paths); @@ -310,29 +318,104 @@ create or replace package body ut_suite_manager is return l_path; end; +-- function group_paths_by_schema(a_paths ut_varchar2_list) return t_schema_paths is +-- l_result t_schema_paths; +-- l_schema varchar2(4000); +-- begin +-- for i in 1 .. a_paths.count loop +-- l_schema := upper(regexp_substr(a_paths(i),'^[^.:]+')); +-- if l_result.exists(l_schema) then +-- l_result(l_schema).extend; +-- l_result(l_schema)(l_result(l_schema).last) := a_paths(i); +-- else +-- l_result(l_schema) := ut_varchar2_list(a_paths(i)); +-- end if; +-- end loop; +-- return l_result; +-- end; +-- +-- function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items is +-- l_paths ut_varchar2_list := a_paths; +-- l_path varchar2(32767); +-- l_schema varchar2(4000); +-- l_suites_info t_schema_suites_info; +-- l_index varchar2(4000 char); +-- l_suite ut_logical_suite; +-- l_objects_to_run ut_suite_items; +-- l_schema_paths t_schema_paths; +-- begin +-- --resolve schema names from paths and group paths by schema name +-- resolve_schema_names(l_paths); +-- +-- l_schema_paths := group_paths_by_schema(l_paths); +-- +-- l_objects_to_run := ut_suite_items(); +-- +-- l_schema := l_schema_paths.first; +-- while l_schema is not null loop +-- l_paths := l_schema_paths(l_schema); +-- l_suites_info := get_schema_suites(l_schema); +-- +-- for i in 1 .. l_paths.count loop +-- l_path := l_paths(i); +-- --run whole schema +-- if regexp_like(l_path, '^[A-Za-z0-9$#_]+$') then +-- l_index := l_suites_info.schema_suites.first; +-- while l_index is not null loop +-- l_objects_to_run.extend; +-- l_objects_to_run(l_objects_to_run.count) := l_suites_info.schema_suites(l_index); +-- l_index := l_suites_info.schema_suites.next(l_index); +-- end loop; +-- else +-- l_suite := get_suite_filtered_by_path( convert_to_suite_path( l_path, l_suites_info.suite_paths ), l_suites_info.schema_suites ); +-- l_objects_to_run.extend; +-- l_objects_to_run(l_objects_to_run.count) := l_suite; +-- end if; +-- end loop; +-- l_schema := l_schema_paths.next(l_schema); +-- end loop; +-- +-- --propagate rollback type to suite items after organizing suites into hierarchy +-- for i in 1 .. l_objects_to_run.count loop +-- l_objects_to_run(i).set_rollback_type( l_objects_to_run(i).get_rollback_type() ); +-- end loop; +-- +-- return l_objects_to_run; +-- end configure_execution_by_path; + function group_paths_by_schema(a_paths ut_varchar2_list) return t_schema_paths is - l_result t_schema_paths; - l_schema varchar2(4000); + c_package_path_regex constant varchar2(100) := '^([A-Za-z0-9$#_]+)(\.([A-Za-z0-9$#_]+))?(\.([A-Za-z0-9$#_]+))?$'; + l_schema varchar2(4000); + l_empty_result t_path_item; + l_result t_path_item; + l_results t_schema_paths; begin for i in 1 .. a_paths.count loop - l_schema := upper(regexp_substr(a_paths(i),'^[^.:]+')); - if l_result.exists(l_schema) then - l_result(l_schema).extend; - l_result(l_schema)(l_result(l_schema).last) := a_paths(i); + l_result := l_empty_result; + if a_paths(i) like '%:%' then + l_schema := upper(regexp_substr(a_paths(i),'^[^.:]+')); + l_result.suite_path := ltrim(regexp_substr(a_paths(i),'[.:].*$'),':'); + else + l_schema := regexp_substr(a_paths(i), c_package_path_regex, subexpression => 1); + l_result.object_name := regexp_substr(a_paths(i), c_package_path_regex, subexpression => 3); + l_result.procedure_name := regexp_substr(a_paths(i), c_package_path_regex, subexpression => 5); + end if; + if l_results.exists(l_schema) then + l_results(l_schema).extend; + l_results(l_schema)(l_results(l_schema).last) := l_result; else - l_result(l_schema) := ut_varchar2_list(a_paths(i)); + l_results(l_schema) := t_path_items(l_result); end if; end loop; - return l_result; + return l_results; end; - function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items is l_paths ut_varchar2_list := a_paths; - l_path varchar2(32767); + l_path_items t_path_items; + l_path_item t_path_item; l_schema varchar2(4000); - l_suites_info t_schema_suites_info; + l_suites ut_suite_items; l_index varchar2(4000 char); - l_suite ut_logical_suite; l_objects_to_run ut_suite_items; l_schema_paths t_schema_paths; begin @@ -345,24 +428,24 @@ create or replace package body ut_suite_manager is l_schema := l_schema_paths.first; while l_schema is not null loop - l_paths := l_schema_paths(l_schema); - l_suites_info := get_schema_suites(l_schema); - - for i in 1 .. l_paths.count loop - l_path := l_paths(i); - --run whole schema - if regexp_like(l_path, '^[A-Za-z0-9$#_]+$') then - l_index := l_suites_info.schema_suites.first; - while l_index is not null loop - l_objects_to_run.extend; - l_objects_to_run(l_objects_to_run.count) := l_suites_info.schema_suites(l_index); - l_index := l_suites_info.schema_suites.next(l_index); - end loop; + l_path_items := l_schema_paths(l_schema); + for i in 1 .. l_path_items.count loop + l_path_item := l_path_items(i); + --whole schema + if l_path_item.object_name is null and l_path_item.suite_path is null then + l_suites := ut_suite_builder.build_schema_suites(upper(l_schema)); + --suite path + elsif l_path_item.suite_path is not null then + l_suites := ut_suite_builder.build_schema_suites(upper(l_schema), l_path_item.suite_path); else - l_suite := get_suite_filtered_by_path( convert_to_suite_path( l_path, l_suites_info.suite_paths ), l_suites_info.schema_suites ); - l_objects_to_run.extend; - l_objects_to_run(l_objects_to_run.count) := l_suite; + l_suites := ut_suite_builder.build_schema_suites(upper(l_schema), l_path_item.object_name, l_path_item.procedure_name); end if; + l_index := l_suites.first; + while l_index is not null loop + l_objects_to_run.extend; + l_objects_to_run(l_objects_to_run.count) := l_suites(l_index); + l_index := l_suites.next(l_index); + end loop; end loop; l_schema := l_schema_paths.next(l_schema); end loop; diff --git a/source/install.sql b/source/install.sql index 902b45aba..d71dcb1d1 100644 --- a/source/install.sql +++ b/source/install.sql @@ -70,6 +70,7 @@ alter session set current_schema = &&ut3_owner; @@install_component.sql 'core/types/ut_executable_test.tps' @@install_component.sql 'core/types/ut_test.tps' @@install_component.sql 'core/types/ut_logical_suite.tps' +@@install_component.sql 'core/types/ut_logical_suites.tps' @@install_component.sql 'core/types/ut_suite.tps' @@install_component.sql 'core/types/ut_suite_context.tps' @@install_component.sql 'core/types/ut_file_mapping.tps' @@ -109,6 +110,10 @@ alter session set current_schema = &&ut3_owner; @@install_component.sql 'core/annotations/ut_annotation_manager.pkb' --suite builder +@@install_component.sql 'core/ut_suite_cache_schema.sql' +@@install_component.sql 'core/ut_suite_cache.sql' +@@install_component.sql 'core/ut_suite_cache_manager.pks' +@@install_component.sql 'core/ut_suite_cache_manager.pkb' @@install_component.sql 'core/ut_suite_builder.pks' @@install_component.sql 'core/ut_suite_builder.pkb' --suite manager diff --git a/source/uninstall_objects.sql b/source/uninstall_objects.sql index cf8b3905f..754a16a34 100644 --- a/source/uninstall_objects.sql +++ b/source/uninstall_objects.sql @@ -55,6 +55,10 @@ drop package ut_suite_manager; drop package ut_suite_builder; +drop table ut_suite_cache; + +drop table ut_suite_cache_schema; + drop package ut; drop table ut_dbms_output_cache; diff --git a/test/core/expectations/test_expectations_cursor.pkb b/test/core/expectations/test_expectations_cursor.pkb index fb75b2da8..ac4fc9acf 100644 --- a/test/core/expectations/test_expectations_cursor.pkb +++ b/test/core/expectations/test_expectations_cursor.pkb @@ -1814,13 +1814,13 @@ Diff:% l_expected_message varchar2(32767); l_actual_message varchar2(32767); begin - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', SYSDATE, ut3.ut_annotations(ut3.ut_annotation(1,'test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) into l_actual_tab from dual; - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', SYSDATE, ut3.ut_annotations(ut3.ut_annotation(1,'test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) @@ -1846,13 +1846,13 @@ Diff:% l_expected_message varchar2(32767); l_actual_message varchar2(32767); begin - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', SYSDATE, ut3.ut_annotations(ut3.ut_annotation(1,'test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) into l_actual_tab from dual; - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', SYSDATE, ut3.ut_annotations(ut3.ut_annotation(1,'test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) @@ -1878,13 +1878,13 @@ Diff:% l_expected_message varchar2(32767); l_actual_message varchar2(32767); begin - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', SYSDATE, ut3.ut_annotations(ut3.ut_annotation(1,'test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) into l_actual_tab from dual; - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', SYSDATE, ut3.ut_annotations(ut3.ut_annotation(1,'test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) @@ -1909,15 +1909,16 @@ Diff:% l_expected_tab ut3.ut_annotated_object; l_expected_message varchar2(32767); l_actual_message varchar2(32767); + l_date date := sysdate; begin - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', l_date, ut3.ut_annotations(ut3.ut_annotation(1,'test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) into l_actual_tab from dual; - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', l_date, ut3.ut_annotations(ut3.ut_annotation(1,'1test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) @@ -1938,8 +1939,8 @@ Diff:% l_expected_message := q'[%Actual: refcursor [ count = 1 ] was expected to equal: refcursor [ count = 1 ] %Diff: %Rows: [ 1 differences ] -%PK TEST - Actual: TESTTESTTEST1testtesttest2testtesttest% -%PK TEST - Expected: TESTTESTTEST11testtesttest2testtesttest%]'; +%PK TEST - Actual: TESTTESTTEST%1testtesttest2testtesttest% +%PK TEST - Expected: TESTTESTTEST%11testtesttest2testtesttest%]'; l_actual_message := ut3.ut_expectation_processor.get_failed_expectations()(1).message; --Assert ut.expect(l_actual_message).to_be_like(l_expected_message); @@ -1954,13 +1955,13 @@ Diff:% l_expected_message varchar2(32767); l_actual_message varchar2(32767); begin - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', SYSDATE, ut3.ut_annotations(ut3.ut_annotation(1,'1test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) into l_actual_tab from dual; - select ut3.ut_annotated_object('TEST','TEST','TEST', + select ut3.ut_annotated_object('TEST','TEST','TEST', SYSDATE, ut3.ut_annotations(ut3.ut_annotation(1,'test','test','test'), ut3.ut_annotation(2,'test','test','test')) ) diff --git a/test/core/test_suite_builder.pkb b/test/core/test_suite_builder.pkb index 19ea81aa0..3216da333 100644 --- a/test/core/test_suite_builder.pkb +++ b/test/core/test_suite_builder.pkb @@ -11,7 +11,7 @@ create or replace package body test_suite_builder is begin open l_cursor for select value(x) from table( ut3.ut_annotated_objects( - ut3.ut_annotated_object('UT3_TESTER', a_package_name, 'PACKAGE', a_annotations) + ut3.ut_annotated_object('UT3_TESTER', a_package_name, 'PACKAGE', SYSDATE, a_annotations) ) ) x; l_suites := ut3.ut_suite_builder.build_suites(l_cursor).schema_suites; l_suite := l_suites(l_suites.first); @@ -843,6 +843,61 @@ create or replace package body test_suite_builder is ); end; + --%test(Gives warning when two contexts have the same name) + procedure duplicate_context_name is + l_actual clob; + l_annotations ut3.ut_annotations; + begin + --Arrange + l_annotations := ut3.ut_annotations( + ut3.ut_annotation(1, 'suite','Cool', null), + ut3.ut_annotation(2, 'beforeall',null, 'suite_level_beforeall'), + ut3.ut_annotation(3, 'test','In suite', 'suite_level_test'), + ut3.ut_annotation(4, 'context','a_context', null), + ut3.ut_annotation(5, 'displayname','A context', null), + ut3.ut_annotation(6, 'beforeall',null, 'context_setup'), + ut3.ut_annotation(7, 'test', 'In context', 'test_in_a_context'), + ut3.ut_annotation(8, 'endcontext',null, null), + ut3.ut_annotation(9, 'context','a_context', null), + ut3.ut_annotation(10, 'displayname','A context', null), + ut3.ut_annotation(11, 'beforeall',null, 'setup_in_duplicated_context'), + ut3.ut_annotation(12, 'test', 'In duplicated context', 'test_in_duplicated_context'), + ut3.ut_annotation(13, 'endcontext',null, null) + ); + --Act + l_actual := invoke_builder_for_annotations(l_annotations, 'SOME_PACKAGE'); + --Assert + ut.expect(l_actual).to_be_like( + '%Context name must be unique in a suite. Context and all of it's content ignored.%at "UT3_TESTER.SOME_PACKAGE", line 9%' + ,'\' + ); + ut.expect(l_actual).to_be_like( + '' || + '%' || + '' || + '%a_contextA contextsome_package.a_context' || + '%' || + '' || + '%test_in_a_contextIn contextsome_package.a_context.test_in_a_context' || + '%' || + '' || + '' || + '%some_packagecontext_setup' || + '%' || + '' || + '' || + '' || + '%suite_level_testIn suitesome_package.suite_level_test' || + '%' || + '' || + '' || + '%some_packagesuite_level_beforeall' || + '%' || + '' || + '' + ); + end; + procedure throws_value_empty is l_actual clob; l_annotations ut3.ut_annotations; diff --git a/test/core/test_suite_builder.pks b/test/core/test_suite_builder.pks index 36517432b..21ca58206 100644 --- a/test/core/test_suite_builder.pks +++ b/test/core/test_suite_builder.pks @@ -39,6 +39,9 @@ create or replace package test_suite_builder is --%test(Gives warning if more than one --%test annotation used) procedure test_annot_duplicated; + --%test(Is added to suite according to annotation order in package spec) + procedure test_annotation_ordering; + --%endcontext --%context(suitepath) @@ -125,6 +128,9 @@ create or replace package test_suite_builder is --%test(Gives warning if --%endcontext is missing a preceding --%context) procedure endcontext_without_context; + --%test(Gives warning when two contexts have the same name and ignores duplicated context) + procedure duplicate_context_name; + --%endcontext --%context(throws) @@ -155,14 +161,6 @@ create or replace package test_suite_builder is --%endcontext - --%context(test) - --%displayname(--%test annontation) - - --%test(Is added to suite according to annotation order in package spec) - procedure test_annotation_ordering; - - --%endcontext - --%context(unknown_annotation) --%displayname(--%bad_annotation) diff --git a/test/core/test_ut_executable.pkb b/test/core/test_ut_executable.pkb index 2d4cde518..d09a25a6d 100644 --- a/test/core/test_ut_executable.pkb +++ b/test/core/test_ut_executable.pkb @@ -8,7 +8,7 @@ create or replace package body test_ut_executable is l_result boolean; begin --Arrange - l_test := ut3.ut_test(a_object_name => 'test_ut_executable',a_name => 'test_ut_executable'); + l_test := ut3.ut_test(a_object_name => 'test_ut_executable',a_name => 'test_ut_executable', a_line_no=> 1); l_executable := ut3.ut_executable_test( null, 'test_ut_executable', 'passing_proc', ut3.ut_utils.gc_test_execute ); --Act l_result := l_executable.do_execute(l_test); @@ -24,7 +24,7 @@ create or replace package body test_ut_executable is l_result boolean; begin --Arrange - l_test := ut3.ut_test(a_object_name => 'test_ut_executable',a_name => 'test_ut_executable'); + l_test := ut3.ut_test(a_object_name => 'test_ut_executable',a_name => 'test_ut_executable', a_line_no=> 1); l_executable := ut3.ut_executable_test( user, 'test_ut_executable', 'output_proc', ut3.ut_utils.gc_test_execute ); --Act l_result := l_executable.do_execute(l_test); @@ -40,7 +40,7 @@ create or replace package body test_ut_executable is l_result boolean; begin --Arrange - l_test := ut3.ut_test(a_object_name => 'test_ut_executable',a_name => 'test_ut_executable'); + l_test := ut3.ut_test(a_object_name => 'test_ut_executable',a_name => 'test_ut_executable', a_line_no=> 1); l_executable := ut3.ut_executable_test( user, 'test_ut_executable', 'throwing_proc', ut3.ut_utils.gc_test_execute ); --Act l_result := l_executable.do_execute(l_test); @@ -80,10 +80,10 @@ create or replace package body test_ut_executable is procedure form_name is begin - ut.expect(ut3.ut_executable_test( user, 'package', 'proc', null ).form_name()).to_equal(user||'.package.proc'); - ut.expect(ut3.ut_executable_test( null, 'package', 'proc', null ).form_name()).to_equal('package.proc'); + ut.expect(ut3.ut_executable_test( user, ' package ', 'proc', null ).form_name()).to_equal(user||'.package.proc'); + ut.expect(ut3.ut_executable_test( null, 'package', ' proc ', null ).form_name()).to_equal('package.proc'); ut.expect(ut3.ut_executable_test( null, 'proc', null, null ).form_name()).to_equal('proc'); - ut.expect(ut3.ut_executable_test( user, 'proc', null, null ).form_name()).to_equal(user||'.proc'); + ut.expect(ut3.ut_executable_test( ' '||user||' ', 'proc', null, null ).form_name()).to_equal(user||'.proc'); end; procedure passing_proc is diff --git a/test/core/test_ut_suite.pkb b/test/core/test_ut_suite.pkb index c66e25af3..9955aa048 100644 --- a/test/core/test_ut_suite.pkb +++ b/test/core/test_ut_suite.pkb @@ -9,13 +9,13 @@ create or replace package body test_ut_suite is l_suite ut3.ut_suite; begin --Arrange - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS', a_line_no=> 1); l_suite.path := 'ut_example_tests'; l_suite.disabled_flag := ut3.ut_utils.boolean_to_int(true); l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'set_g_number_0', ut3.ut_utils.gc_before_all)); l_suite.after_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_before_all)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number')); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number')); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); --Act l_suite.do_execute(); --Assert @@ -32,10 +32,10 @@ create or replace package body test_ut_suite is l_suite ut3.ut_suite; begin --Arrange - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS', a_line_no=> 1); l_suite.path := 'ut_example_tests'; l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_before_all)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'set_g_number_0')); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'set_g_number_0', a_line_no=> 1)); --Act l_suite.do_execute(); --Assert @@ -52,12 +52,12 @@ create or replace package body test_ut_suite is l_suite ut3.ut_suite; begin --Arrange - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS', a_line_no=> 1); l_suite.path := 'ut_example_tests'; l_suite.after_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_after_all)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'set_g_number_0')); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number')); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'set_g_number_0', a_line_no=> 1)); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); --Act l_suite.do_execute(); --Assert @@ -73,9 +73,9 @@ create or replace package body test_ut_suite is procedure package_without_body is l_suite ut3.ut_suite; begin - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_WITHOUT_BODY'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_WITHOUT_BODY', a_line_no=> 1); l_suite.path := 'UT_WITHOUT_BODY'; - l_suite.add_item(ut3.ut_test(a_object_name => 'ut_without_body',a_name => 'test1'/*, a_rollback_type => ut3.ut_utils.gc_rollback_auto*/)); + l_suite.add_item(ut3.ut_test(a_object_name => 'ut_without_body',a_name => 'test1', a_line_no=> 1)); --Act l_suite.do_execute(); --Assert @@ -85,9 +85,9 @@ create or replace package body test_ut_suite is procedure package_with_invalid_body is l_suite ut3.ut_suite; begin - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_WITH_INVALID_BODY'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_WITH_INVALID_BODY', a_line_no=> 1); l_suite.path := 'UT_WITH_INVALID_BODY'; - l_suite.add_item(ut3.ut_test(a_object_name => 'ut_with_invalid_body',a_name => 'test1'/*, a_rollback_type => ut3.ut_utils.gc_rollback_auto*/)); + l_suite.add_item(ut3.ut_test(a_object_name => 'ut_with_invalid_body',a_name => 'test1', a_line_no=> 1)); --Act l_suite.do_execute(); --Assert @@ -99,10 +99,10 @@ create or replace package body test_ut_suite is begin --Arrange execute immediate 'delete from ut$test_table'; - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_TRANSACTION_CONTROL'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_TRANSACTION_CONTROL', a_line_no=> 1); l_suite.path := 'ut_transaction_control'; l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_TRANSACTION_CONTROL', 'setup', ut3.ut_utils.gc_before_all)); - l_suite.add_item(ut3.ut_test(a_object_owner => USER, a_object_name => 'ut_transaction_control',a_name => a_procedure_name)); + l_suite.add_item(ut3.ut_test(a_object_owner => USER, a_object_name => 'ut_transaction_control',a_name => a_procedure_name, a_line_no=> 1)); l_suite.set_rollback_type(a_rollback_type); --Act diff --git a/test/core/test_ut_test.pkb b/test/core/test_ut_test.pkb index ecce27c3c..857ef5e99 100644 --- a/test/core/test_ut_test.pkb +++ b/test/core/test_ut_test.pkb @@ -10,12 +10,12 @@ create or replace package body test_ut_test is l_test ut3.ut_test; begin --Arrange - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS', a_line_no=> 1); l_suite.path := 'ut_example_tests'; l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'set_g_number_0', ut3.ut_utils.gc_before_all)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number')); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number')); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 2)); l_suite.items(l_suite.items.last).disabled_flag := ut3.ut_utils.boolean_to_int(true); --Act l_suite.do_execute(); @@ -34,15 +34,15 @@ create or replace package body test_ut_test is l_test ut3.ut_test; begin --Arrange - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS', a_line_no=> 1); l_suite.path := 'ut_example_tests'; l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'set_g_number_0', ut3.ut_utils.gc_before_all)); - l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number'); + l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); l_test.before_test_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_before_test)); l_test.after_test_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_after_test)); l_suite.add_item(l_test); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number')); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); --Act l_suite.do_execute(); --Assert @@ -60,13 +60,13 @@ create or replace package body test_ut_test is l_test ut3.ut_test; begin --Arrange - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS', a_line_no=> 1); l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'set_g_number_0', ut3.ut_utils.gc_before_all)); - l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number'); + l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); l_test.before_each_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_before_each)); l_test.after_each_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_after_each)); l_suite.add_item(l_test); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number')); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); --Act l_suite.do_execute(); --Assert @@ -84,13 +84,13 @@ create or replace package body test_ut_test is l_test ut3.ut_test; begin --Arrange - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS', a_line_no=> 1); l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'set_g_number_0', ut3.ut_utils.gc_before_all)); - l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number'); + l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); l_test.before_test_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_before_test)); l_test.after_test_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_after_test)); l_suite.add_item(l_test); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number')); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); --Act l_suite.do_execute(); --Assert @@ -108,13 +108,13 @@ create or replace package body test_ut_test is l_test ut3.ut_test; begin --Arrange - l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS'); + l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS', a_line_no=> 1); l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'set_g_number_0', ut3.ut_utils.gc_before_all)); - l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number'); + l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); l_test.before_each_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_before_each)); l_test.after_each_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_after_each)); l_suite.add_item(l_test); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number')); + l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); --Act l_suite.do_execute(); --Assert From f475b7cfea9d7e080b937c31ef88c9c2074ea566 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 2 Nov 2018 02:18:46 +0000 Subject: [PATCH 073/115] Added `suite_cache`. Refactored lots of code for suite parsing/building. (Acceptance) tests need rework due to changes in test execution ordering. --- .../core/annotations/ut_annotated_object.tps | 2 +- .../annotations/ut_annotation_cache_info.sql | 2 +- .../ut_annotation_cache_manager.pkb | 14 +- .../ut_annotation_cache_manager.pks | 2 +- .../annotations/ut_annotation_manager.pkb | 38 +- .../annotations/ut_annotation_manager.pks | 2 +- source/core/types/ut_logical_suite.tpb | 24 +- source/core/types/ut_logical_suite.tps | 7 +- source/core/types/ut_run.tpb | 10 + source/core/types/ut_run.tps | 6 + source/core/types/ut_suite_item.tps | 8 +- source/core/types/ut_test.tpb | 10 + source/core/types/ut_test.tps | 6 + source/core/ut_suite_builder.pkb | 597 ++++++------------ source/core/ut_suite_builder.pks | 62 +- source/core/ut_suite_cache.sql | 4 +- source/core/ut_suite_cache_manager.pkb | 329 ++++------ source/core/ut_suite_cache_manager.pks | 16 +- source/core/ut_suite_cache_schema.sql | 2 +- source/core/ut_suite_manager.pkb | 286 +-------- test/core/test_suite_builder.pkb | 20 +- 21 files changed, 463 insertions(+), 984 deletions(-) diff --git a/source/core/annotations/ut_annotated_object.tps b/source/core/annotations/ut_annotated_object.tps index e78a2a282..1bfefed69 100644 --- a/source/core/annotations/ut_annotated_object.tps +++ b/source/core/annotations/ut_annotated_object.tps @@ -18,7 +18,7 @@ create type ut_annotated_object as object( object_owner varchar2(250), object_name varchar2(250), object_type varchar2(50), - parse_time date, + parse_time timestamp, annotations ut_annotations ) / diff --git a/source/core/annotations/ut_annotation_cache_info.sql b/source/core/annotations/ut_annotation_cache_info.sql index 48f8a606c..fa7eabeec 100644 --- a/source/core/annotations/ut_annotation_cache_info.sql +++ b/source/core/annotations/ut_annotation_cache_info.sql @@ -16,7 +16,7 @@ create table ut_annotation_cache_info ( object_owner varchar2(250) not null, object_name varchar2(250) not null, object_type varchar2(250) not null, - parse_time date not null, + parse_time timestamp not null, constraint ut_annotation_cache_info_pk primary key(cache_id), constraint ut_annotation_cache_info_uk unique (object_owner, object_name, object_type) ) organization index; diff --git a/source/core/annotations/ut_annotation_cache_manager.pkb b/source/core/annotations/ut_annotation_cache_manager.pkb index e9d60730b..c54d7eec3 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pkb +++ b/source/core/annotations/ut_annotation_cache_manager.pkb @@ -22,14 +22,14 @@ create or replace package body ut_annotation_cache_manager as pragma autonomous_transaction; begin update ut_annotation_cache_info i - set i.parse_time = sysdate + set i.parse_time = systimestamp where (i.object_owner, i.object_name, i.object_type) in ((a_object.object_owner, a_object.object_name, a_object.object_type)) returning cache_id into l_cache_id; if sql%rowcount = 0 then insert into ut_annotation_cache_info (cache_id, object_owner, object_name, object_type, parse_time) - values (ut_annotation_cache_seq.nextval, a_object.object_owner, a_object.object_name, a_object.object_type, sysdate) + values (ut_annotation_cache_seq.nextval, a_object.object_owner, a_object.object_name, a_object.object_type, systimestamp) returning cache_id into l_cache_id; end if; @@ -66,15 +66,15 @@ create or replace package body ut_annotation_cache_manager as on (o.object_name = i.object_name and o.object_type = i.object_type and o.object_owner = i.object_owner) - when matched then update set parse_time = sysdate + when matched then update set parse_time = systimestamp when not matched then insert (cache_id, object_owner, object_name, object_type, parse_time) - values (ut_annotation_cache_seq.nextval, o.object_owner, o.object_name, o.object_type, sysdate); + values (ut_annotation_cache_seq.nextval, o.object_owner, o.object_name, o.object_type, systimestamp); commit; end; - function get_annotations_for_objects(a_cached_objects ut_annotation_objs_cache_info, a_parse_date date) return sys_refcursor is + function get_annotations_for_objects(a_cached_objects ut_annotation_objs_cache_info, a_parse_time timestamp) return sys_refcursor is l_results sys_refcursor; begin open l_results for q'[ @@ -92,9 +92,9 @@ create or replace package body ut_annotation_cache_manager as join ut_annotation_cache_info i on o.object_owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type join ut_annotation_cache c on i.cache_id = c.cache_id - where ]'|| case when a_parse_date is null then ':a_parse_date is null' else 'i.parse_time > :a_parse_date' end ||q'[ + where ]'|| case when a_parse_time is null then ':a_parse_date is null' else 'i.parse_time > :a_parse_time' end ||q'[ group by i.object_owner, i.object_name, i.object_type, i.parse_time]' - using a_cached_objects, a_parse_date; + using a_cached_objects, a_parse_time; return l_results; end; diff --git a/source/core/annotations/ut_annotation_cache_manager.pks b/source/core/annotations/ut_annotation_cache_manager.pks index 7663fdc33..2ee586d12 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pks +++ b/source/core/annotations/ut_annotation_cache_manager.pks @@ -32,7 +32,7 @@ create or replace package ut_annotation_cache_manager authid definer as * * @param a_cached_objects a `ut_annotation_objs_cache_info` list with information about objects to get from cache */ - function get_annotations_for_objects(a_cached_objects ut_annotation_objs_cache_info, a_parse_date date) return sys_refcursor; + function get_annotations_for_objects(a_cached_objects ut_annotation_objs_cache_info, a_parse_time timestamp) return sys_refcursor; /** * Removes cached information about annotations for objects on the list and updates parse_time in cache info table. diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb index 7c299b766..9ad1a9e79 100644 --- a/source/core/annotations/ut_annotation_manager.pkb +++ b/source/core/annotations/ut_annotation_manager.pkb @@ -19,7 +19,7 @@ create or replace package body ut_annotation_manager as ------------------------------ --private definitions - function get_annotation_objs_info(a_object_owner varchar2, a_object_type varchar2, a_parse_date date := null) return ut_annotation_objs_cache_info is + function get_annotation_objs_info(a_object_owner varchar2, a_object_type varchar2, a_parse_date timestamp := null) return ut_annotation_objs_cache_info is l_rows sys_refcursor; l_ut_owner varchar2(250) := ut_utils.ut_owner; l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); @@ -31,7 +31,7 @@ create or replace package body ut_annotation_manager as object_owner => o.owner, object_name => o.object_name, object_type => o.object_type, - needs_refresh => case when o.last_ddl_time < i.parse_time then 'N' else 'Y' end + needs_refresh => case when o.last_ddl_time < cast(i.parse_time as date) then 'N' else 'Y' end ) from ]'||l_objects_view||q'[ o left join ]'||l_ut_owner||q'[.ut_annotation_cache_info i @@ -44,7 +44,7 @@ create or replace package body ut_annotation_manager as || case when a_parse_date is null then ':a_parse_date is null' - else 'o.last_ddl_time > :a_parse_date' + else 'o.last_ddl_time > cast(:a_parse_date as date)' end; open l_rows for l_cursor_text using a_object_owner, a_object_type, a_parse_date; fetch l_rows bulk collect into l_result limit 1000000; @@ -148,37 +148,17 @@ create or replace package body ut_annotation_manager as procedure rebuild_annotation_cache( a_object_owner varchar2, a_object_type varchar2, a_info_rows ut_annotation_objs_cache_info) is - l_objects_in_cache_count integer; l_objects_to_parse ut_annotation_objs_cache_info := ut_annotation_objs_cache_info(); begin - --get list of objects in cache - select count(1) into l_objects_in_cache_count - from table(a_info_rows) x where x.needs_refresh = 'N'; - - --if cache is empty and there are objects to parse - if l_objects_in_cache_count = 0 and a_info_rows.count > 0 then + select value(x)bulk collect into l_objects_to_parse from table(a_info_rows) x where x.needs_refresh = 'Y'; + --if some source needs parsing and putting into cache + if l_objects_to_parse.count > 0 then build_annot_cache_for_sources( a_object_owner, a_object_type, - --all schema objects - get_sources_to_annotate(a_object_owner, a_object_type), - a_info_rows + get_sources_to_annotate(a_object_owner, a_object_type, l_objects_to_parse), + l_objects_to_parse ); - - --if not all in cache, get list of objects to rebuild cache for - elsif l_objects_in_cache_count < a_info_rows.count then - - select value(x)bulk collect into l_objects_to_parse from table(a_info_rows) x where x.needs_refresh = 'Y'; - - --if some source needs parsing and putting into cache - if l_objects_to_parse.count > 0 then - build_annot_cache_for_sources( - a_object_owner, a_object_type, - get_sources_to_annotate(a_object_owner, a_object_type, l_objects_to_parse), - l_objects_to_parse - ); - end if; - end if; end; @@ -194,7 +174,7 @@ create or replace package body ut_annotation_manager as ); end; - function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_parse_date date := null) return ut_annotated_objects pipelined is + function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_parse_date timestamp := null) return ut_annotated_objects pipelined is l_info_rows ut_annotation_objs_cache_info; l_cursor sys_refcursor; l_results ut_annotated_objects; diff --git a/source/core/annotations/ut_annotation_manager.pks b/source/core/annotations/ut_annotation_manager.pks index f0468ccd5..829142bd5 100644 --- a/source/core/annotations/ut_annotation_manager.pks +++ b/source/core/annotations/ut_annotation_manager.pks @@ -30,7 +30,7 @@ create or replace package ut_annotation_manager authid current_user as * @param a_parse_date date when object was last parsed * @return array containing annotated objects along with annotations for each object (nested) */ - function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_parse_date date := null) return ut_annotated_objects pipelined; + function get_annotated_objects(a_object_owner varchar2, a_object_type varchar2, a_parse_date timestamp := null) return ut_annotated_objects pipelined; /** * Rebuilds annotation cache for a specified schema and object type. diff --git a/source/core/types/ut_logical_suite.tpb b/source/core/types/ut_logical_suite.tpb index 1acfc776c..70e0ca462 100644 --- a/source/core/types/ut_logical_suite.tpb +++ b/source/core/types/ut_logical_suite.tpb @@ -21,7 +21,7 @@ create or replace type body ut_logical_suite as ) return self as result is begin self.self_type := $$plsql_unit; - self.init(a_object_owner, a_object_name, a_name, 0); + self.init(a_object_owner, a_object_name, a_name, null); self.path := a_path; self.disabled_flag := ut_utils.boolean_to_int(false); self.items := ut_suite_items(); @@ -33,10 +33,26 @@ create or replace type body ut_logical_suite as return true; end; - member procedure add_item(self in out nocopy ut_logical_suite, a_item ut_suite_item) is + overriding member procedure add_item( + self in out nocopy ut_logical_suite, + a_item ut_suite_item, + a_expected_level integer := 1, + a_current_level integer :=1 + ) is begin - self.items.extend; - self.items(self.items.last) := a_item; + if a_expected_level > a_current_level then + if self.items.last is not null then + self.items(self.items.last).add_item(a_item, a_expected_level, a_current_level+1); + else + raise_application_error(-20000, 'cannot add suite item to sub suite at level '||a_expected_level||'. suite items at level '||a_current_level||' are empty'); + end if; + else + if self.items is null then + self.items := ut_suite_items(); + end if; + self.items.extend; + self.items(self.items.last) := a_item; + end if; end; overriding member procedure mark_as_skipped(self in out nocopy ut_logical_suite) is diff --git a/source/core/types/ut_logical_suite.tps b/source/core/types/ut_logical_suite.tps index 85bb80870..2672cacd3 100644 --- a/source/core/types/ut_logical_suite.tps +++ b/source/core/types/ut_logical_suite.tps @@ -25,7 +25,12 @@ create or replace type ut_logical_suite under ut_suite_item ( self in out nocopy ut_logical_suite, a_object_owner varchar2, a_object_name varchar2, a_name varchar2, a_path varchar2 ) return self as result, member function is_valid(self in out nocopy ut_logical_suite) return boolean, - member procedure add_item(self in out nocopy ut_logical_suite, a_item ut_suite_item), + overriding member procedure add_item( + self in out nocopy ut_logical_suite, + a_item ut_suite_item, + a_expected_level integer := 1, + a_current_level integer :=1 + ), overriding member procedure mark_as_skipped(self in out nocopy ut_logical_suite), overriding member procedure set_rollback_type(self in out nocopy ut_logical_suite, a_rollback_type integer), overriding member function do_execute(self in out nocopy ut_logical_suite) return boolean, diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb index 0db9f38c0..f7756cf37 100644 --- a/source/core/types/ut_run.tpb +++ b/source/core/types/ut_run.tpb @@ -51,6 +51,16 @@ create or replace type body ut_run as null; end; + overriding member procedure add_item( + self in out nocopy ut_run, + a_item ut_suite_item, + a_expected_level integer := 1, + a_current_level integer :=1 + ) is + begin + raise_application_error(-20000, 'Cannot add a suite item to ut_run'); + end; + overriding member function do_execute(self in out nocopy ut_run) return boolean is l_completed_without_errors boolean; begin diff --git a/source/core/types/ut_run.tps b/source/core/types/ut_run.tps index 5dc8e0399..3807a2a75 100644 --- a/source/core/types/ut_run.tps +++ b/source/core/types/ut_run.tps @@ -36,6 +36,12 @@ create or replace type ut_run under ut_suite_item ( a_client_character_set varchar2 := null ) return self as result, overriding member procedure mark_as_skipped(self in out nocopy ut_run), + overriding member procedure add_item( + self in out nocopy ut_run, + a_item ut_suite_item, + a_expected_level integer := 1, + a_current_level integer :=1 + ), overriding member function do_execute(self in out nocopy ut_run) return boolean, overriding member procedure calc_execution_result(self in out nocopy ut_run), overriding member procedure mark_as_errored(self in out nocopy ut_run, a_error_stack_trace varchar2), diff --git a/source/core/types/ut_suite_item.tps b/source/core/types/ut_suite_item.tps index 0f08263c4..927ad3807 100644 --- a/source/core/types/ut_suite_item.tps +++ b/source/core/types/ut_suite_item.tps @@ -52,7 +52,7 @@ create or replace type ut_suite_item force under ut_event_item ( /** * Time when the suite item was last parsed from package source */ - parse_time date, + parse_time timestamp, --execution result fields start_time timestamp with time zone, end_time timestamp with time zone, @@ -63,6 +63,12 @@ create or replace type ut_suite_item force under ut_event_item ( member procedure init(self in out nocopy ut_suite_item, a_object_owner varchar2, a_object_name varchar2, a_name varchar2, a_line_no integer), member function get_disabled_flag return boolean, not instantiable member procedure mark_as_skipped(self in out nocopy ut_suite_item), + not instantiable member procedure add_item( + self in out nocopy ut_suite_item, + a_item ut_suite_item, + a_expected_level integer := 1, + a_current_level integer :=1 + ), member procedure set_rollback_type(self in out nocopy ut_suite_item, a_rollback_type integer), member function get_rollback_type return integer, member function create_savepoint_if_needed return varchar2, diff --git a/source/core/types/ut_test.tpb b/source/core/types/ut_test.tpb index ed9692e14..d68b19a87 100644 --- a/source/core/types/ut_test.tpb +++ b/source/core/types/ut_test.tpb @@ -34,6 +34,16 @@ create or replace type body ut_test as return; end; + overriding member procedure add_item( + self in out nocopy ut_test, + a_item ut_suite_item, + a_expected_level integer := 1, + a_current_level integer :=1 + ) is + begin + raise_application_error(-20000, 'Cannot add a suite item to ut_test'); + end; + overriding member procedure mark_as_skipped(self in out nocopy ut_test) is begin ut_event_manager.trigger_event(ut_utils.gc_before_test, self); diff --git a/source/core/types/ut_test.tps b/source/core/types/ut_test.tps index 752ef3ef7..9e26508e4 100644 --- a/source/core/types/ut_test.tps +++ b/source/core/types/ut_test.tps @@ -60,6 +60,12 @@ create or replace type ut_test under ut_suite_item ( a_line_no integer, a_expected_error_codes ut_integer_list := null ) return self as result, overriding member procedure mark_as_skipped(self in out nocopy ut_test), + overriding member procedure add_item( + self in out nocopy ut_test, + a_item ut_suite_item, + a_expected_level integer := 1, + a_current_level integer :=1 + ), overriding member function do_execute(self in out nocopy ut_test) return boolean, overriding member procedure calc_execution_result(self in out nocopy ut_test), overriding member procedure mark_as_errored(self in out nocopy ut_test, a_error_stack_trace varchar2), diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index ce269280a..21e784f7e 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -92,7 +92,7 @@ create or replace package body ut_suite_builder is type t_annotations_info is record ( owner t_object_name, name t_object_name, - parse_time date, + parse_time timestamp, by_line tt_annotations_by_line, by_proc tt_annotations_by_proc, by_name tt_annotations_by_name @@ -121,6 +121,15 @@ create or replace package body ut_suite_builder is a_annotations.by_line.delete(a_start_pos, a_end_pos); end; + + procedure add_items_to_list(a_list in out nocopy ut_suite_items, a_items ut_suite_items) is + begin + for i in 1 .. a_items.count loop + a_list.extend(); + a_list(a_list.last) := a_items(i); + end loop; + end; + ----------------------------------------------- -- Processing annotations ----------------------------------------------- @@ -429,13 +438,12 @@ create or replace package body ut_suite_builder is procedure add_test( a_suite in out nocopy ut_suite, - a_tests in out nocopy tt_tests, + a_suite_items in out nocopy ut_suite_items, a_procedure_name t_object_name, a_annotations t_annotations_info ) is l_test ut_test; l_annotation_texts tt_annotation_texts; - l_annotation_pos binary_integer; l_proc_annotations tt_annotations_by_name := a_annotations.by_proc(a_procedure_name); begin if not l_proc_annotations.exists(gc_test) then @@ -488,10 +496,11 @@ create or replace package body ut_suite_builder is end if; l_test.disabled_flag := ut_utils.boolean_to_int( l_proc_annotations.exists( gc_disabled)); - a_tests( l_proc_annotations( gc_test).first) := l_test; + a_suite_items.extend; + a_suite_items( a_suite_items.last ) := l_test; end; - procedure update_before_after_each( + procedure propagate_before_after_each( a_suite in out nocopy ut_logical_suite, a_before_each_list tt_executables, a_after_each_list tt_executables @@ -508,14 +517,14 @@ create or replace package body ut_suite_builder is a_suite.items(i) := l_test; elsif a_suite.items(i) is of (ut_logical_suite) then l_context := treat(a_suite.items(i) as ut_logical_suite); - update_before_after_each(l_context, a_before_each_list, a_after_each_list); + propagate_before_after_each( l_context, a_before_each_list, a_after_each_list); a_suite.items(i) := l_context; end if; end loop; end if; end; - procedure update_before_after_each( + procedure propagate_before_after_each( a_suite_items in out nocopy ut_suite_items, a_before_each_list tt_executables, a_after_each_list tt_executables @@ -532,7 +541,7 @@ create or replace package body ut_suite_builder is a_suite_items(i) := l_test; elsif a_suite_items(i) is of (ut_logical_suite) then l_context := treat(a_suite_items(i) as ut_logical_suite); - update_before_after_each(l_context.items, a_before_each_list, a_after_each_list); + propagate_before_after_each( l_context.items, a_before_each_list, a_after_each_list); a_suite_items(i) := l_context; end if; end loop; @@ -554,9 +563,10 @@ create or replace package body ut_suite_builder is end if; end; - procedure add_annotated_procedures( + procedure get_annotated_procedures( a_proc_annotations t_annotations_info, a_suite in out nocopy ut_suite, + a_suite_items in out nocopy ut_suite_items, a_before_each_list in out nocopy tt_executables, a_after_each_list in out nocopy tt_executables, a_before_all_list in out nocopy tt_executables, @@ -564,41 +574,17 @@ create or replace package body ut_suite_builder is ) is l_procedure_name t_object_name; l_tests tt_tests; - begin - l_procedure_name := a_proc_annotations.by_proc.first; - while l_procedure_name is not null loop - add_test( a_suite, l_tests, l_procedure_name, a_proc_annotations ); - process_before_after_annot(a_before_each_list, gc_beforeeach, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); - process_before_after_annot(a_after_each_list, gc_aftereach, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); - process_before_after_annot(a_before_all_list, gc_beforeall, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); - process_before_after_annot(a_after_all_list, gc_afterall, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); - l_procedure_name := a_proc_annotations.by_proc.next( l_procedure_name ); - end loop; - a_suite.items := a_suite.items multiset union all convert_list(l_tests); - end; - - function get_annotated_procedures( - a_proc_annotations t_annotations_info, - a_suite in out nocopy ut_suite, - a_before_each_list in out nocopy tt_executables, - a_after_each_list in out nocopy tt_executables, - a_before_all_list in out nocopy tt_executables, - a_after_all_list in out nocopy tt_executables - ) return ut_suite_items is - l_procedure_name t_object_name; - l_tests tt_tests; begin l_procedure_name := a_proc_annotations.by_proc.first; while l_procedure_name is not null loop - add_test( a_suite, l_tests, l_procedure_name, a_proc_annotations ); + add_test( a_suite, a_suite_items, l_procedure_name, a_proc_annotations ); process_before_after_annot(a_before_each_list, gc_beforeeach, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); process_before_after_annot(a_after_each_list, gc_aftereach, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); process_before_after_annot(a_before_all_list, gc_beforeall, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); process_before_after_annot(a_after_all_list, gc_afterall, l_procedure_name, a_proc_annotations.by_proc(l_procedure_name), a_suite); l_procedure_name := a_proc_annotations.by_proc.next( l_procedure_name ); end loop; - return convert_list(l_tests); end; procedure build_suitepath( @@ -629,15 +615,15 @@ create or replace package body ut_suite_builder is a_suite.path := lower(coalesce(a_suite.path, a_suite.object_name)); end; - procedure populate_suite_contents( + procedure add_suite_tests( a_suite in out nocopy ut_suite, - a_annotations t_annotations_info + a_annotations t_annotations_info, + a_suite_items in out nocopy ut_suite_items ) is l_before_each_list tt_executables; l_after_each_list tt_executables; l_before_all_list tt_executables; l_after_all_list tt_executables; - l_executables ut_executables; l_rollback_type ut_utils.t_rollback_type; l_annotation_text t_annotation_text; begin @@ -681,75 +667,14 @@ create or replace package body ut_suite_builder is a_suite.disabled_flag := ut_utils.boolean_to_int(a_annotations.by_name.exists(gc_disabled)); --process procedure annotations for suite - add_annotated_procedures(a_annotations, a_suite, l_before_each_list, l_after_each_list, l_before_all_list, l_after_all_list); + get_annotated_procedures(a_annotations, a_suite, a_suite_items, l_before_each_list, l_after_each_list, l_before_all_list, l_after_all_list); a_suite.set_rollback_type(l_rollback_type); - update_before_after_each(a_suite, l_before_each_list, l_after_each_list); + propagate_before_after_each( a_suite_items, l_before_each_list, l_after_each_list); a_suite.before_all_list := convert_list(l_before_all_list); a_suite.after_all_list := convert_list(l_after_all_list); end; - function get_suite_items( - a_suite in out nocopy ut_suite, - a_annotations t_annotations_info - ) return ut_suite_items is - l_before_each_list tt_executables; - l_after_each_list tt_executables; - l_before_all_list tt_executables; - l_after_all_list tt_executables; - l_rollback_type ut_utils.t_rollback_type; - l_annotation_text t_annotation_text; - l_results ut_suite_items := ut_suite_items(); - begin - if a_annotations.by_name.exists(gc_displayname) then - l_annotation_text := trim(a_annotations.by_name(gc_displayname)(a_annotations.by_name(gc_displayname).first)); - if l_annotation_text is not null then - a_suite.description := l_annotation_text; - else - add_annotation_ignored_warning( - a_suite, gc_displayname, '%%% annotation requires a non-empty parameter value.', - a_annotations.by_name(gc_displayname).first - ); - end if; - warning_on_duplicate_annot(a_suite, a_annotations.by_name, gc_displayname); - end if; - - if a_annotations.by_name.exists(gc_rollback) then - l_rollback_type := get_rollback_type(a_annotations.by_name(gc_rollback)(a_annotations.by_name(gc_rollback).first)); - if l_rollback_type is null then - add_annotation_ignored_warning( - a_suite, gc_rollback, '%%% annotation requires one of values as parameter: "auto" or "manual".', - a_annotations.by_name(gc_rollback).first - ); - end if; - warning_on_duplicate_annot(a_suite, a_annotations.by_name, gc_rollback); - end if; - if a_annotations.by_name.exists(gc_beforeall) then - l_before_all_list := add_executables( a_suite.object_owner, a_suite.object_name, a_annotations.by_name(gc_beforeall), gc_beforeall ); - end if; - if a_annotations.by_name.exists(gc_afterall) then - l_after_all_list := add_executables( a_suite.object_owner, a_suite.object_name, a_annotations.by_name(gc_afterall), gc_afterall ); - end if; - - if a_annotations.by_name.exists(gc_beforeeach) then - l_before_each_list := add_executables( a_suite.object_owner, a_suite.object_name, a_annotations.by_name(gc_beforeeach), gc_beforeeach ); - end if; - if a_annotations.by_name.exists(gc_aftereach) then - l_after_each_list := add_executables( a_suite.object_owner, a_suite.object_name, a_annotations.by_name(gc_aftereach), gc_aftereach ); - end if; - - a_suite.disabled_flag := ut_utils.boolean_to_int(a_annotations.by_name.exists(gc_disabled)); - - --process procedure annotations for suite - l_results := get_annotated_procedures(a_annotations, a_suite, l_before_each_list, l_after_each_list, l_before_all_list, l_after_all_list); - - a_suite.set_rollback_type(l_rollback_type); - update_before_after_each(l_results, l_before_each_list, l_after_each_list); - a_suite.before_all_list := convert_list(l_before_all_list); - a_suite.after_all_list := convert_list(l_after_all_list); - return l_results; - end; - function get_endcontext_position( a_context_ann_pos t_annotation_position, a_package_annotations in out nocopy tt_annotations_by_name @@ -795,10 +720,10 @@ create or replace package body ut_suite_builder is return l_result; end; - - procedure add_suite_contexts( + procedure get_suite_contexts_items( a_suite in out nocopy ut_suite, - a_annotations in out nocopy t_annotations_info + a_annotations in out nocopy t_annotations_info, + a_suite_items out nocopy ut_suite_items ) is l_context_pos t_annotation_position; l_end_context_pos t_annotation_position; @@ -806,9 +731,11 @@ create or replace package body ut_suite_builder is l_ctx_annotations t_annotations_info; l_context ut_suite_context; l_context_no binary_integer := 1; + l_context_items ut_suite_items; type tt_context_names is table of boolean index by t_object_name; l_context_names tt_context_names; begin + a_suite_items := ut_suite_items(); if not a_annotations.by_name.exists(gc_context) then return; end if; @@ -821,65 +748,7 @@ create or replace package body ut_suite_builder is exit; end if; - --create a sub-set of annotations to process as sub-suite (context) - l_ctx_annotations := get_annotations_in_context( a_annotations, l_context_pos, l_end_context_pos); - - l_context_name := coalesce( - l_ctx_annotations.by_line( l_context_pos ).text - , gc_context||'_'||l_context_no - ); - if l_context_names.exists(l_context_name) then - add_annotation_ignored_warning( a_suite, 'context', 'Context name must be unique in a suite. Context and all of it''s content ignored.', l_context_pos ); - else - l_context_names(l_context_name) := true; - l_context := ut_suite_context(a_suite.object_owner, a_suite.object_name, l_context_name, l_context_pos ); - - l_context.path := a_suite.path||'.'||l_context_name; - l_context.description := l_ctx_annotations.by_line( l_context_pos ).text; - - warning_on_duplicate_annot( l_context, l_ctx_annotations.by_name, gc_context ); - - populate_suite_contents( l_context, l_ctx_annotations ); - - a_suite.add_item(l_context); - - end if; - -- remove annotations within context after processing them - delete_annotations_range(a_annotations, l_context_pos, l_end_context_pos); - - exit when not a_annotations.by_name.exists( gc_context); - - l_context_pos := a_annotations.by_name( gc_context).next( l_context_pos); - l_context_no := l_context_no + 1; - end loop; - end; - - function get_suite_contexts_items( - a_suite in out nocopy ut_suite, - a_annotations in out nocopy t_annotations_info - ) return ut_suite_items is - l_context_pos t_annotation_position; - l_end_context_pos t_annotation_position; - l_context_name t_object_name; - l_ctx_annotations t_annotations_info; - l_context ut_suite_context; - l_context_no binary_integer := 1; - type tt_context_names is table of boolean index by t_object_name; - l_context_names tt_context_names; - l_results ut_suite_items := ut_suite_items(); - begin - if not a_annotations.by_name.exists(gc_context) then - return l_results; - end if; - - l_context_pos := a_annotations.by_name( gc_context).first; - - while l_context_pos is not null loop - l_end_context_pos := get_endcontext_position(l_context_pos, a_annotations.by_name ); - if l_end_context_pos is null then - exit; - end if; - + l_context_items := ut_suite_items(); --create a sub-set of annotations to process as sub-suite (context) l_ctx_annotations := get_annotations_in_context( a_annotations, l_context_pos, l_end_context_pos); @@ -900,9 +769,10 @@ create or replace package body ut_suite_builder is warning_on_duplicate_annot( l_context, l_ctx_annotations.by_name, gc_context ); - l_results := l_results multiset union all get_suite_items( l_context, l_ctx_annotations ); - l_results.extend; - l_results(l_results.last) := l_context; + add_suite_tests( l_context, l_ctx_annotations, l_context_items ); + add_items_to_list(a_suite_items, l_context_items); + a_suite_items.extend; + a_suite_items(a_suite_items.last) := l_context; end if; -- remove annotations within context after processing them delete_annotations_range(a_annotations, l_context_pos, l_end_context_pos); @@ -912,7 +782,6 @@ create or replace package body ut_suite_builder is l_context_pos := a_annotations.by_name( gc_context).next( l_context_pos); l_context_no := l_context_no + 1; end loop; - return l_results; end; procedure warning_on_incomplete_context( @@ -963,37 +832,7 @@ create or replace package body ut_suite_builder is end loop; end; - function create_suite( - a_annotations t_annotations_info - ) return ut_logical_suite is - l_annotations t_annotations_info := a_annotations; - l_annotation_pos t_annotation_position; - l_suite ut_suite; - begin - if l_annotations.by_name.exists( gc_suite) then - - --create an incomplete suite - l_annotation_pos := l_annotations.by_name(gc_suite).first; - l_suite := ut_suite(l_annotations.owner, l_annotations.name, l_annotation_pos); - l_suite.description := l_annotations.by_name(gc_suite)(l_annotation_pos); - warning_on_unknown_annotations(l_suite, l_annotations.by_line); - - warning_on_duplicate_annot( l_suite, l_annotations.by_name, gc_suite ); - - build_suitepath( l_suite, l_annotations ); - - add_suite_contexts( l_suite, l_annotations ); - --by this time all contexts were consumed and l_annotations should not have any context/endcontext annotation in it. - warning_on_incomplete_context( l_suite, l_annotations.by_name ); - - populate_suite_contents( l_suite, l_annotations ); - - end if; - return l_suite; - end; - - function build_parent_suites_for_path(a_suite ut_suite) return ut_suite_items is - l_results ut_suite_items := ut_suite_items(); + procedure add_parent_logical_suites( a_suite ut_suite, a_suite_items in out nocopy ut_suite_items) is l_path varchar2(200); l_name varchar2(200); begin @@ -1002,21 +841,20 @@ create or replace package body ut_suite_builder is l_path := substr( l_path, 1, instr(l_path,'.',-1)-1); exit when l_path is null; l_name := substr( l_path, instr(l_path,'.',-1)+1); - l_results.extend; - l_results(l_results.last) := - ut_logical_suite( - a_object_owner => a_suite.object_owner, - a_object_name => l_name, a_name => l_name, a_path => l_path - ); - l_results(l_results.last).parse_time := a_suite.parse_time; + a_suite_items.extend; + a_suite_items( a_suite_items.last) := + ut_logical_suite( + a_object_owner => a_suite.object_owner, + a_object_name => l_name, a_name => l_name, a_path => l_path + ); + a_suite_items( a_suite_items.last).parse_time := a_suite.parse_time; end loop; - return l_results; end; - function create_suite_items( a_annotations t_annotations_info ) return ut_suite_items is - l_annotations t_annotations_info := a_annotations; - l_annotation_pos t_annotation_position; - l_suite ut_suite; - l_results ut_suite_items; + + procedure create_suite_item_list( a_annotations t_annotations_info, a_suite_items out nocopy ut_suite_items ) is + l_annotations t_annotations_info := a_annotations; + l_annotation_pos t_annotation_position; + l_suite ut_suite; begin if l_annotations.by_name.exists(gc_suite) then l_annotation_pos := l_annotations.by_name(gc_suite).first; @@ -1028,58 +866,17 @@ create or replace package body ut_suite_builder is warning_on_duplicate_annot( l_suite, l_annotations.by_name, gc_suite ); build_suitepath( l_suite, l_annotations ); - l_results := get_suite_contexts_items( l_suite, l_annotations ) multiset union all get_suite_items( l_suite, l_annotations ); + get_suite_contexts_items( l_suite, l_annotations, a_suite_items ); + --create suite tests and add + add_suite_tests( l_suite, l_annotations, a_suite_items ); --by this time all contexts were consumed and l_annotations should not have any context/endcontext annotation in it. warning_on_incomplete_context( l_suite, l_annotations.by_name ); - l_results.extend; - l_results(l_results.last) := l_suite; - l_results := l_results multiset union all build_parent_suites_for_path(l_suite); - end if; - return l_results; - end; - function build_suites_hierarchy( a_suites_by_path tt_schema_suites ) return tt_schema_suites is - l_result tt_schema_suites; - l_suite_path varchar2(4000 char); - l_parent_path varchar2(4000 char); - l_name varchar2(4000 char); - l_suites_by_path tt_schema_suites; - begin - l_suites_by_path := a_suites_by_path; - --were iterating in reverse order of the index by path table - -- so the first paths will be the leafs of hierarchy and next will their parents - l_suite_path := l_suites_by_path.last; - ut_utils.debug_log('Input suites to process = '||l_suites_by_path.count); - - while l_suite_path is not null loop - l_parent_path := substr( l_suite_path, 1, instr(l_suite_path,'.',-1)-1); - ut_utils.debug_log('Processing l_suite_path = "'||l_suite_path||'", l_parent_path = "'||l_parent_path||'"'); - --no parent => I'm a root element - if l_parent_path is null then - ut_utils.debug_log(' suite "'||l_suite_path||'" is a root element - adding to return list.'); - l_result(l_suite_path) := l_suites_by_path(l_suite_path); - -- not a root suite - need to add it to a parent suite - else - --parent does not exist and needs to be added - if not l_suites_by_path.exists(l_parent_path) then - l_name := substr( l_parent_path, instr(l_parent_path,'.',-1)+1); - ut_utils.debug_log(' Parent suite "'||l_parent_path||'" not found in the list - Adding suite "'||l_name||'"'); - l_suites_by_path(l_parent_path) := - ut_logical_suite( - a_object_owner => l_suites_by_path(l_suite_path).object_owner, - a_object_name => l_name, a_name => l_name, a_path => l_parent_path - ); - else - ut_utils.debug_log(' Parent suite "'||l_parent_path||'" found in list of suites'); - end if; - ut_utils.debug_log(' adding suite "'||l_suite_path||'" to "'||l_parent_path||'" items'); - l_suites_by_path(l_parent_path).add_item( l_suites_by_path(l_suite_path) ); - end if; - l_suite_path := l_suites_by_path.prior(l_suite_path); - end loop; - ut_utils.debug_log(l_result.count||' root suites created.'); - return l_result; + a_suite_items.extend; + a_suite_items( a_suite_items.last) := l_suite; + add_parent_logical_suites( l_suite, a_suite_items ); + end if; end; function convert_package_annotations(a_object ut_annotated_object) return t_annotations_info is @@ -1108,177 +905,195 @@ create or replace package body ut_suite_builder is return l_result; end; - - function build_suites(a_annotated_objects sys_refcursor) return t_schema_suites_info is - l_suite ut_logical_suite; - l_annotated_objects ut_annotated_objects; - l_all_suites tt_schema_suites; - l_result t_schema_suites_info; - begin - loop - fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; - - for i in 1 .. l_annotated_objects.count loop - l_suite := create_suite(convert_package_annotations(l_annotated_objects(i))); - ut_suite_cache_manager.save_cache( create_suite_items(convert_package_annotations(l_annotated_objects(i))) ); - if l_suite is not null then - l_all_suites(l_suite.path) := l_suite; - l_result.suite_paths(l_suite.object_name) := l_suite.path; - end if; - end loop; - exit when a_annotated_objects%notfound; - end loop; - close a_annotated_objects; - --build hierarchical structure of the suite - -- Restructure single-dimension list into hierarchy of suites by the value of %suitepath attribute value - l_result.schema_suites := build_suites_hierarchy(l_all_suites); - - return l_result; - end; - - procedure refresh_suite_cache(a_annotated_objects sys_refcursor) is - l_suite ut_logical_suite; - l_annotated_objects ut_annotated_objects; - l_all_suites tt_schema_suites; - l_result t_schema_suites_info; - begin - loop - fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; - - for i in 1 .. l_annotated_objects.count loop - ut_suite_cache_manager.save_cache( create_suite_items(convert_package_annotations(l_annotated_objects(i))) ); - end loop; - exit when a_annotated_objects%notfound; - end loop; - close a_annotated_objects; - end; - procedure reconstruct_from_cache( a_suites in out nocopy ut_suite_items, a_suite_data_cursor sys_refcursor ) is type t_item_levels is table of ut_suite_items index by binary_integer; l_items_at_level t_item_levels; - l_tests ut_suite_items; - l_logical_suites ut_logical_suites; - l_levels ut_integer_list; - l_cursor_idx integer; - l_prev_level integer; + l_rows ut_suite_cache_manager.tt_cached_suites; +-- l_items ut_suite_items := ut_suite_items(); + l_tests ut_suite_items := ut_suite_items(); + l_logical_suites ut_logical_suites := ut_logical_suites(); + l_level pls_integer; + l_prev_level pls_integer; + l_idx integer; begin a_suites := ut_suite_items(); loop - if l_cursor_idx is null then - fetch a_suite_data_cursor bulk collect into l_tests, l_logical_suites, l_levels limit 1000; - l_cursor_idx := l_levels.first; + if l_idx is null then + fetch a_suite_data_cursor bulk collect into l_rows limit 1000; +-- l_items.delete; +-- l_items.extend(l_rows.count); + l_tests.delete; + l_tests.extend(l_rows.count); + l_logical_suites.delete; + l_logical_suites.extend(l_rows.count); + for i in 1 .. l_rows.count loop + case l_rows(i).self_type + when 'UT_TEST' then +-- l_items(i) := + l_tests(i) := + ut_test( + self_type => l_rows(i).self_type, + object_owner => l_rows(i).object_owner, object_name => l_rows(i).object_name, + name => l_rows(i).name, description => l_rows(i).description, path => l_rows(i).path, + rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, + line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + before_each_list => l_rows(i).before_each_list, before_test_list => l_rows(i).before_test_list, + item => l_rows(i).item, + after_test_list => l_rows(i).after_test_list, after_each_list => l_rows(i).after_each_list, + all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), + parent_error_stack_trace => null, expected_error_codes => l_rows(i).expected_error_codes + ); + when 'UT_SUITE' then +-- l_items(i) := + l_logical_suites(i) := + ut_suite( + self_type => l_rows(i).self_type, + object_owner => l_rows(i).object_owner, object_name => l_rows(i).object_name, + name => l_rows(i).name, description => l_rows(i).description, path => l_rows(i).path, + rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, + line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items(), + before_all_list => l_rows(i).before_all_list, after_all_list => l_rows(i).after_all_list + ); + when 'UT_SUITE_CONTEXT' then +-- l_items(i) := + l_logical_suites(i) := + ut_suite_context( + self_type => l_rows(i).self_type, + object_owner => l_rows(i).object_owner, object_name => l_rows(i).object_name, name => l_rows(i).name, + description => l_rows(i).description, path => l_rows(i).path, rollback_type => l_rows(i).rollback_type, + disabled_flag => l_rows(i).disabled_flag, line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items(), + before_all_list => l_rows(i).before_all_list, after_all_list => l_rows(i).after_all_list + ); + when 'UT_LOGICAL_SUITE' then +-- l_items(i) := + l_logical_suites(i) := + ut_logical_suite( + self_type => l_rows(i).self_type, + object_owner => l_rows(i).object_owner, object_name => l_rows(i).object_name, name => l_rows(i).name, + description => l_rows(i).description, path => l_rows(i).path, rollback_type => l_rows(i).rollback_type, + disabled_flag => l_rows(i).disabled_flag, line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items() + ); + end case; + end loop; + l_idx := l_rows.first; end if; - exit when l_cursor_idx is null; - if l_levels(l_cursor_idx) > 1 then - if l_prev_level > l_levels(l_cursor_idx) then - l_logical_suites(l_cursor_idx).items := l_items_at_level(l_prev_level); + exit when l_idx is null; + l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1; + if l_level > 1 then + if l_prev_level > l_level then + l_logical_suites(l_idx).items := l_items_at_level(l_prev_level); l_items_at_level(l_prev_level).delete; end if; - if not l_items_at_level.exists((l_levels(l_cursor_idx))) then - l_items_at_level(l_levels(l_cursor_idx)) := ut_suite_items(); + if not l_items_at_level.exists((l_level)) then + l_items_at_level(l_level) := ut_suite_items(); end if; - l_items_at_level(l_levels(l_cursor_idx)).extend; - if l_tests(l_cursor_idx) is not null then - l_items_at_level(l_levels(l_cursor_idx))(l_items_at_level(l_levels(l_cursor_idx)).last) - := l_tests(l_cursor_idx); + l_items_at_level(l_level).extend; + if l_tests(l_idx) is not null then + l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_tests(l_idx); else - l_items_at_level(l_levels(l_cursor_idx))(l_items_at_level(l_levels(l_cursor_idx)).last) - := l_logical_suites(l_cursor_idx); + l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_logical_suites(l_idx); end if; else - if l_prev_level > l_levels(l_cursor_idx) then - l_logical_suites(l_cursor_idx).items := l_items_at_level(l_prev_level); + if l_prev_level > l_level then + l_logical_suites(l_idx).items := l_items_at_level(l_prev_level); l_items_at_level(l_prev_level).delete; end if; a_suites.extend; - if l_tests(l_cursor_idx) is not null then - a_suites(a_suites.last) := l_tests(l_cursor_idx); + if l_tests(l_idx) is not null then + a_suites(a_suites.last) := l_tests(l_idx); else - a_suites(a_suites.last) := l_logical_suites(l_cursor_idx); + a_suites(a_suites.last) := l_logical_suites(l_idx); end if; end if; - l_prev_level := l_levels(l_cursor_idx); - l_cursor_idx := l_levels.next(l_cursor_idx); +-- if l_level = 0 then +-- a_suites.extend; +-- a_suites(a_suites.last) := l_items(l_idx); +-- else +-- a_suites(a_suites.last).add_item( l_items(l_idx), l_level ); +-- end if; + l_prev_level := l_level; + l_idx := l_rows.next(l_idx); end loop; close a_suite_data_cursor; end; - function build_schema_suites_old(a_owner_name varchar2) return t_schema_suites_info is + function build_suites_from_annotations( + a_owner_name varchar2, + a_annotated_objects sys_refcursor, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null + ) return ut_suite_items is + l_suites ut_suite_items; l_annotations_cursor sys_refcursor; + l_annotated_objects ut_annotated_objects; + l_suite_items ut_suite_items; begin - -- form the single-dimension list of suites constructed from parsed packages - open l_annotations_cursor for - q'[select value(x) - from table( - ]'||ut_utils.ut_owner||q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE') - )x ]' - using a_owner_name; - - return build_suites(l_annotations_cursor); - end; + loop + fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; - function get_build_suites(a_owner_name varchar2) return ut_suite_items is - l_suites t_schema_suites_info; - l_results ut_suite_items := ut_suite_items(); - l_index varchar2(4000); - begin - l_suites := build_schema_suites_old(a_owner_name); - l_index := l_suites.schema_suites.first; - while l_index is not null loop - l_results.extend; - l_results(l_results.last) := l_suites.schema_suites(l_index); - l_index := l_suites.schema_suites.next(l_index); + for i in 1 .. l_annotated_objects.count loop + create_suite_item_list( + convert_package_annotations( l_annotated_objects( i ) ), + l_suite_items + ); + ut_suite_cache_manager.save_cache( a_owner_name, l_suite_items ); + end loop; + exit when a_annotated_objects%notfound; end loop; - return l_results; - end; - - - procedure refresh_suite_cache(a_owner_name varchar2) is - l_annotations_cursor sys_refcursor; - begin - open l_annotations_cursor for - q'[select value(x) - from table( - ]'||ut_utils.ut_owner||q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE') - )x ]' - using a_owner_name; - refresh_suite_cache(l_annotations_cursor); - end; + close a_annotated_objects; - function build_schema_suites(a_owner_name varchar2) return ut_suite_items is - l_suites ut_suite_items; - begin - refresh_suite_cache(a_owner_name); - reconstruct_from_cache(l_suites, ut_suite_cache_manager.cached_suite_by_schema(a_owner_name)); + reconstruct_from_cache( + l_suites, + ut_suite_cache_manager.get_cached_suite_data( + a_owner_name, + a_path, + a_object_name, + a_procedure_name ) + ); for i in 1 .. l_suites.count loop - l_suites(i).set_rollback_type(l_suites(i).get_rollback_type); + l_suites( i ).set_rollback_type( l_suites( i ).get_rollback_type ); end loop; return l_suites; end; - function build_schema_suites(a_owner_name varchar2,a_object_name varchar2,a_procedure_name varchar2) return ut_suite_items is - l_suites ut_suite_items; + function build_schema_suites( + a_owner_name varchar2, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null + ) return ut_suite_items is + l_annotations_cursor sys_refcursor; begin - refresh_suite_cache(a_owner_name); - reconstruct_from_cache(l_suites, ut_suite_cache_manager.cached_suite_by_package(a_owner_name, a_object_name, a_procedure_name)); - for i in 1 .. l_suites.count loop - l_suites(i).set_rollback_type(l_suites(i).get_rollback_type); - end loop; - return l_suites; - end; - function build_schema_suites(a_owner_name varchar2,a_path varchar2) return ut_suite_items is - l_suites ut_suite_items; - begin - refresh_suite_cache(a_owner_name); - reconstruct_from_cache(l_suites, ut_suite_cache_manager.cached_suite_by_path(a_owner_name, a_path)); - for i in 1 .. l_suites.count loop - l_suites(i).set_rollback_type(l_suites(i).get_rollback_type); - end loop; - return l_suites; + open l_annotations_cursor for + q'[select value(x) + from table( + ]' || ut_utils.ut_owner || q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE', :a_suite_cache_parse_time) + )x ]' + using a_owner_name, ut_suite_cache_manager.get_schema_parse_time(a_owner_name); + + return build_suites_from_annotations( + a_owner_name, + l_annotations_cursor, + a_path, + a_object_name, + a_procedure_name + ); end; end ut_suite_builder; diff --git a/source/core/ut_suite_builder.pks b/source/core/ut_suite_builder.pks index 0f4d97c76..b3d07b0a8 100644 --- a/source/core/ut_suite_builder.pks +++ b/source/core/ut_suite_builder.pks @@ -20,58 +20,30 @@ create or replace package ut_suite_builder authid current_user is * Responsible for converting annotations into unit test suites */ - --table of ut_suites indexed by suite path - tt_schema_suites('suite.path') gives ut_logical_suite - type tt_schema_suites is table of ut_logical_suite index by varchar2(4000 char); - - --table of suite paths indexed by object name - t_object_suite_path('object_name') = 'suitepath.to.object' - type t_object_suite_path is table of varchar2(4000) index by varchar2(4000 char); - - type t_schema_suites_info is record ( - schema_suites tt_schema_suites, - suite_paths t_object_suite_path - ); - /** * Builds set of hierarchical suites for a given schema * * @param a_owner_name name of the schema to builds suite for + * @param a_path suite path to build suite for (optional) + * @param a_object_name object name to build suite for (optional) + * @param a_object_name procedure name to build suite for (optional) * @return list of suites organized into hierarchy * */ - function build_schema_suites(a_owner_name varchar2) return ut_suite_items; - - /** - * Builds set of hierarchical suites for a given schema - * - * @param a_owner_name name of the schema to builds suite for - * @param a_object_name object name to build suite for - * @param a_object_name procedure name to build suite for (can be null) - * @return list of suites organized into hierarchy - * - */ - function build_schema_suites(a_owner_name varchar2, a_object_name varchar2,a_procedure_name varchar2) return ut_suite_items; - - /** - * Builds set of hierarchical suites for a given schema - * - * @param a_owner_name name of the schema to builds suite for - * @param a_path suite path to build suite for - * @return list of suites organized into hierarchy - * - */ - function build_schema_suites(a_owner_name varchar2,a_path varchar2) return ut_suite_items; - - /** - * Builds set of hierarchical suites for given annotations - * - * @param a_annotated_objects cursor returning ut_annotated_object type - * @return list of suites organized into hierarchy - * - */ - function build_suites(a_annotated_objects sys_refcursor) return t_schema_suites_info; + function build_schema_suites( + a_owner_name varchar2, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null + ) return ut_suite_items; + + function build_suites_from_annotations( + a_owner_name varchar2, + a_annotated_objects sys_refcursor, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null + ) return ut_suite_items; - function get_build_suites(a_owner_name varchar2) return ut_suite_items; - function build_schema_suites_old(a_owner_name varchar2) return t_schema_suites_info; - end ut_suite_builder; / diff --git a/source/core/ut_suite_cache.sql b/source/core/ut_suite_cache.sql index 183f4cf35..09211722b 100644 --- a/source/core/ut_suite_cache.sql +++ b/source/core/ut_suite_cache.sql @@ -75,9 +75,7 @@ alter table ut_suite_cache modify (object_owner not null, path not null, self_ty / alter table ut_suite_cache add constraint ut_suite_cache_pk primary key (object_owner, path) / -create unique index ut_suite_cache_uk on ut_suite_cache(object_owner, object_name, line_no) -/ -create index ut_suite_cache_nu1 on ut_suite_cache(object_owner, object_name) +create index ut_suite_cache_nu1 on ut_suite_cache(object_owner, object_name, parse_time desc) / alter table ut_suite_cache add constraint ut_suite_cache_schema_fk foreign key (object_owner) references ut_suite_cache_schema(object_owner) / diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb index a51ee14a7..33712c589 100644 --- a/source/core/ut_suite_cache_manager.pkb +++ b/source/core/ut_suite_cache_manager.pkb @@ -16,227 +16,130 @@ create or replace package body ut_suite_cache_manager is limitations under the License. */ - function get_suite_by(a_schema_name varchar2, a_path varchar2 := null, a_object_name varchar2 := null, a_procedure_name varchar2 := null) return sys_refcursor is + function get_cached_suite_data( + a_schema_name varchar2, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null + ) return t_cached_suites_cursor is + l_path varchar2( 4000 ); l_result sys_refcursor; begin + if a_path is null and a_object_name is not null then + select min(path) into l_path + from ut_suite_cache + where object_owner = upper(a_schema_name) and object_name = lower(a_object_name) and + name = nvl(lower(a_procedure_name), name); + else + l_path := lower( a_path ); + end if; + + open l_result for - select - case self_type - when 'UT_TEST' - then ut_test( - self_type => self_type, - object_owner => object_owner, object_name => object_name, name => name, - description => description, path => path, rollback_type => rollback_type, - disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, - start_time => null, end_time => null, result => null, warnings => warnings, - results_count => ut_results_counter(), transaction_invalidators => null, - before_each_list => before_each_list, before_test_list => before_test_list, - item => item, after_test_list => after_test_list, after_each_list => after_each_list, - all_expectations => null, failed_expectations => null, - parent_error_stack_trace => null, expected_error_codes => expected_error_codes - ) - end as test_item, - case self_type - when 'UT_SUITE' - then ut_suite( - self_type => self_type, - object_owner => object_owner, object_name => object_name, name => name, - description => description, path => path, rollback_type => rollback_type, - disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, - start_time => null, end_time => null, result => null, warnings => warnings, - results_count => ut_results_counter(), transaction_invalidators => null, - items => ut_suite_items(), - before_all_list => before_all_list, after_all_list => after_all_list - ) - when 'UT_SUITE_CONTEXT' - then ut_suite_context( - self_type => self_type, - object_owner => object_owner, object_name => object_name, name => name, - description => description, path => path, rollback_type => rollback_type, - disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, - start_time => null, end_time => null, result => null, warnings => warnings, - results_count => ut_results_counter(), transaction_invalidators => null, - items => ut_suite_items(), - before_all_list => before_all_list, after_all_list => after_all_list - ) - when 'UT_LOGICAL_SUITE' - then ut_logical_suite( - self_type => self_type, - object_owner => object_owner, object_name => object_name, name => name, - description => description, path => path, rollback_type => rollback_type, - disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, - start_time => null, end_time => null, result => null, warnings => warnings, - results_count => ut_results_counter(), transaction_invalidators => null, - items => ut_suite_items() - ) - end as logical_suite, - length(path) - length( replace(path, '.') )+1 as path_level - from ut_suite_cache x - where ( a_path like path ||'.'||'%' - or ( path like a_path || '%' - and object_name = nvl(lower(a_object_name), object_name) - and name = nvl(lower(a_procedure_name), name) - ) - ) - and object_owner = upper(a_schema_name) - order by path desc, object_name, line_no; - + select c.* + from ut_suite_cache c + -- join all_objects a + -- on a.owner = x.object_owner + -- and a.object_name = x.object_name + -- and a.object_type = 'PACKAGE' + where ( l_path like c.path || '.' || '%' + or ( c.path like l_path || '%' + and c.object_name = nvl(lower(a_object_name), c.object_name) + and c.name = nvl(lower(a_procedure_name), c.name) + ) + ) and c.object_owner = upper(a_schema_name) + order by c.object_owner, + replace(case + when c.self_type in ( 'UT_TEST' ) + then substr(c.path, 1, instr(c.path, '.', -1) - 1) + else c.path + end, '.', chr(0)) desc nulls last, + c.object_name desc, + c.line_no desc; + return l_result; end; - --- function get_suite_by(a_schema_name varchar2, a_path varchar2 := null, a_object_name varchar2 := null, a_procedure_name varchar2 := null) return sys_refcursor is --- l_filter varchar2(1000); --- l_result sys_refcursor; --- l_owner varchar2(250) := ut_utils.ut_owner(); --- begin --- if a_object_name is not null then --- l_filter := ' object_name = lower(:a_object_name)'; --- if a_procedure_name is not null then --- l_filter := l_filter || ' and name = lower(:a_procedure_name)'; --- else --- l_filter := l_filter || ' and :a_procedure_name is null'; --- end if; --- else --- l_filter := ' :a_object_name is null and :a_procedure_name is null'; --- end if; --- open l_result for q'[ --- select --- case self_type --- when 'UT_TEST' --- then ]'||l_owner||q'[.ut_test( --- self_type => self_type, --- object_owner => object_owner, object_name => object_name, name => name, --- description => description, path => path, rollback_type => rollback_type, --- disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, --- start_time => null, end_time => null, result => null, warnings => warnings, --- results_count => ut_results_counter(), transaction_invalidators => null, --- before_each_list => before_each_list, before_test_list => before_test_list, --- item => item, after_test_list => after_test_list, after_each_list => after_each_list, --- all_expectations => null, failed_expectations => null, --- parent_error_stack_trace => null, expected_error_codes => expected_error_codes --- ) --- end as test_item, --- case self_type --- when 'UT_SUITE' --- then ]'||l_owner||q'[.ut_suite( --- self_type => self_type, --- object_owner => object_owner, object_name => object_name, name => name, --- description => description, path => path, rollback_type => rollback_type, --- disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, --- start_time => null, end_time => null, result => null, warnings => warnings, --- results_count => ]'||l_owner||q'[.ut_results_counter(), transaction_invalidators => null, --- items => ut_suite_items(), --- before_all_list => before_all_list, after_all_list => after_all_list --- ) --- when 'UT_SUITE_CONTEXT' --- then ]'||l_owner||q'[.ut_suite_context( --- self_type => self_type, --- object_owner => object_owner, object_name => object_name, name => name, --- description => description, path => path, rollback_type => rollback_type, --- disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, --- start_time => null, end_time => null, result => null, warnings => warnings, --- results_count => ]'||l_owner||q'[.ut_results_counter(), transaction_invalidators => null, --- items => ut_suite_items(), --- before_all_list => before_all_list, after_all_list => after_all_list --- ) --- when 'UT_LOGICAL_SUITE' --- then ]'||l_owner||q'[.ut_logical_suite( --- self_type => self_type, --- object_owner => object_owner, object_name => object_name, name => name, --- description => description, path => path, rollback_type => rollback_type, --- disabled_flag => disabled_flag, line_no => line_no, parse_time => parse_time, --- start_time => null, end_time => null, result => null, warnings => warnings, --- results_count => ]'||l_owner||q'[.ut_results_counter(), transaction_invalidators => null, --- items => ut_suite_items() --- ) --- end as logical_suite, --- length(path) - length( replace(path, '.') )+1 as path_level --- from ]'||l_owner||q'[.ut_suite_cache x --- where ( :a_path like path ||'.'||'%' --- or path like :a_path ||'%' and ]'||l_filter||q'[ ) --- and object_owner = upper(:a_schema_name) --- order by path desc, object_name, line_no]' --- using a_path, a_path, a_object_name, a_procedure_name, a_schema_name; --- --- return l_result; --- end; --- - function cached_suite_by_path(a_schema_name varchar2, a_path varchar2) return sys_refcursor is - begin - return get_suite_by(a_schema_name, a_path); - end; - function cached_suite_by_package(a_schema_name varchar2, a_object_name varchar2, a_procedure_name varchar2) return sys_refcursor is - l_path varchar2(4000); - begin - select min(path) into l_path - from ut_suite_cache - where object_owner = upper(a_schema_name) - and object_name = lower(a_object_name) - and name = nvl(lower(a_procedure_name),name); - return get_suite_by(a_schema_name, l_path, a_object_name, a_procedure_name ); + function get_schema_ut_packages( a_schema_names ut_varchar2_rows ) return ut_object_names is + l_results ut_object_names := ut_object_names( ); + l_schema_names ut_varchar2_rows; + l_object_names ut_varchar2_rows; + begin + select distinct c.object_owner, c.object_name + bulk collect into l_schema_names, l_object_names + from ut_suite_cache c + -- join all_objects a + -- on a.owner = c.object_owner + -- and a.object_name = c.object_name + -- and a.object_type = 'PACKAGE' + join table ( a_schema_names ) s on c.object_owner = upper(s.column_value); + l_results.extend( l_schema_names.count ); + for i in 1 .. l_schema_names.count loop + l_results( i ) := ut_object_name( l_schema_names( i ), l_object_names( i ) ); + end loop; + return l_results; end; - function cached_suite_by_schema(a_schema_name varchar2) return sys_refcursor is + function get_schema_parse_time(a_schema_name varchar2) return timestamp result_cache is + l_cache_parse_time timestamp; begin - return get_suite_by(a_schema_name); + select min(t.parse_time) + into l_cache_parse_time + from ut_suite_cache_schema t + where object_owner = a_schema_name; + return l_cache_parse_time; end; - procedure save_cache(a_suite_items ut_suite_items) is + procedure save_cache(a_object_owner varchar2, a_suite_items ut_suite_items) is pragma autonomous_transaction; - l_annotation_parse_time date; - l_suite_parse_time date; + l_parse_time timestamp; + l_cached_parse_time timestamp; begin if a_suite_items.count = 0 then return; end if; + if a_suite_items(1).self_type != 'UT_LOGICAL_SUITE' then select min(parse_time) - into l_suite_parse_time from ut_suite_cache t + into l_cached_parse_time + from ut_suite_cache t where t.object_name = a_suite_items(1).object_name - and t.object_owner = a_suite_items(1).object_owner - and rownum = 1; + and t.object_owner = a_suite_items(1).object_owner + and rownum = 1; end if; - l_annotation_parse_time := a_suite_items(1).parse_time; + select max(parse_time) into l_parse_time from table(a_suite_items) s; - if l_annotation_parse_time > l_suite_parse_time or l_suite_parse_time is null then + if l_parse_time > l_cached_parse_time or l_cached_parse_time is null then - merge into ut_suite_cache_schema t - using(select object_owner, max(parse_time) parse_time from table(a_suite_items) group by object_owner) s - on (s.object_owner = t.object_owner) - when matched then update - set t.parse_time = s.parse_time - where s.parse_time > t.parse_time - when not matched then - insert (object_owner, parse_time) - values (s.object_owner, s.parse_time); + update ut_suite_cache_schema t + set t.parse_time = l_parse_time + where object_owner = a_object_owner; + + if sql%rowcount = 0 then + insert into ut_suite_cache_schema + (object_owner, parse_time) + values (a_object_owner, l_parse_time); + end if; delete from ut_suite_cache t where (t.object_name, t.object_owner) in (select s.object_name, s.object_owner from table(a_suite_items) s where s.self_type != 'UT_LOGICAL_SUITE'); - merge into ut_suite_cache t - using ( - select self_type, path, object_owner, object_name, name, - line_no, parse_time, description, - rollback_type, disabled_flag, warnings - from table(a_suite_items) x where x.self_type = 'UT_LOGICAL_SUITE' - ) s - on (t.object_name = s.object_name and t.object_owner = s.object_owner) - when not matched then - insert ( + + insert into ut_suite_cache t + ( self_type, path, object_owner, object_name, name, line_no, parse_time, description, rollback_type, disabled_flag, warnings ) - values ( - s.self_type, s.path, s.object_owner, s.object_name, s.name, - s.line_no, s.parse_time, s.description, - s.rollback_type, s.disabled_flag, s.warnings - ); - + select self_type, path, object_owner, object_name, name, + line_no, parse_time, description, + rollback_type, disabled_flag, warnings + from table(a_suite_items) s + where s.self_type = 'UT_LOGICAL_SUITE' + and (s.object_owner, s.path) not in (select c.object_owner, c.path from ut_suite_cache c); insert into ut_suite_cache t ( @@ -248,16 +151,9 @@ create or replace package body ut_suite_cache_manager is before_test_list, after_test_list, expected_error_codes, item ) - with - suite_items as ( select value(x) item from table(a_suite_items) x ), - suites as ( - select treat(item as ut_suite) i from suite_items s - where s.item.self_type in ('UT_SUITE','UT_SUITE_CONTEXT') - ), - tests as ( - select treat(item as ut_test) t from suite_items s - where s.item.self_type in ('UT_TEST') - ) + with suites as ( select treat(value(x) as ut_suite) i + from table(a_suite_items) x + where x.self_type in( 'UT_SUITE', 'UT_SUITE_CONTEXT' ) ) select s.i.self_type as self_type, s.i.path as path, s.i.object_owner as object_owner, s.i.object_name as object_name, s.i.name as name, s.i.line_no as line_no, s.i.parse_time as parse_time, s.i.description as description, @@ -266,19 +162,34 @@ create or replace package body ut_suite_cache_manager is null before_each_list, null after_each_list, null before_test_list, null after_test_list, null expected_error_codes, null item - from suites s - union all - select s.t.self_type as self_type, s.t.path as path, - s.t.object_owner as object_owner, s.t.object_name as object_name, s.t.name as name, - s.t.line_no as line_no, s.t.parse_time as parse_time, s.t.description as description, - s.t.rollback_type as rollback_type, s.t.disabled_flag as disabled_flag, s.t.warnings as warnings, - null before_all_list, null after_all_list, - s.t.before_each_list as before_each_list, s.t.after_each_list as after_each_list, - s.t.before_test_list as before_test_list, s.t.after_test_list as after_test_list, - s.t.expected_error_codes as expected_error_codes, s.t.item as item + from suites s; + + insert into ut_suite_cache t + ( + self_type, path, object_owner, object_name, name, + line_no, parse_time, description, + rollback_type, disabled_flag, warnings, + before_all_list, after_all_list, + before_each_list, after_each_list, + before_test_list, after_test_list, + expected_error_codes, item + ) + with tests as ( select treat(value(x) as ut_test) t + from table ( a_suite_items ) x + where x.self_type in ( 'UT_TEST' ) ) + select s.t.self_type as self_type, s.t.path as path, + s.t.object_owner as object_owner, s.t.object_name as object_name, s.t.name as name, + s.t.line_no as line_no, s.t.parse_time as parse_time, s.t.description as description, + s.t.rollback_type as rollback_type, s.t.disabled_flag as disabled_flag, s.t.warnings as warnings, + null before_all_list, null after_all_list, + s.t.before_each_list as before_each_list, s.t.after_each_list as after_each_list, + s.t.before_test_list as before_test_list, s.t.after_test_list as after_test_list, + s.t.expected_error_codes as expected_error_codes, s.t.item as item from tests s; + + commit; end if; - commit; end; + end ut_suite_cache_manager; / diff --git a/source/core/ut_suite_cache_manager.pks b/source/core/ut_suite_cache_manager.pks index 1b2d1f2f6..f5da97ec7 100644 --- a/source/core/ut_suite_cache_manager.pks +++ b/source/core/ut_suite_cache_manager.pks @@ -19,14 +19,22 @@ create or replace package ut_suite_cache_manager authid definer is /** * Responsible for storing and retrieving suite data from cache */ + subtype t_cached_suite is ut_suite_cache%rowtype; + type tt_cached_suites is table of t_cached_suite; + type t_cached_suites_cursor is ref cursor return t_cached_suite; - procedure save_cache(a_suite_items ut_suite_items); + procedure save_cache(a_object_owner varchar2, a_suite_items ut_suite_items); - function cached_suite_by_path(a_schema_name varchar2, a_path varchar2) return sys_refcursor; + function get_cached_suite_data( + a_schema_name varchar2, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null + ) return t_cached_suites_cursor; - function cached_suite_by_package(a_schema_name varchar2, a_object_name varchar2, a_procedure_name varchar2) return sys_refcursor; + function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names; - function cached_suite_by_schema(a_schema_name varchar2) return sys_refcursor; + function get_schema_parse_time(a_schema_name varchar2) return timestamp result_cache; end ut_suite_cache_manager; / diff --git a/source/core/ut_suite_cache_schema.sql b/source/core/ut_suite_cache_schema.sql index 890c72e0b..ba257dafd 100644 --- a/source/core/ut_suite_cache_schema.sql +++ b/source/core/ut_suite_cache_schema.sql @@ -13,7 +13,7 @@ create table ut_suite_cache_schema ( limitations under the License. */ object_owner varchar2(250) not null, - parse_time date not null, + parse_time timestamp not null, constraint ut_suite_cache_schema_pk primary key(object_owner) ) organization index / diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index dd9ffb5de..04bc26f10 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -16,24 +16,6 @@ create or replace package body ut_suite_manager is limitations under the License. */ - subtype tt_schema_suites is ut_suite_builder.tt_schema_suites; - subtype t_object_suite_path is ut_suite_builder.t_object_suite_path; - subtype t_schema_suites_info is ut_suite_builder.t_schema_suites_info; - - type t_schema_info is record (changed_at date, obj_cnt integer); - - type t_schema_cache is record( - schema_suites tt_schema_suites - ,changed_at date - ,obj_cnt integer - ,suite_paths t_object_suite_path - ); - type tt_schema_suites_list is table of t_schema_cache index by varchar2(128 char); - - g_schema_suites tt_schema_suites_list; - - --- type t_schema_paths is table of ut_varchar2_list index by varchar2(4000 char); type t_path_item is record ( object_name varchar2(250), @@ -45,96 +27,9 @@ create or replace package body ut_suite_manager is ------------------ - function get_schema_info(a_owner_name varchar2) return t_schema_info is - l_info t_schema_info; - l_view_name varchar2(200) := ut_metadata.get_dba_view('dba_objects'); - begin - execute immediate q'[ - select nvl(max(t.last_ddl_time), date '4999-12-31'), count(*) - from ]'||l_view_name||q'[ t - where t.owner = :a_owner_name - and t.object_type in ('PACKAGE')]' - into l_info using a_owner_name; - return l_info; - end; - - procedure update_cache(a_owner_name varchar2, a_suites_info t_schema_suites_info, a_total_obj_cnt integer) is - begin - if a_suites_info.schema_suites.count > 0 then - g_schema_suites(a_owner_name).schema_suites := a_suites_info.schema_suites; - g_schema_suites(a_owner_name).changed_at := sysdate; - g_schema_suites(a_owner_name).obj_cnt := a_total_obj_cnt; - g_schema_suites(a_owner_name).suite_paths := a_suites_info.suite_paths; - elsif g_schema_suites.exists(a_owner_name) then - g_schema_suites.delete(a_owner_name); - end if; - end; - - function cache_valid(a_schema_name varchar2) return boolean is - l_info t_schema_info; - l_result boolean := true; - begin - if not g_schema_suites.exists(a_schema_name) then - l_result := false; - else - l_info := get_schema_info(a_schema_name); - if g_schema_suites(a_schema_name).changed_at <= l_info.changed_at or g_schema_suites(a_schema_name).obj_cnt != l_info.obj_cnt then - l_result := false; - else - l_result := true; - end if; - end if; - return l_result; - end; - - function get_schema_suites(a_schema_name in varchar2) return t_schema_suites_info is - l_result t_schema_suites_info; - begin - -- Currently cache invalidation on DDL is not implemented so schema is rescaned each time - if cache_valid(a_schema_name) then - l_result.schema_suites := g_schema_suites(a_schema_name).schema_suites; - l_result.suite_paths := g_schema_suites(a_schema_name).suite_paths; - else - ut_utils.debug_log('Rescanning schema ' || a_schema_name); - l_result := ut_suite_builder.build_schema_suites_old(a_schema_name); - update_cache(a_schema_name, l_result, get_schema_info(a_schema_name).obj_cnt ); - end if; - - return l_result; - end get_schema_suites; - function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names is - l_schema_ut_packages ut_object_names := ut_object_names(); - l_schema_suites tt_schema_suites; - l_iter varchar2(4000); - procedure populate_suite_ut_packages(a_suite ut_logical_suite, a_packages in out nocopy ut_object_names) is - l_sub_suite ut_logical_suite; - begin - if a_suite is of (ut_suite) then - a_packages.extend; - a_packages(a_packages.last) := ut_object_name(a_suite.object_owner, a_suite.object_name); - end if; - for i in 1 .. a_suite.items.count loop - if a_suite.items(i) is of (ut_logical_suite) then - l_sub_suite := treat(a_suite.items(i) as ut_logical_suite); - populate_suite_ut_packages(l_sub_suite, a_packages); - end if; - end loop; - end; begin - if a_schema_names is not null then - for i in 1 .. a_schema_names.count loop - l_schema_suites := get_schema_suites(a_schema_names(i)).schema_suites; - l_iter := l_schema_suites.first; - while l_iter is not null loop - populate_suite_ut_packages(l_schema_suites(l_iter), l_schema_ut_packages); - l_iter := l_schema_suites.next(l_iter); - end loop; - end loop; - l_schema_ut_packages := set(l_schema_ut_packages); - end if; - - return l_schema_ut_packages; + return ut_suite_cache_manager.get_schema_ut_packages(a_schema_names); end; procedure validate_paths(a_paths in ut_varchar2_list) is @@ -220,169 +115,6 @@ create or replace package body ut_suite_manager is return resolve_schema_names(l_paths); end; - procedure filter_suite_by_path(a_suite in out nocopy ut_suite_item, a_path varchar2) is - c_item_name constant varchar2(32767) := lower(regexp_substr(a_path, '[A-Za-z0-9$#_]+')); - c_child_filter_path constant varchar2(32767) := regexp_substr(a_path, '\.(.+)', subexpression => 1); - l_suite ut_logical_suite; - l_item ut_suite_item; - l_items ut_suite_items := ut_suite_items(); - - function find_item_in_suite(a_suite ut_logical_suite, a_item_name varchar2) return ut_suite_item is - l_item_index binary_integer; - begin - l_item_index := a_suite.items.first; - while l_item_index is not null loop - if lower(a_suite.items(l_item_index).name) = a_item_name then - return a_suite.items(l_item_index); - end if; - l_item_index := a_suite.items.next(l_item_index); - end loop; - return null; - end; - - function find_item_in_suite_contexts(a_suite ut_logical_suite, a_item_name varchar2) return ut_suite_item is - l_item_index binary_integer; - l_context ut_suite_context; - l_item ut_suite_item; - begin - l_item_index := a_suite.items.first; - while l_item_index is not null loop - if a_suite.items(l_item_index) is of (ut_suite_context) then - l_item := find_item_in_suite( - treat(a_suite.items(l_item_index) as ut_suite_context) - , a_item_name - ); - end if; - - if l_item is not null then - l_context := treat(a_suite.items(l_item_index) as ut_suite_context); - l_context.items := ut_suite_items(l_item); - exit; - end if; - l_item_index := a_suite.items.next(l_item_index); - end loop; - return l_context; - end; - begin - if a_suite is of (ut_logical_suite) then - l_suite := treat(a_suite as ut_logical_suite); - - l_item := coalesce( - find_item_in_suite(l_suite, c_item_name) - , find_item_in_suite_contexts(l_suite, c_item_name) - ); - if l_item is not null then - if c_child_filter_path is not null then - filter_suite_by_path(l_item, c_child_filter_path); - end if; - l_items.extend; - l_items(l_items.count) := l_item; - else - raise_application_error(-20203, 'Suite item '||c_item_name||' not found'); - end if; - - l_suite.items := l_items; - a_suite := l_suite; - end if; - end filter_suite_by_path; - - function get_suite_filtered_by_path(a_path varchar2, a_schema_suites tt_schema_suites) return ut_logical_suite is - l_suite ut_logical_suite; - c_suite_path constant varchar2(32767) := regexp_substr(a_path, ':(.+)', subexpression => 1); - c_root_suite_name constant varchar2(32767) := regexp_substr(c_suite_path, '^[A-Za-z0-9$#_]+'); - c_child_filter_path constant varchar2(32767) := regexp_substr(c_suite_path, '\.(.+)', subexpression => 1); - begin - l_suite := a_schema_suites(c_root_suite_name); - if c_child_filter_path is not null then - filter_suite_by_path(l_suite, c_child_filter_path); - end if; - return l_suite; - exception - when no_data_found then - raise_application_error(-20203, 'Suite ' || c_root_suite_name || ' does not exist or is invalid'); - end; - - function convert_to_suite_path(a_path varchar2, a_suite_paths t_object_suite_path) return varchar2 is - c_package_path_regex constant varchar2(100) := '^([A-Za-z0-9$#_]+)\.([A-Za-z0-9$#_]+)(\.([A-Za-z0-9$#_]+))?$'; - l_schema_name varchar2(4000) := regexp_substr(a_path, c_package_path_regex, subexpression => 1); - l_package_name varchar2(4000) := regexp_substr(a_path, c_package_path_regex, subexpression => 2); - l_procedure_name varchar2(4000) := regexp_substr(a_path, c_package_path_regex, subexpression => 4); - l_path varchar2(4000) := a_path; - begin - if regexp_like(l_path, c_package_path_regex) then - if not a_suite_paths.exists(l_package_name) then - raise_application_error(ut_utils.gc_suite_package_not_found,'Suite package '||l_schema_name||'.'||l_package_name|| ' not found'); - end if; - l_path := rtrim(l_schema_name || ':' || a_suite_paths(l_package_name) || '.' || l_procedure_name, '.'); - end if; - return l_path; - end; - --- function group_paths_by_schema(a_paths ut_varchar2_list) return t_schema_paths is --- l_result t_schema_paths; --- l_schema varchar2(4000); --- begin --- for i in 1 .. a_paths.count loop --- l_schema := upper(regexp_substr(a_paths(i),'^[^.:]+')); --- if l_result.exists(l_schema) then --- l_result(l_schema).extend; --- l_result(l_schema)(l_result(l_schema).last) := a_paths(i); --- else --- l_result(l_schema) := ut_varchar2_list(a_paths(i)); --- end if; --- end loop; --- return l_result; --- end; --- --- function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items is --- l_paths ut_varchar2_list := a_paths; --- l_path varchar2(32767); --- l_schema varchar2(4000); --- l_suites_info t_schema_suites_info; --- l_index varchar2(4000 char); --- l_suite ut_logical_suite; --- l_objects_to_run ut_suite_items; --- l_schema_paths t_schema_paths; --- begin --- --resolve schema names from paths and group paths by schema name --- resolve_schema_names(l_paths); --- --- l_schema_paths := group_paths_by_schema(l_paths); --- --- l_objects_to_run := ut_suite_items(); --- --- l_schema := l_schema_paths.first; --- while l_schema is not null loop --- l_paths := l_schema_paths(l_schema); --- l_suites_info := get_schema_suites(l_schema); --- --- for i in 1 .. l_paths.count loop --- l_path := l_paths(i); --- --run whole schema --- if regexp_like(l_path, '^[A-Za-z0-9$#_]+$') then --- l_index := l_suites_info.schema_suites.first; --- while l_index is not null loop --- l_objects_to_run.extend; --- l_objects_to_run(l_objects_to_run.count) := l_suites_info.schema_suites(l_index); --- l_index := l_suites_info.schema_suites.next(l_index); --- end loop; --- else --- l_suite := get_suite_filtered_by_path( convert_to_suite_path( l_path, l_suites_info.suite_paths ), l_suites_info.schema_suites ); --- l_objects_to_run.extend; --- l_objects_to_run(l_objects_to_run.count) := l_suite; --- end if; --- end loop; --- l_schema := l_schema_paths.next(l_schema); --- end loop; --- --- --propagate rollback type to suite items after organizing suites into hierarchy --- for i in 1 .. l_objects_to_run.count loop --- l_objects_to_run(i).set_rollback_type( l_objects_to_run(i).get_rollback_type() ); --- end loop; --- --- return l_objects_to_run; --- end configure_execution_by_path; - function group_paths_by_schema(a_paths ut_varchar2_list) return t_schema_paths is c_package_path_regex constant varchar2(100) := '^([A-Za-z0-9$#_]+)(\.([A-Za-z0-9$#_]+))?(\.([A-Za-z0-9$#_]+))?$'; l_schema varchar2(4000); @@ -409,6 +141,7 @@ create or replace package body ut_suite_manager is end loop; return l_results; end; + function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items is l_paths ut_varchar2_list := a_paths; l_path_items t_path_items; @@ -431,15 +164,12 @@ create or replace package body ut_suite_manager is l_path_items := l_schema_paths(l_schema); for i in 1 .. l_path_items.count loop l_path_item := l_path_items(i); - --whole schema - if l_path_item.object_name is null and l_path_item.suite_path is null then - l_suites := ut_suite_builder.build_schema_suites(upper(l_schema)); - --suite path - elsif l_path_item.suite_path is not null then - l_suites := ut_suite_builder.build_schema_suites(upper(l_schema), l_path_item.suite_path); - else - l_suites := ut_suite_builder.build_schema_suites(upper(l_schema), l_path_item.object_name, l_path_item.procedure_name); - end if; + l_suites := ut_suite_builder.build_schema_suites( + upper(l_schema), + l_path_item.suite_path, + l_path_item.object_name, + l_path_item.procedure_name + ); l_index := l_suites.first; while l_index is not null loop l_objects_to_run.extend; diff --git a/test/core/test_suite_builder.pkb b/test/core/test_suite_builder.pkb index 3216da333..edbee1e1a 100644 --- a/test/core/test_suite_builder.pkb +++ b/test/core/test_suite_builder.pkb @@ -4,17 +4,23 @@ create or replace package body test_suite_builder is a_annotations ut3.ut_annotations, a_package_name varchar2 := 'TEST_SUITE_BUILDER_PACKAGE' ) return clob is - l_suites ut3.ut_suite_builder.tt_schema_suites; + l_suites ut3.ut_suite_items; l_suite ut3.ut_logical_suite; l_cursor sys_refcursor; l_xml xmltype; begin open l_cursor for select value(x) from table( ut3.ut_annotated_objects( - ut3.ut_annotated_object('UT3_TESTER', a_package_name, 'PACKAGE', SYSDATE, a_annotations) + ut3.ut_annotated_object('UT3_TESTER', a_package_name, 'PACKAGE', systimestamp, a_annotations) ) ) x; - l_suites := ut3.ut_suite_builder.build_suites(l_cursor).schema_suites; - l_suite := l_suites(l_suites.first); + + l_suites := ut3.ut_suite_builder.build_suites_from_annotations( + a_owner_name => 'UT3_TESTER', + a_annotated_objects => l_cursor, + a_path => null, + a_object_name => a_package_name + ); + l_suite := treat( l_suites(l_suites.first) as ut3.ut_logical_suite); select deletexml( xmltype(l_suite), @@ -634,6 +640,9 @@ create or replace package body test_suite_builder is '%' || '%' || '%' || + '' || + '%suite_level_testIn suitesome_package.suite_level_test' || + '%' || '' || '%a_contextA contextsome_package.a_context' || '%' || @@ -646,9 +655,6 @@ create or replace package body test_suite_builder is '%' || '' || '' || - '' || - '%suite_level_testIn suitesome_package.suite_level_test' || - '%' || '' || '' || '%some_packagesuite_level_beforeall' || From 4dc48e676f14bae492c5c511f2ac500afa6a2674 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 4 Nov 2018 01:32:48 +0000 Subject: [PATCH 074/115] Interim commit - performance check on Travis. --- .../ut_annotation_cache_manager.pkb | 2 +- .../annotations/ut_annotation_manager.pkb | 2 +- source/core/ut_suite_builder.pkb | 244 ++++++++++++++---- source/core/ut_suite_builder.pks | 5 +- source/core/ut_suite_cache_manager.pkb | 81 +----- source/core/ut_suite_cache_manager.pks | 12 - source/core/ut_suite_manager.pkb | 11 +- .../create_synonyms_and_grants_for_public.sql | 4 + source/create_user_grants.sql | 4 + test/core/test_suite_builder.pkb | 11 +- test/core/test_suite_manager.pkb | 37 +-- 11 files changed, 244 insertions(+), 169 deletions(-) diff --git a/source/core/annotations/ut_annotation_cache_manager.pkb b/source/core/annotations/ut_annotation_cache_manager.pkb index c54d7eec3..9d7d1b95e 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pkb +++ b/source/core/annotations/ut_annotation_cache_manager.pkb @@ -92,7 +92,7 @@ create or replace package body ut_annotation_cache_manager as join ut_annotation_cache_info i on o.object_owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type join ut_annotation_cache c on i.cache_id = c.cache_id - where ]'|| case when a_parse_time is null then ':a_parse_date is null' else 'i.parse_time > :a_parse_time' end ||q'[ + where ]'|| case when a_parse_time is null then ':a_parse_date is null' else 'i.parse_time >= :a_parse_time' end ||q'[ group by i.object_owner, i.object_name, i.object_type, i.parse_time]' using a_cached_objects, a_parse_time; return l_results; diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb index 9ad1a9e79..afa66b2e4 100644 --- a/source/core/annotations/ut_annotation_manager.pkb +++ b/source/core/annotations/ut_annotation_manager.pkb @@ -44,7 +44,7 @@ create or replace package body ut_annotation_manager as || case when a_parse_date is null then ':a_parse_date is null' - else 'o.last_ddl_time > cast(:a_parse_date as date)' + else 'o.last_ddl_time >= cast(:a_parse_date as date)' end; open l_rows for l_cursor_text using a_object_owner, a_object_type, a_parse_date; fetch l_rows bulk collect into l_result limit 1000000; diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index 21e784f7e..358a563f4 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -98,6 +98,10 @@ create or replace package body ut_suite_builder is by_name tt_annotations_by_name ); + subtype t_cached_suite is ut_suite_cache%rowtype; + type tt_cached_suites is table of t_cached_suite; + type t_cached_suites_cursor is ref cursor return t_cached_suite; + procedure delete_annotations_range( a_annotations in out nocopy t_annotations_info, a_start_pos t_annotation_position, @@ -318,7 +322,10 @@ create or replace package body ut_suite_builder is l_pos t_annotation_position := a_list.first; begin while l_pos is not null loop - l_result := l_result multiset union all a_list(l_pos); + for i in 1 .. a_list(l_pos).count loop + l_result.extend; + l_result(l_result.last) := a_list(l_pos)(i); + end loop; l_pos := a_list.next(l_pos); end loop; return l_result; @@ -832,25 +839,6 @@ create or replace package body ut_suite_builder is end loop; end; - procedure add_parent_logical_suites( a_suite ut_suite, a_suite_items in out nocopy ut_suite_items) is - l_path varchar2(200); - l_name varchar2(200); - begin - l_path := a_suite.path; - loop - l_path := substr( l_path, 1, instr(l_path,'.',-1)-1); - exit when l_path is null; - l_name := substr( l_path, instr(l_path,'.',-1)+1); - a_suite_items.extend; - a_suite_items( a_suite_items.last) := - ut_logical_suite( - a_object_owner => a_suite.object_owner, - a_object_name => l_name, a_name => l_name, a_path => l_path - ); - a_suite_items( a_suite_items.last).parse_time := a_suite.parse_time; - end loop; - end; - procedure create_suite_item_list( a_annotations t_annotations_info, a_suite_items out nocopy ut_suite_items ) is l_annotations t_annotations_info := a_annotations; l_annotation_pos t_annotation_position; @@ -875,7 +863,6 @@ create or replace package body ut_suite_builder is a_suite_items.extend; a_suite_items( a_suite_items.last) := l_suite; - add_parent_logical_suites( l_suite, a_suite_items ); end if; end; @@ -905,14 +892,31 @@ create or replace package body ut_suite_builder is return l_result; end; + procedure copy_list_reverse_order( + a_list in out nocopy ut_suite_items + ) is + l_start_idx pls_integer; + l_end_idx pls_integer; + l_item ut_suite_item; + begin + l_start_idx := a_list.first; + l_end_idx := a_list.last; + while l_start_idx < l_end_idx loop + l_item := a_list(l_start_idx); + a_list(l_start_idx) := a_list(l_end_idx); + a_list(l_end_idx) := l_item; + l_end_idx := a_list.prior(l_end_idx); + l_start_idx := a_list.next(l_start_idx); + end loop; + end; + procedure reconstruct_from_cache( - a_suites in out nocopy ut_suite_items, + a_suites out nocopy ut_suite_items, a_suite_data_cursor sys_refcursor ) is type t_item_levels is table of ut_suite_items index by binary_integer; l_items_at_level t_item_levels; - l_rows ut_suite_cache_manager.tt_cached_suites; --- l_items ut_suite_items := ut_suite_items(); + l_rows tt_cached_suites; l_tests ut_suite_items := ut_suite_items(); l_logical_suites ut_logical_suites := ut_logical_suites(); l_level pls_integer; @@ -923,8 +927,6 @@ create or replace package body ut_suite_builder is loop if l_idx is null then fetch a_suite_data_cursor bulk collect into l_rows limit 1000; --- l_items.delete; --- l_items.extend(l_rows.count); l_tests.delete; l_tests.extend(l_rows.count); l_logical_suites.delete; @@ -932,12 +934,11 @@ create or replace package body ut_suite_builder is for i in 1 .. l_rows.count loop case l_rows(i).self_type when 'UT_TEST' then --- l_items(i) := l_tests(i) := ut_test( self_type => l_rows(i).self_type, - object_owner => l_rows(i).object_owner, object_name => l_rows(i).object_name, - name => l_rows(i).name, description => l_rows(i).description, path => l_rows(i).path, + object_owner => l_rows(i).object_owner, object_name => lower(l_rows(i).object_name), + name => lower(l_rows(i).name), description => l_rows(i).description, path => l_rows(i).path, rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, @@ -949,12 +950,11 @@ create or replace package body ut_suite_builder is parent_error_stack_trace => null, expected_error_codes => l_rows(i).expected_error_codes ); when 'UT_SUITE' then --- l_items(i) := l_logical_suites(i) := ut_suite( self_type => l_rows(i).self_type, - object_owner => l_rows(i).object_owner, object_name => l_rows(i).object_name, - name => l_rows(i).name, description => l_rows(i).description, path => l_rows(i).path, + object_owner => l_rows(i).object_owner, object_name => lower(l_rows(i).object_name), + name => lower(l_rows(i).name), description => l_rows(i).description, path => l_rows(i).path, rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, @@ -963,26 +963,26 @@ create or replace package body ut_suite_builder is before_all_list => l_rows(i).before_all_list, after_all_list => l_rows(i).after_all_list ); when 'UT_SUITE_CONTEXT' then --- l_items(i) := l_logical_suites(i) := ut_suite_context( self_type => l_rows(i).self_type, - object_owner => l_rows(i).object_owner, object_name => l_rows(i).object_name, name => l_rows(i).name, - description => l_rows(i).description, path => l_rows(i).path, rollback_type => l_rows(i).rollback_type, - disabled_flag => l_rows(i).disabled_flag, line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, + object_owner => l_rows(i).object_owner, object_name => lower(l_rows(i).object_name), + name => lower(l_rows(i).name), description => l_rows(i).description, path => l_rows(i).path, + rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, + line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items(), before_all_list => l_rows(i).before_all_list, after_all_list => l_rows(i).after_all_list ); when 'UT_LOGICAL_SUITE' then --- l_items(i) := l_logical_suites(i) := ut_logical_suite( self_type => l_rows(i).self_type, - object_owner => l_rows(i).object_owner, object_name => l_rows(i).object_name, name => l_rows(i).name, - description => l_rows(i).description, path => l_rows(i).path, rollback_type => l_rows(i).rollback_type, - disabled_flag => l_rows(i).disabled_flag, line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, + object_owner => l_rows(i).object_owner, object_name => lower(l_rows(i).object_name), + name => lower(l_rows(i).name), description => l_rows(i).description, path => l_rows(i).path, + rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, + line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items() @@ -992,13 +992,15 @@ create or replace package body ut_suite_builder is l_idx := l_rows.first; end if; exit when l_idx is null; + l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1; + if l_level > 1 then if l_prev_level > l_level then l_logical_suites(l_idx).items := l_items_at_level(l_prev_level); l_items_at_level(l_prev_level).delete; end if; - if not l_items_at_level.exists((l_level)) then + if not l_items_at_level.exists(l_level) then l_items_at_level(l_level) := ut_suite_items(); end if; l_items_at_level(l_level).extend; @@ -1019,29 +1021,140 @@ create or replace package body ut_suite_builder is a_suites(a_suites.last) := l_logical_suites(l_idx); end if; end if; --- if l_level = 0 then --- a_suites.extend; --- a_suites(a_suites.last) := l_items(l_idx); --- else --- a_suites(a_suites.last).add_item( l_items(l_idx), l_level ); --- end if; l_prev_level := l_level; l_idx := l_rows.next(l_idx); end loop; + copy_list_reverse_order( a_suites ); close a_suite_data_cursor; end; + function get_cached_suite_data( + a_object_owner varchar2, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null, + a_skip_all_objects boolean := false + ) return t_cached_suites_cursor is + l_path varchar2( 4000 ); + l_result sys_refcursor; + l_ut_owner varchar2(250) := ut_utils.ut_owner; + begin + if a_path is null and a_object_name is not null then + execute immediate 'select min(path) + from '||l_ut_owner||q'[.ut_suite_cache + where object_owner = :a_object_owner + and object_name = :a_object_name + and name = nvl(:a_procedure_name, name)]' + into l_path using upper(a_object_owner), upper(a_object_name), upper(a_procedure_name); + else + l_path := lower( a_path ); + end if; + + open l_result for + q'[with + suite_items as ( + select c.* + from ]'||l_ut_owner||q'[.ut_suite_cache c + where 1 = 1 ]'||case when a_skip_all_objects is null then q'[ + and exists + ( select 1 + from all_objects a + where a.object_name = c.object_name + and a.owner = c.object_owner + and a.object_type = 'PACKAGE' + )]' end ||q'[ + and c.object_owner = :a_object_owner + and ( ]' || case when l_path is not null then q'[ + :l_path||'.' like c.path || '.%' /*all children and self*/ + or ( c.path||'.' like :l_path || '.%' --all parents + ]' + else ' :l_path is null and ( :l_path is null ' end + || case when a_object_name is not null + then 'and c.object_name = :a_object_name ' + else 'and :a_object_name is null' end ||' + '|| case when a_procedure_name is not null + then 'and c.name = :a_procedure_name' + else 'and :a_procedure_name is null' end ||q'[ + ) + ) + ), + gen as ( + select rownum as pos + from xmltable('1 to 100') + ), + suitepaths as ( + select distinct substr(path,1,instr(path,'.',-1)-1) as suitepath, + path, + object_owner + from suite_items + where self_type = 'UT_SUITE' + ), + gen as ( + select rownum as pos + from xmltable('1 to 10') + ), + suitepath_part AS ( + select distinct + substr(b.suitepath, 1, instr(b.suitepath || '.', '.', 1, g.pos) -1) as path, + object_owner + from suitepaths b + join gen g + on g.pos <= regexp_count(b.suitepath, '\w+') + ), + logical_suite_data as ( + select 'UT_LOGICAL_SUITE' as self_type, p.path, p.object_owner, + upper( substr(p.path, instr( p.path, '.', -1 ) + 1 ) ) as object_name, + cast(null as ]'||l_ut_owner||q'[.ut_executables) as x, + cast(null as ]'||l_ut_owner||q'[.ut_integer_list) as y, + cast(null as ]'||l_ut_owner||q'[.ut_executable_test) as z + from suitepath_part p + where p.path + not in (select s.path from suitepaths s) + ), + logical_suites as ( + select s.self_type, s.path, s.object_owner, s.object_name, + s.object_name as name, null as line_no, null as parse_time, + null as description, null as rollback_type, 0 as disabled_flag, + ]'||l_ut_owner||q'[.ut_varchar2_rows() as warnings, + s.x as before_all_list, s.x as after_all_list, + s.x as before_each_list, s.x as before_test_list, + s.x as after_each_list, s.x as after_test_list, + s.y as expected_error_codes, s.z as item + from logical_suite_data s + ), + items as ( + select * from suite_items + union all + select * from logical_suites + ) + select c.* + from items c + order by c.object_owner, + replace(case + when c.self_type in ( 'UT_TEST' ) + then substr(c.path, 1, instr(c.path, '.', -1) ) + else c.path + end, '.', chr(0)) desc nulls last, + c.object_name desc, + c.line_no]' + using upper(a_object_owner), l_path, l_path, upper(a_object_name), upper(a_procedure_name); + + return l_result; + end; + function build_suites_from_annotations( a_owner_name varchar2, a_annotated_objects sys_refcursor, a_path varchar2 := null, a_object_name varchar2 := null, - a_procedure_name varchar2 := null + a_procedure_name varchar2 := null, + a_skip_all_objects boolean := false ) return ut_suite_items is l_suites ut_suite_items; l_annotations_cursor sys_refcursor; l_annotated_objects ut_annotated_objects; l_suite_items ut_suite_items; + l_suite_data_cursor sys_refcursor; begin loop fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; @@ -1059,11 +1172,13 @@ create or replace package body ut_suite_builder is reconstruct_from_cache( l_suites, - ut_suite_cache_manager.get_cached_suite_data( + get_cached_suite_data( a_owner_name, a_path, a_object_name, - a_procedure_name ) + a_procedure_name, + a_skip_all_objects + ) ); for i in 1 .. l_suites.count loop l_suites( i ).set_rollback_type( l_suites( i ).get_rollback_type ); @@ -1078,14 +1193,15 @@ create or replace package body ut_suite_builder is a_procedure_name varchar2 := null ) return ut_suite_items is l_annotations_cursor sys_refcursor; + l_suite_cache_time timestamp; begin - + l_suite_cache_time := ut_suite_cache_manager.get_schema_parse_time(a_owner_name); open l_annotations_cursor for q'[select value(x) from table( ]' || ut_utils.ut_owner || q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE', :a_suite_cache_parse_time) )x ]' - using a_owner_name, ut_suite_cache_manager.get_schema_parse_time(a_owner_name); + using a_owner_name, l_suite_cache_time; return build_suites_from_annotations( a_owner_name, @@ -1096,5 +1212,29 @@ create or replace package body ut_suite_builder is ); end; + function get_schema_ut_packages( a_schema_names ut_varchar2_rows ) return ut_object_names is + l_results ut_object_names := ut_object_names( ); + l_schema_names ut_varchar2_rows; + l_object_names ut_varchar2_rows; + l_ut_owner varchar2(250) := ut_utils.ut_owner; + begin + execute immediate 'select distinct c.object_owner, c.object_name + from '||l_ut_owner||q'[.ut_suite_cache c + join table ( :a_schema_names ) s + on c.object_owner = upper(s.column_value) +-- where exists +-- (select 1 from all_objects a +-- where a.owner = c.object_owner +-- and a.object_name = c.object_name +-- and a.object_type = 'PACKAGE') + ]' + bulk collect into l_schema_names, l_object_names using a_schema_names; + l_results.extend( l_schema_names.count ); + for i in 1 .. l_schema_names.count loop + l_results( i ) := ut_object_name( l_schema_names( i ), l_object_names( i ) ); + end loop; + return l_results; + end; + end ut_suite_builder; / diff --git a/source/core/ut_suite_builder.pks b/source/core/ut_suite_builder.pks index b3d07b0a8..881df24c9 100644 --- a/source/core/ut_suite_builder.pks +++ b/source/core/ut_suite_builder.pks @@ -37,12 +37,15 @@ create or replace package ut_suite_builder authid current_user is a_procedure_name varchar2 := null ) return ut_suite_items; + function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names; + function build_suites_from_annotations( a_owner_name varchar2, a_annotated_objects sys_refcursor, a_path varchar2 := null, a_object_name varchar2 := null, - a_procedure_name varchar2 := null + a_procedure_name varchar2 := null, + a_skip_all_objects boolean := false ) return ut_suite_items; end ut_suite_builder; diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb index 33712c589..cad718ee3 100644 --- a/source/core/ut_suite_cache_manager.pkb +++ b/source/core/ut_suite_cache_manager.pkb @@ -16,71 +16,6 @@ create or replace package body ut_suite_cache_manager is limitations under the License. */ - function get_cached_suite_data( - a_schema_name varchar2, - a_path varchar2 := null, - a_object_name varchar2 := null, - a_procedure_name varchar2 := null - ) return t_cached_suites_cursor is - l_path varchar2( 4000 ); - l_result sys_refcursor; - begin - if a_path is null and a_object_name is not null then - select min(path) into l_path - from ut_suite_cache - where object_owner = upper(a_schema_name) and object_name = lower(a_object_name) and - name = nvl(lower(a_procedure_name), name); - else - l_path := lower( a_path ); - end if; - - - open l_result for - select c.* - from ut_suite_cache c - -- join all_objects a - -- on a.owner = x.object_owner - -- and a.object_name = x.object_name - -- and a.object_type = 'PACKAGE' - where ( l_path like c.path || '.' || '%' - or ( c.path like l_path || '%' - and c.object_name = nvl(lower(a_object_name), c.object_name) - and c.name = nvl(lower(a_procedure_name), c.name) - ) - ) and c.object_owner = upper(a_schema_name) - order by c.object_owner, - replace(case - when c.self_type in ( 'UT_TEST' ) - then substr(c.path, 1, instr(c.path, '.', -1) - 1) - else c.path - end, '.', chr(0)) desc nulls last, - c.object_name desc, - c.line_no desc; - - return l_result; - end; - - - function get_schema_ut_packages( a_schema_names ut_varchar2_rows ) return ut_object_names is - l_results ut_object_names := ut_object_names( ); - l_schema_names ut_varchar2_rows; - l_object_names ut_varchar2_rows; - begin - select distinct c.object_owner, c.object_name - bulk collect into l_schema_names, l_object_names - from ut_suite_cache c - -- join all_objects a - -- on a.owner = c.object_owner - -- and a.object_name = c.object_name - -- and a.object_type = 'PACKAGE' - join table ( a_schema_names ) s on c.object_owner = upper(s.column_value); - l_results.extend( l_schema_names.count ); - for i in 1 .. l_schema_names.count loop - l_results( i ) := ut_object_name( l_schema_names( i ), l_object_names( i ) ); - end loop; - return l_results; - end; - function get_schema_parse_time(a_schema_name varchar2) return timestamp result_cache is l_cache_parse_time timestamp; begin @@ -95,6 +30,7 @@ create or replace package body ut_suite_cache_manager is pragma autonomous_transaction; l_parse_time timestamp; l_cached_parse_time timestamp; + l_object_owner varchar2(250) := upper(a_object_owner); begin if a_suite_items.count = 0 then return; @@ -115,17 +51,20 @@ create or replace package body ut_suite_cache_manager is update ut_suite_cache_schema t set t.parse_time = l_parse_time - where object_owner = a_object_owner; + where object_owner = l_object_owner; if sql%rowcount = 0 then insert into ut_suite_cache_schema (object_owner, parse_time) - values (a_object_owner, l_parse_time); + values (l_object_owner, l_parse_time); end if; delete from ut_suite_cache t where (t.object_name, t.object_owner) - in (select s.object_name, s.object_owner from table(a_suite_items) s where s.self_type != 'UT_LOGICAL_SUITE'); + in ( + select upper(s.object_name), upper(s.object_owner) + from table(a_suite_items) s where s.self_type != 'UT_LOGICAL_SUITE' + ); insert into ut_suite_cache t @@ -134,7 +73,7 @@ create or replace package body ut_suite_cache_manager is line_no, parse_time, description, rollback_type, disabled_flag, warnings ) - select self_type, path, object_owner, object_name, name, + select self_type, path, upper(object_owner), upper(object_name), upper(name), line_no, parse_time, description, rollback_type, disabled_flag, warnings from table(a_suite_items) s @@ -155,7 +94,7 @@ create or replace package body ut_suite_cache_manager is from table(a_suite_items) x where x.self_type in( 'UT_SUITE', 'UT_SUITE_CONTEXT' ) ) select s.i.self_type as self_type, s.i.path as path, - s.i.object_owner as object_owner, s.i.object_name as object_name, s.i.name as name, + upper(s.i.object_owner) as object_owner, upper(s.i.object_name) as object_name, upper(s.i.name) as name, s.i.line_no as line_no, s.i.parse_time as parse_time, s.i.description as description, s.i.rollback_type as rollback_type, s.i.disabled_flag as disabled_flag, s.i.warnings as warnings, s.i.before_all_list as before_all_list, s.i.after_all_list as after_all_list, @@ -178,7 +117,7 @@ create or replace package body ut_suite_cache_manager is from table ( a_suite_items ) x where x.self_type in ( 'UT_TEST' ) ) select s.t.self_type as self_type, s.t.path as path, - s.t.object_owner as object_owner, s.t.object_name as object_name, s.t.name as name, + upper(s.t.object_owner) as object_owner, upper(s.t.object_name) as object_name, upper(s.t.name) as name, s.t.line_no as line_no, s.t.parse_time as parse_time, s.t.description as description, s.t.rollback_type as rollback_type, s.t.disabled_flag as disabled_flag, s.t.warnings as warnings, null before_all_list, null after_all_list, diff --git a/source/core/ut_suite_cache_manager.pks b/source/core/ut_suite_cache_manager.pks index f5da97ec7..919196efa 100644 --- a/source/core/ut_suite_cache_manager.pks +++ b/source/core/ut_suite_cache_manager.pks @@ -19,21 +19,9 @@ create or replace package ut_suite_cache_manager authid definer is /** * Responsible for storing and retrieving suite data from cache */ - subtype t_cached_suite is ut_suite_cache%rowtype; - type tt_cached_suites is table of t_cached_suite; - type t_cached_suites_cursor is ref cursor return t_cached_suite; procedure save_cache(a_object_owner varchar2, a_suite_items ut_suite_items); - function get_cached_suite_data( - a_schema_name varchar2, - a_path varchar2 := null, - a_object_name varchar2 := null, - a_procedure_name varchar2 := null - ) return t_cached_suites_cursor; - - function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names; - function get_schema_parse_time(a_schema_name varchar2) return timestamp result_cache; end ut_suite_cache_manager; diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index 04bc26f10..4aab5503b 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -29,7 +29,7 @@ create or replace package body ut_suite_manager is function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names is begin - return ut_suite_cache_manager.get_schema_ut_packages(a_schema_names); + return ut_suite_builder.get_schema_ut_packages(a_schema_names); end; procedure validate_paths(a_paths in ut_varchar2_list) is @@ -170,6 +170,15 @@ create or replace package body ut_suite_manager is l_path_item.object_name, l_path_item.procedure_name ); + if l_suites.count = 0 then + if l_path_item.suite_path is not null then + raise_application_error(ut_utils.gc_suite_package_not_found,'No suite packages found for path '||l_schema||':'||l_path_item.suite_path|| '.'); + elsif l_path_item.procedure_name is not null then + 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'); + else + raise_application_error(ut_utils.gc_suite_package_not_found,'Suite package '||l_schema||'.'||l_path_item.object_name|| ' does not exist'); + end if; + end if; l_index := l_suites.first; while l_index is not null loop l_objects_to_run.extend; diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql index 1ac5bb9ea..f22a61121 100644 --- a/source/create_synonyms_and_grants_for_public.sql +++ b/source/create_synonyms_and_grants_for_public.sql @@ -86,6 +86,10 @@ grant execute on &&ut3_owner..ut_annotated_object to public; grant execute on &&ut3_owner..ut_annotated_objects to public; grant select on &&ut3_owner..ut_annotation_cache_info to public; grant select on &&ut3_owner..ut_annotation_cache to public; +grant execute on &&ut3_owner..ut_executables to public; +grant execute on &&ut3_owner..ut_executable_test to public; +grant select on &&ut3_owner..ut_suite_cache to public; +grant select on &&ut3_owner..ut_suite_cache_schema to public; grant execute on &&ut3_owner..ut_annotation_cache_manager to public; grant execute on &&ut3_owner..ut_annotation_parser to public; grant execute on &&ut3_owner..ut_annotation_objs_cache_info to public; diff --git a/source/create_user_grants.sql b/source/create_user_grants.sql index 07d9097f3..723fcca58 100644 --- a/source/create_user_grants.sql +++ b/source/create_user_grants.sql @@ -106,6 +106,10 @@ grant execute on &&ut3_owner..ut_annotated_object to &ut3_user; grant execute on &&ut3_owner..ut_annotated_objects to &ut3_user; grant select on &&ut3_owner..ut_annotation_cache_info to &ut3_user; grant select on &&ut3_owner..ut_annotation_cache to &ut3_user; +grant execute on &&ut3_owner..ut_executables to &ut3_user; +grant execute on &&ut3_owner..ut_executable_test to &ut3_user; +grant select on &&ut3_owner..ut_suite_cache to &ut3_user; +grant select on &&ut3_owner..ut_suite_cache_schema to &ut3_user; grant execute on &&ut3_owner..ut_annotation_cache_manager to &ut3_user; grant execute on &&ut3_owner..ut_annotation_parser to &ut3_user; grant execute on &&ut3_owner..ut_annotation_objs_cache_info to &ut3_user; diff --git a/test/core/test_suite_builder.pkb b/test/core/test_suite_builder.pkb index edbee1e1a..e55830266 100644 --- a/test/core/test_suite_builder.pkb +++ b/test/core/test_suite_builder.pkb @@ -18,7 +18,8 @@ create or replace package body test_suite_builder is a_owner_name => 'UT3_TESTER', a_annotated_objects => l_cursor, a_path => null, - a_object_name => a_package_name + a_object_name => a_package_name, + a_skip_all_objects => true ); l_suite := treat( l_suites(l_suites.first) as ut3.ut_logical_suite); @@ -395,7 +396,7 @@ create or replace package body test_suite_builder is ut3.ut_annotation(1, 'suite','Cool', null), ut3.ut_annotation(2, 'beforeall',null, 'first_before_all'), ut3.ut_annotation(3, 'beforeall',null, 'another_before_all'), - ut3.ut_annotation(4, 'beforeeach',null, 'first_bfore_each'), + ut3.ut_annotation(4, 'beforeeach',null, 'first_before_each'), ut3.ut_annotation(5, 'beforeeach',null, 'another_before_each'), ut3.ut_annotation(6, 'aftereach',null, 'first_after_each'), ut3.ut_annotation(7, 'aftereach',null, 'another_after_each'), @@ -640,9 +641,6 @@ create or replace package body test_suite_builder is '%' || '%' || '%' || - '' || - '%suite_level_testIn suitesome_package.suite_level_test' || - '%' || '' || '%a_contextA contextsome_package.a_context' || '%' || @@ -655,6 +653,9 @@ create or replace package body test_suite_builder is '%' || '' || '' || + '' || + '%suite_level_testIn suitesome_package.suite_level_test' || + '%' || '' || '' || '%some_packagesuite_level_beforeall' || diff --git a/test/core/test_suite_manager.pkb b/test/core/test_suite_manager.pkb index 59f1f42ea..5d7e91f3d 100644 --- a/test/core/test_suite_manager.pkb +++ b/test/core/test_suite_manager.pkb @@ -313,7 +313,7 @@ end test_package_with_ctx;]'; ut.expect(l_test1_suite.name).to_equal('test_package_1'); ut.expect(l_test1_suite.items.count).to_equal(3); ut.expect(l_test1_suite.rollback_type).to_equal(ut3.ut_utils.gc_rollback_manual); - l_test2_suite := treat(l_test1_suite.items(3) as ut3.ut_logical_suite); + l_test2_suite := treat(l_test1_suite.items(1) as ut3.ut_logical_suite); ut.expect(l_test2_suite.name).to_equal('test_package_2'); ut.expect(l_test2_suite.items.count).to_equal(3); @@ -515,7 +515,6 @@ end test_package_with_ctx;]'; l_test0_suite ut3.ut_logical_suite; l_test1_suite ut3.ut_suite; - l_test2_suite ut3.ut_suite; begin --Act l_objects_to_run := ut3.ut_suite_manager.configure_execution_by_path(ut3.ut_varchar2_list(c_path)); @@ -529,7 +528,7 @@ end test_package_with_ctx;]'; l_test1_suite := treat(l_test0_suite.items(1) as ut3.ut_suite); ut.expect(l_test1_suite.name).to_equal('test_package_1'); - ut.expect(l_test1_suite.items.count).to_equal(3); + ut.expect(l_test1_suite.items.count).to_equal(2); ut.expect(l_test1_suite.items(1).name).to_equal('test1'); ut.expect(l_test1_suite.items(1).description).to_equal('Test1 from test package 1'); @@ -545,12 +544,6 @@ end test_package_with_ctx;]'; ut.expect(treat(l_test1_suite.items(2) as ut3.ut_test).before_each_list.count).to_be_greater_than(0); ut.expect(treat(l_test1_suite.items(2) as ut3.ut_test).disabled_flag).to_equal(0); - -- temporary behavior. - -- decided that when executed by package, not path, only that package has to execute - l_test2_suite := treat(l_test1_suite.items(3) as ut3.ut_suite); - - ut.expect(l_test2_suite.name).to_equal('test_package_2'); - ut.expect(l_test2_suite.items.count).to_equal(3); end; procedure test_top_pack_by_name_cu is @@ -573,7 +566,7 @@ end test_package_with_ctx;]'; l_test1_suite := treat(l_test0_suite.items(1) as ut3.ut_suite); ut.expect(l_test1_suite.name).to_equal('test_package_1'); - ut.expect(l_test1_suite.items.count).to_equal(3); + ut.expect(l_test1_suite.items.count).to_equal(2); ut.expect(l_test1_suite.items(1).name).to_equal('test1'); ut.expect(l_test1_suite.items(1).description).to_equal('Test1 from test package 1'); @@ -589,12 +582,6 @@ end test_package_with_ctx;]'; ut.expect(treat(l_test1_suite.items(2) as ut3.ut_test).before_each_list.count).to_be_greater_than(0); ut.expect(treat(l_test1_suite.items(2) as ut3.ut_test).disabled_flag).to_equal(0); - -- temporary behavior. - -- decided that when executed by package, not path, only that package has to execute - l_test2_suite := treat(l_test1_suite.items(3) as ut3.ut_suite); - - ut.expect(l_test2_suite.name).to_equal('test_package_2'); - ut.expect(l_test2_suite.items.count).to_equal(3); end; procedure test_top_pack_by_path is @@ -618,7 +605,7 @@ end test_package_with_ctx;]'; ut.expect(l_test1_suite.name).to_equal('test_package_1'); ut.expect(l_test1_suite.items.count).to_equal(3); - l_test2_suite := treat(l_test1_suite.items(3) as ut3.ut_logical_suite); + l_test2_suite := treat(l_test1_suite.items(1) as ut3.ut_logical_suite); ut.expect(l_test2_suite.name).to_equal('test_package_2'); ut.expect(l_test2_suite.items.count).to_equal(3); @@ -645,7 +632,7 @@ end test_package_with_ctx;]'; ut.expect(l_test1_suite.name).to_equal('test_package_1'); ut.expect(l_test1_suite.items.count).to_equal(3); - l_test2_suite := treat(l_test1_suite.items(3) as ut3.ut_logical_suite); + l_test2_suite := treat(l_test1_suite.items(1) as ut3.ut_logical_suite); ut.expect(l_test2_suite.name).to_equal('test_package_2'); ut.expect(l_test2_suite.items.count).to_equal(3); @@ -942,7 +929,7 @@ end;]'; l_objects_to_run ut3.ut_suite_items; begin l_objects_to_run := ut3.ut_suite_manager.configure_execution_by_path(ut3.ut_varchar2_list('ut3.failing_non_existing')); - ut.fail('Non existing package didnt raised exception'); + ut.fail('Non existing package did not raise exception'); exception when others then ut.expect(sqlerrm).to_be_like('%failing_non_existing%'); @@ -952,7 +939,7 @@ end;]'; l_objects_to_run ut3.ut_suite_items; begin l_objects_to_run := ut3.ut_suite_manager.configure_execution_by_path(ut3.ut_varchar2_list('failing_non_existing')); - ut.fail('Non existing package without schema didnt raised exception'); + ut.fail('Non existing package without schema did not raise exception'); exception when others then ut.expect(sqlerrm).to_be_like('%ORA-44001: invalid schema%'); @@ -979,10 +966,10 @@ end;]'; ut.expect(l_test.name).to_equal('test1'); ut.expect(l_test.description).to_equal('A test description, though with comma, is assigned by suite_manager'); - l_test := treat(l_suite.items(2) as ut3.ut_test); - - ut.expect(l_test.name).to_equal('test2'); - ut.expect(l_test.description).to_equal('A test description, though with comma, is assigned by suite_manager'); +-- l_test := treat(l_suite.items(2) as ut3.ut_test); +-- +-- ut.expect(l_test.name).to_equal('test2'); +-- ut.expect(l_test.description).to_equal('A test description, though with comma, is assigned by suite_manager'); end; procedure setup_desc_with_comma is @@ -1029,7 +1016,7 @@ end;'; ut.fail('Cache not invalidated on package drop'); exception when others then - ut.expect(sqlerrm).to_be_like('%tst_package_to_be_dropped%not found%'); + ut.expect(sqlerrm).to_be_like('%tst_package_to_be_dropped%does not exist%'); end; end; From 1611e09b15c5896c9146fe60c7f8b836250c3cea Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 4 Nov 2018 18:30:31 +0000 Subject: [PATCH 075/115] Interim commit some fixes to old tests, examples and code itself. One problem to be solved. Oracle nested tables are **unordered!** and we need an ordered list of before/after items that contain CLOB column, so cannot be varray. --- ...nExampleComplexSuiteWithCustomReporter.sql | 8 +- .../RunExampleTestSuite.sql | 6 +- ...nExampleTestSuiteWithCompositeReporter.sql | 6 +- .../RunExampleTestSuiteWithCustomReporter.sql | 6 +- ...rter.providesCorrectLineFromStacktrace.sql | 2 +- ...e_manager.CacheInvalidaesOnPackageDrop.sql | 12 +- ..._packages.IncludesPackagesWithSutePath.sql | 13 +- .../ut_test/ut_test.AfterEachExecuted.sql | 5 +- .../ut_test.AfterEachProcedureNameInvalid.sql | 5 +- .../ut_test.AfterEachProcedureNameNull.sql | 5 +- .../ut_test/ut_test.BeforeEachExecuted.sql | 5 +- ...ut_test.BeforeEachProcedureNameInvalid.sql | 5 +- .../ut_test.BeforeEachProcedureNameNull.sql | 5 +- ...est.IgnoreTollbackToSavepointException.sql | 2 +- .../ut_test/ut_test.OwnerNameInvalid.sql | 6 +- old_tests/ut_test/ut_test.OwnerNameNull.sql | 6 +- .../ut_test/ut_test.PackageInInvalidState.sql | 2 +- .../ut_test/ut_test.PackageNameInvalid.sql | 2 +- old_tests/ut_test/ut_test.PackageNameNull.sql | 2 +- .../ut_test/ut_test.ProcedureNameInvalid.sql | 2 +- .../ut_test/ut_test.ProcedureNameNull.sql | 2 +- .../ut_test.SetupExecutedBeforeTest.sql | 5 +- .../ut_test.SetupProcedureNameInvalid.sql | 5 +- .../ut_test.SetupProcedureNameNull.sql | 5 +- .../ut_test.TeardownExecutedAfterTest.sql | 5 +- .../ut_test.TeardownProcedureNameInvalid.sql | 5 +- .../ut_test.TeardownProcedureNameNull.sql | 5 +- .../annotations/ut_annotation_cache_seq.sql | 2 +- source/core/ut_suite_builder.pkb | 18 +- source/core/ut_suite_cache.sql | 12 +- source/core/ut_suite_cache_manager.pkb | 185 +++++++++--------- source/core/ut_suite_cache_manager.pks | 7 +- source/core/ut_suite_cache_package.sql | 23 +++ source/core/ut_suite_cache_seq.sql | 16 ++ .../create_synonyms_and_grants_for_public.sql | 1 + source/create_user_grants.sql | 1 + source/install.sql | 2 + test/core/test_suite_builder.pkb | 2 +- 38 files changed, 250 insertions(+), 156 deletions(-) create mode 100644 source/core/ut_suite_cache_package.sql create mode 100644 source/core/ut_suite_cache_seq.sql diff --git a/examples/developer_examples/RunExampleComplexSuiteWithCustomReporter.sql b/examples/developer_examples/RunExampleComplexSuiteWithCustomReporter.sql index 1b9e94bfb..406a1cba2 100644 --- a/examples/developer_examples/RunExampleComplexSuiteWithCustomReporter.sql +++ b/examples/developer_examples/RunExampleComplexSuiteWithCustomReporter.sql @@ -22,8 +22,8 @@ begin ut_event_manager.initialize(); l_parent_suite := ut_logical_suite( a_object_owner=>null, a_object_name => null, a_name => 'complex_test_suite', a_path => null); - l_suite := ut_suite(user, 'ut_exampletest'); - l_test := ut_test(user, 'ut_exampletest','ut_exAmpletest'); + l_suite := ut_suite(user, 'ut_exampletest',a_line_no=>1); + l_test := ut_test(user, 'ut_exampletest','ut_exAmpletest',a_line_no=>3); l_test.description := 'Example test1'; l_test.before_test_list := ut_executables(ut_executable(user, 'ut_exampletest','Setup',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'ut_exampletest','tEardown',ut_utils.gc_after_test)); @@ -32,8 +32,8 @@ begin l_parent_suite.add_item(l_suite); - l_suite := ut_suite(user, 'ut_exampletest2'); - l_test := ut_test(user, 'UT_EXAMPLETEST2','UT_EXAMPLETEST'); + l_suite := ut_suite(user, 'ut_exampletest2',a_line_no=>1); + l_test := ut_test(user, 'UT_EXAMPLETEST2','UT_EXAMPLETEST',a_line_no=>3); l_test.before_test_list := ut_executables(ut_executable(user, 'UT_EXAMPLETEST2','SETUP',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'UT_EXAMPLETEST2','TEARDOWN',ut_utils.gc_after_test)); diff --git a/examples/developer_examples/RunExampleTestSuite.sql b/examples/developer_examples/RunExampleTestSuite.sql index a0a470e46..7b01d1154 100644 --- a/examples/developer_examples/RunExampleTestSuite.sql +++ b/examples/developer_examples/RunExampleTestSuite.sql @@ -15,15 +15,15 @@ declare l_test ut_test; l_expectation ut_expectation_result; begin - l_suite := ut_suite(user, 'ut_exampletest'); + l_suite := ut_suite(user, 'ut_exampletest',a_line_no=>1); l_suite.description := 'Test Suite Name'; - l_test := ut_test(user, 'ut_exampletest','ut_exAmpletest'); + l_test := ut_test(user, 'ut_exampletest','ut_exAmpletest',a_line_no=>3); l_test.description := 'Example test1'; l_test.before_test_list := ut_executables(ut_executable(user, 'ut_exampletest','Setup',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'ut_exampletest','tEardown',ut_utils.gc_after_test)); l_suite.add_item(l_test); - l_test := ut_test(user, 'UT_EXAMPLETEST2','ut_exAmpletest'); + l_test := ut_test(user, 'UT_EXAMPLETEST2','ut_exAmpletest',a_line_no=>6); l_test.description := 'Another example test'; l_test.before_test_list := ut_executables(ut_executable(user, 'UT_EXAMPLETEST2','SETUP',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'UT_EXAMPLETEST2','TEARDOWN',ut_utils.gc_after_test)); diff --git a/examples/developer_examples/RunExampleTestSuiteWithCompositeReporter.sql b/examples/developer_examples/RunExampleTestSuiteWithCompositeReporter.sql index 4f9172510..8876f0874 100644 --- a/examples/developer_examples/RunExampleTestSuiteWithCompositeReporter.sql +++ b/examples/developer_examples/RunExampleTestSuiteWithCompositeReporter.sql @@ -21,11 +21,11 @@ begin ut_event_manager.add_listener(l_doc_reporter); ut_event_manager.add_listener(l_tc_reporter); - suite := ut_suite(user, 'ut_exampletest'); + suite := ut_suite(user, 'ut_exampletest',a_line_no=>1); suite.description := 'Test Suite Name'; - suite.add_item(ut_test(user,'ut_exampletest','ut_exAmpletest')); - suite.add_item(ut_test(user, 'UT_EXAMPLETEST2','UT_EXAMPLETEST')); + suite.add_item(ut_test(user,'ut_exampletest','ut_exAmpletest',a_line_no=>3)); + suite.add_item(ut_test(user, 'UT_EXAMPLETEST2','UT_EXAMPLETEST',a_line_no=>6)); -- provide a reporter to process results l_run := ut_run(ut_suite_items(suite)); diff --git a/examples/developer_examples/RunExampleTestSuiteWithCustomReporter.sql b/examples/developer_examples/RunExampleTestSuiteWithCustomReporter.sql index 59fe15662..e9403809e 100644 --- a/examples/developer_examples/RunExampleTestSuiteWithCustomReporter.sql +++ b/examples/developer_examples/RunExampleTestSuiteWithCustomReporter.sql @@ -22,15 +22,15 @@ begin ut_event_manager.initialize(); -- Install ut_custom_reporter first from example folder - l_suite := ut_suite(user, 'ut_exampletest'); + l_suite := ut_suite(user, 'ut_exampletest',a_line_no=>1); - l_test := ut_test(user, 'ut_exampletest','ut_exAmpletest'); + l_test := ut_test(user, 'ut_exampletest','ut_exAmpletest',a_line_no=>3); l_test.description := 'Example test1'; l_test.before_test_list := ut_executables(ut_executable(user, 'ut_exampletest','Setup',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'ut_exampletest','tEardown',ut_utils.gc_after_test)); l_suite.add_item(l_test); - l_test := ut_test(user, 'UT_EXAMPLETEST2','ut_exAmpletest'); + l_test := ut_test(user, 'UT_EXAMPLETEST2','ut_exAmpletest',a_line_no=>6); l_test.description := 'Another example test'; l_test.before_test_list := ut_executables(ut_executable(user, 'ut_exampletest','SETUP',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'ut_exampletest','TEARDOWN',ut_utils.gc_after_test)); diff --git a/old_tests/ut_reporters/ut_documentation_reporter.providesCorrectLineFromStacktrace.sql b/old_tests/ut_reporters/ut_documentation_reporter.providesCorrectLineFromStacktrace.sql index 66cf41b32..f155117fe 100644 --- a/old_tests/ut_reporters/ut_documentation_reporter.providesCorrectLineFromStacktrace.sql +++ b/old_tests/ut_reporters/ut_documentation_reporter.providesCorrectLineFromStacktrace.sql @@ -18,7 +18,7 @@ Finished % --act select * bulk collect into l_output_data - from table(ut.run('test_reporters',ut_documentation_reporter())); + from table(ut.run(':org.utplsql.utplsql.test.test_reporters',ut_documentation_reporter())); l_output := ut_utils.table_to_clob(l_output_data); diff --git a/old_tests/ut_suite_manager/ut_suite_manager.CacheInvalidaesOnPackageDrop.sql b/old_tests/ut_suite_manager/ut_suite_manager.CacheInvalidaesOnPackageDrop.sql index 6581a9eeb..9715eae8b 100644 --- a/old_tests/ut_suite_manager/ut_suite_manager.CacheInvalidaesOnPackageDrop.sql +++ b/old_tests/ut_suite_manager/ut_suite_manager.CacheInvalidaesOnPackageDrop.sql @@ -28,19 +28,23 @@ drop package tst_package_to_be_dropped set termout on declare - l_test_report ut_varchar2_list; + l_test_report ut_varchar2_list; + l_error_message varchar2(4000); + l_expected varchar2(4000); begin + l_expected := '%tst_package_to_be_dropped%does not exist%'; begin select * bulk collect into l_test_report from table(ut.run(user || '.tst_package_to_be_dropped')); exception when others then - if sqlerrm like '%tst_package_to_be_dropped%not found%' then + l_error_message := sqlerrm; + if l_error_message like l_expected then :test_result := ut_utils.gc_success; end if; end; if :test_result != ut_utils.gc_success or :test_result is null then - dbms_output.put_line('Failed: Expected exception with text like ''%tst_package_to_be_dropped%not found%'' but got:''' || - sqlerrm || ''''); + dbms_output.put_line('Failed: Expected exception with text like '''||l_expected||''' but got:''' || + l_error_message || ''''); end if; end; / diff --git a/old_tests/ut_suite_manager/ut_suite_manager.get_schema_ut_packages.IncludesPackagesWithSutePath.sql b/old_tests/ut_suite_manager/ut_suite_manager.get_schema_ut_packages.IncludesPackagesWithSutePath.sql index 3023c28f0..0f446b7bf 100644 --- a/old_tests/ut_suite_manager/ut_suite_manager.get_schema_ut_packages.IncludesPackagesWithSutePath.sql +++ b/old_tests/ut_suite_manager/ut_suite_manager.get_schema_ut_packages.IncludesPackagesWithSutePath.sql @@ -6,8 +6,9 @@ end; set termout on declare - l_expected ut_object_names; - l_actual ut_object_names; + l_expected ut_object_names; + l_actual ut_object_names; + l_not_found ut_object_names := ut_object_names(); begin l_expected := ut_object_names( ut_object_name(user,'TEST_PACKAGE_1'), @@ -17,7 +18,13 @@ begin ut_object_name(user,'TEST_REPORTERS') ); l_actual := ut_suite_manager.get_schema_ut_packages(ut_varchar2_rows(user)); - if l_actual = l_expected then + for i in 1 .. l_expected.count loop + if l_expected(i) not member of l_actual then + l_not_found.extend; + l_not_found(l_not_found.last) := l_expected(i); + end if; + end loop; + if l_not_found is empty then :test_result := ut_utils.gc_success; else dbms_output.put_line('actual:'||xmltype(anydata.convertcollection(l_actual)).getclobval()); diff --git a/old_tests/ut_test/ut_test.AfterEachExecuted.sql b/old_tests/ut_test/ut_test.AfterEachExecuted.sql index e35564b7b..5711c38e9 100644 --- a/old_tests/ut_test/ut_test.AfterEachExecuted.sql +++ b/old_tests/ut_test/ut_test.AfterEachExecuted.sql @@ -3,8 +3,9 @@ PROMPT Invoke aftereach procedure --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_passing_test' + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null ); begin simple_test.after_each_list := ut_executables(ut_executable(user, 'ut_example_tests', 'aftereach', ut_utils.gc_after_each)); diff --git a/old_tests/ut_test/ut_test.AfterEachProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.AfterEachProcedureNameInvalid.sql index 4d12cd513..15765a811 100644 --- a/old_tests/ut_test/ut_test.AfterEachProcedureNameInvalid.sql +++ b/old_tests/ut_test/ut_test.AfterEachProcedureNameInvalid.sql @@ -3,8 +3,9 @@ PROMPT Does not execute test and reports error when test aftereach procedure nam --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_exampletest' + a_object_name => 'ut_example_tests', + a_name => 'ut_exampletest', + a_line_no => null ); begin simple_test.after_each_list := ut_executables(ut_executable(user, 'ut_example_tests', 'invalid setup name', ut_utils.gc_after_each)); diff --git a/old_tests/ut_test/ut_test.AfterEachProcedureNameNull.sql b/old_tests/ut_test/ut_test.AfterEachProcedureNameNull.sql index 2700e1a10..f40ee8c04 100644 --- a/old_tests/ut_test/ut_test.AfterEachProcedureNameNull.sql +++ b/old_tests/ut_test/ut_test.AfterEachProcedureNameNull.sql @@ -3,8 +3,9 @@ PROMPT Does not invoke aftereach procedure when aftereach procedure name for a t --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_passing_test' + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null ); begin simple_test.after_each_list := ut_executables(ut_executable(user, 'ut_example_tests', '', ut_utils.gc_after_each)); diff --git a/old_tests/ut_test/ut_test.BeforeEachExecuted.sql b/old_tests/ut_test/ut_test.BeforeEachExecuted.sql index 5015d69fd..9d40441ac 100644 --- a/old_tests/ut_test/ut_test.BeforeEachExecuted.sql +++ b/old_tests/ut_test/ut_test.BeforeEachExecuted.sql @@ -3,8 +3,9 @@ PROMPT Invoke beforeeach procedure --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_passing_test' + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null ); begin simple_test.before_each_list := ut_executables(ut_executable(user, 'ut_example_tests', 'beforeeach', ut_utils.gc_before_each)); diff --git a/old_tests/ut_test/ut_test.BeforeEachProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.BeforeEachProcedureNameInvalid.sql index f03b76f08..5a9d40a58 100644 --- a/old_tests/ut_test/ut_test.BeforeEachProcedureNameInvalid.sql +++ b/old_tests/ut_test/ut_test.BeforeEachProcedureNameInvalid.sql @@ -3,8 +3,9 @@ PROMPT Does not execute test and reports error when test beforeeach procedure na --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_exampletest' + a_object_name => 'ut_example_tests', + a_name => 'ut_exampletest', + a_line_no => null ); begin simple_test.before_each_list := ut_executables(ut_executable(user, 'ut_example_tests', 'invalid setup name', ut_utils.gc_before_each)); diff --git a/old_tests/ut_test/ut_test.BeforeEachProcedureNameNull.sql b/old_tests/ut_test/ut_test.BeforeEachProcedureNameNull.sql index e717b128f..66107c462 100644 --- a/old_tests/ut_test/ut_test.BeforeEachProcedureNameNull.sql +++ b/old_tests/ut_test/ut_test.BeforeEachProcedureNameNull.sql @@ -3,8 +3,9 @@ PROMPT Does not invoke setup procedure when beforeeach procedure name for a test --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_passing_test' + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null ); begin simple_test.before_each_list := ut_executables(ut_executable(user, 'ut_example_tests', '', ut_utils.gc_before_each)); diff --git a/old_tests/ut_test/ut_test.IgnoreTollbackToSavepointException.sql b/old_tests/ut_test/ut_test.IgnoreTollbackToSavepointException.sql index 94ad60c3d..3e3c1a814 100644 --- a/old_tests/ut_test/ut_test.IgnoreTollbackToSavepointException.sql +++ b/old_tests/ut_test/ut_test.IgnoreTollbackToSavepointException.sql @@ -2,7 +2,7 @@ PROMPT Checks that rollback exception does not make run to fail --Arrange declare - simple_test ut_test := ut_test(a_object_name => 'ut_example_tests', a_name => 'ut_commit_test'); + simple_test ut_test := ut_test(a_object_name => 'ut_example_tests', a_name => 'ut_commit_test', a_line_no => null); begin simple_test.rollback_type := ut_utils.gc_rollback_auto; --Act diff --git a/old_tests/ut_test/ut_test.OwnerNameInvalid.sql b/old_tests/ut_test/ut_test.OwnerNameInvalid.sql index ba19e0767..5207af574 100644 --- a/old_tests/ut_test/ut_test.OwnerNameInvalid.sql +++ b/old_tests/ut_test/ut_test.OwnerNameInvalid.sql @@ -2,7 +2,11 @@ PROMPT Reports error when test owner name for a test is invalid --Arrange declare - simple_test ut_test := ut_test( a_object_owner => 'invalid owner name', a_object_name => 'ut_example_tests', a_name => 'ut_passing_test'); + simple_test ut_test := ut_test( + a_object_owner => 'invalid owner name', + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null); begin --Act simple_test.do_execute(); diff --git a/old_tests/ut_test/ut_test.OwnerNameNull.sql b/old_tests/ut_test/ut_test.OwnerNameNull.sql index 68acf9144..f57aebf92 100644 --- a/old_tests/ut_test/ut_test.OwnerNameNull.sql +++ b/old_tests/ut_test/ut_test.OwnerNameNull.sql @@ -2,7 +2,11 @@ PROMPT Executes test in current schema when test owner name for a test is null --Arrange declare - simple_test ut_test:= ut_test(a_object_owner => null, a_object_name => 'ut_example_tests', a_name => 'ut_passing_test'); + simple_test ut_test:= ut_test( + a_object_owner => null, + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null); begin --Act simple_test.do_execute(); diff --git a/old_tests/ut_test/ut_test.PackageInInvalidState.sql b/old_tests/ut_test/ut_test.PackageInInvalidState.sql index 31056dcfd..0b87a13d6 100644 --- a/old_tests/ut_test/ut_test.PackageInInvalidState.sql +++ b/old_tests/ut_test/ut_test.PackageInInvalidState.sql @@ -8,7 +8,7 @@ end; set termout on declare - simple_test ut_test := ut_test(a_object_name => 'invalid_package', a_name => 'ut_exampletest'); + simple_test ut_test := ut_test(a_object_name => 'invalid_package', a_name => 'ut_exampletest', a_line_no => null); begin --Act simple_test.do_execute(); diff --git a/old_tests/ut_test/ut_test.PackageNameInvalid.sql b/old_tests/ut_test/ut_test.PackageNameInvalid.sql index 246af45db..b615e7589 100644 --- a/old_tests/ut_test/ut_test.PackageNameInvalid.sql +++ b/old_tests/ut_test/ut_test.PackageNameInvalid.sql @@ -2,7 +2,7 @@ PROMPT Reports error when unit test package name for a test is invalid --Arrange declare - simple_test ut_test := ut_test(a_object_name => 'invalid test package name', a_name => 'ut_passing_test'); + simple_test ut_test := ut_test(a_object_name => 'invalid test package name', a_name => 'ut_passing_test', a_line_no => null); begin --Act simple_test.do_execute(); diff --git a/old_tests/ut_test/ut_test.PackageNameNull.sql b/old_tests/ut_test/ut_test.PackageNameNull.sql index f4420b6b0..59612fa3d 100644 --- a/old_tests/ut_test/ut_test.PackageNameNull.sql +++ b/old_tests/ut_test/ut_test.PackageNameNull.sql @@ -2,7 +2,7 @@ PROMPT Reports error when unit test package name for a test is null --Arrange declare - simple_test ut_test := ut_test(a_object_name => null, a_name => 'ut_passing_test'); + simple_test ut_test := ut_test(a_object_name => null, a_name => 'ut_passing_test', a_line_no => null); begin --Act simple_test.do_execute(); diff --git a/old_tests/ut_test/ut_test.ProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.ProcedureNameInvalid.sql index a66f0deff..2a8e80a9e 100644 --- a/old_tests/ut_test/ut_test.ProcedureNameInvalid.sql +++ b/old_tests/ut_test/ut_test.ProcedureNameInvalid.sql @@ -2,7 +2,7 @@ PROMPT Reports error when test procedure name for a test is invalid --Arrange declare - simple_test ut_test := ut_test(a_object_name => 'ut_example_tests' ,a_name => 'invalid procedure name'); + simple_test ut_test := ut_test(a_object_name => 'ut_example_tests' ,a_name => 'invalid procedure name', a_line_no => null); begin --Act simple_test.do_execute(); diff --git a/old_tests/ut_test/ut_test.ProcedureNameNull.sql b/old_tests/ut_test/ut_test.ProcedureNameNull.sql index 1e702ab2c..df4f0e593 100644 --- a/old_tests/ut_test/ut_test.ProcedureNameNull.sql +++ b/old_tests/ut_test/ut_test.ProcedureNameNull.sql @@ -2,7 +2,7 @@ PROMPT Reports error when test procedure name for a test is null --Arrange declare - simple_test ut_test := ut_test(a_object_name => 'ut_example_tests', a_name => null); + simple_test ut_test := ut_test(a_object_name => 'ut_example_tests', a_name => null, a_line_no => null); begin --Act simple_test.do_execute(); diff --git a/old_tests/ut_test/ut_test.SetupExecutedBeforeTest.sql b/old_tests/ut_test/ut_test.SetupExecutedBeforeTest.sql index e928443f3..2a80cf586 100644 --- a/old_tests/ut_test/ut_test.SetupExecutedBeforeTest.sql +++ b/old_tests/ut_test/ut_test.SetupExecutedBeforeTest.sql @@ -3,8 +3,9 @@ PROMPT Invoke setup procedure before test when setup procedure name is defined --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_passing_test' + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null ); begin simple_test.before_test_list := ut_executables(ut_executable(user, 'ut_example_tests', 'setup', ut_utils.gc_before_test)); diff --git a/old_tests/ut_test/ut_test.SetupProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.SetupProcedureNameInvalid.sql index 3f6fab022..d81141031 100644 --- a/old_tests/ut_test/ut_test.SetupProcedureNameInvalid.sql +++ b/old_tests/ut_test/ut_test.SetupProcedureNameInvalid.sql @@ -3,8 +3,9 @@ PROMPT Does not execute test and reports error when test setup procedure name fo --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_exampletest' + a_object_name => 'ut_example_tests', + a_name => 'ut_exampletest', + a_line_no => null ); begin simple_test.before_test_list := ut_executables(ut_executable(user, 'ut_example_tests', 'invalid setup name', ut_utils.gc_before_test)); diff --git a/old_tests/ut_test/ut_test.SetupProcedureNameNull.sql b/old_tests/ut_test/ut_test.SetupProcedureNameNull.sql index 0622a2295..9269fdd92 100644 --- a/old_tests/ut_test/ut_test.SetupProcedureNameNull.sql +++ b/old_tests/ut_test/ut_test.SetupProcedureNameNull.sql @@ -3,8 +3,9 @@ PROMPT Does not invoke setup procedure when setup procedure name for a test is n --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_passing_test' + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null ); begin simple_test.before_test_list := ut_executables(ut_executable(user, 'ut_example_tests', null, ut_utils.gc_before_test)); diff --git a/old_tests/ut_test/ut_test.TeardownExecutedAfterTest.sql b/old_tests/ut_test/ut_test.TeardownExecutedAfterTest.sql index 55c0026c1..bc733614b 100644 --- a/old_tests/ut_test/ut_test.TeardownExecutedAfterTest.sql +++ b/old_tests/ut_test/ut_test.TeardownExecutedAfterTest.sql @@ -3,8 +3,9 @@ PROMPT Invoke teardown procedure after test when teardown procedure name is defi --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_passing_test' + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null ); begin simple_test.after_test_list := ut_executables(ut_executable(user, 'ut_example_tests', 'teardown', ut_utils.gc_after_test)); diff --git a/old_tests/ut_test/ut_test.TeardownProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.TeardownProcedureNameInvalid.sql index 86bdff66a..5ae61cc13 100644 --- a/old_tests/ut_test/ut_test.TeardownProcedureNameInvalid.sql +++ b/old_tests/ut_test/ut_test.TeardownProcedureNameInvalid.sql @@ -3,8 +3,9 @@ PROMPT Does not execute test and reports error when test teardown procedure name --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_exampletest' + a_object_name => 'ut_example_tests', + a_name => 'ut_exampletest', + a_line_no => null ); begin simple_test.after_test_list := ut_executables(ut_executable(user, 'ut_example_tests', 'invalid setup name', ut_utils.gc_after_test)); diff --git a/old_tests/ut_test/ut_test.TeardownProcedureNameNull.sql b/old_tests/ut_test/ut_test.TeardownProcedureNameNull.sql index a1837d20c..7460ca788 100644 --- a/old_tests/ut_test/ut_test.TeardownProcedureNameNull.sql +++ b/old_tests/ut_test/ut_test.TeardownProcedureNameNull.sql @@ -3,8 +3,9 @@ PROMPT Does not invoke teardown procedure when teardown procedure name for a tes --Arrange declare simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests' - ,a_name => 'ut_passing_test' + a_object_name => 'ut_example_tests', + a_name => 'ut_passing_test', + a_line_no => null ); begin simple_test.after_test_list := ut_executables(ut_executable(user, 'ut_example_tests', null, ut_utils.gc_after_test)); diff --git a/source/core/annotations/ut_annotation_cache_seq.sql b/source/core/annotations/ut_annotation_cache_seq.sql index 028225ddb..1cc97086e 100644 --- a/source/core/annotations/ut_annotation_cache_seq.sql +++ b/source/core/annotations/ut_annotation_cache_seq.sql @@ -12,5 +12,5 @@ create sequence ut_annotation_cache_seq See the License for the specific language governing permissions and limitations under the License. */ -cache 20; +cache 100; diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index 358a563f4..cc2b32309 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -992,7 +992,6 @@ create or replace package body ut_suite_builder is l_idx := l_rows.first; end if; exit when l_idx is null; - l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1; if l_level > 1 then @@ -1055,7 +1054,7 @@ create or replace package body ut_suite_builder is suite_items as ( select c.* from ]'||l_ut_owner||q'[.ut_suite_cache c - where 1 = 1 ]'||case when a_skip_all_objects is null then q'[ + where 1 = 1 ]'||case when not a_skip_all_objects /*1 = 0*/ then q'[ and exists ( select 1 from all_objects a @@ -1112,7 +1111,7 @@ create or replace package body ut_suite_builder is not in (select s.path from suitepaths s) ), logical_suites as ( - select s.self_type, s.path, s.object_owner, s.object_name, + select to_number(null) as id, s.self_type, s.path, s.object_owner, s.object_name, s.object_name as name, null as line_no, null as parse_time, null as description, null as rollback_type, 0 as disabled_flag, ]'||l_ut_owner||q'[.ut_varchar2_rows() as warnings, @@ -1164,7 +1163,12 @@ create or replace package body ut_suite_builder is convert_package_annotations( l_annotated_objects( i ) ), l_suite_items ); - ut_suite_cache_manager.save_cache( a_owner_name, l_suite_items ); + ut_suite_cache_manager.save_object_cache( + a_owner_name, + l_annotated_objects( i ).object_name, + l_annotated_objects( i ).parse_time, + l_suite_items + ); end loop; exit when a_annotated_objects%notfound; end loop; @@ -1202,7 +1206,7 @@ create or replace package body ut_suite_builder is ]' || ut_utils.ut_owner || q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE', :a_suite_cache_parse_time) )x ]' using a_owner_name, l_suite_cache_time; - + return build_suites_from_annotations( a_owner_name, l_annotations_cursor, @@ -1218,8 +1222,8 @@ create or replace package body ut_suite_builder is l_object_names ut_varchar2_rows; l_ut_owner varchar2(250) := ut_utils.ut_owner; begin - execute immediate 'select distinct c.object_owner, c.object_name - from '||l_ut_owner||q'[.ut_suite_cache c + execute immediate 'select c.object_owner, c.object_name + from '||l_ut_owner||q'[.ut_suite_cache_package c join table ( :a_schema_names ) s on c.object_owner = upper(s.column_value) -- where exists diff --git a/source/core/ut_suite_cache.sql b/source/core/ut_suite_cache.sql index 09211722b..adbdf1734 100644 --- a/source/core/ut_suite_cache.sql +++ b/source/core/ut_suite_cache.sql @@ -17,6 +17,7 @@ create table ut_suite_cache ( See the License for the specific language governing permissions and limitations under the License. */ + id, self_type, path, object_owner, @@ -47,6 +48,7 @@ create table ut_suite_cache ( nested table expected_error_codes store as ut_suite_cache_trhows as select + cast(null as number(22)) id, c.self_type, c.path, c.object_owner, @@ -73,11 +75,15 @@ create table ut_suite_cache ( alter table ut_suite_cache modify (object_owner not null, path not null, self_type not null, object_name not null, name not null, parse_time not null) / -alter table ut_suite_cache add constraint ut_suite_cache_pk primary key (object_owner, path) +alter table ut_suite_cache add constraint ut_suite_cache_pk primary key (id) / -create index ut_suite_cache_nu1 on ut_suite_cache(object_owner, object_name, parse_time desc) +alter table ut_suite_cache add constraint ut_suite_cache_uk1 unique (object_owner, path) / -alter table ut_suite_cache add constraint ut_suite_cache_schema_fk foreign key (object_owner) references ut_suite_cache_schema(object_owner) +alter table ut_suite_cache add constraint ut_suite_cache_uk2 unique (object_owner, object_name, line_no) +/ + +alter table ut_suite_cache add constraint ut_suite_cache_schema_fk foreign key (object_owner, object_name) +references ut_suite_cache_package(object_owner, object_name) on delete cascade / drop type ut_tests diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb index cad718ee3..9caf8a946 100644 --- a/source/core/ut_suite_cache_manager.pkb +++ b/source/core/ut_suite_cache_manager.pkb @@ -26,108 +26,113 @@ create or replace package body ut_suite_cache_manager is return l_cache_parse_time; end; - procedure save_cache(a_object_owner varchar2, a_suite_items ut_suite_items) is + procedure save_object_cache( + a_object_owner varchar2, + a_object_name varchar2, + a_parse_time timestamp, + a_suite_items ut_suite_items + ) is pragma autonomous_transaction; - l_parse_time timestamp; l_cached_parse_time timestamp; l_object_owner varchar2(250) := upper(a_object_owner); + l_object_name varchar2(250) := upper(a_object_name); begin if a_suite_items.count = 0 then - return; - end if; - if a_suite_items(1).self_type != 'UT_LOGICAL_SUITE' then - select min(parse_time) - into l_cached_parse_time - from ut_suite_cache t - where t.object_name = a_suite_items(1).object_name - and t.object_owner = a_suite_items(1).object_owner - and rownum = 1; - end if; - - select max(parse_time) into l_parse_time from table(a_suite_items) s; + delete from ut_suite_cache t + where t.object_owner = l_object_owner + and t.object_name = l_object_name; - if l_parse_time > l_cached_parse_time or l_cached_parse_time is null then + delete from ut_suite_cache_package t + where t.object_owner = l_object_owner + and t.object_name = l_object_name; - update ut_suite_cache_schema t - set t.parse_time = l_parse_time - where object_owner = l_object_owner; + else - if sql%rowcount = 0 then - insert into ut_suite_cache_schema - (object_owner, parse_time) - values (l_object_owner, l_parse_time); - end if; - - delete from ut_suite_cache t - where (t.object_name, t.object_owner) - in ( - select upper(s.object_name), upper(s.object_owner) - from table(a_suite_items) s where s.self_type != 'UT_LOGICAL_SUITE' - ); - - - insert into ut_suite_cache t - ( - self_type, path, object_owner, object_name, name, - line_no, parse_time, description, - rollback_type, disabled_flag, warnings - ) - select self_type, path, upper(object_owner), upper(object_name), upper(name), - line_no, parse_time, description, - rollback_type, disabled_flag, warnings - from table(a_suite_items) s - where s.self_type = 'UT_LOGICAL_SUITE' - and (s.object_owner, s.path) not in (select c.object_owner, c.path from ut_suite_cache c); - - insert into ut_suite_cache t + select min(parse_time) + into l_cached_parse_time + from ut_suite_cache_package t + where t.object_name = l_object_name + and t.object_owner = l_object_owner; + + if a_parse_time > l_cached_parse_time or l_cached_parse_time is null then + + update ut_suite_cache_schema t + set t.parse_time = a_parse_time + where object_owner = l_object_owner; + + if sql%rowcount = 0 then + insert into ut_suite_cache_schema + (object_owner, parse_time) + values (l_object_owner, a_parse_time); + end if; + + update ut_suite_cache_package t + set t.parse_time = a_parse_time + where t.object_owner = l_object_owner + and t.object_name = l_object_name; + + if sql%rowcount = 0 then + insert into ut_suite_cache_package + (object_owner, object_name, parse_time) + values (l_object_owner, l_object_name, a_parse_time ); + end if; + + delete from ut_suite_cache t + where t.object_owner = l_object_owner + and t.object_name = l_object_name; + + insert into ut_suite_cache t + ( + id, self_type, path, object_owner, object_name, name, + line_no, parse_time, description, + rollback_type, disabled_flag, warnings, + before_all_list, after_all_list, + before_each_list, after_each_list, + before_test_list, after_test_list, + expected_error_codes, item + ) + with suites as ( + select treat(value(x) as ut_suite) i + from table(a_suite_items) x + where x.self_type in( 'UT_SUITE', 'UT_SUITE_CONTEXT' ) ) + select ut_suite_cache_seq.nextval, s.i.self_type as self_type, s.i.path as path, + upper(s.i.object_owner) as object_owner, upper(s.i.object_name) as object_name, upper(s.i.name) as name, + s.i.line_no as line_no, s.i.parse_time as parse_time, s.i.description as description, + s.i.rollback_type as rollback_type, s.i.disabled_flag as disabled_flag, s.i.warnings as warnings, + s.i.before_all_list as before_all_list, s.i.after_all_list as after_all_list, + null before_each_list, null after_each_list, + null before_test_list, null after_test_list, + null expected_error_codes, null item + from suites s; + + insert into ut_suite_cache t ( - self_type, path, object_owner, object_name, name, - line_no, parse_time, description, - rollback_type, disabled_flag, warnings, - before_all_list, after_all_list, - before_each_list, after_each_list, - before_test_list, after_test_list, - expected_error_codes, item + id, self_type, path, object_owner, object_name, name, + line_no, parse_time, description, + rollback_type, disabled_flag, warnings, + before_all_list, after_all_list, + before_each_list, after_each_list, + before_test_list, after_test_list, + expected_error_codes, item ) - with suites as ( select treat(value(x) as ut_suite) i - from table(a_suite_items) x - where x.self_type in( 'UT_SUITE', 'UT_SUITE_CONTEXT' ) ) - select s.i.self_type as self_type, s.i.path as path, - upper(s.i.object_owner) as object_owner, upper(s.i.object_name) as object_name, upper(s.i.name) as name, - s.i.line_no as line_no, s.i.parse_time as parse_time, s.i.description as description, - s.i.rollback_type as rollback_type, s.i.disabled_flag as disabled_flag, s.i.warnings as warnings, - s.i.before_all_list as before_all_list, s.i.after_all_list as after_all_list, - null before_each_list, null after_each_list, - null before_test_list, null after_test_list, - null expected_error_codes, null item - from suites s; - - insert into ut_suite_cache t - ( - self_type, path, object_owner, object_name, name, - line_no, parse_time, description, - rollback_type, disabled_flag, warnings, - before_all_list, after_all_list, - before_each_list, after_each_list, - before_test_list, after_test_list, - expected_error_codes, item - ) - with tests as ( select treat(value(x) as ut_test) t - from table ( a_suite_items ) x - where x.self_type in ( 'UT_TEST' ) ) - select s.t.self_type as self_type, s.t.path as path, - upper(s.t.object_owner) as object_owner, upper(s.t.object_name) as object_name, upper(s.t.name) as name, - s.t.line_no as line_no, s.t.parse_time as parse_time, s.t.description as description, - s.t.rollback_type as rollback_type, s.t.disabled_flag as disabled_flag, s.t.warnings as warnings, - null before_all_list, null after_all_list, - s.t.before_each_list as before_each_list, s.t.after_each_list as after_each_list, - s.t.before_test_list as before_test_list, s.t.after_test_list as after_test_list, - s.t.expected_error_codes as expected_error_codes, s.t.item as item - from tests s; - - commit; + with tests as ( + select treat(value(x) as ut_test) t + from table ( a_suite_items ) x + where x.self_type in ( 'UT_TEST' ) ) + select ut_suite_cache_seq.nextval, s.t.self_type as self_type, s.t.path as path, + upper(s.t.object_owner) as object_owner, upper(s.t.object_name) as object_name, upper(s.t.name) as name, + s.t.line_no as line_no, s.t.parse_time as parse_time, s.t.description as description, + s.t.rollback_type as rollback_type, s.t.disabled_flag as disabled_flag, s.t.warnings as warnings, + null before_all_list, null after_all_list, + s.t.before_each_list as before_each_list, s.t.after_each_list as after_each_list, + s.t.before_test_list as before_test_list, s.t.after_test_list as after_test_list, + s.t.expected_error_codes as expected_error_codes, s.t.item as item + from tests s; + + end if; end if; + commit; end; end ut_suite_cache_manager; diff --git a/source/core/ut_suite_cache_manager.pks b/source/core/ut_suite_cache_manager.pks index 919196efa..3d5a21f10 100644 --- a/source/core/ut_suite_cache_manager.pks +++ b/source/core/ut_suite_cache_manager.pks @@ -20,7 +20,12 @@ create or replace package ut_suite_cache_manager authid definer is * Responsible for storing and retrieving suite data from cache */ - procedure save_cache(a_object_owner varchar2, a_suite_items ut_suite_items); + procedure save_object_cache( + a_object_owner varchar2, + a_object_name varchar2, + a_parse_time timestamp, + a_suite_items ut_suite_items + ); function get_schema_parse_time(a_schema_name varchar2) return timestamp result_cache; diff --git a/source/core/ut_suite_cache_package.sql b/source/core/ut_suite_cache_package.sql new file mode 100644 index 000000000..46f49e915 --- /dev/null +++ b/source/core/ut_suite_cache_package.sql @@ -0,0 +1,23 @@ +create table ut_suite_cache_package ( + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + object_owner varchar2(250) not null, + object_name varchar2(250) not null, + parse_time timestamp not null, + constraint ut_suite_cache_package_pk primary key(object_owner, object_name), + constraint ut_suite_cache_package_fk foreign key (object_owner) references ut_suite_cache_schema(object_owner) on delete cascade +) organization index +/ + + diff --git a/source/core/ut_suite_cache_seq.sql b/source/core/ut_suite_cache_seq.sql new file mode 100644 index 000000000..0c9c835b8 --- /dev/null +++ b/source/core/ut_suite_cache_seq.sql @@ -0,0 +1,16 @@ +create sequence ut_suite_cache_seq + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ +cache 100; + diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql index f22a61121..4928022eb 100644 --- a/source/create_synonyms_and_grants_for_public.sql +++ b/source/create_synonyms_and_grants_for_public.sql @@ -89,6 +89,7 @@ grant select on &&ut3_owner..ut_annotation_cache to public; grant execute on &&ut3_owner..ut_executables to public; grant execute on &&ut3_owner..ut_executable_test to public; grant select on &&ut3_owner..ut_suite_cache to public; +grant select on &&ut3_owner..ut_suite_cache_package to public; grant select on &&ut3_owner..ut_suite_cache_schema to public; grant execute on &&ut3_owner..ut_annotation_cache_manager to public; grant execute on &&ut3_owner..ut_annotation_parser to public; diff --git a/source/create_user_grants.sql b/source/create_user_grants.sql index 723fcca58..0967a0e8c 100644 --- a/source/create_user_grants.sql +++ b/source/create_user_grants.sql @@ -109,6 +109,7 @@ grant select on &&ut3_owner..ut_annotation_cache to &ut3_user; grant execute on &&ut3_owner..ut_executables to &ut3_user; grant execute on &&ut3_owner..ut_executable_test to &ut3_user; grant select on &&ut3_owner..ut_suite_cache to &ut3_user; +grant select on &&ut3_owner..ut_suite_cache_package to public; grant select on &&ut3_owner..ut_suite_cache_schema to &ut3_user; grant execute on &&ut3_owner..ut_annotation_cache_manager to &ut3_user; grant execute on &&ut3_owner..ut_annotation_parser to &ut3_user; diff --git a/source/install.sql b/source/install.sql index d71dcb1d1..2a7ff8343 100644 --- a/source/install.sql +++ b/source/install.sql @@ -111,6 +111,8 @@ alter session set current_schema = &&ut3_owner; --suite builder @@install_component.sql 'core/ut_suite_cache_schema.sql' +@@install_component.sql 'core/ut_suite_cache_package.sql' +@@install_component.sql 'core/ut_suite_cache_seq.sql' @@install_component.sql 'core/ut_suite_cache.sql' @@install_component.sql 'core/ut_suite_cache_manager.pks' @@install_component.sql 'core/ut_suite_cache_manager.pkb' diff --git a/test/core/test_suite_builder.pkb b/test/core/test_suite_builder.pkb index e55830266..423e29c0a 100644 --- a/test/core/test_suite_builder.pkb +++ b/test/core/test_suite_builder.pkb @@ -414,7 +414,7 @@ create or replace package body test_suite_builder is ut.expect(l_actual).to_be_like( '%%some_package%some_test' || '%' || - '%some_packagefirst_bfore_each' || + '%some_packagefirst_before_each' || '%some_packageanother_before_each' || '%' || '%' || From 15163a82f610bd5198ec0541105818501e82c44d Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 4 Nov 2018 19:52:45 +0000 Subject: [PATCH 076/115] Resolved issue with sorting of nested-tables. Added `seq_no`, numbering before storage and sorting after retrieval. --- source/core/types/ut_executable.tps | 4 ++ source/core/ut_suite_builder.pkb | 96 +++++++++++++++++------------ test/api/test_ut_run.pks | 2 - 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/source/core/types/ut_executable.tps b/source/core/types/ut_executable.tps index 5fa4f3566..8186e4bae 100644 --- a/source/core/types/ut_executable.tps +++ b/source/core/types/ut_executable.tps @@ -25,6 +25,10 @@ create or replace type ut_executable under ut_event_item( error_backtrace varchar2(4000), error_stack varchar2(4000), serveroutput clob, + /** + * Used for ordering of executables, as Oracle doesn not guarantee ordering of items in a nested table. + */ + seq_no integer, constructor function ut_executable( self in out nocopy ut_executable, a_owner varchar2, a_package varchar2, a_procedure_name varchar2, a_executable_type varchar2) return self as result, member function form_name return varchar2, member procedure do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item), diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index cc2b32309..6191bc7e8 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -65,9 +65,6 @@ create or replace package body ut_suite_builder is type tt_executables is table of ut_executables index by t_annotation_position; - type tt_tests is table of ut_test index by t_annotation_position; - - type t_annotation is record( name t_annotation_name, text t_annotation_text, @@ -315,35 +312,46 @@ create or replace package body ut_suite_builder is end loop; end; - function convert_list( - a_list tt_executables + procedure set_seq_no( + a_list in out nocopy ut_executables + ) is + begin + if a_list is not null then + for i in 1 .. a_list.count loop + a_list(i).seq_no := i; + end loop; + end if; + end; + + function sort_by_seq_no( + a_list ut_executables ) return ut_executables is - l_result ut_executables := ut_executables(); - l_pos t_annotation_position := a_list.first; - begin - while l_pos is not null loop - for i in 1 .. a_list(l_pos).count loop - l_result.extend; - l_result(l_result.last) := a_list(l_pos)(i); - end loop; - l_pos := a_list.next(l_pos); + l_results ut_executables := ut_executables(); + begin + if a_list is not null then + l_results.extend(a_list.count); + for i in 1 .. a_list.count loop + l_results(a_list(i).seq_no) := a_list(i); end loop; - return l_result; - end; + end if; + return l_results; + end; function convert_list( - a_list tt_tests - ) return ut_suite_items is - l_result ut_suite_items := ut_suite_items(); + a_list tt_executables + ) return ut_executables is + l_result ut_executables := ut_executables(); l_pos t_annotation_position := a_list.first; - begin - while l_pos is not null loop + begin + while l_pos is not null loop + for i in 1 .. a_list(l_pos).count loop l_result.extend; - l_result(l_result.last) := a_list(l_pos); - l_pos := a_list.next(l_pos); + l_result(l_result.last) := a_list(l_pos)(i); end loop; - return l_result; - end; + l_pos := a_list.next(l_pos); + end loop; + return l_result; + end; function add_executables( a_owner t_object_name, @@ -492,11 +500,13 @@ create or replace package body ut_suite_builder is l_test.before_test_list := convert_list( add_executables( l_test.object_owner, l_test.object_name, l_proc_annotations( gc_beforetest ), gc_beforetest ) ); + set_seq_no(l_test.before_test_list); end if; if l_proc_annotations.exists( gc_aftertest) then l_test.after_test_list := convert_list( add_executables( l_test.object_owner, l_test.object_name, l_proc_annotations( gc_aftertest ), gc_aftertest ) ); + set_seq_no(l_test.after_test_list); end if; if l_proc_annotations.exists( gc_throws) then add_to_throws_numbers_list(a_suite, l_test.expected_error_codes, a_procedure_name, l_proc_annotations( gc_throws)); @@ -519,8 +529,10 @@ create or replace package body ut_suite_builder is for i in 1 .. a_suite.items.count loop if a_suite.items(i) is of (ut_test) then l_test := treat( a_suite.items(i) as ut_test); - l_test.before_each_list := coalesce(convert_list(a_before_each_list),ut_executables()) multiset union all l_test.before_each_list; - l_test.after_each_list := l_test.after_each_list multiset union all coalesce(convert_list(a_after_each_list),ut_executables()); + l_test.before_each_list := convert_list(a_before_each_list) multiset union all l_test.before_each_list; + set_seq_no(l_test.before_each_list); + l_test.after_each_list := l_test.after_each_list multiset union all convert_list(a_after_each_list); + set_seq_no(l_test.after_each_list); a_suite.items(i) := l_test; elsif a_suite.items(i) is of (ut_logical_suite) then l_context := treat(a_suite.items(i) as ut_logical_suite); @@ -543,8 +555,10 @@ create or replace package body ut_suite_builder is for i in 1 .. a_suite_items.count loop if a_suite_items(i) is of (ut_test) then l_test := treat( a_suite_items(i) as ut_test); - l_test.before_each_list := coalesce(convert_list(a_before_each_list),ut_executables()) multiset union all l_test.before_each_list; - l_test.after_each_list := l_test.after_each_list multiset union all coalesce(convert_list(a_after_each_list),ut_executables()); + l_test.before_each_list := convert_list(a_before_each_list) multiset union all l_test.before_each_list; + set_seq_no(l_test.before_each_list); + l_test.after_each_list := l_test.after_each_list multiset union all convert_list(a_after_each_list); + set_seq_no(l_test.after_each_list); a_suite_items(i) := l_test; elsif a_suite_items(i) is of (ut_logical_suite) then l_context := treat(a_suite_items(i) as ut_logical_suite); @@ -580,8 +594,6 @@ create or replace package body ut_suite_builder is a_after_all_list in out nocopy tt_executables ) is l_procedure_name t_object_name; - l_tests tt_tests; - begin l_procedure_name := a_proc_annotations.by_proc.first; while l_procedure_name is not null loop @@ -679,7 +691,9 @@ create or replace package body ut_suite_builder is a_suite.set_rollback_type(l_rollback_type); propagate_before_after_each( a_suite_items, l_before_each_list, l_after_each_list); a_suite.before_all_list := convert_list(l_before_all_list); + set_seq_no(a_suite.before_all_list); a_suite.after_all_list := convert_list(l_after_all_list); + set_seq_no(a_suite.after_all_list); end; function get_endcontext_position( @@ -943,9 +957,9 @@ create or replace package body ut_suite_builder is line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - before_each_list => l_rows(i).before_each_list, before_test_list => l_rows(i).before_test_list, + before_each_list => sort_by_seq_no(l_rows(i).before_each_list), before_test_list => sort_by_seq_no(l_rows(i).before_test_list), item => l_rows(i).item, - after_test_list => l_rows(i).after_test_list, after_each_list => l_rows(i).after_each_list, + after_test_list => sort_by_seq_no(l_rows(i).after_test_list), after_each_list => sort_by_seq_no(l_rows(i).after_each_list), all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), parent_error_stack_trace => null, expected_error_codes => l_rows(i).expected_error_codes ); @@ -960,7 +974,7 @@ create or replace package body ut_suite_builder is start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items(), - before_all_list => l_rows(i).before_all_list, after_all_list => l_rows(i).after_all_list + before_all_list => sort_by_seq_no(l_rows(i).before_all_list), after_all_list => sort_by_seq_no(l_rows(i).after_all_list) ); when 'UT_SUITE_CONTEXT' then l_logical_suites(i) := @@ -973,7 +987,7 @@ create or replace package body ut_suite_builder is start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items(), - before_all_list => l_rows(i).before_all_list, after_all_list => l_rows(i).after_all_list + before_all_list => sort_by_seq_no(l_rows(i).before_all_list), after_all_list => sort_by_seq_no(l_rows(i).after_all_list) ); when 'UT_LOGICAL_SUITE' then l_logical_suites(i) := @@ -1054,7 +1068,7 @@ create or replace package body ut_suite_builder is suite_items as ( select c.* from ]'||l_ut_owner||q'[.ut_suite_cache c - where 1 = 1 ]'||case when not a_skip_all_objects /*1 = 0*/ then q'[ + where 1 = 1 ]'||case when not a_skip_all_objects then q'[ and exists ( select 1 from all_objects a @@ -1226,11 +1240,11 @@ create or replace package body ut_suite_builder is from '||l_ut_owner||q'[.ut_suite_cache_package c join table ( :a_schema_names ) s on c.object_owner = upper(s.column_value) --- where exists --- (select 1 from all_objects a --- where a.owner = c.object_owner --- and a.object_name = c.object_name --- and a.object_type = 'PACKAGE') + where exists + (select 1 from all_objects a + where a.owner = c.object_owner + and a.object_name = c.object_name + and a.object_type = 'PACKAGE') ]' bulk collect into l_schema_names, l_object_names using a_schema_names; l_results.extend( l_schema_names.count ); diff --git a/test/api/test_ut_run.pks b/test/api/test_ut_run.pks index cfc06c80d..927abf6e2 100644 --- a/test/api/test_ut_run.pks +++ b/test/api/test_ut_run.pks @@ -24,7 +24,6 @@ create or replace package test_ut_run is --%test(Runs all tests in current schema with coverage file list) procedure run_proc_cov_file_list; - --%disabled(TODO - currently it executes the package and all child packages) --%test(Runs given package only with package name given as path) procedure run_proc_pkg_name; --%test(Runs all from given package with package name given as path and coverage file list) @@ -57,7 +56,6 @@ create or replace package test_ut_run is --%test(Runs all tests in current schema with coverage file list) procedure run_func_cov_file_list; - --%disabled(TODO - currently it executes the package and all child packages) --%test(Runs given package only with package name given as path) procedure run_func_pkg_name; --%test(Runs all from given package with package name given as path and coverage file list) From 1b14bb5a0909a9a74c153d7d7d0969b3b1b7db2c Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 4 Nov 2018 19:55:37 +0000 Subject: [PATCH 077/115] Fixing re-enabled test. --- test/api/test_ut_run.pkb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api/test_ut_run.pkb b/test/api/test_ut_run.pkb index dae7e175a..9709058d4 100644 --- a/test/api/test_ut_run.pkb +++ b/test/api/test_ut_run.pkb @@ -391,7 +391,7 @@ create or replace package body test_ut_run is execute immediate 'begin :l_results := ut3$user#.test_package_1.run(:a_path); end;' using out l_results, in 'test_package_1'; --Assert - ut.expect( ut3.ut_utils.table_to_clob(l_results) ).to_be_like( '%test_package_bal%' ); + ut.expect( ut3.ut_utils.table_to_clob(l_results) ).to_be_like( '%test_package_1%' ); ut.expect( ut3.ut_utils.table_to_clob(l_results) ).not_to_be_like( '%test_package_2%' ); ut.expect( ut3.ut_utils.table_to_clob(l_results) ).not_to_be_like( '%test_package_3%' ); end; From 3bc8da55d8b7ef6bb8da56c4c1b3121c7126f90a Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 4 Nov 2018 20:43:25 +0000 Subject: [PATCH 078/115] Adding missing items to uninstall. --- source/uninstall_objects.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/uninstall_objects.sql b/source/uninstall_objects.sql index 754a16a34..119695b6d 100644 --- a/source/uninstall_objects.sql +++ b/source/uninstall_objects.sql @@ -57,6 +57,10 @@ drop package ut_suite_builder; drop table ut_suite_cache; +drop sequence ut_suite_cache_seq; + +drop table ut_suite_cache_package; + drop table ut_suite_cache_schema; drop package ut; From 8911f974e6d832f90cb0213f93df88ba53636f3a Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Mon, 5 Nov 2018 23:25:28 +0000 Subject: [PATCH 079/115] Small improvements and cleanup. --- .../annotations/ut_annotation_manager.pkb | 61 ++--- source/core/types/ut_logical_suites.tps | 19 -- source/core/ut_suite_builder.pkb | 219 ++++++++---------- source/install.sql | 1 - 4 files changed, 126 insertions(+), 174 deletions(-) delete mode 100644 source/core/types/ut_logical_suites.tps diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb index afa66b2e4..12eac0190 100644 --- a/source/core/annotations/ut_annotation_manager.pkb +++ b/source/core/annotations/ut_annotation_manager.pkb @@ -58,17 +58,18 @@ create or replace package body ut_annotation_manager as begin open l_result for q'[select s.name, s.text - from ]'||l_sources_view||q'[ s - where s.type = :a_object_type - and s.owner = :a_object_owner - and s.name - in (select x.name - from ]'||l_sources_view||q'[ x - where x.type = :a_object_type - and x.owner = :a_object_owner - and x.text like '%--%\%%' escape '\' - ) - order by name, line]' + from (select s.name, s.text, s.line, + max(case when s.text like '%--%\%%' escape '\' + and regexp_like(s.text,'--\s*%') + then 'Y' else 'N' end + ) + over(partition by s.name) is_annotated + from ]'||l_sources_view||q'[ s + where s.type = :a_object_type + and s.owner = :a_object_owner + ) s + where s.is_annotated = 'Y' + order by s.name, s.line]' using a_object_type, a_object_owner, a_object_type, a_object_owner; return l_result; @@ -81,25 +82,25 @@ create or replace package body ut_annotation_manager as begin l_card := ut_utils.scale_cardinality(cardinality(a_objects_to_refresh)); open l_result for - q'[select /*+ cardinality( r ]'||l_card||q'[ )*/ - s.name, s.text - from table(:a_objects_to_refresh) r - join ]'||l_sources_view||q'[ s - on s.name = r.object_name - where s.type = :a_object_type - and s.owner = :a_object_owner - and s.name - in (select /*+ cardinality( t ]'||l_card||q'[ )*/ - x.name - from table(:a_objects_to_refresh) t - join ]'||l_sources_view||q'[ x - on x.name = t.object_name - where x.type = :a_object_type - and x.owner = :a_object_owner - and x.text like '%--%\%%' escape '\' - ) - order by name, line]' - using a_objects_to_refresh, a_object_type, a_object_owner, a_objects_to_refresh, a_object_type, a_object_owner; + q'[select s.name, s.text + from (select /*+ cardinality( r ]'||l_card||q'[ )*/ + s.name, s.text, s.line, + max(case when s.text like '%--%\%%' escape '\' + and regexp_like(s.text,'--\s*%') + then 'Y' else 'N' end + ) + over(partition by s.name) is_annotated + from table(:a_objects_to_refresh) r + join ]'||l_sources_view||q'[ s + on s.name = r.object_name + and s.owner = r.object_owner + and s.type = r.object_type + where s.type = :a_object_type + and s.owner = :a_object_owner + ) s + where s.is_annotated = 'Y' + order by s.name, s.line]' + using a_objects_to_refresh, a_object_type, a_object_owner; return l_result; end; diff --git a/source/core/types/ut_logical_suites.tps b/source/core/types/ut_logical_suites.tps deleted file mode 100644 index 560f245d0..000000000 --- a/source/core/types/ut_logical_suites.tps +++ /dev/null @@ -1,19 +0,0 @@ -create or replace type ut_logical_suites as - /* - utPLSQL - Version 3 - Copyright 2016 - 2018 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. - */ - table of ut_logical_suite -/ diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index 6191bc7e8..f63088811 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -517,32 +517,6 @@ create or replace package body ut_suite_builder is a_suite_items( a_suite_items.last ) := l_test; end; - procedure propagate_before_after_each( - a_suite in out nocopy ut_logical_suite, - a_before_each_list tt_executables, - a_after_each_list tt_executables - ) is - l_test ut_test; - l_context ut_logical_suite; - begin - if a_suite.items is not null then - for i in 1 .. a_suite.items.count loop - if a_suite.items(i) is of (ut_test) then - l_test := treat( a_suite.items(i) as ut_test); - l_test.before_each_list := convert_list(a_before_each_list) multiset union all l_test.before_each_list; - set_seq_no(l_test.before_each_list); - l_test.after_each_list := l_test.after_each_list multiset union all convert_list(a_after_each_list); - set_seq_no(l_test.after_each_list); - a_suite.items(i) := l_test; - elsif a_suite.items(i) is of (ut_logical_suite) then - l_context := treat(a_suite.items(i) as ut_logical_suite); - propagate_before_after_each( l_context, a_before_each_list, a_after_each_list); - a_suite.items(i) := l_context; - end if; - end loop; - end if; - end; - procedure propagate_before_after_each( a_suite_items in out nocopy ut_suite_items, a_before_each_list tt_executables, @@ -929,113 +903,110 @@ create or replace package body ut_suite_builder is a_suite_data_cursor sys_refcursor ) is type t_item_levels is table of ut_suite_items index by binary_integer; + c_bulk_limit constant pls_integer := 1000; l_items_at_level t_item_levels; l_rows tt_cached_suites; - l_tests ut_suite_items := ut_suite_items(); - l_logical_suites ut_logical_suites := ut_logical_suites(); + l_test ut_test; + l_logical_suite ut_logical_suite; l_level pls_integer; l_prev_level pls_integer; l_idx integer; begin a_suites := ut_suite_items(); loop - if l_idx is null then - fetch a_suite_data_cursor bulk collect into l_rows limit 1000; - l_tests.delete; - l_tests.extend(l_rows.count); - l_logical_suites.delete; - l_logical_suites.extend(l_rows.count); - for i in 1 .. l_rows.count loop - case l_rows(i).self_type - when 'UT_TEST' then - l_tests(i) := - ut_test( - self_type => l_rows(i).self_type, - object_owner => l_rows(i).object_owner, object_name => lower(l_rows(i).object_name), - name => lower(l_rows(i).name), description => l_rows(i).description, path => l_rows(i).path, - rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, - line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - before_each_list => sort_by_seq_no(l_rows(i).before_each_list), before_test_list => sort_by_seq_no(l_rows(i).before_test_list), - item => l_rows(i).item, - after_test_list => sort_by_seq_no(l_rows(i).after_test_list), after_each_list => sort_by_seq_no(l_rows(i).after_each_list), - all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), - parent_error_stack_trace => null, expected_error_codes => l_rows(i).expected_error_codes - ); - when 'UT_SUITE' then - l_logical_suites(i) := - ut_suite( - self_type => l_rows(i).self_type, - object_owner => l_rows(i).object_owner, object_name => lower(l_rows(i).object_name), - name => lower(l_rows(i).name), description => l_rows(i).description, path => l_rows(i).path, - rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, - line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => ut_suite_items(), - before_all_list => sort_by_seq_no(l_rows(i).before_all_list), after_all_list => sort_by_seq_no(l_rows(i).after_all_list) - ); - when 'UT_SUITE_CONTEXT' then - l_logical_suites(i) := - ut_suite_context( - self_type => l_rows(i).self_type, - object_owner => l_rows(i).object_owner, object_name => lower(l_rows(i).object_name), - name => lower(l_rows(i).name), description => l_rows(i).description, path => l_rows(i).path, - rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, - line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => ut_suite_items(), - before_all_list => sort_by_seq_no(l_rows(i).before_all_list), after_all_list => sort_by_seq_no(l_rows(i).after_all_list) - ); - when 'UT_LOGICAL_SUITE' then - l_logical_suites(i) := - ut_logical_suite( - self_type => l_rows(i).self_type, - object_owner => l_rows(i).object_owner, object_name => lower(l_rows(i).object_name), - name => lower(l_rows(i).name), description => l_rows(i).description, path => l_rows(i).path, - rollback_type => l_rows(i).rollback_type, disabled_flag => l_rows(i).disabled_flag, - line_no => l_rows(i).line_no, parse_time => l_rows(i).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(i).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => ut_suite_items() - ); - end case; - end loop; - l_idx := l_rows.first; - end if; - exit when l_idx is null; - l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1; + fetch a_suite_data_cursor bulk collect into l_rows limit c_bulk_limit; + exit when l_rows.count = 0; - if l_level > 1 then - if l_prev_level > l_level then - l_logical_suites(l_idx).items := l_items_at_level(l_prev_level); - l_items_at_level(l_prev_level).delete; - end if; - if not l_items_at_level.exists(l_level) then - l_items_at_level(l_level) := ut_suite_items(); - end if; - l_items_at_level(l_level).extend; - if l_tests(l_idx) is not null then - l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_tests(l_idx); - else - l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_logical_suites(l_idx); - end if; - else - if l_prev_level > l_level then - l_logical_suites(l_idx).items := l_items_at_level(l_prev_level); - l_items_at_level(l_prev_level).delete; - end if; - a_suites.extend; - if l_tests(l_idx) is not null then - a_suites(a_suites.last) := l_tests(l_idx); + l_idx := l_rows.first; + loop + l_test := null; + l_logical_suite := null; + case l_rows(l_idx).self_type + when 'UT_TEST' then + l_test := + ut_test( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + 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), + item => l_rows(l_idx).item, + 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), + all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), + parent_error_stack_trace => null, expected_error_codes => l_rows(l_idx).expected_error_codes + ); + when 'UT_SUITE' then + l_logical_suite := + ut_suite( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items(), + 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) + ); + when 'UT_SUITE_CONTEXT' then + l_logical_suite := + ut_suite_context( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items(), + 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) + ); + when 'UT_LOGICAL_SUITE' then + l_logical_suite := + ut_logical_suite( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items() + ); + end case; + + l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1; + + if l_level > 1 then + if l_prev_level > l_level then + l_logical_suite.items := l_items_at_level(l_prev_level); + l_items_at_level(l_prev_level).delete; + end if; + if not l_items_at_level.exists(l_level) then + l_items_at_level(l_level) := ut_suite_items(); + end if; + l_items_at_level(l_level).extend; + if l_test is not null then + l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_test; + else + l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_logical_suite; + end if; else - a_suites(a_suites.last) := l_logical_suites(l_idx); + if l_prev_level > l_level then + l_logical_suite.items := l_items_at_level(l_prev_level); + l_items_at_level(l_prev_level).delete; + end if; + a_suites.extend; + a_suites(a_suites.last) := l_logical_suite; end if; - end if; - l_prev_level := l_level; - l_idx := l_rows.next(l_idx); + l_prev_level := l_level; + l_idx := l_rows.next(l_idx); + exit when l_idx is null; + end loop; + exit when l_rows.count < c_bulk_limit; end loop; copy_list_reverse_order( a_suites ); close a_suite_data_cursor; @@ -1066,7 +1037,7 @@ create or replace package body ut_suite_builder is open l_result for q'[with suite_items as ( - select c.* + select /*+ cardinality(c 100) */ c.* from ]'||l_ut_owner||q'[.ut_suite_cache c where 1 = 1 ]'||case when not a_skip_all_objects then q'[ and exists @@ -1093,7 +1064,7 @@ create or replace package body ut_suite_builder is ), gen as ( select rownum as pos - from xmltable('1 to 100') + from xmltable('1 to 20') ), suitepaths as ( select distinct substr(path,1,instr(path,'.',-1)-1) as suitepath, diff --git a/source/install.sql b/source/install.sql index 2a7ff8343..31b91a941 100644 --- a/source/install.sql +++ b/source/install.sql @@ -70,7 +70,6 @@ alter session set current_schema = &&ut3_owner; @@install_component.sql 'core/types/ut_executable_test.tps' @@install_component.sql 'core/types/ut_test.tps' @@install_component.sql 'core/types/ut_logical_suite.tps' -@@install_component.sql 'core/types/ut_logical_suites.tps' @@install_component.sql 'core/types/ut_suite.tps' @@install_component.sql 'core/types/ut_suite_context.tps' @@install_component.sql 'core/types/ut_file_mapping.tps' From a1f6b3499cc048d6ea4887546097c0e884845cd7 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 6 Nov 2018 00:33:39 +0000 Subject: [PATCH 080/115] Removing duplicate with block. --- source/core/ut_suite_builder.pkb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index f63088811..f6aceae89 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -1062,10 +1062,6 @@ create or replace package body ut_suite_builder is ) ) ), - gen as ( - select rownum as pos - from xmltable('1 to 20') - ), suitepaths as ( select distinct substr(path,1,instr(path,'.',-1)-1) as suitepath, path, @@ -1075,7 +1071,7 @@ create or replace package body ut_suite_builder is ), gen as ( select rownum as pos - from xmltable('1 to 10') + from xmltable('1 to 20') ), suitepath_part AS ( select distinct From 59f773835e44baf785079d837985d22eebb2013b Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 11 Nov 2018 12:04:04 +0000 Subject: [PATCH 081/115] Adding cache cleanup and "intelligent" join to all_source, only when needed. --- .../ut_annotation_cache_manager.pkb | 17 ++- .../ut_annotation_cache_manager.pks | 9 +- .../annotations/ut_annotation_manager.pkb | 101 ++++++++++++++---- source/core/ut_metadata.pkb | 27 ++++- source/core/ut_metadata.pks | 12 +++ source/core/ut_suite_builder.pkb | 57 +++++++++- source/core/ut_suite_cache_manager.pkb | 12 +++ source/core/ut_suite_cache_manager.pks | 2 + .../annotations/test_annotation_manager.pkb | 54 +++++++++- .../annotations/test_annotation_manager.pks | 13 ++- 10 files changed, 268 insertions(+), 36 deletions(-) diff --git a/source/core/annotations/ut_annotation_cache_manager.pkb b/source/core/annotations/ut_annotation_cache_manager.pkb index 9d7d1b95e..4f9129650 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pkb +++ b/source/core/annotations/ut_annotation_cache_manager.pkb @@ -74,6 +74,21 @@ create or replace package body ut_annotation_cache_manager as commit; end; + procedure remove_from_cache(a_objects ut_annotation_objs_cache_info) is + pragma autonomous_transaction; + begin + + delete from ut_annotation_cache_info i + where exists ( + select 1 from table (a_objects) o + where o.object_name = i.object_name + and o.object_type = i.object_type + and o.object_owner = i.object_owner + ); + + commit; + end; + function get_annotations_for_objects(a_cached_objects ut_annotation_objs_cache_info, a_parse_time timestamp) return sys_refcursor is l_results sys_refcursor; begin @@ -92,7 +107,7 @@ create or replace package body ut_annotation_cache_manager as join ut_annotation_cache_info i on o.object_owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type join ut_annotation_cache c on i.cache_id = c.cache_id - where ]'|| case when a_parse_time is null then ':a_parse_date is null' else 'i.parse_time >= :a_parse_time' end ||q'[ + where ]'|| case when a_parse_time is null then ':a_parse_date is null' else 'i.parse_time > :a_parse_time' end ||q'[ group by i.object_owner, i.object_name, i.object_type, i.parse_time]' using a_cached_objects, a_parse_time; return l_results; diff --git a/source/core/annotations/ut_annotation_cache_manager.pks b/source/core/annotations/ut_annotation_cache_manager.pks index 2ee586d12..1279c8cc3 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pks +++ b/source/core/annotations/ut_annotation_cache_manager.pks @@ -37,10 +37,17 @@ create or replace package ut_annotation_cache_manager authid definer as /** * Removes cached information about annotations for objects on the list and updates parse_time in cache info table. * - * @param a_objects a `ut_annotation_objs_cache_info` list with information about objects to remove from cache + * @param a_objects a `ut_annotation_objs_cache_info` list with information about objects to remove annotations for */ procedure cleanup_cache(a_objects ut_annotation_objs_cache_info); + /** + * Removes information about objects on the list + * + * @param a_objects a `ut_annotation_objs_cache_info` list with information about objects to remove from cache + */ + procedure remove_from_cache(a_objects ut_annotation_objs_cache_info); + /** * Removes cached information about annotations for objects of specified type and specified owner * diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb index 12eac0190..3559982cf 100644 --- a/source/core/annotations/ut_annotation_manager.pkb +++ b/source/core/annotations/ut_annotation_manager.pkb @@ -19,6 +19,38 @@ create or replace package body ut_annotation_manager as ------------------------------ --private definitions +-- function get_missing_objects(a_object_owner varchar2, a_object_type varchar2) return ut_annotation_objs_cache_info is +-- l_rows sys_refcursor; +-- l_ut_owner varchar2(250) := ut_utils.ut_owner; +-- l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); +-- l_cursor_text varchar2(32767); +-- l_result ut_annotation_objs_cache_info; +-- begin +-- l_cursor_text := +-- q'[select ]'||l_ut_owner||q'[.ut_annotation_obj_cache_info( +-- object_owner => i.object_owner, +-- object_name => i.object_name, +-- object_type => i.object_type, +-- needs_refresh => null +-- ) +-- from ]'||l_ut_owner||q'[.ut_annotation_cache_info i +-- where +-- not exists ( +-- select 1 from ]'||l_objects_view||q'[ o +-- where o.owner = i.object_owner +-- and o.object_name = i.object_name +-- and o.object_type = i.object_type +-- and o.owner = :a_object_owner +-- and o.object_type = :a_object_type +-- ) +-- and i.object_owner = :a_object_owner +-- and i.object_type = :a_object_type]'; +-- open l_rows for l_cursor_text using a_object_owner, a_object_type, a_object_owner, a_object_type; +-- fetch l_rows bulk collect into l_result limit 1000000; +-- close l_rows; +-- return l_result; +-- end; + function get_annotation_objs_info(a_object_owner varchar2, a_object_type varchar2, a_parse_date timestamp := null) return ut_annotation_objs_cache_info is l_rows sys_refcursor; l_ut_owner varchar2(250) := ut_utils.ut_owner; @@ -28,25 +60,36 @@ create or replace package body ut_annotation_manager as begin l_cursor_text := q'[select ]'||l_ut_owner||q'[.ut_annotation_obj_cache_info( - object_owner => o.owner, - object_name => o.object_name, - object_type => o.object_type, - needs_refresh => case when o.last_ddl_time < cast(i.parse_time as date) then 'N' else 'Y' end + object_owner => nvl( o.owner, i.object_owner ), + object_name => nvl( o.object_name, i.object_name ), + object_type => nvl( o.object_type, i.object_type ), + needs_refresh => + case + when o.last_ddl_time < cast(i.parse_time as date) then 'N' + when o.owner is null then null + else 'Y' + end ) - from ]'||l_objects_view||q'[ o - left join ]'||l_ut_owner||q'[.ut_annotation_cache_info i + from ( + select * from ]'||l_objects_view||q'[ o + where o.owner = :a_object_owner + and o.object_type = :a_object_type + ) o + full outer join ( + select * from ]'||l_ut_owner||q'[.ut_annotation_cache_info i + where i.object_owner = :a_object_owner + and i.object_type = :a_object_type + ) i on o.owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type - where o.owner = :a_object_owner - and o.object_type = :a_object_type - and ]' + where ]' || case when a_parse_date is null then ':a_parse_date is null' - else 'o.last_ddl_time >= cast(:a_parse_date as date)' + else 'o.last_ddl_time >= cast(:a_parse_date as date) or o.last_ddl_time is null' end; - open l_rows for l_cursor_text using a_object_owner, a_object_type, a_parse_date; + open l_rows for l_cursor_text using a_object_owner, a_object_type, a_object_owner, a_object_type, a_parse_date; fetch l_rows bulk collect into l_result limit 1000000; close l_rows; return l_result; @@ -106,8 +149,9 @@ create or replace package body ut_annotation_manager as end; procedure build_annot_cache_for_sources( - a_object_owner varchar2, a_object_type varchar2, a_sources_cursor sys_refcursor, - a_schema_objects ut_annotation_objs_cache_info + a_object_owner varchar2, + a_object_type varchar2, + a_sources_cursor sys_refcursor ) is l_annotations ut_annotations; c_lines_fetch_limit constant integer := 1000; @@ -118,7 +162,6 @@ create or replace package body ut_annotation_manager as l_parse_time date := sysdate; pragma autonomous_transaction; begin - ut_annotation_cache_manager.cleanup_cache(a_schema_objects); loop fetch a_sources_cursor bulk collect into l_names, l_lines limit c_lines_fetch_limit; for i in 1 .. l_names.count loop @@ -148,17 +191,37 @@ create or replace package body ut_annotation_manager as end; - procedure rebuild_annotation_cache( a_object_owner varchar2, a_object_type varchar2, a_info_rows ut_annotation_objs_cache_info) is - l_objects_to_parse ut_annotation_objs_cache_info := ut_annotation_objs_cache_info(); + procedure rebuild_annotation_cache( + a_object_owner varchar2, + a_object_type varchar2, + a_info_rows ut_annotation_objs_cache_info + ) is + l_objects_to_parse ut_annotation_objs_cache_info; + l_objects_to_remove ut_annotation_objs_cache_info; begin - select value(x)bulk collect into l_objects_to_parse from table(a_info_rows) x where x.needs_refresh = 'Y'; + select value(x)bulk collect into l_objects_to_parse + from table(a_info_rows) x where x.needs_refresh = 'Y'; + + ut_annotation_cache_manager.cleanup_cache(l_objects_to_parse); + + if sys_context('userenv','current_schema') = a_object_owner + or ut_metadata.is_object_visible('ut3.ut_utils') + or ut_metadata.is_object_visible('dba_objects') + then + select value(x)bulk collect into l_objects_to_remove + from table(a_info_rows) x where x.needs_refresh is null; + + ut_annotation_cache_manager.remove_from_cache(l_objects_to_remove); +-- ut_annotation_cache_manager.remove_from_cache( +-- get_missing_objects(a_object_owner, a_object_type) +-- ); + end if; --if some source needs parsing and putting into cache if l_objects_to_parse.count > 0 then build_annot_cache_for_sources( a_object_owner, a_object_type, - get_sources_to_annotate(a_object_owner, a_object_type, l_objects_to_parse), - l_objects_to_parse + get_sources_to_annotate(a_object_owner, a_object_type, l_objects_to_parse) ); end if; end; diff --git a/source/core/ut_metadata.pkb b/source/core/ut_metadata.pkb index 30b0da64e..1693066ec 100644 --- a/source/core/ut_metadata.pkb +++ b/source/core/ut_metadata.pkb @@ -148,15 +148,34 @@ create or replace package body ut_metadata as end; function get_dba_view(a_dba_view_name varchar2) return varchar2 is - l_invalid_object_name exception; l_result varchar2(128) := lower(a_dba_view_name); + begin + if not is_object_visible(a_dba_view_name) then + l_result := replace(l_result,'dba_','all_'); + end if; + return l_result; + end; + + function user_has_execute_any_proc return boolean is + l_ut_owner varchar2(250) := ut_utils.ut_owner; + l_dummy varchar2(250); + begin + execute immediate 'select '||l_ut_owner||'.ut_utils.ut_owner from dual' + into l_dummy; + return true; + exception + when others then + return false; + end; + + function is_object_visible(a_object_name varchar2) return boolean is + l_invalid_object_name exception; pragma exception_init(l_invalid_object_name,-44002); begin - l_result := dbms_assert.sql_object_name(l_result); - return l_result; + return dbms_assert.sql_object_name(a_object_name) is not null; exception when l_invalid_object_name then - return replace(l_result,'dba_','all_'); + return false; end; function package_exists_in_cur_schema(a_object_name varchar2) return boolean is diff --git a/source/core/ut_metadata.pks b/source/core/ut_metadata.pks index 121524a0b..d06c1ea9d 100644 --- a/source/core/ut_metadata.pks +++ b/source/core/ut_metadata.pks @@ -69,6 +69,18 @@ create or replace package ut_metadata authid current_user as */ function get_dba_view(a_dba_view_name varchar2) return varchar2; + /** + * Returns true if object is accessible to current user + * @param a_object_name fully qualified object name (with schema name) + */ + function is_object_visible(a_object_name varchar2) return boolean; + + /** + * Returns true if current user has execute any procedure privilege + * The check is performed by checking if user can execute ut_utils package + */ + function user_has_execute_any_proc return boolean; + /** * Returns true if given object is a package and it exists in current schema * @param a_object_name the name of the object to be checked diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index f6aceae89..4638f5dba 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -1012,6 +1012,31 @@ create or replace package body ut_suite_builder is close a_suite_data_cursor; end; + function get_missing_objects(a_object_owner varchar2) return ut_varchar2_rows is + l_rows sys_refcursor; + l_ut_owner varchar2(250) := ut_utils.ut_owner; + l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); + l_cursor_text varchar2(32767); + l_result ut_varchar2_rows; + begin + l_cursor_text := + q'[select i.object_name + from ]'||l_ut_owner||q'[.ut_suite_cache_package i + where + not exists ( + select 1 from ]'||l_objects_view||q'[ o + where o.owner = i.object_owner + and o.object_name = i.object_name + and o.object_type = 'PACKAGE' + and o.owner = :a_object_owner + ) + and i.object_owner = :a_object_owner]'; + open l_rows for l_cursor_text using a_object_owner, a_object_owner; + fetch l_rows bulk collect into l_result limit 1000000; + close l_rows; + return l_result; + end; + function get_cached_suite_data( a_object_owner varchar2, a_path varchar2 := null, @@ -1177,8 +1202,9 @@ create or replace package body ut_suite_builder is a_object_name varchar2 := null, a_procedure_name varchar2 := null ) return ut_suite_items is - l_annotations_cursor sys_refcursor; - l_suite_cache_time timestamp; + l_annotations_cursor sys_refcursor; + l_suite_cache_time timestamp; + l_skip_all_objects_scan boolean := false; begin l_suite_cache_time := ut_suite_cache_manager.get_schema_parse_time(a_owner_name); open l_annotations_cursor for @@ -1188,12 +1214,23 @@ create or replace package body ut_suite_builder is )x ]' using a_owner_name, l_suite_cache_time; + -- if current user is the onwer or current user has execute any procedure privilege + if sys_context('userenv','current_schema') = a_owner_name + or ut_metadata.is_object_visible('ut3.ut_utils') + then + l_skip_all_objects_scan := true; + end if; + if l_skip_all_objects_scan or ut_metadata.is_object_visible('dba_objects') then + ut_suite_cache_manager.remove_from_cache( a_owner_name, get_missing_objects(a_owner_name) ); + end if; + return build_suites_from_annotations( a_owner_name, l_annotations_cursor, a_path, a_object_name, - a_procedure_name + a_procedure_name, + l_skip_all_objects_scan ); end; @@ -1202,17 +1239,27 @@ create or replace package body ut_suite_builder is l_schema_names ut_varchar2_rows; l_object_names ut_varchar2_rows; l_ut_owner varchar2(250) := ut_utils.ut_owner; + l_need_all_objects_scan boolean := true; begin + -- if current user is the onwer or current user has execute any procedure privilege + if ut_metadata.is_object_visible('ut3.ut_utils') + or (a_schema_names is not null and a_schema_names.count = 1 + and sys_context('userenv','current_schema') = a_schema_names(1)) + then + l_need_all_objects_scan := false; + end if; + execute immediate 'select c.object_owner, c.object_name from '||l_ut_owner||q'[.ut_suite_cache_package c join table ( :a_schema_names ) s - on c.object_owner = upper(s.column_value) + on c.object_owner = upper(s.column_value)]' + || case when l_need_all_objects_scan then q'[ where exists (select 1 from all_objects a where a.owner = c.object_owner and a.object_name = c.object_name and a.object_type = 'PACKAGE') - ]' + ]' end bulk collect into l_schema_names, l_object_names using a_schema_names; l_results.extend( l_schema_names.count ); for i in 1 .. l_schema_names.count loop diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb index 9caf8a946..081b2d590 100644 --- a/source/core/ut_suite_cache_manager.pkb +++ b/source/core/ut_suite_cache_manager.pkb @@ -135,5 +135,17 @@ create or replace package body ut_suite_cache_manager is commit; end; + procedure remove_from_cache(a_schema_name varchar2, a_objects ut_varchar2_rows) is + pragma autonomous_transaction; + begin + delete + from ut_suite_cache_package i + where i.object_owner = a_schema_name + and i.object_name in ( select column_value from table (a_objects) ); + + commit; + end; + + end ut_suite_cache_manager; / diff --git a/source/core/ut_suite_cache_manager.pks b/source/core/ut_suite_cache_manager.pks index 3d5a21f10..02c47988e 100644 --- a/source/core/ut_suite_cache_manager.pks +++ b/source/core/ut_suite_cache_manager.pks @@ -29,5 +29,7 @@ create or replace package ut_suite_cache_manager authid definer is function get_schema_parse_time(a_schema_name varchar2) return timestamp result_cache; + procedure remove_from_cache(a_schema_name varchar2, a_objects ut_varchar2_rows); + end ut_suite_cache_manager; / diff --git a/test/core/annotations/test_annotation_manager.pkb b/test/core/annotations/test_annotation_manager.pkb index 98bea7452..1fb8115ba 100644 --- a/test/core/annotations/test_annotation_manager.pkb +++ b/test/core/annotations/test_annotation_manager.pkb @@ -31,6 +31,7 @@ create or replace package body test_annotation_manager is --%beforetest(some_procedure) procedure some_dummy_test_procedure; end;]'; + execute immediate q'[grant execute on dummy_test_package to public]'; end; procedure modify_dummy_test_package is @@ -56,6 +57,28 @@ create or replace package body test_annotation_manager is execute immediate q'[alter package dummy_test_package compile]'; end; + procedure create_parse_proc_as_ut3$user# is + pragma autonomous_transaction; + begin + execute immediate q'[ + create or replace procedure ut3$user#.parse_annotations is + begin + ut3.ut_annotation_manager.rebuild_annotation_cache('UT3_TESTER','PACKAGE'); + end;]'; + end; + + procedure parse_dummy_test_as_ut3$user# is + pragma autonomous_transaction; + begin + execute immediate 'begin ut3$user#.parse_annotations; end;'; + end; + + procedure drop_parse_proc_as_ut3$user# is + pragma autonomous_transaction; + begin + execute immediate 'drop procedure ut3$user#.parse_annotations'; + end; + procedure cleanup_annotation_cache is pragma autonomous_transaction; begin @@ -204,12 +227,11 @@ create or replace package body test_annotation_manager is l_expected sys_refcursor; l_start_date date; begin - --Arrange - ut3.ut_annotation_manager.rebuild_annotation_cache(user,'PACKAGE'); + parse_dummy_test_as_ut3$user#(); l_start_date := sysdate; drop_dummy_test_package(); --Act - ut3.ut_annotation_manager.rebuild_annotation_cache(user,'PACKAGE'); + parse_dummy_test_as_ut3$user#(); --Assert select max(cache_id) into l_actual_cache_id @@ -217,7 +239,7 @@ create or replace package body test_annotation_manager is where object_owner = user and object_type = 'PACKAGE' and object_name = 'DUMMY_TEST_PACKAGE' and parse_time >= l_start_date; - ut.expect(l_actual_cache_id).to_be_not_null; + ut.expect(l_actual_cache_id).not_to_be_null(); open l_actual for select annotation_position, annotation_name, annotation_text, subobject_name @@ -252,5 +274,29 @@ create or replace package body test_annotation_manager is ut.expect(l_actual).to_be_empty(); end; + procedure cleanup_dropped_data_in_cache is + l_cache_count integer; + l_actual sys_refcursor; + l_expected sys_refcursor; + l_start_date date; + begin + --Arrange + ut3.ut_annotation_manager.rebuild_annotation_cache(user,'PACKAGE'); + l_start_date := sysdate; + drop_dummy_test_package(); + --Act + ut3.ut_annotation_manager.rebuild_annotation_cache(user,'PACKAGE'); + --Assert + select count(1) + into l_cache_count + from ut3.ut_annotation_cache_info + where object_owner = user + and object_type = 'PACKAGE' + and object_name = 'DUMMY_TEST_PACKAGE'; + + ut.expect(l_cache_count).to_equal(0); + + end; + end test_annotation_manager; / diff --git a/test/core/annotations/test_annotation_manager.pks b/test/core/annotations/test_annotation_manager.pks index fb5e0299d..0726c8256 100644 --- a/test/core/annotations/test_annotation_manager.pks +++ b/test/core/annotations/test_annotation_manager.pks @@ -12,6 +12,10 @@ create or replace package test_annotation_manager is procedure create_dummy_test_package; + procedure create_parse_proc_as_ut3$user#; + + procedure drop_parse_proc_as_ut3$user#; + procedure drop_dummy_test_package; --%test(Adds new package to annotation cache info) @@ -34,13 +38,18 @@ create or replace package test_annotation_manager is --%aftertest(drop_dummy_test_package) procedure update_modified_test_package; - --%test(Keeps annotations in cache after object was removed) - --%beforetest(create_dummy_test_package) + --%test(Keeps annotations in cache when object was removed but user can't see whole schema) + --%beforetest(create_dummy_test_package,create_parse_proc_as_ut3$user#) + --%aftertest(drop_parse_proc_as_ut3$user#) procedure keep_dropped_data_in_cache; --%test(Does not return data for dropped object) --%beforetest(create_dummy_test_package) procedure no_data_for_dropped_object; + --%test(Remove object from cache when object dropped and user can see whole schema) + --%beforetest(create_dummy_test_package) + procedure cleanup_dropped_data_in_cache; + end test_annotation_manager; / From cb9cf9790c869286f29363cffcce6aa48770e5fc Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 11 Nov 2018 12:35:01 +0000 Subject: [PATCH 082/115] Resolving some sonar violations. --- .../ut_annotation_cache_manager.pkb | 1 - source/core/ut_metadata.pkb | 1 - source/core/ut_suite_builder.pkb | 32 +++++++------------ 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/source/core/annotations/ut_annotation_cache_manager.pkb b/source/core/annotations/ut_annotation_cache_manager.pkb index 4f9129650..5c40be5b7 100644 --- a/source/core/annotations/ut_annotation_cache_manager.pkb +++ b/source/core/annotations/ut_annotation_cache_manager.pkb @@ -18,7 +18,6 @@ create or replace package body ut_annotation_cache_manager as procedure update_cache(a_object ut_annotated_object) is l_cache_id integer; - l_current_schema varchar2(250) := ut_utils.ut_owner; pragma autonomous_transaction; begin update ut_annotation_cache_info i diff --git a/source/core/ut_metadata.pkb b/source/core/ut_metadata.pkb index 1693066ec..1795c1a0c 100644 --- a/source/core/ut_metadata.pkb +++ b/source/core/ut_metadata.pkb @@ -116,7 +116,6 @@ create or replace package body ut_metadata as end; function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2 is - l_cursor sys_refcursor; l_view_name varchar2(128) := get_dba_view('dba_source'); l_line all_source.text%type; c_key constant varchar2(500) := a_owner || '.' || a_object_name; diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index 4638f5dba..aa0b8ed29 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -58,8 +58,6 @@ create or replace package body ut_suite_builder is gc_endcontext ); - gc_placeholder constant varchar2(3) := '\\%'; - gc_integer_exception constant varchar2(1) := 'I'; gc_named_exception constant varchar2(1) := 'N'; @@ -218,7 +216,6 @@ create or replace package body ut_suite_builder is function get_exception_number (a_exception_var in varchar2) return integer is l_exc_no integer; l_exc_type varchar2(50); - l_sql varchar2(32767); function remap_no_data_found (a_number integer) return integer is begin return case a_number when 100 then -1403 else a_number end; @@ -260,7 +257,7 @@ create or replace package body ut_suite_builder is l_exception_number_list ut_integer_list := ut_integer_list(); c_regexp_for_exception_no constant varchar2(30) := '^-?[[:digit:]]{1,5}$'; begin - /*the a_expected_error_codes is converted to a ut_varchar2_list after that is trimmed and filtered to left only valid exception numbers*/ + --the a_expected_error_codes is converted to a ut_varchar2_list after that is trimmed and filtered to left only valid exception numbers l_throws_list := ut_utils.trim_list_elements(ut_utils.string_to_table(a_annotation_text, ',', 'Y')); for i in 1 .. l_throws_list.count @@ -407,18 +404,15 @@ create or replace package body ut_suite_builder is a_for_annotation varchar2, a_procedure_name t_object_name := null ) is - l_annotation_name t_annotation_name; l_line_no binary_integer; begin - if a_annotations.exists(a_for_annotation) then - if a_annotations(a_for_annotation).count > 1 then - --start from second occurrence of annotation - l_line_no := a_annotations(a_for_annotation).next( a_annotations(a_for_annotation).first ); - while l_line_no is not null loop - add_annotation_ignored_warning( a_suite, a_for_annotation, 'Duplicate annotation %%%.', l_line_no, a_procedure_name ); - l_line_no := a_annotations(a_for_annotation).next( l_line_no ); - end loop; - end if; + if a_annotations.exists(a_for_annotation) and a_annotations(a_for_annotation).count > 1 then + --start from second occurrence of annotation + l_line_no := a_annotations(a_for_annotation).next( a_annotations(a_for_annotation).first ); + while l_line_no is not null loop + add_annotation_ignored_warning( a_suite, a_for_annotation, 'Duplicate annotation %%%.', l_line_no, a_procedure_name ); + l_line_no := a_annotations(a_for_annotation).next( l_line_no ); + end loop; end if; end; @@ -430,8 +424,7 @@ create or replace package body ut_suite_builder is a_invalid_annotations ut_varchar2_list ) is l_annotation_name t_annotation_name; - l_warning varchar2(32767); - l_line_no binary_integer; + l_line_no binary_integer; begin if a_proc_annotations.exists(a_for_annotation) then l_annotation_name := a_proc_annotations.first; @@ -739,9 +732,8 @@ create or replace package body ut_suite_builder is while l_context_pos is not null loop l_end_context_pos := get_endcontext_position(l_context_pos, a_annotations.by_name ); - if l_end_context_pos is null then - exit; - end if; + + exit when l_end_context_pos is null; l_context_items := ut_suite_items(); --create a sub-set of annotations to process as sub-suite (context) @@ -1156,10 +1148,8 @@ create or replace package body ut_suite_builder is a_skip_all_objects boolean := false ) return ut_suite_items is l_suites ut_suite_items; - l_annotations_cursor sys_refcursor; l_annotated_objects ut_annotated_objects; l_suite_items ut_suite_items; - l_suite_data_cursor sys_refcursor; begin loop fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; From 8779025d8ff01fc03a935e16e9199978d8877d52 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 11 Nov 2018 13:09:44 +0000 Subject: [PATCH 083/115] Moving away from full outer join. Added static schema name rather than bind variable. --- .../annotations/ut_annotation_manager.pkb | 112 ++++++++---------- source/core/ut_suite_builder.pkb | 13 +- 2 files changed, 55 insertions(+), 70 deletions(-) diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb index 3559982cf..80de4d1a7 100644 --- a/source/core/annotations/ut_annotation_manager.pkb +++ b/source/core/annotations/ut_annotation_manager.pkb @@ -19,37 +19,37 @@ create or replace package body ut_annotation_manager as ------------------------------ --private definitions --- function get_missing_objects(a_object_owner varchar2, a_object_type varchar2) return ut_annotation_objs_cache_info is --- l_rows sys_refcursor; --- l_ut_owner varchar2(250) := ut_utils.ut_owner; --- l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); --- l_cursor_text varchar2(32767); --- l_result ut_annotation_objs_cache_info; --- begin --- l_cursor_text := --- q'[select ]'||l_ut_owner||q'[.ut_annotation_obj_cache_info( --- object_owner => i.object_owner, --- object_name => i.object_name, --- object_type => i.object_type, --- needs_refresh => null --- ) --- from ]'||l_ut_owner||q'[.ut_annotation_cache_info i --- where --- not exists ( --- select 1 from ]'||l_objects_view||q'[ o --- where o.owner = i.object_owner --- and o.object_name = i.object_name --- and o.object_type = i.object_type --- and o.owner = :a_object_owner --- and o.object_type = :a_object_type --- ) --- and i.object_owner = :a_object_owner --- and i.object_type = :a_object_type]'; --- open l_rows for l_cursor_text using a_object_owner, a_object_type, a_object_owner, a_object_type; --- fetch l_rows bulk collect into l_result limit 1000000; --- close l_rows; --- return l_result; --- end; + function get_missing_objects(a_object_owner varchar2, a_object_type varchar2) return ut_annotation_objs_cache_info is + l_rows sys_refcursor; + l_ut_owner varchar2(250) := ut_utils.ut_owner; + l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); + l_cursor_text varchar2(32767); + l_result ut_annotation_objs_cache_info; + begin + l_cursor_text := + q'[select ]'||l_ut_owner||q'[.ut_annotation_obj_cache_info( + object_owner => i.object_owner, + object_name => i.object_name, + object_type => i.object_type, + needs_refresh => null + ) + from ]'||l_ut_owner||q'[.ut_annotation_cache_info i + where + not exists ( + select 1 from ]'||l_objects_view||q'[ o + where o.owner = i.object_owner + and o.object_name = i.object_name + and o.object_type = i.object_type + and o.owner = :a_object_owner + and o.object_type = :a_object_type + ) + and i.object_owner = :a_object_owner + and i.object_type = :a_object_type]'; + open l_rows for l_cursor_text using a_object_owner, a_object_type, a_object_owner, a_object_type; + fetch l_rows bulk collect into l_result limit 1000000; + close l_rows; + return l_result; + end; function get_annotation_objs_info(a_object_owner varchar2, a_object_type varchar2, a_parse_date timestamp := null) return ut_annotation_objs_cache_info is l_rows sys_refcursor; @@ -60,36 +60,25 @@ create or replace package body ut_annotation_manager as begin l_cursor_text := q'[select ]'||l_ut_owner||q'[.ut_annotation_obj_cache_info( - object_owner => nvl( o.owner, i.object_owner ), - object_name => nvl( o.object_name, i.object_name ), - object_type => nvl( o.object_type, i.object_type ), - needs_refresh => - case - when o.last_ddl_time < cast(i.parse_time as date) then 'N' - when o.owner is null then null - else 'Y' - end + object_owner => o.owner, + object_name => o.object_name, + object_type => o.object_type, + needs_refresh => case when o.last_ddl_time < cast(i.parse_time as date) then 'N' else 'Y' end ) - from ( - select * from ]'||l_objects_view||q'[ o - where o.owner = :a_object_owner - and o.object_type = :a_object_type - ) o - full outer join ( - select * from ]'||l_ut_owner||q'[.ut_annotation_cache_info i - where i.object_owner = :a_object_owner - and i.object_type = :a_object_type - ) i + from ]'||l_objects_view||q'[ o + left join ]'||l_ut_owner||q'[.ut_annotation_cache_info i on o.owner = i.object_owner and o.object_name = i.object_name and o.object_type = i.object_type - where ]' - || case + where o.owner = ']'||a_object_owner||q'[' + and o.object_type = ']'||a_object_type||q'[' + and ]' + || case when a_parse_date is null - then ':a_parse_date is null' - else 'o.last_ddl_time >= cast(:a_parse_date as date) or o.last_ddl_time is null' - end; - open l_rows for l_cursor_text using a_object_owner, a_object_type, a_object_owner, a_object_type, a_parse_date; + then ':a_parse_date is null' + else 'o.last_ddl_time >= cast(:a_parse_date as date)' + end; + open l_rows for l_cursor_text using a_parse_date; fetch l_rows bulk collect into l_result limit 1000000; close l_rows; return l_result; @@ -197,7 +186,6 @@ create or replace package body ut_annotation_manager as a_info_rows ut_annotation_objs_cache_info ) is l_objects_to_parse ut_annotation_objs_cache_info; - l_objects_to_remove ut_annotation_objs_cache_info; begin select value(x)bulk collect into l_objects_to_parse from table(a_info_rows) x where x.needs_refresh = 'Y'; @@ -208,13 +196,9 @@ create or replace package body ut_annotation_manager as or ut_metadata.is_object_visible('ut3.ut_utils') or ut_metadata.is_object_visible('dba_objects') then - select value(x)bulk collect into l_objects_to_remove - from table(a_info_rows) x where x.needs_refresh is null; - - ut_annotation_cache_manager.remove_from_cache(l_objects_to_remove); --- ut_annotation_cache_manager.remove_from_cache( --- get_missing_objects(a_object_owner, a_object_type) --- ); + ut_annotation_cache_manager.remove_from_cache( + get_missing_objects(a_object_owner, a_object_type) + ); end if; --if some source needs parsing and putting into cache diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index aa0b8ed29..fee7524b4 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -1020,10 +1020,10 @@ create or replace package body ut_suite_builder is where o.owner = i.object_owner and o.object_name = i.object_name and o.object_type = 'PACKAGE' - and o.owner = :a_object_owner + and o.owner = ']'||a_object_owner||q'[' ) - and i.object_owner = :a_object_owner]'; - open l_rows for l_cursor_text using a_object_owner, a_object_owner; + and i.object_owner = ']'||a_object_owner||q'[']'; + open l_rows for l_cursor_text; fetch l_rows bulk collect into l_result limit 1000000; close l_rows; return l_result; @@ -1061,10 +1061,11 @@ create or replace package body ut_suite_builder is ( select 1 from all_objects a where a.object_name = c.object_name + and a.object_owner = ']'||upper(a_object_owner)||q'[' and a.owner = c.object_owner and a.object_type = 'PACKAGE' )]' end ||q'[ - and c.object_owner = :a_object_owner + and c.object_owner = ']'||upper(a_object_owner)||q'[' and ( ]' || case when l_path is not null then q'[ :l_path||'.' like c.path || '.%' /*all children and self*/ or ( c.path||'.' like :l_path || '.%' --all parents @@ -1134,7 +1135,7 @@ create or replace package body ut_suite_builder is end, '.', chr(0)) desc nulls last, c.object_name desc, c.line_no]' - using upper(a_object_owner), l_path, l_path, upper(a_object_name), upper(a_procedure_name); + using l_path, l_path, upper(a_object_name), upper(a_procedure_name); return l_result; end; @@ -1238,7 +1239,7 @@ create or replace package body ut_suite_builder is then l_need_all_objects_scan := false; end if; - + execute immediate 'select c.object_owner, c.object_name from '||l_ut_owner||q'[.ut_suite_cache_package c join table ( :a_schema_names ) s From b3e98bec52c70450336dcfdded55a278782c4846 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 11 Nov 2018 23:15:44 +0000 Subject: [PATCH 084/115] Reorganizing code a bit. --- source/core/ut_suite_builder.pkb | 443 ++----------------------------- source/core/ut_suite_builder.pks | 30 +-- source/core/ut_suite_manager.pkb | 430 +++++++++++++++++++++++++++++- source/core/ut_suite_manager.pks | 15 ++ test/core/test_suite_builder.pkb | 2 +- 5 files changed, 457 insertions(+), 463 deletions(-) diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb index fee7524b4..d946b2a5d 100644 --- a/source/core/ut_suite_builder.pkb +++ b/source/core/ut_suite_builder.pkb @@ -93,10 +93,6 @@ create or replace package body ut_suite_builder is by_name tt_annotations_by_name ); - subtype t_cached_suite is ut_suite_cache%rowtype; - type tt_cached_suites is table of t_cached_suite; - type t_cached_suites_cursor is ref cursor return t_cached_suite; - procedure delete_annotations_range( a_annotations in out nocopy t_annotations_info, a_start_pos t_annotation_position, @@ -320,20 +316,6 @@ create or replace package body ut_suite_builder is end if; end; - function sort_by_seq_no( - a_list ut_executables - ) return ut_executables is - l_results ut_executables := ut_executables(); - begin - if a_list is not null then - l_results.extend(a_list.count); - for i in 1 .. a_list.count loop - l_results(a_list(i).seq_no) := a_list(i); - end loop; - end if; - return l_results; - end; - function convert_list( a_list tt_executables ) return ut_executables is @@ -819,33 +801,6 @@ create or replace package body ut_suite_builder is end loop; end; - procedure create_suite_item_list( a_annotations t_annotations_info, a_suite_items out nocopy ut_suite_items ) is - l_annotations t_annotations_info := a_annotations; - l_annotation_pos t_annotation_position; - l_suite ut_suite; - begin - if l_annotations.by_name.exists(gc_suite) then - l_annotation_pos := l_annotations.by_name(gc_suite).first; - l_suite := ut_suite(l_annotations.owner, l_annotations.name, l_annotation_pos); - l_suite.description := l_annotations.by_name( gc_suite)( l_annotation_pos); - l_suite.parse_time := l_annotations.parse_time; - warning_on_unknown_annotations(l_suite, l_annotations.by_line); - - warning_on_duplicate_annot( l_suite, l_annotations.by_name, gc_suite ); - - build_suitepath( l_suite, l_annotations ); - get_suite_contexts_items( l_suite, l_annotations, a_suite_items ); - --create suite tests and add - add_suite_tests( l_suite, l_annotations, a_suite_items ); - - --by this time all contexts were consumed and l_annotations should not have any context/endcontext annotation in it. - warning_on_incomplete_context( l_suite, l_annotations.by_name ); - - a_suite_items.extend; - a_suite_items( a_suite_items.last) := l_suite; - end if; - end; - function convert_package_annotations(a_object ut_annotated_object) return t_annotations_info is l_result t_annotations_info; l_annotation t_annotation; @@ -872,391 +827,33 @@ create or replace package body ut_suite_builder is return l_result; end; - procedure copy_list_reverse_order( - a_list in out nocopy ut_suite_items - ) is - l_start_idx pls_integer; - l_end_idx pls_integer; - l_item ut_suite_item; - begin - l_start_idx := a_list.first; - l_end_idx := a_list.last; - while l_start_idx < l_end_idx loop - l_item := a_list(l_start_idx); - a_list(l_start_idx) := a_list(l_end_idx); - a_list(l_end_idx) := l_item; - l_end_idx := a_list.prior(l_end_idx); - l_start_idx := a_list.next(l_start_idx); - end loop; - end; - - procedure reconstruct_from_cache( - a_suites out nocopy ut_suite_items, - a_suite_data_cursor sys_refcursor - ) is - type t_item_levels is table of ut_suite_items index by binary_integer; - c_bulk_limit constant pls_integer := 1000; - l_items_at_level t_item_levels; - l_rows tt_cached_suites; - l_test ut_test; - l_logical_suite ut_logical_suite; - l_level pls_integer; - l_prev_level pls_integer; - l_idx integer; - begin - a_suites := ut_suite_items(); - loop - fetch a_suite_data_cursor bulk collect into l_rows limit c_bulk_limit; - exit when l_rows.count = 0; - - l_idx := l_rows.first; - loop - l_test := null; - l_logical_suite := null; - case l_rows(l_idx).self_type - when 'UT_TEST' then - l_test := - ut_test( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - 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), - item => l_rows(l_idx).item, - 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), - all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), - parent_error_stack_trace => null, expected_error_codes => l_rows(l_idx).expected_error_codes - ); - when 'UT_SUITE' then - l_logical_suite := - ut_suite( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => ut_suite_items(), - 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) - ); - when 'UT_SUITE_CONTEXT' then - l_logical_suite := - ut_suite_context( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => ut_suite_items(), - 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) - ); - when 'UT_LOGICAL_SUITE' then - l_logical_suite := - ut_logical_suite( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => ut_suite_items() - ); - end case; - - l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1; - - if l_level > 1 then - if l_prev_level > l_level then - l_logical_suite.items := l_items_at_level(l_prev_level); - l_items_at_level(l_prev_level).delete; - end if; - if not l_items_at_level.exists(l_level) then - l_items_at_level(l_level) := ut_suite_items(); - end if; - l_items_at_level(l_level).extend; - if l_test is not null then - l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_test; - else - l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_logical_suite; - end if; - else - if l_prev_level > l_level then - l_logical_suite.items := l_items_at_level(l_prev_level); - l_items_at_level(l_prev_level).delete; - end if; - a_suites.extend; - a_suites(a_suites.last) := l_logical_suite; - end if; - l_prev_level := l_level; - l_idx := l_rows.next(l_idx); - exit when l_idx is null; - end loop; - exit when l_rows.count < c_bulk_limit; - end loop; - copy_list_reverse_order( a_suites ); - close a_suite_data_cursor; - end; - - function get_missing_objects(a_object_owner varchar2) return ut_varchar2_rows is - l_rows sys_refcursor; - l_ut_owner varchar2(250) := ut_utils.ut_owner; - l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); - l_cursor_text varchar2(32767); - l_result ut_varchar2_rows; - begin - l_cursor_text := - q'[select i.object_name - from ]'||l_ut_owner||q'[.ut_suite_cache_package i - where - not exists ( - select 1 from ]'||l_objects_view||q'[ o - where o.owner = i.object_owner - and o.object_name = i.object_name - and o.object_type = 'PACKAGE' - and o.owner = ']'||a_object_owner||q'[' - ) - and i.object_owner = ']'||a_object_owner||q'[']'; - open l_rows for l_cursor_text; - fetch l_rows bulk collect into l_result limit 1000000; - close l_rows; - return l_result; - end; - - function get_cached_suite_data( - a_object_owner varchar2, - a_path varchar2 := null, - a_object_name varchar2 := null, - a_procedure_name varchar2 := null, - a_skip_all_objects boolean := false - ) return t_cached_suites_cursor is - l_path varchar2( 4000 ); - l_result sys_refcursor; - l_ut_owner varchar2(250) := ut_utils.ut_owner; + procedure create_suite_item_list( a_annotated_object ut_annotated_object, a_suite_items out nocopy ut_suite_items ) is + l_annotations t_annotations_info; + l_annotation_pos t_annotation_position; + l_suite ut_suite; begin - if a_path is null and a_object_name is not null then - execute immediate 'select min(path) - from '||l_ut_owner||q'[.ut_suite_cache - where object_owner = :a_object_owner - and object_name = :a_object_name - and name = nvl(:a_procedure_name, name)]' - into l_path using upper(a_object_owner), upper(a_object_name), upper(a_procedure_name); - else - l_path := lower( a_path ); - end if; - - open l_result for - q'[with - suite_items as ( - select /*+ cardinality(c 100) */ c.* - from ]'||l_ut_owner||q'[.ut_suite_cache c - where 1 = 1 ]'||case when not a_skip_all_objects then q'[ - and exists - ( select 1 - from all_objects a - where a.object_name = c.object_name - and a.object_owner = ']'||upper(a_object_owner)||q'[' - and a.owner = c.object_owner - and a.object_type = 'PACKAGE' - )]' end ||q'[ - and c.object_owner = ']'||upper(a_object_owner)||q'[' - and ( ]' || case when l_path is not null then q'[ - :l_path||'.' like c.path || '.%' /*all children and self*/ - or ( c.path||'.' like :l_path || '.%' --all parents - ]' - else ' :l_path is null and ( :l_path is null ' end - || case when a_object_name is not null - then 'and c.object_name = :a_object_name ' - else 'and :a_object_name is null' end ||' - '|| case when a_procedure_name is not null - then 'and c.name = :a_procedure_name' - else 'and :a_procedure_name is null' end ||q'[ - ) - ) - ), - suitepaths as ( - select distinct substr(path,1,instr(path,'.',-1)-1) as suitepath, - path, - object_owner - from suite_items - where self_type = 'UT_SUITE' - ), - gen as ( - select rownum as pos - from xmltable('1 to 20') - ), - suitepath_part AS ( - select distinct - substr(b.suitepath, 1, instr(b.suitepath || '.', '.', 1, g.pos) -1) as path, - object_owner - from suitepaths b - join gen g - on g.pos <= regexp_count(b.suitepath, '\w+') - ), - logical_suite_data as ( - select 'UT_LOGICAL_SUITE' as self_type, p.path, p.object_owner, - upper( substr(p.path, instr( p.path, '.', -1 ) + 1 ) ) as object_name, - cast(null as ]'||l_ut_owner||q'[.ut_executables) as x, - cast(null as ]'||l_ut_owner||q'[.ut_integer_list) as y, - cast(null as ]'||l_ut_owner||q'[.ut_executable_test) as z - from suitepath_part p - where p.path - not in (select s.path from suitepaths s) - ), - logical_suites as ( - select to_number(null) as id, s.self_type, s.path, s.object_owner, s.object_name, - s.object_name as name, null as line_no, null as parse_time, - null as description, null as rollback_type, 0 as disabled_flag, - ]'||l_ut_owner||q'[.ut_varchar2_rows() as warnings, - s.x as before_all_list, s.x as after_all_list, - s.x as before_each_list, s.x as before_test_list, - s.x as after_each_list, s.x as after_test_list, - s.y as expected_error_codes, s.z as item - from logical_suite_data s - ), - items as ( - select * from suite_items - union all - select * from logical_suites - ) - select c.* - from items c - order by c.object_owner, - replace(case - when c.self_type in ( 'UT_TEST' ) - then substr(c.path, 1, instr(c.path, '.', -1) ) - else c.path - end, '.', chr(0)) desc nulls last, - c.object_name desc, - c.line_no]' - using l_path, l_path, upper(a_object_name), upper(a_procedure_name); - - return l_result; - end; + l_annotations := convert_package_annotations( a_annotated_object ); - function build_suites_from_annotations( - a_owner_name varchar2, - a_annotated_objects sys_refcursor, - a_path varchar2 := null, - a_object_name varchar2 := null, - a_procedure_name varchar2 := null, - a_skip_all_objects boolean := false - ) return ut_suite_items is - l_suites ut_suite_items; - l_annotated_objects ut_annotated_objects; - l_suite_items ut_suite_items; - begin - loop - fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; + if l_annotations.by_name.exists(gc_suite) then + l_annotation_pos := l_annotations.by_name(gc_suite).first; + l_suite := ut_suite(l_annotations.owner, l_annotations.name, l_annotation_pos); + l_suite.description := l_annotations.by_name( gc_suite)( l_annotation_pos); + l_suite.parse_time := l_annotations.parse_time; + warning_on_unknown_annotations(l_suite, l_annotations.by_line); - for i in 1 .. l_annotated_objects.count loop - create_suite_item_list( - convert_package_annotations( l_annotated_objects( i ) ), - l_suite_items - ); - ut_suite_cache_manager.save_object_cache( - a_owner_name, - l_annotated_objects( i ).object_name, - l_annotated_objects( i ).parse_time, - l_suite_items - ); - end loop; - exit when a_annotated_objects%notfound; - end loop; - close a_annotated_objects; - - reconstruct_from_cache( - l_suites, - get_cached_suite_data( - a_owner_name, - a_path, - a_object_name, - a_procedure_name, - a_skip_all_objects - ) - ); - for i in 1 .. l_suites.count loop - l_suites( i ).set_rollback_type( l_suites( i ).get_rollback_type ); - end loop; - return l_suites; - end; + warning_on_duplicate_annot( l_suite, l_annotations.by_name, gc_suite ); - function build_schema_suites( - a_owner_name varchar2, - a_path varchar2 := null, - a_object_name varchar2 := null, - a_procedure_name varchar2 := null - ) return ut_suite_items is - l_annotations_cursor sys_refcursor; - l_suite_cache_time timestamp; - l_skip_all_objects_scan boolean := false; - begin - l_suite_cache_time := ut_suite_cache_manager.get_schema_parse_time(a_owner_name); - open l_annotations_cursor for - q'[select value(x) - from table( - ]' || ut_utils.ut_owner || q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE', :a_suite_cache_parse_time) - )x ]' - using a_owner_name, l_suite_cache_time; - - -- if current user is the onwer or current user has execute any procedure privilege - if sys_context('userenv','current_schema') = a_owner_name - or ut_metadata.is_object_visible('ut3.ut_utils') - then - l_skip_all_objects_scan := true; - end if; - if l_skip_all_objects_scan or ut_metadata.is_object_visible('dba_objects') then - ut_suite_cache_manager.remove_from_cache( a_owner_name, get_missing_objects(a_owner_name) ); - end if; + build_suitepath( l_suite, l_annotations ); + get_suite_contexts_items( l_suite, l_annotations, a_suite_items ); + --create suite tests and add + add_suite_tests( l_suite, l_annotations, a_suite_items ); - return build_suites_from_annotations( - a_owner_name, - l_annotations_cursor, - a_path, - a_object_name, - a_procedure_name, - l_skip_all_objects_scan - ); - end; + --by this time all contexts were consumed and l_annotations should not have any context/endcontext annotation in it. + warning_on_incomplete_context( l_suite, l_annotations.by_name ); - function get_schema_ut_packages( a_schema_names ut_varchar2_rows ) return ut_object_names is - l_results ut_object_names := ut_object_names( ); - l_schema_names ut_varchar2_rows; - l_object_names ut_varchar2_rows; - l_ut_owner varchar2(250) := ut_utils.ut_owner; - l_need_all_objects_scan boolean := true; - begin - -- if current user is the onwer or current user has execute any procedure privilege - if ut_metadata.is_object_visible('ut3.ut_utils') - or (a_schema_names is not null and a_schema_names.count = 1 - and sys_context('userenv','current_schema') = a_schema_names(1)) - then - l_need_all_objects_scan := false; + a_suite_items.extend; + a_suite_items( a_suite_items.last) := l_suite; end if; - - execute immediate 'select c.object_owner, c.object_name - from '||l_ut_owner||q'[.ut_suite_cache_package c - join table ( :a_schema_names ) s - on c.object_owner = upper(s.column_value)]' - || case when l_need_all_objects_scan then q'[ - where exists - (select 1 from all_objects a - where a.owner = c.object_owner - and a.object_name = c.object_name - and a.object_type = 'PACKAGE') - ]' end - bulk collect into l_schema_names, l_object_names using a_schema_names; - l_results.extend( l_schema_names.count ); - for i in 1 .. l_schema_names.count loop - l_results( i ) := ut_object_name( l_schema_names( i ), l_object_names( i ) ); - end loop; - return l_results; end; end ut_suite_builder; diff --git a/source/core/ut_suite_builder.pks b/source/core/ut_suite_builder.pks index 881df24c9..5e2624a30 100644 --- a/source/core/ut_suite_builder.pks +++ b/source/core/ut_suite_builder.pks @@ -21,32 +21,12 @@ create or replace package ut_suite_builder authid current_user is */ /** - * Builds set of hierarchical suites for a given schema - * - * @param a_owner_name name of the schema to builds suite for - * @param a_path suite path to build suite for (optional) - * @param a_object_name object name to build suite for (optional) - * @param a_object_name procedure name to build suite for (optional) - * @return list of suites organized into hierarchy - * + * Creates a list of suite items for an annotated object */ - function build_schema_suites( - a_owner_name varchar2, - a_path varchar2 := null, - a_object_name varchar2 := null, - a_procedure_name varchar2 := null - ) return ut_suite_items; - - function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names; - - function build_suites_from_annotations( - a_owner_name varchar2, - a_annotated_objects sys_refcursor, - a_path varchar2 := null, - a_object_name varchar2 := null, - a_procedure_name varchar2 := null, - a_skip_all_objects boolean := false - ) return ut_suite_items; + procedure create_suite_item_list( + a_annotated_object ut_annotated_object, + a_suite_items out nocopy ut_suite_items + ); end ut_suite_builder; / diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index 4aab5503b..5e296f02e 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -25,12 +25,11 @@ create or replace package body ut_suite_manager is type t_path_items is table of t_path_item; type t_schema_paths is table of t_path_items index by varchar2(250 char); - ------------------ + subtype t_cached_suite is ut_suite_cache%rowtype; + type tt_cached_suites is table of t_cached_suite; + type t_cached_suites_cursor is ref cursor return t_cached_suite; - function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names is - begin - return ut_suite_builder.get_schema_ut_packages(a_schema_names); - end; + ------------------ procedure validate_paths(a_paths in ut_varchar2_list) is l_path varchar2(32767); @@ -108,13 +107,6 @@ create or replace package body ut_suite_manager is l_schema_names := resolve_schema_names(a_paths); end; - function get_schema_names(a_paths ut_varchar2_list) return ut_varchar2_rows is - l_paths ut_varchar2_list; - begin - l_paths := a_paths; - return resolve_schema_names(l_paths); - end; - function group_paths_by_schema(a_paths ut_varchar2_list) return t_schema_paths is c_package_path_regex constant varchar2(100) := '^([A-Za-z0-9$#_]+)(\.([A-Za-z0-9$#_]+))?(\.([A-Za-z0-9$#_]+))?$'; l_schema varchar2(4000); @@ -141,7 +133,417 @@ create or replace package body ut_suite_manager is end loop; return l_results; end; - + + + function sort_by_seq_no( + a_list ut_executables + ) return ut_executables is + l_results ut_executables := ut_executables(); + begin + if a_list is not null then + l_results.extend(a_list.count); + for i in 1 .. a_list.count loop + l_results(a_list(i).seq_no) := a_list(i); + end loop; + end if; + return l_results; + end; + + procedure copy_list_reverse_order( + a_list in out nocopy ut_suite_items + ) is + l_start_idx pls_integer; + l_end_idx pls_integer; + l_item ut_suite_item; + begin + l_start_idx := a_list.first; + l_end_idx := a_list.last; + while l_start_idx < l_end_idx loop + l_item := a_list(l_start_idx); + a_list(l_start_idx) := a_list(l_end_idx); + a_list(l_end_idx) := l_item; + l_end_idx := a_list.prior(l_end_idx); + l_start_idx := a_list.next(l_start_idx); + end loop; + end; + + procedure reconstruct_from_cache( + a_suites out nocopy ut_suite_items, + a_suite_data_cursor sys_refcursor + ) is + type t_item_levels is table of ut_suite_items index by binary_integer; + c_bulk_limit constant pls_integer := 1000; + l_items_at_level t_item_levels; + l_rows tt_cached_suites; + l_test ut_test; + l_logical_suite ut_logical_suite; + l_level pls_integer; + l_prev_level pls_integer; + l_idx integer; + begin + a_suites := ut_suite_items(); + loop + fetch a_suite_data_cursor bulk collect into l_rows limit c_bulk_limit; + exit when l_rows.count = 0; + + l_idx := l_rows.first; + loop + l_test := null; + l_logical_suite := null; + case l_rows(l_idx).self_type + when 'UT_TEST' then + l_test := + ut_test( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + 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), + item => l_rows(l_idx).item, + 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), + all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), + parent_error_stack_trace => null, expected_error_codes => l_rows(l_idx).expected_error_codes + ); + when 'UT_SUITE' then + l_logical_suite := + ut_suite( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items(), + 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) + ); + when 'UT_SUITE_CONTEXT' then + l_logical_suite := + ut_suite_context( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items(), + 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) + ); + when 'UT_LOGICAL_SUITE' then + l_logical_suite := + ut_logical_suite( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items() + ); + end case; + + l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1; + + if l_level > 1 then + if l_prev_level > l_level then + l_logical_suite.items := l_items_at_level(l_prev_level); + l_items_at_level(l_prev_level).delete; + end if; + if not l_items_at_level.exists(l_level) then + l_items_at_level(l_level) := ut_suite_items(); + end if; + l_items_at_level(l_level).extend; + if l_test is not null then + l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_test; + else + l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_logical_suite; + end if; + else + if l_prev_level > l_level then + l_logical_suite.items := l_items_at_level(l_prev_level); + l_items_at_level(l_prev_level).delete; + end if; + a_suites.extend; + a_suites(a_suites.last) := l_logical_suite; + end if; + l_prev_level := l_level; + l_idx := l_rows.next(l_idx); + exit when l_idx is null; + end loop; + exit when l_rows.count < c_bulk_limit; + end loop; + copy_list_reverse_order( a_suites ); + close a_suite_data_cursor; + end; + + function get_missing_objects(a_object_owner varchar2) return ut_varchar2_rows is + l_rows sys_refcursor; + l_ut_owner varchar2(250) := ut_utils.ut_owner; + l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); + l_cursor_text varchar2(32767); + l_result ut_varchar2_rows; + begin + l_cursor_text := + q'[select i.object_name + from ]'||l_ut_owner||q'[.ut_suite_cache_package i + where + not exists ( + select 1 from ]'||l_objects_view||q'[ o + where o.owner = i.object_owner + and o.object_name = i.object_name + and o.object_type = 'PACKAGE' + and o.owner = ']'||a_object_owner||q'[' + ) + and i.object_owner = ']'||a_object_owner||q'[']'; + open l_rows for l_cursor_text; + fetch l_rows bulk collect into l_result limit 1000000; + close l_rows; + return l_result; + end; + + function get_cached_suite_data( + a_object_owner varchar2, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null, + a_skip_all_objects boolean := false + ) return t_cached_suites_cursor is + l_path varchar2( 4000 ); + l_result sys_refcursor; + l_ut_owner varchar2(250) := ut_utils.ut_owner; + begin + if a_path is null and a_object_name is not null then + execute immediate 'select min(path) + from '||l_ut_owner||q'[.ut_suite_cache + where object_owner = :a_object_owner + and object_name = :a_object_name + and name = nvl(:a_procedure_name, name)]' + into l_path using upper(a_object_owner), upper(a_object_name), upper(a_procedure_name); + else + l_path := lower( a_path ); + end if; + + open l_result for + q'[with + suite_items as ( + select /*+ cardinality(c 100) */ c.* + from ]'||l_ut_owner||q'[.ut_suite_cache c + where 1 = 1 ]'||case when not a_skip_all_objects then q'[ + and exists + ( select 1 + from all_objects a + where a.object_name = c.object_name + and a.object_owner = ']'||upper(a_object_owner)||q'[' + and a.owner = c.object_owner + and a.object_type = 'PACKAGE' + )]' end ||q'[ + and c.object_owner = ']'||upper(a_object_owner)||q'[' + and ( ]' || case when l_path is not null then q'[ + :l_path||'.' like c.path || '.%' /*all children and self*/ + or ( c.path||'.' like :l_path || '.%' --all parents + ]' + else ' :l_path is null and ( :l_path is null ' end + || case when a_object_name is not null + then 'and c.object_name = :a_object_name ' + else 'and :a_object_name is null' end ||' + '|| case when a_procedure_name is not null + then 'and c.name = :a_procedure_name' + else 'and :a_procedure_name is null' end ||q'[ + ) + ) + ), + suitepaths as ( + select distinct substr(path,1,instr(path,'.',-1)-1) as suitepath, + path, + object_owner + from suite_items + where self_type = 'UT_SUITE' + ), + gen as ( + select rownum as pos + from xmltable('1 to 20') + ), + suitepath_part AS ( + select distinct + substr(b.suitepath, 1, instr(b.suitepath || '.', '.', 1, g.pos) -1) as path, + object_owner + from suitepaths b + join gen g + on g.pos <= regexp_count(b.suitepath, '\w+') + ), + logical_suite_data as ( + select 'UT_LOGICAL_SUITE' as self_type, p.path, p.object_owner, + upper( substr(p.path, instr( p.path, '.', -1 ) + 1 ) ) as object_name, + cast(null as ]'||l_ut_owner||q'[.ut_executables) as x, + cast(null as ]'||l_ut_owner||q'[.ut_integer_list) as y, + cast(null as ]'||l_ut_owner||q'[.ut_executable_test) as z + from suitepath_part p + where p.path + not in (select s.path from suitepaths s) + ), + logical_suites as ( + select to_number(null) as id, s.self_type, s.path, s.object_owner, s.object_name, + s.object_name as name, null as line_no, null as parse_time, + null as description, null as rollback_type, 0 as disabled_flag, + ]'||l_ut_owner||q'[.ut_varchar2_rows() as warnings, + s.x as before_all_list, s.x as after_all_list, + s.x as before_each_list, s.x as before_test_list, + s.x as after_each_list, s.x as after_test_list, + s.y as expected_error_codes, s.z as item + from logical_suite_data s + ), + items as ( + select * from suite_items + union all + select * from logical_suites + ) + select c.* + from items c + order by c.object_owner, + replace(case + when c.self_type in ( 'UT_TEST' ) + then substr(c.path, 1, instr(c.path, '.', -1) ) + else c.path + end, '.', chr(0)) desc nulls last, + c.object_name desc, + c.line_no]' + using l_path, l_path, upper(a_object_name), upper(a_procedure_name); + + return l_result; + end; + + function build_schema_suites( + a_owner_name varchar2, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null + ) return ut_suite_items is + l_annotations_cursor sys_refcursor; + l_suite_cache_time timestamp; + l_skip_all_objects_scan boolean := false; + begin + l_suite_cache_time := ut_suite_cache_manager.get_schema_parse_time(a_owner_name); + open l_annotations_cursor for + q'[select value(x) + from table( + ]' || ut_utils.ut_owner || q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE', :a_suite_cache_parse_time) + )x ]' + using a_owner_name, l_suite_cache_time; + + -- if current user is the onwer or current user has execute any procedure privilege + if sys_context('userenv','current_schema') = a_owner_name + or ut_metadata.is_object_visible('ut3.ut_utils') + then + l_skip_all_objects_scan := true; + end if; + if l_skip_all_objects_scan or ut_metadata.is_object_visible('dba_objects') then + ut_suite_cache_manager.remove_from_cache( a_owner_name, get_missing_objects(a_owner_name) ); + end if; + + return build_suites_from_annotations( + a_owner_name, + l_annotations_cursor, + a_path, + a_object_name, + a_procedure_name, + l_skip_all_objects_scan + ); + end; + + ----------------------------------------------- + ----------------------------------------------- + ------------- Public definitions ------------- + + function build_suites_from_annotations( + a_owner_name varchar2, + a_annotated_objects sys_refcursor, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null, + a_skip_all_objects boolean := false + ) return ut_suite_items is + l_suites ut_suite_items; + l_annotated_objects ut_annotated_objects; + l_suite_items ut_suite_items; + begin + loop + fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; + + for i in 1 .. l_annotated_objects.count loop + ut_suite_builder.create_suite_item_list( l_annotated_objects( i ), l_suite_items ); + ut_suite_cache_manager.save_object_cache( + a_owner_name, + l_annotated_objects( i ).object_name, + l_annotated_objects( i ).parse_time, + l_suite_items + ); + end loop; + exit when a_annotated_objects%notfound; + end loop; + close a_annotated_objects; + + reconstruct_from_cache( + l_suites, + get_cached_suite_data( + a_owner_name, + a_path, + a_object_name, + a_procedure_name, + a_skip_all_objects + ) + ); + for i in 1 .. l_suites.count loop + l_suites( i ).set_rollback_type( l_suites( i ).get_rollback_type ); + end loop; + return l_suites; + end; + + function get_schema_ut_packages(a_schema_names ut_varchar2_rows) return ut_object_names is + l_results ut_object_names := ut_object_names( ); + l_schema_names ut_varchar2_rows; + l_object_names ut_varchar2_rows; + l_ut_owner varchar2(250) := ut_utils.ut_owner; + l_need_all_objects_scan boolean := true; + begin + -- if current user is the onwer or current user has execute any procedure privilege + if ut_metadata.is_object_visible('ut3.ut_utils') + or (a_schema_names is not null and a_schema_names.count = 1 + and sys_context('userenv','current_schema') = a_schema_names(1)) + then + l_need_all_objects_scan := false; + end if; + + execute immediate 'select c.object_owner, c.object_name + from '||l_ut_owner||q'[.ut_suite_cache_package c + join table ( :a_schema_names ) s + on c.object_owner = upper(s.column_value)]' + || case when l_need_all_objects_scan then q'[ + where exists + (select 1 from all_objects a + where a.owner = c.object_owner + and a.object_name = c.object_name + and a.object_type = 'PACKAGE') + ]' end + bulk collect into l_schema_names, l_object_names using a_schema_names; + l_results.extend( l_schema_names.count ); + for i in 1 .. l_schema_names.count loop + l_results( i ) := ut_object_name( l_schema_names( i ), l_object_names( i ) ); + end loop; + return l_results; + end; + + function get_schema_names(a_paths ut_varchar2_list) return ut_varchar2_rows is + l_paths ut_varchar2_list; + begin + l_paths := a_paths; + return resolve_schema_names(l_paths); + end; + function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items is l_paths ut_varchar2_list := a_paths; l_path_items t_path_items; @@ -164,7 +566,7 @@ create or replace package body ut_suite_manager is l_path_items := l_schema_paths(l_schema); for i in 1 .. l_path_items.count loop l_path_item := l_path_items(i); - l_suites := ut_suite_builder.build_schema_suites( + l_suites := build_schema_suites( upper(l_schema), l_path_item.suite_path, l_path_item.object_name, diff --git a/source/core/ut_suite_manager.pks b/source/core/ut_suite_manager.pks index 3fde7f6b5..22c27fea9 100644 --- a/source/core/ut_suite_manager.pks +++ b/source/core/ut_suite_manager.pks @@ -45,5 +45,20 @@ create or replace package ut_suite_manager authid current_user is */ function get_schema_names(a_paths ut_varchar2_list) return ut_varchar2_rows; + + /** + * Constructs a list of suites based on the list of annotations passed + * the suites are stored in cache + */ + function build_suites_from_annotations( + a_owner_name varchar2, + a_annotated_objects sys_refcursor, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null, + a_skip_all_objects boolean := false + ) return ut_suite_items; + + end ut_suite_manager; / diff --git a/test/core/test_suite_builder.pkb b/test/core/test_suite_builder.pkb index 423e29c0a..bd76e88d8 100644 --- a/test/core/test_suite_builder.pkb +++ b/test/core/test_suite_builder.pkb @@ -14,7 +14,7 @@ create or replace package body test_suite_builder is ut3.ut_annotated_object('UT3_TESTER', a_package_name, 'PACKAGE', systimestamp, a_annotations) ) ) x; - l_suites := ut3.ut_suite_builder.build_suites_from_annotations( + l_suites := ut3.ut_suite_manager.build_suites_from_annotations( a_owner_name => 'UT3_TESTER', a_annotated_objects => l_cursor, a_path => null, From 64dfb41ab3ca8165ca976c0ab9624820ee7b8692 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Mon, 12 Nov 2018 01:18:20 +0000 Subject: [PATCH 085/115] Output buffer&reporters performance improvements --- .../output_buffers/ut_output_buffer_base.tps | 1 + .../output_buffers/ut_output_table_buffer.tpb | 23 +++-- .../output_buffers/ut_output_table_buffer.tps | 1 + source/core/types/ut_output_reporter_base.tpb | 5 ++ source/core/types/ut_output_reporter_base.tps | 2 +- source/core/ut_utils.pkb | 48 +++++++++- source/core/ut_utils.pks | 15 ++++ .../ut_coverage_cobertura_reporter.tpb | 79 +++++++++-------- .../reporters/ut_coverage_html_reporter.tpb | 3 +- .../ut_coverage_report_html_helper.pkb | 87 +++++++++---------- .../ut_coverage_report_html_helper.pks | 2 +- .../reporters/ut_coverage_sonar_reporter.tpb | 65 +++++++------- source/reporters/ut_coveralls_reporter.tpb | 48 +++++----- source/reporters/ut_junit_reporter.tpb | 82 +++++++++-------- source/reporters/ut_sonar_test_reporter.tpb | 27 +++--- source/reporters/ut_teamcity_reporter.tpb | 56 ++++++++---- source/reporters/ut_tfs_junit_reporter.tpb | 55 ++++++------ .../test_cov_cobertura_reporter.pkb | 7 +- .../test_coverage/test_coveralls_reporter.pkb | 15 +++- 19 files changed, 372 insertions(+), 249 deletions(-) diff --git a/source/core/output_buffers/ut_output_buffer_base.tps b/source/core/output_buffers/ut_output_buffer_base.tps index f1d71c502..6f69047d9 100644 --- a/source/core/output_buffers/ut_output_buffer_base.tps +++ b/source/core/output_buffers/ut_output_buffer_base.tps @@ -20,6 +20,7 @@ create or replace type ut_output_buffer_base authid definer as object( member procedure init(self in out nocopy ut_output_buffer_base), not instantiable member procedure close(self in ut_output_buffer_base), not instantiable member procedure send_line(self in ut_output_buffer_base, a_text varchar2), + not instantiable member procedure send_lines(self in ut_output_buffer_base, a_text_list ut_varchar2_rows), not instantiable member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_varchar2_rows pipelined, not instantiable member function get_lines_cursor(a_initial_timeout natural := null, a_timeout_sec natural := null) return sys_refcursor, not instantiable member procedure lines_to_dbms_output(self in ut_output_buffer_base, a_initial_timeout natural := null, a_timeout_sec natural := null) diff --git a/source/core/output_buffers/ut_output_table_buffer.tpb b/source/core/output_buffers/ut_output_table_buffer.tpb index 0cc68b76b..e7045b9df 100644 --- a/source/core/output_buffers/ut_output_table_buffer.tpb +++ b/source/core/output_buffers/ut_output_table_buffer.tpb @@ -47,16 +47,15 @@ create or replace type body ut_output_table_buffer is end; overriding member procedure send_line(self in ut_output_table_buffer, a_text varchar2) is - l_text_list ut_varchar2_rows; pragma autonomous_transaction; begin if a_text is not null then if length(a_text) > ut_utils.gc_max_storage_varchar2_len then - l_text_list := ut_utils.convert_collection(ut_utils.clob_to_table(a_text, ut_utils.gc_max_storage_varchar2_len)); - insert - into ut_output_buffer_tmp(output_id, message_id, text) - select self.output_id, ut_message_id_seq.nextval, t.column_value - from table(l_text_list) t; + self.send_lines( + ut_utils.convert_collection( + ut_utils.clob_to_table(a_text, ut_utils.gc_max_storage_varchar2_len) + ) + ); else insert into ut_output_buffer_tmp(output_id, message_id, text) values (self.output_id, ut_message_id_seq.nextval, a_text); @@ -65,6 +64,18 @@ create or replace type body ut_output_table_buffer is end if; end; + overriding member procedure send_lines(self in ut_output_table_buffer, a_text_list ut_varchar2_rows) is + pragma autonomous_transaction; + begin + insert into ut_output_buffer_tmp(output_id, message_id, text) + select self.output_id, ut_message_id_seq.nextval, t.column_value + from table(a_text_list) t + where t.column_value is not null; + + commit; + end; + + overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_varchar2_rows pipelined is l_buffer_data ut_varchar2_rows; l_already_waited_for number(10,2) := 0; diff --git a/source/core/output_buffers/ut_output_table_buffer.tps b/source/core/output_buffers/ut_output_table_buffer.tps index 96628de77..0e6f83770 100644 --- a/source/core/output_buffers/ut_output_table_buffer.tps +++ b/source/core/output_buffers/ut_output_table_buffer.tps @@ -20,6 +20,7 @@ create or replace type ut_output_table_buffer under ut_output_buffer_base ( constructor function ut_output_table_buffer(self in out nocopy ut_output_table_buffer, a_output_id raw := null) return self as result, overriding member procedure init(self in out nocopy ut_output_table_buffer), overriding member procedure send_line(self in ut_output_table_buffer, a_text varchar2), + overriding member procedure send_lines(self in ut_output_table_buffer, a_text_list ut_varchar2_rows), overriding member procedure close(self in ut_output_table_buffer), overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_varchar2_rows pipelined, overriding member function get_lines_cursor(a_initial_timeout natural := null, a_timeout_sec natural := null) return sys_refcursor, diff --git a/source/core/types/ut_output_reporter_base.tpb b/source/core/types/ut_output_reporter_base.tpb index 32e8b225b..3f62d6546 100644 --- a/source/core/types/ut_output_reporter_base.tpb +++ b/source/core/types/ut_output_reporter_base.tpb @@ -46,6 +46,11 @@ create or replace type body ut_output_reporter_base is self.output_buffer.send_line(a_text); end; + member procedure print_text_lines(self in out nocopy ut_output_reporter_base, a_text_lines ut_varchar2_rows) is + begin + self.output_buffer.send_lines(a_text_lines); + end; + final member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural) return ut_varchar2_rows pipelined is begin for i in (select column_value from table(self.output_buffer.get_lines(a_initial_timeout, a_timeout_sec))) loop diff --git a/source/core/types/ut_output_reporter_base.tps b/source/core/types/ut_output_reporter_base.tps index a0a9f63f6..e23ac9273 100644 --- a/source/core/types/ut_output_reporter_base.tps +++ b/source/core/types/ut_output_reporter_base.tps @@ -22,7 +22,7 @@ create or replace type ut_output_reporter_base under ut_reporter_base( overriding member procedure before_calling_run(self in out nocopy ut_output_reporter_base, a_run in ut_run), member procedure print_text(self in out nocopy ut_output_reporter_base, a_text varchar2), - + member procedure print_text_lines(self in out nocopy ut_output_reporter_base, a_text_lines ut_varchar2_rows), member procedure print_clob(self in out nocopy ut_output_reporter_base, a_clob clob), final member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_varchar2_rows pipelined, diff --git a/source/core/ut_utils.pkb b/source/core/ut_utils.pkb index 2528c04e7..d70357462 100644 --- a/source/core/ut_utils.pkb +++ b/source/core/ut_utils.pkb @@ -326,7 +326,51 @@ create or replace package body ut_utils is end if; end append_to_list; -procedure append_to_clob(a_src_clob in out nocopy clob, a_clob_table t_clob_tab, a_delimiter varchar2:= chr(10)) is + procedure append_to_list(a_list in out nocopy ut_varchar2_rows, a_items ut_varchar2_rows) is + begin + if a_items is not null then + if a_list is null then + a_list := ut_varchar2_rows(); + end if; + for i in 1 .. a_items.count loop + a_list.extend; + a_list(a_list.last) := a_items(i); + end loop; + end if; + end; + + procedure append_to_list(a_list in out nocopy ut_varchar2_rows, a_item clob) is + begin + append_to_list( + a_list, + convert_collection( + clob_to_table( a_item, ut_utils.gc_max_storage_varchar2_len ) + ) + ); + end; + + procedure append_to_list(a_list in out nocopy ut_varchar2_rows, a_item varchar2) is + l_items ut_varchar2_rows; + begin + if a_item is not null then + if a_list is null then + a_list := ut_varchar2_rows(); + end if; + if length(a_item) > gc_max_storage_varchar2_len then + append_to_list( + a_list, + ut_utils.convert_collection( + ut_utils.clob_to_table( a_item, gc_max_storage_varchar2_len ) + ) + ); + else + a_list.extend; + a_list(a_list.last) := a_item; + end if; + end if; + end append_to_list; + + procedure append_to_clob(a_src_clob in out nocopy clob, a_clob_table t_clob_tab, a_delimiter varchar2:= chr(10)) is begin if a_clob_table is not null and cardinality(a_clob_table) > 0 then if a_src_clob is null then @@ -522,7 +566,7 @@ procedure append_to_clob(a_src_clob in out nocopy clob, a_clob_table t_clob_tab, ||'?>'; end; - function trim_list_elements(a_list IN ut_varchar2_list, a_regexp_to_trim in varchar2 default '[:space:]') return ut_varchar2_list is + function trim_list_elements(a_list ut_varchar2_list, a_regexp_to_trim varchar2 default '[:space:]') return ut_varchar2_list is l_trimmed_list ut_varchar2_list; l_index integer; begin diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 60f189a66..2a892c1e9 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -247,6 +247,21 @@ create or replace package ut_utils authid definer is */ procedure append_to_list(a_list in out nocopy ut_varchar2_list, a_item varchar2); + /** + * Append a item to the end of ut_varchar2_rows + */ + procedure append_to_list(a_list in out nocopy ut_varchar2_rows, a_item varchar2); + + /** + * Append a item to the end of ut_varchar2_rows + */ + procedure append_to_list(a_list in out nocopy ut_varchar2_rows, a_item clob); + + /** + * Append a list of items to the end of ut_varchar2_rows + */ + procedure append_to_list(a_list in out nocopy ut_varchar2_rows, a_items ut_varchar2_rows); + procedure append_to_clob(a_src_clob in out nocopy clob, a_clob_table t_clob_tab, a_delimiter varchar2 := chr(10)); procedure append_to_clob(a_src_clob in out nocopy clob, a_new_data clob); diff --git a/source/reporters/ut_coverage_cobertura_reporter.tpb b/source/reporters/ut_coverage_cobertura_reporter.tpb index 0d702dbbd..18221e3d9 100644 --- a/source/reporters/ut_coverage_cobertura_reporter.tpb +++ b/source/reporters/ut_coverage_cobertura_reporter.tpb @@ -39,8 +39,7 @@ create or replace type body ut_coverage_cobertura_reporter is l_line_no := a_unit_coverage.lines.first; if l_line_no is null then for i in 1 .. a_unit_coverage.total_lines loop - l_file_part := ''||chr(10); - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_clob(l_result, ''); end loop; else while l_line_no is not null loop @@ -68,71 +67,75 @@ create or replace type body ut_coverage_cobertura_reporter is function get_coverage_xml( a_coverage_data ut_coverage.t_coverage, a_run ut_run - ) return clob is + ) return ut_varchar2_rows is l_file_part varchar2(32767); - l_result clob; + l_result ut_varchar2_rows := ut_varchar2_rows(); l_unit ut_coverage.t_full_name; l_obj_name ut_coverage.t_object_name; - c_coverage_def constant varchar2(200) := ''||chr(10); - c_file_footer constant varchar2(30) := ''||chr(10); + c_coverage_def constant varchar2(200) := ''; + c_file_footer constant varchar2(30) := ''; c_coverage_footer constant varchar2(30) := ''; - c_sources_footer constant varchar2(30) := ''||chr(10); - c_packages_footer constant varchar2(30) := ''||chr(10); - c_package_footer constant varchar2(30) := ''||chr(10); - c_class_footer constant varchar2(30) := ''||chr(10); - c_lines_footer constant varchar2(30) := ''||chr(10); + c_sources_footer constant varchar2(30) := ''; + c_packages_footer constant varchar2(30) := ''; + c_package_footer constant varchar2(30) := ''; + c_class_footer constant varchar2(30) := ''; + c_lines_footer constant varchar2(30) := ''; l_epoch varchar2(50) := (sysdate - to_date('01-01-1970 00:00:00', 'dd-mm-yyyy hh24:mi:ss')) * 24 * 60 * 60; begin - dbms_lob.createtemporary(l_result,true); - - ut_utils.append_to_clob(l_result, ut_utils.get_xml_header(a_run.client_character_set)||chr(10)); - ut_utils.append_to_clob(l_result, c_coverage_def); + ut_utils.append_to_list( l_result, ut_utils.get_xml_header(a_run.client_character_set) ); + ut_utils.append_to_list( l_result, c_coverage_def ); --write header - l_file_part:= ''; - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list( + l_result, + '' + ); --Write sources l_unit := a_coverage_data.objects.first; - l_file_part := ''||CHR(10); - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list( l_result, '' ); while l_unit is not null loop - l_file_part := ''||dbms_xmlgen.convert(l_unit)||''||chr(10); - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list(l_result, ''||dbms_xmlgen.convert(l_unit)||''); l_unit := a_coverage_data.objects.next(l_unit); end loop; - ut_utils.append_to_clob(l_result, c_sources_footer); + ut_utils.append_to_list(l_result, c_sources_footer); --write packages l_unit := a_coverage_data.objects.first; - l_file_part := ''||CHR(10); - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list(l_result, ''); while l_unit is not null loop l_obj_name := a_coverage_data.objects(l_unit).name; - l_file_part := ''||CHR(10); - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list( + l_result, + '' + ); - l_file_part := ''||CHR(10); - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list( + l_result, + '' + ); - l_file_part := ''||CHR(10); - ut_utils.append_to_clob(l_result, l_file_part); - - dbms_lob.append(l_result,get_lines_xml(a_coverage_data.objects(l_unit))); + ut_utils.append_to_list(l_result, ''); + + ut_utils.append_to_list( l_result, get_lines_xml(a_coverage_data.objects(l_unit)) ); - ut_utils.append_to_clob(l_result, c_lines_footer); - ut_utils.append_to_clob(l_result, c_class_footer); - ut_utils.append_to_clob(l_result, c_package_footer); + ut_utils.append_to_list(l_result, c_lines_footer); + ut_utils.append_to_list(l_result, c_class_footer); + ut_utils.append_to_list(l_result, c_package_footer); l_unit := a_coverage_data.objects.next(l_unit); end loop; - ut_utils.append_to_clob(l_result, c_packages_footer); - ut_utils.append_to_clob(l_result, c_coverage_footer); + ut_utils.append_to_list(l_result, c_packages_footer); + ut_utils.append_to_list(l_result, c_coverage_footer); return l_result; end; begin @@ -140,7 +143,7 @@ create or replace type body ut_coverage_cobertura_reporter is l_coverage_data := ut_coverage.get_coverage_data(a_run.coverage_options); - self.print_clob( get_coverage_xml( l_coverage_data, a_run ) ); + self.print_text_lines( get_coverage_xml( l_coverage_data, a_run ) ); (self as ut_reporter_base).after_calling_run(a_run); end; diff --git a/source/reporters/ut_coverage_html_reporter.tpb b/source/reporters/ut_coverage_html_reporter.tpb index a6b5b4517..77d4b46ff 100644 --- a/source/reporters/ut_coverage_html_reporter.tpb +++ b/source/reporters/ut_coverage_html_reporter.tpb @@ -29,13 +29,12 @@ create or replace type body ut_coverage_html_reporter is end; overriding member procedure after_calling_run(self in out nocopy ut_coverage_html_reporter, a_run in ut_run) as - l_report_lines ut_varchar2_list; 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( + self.print_text_lines( ut_coverage_report_html_helper.get_index( a_coverage_data => l_coverage_data, a_assets_path => self.assets_path, diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb index 725a232f2..3ab0b1fb6 100644 --- a/source/reporters/ut_coverage_report_html_helper.pkb +++ b/source/reporters/ut_coverage_report_html_helper.pkb @@ -101,11 +101,12 @@ create or replace package body ut_coverage_report_html_helper is -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_details_file_content( + a_object_id varchar2, + a_unit ut_object_name, + a_unit_coverage ut_coverage.t_unit_coverage + ) return ut_varchar2_rows is + function get_block_file_attributes(a_coverage_unit ut_coverage.t_unit_coverage) return varchar2 is l_result varchar2(32767); begin @@ -129,15 +130,14 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a 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); + return ut_varchar2_rows is + l_file_part varchar2(32767); + l_result ut_varchar2_rows := ut_varchar2_rows(); + l_coverage_pct number(5, 2); l_coverage_block_pct number(5, 2); - l_hits varchar2(30); - l_blocks varchar2(30); + 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); @@ -145,7 +145,7 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a 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); + ut_utils.append_to_list(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 @@ -191,22 +191,20 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a ' || (dbms_xmlgen.convert(a_source_code(line_no))) || ''; end if; - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list(l_result, l_file_part); end loop; l_file_part := '
'; - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list(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; + return build_details_file_content( + a_object_id, + a_unit.identity, + ut_coverage_helper.get_tmp_table_object_lines(a_unit.owner, a_unit.name), + a_unit_coverage + ); end; function get_block_list_attributes(a_coverage_unit ut_coverage.t_coverage) return varchar2 is @@ -220,20 +218,18 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a 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) return ut_varchar2_rows 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_result ut_varchar2_rows; 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'|| @@ -251,7 +247,7 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a 'File% coveredLinesRelevant LinesLines coveredLines missed' ||'Avg. Hits / Line ' || ''; - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list( l_result, l_file_part ); l_unit := a_coverage.objects.first; loop exit when l_unit is null; @@ -266,11 +262,11 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a '' || 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); + ut_utils.append_to_list( l_result, l_file_part ); l_unit := a_coverage.objects.next(l_unit); end loop; l_file_part := '

'; - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list( l_result, l_file_part ); return l_result; end; @@ -283,10 +279,10 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a a_project_name varchar2 := null, a_command_line varchar2 := null, a_charset varchar2 := null - ) return clob is + ) return ut_varchar2_rows is l_file_part varchar2(32767); - l_result clob; + l_result ut_varchar2_rows := ut_varchar2_rows(); l_title varchar2(250); l_coverage_pct number(5, 2); l_time_str varchar2(50); @@ -302,8 +298,6 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a 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' @@ -323,32 +317,35 @@ function get_details_file_content(a_object_id varchar2, a_unit ut_object_name, a ''; - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list(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 d140588ad..bc4d025f3 100644 --- a/source/reporters/ut_coverage_report_html_helper.pks +++ b/source/reporters/ut_coverage_report_html_helper.pks @@ -37,7 +37,7 @@ create or replace package ut_coverage_report_html_helper authid current_user is a_project_name varchar2 := null, a_command_line varchar2 := null, a_charset varchar2 := null - ) return clob; + ) return ut_varchar2_rows; end; / diff --git a/source/reporters/ut_coverage_sonar_reporter.tpb b/source/reporters/ut_coverage_sonar_reporter.tpb index 249736f92..fcc213665 100644 --- a/source/reporters/ut_coverage_sonar_reporter.tpb +++ b/source/reporters/ut_coverage_sonar_reporter.tpb @@ -26,73 +26,72 @@ create or replace type body ut_coverage_sonar_reporter is overriding member procedure after_calling_run(self in out nocopy ut_coverage_sonar_reporter, a_run in ut_run) as - l_report_lines ut_varchar2_list; - l_coverage_data ut_coverage.t_coverage; - function get_lines_xml(a_unit_coverage ut_coverage.t_unit_coverage) return clob is + + function get_lines_xml(a_unit_coverage ut_coverage.t_unit_coverage) return ut_varchar2_rows is l_file_part varchar2(32767); - l_result clob; + l_result ut_varchar2_rows := ut_varchar2_rows(); l_line_no binary_integer; begin - dbms_lob.createtemporary(l_result, true); l_line_no := a_unit_coverage.lines.first; if l_line_no is null then for i in 1 .. a_unit_coverage.total_lines loop - l_file_part := ''||chr(10); - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list(l_result, ''); end loop; else while l_line_no is not null loop if a_unit_coverage.lines(l_line_no).executions = 0 then - l_file_part := ''||chr(10); + l_file_part := ''; else l_file_part := ''||chr(10); + l_file_part := l_file_part ||'/>'; end if; - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list(l_result, l_file_part); l_line_no := a_unit_coverage.lines.next(l_line_no); end loop; end if; return l_result; end; + function get_coverage_xml( a_coverage_data ut_coverage.t_coverage, a_run ut_run - ) return clob is - l_file_part varchar2(32767); - l_result clob; + ) return ut_varchar2_rows is + l_result ut_varchar2_rows := ut_varchar2_rows(); l_unit ut_coverage.t_full_name; - c_coverage_header constant varchar2(30) := ''||chr(10); - c_file_footer constant varchar2(30) := '
'||chr(10); + c_coverage_header constant varchar2(30) := ''; + c_file_footer constant varchar2(30) := '
'; c_coverage_footer constant varchar2(30) := ''; - begin - dbms_lob.createtemporary(l_result,true); + begin - ut_utils.append_to_clob(l_result, ut_utils.get_xml_header(a_run.client_character_set)||chr(10)); - ut_utils.append_to_clob(l_result, c_coverage_header); - l_unit := a_coverage_data.objects.first; - while l_unit is not null loop - l_file_part := ''||chr(10); - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list(l_result, ut_utils.get_xml_header(a_run.client_character_set)); + ut_utils.append_to_list(l_result, c_coverage_header); + l_unit := a_coverage_data.objects.first; + while l_unit is not null loop + ut_utils.append_to_list(l_result, ''); - dbms_lob.append(l_result,get_lines_xml(a_coverage_data.objects(l_unit))); + ut_utils.append_to_list(l_result,get_lines_xml(a_coverage_data.objects(l_unit))); - ut_utils.append_to_clob(l_result, c_file_footer); + ut_utils.append_to_list(l_result, c_file_footer); - l_unit := a_coverage_data.objects.next(l_unit); - end loop; - ut_utils.append_to_clob(l_result, c_coverage_footer); - return l_result; - end; + l_unit := a_coverage_data.objects.next(l_unit); + end loop; + ut_utils.append_to_list(l_result, c_coverage_footer); + return l_result; + end; + begin ut_coverage.coverage_stop(); - l_coverage_data := ut_coverage.get_coverage_data(a_run.coverage_options); - - self.print_clob( get_coverage_xml( l_coverage_data, a_run ) ); + self.print_text_lines( + get_coverage_xml( + ut_coverage.get_coverage_data(a_run.coverage_options), + a_run + ) + ); end; overriding member function get_description return varchar2 as diff --git a/source/reporters/ut_coveralls_reporter.tpb b/source/reporters/ut_coveralls_reporter.tpb index 3681147f3..8be96715f 100644 --- a/source/reporters/ut_coveralls_reporter.tpb +++ b/source/reporters/ut_coveralls_reporter.tpb @@ -25,22 +25,19 @@ create or replace type body ut_coveralls_reporter is end; overriding member procedure after_calling_run(self in out nocopy ut_coveralls_reporter, a_run in ut_run) as - l_report_lines ut_varchar2_list; - l_coverage_data ut_coverage.t_coverage; - function get_lines_json(a_unit_coverage ut_coverage.t_unit_coverage) return clob is + function get_lines_json(a_unit_coverage ut_coverage.t_unit_coverage) return ut_varchar2_rows is l_file_part varchar2(32767); - l_result clob; + l_result ut_varchar2_rows := ut_varchar2_rows(); l_last_line_no binary_integer; c_coverage_header constant varchar2(30) := '"coverage": ['; c_null constant varchar2(4) := 'null'; begin - dbms_lob.createtemporary(l_result, true); - ut_utils.append_to_clob(l_result, c_coverage_header); + ut_utils.append_to_list(l_result, c_coverage_header); l_last_line_no := a_unit_coverage.lines.last; if l_last_line_no is null then - ut_utils.append_to_clob( + ut_utils.append_to_list( l_result , rpad( to_clob( '0' ), ( a_unit_coverage.total_lines * 3 ) - 2, ','||chr(10)||'0' ) ); @@ -54,48 +51,47 @@ create or replace type body ut_coveralls_reporter is if line_no < l_last_line_no then l_file_part := l_file_part ||','; end if; - ut_utils.append_to_clob(l_result, l_file_part||chr(10)); + ut_utils.append_to_list(l_result, l_file_part); end loop; end if; - ut_utils.append_to_clob(l_result, ']'); + ut_utils.append_to_list(l_result, ']'); return l_result; end; function get_coverage_json( a_coverage_data ut_coverage.t_coverage - ) return clob is + ) return ut_varchar2_rows is l_file_part varchar2(32767); - l_result clob; + l_result ut_varchar2_rows := ut_varchar2_rows(); l_unit ut_coverage.t_full_name; - c_coverage_header constant varchar2(30) := '{"source_files":['||chr(10); - c_coverage_footer constant varchar2(30) := ']}'||chr(10)||chr(10)||chr(10)||chr(10)||' '; - begin - dbms_lob.createtemporary(l_result,true); - - ut_utils.append_to_clob(l_result, c_coverage_header); + c_coverage_header constant varchar2(30) := '{"source_files":['; + c_coverage_footer constant varchar2(30) := ']}'||chr(10)||' '; + begin + ut_utils.append_to_list(l_result, c_coverage_header); l_unit := a_coverage_data.objects.first; while l_unit is not null loop - l_file_part := '{ "name": "'||l_unit||'",'||chr(10); - ut_utils.append_to_clob(l_result, l_file_part); + ut_utils.append_to_list(l_result, '{ "name": "'||l_unit||'",'); - dbms_lob.append(l_result,get_lines_json(a_coverage_data.objects(l_unit))); + ut_utils.append_to_list(l_result,get_lines_json(a_coverage_data.objects(l_unit))); - ut_utils.append_to_clob(l_result, '}'); + ut_utils.append_to_list(l_result, '}'); l_unit := a_coverage_data.objects.next(l_unit); if l_unit is not null then - ut_utils.append_to_clob(l_result, ','||chr(10)); + ut_utils.append_to_list(l_result, ','); end if; end loop; - ut_utils.append_to_clob(l_result, c_coverage_footer); + ut_utils.append_to_list(l_result, c_coverage_footer); return l_result; end; begin ut_coverage.coverage_stop(); - l_coverage_data := ut_coverage.get_coverage_data(a_run.coverage_options); - - self.print_clob( get_coverage_json( l_coverage_data ) ); + self.print_text_lines( + get_coverage_json( + ut_coverage.get_coverage_data(a_run.coverage_options) + ) + ); end; overriding member function get_description return varchar2 as diff --git a/source/reporters/ut_junit_reporter.tpb b/source/reporters/ut_junit_reporter.tpb index 63d256aab..bc88aa8af 100644 --- a/source/reporters/ut_junit_reporter.tpb +++ b/source/reporters/ut_junit_reporter.tpb @@ -35,48 +35,54 @@ create or replace type body ut_junit_reporter is end; procedure print_test_elements(a_test ut_test) is - l_lines ut_varchar2_list; + l_results ut_varchar2_rows := ut_varchar2_rows(); + l_lines ut_varchar2_list; l_output clob; begin - self.print_text(''); + ut_utils.append_to_list( + l_results, + '' + ); if a_test.result = ut_utils.gc_disabled then - self.print_text(''); + ut_utils.append_to_list( l_results, '' ); end if; if a_test.result = ut_utils.gc_error then - self.print_text(''); - self.print_text(c_cddata_tag_start); - self.print_clob(ut_utils.table_to_clob(a_test.get_error_stack_traces())); - self.print_text(c_cddata_tag_end); - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, c_cddata_tag_start); + ut_utils.append_to_list( l_results, ut_utils.convert_collection(a_test.get_error_stack_traces()) ); + ut_utils.append_to_list( l_results, c_cddata_tag_end); + ut_utils.append_to_list( l_results, ''); elsif a_test.result > ut_utils.gc_success then - self.print_text(''); + ut_utils.append_to_list( l_results, ''); for i in 1 .. a_test.failed_expectations.count loop l_lines := a_test.failed_expectations(i).get_result_lines(); for j in 1 .. l_lines.count loop - self.print_text(dbms_xmlgen.convert(l_lines(j))); + ut_utils.append_to_list( l_results, dbms_xmlgen.convert(l_lines(j)) ); end loop; - self.print_text(dbms_xmlgen.convert(a_test.failed_expectations(i).caller_info)); + ut_utils.append_to_list( l_results, dbms_xmlgen.convert(a_test.failed_expectations(i).caller_info) ); end loop; - self.print_text(''); + ut_utils.append_to_list( l_results, ''); end if; -- TODO - decide if we need/want to use the tag too l_output := a_test.get_serveroutputs(); if l_output is not null then - self.print_text(''); - self.print_text(c_cddata_tag_start); - self.print_clob(l_output); - self.print_text(c_cddata_tag_end); - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, c_cddata_tag_start); + ut_utils.append_to_list( l_results, l_output); + ut_utils.append_to_list( l_results, c_cddata_tag_end ); + ut_utils.append_to_list( l_results, '' ); else - self.print_text(''); + ut_utils.append_to_list( l_results, ''); end if; - self.print_text(''); - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, ''); + + self.print_text_lines(l_results); end; procedure print_suite_elements(a_suite ut_logical_suite, a_suite_id in out nocopy integer) is @@ -84,6 +90,7 @@ create or replace type body ut_junit_reporter is a_suite.results_count.failure_count + a_suite.results_count.errored_count; l_suite ut_suite; l_tests ut_suite_items := ut_suite_items(); + l_results ut_varchar2_rows := ut_varchar2_rows(); l_data clob; l_errors ut_varchar2_list; begin @@ -111,28 +118,31 @@ create or replace type body ut_junit_reporter is l_data := l_suite.get_serveroutputs(); if l_data is not null and l_data != empty_clob() then - self.print_text(''); - self.print_text(c_cddata_tag_start); - self.print_clob(l_data); - self.print_text(c_cddata_tag_end); - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, c_cddata_tag_start); + ut_utils.append_to_list( l_results, l_data); + ut_utils.append_to_list( l_results, c_cddata_tag_end); + ut_utils.append_to_list( l_results, ''); else - self.print_text(''); + ut_utils.append_to_list( l_results, ''); end if; l_errors := l_suite.get_error_stack_traces(); if l_errors is not empty then - self.print_text(''); - self.print_text(c_cddata_tag_start); - self.print_clob(ut_utils.table_to_clob(l_errors)); - self.print_text(c_cddata_tag_end); - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, c_cddata_tag_start); + ut_utils.append_to_list( l_results, ut_utils.table_to_clob(l_errors)); + ut_utils.append_to_list( l_results, c_cddata_tag_end); + ut_utils.append_to_list( l_results, ''); else - self.print_text(''); + ut_utils.append_to_list( l_results, ''); end if; end if; - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + + self.print_text_lines(l_results); end; + begin l_suite_id := 0; self.print_text(ut_utils.get_xml_header(a_run.client_character_set)); diff --git a/source/reporters/ut_sonar_test_reporter.tpb b/source/reporters/ut_sonar_test_reporter.tpb index 913ae8b50..1da349d83 100644 --- a/source/reporters/ut_sonar_test_reporter.tpb +++ b/source/reporters/ut_sonar_test_reporter.tpb @@ -43,28 +43,31 @@ create or replace type body ut_sonar_test_reporter is end; procedure print_test_results(a_test ut_test) is - l_lines ut_varchar2_list; + l_results ut_varchar2_rows := ut_varchar2_rows(); + l_lines ut_varchar2_list; begin - self.print_text(''); + ut_utils.append_to_list( l_results, ''); if a_test.result = ut_utils.gc_disabled then - self.print_text(''); + ut_utils.append_to_list( l_results, ''); elsif a_test.result = ut_utils.gc_error then - self.print_text(''); - self.print_text(''); - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, ''); elsif a_test.result > ut_utils.gc_success then - self.print_text(''); + ut_utils.append_to_list( l_results, ''); for i in 1 .. a_test.failed_expectations.count loop l_lines := a_test.failed_expectations(i).get_result_lines(); for i in 1 .. l_lines.count loop - self.print_text(dbms_xmlgen.convert(l_lines(i))); + ut_utils.append_to_list( l_results, dbms_xmlgen.convert(l_lines(i))); end loop; end loop; - self.print_text(''); + ut_utils.append_to_list( l_results, ''); end if; - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + + self.print_text_lines(l_results); end; procedure print_suite_results(a_suite ut_logical_suite, a_file_mappings ut_file_mappings) is diff --git a/source/reporters/ut_teamcity_reporter.tpb b/source/reporters/ut_teamcity_reporter.tpb index 086775254..a8a7ad45b 100644 --- a/source/reporters/ut_teamcity_reporter.tpb +++ b/source/reporters/ut_teamcity_reporter.tpb @@ -57,6 +57,7 @@ create or replace type body ut_teamcity_reporter is end; overriding member procedure after_calling_test(self in out nocopy ut_teamcity_reporter, a_test in ut_test) is + l_results ut_varchar2_rows := ut_varchar2_rows(); l_test_full_name varchar2(4000); l_std_err_msg varchar2(32767); begin @@ -64,10 +65,10 @@ create or replace type body ut_teamcity_reporter is lower(a_test.item.procedure_name); if a_test.result = ut_utils.gc_disabled then - self.print_text(ut_teamcity_reporter_helper.test_disabled(l_test_full_name)); + ut_utils.append_to_list( l_results, ut_teamcity_reporter_helper.test_disabled(l_test_full_name)); else - self.print_clob(a_test.get_serveroutputs()); + ut_utils.append_to_list( l_results, a_test.get_serveroutputs()); if a_test.result = ut_utils.gc_error then for i in 1 .. a_test.before_each_list.count loop @@ -98,27 +99,52 @@ create or replace type body ut_teamcity_reporter is end if; end loop; - self.print_text(ut_teamcity_reporter_helper.test_std_err(a_test_name => l_test_full_name - ,a_out => trim(l_std_err_msg))); - self.print_text(ut_teamcity_reporter_helper.test_failed(a_test_name => l_test_full_name - ,a_msg => 'Error occured' - ,a_details => trim(l_std_err_msg) || case when a_test.failed_expectations is not null and a_test.failed_expectations.count>0 then a_test.failed_expectations(1) - .message end)); + ut_utils.append_to_list( + l_results, + ut_teamcity_reporter_helper.test_std_err( + a_test_name => l_test_full_name, + a_out => trim(l_std_err_msg) + ) + ); + ut_utils.append_to_list( + l_results, + ut_teamcity_reporter_helper.test_failed( + a_test_name => l_test_full_name, + a_msg => 'Error occured', + a_details => + trim(l_std_err_msg) + || case when a_test.failed_expectations is not null + and a_test.failed_expectations.count>0 + then a_test.failed_expectations(1).message end + ) + ); elsif a_test.failed_expectations is not null and a_test.failed_expectations.count > 0 then -- Teamcity supports only a single failure message - self.print_text(ut_teamcity_reporter_helper.test_failed(a_test_name => l_test_full_name - ,a_msg => a_test.failed_expectations(a_test.failed_expectations.first).description - ,a_details => a_test.failed_expectations(a_test.failed_expectations.first).message )); + ut_utils.append_to_list( + l_results, + ut_teamcity_reporter_helper.test_failed( + a_test_name => l_test_full_name, + a_msg => a_test.failed_expectations(a_test.failed_expectations.first).description, + a_details => a_test.failed_expectations(a_test.failed_expectations.first).message ) + ); elsif a_test.result = ut_utils.gc_failure then - self.print_text(ut_teamcity_reporter_helper.test_failed(a_test_name => l_test_full_name - ,a_msg => 'Test failed')); + ut_utils.append_to_list( + l_results, + ut_teamcity_reporter_helper.test_failed( + a_test_name => l_test_full_name, + a_msg => 'Test failed' + ) + ); end if; - self.print_text(ut_teamcity_reporter_helper.test_finished(l_test_full_name, trunc(a_test.execution_time * 1e3))); + ut_utils.append_to_list( + l_results, + ut_teamcity_reporter_helper.test_finished(l_test_full_name, trunc(a_test.execution_time * 1e3)) + ); end if; - + self.print_text_lines(l_results); end; overriding member function get_description return varchar2 as diff --git a/source/reporters/ut_tfs_junit_reporter.tpb b/source/reporters/ut_tfs_junit_reporter.tpb index d3edd1208..5f3770b23 100644 --- a/source/reporters/ut_tfs_junit_reporter.tpb +++ b/source/reporters/ut_tfs_junit_reporter.tpb @@ -54,8 +54,8 @@ create or replace type body ut_tfs_junit_reporter is end; procedure print_test_results(a_test ut_test) is - l_lines ut_varchar2_list; - l_output clob; + l_results ut_varchar2_rows := ut_varchar2_rows(); + l_lines ut_varchar2_list; begin self.print_text(''); @@ -68,30 +68,33 @@ create or replace type body ut_tfs_junit_reporter is */ if a_test.result = ut_utils.gc_error then - self.print_text(''); - self.print_text(''); - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, ''); -- Do not count error as failure elsif a_test.result = ut_utils.gc_failure then - self.print_text(''); + ut_utils.append_to_list( l_results, ''); for i in 1 .. a_test.failed_expectations.count loop l_lines := a_test.failed_expectations(i).get_result_lines(); for j in 1 .. l_lines.count loop - self.print_text(dbms_xmlgen.convert(l_lines(j))); + ut_utils.append_to_list( l_results, dbms_xmlgen.convert(l_lines(j))); end loop; - self.print_text(dbms_xmlgen.convert(a_test.failed_expectations(i).caller_info)); + ut_utils.append_to_list( l_results, dbms_xmlgen.convert(a_test.failed_expectations(i).caller_info)); end loop; - self.print_text(''); + ut_utils.append_to_list( l_results, ''); end if; - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + + self.print_text_lines(l_results); end; procedure print_suite_results(a_suite ut_logical_suite, a_suite_id in out nocopy integer) is l_tests_count integer := a_suite.results_count.disabled_count + a_suite.results_count.success_count + a_suite.results_count.failure_count + a_suite.results_count.errored_count; + l_results ut_varchar2_rows := ut_varchar2_rows(); l_suite ut_suite; l_outputs clob; l_errors ut_varchar2_list; @@ -116,26 +119,28 @@ create or replace type body ut_tfs_junit_reporter is l_suite := treat(a_suite as ut_suite); l_outputs := l_suite.get_serveroutputs(); if l_outputs is not null and l_outputs != empty_clob() then - self.print_text(''); - self.print_text(''); - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, ''); else - self.print_text(''); + ut_utils.append_to_list( l_results, ''); end if; l_errors := l_suite.get_error_stack_traces(); if l_errors is not empty then - self.print_text(''); - self.print_text(''); - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, ''); + ut_utils.append_to_list( l_results, ''); else - self.print_text(''); + ut_utils.append_to_list( l_results, ''); end if; - self.print_text(''); + ut_utils.append_to_list( l_results, ''); + + self.print_text_lines(l_results); end if; end; diff --git a/test/core/reporters/test_coverage/test_cov_cobertura_reporter.pkb b/test/core/reporters/test_coverage/test_cov_cobertura_reporter.pkb index e89fbd283..cabf64e90 100644 --- a/test/core/reporters/test_coverage/test_cov_cobertura_reporter.pkb +++ b/test/core/reporters/test_coverage/test_cov_cobertura_reporter.pkb @@ -7,9 +7,10 @@ create or replace package body test_cov_cobertura_reporter is begin --Arrange l_expected := - ' + q'[ - + + test/ut3.dummy_coverage.pkb @@ -23,7 +24,7 @@ create or replace package body test_cov_cobertura_reporter is -'; +]'; --Act select * bulk collect into l_results diff --git a/test/core/reporters/test_coverage/test_coveralls_reporter.pkb b/test/core/reporters/test_coverage/test_coveralls_reporter.pkb index 3b6b88346..774e796a0 100644 --- a/test/core/reporters/test_coverage/test_coveralls_reporter.pkb +++ b/test/core/reporters/test_coverage/test_coveralls_reporter.pkb @@ -8,14 +8,17 @@ create or replace package body test_coveralls_reporter is --Arrange l_expected := q'[{"source_files":[ { "name": "test/ut3.dummy_coverage.pkb", -"coverage": [null, +"coverage": [ +null, null, null, 1, 0, null, 1 -]}]} +] +} +]} ]'; --Act select * @@ -42,7 +45,8 @@ null, --Arrange l_expected := q'[{"source_files":[ { "name": "ut3.dummy_coverage", -"coverage": [0, +"coverage": [ +0, 0, 0, 0, @@ -51,7 +55,10 @@ null, 0, 0, 0, -0]}]} +0 +] +} +]} ]'; test_coverage.cleanup_dummy_coverage; From 9ea805b61eb7392deed411da6b04fe5fdcc4ccd8 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Mon, 12 Nov 2018 01:37:48 +0000 Subject: [PATCH 086/115] Increased fetch size for coverage sources tmp seeding. --- source/core/coverage/ut_coverage.pkb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index 64d625d84..06a738f0c 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -135,7 +135,7 @@ create or replace package body ut_coverage is 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; + fetch l_cov_sources_crsr bulk collect into l_cov_sources_data limit 10000; ut_coverage_helper.insert_into_tmp_table(l_cov_sources_data); From 248bf8c7c4f50195ef33865a657e7bf3904fa596 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 13 Nov 2018 00:56:43 +0000 Subject: [PATCH 087/115] Small refactoring. Adding new function to return list of suites and tests. --- source/core/ut_suite_manager.pkb | 215 +++++++++++++++++++++++-------- source/core/ut_suite_manager.pks | 15 +++ 2 files changed, 177 insertions(+), 53 deletions(-) diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index 5e296f02e..82376a846 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -149,7 +149,7 @@ create or replace package body ut_suite_manager is return l_results; end; - procedure copy_list_reverse_order( + procedure reverse_list_order( a_list in out nocopy ut_suite_items ) is l_start_idx pls_integer; @@ -277,9 +277,14 @@ create or replace package body ut_suite_manager is end loop; exit when l_rows.count < c_bulk_limit; end loop; - copy_list_reverse_order( a_suites ); + + reverse_list_order( a_suites ); + + for i in 1 .. a_suites.count loop + a_suites( i ).set_rollback_type( a_suites( i ).get_rollback_type ); + end loop; close a_suite_data_cursor; - end; + end reconstruct_from_cache; function get_missing_objects(a_object_owner varchar2) return ut_varchar2_rows is l_rows sys_refcursor; @@ -338,7 +343,7 @@ create or replace package body ut_suite_manager is ( select 1 from all_objects a where a.object_name = c.object_name - and a.object_owner = ']'||upper(a_object_owner)||q'[' + and a.owner = ']'||upper(a_object_owner)||q'[' and a.owner = c.object_owner and a.object_type = 'PACKAGE' )]' end ||q'[ @@ -417,44 +422,91 @@ create or replace package body ut_suite_manager is return l_result; end; - function build_schema_suites( - a_owner_name varchar2, - a_path varchar2 := null, - a_object_name varchar2 := null, - a_procedure_name varchar2 := null - ) return ut_suite_items is + function can_skip_all_objects_scan( + a_owner_name varchar2 + ) return boolean is + begin + return sys_context( 'userenv', 'current_schema' ) = a_owner_name or ut_metadata.is_object_visible( ut_utils.ut_owner ||'.ut_utils' ); + end; + + procedure build_and_cache_suites( + a_owner_name varchar2, + a_annotated_objects sys_refcursor + ) is + l_annotated_objects ut_annotated_objects; + l_suite_items ut_suite_items; + begin + loop + fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; + + for i in 1 .. l_annotated_objects.count loop + ut_suite_builder.create_suite_item_list( l_annotated_objects( i ), l_suite_items ); + ut_suite_cache_manager.save_object_cache( + a_owner_name, + l_annotated_objects( i ).object_name, + l_annotated_objects( i ).parse_time, + l_suite_items + ); + end loop; + exit when a_annotated_objects%notfound; + end loop; + close a_annotated_objects; + + end; + + procedure refresh_cache( + a_owner_name varchar2, + a_annotations_cursor sys_refcursor := null + ) is l_annotations_cursor sys_refcursor; l_suite_cache_time timestamp; - l_skip_all_objects_scan boolean := false; begin l_suite_cache_time := ut_suite_cache_manager.get_schema_parse_time(a_owner_name); - open l_annotations_cursor for - q'[select value(x) - from table( - ]' || ut_utils.ut_owner || q'[.ut_annotation_manager.get_annotated_objects(:a_owner_name, 'PACKAGE', :a_suite_cache_parse_time) - )x ]' - using a_owner_name, l_suite_cache_time; - - -- if current user is the onwer or current user has execute any procedure privilege - if sys_context('userenv','current_schema') = a_owner_name - or ut_metadata.is_object_visible('ut3.ut_utils') - then - l_skip_all_objects_scan := true; + if a_annotations_cursor is not null then + l_annotations_cursor := a_annotations_cursor; + else + open l_annotations_cursor for + q'[select value(x) + from table( + ]' || ut_utils.ut_owner || q'[.ut_annotation_manager.get_annotated_objects( + :a_owner_name, 'PACKAGE', :a_suite_cache_parse_time + ) + )x ]' + using a_owner_name, l_suite_cache_time; end if; - if l_skip_all_objects_scan or ut_metadata.is_object_visible('dba_objects') then + + build_and_cache_suites(a_owner_name, l_annotations_cursor); + + if can_skip_all_objects_scan(a_owner_name) or ut_metadata.is_object_visible( 'dba_objects') then ut_suite_cache_manager.remove_from_cache( a_owner_name, get_missing_objects(a_owner_name) ); end if; - return build_suites_from_annotations( - a_owner_name, - l_annotations_cursor, - a_path, - a_object_name, - a_procedure_name, - l_skip_all_objects_scan - ); end; + function get_suites_for_path( + a_owner_name varchar2, + a_path varchar2 := null, + a_object_name varchar2 := null, + a_procedure_name varchar2 := null + ) return ut_suite_items is + l_suites ut_suite_items; + begin + refresh_cache(a_owner_name); + + reconstruct_from_cache( + l_suites, + get_cached_suite_data( + a_owner_name, + a_path, + a_object_name, + a_procedure_name, + can_skip_all_objects_scan(a_owner_name) + ) + ); + return l_suites; + + end get_suites_for_path; + ----------------------------------------------- ----------------------------------------------- ------------- Public definitions ------------- @@ -468,24 +520,8 @@ create or replace package body ut_suite_manager is a_skip_all_objects boolean := false ) return ut_suite_items is l_suites ut_suite_items; - l_annotated_objects ut_annotated_objects; - l_suite_items ut_suite_items; begin - loop - fetch a_annotated_objects bulk collect into l_annotated_objects limit 10; - - for i in 1 .. l_annotated_objects.count loop - ut_suite_builder.create_suite_item_list( l_annotated_objects( i ), l_suite_items ); - ut_suite_cache_manager.save_object_cache( - a_owner_name, - l_annotated_objects( i ).object_name, - l_annotated_objects( i ).parse_time, - l_suite_items - ); - end loop; - exit when a_annotated_objects%notfound; - end loop; - close a_annotated_objects; + build_and_cache_suites(a_owner_name, a_annotated_objects); reconstruct_from_cache( l_suites, @@ -497,9 +533,6 @@ create or replace package body ut_suite_manager is a_skip_all_objects ) ); - for i in 1 .. l_suites.count loop - l_suites( i ).set_rollback_type( l_suites( i ).get_rollback_type ); - end loop; return l_suites; end; @@ -566,7 +599,7 @@ create or replace package body ut_suite_manager is l_path_items := l_schema_paths(l_schema); for i in 1 .. l_path_items.count loop l_path_item := l_path_items(i); - l_suites := build_schema_suites( + l_suites := get_suites_for_path( upper(l_schema), l_path_item.suite_path, l_path_item.object_name, @@ -599,5 +632,81 @@ create or replace package body ut_suite_manager is return l_objects_to_run; end configure_execution_by_path; + function get_suites_info(a_owner_name varchar2) return tt_suite_items pipelined is + l_cursor sys_refcursor; + l_ut_owner varchar2(250) := ut_utils.ut_owner; + c_bulk_limit constant integer := 100; + l_results tt_suite_items; + begin + refresh_cache(a_owner_name); + + open l_cursor for + q'[with + suite_items as ( + select /*+ cardinality(c 100) */ c.* + from ]'||l_ut_owner||q'[.ut_suite_cache c + where 1 = 1 ]'||case when can_skip_all_objects_scan(a_owner_name) then q'[ + and exists + ( select 1 + from all_objects a + where a.object_name = c.object_name + and a.owner = ']'||upper(a_owner_name)||q'[' + and a.owner = c.object_owner + and a.object_type = 'PACKAGE' + )]' end ||q'[ + and c.object_owner = ']'||upper(a_owner_name)||q'[' + ), + suitepaths as ( + select distinct + substr(path,1,instr(path,'.',-1)-1) as suitepath, + path, + object_owner + from suite_items + where self_type = 'UT_SUITE' + ), + gen as ( + select rownum as pos + from xmltable('1 to 20') + ), + suitepath_part AS ( + select distinct + substr(b.suitepath, 1, instr(b.suitepath || '.', '.', 1, g.pos) -1) as path, + object_owner + from suitepaths b + join gen g + on g.pos <= regexp_count(b.suitepath, '\w+') + ), + logical_suites as ( + select 'UT_LOGICAL_SUITE' as item_type, + p.path, p.object_owner, + upper( substr(p.path, instr( p.path, '.', -1 ) + 1 ) ) as object_name + from suitepath_part p + where p.path + not in (select s.path from suitepaths s) + ), + items as ( + select object_owner, object_name, name as item_name, + description as item_description, self_type as item_type, line_no as item_line_no, + path, disabled_flag + from suite_items + union all + select object_owner, object_name, object_name as item_name, + null as item_description, item_type, null as item_line_no, + s.path, 0 as disabled_flag + from logical_suites s + ) + select c.* + from items c]'; + loop + fetch l_cursor bulk collect into l_results limit c_bulk_limit; + for i in 1 .. l_results.count loop + pipe row (l_results(i)); + end loop; + exit when l_cursor%notfound; + end loop; + close l_cursor; + + end; + end ut_suite_manager; / diff --git a/source/core/ut_suite_manager.pks b/source/core/ut_suite_manager.pks index 22c27fea9..65440b22b 100644 --- a/source/core/ut_suite_manager.pks +++ b/source/core/ut_suite_manager.pks @@ -59,6 +59,21 @@ create or replace package ut_suite_manager authid current_user is a_skip_all_objects boolean := false ) return ut_suite_items; + type t_suite_item_rec is record ( + object_owner varchar2(250), + object_name varchar2(250), + item_name varchar2(250), + item_description varchar2(250), + item_type varchar2(250), + item_line_no varchar2(250), + path varchar2(4000), + disabled_flag integer + ); + + type tt_suite_items is table of t_suite_item_rec; + + function get_suites_info(a_owner_name varchar2) return tt_suite_items pipelined; + end ut_suite_manager; / From 8fc2ea6e3364ad9e1180700f8e214641089ec09d Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Thu, 15 Nov 2018 00:25:39 +0000 Subject: [PATCH 088/115] Further optimizations to suite parsing. Changed functions to procedures to avoid copying of large memmory segments. --- source/api/ut_runner.pkb | 3 +- .../core/annotations/ut_annotation_parser.pkb | 2 +- source/core/ut_suite_cache_manager.pkb | 7 +- source/core/ut_suite_manager.pkb | 200 +++++++++++------- source/core/ut_suite_manager.pks | 9 + 5 files changed, 136 insertions(+), 85 deletions(-) diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index c04fa5112..3a2d6583b 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -128,7 +128,7 @@ create or replace package body ut_runner is l_include_object_names := to_ut_object_list(a_include_objects, l_coverage_schema_names); l_run := ut_run( - ut_suite_manager.configure_execution_by_path(l_paths), + null, l_paths, l_coverage_schema_names, l_exclude_object_names, @@ -137,6 +137,7 @@ create or replace package body ut_runner is set(a_test_file_mappings), a_client_character_set ); + ut_suite_manager.configure_execution_by_path(l_paths, l_run.items); l_run.do_execute(); finish_run(l_run); diff --git a/source/core/annotations/ut_annotation_parser.pkb b/source/core/annotations/ut_annotation_parser.pkb index 2467c6262..aec9e7585 100644 --- a/source/core/annotations/ut_annotation_parser.pkb +++ b/source/core/annotations/ut_annotation_parser.pkb @@ -155,7 +155,7 @@ create or replace package body ut_annotation_parser as -- position index is shifted by 1 because gc_annot_comment_pattern contains ^ as first sign -- but after instr index already points to the char on that line l_comment_pos := l_comment_pos-1; - l_comment_line := regexp_count(substr(a_source,1,l_comment_pos),chr(10),1,'m')+1; + l_comment_line := length(substr(a_source,1,l_comment_pos))-length(replace(substr(a_source,1,l_comment_pos),chr(10)))+1; l_comments(l_comment_line) := trim(regexp_substr(srcstr => a_source ,pattern => gc_annot_comment_pattern ,occurrence => 1 diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb index 081b2d590..ba51a242f 100644 --- a/source/core/ut_suite_cache_manager.pkb +++ b/source/core/ut_suite_cache_manager.pkb @@ -138,8 +138,11 @@ create or replace package body ut_suite_cache_manager is procedure remove_from_cache(a_schema_name varchar2, a_objects ut_varchar2_rows) is pragma autonomous_transaction; begin - delete - from ut_suite_cache_package i + delete from ut_suite_cache i + where i.object_owner = a_schema_name + and i.object_name in ( select column_value from table (a_objects) ); + + delete from ut_suite_cache_package i where i.object_owner = a_schema_name and i.object_name in ( select column_value from table (a_objects) ); diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index 82376a846..4c2d06ab9 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -29,6 +29,7 @@ create or replace package body ut_suite_manager is type tt_cached_suites is table of t_cached_suite; type t_cached_suites_cursor is ref cursor return t_cached_suite; + type t_item_levels is table of ut_suite_items index by binary_integer; ------------------ procedure validate_paths(a_paths in ut_varchar2_list) is @@ -167,33 +168,19 @@ create or replace package body ut_suite_manager is end loop; end; - procedure reconstruct_from_cache( - a_suites out nocopy ut_suite_items, - a_suite_data_cursor sys_refcursor - ) is - type t_item_levels is table of ut_suite_items index by binary_integer; - c_bulk_limit constant pls_integer := 1000; - l_items_at_level t_item_levels; - l_rows tt_cached_suites; - l_test ut_test; - l_logical_suite ut_logical_suite; - l_level pls_integer; - l_prev_level pls_integer; - l_idx integer; + function get_logical_suite( + l_rows tt_cached_suites, + l_idx pls_integer, + l_level pls_integer, + l_prev_level pls_integer, + l_items_at_level t_item_levels + ) return ut_logical_suite is begin - a_suites := ut_suite_items(); - loop - fetch a_suite_data_cursor bulk collect into l_rows limit c_bulk_limit; - exit when l_rows.count = 0; - - l_idx := l_rows.first; - loop - l_test := null; - l_logical_suite := null; - case l_rows(l_idx).self_type - when 'UT_TEST' then - l_test := - ut_test( + return + case l_rows(l_idx).self_type + when 'UT_SUITE' then + case when l_prev_level > l_level then + ut_suite( self_type => l_rows(l_idx).self_type, object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, @@ -201,14 +188,10 @@ create or replace package body ut_suite_manager is line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - 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), - item => l_rows(l_idx).item, - 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), - all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), - parent_error_stack_trace => null, expected_error_codes => l_rows(l_idx).expected_error_codes - ); - when 'UT_SUITE' then - l_logical_suite := + items => l_items_at_level(l_prev_level), + 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) + ) + else ut_suite( self_type => l_rows(l_idx).self_type, 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 results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items(), 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) - ); - when 'UT_SUITE_CONTEXT' then - l_logical_suite := + ) + end + when 'UT_SUITE_CONTEXT' then + case when l_prev_level > l_level then + ut_suite_context( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => l_items_at_level(l_prev_level), + 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) + ) + else ut_suite_context( self_type => l_rows(l_idx).self_type, 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 results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items(), 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) - ); - when 'UT_LOGICAL_SUITE' then - l_logical_suite := + ) + end + when 'UT_LOGICAL_SUITE' then + case when l_prev_level > l_level then + ut_logical_suite( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => l_items_at_level(l_prev_level) + ) + else ut_logical_suite( self_type => l_rows(l_idx).self_type, 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 start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items() - ); - end case; + ) + end + end; + end; + + procedure reconstruct_from_cache( + a_suites in out nocopy ut_suite_items, + a_suite_data_cursor sys_refcursor + ) is + c_bulk_limit constant pls_integer := 1000; + l_items_at_level t_item_levels; + l_rows tt_cached_suites; + l_logical_suite ut_logical_suite; + l_level pls_integer; + l_prev_level pls_integer; + l_idx integer; + begin + loop + fetch a_suite_data_cursor bulk collect into l_rows limit c_bulk_limit; + exit when l_rows.count = 0; + l_idx := l_rows.first; + loop l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1; - if l_level > 1 then - if l_prev_level > l_level then - l_logical_suite.items := l_items_at_level(l_prev_level); - l_items_at_level(l_prev_level).delete; - end if; if not l_items_at_level.exists(l_level) then l_items_at_level(l_level) := ut_suite_items(); end if; l_items_at_level(l_level).extend; - if l_test is not null then - l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_test; + if l_rows(l_idx).self_type = 'UT_TEST' then + l_items_at_level(l_level)(l_items_at_level(l_level).last) := + ut_test( + self_type => l_rows(l_idx).self_type, + object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), + name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, + rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, + line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + 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), + item => l_rows(l_idx).item, + 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), + all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), + parent_error_stack_trace => null, expected_error_codes => l_rows(l_idx).expected_error_codes + ); else - l_items_at_level(l_level)(l_items_at_level(l_level).last) := l_logical_suite; - end if; + pragma inline(get_logical_suite, 'YES'); + 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 ); + end if; else - if l_prev_level > l_level then - l_logical_suite.items := l_items_at_level(l_prev_level); - l_items_at_level(l_prev_level).delete; - end if; a_suites.extend; - a_suites(a_suites.last) := l_logical_suite; + pragma inline(get_logical_suite, 'YES'); + a_suites(a_suites.last) := get_logical_suite(l_rows, l_idx, l_level,l_prev_level, l_items_at_level ); + end if; + if l_prev_level > l_level then + l_items_at_level(l_prev_level).delete; end if; l_prev_level := l_level; l_idx := l_rows.next(l_idx); @@ -483,18 +521,18 @@ create or replace package body ut_suite_manager is end; - function get_suites_for_path( + procedure add_suites_for_path( a_owner_name varchar2, a_path varchar2 := null, a_object_name varchar2 := null, - a_procedure_name varchar2 := null - ) return ut_suite_items is - l_suites ut_suite_items; + a_procedure_name varchar2 := null, + a_suites in out nocopy ut_suite_items + ) is begin refresh_cache(a_owner_name); reconstruct_from_cache( - l_suites, + a_suites, get_cached_suite_data( a_owner_name, a_path, @@ -503,9 +541,8 @@ create or replace package body ut_suite_manager is can_skip_all_objects_scan(a_owner_name) ) ); - return l_suites; - end get_suites_for_path; + end; ----------------------------------------------- ----------------------------------------------- @@ -519,7 +556,7 @@ create or replace package body ut_suite_manager is a_procedure_name varchar2 := null, a_skip_all_objects boolean := false ) return ut_suite_items is - l_suites ut_suite_items; + l_suites ut_suite_items := ut_suite_items(); begin build_and_cache_suites(a_owner_name, a_annotated_objects); @@ -578,58 +615,59 @@ create or replace package body ut_suite_manager is end; function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items is + l_suites ut_suite_items := ut_suite_items(); + begin + configure_execution_by_path(a_paths, l_suites ); + return l_suites; + end; + + procedure configure_execution_by_path(a_paths in ut_varchar2_list, a_suites out nocopy ut_suite_items) is l_paths ut_varchar2_list := a_paths; l_path_items t_path_items; l_path_item t_path_item; l_schema varchar2(4000); - l_suites ut_suite_items; + l_suites_count pls_integer := 0; l_index varchar2(4000 char); - l_objects_to_run ut_suite_items; l_schema_paths t_schema_paths; begin + a_suites := ut_suite_items(); --resolve schema names from paths and group paths by schema name resolve_schema_names(l_paths); l_schema_paths := group_paths_by_schema(l_paths); - l_objects_to_run := ut_suite_items(); - l_schema := l_schema_paths.first; while l_schema is not null loop l_path_items := l_schema_paths(l_schema); for i in 1 .. l_path_items.count loop l_path_item := l_path_items(i); - l_suites := get_suites_for_path( + add_suites_for_path( upper(l_schema), l_path_item.suite_path, l_path_item.object_name, - l_path_item.procedure_name + l_path_item.procedure_name, + a_suites ); - if l_suites.count = 0 then + if a_suites.count = l_suites_count then if l_path_item.suite_path is not null then raise_application_error(ut_utils.gc_suite_package_not_found,'No suite packages found for path '||l_schema||':'||l_path_item.suite_path|| '.'); elsif l_path_item.procedure_name is not null then 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'); - else + elsif l_path_item.object_name is not null then raise_application_error(ut_utils.gc_suite_package_not_found,'Suite package '||l_schema||'.'||l_path_item.object_name|| ' does not exist'); end if; end if; - l_index := l_suites.first; - while l_index is not null loop - l_objects_to_run.extend; - l_objects_to_run(l_objects_to_run.count) := l_suites(l_index); - l_index := l_suites.next(l_index); - end loop; + l_index := a_suites.first; + l_suites_count := a_suites.count; end loop; l_schema := l_schema_paths.next(l_schema); end loop; --propagate rollback type to suite items after organizing suites into hierarchy - for i in 1 .. l_objects_to_run.count loop - l_objects_to_run(i).set_rollback_type( l_objects_to_run(i).get_rollback_type() ); + for i in 1 .. a_suites.count loop + a_suites(i).set_rollback_type( a_suites(i).get_rollback_type() ); end loop; - return l_objects_to_run; end configure_execution_by_path; function get_suites_info(a_owner_name varchar2) return tt_suite_items pipelined is diff --git a/source/core/ut_suite_manager.pks b/source/core/ut_suite_manager.pks index 65440b22b..408a8a355 100644 --- a/source/core/ut_suite_manager.pks +++ b/source/core/ut_suite_manager.pks @@ -39,6 +39,15 @@ create or replace package ut_suite_manager authid current_user is */ function configure_execution_by_path(a_paths in ut_varchar2_list) return ut_suite_items; + /** + * Builds a hierarchical suites based on given suite-paths + * + * @param a_paths list of suite-paths or procedure names or package names or schema names + * @param a_suites returned array containing root suites-ready to be executed + * + */ + procedure configure_execution_by_path(a_paths in ut_varchar2_list, a_suites out nocopy ut_suite_items); + /** * Cleanup paths by removing leading/trailing whitespace and making paths lowercase * Get list of schema names from execution paths. From 3543e3d905dfe76c322ab527ca5d5007a34f901f Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Thu, 15 Nov 2018 00:26:55 +0000 Subject: [PATCH 089/115] Disabled `PLSQL_OPTIMIZE_LEVEL=0` for testing --- .travis/install.sh | 4 ++-- .travis/install_utplsql_release.sh | 2 +- test/core.pkb | 2 +- test/install_tests.sql | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis/install.sh b/.travis/install.sh index e37cfa35f..03b69a8b1 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -9,7 +9,7 @@ set feedback off set verify off --alter session set plsql_warnings = 'ENABLE:ALL', 'DISABLE:(5004,5018,6000,6001,6003,6009,6010,7206)'; -alter session set plsql_optimize_level=0; +--alter session set plsql_optimize_level=0; @install_headless.sql $UT3_OWNER $UT3_OWNER_PASSWORD SQL @@ -45,7 +45,7 @@ SQL set feedback off set verify off - alter session set plsql_optimize_level=0; + --alter session set plsql_optimize_level=0; @install.sql $UT3_OWNER SQL diff --git a/.travis/install_utplsql_release.sh b/.travis/install_utplsql_release.sh index 889e098da..7d1c24df7 100644 --- a/.travis/install_utplsql_release.sh +++ b/.travis/install_utplsql_release.sh @@ -37,7 +37,7 @@ end; SQL "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA < Date: Thu, 15 Nov 2018 00:33:56 +0000 Subject: [PATCH 090/115] Fixed formal parameter names --- source/core/ut_suite_manager.pkb | 108 ++++++++++++++++--------------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index 4c2d06ab9..03eb35a86 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -169,87 +169,91 @@ create or replace package body ut_suite_manager is end; function get_logical_suite( - l_rows tt_cached_suites, - l_idx pls_integer, - l_level pls_integer, - l_prev_level pls_integer, - l_items_at_level t_item_levels + a_rows tt_cached_suites, + a_idx pls_integer, + a_level pls_integer, + a_prev_level pls_integer, + a_items_at_level t_item_levels ) return ut_logical_suite is begin return - case l_rows(l_idx).self_type + case a_rows( a_idx ).self_type when 'UT_SUITE' then - case when l_prev_level > l_level then + case when a_prev_level > a_level then ut_suite( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => l_items_at_level(l_prev_level), - 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) + items => a_items_at_level(a_prev_level), + before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( + a_rows( a_idx ).after_all_list) ) else ut_suite( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items(), - 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) + before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( + a_rows( a_idx ).after_all_list) ) end when 'UT_SUITE_CONTEXT' then - case when l_prev_level > l_level then + case when a_prev_level > a_level then ut_suite_context( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => l_items_at_level(l_prev_level), - 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) + items => a_items_at_level(a_prev_level), + before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( + a_rows( a_idx ).after_all_list) ) else ut_suite_context( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items(), - 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) + before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( + a_rows( a_idx ).after_all_list) ) end when 'UT_LOGICAL_SUITE' then - case when l_prev_level > l_level then + case when a_prev_level > a_level then ut_logical_suite( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => l_items_at_level(l_prev_level) + items => a_items_at_level(a_prev_level) ) else ut_logical_suite( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), items => ut_suite_items() ) From f7f68116bbe600ea9dc049b8dff6fd41ce4dd981 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Thu, 15 Nov 2018 01:09:49 +0000 Subject: [PATCH 091/115] Revert "Disabled `PLSQL_OPTIMIZE_LEVEL=0` for testing" This reverts commit 3543e3d --- .travis/install.sh | 4 ++-- .travis/install_utplsql_release.sh | 2 +- test/core.pkb | 2 +- test/install_tests.sql | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis/install.sh b/.travis/install.sh index 03b69a8b1..e37cfa35f 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -9,7 +9,7 @@ set feedback off set verify off --alter session set plsql_warnings = 'ENABLE:ALL', 'DISABLE:(5004,5018,6000,6001,6003,6009,6010,7206)'; ---alter session set plsql_optimize_level=0; +alter session set plsql_optimize_level=0; @install_headless.sql $UT3_OWNER $UT3_OWNER_PASSWORD SQL @@ -45,7 +45,7 @@ SQL set feedback off set verify off - --alter session set plsql_optimize_level=0; + alter session set plsql_optimize_level=0; @install.sql $UT3_OWNER SQL diff --git a/.travis/install_utplsql_release.sh b/.travis/install_utplsql_release.sh index 7d1c24df7..889e098da 100644 --- a/.travis/install_utplsql_release.sh +++ b/.travis/install_utplsql_release.sh @@ -37,7 +37,7 @@ end; SQL "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA < Date: Fri, 16 Nov 2018 01:11:03 +0000 Subject: [PATCH 092/115] Refactored procedure `get_unit_test_info` to return more relevant information based on info suite cache. Suite cache is refreshed when calling procedure (as needed). --- source/api/ut_runner.pkb | 15 ++------- source/api/ut_runner.pks | 16 ++-------- source/api/ut_suite_item_info.tps | 27 ++++++++++++++++ source/api/ut_suite_items_info.tps | 19 +++++++++++ source/core/ut_suite_manager.pkb | 32 +++++++++---------- source/core/ut_suite_manager.pks | 20 ++++-------- .../create_synonyms_and_grants_for_public.sql | 4 +++ source/install.sql | 2 ++ source/uninstall_objects.sql | 4 +++ test/api/test_ut_runner.pkb | 14 +++++--- 10 files changed, 94 insertions(+), 59 deletions(-) create mode 100644 source/api/ut_suite_item_info.tps create mode 100644 source/api/ut_suite_items_info.tps diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index 3a2d6583b..e59caccb6 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -165,21 +165,12 @@ create or replace package body ut_runner is ut_annotation_manager.purge_cache(a_object_owner, a_object_type); end; - function get_unit_test_info(a_owner varchar2, a_package_name varchar2 := null) return tt_annotations pipelined is + function get_unit_test_info(a_owner varchar2, a_package_name varchar2 ) return ut_suite_items_info pipelined is l_cursor sys_refcursor; - l_filter varchar2(100); - l_ut_owner varchar2(250) := ut_utils.ut_owner; - l_results tt_annotations; + l_results ut_suite_items_info; c_bulk_limit constant integer := 10; begin - l_filter := case when a_package_name is null then 'is null' else '= o.object_name' end; - open l_cursor for - 'select o.object_owner, o.object_name, upper(a.subobject_name),' || - ' a.position, a.name, a.text' || - ' from table('||l_ut_owner||'.ut_annotation_manager.get_annotated_objects(:a_owner, ''PACKAGE'')) o,' || - ' table(o.annotations) a' || - ' where :a_package_name ' || l_filter - using a_owner, a_package_name; + l_cursor := ut_suite_manager.get_suites_info( a_owner, a_package_name ); loop fetch l_cursor bulk collect into l_results limit c_bulk_limit; for i in 1 .. l_results.count loop diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index 45b8cb642..e7e53a5e2 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -87,24 +87,14 @@ create or replace package ut_runner authid current_user is procedure purge_cache(a_object_owner varchar2 := null, a_object_type varchar2 := null); - type t_annotation_rec is record ( - package_owner varchar2(250), - package_name varchar2(250), - procedure_name varchar2(250), - annotation_pos number(5,0), - annotation_name varchar2(1000), - annotation_text varchar2(4000) - ); - type tt_annotations is table of t_annotation_rec; - /** - * Returns a pipelined collection containing information about unit tests package/packages for a given owner + * Returns a pipelined collection containing information about unit test suites and the tests contained in them * * @param a_owner owner of unit tests to retrieve * @param a_package_name optional name of unit test package to retrieve, if NULLm all unit test packages are returned - * @return tt_annotations table of records + * @return ut_suite_items_info table of objects */ - function get_unit_test_info(a_owner varchar2, a_package_name varchar2 := null) return tt_annotations pipelined; + function get_unit_test_info(a_owner varchar2, a_package_name varchar2) return ut_suite_items_info pipelined; type t_reporter_rec is record ( reporter_object_name varchar2(250), diff --git a/source/api/ut_suite_item_info.tps b/source/api/ut_suite_item_info.tps new file mode 100644 index 000000000..eefef4db0 --- /dev/null +++ b/source/api/ut_suite_item_info.tps @@ -0,0 +1,27 @@ +create or replace type ut_suite_item_info as object ( + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + object_owner varchar2(250), + object_name varchar2(250), + item_name varchar2(250), + item_description varchar2(250), + item_type varchar2(250), + item_line_no integer, + path varchar2(4000), + disabled_flag integer +) +/ diff --git a/source/api/ut_suite_items_info.tps b/source/api/ut_suite_items_info.tps new file mode 100644 index 000000000..d84ed9092 --- /dev/null +++ b/source/api/ut_suite_items_info.tps @@ -0,0 +1,19 @@ +create or replace type ut_suite_items_info as + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + table of ut_suite_item_info +/ diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index 03eb35a86..628350b10 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -674,15 +674,14 @@ create or replace package body ut_suite_manager is end configure_execution_by_path; - function get_suites_info(a_owner_name varchar2) return tt_suite_items pipelined is - l_cursor sys_refcursor; + function get_suites_info(a_owner_name varchar2, a_package_name varchar2) return sys_refcursor is + l_result sys_refcursor; l_ut_owner varchar2(250) := ut_utils.ut_owner; - c_bulk_limit constant integer := 100; - l_results tt_suite_items; begin + refresh_cache(a_owner_name); - open l_cursor for + open l_result for q'[with suite_items as ( select /*+ cardinality(c 100) */ c.* @@ -696,7 +695,12 @@ create or replace package body ut_suite_manager is and a.owner = c.object_owner and a.object_type = 'PACKAGE' )]' end ||q'[ - and c.object_owner = ']'||upper(a_owner_name)||q'[' + and c.object_owner = ']'||upper(a_owner_name) ||q'[' + and ]' + || case when a_package_name is not null + then 'c.object_name = :a_package_name' + else ':a_package_name is null' end + || q'[ ), suitepaths as ( select distinct @@ -737,17 +741,13 @@ create or replace package body ut_suite_manager is s.path, 0 as disabled_flag from logical_suites s ) - select c.* - from items c]'; - loop - fetch l_cursor bulk collect into l_results limit c_bulk_limit; - for i in 1 .. l_results.count loop - pipe row (l_results(i)); - end loop; - exit when l_cursor%notfound; - end loop; - close l_cursor; + select ]'||l_ut_owner||q'[.ut_suite_item_info( + object_owner, object_name, item_name, item_description, + item_type, item_line_no, path, disabled_flag + ) + from items c]' using upper(a_package_name); + return l_result; end; end ut_suite_manager; diff --git a/source/core/ut_suite_manager.pks b/source/core/ut_suite_manager.pks index 408a8a355..6e87b08a8 100644 --- a/source/core/ut_suite_manager.pks +++ b/source/core/ut_suite_manager.pks @@ -68,20 +68,14 @@ create or replace package ut_suite_manager authid current_user is a_skip_all_objects boolean := false ) return ut_suite_items; - type t_suite_item_rec is record ( - object_owner varchar2(250), - object_name varchar2(250), - item_name varchar2(250), - item_description varchar2(250), - item_type varchar2(250), - item_line_no varchar2(250), - path varchar2(4000), - disabled_flag integer - ); - type tt_suite_items is table of t_suite_item_rec; - - function get_suites_info(a_owner_name varchar2) return tt_suite_items pipelined; + /** + * Returns a ref cursor containing information about unit test suites and the tests contained in them + * + * @param a_owner owner of unit tests to retrieve + * @return ut_suite_items_info table of objects + */ + function get_suites_info(a_owner_name varchar2, a_package_name varchar2) return sys_refcursor; end ut_suite_manager; diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql index 4928022eb..b8daca313 100644 --- a/source/create_synonyms_and_grants_for_public.sql +++ b/source/create_synonyms_and_grants_for_public.sql @@ -95,6 +95,8 @@ grant execute on &&ut3_owner..ut_annotation_cache_manager to public; grant execute on &&ut3_owner..ut_annotation_parser to public; grant execute on &&ut3_owner..ut_annotation_objs_cache_info to public; grant execute on &&ut3_owner..ut_annotation_obj_cache_info to public; +grant execute on &&ut3_owner..ut_suite_items_info to public; +grant execute on &&ut3_owner..ut_suite_item_info to public; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'grant select, insert, delete, update on &&ut3_owner..dbmspcc_blocks to public'; @@ -152,6 +154,8 @@ create public synonym ut_file_mapper for &&ut3_owner..ut_file_mapper; create public synonym ut_key_value_pairs for &&ut3_owner..ut_key_value_pairs; create public synonym ut_key_value_pair for &&ut3_owner..ut_key_value_pair; create public synonym ut_sonar_test_reporter for &&ut3_owner..ut_sonar_test_reporter; +create public synonym ut_suite_items_info for &&ut3_owner..ut_suite_items_info; +create public synonym ut_suite_item_info for &&ut3_owner..ut_suite_item_info; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'create public synonym dbmspcc_blocks for &&ut3_owner..dbmspcc_blocks'; diff --git a/source/install.sql b/source/install.sql index 31b91a941..50d70c944 100644 --- a/source/install.sql +++ b/source/install.sql @@ -259,6 +259,8 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema @@install_component.sql 'reporters/ut_documentation_reporter.tpb' --plugin interface API for running utPLSQL +@@install_component.sql 'api/ut_suite_item_info.tps' +@@install_component.sql 'api/ut_suite_items_info.tps' @@install_component.sql 'api/ut_runner.pks' @@install_component.sql 'api/ut_runner.pkb' diff --git a/source/uninstall_objects.sql b/source/uninstall_objects.sql index 119695b6d..97f2c5a5d 100644 --- a/source/uninstall_objects.sql +++ b/source/uninstall_objects.sql @@ -51,6 +51,10 @@ drop package ut_teamcity_reporter_helper; drop package ut_runner; +drop type ut_suite_items_info force; + +drop type ut_suite_item_info force; + drop package ut_suite_manager; drop package ut_suite_builder; diff --git a/test/api/test_ut_runner.pkb b/test/api/test_ut_runner.pkb index 3a8f6f670..5a9e4830a 100644 --- a/test/api/test_ut_runner.pkb +++ b/test/api/test_ut_runner.pkb @@ -273,12 +273,16 @@ end;'; begin --Arrange open l_expected for - select 'UT3_TESTER' package_owner, 'DUMMY_TEST_PACKAGE' package_name, - to_char(null) procedure_name, 2 annotation_pos, 'suite' annotation_name, 'dummy_test_suite' annotation_text + select + 'UT3_TESTER' object_owner, 'DUMMY_TEST_PACKAGE' object_name, 'DUMMY_TEST_PACKAGE' item_name, + 'dummy_test_suite' item_description, 'UT_SUITE' item_type, 2 item_line_no, + 'dummy_test_package' path, 0 disabled_flag from dual union all - select 'UT3_TESTER', 'DUMMY_TEST_PACKAGE', to_char(null), 3, 'rollback', 'manual' from dual union all - select 'UT3_TESTER', 'DUMMY_TEST_PACKAGE', 'SOME_DUMMY_TEST_PROCEDURE', 5, 'test', 'dummy_test' from dual union all - select 'UT3_TESTER', 'DUMMY_TEST_PACKAGE', 'SOME_DUMMY_TEST_PROCEDURE', 6, 'beforetest', 'some_procedure' from dual; + select + 'UT3_TESTER' object_owner, 'DUMMY_TEST_PACKAGE' object_name, 'SOME_DUMMY_TEST_PROCEDURE' item_name, + 'dummy_test' item_description, 'UT_TEST' item_type, 5 item_line_no, + 'dummy_test_package.some_dummy_test_procedure' path, 0 disabled_flag + from dual; --Act open l_actual for select * from table(ut3.ut_runner.get_unit_test_info('UT3_TESTER','DUMMY_TEST_PACKAGE')); --Assert From e1f1eec2024126a50168c2613bfeb9b2e989f7c1 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 16 Nov 2018 23:35:06 +0000 Subject: [PATCH 093/115] Renamed `get_unit_test_info` to `get_suites_info` - the latter one was not used uin prior versions. Added functions `is_test`, `is_suite`, `has_suite` to perform checks for test/suite existance at prcedure, package, schema level. --- source/api/ut_runner.pkb | 38 ++++++++++++++++- source/api/ut_runner.pks | 28 ++++++++++++- source/core/ut_suite_cache_manager.pkb | 2 +- source/core/ut_suite_manager.pkb | 51 ++++++++++++++++++++++- source/core/ut_suite_manager.pks | 25 ++++++++++- test/api/test_ut_runner.pkb | 57 +++++++++++++++++++++++++- test/api/test_ut_runner.pks | 40 +++++++++++++++++- 7 files changed, 231 insertions(+), 10 deletions(-) diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index e59caccb6..64faf91ed 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -165,7 +165,7 @@ create or replace package body ut_runner is ut_annotation_manager.purge_cache(a_object_owner, a_object_type); end; - function get_unit_test_info(a_owner varchar2, a_package_name varchar2 ) return ut_suite_items_info pipelined is + function get_suites_info(a_owner varchar2, a_package_name varchar2 := null) return ut_suite_items_info pipelined is l_cursor sys_refcursor; l_results ut_suite_items_info; c_bulk_limit constant integer := 10; @@ -182,6 +182,42 @@ create or replace package body ut_runner is return; end; + function is_test(a_owner varchar2, a_package_name varchar2, a_procedure_name varchar2) return boolean is + l_result boolean := false; + begin + if a_owner is not null and a_package_name is not null and a_procedure_name is not null then + + l_result := ut_suite_manager.suite_item_exists( a_owner, a_package_name, a_procedure_name ); + + end if; + + return l_result; + end; + + function is_suite(a_owner varchar2, a_package_name varchar2) return boolean is + l_result boolean := false; + begin + if a_owner is not null and a_package_name is not null then + + l_result := ut_suite_manager.suite_item_exists( a_owner, a_package_name ); + + end if; + + return l_result; + end; + + function has_suites(a_owner varchar2) return boolean is + l_result boolean := false; + begin + if a_owner is not null then + + l_result := ut_suite_manager.suite_item_exists( a_owner ); + + end if; + + return l_result; + end; + function get_reporters_list return tt_reporters_info pipelined is l_cursor sys_refcursor; l_owner varchar2(128) := upper(ut_utils.ut_owner()); diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index e7e53a5e2..9dc18b9b9 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -94,7 +94,33 @@ create or replace package ut_runner authid current_user is * @param a_package_name optional name of unit test package to retrieve, if NULLm all unit test packages are returned * @return ut_suite_items_info table of objects */ - function get_unit_test_info(a_owner varchar2, a_package_name varchar2) return ut_suite_items_info pipelined; + function get_suites_info(a_owner varchar2, a_package_name varchar2 := null) return ut_suite_items_info pipelined; + + + /** + * Returns true if given procedure is a test in a test suite, false otherwise + * + * @param a_owner owner of test package + * @param a_package_name name of test package + * @param a_procedure_name name of test procedure + */ + function is_test(a_owner varchar2, a_package_name varchar2, a_procedure_name varchar2) return boolean; + + /** + * Returns true if given package is a test suite, false otherwise + * + * @param a_owner owner of test package + * @param a_package_name name of test package + */ + function is_suite(a_owner varchar2, a_package_name varchar2) return boolean; + + /** + * Returns true if given schema contains test suites, false otherwise + * + * @param a_owner owner of test package + */ + function has_suites(a_owner varchar2) return boolean; + type t_reporter_rec is record ( reporter_object_name varchar2(250), diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb index ba51a242f..ce7f018e0 100644 --- a/source/core/ut_suite_cache_manager.pkb +++ b/source/core/ut_suite_cache_manager.pkb @@ -37,7 +37,7 @@ create or replace package body ut_suite_cache_manager is l_object_owner varchar2(250) := upper(a_object_owner); l_object_name varchar2(250) := upper(a_object_name); begin - if a_suite_items.count = 0 then + if a_suite_items is not null and a_suite_items.count = 0 then delete from ut_suite_cache t where t.object_owner = l_object_owner diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index 628350b10..5dfeedfc8 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -674,7 +674,10 @@ create or replace package body ut_suite_manager is end configure_execution_by_path; - function get_suites_info(a_owner_name varchar2, a_package_name varchar2) return sys_refcursor is + function get_suites_info( + a_owner_name varchar2, + a_package_name varchar2 := null + ) return sys_refcursor is l_result sys_refcursor; l_ut_owner varchar2(250) := ut_utils.ut_owner; begin @@ -750,5 +753,51 @@ create or replace package body ut_suite_manager is return l_result; end; + function suite_item_exists( + a_owner_name varchar2, + a_package_name varchar2 := null, + a_procedure_name varchar2 := null, + a_item_type varchar2 := null + ) return boolean is + l_result integer; + l_ut_owner varchar2(250) := ut_utils.ut_owner; + begin + refresh_cache(a_owner_name); + + execute immediate q'[ + select count(1) from dual + where exists ( + select 1 + from ]'||l_ut_owner||q'[.ut_suite_cache c + where 1 = 1 ]'||case when can_skip_all_objects_scan(a_owner_name) then q'[ + and exists + ( select 1 + from all_objects a + where a.object_name = c.object_name + and a.owner = :a_owner_name + and a.owner = c.object_owner + and a.object_type = 'PACKAGE' + )]' else q'[ + and :a_owner_name is not null ]' end ||q'[ + and c.object_owner = :a_owner_name + and ]' + || case when a_package_name is not null + then 'c.object_name = :a_package_name' + else ':a_package_name is null' end + || q'[ + and ]' + || case when a_procedure_name is not null + then 'c.name = :a_procedure_name' + else ':a_procedure_name is null' end + || q'[ + )]' + into l_result + using + upper(a_owner_name), upper(a_owner_name), + upper(a_package_name), upper(a_procedure_name); + + return l_result > 0; + end; + end ut_suite_manager; / diff --git a/source/core/ut_suite_manager.pks b/source/core/ut_suite_manager.pks index 6e87b08a8..5fd82f9be 100644 --- a/source/core/ut_suite_manager.pks +++ b/source/core/ut_suite_manager.pks @@ -72,10 +72,31 @@ create or replace package ut_suite_manager authid current_user is /** * Returns a ref cursor containing information about unit test suites and the tests contained in them * - * @param a_owner owner of unit tests to retrieve + * @param a_owner owner of unit tests to retrieve + * @param a_package_name name of test package (optional) + * @param a_procedure_name name of test procedure (optional) * @return ut_suite_items_info table of objects */ - function get_suites_info(a_owner_name varchar2, a_package_name varchar2) return sys_refcursor; + function get_suites_info( + a_owner_name varchar2, + a_package_name varchar2 := null + ) return sys_refcursor; + + /** + * Returns true if given suite item exists + * + * @param a_owner owner of items to retrieve + * @param a_package_name name of suite package (optional) + * @param a_procedure_name name of suite item (optional) + * @param a_item_type suite_item type (optional) + * @return ut_suite_items_info table of objects + */ + function suite_item_exists( + a_owner_name varchar2, + a_package_name varchar2 := null, + a_procedure_name varchar2 := null, + a_item_type varchar2 := null + ) return boolean; end ut_suite_manager; diff --git a/test/api/test_ut_runner.pkb b/test/api/test_ut_runner.pkb index 5a9e4830a..496099b77 100644 --- a/test/api/test_ut_runner.pkb +++ b/test/api/test_ut_runner.pkb @@ -267,7 +267,7 @@ end;'; ut.expect(l_actual).to_equal(0); end; - procedure test_get_unit_test_info is + procedure test_get_suites_info is l_expected sys_refcursor; l_actual sys_refcursor; begin @@ -284,7 +284,7 @@ end;'; 'dummy_test_package.some_dummy_test_procedure' path, 0 disabled_flag from dual; --Act - open l_actual for select * from table(ut3.ut_runner.get_unit_test_info('UT3_TESTER','DUMMY_TEST_PACKAGE')); + open l_actual for select * from table(ut3.ut_runner.get_suites_info('UT3_TESTER','DUMMY_TEST_PACKAGE')); --Assert ut.expect(l_actual).to_equal(l_expected); end; @@ -534,6 +534,59 @@ end;'; ut.expect(l_actual).to_be_like('%Finished in % seconds %2 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s)%'); end; + + procedure is_test_true is + begin + ut.expect( + ut3.ut_runner.is_test( + a_owner => 'UT3_TESTER', + a_package_name => 'DUMMY_TEST_PACKAGE', + a_procedure_name => 'SOME_DUMMY_TEST_PROCEDURE' + ) + ).to_be_true(); + ut.expect( ut3.ut_runner.is_test( 'ut3_tester','dummy_test_package','some_dummy_test_procedure' ) ).to_be_true(); + end; + + procedure is_test_false is + begin + ut.expect( ut3.ut_runner.is_test( 'UT3_TESTER','DUMMY_TEST_PACKAGE', 'BAD' ) ).to_be_false(); + ut.expect( ut3.ut_runner.is_test( 'UT3_TESTER','DUMMY_TEST_PACKAGE', null ) ).to_be_false(); + ut.expect( ut3.ut_runner.is_test( 'UT3_TESTER',null,'some_dummy_test_procedure' ) ).to_be_false(); + ut.expect( ut3.ut_runner.is_test( null,'DUMMY_TEST_PACKAGE','some_dummy_test_procedure' ) ).to_be_false(); + end; + + procedure is_suite_true is + begin + ut.expect( + ut3.ut_runner.is_suite( + a_owner => 'UT3_TESTER', + a_package_name => 'DUMMY_TEST_PACKAGE' + ) + ).to_be_true(); + + ut.expect( ut3.ut_runner.is_suite( 'ut3_tester','dummy_test_package' ) ).to_be_true(); + end; + + procedure is_suite_false is + begin + ut.expect( ut3.ut_runner.is_suite( 'UT3_TESTER','BAD' ) ).to_be_false(); + ut.expect( ut3.ut_runner.is_suite( 'UT3_TESTER', null ) ).to_be_false(); + ut.expect( ut3.ut_runner.is_suite( null,'DUMMY_TEST_PACKAGE' ) ).to_be_false(); + end; + + procedure has_suites_true is + begin + ut.expect( ut3.ut_runner.has_suites( a_owner => 'UT3_TESTER' ) ).to_be_true(); + + ut.expect( ut3.ut_runner.has_suites( 'ut3_tester' ) ).to_be_true(); + end; + + procedure has_suites_false is + begin + ut.expect( ut3.ut_runner.has_suites( 'UT3' ) ).to_be_false(); + ut.expect( ut3.ut_runner.has_suites( 'BAD' ) ).to_be_false(); + ut.expect( ut3.ut_runner.has_suites( null ) ).to_be_false(); + end; end; / diff --git a/test/api/test_ut_runner.pks b/test/api/test_ut_runner.pks index 74c93dbae..54300af1b 100644 --- a/test/api/test_ut_runner.pks +++ b/test/api/test_ut_runner.pks @@ -43,10 +43,10 @@ create or replace package test_ut_runner is --%aftertest(cleanup_cache) procedure test_rebuild_cache_schema_type; - --%test(get_unit_tests_info returns a cursor containing records for a newly created test) + --%test(get_suites_info returns a cursor containing records for a newly created test) --%beforetest(setup_cache_objects) --%aftertest(cleanup_cache) - procedure test_get_unit_test_info; + procedure test_get_suites_info; --%test(get_reporters_list returns a cursor containing all built-in reporters and information about output-reporter) --%beforetest(setup_cache_objects) @@ -91,5 +91,41 @@ create or replace package test_ut_runner is --%endcontext + --%context(is_test) + --%beforeall(setup_cache_objects) + --%afterall(cleanup_cache) + + --%test(Returns true when procedure is a test) + procedure is_test_true; + + --%test(Returns false when procedure is not a test) + procedure is_test_false; + + --%endcontext + + --%context(is_suite) + --%beforeall(setup_cache_objects) + --%afterall(cleanup_cache) + + --%test(Returns true when package is a test suite) + procedure is_suite_true; + + --%test(Returns false when package is not a test suite) + procedure is_suite_false; + + --%endcontext + + --%context(has_suites) + --%beforeall(setup_cache_objects) + --%afterall(cleanup_cache) + + --%test(Returns true when schema contains test suites) + procedure has_suites_true; + + --%test(Returns false when schema does not contain test suites) + procedure has_suites_false; + + --%endcontext + end; / From d8d251fad3c877f86f9cd66ebcde5ee0d885c793 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 16 Nov 2018 23:36:16 +0000 Subject: [PATCH 094/115] Improved automation of `refresh_sources.sh` The script will now automatically copy `*.jar` files into `/utPLSQL-cli/lib` directory. --- .gitignore | 1 + CONTRIBUTING.md | 8 ++++++-- development/refresh_sources.sh | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 197d0f5e9..a6f721188 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ node_modules/ utPLSQL_latest_release/ utPLSQL-cli/ development/env.sh +development/*.jar *.log # exclusions based on artifacts created via actions documented in CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e82a4ce4..ffb8bba69 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,14 +89,18 @@ export CONNECTION_STR=127.0.0.1:1521/xe # Adjust the connect string export ORACLE_PWD=oracle # Adjust your local SYS password ``` +### Download Oracle JDBC drivers + +Download `ojdbc8-xxx.jar` and `orai18n-xxx.jar` from [Oracle](https://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html). +Place them in `development` directory of the project. + + ### Download utPLSQL release sources and utplsq-cli The below script is fetching latest release version from utPLSQL repository. Latest release version is used for self-testing. ```bash development/refresh_sources.sh ``` -> **Important notice:** -> You'll have to provide the ojdbc.jar in the folder utPLSQL-cli/lib manually due to Oracle licensing restrictions. ### Setup local database for utPLSQL development diff --git a/development/refresh_sources.sh b/development/refresh_sources.sh index e051787a1..9474c3553 100755 --- a/development/refresh_sources.sh +++ b/development/refresh_sources.sh @@ -16,3 +16,4 @@ curl -Lk -o utPLSQL-cli.zip https://github.com/utPLSQL/utPLSQL-cli/releases/down # unzip utPLSQL-cli and remove the zip file unzip utPLSQL-cli.zip && chmod u+x utPLSQL-cli/bin/utplsql && rm utPLSQL-cli.zip +cp development/*.jar utPLSQL-cli/lib/ From eb3df218fc958977735f196bb7474628ae8ac40e Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Fri, 16 Nov 2018 23:54:37 +0000 Subject: [PATCH 095/115] Fixing failing test. --- test/api/test_ut_runner.pkb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api/test_ut_runner.pkb b/test/api/test_ut_runner.pkb index 496099b77..0b9b85f9a 100644 --- a/test/api/test_ut_runner.pkb +++ b/test/api/test_ut_runner.pkb @@ -583,7 +583,7 @@ end;'; procedure has_suites_false is begin - ut.expect( ut3.ut_runner.has_suites( 'UT3' ) ).to_be_false(); + ut.expect( ut3.ut_runner.has_suites( 'UT3_LATEST_RELEASE' ) ).to_be_false(); ut.expect( ut3.ut_runner.has_suites( 'BAD' ) ).to_be_false(); ut.expect( ut3.ut_runner.has_suites( null ) ).to_be_false(); end; From d21134858d2ec73a955070fb2048e408c9a7e7ae Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sat, 17 Nov 2018 02:01:24 +0000 Subject: [PATCH 096/115] Added control over rollback behavior in `ut_runner.run` Fixed failing test. --- source/api/ut_runner.pkb | 11 ++++++++--- source/api/ut_runner.pks | 6 +++++- source/core/annotations/ut_annotation_manager.pkb | 8 ++++---- source/core/coverage/ut_coverage.pkb | 2 +- source/core/ut_metadata.pkb | 15 +++++++++++++-- source/core/ut_metadata.pks | 12 +++++++++++- source/core/ut_suite_manager.pkb | 9 +++------ source/core/ut_utils.pkb | 1 - source/reporters/ut_coveralls_reporter.tpb | 1 - test/api/test_ut_runner.pkb | 7 ++----- test/api/test_ut_runner.pks | 12 ++++++++---- 11 files changed, 55 insertions(+), 29 deletions(-) diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index 64faf91ed..f6d7a6d92 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -83,7 +83,8 @@ create or replace package body ut_runner is a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean := false, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_perform_rollback boolean := true ) is l_run ut_run; l_coverage_schema_names ut_varchar2_rows; @@ -141,13 +142,17 @@ create or replace package body ut_runner is l_run.do_execute(); finish_run(l_run); - rollback; + if a_perform_rollback then + rollback; + end if; exception when others then finish_run(l_run); dbms_output.put_line(dbms_utility.format_error_backtrace); dbms_output.put_line(dbms_utility.format_error_stack); - rollback; + if a_perform_rollback then + rollback; + end if; raise; end; if a_fail_on_errors and l_run.result in (ut_utils.gc_failure, ut_utils.gc_error) then diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index 9dc18b9b9..1ea997031 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -43,6 +43,9 @@ create or replace package ut_runner authid current_user is * @param a_include_objects list of database objects (in format 'owner.name') that coverage should be reported on * @param a_exclude_objects list of database objects (in format 'owner.name') that coverage should be skipped for * @param a_fail_on_errors true/false - should an exception be thrown when tests are completed with failures/errors + * @param a_client_character_set if provided, affects some of reporters by setting specific character set for XML/HTML reports + * @param a_perform_rollback true/false - should rollback be performed as part of test execution (default true) + * * @example * Parameter `a_paths` accepts values of the following formats: @@ -65,7 +68,8 @@ create or replace package ut_runner authid current_user is a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean := false, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_perform_rollback boolean := true ); /** diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb index 80de4d1a7..1c7e39273 100644 --- a/source/core/annotations/ut_annotation_manager.pkb +++ b/source/core/annotations/ut_annotation_manager.pkb @@ -22,7 +22,7 @@ create or replace package body ut_annotation_manager as function get_missing_objects(a_object_owner varchar2, a_object_type varchar2) return ut_annotation_objs_cache_info is l_rows sys_refcursor; l_ut_owner varchar2(250) := ut_utils.ut_owner; - l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); + l_objects_view varchar2(200) := ut_metadata.get_objects_view_name(); l_cursor_text varchar2(32767); l_result ut_annotation_objs_cache_info; begin @@ -54,7 +54,7 @@ create or replace package body ut_annotation_manager as function get_annotation_objs_info(a_object_owner varchar2, a_object_type varchar2, a_parse_date timestamp := null) return ut_annotation_objs_cache_info is l_rows sys_refcursor; l_ut_owner varchar2(250) := ut_utils.ut_owner; - l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); + l_objects_view varchar2(200) := ut_metadata.get_objects_view_name(); l_cursor_text varchar2(32767); l_result ut_annotation_objs_cache_info; begin @@ -86,7 +86,7 @@ create or replace package body ut_annotation_manager as function get_sources_to_annotate(a_object_owner varchar2, a_object_type varchar2) return sys_refcursor is l_result sys_refcursor; - l_sources_view varchar2(200) := ut_metadata.get_dba_view('dba_source'); + l_sources_view varchar2(200) := ut_metadata.get_source_view_name(); begin open l_result for q'[select s.name, s.text @@ -109,7 +109,7 @@ create or replace package body ut_annotation_manager as function get_sources_to_annotate(a_object_owner varchar2, a_object_type varchar2, a_objects_to_refresh ut_annotation_objs_cache_info) return sys_refcursor is l_result sys_refcursor; - l_sources_view varchar2(200) := ut_metadata.get_dba_view('dba_source'); + l_sources_view varchar2(200) := ut_metadata.get_source_view_name(); l_card natural; begin l_card := ut_utils.scale_cardinality(cardinality(a_objects_to_refresh)); diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb index 06a738f0c..6acca42bd 100644 --- a/source/core/coverage/ut_coverage.pkb +++ b/source/core/coverage/ut_coverage.pkb @@ -38,7 +38,7 @@ create or replace package body ut_coverage is 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'); + l_view_name varchar2(200) := ut_metadata.get_source_view_name(); 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'; diff --git a/source/core/ut_metadata.pkb b/source/core/ut_metadata.pkb index 1795c1a0c..d500bff61 100644 --- a/source/core/ut_metadata.pkb +++ b/source/core/ut_metadata.pkb @@ -66,7 +66,7 @@ create or replace package body ut_metadata as l_schema varchar2(200); l_package_name varchar2(200); l_procedure_name varchar2(200); - l_view_name varchar2(200) := get_dba_view('dba_objects'); + l_view_name varchar2(200) := get_objects_view_name; begin l_schema := a_owner_name; @@ -116,7 +116,7 @@ create or replace package body ut_metadata as end; function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2 is - l_view_name varchar2(128) := get_dba_view('dba_source'); + l_view_name varchar2(128) := get_source_view_name(); l_line all_source.text%type; c_key constant varchar2(500) := a_owner || '.' || a_object_name; begin @@ -155,6 +155,17 @@ create or replace package body ut_metadata as return l_result; end; + function get_source_view_name return varchar2 is + begin + return get_dba_view('dba_source'); + end; + + + function get_objects_view_name return varchar2 is + begin + return get_dba_view('dba_objects'); + end; + function user_has_execute_any_proc return boolean is l_ut_owner varchar2(250) := ut_utils.ut_owner; l_dummy varchar2(250); diff --git a/source/core/ut_metadata.pks b/source/core/ut_metadata.pks index d06c1ea9d..16172a1f1 100644 --- a/source/core/ut_metadata.pks +++ b/source/core/ut_metadata.pks @@ -64,11 +64,21 @@ create or replace package ut_metadata authid current_user as procedure reset_source_definition_cache; /** - * Returns dba_... view name if it is accessible, otherwise it returns all_xxx view + * Returns dba_... view name if it is accessible, otherwise it returns all_... view * @param a_dba_view_name the name of dba view requested */ function get_dba_view(a_dba_view_name varchar2) return varchar2; + /** + * Returns dba_source if accessible otherwise returns all_source + */ + function get_source_view_name return varchar2; + + /** + * Returns dba_objects if accessible otherwise returns all_objects + */ + function get_objects_view_name return varchar2; + /** * Returns true if object is accessible to current user * @param a_object_name fully qualified object name (with schema name) diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index 5dfeedfc8..fe76b2ed7 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -268,17 +268,15 @@ create or replace package body ut_suite_manager is c_bulk_limit constant pls_integer := 1000; l_items_at_level t_item_levels; l_rows tt_cached_suites; - l_logical_suite ut_logical_suite; l_level pls_integer; l_prev_level pls_integer; l_idx integer; begin loop fetch a_suite_data_cursor bulk collect into l_rows limit c_bulk_limit; - exit when l_rows.count = 0; l_idx := l_rows.first; - loop + while l_idx is not null loop l_level := length(l_rows(l_idx).path) - length( replace(l_rows(l_idx).path, '.') ) + 1; if l_level > 1 then if not l_items_at_level.exists(l_level) then @@ -315,9 +313,8 @@ create or replace package body ut_suite_manager is end if; l_prev_level := l_level; l_idx := l_rows.next(l_idx); - exit when l_idx is null; end loop; - exit when l_rows.count < c_bulk_limit; + exit when a_suite_data_cursor%NOTFOUND; end loop; reverse_list_order( a_suites ); @@ -331,7 +328,7 @@ create or replace package body ut_suite_manager is function get_missing_objects(a_object_owner varchar2) return ut_varchar2_rows is l_rows sys_refcursor; l_ut_owner varchar2(250) := ut_utils.ut_owner; - l_objects_view varchar2(200) := ut_metadata.get_dba_view('dba_objects'); + l_objects_view varchar2(200) := ut_metadata.get_objects_view_name(); l_cursor_text varchar2(32767); l_result ut_varchar2_rows; begin diff --git a/source/core/ut_utils.pkb b/source/core/ut_utils.pkb index d70357462..928da6ca1 100644 --- a/source/core/ut_utils.pkb +++ b/source/core/ut_utils.pkb @@ -350,7 +350,6 @@ create or replace package body ut_utils is end; procedure append_to_list(a_list in out nocopy ut_varchar2_rows, a_item varchar2) is - l_items ut_varchar2_rows; begin if a_item is not null then if a_list is null then diff --git a/source/reporters/ut_coveralls_reporter.tpb b/source/reporters/ut_coveralls_reporter.tpb index 8be96715f..46c0947d0 100644 --- a/source/reporters/ut_coveralls_reporter.tpb +++ b/source/reporters/ut_coveralls_reporter.tpb @@ -61,7 +61,6 @@ create or replace type body ut_coveralls_reporter is function get_coverage_json( a_coverage_data ut_coverage.t_coverage ) return ut_varchar2_rows is - l_file_part varchar2(32767); l_result ut_varchar2_rows := ut_varchar2_rows(); l_unit ut_coverage.t_full_name; c_coverage_header constant varchar2(30) := '{"source_files":['; diff --git a/test/api/test_ut_runner.pkb b/test/api/test_ut_runner.pkb index 0b9b85f9a..8b0b6f630 100644 --- a/test/api/test_ut_runner.pkb +++ b/test/api/test_ut_runner.pkb @@ -81,16 +81,13 @@ end;'; procedure keep_an_open_transaction is l_expected varchar2(300); - l_output_data dbms_output.chararr; - l_num_lines integer := 100000; begin --Arrange create_test_spec(); create_test_body(0); l_expected := dbms_transaction.local_transaction_id(true); --Act - ut3.ut.run('test_cache'); - dbms_output.get_lines( l_output_data, l_num_lines); + ut3.ut_runner.run(ut3.ut_varchar2_list('test_cache'),null, a_perform_rollback => false); --Assert ut.expect(dbms_transaction.local_transaction_id()).to_equal(l_expected); drop_test_package(); @@ -105,7 +102,7 @@ end;'; create_test_body(0); rollback; --Act - ut3.ut.run('test_cache'); + ut3.ut_runner.run(ut3.ut_varchar2_list('test_cache'),null); dbms_output.get_lines( l_output_data, l_num_lines); --Assert ut.expect(dbms_transaction.local_transaction_id()).to_be_null(); diff --git a/test/api/test_ut_runner.pks b/test/api/test_ut_runner.pks index 54300af1b..d67ee45fc 100644 --- a/test/api/test_ut_runner.pks +++ b/test/api/test_ut_runner.pks @@ -10,18 +10,22 @@ create or replace package test_ut_runner is --%test(closes open transactions if no transaction was open before run) procedure close_newly_opened_transaction; - --%test(version_compatibility_check compares major, minor and bugfix number) + --%context(version_compatibility_check) + + --%test(compares major, minor and bugfix number) procedure version_comp_check_compare; - --%test(version_compatibility_check ignores build number) + --%test(ignores build number) procedure version_comp_check_ignore; - --%test(version_compatibility_check compares short version to a full version) + --%test(compares short version to a full version) procedure version_comp_check_short; - --%test(version_compatibility_check raises exception when invalid version passed) + --%test(raises exception when invalid version passed) procedure version_comp_check_exception; + --%endcontext + --%test(run resets cache of package body after every run) procedure run_reset_package_body_cache; From d887889275bfeb4faab7be6e270a4290b80d4615 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sat, 17 Nov 2018 20:31:20 +0000 Subject: [PATCH 097/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 60f189a66..c384bb693 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2321-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2365-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From f3421958d1cfa6bb90924cd923cb25cadced80f7 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sat, 17 Nov 2018 21:11:56 +0000 Subject: [PATCH 098/115] Reverting rollback changes - they should go as a separate PR. --- development/releasing.md | 3 ++- source/api/ut_runner.pkb | 11 +++-------- source/api/ut_runner.pks | 5 +---- source/api/ut_suite_item_info.tps | 16 ++++++++-------- test/api/test_ut_runner.pkb | 7 +++++-- 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/development/releasing.md b/development/releasing.md index added5a92..7c8d779ef 100644 --- a/development/releasing.md +++ b/development/releasing.md @@ -9,7 +9,8 @@ To create a release: - wait for th build to complete successfully - merge the release branch to master and wait for master build to complete successfully - create a release from the master branch using [github releases page](https://github.com/utPLSQL/utPLSQL/releases) and populate release description using information found on the issues and pull requests since previous release. - To find issues closed after certain date use [advanced filters](https://help.github.com/articles/searching-issues-and-pull-requests/#search-by-open-or-closed-state) + To find issues closed after certain date use [advanced filters](https://help.github.com/articles/searching-issues-and-pull-requests/#search-by-open-or-closed-state). + Example: [`is:issue closed:>2018-07-22`](https://github.com/utPLSQL/utPLSQL/issues?utf8=%E2%9C%93&q=is%3Aissue+closed%3A%3E2018-07-22+) The following will happen: - build executed on branch `release/vX.Y.Z-[something]` updates files `sonar-project.properties`, `VERSION` with project version derived from the release branch name diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index f6d7a6d92..64faf91ed 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -83,8 +83,7 @@ create or replace package body ut_runner is a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean := false, - a_client_character_set varchar2 := null, - a_perform_rollback boolean := true + a_client_character_set varchar2 := null ) is l_run ut_run; l_coverage_schema_names ut_varchar2_rows; @@ -142,17 +141,13 @@ create or replace package body ut_runner is l_run.do_execute(); finish_run(l_run); - if a_perform_rollback then - rollback; - end if; + rollback; exception when others then finish_run(l_run); dbms_output.put_line(dbms_utility.format_error_backtrace); dbms_output.put_line(dbms_utility.format_error_stack); - if a_perform_rollback then - rollback; - end if; + rollback; raise; end; if a_fail_on_errors and l_run.result in (ut_utils.gc_failure, ut_utils.gc_error) then diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index 1ea997031..8791a4e36 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -44,8 +44,6 @@ create or replace package ut_runner authid current_user is * @param a_exclude_objects list of database objects (in format 'owner.name') that coverage should be skipped for * @param a_fail_on_errors true/false - should an exception be thrown when tests are completed with failures/errors * @param a_client_character_set if provided, affects some of reporters by setting specific character set for XML/HTML reports - * @param a_perform_rollback true/false - should rollback be performed as part of test execution (default true) - * * @example * Parameter `a_paths` accepts values of the following formats: @@ -68,8 +66,7 @@ create or replace package ut_runner authid current_user is a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean := false, - a_client_character_set varchar2 := null, - a_perform_rollback boolean := true + a_client_character_set varchar2 := null ); /** diff --git a/source/api/ut_suite_item_info.tps b/source/api/ut_suite_item_info.tps index eefef4db0..bf6fd6ecf 100644 --- a/source/api/ut_suite_item_info.tps +++ b/source/api/ut_suite_item_info.tps @@ -15,13 +15,13 @@ create or replace type ut_suite_item_info as object ( See the License for the specific language governing permissions and limitations under the License. */ - object_owner varchar2(250), - object_name varchar2(250), - item_name varchar2(250), - item_description varchar2(250), - item_type varchar2(250), - item_line_no integer, - path varchar2(4000), - disabled_flag integer + object_owner varchar2( 250 ), -- the owner of test suite packages + object_name varchar2( 250 ), -- the name of test suite package + item_name varchar2( 250 ), -- the name of suite/test + item_description varchar2( 250 ), -- the description of suite/suite item + item_type varchar2( 250 ), -- the type of item (UT_SUITE/UT_SUITE_CONTEXT/UT_TEST) + item_line_no integer, -- line_number where annotation identifying the item exists + path varchar2( 4000 ),-- suitepath of the item + disabled_flag integer -- 0 (zero) if item is not disabled, 1 if item is disabled by --%disabled annotation ) / diff --git a/test/api/test_ut_runner.pkb b/test/api/test_ut_runner.pkb index 8b0b6f630..0b9b85f9a 100644 --- a/test/api/test_ut_runner.pkb +++ b/test/api/test_ut_runner.pkb @@ -81,13 +81,16 @@ end;'; procedure keep_an_open_transaction is l_expected varchar2(300); + l_output_data dbms_output.chararr; + l_num_lines integer := 100000; begin --Arrange create_test_spec(); create_test_body(0); l_expected := dbms_transaction.local_transaction_id(true); --Act - ut3.ut_runner.run(ut3.ut_varchar2_list('test_cache'),null, a_perform_rollback => false); + ut3.ut.run('test_cache'); + dbms_output.get_lines( l_output_data, l_num_lines); --Assert ut.expect(dbms_transaction.local_transaction_id()).to_equal(l_expected); drop_test_package(); @@ -102,7 +105,7 @@ end;'; create_test_body(0); rollback; --Act - ut3.ut_runner.run(ut3.ut_varchar2_list('test_cache'),null); + ut3.ut.run('test_cache'); dbms_output.get_lines( l_output_data, l_num_lines); --Assert ut.expect(dbms_transaction.local_transaction_id()).to_be_null(); From eeae79be2df3efad9c8a58a54407470afbda1d8a Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sat, 17 Nov 2018 21:55:19 +0000 Subject: [PATCH 099/115] Added documentation for new functionality. Added default value for owner, when calling `get_suites_info` --- docs/index.md | 1 + docs/userguide/querying_suites.md | 83 ++++++++++++++++++++++++++++ docs/userguide/running-unit-tests.md | 4 +- mkdocs.yml | 1 + source/api/ut_runner.pkb | 4 +- source/api/ut_runner.pks | 6 +- test/api/test_ut_runner.pkb | 2 +- 7 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 docs/userguide/querying_suites.md diff --git a/docs/index.md b/docs/index.md index 693c8076b..b92a78688 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,6 +10,7 @@ The framework follows industry standards and best patterns of modern Unit Testin - [Expectations](userguide/expectations.md) - [Advanced data comparison](userguide/advanced_data_comparison.md) - [Running unit tests](userguide/running-unit-tests.md) + - [Querying for test suites](userguide/querying_suites.md) - [Testing best pracitces](userguide/best-practices.md) - [Upgrade utPLSQL](userguide/upgrade.md) - Reporting diff --git a/docs/userguide/querying_suites.md b/docs/userguide/querying_suites.md new file mode 100644 index 000000000..1b1c64185 --- /dev/null +++ b/docs/userguide/querying_suites.md @@ -0,0 +1,83 @@ +# Qyerying for test suites + + +## Obtaining information about suites + +utPLSQL framework provides ability to read inforamtion about unit test suites that exist in a schema. + +Pipelined table function `ut_runner.get_suites_info(a_owner, a_package_name)` allows you to retrieve information about: + +- all suites that exist in a given user/schema +- individual test suite pacakage + +Querying the data from function provides the follwing details: + +- `object_owner` - the owner of test suite packages +- `object_name` - the name of test suite package +- `item_name` - the name of suite/test +- `item_description` - the description of suite/suite item +- `item_type` - the type of item (UT_SUITE/UT_SUITE_CONTEXT/UT_TEST/UT_LOGICAL_SUITE) +- `item_line_no` - line_number where annotation identifying the item exists +- `path` - suitepath of the item +- `disabled_flag` - (0/1) indicator if item is disabled by --%disabled annotation + +To get list of all test suites in current schema +```sql +select * from table(ut_runner.get_suites_info()) where item_type = 'UT_SUITE'; +``` + +To get list of all tests for test suite `TEST_STUFF` in current user schema +```sql +select * from table(ut_runner.get_suites_info(USER, 'TEST_STUFF')) where item_type = 'UT_TEST'; +``` + +To get a full information about suite `TEST_STUFF` including suite description, all contexts and tests in a suite +```sql +select * from table(ut_runner.get_suites_info(USER, 'TEST_STUFF')) where item_type = 'UT_TEST'; +``` + +## Checking if schema contains tests + +Function `ut_runner.has_suites(a_owner)` returns boolean value indicating if given schema contains test suites. + +Example: +```sql +begin + if ut_runner.has_suites(USER) then + dbms_output.put_line( 'User '||USER||' owns test suites' ); + else + dbms_output.put_line( 'User '||USER||' does not own test suites' ); + end if; +end; +``` + +## Checking if package is a test suite + +Function `ut_runner.is_suite(a_owner, a_package_name) ` returns boolean value indicating if given package is a test suites. + +Example: +```sql +begin + if ut_runner.is_suite(USER,'TEST_STUFF') then + dbms_output.put_line( 'Package '||USER||'.TEST_STUFF is a test suite' ); + else + dbms_output.put_line( 'Package '||USER||'.TEST_STUFF is not a test suite' ); + end if; +end; +``` + +## Checking if procedure is a test within a suite + +Function `ut_runner.is_test(a_owner, a_package_name, a_procedure_name) ` returns boolean value indicating if given package is a test suites. + +Example: +```sql +begin + if ut_runner.is_test(USER,'TEST_STUFF','A_TEST_TO_CHECK_STUFF') then + dbms_output.put_line( 'Procedure '||USER||'.TEST_STUFF.A_TEST_TO_CHECK_STUFF is a test' ); + else + dbms_output.put_line( 'Procedure '||USER||'.TEST_STUFF.A_TEST_TO_CHECK_STUFF is not a test' ); + end if; +end; +``` + diff --git a/docs/userguide/running-unit-tests.md b/docs/userguide/running-unit-tests.md index 54116cf65..f680a2e38 100644 --- a/docs/userguide/running-unit-tests.md +++ b/docs/userguide/running-unit-tests.md @@ -1,12 +1,12 @@ # Running tests -The utPLSQL framework provides two main entry points to run unit tests from within the database: +utPLSQL framework provides two main entry points to run unit tests from within the database: - `ut.run` procedures and functions - `ut_runner.run` procedures These two entry points differ in purpose and behavior. -Most of the time you will want to use `ut.run` as `ut_runner` is designed for API integration and does not output the results to the screen directly. +Most of the time you will want to use `ut.run` as `ut_runner.run` is designed for API integration and does not display the results to the screen. # Running from CI servers and command line diff --git a/mkdocs.yml b/mkdocs.yml index 7bffe0c71..f9a2687a8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -18,6 +18,7 @@ nav: - Expectations: userguide/expectations.md - Advanced data comparison: userguide/advanced_data_comparison.md - Running unit tests: userguide/running-unit-tests.md + - Querying for test suites: userguide/querying_suites.md - Testing best pracitces: userguide/best-practices.md - Upgrade utPLSQL: userguide/upgrade.md - Reporting: diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index 64faf91ed..816e9e302 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -165,12 +165,12 @@ create or replace package body ut_runner is ut_annotation_manager.purge_cache(a_object_owner, a_object_type); end; - function get_suites_info(a_owner varchar2, a_package_name varchar2 := null) return ut_suite_items_info pipelined is + function get_suites_info(a_owner varchar2 := null, a_package_name varchar2 := null) return ut_suite_items_info pipelined is l_cursor sys_refcursor; l_results ut_suite_items_info; c_bulk_limit constant integer := 10; begin - l_cursor := ut_suite_manager.get_suites_info( a_owner, a_package_name ); + l_cursor := ut_suite_manager.get_suites_info( nvl(a_owner,sys_context('userenv', 'current_schema')), a_package_name ); loop fetch l_cursor bulk collect into l_results limit c_bulk_limit; for i in 1 .. l_results.count loop diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index 8791a4e36..acef16c50 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -91,11 +91,11 @@ create or replace package ut_runner authid current_user is /** * Returns a pipelined collection containing information about unit test suites and the tests contained in them * - * @param a_owner owner of unit tests to retrieve - * @param a_package_name optional name of unit test package to retrieve, if NULLm all unit test packages are returned + * @param a_owner owner of unit tests to retrieve (optional), if NULL, current schema is used + * @param a_package_name name of unit test package to retrieve (optional), if NULL all unit test packages are returned * @return ut_suite_items_info table of objects */ - function get_suites_info(a_owner varchar2, a_package_name varchar2 := null) return ut_suite_items_info pipelined; + function get_suites_info(a_owner varchar2 := null, a_package_name varchar2 := null) return ut_suite_items_info pipelined; /** diff --git a/test/api/test_ut_runner.pkb b/test/api/test_ut_runner.pkb index 0b9b85f9a..96ae08a94 100644 --- a/test/api/test_ut_runner.pkb +++ b/test/api/test_ut_runner.pkb @@ -284,7 +284,7 @@ end;'; 'dummy_test_package.some_dummy_test_procedure' path, 0 disabled_flag from dual; --Act - open l_actual for select * from table(ut3.ut_runner.get_suites_info('UT3_TESTER','DUMMY_TEST_PACKAGE')); + open l_actual for select * from table(ut3.ut_runner.get_suites_info(NULL,'DUMMY_TEST_PACKAGE')); --Assert ut.expect(l_actual).to_equal(l_expected); end; From 6bf2c8e39e2b43e4132c3555d35cd27d10130485 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 00:26:21 +0000 Subject: [PATCH 100/115] Added ability to control rollback bekavior of a test-run. --- source/api/ut.pkb | 91 +++++++++++-------- source/api/ut.pks | 18 ++-- source/api/ut_runner.pkb | 18 ++-- source/api/ut_runner.pks | 4 +- source/core/types/ut_logical_suite.tpb | 6 +- source/core/types/ut_logical_suite.tps | 2 +- source/core/types/ut_run.tpb | 8 ++ source/core/types/ut_run.tps | 1 + source/core/types/ut_suite_item.tpb | 4 +- source/core/types/ut_suite_item.tps | 2 +- test/api/test_ut_run.pkb | 116 +++++++++++++++++++++++++ test/api/test_ut_run.pks | 15 ++++ 12 files changed, 231 insertions(+), 54 deletions(-) diff --git a/source/api/ut.pkb b/source/api/ut.pkb index bd241ce13..bb599704e 100644 --- a/source/api/ut.pkb +++ b/source/api/ut.pkb @@ -18,6 +18,7 @@ create or replace package body ut is */ g_nls_date_format varchar2(4000); + gc_fail_on_errors constant boolean := false; function version return varchar2 is begin @@ -117,7 +118,6 @@ create or replace package body ut is a_client_character_set varchar2 := null ) is pragma autonomous_transaction; - c_fail_on_errors constant boolean := false; begin a_reporter := coalesce(a_reporter,ut_documentation_reporter()); ut_runner.run( @@ -129,7 +129,7 @@ create or replace package body ut is a_test_file_mappings, a_include_objects, a_exclude_objects, - c_fail_on_errors, + gc_fail_on_errors, a_client_character_set ); rollback; @@ -147,7 +147,6 @@ create or replace package body ut is a_client_character_set varchar2 := null ) is pragma autonomous_transaction; - c_fail_on_errors constant boolean := false; begin a_reporter := coalesce(a_reporter,ut_documentation_reporter()); ut_runner.run( @@ -159,7 +158,7 @@ create or replace package body ut is ut_file_mapper.build_file_mappings(a_test_files), a_include_objects, a_exclude_objects, - c_fail_on_errors, + gc_fail_on_errors, a_client_character_set ); rollback; @@ -406,21 +405,39 @@ create or replace package body ut is a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ) is l_reporter ut_reporter_base := a_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_client_character_set - ); + if a_force_manual_rollback then + l_reporter := coalesce(l_reporter,ut_documentation_reporter()); + ut_runner.run( + a_paths, + ut_reporters(l_reporter), + a_color_console, + a_coverage_schemes, + a_source_file_mappings, + a_test_file_mappings, + a_include_objects, + a_exclude_objects, + gc_fail_on_errors, + a_client_character_set, + a_force_manual_rollback + ); + else + 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_client_character_set + ); + end if; if l_reporter is of (ut_output_reporter_base) then treat(l_reporter as ut_output_reporter_base).lines_to_dbms_output(); end if; @@ -436,25 +453,23 @@ create or replace package body ut is a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ) is l_reporter ut_reporter_base := a_reporter; begin - run_autonomous( + ut.run( a_paths, l_reporter, - ut_utils.boolean_to_int(a_color_console), + a_color_console, a_coverage_schemes, - a_source_files, - a_test_files, + 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_client_character_set + a_client_character_set, + a_force_manual_rollback ); - if l_reporter is of (ut_output_reporter_base) then - treat(l_reporter as ut_output_reporter_base).lines_to_dbms_output(); - end if; - raise_if_packages_invalidated(); end; procedure run( @@ -465,7 +480,8 @@ create or replace package body ut is a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ) is begin ut.run( @@ -477,7 +493,8 @@ create or replace package body ut is a_test_file_mappings, a_include_objects, a_exclude_objects, - a_client_character_set + a_client_character_set, + a_force_manual_rollback ); end; @@ -489,7 +506,8 @@ create or replace package body ut is a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ) is begin ut.run( @@ -501,7 +519,8 @@ create or replace package body ut is a_test_files, a_include_objects, a_exclude_objects, - a_client_character_set + a_client_character_set, + a_force_manual_rollback ); end; @@ -514,7 +533,8 @@ create or replace package body ut is a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ) is begin ut.run( @@ -526,7 +546,8 @@ create or replace package body ut is a_test_file_mappings, a_include_objects, a_exclude_objects, - a_client_character_set + a_client_character_set, + a_force_manual_rollback ); end; @@ -539,7 +560,8 @@ create or replace package body ut is a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ) is begin ut.run( @@ -551,7 +573,8 @@ create or replace package body ut is a_test_files, a_include_objects, a_exclude_objects, - a_client_character_set + a_client_character_set, + a_force_manual_rollback ); end; diff --git a/source/api/ut.pks b/source/api/ut.pks index 59c709a33..25c9e6493 100644 --- a/source/api/ut.pks +++ b/source/api/ut.pks @@ -125,7 +125,8 @@ create or replace package ut authid current_user as a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ); procedure run( @@ -136,7 +137,8 @@ create or replace package ut authid current_user as a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ); procedure run( @@ -148,7 +150,8 @@ create or replace package ut authid current_user as a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ); procedure run( @@ -160,7 +163,8 @@ create or replace package ut authid current_user as a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ); procedure run( @@ -172,7 +176,8 @@ create or replace package ut authid current_user as a_test_file_mappings ut_file_mappings := null, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ); procedure run( @@ -184,7 +189,8 @@ create or replace package ut authid current_user as a_test_files ut_varchar2_list, a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ); /** diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb index c04fa5112..a4c2b3dc6 100644 --- a/source/api/ut_runner.pkb +++ b/source/api/ut_runner.pkb @@ -42,13 +42,16 @@ create or replace package body ut_runner is return l_result; end; - procedure finish_run(a_run ut_run) is + procedure finish_run(a_run ut_run, a_force_manual_rollback boolean) is begin ut_utils.cleanup_temp_tables; ut_event_manager.trigger_event(ut_utils.gc_finalize, a_run); ut_metadata.reset_source_definition_cache; ut_utils.read_cache_to_dbms_output(); ut_coverage_helper.cleanup_tmp_table(); + if not a_force_manual_rollback then + rollback; + end if; end; @@ -83,7 +86,8 @@ create or replace package body ut_runner is a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean := false, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ) is l_run ut_run; l_coverage_schema_names ut_varchar2_rows; @@ -137,16 +141,18 @@ create or replace package body ut_runner is set(a_test_file_mappings), a_client_character_set ); + if a_force_manual_rollback then + l_run.set_rollback_type(ut_utils.gc_rollback_manual, a_force=>true); + end if; + l_run.do_execute(); - finish_run(l_run); - rollback; + finish_run(l_run, a_force_manual_rollback); exception when others then - finish_run(l_run); + finish_run(l_run, a_force_manual_rollback); dbms_output.put_line(dbms_utility.format_error_backtrace); dbms_output.put_line(dbms_utility.format_error_stack); - rollback; raise; end; if a_fail_on_errors and l_run.result in (ut_utils.gc_failure, ut_utils.gc_error) then diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks index 45b8cb642..b1511c623 100644 --- a/source/api/ut_runner.pks +++ b/source/api/ut_runner.pks @@ -43,6 +43,7 @@ create or replace package ut_runner authid current_user is * @param a_include_objects list of database objects (in format 'owner.name') that coverage should be reported on * @param a_exclude_objects list of database objects (in format 'owner.name') that coverage should be skipped for * @param a_fail_on_errors true/false - should an exception be thrown when tests are completed with failures/errors + * @param a_force_manual_rollback true/false - should the transaction control be forced to --%rollback(manual) and no rollback issued at the end of the run * * @example * Parameter `a_paths` accepts values of the following formats: @@ -65,7 +66,8 @@ create or replace package ut_runner authid current_user is a_include_objects ut_varchar2_list := null, a_exclude_objects ut_varchar2_list := null, a_fail_on_errors boolean := false, - a_client_character_set varchar2 := null + a_client_character_set varchar2 := null, + a_force_manual_rollback boolean := false ); /** diff --git a/source/core/types/ut_logical_suite.tpb b/source/core/types/ut_logical_suite.tpb index 0443bf105..97c089ecb 100644 --- a/source/core/types/ut_logical_suite.tpb +++ b/source/core/types/ut_logical_suite.tpb @@ -51,11 +51,11 @@ create or replace type body ut_logical_suite as self.calc_execution_result(); end; - overriding member procedure set_rollback_type(self in out nocopy ut_logical_suite, a_rollback_type integer) is + overriding member procedure set_rollback_type(self in out nocopy ut_logical_suite, a_rollback_type integer, a_force boolean := false) is begin - self.rollback_type := coalesce(self.rollback_type, a_rollback_type); + self.rollback_type := case when a_force then a_rollback_type else coalesce(self.rollback_type, a_rollback_type) end; for i in 1 .. self.items.count loop - self.items(i).set_rollback_type(self.rollback_type); + self.items(i).set_rollback_type(self.rollback_type, a_force); end loop; end; diff --git a/source/core/types/ut_logical_suite.tps b/source/core/types/ut_logical_suite.tps index 85bb80870..e9ee20a93 100644 --- a/source/core/types/ut_logical_suite.tps +++ b/source/core/types/ut_logical_suite.tps @@ -27,7 +27,7 @@ create or replace type ut_logical_suite under ut_suite_item ( member function is_valid(self in out nocopy ut_logical_suite) return boolean, member procedure add_item(self in out nocopy ut_logical_suite, a_item ut_suite_item), overriding member procedure mark_as_skipped(self in out nocopy ut_logical_suite), - overriding member procedure set_rollback_type(self in out nocopy ut_logical_suite, a_rollback_type integer), + overriding member procedure set_rollback_type(self in out nocopy ut_logical_suite, a_rollback_type integer, a_force boolean := false), overriding member function do_execute(self in out nocopy ut_logical_suite) return boolean, overriding member procedure calc_execution_result(self in out nocopy ut_logical_suite), overriding member procedure mark_as_errored(self in out nocopy ut_logical_suite, a_error_stack_trace varchar2), diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb index 0db9f38c0..d77999a57 100644 --- a/source/core/types/ut_run.tpb +++ b/source/core/types/ut_run.tpb @@ -75,6 +75,14 @@ create or replace type body ut_run as return l_completed_without_errors; end; + overriding member procedure set_rollback_type(self in out nocopy ut_run, a_rollback_type integer, a_force boolean := false) is + begin + self.rollback_type := case when a_force then a_rollback_type else coalesce(self.rollback_type, a_rollback_type) end; + for i in 1 .. self.items.count loop + self.items(i).set_rollback_type(self.rollback_type, a_force); + end loop; + end; + overriding member procedure calc_execution_result(self in out nocopy ut_run) is l_result integer(1); begin diff --git a/source/core/types/ut_run.tps b/source/core/types/ut_run.tps index 5dc8e0399..e4309e126 100644 --- a/source/core/types/ut_run.tps +++ b/source/core/types/ut_run.tps @@ -37,6 +37,7 @@ create or replace type ut_run under ut_suite_item ( ) return self as result, overriding member procedure mark_as_skipped(self in out nocopy ut_run), overriding member function do_execute(self in out nocopy ut_run) return boolean, + overriding member procedure set_rollback_type(self in out nocopy ut_run, a_rollback_type integer, a_force boolean := false), overriding member procedure calc_execution_result(self in out nocopy ut_run), overriding member procedure mark_as_errored(self in out nocopy ut_run, a_error_stack_trace varchar2), overriding member function get_error_stack_traces return ut_varchar2_list, diff --git a/source/core/types/ut_suite_item.tpb b/source/core/types/ut_suite_item.tpb index a3319a4d8..0d1faffa3 100644 --- a/source/core/types/ut_suite_item.tpb +++ b/source/core/types/ut_suite_item.tpb @@ -37,9 +37,9 @@ create or replace type body ut_suite_item as return ut_utils.int_to_boolean(self.disabled_flag); end; - member procedure set_rollback_type(self in out nocopy ut_suite_item, a_rollback_type integer) is + member procedure set_rollback_type(self in out nocopy ut_suite_item, a_rollback_type integer, a_force boolean := false) is begin - self.rollback_type := coalesce(self.rollback_type, a_rollback_type); + self.rollback_type := case when a_force then a_rollback_type else coalesce(self.rollback_type, a_rollback_type) end; end; member function get_rollback_type return integer is diff --git a/source/core/types/ut_suite_item.tps b/source/core/types/ut_suite_item.tps index 52b6a2a19..f0821fbb8 100644 --- a/source/core/types/ut_suite_item.tps +++ b/source/core/types/ut_suite_item.tps @@ -56,7 +56,7 @@ create or replace type ut_suite_item force under ut_event_item ( member procedure set_disabled_flag(self in out nocopy ut_suite_item, a_disabled_flag boolean), member function get_disabled_flag return boolean, not instantiable member procedure mark_as_skipped(self in out nocopy ut_suite_item), - member procedure set_rollback_type(self in out nocopy ut_suite_item, a_rollback_type integer), + member procedure set_rollback_type(self in out nocopy ut_suite_item, a_rollback_type integer, a_force boolean := false), member function get_rollback_type return integer, member function create_savepoint_if_needed return varchar2, member procedure rollback_to_savepoint(self in out nocopy ut_suite_item, a_savepoint varchar2), diff --git a/test/api/test_ut_run.pkb b/test/api/test_ut_run.pkb index dae7e175a..50612e53c 100644 --- a/test/api/test_ut_run.pkb +++ b/test/api/test_ut_run.pkb @@ -355,6 +355,122 @@ create or replace package body test_ut_run is ut.expect( l_results ).to_be_like( '%test_package_1%test_package_2%test_package_3%' ); end; + procedure transaction_setup is + pragma autonomous_transaction; + begin + execute immediate 'create table transaction_test_table(message varchar2(100))'; + execute immediate 'create or replace package test_transaction is + --%suite + + --%test + procedure insert_row; + + --%test + procedure insert_and_raise; + end; + '; + execute immediate 'create or replace package body test_transaction is + procedure insert_row is + begin + insert into transaction_test_table values (''2 - inside the test_transaction.insert_row test''); + end; + procedure insert_and_raise is + begin + insert into transaction_test_table values (''2 - inside the test_transaction.insert_row test''); + raise no_data_found; + end; + end; + '; + + end; + + procedure transaction_cleanup is + pragma autonomous_transaction; + begin + begin + execute immediate 'drop table transaction_test_table'; + exception + when others then null; + end; + begin + execute immediate 'drop pacakge test_transaction'; + exception + when others then null; + end; + end; + + procedure run_proc_keep_test_data is + l_expected sys_refcursor; + l_actual sys_refcursor; + l_results clob; + begin + --Arrange + execute immediate ' + insert into transaction_test_table values (''1 - inside the test_ut_run.run_proc_keep_test_changes test'')'; + + --Act + ut3.ut.run('test_transaction.insert_row', a_force_manual_rollback => true); + l_results := get_dbms_output_as_clob(); + + --Assert + open l_expected for + select '1 - inside the test_ut_run.run_proc_keep_test_changes test' as message from dual + union all + select '2 - inside the test_transaction.insert_row test' from dual + order by 1; + + open l_actual for 'select * from transaction_test_table order by 1'; + + ut.expect( l_actual ).to_equal(l_expected); + end; + + procedure run_proc_keep_test_data_raise is + l_expected sys_refcursor; + l_actual sys_refcursor; + l_results clob; + begin + --Arrange + execute immediate ' + insert into transaction_test_table values (''1 - inside the test_ut_run.run_proc_keep_test_changes test'')'; + + --Act + ut3.ut.run('test_transaction.insert_and_raise', a_force_manual_rollback => true); + l_results := get_dbms_output_as_clob(); + + --Assert + open l_expected for + select '1 - inside the test_ut_run.run_proc_keep_test_changes test' as message from dual + union all + select '2 - inside the test_transaction.insert_row test' from dual + order by 1; + + open l_actual for 'select * from transaction_test_table order by 1'; + + ut.expect( l_actual ).to_equal(l_expected); + end; + + procedure run_proc_discard_test_data is + l_expected sys_refcursor; + l_actual sys_refcursor; + l_results clob; + begin + --Arrange + execute immediate ' + insert into transaction_test_table values (''1 - inside the test_ut_run.run_proc_keep_test_changes test'')'; + + --Act + ut3.ut.run('test_transaction.insert_row'); + l_results := get_dbms_output_as_clob(); + + --Assert + open l_expected for + select '1 - inside the test_ut_run.run_proc_keep_test_changes test' as message from dual; + + open l_actual for 'select * from transaction_test_table order by 1'; + + ut.expect( l_actual ).to_equal(l_expected); + end; + procedure run_func_no_params is l_results ut3.ut_varchar2_list; begin diff --git a/test/api/test_ut_run.pks b/test/api/test_ut_run.pks index cfc06c80d..b5fa8bd69 100644 --- a/test/api/test_ut_run.pks +++ b/test/api/test_ut_run.pks @@ -44,6 +44,21 @@ create or replace package test_ut_run is --%endcontext + --%context(run_proc_transaction_control) + + --%beforeall + procedure transaction_setup; + --%afterall + procedure transaction_cleanup; + --%test(Leaves transaction open and uncommitted with a_force_manual_rollback) + procedure run_proc_keep_test_data; + --%test(Leaves transaction open and uncommitted with a_force_manual_rollback with exceptions) + procedure run_proc_keep_test_data_raise; + --%test(Does not impact current transaction when ran without a_force_manual_rollback) + procedure run_proc_discard_test_data; + + --%endcontext + --%context(ut_run_function) --%displayname(ut.run() function options) From 4e3a654adde8c1fcb4c316d002ca3a4383d4bb98 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 00:40:04 +0000 Subject: [PATCH 101/115] Updated documentation. --- docs/userguide/running-unit-tests.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/userguide/running-unit-tests.md b/docs/userguide/running-unit-tests.md index 54116cf65..b67569b8f 100644 --- a/docs/userguide/running-unit-tests.md +++ b/docs/userguide/running-unit-tests.md @@ -131,6 +131,26 @@ Executes all tests from package _HR.TEST_APPLY_BONUS_ and provide outputs to DBM For details on build-in reporters look at [reporters documentation](reporters.md). +## Keeping uncommited data after test-run + +utPLSQL by default runs tests in autonomous transaction and performs automatic rollback to assure that tests do not impact one-another and do not have impact on the current session in your IDE. + +If you would like to keep your uncommited data persisted after running tests, you can do so by using `a_force_manual_rollback` flag. +Setting this flag to true has following side-effects: + +- test execution is done in current transaction - if while running tests commit or rollback is issued your current session data will get commited too. +- automatic rollback is forced to be disabled in test-run even if it was explicitly enabled by using annotation `--%rollback(manual) + +Example invocation: +```sql +begin + ut.run('hr.test_apply_bonus', a_force_manual_rollback => true); +end; +``` + + +This option is not anvailable when running tests using `ut.run` as a table function. + ## ut.run functions The `ut.run` functions provide exactly the same functionality as the `ut.run` procedures. From 611092353d6e748b775cc51177007f5588771e7a Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 01:10:07 +0000 Subject: [PATCH 102/115] Updated documentation to include infrmation about reports encoding. --- docs/userguide/reporters.md | 8 ++++---- docs/userguide/running-unit-tests.md | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/userguide/reporters.md b/docs/userguide/reporters.md index 2fddbbfd7..6d3e8a326 100644 --- a/docs/userguide/reporters.md +++ b/docs/userguide/reporters.md @@ -42,7 +42,7 @@ Example outputs from documentation reporter. # JUnit reporter Most of continuous integration servers (like Jenkins) are capable of consuming unit test execution results in [JUnit](https://en.wikipedia.org/wiki/JUnit) format. -The `ut_junit_reporter` in earlier version referred as ut_xunit_reporter is producing outcomes as JUnit-compatible XML unit test report, that can be used by CI servers to display their custom reports and provide metrics (like tests execution trends). +The `ut_junit_reporter` in earlier version referred as `ut_xunit_reporter` is producing outcomes as JUnit-compatible XML unit test report, that can be used by CI servers to display their custom reports and provide metrics (like tests execution trends). Please note that in previous versions it was called ut_xunit_reporter and for backward compatibility that name still exists. Invocation of tests with JUnit reporter. @@ -63,7 +63,7 @@ Example of failure report details # Teamcity reporter -[Teamcity](https://www.jetbrains.com/teamcity/) is a CI server by Jetbrains. It supports XUnit reporting and additionally has it's own format of reporting that allows tracking of progress of a CI step/task as it executes. +[Teamcity](https://www.jetbrains.com/teamcity/) is a CI server by Jetbrains. It supports JUnit reporting and additionally has it's own format of reporting that allows tracking of progress of a CI step/task as it executes. The TeamCity format developed by Jetbrains is supported by utPLSQL with `ut_teamcity_reporter`. Invocation of tests with Teamcity reporter. @@ -74,11 +74,11 @@ The `ut_teamcity_reporter` doesn't accept any arguments. Example of unit test report from Teamcity CI server. -![xunit_reporter_outputs](../images/teamcity_report_example.png) +![junit_reporter_outputs](../images/teamcity_report_example.png) Example of failure report details -![xunit_reporter_outputs](../images/teamcity_report_example_errors.png) +![junit_reporter_outputs_errors](../images/teamcity_report_example_errors.png) # Sonar test reporter diff --git a/docs/userguide/running-unit-tests.md b/docs/userguide/running-unit-tests.md index 54116cf65..afe2c7ac9 100644 --- a/docs/userguide/running-unit-tests.md +++ b/docs/userguide/running-unit-tests.md @@ -123,10 +123,10 @@ You can execute any set of tests with any of the predefined reporters. ```sql begin - ut.run('hr.test_apply_bonus', ut_xunit_reporter()); + ut.run('hr.test_apply_bonus', ut_junit_reporter()); end; ``` -Executes all tests from package _HR.TEST_APPLY_BONUS_ and provide outputs to DBMS_OUTPUT using the XUnit reporter. +Executes all tests from package _HR.TEST_APPLY_BONUS_ and provide outputs to DBMS_OUTPUT using the JUnit reporter. For details on build-in reporters look at [reporters documentation](reporters.md). @@ -140,7 +140,7 @@ Functions provide output as a pipelined stream and therefore need to be executed Example. ```sql -select * from table(ut.run('hr.test_apply_bonus', ut_xunit_reporter())); +select * from table(ut.run('hr.test_apply_bonus', ut_junit_reporter())); ``` # ut_runner.run procedures @@ -158,3 +158,17 @@ The concept is pretty simple. - as a separate thread, start `ut_runner.run` and pass reporters with previously defined output_ids. - for each reporter start a separate thread and read outputs from the `ut_output_buffer.get_lines` table function by providing the output_id defined in the main thread. +# Reports characterset encoding + +To get properly encoded reports, when running utPLSQL with HTML/XML reports on data containing national characters you need to provide your client character set when calling `ut.run` functions and procedures. + +If you run your tests using `utPLSQL-cli`, this is done automatically and no action needs to be taken. + +To make sure that the reports will display your national characters properly when running from IDE like SQLDeveloper/TOAD/SQLPlus or sqlcl you need to provide the charaterset manualy to `ut.run`. + +Example call with characterset provided: +```sql +begin + ut.run('hr.test_apply_bonus', ut_junit_reporter(), a_client_character_set => 'Windows-1251'); +end; +``` \ No newline at end of file From 74ec9a1f3cefa713d49cf777c731290552bb1c8b Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 14:50:10 +0000 Subject: [PATCH 103/115] Removed unused code. Added additional tests to: - cover functionality of reporting warnings on transaction invalidation with sub-suites. - cover functionality of failing a test in sub-suite when beforeall fails in parent suite with logical suites in between. Refactored `ut_teamcity_reporter` a bit. --- examples/RunDeveloperExamples.sql | 2 - ...nExampleComplexSuiteWithCustomReporter.sql | 56 ------------ .../RunExampleTestSuite.sql | 6 +- ...nExampleTestSuiteWithCompositeReporter.sql | 14 +-- .../RunExampleTestSuiteWithCustomReporter.sql | 6 +- .../annotations/ut_annotation_manager.pkb | 2 +- .../core/types/ut_console_reporter_base.tpb | 10 --- .../core/types/ut_console_reporter_base.tps | 6 +- source/core/types/ut_logical_suite.tpb | 39 -------- source/core/types/ut_logical_suite.tps | 10 --- source/core/types/ut_run.tpb | 24 +---- source/core/types/ut_run.tps | 6 -- source/core/types/ut_suite_item.tps | 6 -- source/core/types/ut_test.tpb | 10 --- source/core/types/ut_test.tps | 6 -- source/core/ut_metadata.pkb | 20 +---- source/core/ut_metadata.pks | 6 -- source/core/ut_suite_manager.pkb | 4 +- source/core/ut_utils.pkb | 16 +--- source/core/ut_utils.pks | 6 -- source/reporters/ut_ansiconsole_helper.pkb | 10 --- source/reporters/ut_ansiconsole_helper.pks | 4 - source/reporters/ut_teamcity_reporter.tpb | 51 +++++------ test/api/test_ut_run.pkb | 88 +++++++++++++++++++ test/api/test_ut_run.pks | 15 ++++ test/core/test_ut_suite.pkb | 24 +++-- test/core/test_ut_test.pkb | 30 ++++--- 27 files changed, 186 insertions(+), 291 deletions(-) delete mode 100644 examples/developer_examples/RunExampleComplexSuiteWithCustomReporter.sql diff --git a/examples/RunDeveloperExamples.sql b/examples/RunDeveloperExamples.sql index ec4301e88..d34914b58 100644 --- a/examples/RunDeveloperExamples.sql +++ b/examples/RunDeveloperExamples.sql @@ -6,8 +6,6 @@ set linesize 1000 exec ut_ansiconsole_helper.color_enabled(true); --developer examples -prompt RunExampleComplexSuiteWithCustomReporter -@@developer_examples/RunExampleComplexSuiteWithCustomReporter.sql prompt RunExampleTestSuiteWithCustomReporter @@developer_examples/RunExampleTestSuiteWithCustomReporter.sql prompt RunExampleTestAnnotationsParsingTimeHugePackage diff --git a/examples/developer_examples/RunExampleComplexSuiteWithCustomReporter.sql b/examples/developer_examples/RunExampleComplexSuiteWithCustomReporter.sql deleted file mode 100644 index 406a1cba2..000000000 --- a/examples/developer_examples/RunExampleComplexSuiteWithCustomReporter.sql +++ /dev/null @@ -1,56 +0,0 @@ ---Shows how to create a test suite with the default reporter which is dbms_output ---No tables are used for this. ---Suite Management packages are when developed will make this easier. ---Clear Screen -Set Serveroutput On Size Unlimited format truncated -set echo off ---install the example unit test packages -@@ut_exampletest.pks -@@ut_exampletest.pkb -@@ut_exampletest2.pks -@@ut_exampletest2.pkb -@@ut_custom_reporter.tps -@@ut_custom_reporter.tpb - -declare - l_parent_suite ut_logical_suite; - l_suite ut_suite; - l_test ut_test; - l_reporter ut_output_reporter_base; - l_run ut_run; -begin - ut_event_manager.initialize(); - l_parent_suite := ut_logical_suite( a_object_owner=>null, a_object_name => null, a_name => 'complex_test_suite', a_path => null); - - l_suite := ut_suite(user, 'ut_exampletest',a_line_no=>1); - l_test := ut_test(user, 'ut_exampletest','ut_exAmpletest',a_line_no=>3); - l_test.description := 'Example test1'; - l_test.before_test_list := ut_executables(ut_executable(user, 'ut_exampletest','Setup',ut_utils.gc_before_test)); - l_test.after_test_list := ut_executables(ut_executable(user, 'ut_exampletest','tEardown',ut_utils.gc_after_test)); - - l_suite.add_item(l_test); - l_parent_suite.add_item(l_suite); - - - l_suite := ut_suite(user, 'ut_exampletest2',a_line_no=>1); - l_test := ut_test(user, 'UT_EXAMPLETEST2','UT_EXAMPLETEST',a_line_no=>3); - l_test.before_test_list := ut_executables(ut_executable(user, 'UT_EXAMPLETEST2','SETUP',ut_utils.gc_before_test)); - l_test.after_test_list := ut_executables(ut_executable(user, 'UT_EXAMPLETEST2','TEARDOWN',ut_utils.gc_after_test)); - - l_suite.add_item(l_test); - l_parent_suite.add_item(l_suite); - - -- provide a reporter to process results - l_reporter := ut_custom_reporter(a_tab_size => 2); - ut_event_manager.add_listener(l_reporter); - l_run := ut_run(ut_suite_items(l_parent_suite)); - l_run.do_execute(); - ut_event_manager.trigger_event(ut_utils.gc_finalize, l_run); - l_reporter.lines_to_dbms_output(); -end; -/ - -drop type ut_custom_reporter; -drop package ut_exampletest; -drop package ut_exampletest2; -exec dbms_session.reset_package; diff --git a/examples/developer_examples/RunExampleTestSuite.sql b/examples/developer_examples/RunExampleTestSuite.sql index 7b01d1154..950450cd5 100644 --- a/examples/developer_examples/RunExampleTestSuite.sql +++ b/examples/developer_examples/RunExampleTestSuite.sql @@ -21,13 +21,15 @@ begin l_test.description := 'Example test1'; l_test.before_test_list := ut_executables(ut_executable(user, 'ut_exampletest','Setup',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'ut_exampletest','tEardown',ut_utils.gc_after_test)); - l_suite.add_item(l_test); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := l_test; l_test := ut_test(user, 'UT_EXAMPLETEST2','ut_exAmpletest',a_line_no=>6); l_test.description := 'Another example test'; l_test.before_test_list := ut_executables(ut_executable(user, 'UT_EXAMPLETEST2','SETUP',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'UT_EXAMPLETEST2','TEARDOWN',ut_utils.gc_after_test)); - l_suite.add_item(l_test); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := l_test; l_suite.do_execute(); diff --git a/examples/developer_examples/RunExampleTestSuiteWithCompositeReporter.sql b/examples/developer_examples/RunExampleTestSuiteWithCompositeReporter.sql index 8876f0874..f247e06db 100644 --- a/examples/developer_examples/RunExampleTestSuiteWithCompositeReporter.sql +++ b/examples/developer_examples/RunExampleTestSuiteWithCompositeReporter.sql @@ -12,7 +12,7 @@ set echo off PROMPT Runs test report using composite reporter declare - suite ut_logical_suite; + l_suite ut_logical_suite; l_doc_reporter ut_output_reporter_base := ut_documentation_reporter(); l_tc_reporter ut_output_reporter_base := ut_teamcity_reporter(); l_run ut_run; @@ -21,14 +21,16 @@ begin ut_event_manager.add_listener(l_doc_reporter); ut_event_manager.add_listener(l_tc_reporter); - suite := ut_suite(user, 'ut_exampletest',a_line_no=>1); - suite.description := 'Test Suite Name'; + l_suite := ut_suite(user, 'ut_exampletest',a_line_no=>1); + l_suite.description := 'Test Suite Name'; - suite.add_item(ut_test(user,'ut_exampletest','ut_exAmpletest',a_line_no=>3)); - suite.add_item(ut_test(user, 'UT_EXAMPLETEST2','UT_EXAMPLETEST',a_line_no=>6)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut_test(user,'ut_exampletest','ut_exAmpletest',a_line_no=>3); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut_test(user, 'UT_EXAMPLETEST2','UT_EXAMPLETEST',a_line_no=>6); -- provide a reporter to process results - l_run := ut_run(ut_suite_items(suite)); + l_run := ut_run(ut_suite_items(l_suite)); l_run.do_execute(); ut_event_manager.trigger_event(ut_utils.gc_finalize, l_run); diff --git a/examples/developer_examples/RunExampleTestSuiteWithCustomReporter.sql b/examples/developer_examples/RunExampleTestSuiteWithCustomReporter.sql index e9403809e..2cae9db53 100644 --- a/examples/developer_examples/RunExampleTestSuiteWithCustomReporter.sql +++ b/examples/developer_examples/RunExampleTestSuiteWithCustomReporter.sql @@ -28,13 +28,15 @@ begin l_test.description := 'Example test1'; l_test.before_test_list := ut_executables(ut_executable(user, 'ut_exampletest','Setup',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'ut_exampletest','tEardown',ut_utils.gc_after_test)); - l_suite.add_item(l_test); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := l_test; l_test := ut_test(user, 'UT_EXAMPLETEST2','ut_exAmpletest',a_line_no=>6); l_test.description := 'Another example test'; l_test.before_test_list := ut_executables(ut_executable(user, 'ut_exampletest','SETUP',ut_utils.gc_before_test)); l_test.after_test_list := ut_executables(ut_executable(user, 'ut_exampletest','TEARDOWN',ut_utils.gc_after_test)); - l_suite.add_item(l_test); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := l_test; -- provide a reporter to process results tabbing each hierarcy level by tab_size l_reporter := ut_custom_reporter(a_tab_size => 2); diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb index 1c7e39273..6dbe1d3ec 100644 --- a/source/core/annotations/ut_annotation_manager.pkb +++ b/source/core/annotations/ut_annotation_manager.pkb @@ -193,7 +193,7 @@ create or replace package body ut_annotation_manager as ut_annotation_cache_manager.cleanup_cache(l_objects_to_parse); if sys_context('userenv','current_schema') = a_object_owner - or ut_metadata.is_object_visible('ut3.ut_utils') + or ut_metadata.user_has_execute_any_proc() or ut_metadata.is_object_visible('dba_objects') then ut_annotation_cache_manager.remove_from_cache( diff --git a/source/core/types/ut_console_reporter_base.tpb b/source/core/types/ut_console_reporter_base.tpb index 70513223c..0245edde3 100644 --- a/source/core/types/ut_console_reporter_base.tpb +++ b/source/core/types/ut_console_reporter_base.tpb @@ -36,20 +36,10 @@ create or replace type body ut_console_reporter_base is self.print_text(ut_ansiconsole_helper.yellow(a_text)); end; - member procedure print_blue_text(self in out nocopy ut_console_reporter_base, a_text varchar2) is - begin - self.print_text(ut_ansiconsole_helper.red(a_text)); - end; - member procedure print_cyan_text(self in out nocopy ut_console_reporter_base, a_text varchar2) is begin self.print_text(ut_ansiconsole_helper.cyan(a_text)); end; - member procedure print_magenta_text(self in out nocopy ut_console_reporter_base, a_text varchar2) is - begin - self.print_text(ut_ansiconsole_helper.magenta(a_text)); - end; - end; / diff --git a/source/core/types/ut_console_reporter_base.tps b/source/core/types/ut_console_reporter_base.tps index b74b08033..3736e4d33 100644 --- a/source/core/types/ut_console_reporter_base.tps +++ b/source/core/types/ut_console_reporter_base.tps @@ -23,11 +23,7 @@ create or replace type ut_console_reporter_base under ut_output_reporter_base( member procedure print_yellow_text(self in out nocopy ut_console_reporter_base, a_text varchar2), - member procedure print_blue_text(self in out nocopy ut_console_reporter_base, a_text varchar2), - - member procedure print_cyan_text(self in out nocopy ut_console_reporter_base, a_text varchar2), - - member procedure print_magenta_text(self in out nocopy ut_console_reporter_base, a_text varchar2) + member procedure print_cyan_text(self in out nocopy ut_console_reporter_base, a_text varchar2) ) not final not instantiable / diff --git a/source/core/types/ut_logical_suite.tpb b/source/core/types/ut_logical_suite.tpb index 70e0ca462..306ef3b36 100644 --- a/source/core/types/ut_logical_suite.tpb +++ b/source/core/types/ut_logical_suite.tpb @@ -16,45 +16,6 @@ create or replace type body ut_logical_suite as limitations under the License. */ - constructor function ut_logical_suite( - self in out nocopy ut_logical_suite,a_object_owner varchar2, a_object_name varchar2, a_name varchar2, a_path varchar2 - ) return self as result is - begin - self.self_type := $$plsql_unit; - self.init(a_object_owner, a_object_name, a_name, null); - self.path := a_path; - self.disabled_flag := ut_utils.boolean_to_int(false); - self.items := ut_suite_items(); - return; - end; - - member function is_valid(self in out nocopy ut_logical_suite) return boolean is - begin - return true; - end; - - overriding member procedure add_item( - self in out nocopy ut_logical_suite, - a_item ut_suite_item, - a_expected_level integer := 1, - a_current_level integer :=1 - ) is - begin - if a_expected_level > a_current_level then - if self.items.last is not null then - self.items(self.items.last).add_item(a_item, a_expected_level, a_current_level+1); - else - raise_application_error(-20000, 'cannot add suite item to sub suite at level '||a_expected_level||'. suite items at level '||a_current_level||' are empty'); - end if; - else - if self.items is null then - self.items := ut_suite_items(); - end if; - self.items.extend; - self.items(self.items.last) := a_item; - end if; - end; - overriding member procedure mark_as_skipped(self in out nocopy ut_logical_suite) is begin ut_event_manager.trigger_event(ut_utils.gc_before_suite, self); diff --git a/source/core/types/ut_logical_suite.tps b/source/core/types/ut_logical_suite.tps index 2672cacd3..a9043c87e 100644 --- a/source/core/types/ut_logical_suite.tps +++ b/source/core/types/ut_logical_suite.tps @@ -21,16 +21,6 @@ create or replace type ut_logical_suite under ut_suite_item ( */ items ut_suite_items, - constructor function ut_logical_suite( - self in out nocopy ut_logical_suite, a_object_owner varchar2, a_object_name varchar2, a_name varchar2, a_path varchar2 - ) return self as result, - member function is_valid(self in out nocopy ut_logical_suite) return boolean, - overriding member procedure add_item( - self in out nocopy ut_logical_suite, - a_item ut_suite_item, - a_expected_level integer := 1, - a_current_level integer :=1 - ), overriding member procedure mark_as_skipped(self in out nocopy ut_logical_suite), overriding member procedure set_rollback_type(self in out nocopy ut_logical_suite, a_rollback_type integer), overriding member function do_execute(self in out nocopy ut_logical_suite) return boolean, diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb index f7756cf37..a1ee19bd2 100644 --- a/source/core/types/ut_run.tpb +++ b/source/core/types/ut_run.tpb @@ -51,16 +51,6 @@ create or replace type body ut_run as null; end; - overriding member procedure add_item( - self in out nocopy ut_run, - a_item ut_suite_item, - a_expected_level integer := 1, - a_current_level integer :=1 - ) is - begin - raise_application_error(-20000, 'Cannot add a suite item to ut_run'); - end; - overriding member function do_execute(self in out nocopy ut_run) return boolean is l_completed_without_errors boolean; begin @@ -103,19 +93,7 @@ create or replace type body ut_run as overriding member procedure mark_as_errored(self in out nocopy ut_run, a_error_stack_trace varchar2) is begin - ut_utils.debug_log('ut_run.fail'); - - ut_event_manager.trigger_event(ut_utils.gc_before_run, self); - self.start_time := current_timestamp; - - for i in 1 .. self.items.count loop - self.items(i).mark_as_errored(a_error_stack_trace); - end loop; - - self.calc_execution_result(); - self.end_time := self.start_time; - - ut_event_manager.trigger_event(ut_utils.gc_after_run, self); + null; end; overriding member function get_error_stack_traces return ut_varchar2_list is diff --git a/source/core/types/ut_run.tps b/source/core/types/ut_run.tps index 3807a2a75..5dc8e0399 100644 --- a/source/core/types/ut_run.tps +++ b/source/core/types/ut_run.tps @@ -36,12 +36,6 @@ create or replace type ut_run under ut_suite_item ( a_client_character_set varchar2 := null ) return self as result, overriding member procedure mark_as_skipped(self in out nocopy ut_run), - overriding member procedure add_item( - self in out nocopy ut_run, - a_item ut_suite_item, - a_expected_level integer := 1, - a_current_level integer :=1 - ), overriding member function do_execute(self in out nocopy ut_run) return boolean, overriding member procedure calc_execution_result(self in out nocopy ut_run), overriding member procedure mark_as_errored(self in out nocopy ut_run, a_error_stack_trace varchar2), diff --git a/source/core/types/ut_suite_item.tps b/source/core/types/ut_suite_item.tps index 927ad3807..e91b2afd0 100644 --- a/source/core/types/ut_suite_item.tps +++ b/source/core/types/ut_suite_item.tps @@ -63,12 +63,6 @@ create or replace type ut_suite_item force under ut_event_item ( member procedure init(self in out nocopy ut_suite_item, a_object_owner varchar2, a_object_name varchar2, a_name varchar2, a_line_no integer), member function get_disabled_flag return boolean, not instantiable member procedure mark_as_skipped(self in out nocopy ut_suite_item), - not instantiable member procedure add_item( - self in out nocopy ut_suite_item, - a_item ut_suite_item, - a_expected_level integer := 1, - a_current_level integer :=1 - ), member procedure set_rollback_type(self in out nocopy ut_suite_item, a_rollback_type integer), member function get_rollback_type return integer, member function create_savepoint_if_needed return varchar2, diff --git a/source/core/types/ut_test.tpb b/source/core/types/ut_test.tpb index d68b19a87..ed9692e14 100644 --- a/source/core/types/ut_test.tpb +++ b/source/core/types/ut_test.tpb @@ -34,16 +34,6 @@ create or replace type body ut_test as return; end; - overriding member procedure add_item( - self in out nocopy ut_test, - a_item ut_suite_item, - a_expected_level integer := 1, - a_current_level integer :=1 - ) is - begin - raise_application_error(-20000, 'Cannot add a suite item to ut_test'); - end; - overriding member procedure mark_as_skipped(self in out nocopy ut_test) is begin ut_event_manager.trigger_event(ut_utils.gc_before_test, self); diff --git a/source/core/types/ut_test.tps b/source/core/types/ut_test.tps index 9e26508e4..752ef3ef7 100644 --- a/source/core/types/ut_test.tps +++ b/source/core/types/ut_test.tps @@ -60,12 +60,6 @@ create or replace type ut_test under ut_suite_item ( a_line_no integer, a_expected_error_codes ut_integer_list := null ) return self as result, overriding member procedure mark_as_skipped(self in out nocopy ut_test), - overriding member procedure add_item( - self in out nocopy ut_test, - a_item ut_suite_item, - a_expected_level integer := 1, - a_current_level integer :=1 - ), overriding member function do_execute(self in out nocopy ut_test) return boolean, overriding member procedure calc_execution_result(self in out nocopy ut_test), overriding member procedure mark_as_errored(self in out nocopy ut_test, a_error_stack_trace varchar2), diff --git a/source/core/ut_metadata.pkb b/source/core/ut_metadata.pkb index d500bff61..92afa706e 100644 --- a/source/core/ut_metadata.pkb +++ b/source/core/ut_metadata.pkb @@ -22,12 +22,6 @@ create or replace package body ut_metadata as ------------------------------ --public definitions - procedure do_resolve(a_owner in out nocopy varchar2, a_object in out nocopy varchar2) is - l_procedure_name varchar2(200); - begin - do_resolve(a_owner, a_object, l_procedure_name ); - end do_resolve; - procedure do_resolve(a_owner in out nocopy varchar2, a_object in out nocopy varchar2, a_procedure_name in out nocopy varchar2) is l_name varchar2(200); l_context integer := 1; --plsql @@ -83,9 +77,6 @@ create or replace package body ut_metadata as -- expect both package and body to be valid return l_cnt = 1; - exception - when others then - return false; end; function procedure_exists(a_owner_name varchar2, a_package_name in varchar2, a_procedure_name in varchar2) @@ -110,9 +101,6 @@ create or replace package body ut_metadata as --expect one method only for the package with that name. return l_cnt = 1; - exception - when others then - return false; end; function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2 is @@ -168,14 +156,8 @@ create or replace package body ut_metadata as function user_has_execute_any_proc return boolean is l_ut_owner varchar2(250) := ut_utils.ut_owner; - l_dummy varchar2(250); begin - execute immediate 'select '||l_ut_owner||'.ut_utils.ut_owner from dual' - into l_dummy; - return true; - exception - when others then - return false; + return is_object_visible(l_ut_owner||'.ut_utils'); end; function is_object_visible(a_object_name varchar2) return boolean is diff --git a/source/core/ut_metadata.pks b/source/core/ut_metadata.pks index 16172a1f1..9a0ac2b00 100644 --- a/source/core/ut_metadata.pks +++ b/source/core/ut_metadata.pks @@ -39,12 +39,6 @@ create or replace package ut_metadata authid current_user as function procedure_exists(a_owner_name varchar2, a_package_name in varchar2, a_procedure_name in varchar2) return boolean; - /** - * Resolves [owner.]object using dbms_utility.name_resolve and returns resolved parts - * - */ - procedure do_resolve(a_owner in out nocopy varchar2, a_object in out nocopy varchar2); - /** * Resolves [owner.]object[.procedure] using dbms_utility.name_resolve and returns resolved parts * diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index fe76b2ed7..19862992d 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -465,7 +465,7 @@ create or replace package body ut_suite_manager is a_owner_name varchar2 ) return boolean is begin - return sys_context( 'userenv', 'current_schema' ) = a_owner_name or ut_metadata.is_object_visible( ut_utils.ut_owner ||'.ut_utils' ); + return sys_context( 'userenv', 'current_schema' ) = a_owner_name or ut_metadata.user_has_execute_any_proc(); end; procedure build_and_cache_suites( @@ -582,7 +582,7 @@ create or replace package body ut_suite_manager is l_need_all_objects_scan boolean := true; begin -- if current user is the onwer or current user has execute any procedure privilege - if ut_metadata.is_object_visible('ut3.ut_utils') + if ut_metadata.user_has_execute_any_proc() or (a_schema_names is not null and a_schema_names.count = 1 and sys_context('userenv','current_schema') = a_schema_names(1)) then diff --git a/source/core/ut_utils.pkb b/source/core/ut_utils.pkb index 928da6ca1..dbe57f866 100644 --- a/source/core/ut_utils.pkb +++ b/source/core/ut_utils.pkb @@ -55,18 +55,6 @@ create or replace package body ut_utils is return '"'|| utl_raw.cast_to_varchar2(utl_encode.base64_encode(sys_guid()))||'"'; end; - /* - Procedure: validate_rollback_type - - Validates passed value against supported rollback types - */ - procedure validate_rollback_type(a_rollback_type number) is - begin - if a_rollback_type not in (gc_rollback_auto, gc_rollback_manual) then - raise_application_error(-20200,'Rollback type is not supported'); - end if; - end validate_rollback_type; - procedure debug_log(a_message varchar2) is begin $if $$ut_trace $then @@ -604,15 +592,13 @@ create or replace package body ut_utils is end; function xmlgen_escaped_string(a_string in varchar2) return varchar2 is - l_result varchar2(4000); + l_result varchar2(4000) := a_string; l_sql varchar2(32767) := q'!select q'[!'||a_string||q'!]' as "!'||a_string||'" from dual'; begin if a_string is not null then select extract(dbms_xmlgen.getxmltype(l_sql),'/*/*/*').getRootElement() into l_result from dual; - else - l_result := a_string; end if; return l_result; end; diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 2a892c1e9..40b084d30 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -183,12 +183,6 @@ create or replace package ut_utils authid definer is function int_to_boolean(a_value integer) return boolean; - /** - * Validates passed value against supported rollback types - */ - procedure validate_rollback_type(a_rollback_type number); - - /** * * Splits a given string into table of string by delimiter. diff --git a/source/reporters/ut_ansiconsole_helper.pkb b/source/reporters/ut_ansiconsole_helper.pkb index ceb0cf53f..d9c0617e0 100644 --- a/source/reporters/ut_ansiconsole_helper.pkb +++ b/source/reporters/ut_ansiconsole_helper.pkb @@ -53,16 +53,6 @@ create or replace package body ut_ansiconsole_helper as return add_color(a_text, gc_yellow); end; - function blue(a_text varchar2) return varchar2 is - begin - return add_color(a_text, gc_blue); - end; - - function magenta(a_text varchar2) return varchar2 is - begin - return add_color(a_text, gc_magenta); - end; - function cyan(a_text varchar2) return varchar2 is begin return add_color(a_text, gc_cyan); diff --git a/source/reporters/ut_ansiconsole_helper.pks b/source/reporters/ut_ansiconsole_helper.pks index 29d746c7b..f34ff12bd 100644 --- a/source/reporters/ut_ansiconsole_helper.pks +++ b/source/reporters/ut_ansiconsole_helper.pks @@ -23,10 +23,6 @@ create or replace package ut_ansiconsole_helper as function yellow(a_text varchar2) return varchar2; - function blue(a_text varchar2) return varchar2; - - function magenta(a_text varchar2) return varchar2; - function cyan(a_text varchar2) return varchar2; end; / diff --git a/source/reporters/ut_teamcity_reporter.tpb b/source/reporters/ut_teamcity_reporter.tpb index a8a7ad45b..d01e85153 100644 --- a/source/reporters/ut_teamcity_reporter.tpb +++ b/source/reporters/ut_teamcity_reporter.tpb @@ -60,6 +60,25 @@ create or replace type body ut_teamcity_reporter is l_results ut_varchar2_rows := ut_varchar2_rows(); l_test_full_name varchar2(4000); l_std_err_msg varchar2(32767); + function add_error_message( a_message varchar2, a_message_name varchar2) return varchar2 is + begin + return + case + when a_message is not null + then a_message_name || chr(10) || a_message || chr(10) + end; + end; + function add_error_messages(a_executables ut_executables, a_message_name varchar2) return varchar2 is + l_message varchar2(32767); + l_idx binary_integer; + begin + l_idx := a_executables.first; + while l_idx is not null loop + l_message := l_message || add_error_message(a_executables(l_idx).error_backtrace, a_message_name); + l_idx := a_executables.next(l_idx); + end loop; + return l_message; + end; begin l_test_full_name := lower(a_test.item.owner_name) || '.' || lower(a_test.item.object_name) || '.' || lower(a_test.item.procedure_name); @@ -71,33 +90,11 @@ create or replace type body ut_teamcity_reporter is ut_utils.append_to_list( l_results, a_test.get_serveroutputs()); if a_test.result = ut_utils.gc_error then - for i in 1 .. a_test.before_each_list.count loop - if a_test.before_each_list(i).error_backtrace is not null then - l_std_err_msg := l_std_err_msg || 'Before each exception:' || chr(10) || a_test.before_each_list(i).error_backtrace || chr(10); - end if; - end loop; - - for i in 1 .. a_test.before_test_list.count loop - if a_test.before_test_list(i).error_backtrace is not null then - l_std_err_msg := l_std_err_msg || 'Before test exception:' || chr(10) || a_test.before_test_list(i).error_backtrace || chr(10); - end if; - end loop; - - if a_test.item.error_backtrace is not null then - l_std_err_msg := l_std_err_msg || 'Test exception:' || chr(10) || a_test.item.error_backtrace || chr(10); - end if; - - for i in 1 .. a_test.after_test_list.count loop - if a_test.after_test_list(i).error_backtrace is not null then - l_std_err_msg := l_std_err_msg || 'After test exception:' || chr(10) || a_test.after_test_list(i).error_backtrace || chr(10); - end if; - end loop; - - for i in 1 .. a_test.after_each_list.count loop - if a_test.after_each_list(i).error_backtrace is not null then - l_std_err_msg := l_std_err_msg || 'After each exception:' || chr(10) || a_test.after_each_list(i).error_backtrace || chr(10); - end if; - end loop; + l_std_err_msg := l_std_err_msg || add_error_messages(a_test.before_each_list, 'Before each exception:'); + l_std_err_msg := l_std_err_msg || add_error_messages(a_test.before_test_list, 'Before test exception:'); + l_std_err_msg := l_std_err_msg || add_error_message(a_test.item.error_backtrace, 'Test exception:'); + l_std_err_msg := l_std_err_msg || add_error_messages(a_test.after_test_list, 'After test exception:'); + l_std_err_msg := l_std_err_msg || add_error_messages(a_test.after_each_list, 'After each exception:'); ut_utils.append_to_list( l_results, diff --git a/test/api/test_ut_run.pkb b/test/api/test_ut_run.pkb index 9709058d4..ecf123d5e 100644 --- a/test/api/test_ut_run.pkb +++ b/test/api/test_ut_run.pkb @@ -355,6 +355,94 @@ create or replace package body test_ut_run is ut.expect( l_results ).to_be_like( '%test_package_1%test_package_2%test_package_3%' ); end; + procedure create_suite_with_commit is + pragma autonomous_transaction; + begin + execute immediate 'create or replace package test_commit_warning is + --%suite + --%suitepath(ut.run.transaction) + + --%test + procedure does_commit; + end;'; + execute immediate 'create or replace package body test_commit_warning is + procedure does_commit is + begin + ut3.ut.expect(1).to_equal(1); + commit; + end; + end;'; + end; + + procedure drop_suite_with_commit is + pragma autonomous_transaction; + begin + execute immediate 'drop package test_commit_warning'; + end; + + procedure run_proc_warn_on_commit is + l_results clob; + begin + ut3.ut.run('test_commit_warning'); + l_results := get_dbms_output_as_clob(); + ut.expect(l_results).to_be_like( + '%Unable to perform automatic rollback after test%'|| + 'An implicit or explicit commit/rollback occurred in procedures:%' || + 'does_commit%' || + 'Use the "--%rollback(manual)" annotation or remove commit/rollback/ddl statements that are causing the issue.%' + ); + end; + + procedure create_failing_beforeall_suite is + pragma autonomous_transaction; + begin + execute immediate 'create or replace package parent_suite is + --%suite + --%suitepath(ut.run.failing_setup) + + --%beforeall + procedure failing_setup; + end;'; + execute immediate 'create or replace package body parent_suite is + procedure failing_setup is + begin + raise no_data_found; + end; + end;'; + execute immediate 'create or replace package child_suite is + --%suite + --%suitepath(ut.run.failing_setup.parent_suite.some_sub_suite) + + --%test + procedure does_stuff; + end;'; + execute immediate 'create or replace package body child_suite is + procedure does_stuff is + begin + ut3.ut.expect(1).to_equal(1); + end; + end;'; + end; + + procedure drop_failing_beforeall_suite is + pragma autonomous_transaction; + begin + execute immediate 'drop package parent_suite'; + execute immediate 'drop package child_suite'; + end; + + procedure run_proc_fail_child_suites is + l_results clob; + begin + ut3.ut.run('child_suite'); + l_results := get_dbms_output_as_clob(); + ut.expect(l_results).to_be_like( + '%1) does_stuff%' || + 'ORA-01403: no data found%' || + 'ORA-06512: at "UT3_TESTER.PARENT_SUITE%' + ); + end; + procedure run_func_no_params is l_results ut3.ut_varchar2_list; begin diff --git a/test/api/test_ut_run.pks b/test/api/test_ut_run.pks index 927abf6e2..81eb801a3 100644 --- a/test/api/test_ut_run.pks +++ b/test/api/test_ut_run.pks @@ -41,6 +41,21 @@ create or replace package test_ut_run is --%test(Runs all tests in current schema with empty path list given) procedure run_proc_empty_path_list; + procedure create_suite_with_commit; + procedure drop_suite_with_commit; + --%test(Reports a warning if transaction was invalidated by test with automatic rollback) + --%beforetest(create_suite_with_commit) + --%aftertest(drop_suite_with_commit) + procedure run_proc_warn_on_commit; + + + procedure create_failing_beforeall_suite; + procedure drop_failing_beforeall_suite; + --%test(Marks child suite as failed when parent's suite beforeall fails) + --%beforetest(create_failing_beforeall_suite) + --%aftertest(drop_failing_beforeall_suite) + procedure run_proc_fail_child_suites; + --%endcontext diff --git a/test/core/test_ut_suite.pkb b/test/core/test_ut_suite.pkb index 9955aa048..557d3cb7b 100644 --- a/test/core/test_ut_suite.pkb +++ b/test/core/test_ut_suite.pkb @@ -14,8 +14,10 @@ create or replace package body test_ut_suite is l_suite.disabled_flag := ut3.ut_utils.boolean_to_int(true); l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'set_g_number_0', ut3.ut_utils.gc_before_all)); l_suite.after_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_before_all)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); --Act l_suite.do_execute(); --Assert @@ -35,7 +37,8 @@ create or replace package body test_ut_suite is l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_EXAMPLE_TESTS', a_line_no=> 1); l_suite.path := 'ut_example_tests'; l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_before_all)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'set_g_number_0', a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'set_g_number_0', a_line_no=> 1); --Act l_suite.do_execute(); --Assert @@ -56,8 +59,10 @@ create or replace package body test_ut_suite is l_suite.path := 'ut_example_tests'; l_suite.after_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_after_all)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'set_g_number_0', a_line_no=> 1)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'set_g_number_0', a_line_no=> 1); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); --Act l_suite.do_execute(); --Assert @@ -75,7 +80,8 @@ create or replace package body test_ut_suite is begin l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_WITHOUT_BODY', a_line_no=> 1); l_suite.path := 'UT_WITHOUT_BODY'; - l_suite.add_item(ut3.ut_test(a_object_name => 'ut_without_body',a_name => 'test1', a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'ut_without_body',a_name => 'test1', a_line_no=> 1); --Act l_suite.do_execute(); --Assert @@ -87,7 +93,8 @@ create or replace package body test_ut_suite is begin l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_WITH_INVALID_BODY', a_line_no=> 1); l_suite.path := 'UT_WITH_INVALID_BODY'; - l_suite.add_item(ut3.ut_test(a_object_name => 'ut_with_invalid_body',a_name => 'test1', a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'ut_with_invalid_body',a_name => 'test1', a_line_no=> 1); --Act l_suite.do_execute(); --Assert @@ -102,7 +109,8 @@ create or replace package body test_ut_suite is l_suite := ut3.ut_suite(a_object_owner => USER, a_object_name => 'UT_TRANSACTION_CONTROL', a_line_no=> 1); l_suite.path := 'ut_transaction_control'; l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_TRANSACTION_CONTROL', 'setup', ut3.ut_utils.gc_before_all)); - l_suite.add_item(ut3.ut_test(a_object_owner => USER, a_object_name => 'ut_transaction_control',a_name => a_procedure_name, a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_owner => USER, a_object_name => 'ut_transaction_control',a_name => a_procedure_name, a_line_no=> 1); l_suite.set_rollback_type(a_rollback_type); --Act diff --git a/test/core/test_ut_test.pkb b/test/core/test_ut_test.pkb index 857ef5e99..5b401463c 100644 --- a/test/core/test_ut_test.pkb +++ b/test/core/test_ut_test.pkb @@ -14,8 +14,10 @@ create or replace package body test_ut_test is l_suite.path := 'ut_example_tests'; l_suite.before_all_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'set_g_number_0', ut3.ut_utils.gc_before_all)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 2)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 2); l_suite.items(l_suite.items.last).disabled_flag := ut3.ut_utils.boolean_to_int(true); --Act l_suite.do_execute(); @@ -41,8 +43,10 @@ create or replace package body test_ut_test is l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); l_test.before_test_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_before_test)); l_test.after_test_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_after_test)); - l_suite.add_item(l_test); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := l_test; + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); --Act l_suite.do_execute(); --Assert @@ -65,8 +69,10 @@ create or replace package body test_ut_test is l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); l_test.before_each_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_before_each)); l_test.after_each_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_after_each)); - l_suite.add_item(l_test); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := l_test; + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); --Act l_suite.do_execute(); --Assert @@ -89,8 +95,10 @@ create or replace package body test_ut_test is l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); l_test.before_test_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_before_test)); l_test.after_test_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_after_test)); - l_suite.add_item(l_test); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := l_test; + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); --Act l_suite.do_execute(); --Assert @@ -113,8 +121,10 @@ create or replace package body test_ut_test is l_test := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); l_test.before_each_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'failing_procedure', ut3.ut_utils.gc_before_each)); l_test.after_each_list := ut3.ut_executables(ut3.ut_executable(USER, 'UT_EXAMPLE_TESTS', 'add_1_to_g_number', ut3.ut_utils.gc_after_each)); - l_suite.add_item(l_test); - l_suite.add_item(ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1)); + l_suite.items.extend; + l_suite.items(l_suite.items.last) := l_test; + l_suite.items.extend; + l_suite.items(l_suite.items.last) := ut3.ut_test(a_object_name => 'UT_EXAMPLE_TESTS',a_name => 'add_1_to_g_number', a_line_no=> 1); --Act l_suite.do_execute(); --Assert From 44d61d921406077a58080c3538448217d07b5d7d Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 15:35:50 +0000 Subject: [PATCH 104/115] Recovering exception handlers as they are needed for handling invalid object names. --- source/core/ut_metadata.pkb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/core/ut_metadata.pkb b/source/core/ut_metadata.pkb index 92afa706e..c905ebefe 100644 --- a/source/core/ut_metadata.pkb +++ b/source/core/ut_metadata.pkb @@ -77,6 +77,9 @@ create or replace package body ut_metadata as -- expect both package and body to be valid return l_cnt = 1; + exception + when others then + return false; end; function procedure_exists(a_owner_name varchar2, a_package_name in varchar2, a_procedure_name in varchar2) @@ -101,6 +104,9 @@ create or replace package body ut_metadata as --expect one method only for the package with that name. return l_cnt = 1; + exception + when others then + return false; end; function get_source_definition_line(a_owner varchar2, a_object_name varchar2, a_line_no integer) return varchar2 is From 360a8895645d9065cb48ebf3d8af6fb175c4eec9 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 18:26:05 +0000 Subject: [PATCH 105/115] Moved some of old tests into new tests. Disabled coverage gathering on old tests. --- old_tests/RunAll.sql | 633 +++++++++--------- ...e_manager.CacheInvalidaesOnPackageDrop.sql | 50 -- .../ut_suite_manager.emptySuitePath.sql | 41 -- .../ut_test/ut_test.AfterEachExecuted.sql | 20 - .../ut_test.AfterEachProcedureNameInvalid.sql | 21 - .../ut_test.AfterEachProcedureNameNull.sql | 21 - .../ut_test.ApplicationInfoOnExecution.sql | 149 ----- .../ut_test/ut_test.BeforeEachExecuted.sql | 21 - ...ut_test.BeforeEachProcedureNameInvalid.sql | 20 - .../ut_test.BeforeEachProcedureNameNull.sql | 22 - ...est.IgnoreTollbackToSavepointException.sql | 17 - .../ut_test/ut_test.OwnerNameInvalid.sql | 21 - old_tests/ut_test/ut_test.OwnerNameNull.sql | 18 - .../ut_test/ut_test.PackageInInvalidState.sql | 27 - .../ut_test/ut_test.PackageNameInvalid.sql | 16 - old_tests/ut_test/ut_test.PackageNameNull.sql | 16 - .../ut_test/ut_test.ProcedureNameInvalid.sql | 16 - .../ut_test/ut_test.ProcedureNameNull.sql | 16 - .../ut_test.ReportWarningOnRollbackFailed.sql | 58 -- .../ut_test.SetupExecutedBeforeTest.sql | 21 - .../ut_test.SetupProcedureNameInvalid.sql | 20 - .../ut_test.SetupProcedureNameNull.sql | 22 - .../ut_test.TeardownExecutedAfterTest.sql | 20 - .../ut_test.TeardownProcedureNameInvalid.sql | 20 - .../ut_test.TeardownProcedureNameNull.sql | 21 - .../ut_test/ut_test.TestOutputGathering.sql | 103 --- .../ut_test.TestOutputGatheringWhenEmpty.sql | 55 -- sonar-project.properties | 2 +- test/core/test_ut_test.pkb | 556 +++++++++++++++ test/core/test_ut_test.pks | 66 ++ test/helpers/ut_example_tests.pkb | 4 + test/helpers/ut_example_tests.pks | 12 +- 32 files changed, 936 insertions(+), 1189 deletions(-) delete mode 100644 old_tests/ut_suite_manager/ut_suite_manager.CacheInvalidaesOnPackageDrop.sql delete mode 100644 old_tests/ut_suite_manager/ut_suite_manager.emptySuitePath.sql delete mode 100644 old_tests/ut_test/ut_test.AfterEachExecuted.sql delete mode 100644 old_tests/ut_test/ut_test.AfterEachProcedureNameInvalid.sql delete mode 100644 old_tests/ut_test/ut_test.AfterEachProcedureNameNull.sql delete mode 100644 old_tests/ut_test/ut_test.ApplicationInfoOnExecution.sql delete mode 100644 old_tests/ut_test/ut_test.BeforeEachExecuted.sql delete mode 100644 old_tests/ut_test/ut_test.BeforeEachProcedureNameInvalid.sql delete mode 100644 old_tests/ut_test/ut_test.BeforeEachProcedureNameNull.sql delete mode 100644 old_tests/ut_test/ut_test.IgnoreTollbackToSavepointException.sql delete mode 100644 old_tests/ut_test/ut_test.OwnerNameInvalid.sql delete mode 100644 old_tests/ut_test/ut_test.OwnerNameNull.sql delete mode 100644 old_tests/ut_test/ut_test.PackageInInvalidState.sql delete mode 100644 old_tests/ut_test/ut_test.PackageNameInvalid.sql delete mode 100644 old_tests/ut_test/ut_test.PackageNameNull.sql delete mode 100644 old_tests/ut_test/ut_test.ProcedureNameInvalid.sql delete mode 100644 old_tests/ut_test/ut_test.ProcedureNameNull.sql delete mode 100644 old_tests/ut_test/ut_test.ReportWarningOnRollbackFailed.sql delete mode 100644 old_tests/ut_test/ut_test.SetupExecutedBeforeTest.sql delete mode 100644 old_tests/ut_test/ut_test.SetupProcedureNameInvalid.sql delete mode 100644 old_tests/ut_test/ut_test.SetupProcedureNameNull.sql delete mode 100644 old_tests/ut_test/ut_test.TeardownExecutedAfterTest.sql delete mode 100644 old_tests/ut_test/ut_test.TeardownProcedureNameInvalid.sql delete mode 100644 old_tests/ut_test/ut_test.TeardownProcedureNameNull.sql delete mode 100644 old_tests/ut_test/ut_test.TestOutputGathering.sql delete mode 100644 old_tests/ut_test/ut_test.TestOutputGatheringWhenEmpty.sql diff --git a/old_tests/RunAll.sql b/old_tests/RunAll.sql index f785aabc1..282a01ff7 100644 --- a/old_tests/RunAll.sql +++ b/old_tests/RunAll.sql @@ -50,41 +50,14 @@ exec ut_coverage.set_develop_mode(true); @@lib/RunTest.sql ut_reporters/ut_html_reporter.UserOverrideSchemaCoverage.sql @@lib/RunTest.sql ut_suite_manager/ut_suite_manager.AllowsDescriptionsWithComma.sql -@@lib/RunTest.sql ut_suite_manager/ut_suite_manager.emptySuitePath.sql @@lib/RunTest.sql ut_suite_manager/ut_suite_manager.get_schema_ut_packages.IncludesPackagesWithSutePath.sql @@lib/RunTest.sql ut_suite_manager/ut_suite_manager.IncludesInvalidPackageBodiesInTheRun.sql -@@lib/RunTest.sql ut_suite_manager/ut_suite_manager.CacheInvalidaesOnPackageDrop.sql @@lib/RunTest.sql ut_suite_manager/ut_suite_manager.PackageWithDollarSign.sql @@lib/RunTest.sql ut_suite_manager/ut_suite_manager.PackageWithHash.sql @@lib/RunTest.sql ut_suite_manager/ut_suite_manager.TestWithDollarSign.sql @@lib/RunTest.sql ut_suite_manager/ut_suite_manager.TestWithHashSign.sql -@@lib/RunTest.sql ut_test/ut_test.OwnerNameInvalid.sql -@@lib/RunTest.sql ut_test/ut_test.OwnerNameNull.sql -@@lib/RunTest.sql ut_test/ut_test.PackageInInvalidState.sql -@@lib/RunTest.sql ut_test/ut_test.PackageNameInvalid.sql -@@lib/RunTest.sql ut_test/ut_test.PackageNameNull.sql -@@lib/RunTest.sql ut_test/ut_test.ProcedureNameInvalid.sql -@@lib/RunTest.sql ut_test/ut_test.ProcedureNameNull.sql -@@lib/RunTest.sql ut_test/ut_test.SetupExecutedBeforeTest.sql -@@lib/RunTest.sql ut_test/ut_test.SetupProcedureNameInvalid.sql -@@lib/RunTest.sql ut_test/ut_test.SetupProcedureNameNull.sql -@@lib/RunTest.sql ut_test/ut_test.TeardownExecutedAfterTest.sql -@@lib/RunTest.sql ut_test/ut_test.TeardownProcedureNameInvalid.sql -@@lib/RunTest.sql ut_test/ut_test.TeardownProcedureNameNull.sql -@@lib/RunTest.sql ut_test/ut_test.IgnoreTollbackToSavepointException.sql -@@lib/RunTest.sql ut_test/ut_test.AfterEachExecuted.sql -@@lib/RunTest.sql ut_test/ut_test.AfterEachProcedureNameInvalid.sql -@@lib/RunTest.sql ut_test/ut_test.AfterEachProcedureNameNull.sql -@@lib/RunTest.sql ut_test/ut_test.BeforeEachExecuted.sql -@@lib/RunTest.sql ut_test/ut_test.BeforeEachProcedureNameInvalid.sql -@@lib/RunTest.sql ut_test/ut_test.BeforeEachProcedureNameNull.sql -@@lib/RunTest.sql ut_test/ut_test.TestOutputGathering.sql -@@lib/RunTest.sql ut_test/ut_test.TestOutputGatheringWhenEmpty.sql -@@lib/RunTest.sql ut_test/ut_test.ReportWarningOnRollbackFailed.sql -@@lib/RunTest.sql ut_test/ut_test.ApplicationInfoOnExecution.sql - @@ut_utils/ut_utils.clob_to_table.sql @@ut_utils/ut_utils.table_to_clob.sql @@lib/RunTest.sql ut_utils/ut_utils.append_to_clob.worksWithMultiByteChars.sql @@ -110,309 +83,309 @@ drop type utplsql_test_reporter; drop package test_reporters; drop package ut3$user#.html_coverage_test; -set timing on -prompt Generating coverage data to reporter outputs - -var html_reporter_id varchar2(32); -var sonar_reporter_id varchar2(32); -var coveralls_reporter_id varchar2(32); -declare - l_reporter ut_reporter_base; - l_project_file_list ut_varchar2_list; - l_test_run ut_run; -begin - l_project_file_list := ut_varchar2_list( - 'source/api', - 'source/core', - 'source/create_synonyms_and_grants_for_public.sql', - 'source/create_synonyms_and_grants_for_user.sql', - 'source/create_utplsql_owner.sql', - 'source/expectations', - 'source/install.log', - 'source/install.sql', - 'source/install_headless.sql', - 'source/license.txt', - 'source/readme.md', - 'source/reporters', - 'source/uninstall.log', - 'source/uninstall.sql', - 'source/api/be_between.syn', - 'source/api/be_empty.syn', - 'source/api/be_false.syn', - 'source/api/be_greater_or_equal.syn', - 'source/api/be_greater_than.syn', - 'source/api/be_less_or_equal.syn', - 'source/api/be_less_than.syn', - 'source/api/be_like.syn', - 'source/api/be_not_null.syn', - 'source/api/be_null.syn', - 'source/api/be_true.syn', - 'source/api/equal.syn', - 'source/api/match.syn', - 'source/api/ut.pkb', - 'source/api/ut.pks', - 'source/api/ut_runner.pkb', - 'source/api/ut_runner.pks', - 'source/core/coverage', - 'source/core/output_buffers', - 'source/core/types', - 'source/core/annotations/ut_annotation_manager.pkb', - 'source/core/annotations/ut_annotation_manager.pks', - 'source/core/annotations/ut_annotation_parser.pkb', - 'source/core/annotations/ut_annotation_parser.pks', - 'source/core/annotations/ut_annotation_cache_manager.pkb', - 'source/core/annotations/ut_annotation_cache_manager.pks', - 'source/core/ut_expectation_processor.pkb', - 'source/core/ut_expectation_processor.pks', - 'source/core/ut_file_mapper.pkb', - 'source/core/ut_file_mapper.pks', - 'source/core/ut_metadata.pkb', - 'source/core/ut_metadata.pks', - 'source/core/ut_suite_manager.pkb', - 'source/core/ut_suite_manager.pks', - 'source/core/ut_utils.pkb', - 'source/core/ut_utils.pks', - 'source/core/coverage/proftab.sql', - 'source/core/coverage/ut_coverage.pkb', - 'source/core/coverage/ut_coverage.pks', - 'source/core/coverage/ut_coverage_helper.pkb', - 'source/core/coverage/ut_coverage_helper.pks', - 'source/core/coverage/ut_coverage_sources_tmp.sql', - 'source/core/coverage/ut_coverage_reporter_base.tpb', - 'source/core/coverage/ut_coverage_reporter_base.tps', - 'source/core/output_buffers/ut_message_id_seq.sql', - 'source/core/output_buffers/ut_output_buffer_base.tps', - 'source/core/output_buffers/ut_output_buffer_info_tmp.sql', - 'source/core/output_buffers/ut_output_buffer_tmp.sql', - 'source/core/output_buffers/ut_output_table_buffer.tpb', - 'source/core/output_buffers/ut_output_table_buffer.tps', - 'source/core/types/ut_console_reporter_base.tpb', - 'source/core/types/ut_console_reporter_base.tps', - 'source/core/types/ut_coverage_options.tps', - 'source/core/types/ut_event_listener.tpb', - 'source/core/types/ut_event_listener.tps', - 'source/core/types/ut_event_listener_base.tps', - 'source/core/types/ut_executable.tpb', - 'source/core/types/ut_executable.tps', - 'source/core/types/ut_expectation_result.tpb', - 'source/core/types/ut_expectation_result.tps', - 'source/core/types/ut_expectation_results.tps', - 'source/core/types/ut_file_mapping.tpb', - 'source/core/types/ut_file_mapping.tps', - 'source/core/types/ut_file_mappings.tps', - 'source/core/types/ut_key_value_pair.tps', - 'source/core/types/ut_key_value_pairs.tps', - 'source/core/types/ut_logical_suite.tpb', - 'source/core/types/ut_logical_suite.tps', - 'source/core/types/ut_object_name.tpb', - 'source/core/types/ut_object_name.tps', - 'source/core/types/ut_object_names.tps', - 'source/core/types/ut_output_reporter_base.tpb', - 'source/core/types/ut_output_reporter_base.tps', - 'source/core/types/ut_reporters.tps', - 'source/core/types/ut_reporter_base.tpb', - 'source/core/types/ut_reporter_base.tps', - 'source/core/types/ut_results_counter.tpb', - 'source/core/types/ut_results_counter.tps', - 'source/core/types/ut_run.tpb', - 'source/core/types/ut_run.tps', - 'source/core/types/ut_suite.tpb', - 'source/core/types/ut_suite.tps', - 'source/core/types/ut_suite_item.tpb', - 'source/core/types/ut_suite_item.tps', - 'source/core/types/ut_suite_items.tps', - 'source/core/types/ut_test.tpb', - 'source/core/types/ut_test.tps', - 'source/core/types/ut_varchar2_list.tps', - 'source/core/types/ut_varchar2_rows.tps', - 'source/expectations/data_values', - 'source/expectations/matchers', - 'source/expectations/ut_expectation.tpb', - 'source/expectations/ut_expectation.tps', - 'source/expectations/ut_expectation_anydata.tpb', - 'source/expectations/ut_expectation_anydata.tps', - 'source/expectations/ut_expectation_blob.tpb', - 'source/expectations/ut_expectation_blob.tps', - 'source/expectations/ut_expectation_boolean.tpb', - 'source/expectations/ut_expectation_boolean.tps', - 'source/expectations/ut_expectation_clob.tpb', - 'source/expectations/ut_expectation_clob.tps', - 'source/expectations/ut_expectation_date.tpb', - 'source/expectations/ut_expectation_date.tps', - 'source/expectations/ut_expectation_dsinterval.tpb', - 'source/expectations/ut_expectation_dsinterval.tps', - 'source/expectations/ut_expectation_number.tpb', - 'source/expectations/ut_expectation_number.tps', - 'source/expectations/ut_expectation_refcursor.tpb', - 'source/expectations/ut_expectation_refcursor.tps', - 'source/expectations/ut_expectation_timestamp.tpb', - 'source/expectations/ut_expectation_timestamp.tps', - 'source/expectations/ut_expectation_timestamp_ltz.tpb', - 'source/expectations/ut_expectation_timestamp_ltz.tps', - 'source/expectations/ut_expectation_timestamp_tz.tpb', - 'source/expectations/ut_expectation_timestamp_tz.tps', - 'source/expectations/ut_expectation_varchar2.tpb', - 'source/expectations/ut_expectation_varchar2.tps', - 'source/expectations/ut_expectation_yminterval.tpb', - 'source/expectations/ut_expectation_yminterval.tps', - 'source/expectations/data_values/ut_cursor_data.sql', - 'source/expectations/data_values/ut_data_value.tpb', - 'source/expectations/data_values/ut_data_value.tps', - 'source/expectations/data_values/ut_data_value_anydata.tpb', - 'source/expectations/data_values/ut_data_value_anydata.tps', - 'source/expectations/data_values/ut_data_value_blob.tpb', - 'source/expectations/data_values/ut_data_value_blob.tps', - 'source/expectations/data_values/ut_data_value_boolean.tpb', - 'source/expectations/data_values/ut_data_value_boolean.tps', - 'source/expectations/data_values/ut_data_value_clob.tpb', - 'source/expectations/data_values/ut_data_value_clob.tps', - 'source/expectations/data_values/ut_data_value_collection.tpb', - 'source/expectations/data_values/ut_data_value_collection.tps', - 'source/expectations/data_values/ut_data_value_date.tpb', - 'source/expectations/data_values/ut_data_value_date.tps', - 'source/expectations/data_values/ut_data_value_dsinterval.tpb', - 'source/expectations/data_values/ut_data_value_dsinterval.tps', - 'source/expectations/data_values/ut_data_value_number.tpb', - 'source/expectations/data_values/ut_data_value_number.tps', - 'source/expectations/data_values/ut_data_value_object.tpb', - 'source/expectations/data_values/ut_data_value_object.tps', - 'source/expectations/data_values/ut_data_value_refcursor.tpb', - 'source/expectations/data_values/ut_data_value_refcursor.tps', - 'source/expectations/data_values/ut_data_value_timestamp.tpb', - 'source/expectations/data_values/ut_data_value_timestamp.tps', - 'source/expectations/data_values/ut_data_value_timestamp_ltz.tpb', - 'source/expectations/data_values/ut_data_value_timestamp_ltz.tps', - 'source/expectations/data_values/ut_data_value_timestamp_tz.tpb', - 'source/expectations/data_values/ut_data_value_timestamp_tz.tps', - 'source/expectations/data_values/ut_data_value_varchar2.tpb', - 'source/expectations/data_values/ut_data_value_varchar2.tps', - 'source/expectations/data_values/ut_data_value_yminterval.tpb', - 'source/expectations/data_values/ut_data_value_yminterval.tps', - 'source/expectations/matchers/ut_be_between.tpb', - 'source/expectations/matchers/ut_be_between.tps', - 'source/expectations/matchers/ut_be_empty.tpb', - 'source/expectations/matchers/ut_be_empty.tps', - 'source/expectations/matchers/ut_be_false.tpb', - 'source/expectations/matchers/ut_be_false.tps', - 'source/expectations/matchers/ut_be_greater_or_equal.tpb', - 'source/expectations/matchers/ut_be_greater_or_equal.tps', - 'source/expectations/matchers/ut_be_greater_than.tpb', - 'source/expectations/matchers/ut_be_greater_than.tps', - 'source/expectations/matchers/ut_be_less_or_equal.tpb', - 'source/expectations/matchers/ut_be_less_or_equal.tps', - 'source/expectations/matchers/ut_be_less_than.tpb', - 'source/expectations/matchers/ut_be_less_than.tps', - 'source/expectations/matchers/ut_be_like.tpb', - 'source/expectations/matchers/ut_be_like.tps', - 'source/expectations/matchers/ut_be_not_null.tpb', - 'source/expectations/matchers/ut_be_not_null.tps', - 'source/expectations/matchers/ut_be_null.tpb', - 'source/expectations/matchers/ut_be_null.tps', - 'source/expectations/matchers/ut_be_true.tpb', - 'source/expectations/matchers/ut_be_true.tps', - 'source/expectations/matchers/ut_equal.tpb', - 'source/expectations/matchers/ut_equal.tps', - 'source/expectations/matchers/ut_match.tpb', - 'source/expectations/matchers/ut_match.tps', - 'source/expectations/matchers/ut_matcher.tpb', - 'source/expectations/matchers/ut_matcher.tps', - 'source/expectations/matchers/ut_comparison_matcher.tpb', - 'source/expectations/matchers/ut_comparison_matcher.tps', - 'source/reporters/ut_ansiconsole_helper.pkb', - 'source/reporters/ut_ansiconsole_helper.pks', - 'source/reporters/ut_coverage_html_reporter.tpb', - 'source/reporters/ut_coverage_html_reporter.tps', - 'source/reporters/ut_coverage_report_html_helper.pkb', - 'source/reporters/ut_coverage_report_html_helper.pks', - 'source/reporters/ut_coveralls_reporter.tpb', - 'source/reporters/ut_coveralls_reporter.tps', - 'source/reporters/ut_coverage_sonar_reporter.tpb', - 'source/reporters/ut_coverage_sonar_reporter.tps', - 'source/reporters/ut_documentation_reporter.tpb', - 'source/reporters/ut_documentation_reporter.tps', - 'source/reporters/ut_sonar_test_reporter.tpb', - 'source/reporters/ut_sonar_test_reporter.tps', - 'source/reporters/ut_teamcity_reporter.tpb', - 'source/reporters/ut_teamcity_reporter.tps', - 'source/reporters/ut_teamcity_reporter_helper.pkb', - 'source/reporters/ut_teamcity_reporter_helper.pks'); - - l_test_run := ut_run(a_items => ut_suite_items(), a_project_file_mappings => ut_file_mapper.build_file_mappings( user,l_project_file_list)); - - --run for the first time to gather coverage and timings on reporters too - l_reporter := ut_coverage_html_reporter(a_project_name => 'utPLSQL v3'); - l_reporter.after_calling_run(l_test_run); - l_reporter.on_finalize(l_test_run); - - l_reporter := ut_coverage_sonar_reporter(); - l_reporter.after_calling_run(l_test_run); - l_reporter.on_finalize(l_test_run); - - l_reporter := ut_coveralls_reporter(); - l_reporter.after_calling_run(l_test_run); - l_reporter.on_finalize(l_test_run); - - ut_coverage.set_develop_mode(false); - ut_coverage.coverage_stop(); - - --run for the second time to get the coverage report - l_reporter := ut_coverage_html_reporter(a_project_name => 'utPLSQL v3'); - l_reporter.after_calling_run(l_test_run); - l_reporter.on_finalize(l_test_run); - :html_reporter_id := l_reporter.get_reporter_id; - - l_reporter := ut_coverage_sonar_reporter(); - l_reporter.after_calling_run(l_test_run); - l_reporter.on_finalize(l_test_run); - :sonar_reporter_id := l_reporter.get_reporter_id; - - l_reporter := ut_coveralls_reporter(); - l_reporter.after_calling_run(l_test_run); - l_reporter.on_finalize(l_test_run); - :coveralls_reporter_id := l_reporter.get_reporter_id; -end; -/ - -set timing off -prompt Spooling outcomes to coverage.xml -set termout off -set feedback off -set arraysize 50 -spool coverage.xml -declare - l_reporter ut_output_reporter_base := ut_coverage_sonar_reporter(); -begin - l_reporter.set_reporter_id(:sonar_reporter_id); - l_reporter.lines_to_dbms_output(a_initial_timeout=>1, a_timeout_sec=>1); -end; -/ -spool off - -set termout on -prompt Spooling outcomes to coverage.json -set termout off -spool coverage.json -declare - l_reporter ut_output_reporter_base := ut_coveralls_reporter(); -begin - l_reporter.set_reporter_id(:coveralls_reporter_id); - l_reporter.lines_to_dbms_output(a_initial_timeout=>1, a_timeout_sec=>1); -end; -/ -spool off - -set termout on -prompt Spooling outcomes to coverage.html -set termout off -spool coverage.html -declare - l_reporter ut_output_reporter_base := ut_coverage_html_reporter(); -begin - l_reporter.set_reporter_id(:html_reporter_id); - l_reporter.lines_to_dbms_output(a_initial_timeout=>1, a_timeout_sec=>1); -end; -/ -spool off +-- set timing on +-- prompt Generating coverage data to reporter outputs +-- +-- var html_reporter_id varchar2(32); +-- var sonar_reporter_id varchar2(32); +-- var coveralls_reporter_id varchar2(32); +-- declare +-- l_reporter ut_reporter_base; +-- l_project_file_list ut_varchar2_list; +-- l_test_run ut_run; +-- begin +-- l_project_file_list := ut_varchar2_list( +-- 'source/api', +-- 'source/core', +-- 'source/create_synonyms_and_grants_for_public.sql', +-- 'source/create_synonyms_and_grants_for_user.sql', +-- 'source/create_utplsql_owner.sql', +-- 'source/expectations', +-- 'source/install.log', +-- 'source/install.sql', +-- 'source/install_headless.sql', +-- 'source/license.txt', +-- 'source/readme.md', +-- 'source/reporters', +-- 'source/uninstall.log', +-- 'source/uninstall.sql', +-- 'source/api/be_between.syn', +-- 'source/api/be_empty.syn', +-- 'source/api/be_false.syn', +-- 'source/api/be_greater_or_equal.syn', +-- 'source/api/be_greater_than.syn', +-- 'source/api/be_less_or_equal.syn', +-- 'source/api/be_less_than.syn', +-- 'source/api/be_like.syn', +-- 'source/api/be_not_null.syn', +-- 'source/api/be_null.syn', +-- 'source/api/be_true.syn', +-- 'source/api/equal.syn', +-- 'source/api/match.syn', +-- 'source/api/ut.pkb', +-- 'source/api/ut.pks', +-- 'source/api/ut_runner.pkb', +-- 'source/api/ut_runner.pks', +-- 'source/core/coverage', +-- 'source/core/output_buffers', +-- 'source/core/types', +-- 'source/core/annotations/ut_annotation_manager.pkb', +-- 'source/core/annotations/ut_annotation_manager.pks', +-- 'source/core/annotations/ut_annotation_parser.pkb', +-- 'source/core/annotations/ut_annotation_parser.pks', +-- 'source/core/annotations/ut_annotation_cache_manager.pkb', +-- 'source/core/annotations/ut_annotation_cache_manager.pks', +-- 'source/core/ut_expectation_processor.pkb', +-- 'source/core/ut_expectation_processor.pks', +-- 'source/core/ut_file_mapper.pkb', +-- 'source/core/ut_file_mapper.pks', +-- 'source/core/ut_metadata.pkb', +-- 'source/core/ut_metadata.pks', +-- 'source/core/ut_suite_manager.pkb', +-- 'source/core/ut_suite_manager.pks', +-- 'source/core/ut_utils.pkb', +-- 'source/core/ut_utils.pks', +-- 'source/core/coverage/proftab.sql', +-- 'source/core/coverage/ut_coverage.pkb', +-- 'source/core/coverage/ut_coverage.pks', +-- 'source/core/coverage/ut_coverage_helper.pkb', +-- 'source/core/coverage/ut_coverage_helper.pks', +-- 'source/core/coverage/ut_coverage_sources_tmp.sql', +-- 'source/core/coverage/ut_coverage_reporter_base.tpb', +-- 'source/core/coverage/ut_coverage_reporter_base.tps', +-- 'source/core/output_buffers/ut_message_id_seq.sql', +-- 'source/core/output_buffers/ut_output_buffer_base.tps', +-- 'source/core/output_buffers/ut_output_buffer_info_tmp.sql', +-- 'source/core/output_buffers/ut_output_buffer_tmp.sql', +-- 'source/core/output_buffers/ut_output_table_buffer.tpb', +-- 'source/core/output_buffers/ut_output_table_buffer.tps', +-- 'source/core/types/ut_console_reporter_base.tpb', +-- 'source/core/types/ut_console_reporter_base.tps', +-- 'source/core/types/ut_coverage_options.tps', +-- 'source/core/types/ut_event_listener.tpb', +-- 'source/core/types/ut_event_listener.tps', +-- 'source/core/types/ut_event_listener_base.tps', +-- 'source/core/types/ut_executable.tpb', +-- 'source/core/types/ut_executable.tps', +-- 'source/core/types/ut_expectation_result.tpb', +-- 'source/core/types/ut_expectation_result.tps', +-- 'source/core/types/ut_expectation_results.tps', +-- 'source/core/types/ut_file_mapping.tpb', +-- 'source/core/types/ut_file_mapping.tps', +-- 'source/core/types/ut_file_mappings.tps', +-- 'source/core/types/ut_key_value_pair.tps', +-- 'source/core/types/ut_key_value_pairs.tps', +-- 'source/core/types/ut_logical_suite.tpb', +-- 'source/core/types/ut_logical_suite.tps', +-- 'source/core/types/ut_object_name.tpb', +-- 'source/core/types/ut_object_name.tps', +-- 'source/core/types/ut_object_names.tps', +-- 'source/core/types/ut_output_reporter_base.tpb', +-- 'source/core/types/ut_output_reporter_base.tps', +-- 'source/core/types/ut_reporters.tps', +-- 'source/core/types/ut_reporter_base.tpb', +-- 'source/core/types/ut_reporter_base.tps', +-- 'source/core/types/ut_results_counter.tpb', +-- 'source/core/types/ut_results_counter.tps', +-- 'source/core/types/ut_run.tpb', +-- 'source/core/types/ut_run.tps', +-- 'source/core/types/ut_suite.tpb', +-- 'source/core/types/ut_suite.tps', +-- 'source/core/types/ut_suite_item.tpb', +-- 'source/core/types/ut_suite_item.tps', +-- 'source/core/types/ut_suite_items.tps', +-- 'source/core/types/ut_test.tpb', +-- 'source/core/types/ut_test.tps', +-- 'source/core/types/ut_varchar2_list.tps', +-- 'source/core/types/ut_varchar2_rows.tps', +-- 'source/expectations/data_values', +-- 'source/expectations/matchers', +-- 'source/expectations/ut_expectation.tpb', +-- 'source/expectations/ut_expectation.tps', +-- 'source/expectations/ut_expectation_anydata.tpb', +-- 'source/expectations/ut_expectation_anydata.tps', +-- 'source/expectations/ut_expectation_blob.tpb', +-- 'source/expectations/ut_expectation_blob.tps', +-- 'source/expectations/ut_expectation_boolean.tpb', +-- 'source/expectations/ut_expectation_boolean.tps', +-- 'source/expectations/ut_expectation_clob.tpb', +-- 'source/expectations/ut_expectation_clob.tps', +-- 'source/expectations/ut_expectation_date.tpb', +-- 'source/expectations/ut_expectation_date.tps', +-- 'source/expectations/ut_expectation_dsinterval.tpb', +-- 'source/expectations/ut_expectation_dsinterval.tps', +-- 'source/expectations/ut_expectation_number.tpb', +-- 'source/expectations/ut_expectation_number.tps', +-- 'source/expectations/ut_expectation_refcursor.tpb', +-- 'source/expectations/ut_expectation_refcursor.tps', +-- 'source/expectations/ut_expectation_timestamp.tpb', +-- 'source/expectations/ut_expectation_timestamp.tps', +-- 'source/expectations/ut_expectation_timestamp_ltz.tpb', +-- 'source/expectations/ut_expectation_timestamp_ltz.tps', +-- 'source/expectations/ut_expectation_timestamp_tz.tpb', +-- 'source/expectations/ut_expectation_timestamp_tz.tps', +-- 'source/expectations/ut_expectation_varchar2.tpb', +-- 'source/expectations/ut_expectation_varchar2.tps', +-- 'source/expectations/ut_expectation_yminterval.tpb', +-- 'source/expectations/ut_expectation_yminterval.tps', +-- 'source/expectations/data_values/ut_cursor_data.sql', +-- 'source/expectations/data_values/ut_data_value.tpb', +-- 'source/expectations/data_values/ut_data_value.tps', +-- 'source/expectations/data_values/ut_data_value_anydata.tpb', +-- 'source/expectations/data_values/ut_data_value_anydata.tps', +-- 'source/expectations/data_values/ut_data_value_blob.tpb', +-- 'source/expectations/data_values/ut_data_value_blob.tps', +-- 'source/expectations/data_values/ut_data_value_boolean.tpb', +-- 'source/expectations/data_values/ut_data_value_boolean.tps', +-- 'source/expectations/data_values/ut_data_value_clob.tpb', +-- 'source/expectations/data_values/ut_data_value_clob.tps', +-- 'source/expectations/data_values/ut_data_value_collection.tpb', +-- 'source/expectations/data_values/ut_data_value_collection.tps', +-- 'source/expectations/data_values/ut_data_value_date.tpb', +-- 'source/expectations/data_values/ut_data_value_date.tps', +-- 'source/expectations/data_values/ut_data_value_dsinterval.tpb', +-- 'source/expectations/data_values/ut_data_value_dsinterval.tps', +-- 'source/expectations/data_values/ut_data_value_number.tpb', +-- 'source/expectations/data_values/ut_data_value_number.tps', +-- 'source/expectations/data_values/ut_data_value_object.tpb', +-- 'source/expectations/data_values/ut_data_value_object.tps', +-- 'source/expectations/data_values/ut_data_value_refcursor.tpb', +-- 'source/expectations/data_values/ut_data_value_refcursor.tps', +-- 'source/expectations/data_values/ut_data_value_timestamp.tpb', +-- 'source/expectations/data_values/ut_data_value_timestamp.tps', +-- 'source/expectations/data_values/ut_data_value_timestamp_ltz.tpb', +-- 'source/expectations/data_values/ut_data_value_timestamp_ltz.tps', +-- 'source/expectations/data_values/ut_data_value_timestamp_tz.tpb', +-- 'source/expectations/data_values/ut_data_value_timestamp_tz.tps', +-- 'source/expectations/data_values/ut_data_value_varchar2.tpb', +-- 'source/expectations/data_values/ut_data_value_varchar2.tps', +-- 'source/expectations/data_values/ut_data_value_yminterval.tpb', +-- 'source/expectations/data_values/ut_data_value_yminterval.tps', +-- 'source/expectations/matchers/ut_be_between.tpb', +-- 'source/expectations/matchers/ut_be_between.tps', +-- 'source/expectations/matchers/ut_be_empty.tpb', +-- 'source/expectations/matchers/ut_be_empty.tps', +-- 'source/expectations/matchers/ut_be_false.tpb', +-- 'source/expectations/matchers/ut_be_false.tps', +-- 'source/expectations/matchers/ut_be_greater_or_equal.tpb', +-- 'source/expectations/matchers/ut_be_greater_or_equal.tps', +-- 'source/expectations/matchers/ut_be_greater_than.tpb', +-- 'source/expectations/matchers/ut_be_greater_than.tps', +-- 'source/expectations/matchers/ut_be_less_or_equal.tpb', +-- 'source/expectations/matchers/ut_be_less_or_equal.tps', +-- 'source/expectations/matchers/ut_be_less_than.tpb', +-- 'source/expectations/matchers/ut_be_less_than.tps', +-- 'source/expectations/matchers/ut_be_like.tpb', +-- 'source/expectations/matchers/ut_be_like.tps', +-- 'source/expectations/matchers/ut_be_not_null.tpb', +-- 'source/expectations/matchers/ut_be_not_null.tps', +-- 'source/expectations/matchers/ut_be_null.tpb', +-- 'source/expectations/matchers/ut_be_null.tps', +-- 'source/expectations/matchers/ut_be_true.tpb', +-- 'source/expectations/matchers/ut_be_true.tps', +-- 'source/expectations/matchers/ut_equal.tpb', +-- 'source/expectations/matchers/ut_equal.tps', +-- 'source/expectations/matchers/ut_match.tpb', +-- 'source/expectations/matchers/ut_match.tps', +-- 'source/expectations/matchers/ut_matcher.tpb', +-- 'source/expectations/matchers/ut_matcher.tps', +-- 'source/expectations/matchers/ut_comparison_matcher.tpb', +-- 'source/expectations/matchers/ut_comparison_matcher.tps', +-- 'source/reporters/ut_ansiconsole_helper.pkb', +-- 'source/reporters/ut_ansiconsole_helper.pks', +-- 'source/reporters/ut_coverage_html_reporter.tpb', +-- 'source/reporters/ut_coverage_html_reporter.tps', +-- 'source/reporters/ut_coverage_report_html_helper.pkb', +-- 'source/reporters/ut_coverage_report_html_helper.pks', +-- 'source/reporters/ut_coveralls_reporter.tpb', +-- 'source/reporters/ut_coveralls_reporter.tps', +-- 'source/reporters/ut_coverage_sonar_reporter.tpb', +-- 'source/reporters/ut_coverage_sonar_reporter.tps', +-- 'source/reporters/ut_documentation_reporter.tpb', +-- 'source/reporters/ut_documentation_reporter.tps', +-- 'source/reporters/ut_sonar_test_reporter.tpb', +-- 'source/reporters/ut_sonar_test_reporter.tps', +-- 'source/reporters/ut_teamcity_reporter.tpb', +-- 'source/reporters/ut_teamcity_reporter.tps', +-- 'source/reporters/ut_teamcity_reporter_helper.pkb', +-- 'source/reporters/ut_teamcity_reporter_helper.pks'); +-- +-- l_test_run := ut_run(a_items => ut_suite_items(), a_project_file_mappings => ut_file_mapper.build_file_mappings( user,l_project_file_list)); +-- +-- --run for the first time to gather coverage and timings on reporters too +-- l_reporter := ut_coverage_html_reporter(a_project_name => 'utPLSQL v3'); +-- l_reporter.after_calling_run(l_test_run); +-- l_reporter.on_finalize(l_test_run); +-- +-- l_reporter := ut_coverage_sonar_reporter(); +-- l_reporter.after_calling_run(l_test_run); +-- l_reporter.on_finalize(l_test_run); +-- +-- l_reporter := ut_coveralls_reporter(); +-- l_reporter.after_calling_run(l_test_run); +-- l_reporter.on_finalize(l_test_run); +-- +-- ut_coverage.set_develop_mode(false); +-- ut_coverage.coverage_stop(); +-- +-- --run for the second time to get the coverage report +-- l_reporter := ut_coverage_html_reporter(a_project_name => 'utPLSQL v3'); +-- l_reporter.after_calling_run(l_test_run); +-- l_reporter.on_finalize(l_test_run); +-- :html_reporter_id := l_reporter.get_reporter_id; +-- +-- l_reporter := ut_coverage_sonar_reporter(); +-- l_reporter.after_calling_run(l_test_run); +-- l_reporter.on_finalize(l_test_run); +-- :sonar_reporter_id := l_reporter.get_reporter_id; +-- +-- l_reporter := ut_coveralls_reporter(); +-- l_reporter.after_calling_run(l_test_run); +-- l_reporter.on_finalize(l_test_run); +-- :coveralls_reporter_id := l_reporter.get_reporter_id; +-- end; +-- / +-- +-- set timing off +-- prompt Spooling outcomes to coverage.xml +-- set termout off +-- set feedback off +-- set arraysize 50 +-- spool coverage.xml +-- declare +-- l_reporter ut_output_reporter_base := ut_coverage_sonar_reporter(); +-- begin +-- l_reporter.set_reporter_id(:sonar_reporter_id); +-- l_reporter.lines_to_dbms_output(a_initial_timeout=>1, a_timeout_sec=>1); +-- end; +-- / +-- spool off +-- +-- set termout on +-- prompt Spooling outcomes to coverage.json +-- set termout off +-- spool coverage.json +-- declare +-- l_reporter ut_output_reporter_base := ut_coveralls_reporter(); +-- begin +-- l_reporter.set_reporter_id(:coveralls_reporter_id); +-- l_reporter.lines_to_dbms_output(a_initial_timeout=>1, a_timeout_sec=>1); +-- end; +-- / +-- spool off +-- +-- set termout on +-- prompt Spooling outcomes to coverage.html +-- set termout off +-- spool coverage.html +-- declare +-- l_reporter ut_output_reporter_base := ut_coverage_html_reporter(); +-- begin +-- l_reporter.set_reporter_id(:html_reporter_id); +-- l_reporter.lines_to_dbms_output(a_initial_timeout=>1, a_timeout_sec=>1); +-- end; +-- / +-- spool off set termout on spool stats.log diff --git a/old_tests/ut_suite_manager/ut_suite_manager.CacheInvalidaesOnPackageDrop.sql b/old_tests/ut_suite_manager/ut_suite_manager.CacheInvalidaesOnPackageDrop.sql deleted file mode 100644 index 9715eae8b..000000000 --- a/old_tests/ut_suite_manager/ut_suite_manager.CacheInvalidaesOnPackageDrop.sql +++ /dev/null @@ -1,50 +0,0 @@ -set termout off -create or replace package tst_package_to_be_dropped as - --%suite - - --%test - procedure test1; -end; -/ - -create or replace package body tst_package_to_be_dropped as - procedure test1 is begin ut.expect(1).to_equal(1); end; - procedure test2 is begin ut.expect(1).to_equal(1); end; -end; -/ - -set termout on - -declare - l_test_report ut_varchar2_list; -begin - select * bulk collect into l_test_report from table(ut.run(USER||'.tst_package_to_be_dropped')); -end; -/ - -set termout off -drop package tst_package_to_be_dropped -/ -set termout on - -declare - l_test_report ut_varchar2_list; - l_error_message varchar2(4000); - l_expected varchar2(4000); -begin - l_expected := '%tst_package_to_be_dropped%does not exist%'; - begin - select * bulk collect into l_test_report from table(ut.run(user || '.tst_package_to_be_dropped')); - exception - when others then - l_error_message := sqlerrm; - if l_error_message like l_expected then - :test_result := ut_utils.gc_success; - end if; - end; - if :test_result != ut_utils.gc_success or :test_result is null then - dbms_output.put_line('Failed: Expected exception with text like '''||l_expected||''' but got:''' || - l_error_message || ''''); - end if; -end; -/ diff --git a/old_tests/ut_suite_manager/ut_suite_manager.emptySuitePath.sql b/old_tests/ut_suite_manager/ut_suite_manager.emptySuitePath.sql deleted file mode 100644 index a957f7873..000000000 --- a/old_tests/ut_suite_manager/ut_suite_manager.emptySuitePath.sql +++ /dev/null @@ -1,41 +0,0 @@ -set termout off -create or replace package tst_empty_suite_path as - --%suite - --%suitepath - - --%test - procedure test1; -end; -/ - -create or replace package body tst_empty_suite_path as - procedure test1 is begin ut.expect(1).to_equal(1); end; -end; -/ - -set termout on - -declare - l_objects_to_run ut_suite_items; - l_suite ut_suite; -begin - - --act - l_objects_to_run := ut_suite_manager.configure_execution_by_path(ut_varchar2_list('tst_empty_suite_path')); - - --Assert - ut.expect(l_objects_to_run.count).to_equal(1); - - l_suite := treat(l_objects_to_run(1) as ut_suite); - - ut.expect(l_suite.name).to_equal('tst_empty_suite_path'); - - if ut_expectation_processor.get_status = ut_utils.gc_success then - :test_result := ut_utils.gc_success; - end if; - -end; -/ - -drop package tst_empty_suite_path -/ diff --git a/old_tests/ut_test/ut_test.AfterEachExecuted.sql b/old_tests/ut_test/ut_test.AfterEachExecuted.sql deleted file mode 100644 index 5711c38e9..000000000 --- a/old_tests/ut_test/ut_test.AfterEachExecuted.sql +++ /dev/null @@ -1,20 +0,0 @@ -PROMPT Invoke aftereach procedure - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null - ); -begin - simple_test.after_each_list := ut_executables(ut_executable(user, 'ut_example_tests', 'aftereach', ut_utils.gc_after_each)); ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_success and ut_example_tests.g_char2 = 'F' then - :test_result := ut_utils.gc_success; - end if; -end; -/ - diff --git a/old_tests/ut_test/ut_test.AfterEachProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.AfterEachProcedureNameInvalid.sql deleted file mode 100644 index 15765a811..000000000 --- a/old_tests/ut_test/ut_test.AfterEachProcedureNameInvalid.sql +++ /dev/null @@ -1,21 +0,0 @@ -PROMPT Does not execute test and reports error when test aftereach procedure name for a test is invalid - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_exampletest', - a_line_no => null - ); -begin - simple_test.after_each_list := ut_executables(ut_executable(user, 'ut_example_tests', 'invalid setup name', ut_utils.gc_after_each)); - ut_example_tests.g_char := 'x'; - ut_example_tests.g_char2 := 'x'; ---Act - simple_test.do_execute(); ---Assert - if ut_example_tests.g_char2 = 'x' and simple_test.result = ut_utils.gc_error then - :test_result := ut_utils.gc_success; - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.AfterEachProcedureNameNull.sql b/old_tests/ut_test/ut_test.AfterEachProcedureNameNull.sql deleted file mode 100644 index f40ee8c04..000000000 --- a/old_tests/ut_test/ut_test.AfterEachProcedureNameNull.sql +++ /dev/null @@ -1,21 +0,0 @@ -PROMPT Does not invoke aftereach procedure when aftereach procedure name for a test is null - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null - ); -begin - simple_test.after_each_list := ut_executables(ut_executable(user, 'ut_example_tests', '', ut_utils.gc_after_each)); ---Act - simple_test.do_execute(); ---Assert - if ut_example_tests.g_char2 = 'a' then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('expected: ut_example_tests.g_char = ''a'', got: '||ut_example_tests.g_char2 ); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.ApplicationInfoOnExecution.sql b/old_tests/ut_test/ut_test.ApplicationInfoOnExecution.sql deleted file mode 100644 index 1ffa7fc11..000000000 --- a/old_tests/ut_test/ut_test.ApplicationInfoOnExecution.sql +++ /dev/null @@ -1,149 +0,0 @@ -create or replace package ut_output_tests -as - --%suite - - gv_before_all_client_info varchar2(200); - gv_before_each_client_info varchar2(200); - gv_before_test_client_info varchar2(200); - gv_after_test_client_info varchar2(200); - gv_after_each_client_info varchar2(200); - gv_after_all_client_info varchar2(200); - - --%test - --%beforetest(before_test) - --%aftertest(after_test) - procedure the_test; - - --%beforeall - procedure beforeall; - - --%beforeeach - procedure beforeeach; - - procedure before_test; - procedure after_test; - - --%aftereach - procedure aftereach; - - --%afterall - procedure afterall; - -end; -/ - -create or replace package body ut_output_tests -as - - procedure the_test - as - l_module_name varchar2(4000); - l_action_name varchar2(4000); - l_client_info varchar2(4000); - begin - --Generate empty output - dbms_output.put_line(''); - ut.expect(1,'Test 1 Should Pass').to_equal(1); - dbms_application_info.read_module(module_name => l_module_name, action_name => l_action_name); - dbms_application_info.read_client_info(l_client_info); - ut.expect(l_module_name).to_equal('utPLSQL'); - ut.expect(l_action_name).to_be_like('ut_output_tests'); - ut.expect(l_client_info).to_be_like('the_test'); - end; - - procedure beforeall is - begin - dbms_application_info.read_client_info(gv_before_all_client_info); - end; - - procedure beforeeach is - begin - dbms_application_info.read_client_info(gv_before_each_client_info); - end; - - procedure before_test is - begin - dbms_application_info.read_client_info(gv_before_test_client_info); - end; - procedure after_test is - begin - dbms_application_info.read_client_info(gv_after_test_client_info); - end; - - procedure aftereach is - begin - dbms_application_info.read_client_info(gv_after_each_client_info); - end; - - procedure afterall is - begin - dbms_application_info.read_client_info(gv_after_all_client_info); - end; - -end; -/ - -declare - l_output_data dbms_output.chararr; - l_num_lines integer := 100000; - l_output clob; - l_result boolean := true; - l_client_info varchar2(4000); -begin - --act - ut.run('ut_output_tests'); - - --assert - dbms_output.get_lines( l_output_data, l_num_lines); - dbms_lob.createtemporary(l_output,true); - for i in 1 .. l_num_lines loop - dbms_lob.append(l_output,l_output_data(i)); - end loop; - - execute immediate 'begin :i := ut_output_tests.gv_before_all_client_info; end;' using out l_client_info; - if not nvl(l_client_info = 'beforeall', false) then - dbms_output.put_line('Wrong before all text: '||l_client_info); - l_result := false; - end if; - execute immediate 'begin :i := ut_output_tests.gv_before_each_client_info; end;' using out l_client_info; - if not nvl(l_client_info = 'beforeeach', false) then - dbms_output.put_line('Wrong before each text: '||l_client_info); - l_result := false; - end if; - execute immediate 'begin :i := ut_output_tests.gv_before_test_client_info; end;' using out l_client_info; - if not nvl(l_client_info = 'before_test', false) then - dbms_output.put_line('Wrong before test text: '||l_client_info); - l_result := false; - end if; - execute immediate 'begin :i := ut_output_tests.gv_after_test_client_info; end;' using out l_client_info; - if not nvl(l_client_info = 'after_test', false) then - dbms_output.put_line('Wrong after test text: '||l_client_info); - l_result := false; - end if; - execute immediate 'begin :i := ut_output_tests.gv_after_each_client_info; end;' using out l_client_info; - if not nvl(l_client_info = 'aftereach', false) then - dbms_output.put_line('Wrong after each text: '||l_client_info); - l_result := false; - end if; - execute immediate 'begin :i := ut_output_tests.gv_after_all_client_info; end;' using out l_client_info; - if not nvl(l_client_info = 'afterall', false) then - dbms_output.put_line('Wrong after all text: '||l_client_info); - l_result := false; - end if; - - if not nvl(l_output like '%0 failed, 0 errored, 0 disabled, 0 warning(s)%',false) then - l_result := false; - for i in 1 .. l_num_lines loop - dbms_output.put_line(l_output_data(i)); - end loop; - dbms_output.put_line('Failed: Wrong output'); - end if; - if l_result then - :test_result := ut_utils.gc_success; - end if; -end; -/ - -drop package ut_output_tests -/ - diff --git a/old_tests/ut_test/ut_test.BeforeEachExecuted.sql b/old_tests/ut_test/ut_test.BeforeEachExecuted.sql deleted file mode 100644 index 9d40441ac..000000000 --- a/old_tests/ut_test/ut_test.BeforeEachExecuted.sql +++ /dev/null @@ -1,21 +0,0 @@ -PROMPT Invoke beforeeach procedure - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null - ); -begin - simple_test.before_each_list := ut_executables(ut_executable(user, 'ut_example_tests', 'beforeeach', ut_utils.gc_before_each)); - ut_example_tests.g_number2 := null; ---Act - simple_test.do_execute(); ---Assert - if ut_example_tests.g_number2 = 1 then - :test_result := ut_utils.gc_success; - end if; -end; -/ - diff --git a/old_tests/ut_test/ut_test.BeforeEachProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.BeforeEachProcedureNameInvalid.sql deleted file mode 100644 index 5a9d40a58..000000000 --- a/old_tests/ut_test/ut_test.BeforeEachProcedureNameInvalid.sql +++ /dev/null @@ -1,20 +0,0 @@ -PROMPT Does not execute test and reports error when test beforeeach procedure name for a test is invalid - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_exampletest', - a_line_no => null - ); -begin - simple_test.before_each_list := ut_executables(ut_executable(user, 'ut_example_tests', 'invalid setup name', ut_utils.gc_before_each)); - ut_example_tests.g_char2 := null; ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_error and ut_example_tests.g_char2 is null then - :test_result := ut_utils.gc_success; - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.BeforeEachProcedureNameNull.sql b/old_tests/ut_test/ut_test.BeforeEachProcedureNameNull.sql deleted file mode 100644 index 66107c462..000000000 --- a/old_tests/ut_test/ut_test.BeforeEachProcedureNameNull.sql +++ /dev/null @@ -1,22 +0,0 @@ -PROMPT Does not invoke setup procedure when beforeeach procedure name for a test is null - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null - ); -begin - simple_test.before_each_list := ut_executables(ut_executable(user, 'ut_example_tests', '', ut_utils.gc_before_each)); - ut_example_tests.g_number2 := null; ---Act - simple_test.do_execute(); ---Assert - if ut_example_tests.g_number2 is null then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('expected: ut_example_tests.g_number is null, got: '||ut_example_tests.g_number2 ); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.IgnoreTollbackToSavepointException.sql b/old_tests/ut_test/ut_test.IgnoreTollbackToSavepointException.sql deleted file mode 100644 index 3e3c1a814..000000000 --- a/old_tests/ut_test/ut_test.IgnoreTollbackToSavepointException.sql +++ /dev/null @@ -1,17 +0,0 @@ -PROMPT Checks that rollback exception does not make run to fail - ---Arrange -declare - simple_test ut_test := ut_test(a_object_name => 'ut_example_tests', a_name => 'ut_commit_test', a_line_no => null); -begin - simple_test.rollback_type := ut_utils.gc_rollback_auto; ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_success then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('simple_test.result = '||ut_utils.test_result_to_char(simple_test.result)); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.OwnerNameInvalid.sql b/old_tests/ut_test/ut_test.OwnerNameInvalid.sql deleted file mode 100644 index 5207af574..000000000 --- a/old_tests/ut_test/ut_test.OwnerNameInvalid.sql +++ /dev/null @@ -1,21 +0,0 @@ -PROMPT Reports error when test owner name for a test is invalid - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_owner => 'invalid owner name', - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null); -begin ---Act - simple_test.do_execute(); - ---Assert - if simple_test.result = ut_utils.gc_error then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('simple_test.result = '||ut_utils.test_result_to_char(simple_test.result)); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.OwnerNameNull.sql b/old_tests/ut_test/ut_test.OwnerNameNull.sql deleted file mode 100644 index f57aebf92..000000000 --- a/old_tests/ut_test/ut_test.OwnerNameNull.sql +++ /dev/null @@ -1,18 +0,0 @@ -PROMPT Executes test in current schema when test owner name for a test is null - ---Arrange -declare - simple_test ut_test:= ut_test( - a_object_owner => null, - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null); -begin ---Act - simple_test.do_execute(); ---Assert - if ut_example_tests.g_char = 'a' then - :test_result := simple_test.result; - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.PackageInInvalidState.sql b/old_tests/ut_test/ut_test.PackageInInvalidState.sql deleted file mode 100644 index 0b87a13d6..000000000 --- a/old_tests/ut_test/ut_test.PackageInInvalidState.sql +++ /dev/null @@ -1,27 +0,0 @@ -set termout off ---Arrange -create or replace package invalid_package is - v_variable non_existing_type; - procedure ut_exampletest; -end; -/ -set termout on - -declare - simple_test ut_test := ut_test(a_object_name => 'invalid_package', a_name => 'ut_exampletest', a_line_no => null); -begin ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_error then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('simple_test.result = '||ut_utils.test_result_to_char(simple_test.result)); - end if; -end; -/ - -set termout off ---Cleanup -drop package invalid_package; -set termout off diff --git a/old_tests/ut_test/ut_test.PackageNameInvalid.sql b/old_tests/ut_test/ut_test.PackageNameInvalid.sql deleted file mode 100644 index b615e7589..000000000 --- a/old_tests/ut_test/ut_test.PackageNameInvalid.sql +++ /dev/null @@ -1,16 +0,0 @@ -PROMPT Reports error when unit test package name for a test is invalid - ---Arrange -declare - simple_test ut_test := ut_test(a_object_name => 'invalid test package name', a_name => 'ut_passing_test', a_line_no => null); -begin ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_error then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('simple_test.result = '||ut_utils.test_result_to_char(simple_test.result)); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.PackageNameNull.sql b/old_tests/ut_test/ut_test.PackageNameNull.sql deleted file mode 100644 index 59612fa3d..000000000 --- a/old_tests/ut_test/ut_test.PackageNameNull.sql +++ /dev/null @@ -1,16 +0,0 @@ -PROMPT Reports error when unit test package name for a test is null - ---Arrange -declare - simple_test ut_test := ut_test(a_object_name => null, a_name => 'ut_passing_test', a_line_no => null); -begin ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_error then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('simple_test.result = '||ut_utils.test_result_to_char(simple_test.result)); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.ProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.ProcedureNameInvalid.sql deleted file mode 100644 index 2a8e80a9e..000000000 --- a/old_tests/ut_test/ut_test.ProcedureNameInvalid.sql +++ /dev/null @@ -1,16 +0,0 @@ -PROMPT Reports error when test procedure name for a test is invalid - ---Arrange -declare - simple_test ut_test := ut_test(a_object_name => 'ut_example_tests' ,a_name => 'invalid procedure name', a_line_no => null); -begin ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_error then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('simple_test.result = '||ut_utils.test_result_to_char(simple_test.result)); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.ProcedureNameNull.sql b/old_tests/ut_test/ut_test.ProcedureNameNull.sql deleted file mode 100644 index df4f0e593..000000000 --- a/old_tests/ut_test/ut_test.ProcedureNameNull.sql +++ /dev/null @@ -1,16 +0,0 @@ -PROMPT Reports error when test procedure name for a test is null - ---Arrange -declare - simple_test ut_test := ut_test(a_object_name => 'ut_example_tests', a_name => null, a_line_no => null); -begin ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_error then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('simple_test.result = '||ut_utils.test_result_to_char(simple_test.result)); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.ReportWarningOnRollbackFailed.sql b/old_tests/ut_test/ut_test.ReportWarningOnRollbackFailed.sql deleted file mode 100644 index 0e54d401c..000000000 --- a/old_tests/ut_test/ut_test.ReportWarningOnRollbackFailed.sql +++ /dev/null @@ -1,58 +0,0 @@ -create or replace package ut_output_test_rollback -as - --%suite - - --%test - procedure tt; - -end; -/ - -create or replace package body ut_output_test_rollback -as - - procedure tt is - begin - commit; - end; - -end; -/ - -declare - l_lines ut_varchar2_list; - l_results clob; -begin - --act - select * bulk collect into l_lines from table(ut.run('ut_output_test_rollback')); - - l_results := ut_utils.table_to_clob(l_lines); - - --assert - if l_results like q'[%Warnings: -% - 1) ut_output_test_rollback.tt - Unable to perform automatic rollback after test. An implicit or explicit commit/rollback occurred in procedures: - ut3.ut_output_test_rollback.tt - Use the "--%rollback(manual)" annotation or remove commit/rollback/ddl statements that are causing the issue. -% - 2) ut_output_test_rollback - Unable to perform automatic rollback after test suite. An implicit or explicit commit/rollback occurred in procedures: - ut3.ut_output_test_rollback.tt - Use the "--%rollback(manual)" annotation or remove commit/rollback/ddl statements that are causing the issue. -% -Finished in % seconds -1 tests, 0 failed, 0 errored, 0 disabled, 2 warning(s)%]' then - :test_result := ut_utils.gc_success; - else - for i in 1 .. l_lines.count loop - dbms_output.put_line(l_lines(i)); - end loop; - dbms_output.put_line('Failed: Wrong output'); - end if; -end; -/ - -drop package ut_output_test_rollback -/ - diff --git a/old_tests/ut_test/ut_test.SetupExecutedBeforeTest.sql b/old_tests/ut_test/ut_test.SetupExecutedBeforeTest.sql deleted file mode 100644 index 2a80cf586..000000000 --- a/old_tests/ut_test/ut_test.SetupExecutedBeforeTest.sql +++ /dev/null @@ -1,21 +0,0 @@ -PROMPT Invoke setup procedure before test when setup procedure name is defined - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null - ); -begin - simple_test.before_test_list := ut_executables(ut_executable(user, 'ut_example_tests', 'setup', ut_utils.gc_before_test)); - ut_example_tests.g_number := null; ---Act - simple_test.do_execute(); ---Assert - if ut_example_tests.g_number = 1 then - :test_result := ut_utils.gc_success; - end if; -end; -/ - diff --git a/old_tests/ut_test/ut_test.SetupProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.SetupProcedureNameInvalid.sql deleted file mode 100644 index d81141031..000000000 --- a/old_tests/ut_test/ut_test.SetupProcedureNameInvalid.sql +++ /dev/null @@ -1,20 +0,0 @@ -PROMPT Does not execute test and reports error when test setup procedure name for a test is invalid - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_exampletest', - a_line_no => null - ); -begin - simple_test.before_test_list := ut_executables(ut_executable(user, 'ut_example_tests', 'invalid setup name', ut_utils.gc_before_test)); - ut_example_tests.g_char := null; ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_error and ut_example_tests.g_char is null then - :test_result := ut_utils.gc_success; - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.SetupProcedureNameNull.sql b/old_tests/ut_test/ut_test.SetupProcedureNameNull.sql deleted file mode 100644 index 9269fdd92..000000000 --- a/old_tests/ut_test/ut_test.SetupProcedureNameNull.sql +++ /dev/null @@ -1,22 +0,0 @@ -PROMPT Does not invoke setup procedure when setup procedure name for a test is null - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null - ); -begin - simple_test.before_test_list := ut_executables(ut_executable(user, 'ut_example_tests', null, ut_utils.gc_before_test)); - ut_example_tests.g_number := null; ---Act - simple_test.do_execute(); ---Assert - if ut_example_tests.g_number is null then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('expected: ut_example_tests.g_number is null, got: '||ut_example_tests.g_number ); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.TeardownExecutedAfterTest.sql b/old_tests/ut_test/ut_test.TeardownExecutedAfterTest.sql deleted file mode 100644 index bc733614b..000000000 --- a/old_tests/ut_test/ut_test.TeardownExecutedAfterTest.sql +++ /dev/null @@ -1,20 +0,0 @@ -PROMPT Invoke teardown procedure after test when teardown procedure name is defined - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null - ); -begin - simple_test.after_test_list := ut_executables(ut_executable(user, 'ut_example_tests', 'teardown', ut_utils.gc_after_test)); ---Act - simple_test.do_execute(); ---Assert - if simple_test.result = ut_utils.gc_success and ut_example_tests.g_char is null then - :test_result := ut_utils.gc_success; - end if; -end; -/ - diff --git a/old_tests/ut_test/ut_test.TeardownProcedureNameInvalid.sql b/old_tests/ut_test/ut_test.TeardownProcedureNameInvalid.sql deleted file mode 100644 index 5ae61cc13..000000000 --- a/old_tests/ut_test/ut_test.TeardownProcedureNameInvalid.sql +++ /dev/null @@ -1,20 +0,0 @@ -PROMPT Does not execute test and reports error when test teardown procedure name for a test is invalid - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_exampletest', - a_line_no => null - ); -begin - simple_test.after_test_list := ut_executables(ut_executable(user, 'ut_example_tests', 'invalid setup name', ut_utils.gc_after_test)); - ut_example_tests.g_char := 'x'; ---Act - simple_test.do_execute(); ---Assert - if ut_example_tests.g_char = 'x' and simple_test.result = ut_utils.gc_error then - :test_result := ut_utils.gc_success; - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.TeardownProcedureNameNull.sql b/old_tests/ut_test/ut_test.TeardownProcedureNameNull.sql deleted file mode 100644 index 7460ca788..000000000 --- a/old_tests/ut_test/ut_test.TeardownProcedureNameNull.sql +++ /dev/null @@ -1,21 +0,0 @@ -PROMPT Does not invoke teardown procedure when teardown procedure name for a test is null - ---Arrange -declare - simple_test ut_test := ut_test( - a_object_name => 'ut_example_tests', - a_name => 'ut_passing_test', - a_line_no => null - ); -begin - simple_test.after_test_list := ut_executables(ut_executable(user, 'ut_example_tests', null, ut_utils.gc_after_test)); ---Act - simple_test.do_execute(); ---Assert - if ut_example_tests.g_char = 'a' then - :test_result := ut_utils.gc_success; - else - dbms_output.put_line('expected: ut_example_tests.g_char = ''a'', got: '''||ut_example_tests.g_char||'''' ); - end if; -end; -/ diff --git a/old_tests/ut_test/ut_test.TestOutputGathering.sql b/old_tests/ut_test/ut_test.TestOutputGathering.sql deleted file mode 100644 index 14181a4b0..000000000 --- a/old_tests/ut_test/ut_test.TestOutputGathering.sql +++ /dev/null @@ -1,103 +0,0 @@ -create or replace package ut_output_tests -as - --%suite - - --%beforeeach - procedure beforeeach; - - --%aftereach - procedure aftereach; - - --%test - --%beforetest(beforetest) - --%aftertest(aftertest) - procedure ut_passing_test; - - procedure beforetest; - - procedure aftertest; - - --%beforeall - procedure beforeall; - --%afterall - procedure afterall; - -end; -/ - -create or replace package body ut_output_tests -as - - procedure beforetest as - begin - dbms_output.put_line(''); - end; - - procedure aftertest - as - begin - dbms_output.put_line(''); - end; - - procedure beforeeach as - begin - dbms_output.put_line(''); - end; - - procedure aftereach - as - begin - dbms_output.put_line(''); - end; - - procedure ut_passing_test - as - begin - dbms_output.put_line(''); - ut.expect(1,'Test 1 Should Pass').to_equal(1); - end; - - procedure beforeall is - begin - dbms_output.put_line(''); - end; - - procedure afterall is - begin - dbms_output.put_line(''); - end; - -end; -/ - -declare - l_output_data dbms_output.chararr; - l_num_lines integer := 100000; - l_output clob; -begin - --act - ut.run('ut_output_tests'); - - --assert - dbms_output.get_lines( l_output_data, l_num_lines); - dbms_lob.createtemporary(l_output,true); - for i in 1 .. l_num_lines loop - dbms_lob.append(l_output,l_output_data(i)); - end loop; - - if l_output like '%%%%%%%%1 tests, 0 failed, 0 errored%' then - :test_result := ut_utils.gc_success; - end if; - - if :test_result != ut_utils.gc_success or :test_result is null then - for i in 1 .. l_num_lines loop - dbms_output.put_line(l_output_data(i)); - end loop; - dbms_output.put_line('Failed: Wrong output'); - end if; -end; -/ - -drop package ut_output_tests -/ - diff --git a/old_tests/ut_test/ut_test.TestOutputGatheringWhenEmpty.sql b/old_tests/ut_test/ut_test.TestOutputGatheringWhenEmpty.sql deleted file mode 100644 index dcd82fbad..000000000 --- a/old_tests/ut_test/ut_test.TestOutputGatheringWhenEmpty.sql +++ /dev/null @@ -1,55 +0,0 @@ -create or replace package ut_output_tests -as - --%suite - - --%test - procedure ut_passing_test; - -end; -/ - -create or replace package body ut_output_tests -as - - procedure ut_passing_test - as - begin - --Generate empty output - dbms_output.put_line(''); - ut.expect(1,'Test 1 Should Pass').to_equal(1); - end; - -end; -/ - -declare - l_output_data dbms_output.chararr; - l_num_lines integer := 100000; - l_output clob; -begin - --act - ut.run('ut_output_tests'); - - --assert - dbms_output.get_lines( l_output_data, l_num_lines); - dbms_lob.createtemporary(l_output,true); - for i in 1 .. l_num_lines loop - dbms_lob.append(l_output,l_output_data(i)); - end loop; - - if l_output like '%0 failed, 0 errored, 0 disabled, 0 warning(s)%' then - :test_result := ut_utils.gc_success; - end if; - - if :test_result != ut_utils.gc_success or :test_result is null then - for i in 1 .. l_num_lines loop - dbms_output.put_line(l_output_data(i)); - end loop; - dbms_output.put_line('Failed: Wrong output'); - end if; -end; -/ - -drop package ut_output_tests -/ - diff --git a/sonar-project.properties b/sonar-project.properties index a1fabbede..e13de646b 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -9,7 +9,7 @@ sonar.projectVersion=v3.1.3-develop # If not set, SonarQube starts looking for source code from the directory containing # the sonar-project.properties file. sonar.sources=./source -sonar.coverageReportPaths=./old_tests/coverage.xml,coverage.xml +sonar.coverageReportPaths=coverage.xml sonar.tests=./test sonar.testExecutionReportPaths=./test_results.xml sonar.links.issue=https://github.com/utPLSQL/utPLSQL/issues diff --git a/test/core/test_ut_test.pkb b/test/core/test_ut_test.pkb index 5b401463c..b521d6841 100644 --- a/test/core/test_ut_test.pkb +++ b/test/core/test_ut_test.pkb @@ -137,5 +137,561 @@ create or replace package body test_ut_test is ut.expect(l_suite.results_count.errored_count).to_equal(1); end; + procedure after_each_executed is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.after_each_list := ut3.ut_executables(ut3.ut_executable(user, 'ut_example_tests', 'add_1_to_g_number', ut3.ut_utils.gc_after_each)); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_success); + ut.expect(ut_example_tests.g_number).to_equal(1); + end; + + procedure after_each_proc_name_invalid is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.after_each_list := ut3.ut_executables( + ut3.ut_executable(user, 'ut_example_tests', 'invalid setup name', ut3.ut_utils.gc_after_each) + ); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + ut.expect(ut_example_tests.g_number).to_equal(0); + end; + + procedure after_each_procedure_name_null is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.after_each_list := ut3.ut_executables( + ut3.ut_executable(user, 'ut_example_tests', null, ut3.ut_utils.gc_after_each) + ); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + ut.expect(ut_example_tests.g_number).to_equal(0); + end; + + procedure create_app_info_package is + pragma autonomous_transaction; + begin + execute immediate q'[create or replace package ut_output_tests + as + --%suite + + gv_before_all_client_info varchar2(200); + gv_before_each_client_info varchar2(200); + gv_before_test_client_info varchar2(200); + gv_after_test_client_info varchar2(200); + gv_after_each_client_info varchar2(200); + gv_after_all_client_info varchar2(200); + + --%test + --%beforetest(before_test) + --%aftertest(after_test) + procedure the_test; + + --%beforeall + procedure beforeall; + + --%beforeeach + procedure beforeeach; + + procedure before_test; + procedure after_test; + + --%aftereach + procedure aftereach; + + --%afterall + procedure afterall; + + end;]'; + execute immediate q'[create or replace package body ut_output_tests + as + + procedure the_test + as + l_module_name varchar2(4000); + l_action_name varchar2(4000); + l_client_info varchar2(4000); + begin + --Generate empty output + dbms_output.put_line(''); + ut.expect(1,'Test 1 Should Pass').to_equal(1); + dbms_application_info.read_module(module_name => l_module_name, action_name => l_action_name); + dbms_application_info.read_client_info(l_client_info); + ut.expect(l_module_name).to_equal('utPLSQL'); + ut.expect(l_action_name).to_be_like('ut_output_tests'); + ut.expect(l_client_info).to_be_like('the_test'); + end; + + procedure beforeall is + begin + dbms_application_info.read_client_info(gv_before_all_client_info); + end; + + procedure beforeeach is + begin + dbms_application_info.read_client_info(gv_before_each_client_info); + end; + + procedure before_test is + begin + dbms_application_info.read_client_info(gv_before_test_client_info); + end; + procedure after_test is + begin + dbms_application_info.read_client_info(gv_after_test_client_info); + end; + + procedure aftereach is + begin + dbms_application_info.read_client_info(gv_after_each_client_info); + end; + + procedure afterall is + begin + dbms_application_info.read_client_info(gv_after_all_client_info); + end; + + end;]'; + end; + + procedure drop_app_info_package is + pragma autonomous_transaction; + begin + execute immediate q'[drop package ut_output_tests]'; + end; + + procedure application_info_on_execution is + l_output_data ut3.ut_varchar2_list; + l_output clob; + function get_test_value(a_variable_name varchar2) return varchar2 is + l_result varchar2(4000); + begin + execute immediate 'begin :i := ut_output_tests.'||a_variable_name||'; end;' using out l_result; + return l_result; + end; + begin + --act + select * bulk collect into l_output_data + from table(ut3.ut.run('ut_output_tests')); + l_output := ut3.ut_utils.table_to_clob(l_output_data); + --assert + + ut.expect(get_test_value('gv_before_all_client_info')).to_equal('beforeall'); + ut.expect(get_test_value('gv_before_each_client_info')).to_equal('beforeeach'); + ut.expect(get_test_value('gv_before_test_client_info')).to_equal('before_test'); + ut.expect(get_test_value('gv_after_test_client_info')).to_equal('after_test'); + ut.expect(get_test_value('gv_after_each_client_info')).to_equal('aftereach'); + ut.expect(get_test_value('gv_after_all_client_info')).to_equal('afterall'); + ut.expect(l_output).to_be_like('%0 failed, 0 errored, 0 disabled, 0 warning(s)%'); + end; + + procedure before_each_executed is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'add_1_to_g_number', + a_line_no => null + ); + begin + l_test.before_each_list := ut3.ut_executables(ut3.ut_executable(user, 'ut_example_tests', 'set_g_number_0', ut3.ut_utils.gc_before_each)); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_success); + ut.expect(ut_example_tests.g_number).to_equal(1); + end; + + + procedure before_each_proc_name_invalid is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.before_each_list := ut3.ut_executables( + ut3.ut_executable(user, 'ut_example_tests', 'invalid setup name', ut3.ut_utils.gc_before_each) + ); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + ut.expect(ut_example_tests.g_number).to_be_null; + end; + + procedure before_each_proc_name_null is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.before_each_list := ut3.ut_executables( + ut3.ut_executable(user, 'ut_example_tests', null, ut3.ut_utils.gc_before_each) + ); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + ut.expect(ut_example_tests.g_number).to_be_null; + end; + + procedure ignore_savepoint_exception is + pragma autonomous_transaction; + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'ut_commit_test', + a_line_no => null + ); + begin + l_test.rollback_type := ut3.ut_utils.gc_rollback_auto; + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_success); + end; + + procedure owner_name_invalid is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_owner => 'invalid owner name', + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + end; + + procedure owner_name_null is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_owner => null, + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_success); + ut.expect(ut_example_tests.g_number).to_equal(0); + end; + + + procedure create_invalid_package is + pragma autonomous_transaction; + begin + execute immediate 'create or replace package invalid_package is + v_variable non_existing_type; + procedure ut_exampletest; + end;'; + exception when others then + null; + end; + + procedure drop_invalid_package is + pragma autonomous_transaction; + begin + execute immediate 'drop package invalid_package'; + exception when others then + null; + end; + + procedure package_in_invalid_state is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'invalid_package', + a_name => 'ut_exampletest', + a_line_no => null + ); + begin + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + end; + + procedure package_name_invalid is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'invalid package name', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + end; + + procedure package_name_null is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => null, + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + end; + + procedure procedure_name_invalid is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'invalid procedure name', + a_line_no => null + ); + begin + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + end; + + procedure procedure_name_null is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => null, + a_line_no => null + ); + begin + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + end; + + procedure before_test_executed is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'add_1_to_g_number', + a_line_no => null + ); + begin + l_test.before_test_list := ut3.ut_executables(ut3.ut_executable(user, 'ut_example_tests', 'set_g_number_0', ut3.ut_utils.gc_before_test)); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_success); + ut.expect(ut_example_tests.g_number).to_equal(1); + end; + + procedure before_test_proc_name_invalid is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.before_test_list := ut3.ut_executables( + ut3.ut_executable(user, 'ut_example_tests', 'invalid setup name', ut3.ut_utils.gc_before_test) + ); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + ut.expect(ut_example_tests.g_number).to_be_null; + end; + + procedure before_test_proc_name_null is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.before_test_list := ut3.ut_executables( + ut3.ut_executable(user, 'ut_example_tests', null, ut3.ut_utils.gc_before_test) + ); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + ut.expect(ut_example_tests.g_number).to_be_null; + end; + + procedure after_test_executed is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.after_test_list := ut3.ut_executables(ut3.ut_executable(user, 'ut_example_tests', 'add_1_to_g_number', ut3.ut_utils.gc_after_test)); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_success); + ut.expect(ut_example_tests.g_number).to_equal(1); + end; + + procedure after_test_proce_name_invalid is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.after_test_list := ut3.ut_executables( + ut3.ut_executable(user, 'ut_example_tests', 'invalid procedure name', ut3.ut_utils.gc_after_test) + ); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + ut.expect(ut_example_tests.g_number).to_equal(0); + end; + + procedure after_test_proc_name_null is + --Arrange + l_test ut3.ut_test := ut3.ut_test( + a_object_name => 'ut_example_tests', + a_name => 'set_g_number_0', + a_line_no => null + ); + begin + l_test.after_test_list := ut3.ut_executables( + ut3.ut_executable(user, 'ut_example_tests', null, ut3.ut_utils.gc_after_test) + ); + --Act + l_test.do_execute(); + --Assert + ut.expect(l_test.result).to_equal(ut3.ut_utils.gc_error); + ut.expect(ut_example_tests.g_number).to_equal(0); + end; + + procedure create_output_package is + pragma autonomous_transaction; + begin + execute immediate q'[create or replace package ut_output_tests + as + --%suite + + --%beforeeach + procedure beforeeach; + + --%aftereach + procedure aftereach; + + --%test + --%beforetest(beforetest) + --%aftertest(aftertest) + procedure ut_passing_test; + + procedure beforetest; + + procedure aftertest; + + --%beforeall + procedure beforeall; + --%afterall + procedure afterall; + + end;]'; + execute immediate q'[create or replace package body ut_output_tests + as + + procedure beforetest is + begin + dbms_output.put_line(''); + end; + + procedure aftertest is + begin + dbms_output.put_line(''); + end; + + procedure beforeeach is + begin + dbms_output.put_line(''); + end; + + procedure aftereach is + begin + dbms_output.put_line(''); + end; + + procedure ut_passing_test is + begin + dbms_output.put_line(''); + ut.expect(1,'Test 1 Should Pass').to_equal(1); + end; + + procedure beforeall is + begin + dbms_output.put_line(''); + end; + + procedure afterall is + begin + dbms_output.put_line(''); + end; + + end;]'; + exception when others then + null; + end; + + procedure drop_output_package is + pragma autonomous_transaction; + begin + execute immediate 'drop package ut_output_tests'; + exception when others then + null; + end; + + procedure test_output_gathering is + l_output_data ut3.ut_varchar2_list; + l_output clob; + begin + select * bulk collect into l_output_data + from table(ut3.ut.run('ut_output_tests')); + l_output := ut3.ut_utils.table_to_clob(l_output_data); + ut.expect(l_output).to_be_like( + '%%%%%%%%1 tests, 0 failed, 0 errored%' + ); + end; + + end; / diff --git a/test/core/test_ut_test.pks b/test/core/test_ut_test.pks index de6107326..5ee6e35ce 100644 --- a/test/core/test_ut_test.pks +++ b/test/core/test_ut_test.pks @@ -22,5 +22,71 @@ create or replace package test_ut_test is procedure beforeeach_errors; + --%context(executables in test) + + --%test(Executes aftereach procedure) + procedure after_each_executed; + + --%test(Fails test when aftereach procedure name invalid) + procedure after_each_proc_name_invalid; + --%test(Tails test when aftereach procedure name null) + procedure after_each_procedure_name_null; + + procedure create_app_info_package; + procedure drop_app_info_package; + --%beforetest(create_app_info_package) + --%aftertest(drop_app_info_package) + --%test(Sets application_info on execution of individual items) + procedure application_info_on_execution; + + --%test(Executes beforeeach procedure) + procedure before_each_executed; + --%test(Fails test when beforeeach procedure name invalid) + procedure before_each_proc_name_invalid; + --%test(Fails test when beforeeach procedure name null) + procedure before_each_proc_name_null; + --%test(Does not raise exception when rollback to savepoint fails) + procedure ignore_savepoint_exception; + --%test(Fails when owner name invalid) + procedure owner_name_invalid; + --%test(Runs test as current schema when owner name null) + procedure owner_name_null; + + procedure create_invalid_package; + procedure drop_invalid_package; + --%beforetest(create_app_info_package) + --%aftertest(drop_app_info_package) + --%test(Fails the test that references package with compilation errors) + procedure package_in_invalid_state; + --%test(Fails the test when package name is invalid) + procedure package_name_invalid; + --%test(Fails the test when package name is null) + procedure package_name_null; + --%test(Fails the test when procedure name invalid) + procedure procedure_name_invalid; + --%test(Fails the test when procedure name null) + procedure procedure_name_null; + + + --%test(Executes befroretest procedure) + procedure before_test_executed; + --%test(Fails test when befroretest procedure name invalid) + procedure before_test_proc_name_invalid; + --%test(Fails test when befroretest procedure name is null) + procedure before_test_proc_name_null; + --%test(Executes aftertest procedure) + procedure after_test_executed; + --%test(Fails test when aftertest procedure name invalid) + procedure after_test_proce_name_invalid; + --%test(Fails test when aftertest procedure name is null) + procedure after_test_proc_name_null; + + procedure create_output_package; + procedure drop_output_package; + --%beforetest(create_output_package) + --%aftertest(drop_output_package) + --%test(Test output gathering) + procedure test_output_gathering; + end; / diff --git a/test/helpers/ut_example_tests.pkb b/test/helpers/ut_example_tests.pkb index 5059103b6..d8afd592a 100644 --- a/test/helpers/ut_example_tests.pkb +++ b/test/helpers/ut_example_tests.pkb @@ -16,5 +16,9 @@ as g_number := 1 / 0; end; + procedure ut_commit_test is + begin + commit; + end; end; / diff --git a/test/helpers/ut_example_tests.pks b/test/helpers/ut_example_tests.pks index 7ff75ce12..428d55743 100644 --- a/test/helpers/ut_example_tests.pks +++ b/test/helpers/ut_example_tests.pks @@ -1,8 +1,8 @@ -create or replace package ut_example_tests -as - g_number number; - procedure set_g_number_0; - procedure add_1_to_g_number; - procedure failing_procedure; +create or replace package ut_example_tests as + g_number number; + procedure set_g_number_0; + procedure add_1_to_g_number; + procedure failing_procedure; + procedure ut_commit_test; end; / From 0ee3ce26f5c4567581869d80e73929dcbba5cbac Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 18:42:18 +0000 Subject: [PATCH 106/115] Added missing endcontext in `test_ut_test` --- test/core/test_ut_test.pks | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/core/test_ut_test.pks b/test/core/test_ut_test.pks index 5ee6e35ce..ee888ecd3 100644 --- a/test/core/test_ut_test.pks +++ b/test/core/test_ut_test.pks @@ -88,5 +88,7 @@ create or replace package test_ut_test is --%test(Test output gathering) procedure test_output_gathering; + --%endcontext + end; / From 48aa33819d94636b4286c6ca9f589c90ae88bff2 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 19:04:05 +0000 Subject: [PATCH 107/115] Removed unused constants. --- source/reporters/ut_ansiconsole_helper.pkb | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/reporters/ut_ansiconsole_helper.pkb b/source/reporters/ut_ansiconsole_helper.pkb index d9c0617e0..07d9ee9a7 100644 --- a/source/reporters/ut_ansiconsole_helper.pkb +++ b/source/reporters/ut_ansiconsole_helper.pkb @@ -18,8 +18,6 @@ create or replace package body ut_ansiconsole_helper as gc_red constant varchar2(7) := chr(27) || '[31m'; gc_green constant varchar2(7) := chr(27) || '[32m'; gc_yellow constant varchar2(7) := chr(27) || '[33m'; - gc_blue constant varchar2(7) := chr(27) || '[34m'; - gc_magenta constant varchar2(7) := chr(27) || '[35m'; gc_cyan constant varchar2(7) := chr(27) || '[36m'; gc_reset constant varchar2(7) := chr(27) || '[0m'; g_enabled boolean := false; From b33aaaee70db13038760f8401c101767b80e2309 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 20:41:28 +0000 Subject: [PATCH 108/115] Added additional test for display of parser warnings. Fixed issue with warnings not getting shown. --- source/core/ut_suite_manager.pkb | 201 ++++++++++++++++--------------- test/api/test_ut_run.pkb | 42 ++++++- test/api/test_ut_run.pks | 6 + 3 files changed, 148 insertions(+), 101 deletions(-) diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb index 19862992d..3c2c713eb 100644 --- a/source/core/ut_suite_manager.pkb +++ b/source/core/ut_suite_manager.pkb @@ -174,91 +174,112 @@ create or replace package body ut_suite_manager is a_level pls_integer, a_prev_level pls_integer, a_items_at_level t_item_levels - ) return ut_logical_suite is + ) return ut_suite_item is + l_result ut_suite_item; begin - return case a_rows( a_idx ).self_type when 'UT_SUITE' then - case when a_prev_level > a_level then - ut_suite( - self_type => a_rows( a_idx ).self_type, - object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), - name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, - rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, - line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, - start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => a_items_at_level(a_prev_level), - before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( - a_rows( a_idx ).after_all_list) - ) - else - ut_suite( - self_type => a_rows( a_idx ).self_type, - object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), - name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, - rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, - line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, - start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => ut_suite_items(), - before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( - a_rows( a_idx ).after_all_list) - ) - end + l_result := + case when a_prev_level > a_level then + ut_suite( + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => a_items_at_level(a_prev_level), + before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( + a_rows( a_idx ).after_all_list) + ) + else + ut_suite( + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items(), + before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( + a_rows( a_idx ).after_all_list) + ) + end; when 'UT_SUITE_CONTEXT' then - case when a_prev_level > a_level then - ut_suite_context( - self_type => a_rows( a_idx ).self_type, - object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), - name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, - rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, - line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, - start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => a_items_at_level(a_prev_level), - before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( - a_rows( a_idx ).after_all_list) - ) - else - ut_suite_context( - self_type => a_rows( a_idx ).self_type, - object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), - name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, - rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, - line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, - start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => ut_suite_items(), - before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( - a_rows( a_idx ).after_all_list) - ) - end + l_result := + case when a_prev_level > a_level then + ut_suite_context( + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => a_items_at_level(a_prev_level), + before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( + a_rows( a_idx ).after_all_list) + ) + else + ut_suite_context( + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items(), + before_all_list => sort_by_seq_no( a_rows( a_idx ).before_all_list), after_all_list => sort_by_seq_no( + a_rows( a_idx ).after_all_list) + ) + end; when 'UT_LOGICAL_SUITE' then - case when a_prev_level > a_level then - ut_logical_suite( - self_type => a_rows( a_idx ).self_type, - object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), - name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, - rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, - line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, - start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => a_items_at_level(a_prev_level) - ) - else - ut_logical_suite( - self_type => a_rows( a_idx ).self_type, - object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), - name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, - rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, - line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, - start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, + l_result := + case when a_prev_level > a_level then + ut_logical_suite( + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => a_items_at_level(a_prev_level) + ) + else + ut_logical_suite( + self_type => a_rows( a_idx ).self_type, + object_owner => a_rows( a_idx ).object_owner, object_name => lower( a_rows( a_idx ).object_name), + name => lower( a_rows( a_idx ).name), description => a_rows( a_idx ).description, path => a_rows( a_idx ).path, + rollback_type => a_rows( a_idx ).rollback_type, disabled_flag => a_rows( a_idx ).disabled_flag, + line_no => a_rows( a_idx ).line_no, parse_time => a_rows( a_idx ).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows( a_idx ).warnings, + results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), + items => ut_suite_items() + ) + end; + when 'UT_TEST' then + l_result := + ut_test( + self_type => a_rows(a_idx).self_type, + object_owner => a_rows(a_idx).object_owner, object_name => lower(a_rows(a_idx).object_name), + name => lower(a_rows(a_idx).name), description => a_rows(a_idx).description, path => a_rows(a_idx).path, + rollback_type => a_rows(a_idx).rollback_type, disabled_flag => a_rows(a_idx).disabled_flag, + line_no => a_rows(a_idx).line_no, parse_time => a_rows(a_idx).parse_time, + start_time => null, end_time => null, result => null, warnings => a_rows(a_idx).warnings, results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - items => ut_suite_items() - ) - end - end; + before_each_list => sort_by_seq_no(a_rows(a_idx).before_each_list), before_test_list => sort_by_seq_no(a_rows(a_idx).before_test_list), + item => a_rows(a_idx).item, + after_test_list => sort_by_seq_no(a_rows(a_idx).after_test_list), after_each_list => sort_by_seq_no(a_rows(a_idx).after_each_list), + all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), + parent_error_stack_trace => null, expected_error_codes => a_rows(a_idx).expected_error_codes + ); + end case; + l_result.results_count.warnings_count := l_result.warnings.count; + return l_result; end; procedure reconstruct_from_cache( @@ -283,26 +304,8 @@ create or replace package body ut_suite_manager is l_items_at_level(l_level) := ut_suite_items(); end if; l_items_at_level(l_level).extend; - if l_rows(l_idx).self_type = 'UT_TEST' then - l_items_at_level(l_level)(l_items_at_level(l_level).last) := - ut_test( - self_type => l_rows(l_idx).self_type, - object_owner => l_rows(l_idx).object_owner, object_name => lower(l_rows(l_idx).object_name), - name => lower(l_rows(l_idx).name), description => l_rows(l_idx).description, path => l_rows(l_idx).path, - rollback_type => l_rows(l_idx).rollback_type, disabled_flag => l_rows(l_idx).disabled_flag, - line_no => l_rows(l_idx).line_no, parse_time => l_rows(l_idx).parse_time, - start_time => null, end_time => null, result => null, warnings => l_rows(l_idx).warnings, - results_count => ut_results_counter(), transaction_invalidators => ut_varchar2_list(), - 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), - item => l_rows(l_idx).item, - 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), - all_expectations => ut_expectation_results(), failed_expectations => ut_expectation_results(), - parent_error_stack_trace => null, expected_error_codes => l_rows(l_idx).expected_error_codes - ); - else - pragma inline(get_logical_suite, 'YES'); - 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 ); - end if; + pragma inline(get_logical_suite, 'YES'); + 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 ); else a_suites.extend; pragma inline(get_logical_suite, 'YES'); diff --git a/test/api/test_ut_run.pkb b/test/api/test_ut_run.pkb index ecf123d5e..c52551b33 100644 --- a/test/api/test_ut_run.pkb +++ b/test/api/test_ut_run.pkb @@ -806,7 +806,45 @@ Failures:% begin execute immediate 'drop package invalid_pckag_that_revalidates'; execute immediate 'drop package parent_specs'; - end; - + end; + + procedure run_and_report_warnings is + l_results ut3.ut_varchar2_list; + l_actual clob; + begin + + select * bulk collect into l_results from table(ut3.ut.run('bad_annotations')); + l_actual := ut3.ut_utils.table_to_clob(l_results); + + ut.expect(l_actual).to_be_like('%Invalid annotation "--%context". Cannot find following "--%endcontext". Annotation ignored.% +%1 tests, 0 failed, 0 errored, 0 disabled, 1 warning(s)%'); + + end; + + procedure create_bad_annot is + pragma autonomous_transaction; + begin + execute immediate q'[ + create or replace package bad_annotations as + --%suite + + --%context + + --%test(invalidspecs) + procedure test1; + + end;]'; + + execute immediate q'[ + create or replace package body bad_annotations as + procedure test1 is begin ut.expect(1).to_equal(1); end; + end;]'; + + end; + procedure drop_bad_annot is + pragma autonomous_transaction; + begin + execute immediate 'drop package bad_annotations'; + end; end; / diff --git a/test/api/test_ut_run.pks b/test/api/test_ut_run.pks index 81eb801a3..2ed325b86 100644 --- a/test/api/test_ut_run.pks +++ b/test/api/test_ut_run.pks @@ -114,6 +114,12 @@ create or replace package test_ut_run is procedure generate_invalid_spec; procedure drop_invalid_spec; + --%test(Provides warnings on invalid annotations) + --%beforetest(create_bad_annot) + --%aftertest(drop_bad_annot) + procedure run_and_report_warnings; + procedure create_bad_annot; + procedure drop_bad_annot; --%endcontext end; From 1e5681b5e79fbd1bd8eb21006d8907237cbe80f2 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sun, 18 Nov 2018 21:43:10 +0000 Subject: [PATCH 109/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index b35bc3302..f4b59da5a 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2365-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2389-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 5bb077d3ea1bebdc44dbea5883e27ee1b95062e2 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sun, 18 Nov 2018 22:06:38 +0000 Subject: [PATCH 110/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index f4b59da5a..195b2b6cb 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2389-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2390-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From cad7bad100688ff7c8fb8271313c0bf53ed4bf50 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 18 Nov 2018 23:49:50 +0000 Subject: [PATCH 111/115] Added description fo timestamp bind-variable comparison in cursor. Resolves #771 --- docs/userguide/expectations.md | 96 ++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/docs/userguide/expectations.md b/docs/userguide/expectations.md index 4c6f3aa68..b02605605 100644 --- a/docs/userguide/expectations.md +++ b/docs/userguide/expectations.md @@ -445,6 +445,8 @@ utPLSQL is capable of comparing compound data-types including: - Cursors, nested table and varray types are compared as **ordered lists of elements**. If order of elements differ, expectation will fail. - Comparison of compound data is data-type aware. So a column `ID NUMBER` in a cursor is not the same as `ID VARCHAR2(100)`, even if they both hold the same numeric values. - Comparison of cursor columns containing `DATE` will only compare date part **and ignore time** by default. See [Comparing cursor data containing DATE fields](#comparing-cursor-data-containing-date-fields) to check how to enable date-time comparison in cursors. +- Comparison of cursor returning `TIMESTAMP` **columns** against cursor returning `TIMESTAMP` **bind variables** requires variables to be casted to proper precision. This is an Oracle SQL - PLSQL compatibility issue and usage of CAST is the only known workaround for now. +See [Comparing cursor data containing TIMESTAMP bind variables](#comparing-cursor-data-containing-timestamp-bind-variables) for examples. - To compare nested table/varray type you need to convert it to `anydata` by using `anydata.convertCollection()` - To compare object type you need to convert it to `anydata` by using `anydata.convertObject()` - It is possible to compare PL/SQL records, collections, varrays and associative arrays. To compare this types of data, use cursor comparison feature of utPLSQL and TABLE operator in SQL query @@ -749,6 +751,100 @@ In the above example: - The test `get_events_for_date_range` will succeed, as the `l_expected_bad_date` cursor contains different date-time then the cursor returned by `get_events` function call. - The test `bad_test` will fail, as the column `event_date` will get compared as DATE without TIME. +### Comparing cursor data containing TIMESTAMP bind variables + +To properly compare `timestamp` column data returned by cursor against bind variable data from another cursor, a conversion needs to be done. + +This applies to `timestamp`,`timestamp with timezone`, `timestamp with local timezone` data types. + +Example below illustrates usage of `cast` operator to assure appropriate precision is applied on timestamp bind-variables in cursor result-set +```sql +drop table timestamps; +create table timestamps ( + ts3 timestamp (3), + ts6 timestamp (6), + ts9 timestamp (9) +); + +create or replace package timestamps_api is + procedure load ( + i_timestamp3 timestamps.ts3%type, + i_timestamp6 timestamps.ts6%type, + i_timestamp9 timestamps.ts9%type + ); +end; +/ + +create or replace package body timestamps_api is + procedure load ( + i_timestamp3 timestamps.ts3%type, + i_timestamp6 timestamps.ts6%type, + i_timestamp9 timestamps.ts9%type + ) + is + begin + insert into timestamps (ts3, ts6, ts9) + values (i_timestamp3, i_timestamp6, i_timestamp9); + end; +end; +/ + + +create or replace package test_timestamps_api is + -- %suite + + -- %test(Loads data into timestamps table) + procedure test_load; +end; +/ + +create or replace package body test_timestamps_api is + procedure test_load is + l_time timestamp(9); + l_expected sys_refcursor; + l_actual sys_refcursor; + begin + --Arrange + l_time := systimestamp; + + open l_expected for + select + cast(l_time as timestamp(3)) as ts3, + cast(l_time as timestamp(6)) as ts6, + cast(l_time as timestamp(9)) as ts9 + from dual; + + --Act + timestamps_api.load ( + l_time, l_time, l_time + ); + + --Assert + open l_actual for + select ts3, ts6, ts9 + from timestamps; + + ut.expect (l_actual).to_equal (l_expected); + + end; +end; +/ + +begin + ut.run ('test_timestamps_api'); +end; +/ +``` + +The execution of the above runs successfully +``` +test_timestamps_api + Loads data into timestamps table [.046 sec] + +Finished in .048181 seconds +1 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s) +``` + # Negating a matcher Expectations provide a very convenient way to perform a check on a negated matcher. From c2e75866afc299005f64344544a95a5116b3be9a Mon Sep 17 00:00:00 2001 From: Travis CI Date: Mon, 19 Nov 2018 12:00:27 +0000 Subject: [PATCH 112/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 195b2b6cb..36d056a26 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2390-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2394-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 3e5d1ba9004d6ee2d2a195e51a2846063c371604 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Tue, 20 Nov 2018 00:08:45 +0000 Subject: [PATCH 113/115] Updated project version after build [skip ci] --- source/core/ut_utils.pks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 36d056a26..835a30cea 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2394-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2397-develop'; /* Constants: Event names */ subtype t_event_name is varchar2(30); From 816873698ab8c4924a46961fe7583ec30c57643d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20G=C4=99bal?= Date: Tue, 20 Nov 2018 00:31:09 +0000 Subject: [PATCH 114/115] Update readme.md --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 5dbec9166..7d04ae81a 100644 --- a/readme.md +++ b/readme.md @@ -233,3 +233,4 @@ __Project Directories__ * examples - Example source code and unit tests * source - The installation code for utPLSQL * tests - Tests for utPLSQL framework + From d13b0ef156f5a42b1e3a7cd15e16153db9384e79 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Tue, 20 Nov 2018 00:40:23 +0000 Subject: [PATCH 115/115] Updated project version after build [skip ci] --- VERSION | 2 +- sonar-project.properties | 2 +- source/core/ut_utils.pks | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index ed4f9d9f8..66cfae52b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.1.3-develop +v3.1.3 diff --git a/sonar-project.properties b/sonar-project.properties index e13de646b..a0288a65d 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,7 +2,7 @@ sonar.projectKey=utPLSQL # this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1. sonar.projectName=utPLSQL -sonar.projectVersion=v3.1.3-develop +sonar.projectVersion=v3.1.3 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. # Since SonarQube 4.2, this property is optional if sonar.modules is set. diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks index 835a30cea..e5de6d623 100644 --- a/source/core/ut_utils.pks +++ b/source/core/ut_utils.pks @@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is * */ - gc_version constant varchar2(50) := 'v3.1.3.2397-develop'; + gc_version constant varchar2(50) := 'v3.1.3.2398'; /* Constants: Event names */ subtype t_event_name is varchar2(30);