Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test corrupted db #5470

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Test corrupted db #5470

wants to merge 9 commits into from

Conversation

gitofanindya
Copy link
Collaborator

@gitofanindya gitofanindya commented Nov 27, 2024

Summary by Sourcery

Enhance logging in database operations and simulate a test failure scenario for corrupted database handling.

Enhancements:

  • Add detailed logging to database migration and connection processes to aid in debugging.

Tests:

  • Introduce a failing assertion in the test_corrupted_database test case to simulate a test failure scenario.

Copy link
Contributor

sourcery-ai bot commented Nov 27, 2024

Reviewer's Guide by Sourcery

This PR implements changes to handle corrupted database scenarios and modifies datetime handling in SQLite operations. The changes primarily focus on adding debug logging, improving error handling during database migrations, and implementing a new datetime adaptation mechanism for SQLite operations.

Class diagram for AutoRetryCursor modifications

classDiagram
    class AutoRetryCursor {
        +adapt_datetime_iso(val)
        +execute(sql: str, parameters: Iterable[Any])
    }
    note for AutoRetryCursor "Added adapt_datetime_iso method and modified execute method to handle datetime adaptation for SQLite operations."
Loading

File-Level Changes

Change Details Files
Added datetime adaptation functionality for SQLite operations
  • Added new adapt_datetime_iso method to handle datetime conversion
  • Modified execute method to register datetime adapter for SQLite parameters
  • Replaced direct super().execute call with adapted parameter handling
nxdrive/dao/base.py
Enhanced database migration process with detailed logging and error handling
  • Added debug print statements throughout the migration process
  • Implemented try-catch blocks for critical migration operations
  • Added detailed logging for table operations during migration
  • Enhanced visibility of column operations during table migration
nxdrive/dao/base.py
Added additional debug logging for database connections
  • Added print statements for connection creation and management
  • Enhanced logging for database file existence checks
  • Added connection state tracking logs
nxdrive/dao/base.py
Modified test case for corrupted database scenario
  • Added failing assertion to test case
tests/unit/test_engine_dao.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time. You can also use
    this command to specify where the summary should be inserted.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @gitofanindya - I've reviewed your changes and found some issues that need to be addressed.

Blocking issues:

  • The test appears to be intentionally failing with an invalid assertion (link)

Overall Comments:

  • Remove all debug print statements and use the existing logging mechanism instead. Print statements are not appropriate for production code.
  • The test modification assert 1 == 0 will always fail and should be removed. If this is a test for corrupted database handling, it should have meaningful assertions.
  • Exception handling should use specific exception types and proper error handling rather than broad Exception catches with print statements.
Here's what I looked at during the review
  • 🟡 General issues: 1 issue found
  • 🟢 Security: all looks good
  • 🔴 Testing: 1 blocking issue
  • 🟡 Complexity: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

import sqlite3
# return super().execute(sql, parameters)
# new_param = tuple( datetime.fromtimestamp(param, tz=timezone.utc) if isinstance(param, datetime) else param for param in parameters )
new_param = tuple( sqlite3.register_adapter(param, self.adapt_datetime_iso) if isinstance(param, datetime) else param for param in parameters )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Registering SQLite adapters inside execute() is unsafe and inefficient

The register_adapter call modifies global state and should be done once at module level. This could cause thread-safety issues and adds unnecessary overhead on every query. Consider moving the adapter registration to module initialization.

Comment on lines 210 to +211
assert len(cols) == 3
assert 1 == 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (testing): The test appears to be intentionally failing with an invalid assertion

The addition of assert 1 == 0 seems to be a debugging artifact that will always fail. This should be removed as it doesn't contribute to testing the database corruption scenario.

class AutoRetryCursor(Cursor):
def adapt_datetime_iso(self, val):
return datetime.fromtimestamp(val.strftime('%s'), tz=timezone.utc)
def execute(self, sql: str, parameters: Iterable[Any] = ()) -> Cursor:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider moving datetime adaptation logic out of the execute() method into a connection-level adapter setup.

The datetime handling in execute() adds unnecessary complexity by mixing adaptation concerns with execution logic. Instead of registering adapters per-parameter during execution, use SQLite's built-in adapter system:

# In _create_main_conn or __init__
def _setup_adapters(self, connection):
    def adapt_datetime_iso(val):
        return val.strftime('%s')
    sqlite3.register_adapter(datetime, adapt_datetime_iso)
    return connection

# Simplify execute() back to:
def execute(self, sql: str, parameters: Iterable[Any] = ()) -> Cursor:
    count = 1
    while True:
        count += 1
        try:
            return super().execute(sql, parameters)
        except OperationalError as exc:
            log.info(
                f"Retry locked database #{count}, {sql=}, {parameters=}",
                exc_info=True,
            )
            if count > 5:
                raise exc

This approach:

  1. Registers the adapter once at connection time
  2. Keeps the cursor focused on its core responsibility
  3. Uses SQLite's built-in type adaptation system as intended

self._create_table(cursor, name, force=True)
print(">>>> called _create_table")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Extract duplicate code into method (extract-duplicate-method)

Copy link

codecov bot commented Nov 27, 2024

Codecov Report

Attention: Patch coverage is 92.30769% with 4 lines in your changes missing coverage. Please review.

Project coverage is 52.08%. Comparing base (9805a47) to head (62c1dc4).

Files with missing lines Patch % Lines
nxdrive/dao/base.py 91.83% 4 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #5470   +/-   ##
=======================================
  Coverage   52.08%   52.08%           
=======================================
  Files          96       96           
  Lines       16094    16144   +50     
=======================================
+ Hits         8382     8409   +27     
- Misses       7712     7735   +23     
Flag Coverage Δ
functional 42.90% <40.38%> (+0.02%) ⬆️
integration 2.00% <0.00%> (-0.01%) ⬇️
unit 40.52% <90.38%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant