Skip to content

Commit 38108f6

Browse files
committed
Stop execution if tool version already installed unless -Force is specified
1 parent 7cb550b commit 38108f6

File tree

7 files changed

+277
-41
lines changed

7 files changed

+277
-41
lines changed

Tests/BuildkitTools.Tests.ps1

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ Describe "BuildkitTools.psm1" {
5555
Mock Test-EmptyDirectory -ModuleName 'BuildkitTools' -MockWith { return $true }
5656
Mock Install-Buildkit -ModuleName 'BuildkitTools'
5757
Mock Remove-Item -ModuleName 'BuildkitTools'
58+
59+
# Mock for Invoke-ExecutableCommand- "nerdctl --version"
60+
$mockExecutablePath = "$TestDrive\Program Files\Buildkit\bin\buildkitd.exe"
61+
$mockConfigStdOut = New-MockObject -Type 'System.IO.StreamReader' -Methods @{ ReadToEnd = { return "buildkitd github.com/moby/buildkit v1.0.0 c949t3ti0484" } }
62+
$mockProcess = New-MockObject -Type 'System.Diagnostics.Process' -Properties @{
63+
StandardOutput = $mockConfigStdOut
64+
ExitCode = 0
65+
}
66+
Mock Invoke-ExecutableCommand -ModuleName "BuildkitTools" -MockWith { return $mockProcess } -ParameterFilter {
67+
$Executable -eq "$mockExecutablePath" -and
68+
$Arguments -eq "--version" }
5869
}
5970

6071
AfterEach {
@@ -77,6 +88,7 @@ Describe "BuildkitTools.psm1" {
7788
It "Should use defaults" {
7889
Install-Buildkit -Force -Confirm:$false
7990

91+
Should -Invoke Get-BuildkitLatestVersion -ModuleName 'BuildkitTools' -Times 1 -Exactly -Scope It
8092
Should -Invoke Uninstall-Buildkit -ModuleName 'BuildkitTools' -Times 0 -Exactly -Scope It
8193
Should -Invoke Get-InstallationFile -ModuleName 'BuildkitTools' -ParameterFilter {
8294
$fileParameters[0].Feature -eq "Buildkit" -and
@@ -127,11 +139,35 @@ Describe "BuildkitTools.psm1" {
127139
-ParameterFilter { $BuildKitPath -eq "$Env:ProgramFiles\Buildkit" -and $WinCNIPath -eq "" }
128140
}
129141

142+
It "Should not reinstall tool if version already exists and force is not specified" {
143+
Mock Test-EmptyDirectory -ModuleName 'BuildkitTools' -MockWith { return $false }
144+
145+
# Mock for Get-ChildItem - "buildkitd.exe"
146+
Mock Get-ChildItem -ModuleName 'BuildkitTools' -ParameterFilter {
147+
$Path -eq "$Env:ProgramFiles\Buildkit" -and
148+
$Recurse -eq $true
149+
$Filter -eq "buildkitd.exe"
150+
} -MockWith { return @{FullName = "$mockExecutablePath" } }
151+
152+
Install-Buildkit -Confirm:$false
153+
Should -Invoke Uninstall-Buildkit -ModuleName 'BuildkitTools' -Times 0
154+
Should -Invoke Install-RequiredFeature -ModuleName 'BuildkitTools' -Times 0
155+
}
156+
130157
It "Should uninstall tool if it is already installed" {
131158
Mock Test-EmptyDirectory -ModuleName 'BuildkitTools' -MockWith { return $false }
132159

160+
# Mock for Get-ChildItem - "buildkitd.exe"
161+
Mock Get-ChildItem -ModuleName 'BuildkitTools' -ParameterFilter {
162+
$Path -eq "$Env:ProgramFiles\Buildkit" -and
163+
$Recurse -eq $true
164+
$Filter -eq "buildkitd.exe"
165+
} -MockWith { return @{FullName = "$mockExecutablePath" } }
166+
133167
Install-Buildkit -Force -Confirm:$false
134168

169+
Should -Invoke Invoke-ExecutableCommand -ModuleName "BuildkitTools" `
170+
-ParameterFilter { ($Executable -eq $mockExecutablePath ) -and ($Arguments -eq "--version") }
135171
Should -Invoke Uninstall-Buildkit -ModuleName 'BuildkitTools' -Times 1 -Exactly -Scope It `
136172
-ParameterFilter { $Path -eq "$Env:ProgramFiles\Buildkit" -and $force -eq $true }
137173
}
@@ -140,7 +176,14 @@ Describe "BuildkitTools.psm1" {
140176
Mock Test-EmptyDirectory -ModuleName 'BuildkitTools' -MockWith { return $false }
141177
Mock Uninstall-Buildkit -ModuleName 'BuildkitTools' -MockWith { throw 'Error' }
142178

143-
{ Install-Buildkit -Confirm:$false } | Should -Throw "Buildkit installation failed. Error"
179+
# Mock for Get-ChildItem - "buildkitd.exe"
180+
Mock Get-ChildItem -ModuleName 'BuildkitTools' -ParameterFilter {
181+
$Path -eq "$Env:ProgramFiles\Buildkit" -and
182+
$Recurse -eq $true
183+
$Filter -eq "buildkitd.exe"
184+
} -MockWith { return @{FullName = "$mockExecutablePath" } }
185+
186+
{ Install-Buildkit -Confirm:$false -Force } | Should -Throw "Buildkit installation failed. Error"
144187
}
145188
}
146189

Tests/ContainerdTools.Tests.ps1

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ Describe "ContainerdTools.psm1" {
5555
Mock Test-EmptyDirectory -ModuleName 'ContainerdTools' -MockWith { return $true }
5656
Mock Install-Containerd -ModuleName 'ContainerdTools'
5757
Mock Remove-Item -ModuleName 'ContainerdTools'
58+
59+
# Mock for Invoke-ExecutableCommand- "nerdctl --version"
60+
$mockExecutablePath = "$TestDrive\Program Files\Containerd\bin\containerd.exe"
61+
$mockConfigStdOut = New-MockObject -Type 'System.IO.StreamReader' -Methods @{ ReadToEnd = { return "containerd github.com/containerd/containerd/v1 v1.0.0 c949t3ti0484" } }
62+
$mockProcess = New-MockObject -Type 'System.Diagnostics.Process' -Properties @{
63+
StandardOutput = $mockConfigStdOut
64+
ExitCode = 0
65+
}
66+
Mock Invoke-ExecutableCommand -ModuleName "ContainerdTools" -MockWith { return $mockProcess } -ParameterFilter {
67+
$Executable -eq "$mockExecutablePath" -and
68+
$Arguments -eq "--version" }
5869
}
5970

6071
It 'Should not process on implicit request for validation (WhatIfPreference)' {
@@ -73,6 +84,7 @@ Describe "ContainerdTools.psm1" {
7384
It "Should use defaults" {
7485
Install-Containerd -Force -Confirm:$false
7586

87+
Should -Invoke Get-ContainerdLatestVersion -ModuleName 'ContainerdTools' -Times 1 -Exactly -Scope It
7688
Should -Invoke Uninstall-Containerd -ModuleName 'ContainerdTools' -Times 0 -Exactly -Scope It
7789
Should -Invoke Get-InstallationFile -ModuleName 'ContainerdTools' -ParameterFilter {
7890
($fileParameters[0].Feature -eq "Containerd") -and
@@ -119,11 +131,35 @@ Describe "ContainerdTools.psm1" {
119131
-ParameterFilter { $ContainerdPath -eq "$Env:ProgramFiles\Containerd" }
120132
}
121133

134+
It "Should not reinstall tool if version already exists and force is not specified" {
135+
Mock Test-EmptyDirectory -ModuleName 'ContainerdTools' -MockWith { return $false }
136+
137+
# Mock for Get-ChildItem - "containerd.exe"
138+
Mock Get-ChildItem -ModuleName 'ContainerdTools' -ParameterFilter {
139+
$Path -eq "$Env:ProgramFiles\Containerd" -and
140+
$Recurse -eq $true
141+
$Filter -eq "containerd.exe"
142+
} -MockWith { return @{FullName = "$mockExecutablePath" } }
143+
144+
Install-Containerd -Confirm:$false
145+
Should -Invoke Uninstall-Containerd -ModuleName 'ContainerdTools' -Times 0
146+
Should -Invoke Install-RequiredFeature -ModuleName 'ContainerdTools' -Times 0
147+
}
148+
122149
It "Should uninstall tool if it is already installed" {
123150
Mock Test-EmptyDirectory -ModuleName 'ContainerdTools' -MockWith { return $false }
124151

152+
# Mock for Get-ChildItem - "containerd.exe"
153+
Mock Get-ChildItem -ModuleName 'ContainerdTools' -ParameterFilter {
154+
$Path -eq "$Env:ProgramFiles\Containerd" -and
155+
$Recurse -eq $true
156+
$Filter -eq "containerd.exe"
157+
} -MockWith { return @{FullName = "$mockExecutablePath" } }
158+
125159
Install-Containerd -Force -Confirm:$false
126160

161+
Should -Invoke Invoke-ExecutableCommand -ModuleName "ContainerdTools" `
162+
-ParameterFilter { ($Executable -eq $mockExecutablePath ) -and ($Arguments -eq "--version") }
127163
Should -Invoke Uninstall-Containerd -ModuleName 'ContainerdTools' -Times 1 -Exactly -Scope It `
128164
-ParameterFilter { $Path -eq "$Env:ProgramFiles\Containerd" -and $force -eq $true }
129165
}
@@ -132,7 +168,14 @@ Describe "ContainerdTools.psm1" {
132168
Mock Test-EmptyDirectory -ModuleName 'ContainerdTools' -MockWith { return $false }
133169
Mock Uninstall-Containerd -ModuleName 'ContainerdTools' -MockWith { throw 'Error' }
134170

135-
{ Install-Containerd -Confirm:$false } | Should -Throw "Containerd installation failed. Error"
171+
# Mock for Get-ChildItem - "containerd.exe"
172+
Mock Get-ChildItem -ModuleName 'ContainerdTools' -ParameterFilter {
173+
$Path -eq "$Env:ProgramFiles\Containerd" -and
174+
$Recurse -eq $true
175+
$Filter -eq "containerd.exe"
176+
} -MockWith { return @{FullName = "$mockExecutablePath" } }
177+
178+
{ Install-Containerd -Confirm:$false -Force } | Should -Throw "Containerd installation failed. Error"
136179
}
137180
}
138181

Tests/NerdctlTools.Tests.ps1

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ Describe "NerdctlTools.psm1" {
1414
$RootPath = Split-Path -Parent $PSScriptRoot
1515
$ModuleParentPath = Join-Path -Path $RootPath -ChildPath 'Containers-Toolkit'
1616
Import-Module -Name "$ModuleParentPath\Private\CommonToolUtilities.psm1" -Force
17-
Import-Module -Name "$ModuleParentPath\Public\NerdctlTools.psm1"
1817
Import-Module -Name "$ModuleParentPath\Public\ContainerdTools.psm1"
18+
Import-Module -Name "$ModuleParentPath\Public\BuildkitTools.psm1"
1919
Import-Module -Name "$ModuleParentPath\Public\ContainerNetworkTools.psm1"
2020
Import-Module -Name "$ModuleParentPath\Public\NerdctlTools.psm1" -Force
2121
}
@@ -26,8 +26,8 @@ Describe "NerdctlTools.psm1" {
2626

2727
AfterAll {
2828
Remove-Module -Name "$ModuleParentPath\Private\CommonToolUtilities.psm1" -Force -ErrorAction Ignore
29-
Remove-Module -Name "$ModuleParentPath\Public\BuildkitTools.psm1" -Force -ErrorAction Ignore
3029
Remove-Module -Name "$ModuleParentPath\Public\ContainerdTools.psm1" -Force -ErrorAction Ignore
30+
Remove-Module -Name "$ModuleParentPath\Public\BuildkitTools.psm1" -Force -ErrorAction Ignore
3131
Remove-Module -Name "$ModuleParentPath\Public\ContainerNetworkTools.psm1" -Force -ErrorAction Ignore
3232
Remove-Module -Name "$ModuleParentPath\Public\NerdctlTools.psm1" -Force -ErrorAction Ignore
3333
}
@@ -49,6 +49,17 @@ Describe "NerdctlTools.psm1" {
4949
Mock Install-WinCNIPlugin -ModuleName 'NerdctlTools'
5050
Mock Install-Nerdctl -ModuleName 'NerdctlTools'
5151
Mock Remove-Item -ModuleName 'NerdctlTools'
52+
53+
# Mock for Invoke-ExecutableCommand- "nerdctl --version"
54+
$mockExecutablePath = "$TestDrive\Program Files\nerdctl\nerdctl.exe"
55+
$mockConfigStdOut = New-MockObject -Type 'System.IO.StreamReader' -Methods @{ ReadToEnd = { return "nerdctl version v7.9.8" } }
56+
$mockProcess = New-MockObject -Type 'System.Diagnostics.Process' -Properties @{
57+
StandardOutput = $mockConfigStdOut
58+
ExitCode = 0
59+
}
60+
Mock Invoke-ExecutableCommand -ModuleName "NerdctlTools" -MockWith { return $mockProcess } -ParameterFilter {
61+
$Executable -eq "$mockExecutablePath" -and
62+
$Arguments -eq "--version" }
5263
}
5364

5465
It 'Should not process on implicit request for validation (WhatIfPreference)' {
@@ -67,6 +78,7 @@ Describe "NerdctlTools.psm1" {
6778
It "Should use defaults" {
6879
Install-Nerdctl -Force -Confirm:$false
6980

81+
Should -Invoke Get-NerdctlLatestVersion -ModuleName 'NerdctlTools' -Times 1 -Exactly -Scope It
7082
Should -Invoke Uninstall-Nerdctl -ModuleName 'NerdctlTools' -Times 0 -Exactly -Scope It
7183
Should -Invoke Get-InstallationFile -ModuleName 'NerdctlTools' -ParameterFilter {
7284
$fileParameters[0].Feature -eq "nerdctl" -and
@@ -117,11 +129,35 @@ Describe "NerdctlTools.psm1" {
117129
Should -Invoke Install-WinCNIPlugin -ModuleName 'NerdctlTools' -Times 0 -Exactly -Scope It
118130
}
119131

132+
It "Should not reinstall tool if version already exists and force is not specified" {
133+
Mock Test-EmptyDirectory -ModuleName 'ContainerdTools' -MockWith { return $false }
134+
135+
# Mock for Get-ChildItem - "nerdctl.exe"
136+
Mock Get-ChildItem -ModuleName 'NerdctlTools' -ParameterFilter {
137+
$Path -eq "$Env:ProgramFiles\nerdctl" -and
138+
$Recurse -eq $true
139+
$Filter -eq "nerdctl.exe"
140+
} -MockWith { return @{FullName = "$mockExecutablePath" } }
141+
142+
Install-Nerdctl -Confirm:$false
143+
Should -Invoke Uninstall-Nerdctl -ModuleName 'NerdctlTools' -Times 0
144+
Should -Invoke Install-RequiredFeature -ModuleName 'NerdctlTools' -Times 0
145+
}
146+
120147
It "Should uninstall tool if it is already installed" {
121148
Mock Test-EmptyDirectory -ModuleName 'NerdctlTools' -MockWith { return $false }
122149

150+
# Mock for Get-ChildItem - "nerdctl.exe"
151+
Mock Get-ChildItem -ModuleName 'NerdctlTools' -ParameterFilter {
152+
$Path -eq "$Env:ProgramFiles\nerdctl" -and
153+
$Recurse -eq $true
154+
$Filter -eq "nerdctl.exe"
155+
} -MockWith { return @{FullName = "$mockExecutablePath" } }
156+
123157
Install-Nerdctl -Force -Confirm:$false
124158

159+
Should -Invoke Invoke-ExecutableCommand -ModuleName "NerdctlTools" `
160+
-ParameterFilter { ($Executable -eq $mockExecutablePath ) -and ($Arguments -eq "--version") }
125161
Should -Invoke Uninstall-Nerdctl -ModuleName 'NerdctlTools' -Times 1 -Exactly -Scope It `
126162
-ParameterFilter { $Path -eq "$Env:ProgramFiles\nerdctl" }
127163
}
@@ -130,19 +166,26 @@ Describe "NerdctlTools.psm1" {
130166
Mock Test-EmptyDirectory -ModuleName 'NerdctlTools' -MockWith { return $false }
131167
Mock Uninstall-Nerdctl -ModuleName 'NerdctlTools' -MockWith { throw 'Error' }
132168

133-
{ Install-Nerdctl -Confirm:$false } | Should -Throw "nerdctl installation failed. Error"
169+
# Mock for Get-ChildItem - "nerdctl.exe"
170+
Mock Get-ChildItem -ModuleName 'NerdctlTools' -ParameterFilter {
171+
$Path -eq "$Env:ProgramFiles\nerdctl" -and
172+
$Recurse -eq $true
173+
$Filter -eq "nerdctl.exe"
174+
} -MockWith { return @{FullName = "$mockExecutablePath" } }
175+
176+
{ Install-Nerdctl -Confirm:$false -Force } | Should -Throw "nerdctl installation failed. Error"
134177
}
135178

136179
It "Should install all dependencies if 'All' is specified" {
137-
Install-Nerdctl -Dependencies 'All' -Confirm:$false
180+
Install-Nerdctl -Dependencies 'All' -Confirm:$false -Force
138181

139182
Should -Invoke Install-Containerd -ModuleName 'NerdctlTools' -Times 1 -Exactly -Scope It
140183
Should -Invoke Install-Buildkit -ModuleName 'NerdctlTools' -Times 1 -Exactly -Scope It
141184
Should -Invoke Install-WinCNIPlugin -ModuleName 'NerdctlTools' -Times 1 -Exactly -Scope It
142185
}
143186

144187
It "Should install specified dependencies" {
145-
Install-Nerdctl -Dependencies 'containerd' -Confirm:$false
188+
Install-Nerdctl -Dependencies 'containerd' -Confirm:$false -Force
146189

147190
Should -Invoke Install-Containerd -ModuleName 'NerdctlTools' -Times 1 -Exactly -Scope It
148191
Should -Invoke Install-Buildkit -ModuleName 'NerdctlTools' -Times 0 -Exactly -Scope It

containers-toolkit/Private/CommonToolUtilities.psm1

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ function Get-LatestToolVersion($repository) {
8585
}
8686
}
8787

88+
function Test-IsLatestVersion($Tool, $Version, $LatestVersion) {
89+
$currentVersion = [System.Version]$Version
90+
$latestVersion = [System.Version]$latestVersion
91+
92+
$isLatest = ($currentVersion -eq $latestVersion)
93+
if (-not $isLatest) {
94+
Write-Warning "A newer version of $tool is available. { Version: $currentVersion, Latest version: $latestVersion }"
95+
}
96+
return $isLatest
97+
}
98+
8899
function Test-EmptyDirectory($path) {
89100
if (-not (Test-Path -Path $path)) {
90101
return $true
@@ -513,6 +524,8 @@ function Test-FileChecksum {
513524
$isValid = $downloadedChecksum.Hash -eq $checksum
514525
$found = $true
515526
return
527+
} else {
528+
Write-Debug "File name does not match. {checksum file: $filename, downloaded file: $downloadedFileName}"
516529
}
517530
}
518531

@@ -891,6 +904,7 @@ function Invoke-ExecutableCommand {
891904

892905

893906
Export-ModuleMember -Function Get-LatestToolVersion
907+
Export-ModuleMember -Function Test-IsLatestVersion
894908
Export-ModuleMember -Function Get-DefaultInstallPath
895909
Export-ModuleMember -Function Test-EmptyDirectory
896910
Export-ModuleMember -Function Get-InstallationFile

0 commit comments

Comments
 (0)