danielwertheim

danielwertheim


notes from a passionate developer

Developer that lives by the mantra "code is meant to be shared".

Share


Tags


Disclaimer

This is a personal blog. The opinions expressed here represent my own and not those of my employer, nor current or previous. All content is published "as is", without warranty of any kind and I don't take any responsibility and can't be liable for any claims, damages or other liabilities that might be caused by the content.

Using ScriptCS and NancyFx to bootstrap my test environment

Daniel WertheimDaniel Wertheim

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

Developer that lives by the mantra "code is meant to be shared".

Comments