Skip to content

Clean tests instability#1010

Merged
Meklo merged 15 commits into
mainfrom
marcellinh/clean_loadflow_tests_instability
Jun 22, 2026
Merged

Clean tests instability#1010
Meklo merged 15 commits into
mainfrom
marcellinh/clean_loadflow_tests_instability

Conversation

@Meklo

@Meklo Meklo commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

PR Summary

Two distinct causes of instability were identified and fixed.

1. Races on non-blocking async deletions

Several cleanup paths dispatch remote-resource deletions as fire-and-forget tasks via studyServerExecutionService.runAsync (e.g. invalidateRootNetworkRemoteInfos with blocking=false). Tests that verify those deletions race the executor pool: the verify can run before the task does. Since deleteCase is the last task submitted, it's the one that fails most often (seen in testCreateRootNetworkConsumerWithoutRequest, and latent in testDeleteRootNetwork).

Fix: use synchronizeStudyServerExecutionService when needed

2. Double deletion of the creation request (testCreateStudyWithErrorDuringCaseImport)

On a synchronous 5xx during import, deleteStudyIfNotCreationInProgress is called concurrently by two paths:

  • the catch block in createStudy (request thread)
  • consumeCaseImportFailed (RabbitMQ consumer)

Depending on ordering, the consumer can read an already-deleted study_creation_request, fall into the branch that calls getStudyStudy not found, the exception is swallowed, and the STUDY_CREATION_FINISHED notification is never emitted → the test waits for a message that never arrives.

Fix: doDeleteStudyIfNotCreationInProgress made idempotent — if neither the creation request nor the study exists, it no-ops instead of throwing. The consumer then always reaches emitStudyCreationError, regardless of which path wins the race.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

StudyService#doDeleteStudyIfNotCreationInProgress now guards cleanup on both the absence of a creation request and the presence of a study entity, and switches creation-request deletion to deleteAllByIdInBatch. Tests in LoadFlowTest, RootNetworkTest, and StudyTest add inline async synchronization and a missing broker-message assertion.

Changes

Study deletion fix, async test isolation, and notification verification

Layer / File(s) Summary
StudyService cleanup guard and batch deletion
src/main/java/org/gridsuite/study/server/service/StudyService.java
The deletion branch now executes only when both no creation request exists and a study entity is present, removing the inner studyEntity.ifPresent wrapper. Creation-request deletion switches from deleteById to deleteAllByIdInBatch with a singleton list.
Async inline execution wired into LoadFlowTest and RootNetworkTest
src/test/java/org/gridsuite/study/server/loadflow/LoadFlowTest.java, src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java
Both test classes add a @MockitoSpyBean for StudyServerExecutionService and call synchronizeStudyServerExecutionService before assertions in testDeleteResults, testCreateRootNetworkConsumerWithoutRequest, and testDeleteRootNetwork. Wildcard imports are expanded to explicit names; a stale comment is corrected to "loadflow results".
Creation-finished broker message assertion in StudyTest
src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java
testCreateStudyWithErrorDuringCaseImport now consumes a second study.update message and asserts its type is UPDATE_TYPE_STUDY_CREATION_FINISHED with the expected HEADER_USER_ID, verifying the started→finished notification sequence on case-import failure.

Suggested Reviewers

  • FranckLecuyer
  • AbdelHedhili
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Clean tests instability' directly relates to the main objective of fixing test instability issues caused by race conditions and async operations.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description clearly explains two distinct issues: races on non-blocking async deletions and double deletion of creation requests, with fixes detailed for each.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/test/java/org/gridsuite/study/server/loadflow/LoadFlowTest.java (1)

581-584: Consider explicitly resetting the studyServerExecutionService stub to follow defensive coding practices.

At line 581-584, the runAsync() method is stubbed on a shared @MockitoSpyBean. While @MockitoSpyBean defaults to MockReset.AFTER (automatically resetting after each test), adding an explicit reset(studyServerExecutionService) at the end of the test provides a defensive guard against unexpected framework behavior changes and clarifies intent for future maintainers.

This stub affects async execution behavior and could silently change test semantics if reset semantics ever diverge from expectations. A one-line reset call in the test's cleanup section would be prudent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/org/gridsuite/study/server/loadflow/LoadFlowTest.java` around
lines 581 - 584, The test is stubbing the runAsync() method on the shared
studyServerExecutionService MockitoSpyBean without explicitly resetting it after
the test completes. Add an explicit reset(studyServerExecutionService) call at
the end of the test method (in the cleanup section or after the assertions) to
defensively ensure the stub is cleared and make the intent clear for future
maintainers, protecting against potential framework behavior changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/test/java/org/gridsuite/study/server/loadflow/LoadFlowTest.java`:
- Around line 581-584: The test is stubbing the runAsync() method on the shared
studyServerExecutionService MockitoSpyBean without explicitly resetting it after
the test completes. Add an explicit reset(studyServerExecutionService) call at
the end of the test method (in the cleanup section or after the assertions) to
defensively ensure the stub is cleared and make the intent clear for future
maintainers, protecting against potential framework behavior changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5da3819d-9c77-43c2-9914-5dcef3318bca

📥 Commits

Reviewing files that changed from the base of the PR and between 2d9485e and 916acf3.

📒 Files selected for processing (3)
  • src/main/java/org/gridsuite/study/server/service/StudyService.java
  • src/test/java/org/gridsuite/study/server/loadflow/LoadFlowTest.java
  • src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java

@Meklo Meklo force-pushed the marcellinh/clean_loadflow_tests_instability branch from 9ef2138 to 916acf3 Compare June 16, 2026 14:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/org/gridsuite/study/server/service/ConsumerService.java`:
- Around line 348-350: Replace the two System.out.println statements with proper
logging using the existing LOGGER instance. The first println statement that
outputs "AAAAAAAAAAAAAAAAAAAAAAA " and checks receiver.getCaseImportAction()
should be replaced with a descriptive log message (e.g., using LOGGER.debug or
LOGGER.info) that includes the actual CaseImportAction value. The second println
statement that outputs "OOOOOOOOOOOOOOOOOOOOOOOOO" should similarly be replaced
with a meaningful log message describing the action being performed when
CaseImportAction.STUDY_CREATION is detected. This ensures proper logging
framework integration with appropriate log levels and structured output instead
of bypassing the logging configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4147beba-4bfc-4ae9-b99e-f1aaae669a6b

📥 Commits

Reviewing files that changed from the base of the PR and between 916acf3 and d3f6022.

📒 Files selected for processing (1)
  • src/main/java/org/gridsuite/study/server/service/ConsumerService.java

Comment thread src/main/java/org/gridsuite/study/server/service/ConsumerService.java Outdated
Hugo Marcellin added 2 commits June 16, 2026 16:58
@Meklo Meklo force-pushed the marcellinh/clean_loadflow_tests_instability branch from 12dc0ec to e5e0103 Compare June 17, 2026 09:30
@Meklo Meklo changed the title Clean loadflow tests instability Clean tests instability Jun 17, 2026
* functions launch new threads in non blocking mode
*/

public static void executeAsyncOnMainThread(StudyServerExecutionService studyServerExecutionService) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same as synchronizeStudyServerExecutionService ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Seems like it ! I'll try swaping it with yours

deleteStudyInfos = new DeleteStudyInfos(rootNetworkInfos, modificationGroupUuids);
} else {
studyCreationRequestRepository.deleteById(studyCreationRequestEntity.get().getId());
studyCreationRequestEntity.ifPresent(creationRequestEntity -> studyCreationRequestRepository.deleteAllByIdInBatch(List.of(creationRequestEntity.getId())));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why deleteAllByIdInBatch ?

removeWorkspacesConfig(s.getWorkspacesConfigUuid());
removeNadConfigs(s.getNadConfigsUuids().stream().toList());
});
StudyEntity s = studyEntity.get();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No need to delete something ih study is absent ?

@sonarqubecloud

Copy link
Copy Markdown

@Meklo Meklo merged commit 5f1fb1e into main Jun 22, 2026
6 checks passed
@Meklo Meklo deleted the marcellinh/clean_loadflow_tests_instability branch June 22, 2026 15:44
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.

2 participants