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

OSOE-353: Add duplicate SQL query detector in Lombiq.UITestingToolbox #216

Open
wants to merge 77 commits into
base: dev
Choose a base branch
from

Conversation

dministro
Copy link
Member

@dministro dministro commented Oct 24, 2022

OSOE-353
Fixes #93

Summary by CodeRabbit

  • New Features

    • Introduced a "Duplicated SQL query detector" to improve test efficiency and resource usage.
    • Added configuration settings for UI Testing Toolbox to enhance SQL query monitoring.
    • Implemented a new set of tests for detecting duplicated SQL queries.
  • Enhancements

    • Improved test environment with additional configuration options for database command execution thresholds.
    • Enhanced navigation and page load testing with new counter data collection and assertion capabilities.
    • Expanded testing toolbox with classes and interfaces to support performance metric collection.
  • Documentation

    • Updated the Readme to reflect new testing features and configurations.
  • Bug Fixes

    • Fixed issues related to database command execution tracking during tests.
  • Refactor

    • Refactored database connection and command wrappers to support performance data collection.
  • Tests

    • Added tests for new functionality and performance monitoring features.
  • Chores

    • Updated internal test infrastructure to incorporate new counter data collector services.

@github-actions
Copy link

This pull request has merge conflicts. Please resolve those before requesting a review.

Copy link
Member

@Piedone Piedone left a comment

Choose a reason for hiding this comment

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

Impressive!


namespace Lombiq.Tests.UI.Services;

public class PhaseCounterConfiguration
Copy link
Member

Choose a reason for hiding this comment

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

Mention this feature in the root Readme.

Copy link
Member

Choose a reason for hiding this comment

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

This still needs to be done.

/// <summary>
/// Gets the currently running <see cref="CounterDataCollector"/> instance.
/// </summary>
public CounterDataCollector CounterDataCollector { get; init; }
Copy link
Member

Choose a reason for hiding this comment

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

This needs to be possible to be completely disabled too.

Copy link
Member

Choose a reason for hiding this comment

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

This still needs to be done. The page change dumps should also only be written when duplicate SQL query detection is enabled.

{
}

private static string FormatMessage(
Copy link
Member

Choose a reason for hiding this comment

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

Generate exception messages that are easier to understand than:

DbExecuteCounterKey
SELECT [Document].* FROM [Document] WHERE [Document].[Type] = @type LIMIT 1
[0]Type = OrchardCore.Settings.SiteSettings, OrchardCore.Settings

IntegerCounterValue value: 26
Counter value is greater then DbCommandExecutionRepetitionThreshold, threshold: 22

I as an ordinary developer who didn't set up these counter thresholds but just wanted to change something unrelated but accidentally implemented a SELECT N+1 issue, should be able to understand what I did wrong.

Copy link
Member

Choose a reason for hiding this comment

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

While the current message is better, it's still cryptic when you first see it.

SessionProbe, [GET]https://localhost:9341/Admin
Database reader read counter
Query: SELECT [Document].* FROM [Document] WHERE [Document].[Type] = @type LIMIT 1
Parameters: [0]Type = OrchardCore.AdminMenu.Models.AdminMenuList, OrchardCore.AdminMenu
Count: 2
Counter value is greater then SessionThreshold.DbReaderReadThreshold, threshold: 0.

Start the exception with a message that explains, in plain English, what happened.

dministro and others added 16 commits November 7, 2022 17:31
Addressing "This needs to be possible to be completely disabled too."
Addressing ""human-readable" everywhere."
Addressing counting on page load not just navigation request
Addressing counting command text with and without parameters
Addressing "Keep the order of private fields and ctor assignments the same as the ctor parameters."
Addressing "Comment why this is necessary."
Addressing "After a page change, write all counters' values to the TestOutput for debugging."
Copy link
Contributor

coderabbitai bot commented Dec 29, 2023

@Piedone, no worries at all! I'm here to assist you. If you have any specific areas or files in the pull request that you would like me to review, please let me know. Otherwise, I will proceed with a general review of the changes.

Action performed

Review triggered.

@Piedone
Copy link
Member

Piedone commented Dec 29, 2023

These comments seem useful, please check them out. You can also chat with the bot, see the tips under #216 (comment).

Comment on lines 5 to 8
/// <summary>
/// Gets or sets a value indicating whether the current threshold configuration and checking is disabled.
/// </summary>
public bool Disable { get; set; } = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

The property Disable should be renamed to IsEnabled and its logic inverted for consistency with common API naming conventions. This change also addresses a previous review comment.

- public bool Disable { get; set; } = true;
+ public bool IsEnabled { get; set; } = false;

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
/// <summary>
/// Gets or sets a value indicating whether the current threshold configuration and checking is disabled.
/// </summary>
public bool Disable { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether the current threshold configuration and checking is disabled.
/// </summary>
public bool IsEnabled { get; set; } = false;

}),
};

public static bool DefaultExcludeFilter(ICounterKey key) => DefaultExcludeList.Contains(key);
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider optimizing the DefaultExcludeFilter method if the default exclude list grows large. Using a more efficient lookup method, such as a hash set, could improve performance.

- public static bool DefaultExcludeFilter(ICounterKey key) => DefaultExcludeList.Contains(key);
+ public static bool DefaultExcludeFilter(ICounterKey key) => DefaultExcludeListHashSet.Contains(key);
+ private static HashSet<ICounterKey> DefaultExcludeListHashSet = new HashSet<ICounterKey>(DefaultExcludeList);

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
public static bool DefaultExcludeFilter(ICounterKey key) => DefaultExcludeList.Contains(key);
public static bool DefaultExcludeFilter(ICounterKey key) => DefaultExcludeListHashSet.Contains(key);
private static HashSet<ICounterKey> DefaultExcludeListHashSet = new HashSet<ICounterKey>(DefaultExcludeList);

Comment on lines 32 to 58
public CounterThresholdConfiguration NavigationThreshold { get; set; } = new CounterThresholdConfiguration
{
DbCommandIncludingParametersExecutionCountThreshold = 11,
DbCommandExcludingParametersExecutionThreshold = 22,
DbReaderReadThreshold = 11,
};

/// <summary>
/// Gets or sets threshold configuration used per <see cref="YesSql.ISession"/> lifetime. See:
/// <see cref="SessionProbe"/>.
/// </summary>
public CounterThresholdConfiguration SessionThreshold { get; set; } = new CounterThresholdConfiguration
{
DbCommandIncludingParametersExecutionCountThreshold = 22,
DbCommandExcludingParametersExecutionThreshold = 44,
DbReaderReadThreshold = 11,
};

/// <summary>
/// Gets or sets threshold configuration used per page load. See: <see cref="PageLoadProbe"/>.
/// </summary>
public CounterThresholdConfiguration PageLoadThreshold { get; set; } = new CounterThresholdConfiguration
{
DbCommandIncludingParametersExecutionCountThreshold = 22,
DbCommandExcludingParametersExecutionThreshold = 44,
DbReaderReadThreshold = 11,
};
Copy link
Member

Choose a reason for hiding this comment

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

Please add a piece of docs contrasting these three configs: when would you want to use each?

dministro added 20 commits May 7, 2024 00:00
… instead of KeyValuePair<>

Setting default configuration more generic
Moving OSOCE default configuration to OrchardCoreUITestExecutorConfiguration
…re exactly matching with the counter values captured during navigation.
Adding more sample tests
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.

Add duplicate SQL query detector (OSOE-353)
4 participants