Skip to content

Commit

Permalink
1.13.0 (#323)
Browse files Browse the repository at this point in the history
* versioning

* Performance of DB Access in UT Check (#320)

* Update README.md

* disabling rfc

* Update changelog.txt

* Update changelog.txt

* 1.12.0

* Profile Tool - UX Refinement (#313)

Minor UX Changes

* Update changelog.txt

* Update changelog.txt

* Performance (#317)

* buffer size

* fixing dump when object is not supported by sci

* solving dump when ref scan is not set

* Update y_ref_scan_manager.clas.abap

* Update changelog.txt

* removing shared memory (#319)

* Update changelog.txt

* Performance Improvements (#318)

* moving application component valid. to ref_scan

* wip

* changing validation sequence

* fixing minor bug

* fixing bug

* refactoring former buffer

* syntax error

* fixing ut

* fixing unit test base

* abaplint hint

* Update changelog.txt

* wip

* minor update

* minor change

* Code review (#322)

* removing unused exception

* solving empty catch

* moving buffer cleanup

* pretty printer

* Update y_code_pal_version.intf.abap

* commented changes

Co-authored-by: Eugen Günther <64586309+eugen-guenther-sap@users.noreply.github.com>
Co-authored-by: Eugen Guenther <eugen.guenther@sap.com>

* minor change

* Update changelog.txt

Co-authored-by: Eugen Günther <64586309+eugen-guenther-sap@users.noreply.github.com>
Co-authored-by: Eugen Guenther <eugen.guenther@sap.com>
  • Loading branch information
3 people authored Mar 24, 2021
1 parent 73579ed commit 702c43b
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 104 deletions.
5 changes: 5 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ Upgrade Note
------------------
Whenever you upgrade code pal for ABAP, it is highly recommended to execute the Y_CI_CHECK_REGISTRATION report to activate/reactivate the Checks (SE38 transaction) and regenerate the respective code inspector variant (SCI transaction)

2021-03-24 v.1.13.0
------------------
* y_ref_scan_manager_double
* y_check_db_access_in_ut

2021-02-24 v1.12.3
------------------
* Object Creation Date from TRDIR table
Expand Down
292 changes: 193 additions & 99 deletions src/checks/y_check_db_access_in_ut.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,81 @@ CLASS y_check_db_access_in_ut DEFINITION PUBLIC INHERITING FROM y_check_base CRE
METHODS constructor.

PROTECTED SECTION.
METHODS inspect_statements REDEFINITION.
METHODS inspect_structures REDEFINITION.
METHODS inspect_tokens REDEFINITION.

PRIVATE SECTION.
CONSTANTS risk_level_harmless TYPE string VALUE 'HARMLESS'.
CONSTANTS risk_level_dangerous TYPE string VALUE 'DANGEROUS'.
CONSTANTS risk_level_critical TYPE string VALUE 'CRITICAL'.
CONSTANTS risk_level_not_set TYPE string VALUE 'NOT_SET'.

DATA tokens_not_allowed TYPE y_char255_tab.
DATA has_framework TYPE abap_bool.

METHODS inspect_class_definition IMPORTING class_implementation TYPE sstruc.
CONSTANTS: BEGIN OF risk_level,
harmless TYPE string VALUE 'HARMLESS',
dangerous TYPE string VALUE 'DANGEROUS',
critical TYPE string VALUE 'CRITICAL',
END OF risk_level.

CONSTANTS: BEGIN OF check_for,
alter TYPE char40 VALUE 'ALTER',
delete TYPE char40 VALUE 'DELETE',
update TYPE char40 VALUE 'UPDATE',
modify TYPE char40 VALUE 'MODIFY',
insert TYPE char40 VALUE 'INSERT',
select TYPE char40 VALUE 'SELECT',
commit TYPE char40 VALUE 'COMMIT',
rollback TYPE char40 VALUE 'ROLLBACK',
END OF check_for.

CONSTANTS: BEGIN OF framework,
qsql_if TYPE char40 VALUE 'IF_OSQL_TEST_ENVIRONMENT',
qsql_cl TYPE char40 VALUE 'CL_OSQL_TEST_ENVIRONMENT',
cds_if TYPE char40 VALUE 'IF_CDS_TEST_ENVIRONMENT',
cds_cl TYPE char40 VALUE 'CL_CDS_TEST_ENVIRONMENT',
END OF framework.

CONSTANTS: BEGIN OF keys,
from TYPE char40 VALUE 'FROM',
into TYPE char40 VALUE 'INTO',
class TYPE char40 VALUE 'CLASS',
table TYPE char4 VALUE 'TABL',
END OF keys.

TYPES: BEGIN OF properties,
name TYPE string,
risk_level TYPE string,
END OF properties.

DATA defined_classes TYPE STANDARD TABLE OF properties.

METHODS get_class_name IMPORTING structure TYPE sstruc
RETURNING VALUE(result) TYPE string
RAISING cx_sy_itab_line_not_found.

METHODS get_risk_level IMPORTING statement TYPE sstmnt
RETURNING VALUE(result) TYPE string.

METHODS add_line_to_defined_classes IMPORTING statement TYPE sstmnt
structure TYPE sstruc.
METHODS check_class IMPORTING index TYPE i
statement TYPE sstmnt
structure TYPE sstruc.

METHODS is_part_of_framework IMPORTING structure TYPE sstruc
RETURNING VALUE(result) TYPE abap_bool.

METHODS is_persistent_object IMPORTING obj_name TYPE string
RETURNING VALUE(result) TYPE abap_bool.

METHODS consolidade_tokens IMPORTING statement TYPE sstmnt
RETURNING VALUE(result) TYPE string.

METHODS has_ddic_itab_same_syntax IMPORTING token TYPE char255
RETURNING VALUE(result) TYPE abap_bool.

METHODS is_internal_table IMPORTING statement TYPE sstmnt
RETURNING VALUE(result) TYPE abap_bool.

METHODS is_an_attribution IMPORTING statement TYPE sstmnt
RETURNING VALUE(result) TYPE abap_bool.
METHODS get_forbidden_tokens IMPORTING class_name TYPE string
RETURNING VALUE(result) TYPE y_char255_tab.

METHODS has_ddic_itab_same_syntax IMPORTING token TYPE stokesx
RETURNING VALUE(result) TYPE abap_bool.

ENDCLASS.



CLASS y_check_db_access_in_ut IMPLEMENTATION.
CLASS Y_CHECK_DB_ACCESS_IN_UT IMPLEMENTATION.


METHOD constructor.
Expand All @@ -51,131 +92,184 @@ CLASS y_check_db_access_in_ut IMPLEMENTATION.
settings-apply_on_test_code = abap_true.
settings-documentation = |{ c_docs_path-checks }db-access-in-ut.md|.

relevant_statement_types = VALUE #( ( scan_struc_stmnt_type-class_implementation ) ).
relevant_statement_types = VALUE #( ( scan_struc_stmnt_type-class_definition )
( scan_struc_stmnt_type-class_implementation ) ).
relevant_structure_types = VALUE #( ).

set_check_message( 'Database access(es) within a Unit-Test should be removed!' ).
ENDMETHOD.


METHOD inspect_statements.
inspect_class_definition( structure ).
METHOD inspect_tokens.
CASE structure-stmnt_type.
WHEN scan_struc_stmnt_type-class_definition.
add_line_to_defined_classes( statement = statement
structure = structure ).

WHEN scan_struc_stmnt_type-class_implementation.
check_class( index = index
statement = statement
structure = structure ).

ENDCASE.
ENDMETHOD.


METHOD is_persistent_object.
DATA(upper_name) = to_upper( obj_name ).
SELECT * FROM tadir
WHERE obj_name = @upper_name
AND object = @keys-table
AND delflag = @space
INTO TABLE @DATA(tmp).

result = xsdbool( sy-subrc = 0 ).
ENDMETHOD.


METHOD is_internal_table.
DATA(second_token) = get_token_abs( statement-from + 1 ).
DATA(third_token) = get_token_abs( statement-from + 2 ).

IF has_framework = abap_true.
IF second_token = keys-into.
RETURN.
ENDIF.

super->inspect_statements( structure ).
DATA(table_name) = COND #( WHEN second_token = keys-from THEN third_token
ELSE second_token ).

result = xsdbool( is_persistent_object( table_name ) = abap_false ).
ENDMETHOD.


METHOD inspect_tokens.
DATA(tokens) = consolidade_tokens( statement ).
METHOD add_line_to_defined_classes.
DATA(class_config) = VALUE properties( name = get_class_name( structure ) ).

LOOP AT tokens_not_allowed ASSIGNING FIELD-SYMBOL(<token_not_allowed>).
IF tokens NP <token_not_allowed>.
CONTINUE.
ENDIF.
IF line_exists( defined_classes[ name = class_config-name ] ).
RETURN.
ENDIF.

IF is_an_attribution( statement ) = abap_true.
CONTINUE.
ENDIF.
class_config-risk_level = get_risk_level( statement ).

IF has_ddic_itab_same_syntax( <token_not_allowed> ) = abap_true
AND is_internal_table( statement ) = abap_true.
CONTINUE.
ENDIF.
IF is_part_of_framework( structure ) = abap_false.
APPEND class_config TO defined_classes.
ENDIF.
ENDMETHOD.

DATA(check_configuration) = detect_check_configuration( statement ).

IF check_configuration IS INITIAL.
RETURN.
ENDIF.
METHOD check_class.
DATA(class_name) = get_class_name( structure ).
IF NOT line_exists( defined_classes[ name = class_name ] ).
RETURN.
ENDIF.

raise_error( statement_level = statement-level
statement_index = index
statement_from = statement-from
error_priority = check_configuration-prio ).
DATA(forbidden_tokens) = get_forbidden_tokens( class_name ).

ENDLOOP.
ENDMETHOD.
DATA(token) = ref_scan_manager->tokens[ statement-from ].

IF NOT line_exists( forbidden_tokens[ table_line = token-str ] ).
RETURN.
ENDIF.

METHOD is_persistent_object.
cl_abap_structdescr=>describe_by_name( EXPORTING p_name = obj_name
EXCEPTIONS OTHERS = 1 ).
result = xsdbool( sy-subrc = 0 ).
ENDMETHOD.
IF has_ddic_itab_same_syntax( token ) = abap_true
AND is_internal_table( statement ) = abap_true.
RETURN.
ENDIF.

IF ref_scan_manager->tokens[ statement-from + 1 ]-str = '='.
RETURN.
ENDIF.

DATA(check_configuration) = detect_check_configuration( statement ).

METHOD inspect_class_definition.
DATA test_risk_level TYPE string.
IF check_configuration IS INITIAL.
RETURN.
ENDIF.

raise_error( statement_level = statement-level
statement_index = index
statement_from = statement-from
error_priority = check_configuration-prio ).
ENDMETHOD.


METHOD get_forbidden_tokens.
DATA risk_lvl TYPE properties-risk_level.
TRY.
DATA(class_definition) = ref_scan_manager->structures[ class_implementation-back ].
risk_lvl = defined_classes[ name = class_name ]-risk_level.
CATCH cx_sy_itab_line_not_found.
RETURN.
risk_lvl = space.
ENDTRY.

has_framework = abap_false.
CASE risk_lvl.
WHEN risk_level-dangerous OR risk_level-critical.
result = VALUE #( ( check_for-alter )
( check_for-delete )
( check_for-update )
( check_for-modify ) ).
WHEN OTHERS.
result = VALUE #( ( check_for-alter )
( check_for-delete )
( check_for-update )
( check_for-modify )
( check_for-insert )
( check_for-select )
( check_for-commit )
( check_for-rollback ) ).
ENDCASE.
ENDMETHOD.


METHOD is_part_of_framework.
LOOP AT ref_scan_manager->statements ASSIGNING FIELD-SYMBOL(<statement>)
FROM class_definition-stmnt_from TO class_definition-stmnt_to.
DATA(tokens) = consolidade_tokens( <statement> ).

test_risk_level = COND #( WHEN tokens CS 'RISK LEVEL HARMLESS' THEN risk_level_harmless
WHEN tokens CS 'RISK LEVEL DANGEROUS' THEN risk_level_dangerous
WHEN tokens CS 'RISK LEVEL CRITICAL' THEN risk_level_critical
ELSE test_risk_level ).

has_framework = COND #( WHEN tokens CS 'IF_OSQL_TEST_ENVIRONMENT' THEN abap_true
WHEN tokens CS 'CL_OSQL_TEST_ENVIRONMENT' THEN abap_true
WHEN tokens CS 'IF_CDS_TEST_ENVIRONMENT' THEN abap_true
WHEN tokens CS 'CL_CDS_TEST_ENVIRONMENT' THEN abap_true
ELSE has_framework ).
FROM structure-stmnt_from TO structure-stmnt_to.

LOOP AT ref_scan_manager->tokens ASSIGNING FIELD-SYMBOL(<token>)
FROM <statement>-from TO <statement>-to
WHERE str = framework-qsql_if OR
str = framework-qsql_cl OR
str = framework-cds_if OR
str = framework-cds_cl.
result = abap_true.
RETURN.
ENDLOOP.

ENDLOOP.
ENDMETHOD.

test_risk_level = COND #( WHEN test_risk_level IS INITIAL THEN risk_level_not_set
ELSE test_risk_level ).

tokens_not_allowed = COND #( WHEN test_risk_level = risk_level_harmless THEN VALUE #( ( 'ALTER *' ) ( 'DELETE *' ) ( 'UPDATE *' ) ( 'MODIFY *' ) ( 'INSERT INTO *' ) ( 'SELECT *' ) ( 'COMMIT*' ) ( 'ROLLBACK*' ) )
WHEN test_risk_level = risk_level_not_set THEN VALUE #( ( 'ALTER *' ) ( 'DELETE *' ) ( 'UPDATE *' ) ( 'MODIFY *' ) ( 'INSERT INTO *' ) ( 'SELECT *' ) ( 'COMMIT*' ) ( 'ROLLBACK*' ) )
WHEN test_risk_level = risk_level_dangerous THEN VALUE #( ( 'ALTER *' ) ( 'DELETE *' ) ( 'UPDATE *' ) ( 'MODIFY *' ) )
WHEN test_risk_level = risk_level_critical THEN VALUE #( ( 'ALTER *' ) ( 'DELETE *' ) ( 'UPDATE *' ) ( 'MODIFY *' ) ) ).
METHOD get_class_name.
DATA(index) = ref_scan_manager->statements[ structure-stmnt_from ]-from.
IF get_token_abs( index ) = keys-class.
result = get_token_abs( index + 1 ).
ENDIF.
ENDMETHOD.


METHOD consolidade_tokens.
METHOD get_risk_level.
LOOP AT ref_scan_manager->tokens ASSIGNING FIELD-SYMBOL(<token>)
FROM statement-from TO statement-to.
result = COND #( WHEN result IS INITIAL THEN condense( <token>-str )
ELSE |{ result } { condense( <token>-str ) }| ).
FROM statement-from TO statement-to
WHERE str = risk_level-harmless
OR str = risk_level-dangerous
OR str = risk_level-critical.
result = <token>-str.
ENDLOOP.
ENDMETHOD.


METHOD has_ddic_itab_same_syntax.
result = xsdbool( token CS 'MODIFY'
OR token CS 'UPDATE'
OR token CS 'DELETE' ).
ENDMETHOD.

METHOD inspect_structures.
relevant_statement_types = VALUE #( ( scan_struc_stmnt_type-class_definition ) ).
super->inspect_structures( ).

METHOD is_internal_table.
DATA(second_token) = get_token_abs( statement-from + 1 ).
DATA(third_token) = get_token_abs( statement-from + 2 ).

DATA(table) = COND #( WHEN second_token = 'FROM' THEN third_token
ELSE second_token ).

result = xsdbool( is_persistent_object( table ) = abap_false ).
relevant_statement_types = VALUE #( ( scan_struc_stmnt_type-class_implementation ) ).
super->inspect_structures( ).
ENDMETHOD.


METHOD is_an_attribution.
DATA(second_token) = get_token_abs( statement-from + 1 ).
result = xsdbool( second_token = '=' ).
METHOD has_ddic_itab_same_syntax.
result = xsdbool( token-str = check_for-modify
OR token-str = check_for-update
OR token-str = check_for-delete
OR token-str = check_for-insert ).
ENDMETHOD.


ENDCLASS.
1 change: 0 additions & 1 deletion src/checks/y_check_db_access_in_ut.clas.testclasses.abap
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,6 @@ CLASS ltc_exec_sql IMPLEMENTATION.
ENDCLASS.



CLASS ltc_attribution DEFINITION INHERITING FROM ltc_risk_harmless FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
PROTECTED SECTION.
METHODS get_code_without_issue REDEFINITION.
Expand Down
Loading

0 comments on commit 702c43b

Please sign in to comment.