Skip to content

Fix API test authentication in BCApps - #10085

Open
Prangshuman Das (t-prda) wants to merge 158 commits into
mainfrom
prdas/646383-api-test-auth
Open

Fix API test authentication in BCApps#10085
Prangshuman Das (t-prda) wants to merge 158 commits into
mainfrom
prdas/646383-api-test-auth

Conversation

@t-prda

@t-prda Prangshuman Das (t-prda) commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Enable Business Central API tests under UserPassword authentication while retaining Windows/SaaS ambient authentication. HTTP-dependent tests run with Disabled isolation on freshly restored tenant workers.

AB#646383

Current head: 25916aeb85. Includes independent Czech test-fixture prerequisite #11370, the explicit UncategorizedTests scheduler profile and isolated discovery. All eight follow-ups are refreshed. 92 mocked checks and PowerShell CI passed, including the analyzer. Combined runtime CI completed failed at 2026-09-11T17:31:15Z: 116 successful jobs, 46 failed and two skipped. The failures are 45 test lanes containing the 12 known Expense failures, plus the aggregate status check. No additional final auth-scope failure was established.

Final verification on the current head

All six CU 139494 provider-contract methods passed in W1 Legacy1. All 14 previously failing Czech scenarios pass (CZ Default). The Danish stale-record target also passed. Credential removal succeeded in 113/113 test jobs, and all 159 cleanup steps succeeded.

W1 final typed test cases Passed Failed Skipped
APIV1 441 0 26
APIV2 697 0 21
Expense Agent 865 12 12

These are final JUnit cases, not HTTP-request counts; retries are not double-counted. APIV2 RapidStart's five methods passed in 21 country artifacts (105 successful cases), including all three formerly stuck Scheduled. All 22 Uncategorized lanes succeeded, but India recorded no API cases and is not counted as a RapidStart pass. The three deferred APIV1 polling methods remain skipped.

The 12 remaining Expense methods concern permission behavior and deletion/date/filter scenarios. They were also observed in the earlier #11340 baseline; current relevant test sources match that evidence. The current CZ-only prerequisite run records no Expense cases, so its successful lanes are not evidence those failures are fixed. Further Expense behavior/permission changes are outside this auth repair's scope. No failures are hidden through new exclusions, relaxed assertions or weaker isolation. Existing recovered API HTTP 500s and explicitly tolerated native-test failures remain instability signals, not proof of first-attempt stability.

Automatic repair monitoring stopped at this scope boundary. The independently started AU retry completed successfully: CZ prerequisite CI passed on attempt 2 at 2026-09-11T19:28:34Z. This does not change the main auth run's Expense failures or its broader coverage. Passive observation is now complete; the retry was not initiated by this assistant.

The previous head's analyzer crashed internally twice, including one bounded job-only retry; no rule suppression or blind retry was added. Local analysis then identified and corrected the automatic-variable issue, without claiming it proved the cause of the analyzer crash. Other pre-existing module warnings were left unchanged. The previous runtime run is now cancelled; its incomplete results are not treated as validation of the new fixture/profile.

Prerequisite #11370 changes exactly two Czech test-library calls to the existing FindGeneralPostingSetupInvtBase helper, which reuses or creates a configured posting fixture. The old lookup unconditionally required existing nonblank posting groups. This removes a dependency on another suite's retained data without weakening Codeunit isolation or changing production posting logic. The source trace also found baseline Disabled-runner state leakage; exact baseline CZ suite-state snapshots were not captured. Runtime recovery of the fourteen tests is now verified above. Like #11340, this independently reviewable prerequisite targets main; until merged there, its small diff is included here for combined validation.

The preceding 6d1663c8a7 run verified the DK stale-record scenario passed (DK Default). Isolated discovery did not resolve its 14 CZ fixture failures; those required the separate fixture correction now verified above. That run also exposed three APIV2 RapidStart tests remaining Scheduled when background tasks were disabled, motivating the explicit profile now verified in FI. The superseded run was cancelled after those results were captured; its partial results are not an overall pass.

Typed multi-tenant discovery now uses cloned parameters on the first secondary tenant, restoring that worker from the untouched primary in finally before any template copy or test dispatch. The primary is never the discovery target in that path. Empty discovery and failure paths also restore the worker; Legacy and existing single-tenant behavior are preserved. Tenant IDs and database names must be nonblank and unique before destructive restore operations. This adds one restoration per typed multi-tenant discovery.

The harness no longer enables/disables Task Scheduler or restarts NST for the clean phase. RequiredTestIsolation = Disabled does not imply background tasks should run. Pipeline configuration remains authoritative. The repository explicitly enables background execution only for UncategorizedTests, which contains APIV1/APIV2 RapidStart polling cases. Unit, Integration and Legacy profiles remain unchanged; no new RU lane or app/codeunit allowlist is added. This also supplies the background-task prerequisite for the separately deferred APIV1 polling cases in #11322.

Earlier full runtime evidence (b05ed58024, before the harness/profile corrections)

Both auth run 34532226875 and prerequisite-only run 34532211672 passed all 46 build jobs, but finished failed overall. The repaired Approve/Submit/Reject Travel Request action tests passed in every available Integration artifact: 21 auth countries and 22 on the prerequisite branch. All six provider-contract tests passed on b05ed58024 (W1 Legacy1).

W1 final test cases Passed Failed Skipped
APIV1 441 0 26
APIV2 697 0 21
Expense Agent 865 12 12

Counts combine final Default, Integration and Uncategorized results; they are not HTTP-request counts and do not double-count retries. The 12 Expense failures also occur without the auth changes: six permission tests and six deletion/date/filter tests. Fourteen additional CZ fixture failures and one DK stale-job-queue-record failure occur only in the auth run and pass standalone; their harness association is being investigated, not dismissed because the test source is unchanged. Initial IT/SE capability API HTTP 500 failures recovered on existing retries and remain an instability signal.

The auth run has 114 successful, 47 failed, one cancelled and two skipped workflow jobs (66/113 test jobs passed). Infrastructure/finalization failures also remain. Credential removal succeeded on 111 tasks; no successful removal is inferred for the two interrupted test tasks.

The exact tested merges are b56e307545 (auth) and eb2544f0cb (prerequisite), both against main 3fe923d471. Those revisions, rather than stale branch-only source, underpin the comparison. No new exclusions or unrelated production fixes were added.

The first prerequisite attempt (a4ed3c3f18, auth 2028f76ec0) failed AL0175 because this built-in system option does not support direct = comparison. Those superseded runs were requested to stop after the corrected heads were published. The correction uses Assert.AreEqual(Format(expected), Format(actual), message), now verified by the actual CI compilation and page-action results above. The unchanged auth/scheduler code passed 69 local checks and PowerShell CI on 2028f76ec0.

The preceding initializer head 1916826fc7 reviewed all 160 Graph callers, moved license-safe date setup from OnRun into Initialize, and made provider selection once-only where an existing initialization guard and retained Graph instance permit it. Read-only review of 396c38..1916826 found no significant issues.

Run 34472110108, on 1916826fc7, finished failed at 2026-09-10T17:55:52Z: 68 failed workflow tasks, 94 successful and two skipped. All 67 failed test tasks were classified: 64 confirm CU 148339 CS1503 during discovery; three Uncategorized runners (CA, DE, GB) disconnected, with unavailable logs and confirming check annotations. The remaining failure is the aggregate status check. All 46 Legacy test tasks passed. W1 Legacy1 explicitly reports all six CU 139494 provider-contract methods successful on the initializer-refactored head. Credential removal succeeded on 110 test tasks; the three disconnected runners have no confirmed cleanup result.

Merged upstream main 2b77a80c1c and resolved the Expense exclusion-file conflict, preserving all 22 entries. GitHub reported this PR mergeable; no new BCApps-SyncMirror result was available at the last check. The discovery blocker came from upstream SpendRequestTest.Codeunit.al (CU 148339, introduced by #11007), whose three Assert.AreEqual calls require an unsupported built-in WebServiceActionResultCode to Variant conversion. Discovery compiles the codeunit before test filtering. Prerequisite #11340 compares the formatted actual and expected Updated values, preserving all three assertions and their messages without hardcoding localized text or numeric values. This separately reviewable prerequisite targets main independently; until it is merged there, its three lines are also present in this PR's diff. No PR is automatically merged.

Production head 6cd9bf1a09 passed all six AL provider-contract tests and PowerShell validation. Pull Request Build finished with 112/113 test jobs passing; the overall result is failed, solely due to 14 missing-General-Posting-Setup failures in unchanged Czech advance-payment tests (CUs148108/148109, CZ Default). They remain enabled and are not hidden by new exclusions. Credential cleanup succeeded in all113test jobs, including the failing lane. AL is unchanged from 2a553ac72f, whose Windows validation passed. Historical timing below is not a fresh measurement of this refactor.

Authentication design

  • An extensible API Test Authentication enum selects an API Test Auth Provider; None is the no-op default.
  • Tests explicitly select Microsoft Test Environment in Initialize, on the same codeunit-global Graph instance that sends requests. Selection is after existing early-return guards where the instance is retained (92 callers), inside four existing negative initialization branches, and idempotent in 64 unguarded initializers. Missing or unused initialization paths are reviewed and wired individually; selection is removed from OnRun. No new guard changes existing fixture/callback frequency.
  • Re-selecting the same provider is idempotent: it retains the interface instance and its cached state. AuthenticationProviderResolved remains instance-scoped for lazy default resolution.
  • The interface becomes ConfigureAuthentication(var Authentication: Codeunit "API Test Auth Context"). Providers configure credentials through this narrow context, not a mutable HTTP request.
  • No target-URL parameter or destination guard. Selecting a provider authorizes it to configure every request through that Graph instance, including overridden URLs.
  • The Microsoft provider exits first for SaaS and for Security Group.IsWindowsAuthentication(), the public System Application helper backed by the platform authentication check. It does not infer authentication from a User-table Windows SID or require a User-table read.
  • Otherwise, it reuses a successfully cached SecretText password; if uncached, it reads the protected container password when present, or Key Vault when absent. An unreadable/empty configured credential produces an error rather than silent fallback.
  • Password caching uses one SecretText; the extra resolved/required booleans and cache-result helper are removed.
  • Credential application still uses Http Web Request Mgt.AddBasicAuthentication. OnAfterInitializeWebRequestWithURL remains the final trusted request-customization event.

Partners can extend the enum and implement the provider without depending on Microsoft password-file or Key Vault conventions.

The supported trust boundary is admitted OnPrem test code plus protected secret provisioning, not Access = Internal. Existing public OnPrem Key Vault and file-backed test helpers already expose equivalent credential access in that environment. The wrapper adds no elevated AL permission declarations.

Credential setup records the exact backing path before copying the password. A final always() workflow step stops remaining container consumers and deletes that file before normal container teardown, including failure/cancellation paths where the runner remains available. Cleanup failures are surfaced; abrupt runner/VM loss remains outside the guarantee. The credential is not deleted after the first read or while parallel tests still need it.

Provider regression coverage includes the URL-free contract, no-auth default, final-event ordering, provider reuse, repeated selection, selection changes, and instance isolation. Structural checks cover the early Windows/SaaS exit, credential-source/cache ordering, and initialization entry points.

Test execution and scope

The HTTP request executes in a separate NST session and must see committed setup. Ordinary test transaction isolation cannot make that session part of the AL test transaction.

The scheduler discovers RequiredTestIsolation = Disabled from apps already selected for UnitTest, IntegrationTest and Uncategorized lanes, retaining test-type and disabled-test filters. Legacy buckets retain ordinary execution: the underlying helper ignores required isolation when no test type is supplied, so untyped clean discovery is deliberately not used. There is no separate app allowlist and no country-specific disabled-test logic.

It creates a database template from the primary kept untouched during secondary-tenant discovery, restores secondary tenants before clean codeunit execution, batches restores separately from execution, restores tenants afterward, and merges results into normal JUnit output. It preserves the pipeline's Task Scheduler configuration rather than overriding it. BCApps already had multitenant containers; this uses them as clean workers.

License-safe work dates remain: the helper is used by 117 test codeunits. Historical XML results show 46 distinct methods in 19 codeunits encountering the licensed-date restriction; 117 is the rollout scope, not the demonstrated failure count.

All 117 former OnRun date calls are removed. There are now 117 Initialize date sites, including six existing sites, plus 11 preserved method-local calls. Unlike provider state, WorkDate is session state: the runner reapplies company WorkDate before each method. Therefore the date is set before fixture creation and the initialization guard, not once per codeunit. Seventy-six previously indirect APIV2 test entries now call Initialize before creating fixtures.

The eight business-fixture/product areas below have been removed from this PR. The first seven account for 37 method-specific temporary exclusions across 20 codeunits (21 observed failures plus 16 additional affected methods). The extra APIV1 layer accounts for ten additional conservative exclusions; these are not newly observed failures of the reverted code. This makes 47 temporarily deferred methods, not entire disabled codeunits. Existing nine APIV2 whole-codeunit exclusions and all 22 newer/out-of-scope Expense Agent exclusions remain.

Native GitHub stack #11232

This PR #10085 is the bottom layer, targeting main. Eight follow-up PRs form a native GitHub stack above it, in the order below; each targets the preceding PR's branch and shows only its own fix and corresponding test re-enablement. GitHub's stack UI is available from these PRs. Existing PR numbers were retained without force-pushing any branch.

Area PR
VAT posting setup fixtures #11224
Credit-memo/invoice cancellation reason codes #11225
Italian payment-discount fixture/assertion #11226
Quote posting/document dates #11227
Vendor-payment journal numbering #11228
Additional field-comparison exclusions #11229
Production return-shipment PDF report selection #11230
APIV1 blank-line lookup, RapidStart polling/fixtures, journal handler and invoice Foundation setup #11322

Each fix layer removes only its own temporary exclusions (12, 10, 1, 2, 2, 10, 0, and 10 methods respectively). The top layer restores all 47 methods deferred by the auth base, while preserving pre-existing exclusions. Each child's parent tip is verified as an ancestor, and each comparison is restricted to that layer's intended files.

These are separately reviewable drafts, not claims of completed runtime validation. The repository's current pull-request build trigger targets main, releases/*, and features/*; later updates to layers targeting personal feature branches are not automatically covered by that trigger. No workflow-policy expansion or merge is performed here.

The additional APIV1 layer changes eight AL files plus its exclusion manifest. Its RapidStart fixture-lifetime fix removes that codeunit's guard, so provider selection there becomes per-invocation but stays idempotent; license-safe WorkDate still precedes fixture cleanup/generation. Existing Expense fixture changes are not part of this additional split.

Historical validation and NAV evidence

Prior-head refactor evidence (not validation of the latest initializer changes)

  • Run 34316231134, head 6cd9bf1a09: 160 jobs succeeded, two failed (CZ Default and the aggregate status check), two skipped. Of113test jobs,112passed; no other test lane failed.

  • Final W1 Legacy1 JUnit confirms CU139494 has six cases, zero failures, and zero skips: default no-auth, extended provider/event ordering, reuse, instance scoping, repeated selection, and switching to None.

  • W1 Legacy1 live log confirms ordinary Legacy execution; the erroneous938-codeunit clean-discovery loop is no longer used. All113explicit credential-cleanup steps succeeded.

  • The remaining CI blocker is14Czech purchase/sales advance-payment methods lacking General Posting Setup. Those source files are unchanged by this PR; no workaround or new exclusion was added.

  • NAV Buddybuild2726212 and SDL2726213 passed the identical AL implementation (before the final PowerShell/workflow-only review batch). Gatejob3634036 verifies211APIV1/APIV2Integrationmethods passed under Windows. NAV selection remains unchanged and the known legacy selection gap is not claimed fixed.

  • The refactor's second CI run compiled successfully and produced W1 Integration (2,840 tests) and Uncategorized (2,658 tests) results with zero failures. NAV Buddybuild 2726212 and SDL 2726213 passed; gatejob 3634036 reports 211 APIV1/APIV2 Integration methods passing under Windows.

  • That CI run was not green overall: CZ Default had 14 missing-General-Posting-Setup fixture failures in unchanged advance-payment tests, and US Uncategorized had a client-close timeout despite zero published JUnit assertion failures.

  • A real scheduler regression was then identified: untyped Legacy discovery scheduled 938 ordinary W1 codeunits as clean Disabled work, causing six-hour timeouts and preventing provider-contract results from being collected. 6cd9bf1a09 corrected this; the final run confirmed ordinary Legacy execution and all six provider cases passed. None of the earlier timeouts is described as successful validation.

  • Earlier BCApps head a6fac87c69: Pull Request Build and PowerShell checks passed; 173 checks passed and two skipped. Four provider tests and 50 scheduler/static tests passed at that stage. These are not results for the current refactor.

  • Pointer-only NAV PR #253796, using isolated BCApps cc8167987e: Buddybuild 2721741 and SDL 2721742 passed on merge 066b652da5b7d058e5fd21ac77089849b37381a7. No automatic merge is enabled. NAV selection, native exclusions and company setup were not changed.

  • ADO published no method-level TRX, but gatejob task logs do contain method results. Uptake job 3633108 reported no APIV1/APIV2 methods in W1 web-service execution; its typed Integration task ran APIV1 - Item Variants E2E.TestDeleteInUse successfully.

  • A normal NAV master baseline, job 3633605, reported 806 APIV1/APIV2 methods in W1 web-service execution and all 12 VAT-related methods passing across W1 web-service/Integration tasks. Item Variants TestDeleteInUse also passed in CA and US Integration.

  • The selection gap is separate: NAV's legacy caller uses a Disabled runner but defaults required-isolation selection to None; newly marked Disabled codeunits can be filtered out. It is reported, not fixed here.

  • Configured company names/types match for the seven VAT-related codeunits. NAV restores legacy Extended demo data; BCApps regenerates CRONUS with Contoso and resets clean tenants per codeunit. Matching names and passing baseline methods do not identify the precise causal VAT-data difference.

How much CI time does API enablement add?

The measured increase was about 13-15% in aggregate runner consumption, not a 13-15% increase in developer waiting time. Overall workflow elapsed increased by 2.44 minutes at the median and 5.73 minutes on average.

A paired experiment used fixed control #10904 and API-enabled #10905, with matching harmless CI markers. Run IDs: 33528153281 and 33528158102. Three complete pairs passed (attempts 1, 4 and 8); infrastructure-invalid attempts were excluded.

Metric Mean paired change Median Observed range
W1 aggregate runner time +74.46 min / +14.61% +15.20% +13.06% to +15.57%
All-country aggregate runner time +1,482.42 min / +12.75% +12.84% +11.09% to +14.32%
Longest W1 test job +4.30 min +4.19 min -0.95 to +9.67 min
Longest all-country test job +0.55 min -0.43 min -4.43 to +6.51 min
Overall workflow elapsed +5.73 min +2.44 min +1.37 to +13.38 min

Aggregate runner time sums parallel job durations; it is neither elapsed pipeline time nor measured CPU utilization. Longest-job duration is a critical-path proxy, not a full workflow dependency-path measurement.

There is no dedicated API job. Work is absorbed by existing Default, Integration and Uncategorized lanes. Their mean W1 job-duration increases were +27.66, +13.20 and +27.67 minutes respectively; Legacy lane changes were variable. Build startup and runner allocation also affect overall elapsed time.

Limitations: only three of five planned successful pairs were obtained; subsequent frozen runs hit warning-baseline drift. These measurements cover the earlier broader API-enabled implementation, before the current business-fix split and initialization/provider refactor. They are the available empirical estimate, not a guaranteed increase or a fresh measurement of the final refactored PR.

@t-prda
Prangshuman Das (t-prda) requested review from a team August 10, 2026 11:01
@github-actions github-actions Bot added Build: scripts & configs Build scripts and configuration files AL: Apps (W1) Add-on apps for W1 Team: Integrations GitHub request for Integrations area labels Aug 10, 2026
@github-actions github-actions Bot added this to the Version 29.0 milestone Aug 10, 2026
Comment thread build/scripts/NewBcContainer.ps1 Fixed
Comment thread build/scripts/NewBcContainer.ps1 Fixed
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
@t-prda
Prangshuman Das (t-prda) marked this pull request as draft August 10, 2026 11:20

Copilot AI left a comment

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.

Pull request overview

This PR centralizes Basic authentication injection for Library - Graph Mgt-based API tests so they can run in NavUserPassword (UserPassword) containers, and then re-enables several previously disabled API/E2E test suites. It replaces an app-specific Expense Agent auth helper with a shared TestLibraries subscriber and adds a container-side “credential bridge” file so the test runner can obtain the password without requiring Azure Key Vault.

Changes:

  • Added Library - Graph Auth Mgt. as an event subscriber to inject Basic auth for non-Windows test users, sourcing the password from a container file or (fallback) Azure Key Vault.
  • Removed the Expense Agent test-only auth helper + manual subscription binding; tests now rely on the shared subscriber.
  • Re-enabled multiple API/E2E test suites by removing entries from various *.DisabledTest.json files (and deleting the APIV1/APIV2 exclusion lists), and updated container provisioning to create the API-test password bridge file.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al New shared subscriber that injects Basic auth into Library - Graph Mgt requests for NavUserPassword scenarios.
build/scripts/NewBcContainer.ps1 Writes the container password bridge file and sets ACLs so server-side AL can read it.
src/Apps/W1/ExpenseAgent/test/src/Helper/ExpenseAPITestAuthHelper.Codeunit.al Removes app-specific auth injection helper in favor of shared TestLibraries implementation.
src/Apps/W1/ExpenseAgent/test/src/API/ExpenseUsersAPITest.Codeunit.al Drops manual subscription binding to the removed helper.
src/Apps/W1/ExpenseAgent/test/src/API/ExpenseProjectsAPITest.Codeunit.al Drops manual subscription binding to the removed helper.
src/Apps/W1/ExpenseAgent/test/src/API/ExpensePerDiemLocationsTest.Codeunit.al Drops manual subscription binding to the removed helper.
src/Apps/W1/ExpenseAgent/test/src/API/ExpenseCapabilitiesAPITest.Codeunit.al Drops manual subscription binding to the removed helper.
src/DisabledTests/Tests-Integration/Tests-Integration.DisabledTest.json Re-enables specific integration API tests by removing disable entries.
src/DisabledTests/Tests-Graph/Tests-Graph.DisabledTest.json Re-enables specific Graph E2E tests by removing disable entries.
src/DisabledTests/Sustainability_Tests/Sustainability_Tests.DisabledTest.json Re-enables Sustainability API tests by removing disable entries.
src/DisabledTests/Quality_Management-Tests/Quality_Management-Tests.DisabledTest.json Re-enables Quality Management API tests by removing disable entry.
src/DisabledTests/IRS_Forms_Tests/IRS_Forms_Tests.DisabledTest.json Re-enables IRS 1099 API test by removing disable entry.
src/DisabledTests/E-Document_Core_Tests/E-Document Core Tests.DisabledTest.json Re-enables E-Document API tests by removing disable entry.
src/DisabledTests/_Exclude_APIV2__Tests/_Exclude_APIV2__Tests.DisabledTest.json Deletes the APIV2 exclusion list (re-enables APIV2 suite).
src/DisabledTests/_Exclude_APIV1__Tests/_Exclude_APIV1__Tests.DisabledTest.json Deletes the APIV1 exclusion list (re-enables APIV1 suite).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread build/scripts/NewBcContainer.ps1 Outdated
Comment thread build/scripts/NewBcContainer.ps1 Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread build/scripts/NewBcContainer.ps1 Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
@t-prda

Copy link
Copy Markdown
Contributor Author

Agentic PR Review - Round 1

Recommendation: Accept

What this PR does

This PR adds an explicit authentication bridge for API tests that use Library - Graph Mgt. in BCApps UserPassword containers. The subscriber is manual, each affected API test codeunit opts in, Windows-authenticated NAV gates keep their existing behavior, and local NAV UserPassword runs can use the existing Key Vault secret.

The change addresses the gate difference directly. It does not change application API behavior, and it avoids making partner test code automatically depend on the BCApps credential bridge.

Suggestions

None.

Risk assessment and necessity

Risk: The change touches shared test infrastructure and re-enables many existing suites, so CI isolation and concurrency failures may still need separate gate work. The authentication subscriber itself is manually scoped and internal.

Necessity: The change is required because BCApps runs these tests with UserPassword while NAV's normal uptake gates use Windows authentication. Without the bridge, the API suites fail with 401 responses and remain disabled.


[AI-PR-REVIEW] version=1 promptVersion=1 system=github pr=10085 round=1 by=t-prda at=2026-08-12T09:27:33Z lastSha=6fe7981474d813fcafab57bc6e6fa0c429df80a5 reviewKey=e0d301ad1af589367637a08b287af9af4fb26402df7532abc2876a0a48dbabc7 suggestions=none

@github-actions github-actions Bot added the Build: Automation Workflows and other setup in .github folder label Aug 13, 2026
/// <summary>
/// Specifies the authentication provider used for API test requests.
/// </summary>
enum 131023 "API Test Authentication" implements "API Test Auth Provider"

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.

$\textbf{🟡\ Medium\ Severity\ —\ Interfaces}$

This new authentication seam is modelled as an extensible enum that implements the interface, so tests must extend the enum just to inject a mock provider. For an injectable dependency, prefer accepting Interface "API Test Auth Provider" directly and assign the implementing codeunit to the interface variable; keep enum-backed selection only as optional convenience wiring.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

Caption = 'None';
Implementation = "API Test Auth Provider" = "No API Test Auth Provider";
}
value(1; "Microsoft Test Environment")

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.

$\textbf{🟠\ High\ Severity\ —\ Security}$

The new public authentication selector exposes privileged work that only looks protected by Access = Internal: any dependent test app can select Enum::"API Test Authentication"::"Microsoft Test Environment" and drive Library - Graph Mgt to attach the current environment's API-test password to a caller-chosen request. internal is not an authorization boundary; keep this provider behind a non-public selector or add an explicit authorization/host restriction before credentials are applied.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

codeunit 139842 "APIV2 - Pictures E2E"
{
Subtype = Test;
RequiredTestIsolation = Disabled;

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.

$\textbf{🔴\ Critical\ Severity\ —\ Testing}$

This PR starts opting the API E2E suites into RequiredTestIsolation = Disabled even though the tests commit setup data before calling the API (for example this codeunit commits customers, vendors, items, contacts, and pictures in nearly every test). That means the suite now runs under a non-isolating runner while leaving committed records behind for later tests, creating order-dependent results instead of a clean database per test/codeunit.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 11

Recommendation: Accept with Suggestions

What this PR does

This change adds shared API test authentication, container password provisioning and cleanup, and clean-tenant scheduling so API tests can run under UserPassword without breaking ambient-auth environments.

The approach fits the problem: the provider exits for ambient authentication, Basic auth is applied through the shared Graph test library when needed, and the broad API test opt-in matches the enablement scope. The remaining concerns are in the runner: the transient classifier is still too broad, and clean Disabled-isolation result files can collide with later tenant result files.

Status of previous suggestions
ID Title Status Author response
S1 Separate the production report change Addressed The production report file remains outside the current net diff.
S2 Cache the mock Key Vault setup Addressed Still addressed in the current provider implementation.
S3 Keep the affected-app test exact Addressed Still addressed in the current scheduler tests.
S4 Clarify the E-Doc Graph variables Addressed Still addressed in the current E-Document test changes.
S5 Clean up the container password file Addressed The cleanup path remains registered, stopped, and deleted through the exact backing file flow.
New observations (commits since round 10)

S6 (🟠 Moderate): Narrow the transient error match
The new transient detector matches any ClientSession State is InError, not only the known page-130455 race. That can re-run a real client or test failure as a transient platform issue. Please include the specific page 130455 or InteractionManager context in this match.

S7 (🟠 Moderate): Use separate clean-test result files
Clean Disabled-isolation codeunits write to the same tenant-suffixed result files that normal app jobs use later. A later normal job on that tenant can replace the clean-codeunit XML before the final merge. Please use a distinct suffix for clean-codeunit jobs and merge it explicitly.

Risk assessment and necessity

Risk: Product behavior is not changed, but this test-infrastructure path can hide failures or lose published test evidence. Credential handling now creates a shared file in the container mount; the ACL and cleanup flow reduce exposure, while abrupt runner loss remains outside the code guarantee.

Necessity: The API tests cannot be broadly re-enabled in UserPassword containers unless the HTTP request session can authenticate and Disabled-isolation tests have fresh tenant workers. The scope is appropriate for a test-enablement base, with business fixture fixes kept separate.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=10085 round=11 by=alexei-dobriansky at=2026-09-10T06:30:39Z lastSha=396c38c8c3a209011e68bfd082f7aef9bc2d2f23 reviewKey=53b451d962b2311d960e22f010ae640c1ef7048c019c4aa37eed85dede185c08 suggestions=S1@b79ed4f7:addressed,S2@373f05d4:addressed,S3@daa56c26:addressed,S4@7d6c760a:addressed,S5@227b86e9:addressed,S6@8ea4b299:new,S7@66cd1f4e:new parentRound=10

Follow reviewed global-instance lifetimes: provider after existing initialization guards, work date per test. Separate residual APIV1 reliability fixes and preserve deferred method scope for an additional native-stack layer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Assert.IsTrue(LibraryGraphMgt.GetObjectIDFromJSON(ResponseText, 'id', ApprovalEntryId), 'Could not find approval entry');
end;

local procedure Initialize()

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.

$\textbf{🟡\ Medium\ Severity\ —\ Testing}$

This PR's rollout re-enables broad API/E2E coverage, but 37 of the changed test codeunits call LibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::"Microsoft Test Environment") in their Initialize procedure without also calling LibraryGraphMgt.SetLicenseSafeWorkDate(), unlike the other ~113+ peer suites updated in the same PR. That leaves these tests running on the ambient work date instead of the November-15 license-safe date the rest of the rollout now depends on, which is inconsistent and could reintroduce the license/date sensitivity this change set is otherwise fixing, especially for the tests being re-enabled via the large deletions in _Exclude_APIV1__Tests.DisabledTest.json, _Exclude_APIV2__Tests.DisabledTest.json, and Expense_Agent_Tests.DisabledTest.json. Recommend confirming this omission is intentional (e.g. those specific suites are date-insensitive) or adding the missing SetLicenseSafeWorkDate() call for consistency.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

VerifyNoRemainingCalls();
end;

local procedure Initialize()

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.

$\textbf{🟡\ Medium\ Severity\ —\ Testing}$

API Test Auth Provider Tests (codeunit 139494) forces EnvironmentInfoTestLibrary.SetTestabilitySoftwareAsAService(false) inside its Initialize() procedure and never restores the prior environment setting afterward. Environment Info Test Library mocks a SingleInstance-like environment flag, so if this codeunit does not run with full test isolation, later tests executed in the same session can inherit the forced on-prem environment mock and exercise authentication logic (which branches on EnvironmentInfo.IsSaaSInfrastructure() in Microsoft Test Auth Provider) under the wrong environment contract, making suite behavior order-dependent. Recommend explicitly restoring the previous environment setting (or bracketing the mock per test) rather than relying on isolation defaults.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 12

Recommendation: Accept with Suggestions

What this PR does

This change adds shared authentication for API tests, prepares clean tenants for tests that require disabled isolation, and re-enables the affected API suites under UserPassword while preserving ambient-auth runs.

The latest commit moves license-safe dates into each test initialization path and keeps provider selection once-only where the Graph library instance is retained. That direction is sound: the static scan found all 160 Graph-requesting test codeunits still select the Microsoft test provider, none select it from OnRun, and the date setup is no longer left in OnRun. The two runner concerns from the prior review are still open.

Status of previous suggestions
ID Title Status Author response
S1 Separate the production report change Addressed The production report file remains outside the current net diff.
S2 Cache the mock Key Vault setup Addressed The provider still caches only a successfully resolved password and keeps the container credential ahead of the fallback source.
S3 Keep the affected-app test exact Addressed The structural test still checks the exact Graph-requesting codeunits and now covers 160 callers.
S4 Clarify the E-Doc Graph variables Addressed The current diff does not reintroduce the unclear Graph variable pattern.
S5 Clean up the container password file Addressed The setup still records the exact backing file and the final cleanup stops consumers before deleting that file.
S6 Narrow the transient error match Not addressed The classifier still treats a plain ClientSession State is InError as transient without the page 130455 or InteractionManager context.
S7 Use separate clean-test result files Not addressed Clean disabled-isolation codeunits still use tenant-suffixed result files that normal app jobs can reuse later.
New observations (commits since round 11)

None - the latest changes only move authentication/date setup into initialization paths and did not add a new changed-span issue.

Risk assessment and necessity

Risk: Product behavior is unchanged, but the test-infrastructure path is broad. The remaining risk is that the runner may retry a real failure as transient, or lose clean-codeunit result evidence when a later normal job writes the same tenant result file. Current runtime CI is still pending.

Necessity: The API suites need a shared authentication path and clean disabled-isolation execution to run reliably in UserPassword containers. The scope remains justified, and the latest initialization changes are necessary to keep test dates license-safe before fixtures are created.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=10085 round=12 by=alexei-dobriansky at=2026-09-10T12:31:33Z lastSha=1916826fc70638192a121738a18b6c2c3075a5d5 reviewKey=22a838a5888a96ec139cfbcb063d62adfe14c3aa07043620e7dc837d637587f9 suggestions=S1@b79ed4f7:addressed,S2@373f05d4:addressed,S3@daa56c26:addressed,S4@7d6c760a:addressed,S5@227b86e9:addressed,S6@8ea4b299:notaddressed,S7@66cd1f4e:notaddressed parentRound=11

Compare the built-in WebServiceActionResultCode directly and pass the Boolean to Assert.IsTrue instead of requiring an unsupported Variant conversion. Preserve the expected Updated value, diagnostics, fixtures and exclusions.

AB#646383

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Include the three-line assertion fix from PR #11340 so typed API-test discovery can compile CU 148339. Keep existing exclusions and authentication behavior unchanged.

AB#646383

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
/// <summary>
/// Leaves API test requests configured with the transport's default authentication behavior.
/// </summary>
codeunit 131024 "No API Test Auth Provider" implements "API Test Auth Provider"

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.

$\textbf{🟡\ Medium\ Severity\ —\ Breaking\ Changes}$

The new codeunit "No API Test Auth Provider" is public even though it looks like an implementation detail behind the public enum/interface-based authentication extension point. Leaving it public makes the concrete provider itself part of the supported API surface; mark the object internal and keep only the intended extensibility contract public.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

codeunit 131024 "No API Test Auth Provider" implements "API Test Auth Provider"
{
    Access = Internal;

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

if IsInitialized then
exit;

BindSubscription(APITestAuthProviderTests);

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.

$\textbf{🟠\ High\ Severity\ —\ Events}$

This test codeunit correctly uses a manual subscriber for scoped behavior, but it binds the global APITestAuthProviderTests instance in Initialize() and never unbinds it. Because that bound instance outlives the Initialize() call, later unrelated requests in the same session can still hit RecordFinalRequestEvent and keep mutating the recorder. Bind the subscriber only for each test's active scope, or add a matching UnbindSubscription when that scope ends.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

…insic

Direct equality of WebServiceActionResultCode is rejected by AL0175. Format emits the explicit ALCompiler.ToNavValue system-option conversion; compare both formatted values while retaining the expected Updated code and existing diagnostics.

AB#646383

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Use the corrected Format-based assertions from PR #11340. Retain all authentication, initialization, exclusion and stack scope decisions.

AB#646383

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
/// <param name="Authentication">The authentication context to configure.</param>
procedure ConfigureAuthentication(var Authentication: Codeunit "API Test Auth Context")
var
Password: SecretText;

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.

$\textbf{🟡\ Medium\ Severity\ —\ Security}$

The mock auth provider needlessly materializes the Basic-auth password in a plain Text local before converting it to SecretText. Keep the credential in SecretText from creation to the HTTP sink so it never becomes debugger-visible plain text.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        Password: SecretText;
    begin
        InvocationCount += 1;
        APITestAuthRecorder.RecordCall(StrSubstNo(ProviderCallTok, InvocationCount));
        Password := SecretText.SecretStrSubstNo(PasswordTxt);

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

Run typed multi-tenant discovery on a secondary tenant and restore it from the untouched primary in finally before template creation or dispatch. Preserve Legacy and single-tenant behavior. Do not override the pipeline Task Scheduler configuration. Add stateful discovery, restoration, failure-path and tenant-safety regressions; 88 mocked checks pass.

AB#646383

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 13

Recommendation: Accept with Suggestions

What this PR does

This change adds shared authentication for API tests, prepares clean tenants for tests that require disabled isolation, and re-enables the affected API suites under UserPassword while preserving ambient-auth runs.

The latest commits are targeted. The action-result assertions now compare formatted option values, which avoids the unsupported direct comparison. The clean-test discovery path now uses a secondary tenant, restores it from the primary database before template creation, and leaves the configured Task Scheduler state alone. Those updates address the latest harness concerns without changing product behavior. The two older runner concerns below are still open.

Status of previous suggestions
ID Title Status Author response
S1 Separate the production report change Addressed Still outside the current net diff.
S2 Cache the mock Key Vault setup Addressed The provider still caches only a successfully resolved password and keeps the container credential ahead of the fallback source.
S3 Keep the affected-app test exact Addressed The structural test still checks the exact Graph-requesting codeunits and the current scope.
S4 Clarify the E-Doc Graph variables Addressed The current diff does not reintroduce the unclear Graph variable pattern.
S5 Clean up the container password file Addressed The setup still records the backing file and the final cleanup stops consumers before deleting it.
S6 Narrow the transient error match Not addressed The classifier still treats a plain ClientSession State is InError as transient without the page 130455 or InteractionManager context.
S7 Use separate clean-test result files Not addressed Clean disabled-isolation codeunits still start jobs with the tenant suffix, so later normal app jobs on the same tenant can reuse that result file.
New observations (commits since round 12)

None - the latest changes address fixture preservation, task scheduling, and the action-result assertion compile issue without adding a new changed-span issue.

S6 (🟠 Moderate): Narrow the transient error match
The transient detector still matches any ClientSession State is InError. That can re-run a real client or test failure as a transient platform issue. Please include the specific page 130455 or InteractionManager context in this match.

S7 (🟠 Moderate): Use separate clean-test result files
Clean Disabled-isolation codeunits still write through the normal tenant-suffixed result file path. A later normal job on that tenant can replace that XML before the final merge. Please use a distinct suffix for clean-codeunit jobs and merge it explicitly.

Risk assessment and necessity

Risk: Product behavior is unchanged, but the test-infrastructure path is broad. The latest changes reduce risk by preserving the primary fixture and by not overriding Task Scheduler. The remaining risk is that the runner may retry a real failure as transient, or lose clean-codeunit result evidence when a later normal job writes the same tenant result file. The current runtime validation is still in progress.

Necessity: The API suites need a shared authentication path and clean disabled-isolation execution to run reliably in UserPassword containers. The latest fixture and scheduler changes are necessary to keep discovery from dirtying the primary tenant and to respect the pipeline's configured background-task behavior.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=10085 round=13 by=alexei-dobriansky at=2026-09-11T09:55:52Z lastSha=6d1663c8a79e2349ca272d06ed54c1965503c59e reviewKey=1146309fc1297acb1df190322533216683f3d31e121b31efb7ce85ac2d4308db suggestions=S1@b79ed4f7:addressed,S2@373f05d4:addressed,S3@daa56c26:addressed,S4@7d6c760a:addressed,S5@227b86e9:addressed,S6@8ea4b299:notaddressed,S7@66cd1f4e:notaddressed parentRound=12

Configure enableTaskScheduler only for the existing UncategorizedTests build mode, which contains APIV1/APIV2 RapidStart polling tests. Leave Unit, Integration and Legacy profiles unchanged and keep the harness from overriding configuration. Preserve RU existing lane selection. Add profile/dependency coverage; 92 mocked checks pass.

AB#646383

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Comment thread build/scripts/tests/ParallelTestExecution.Test.ps1 Fixed
Use the existing find-or-create general posting setup helper in the sales and purchase test libraries instead of requiring data left by another test suite. No production logic or isolation settings change.

AB#646383

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Bring in PR #11370 so the advance-payment tests find or create their own posting fixture under Codeunit isolation. Preserve production logic, authentication behavior, exclusions and scheduler policy.

AB#646383

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Rename the loop variable without changing runtime code or profile configuration. The changed file has zero PSScriptAnalyzer findings and all 92 mocked checks pass.

AB#646383

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
procedure InitializeWebRequestWithURL(var HttpWebRequestMgt: Codeunit "Http Web Request Mgt."; TargetURL: Text)
begin
HttpWebRequestMgt.Initialize(TargetURL);
ApplyAuthentication(HttpWebRequestMgt);

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.

$\textbf{🟠\ High\ Severity\ —\ Security}$

InitializeWebRequestWithURL now calls ApplyAuthentication(HttpWebRequestMgt) before raising the public integration event OnAfterInitializeWebRequestWithURL(HttpWebRequestMgt). Because HttpWebRequestMgt is passed as a var parameter, any extension subscribing to this event now receives an already-authenticated request object (e.g. carrying an Authorization header/token set by the active auth provider). This effectively exposes authentication material through an integration-event surface that any subscriber on the tenant can read. Consider raising the event before authentication is applied, or exclude auth-bearing objects from event parameters.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

# No-op for single-app/single-tenant.
$pending = @(Invoke-WarmupDispatch -Parameters $parameters -Pending $pending -AppIdByName $appIdByName `
-Tenants $tenants -ScriptPath $scriptPath -TestType $testType -State $state)
-Tenants $tenants -ScriptPath $scriptPath -TestType $testType -State $state `

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.

$\textbf{🟡\ Medium\ Severity\ —\ Testing}$

Invoke-ParallelTestExecution() passes -SkipAutomaticDisabledPass on every warmup, normal, and rerun dispatch instead of only for apps explicitly moved to the clean-tenant RequiredTestIsolation=Disabled lane. In UnitTest runs this suppresses the fallback pass in RunTestsInBcContainer.ps1 for ordinary apps too, so an app whose clean-tenant discovery is empty or incomplete can silently miss its disabled-isolation test coverage. Thread the actual clean-tenant app set through these call sites and only skip the fallback for those apps.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.41.6

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 14

Recommendation: Accept with Suggestions

What this PR does

This change adds shared authentication for API tests, prepares clean tenants for tests that require Disabled isolation, and re-enables affected API suites under UserPassword while keeping ambient-auth runs.

The latest commits are targeted. They enable background task execution only for the Uncategorized test profile, make the Czech advance-payment test fixtures create or reuse a posting setup with inventory accounts, and avoid shadowing PowerShell's automatic profile variable in the profile tests. These changes address the latest scheduler, fixture, and analyzer concerns without changing product behavior. The two older runner concerns below are still open.

Status of previous suggestions
ID Title Status Author response
S1 Separate the production report change Addressed Still outside the current net diff.
S2 Cache the mock Key Vault setup Addressed The provider still caches only a successfully resolved password and keeps the container credential ahead of the fallback source.
S3 Keep the affected-app test exact Addressed The structural test still checks the exact Graph-requesting codeunits and the current scope.
S4 Clarify the E-Doc Graph variables Addressed The current diff does not reintroduce the unclear Graph variable pattern.
S5 Clean up the container password file Addressed The setup still records the backing file and the final cleanup stops consumers before deleting it.
S6 Narrow the transient error match Not addressed The classifier still treats a plain ClientSession State is InError as transient without the page 130455 or InteractionManager context.
S7 Use separate clean-test result files Not addressed Clean Disabled-isolation codeunits still start jobs with the tenant suffix, so later normal app jobs on the same tenant can reuse that result file.
New observations (commits since round 13)

None - the latest commits address the scheduler profile, Czech posting fixtures, and the profile-test variable name without adding a new changed-span issue.

S6 (🟠 Moderate): Narrow the transient error match
The transient detector still matches any ClientSession State is InError. That can re-run a real client or test failure as a transient platform issue. Please include the specific page 130455 or InteractionManager context in this match.

S7 (🟠 Moderate): Use separate clean-test result files
Clean Disabled-isolation codeunits still write through the normal tenant-suffixed result file path. A later normal job on that tenant can replace that XML before the final merge. Please use a distinct suffix for clean-codeunit jobs and merge it explicitly.

Risk assessment and necessity

Risk: Product behavior is unchanged, but the test runner path is broad. The latest changes reduce risk by enabling the scheduler only for the Uncategorized profile and by making the Czech fixtures self-contained. The remaining risk is that the runner may retry a real failure as transient, or lose clean-codeunit result evidence when a later normal job writes the same tenant result file. Current runtime validation is still in progress.

Necessity: The API suites need a shared authentication path and clean Disabled-isolation execution to run reliably in UserPassword containers. The latest fixture and scheduler changes are necessary to keep polling tests runnable and to remove a dependency on retained Czech fixture data.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=10085 round=14 by=alexei-dobriansky at=2026-09-11T12:58:20Z lastSha=25916aeb859666d6b30939000cac2b41cf2febba reviewKey=5d8f67c72b60a9c40a0eea16f305c7493db065a5f37ed2bbbd7ebfdeef21ccf0 suggestions=S1@b79ed4f7:addressed,S2@373f05d4:addressed,S3@daa56c26:addressed,S4@7d6c760a:addressed,S5@227b86e9:addressed,S6@8ea4b299:notaddressed,S7@66cd1f4e:notaddressed parentRound=13

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AL: Apps (W1) Add-on apps for W1 Build: Automation Workflows and other setup in .github folder Build: scripts & configs Build scripts and configuration files ExpenseManagement Team: SCM GitHub request for SCM area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants