Skip to content

Commit

Permalink
Enable setup of logging query results during library import and using…
Browse files Browse the repository at this point in the history
… a dedicated keyword 'Set Logging Query Results' (#218)
  • Loading branch information
amochin authored Aug 14, 2024
1 parent 261c32a commit b65afdf
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 5 deletions.
37 changes: 35 additions & 2 deletions src/DatabaseLibrary/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ class DatabaseLibrary(ConnectionManager, Query, Assertion):
|
= Inline assertions =
Keywords that accept arguments ``assertion_operator`` <`AssertionOperator`> and ``expected_value``
Keywords, that accept arguments ``assertion_operator`` <`AssertionOperator`> and ``expected_value``,
perform a check according to the specified condition - using the [https://github.com/MarketSquare/AssertionEngine|Assertion Engine].
Examples:
| Check Row Count | SELECT id FROM person | *==* | 2 |
| Check Query Result | SELECT first_name FROM person | *contains* | Allan |
= Retry mechanism =
Assertion keywords that accept arguments ``retry_timeout`` and ``retry_pause`` support waiting for assertion to pass.
Assertion keywords, that accept arguments ``retry_timeout`` and ``retry_pause``, support waiting for assertion to pass.
Setting the ``retry_timeout`` argument enables the mechanism -
in this case the SQL request and the assertion are executed in a loop,
Expand All @@ -118,6 +118,27 @@ class DatabaseLibrary(ConnectionManager, Query, Assertion):
| Check Row Count | SELECT id FROM person | *==* | 2 | retry_timeout=10 seconds |
| Check Query Result | SELECT first_name FROM person | *contains* | Allan | retry_timeout=5s | retry_timeout=1s |
= Logging query results =
Keywords, that fetch results of a SQL query, print the result rows as a table in RF log.
- A log head limit of *50 rows* is applied, other table rows are truncated in the log message.
- The limit and the logging in general can be adjusted any time in your tests using the Keyword `Set Logging Query Results`.
You can also setup the limit or disable the logging during the library import.
Examples:
| # Default behavior - logging of query results is enabled, log head is 50 rows.
| *** Settings ***
| Library DatabaseLibrary
|
| # Logging of query results is disabled, log head is 50 rows (default).
| Library DatabaseLibrary log_query_results=False
|
| # Logging of query results is enabled (default), log head is 10 rows.
| Library DatabaseLibrary log_query_results_head=10
|
| # Logging of query results is enabled (default), log head limit is disabled (log all rows).
| Library DatabaseLibrary log_query_results_head=0
= Database modules compatibility =
The library is basically compatible with any [https://peps.python.org/pep-0249|Python Database API Specification 2.0] module.
Expand All @@ -128,3 +149,15 @@ class DatabaseLibrary(ConnectionManager, Query, Assertion):
"""

ROBOT_LIBRARY_SCOPE = "GLOBAL"

def __init__(self, log_query_results=True, log_query_results_head=50):
"""
The library can be imported without any arguments:
| *** Settings ***
| Library DatabaseLibrary
Use optional library import parameters to disable `Logging query results` or setup the log head.
"""
ConnectionManager.__init__(self)
if log_query_results_head < 0:
raise ValueError(f"Wrong log head value provided: {log_query_results_head}. The value can't be negative!")
Query.__init__(self, log_query_results=log_query_results, log_query_results_head=log_query_results_head)
33 changes: 30 additions & 3 deletions src/DatabaseLibrary/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class Query:
Query handles all the querying done by the Database Library.
"""

def __init__(self, log_query_results, log_query_results_head):
self.LOG_QUERY_RESULTS = log_query_results
self.LOG_QUERY_RESULTS_HEAD = log_query_results_head

def query(
self,
selectStatement: str,
Expand Down Expand Up @@ -86,7 +90,7 @@ def query(
self._execute_sql(cur, selectStatement, parameters=parameters)
all_rows = cur.fetchall()
col_names = [c[0] for c in cur.description]
self._log_query_result(col_names, all_rows)
self._log_query_results(col_names, all_rows)
if returnAsDict:
return [dict(zip(col_names, row)) for row in all_rows]
return all_rows
Expand Down Expand Up @@ -132,7 +136,7 @@ def row_count(
else:
current_row_count = cur.rowcount
logger.info(f"Retrieved {current_row_count} rows")
self._log_query_result(col_names, data)
self._log_query_results(col_names, data)
return current_row_count
finally:
if cur and not sansTran:
Expand Down Expand Up @@ -552,6 +556,24 @@ def call_stored_procedure(
if cur and not sansTran:
db_connection.client.rollback()

def set_logging_query_results(self, enabled: Optional[bool] = None, log_head: Optional[int] = None):
"""
Allows to enable/disable logging of query results and to adjust the log head value.
- Overrides the values, which were set during the library import.
- See `Logging query results` for details.
Examples:
| Set Logging Query Results | enabled=False |
| Set Logging Query Results | enabled=True | log_head=0 |
| Set Logging Query Results | log_head=10 |
"""
if enabled is not None:
self.LOG_QUERY_RESULTS = enabled
if log_head is not None:
if log_head < 0:
raise ValueError(f"Wrong log head value provided: {log_head}. The value can't be negative!")
self.LOG_QUERY_RESULTS_HEAD = log_head

def _execute_sql(
self,
cur,
Expand All @@ -577,12 +599,17 @@ def _execute_sql(
logger.debug(f"Executing sql '{sql_statement}' with parameters: {parameters}")
return cur.execute(sql_statement, parameters)

def _log_query_result(self, col_names, result_rows, log_head=50):
def _log_query_results(self, col_names, result_rows, log_head: Optional[int] = None):
"""
Logs the `result_rows` of a query in RF log as a HTML table.
The `col_names` are needed for the table header.
Max. `log_head` rows are logged (`0` disables the limit).
"""
if not self.LOG_QUERY_RESULTS:
return

if log_head is None:
log_head = self.LOG_QUERY_RESULTS_HEAD
cell_border_and_align = "border: 1px solid rgb(160 160 160);padding: 8px 10px;text-align: center;"
table_border = "2px solid rgb(140 140 140)"
row_index_color = "#d6ecd4"
Expand Down
14 changes: 14 additions & 0 deletions test/tests/common_tests/import_params.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
*** Settings ***
Documentation Tests for parameters used when importing the library
*** Test Cases ***
Import Without Parameters Is Valid
Import Library DatabaseLibrary

Log Query Results Params Cause No Crash
Import Library DatabaseLibrary log_query_results=False log_query_results_head=0

Log Query Results Head - Negative Value Not Allowed
Run Keyword And Expect Error
... STARTS: Initializing library 'DatabaseLibrary' with arguments [ log_query_results_head=-1 ] failed: ValueError: Wrong log head value provided: -1. The value can't be negative!
... Import Library DatabaseLibrary log_query_results_head=-1
15 changes: 15 additions & 0 deletions test/tests/common_tests/log_query_results.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*** Settings ***
Documentation Tests for keywords controlling the logging query results
Resource ../../resources/common.resource

Suite Setup Connect To DB
Suite Teardown Disconnect From Database
Test Setup Create Person Table And Insert Data
Test Teardown Drop Tables Person And Foobar

*** Test Cases ***
Calling The Keyword Causes No Crash
Set Logging Query Results enabled=False
Set Logging Query Results enabled=True log_head=0
Set Logging Query Results log_head=30

0 comments on commit b65afdf

Please sign in to comment.