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

SONARJAVA-5291 Create rule S7177: @DirtiesContext should be properly configured #4610

Merged
merged 9 commits into from
Jan 27, 2025
23 changes: 23 additions & 0 deletions rules/S7177/java/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"title": "@DirtiesContext should be properly configured",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be clearer to use: Use appropriate @DirtiesContext mode or something similar

"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
erwan-serandour marked this conversation as resolved.
Show resolved Hide resolved
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-7177",
"sqKey": "S7177",
"scope": "Tests",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"code": {
"impacts": {
"RELIABILITY": "MEDIUM"
},
"attribute": "LOGICAL"
}
}
50 changes: 50 additions & 0 deletions rules/S7177/java/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
The `@DirtiesContext` annotation configuration should make sense with the appropriate mode for the target scope.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think, we can remove this part


== Why is this an issue?

The `@DirtiesContext` annotation marks the ApplicationContext as dirty and indicates that it should be cleared and recreated.
This is important in tests that modify the context, such as altering the state of singleton beans or databases.
However, improper use of the test phase configurations (such as `classMode` or `methodMode`) can lead to redundant or unnecessary context reloads,
potentially impacting performance or leading to incorrect test behavior.
erwan-serandour marked this conversation as resolved.
Show resolved Hide resolved

Misusing `@DirtiesContext` by selecting incorrect `classMode` and `methodMode` values can result in unnecessary context reloads.
For example, using `BEFORE_EACH_TEST_METHOD` at the class level along with `AFTER_METHOD` at the method level triggers unnecessary context reloads increasing test execution time.
This redundancy wastes resources, increases test execution time, and could lead to unexpected test failures.

Also, configuring the `methodMode` at the class level or the `classMode` at the method level does not have meaning and will not have the expected behavior.

erwan-serandour marked this conversation as resolved.
Show resolved Hide resolved
This rule will raise an issue when the incorrect mode is configured on a @DirtiesContext annotation targeting a different scope.
erwan-serandour marked this conversation as resolved.
Show resolved Hide resolved

== How to fix it

=== Code examples

==== Noncompliant code example

[source,java,diff-id=1,diff-type=noncompliant]
----
@ContextConfiguration
@DirtiesContext(methodMode = MethodMode.AFTER_METHOD) // Noncompliant, for class-level control, use classMode instead.
public class TestClass {
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) // Non compliant, for method-level control use methodMode instead
public void test() {...}
}
----

==== Compliant solution

[source,java,diff-id=1,diff-type=compliant]
----
@ContextConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class TestClass {
@DirtiesContext(methodMode = MethodMode.AFTER_METHOD)
public void test() {...}
}
----

== Resources

=== Documentation

* Spring documentation - https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/annotation/DirtiesContext.html[@DirtiesContext]
2 changes: 2 additions & 0 deletions rules/S7177/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
Loading