Conversation
OptionsControllerTests and DataController_LayoutEvaluatorTests both used instance 500600/cff1cb24-5bc1-4888-8e06-c634753c5144. xUnit runs the two classes in parallel, and TestData.PrepareInstance in OptionsControllerTests deletes and recreates the instance's data files while the layout evaluator test is PUTting to the same data element, which intermittently fails with FileNotFoundException. Copy the fixture to a new instance and data element GUID that only DataController_LayoutEvaluatorTests uses.
…tree GetInstancePath(partyId, guid) searched for the instance file with a recursive Directory.GetFiles over the whole instances directory. That descends into the data folders of every other instance, including ones a parallel test is deleting via TestData.DeleteInstanceAndData, which on Windows fails with UnauthorizedAccessException and turns e.g. InstancesController_PostNewInstanceTests.PostNewInstanceWithContent_ValidFilename_Succeeds into an intermittent 500. Probe the fixed org/app/partyId/instance.json layout instead, and make GetInstances walk directory levels so it only lists files at the instance level. The party filter was also a substring match (1337 matched 501337).
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID:
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. Comment |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The exact party-directory lookup fix lacks deterministic regression coverage.
Review effort: Balanced
Findings: 1
What changed in this PR
Fixes intermittent API test races caused by shared fixtures and recursive instance-directory enumeration.
Changes:
- Gives layout evaluator tests dedicated instance/data fixtures.
- Limits instance discovery to the fixed directory structure.
- Uses exact party-directory matching.
| File | Description |
|---|---|
Mocks/InstanceClientMockSi.cs |
Avoids recursive instance-data traversal. |
Data/.../blob/a2e9d1b4-...pretest |
Adds isolated XML fixture. |
Data/.../a2e9d1b4-...pretest.json |
Adds isolated data metadata. |
Data/.../7f1a3c0e-...pretest.json |
Adds isolated instance metadata. |
Controllers/DataController_LayoutEvaluatorTests.cs |
Uses the isolated fixture identifiers. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Description
Altinn.App.Api.Testshas been failing intermittently in CI. The two failure modes seen in recent runs are both races between test classes that xUnit runs in parallel inside one test process, on the shared on-disk instance fixtures underData/Instances. They are not related to which target framework runs the tests: each test process already gets its own copy of the fixtures, and the failures happened inside that private copy.OptionsControllerTests(11 tests) andDataController_LayoutEvaluatorTestsboth used instance500600/cff1cb24-5bc1-4888-8e06-c634753c5144intdd/contributer-restriction.TestData.PrepareInstancedeletes and recreates the instance's data files, so while anOptionsControllerTeststest prepared the instance, the layout evaluator test'sPUTto the data element failed withFileNotFoundException(run, run). The fixture is copied to a new instance GUID (and data element GUID) that onlyDataController_LayoutEvaluatorTestsuses.InstanceClientMockSi.GetInstancePath(partyId, guid)located the instance file withDirectory.GetFiles(..., SearchOption.AllDirectories)over the whole instances directory. That descends into the data folders of every other instance, including one that a parallel test is deleting throughTestData.DeleteInstanceAndData. On Windows a directory in pending-delete state is reported as access denied, so the enumeration threw and e.g.InstancesController_PostNewInstanceTests.PostNewInstanceWithContent_ValidFilename_Succeedsgot a 500 (run). The lookup now probes the fixedorg/app/partyId/guid.jsonlayout, walking only the org and app directories, which no test deletes.GetInstancesis changed the same way: it walks the remaining directory levels and lists only the*.jsonfiles at the instance level, so it reads the same files as before without enumerating into the instance folders.The old party filter in
GetInstancePathwas a substring match on the path, so party1337also matched501337. The new lookup compares the directory name exactly.Verification
Altinn.App.Api.Testswas run locally on both target frameworks after each commit: 467 tests pass on net10.0 and 466 on net8.0. Three further net10.0 runs only failed inAddRuntimeConfigFiles_Production_ReloadsWhenKubernetesDataSymlinkChanges, which times out waiting for a file-watcher event in the sandbox used for testing, fails the same way on unmodifiedmainthere, and is skipped on Windows in CI.The Windows race can only be reproduced on Windows, so that part is verified by reasoning about the code and by the test run, not by reproducing the original failure.
Documentation