GoEddie / SQLCover

Apache License 2.0
61 stars 53 forks source link

SQLCover.CodeCoverage.Stop() gives Exception calling "Stop" with "0" argument(s): "Value cannot be null. Parameter name: source" #56

Closed OCS2000 closed 4 years ago

OCS2000 commented 4 years ago

Describe the bug SQLCover.CodeCoverage.Stop() results in error message: Exception calling "Stop" with "0" argument(s): "Value cannot be null. Parameter name: source".

To Reproduce Steps to reproduce the behavior:

  1. Install SQL Server 2019
  2. Install Redgate SQL Change Automation 4.3
  3. Install SQLCover release 0.5.0 to the "SQLCover" directory
  4. Run this PowerShell script: $packageVersion = "1.0.0" $packageID = "MyPackage" $serverInstance = "." $temporaryConnectionString = "Data Source=.;Integrated Security=True" $sqlCoverDllPath = "SQLCover\SQLCover.dll"

Import-Module SqlChangeAutomation -ErrorAction SilentlyContinue -ErrorVariable +ImportErrors

$statePath = Split-Path -Parent $MyInvocation.MyCommand.Path $scriptsFolder = Join-Path -Path $statePath -ChildPath "..\State"

$validatedScriptsFolder = Invoke-DatabaseBuild $scriptsFolder -TemporaryDatabaseServer $temporaryConnectionString $packageFilename = $packageID + "." + $packageVersion + ".nupkg"; If (Test-Path $packageFilename) { Remove-Item $packageFilename }

$databasePackage = New-DatabaseBuildArtifact $validatedScriptsFolder -PackageId $packageID -PackageVersion $packageVersion Export-DatabaseBuildArtifact $databasePackage -Path "."

$database = New-Guid

Unblock-File -Path $sqlCoverDllPath

Add-Type -Path $sqlCoverDllPath

Invoke-SqlCmd -ServerInstance $serverInstance -Query "CREATE DATABASE [$database]; ALTER DATABASE [$database] SET TRUSTWORTHY ON" $coverage = New-Object SQLCover.CodeCoverage($temporaryConnectionString, $database) $coverage.Start() $temporaryDatabase = New-DatabaseConnection -ServerInstance $serverInstance -Database $database $testResults = Invoke-DatabaseTests $databasePackage -TemporaryDatabase $temporaryDatabase $coverageResults = $coverage.Stop()

Write-Host "CoverageResults: $coverageResults"

Expected behavior $coverageResults referencing a CoverageResult object instance.

Desktop (please complete the following information):

Additional context The exception happens even if there are no tests to be run.

If I change "$testResults = Invoke-DatabaseTests $databasePackage -TemporaryDatabase $temporaryDatabase" to: "#$testResults = Invoke-DatabaseTests $databasePackage -TemporaryDatabase $temporaryDatabase"

then the new script runs without an error.

Output:

PS> .\Reproduce.ps1 Invoke-DatabaseBuild, SQL Change Automation 4.3.20205.21469, Copyright © Red Gate Software Ltd 2014-2019 Validating SQL Source Control project 'REMOVED'. Schema validation successful. New-DatabaseBuildArtifact, SQL Change Automation 4.3.20205.21469, Copyright © Red Gate Software Ltd 2014-2019 Export-DatabaseBuildArtifact, SQL Change Automation 4.3.20205.21469, Copyright © Red Gate Software Ltd 2014-2019 Database build artifact exported to file 'REMOVED\MyPackage.1.0.0.nupkg'. New-DatabaseConnection, SQL Change Automation 4.3.20205.21469, Copyright © Red Gate Software Ltd 2014-2019 Invoke-DatabaseTests, SQL Change Automation 4.3.20205.21469, Copyright © Red Gate Software Ltd 2014-2019 Cleaning database 'aab10b86-1eba-48a1-8fe7-ed7de7db3479' on server 'REMOVED'. Running tests contained in SQL Source Control build artifact Collecting results All tests passed Exception calling "Stop" with "0" argument(s): "Value cannot be null. Parameter name: source" At Reproduce.ps1:34 char:1

CoverageResults:

=== Please at me @GoEddie so I receive a notification

OCS2000 commented 4 years ago

@GoEddie, do you have any advice on this issue?

GoEddie commented 4 years ago

Are you settting the name of the database in the connection string to the temporary database?

OCS2000 commented 4 years ago

@GoEddie, thank you for your suggestion. I did not, but I did just try this now and with this change I get the same error: $temporaryConnectionStringWithInitialCatalog = "$temporaryConnectionString;Initial Catalog=$database" $coverage = New-Object SQLCover.CodeCoverage($temporaryConnectionStringWithInitialCatalog, $database)

GoEddie commented 4 years ago

I can't help thinking that the error is something to do with the connection string, that error isn't generated by SQLCover but (I think) by the sql connection. Try using this for the connection string "server=servername;integrated security=sspi;" instead of data source.

OCS2000 commented 4 years ago

"server=servername;integrated security=sspi;" with MS SQL instance name changed gives the same error. I'm not able to identify where in the SQLCover source code such error can arise. Still I have confirmed that the error definitely occur on this line: "$coverageResults = $coverage.Stop()" and that "$coverage.Start()" returns without an error.

GoEddie commented 4 years ago

If you download the source, you can debug it by passing true for the debug flag to Start - then if you attach visual studio it should stop on the line where the exception occurs.

I’d turn on logging as well.

To get to those flags you call the constructor without the defaults.

OCS2000 commented 4 years ago

This issue has now been resolved although I don't understand the cause of the exception. All versions I built myself from source code in the Git repository using the latest Visual Studio Community 2019 does not produce this exception.

https://github.com/GoEddie/SQLCover/archive/0.5.0.zip: Exception https://github.com/GoEddie/SQLCover/commit/922d7d2bc018faf3833ef69421efd3988ef8b8f7: No exception (Debug & Release) https://github.com/GoEddie/SQLCover/tree/0.5.0-p: No exception (Release) https://github.com/GoEddie/SQLCover/tree/0.5.0: No exception (Release)