Skip to content

Commit 216fb37

Browse files
authored
Refactor uninstall to add -purge flag
- Refactor uninstall to only remove program data files when the `-purge` flag is passsed - Add unit tests for the `-purge` functionality - Update documentation for -purge flag and other documentation issues - Minor bug fixes
1 parent cb3edde commit 216fb37

33 files changed

+1818
-1279
lines changed

.github/pull_request_template.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ _How to test the changes_
1717

1818
### Relevant Links
1919

20-
Any links from your research that help explain the changes
20+
_Any links from your research that help explain the changes_
2121

2222
## Checklist
2323

Tests/BuildkitTools.Tests.ps1

Lines changed: 70 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@ Describe "BuildkitTools.psm1" {
3030
Mock Test-ServiceRegistered -ModuleName 'BuildkitTools' -MockWith { return $true }
3131
}
3232

33+
BeforeEach {
34+
Remove-Item -Path "$TestDrive" -Re -Force -ErrorAction Ignore
35+
}
36+
3337
AfterEach {
3438
$ENV:PESTER = $false
39+
Remove-Item -Path "$TestDrive" -Re -Force -ErrorAction Ignore
3540
}
3641

3742
AfterAll {
@@ -124,7 +129,11 @@ Describe "BuildkitTools.psm1" {
124129
Install-Buildkit -Setup -Force -Confirm:$false
125130

126131
Should -Invoke Register-BuildkitdService -Times 1 -Exactly -Scope It -ModuleName 'BuildkitTools' `
127-
-ParameterFilter { $BuildKitPath -eq "$Env:ProgramFiles\Buildkit" -and $WinCNIPath -eq "" }
132+
-ParameterFilter {
133+
$BuildKitPath -eq "$Env:ProgramFiles\Buildkit" -and
134+
$WinCNIPath -eq "$ENV:ProgramFiles\Containerd\cni"
135+
$Start -eq $true
136+
}
128137
}
129138

130139
It "Should uninstall tool if it is already installed" {
@@ -164,10 +173,8 @@ Describe "BuildkitTools.psm1" {
164173

165174
Context "Register-BuildkitdService" -Tag "Register-BuildkitdService" {
166175
BeforeAll {
167-
$MockBuildKitPath = "$TestDrive\Program Files\Buildkit"
168-
New-Item -Path "$MockBuildKitPath\bin\buildkitd.exe" -ItemType 'File' -Force | Out-Null
169-
New-Item -Path 'TestDrive:\Program Files\Containerd\cni\conf' -ItemType 'Directory' -Force | Out-Null
170-
Set-Content -Path "TestDrive:\Program Files\Containerd\cni\conf\0-containerd-nat.conf" -Value 'Nat config data here' -Force
176+
$MockBuildKitPath = "C:\Program Files\Buildkit"
177+
$expectedExecutablePath = "$MockBuildKitPath\bin\buildkitd.exe"
171178

172179
Mock Test-Path -ModuleName "BuildkitTools" { return $true }
173180
Mock Add-MpPreference -ModuleName "BuildkitTools"
@@ -176,7 +183,7 @@ Describe "BuildkitTools.psm1" {
176183
-MockWith { return $MockBuildKitPath } `
177184
-ParameterFilter { $Tool -eq "Buildkit" }
178185
Mock Get-DefaultInstallPath -ModuleName "BuildkitTools" `
179-
-MockWith { return "$TestDrive\Program Files\Containerd" } `
186+
-MockWith { return "C:\Program Files\Containerd" } `
180187
-ParameterFilter { $Tool -eq "containerd" }
181188

182189
$obj = New-MockObject -Type 'System.Diagnostics.Process' -Properties @{ ExitCode = 0 }
@@ -188,36 +195,39 @@ Describe "BuildkitTools.psm1" {
188195
Mock Test-ServiceRegistered -ModuleName 'BuildkitTools' -MockWith { return $false }
189196
}
190197

191-
AfterAll {
192-
Get-ChildItem -Path 'TestDrive:\' | Remove-Item -Recurse -Force
193-
}
194-
195198
It "Should successfully register buildkitd service using defaults" {
196-
$MockWinCNIPath = "$TestDrive\Program Files\Containerd\cni"
197-
$MockCniBinDir = "$MockWinCNIPath\bin"
198-
$MockCniConfPath = "$MockWinCNIPath\conf\0-containerd-nat.conf"
199-
200199
Register-BuildkitdService -Force
201200

202-
$expectedExecutablePath = "$TestDrive\Program Files\buildkit\bin\buildkitd.exe"
203-
$expectedCommandArguments = "--register-service --debug --containerd-worker=true --containerd-cni-config-path=`"$MockCniConfPath`" --containerd-cni-binary-dir=`"$MockCniBinDir`" --service-name buildkitd"
201+
# The default path for Buildkit is $Env:ProgramFiles\Buildkit.
202+
# Since tests are run as a user (not as admin), it is not possible to create a conf file in the default path.
203+
$expectedCommandArguments = "--register-service --debug --containerd-worker=true --service-name buildkitd"
204204

205-
Should -Invoke Invoke-ExecutableCommand -Times 1 -Scope It -ModuleName "BuildkitTools" `
206-
-ParameterFilter { ($Executable -eq $expectedExecutablePath ) -and ($Arguments -eq $expectedCommandArguments) }
205+
Should -Invoke Invoke-ExecutableCommand -Times 1 -Scope It -ModuleName "BuildkitTools" -ParameterFilter {
206+
($Executable -eq $expectedExecutablePath ) -and
207+
($Arguments -eq $expectedCommandArguments)
208+
}
207209
Should -Invoke Start-BuildkitdService -Times 0 -Scope It -ModuleName "BuildkitTools"
208210
}
209211

210212
It "Should successfully register buildkitd service using custom values" {
213+
# Create mock .conf file
211214
$MockWinCNIPath = "$TestDrive\Program Files\Containerd\cni"
212215
$MockCniBinDir = "$MockWinCNIPath\bin"
213-
$MockCniConfPath = "$TestDrive\Program Files\Containerd\cni\conf\0-containerd-nat.conf"
216+
$MockCniConfDir = "$MockWinCNIPath\conf"
217+
$MockCniConfPath = "$MockCniConfDir\0-containerd-nat.conf"
218+
New-Item -Path "$MockCniConfDir" -ItemType 'Directory' -Force | Out-Null
219+
Set-Content -Path "$MockCniConfPath" -Value 'Nat config data here' -Force
214220

215221
Register-BuildkitdService -WinCNIPath $MockWinCNIPath -BuildKitPath $MockBuildKitPath -Start -Force
216222

217223
$expectedExecutablePath = "$MockBuildKitPath\bin\buildkitd.exe"
218224
$expectedCommandArguments = "--register-service --debug --containerd-worker=true --containerd-cni-config-path=`"$MockCniConfPath`" --containerd-cni-binary-dir=`"$MockCniBinDir`" --service-name buildkitd"
225+
Write-Host "'$expectedCommandArguments'" -ForegroundColor Magenta
219226
Should -Invoke Invoke-ExecutableCommand -Times 1 -Scope It -ModuleName "BuildkitTools" `
220-
-ParameterFilter { ($Executable -eq $expectedExecutablePath ) -and ($Arguments -eq $expectedCommandArguments) }
227+
-ParameterFilter {
228+
($Executable -eq $expectedExecutablePath ) -and
229+
($Arguments -eq $expectedCommandArguments)
230+
}
221231
Should -Invoke Start-BuildkitdService -Times 1 -Scope It -ModuleName "BuildkitTools"
222232
}
223233

@@ -252,12 +262,14 @@ Describe "BuildkitTools.psm1" {
252262
Mock Test-ConfFileEmpty -ModuleName "BuildkitTools" { return $true }
253263
Mock Get-ConsentToRegisterBuildkit -ModuleName "BuildkitTools" { return $yesValue }
254264

255-
Register-BuildkitdService -WinCNIPath "$TestDrive\SomeOtherFolder" -Force
265+
Register-BuildkitdService -WinCNIPath $MockWinCNIPath -BuildKitPath $MockBuildKitPath -Start -Force
256266

257-
$expectedExecutablePath = "$MockBuildKitPath\bin\buildkitd.exe"
258267
$expectedCommandArguments = '--register-service --debug --containerd-worker=true --service-name buildkitd'
259268
Should -Invoke Invoke-ExecutableCommand -Times 1 -Scope It -ModuleName "BuildkitTools" `
260-
-ParameterFilter { ($Executable -eq $expectedExecutablePath ) -and ($Arguments -eq $expectedCommandArguments) }
269+
-ParameterFilter {
270+
($Executable -eq $expectedExecutablePath ) -and
271+
($Arguments -eq $expectedCommandArguments)
272+
}
261273
}
262274

263275
It "Should throw an error if user does not consent to registering buildkitd service without NAT conf file" {
@@ -302,35 +314,36 @@ Describe "BuildkitTools.psm1" {
302314
}
303315

304316
It "Should successfully uninstall Buildkit" {
305-
Mock Uninstall-BuildkitHelper -ModuleName 'BuildkitTools'
317+
Uninstall-Buildkit -Path 'TestDrive:\Custom\Buildkit\' -Confirm:$false -Force
318+
319+
# Should stop and deregister the buildkitd service
320+
Should -Invoke Stop-BuildkitdService -Times 1 -Scope It -ModuleName "BuildkitTools"
321+
Should -Invoke Unregister-Buildkitd -Times 1 -Scope It -ModuleName "BuildkitTools"
306322

307-
Uninstall-Buildkit -Path 'TestDrive:\Program Files\Buildkit' -Confirm:$false -Force
323+
# Should remove buildkit dir
324+
Should -Invoke Remove-Item -Times 1 -Scope It -ModuleName "BuildkitTools" `
325+
-ParameterFilter { $Path -eq 'TestDrive:\Custom\Buildkit\bin' }
308326

309-
Should -Invoke Uninstall-BuildkitHelper -Times 1 -Scope It -ModuleName "BuildkitTools" `
310-
-ParameterFilter { $Path -eq 'TestDrive:\Program Files\Buildkit' }
327+
# Should not purge program data
328+
Should -Invoke Remove-Item -Times 0 -Scope It -ModuleName "BuildkitTools" `
329+
-ParameterFilter { $Path -eq 'HKLM:\SYSTEM\CurrentControlSet\Services\buildkit' }
330+
Should -Invoke Uninstall-ProgramFiles -Times 0 -Scope It -ModuleName "BuildkitTools" `
331+
-ParameterFilter { $Path -eq "$ENV:ProgramData\Buildkit" }
332+
Should -Invoke Remove-FeatureFromPath -Times 0 -Scope It -ModuleName "BuildkitTools" `
333+
-ParameterFilter { $Feature -eq "buildkit" }
311334
}
312335

313336
It "Should successfully uninstall Buildkit from default path" {
314-
Mock Uninstall-BuildkitHelper -ModuleName 'BuildkitTools'
315-
316337
Uninstall-Buildkit -Confirm:$false -Force
317338

318-
Should -Invoke Uninstall-BuildkitHelper -Times 1 -Scope It -ModuleName "BuildkitTools" `
319-
-ParameterFilter { $Path -eq 'TestDrive:\Program Files\Buildkit' }
339+
Should -Invoke Remove-Item -Times 0 -Scope It -ModuleName "BuildkitTools" `
340+
-ParameterFilter { $Path -eq 'TestDrive:\Program Files\Buildkit\bin' }
320341
}
321342

322-
It "Should throw an error if user does not consent to uninstalling Buildkit" {
323-
$ENV:PESTER = $true
324-
{ Uninstall-Buildkit -Path 'TestDrive:\Program Files\Buildkit' -Confirm:$false -Force:$false } | Should -Throw "Buildkit uninstallation cancelled."
325-
}
343+
It "Should successfully purge program data" {
344+
Uninstall-Buildkit -Path 'TestDrive:\Program Files\Buildkit' -Confirm:$false -Force -Purge
326345

327-
It "Should successfully call uninstall Buildkit helper function" {
328-
Uninstall-BuildkitHelper -Path 'TestDrive:\Program Files\Buildkit'
329-
330-
Should -Invoke Stop-BuildkitdService -Times 1 -Scope It -ModuleName "BuildkitTools"
331-
Should -Invoke Unregister-Buildkitd -Times 1 -Scope It -ModuleName "BuildkitTools"
332-
Should -Invoke Remove-Item -Times 1 -Scope It -ModuleName "BuildkitTools" `
333-
-ParameterFilter { $Path -eq 'HKLM:\SYSTEM\CurrentControlSet\Services\buildkit' }
346+
# Should purge program data
334347
Should -Invoke Remove-Item -Times 1 -Scope It -ModuleName "BuildkitTools" `
335348
-ParameterFilter { $Path -eq 'TestDrive:\Program Files\Buildkit' }
336349
Should -Invoke Uninstall-ProgramFiles -Times 1 -Scope It -ModuleName "BuildkitTools" `
@@ -339,26 +352,35 @@ Describe "BuildkitTools.psm1" {
339352
-ParameterFilter { $Feature -eq "buildkit" }
340353
}
341354

355+
It "Should do nothing if user does not consent to uninstalling Buildkit" {
356+
$ENV:PESTER = $true
357+
Uninstall-Buildkit -Path 'TestDrive:\Program Files\Buildkit' -Confirm:$false -Force:$false
358+
359+
# Should NOT stop and deregister the buildkit service
360+
Should -Invoke Stop-BuildkitdService -Times 0 -Scope It -ModuleName "BuildkitTools"
361+
Should -Invoke Unregister-Buildkitd -Times 0 -Scope It -ModuleName "BuildkitTools"
362+
363+
# Should NOT remove buildkit binaries/dir
364+
Should -Invoke Remove-Item -Times 0 -Scope It -ModuleName "BuildkitTools"
365+
}
366+
342367
It "Should do nothing if buildkit is not installed at specified path" {
343368
Mock Test-EmptyDirectory -ModuleName 'BuildkitTools' -MockWith { return $true }
344369

345-
Uninstall-BuildkitHelper -Path 'TestDrive:\Program Files\Buildkit'
370+
Uninstall-Buildkit -Path 'TestDrive:\Program Files\Buildkit' -Confirm:$false
346371

347372
Should -Invoke Stop-BuildkitdService -Times 0 -Scope It -ModuleName "BuildkitTools"
348373
Should -Invoke Unregister-Buildkitd -Times 0 -Scope It -ModuleName "BuildkitTools"
349374
Should -Invoke Remove-Item -Times 0 -Scope It -ModuleName "BuildkitTools"
350-
Should -Invoke Remove-FeatureFromPath -Times 0 -Scope It -ModuleName "BuildkitTools"
351-
352-
$Error[0].Exception.Message | Should -BeExactly 'Buildkit does not exist at TestDrive:\Program Files\Buildkit or the directory is empty.'
353375
}
354376

355377
It "Should throw an error if buildkitd service stop or unregister was unsuccessful" {
356378
Mock Stop-BuildkitdService -ModuleName 'BuildkitTools' -MockWith { Throw 'Error' }
357379

358-
{ Uninstall-BuildkitHelper -Path 'TestDrive:\Program Files\Buildkit' } | Should -Throw "Could not stop or unregister buildkitd service.*"
380+
{ Uninstall-Buildkit -Path 'TestDrive:\Program Files\Buildkit' -Confirm:$false -Force -Purge } | Should -Throw "*Could not stop or unregister buildkitd service.*"
359381
Should -Invoke Unregister-Buildkitd -Times 0 -Scope It -ModuleName "BuildkitTools"
360382
Should -Invoke Remove-Item -Times 0 -Scope It -ModuleName "BuildkitTools"
361383
Should -Invoke Remove-FeatureFromPath -Times 0 -Scope It -ModuleName "BuildkitTools"
362384
}
363385
}
364-
}
386+
}

Tests/ContainerNetworkTools.Tests.ps1

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ Describe "ContainerNetworkTools.psm1" {
157157
Mock New-HNSNetwork -ModuleName 'ContainerNetworkTools'
158158
Mock Restart-Service -ModuleName 'ContainerNetworkTools'
159159
Mock Install-WinCNIPlugin -ModuleName 'ContainerNetworkTools'
160+
Mock Set-Content -ModuleName 'ContainerNetworkTools' -ParameterFilter {
161+
$Path -eq "$ENV:ProgramFiles\Containerd\cni\conf\0-containerd-nat.conf" }
160162
}
161163

162164
It "Should use defaults" {
@@ -169,9 +171,14 @@ Describe "ContainerNetworkTools.psm1" {
169171
$Gateway -eq '99.2.0.8'
170172
$AddressPrefix -eq '99.2.0.0/16'
171173
}
174+
175+
# NOTE: Since we are running as non-admin, we are not able to write to the default path
176+
# "C:\Program Files\Containerd\cni\conf\0-containerd-nat.conf". Instead, we test that
177+
# Set-Content is called with the correct parameters.
172178
$MockConfFilePath = "C:\Program Files\Containerd\cni\conf\0-containerd-nat.conf"
173-
$MockConfFilePath | Should -Exist
174-
$MockConfFilePath | Should -FileContentMatch "`"cniVersion`": `"1.0.0`""
179+
Should -Invoke Set-Content -ModuleName 'ContainerNetworkTools' -ParameterFilter {
180+
$Path -eq $MockConfFilePath
181+
}
175182
}
176183

177184
It "Should use user-specified values" {
@@ -257,42 +264,33 @@ Describe "ContainerNetworkTools.psm1" {
257264
}
258265

259266
It "Should successfully uninstall WinCNI plugins" {
260-
Mock Uninstall-WinCNIPluginHelper -ModuleName 'ContainerNetworkTools'
267+
Uninstall-WinCNIPlugin -Path 'TestDrive:\Program Files' -Confirm:$false -Force
261268

262-
Uninstall-WinCNIPlugin -Confirm:$false -Path 'TestDrive:\Program Files\cni' -Force
263-
264-
Should -Invoke Uninstall-WinCNIPluginHelper -Times 1 -Scope It -ModuleName "ContainerNetworkTools" `
269+
# Should remove containerd/cni dir
270+
Should -Invoke Remove-Item -Times 1 -Scope It -ModuleName "ContainerNetworkTools" `
265271
-ParameterFilter { $Path -eq 'TestDrive:\Program Files\cni' }
266272
}
267273

268274
It "Should successfully uninstall WinCNI plugins from default path" {
269-
Mock Uninstall-WinCNIPluginHelper -ModuleName 'ContainerNetworkTools'
270-
271275
Uninstall-WinCNIPlugin -Confirm:$false -Force
272276

273-
Should -Invoke Uninstall-WinCNIPluginHelper -Times 1 -Scope It -ModuleName "ContainerNetworkTools" `
274-
-ParameterFilter { $Path -eq 'TestDrive:\Program Files\Containerd\cni' }
277+
Should -Invoke Remove-Item -Times 1 -Scope It -ModuleName "ContainerNetworkTools" `
278+
-ParameterFilter { $Path -eq "$ENV:ProgramFiles\Containerd\cni" }
275279
}
276280

277-
It "Should throw an error if user does not consent to uninstalling WinCNIPlugin" {
281+
It "Should do nothing if user does not consent to uninstalling WinCNIPlugin" {
278282
$ENV:PESTER = $true
279-
{ Uninstall-WinCNIPlugin -Confirm:$false -Path 'TestDrive:\Program Files\cni' -Force:$false } | Should -Throw "Windows CNI plugins uninstallation cancelled."
280-
}
281-
282-
It "Should successfully call uninstall WinCNIPlugin helper function" {
283-
Uninstall-WinCNIPluginHelper -Path 'TestDrive:\TestDir\cni'
283+
Uninstall-WinCNIPlugin -Confirm:$false -Force:$false
284284

285-
Should -Invoke Remove-Item -Times 1 -Scope It -ModuleName "ContainerNetworkTools" `
286-
-ParameterFilter { $Path -eq 'TestDrive:\TestDir\cni' }
285+
# Should NOT remove WinCNIPlugin binaries/dir
286+
Should -Invoke Remove-Item -Times 0 -Scope It -ModuleName "ContainerNetworkTools"
287287
}
288288

289289
It "Should do nothing if WinCNI plugins is not installed at specified path" {
290290
Mock Test-EmptyDirectory -ModuleName 'ContainerNetworkTools' -MockWith { return $true }
291291

292-
Uninstall-WinCNIPluginHelper -Path 'TestDrive:\TestDir\cni'
292+
Uninstall-WinCNIPlugin -Path 'TestDrive:\TestDir\cni' -Confirm:$false
293293
Should -Invoke Remove-Item -Times 0 -Scope It -ModuleName "ContainerNetworkTools"
294-
295-
$Error[0].Exception.Message | Should -Be 'Windows CNI plugin does not exist at TestDrive:\TestDir\cni or the directory is empty.'
296294
}
297295
}
298296
}

0 commit comments

Comments
 (0)