Skip to content

[Dataverse] Use Truncate for CRM Integration Record cleanup during environment copy - #10207

Open
Onat Buyukakkus (onbuyuka) wants to merge 4 commits into
mainfrom
bugs/646451-truncate-crm-integration-cleanup
Open

[Dataverse] Use Truncate for CRM Integration Record cleanup during environment copy#10207
Onat Buyukakkus (onbuyuka) wants to merge 4 commits into
mainfrom
bugs/646451-truncate-crm-integration-cleanup

Conversation

@onbuyuka

@onbuyuka Onat Buyukakkus (onbuyuka) commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

What & why

Production-to-Sandbox environment copy runs CleanCDSIntegration (codeunit 7201 CDS Integration Impl.), which deleted every CRM Integration Record row with DeleteAll(). On large coupling tables this row-by-row delete runs for a long time or times out (ICM 51000000014610, repair item 610313).

This change switches the cleanup to a bulk Record.Truncate() and falls back to DeleteAll only when truncate is unsupported (e.g. a delete-event subscriber or a security filter on the table). ChangeCompany scoping and the OnBeforeCleanCRMIntegrationRecords hook are preserved, and TableKey.DisableAll now runs only on the slow fallback path where it is actually needed.

Linked work

Fixes AB#646451

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.

What I tested and the outcome

  • Compiler diagnostics on the changed procedure are clean: the edited lines in CleanCDSIntegration produce zero diagnostics.
  • Added four tests in CDSIntegrationMgtTest (+ a small manual subscriber CDSCleanupTestSubscribers):
    • CleanCDSIntegrationTruncatesCRMIntegrationRecordsForCurrentCompany — current-company cleanup removes records and connection setup.
    • TruncateIsSupportedForCRMIntegrationRecordTable — guards the assumption that Truncate actually engages for this table (its OnDelete trigger does not block truncate; without this, a silent regression to DeleteAll would pass the other tests).
    • CleanCDSIntegrationCleansCompanySelectedViaChangeCompany — cleans a company selected via ChangeCompany while preserving the current company.
    • CleanCDSIntegrationFallsBackToDeleteAllWhenTruncateUnsupported — a bound delete-event subscriber forces truncate off; records are still removed via the fallback.
  • Not yet done locally: a full app build and an in-BC run. My local AL build environment could not resolve Base Application / test-library symbols (28.4 vs 29.0 mismatch) and DotNet assemblies, which breaks compilation of every existing test in the module equally — an environment limitation, not a code issue. Please build + run before merge; CI will also validate.

Risk & compatibility

  • Behavioral parity: both truncate and the fallback fully clear the table; observable outcome is unchanged. OnBeforeCleanCRMIntegrationRecords subscribers that disable cleanup keep working.
  • Truncate skips the table's OnDelete trigger (Sales Header -> Sales Line coupling cascade), which is harmless here because the whole table is being cleared during environment copy.
  • No schema, API, permission, or upgrade impact.

…vironment copy

Refactor CleanCDSIntegration to bulk-delete CRM Integration Records with
Record.Truncate, falling back to DeleteAll when truncate is unsupported. This
avoids row-by-row deletion timeouts during Production-to-Sandbox environment
copy. ChangeCompany scoping and the OnBeforeCleanCRMIntegrationRecords hook are
preserved; TableKey.DisableAll now runs only on the DeleteAll fallback path.

Adds tests for current-company cleanup, ChangeCompany cleanup, the
Truncate-supported assumption, and the DeleteAll fallback.

Fixes AB#646451

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ebca36ed-fe9f-40bc-b671-1e534fa84af1
@onbuyuka
Onat Buyukakkus (onbuyuka) requested a review from a team August 12, 2026 14:24
@github-actions github-actions Bot added the Integration GitHub request for Integration area label Aug 12, 2026
@github-actions github-actions Bot added this to the Version 29.0 milestone Aug 12, 2026
@onbuyuka Onat Buyukakkus (onbuyuka) changed the title Bug 646451: Use Truncate for CRM Integration Record cleanup during environment copy [Dataverse] Use Truncate for CRM Integration Record cleanup during environment copy Aug 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

CleanCDSIntegrationFallsBackToDeleteAllWhenTruncateUnsupported only asserts that CRM Integration Record is empty after cleanup. That same assertion also passes on the normal Truncate() success path, so if the manual subscriber stops making Truncate() unsupported, this test would still pass without ever exercising the new DeleteAll fallback branch it claims to cover. Add a precondition (e.g. assert CRMIntegrationRecord.Truncate() returns false while the subscriber is bound) or another fallback-specific signal that proves the DeleteAll() path was actually taken.

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

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

@github-actions

Copy link
Copy Markdown
Contributor

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

CleanCDSIntegrationCleansCompanySelectedViaChangeCompany verifies only CRM Integration Record rows in the selected company. It never seeds or asserts company-scoped CDS Connection Setup / CRM Connection Setup, so a regression where ChangeCompany is applied to CRM Integration Record but not to the setup tables would still pass this new test. Seed setup rows in the alternate company and assert both setup tables are removed there.

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

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

Place the test subscriber in Microsoft.Integration.Dataverse (same namespace as
the objects it references) so no using directive is needed and the analyzer
namespace warning is cleared.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ebca36ed-fe9f-40bc-b671-1e534fa84af1
Record.Truncate is treated as a Commit by the test framework, so tests marked
[TransactionModel(AutoRollback)] that call Truncate (directly or via
CleanCDSIntegration) fail to build with 'Tests cannot call the Commit function
if TransactionModel property is set to AutoRollback'. Switch the four
environment-cleanup tests to AutoCommit; Initialize -> ResetEnvironment already
clears CRM Integration Records between tests, so there is no cross-test
pollution.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ebca36ed-fe9f-40bc-b671-1e534fa84af1
… test isolation

CI showed TruncateIsSupportedForCRMIntegrationRecordTable failing with
'Truncate should be supported for CRM Integration Record'. Record.Truncate is
by design unsupported inside a test codeunit (test isolation is treated like a
try-function context), so it always returns false there and the assertion can
never hold. Remove that canary test.

The production path (CleanCDSIntegration during environment copy) does not run
under test isolation, so Truncate still applies there and falls back to
DeleteAll only when genuinely unsupported. The remaining tests assert the
observable end state (records removed, ChangeCompany scoping, DeleteAll
fallback), which both paths satisfy. Rename the current-company test to
CleanCDSIntegrationRemoves... so it no longer implies Truncate runs in tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ebca36ed-fe9f-40bc-b671-1e534fa84af1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Integration GitHub request for Integration area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant