Pumping Iron – Ruby & .NET testing

After being inspired by Ben Hall’s “Testing C# and ASP.NET using Ruby” session at DDD8, I decided to give Ruby testing a go.

This article shows the basics of how to get started, for the added cool-ness of BDD and Cucumber check out Bens slides from the talk.

What do I need?

IronRuby

IronRuby is Ruby for the .NET platform build on the DLR which allows you to use the Ruby language to interact with your existing .NET code.

RubyMine

RubyMine is a very cool IDE for developing Ruby applications that Ben used in his DDD demo, there are many other Ruby IDEs available including TextMate for the Mac and RadRails for Eclipse.

Now that we have all the none .NET pre-reqs downloaded and installed we can get to business.

Create Application Under Test

First things first, lets set up a skeleton application in Visual Studio that we will test. Here I just created a blank class library called IronRubyMine with the Person class within it. Build this code so that we have a dll in the bin/Debug directory.

namespace IronRubyMine
{
    public class Person
    {
    }
}

Setting up RubyMine for IronRuby

Within RubyMine I have then created a project in the same directory as my sln file for C# application, this will generate all your Ruby classes in the same location as your .NET app.

Once we have the Ruby solution we need to do a few tweaks to get it to work smoothly with .NET. Start off by adding the IronRuby SDK for use with the project (File – Settings – Ruby SDK – Add SDK…) and browse to the location of your IronRuby install and the ir.exe file.

IronRubyMine - Dom Green

Now RubyMine is using the IronRuby SDK we need to make another minor tweak to the Run/Debug configuration the files in the project. You will need to alter the Ruby Arguments to:

-e STDOUT.sync=true;STDERR.sync=true;load($0)

IronRuby Configuration - Dom Green

There are a number of discussions on the RubyMine forums how to best do this, but I have found that this alteration is the easiest and most straight forward way to get it all working.

Red – Create Failing Test

With our environments set up we create a simple test that fails before we write the code that we want and make the test pass.

require "test/unit"
require "IronRubyMine/bin/Debug/IronRubyMine.dll"

class PersonTest < Test::Unit::TestCase

  include IronRubyMine

  def test_create_person_called_dominic
    dominic = Person.new("Dominic")
    assert_not_nil(dominic)
  end
end

The second line pulls in the .NET dll that we created in our app allowing IronRuby to call any classes and methods that we create in our C# code. This is then used further down to create a Person object.

On running this test we will get a red light as we haven’t yet implemented the C# code to go alongside the test.

PersonFailedTest - Dom Green 

Green – Make Tests Pass

Now we can go back to Visual Studio and create a Person constructor that will take in a name, hopefully making our tests go green.

PersonDotNetCode - Dom Green

Once we have the code in place, build the application to ensure that the dll is updated and our IronRuby code is using the latest implementation.

Now jump back into RubyMine and re-run the tests.

PersonTestPass - Dom Green 

Refactor…

You get the picture, with all our tests now passing we can do any refactoring needed and then go on to create more tests.

With this simple implementation in place we can build on this to implement more advanced techniques described in Bens presentation.

Eye On Earth hits BBC News

I am proud to say that a project I recently worked on has just been featured on the BBC News website.

image

Eye On Earth is a stunning Silverlight application build on Windows Azure, developed by Microsoft MCS UK and the European Environmental Agency.

Check out the full article here.

Find out more about Eye on Earth here.

DDDScotland – Vote for my session

DDDCloud - Dominic Green

Vote for my session

Voting for sessions at DDD Scotland is open and this is a plea that you all go and vote for my session at the event (doesn’t even matter if your attending – just vote for me).

I will be doing a session on what I have learned about Azure and cloud computing over the past year I have been developing on the platform. This knowledge is expanding daily so I have a lot to share, including best practice, deployment and some nifty “cloud patterns”.

Cloud Coffee – A Year Developing on Windows Azure

 

DG - Dominic GreenCloud Coffee is the latest in a wide range of coffee shops on the high-street. What makes Cloud Coffee different is that they use latest “cloud” principles, keeping costs low by using utility based staffing, maintaining a decoupled working environment and ensuring good scalability to meet customer demand. Cloud Coffee has very quickly risen to high street fame.

This analogy will help you understand how things work in the cloud, specifically Windows Azure. During this talk Dominic will elaborate and expand upon on the concept of ‘Cloud Coffee’, sharing some of the lessons he learned, best practices and patterns that have emerged whilst developing one of the first production applications for the Windows Azure Platform.

Why are you still on this page?! Go vote. :)

WCF Hot Fix – Don’t be showing your nodes

When browsing to a WCF endpoint hosted in an Azure web role you normally get back a web page for the service showing the location of the individual node / web role that is serving up your request (seen blurred out here) instead of the actual endpoint.

This isn’t great as you don’t want everyone knowing about your internal system and especially the URL of one of your web roles, with which they could do who know what.

image

This can easily be fixed with this patch for WCF that will now show the expected endpoint. This endpoint is actually the address of the load balancer that will then forward your request to an web role.

Once the patch is download and installed you can then simply add the following xml snippet into your behaviour for the WCF service:

image

With this snippet added into your web.config you can browse back to the previous service and will now see that the correct URL is displayed for your service.

image

Paying or Not Paying?

Dominic Green - azurepayment

I have recently been asked a number of questions both internally and from customers about when you will be billed for Azure usage.

As Eric Nelson’s recent post describes, if you suspend a service you will still be paying this is due to the fact you will still have your application deployed on the server ready to start again. With your application utilizing the server others will not be able to provision its usage.

When you select delete you will stop paying as you will no longer have servers provisioned for your application and the recourses will be freed up for others to use.

Windows Azure Memcached-ed

Memcached is a distributed cache used to help speeding up large scale web applications by taking pressure off the database. Memcached is used by many of the internets biggest sites, including Twitter, Wikipedia, and YouTube to name just a few.

A distributed cache is one of the things that I’ve been hoping to see released for Windows Azure for quite a while, and I am hoping that AppFabric Caching will make the move to the cloud in the coming year. However, until that happens I was determined to find a way to get a distributed cache and this great Windows Azure Memcached sample showed me how.

“Brad Fitzpatrick, I love your ass!"

Sorry, I just couldn’t help myself. I found this great quote on in the Caching Story page of the Memcached wiki.

After installing and setting up Memcached you will be able to cache any data, including data that is retrieved from your database so that the next time you need it you can get it from cache and not need to re-query your database. Therefore, reduce the pressure on the database and earning the love of our DBA.

Azure Memcached sample

You can download the sample code for Windows Azure from the codeplex download page you then need to download a Windows friendly version of Memcached (here is where I got mine). With the sample code from codeplex just add the memcached exe to your worker roles. You will now be able to run the sample code either on the dev fabric or in the cloud.

One thing to watch out for, the Memcached exe’s seem to take an age to get up and running. I actually left mine to set up overnight (glad I’m still on a CTP account) as the Memcached Worker Roles were all showing busy for a long time, during which the sample would not work correctly.

After the servers have started up you can easily set and retrieve values from the cache as shown in the screenshots below.

Dominic Green - memchacedsetDominic Green - memchacedget 

 

Under the hood

Now that we have got our distributed cache working lets have a look how the sample code works.

Memcached Server

On the server side we set up an internal endpoint that will be used to connect the clients to the Memcached server. When the node is created we launch the Memcached server that we downloaded before, passing in the nodes cache size and endpoint as arguments.

          string arguments = 	"-m " + cacheSize +
				" -l " + endpoint.Address +
				" -p " + endpoint.Port;

            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.CreateNoWindow = false;
            startInfo.UseShellExecute = false;
            startInfo.FileName = "memcached.exe";
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            startInfo.Arguments = arguments;

This node is now exposing a Memcached server, which can be used by the client nodes to cache data.

Utilizing Memcached – Clients

The client node in the example looks a lot more complicated that it actually is. The most important part is adding the configuration for our memcached client within the settings tab of the node.

Dominic Green - client settings

Then comes the interesting bit using the Enyim caching library (others libraries are available) and creating a MemcachedClient object, allowing us to get and set objects in the cache.

Each time a new MemcacedClient is needed the program loads a configuration based upon the data within the settings (picture above) and then loops through all of the instances of memcached servers nodes that we are running in our hosted service getting their endpoint, to add this to the configuration of available servers.

            _endpoints = new Dictionary();

            foreach (var endpoint in RoleEnvironment.Roles[_memcachedRoleName].Instances)
            {
                foreach (var epi in endpoint.InstanceEndpoints)
                  {
                    if (epi.Key == "memcached")
                    {

                        _endpoints.Add(epi.Value.RoleInstance.Id.ToString(),epi.Value.IPEndpoint);
                    }
                }
            }

Now that the connection to our memcached nodes we can use the caching library to set and get values in the cache.

AzureMemcached.Client.Store(StoreMode.Set, key, value);          

AzureMemcached.Client.Get(key);

With this code we now have distributed caching on Windows Azure, and can use the example to build out much bigger applications. :-)  

DDD 2010 – Registration opens today

Registration for Developer Developer Developer 2010 will open later today at 13:00, but you better be quick to sign up as last years tickets were snapped up in a few hours.

This year boasts some of the best sessions that I have seen in a while with proposed (corrected by @plip) presentations on a wide range of subjects from MonoTouch by Chris Hardy, .NET development for the iPhone, right through to Jon Skeet submitting a  number of sessions including one on NodaTime and C# 4.0 and a UK conference just wouldn’t be complete without Seb giving a talk on Open Rasta.

Go to the DDD site here, view the sessions and register.

Google, teleporting goats since 2010

Dom Green - Teleporting Goats

Now I can see why some people have been raving about Google’s Chrome browser, it not only serves up the internet … it can teleport goats!!

Want to transport some Goats Yourself?

Follow these easy repro steps:

0. Download and launch Google Chrome
1. Shift + Esc
2. Right click on any process
3. Select “Goats teleported”
4. Uninstall Chrome

(note: I have taken the liberty of adding extra steps to the repro)

The official bug (Issue 31482 – Huge amount of goats teleported) has some great comments and definitely shows that geeks know how to have a laugh.

I stumbled upon this little gem thanks to Barry Dorrans (@blowdart).

Service management API – REST on REST

In a previous post I mentioned using the Service Management API sample library to call out to the Azure fabric from within a C# application.

The natural progression from here was to get the code working from within a web or worker role instance hosted within the cloud. Using a web role, I used the OnStart method to set up a IServiceManagent class that could then be shared with the remainder of the classes within the role.

When tracing the hosted services from either the OnStart method or from within default.aspx.cs I could successfully print out all of the services within my account. However, when I set up a WCF REST service to return these hosted services in an array I started to get an error with the connection to the Management API. Giving a argument error stating that a property with the name “httpRequest” is not present. This was even happening when I was using exactly the same code as I was elsewhere.

Dominic Green - httpRequest

After a push in the right direction from Simon Davies we found out  that the issue was in the WCF REST service already having an OperationContext from the original REST call before calling out to the Service Management API. This handy blog post, help solve all my issues, all that was needed was to create a second OperationalContext before calling the management service.

using(new OperationContextScope((IContextChannel)WebRole.serviceManagement))
{
  var hostedServices = WebRole.serviceManagement.ListHostedServices(subscriberID);

  foreach (HostedService service in hostedServices)
  {
    Trace.TraceInformation("Hosted Service: {0}", service.ServiceName);
  }
}
            

Ta dar … everything now works, we can use the above code snippet to retrieve back all our hosted services by calling our own web role.

Message Queue – What’s In A Name?

One things I am constantly falling into the trap of doing is naming my message queues using camel casing when naming my queues giving names such as “mySuperQueue” which ends up throwing the below error. Which because it gives us very little information tends to lead to me debugging the code for a while before I remember that capitals and other special characters are not allowed in queue names.

Dominic Green - queueError The rules on naming queue are:

A queue name must start with a letter or number, and may contain only letters, numbers, and the dash (-) character.

The first and last letters in the queue name must be alphanumeric. The dash (-) character may not be the first or last letter.

All letters in a queue name must be lowercase.

A queue name must be from 3 through 63 characters long.

So to try and stop myself making this mistake in the future I have put together a quick code snippet that allows me to pass in the proposed queue name and view if it is valid.

            bool match = false;
            var exp = new Regex(@"^[0-9a-z]+-*[0-9a-z]+$");

            if (exp.IsMatch(input))
            {
                if (input.Length >= 3 && input.Length <= 63)
                {
                    match = true;
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("VALID Queue Name: {0}", input);
                }
            }

            if (!match)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("INVALID Queue Name: {0}", input);
            }

 

Dominic Green - QueueNames

Hopefully this small snippet will be able to save me a lot of time by instantly flagging a queue name that is invalid, then either notifying the user before the queues are created or even fixing the queue name so that it is in a correct format.