AppVeyor

Deploying the Azure Cosmos DB emulator when building with AppVeyor

Azure Cosmos DB is Microsoft’s globally distributed, horizontally partitioned, multi-model database service. AppVeyor is a Continuous Integration solution for Windows. The key question is how can I test my solution, built on appveyor, with an Azure Cosmos DB back-end? Before going further, you need to know that Azure Cosmos DB has an emulator that you can run on any Windows machine. You can use to develop but also to test your solution. I’d not recommend load tests but unit or integration tests are supported.

The first step is to download the emulator (only 26MB) on your Appveyor build machine. You can do this during the install step by the help of this one line script in PowerShell:

Start-FileDownload 'https://aka.ms/cosmosdb-emulator' -FileName 'c:\projects\cosmos-db.msi'

When the file is downloaded, you will need to execute it to install the emulator on the machine. Using a few parameters of the installer this can be acheived without the need to click on buttons.

cmd /c start /wait msiexec /i "c:\projects\cosmos-db.msi" /qn /quiet /norestart /log install.log

Then, once the software is installed, you’ll need to run it. As it will run in background you won’t need UI or Data Explorer. These options can be turned off by the means of the parameters /NoUI and /No-Explorer.

"C:\Program Files\Azure Cosmos DB Emulator\CosmosDB.Emulator.exe"  /NoExplorer /NoUI

To avoid to run it interactively in the build execution context, you’ll need to start it in another process. It can be done with PowerShell Start-Process

Finally, you cannot expect that this kind of software is starting in a milli-second. You’ll have to pool and check if a connection is possible or not. that’s the goal of this PowerShell script:

$attempt = 0
$client = New-Object System.Net.Sockets.TcpClient([System.Net.Sockets.AddressFamily]::InterNetwork)

do {
	$attempt++
	try {    
		$client.Connect("127.0.0.1", 8081)
		write-host "CosmosDB started"
	}
	catch {
		$client.Close()
		if($attempt -eq 5) {
			write-host "CosmosDB was not started"
		} else {
			[int]$sleepTime = 3*$attempt
			write-host "CosmosDB is not started. Retry after $sleepTime seconds..."
			sleep $sleepTime;
		}
	}
}while(!$client.Connected -and $attempt -lt $max)

If the emulator has not started after 15 seconds, something is going wrong and you should step out of this loop.

The full listing with all actions taken during the install step of your build process is visible there:

appveyor-cosmosdb-emulator

If you’ve troubles, it can be useful to check if the port 8081 is listening: this can be easily done with the help of the command netstat -ab that you can add as a fifth action in your install step.

Advertisements