Skip to content

Enable cloud-migration ReplicateData test (CU 135160 TestReplicateDataProperty)#9423

Open
aholstrup1 wants to merge 12 commits into
mainfrom
aholstrup1-automatic-disco
Open

Enable cloud-migration ReplicateData test (CU 135160 TestReplicateDataProperty)#9423
aholstrup1 wants to merge 12 commits into
mainfrom
aholstrup1-automatic-disco

Conversation

@aholstrup1

@aholstrup1 aholstrup1 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

What & why

Codeunit 135160 "Cloud Migration Property Test" has a single test, TestReplicateDataProperty, which asserts that no table is included in cloud migration unless it is on the approved list — i.e. developers must set ReplicateData = false on tables that should not be migrated from on-prem. That test was on the CI disabled-test skip list, so it never ran, and a large backlog of tables shipping with the wrong ReplicateData property accumulated undetected.

This PR re-enables only that test and introduces a mechanism to temporarily exclude the apps that currently still ship offending tables, so the check can be turned back on now while the debt is burned down per-app. The 10 Test Granules permission-set checks in the same test app stay disabled for now (separate follow-up).

What changed

  • src/DisabledTests/Tests-NewObjects-Internal/Tests-NewObjects-Internal.DisabledTest.json — restored with the 10 Test Granules methods still disabled; only the TestReplicateDataProperty entry is removed, re-enabling that single test in CI.
  • src/Layers/W1/Tests/NewObjectTests-Internal/CloudMigrationPropertyTest.Codeunit.al — adds an app-id exclusion mechanism (mirrors PR Re-enable Data Classification test (CU 135153 TestDataSensitivities) in CI #9114):
    • GetAppsPendingCloudMigrationProperty — a temporary allow-list of app ids (78 apps) that still ship tables with incorrect ReplicateData.
    • IsTablePendingCloudMigrationProperty — resolves an offending table to its owning app via AllObj."App Package ID" -> NAV App Installed App."App ID" and skips it if the app is grandfathered.
    • Any offending table whose owning app is not on the list still fails the test, so new regressions are caught.
  • src/System Application/Test/.../TestMediaCleanup.Table.al and RecordReferenceTest.Table.al — set ReplicateData = false directly. These two System Application test tables are the only offenders outside src/Apps, so they are fixed rather than grandfathered.
  • .github/AL-Go-Settings.json — adds src/DisabledTests/* to fullBuildPatterns so edits to disabled-test lists trigger a full CI test run.

Linked work

Fixes #

How I validated this

  • I read the full diff and it contains only changes I intended.
  • I built the affected app(s) locally with no new analyzer warnings.
  • I ran the change in Business Central and confirmed it behaves as expected.
  • I added or updated tests for the new behavior, or explained below why none are needed.

What I tested and the outcome

The grandfather app-id list was derived empirically from the actual TestReplicateDataProperty failures across all 22 country builds of a prior CI run (543 distinct offending tables mapped to their owning apps). CI on this PR is the validation that the test now passes with the 78 apps grandfathered and the 2 System App tables fixed.

Risk & compatibility

The exclusion list is a temporary bridge and must burn down to zero as each app sets ReplicateData = false on its offending tables. New tables in apps that are not on the list are still enforced, so this does not create a blind spot for other apps. No product runtime behavior changes.

@aholstrup1 aholstrup1 requested review from a team July 14, 2026 11:24
@github-actions

Copy link
Copy Markdown
Contributor

Could not find a linked ADO work item. Please link one by using the pattern 'AB#' followed by the relevant work item number. You may use the 'Fixes' keyword to automatically resolve the work item when the pull request is merged. E.g. 'Fixes AB#1234'

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Copilot PR Review

Iteration 5 · Outcome: completed

Knowledge source: https://github.com/microsoft/BCQuality@186d8a131465475c79244d994acb872cd5c0d4bf

Orchestrator pre-filter (2 file(s) excluded)

  • layer-disabled (knowledge) : 2 file(s)

Findings produced by the AL review agent v1.7.3. Reply 👎 on any inline comment to flag false positives.

@aholstrup1 aholstrup1 requested a review from a team as a code owner July 15, 2026 06:17
@github-actions github-actions Bot added the Build: scripts & configs Build scripts and configuration files label Jul 15, 2026
Convert the 7 permission-set checks in CU 132532 from fail-fast to accumulate-and-report so a single test run surfaces the complete list of violations instead of only the first one. Reuses the existing ArrayList + String.Join pattern already used by AllAppTablesAreInPermissionSet.
begin
// If this test fails, it means that you added a local Table but forgot to add it to the local permission set
// If the table uses inherent permissions, it is excluded from this check by adding to GetTablesWithInherentEntitlements
Errors := Errors.ArrayList();

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\ —\ Error\ Handling} \quad \color{gray}{\texttt{\small Iteration\ 3}}$

AllLocalAppObjectsAreInLocalPermissionSet hand-rolls error aggregation with a DotNet ArrayList and String.Join instead of using the platform's ErrorBehavior::Collect feature.

This reimplements collection, loses each violation's ErrorInfo structure, and skips telemetry classification. The pattern is copied identically into 4 other test methods in this same codeunit (AllLocalAppObjectsAreInO365FullPermissionSet, AllLocalAppObjectsAreInO365BusFullPermissionSet, AllPermissionsAreObjects, VerifyTempPSinPS), each expanding this anti-pattern's footprint.

Recommendation:

  • mark the per-item validation as a separate procedure attributed [ErrorBehavior(ErrorBehavior::Collect)] invoked via Codeunit.Run, then call HasCollectedErrors()/GetCollectedErrors(true) to build the final aggregate error.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

// If this test fails, it means that you added a local Table but forgot to add it to the O365 Full Access permission set
// To do this, open COD101982 and add the Object here.
// If the table uses inherent permissions, it is excluded from this check by adding to GetTablesWithInherentEntitlements
Errors := Errors.ArrayList();

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\ —\ Error\ Handling} \quad \color{gray}{\texttt{\small Iteration\ 3}}$

AllLocalAppObjectsAreInO365FullPermissionSet hand-rolls error aggregation with a DotNet ArrayList and String.Join instead of the platform's ErrorBehavior::Collect feature, reimplementing collection and losing per-violation ErrorInfo structure.

See the sibling finding on AllLocalAppObjectsAreInLocalPermissionSet in this same file for the recommended fix (per-item procedure attributed [ErrorBehavior(ErrorBehavior::Collect)], then HasCollectedErrors()/GetCollectedErrors(true)).

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

// If this test fails, it means that you added a local Table but forgot to add it to the O365 Bus Full Access permission set
// To do this, open COD101982 and add the Object here.
// If the table uses inherent permissions, it is excluded from this check by adding to GetTablesWithInherentEntitlements
Errors := Errors.ArrayList();

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\ —\ Error\ Handling} \quad \color{gray}{\texttt{\small Iteration\ 3}}$

AllLocalAppObjectsAreInO365BusFullPermissionSet hand-rolls error aggregation with a DotNet ArrayList and String.Join instead of the platform's ErrorBehavior::Collect feature, reimplementing collection and losing per-violation ErrorInfo structure.

See the sibling finding on AllLocalAppObjectsAreInLocalPermissionSet in this same file for the recommended fix.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

begin

// CopyAllAppTableObjectsToTempBuffer and CopyAllTablePermissionsToTempBuffer to contain correct ranges
Errors := Errors.ArrayList();

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\ —\ Error\ Handling} \quad \color{gray}{\texttt{\small Iteration\ 3}}$

AllPermissionsAreObjects hand-rolls error aggregation with a DotNet ArrayList and String.Join instead of the platform's ErrorBehavior::Collect feature, reimplementing collection and losing per-violation ErrorInfo structure.

See the sibling finding on AllLocalAppObjectsAreInLocalPermissionSet in this same file for the recommended fix.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

Errors: DotNet ArrayList;
String: DotNet String;
begin
Errors := Errors.ArrayList();

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\ —\ Error\ Handling} \quad \color{gray}{\texttt{\small Iteration\ 3}}$

VerifyTempPSinPS hand-rolls error aggregation with a DotNet ArrayList and String.Join instead of the platform's ErrorBehavior::Collect feature, reimplementing collection and losing per-violation ErrorInfo structure.

See the sibling finding on AllLocalAppObjectsAreInLocalPermissionSet in this same file for the recommended fix.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

Mirror the CU 132532 permission-set accumulate-and-report change into the CZ layer copy to satisfy MicroApp propagation validation. CZ's intentionally commented-out local permission-set check is left unchanged.
@github-actions

Copy link
Copy Markdown
Contributor

$\textbf{🟠\ High\ Severity\ —\ Error\ Handling} \quad \color{gray}{\texttt{\small Iteration\ 4}}$

Multiple test methods in this codeunit now hand-roll error accumulation with a DotNet ArrayList (Errors.Add(...) inside a loop, then Error(String.Join(...)) at the end) instead of using the platform's ErrorBehavior::Collect feature.

The referenced guidance calls this exact shape an anti-pattern: it reimplements the collection feature, loses each failure's ErrorInfo structure, and skips telemetry classification. The change is functionally reasonable (report every missing permission/table instead of stopping at the first), but the same outcome is achievable by marking a per-item check procedure ErrorBehavior::Collect, invoking it via Codeunit.Run per item, and aggregating with HasCollectedErrors()/GetCollectedErrors(true) as the good sample shows.

Knowledge:

Line mapping was unavailable, so this was posted as an issue comment.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

Groenbech96
Groenbech96 previously approved these changes Jul 16, 2026
Re-scope the PR to enable just the cloud-migration ReplicateData check (CU 135160 TestReplicateDataProperty) and keep the 10 Test Granules permission-set checks disabled for now.

- Tests-NewObjects-Internal.DisabledTest.json: restore the 10 Test Granules entries, remove only TestReplicateDataProperty so it runs in CI.

- CloudMigrationPropertyTest.Codeunit.al: add GetAppsPendingCloudMigrationProperty / IsTablePendingCloudMigrationProperty to temporarily exempt the 78 src/Apps apps that still ship tables with incorrect ReplicateData, so new regressions in other apps are still caught. List must burn down to zero.

- TestMediaCleanup / RecordReferenceTest (System Application test tables): set ReplicateData = false directly instead of grandfathering, since they are outside src/Apps.

- Revert the accumulate-and-report changes to Test Granules (W1 + CZ) since those tests stay disabled in this scope.

- AL-Go-Settings.json: add src/DisabledTests/* to fullBuildPatterns so disabled-test edits trigger a full test run.
@aholstrup1 aholstrup1 changed the title Re-enable Tests-NewObjects-Internal disabled tests Enable cloud-migration ReplicateData test (CU 135160 TestReplicateDataProperty) Jul 16, 2026
@github-actions github-actions Bot added Build: Automation Workflows and other setup in .github folder AL: System Application labels Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AL: System Application Build: Automation Workflows and other setup in .github folder Build: scripts & configs Build scripts and configuration files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants