aboutsummaryrefslogtreecommitdiff
path: root/scripts/test_scripts/block-clone-test-windows.ps1
blob: df24831a4d4725d3e46507c479fca5d8050636c3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# Test block-clone functionality on a temporary ReFS VHD.
#
# Requires:
#   - Administrator privileges
#   - Windows Server, or Windows 10/11 Pro for Workstations (ReFS support)
#   - Hyper-V PowerShell module (for New-VHD), or diskpart fallback
#
# Usage:
#   # From an elevated PowerShell prompt:
#   .\scripts\test_scripts\block-clone-test-windows.ps1 [-TestBinary <path>]
#
# If -TestBinary is not given, defaults to build\windows\x64\debug\zencore-test.exe
# relative to the repository root.

param(
    [string]$TestBinary = ""
)

$ErrorActionPreference = "Stop"

$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$RepoRoot = (Resolve-Path "$ScriptDir\..\..").Path

if (-not $TestBinary) {
    $TestBinary = Join-Path $RepoRoot "build\windows\x64\debug\zencore-test.exe"
}

$ImageSizeMB = 2048
$TestCases = "TryCloneFile,CopyFile.Clone,SupportsBlockRefCounting,CloneQueryInterface"

$VhdPath = ""
$MountLetter = ""

function Cleanup {
    $ErrorActionPreference = "SilentlyContinue"

    if ($MountLetter) {
        Write-Host "Dismounting VHD ..."
        Dismount-VHD -Path $VhdPath -ErrorAction SilentlyContinue
    }
    if ($VhdPath -and (Test-Path $VhdPath)) {
        Remove-Item -Force $VhdPath -ErrorAction SilentlyContinue
    }
}

trap {
    Cleanup
    throw $_
}

# --- Preflight checks ---

$IsAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
    [Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $IsAdmin) {
    Write-Error "This script must be run as Administrator (for VHD mount/format)."
    exit 1
}

if (-not (Test-Path $TestBinary)) {
    Write-Error "Test binary not found: $TestBinary`nHint: build with 'xmake config -m debug && xmake build zencore-test'"
    exit 1
}

# Check that ReFS formatting is available
$RefsAvailable = $true
try {
    # A quick check: on non-Server/Workstation SKUs, Format-Volume -FileSystem ReFS will fail
    $OsCaption = (Get-CimInstance Win32_OperatingSystem).Caption
    if ($OsCaption -notmatch "Server|Workstation|Enterprise") {
        Write-Warning "ReFS may not be available on this Windows edition: $OsCaption"
        Write-Warning "Continuing anyway — format step will fail if unsupported."
    }
} catch {
    # Non-fatal, just proceed
}

# --- Create and mount ReFS VHD ---

$VhdPath = Join-Path $env:TEMP "refs-clone-test-$([guid]::NewGuid().ToString('N').Substring(0,8)).vhdx"

Write-Host "Creating ${ImageSizeMB}MB VHDX at $VhdPath ..."

try {
    # Prefer Hyper-V cmdlet if available
    New-VHD -Path $VhdPath -SizeBytes ($ImageSizeMB * 1MB) -Fixed | Out-Null
} catch {
    # Fallback to diskpart
    Write-Host "New-VHD not available, falling back to diskpart ..."
    $DiskpartScript = @"
create vdisk file="$VhdPath" maximum=$ImageSizeMB type=fixed
"@
    $DiskpartScript | diskpart | Out-Null
}

Write-Host "Mounting and initializing VHD ..."

Mount-VHD -Path $VhdPath
$Disk = Get-VHD -Path $VhdPath | Get-Disk

# Suppress Explorer's auto-open / "format disk?" prompts for the raw partition
Stop-Service ShellHWDetection -ErrorAction SilentlyContinue

try {
    Initialize-Disk -Number $Disk.Number -PartitionStyle GPT -ErrorAction SilentlyContinue
    $Partition = New-Partition -DiskNumber $Disk.Number -UseMaximumSize -AssignDriveLetter
    $MountLetter = $Partition.DriveLetter

    Write-Host "Formatting ${MountLetter}: as ReFS with integrity disabled ..."
    Format-Volume -DriveLetter $MountLetter -FileSystem ReFS -NewFileSystemLabel "CloneTest" -Confirm:$false | Out-Null

    # Disable integrity streams (required for block cloning to work on ReFS)
    Set-FileIntegrity "${MountLetter}:\" -Enable $false -ErrorAction SilentlyContinue
} finally {
    Start-Service ShellHWDetection -ErrorAction SilentlyContinue
}

$MountRoot = "${MountLetter}:\"

# --- Copy test binary and run ---

Write-Host "Copying test binary to ReFS volume ..."
Copy-Item $TestBinary "$MountRoot\zencore-test.exe"

Write-Host "Running block-clone tests ..."
Write-Host "---"

$proc = Start-Process -FilePath "$MountRoot\zencore-test.exe" `
    -ArgumentList "--test-suite=core.filesystem", "--test-case=$TestCases" `
    -NoNewWindow -Wait -PassThru

Write-Host "---"

if ($proc.ExitCode -ne 0) {
    Write-Error "Tests failed with exit code $($proc.ExitCode)"
    Cleanup
    exit $proc.ExitCode
}

Write-Host "ReFS: all block-clone tests passed."

# --- Cleanup ---

Cleanup
Write-Host "Done."