When building on my OSS project MyCouch I want to target both a running local install of CouchDb as well as a cloud hosted and cluster enabled CouchDb install with Cloudant. Doing this, involves exposing my Cloudant account specifics. Of course I can add this as encrypted info somewhere in the repo, or have a file that is ignored or something, but since my project also targets Windows store apps, App.configs
are out of the question. And reading external files with Windows store apps in test environments using xUnit
is still somewhat sketchy, so I thought, why not use HTTP
? We have some nice building blocks as .Net developers to accomplish this. Using ScriptCS and Nancy this really is a breeze. I will show you two different solutions. One hardcoded and one serving JSON-files.
First, get ScriptCS installed. Head over to ScriptCS and follow one of the guides for getting ScriptCS installed onto your environment.
Second, install the Nancy script-pack. There’s a simple example showing you how to use the Nancy Script-pack, but it’s really easy, just pay attention:
cmd:\>scriptcs -install ScriptCs-Nancy
Then just create a simple Nancy module in a file named something that suits you, e.g. server.csx
. In that file, add the following code:
Require<NancyPack>().At(8991).Host();
public class TestEnvironmentsModule
: NancyModule
{
public TestEnvironmentsModule()
: base("testenvironments")
{
Get["/local"] = _ => {
return Response.AsJson(new TestEnvironment
{
Client = new ClientConfig
{
ServerUrl = "http://localhost:5984",
DbName = "mycouchtests",
User = "mycouchtester",
Password = "p@ssword"
}
});
};
//This is the one were I on my machine
//would configure differently
Get["/cloudant"] = _ => {
return Response.AsJson(new TestEnvironment
{
Client = new ClientConfig
{
ServerUrl = "http://localhost:5984",
DbName = "mycouchtests",
User = "mycouchtester",
Password = "p@ssword"
}
});
};
}
private class TestEnvironment
{
public ClientConfig Client { get; set;}
}
private class ClientConfig
{
public string ServerUrl { get; set;}
public string DbName { get; set;}
public string User { get; set;}
public string Password { get; set;}
}
}
With the code in place, just start the server:
cmd:\scriptcs server.csx
Pretty simple. The server will listen on http://localhost:8991/testenvironments
and deliver two different configurations. You should be able to try it in the browser.
But, can’t we make it serve JSON-files instead? Yes, of course. You could e.g. create a folder testenvironments
with files in, e.g local.json
and cloudant.json
and then update the server.csx
to:
using Nancy.Responses;
Require<NancyPack>().At(8991).Host();
public class TestEnvironmentsModule
: NancyModule
{
public TestEnvironmentsModule()
: base("testenvironments")
{
Get["/{config}"] = p => {
var kv = (IDictionary<string, object>)p;
var config = kv.ContainsKey("config")
? kv["config"].ToString()
: null;
if (config == null) return config;
return new GenericFileResponse(
string.Concat("testenvironments/", config, ".json"));
};
}
}
Elevated trust issues? You could do a simple workaround. Create a simple bat-file start.bat
with one line in it:
powershell start-process scriptcs.exe server.csx -verb runas
After that you will be able to (in a non-elevated command prompt) just start the server by invoking the bat-file.
Third, consume the config. It’s a simple HTTP GET, that delivers JSON, and I can now in, the bootstraping of my integration tests, request the JSON, deserialize it and pick the info I need. And I can even automate scriptcs
in a build script etc.
Not sure yet if it’s a brilliant idea and if it’s something I will stick to. But for now it solves my problem.
Cheers,
//Daniel