@@ -50,6 +50,21 @@ Describe $CommandName -Tag IntegrationTests {
5050 $PSDefaultParameterValues.Remove (" *-Dba*:EnableException" )
5151 }
5252
53+ Context " A missing file does not eat an iteration of the caller's loop" {
54+ It " Warns and completes every iteration" {
55+ # The begin block guards used to run Stop-Function -Continue without an enclosing loop -
56+ # the continue escaped the command and consumed an iteration of this very loop, so the
57+ # counter fell short (#10638).
58+ $loopCount = 0
59+ foreach ($i in 1 .. 3 ) {
60+ $null = Import-DbaSpConfigure - SqlInstance $TestConfig.InstanceSingle - Path " $exportPath \does-not-exist.sql" - WarningAction SilentlyContinue
61+ $loopCount ++
62+ }
63+ $loopCount | Should - Be 3
64+ $WarnVar | Should - BeLike " *Not Found*"
65+ }
66+ }
67+
5368 Context " The connection of the caller is left alone when importing from a file (#10554)" {
5469 BeforeAll {
5570 $PSDefaultParameterValues [" *-Dba*:EnableException" ] = $true
@@ -246,4 +261,60 @@ SELECT name, value, value_in_use FROM sys.configurations WHERE name IN ('cost th
246261 $WarnVar [-1 ] | Should -Match " Some configuration options will be updated once SQL Server is restarted"
247262 }
248263 }
264+
265+ Context " A guard interrupt still closes the connection the command opened (#10554)" {
266+ BeforeAll {
267+ # This pins the invariant that a guard interrupt leaves no session of the command
268+ # behind. Probed while writing it: SMO's auto-disconnect returns the physical
269+ # connection after every batch for every connection the command opens itself - the
270+ # skipped end-block disconnect was therefore not observable on any reachable input
271+ # shape, and this test also passes on the unfixed code. It stands guard for the day a
272+ # connection is held open eagerly. The application name marks the session so the count
273+ # below finds exactly this one; Pooling=False makes a survivor impossible to miss.
274+ $guardAppName = " dbatoolsci_spconfigure_guard_$ ( Get-Random ) "
275+ $guardConnectionString = " Data Source=$ ( $TestConfig.InstanceSingle ) ;Integrated Security=True;Trust Server Certificate=True;Pooling=False;Application Name=$guardAppName "
276+
277+ # The missing file is the guard under test: the begin block has already opened the
278+ # connection when it stops, so the end block cleanup must run despite the interrupt.
279+ $splatGuardImport = @ {
280+ SqlInstance = $guardConnectionString
281+ Path = " $exportPath \does-not-exist.sql"
282+ WarningAction = " SilentlyContinue"
283+ }
284+ $null = Import-DbaSpConfigure @splatGuardImport
285+ # Invoke-DbaQuery below writes to $WarnVar as well, so it has to be kept here.
286+ $guardWarnings = $WarnVar
287+
288+ $PSDefaultParameterValues [" *-Dba*:EnableException" ] = $true
289+
290+ $guardSessionQuery = @"
291+ SELECT COUNT(*) AS SessionCount FROM sys.dm_exec_sessions WHERE program_name = '$guardAppName '
292+ "@
293+ $guardSessionCount = (Invoke-DbaQuery - SqlInstance $TestConfig.InstanceSingle - Query $guardSessionQuery ).SessionCount
294+
295+ $PSDefaultParameterValues.Remove (" *-Dba*:EnableException" )
296+ }
297+
298+ AfterAll {
299+ $PSDefaultParameterValues [" *-Dba*:EnableException" ] = $true
300+
301+ # On a defective command the non-pooled session survives - close the cached connection
302+ # and kill any remaining marked session so nothing leaks into later tests.
303+ $guardEntry = Get-DbaConnectedInstance | Where-Object ConnectionString -match $guardAppName
304+ if ($guardEntry ) {
305+ $null = $guardEntry.ConnectionObject | Disconnect-DbaInstance
306+ }
307+ $null = Get-DbaProcess - SqlInstance $TestConfig.InstanceSingle - Program $guardAppName - WarningAction SilentlyContinue | Stop-DbaProcess - WarningAction SilentlyContinue
308+
309+ $PSDefaultParameterValues.Remove (" *-Dba*:EnableException" )
310+ }
311+
312+ It " warns about the missing file" {
313+ $guardWarnings | Should - BeLike " *Not Found*"
314+ }
315+
316+ It " closes the non-pooled connection it opened although the guard interrupted the command" {
317+ $guardSessionCount | Should - Be 0
318+ }
319+ }
249320}
0 commit comments