Skip to content

Commit 6c184b5

Browse files
committed
fix(tests): recreate SSH session in each context to prevent Broken runspace errors
1 parent e25f04d commit 6c184b5

1 file changed

Lines changed: 74 additions & 56 deletions

File tree

tests/main-test.ps1

Lines changed: 74 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -42,100 +42,101 @@ function CleanUpContainers {
4242
[string]$hostname, [string]$username = $server -split ' '
4343
$username = $username -replace "ansible_user=", ""
4444

45-
$session = New-PSSession -HostName $hostname -UserName $username -SSHTransport
46-
4745

4846
#region Pester tests
4947
Describe "Docker Container Tests" {
5048
Context "Default Configuration" {
5149
BeforeAll {
52-
# run the main script
50+
$global:session = New-PSSession -HostName $hostname -UserName $username -SSHTransport
5351
pwsh -File $scriptPath -ConfigPath "$configDir/default.psd1" -InventoryPath $InventoryPath -become $become
5452
}
53+
AfterAll {
54+
Remove-PSSession $global:session
55+
}
5556

5657
It "Should ensure the pihole container is running correctly" {
57-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
58+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
5859
docker ps --filter "name=Pi-DNStack_pihole" --format "{{.Names}}"
5960
}
6061
$result | Should -Not -BeNullOrEmpty
6162
}
6263

6364
It "Should ensure the pihole container is bound to port 80 and 53" {
64-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
65+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
6566
docker inspect Pi-DNStack_pihole --format '{{range .HostConfig.PortBindings}}{{.}}{{end}}'
6667
}
6768
$result | Should -Match "80"
6869
$result | Should -Match "53"
6970
}
7071

7172
It "Should ensure the pihole container has the correct mount for /etc/pihole" {
72-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
73+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
7374
docker inspect Pi-DNStack_pihole --format '{{range .Mounts}}{{.Source}}{{end}}'
7475
}
7576
$result | Should -Match "/etc/pihole"
7677
}
7778

7879
It "Should ensure the restart policy is set to 'unless-stopped'" {
79-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
80+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
8081
docker inspect Pi-DNStack_pihole --format '{{.HostConfig.RestartPolicy.Name}}'
8182
}
8283
$result | Should -Match "unless-stopped"
8384
}
8485

8586
It "Should ensure the container network is set to 'bridge'" {
86-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
87+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
8788
docker inspect Pi-DNStack_pihole --format '{{.HostConfig.NetworkMode}}'
8889
}
8990
$result | Should -Match "bridge"
9091
}
9192

9293
It "Should ensure the unbound container is running correctly" {
93-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
94+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
9495
docker ps --filter "name=Pi-DNStack_pihole" --format "{{.Names}}"
9596
}
9697
$result | Should -Not -BeNullOrEmpty
9798
}
9899

99100
It "Should ensure the cloudflared container is running correctly" {
100-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
101+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
101102
docker ps --filter "name=Pi-DNStack_cloudflared" --format "{{.Names}}"
102103
}
103104
$result | Should -Not -BeNullOrEmpty
104105
}
105106

106107
It "Should ensure the pihole container is resolving correctly" {
107-
[string]$server = Invoke-Command -Session $session -ScriptBlock {
108+
[string]$server = Invoke-Command -Session $global:session -ScriptBlock {
108109
docker inspect Pi-DNStack_pihole --format '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
109110
}
110-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
111+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
111112
nslookup google.com $server
112113
} -ArgumentList $server
113114
$result | Should -Match "Non-authoritative answer"
114115
}
115116

116117
It "Should ensure DNSSEC is enabled" {
117-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
118+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
118119
docker exec Pi-DNStack_pihole cat /etc/pihole/setupVars.conf
119120
}
120121
$result | Should -Match "DNSSEC=true"
121122
}
122123

123124
It "Should ensure the adlists are set correctly" {
124-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
125+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
125126
docker exec Pi-DNStack_pihole pihole-FTL sqlite3 /etc/pihole/gravity.db "SELECT * FROM adlist"
126127
}
127128
$result | Should -Match "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
128129
}
129130

130131
It "Should ensure interface is set to eth0" {
131-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
132+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
132133
docker exec Pi-DNStack_pihole cat /etc/pihole/setupVars.conf
133134
}
134135
$result | Should -Match "PIHOLE_INTERFACE=eth0"
135136
}
136137

137138
It "Should ensure pihole listens on local" {
138-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
139+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
139140
docker exec Pi-DNStack_pihole cat /etc/pihole/setupVars.conf
140141
}
141142
$result | Should -Match "DNSMASQ_LISTENING=local"
@@ -144,36 +145,39 @@ Describe "Docker Container Tests" {
144145

145146
Context "Unbound Disabled" {
146147
BeforeAll {
147-
# run the main script
148+
$global:session = New-PSSession -HostName $hostname -UserName $username -SSHTransport
148149
pwsh -File $scriptPath -ConfigPath "$configDir/unbound_disabled.psd1" -InventoryPath $InventoryPath -become $become
149150
}
151+
AfterAll {
152+
Remove-PSSession $global:session
153+
}
150154

151155
It "Should ensure the unbound container is not running" {
152-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
156+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
153157
docker ps --filter "name=Pi-DNStack_unbound" --format "{{.Names}}" | wc -l
154158
}
155159
$result | Should -Be "0"
156160
}
157161

158162
It "Should ensure the cloudflared container is still running correctly" {
159-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
163+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
160164
docker ps --filter "name=Pi-DNStack_cloudflared" --format "{{.Names}}"
161165
}
162166
$result | Should -Not -BeNullOrEmpty
163167
}
164168

165169
It "Should ensure the pihole container is still running correctly" {
166-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
170+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
167171
docker ps --filter "name=Pi-DNStack_pihole" --format "{{.Names}}"
168172
}
169173
$result | Should -Not -BeNullOrEmpty
170174
}
171175

172176
It "Should ensure the pihole container is resolving correctly" {
173-
[string]$server = Invoke-Command -Session $session -ScriptBlock {
177+
[string]$server = Invoke-Command -Session $global:session -ScriptBlock {
174178
docker inspect Pi-DNStack_pihole --format '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
175179
}
176-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
180+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
177181
nslookup google.com $server
178182
} -ArgumentList $server
179183
$result | Should -Match "Non-authoritative answer"
@@ -182,35 +186,39 @@ Describe "Docker Container Tests" {
182186

183187
Context "Cloudflared Disabled" {
184188
BeforeAll {
185-
# run the main script
189+
$global:session = New-PSSession -HostName $hostname -UserName $username -SSHTransport
186190
pwsh -File $scriptPath -ConfigPath "$configDir/cloudflared_disabled.psd1" -InventoryPath $InventoryPath -become $become
187191
}
192+
AfterAll {
193+
Remove-PSSession $global:session
194+
}
195+
188196
It "Should ensure the cloudflared container is not running" {
189-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
197+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
190198
docker ps --filter "name=Pi-DNStack_cloudflared" --format "{{.Names}}" | wc -l
191199
}
192200
$result | Should -Be "0"
193201
}
194202

195203
It "Should ensure the unbound container is still running correctly" {
196-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
204+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
197205
docker ps --filter "name=Pi-DNStack_unbound" --format "{{.Names}}"
198206
}
199207
$result | Should -Not -BeNullOrEmpty
200208
}
201209

202210
It "Should ensure the pihole container is still running correctly" {
203-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
211+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
204212
docker ps --filter "name=Pi-DNStack_pihole" --format "{{.Names}}"
205213
}
206214
$result | Should -Not -BeNullOrEmpty
207215
}
208216

209217
It "Should ensure the pihole container is resolving correctly" {
210-
[string]$server = Invoke-Command -Session $session -ScriptBlock {
218+
[string]$server = Invoke-Command -Session $global:session -ScriptBlock {
211219
docker inspect Pi-DNStack_pihole --format '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
212220
}
213-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
221+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
214222
nslookup google.com $server
215223
} -ArgumentList $server
216224
$result | Should -Match "Non-authoritative answer"
@@ -219,97 +227,103 @@ Describe "Docker Container Tests" {
219227

220228
Context "StackName Changed" {
221229
BeforeAll {
230+
$global:session = New-PSSession -HostName $hostname -UserName $username -SSHTransport
222231
# as we change stackname we need to clear old containers to avoid port conflicts
223-
CleanUpContainers -session $session "$configDir/cloudflared_disabled.psd1"
232+
CleanUpContainers -session $global:session "$configDir/cloudflared_disabled.psd1"
224233
# run the main script
225234
pwsh -File $scriptPath -ConfigPath "$configDir/stackName_changed.psd1" -InventoryPath $InventoryPath -become $become
226235
}
236+
AfterAll {
237+
CleanUpContainers -session $global:session "$configDir/stackName_changed.psd1"
238+
Remove-PSSession $global:session
239+
}
240+
227241
It "Should ensure the stack name is set to 'custom_stack'" {
228-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
242+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
229243
docker ps | grep "custom_stack"
230244
}
231245
$result | Should -Not -BeNullOrEmpty
232246
}
233-
234-
# remove the containers after the context
235-
AfterAll {
236-
CleanUpContainers -session $session "$configDir/stackName_changed.psd1"
237-
}
238247
}
239248

240249
Context "Multiple Changes" {
241250
BeforeAll {
251+
$global:session = New-PSSession -HostName $hostname -UserName $username -SSHTransport
242252
# run the main script
243253
pwsh -File $scriptPath -ConfigPath "$configDir/changes.psd1" -InventoryPath $InventoryPath -become $become
244254
}
255+
AfterAll {
256+
Remove-PSSession $global:session
257+
}
258+
245259
It "Should ensure the restart policy is set to 'always'" {
246-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
260+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
247261
docker inspect Pi-DNStack_pihole --format '{{.HostConfig.RestartPolicy.Name}}'
248262
}
249263
$result | Should -Match "always"
250264
}
251265

252266
It "Should ensure the Pi-hole container is bound to port 8081 and 5356" {
253-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
267+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
254268
docker inspect Pi-DNStack_pihole --format '{{range .HostConfig.PortBindings}}{{.}}{{end}}'
255269
}
256270
$result | Should -Match "8081"
257271
$result | Should -Match "5356"
258272
}
259273

260274
It "Should ensure the unbound container is bound to port 5353" {
261-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
275+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
262276
docker inspect Pi-DNStack_unbound --format '{{range .HostConfig.PortBindings}}{{.}}{{end}}'
263277
}
264278
$result | Should -Match "5353"
265279
}
266280

267281
It "Should ensure the cloudflared container is bound to port 5054" {
268-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
282+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
269283
docker inspect Pi-DNStack_cloudflared --format '{{range .HostConfig.PortBindings}}{{.}}{{end}}'
270284
}
271285
$result | Should -Match "5054"
272286
}
273287

274288
It "Should ensure the Pi-hole password is changed" {
275-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
289+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
276290
docker inspect Pi-DNStack_pihole --format '{{range .Config.Env}}{{println .}}{{end}}'
277291
}
278292
$result | Should -Match "FTLCONF_webserver_api_password=secret"
279293
}
280294

281295
It "Should ensure volume path is changed" {
282-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
296+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
283297
docker inspect Pi-DNStack_pihole --format '{{range .Mounts}}{{.Source}}{{end}}'
284298
}
285299
$result | Should -Match "/etc/test/pihole"
286300
$result | Should -Match "/etc/test/dnsmasq.d"
287301
}
288302

289303
It "Should ensure DNSSEC is disabled" {
290-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
304+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
291305
docker exec Pi-DNStack_pihole cat /etc/pihole/setupVars.conf
292306
}
293307
$result | Should -Match "DNSSEC=false"
294308
}
295309

296310
It "Should ensure the adlists are set correctly" {
297-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
311+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
298312
docker exec Pi-DNStack_pihole pihole-FTL sqlite3 /etc/pihole/gravity.db "SELECT * FROM adlist"
299313
}
300314
$result | Should -Match "https://test.com"
301315
$result | Should -Not -Match "https://v.firebog.net/hosts/static/w3kbl.txt"
302316
}
303317

304318
It "Should ensure interface is set to eth1" {
305-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
319+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
306320
docker exec Pi-DNStack_pihole cat /etc/pihole/setupVars.conf
307321
}
308322
$result | Should -Match "PIHOLE_INTERFACE=eth1"
309323
}
310324

311325
It "Should ensure pihole listens on all" {
312-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
326+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
313327
docker exec Pi-DNStack_pihole cat /etc/pihole/setupVars.conf
314328
}
315329
$result | Should -Match "DNSMASQ_LISTENING=all"
@@ -318,45 +332,49 @@ Describe "Docker Container Tests" {
318332

319333
Context "Host Network" {
320334
BeforeAll {
335+
$global:session = New-PSSession -HostName $hostname -UserName $username -SSHTransport
321336
# run the main script
322337
pwsh -File $scriptPath -ConfigPath "$configDir/host_network.psd1" -InventoryPath $InventoryPath -become $become
323338
}
339+
AfterAll {
340+
Remove-PSSession $global:session
341+
}
324342

325343
It "Should ensure the container network is set to 'host'" {
326-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
344+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
327345
docker inspect Pi-DNStack_pihole --format '{{.HostConfig.NetworkMode}}'
328346
}
329347
$result | Should -Match "host"
330348
}
331349

332350
It "Should ensure the pihole container has no ports bound" {
333-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
351+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
334352
docker inspect Pi-DNStack_pihole --format '{{range .HostConfig.PortBindings}}{{.}}{{end}}'
335353
}
336354
$result | Should -BeNullOrEmpty
337355
}
338356

339357
It "Should ensure the cloudflared container has no ports bound" {
340-
[string]$result = Invoke-Command -Session $session -ScriptBlock {
358+
[string]$result = Invoke-Command -Session $global:session -ScriptBlock {
341359
docker inspect Pi-DNStack_cloudflared --format '{{range .HostConfig.PortBindings}}{{.}}{{end}}'
342360
}
343361
$result | Should -BeNullOrEmpty
344362
}
345363
}
346364

347365
Context "Password not changed" {
366+
BeforeAll {
367+
$global:session = New-PSSession -HostName $hostname -UserName $username -SSHTransport
368+
}
369+
AfterAll {
370+
CleanUpContainers -session $global:session "$configDir/password_not_changed.psd1"
371+
Remove-PSSession $global:session
372+
}
373+
348374
It "Should throw an error if the password is not changed" {
349375
pwsh -File $scriptPath -ConfigPath "$configDir/password_not_changed.psd1" -InventoryPath $InventoryPath -become $become 2>&1
350376
$LastExitCode | Should -Not -Be 0
351377
}
352-
353-
# remove the containers after the last context
354-
AfterAll {
355-
CleanUpContainers -session $session "$configDir/password_not_changed.psd1"
356-
}
357378
}
358379
}
359380
#endregion
360-
361-
# cleanup
362-
Remove-PSSession $session

0 commit comments

Comments
 (0)