Invoke-DbaDbLogShipping - avoid Azure blob name collision - #10679
simonyang08 wants to merge 1 commit into
Conversation
…0667) When Invoke-DbaDbLogShipping backs up to Azure blob storage it builds the backup file name from a Get-Date timestamp with second resolution. Two CI runs that hit the cmdlet within the same wall-clock second produced the same FullBackup_PreLogShipping blob name on the shared Azure container, so the second run failed with 'Cannot open backup device ... Operating system error 50' even when nothing in the PR was actually wrong. Two minimal changes close the bug: * Production: build the Azure timestamp with millisecond precision (yyyyMMddHHmmssfff). Two callers that enter the cmdlet inside the same second now produce different blob names, regardless of how the caller picks the database name. * CI: scope the dbatoolsci_logship_azure database name with GITHUB_RUN_ID and GITHUB_RUN_ATTEMPT in .github/scripts/gh-actions.ps1, so concurrent linux-tests jobs (and reruns) never reuse the same database or blob. The Azure integration test still needs a real SQL Server plus the shared Azure container to actually run, so the regression is asserted on the shape of the inputs that drive the blob name: a new unit test reads the production source and the CI script and verifies the timestamp carries the millisecond 'fff' format specifier and the database name carries GITHUB_RUN_ID. This catches a future revert to second resolution or a revert to the hard-coded database name without requiring the Azure fixture. Signed-off-by: simonyang08 <ppt5928@gmail.com>
|
Thanks for picking this up. I filed #10667, so here is a review from that side. Short version: the change to
|
|
A personal question, @simonyang08: Are you a user of dbatools or just someone (or an AI bot) looking for things to fix? @potatoqualitee - If you agree I would open a separate pr with the changes to .github/scripts/gh-actions.ps1 and close this pr. |
Issue
#10667: the Azure log shipping integration test failed on PR #10665 with
Cannot open backup device ... Operating system error 50even though #10665 only changed three SSIS message strings. The reason was that three PRs (#10664, #10665, #10666) hit the sameInvoke-DbaDbLogShippingcall inside the same wall-clock second, all produced the sameFullBackup_PreLogShipping_<yyyyMMddHHmmss>.bakblob name, and the second runner's upload lost the race.Root cause
Two cooperating causes:
public/Invoke-DbaDbLogShipping.ps1builds the Azure timestamp with second resolution (Get-Date -Format "yyyyMMddHHmmss")..github/scripts/gh-actions.ps1pins both test database names (dbatoolsci_logship_azure,dbatoolsci_logship_addsecondary) for every run, so concurrent jobs and reruns share database and blob names.Fix
yyyyMMddHHmmssfff). Two callers inside the same second produce different blob names regardless of how the caller picks the database. The otherGet-Datecalls in the file are schedule start dates that never touch file names.GITHUB_RUN_ID(+GITHUB_RUN_ATTEMPTfor reruns), so concurrent jobs and reruns never share a database or a blob. The--prefixcleanup continues to work because the prefix is still rooted indbatoolsci_logship_azure/dbatoolsci_logship_addsecondary.Tests
New
tests/Invoke-DbaDbLogShipping.Azure.Tests.ps1(Pester 6,-Tag UnitTests) reads the production source and the CI script and asserts the millisecond specifier and the per-runGITHUB_RUN_IDscoping. These assertions catch a future revert to second resolution or a hardcoded database name without needing the Azure fixture, matching the source-content style already used indbatools.Tests.ps1compliance checks.Verified locally: the new spec is green under Pester 6.1.0, and the existing
Invoke-DbaDbLogShipping/Remove-DbaDbLogShippingspecs still pass with the module imported.Scope
3 files, 92 insertions, 3 deletions. No new parameters, no new dependencies.
Fixes #10667