How to pass SQLCMD variables du MSBuild during Build? - visual-studio

I am referencing a database project during publish in a second database project. For easier reference, let's call them Database and Database.Tests.
Database is being referenced by Database.Tests
During deployment the Database project will be deployed twice to the same machine. Once as "Database" and once as part of "Database.Tests"
Doing this manually using the publish option is working as expected, however when using SqlPackage.exe I am running into an error when publishing the seoncd database:
*** Could not deploy package.
Error SQL72014: .Net SqlClient Data Provider: Msg 33415, Level 16, State 4, Line 5 FILESTREAM DIRECTORY_NAME 'AZE' attempting to be set on database 'Database.Tests' is not unique in this SQL Server instance. Provide a unique value for the database option FILESTREAM DIRECTORY_NAME to enable non-transacted access.
Error SQL72045: Script execution error. The executed script:
IF EXISTS (SELECT 1
FROM [master].[dbo].[sysdatabases]
WHERE [name] = N'$(DatabaseName)')
BEGIN
ALTER DATABASE [$(DatabaseName)]
SET FILESTREAM(NON_TRANSACTED_ACCESS = FULL, DIRECTORY_NAME = N'AZE'),
CONTAINMENT = NONE
WITH ROLLBACK IMMEDIATE;
END
Here is what I am doing. the first thing is to create the test database. To do that I am deploying tSQLt, the Database project and lastly the database.tests project using the following sqlPackage.exe commands:
"C:\Program Files\Microsoft SQL Server\150\DAC\bin\SqlPackage.exe" /Action:Publish ^
/SourceFile:"Database.dacpac" ^
/TargetDatabaseName:"Database.Tests" ^
/TargetServerName:"server\instance" ^
/v:MSSQL_USER="some_user" ^
/v:MSSQL_PASSWORD="somepassword"
"C:\Program Files\Microsoft SQL Server\150\DAC\bin\SqlPackage.exe" /Action:Publish ^
/SourceFile:"Database.dacpac" ^
/TargetDatabaseName:"Database.Tests" ^
/TargetServerName:"server\instance"
"C:\Program Files\Microsoft SQL Server\150\DAC\bin\SqlPackage.exe" /Action:Publish ^
/SourceFile:"Database.Tests.dacpac" ^
/TargetDatabaseName:"Database.Tests" ^
/TargetServerName:"server\instance"
# at this point we deploy the second database into a database called `Database`
"C:\Program Files\Microsoft SQL Server\150\DAC\bin\SqlPackage.exe" /Action:Publish ^
/SourceFile:"Database.dacpac" ^
/TargetDatabaseName:"Database" ^
/TargetServerName:"server\instance" ^
/v:MSSQL_USER="some_user" ^
/v:MSSQL_PASSWORD="somepassword"
Can I dynamically change the filestream directory setting at deployment-time or circumvent this issue in some other way? In theory I only need the schema, sprocs and functions from the Database project in my test database to execute my tSQLt tests and nothing else.

This may not answer your question directly, but here goes.
We make extensive use of SSDT and tSQLt. In our database solutions, the unit tests reside in their own project. (Using composite projects the root project is everything common to all environments; dev, stage, prod and unit test are separate projects in the solution.) The dev project has a database reference to the unit test project. The reference is marked as same database. That way when dev deploys it carries the unit test project items with it. And the unit test project would not need the FILESTREAM settings.
FILESTREAM settings would be relative to each environment project and would not be in the unit test project. That way only a single reference is ever deployed.
If you only have the root project and a unit test project in the solution you could still accomplish it with a database reference as noted above. Either way, the unit test project is never deployed directly, only by reference from another project in the solution.

Related

When running mstest under OpenCover, I get an error regarding the .vsmdi.trx file

I am having a problem when trying to run a VS10 test suite through OpenCover, using mstest as my target application.
Running the tests directly with MsTest works with this command:
"C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe" /resultsfile:"<application_root_path>\UnitTestResults\MyProject.vsmdi.trx" /testmetadata:"MyProject.vsmdi" /testlist:"ServiceTests" /testlist:"DatabaseTests"
However, when trying to run the same command under OpenCover, like this:
OpenCover\Opencover.console.exe -register:user -target:"C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe" -targetargs:"/resultsfile:"<application_root_path>\UnitTestResults\MyProject.vsmdi.trx" /testmetadata:"MyProject.vsmdi" /testlist:"ServiceTests" /testlist:"DatabaseTests"" -output:<application_root_path>\UnitTestResults\Coverage
it fails, with the following error, regarding the .vsmdi.trx file (which I gather should be created by MsTest after the tests run):
Error occurred while loading document '<application_root_path>\UnitTestResults\MyProject.vsmdi.trx'.
Code: 0x800c0006
The system cannot locate the object specified.
So, basically, it complains that it cannot find the results file, before running the tests, but that file is supposed to be created at the end of the run.
Might this be an issue related to OpenCover, as the same params work when running directly with mstest?
I checked my paths and they all work out, even the one in the error is the path where the file should be generated by mstest.
Thanks.
It looks like you may need to escape your quotes when passing your data via targetargs
-targetargs:"/resultsfile:"<application...""
becomes
-targetargs:"/resultsfile:\"<application...\""
as detailed in the wiki on handling spaces.
Alternatively put your command to execute your tests in a cmd/bat file and then use opencover to execute that.

CREATE DATABASE fails using VSDBCMD

When trying to deploy a VS2010 database project using the VSDBCMD tool, I get the following error:
SQL01268 .Net SqlClient Data Provider: Msg 5133, Level 16, State 1, Line 1 Directory lookup for the file "D:\MSSQL10_50\MSSQL10_50.MSSQLSERVER\MSSQL\Data\Data.mdf" failed with the operating system error 21(failed to retrieve text for this error. Reason: 1815).
SQL01268 .Net SqlClient Data Provider: Msg 1802, Level 16, State 1, Line 1 CREATE DATABASE failed. Some file names listed could not be created. Check related errors.
However, if I take the SQL script generated by VSDBCMD and run it in SQL Management Studio, it works fine. Similarly, I can create the DB manually in Mgt Studio.
'Operating system error 21' is apparently Device Not Ready, but this looks spurious to me... The folder paths are all correct, and unlocking the security on the folders doesn't fix the issue (e.g. 'everyone' > full control). Also, there are no errors in the SQL log or event viewer on the server.
What is different between running VSDBCMD on the command line, and running the same SQL script through Management Studio??
Any ideas very welcome!
Chris
As per my own comments, this error was because the drive didn't actually exist.
If you are creating database with vsdbcmd in a server based on a dbschema, it would be nice to set path location for data and log files.
To change log path location in your .dbschema file:
<Element Type="ISql90File" Name="[YOUR_DATABASE_NAME_Data]">
<Property Name="FileName" Value="E:\YOUR DATA FOLDER\$(DatabaseName)_Data.MDF" />
<Element Type="ISql90File" Name="[YOUR_DATABASE_NAME_Log]">
<Property Name="FileName" Value="E:\YOUR LOGS FOLDER\$(DatabaseName)_Log.LDF" />
then import it into Sql Server using Command prompt:
CD\
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VSTSDB\Deploy\vsdbcmd.exe" /a:Deploy
/cs:"Server=YOUR_SERVER\YOUR_INSTANCE;User Id=YOUR_USER;Password=YOUR_PASS;Pooling=false"
/dsp:Sql /dd+ /model:"C:\FOLDER\YOUR_DBSCHEMA_FILE.dbschema"
/p:TargetDatabase="YOUR_DATABASE_NAME"
More info on vsdbcmd: http://msdn.microsoft.com/en-us/library/dd193283.aspx

VS2010 DB Project Deploy Error SQL01268 Directory Lookup Failed

My VS2010 database deploy is failing on my build server, which has SQL Server 2008 R2 installed on it. Here's the output that's relevant:
Creating Acme.Database...
D:\TeamCity\BuildAgent\Work\da2fc5ebd5805d44\src\Acme.Database\sql\Acme.Database.sql(30,0): Error SQL01268: .Net SqlClient Data Provider: Msg 5133, Level 16, State 1, Line 1 Directory lookup for the file "C:\Program Files\Microsoft SQL Server**MSSQL10.MSSQLSERVER**\MSSQL\DATA\Acme_Database_log.ldf" failed with the operating system error 3(The system cannot find the path specified.).
D:\TeamCity\BuildAgent\Work\da2fc5ebd5805d44\src\Acme.Database\sql\Acme.Database.sql(30,0): Error SQL01268: .Net SqlClient Data Provider: Msg 1802, Level 16, State 1, Line 1 CREATE DATABASE failed. Some file names listed could not be created. Check related errors.
An error occurred while the batch was being executed.
The actual path is here:
C:\Program Files\Microsoft SQL Server**MSSQL10_50.MSSQLSERVER**\MSSQL\DATA\Acme_Database.mdf
The only reference to the path I could find in the database project was in the root folder, a file called:
PRIMARY.Acme_Database.sqlfile.sql
It includes an ALTER DATABASE statement that I changed to use the _50 path, but this did not fix the issue.
I'm not sure why the db project needs to know where the actual database MDF file is located in any case - I would have thought it could just connect to it vis TSQL, but in any case I can't get the project to deploy with this error and would appreciate any help.
Turns out if you specify a "file" in Schema Objects\Database Level Objects\Storage\Files (use Add Item, File) the values specified in the path override those looked up from the Server. If you must specify them use the variables from sqlcmdvariables $(DefaultdataPath)$(Databasename) to fill things out.
Take a look at the default file path on the server itself.
Screencast: http://screencast.com/t/OWM5ODFjZj
The fact that you don't have a path specified could likely be the issue.
[Update]
The reason I suggest this is that during the creation of the deployment script, if you have not specified the settings in the Project Settings -> Deployment tab, the DefaultDataPath is looked up from the target server's path.
I don't know anything about TeamCity really so this may be a stupid question, but how are you doing the deployment? It looks like the MSBuild deploy task for a DB project can take a property that gives the data path:
http://www.codewrecks.com/blog/index.php/2009/10/06/deploy-a-database-project-with-tfs-build/
Can you set the path that way?
I had the same error, but a different solution.
For me everything was correct (as far as I can tell), but the generated deploy script set the path variables before the databasename variable - resulting in a reference to a variable that did not exist. I updated Database.sqlcmdvars to hardcode the database name value - not best practice, but a sufficient workaround for my needs.

Running a generic test after a successful build using vs and TFS 2010

I'm using team explorer under vs2010 to queue a build that is configured to run an automated test after the build. The automated test section is configured to use a vsmdi file that defines one testlist with one generic test that only opens calc.exe.
Looking in the log, after the successful build, mstest generates the following error log and calc is not running on the build agent:
Run MSTest for Metadata File
The MSTestActivity was invoked without a value for Platform or Flavor. The values Mixed Platforms and Debug were used.
C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe /nologo /usestderr /searchpathroot:"C:\Builds\4\CITest\CI_AUT_1\Binaries" /resultsfileroot:"C:\Builds\4\CITest\CI_AUT_1\TestResults" /testmetadata:"C:\Builds\4\CITest\CI_AUT_1\Sources\AUT1.vsmdi" /testlist:"TestList1" /publish:"http://vmftrnd70.devlab.ad:8080/tfs/QTPCollection" /publishbuild:"vstfs:///Build/Build/82" /teamproject:"CITest" /platform:"Mixed Platforms" /flavor:"Debug"
Loading C:\Builds\4\CITest\CI_AUT_1\Sources\AUT1.vsmdi...
Search path(s) for tests:
C:\Builds\4\CITest\CI_AUT_1\Binaries
C:\Builds\4\CITest\CI_AUT_1\Sources
Search path(s) for default test settings:
C:\Builds\4\CITest\CI_AUT_1\Sources
Failed to load tests from 'C:\Builds\4\CITest\CI_AUT_1\Binaries\generictest1.generictest': Microsoft.VisualStudio.TestTools.TestManagement.InvalidStorageExtensionException: File extension specified '.generictest' is not a valid test extension.
at Microsoft.VisualStudio.TestTools.TestManagement.Tmi.GetTestTypeInfosForExtension(String ext)
at Microsoft.VisualStudio.TestTools.TestManagement.Tmi.GetTestTypesNotManagedInStorage(String storage)
at Microsoft.VisualStudio.TestTools.TestManagement.Tmi.LoadTestsFromTipsHelper(IEnumerable`1 locations, ProjectData projectData)
at Microsoft.VisualStudio.TestTools.TestManagement.Tmi.LoadTests(IEnumerable`1 locations, ProjectData projectData, TestConflictHandler vetoingHandler)
at Microsoft.VisualStudio.TestTools.TestManagement.Tmi.LoadTests(String location, ProjectData projectData, TestConflictHandler vetoingHandler)
at Microsoft.VisualStudio.TestTools.TestManagement.Tmi.LoadTestLinkStorageHelper.LoadTests(String fullStoragePath, ProjectData projectData)
at Microsoft.VisualStudio.TestTools.TestManagement.Tmi.SimpleLoadTestLinkStorageHelper.Load(String fullStoragePath, ProjectData projectData)
Starting execution...
Test GenericTest1 cannot be found.
No tests to execute.
I've tried all possible ways to get the generic test to run after the build with no success...
Nothing about this on msdn\google,
Thank you for any clue you can think of.
You need full Visual Studio installed to recognise the filetype
I haven't used generic tests myself, but from the msdn documentation it looks like they have to be treated as test containers.
In your build definition, change the process to use a test container and use ***.generictest instead of ***test*.dll and see if that works.
As a note, if you are firing up a GUI tool like calc.exe, then your build server will need to be running interactively otherwise you'll have test failures.

SubSonic 3 Regenerate ActiveRecord Class Automatically?

I have a SQLite database and SubSonic3, finally got a clue on how to generate the .cs from the .tt in Visual Studio. My stuff builds now.
I can kick off MSBuild automatically to build my project, but I would like to add a pre-build event to regen the ActiveRecord.cs cleanly so any database changes end up there for future Unit tests.
How can I simulate the 'run external tool' in the Visual Studio GUI?
Thanks.
You can run the TextTemplating tool from the command line:
C:\Program Files\Common Files\Microsoft Shared\TextTemplating\1.2\TextTransform.exe "path/to/your/ttfile.tt" -out <outFileName>
Use TextTransform.exe /help for more command line arguments you can use.
At this time, the SubSonic's Settings.ttinclude file must be run from within the VisualStudio application, and can not be run from the command line. This is because Settings.ttinclude uses the project context to locate the App.config / Web.config file so that it can look up the connection string.
Attempting to run via command line using TextTransform.exe will result in the error:
error : Running transformation: System.InvalidCastException: Unable to cast object of type 'Microsoft.VisualStudio.TextTemplating.CommandLine.CommandLineHost' to type 'System.IServiceProvider'.
This stems from this method in Settings.ttinclude:
public EnvDTE.Project GetCurrentProject() {
IServiceProvider _ServiceProvider = (IServiceProvider)Host;
...
}
By hacking the Settings.ttinclude file, you can set up Subsonic to run from the command line.
Just modify it to set your connection string as the return value of GetConnectionString and taking out all other logic.

Resources