Skip to content

Fix #62 (health-summary timezone) and #61 (robocopy credential warning) - #66

Open
BangRocket wants to merge 2 commits into
mainfrom
fix/open-bugs
Open

BangRocket wants to merge 2 commits into
mainfrom
fix/open-bugs

Conversation

@BangRocket

@BangRocket BangRocket commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes the two open bug reports filed against the metrics/transfer code.

Fixes #62 — Get-SEBHealthSummary timezone bug

Get-SEBHealthSummary re-[datetime]::Parse(...)d the metric timestamp that ConvertFrom-Json had already deserialized as Kind=Utc. Re-parsing a [datetime] stringifies it without an offset (Kind=Unspecified), and .ToUniversalTime() then assumes local time, so the reported "time since last backup" / 7-day success window was shifted by the host's UTC offset (a 4-hour drift on a UTC-4 host).

Fix: coerce the stored value to UTC instead of re-parsing it (SpecifyKind(Utc) for a [datetime], AssumeUniversal | AdjustToUniversal for a string) at both the last-successful-age and 7-day-window sites. Tightened the test per the issue: a backup written exactly 5h ago must report ~5h on any host (was deliberately left loose to avoid locale flakiness).

Fixes #61 — Copy-SEBThrottled silently ignores -Credential on robocopy

The robocopy strategy runs & robocopy @args and never references $Credential (BITS and Copy-Item do honor it), so an operator passing -Credential with a robocopy transfer got a silent no-op running as the calling identity. Now warns on the robocopy path when -Credential is supplied, and the .PARAMETER Credential help states which strategies honor it. The honesty-guard test now asserts the warning is emitted (and that the credential still never reaches the robocopy arg vector).

Testing

Invoke-Pester -Path Tests/MetricsCollector,Tests/NetworkThrottle,Tests/Contract
  • #62 is fully verified on macOS PowerShell 7 (14/14 in Get-SEBHealthSummary.Tests.ps1, including the new timezone-invariant age assertion that fails pre-fix on a non-UTC host).
  • #61's updated test exercises the robocopy path, which depends on the robocopy executable, so it runs in CI on Windows (no robocopy on the macOS dev host). The code change parses clean and introduces zero regressions in the non-robocopy paths.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Health summaries now calculate backup age and recent success rates using consistent UTC timestamps, reducing timezone-related inaccuracies.
    • When throttled copying falls back to robocopy, credential handling is now clearer: a warning appears if credentials are provided but can’t be used.
  • Documentation

    • Updated help text to better explain when credentials are supported during file transfer.

Get-SEBHealthSummary re-Parsed the JSON-deserialized metric timestamp, dropping it to
Kind=Unspecified, so .ToUniversalTime() assumed local time and shifted the reported age by
the host's UTC offset (~4h on a UTC-4 host). Coerce the stored value to UTC instead
(SpecifyKind for a [datetime], AssumeUniversal+AdjustToUniversal for a string) at both the
last-successful-age and 7-day-window sites.

Tighten the test: a backup written exactly 5h ago must report ~5h on any host.

Fixes #62.
Copy-SEBThrottled's robocopy strategy invokes the native exe as `& robocopy @args` and
never references $Credential, so an operator passing -Credential with a robocopy transfer
got a silent no-op (the copy ran as the calling identity) while BITS and Copy-Item honor it.
Emit a Write-Warning on the robocopy path when -Credential is supplied, and correct the
.PARAMETER Credential help to state which strategies honor it.

Update the honesty-guard test to assert the warning is now emitted (and that the credential
still never reaches the robocopy arg vector).

Fixes #61.
@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR normalizes metric timestamps to UTC in Get-SEBHealthSummary, applies the new conversion to backup-age and recent-metric calculations, and updates Copy-SEBThrottled so robocopy warns when -Credential is provided. Matching tests were added or adjusted for both behaviors.

Changes

UTC timestamp handling

Layer / File(s) Summary
UTC conversion helper
Modules/MetricsCollector/Public/Get-SEBHealthSummary.ps1
Get-SEBHealthSummary adds $toUtc and uses it for last-successful-backup age and the seven-day metric filter.
Timezone age test
Tests/MetricsCollector/Get-SEBHealthSummary.Tests.ps1
A new Pester context verifies LastSuccessfulBackupAge stays near five hours for a UTC-stamped metric entry.

Robocopy credential handling

Layer / File(s) Summary
Robocopy credential warning
Modules/NetworkThrottle/Public/Copy-SEBThrottled.ps1
Copy-SEBThrottled updates the -Credential help text and emits a warning when robocopy receives a credential.
Warning expectation test
Tests/NetworkThrottle/Copy-SEBThrottled.Tests.ps1
The robocopy-path Pester test now expects a warning mentioning that -Credential is ignored.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I hop through the logs by moonbeam light,
and nibble on timestamps set just right.
Robocopy now thumps a warning drum,
while backup ages stay where they come from.
🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two linked fixes: health-summary timezone handling and robocopy credential warning.
Linked Issues check ✅ Passed The PR addresses #62 by treating timestamps as UTC and #61 by warning that robocopy ignores -Credential, with matching tests and docs.
Out of Scope Changes check ✅ Passed The changes stay within the two linked bug fixes and their test/help text updates, with no unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/open-bugs

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Modules/NetworkThrottle/Public/Copy-SEBThrottled.ps1`:
- Around line 133-137: The ignored-credential warning in the robocopy branch is
bypassing the module’s standard logging path by using direct warning output.
Update the $Credential check in Copy-SEBThrottled to route this message through
Write-SEBLog with WARN level (or the approved logging wrapper used elsewhere in
the module) so the warning is captured consistently in project logs while
preserving warning behavior.
- Around line 44-47: The help text for Copy-SEBThrottled.ps1 incorrectly claims
that Strategy 3 (Copy-Item) honors -Credential. Update the comment block near
the transfer strategy descriptions to remove that support statement and document
Strategy 3 as requiring pre-authenticated UNC access (for example via
New-PSDrive) instead. Keep the BITS/Strategy 1 credential wording, and make sure
the robocopy note remains unchanged.

In `@Tests/NetworkThrottle/Copy-SEBThrottled.Tests.ps1`:
- Around line 173-176: The warning assertion is too generic and can pass for
unrelated warnings; tighten it so it specifically verifies the
robocopy/Copy-SEBThrottled path. Update the existing Pester expectation around
the $warnings check in Copy-SEBThrottled.Tests.ps1 to include robocopy (or
calling identity) alongside Credential and ignored, so the test stays bound to
the issue `#61` contract and not to any other warning source.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3bc9350f-306f-4974-9851-3f00de9595c8

📥 Commits

Reviewing files that changed from the base of the PR and between 4a31db1 and dfe543b.

📒 Files selected for processing (4)
  • Modules/MetricsCollector/Public/Get-SEBHealthSummary.ps1
  • Modules/NetworkThrottle/Public/Copy-SEBThrottled.ps1
  • Tests/MetricsCollector/Get-SEBHealthSummary.Tests.ps1
  • Tests/NetworkThrottle/Copy-SEBThrottled.Tests.ps1

Comment on lines +44 to +47
An optional PSCredential object for authenticating to UNC paths. Honored by the BITS
(Strategy 1) and Copy-Item (Strategy 3) paths. The robocopy path (Strategy 2) CANNOT use
it -- robocopy runs as the calling identity and has no credential parameter -- so a
-Credential supplied on a robocopy transfer is ignored with a warning (see issue #61).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the target file and nearby lines.
file="Modules/NetworkThrottle/Public/Copy-SEBThrottled.ps1"
wc -l "$file"
cat -n "$file" | sed -n '1,220p'

Repository: SandboxServers/SEBackup

Length of output: 12071


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check for module logging conventions and any use of Copy-Item -Credential elsewhere.
rg -n --hidden --glob 'Modules/**/*.ps1' 'Write-Warning|Write-SEBLog|Copy-Item.*Credential|Credential' Modules/NetworkThrottle Modules | sed -n '1,220p'

Repository: SandboxServers/SEBackup

Length of output: 34251


🌐 Web query:

PowerShell 7 Copy-Item -Credential FileSystem provider UNC support documentation

💡 Result:

The Copy-Item cmdlet in PowerShell 7 does not support the -Credential parameter when using the FileSystem provider [1][2][3]. Although the -Credential parameter appears in the syntax for Copy-Item, it is not functional for built-in PowerShell providers like the FileSystem provider [1][3][4]. If you attempt to use it, you will receive an error indicating that the provider does not support credentials [5]. The parameter is included in the cmdlet definition primarily for compatibility with third-party or custom PowerShell providers that may require explicit credentials to perform operations [4]. To access a UNC path with specific credentials in PowerShell 7, the recommended approach is to use the New-PSDrive cmdlet [6][7]. The FileSystem provider explicitly supports the -Credential parameter within New-PSDrive when mapping a network share (UNC path) [8][7]. Standard workflow: 1. Define your credentials using a PSCredential object [6][8]. 2. Create a temporary or persistent mapped drive using New-PSDrive with those credentials [8][7]. 3. Perform the Copy-Item operation using the drive letter or path associated with the new PSDrive [7]. Example: $cred = Get-Credential New-PSDrive -Name "RemoteShare" -PSProvider FileSystem -Root "\Server\Share" -Credential $cred Copy-Item -Path "C:\Source\file.txt" -Destination "RemoteShare:\file.txt"

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="Modules/NetworkThrottle/Public/Copy-SEBThrottled.ps1"

echo "== target file =="
wc -l "$file"
cat -n "$file" | sed -n '1,220p'

echo
echo "== relevant usages =="
rg -n --hidden --glob 'Modules/**/*.ps1' 'Write-Warning|Write-SEBLog|Copy-Item.*-Credential|Copy-Item|robocopy|Strategy 2|Strategy 3' Modules/NetworkThrottle Modules | sed -n '1,220p'

Repository: SandboxServers/SEBackup

Length of output: 46813


Remove Copy-Item -Credential from this help text. Copy-Item on the FileSystem provider does not honor -Credential in PowerShell 7, so Strategy 3 should be documented as requiring pre-authenticated access (for example via New-PSDrive) or limited to BITS only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Modules/NetworkThrottle/Public/Copy-SEBThrottled.ps1` around lines 44 - 47,
The help text for Copy-SEBThrottled.ps1 incorrectly claims that Strategy 3
(Copy-Item) honors -Credential. Update the comment block near the transfer
strategy descriptions to remove that support statement and document Strategy 3
as requiring pre-authenticated UNC access (for example via New-PSDrive) instead.
Keep the BITS/Strategy 1 credential wording, and make sure the robocopy note
remains unchanged.

Comment on lines +133 to +137
if ($Credential) {
Write-Warning ("Copy-SEBThrottled: -Credential is ignored by the robocopy transfer strategy " +
"(robocopy runs as the calling identity and has no credential parameter). For a credentialed " +
"transfer use -UseBITS, or pre-authenticate the destination (e.g. a mapped/`New-PSDrive` share) " +
"so the current identity can reach it.")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Route the ignored-credential warning through the project logger.

This new branch writes directly with Write-Warning, so the event bypasses the standard module logging path. Please emit it via Write-SEBLog -Level WARN (or the project-approved wrapper that preserves warning behavior) so it is captured consistently in module logs. As per coding guidelines, “Use Write-SEBLog for all log output. Do not use Write-Host in module code.” As per path instructions, “Use Write-SEBLog for output, never Write-Host in module code.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Modules/NetworkThrottle/Public/Copy-SEBThrottled.ps1` around lines 133 - 137,
The ignored-credential warning in the robocopy branch is bypassing the module’s
standard logging path by using direct warning output. Update the $Credential
check in Copy-SEBThrottled to route this message through Write-SEBLog with WARN
level (or the approved logging wrapper used elsewhere in the module) so the
warning is captured consistently in project logs while preserving warning
behavior.

Sources: Coding guidelines, Path instructions

Comment on lines +173 to +176
($warnings -join ' ') | Should -Match 'Credential' # warned: not silently dropped
($warnings -join ' ') | Should -Match 'ignored'
# Pester's -Match is case-insensitive; the credential (username or any '/credential' switch
# robocopy has no concept of) must appear nowhere in the arg vector.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin the warning assertion to robocopy specifically.

Matching only Credential and ignored would still pass on an unrelated warning from another layer. Add robocopy (or calling identity) to keep this test locked to the issue #61 contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/NetworkThrottle/Copy-SEBThrottled.Tests.ps1` around lines 173 - 176,
The warning assertion is too generic and can pass for unrelated warnings;
tighten it so it specifically verifies the robocopy/Copy-SEBThrottled path.
Update the existing Pester expectation around the $warnings check in
Copy-SEBThrottled.Tests.ps1 to include robocopy (or calling identity) alongside
Credential and ignored, so the test stays bound to the issue `#61` contract and
not to any other warning source.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant