robocode and domain driven design

In two series of robocode posts, I've been discovering how to test drive a robot from scratch and how to do this through acceptance testing. I have yet to actually implement any substantial real code that manipulates the robot outside of any experimentations I've done a few months ago in some test libraries.

If you've been following my posts so far you may have realised that I'm actually more interested in how to solve a new problem space in a productive manner just as I would professionally. It's a chance to expand upon being agile, test driven, acceptance test focused to the solution required and a great way to try out new things and help me up my game in my process of continually being new at development.

I'm literally only a few blog posts behind the implementation so am sharing the experience as I go and one of the next things I want to introduce into my robocode implementation is some strategic elements of domain driven design.

Now I may be complicating this process  to a level far beyond what I might actually achieve with the robot code itself given that I know little about artificial intelligence and implementing winning strategies; introducing some elements of domain driven design may indeed result in over-engineering.
But that's what experimentation is all about and I'm looking forward to finding cool insights and discovering where the sweet spot is with bounded contexts and the size of the problem space at hand.

So caveat's and justifications out of the way, here's my new idea:

A robot can be quite complex and there are many things to address - decision making around where to be on the battlefield, what enemy to target, how to move, what strategy to employ. Then there's calculating distances, bearings, vectors, not to mention current gun heat, current position, energy levels. I can imagine its very involved when trying to develop a winning strategy.

As yet I know very little about these areas so I consider myself both the naive customer and the developer who has to learn about the new models the customer describes.

The solution? Break it down into contexts and simplify each area to make it more understandable, extensible and hopefully easier to identify what effects changes have to a battle.

My initial plan is to break it down into something like the diagram below - I may not stick with this in the long term, but this is my initial design idea:

ddd

The diagram above illustrates the bounded contexts I will have in my application and in between them all is the world state - this will be maintained and published via rx framework observables. Each context has a translator that will transform the world state into context specific observables each with their own dialect of the robocode ubiquitous language.

The decision context will be responsible for making decisions about where to be, what enemy to target, whether to be in close, out far away, etc. This area will deal with "enemies" and the relevant data that it will require.

The calculation context will be responsible for calculations for targeting, pathfinding and the data required for issuing commands. This area will deal with "targets" and their associated data.

The third context is the manipulation area that deals with making commands to robocode and interfacing with my robot adapter. I already have a robot engine that would be a possible candidate for this category. This area will deal with "tanks" or "robots".

Looks good to me on paper, but we'll have to see how it pans out in practice.
I already have a few misgivings that my context maps that convert to "enemies" and "targets" may actually share much of the same data and will be simply contextualising it in a different way. But that may be a good thing perhaps?

Throughout I'll not be doing any up front architectural changes, and will still be applying that YAGNI principle as I drive my implementation through context specifications. The above is just a roadmap to something I think may be useful.

I would love to receive some feedback on this so if you have been interested in my robocode series so far please share your thoughts in the comments on this blog.

Posted at at 7:11 AM on Tuesday, August 31, 2010 by Posted by Justin Davies | 1 comments Links to this post   | Filed under: ,

identifying why the robot doesn't fire

In my previous post I am now issuing instructions to the robot, but I have some unexpected behaviour in that my assumptions about the way the battle would run must be incorrect.
The behaviour I'm seeing is that at the start of the battle the robot scans 360 degrees but never fires even though I have a Fire() command in my scanned event.

I've already posted about the fact that I have debugging limitations - my assembly is in the GAC and I therefore cannot debug into the robocode process as I used to. So it took me a while to find a way to debug this and here's where I conducted some temporary surgery to try and establish the cause: (only part of the robot code shown)

    public class SlayerRobot : Robot, ImARobot
    {
        public void LookForEnemies()
        {
            DebugProperty["lookForEnemies"] = "true";
            TurnRadarRight(360);
        }

        public override void OnScannedRobot(ScannedRobotEvent evnt)
        {
            DebugProperty["scanned"] = "true";
            Fire(1);
        }   
    }

By adding debug lines through robocode, I can watch the turn snapshot window in the robocode GUI (via the "Main battle log" button) as the turns progress and see these debugging messages appear at runtime. You have to be quick or have it paused and progress one turn turn at a time, because these debug properties appear only for the turn they were issued in.

lookForEnemiesDebug

In turn 1, I can see that my robot is indeed looking for enemies.

scannedDebug

In turn 11, my robot does recognise another robot, but my Fire() code obviously doesn't take effect.

I remember reading on the wiki that the "guns start hot" and after some searching I find in the games physics page:

GunHeat generated: 1 + firepower / 5. You cannot fire if gunHeat > 0.
All guns are hot at the start of each round.

So either wasn't paying enough attention for missing that or its not an obvious start of battle limitation. Either way I can verify that this is the cause of my robot's dormancy with some extra surgical code:

    public class SlayerRobot : Robot, ImARobot
    {
        public void LookForEnemies()
        {
            DebugProperty["lookForEnemies"] = "true";
            DebugProperty["gunheat"] = GunHeat.ToString();
            TurnRadarRight(360);
        }

        public override void OnScannedRobot(ScannedRobotEvent evnt)
        {
            DebugProperty["scanned"] = "true";
            DebugProperty["gunheat"] = GunHeat.ToString();
            Fire(1);
        }   
    }

I then get the following debug output:

lookForEnemiesDebug2

The gun heat is 2.9 at the start of turn 1.

scannedDebug2

The gun heat still hasn't cooled right down, its only down to 2 by turn 10.

Therefore I need to do a bit more work in keeping the state of the robot that was scanned until such time as I can fire.

As I look into this and think about new observables I would need, I make what I consider a massive leap forward in my thinking for this project so need to stop and re-assess what I've done so far.

Eric Evans called this a breakthrough when "refactoring toward deeper insight":

"Each refinement of code and model gives developers a clearer view. This clarity creates the potential for a breakthrough of insights"

In introducing these observables and through the debugging process above I've discovered some new insights into the layout of my code and want to introduce a different structure.
My next post will break from code and attempt to illustrate my new thought process behind my robot.

Posted at at 7:09 AM on Friday, August 27, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under:

making the robocode robot work

In previous posts in this series I've been exploring acceptance testing my robocode robot. I've passed an acceptance test that ensures it never gets disabled at the start but I still have once acceptance test that is failing.
Some time ago, I wrote the following acceptance test:

In a one round battle, fighting against a single robot that does not move, the slayer robot should win.

I've yet to pass this test - I found a random seed that ensures the battle is a draw if my robot does not move and as yet I have not issued a single command to the robot.
So here's my first steps into doing just that.

I'm starting with the specifications for my RobotEngine - at the moment this takes in one ImAnObserver in the constructor, so I add a new specification for multiple observers shown at the bottom of the following code:

    public class when_initialising_a_robot_engine : with_a_robot_engine
    {
        Because of = () => robotEngine.Initialise(robot);

        It should_tell_the_statistics_writer_to_ensure_we_have_clean_statistics = () =>
            statisticsManager.AssertWasCalled(s => s.EnsureWeStartWithCleanStatistics());

        It should_ensure_that_we_have_something_to_observe_the_start_of_each_turn = () =>
            robotEngine.AtTheStartOfEachTurn.ShouldNotBeNull();

        It should_ask_the_first_observer_to_observe = () =>
            firstObserver.AssertWasCalled(o => o.Observe(robotEngine));

        It should_ask_the_second_observer_to_observe = () =>                  <---
           secondObserver.AssertWasCalled(o => o.Observe(robotEngine));       <---
    }

The RobotEngine changes accordingly:

        public RobotEngine(IManageStatistics statisticsManager, 
                           IEnumerable<ImAnObserver> observers)
        {
            this.statisticsManager = statisticsManager;
            this.observers = observers;
        }

        public void Initialise(ImARobot robot)
        {
            this.robot = robot;
            statisticsManager.EnsureWeStartWithCleanStatistics();
            CreateObservableForTheStartOfEachTurnFromTheRobot(robot);
            foreach (var observer in observers)
            {
                observer.Observe(this);
            }
        }

Now that every observer gets an opportunity to subscribe to rx observables, I can create myself a new observable that will activate the first commands on the first few turns - here is the StartOfTheBattleObserver class specification:

    public class when_at_the_start_of_the_battle : with_a_start_of_battle_observer
    {
        Establish context = () =>
        {
            statusAtTheStartOfTheTurn = new StatusAtTheStartOfATurn { TurnNumber = 1 };
            statusAtTheStartOfATurnEvent.Stub(s => s.EventArgs)
                                        .Return(statusAtTheStartOfTheTurn);

            startOfTheTurnObservable = Observable.Return(statusAtTheStartOfATurnEvent);

            robotEngine.Stub(e => e.AtTheStartOfEachTurn).Return(startOfTheTurnObservable);
        };

        Because of = () => observer.Observe(robotEngine);

        It should_subscribe_to_the_observable_and_recognise_the_first_turn = () =>
            observer.RecognisedTheFirstTurn.ShouldBeTrue();
    }

    public class with_a_start_of_battle_observer
    {
     Establish context = () =>
        {
            statusAtTheStartOfATurnEvent = 
                MockRepository.GenerateStub<IEvent<StatusAtTheStartOfATurn>>();
            robotEngine = MockRepository.GenerateStub<ImARobotEngine>();
            observer = new StartOfTheBattleObserver();
        };

        protected static StatusAtTheStartOfATurn statusAtTheStartOfTheTurn;
        protected static IEvent<StatusAtTheStartOfATurn> statusAtTheStartOfATurnEvent;
        protected static IObservable<IEvent<StatusAtTheStartOfATurn>> startOfTheTurnObservable;
        protected static ImARobotEngine robotEngine;
        protected static StartOfTheBattleObserver observer;
    }

I'm creating a new observable in my set up that has turn number 1 in the status and am using the same eventing and observable as the last observer - the start of the turn observable. I then assert against a property on the observer - RecognisedTheFirstTurn.
Here's how I get this to pass:

    public class StartOfTheBattleObserver : ImAnObserver
    {
        public void Observe(ImARobotEngine robotEngine)
        {
            robotEngine.AtTheStartOfEachTurn.Where(x => x.EventArgs.TurnNumber ==1)
                       .Subscribe(x => RecognisedTheFirstTurn = true);
        }

        public bool RecognisedTheFirstTurn { get; private set; }
    }

The next step is to issue an instruction to the robot itself, but this observer has no knowledge of the robot instance - this is purposeful. So I need a hook in the robot engine for it to issue instructions and I add that in the specification:

    public class when_at_the_start_of_the_battle : with_a_start_of_battle_observer
    {
        Establish context = () =>
        {
            statusAtTheStartOfTheTurn = new StatusAtTheStartOfATurn { TurnNumber = 1 };
            statusAtTheStartOfATurnEvent.Stub(s => s.EventArgs)
                                        .Return(statusAtTheStartOfTheTurn);

            startOfTheTurnObservable = Observable.Return(statusAtTheStartOfATurnEvent);

            robotEngine.Stub(e => e.AtTheStartOfEachTurn).Return(startOfTheTurnObservable);
            robotEngine.Stub(e => e.IssueInstructionsToRobot(null))
                       .IgnoreArguments().Do(RecordInstruction);
        };

        It should_subscribe_to_the_observable_and_recognise_the_first_turn = () =>
            observer.RecognisedTheFirstTurn.ShouldBeTrue();

        It should_issue_instructions_for_the_robot_engine_to_look_for_enemies = () =>
            ShouldHaveIssuedInstruction(x => x.LookForEnemies());

        static void ShouldHaveIssuedInstruction(Action<ImARobot> expectedInstruction)
        {
            var robot = MockRepository.GenerateStub<ImARobot>();
            if(instructionSentToRobotEngine!=null)
                instructionSentToRobotEngine(robot);
            robot.AssertWasCalled(expectedInstruction);
        }

        static Action<Action<ImARobot>> RecordInstruction = i => 
                                             instructionSentToRobotEngine = i;
        
        static Action<ImARobot> instructionSentToRobotEngine;
    }

On the RobotEngine interface, this specification has driven a new signature for issuing robot instructions... this can be seen in the stubbing of the robot engine:  there is a new method  IssueInstructionToRobot(Action<ImARobot> instruction).

In this stubbed method I'm recording the action that was sent in by providing the two members at the bottom of the specification.

In my assertion I am then applying this action to the robot stub and asserting that a certain instruction was issued - the LookForEnemies instruction. Here is the implementation code:

    public class StartOfTheBattleObserver : ImAnObserver
    {
        public void Observe(ImARobotEngine robotEngine)
        {
            HaveNotLookedForEnemies = true;

            robotEngine.AtTheStartOfEachTurn.Where(x => x.EventArgs.TurnNumber < 10  
                                                              && HaveNotLookedForEnemies)
                       .Subscribe(x =>
                        {
                           RecognisedTheFirstTurn = true;
                           robotEngine.IssueInstructionsToRobot(r => r.LookForEnemies());
                           HaveNotLookedForEnemies = false;
                        });
        }

        protected bool HaveNotLookedForEnemies { get; private set; }

        public bool RecognisedTheFirstTurn { get; private set; }
    }

    public interface ImARobotEngine
    {
        void Initialise(ImARobot robot);

        void IssueInstructionsToRobot(Action<ImARobot> instruction);

        IObservable<IEvent<StatusAtTheStartOfATurn>> AtTheStartOfEachTurn { get; }
    }

    public interface ImARobot
    {
        event EventHandler<StatusAtTheStartOfATurn> StartOfEveryTurn;
        void LookForEnemies();
    }

I've now got an observer that reacts to turn number one (in fact the code above shows a more progressed version where I wrote an additional specification to ensure this happens regardless of whether my robot skips a few turns, or something else untoward happens).
It issues instruction to the robot to look for enemies.

The last part of this implementation is to issue that command in the robot and I do this directly without a specification as it is in my robot adapter layer that speaks directly to robocode:

    public class SlayerRobot : Robot, ImARobot
    {

        public void LookForEnemies()
        {
            TurnRadarRight(360);
        }

        public override void OnScannedRobot(ScannedRobotEvent evnt)
        {
            Fire(1);
        }
    }

So now in theory I'm ready to go and should have my robot firing when it scans other robots.

When I run the battle, my robot scans as shown below, so the observable is being picked up and the instruction is being issued to the robot:

scanning

However, the robot never fires!

I get one 360 rotation of the radar and then the robot is dormant for the rest of the round.
In the next post I'll illustrate the cause and move onto addressing this.

Posted at at 8:04 AM on Wednesday, August 25, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

moving from nunit to machine.specifications

Making the transition from NUnit tests can be hard for a team that is invested in that style of testing and have been doing that for a number of years. The foreign nature of a context specification style testing framework and seeing a mass of delegate declarations can prove a barrier for migration, so here's my recommendation for making a smoother transition between the two.
I'll be illustrating how to move from a typical NUnit style of testing to using Machine.Specifications.

First, we need to examine how tests are currently being written in NUnit. A typical test may look something like this fictitious class:

    [TestFixture]
    public class FileInspectorTests
    {
        IFileInspector fileInspector;
        FakeFileReader fileReader;

        public void TestCallsReader()
        {
            fileReader = new FakeFileReader();
            fileReader.FakeContent = "fake content for the test";
            fileInspector = new FileInspector(fileReader);
            fileInspector.InspectFile("filename");
            Assert.IsTrue(fileReader.GetContentWasCalled);
        }

        [Test]
        public void TestFindsSecondWord()
        {
            fileReader = new FakeFileReader();
            fileReader.FakeContent = "first second third fourth";
            fileInspector = new FileInspector(fileReader);
            fileInspector.InspectFile("filename");
            Assert.AreEqual("second", fileInspector.SecondWord);
        }

        public class FakeFileReader : IFileReader
        {
            public string GetContentFromFile(string file)
            {
                GetContentWasCalled = true;
                return FakeContent;
            }

            public bool GetContentWasCalled { get; set; }            

            public string FakeContent { get; set;}
        }
    }

Here we have a few simple tests and these are of a common pattern for NUnit (in my experience). We'll be looking at shaping this into a better NUnit test first before we consider moving to another framework.

  • Step one : use a mocking framework instead of simple hand rolled stubs

The simple hand rolled stub above is the FakeFileReader and this is just extra code that isn't required. Today's mocking frameworks are very flexible and can provide proxies for our abstractions without us having to create new classes.
Also, many mocking frameworks utilise lambdas which is a great step towards using Machine.Specifications.
Here's an example using Rhino Mocks:

    [TestFixture]
    public class FileInspectorTests
    {
        IFileInspector fileInspector;
        IFileReader fileReader;

        public void TestCallsReader()
        {
            var fileName = "filename";
            var fakeContent = "fake content for the test";

            fileReader = MockRepository.GenerateStub<IFileReader>();            
            fileReader.Stub(x => x.GetContentFromFile(fileName)).Return(fakeContent);

            fileInspector = new FileInspector(fileReader);
            fileInspector.InspectFile("filename");
            
            fileReader.AssertWasCalled(x=> x.GetContentFromFile(fileName));
        }

        [Test]
        public void TestFindsSecondWord()
        {
            var fileName = "filename";
            var fakeContent = "first second third fourth";

            fileReader = MockRepository.GenerateStub<IFileReader>();
            fileReader.Stub(x => x.GetContentFromFile(fileName)).Return(fakeContent);

            fileInspector = new FileInspector(fileReader);
            fileInspector.InspectFile("filename");
            Assert.AreEqual("second", fileInspector.SecondWord);
        }
    }

A stub is created and we stub the method to return the content, finally asserting that the stub recorded a call to the method with the correct parameters.
No extra class, and two lambdas to introduce familiarity with delegates - all good so far.

  • Step Two : move to a contextual style of testing - the AAA pattern

There is a testing pattern called the AAA pattern that enables you to separate set up, system under test execution and your assertions from each other. It stands for Arrange, Act, Assert.
By introducing a base class for this more contextual style we can follow this pattern when NUnit testing:

    [TestFixture]
    public class FileInspectorTests : ContextTest
    {
        IFileInspector fileInspector;
        IFileReader fileReader;
        string fileName;
        string fakeContent;

        protected override void Arrange()
        {
            fileName = "filename";
            fakeContent = "fake content for the test";
            fileReader = MockRepository.GenerateStub<IFileReader>();
            fileReader.Stub(x => x.GetContentFromFile(fileName)).Return(fakeContent);
            fileInspector = new FileInspector(fileReader);
        }

        protected override void Act()
        {
            fileInspector.InspectFile("filename");
        }

        [Test]
        public void TestCallsReader()
        {
            fileReader.AssertWasCalled(x=> x.GetContentFromFile(fileName));
        }

        [Test]
        public void TestFindsSecondWord()
        {
            Assert.AreEqual("second", fileInspector.SecondWord);
        }
    }

    public abstract class ContextTest
    {
        [TestFixtureSetUp]
        public void SetUp()
        {
            Arrange();
            Act();
        }

        protected abstract void Arrange();

        protected abstract void Act();
    }

This makes our test much cleaner - we've removed duplication of the setup and the system under test execution and more importantly we can clearly see what is being tested; there is a single line in the Act() method that illustrates what is being executed.

  • Step Three : use contextual descriptions for tests classes and assertive methods

The structure of the test above is great, but we can improve upon this layout by simple describing our tests with intuitive naming on the class and the methods. Keeping in the NUnit style, my recommendation is that you move to something like the following:

    [TestFixture]
    public class FileInspectorTest_WhenInspectingAFileFromAFileName : ContextTest
    {
        IFileInspector fileInspector;
        IFileReader fileReader;
        string fileName;
        string fakeContent;

        protected override void Arrange()
        {
            fileName = "filename";
            fakeContent = "fake content for the test";
            fileReader = MockRepository.GenerateStub<IFileReader>();
            fileReader.Stub(x => x.GetContentFromFile(fileName)).Return(fakeContent);
            fileInspector = new FileInspector(fileReader);
        }

        protected override void Act()
        {
            fileInspector.InspectFile("filename");
        }

        [Test]
        public void ShouldTellTheFileReaderToObtainTheContentFromTheFile()
        {
            fileReader.AssertWasCalled(x=> x.GetContentFromFile(fileName));
        }

        [Test]
        public void ShouldFindTheCorrectSecondWord()
        {
            Assert.AreEqual("second", fileInspector.SecondWord);
        }
    }

This test now hopefully rolls off the tongue a bit better - "it is a file inspector test and when inspecting a file from a file name it should tell the file reader to obtain the content from the file and it should find the correct second word".

  • Step Four : illustrate to the team how an Nunit test could morph to a delegate driven framework

I've found that to get to grips with the delegate driven nature of Machine.Specification it is helpful to illustrate how we can move the above test to using strong delegates and we effectively morph the test into a Machine.Specification style test.
We begin this step by moving the arrange and act into Action delegates:

    [TestFixture]
    public class FileInspectorTest_WhenInspectingAFileFromAFileName : ContextTest
    {
        static IFileInspector fileInspector;
        static IFileReader fileReader;
        static string fileName;
        static string fakeContent;

        Action arrange = () =>
         {
             fileName = "filename";
             fakeContent = "fake content for the test";
             fileReader = MockRepository.GenerateStub<IFileReader>();
             fileReader.Stub(x => x.GetContentFromFile(fileName)).Return(fakeContent);
             fileInspector = new FileInspector(fileReader);
         };

        Action act = () =>
         {
             fileInspector.InspectFile("filename");
         };

        protected override void Arrange()
        {
            arrange();
        }

        protected override void Act()
        {
            act();
        }

        [Test]
        public void ShouldTellTheFileReaderToObtainTheContentFromTheFile()
        {
            fileReader.AssertWasCalled(x=> x.GetContentFromFile(fileName));
        }

        [Test]
        public void ShouldFindTheCorrectSecondWord()
        {
            Assert.AreEqual("second", fileInspector.SecondWord);
        }
    }

We've added two new delegates and moved the code from Arrange and Act accordingly and we execute those delegates within our arrange and our act. It's now time to do the same for the tests:

    [TestFixture]
    public class FileInspectorTest_WhenInspectingAFileFromAFileName : ContextTest
    {
        static IFileInspector fileInspector;
        static IFileReader fileReader;
        static string fileName;
        static string fakeContent;

        Action arrange = () =>
         {
             fileName = "filename";
             fakeContent = "fake content for the test";
             fileReader = MockRepository.GenerateStub<IFileReader>();
             fileReader.Stub(x => x.GetContentFromFile(fileName)).Return(fakeContent);
             fileInspector = new FileInspector(fileReader);
         };

        Action act = () =>
         {
             fileInspector.InspectFile("filename");
         };

        protected override void Arrange()
        {
            arrange();
        }

        protected override void Act()
        {
            act();
        }

        Action shouldTellTheFileReaderToObtainTheContentFromTheFile = () => 
            fileReader.AssertWasCalled(x => x.GetContentFromFile(fileName));

        Action shouldFindTheCorrectSecondWord = () =>
            Assert.AreEqual("second", fileInspector.SecondWord);

        [Test]
        public void ShouldTellTheFileReaderToObtainTheContentFromTheFile()
        {
            shouldTellTheFileReaderToObtainTheContentFromTheFile();   
        }

        [Test]
        public void ShouldFindTheCorrectSecondWord()
        {
            shouldFindTheCorrectSecondWord();
        }
    }

Now we control all of our tests through delegates, but we have to explicitly call them with our AAA context test structure.

What if the testing framework could call these delegates on our behalf? How would it be able to keep the AAA syntax and ensure they are called in the correct order?

If we create some strong delegates of our own, we can effectively give each delegate a type and this can then be examined through reflection:

    [TestFixture]
    public class FileInspectorTest_WhenInspectingAFileFromAFileName : ContextTest
    {
        static IFileInspector fileInspector;
        static IFileReader fileReader;
        static string fileName;
        static string fakeContent;

        public delegate void Arrange();

        public delegate void Act();

        public delegate void Assertion();

        Arrange arrange = () =>
         {
             fileName = "filename";
             fakeContent = "fake content for the test";
             fileReader = MockRepository.GenerateStub<IFileReader>();
             fileReader.Stub(x => x.GetContentFromFile(fileName)).Return(fakeContent);
             fileInspector = new FileInspector(fileReader);
         };

        Act act = () =>
         {
             fileInspector.InspectFile("filename");
         };

        Assertion shouldTellTheFileReaderToObtainTheContentFromTheFile = () => 
            fileReader.AssertWasCalled(x => x.GetContentFromFile(fileName));

        Assertion shouldFindTheCorrectSecondWord = () =>
            Assert.AreEqual("second", fileInspector.SecondWord);
    }

Our test now looks very different and we effectively have the same pattern as Machine.Specifications or other delegate driven testing frameworks. It would be very easy to reflect on the type and pull out each delegate at runtime which these frameworks do in some manner such as:

        var arranges = typeof(FileInspectorTest_WhenInspectingAFileFromAFileName)
            .GetFields(BindingFlags.NonPublic)
            .Where(x => x.FieldType == typeof(Arrange));

        var acts = typeof(FileInspectorTest_WhenInspectingAFileFromAFileName)
         .GetFields(BindingFlags.NonPublic)
         .Where(x => x.FieldType == typeof(Act));

        var assertions = typeof(FileInspectorTest_WhenInspectingAFileFromAFileName)
         .GetFields(BindingFlags.NonPublic)
         .Where(x => x.FieldType == typeof(Assertion));
  • Step Five : make the transition to Machine.Specifications and embrace the full contextual syntax and descriptive style
    [Subject(typeof(FileInspector))]
    public class when_inspecting_a_file_from_a_file_name
    {
        Establish context = () =>
        {
            fileName = "filename";
            fakeContent = "fake content for the test";
            fileReader = MockRepository.GenerateStub<IFileReader>();
            fileReader.Stub(x => x.GetContentFromFile(fileName)).Return(fakeContent);
            fileInspector = new FileInspector(fileReader);
        };

        Because of = () => fileInspector.InspectFile("filename");

        It should_tell_the_file_reader_to_obtain_the_content_from_the_file = () =>
            fileReader.AssertWasCalled(x => x.GetContentFromFile(fileName));

        It should_find_the_correct_second_word = () =>
            Assert.AreEqual("second", fileInspector.SecondWord);

        static string fileName;
        static string fakeContent;
        static IFileReader fileReader;
        static FileInspector fileInspector;
    }

Posted at at 7:01 AM on Monday, August 23, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

iobservable<ievent<t>> with robocode

I've been working on a robocode robot and in my last post worked on the robot engine having successfully enabled subscription to an observable from the rx framework.
This post continues with that work and enables a subscription to turn 50 to pass an acceptance test I set up in an earlier post.

I'm going back to the Initialise() call on the robot engine and add in some code on my specification set up (new code is highlighted below):

    public class with_a_robot_engine
    {
        Establish context = () =>
        {
            statisticsManager = MockRepository.GenerateStub<IManageStatistics>();
            observer = MockRepository.GenerateStub<ImAnObserver>();               <---
            robotEngine = new RobotEngine(statisticsManager, observer);           <---
            robot = MockRepository.GenerateStub<ImARobot>();
        };

        protected static ImARobotEngine robotEngine;
        protected static ImARobot robot;
        protected static IManageStatistics statisticsManager;
        protected static ImAnObserver observer;                                   <---
    }

I'm creating a stub of a new interface "ImAnObserver" and have added a parameter on the robot engine constructor.
Later on I envsion this being an IEnumerable<ImAnObserver> but with YAGNI, I only need the one instance for now.
I can now add a new assertion at the bottom of my specification:

    public class when_initialising_a_robot_engine : with_a_robot_engine
    {
        Because of = () => robotEngine.Initialise(robot);

        It should_tell_the_statistics_writer_to_ensure_we_have_clean_statistics = () =>
            statisticsManager.AssertWasCalled(s => s.EnsureWeStartWithCleanStatistics());

        It should_ensure_that_we_have_something_to_observe_the_start_of_each_turn = () =>
            robotEngine.AtTheStartOfEachTurn.ShouldNotBeNull();

        It should_ask_the_observer_to_observe = () =>
            observer.AssertWasCalled(o => o.Observe(robotEngine));
    }

I'm now asserting that this observer was told to observe, and I add that method to the interface.
This specification fails, so I can implement this in the robot engine with a few additional lines:

    public class RobotEngine : ImARobotEngine
    {
        readonly IManageStatistics statisticsManager;
        readonly ImAnObserver observer;

        public RobotEngine(IManageStatistics statisticsManager, ImAnObserver observer)
        {
            this.statisticsManager = statisticsManager;
            this.observer = observer;
        }

        public void Initialise(ImARobot robot)
        {
            statisticsManager.EnsureWeStartWithCleanStatistics();
            CreateObservableForTheStartOfEachTurnFromTheRobot(robot);
            observer.Observe(this);
        }

        void CreateObservableForTheStartOfEachTurnFromTheRobot(ImARobot robot)
        {
            AtTheStartOfEachTurn = Observable.FromEvent<StatusAtTheStartOfATurn>(
                                             ev => robot.StartOfEveryTurn += ev,
                                             ev => robot.StartOfEveryTurn -= ev);            
        }

        public IObservable<IEvent<StatusAtTheStartOfATurn>> AtTheStartOfEachTurn 
                                                            { get; private set; }
    }

I've now hooked in my observer and can move onto creating a specification for a concrete version. I've already got an IOC container that resolves all types to their implemented interfaces, so I just need the type to be available for it to roll in at runtime.
The new BattleReachedAReasonableTurnObserverSpecs.cs specification is:

    public class when_at_the_start_of_turn_fifty
    {
        Establish context = () =>
        {
            statusAtTheStartOfTheTurn = new StatusAtTheStartOfATurn { TurnNumber = 50 };
            statusAtTheStartOfATurnEvent = MockRepository.GenerateStub
                                                      <IEvent<StatusAtTheStartOfATurn>>();
            statusAtTheStartOfATurnEvent.Stub(s => s.EventArgs)
                                        .Return(statusAtTheStartOfTheTurn);
            startOfTheTurnObservable = Observable.Return(statusAtTheStartOfATurnEvent);

            robotEngine = MockRepository.GenerateStub<ImARobotEngine>();
            robotEngine.Stub(e => e.AtTheStartOfEachTurn).Return(startOfTheTurnObservable);
            observer = new BattleReachedAReasonableTurnObserver();
        };

        Because of = () => observer.Observe(robotEngine);

        It should_subscribe_to_the_observable_and_recognise_turn_fifty = () =>
            observer.ReachedTurnFifty.ShouldBeTrue();

        static StatusAtTheStartOfATurn statusAtTheStartOfTheTurn;
        static IEvent<StatusAtTheStartOfATurn> statusAtTheStartOfATurnEvent;
        static IObservable<IEvent<StatusAtTheStartOfATurn>> startOfTheTurnObservable;
        static ImARobotEngine robotEngine;
        static BattleReachedAReasonableTurnObserver observer;
    }

In this specification I'm creating a new StatusAtTheStartOfATurn event argument with turn fifty and am returning this on a stubbed IEvent<StatusAtTheStartOfATurn> instance.
I then create a new observable that will return this stub and set up a RobotEngine stub to return this observable.
My assertion is performed on a public property of the concrete observer where ReachedTurnFifty should be true.
The spec fails, so I now provide the implementation in basic form:

    public class BattleReachedAReasonableTurnObserver : ImAnObserver
    {
        public void Observe(ImARobotEngine robotEngine)
        {
            robotEngine.AtTheStartOfEachTurn.Subscribe(start => ReachedTurnFifty = true);
        }

        public bool ReachedTurnFifty { get; private set; }
    }

This passes my specification, so I now want to put some edge cases in for this:

    public class when_at_the_start_of_turn_fifty : with_an_observer
    {
        Establish context = () =>
        {
            statusAtTheStartOfTheTurn = new StatusAtTheStartOfATurn {TurnNumber = 50};
            statusAtTheStartOfATurnEvent.Stub(s => s.EventArgs)
                                        .Return(statusAtTheStartOfTheTurn);
            startOfTheTurnObservable = Observable.Return(statusAtTheStartOfATurnEvent);
            robotEngine.Stub(e => e.AtTheStartOfEachTurn).Return(startOfTheTurnObservable);
        };

        It should_subscribe_to_the_observable_and_recognise_turn_fifty = () =>
            observer.ReachedTurnFifty.ShouldBeTrue();
    }

    public class when_at_the_start_of_turn_fourty_nine : with_an_observer
    {
        Establish context = () =>
        {
            statusAtTheStartOfTheTurn = new StatusAtTheStartOfATurn { TurnNumber = 49 };
            statusAtTheStartOfATurnEvent.Stub(s => s.EventArgs)
                                        .Return(statusAtTheStartOfTheTurn);
            startOfTheTurnObservable = Observable.Return(statusAtTheStartOfATurnEvent);
            robotEngine.Stub(e => e.AtTheStartOfEachTurn).Return(startOfTheTurnObservable);
        };

        It should_subscribe_to_the_observable_but_not_have_recognised_turn_fifty = () =>
            observer.ReachedTurnFifty.ShouldBeFalse();
    }

    public class when_starting_at_turn_fifty_one_and_fifty_never_happened : with_an_observer
    {
        Establish context = () =>
        {
            statusAtTheStartOfTheTurn = new StatusAtTheStartOfATurn { TurnNumber = 51 };
            statusAtTheStartOfATurnEvent.Stub(s => s.EventArgs)
                                        .Return(statusAtTheStartOfTheTurn);
            startOfTheTurnObservable = Observable.Return(statusAtTheStartOfATurnEvent);
            robotEngine.Stub(e => e.AtTheStartOfEachTurn).Return(startOfTheTurnObservable);
        };

        It should_subscribe_to_the_observable_but_not_have_recognised_turn_fifty = () =>
            observer.ReachedTurnFifty.ShouldBeFalse();
    }

    public class with_an_observer
    {
        Establish context = () =>
        {
            statusAtTheStartOfATurnEvent = MockRepository.GenerateStub
                                                <IEvent<StatusAtTheStartOfATurn>>();
            robotEngine = MockRepository.GenerateStub<ImARobotEngine>();
            observer = new BattleReachedAReasonableTurnObserver();
        };

        Because of = () => observer.Observe(robotEngine);

        protected static StatusAtTheStartOfATurn statusAtTheStartOfTheTurn;
        protected static IEvent<StatusAtTheStartOfATurn> statusAtTheStartOfATurnEvent;
        protected static IObservable<IEvent<StatusAtTheStartOfATurn>> startOfTheTurnObservable;
        protected static ImARobotEngine robotEngine;
        protected static BattleReachedAReasonableTurnObserver observer;
    }

This changes the implementation to:

    public class BattleReachedAReasonableTurnObserver : ImAnObserver
    {
        public void Observe(ImARobotEngine robotEngine)
        {
            robotEngine.AtTheStartOfEachTurn.Where(s => s.EventArgs.TurnNumber == 50)
                                            .Subscribe(s => ReachedTurnFifty = true);
        }

        public bool ReachedTurnFifty { get; private set; }
    }

I now have an observer that reacts to turn fifty and I will now be able to write my statistics out to a file. My plan in the future is to have a statistics state that is updated by various observers and finally written at the end of the battle. But for now with the YAGNI principle in mind, I'm just going to inject the statistics manager into the observer. I add to the set up:

    statisticsManager = MockRepository.GenerateStub<IManageStatistics>();
    observer = new BattleReachedAReasonableTurnObserver(statisticsManager);

I can then use this stub to assert against:

    public class when_at_the_start_of_turn_fifty : with_an_observer
    {
        Establish context = () =>
        {
            statusAtTheStartOfTheTurn = new StatusAtTheStartOfATurn {TurnNumber = 50};
            statusAtTheStartOfATurnEvent.Stub(s => s.EventArgs).Return(statusAtTheStartOfTheTurn);
            startOfTheTurnObservable = Observable.Return(statusAtTheStartOfATurnEvent);
            robotEngine.Stub(e => e.AtTheStartOfEachTurn).Return(startOfTheTurnObservable);
        };

        It should_subscribe_to_the_observable_and_recognise_turn_fifty = () =>
            observer.ReachedTurnFifty.ShouldBeTrue();

        It should_ask_the_statistics_manager_to_write_the_statistics = () =>
            statisticsManager.AssertWasCalled(m => m.WriteStatistics(true));
    }

And I get this to pass with:

    public class BattleReachedAReasonableTurnObserver : ImAnObserver
    {
        readonly IManageStatistics statisticsManager;

        public BattleReachedAReasonableTurnObserver(IManageStatistics statisticsManager)
        {
            this.statisticsManager = statisticsManager;
        }

        public void Observe(ImARobotEngine robotEngine)
        {
            robotEngine.AtTheStartOfEachTurn.Where(s => s.EventArgs.TurnNumber == 50)
                       .Subscribe(s =>
                               {
                                   ReachedTurnFifty = true;
                                   statisticsManager.WriteStatistics(ReachedTurnFifty);
                               });
        }

        public bool ReachedTurnFifty { get; private set; }
    }

Finally I write a specification for the statistics manager and refactor the original specification which was detailed in a previous post. I'm using Machine.Specification behaviours to share common assertions between the two specifications. The new specification is at the bottom:

    public class when_told_to_ensure_that_we_start_with_clean_statistics : 
                                                     with_a_statistics_manager
    {
        Because of = () => statisticsManager.EnsureWeStartWithCleanStatistics();

        Behaves_like<a_statistics_manager_that_writes_statistics> 
                              a_statistics_manager_that_writes_statistics;

        It should_contain_reached_turn_fifty_statistic_with_a_false_value = () =>
            statisticsPassedToWriter.Element(StatisticsManager.ReachedTurn50NodeName)
                                    .Value.ShouldEqual("false");
    }

    public class with_a_statistics_manager
    {
        Establish context = () =>
        {
            statisticsWriter = MockRepository.GenerateStub<IWriteStatistics>();
            statisticsWriter.Stub(w => w.WriteStatistics(null))
                            .IgnoreArguments()
                            .Do(RecordStatisticsPassedToWriter);
            statisticsPassedToWriter = null;

            statisticsManager = new StatisticsManager(statisticsWriter);
        };

        static Action<XElement> RecordStatisticsPassedToWriter = x => 
                                                  statisticsPassedToWriter = x;
    
        protected static XElement statisticsPassedToWriter;
        protected static IManageStatistics statisticsManager;
        protected static IWriteStatistics statisticsWriter;
    }

    [Behaviors]
    public class a_statistics_manager_that_writes_statistics
    {
        It should_tell_the_statistics_writer_to_write_some_statistics = () =>
        statisticsWriter.AssertWasCalled(w => w.WriteStatistics(Arg<XElement>.Is.NotNull));

        It should_start_statistics_with_a_statistics_node = () =>
            statisticsPassedToWriter.Name.ToString()
                                         .ShouldEqual(StatisticsManager.StatisticsNodeName);

        It should_contain_the_written_time_statistic_with_the_current_date_and_time = () =>
            statisticsPassedToWriter.Element(StatisticsManager.StatisticsWrittenNodeName)
                                    .Value.ShouldEqual(DateTime.Now.ToShortDateString() + " "
                                                        + DateTime.Now.ToShortTimeString());

        protected static IWriteStatistics statisticsWriter;
        protected static XElement statisticsPassedToWriter;
    }

    public class when_asked_to_write_statistics : with_a_statistics_manager
    {
        Establish context = () => reachedTurnFifty = true;

        Because of = () => statisticsManager.WriteStatistics(reachedTurnFifty);

        Behaves_like<a_statistics_manager_that_writes_statistics> 
                              a_statistics_manager_that_writes_statistics;

        It should_contain_reached_turn_fifty_statistic_with_a_true_value = () =>
            statisticsPassedToWriter.Element(StatisticsManager.ReachedTurn50NodeName)
                                    .Value.ShouldEqual("true");

        static bool reachedTurnFifty;
    }

When asked to write statistics, I'm ensuring it writes out true to the xml file and my behaviours add the additional It delegates. Here's what that looks like in the test runner:

behaviours

The implementation of the statistics manager is now changed to make these specifications pass:

    public class StatisticsManager : IManageStatistics
    {
        public static readonly string StatisticsNodeName = "statistics";
        public static readonly string ReachedTurn50NodeName = "reachedTurn50";
        public static readonly string StatisticsWrittenNodeName = "statisticsWritten";

        IWriteStatistics statisticsWriter;

        public StatisticsManager(IWriteStatistics statisticsWriter)
        {
            this.statisticsWriter = statisticsWriter;
        }

        public void EnsureWeStartWithCleanStatistics()
        {
            XElement statistics = GetStatisticsElementWithReachedTurnFiftyValueOf(false);
            statisticsWriter.WriteStatistics(statistics);
        }

        public void WriteStatistics(bool reachedTurnFifty)
        {
            XElement statistics = GetStatisticsElementWithReachedTurnFiftyValueOf(
                                                                          reachedTurnFifty);
            statisticsWriter.WriteStatistics(statistics);
        }

        XElement GetStatisticsElementWithReachedTurnFiftyValueOf(bool reachedTurnFifty)
        {
            var statistics = new XElement(StatisticsNodeName);
            statistics.Add(new XElement(ReachedTurn50NodeName, reachedTurnFifty.ToString()
                                                                               .ToLower()));
            statistics.Add(new XElement(StatisticsWrittenNodeName, GetCurrentDateTime()));
            return statistics;
        }

        string GetCurrentDateTime()
        {
            return DateTime.Now.ToString("dd/MM/yyyy HH:mm");
        }
    }

So I'm now finished and ready to run my acceptance test. As a reminder here is the acceptance test where it reads an external file once the battle is complete:

    public class in_a_one_round_battle_that_the_slayer_robot_takes_part_in : acceptance_test
    {
        Establish context = () => battleName = "in_a_one_round_battle";

        It should_not_disable_the_robot_at_the_start_of_battle = () =>
            robotStatistics.ReachedTurn50.ShouldBeTrue();
    }

When I run it - the acceptance test is successful and I'm all done on this piece of work, ensuring my robot is never disabled at the start of a battle.
success

Posted at at 7:01 AM on Friday, August 20, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,

hooking up the engine to my robocode robot

In previous posts I've set up an acceptance test that expects some statistics to be written out at turn fifty to ensure my robot is not disabled at the start of a battle. I now need to hook up my robot engine so that it can detect that turn.

I'm going to be using the Rx framework and plan to utilise the observable FromEvent() extension method, so I want an event to be triggered on my robot when the OnStatus() method is called by robocode - this happens at the start of every turn.
Here's the beginning of my specification:

    public class when_robocode_upates_the_turn_status_on_a_robot : with_robot_set_up
    {
        Establish context = () =>                   
        {    
            robotStatus = ???;
            statusEvent = new StatusEvent(robotStatus);
        };

        Because of = () => robot.OnStatus(statusEvent);
    }

I'm using a previous base class that simply sets up a real SlayerRobot and in my because method I want to call the OnStatus method with a status event instance. This presents me with a problem though - the robocode RobotStatus class is a public sealed class with private constructors used for serializing:

private RobotStatus(double energy, double x, double y, double bodyHeading, double gunHeading,
                    double radarHeading, double velocity, double bodyTurnRemaining,
                    double radarTurnRemaining, double gunTurnRemaining,
                    double distanceRemaining, double gunHeat,
                    int others, int roundNum, int numRounds, long time);

I decide to construct one anyway, so I create a class specifically for dealing with this issue:

    internal static class RobocodeSpy
    {
        public static RobotStatus CreateARobotStatus(long time)
        {
            double d = 0;
            int i = 0;

            Type[] types = new Type[16];
            var doubleTypes = types.Take(12).Select(t => typeof (double));
            var intTypes = types.Skip(12).Take(3).Select(t => typeof (int));
            var longTypes = types.Skip(15).Select(t => typeof (long));
            types = doubleTypes.Concat(intTypes).Concat(longTypes).ToArray();

            object[] parameters = new object[16];
            var doubles = parameters.Take(12).Select<object, object>(p => d);
            var ints = parameters.Skip(12).Take(3).Select<object, object>(p => i);
            var longs = parameters.Skip(15).Select<object, object>(p => time);
            parameters = doubles.Concat(ints).Concat(longs).ToArray();

            ConstructorInfo ci = typeof(RobotStatus).GetConstructor(BindingFlags.NonPublic | 
                              BindingFlags.Instance, null, types, null);
            
            object status = ci.Invoke(parameters);

            return (RobotStatus)status;
        }
    }

I can now construct a RobotStatus class with the right time indicating a turn, so I can complete my specification:

    public class when_robocode_upates_the_turn_status_on_a_robot : with_robot_set_up
    {
        Establish context = () =>                   
        {
            robot.StartOfEveryTurn += (s, e) =>  statusAtStartOfTheTurn = e;

            turnNumber = 34;
            robotStatus = RobocodeSpy.CreateARobotStatus(turnNumber);
            statusEvent = new StatusEvent(robotStatus);
        };

        Because of = () => robot.OnStatus(statusEvent);

        It should_update_the_start_of_every_turn_event_with_the_turn_number = () =>
            statusAtStartOfTheTurn.TurnNumber.ShouldEqual(turnNumber);

        static StatusEvent statusEvent;
        static RobotStatus robotStatus;
        static long turnNumber;
        static StatusAtTheStartOfATurn statusAtStartOfTheTurn;
    }

I define a new event that I want to see on my robot - the StartOfEveryTurn event and I assign an event handler to it to capture the event arguments which I want to be of a new type "StatusAtTheStartOfATurn".
I then construct the objects required for the event and defining a turn and then in the Because action I raise the event.
I expect that the turn number of 34 should make its way into the event arguments.

Here is the relevant part of the robot class that makes this specification pass:

    public class SlayerRobot : Robot, ImARobot
    {
        public event EventHandler<StatusAtTheStartOfATurn> StartOfEveryTurn;

        public override void OnStatus(StatusEvent e)
        {
            StartOfEveryTurn(this, new StatusAtTheStartOfATurn {TurnNumber = e.Status.Time});
        }
    }

    public class StatusAtTheStartOfATurn : EventArgs
    {
        public long TurnNumber { get; set; }
    }

I also don't want this to blow up if no handlers have been assigned to this event, so I write an additional specification:

    public class when_robocode_upates_the_turn_status_on_a_robot_that_has_nothing_listening_
                            to_the_start_of_every_turn : with_robot_set_up
    {
        Establish context = () =>
        {           
            turnNumber = 34;
            robotStatus = RobocodeSpy.CreateARobotStatus(turnNumber);
            statusEvent = new StatusEvent(robotStatus);
        };

        Because of = ()=> caughtException = Catch.Exception(() => robot.OnStatus(statusEvent));

        It should_not_fail = () =>
            caughtException.ShouldBeNull();

        static StatusEvent statusEvent;
        static RobotStatus robotStatus;
        static long turnNumber;
        static Exception caughtException;
    }

This currently fails with a NullReferenceException, so I make this pass via the robot's constructor:

    public class SlayerRobot : Robot, ImARobot
    {
        public event EventHandler<StatusAtTheStartOfATurn> StartOfEveryTurn;

        public SlayerRobot()
        {
            ServiceLocator = new ServiceLocator();
            StartOfEveryTurn += (s,e)=> {};
        }
    }

I've now got my own hook into the start of every turn and I've described this in my own terms, making it more verbose and a bit more intuitive.

I now need to get my own RobotEngine class to transform this into an observable, so again begin with adding to a previous specification for when the robot engine is initialised:

    public class when_initialising_a_robot_engine : with_a_robot_engine
    {
        Because of = () => robotEngine.Initialise(robot);

        It should_tell_the_statistics_writer_to_ensure_we_have_clean_statistics = () =>
            statisticsManager.AssertWasCalled(s => s.EnsureWeStartWithCleanStatistics());

        It should_ensure_that_we_have_something_to_observe_the_start_of_each_turn = () =>
            robotEngine.AtTheStartOfEachTurn.ShouldNotBeNull();    
    }

    public class with_a_robot_engine
    {
        Establish context = () =>
        {
            statisticsManager = MockRepository.GenerateStub<IManageStatistics>();
            robotEngine = new RobotEngine(statisticsManager);
            robot = MockRepository.GenerateStub<ImARobot>();
        };

        protected static ImARobotEngine robotEngine;
        protected static ImARobot robot;
        protected static IManageStatistics statisticsManager;
    }

The following simple code introduced in the Initialise method makes this specification pass:

    public class RobotEngine : ImARobotEngine
    {
        readonly IManageStatistics statisticsManager;

        public RobotEngine(IManageStatistics statisticsManager)
        {
            this.statisticsManager = statisticsManager;
        }

        public void Initialise(ImARobot robot)
        {
            statisticsManager.EnsureWeStartWithCleanStatistics();
            CreateObservableForTheStartOfEachTurnFromTheRobot(robot);
        }

        void CreateObservableForTheStartOfEachTurnFromTheRobot(ImARobot robot)
        {
            AtTheStartOfEachTurn = Observable.Return<IEvent<StatusAtTheStartOfATurn>>(null);
        }

        public IObservable<IEvent<StatusAtTheStartOfATurn>> AtTheStartOfEachTurn 
                                                             { get; private set; }
    }

I have an observable, but it is not tied up to the robot's event, so I need another specification for that:

    public class when_the_start_of_a_turn_occurs : with_a_robot_engine
    {
        Establish context = () => 
        {
            expectedTurnNumber = 784;
            statusAtTheStartOfATurn = new StatusAtTheStartOfATurn 
                                           { TurnNumber = expectedTurnNumber};

            robotEngine.Initialise(robot);
            robotEngine.AtTheStartOfEachTurn.Subscribe(t => 
                observedTurnNumber = (t==null) ? 0 : t.EventArgs.TurnNumber);
        };

        Because of = () => robot.Raise(x => x.StartOfEveryTurn += null, 
                                             robot, statusAtTheStartOfATurn);

        It should_be_able_to_observe_the_start_of_the_turn = () =>
            observedTurnNumber.ShouldEqual(expectedTurnNumber);

        static StatusAtTheStartOfATurn statusAtTheStartOfATurn;
        static long expectedTurnNumber;
        static long observedTurnNumber;
    }

I first initialise the robot engine and then subscribe to the IObservable<IEvent<StatusAtTheStartOfATurn>> where the EventArgs of the object used in the subscription is of type StatusAtTheStartOfATurn.
I then raise an event using Rhino Mocks sending in my constructed status.
I can then assert that the observed turn number is the expected one - this specification fails, so I can now replace the implementation in RobotEngine with the real one:

        void CreateObservableForTheStartOfEachTurnFromTheRobot(ImARobot robot)
        {
            AtTheStartOfEachTurn = Observable.FromEvent<StatusAtTheStartOfATurn>(
                                             ev => robot.StartOfEveryTurn += ev,
                                             ev => robot.StartOfEveryTurn -= ev);            
        }

My specification passes and I now have an observable created from the OnStatus() event of the robocode robot.
In my next post I'll explore how to subscribe to this for turn fifty to pass my original acceptance test.

Here's the RobotEngine code in full:

    public class RobotEngine : ImARobotEngine
    {
        readonly IManageStatistics statisticsManager;

        public RobotEngine(IManageStatistics statisticsManager)
        {
            this.statisticsManager = statisticsManager;
        }

        public void Initialise(ImARobot robot)
        {
            statisticsManager.EnsureWeStartWithCleanStatistics();
            CreateObservableForTheStartOfEachTurnFromTheRobot(robot);
        }

        void CreateObservableForTheStartOfEachTurnFromTheRobot(ImARobot robot)
        {
            AtTheStartOfEachTurn = Observable.FromEvent<StatusAtTheStartOfATurn>(
                                             ev => robot.StartOfEveryTurn += ev,
                                             ev => robot.StartOfEveryTurn -= ev);            
        }

        public IObservable<IEvent<StatusAtTheStartOfATurn>> AtTheStartOfEachTurn 
                                             { get; private set; }
    }

Posted at at 7:18 AM on Wednesday, August 18, 2010 by Posted by Justin Davies | 2 comments Links to this post   | Filed under: , ,

working with robocode and the rx framework

I'm starting on a new series of robocode posts that will show my first steps into a robocode robot and I'm treating this as an opportunity to try out some new things, one of which is the new Rx framework from Microsoft. I'm using the 3.5 framework download available from the Rx website (as I have yet to upgrade to 4.0 and VS2010).

Getting this to work with robocode was not easy though and I've had to make a few sacrifices to get this to work (see below) but this is OK for me as the robot battles are happening on my own computer. I therefore wouldn't necessarily recommend using this for a robot you want to compete with online.

When I first hooked up the Rx framework my robot was immediately banned but I couldn't see why in the message printed out on the console. Then I noticed that my offending code using Rx was sitting in a static initializer, so I pulled it into a member method instead.
This then provided me with the real problem - a security violation with "that assembly does not allow partially trusted callers".
(this may be a bug in the robocode fix where static initializer security issues are not caught/cannot be caught in the same manner upon robot creation and security exceptions are not written to the console)

I *think* it was the System.Reactive assembly that didn't allow partially trusted callers and after much wrestling with different fixes I finally got it to work. I can't say for sure that this is the definitive solution, but it works and I don't want to touch it!

I installed the System.Observable, System.CoreEx and System.Reactive 3.5 assemblies in the GAC and I introduced a post build step in my robot assembly so that it registers my assembly in the GAC (and of course I have to sign my robot assembly).
What I *think* happens is that a partially trusted call comes into my robot assembly, but because that is signed and GAC'd it can safely pass on a call to the System.Reactive assembly, fixing my issue.

This means I have had to make a few sacrifices and have the following constraints:

  • My robot assembly is installed in the GAC and I have a post build step to register it
  • I therefore have to run Visual studio as an administrator (which I normally restrict)
  • I can't debug my code through visual studio anymore as it picks up the assembly from the GAC

Now my robot works with Rx 3.5 and I'm free to proceed with my experimentation - the next post will start this new journey.

Posted at at 7:28 AM on Monday, August 16, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

writing the statistics file

In my previous post I'd set up my acceptance test to read an xml statistic file to establish whether the robot reached turn 50 in the acceptance test battle.

I now need to start on the implementation of writing this statistics file and I start with a specification for my as yet non-existent RobotEngine class.
In a very early post I had described how the SlayerRobot calls the InitialiseMethod, passing itself in (to an abstracted interface of ImARobot) and this is where I start:

    public class when_initialising_a_robot_engine
    {
        Establish context = () =>
        {
            statisticsManager = MockRepository.GenerateStub<IManageStatistics>();                                    
            robotEngine = new RobotEngine(statisticsManager);
            robot = MockRepository.GenerateStub<ImARobot>();
        };

        Because of = () => robotEngine.Initialise(robot);

        It should_tell_the_statistics_writer_to_ensure_we_have_clean_statistics = () =>
            statisticsManager.AssertWasCalled(s => s.EnsureWeStartWithCleanStatistics());

        static ImARobotEngine robotEngine;
        static ImARobot robot;
        static IManageStatistics statisticsManager;
    }

I'm creating a stubbed statistics manager against a new interface "IManageStatistics" and I want the robot engine to ensure that we start with some clean statistics - effectively resetting the values.
I implement this very easily:

    public class RobotEngine : ImARobotEngine
    {
        readonly IManageStatistics statisticsManager;

        public RobotEngine(IManageStatistics statisticsManager)
        {
            this.statisticsManager = statisticsManager;
        }

        public void Initialise(ImARobot robot)
        {
            statisticsManager.EnsureWeStartWithCleanStatistics();
        }
    }

I can now move onto the statistics manger specification:

    public class when_told_to_ensure_that_we_start_with_clean_statistics
    {
        Establish context = () =>
        {
            statisticsWriter = MockRepository.GenerateStub<IWriteStatistics>();
            statisticsManager = new StatisticsManager(statisticsWriter);
        };

        Because of = () => statisticsManager.EnsureWeStartWithCleanStatistics();

        It should_tell_the_statistics_writer_to_write_some_statistics = () =>
            statisticsWriter.AssertWasCalled(w => w.WriteStatistics(Arg<XElement>.Is.NotNull));

        static IManageStatistics statisticsManager;
        static IWriteStatistics statisticsWriter;
    }

I've abstracted the writing of the file to a call where the statistics manager will tell the writer to write an XElement it has built up. The implementation is trivial, so I'll move onto the next set of specifications - creating the XElement.
Here's the xml file I want to replicate:

xmlStatistics

    public class when_told_to_ensure_that_we_start_with_clean_statistics
    {
        Establish context = () =>
        {
            statisticsWriter = MockRepository.GenerateStub<IWriteStatistics>();
            statisticsWriter.Stub(w => w.WriteStatistics(null))
                            .IgnoreArguments()
                            .Do(RecordStatisticsPassedToWriter);
            statisticsPassedToWriter = null;

            statisticsManager = new StatisticsManager(statisticsWriter);
        };

        Because of = () => statisticsManager.EnsureWeStartWithCleanStatistics();

        It should_tell_the_statistics_writer_to_write_some_statistics = () =>
            statisticsWriter.AssertWasCalled(w => w.WriteStatistics(Arg<XElement>.Is.NotNull));

        It should_start_statistics_with_a_statistics_node = () =>
            statisticsPassedToWriter.Name.ToString()
                                         .ShouldEqual(StatisticsManager.StatisticsNodeName);

        It should_contain_the_written_time_statistic_with_the_current_date_and_time = () =>
            statisticsPassedToWriter.Element(StatisticsManager.StatisticsWrittenNodeName)
                                    .Value.ShouldEqual(DateTime.Now.ToShortDateString() + " " 
                                                        + DateTime.Now.ToShortTimeString());

        It shouild_contain_reached_turn_fifty_statistic_with_a_false_value = () =>
            statisticsPassedToWriter.Element(StatisticsManager.ReachedTurn50NodeName)
                                    .Value.ShouldEqual("false");

        static Action<XElement> RecordStatisticsPassedToWriter = x =>
                                                    statisticsPassedToWriter = x;

        static IManageStatistics statisticsManager;
        static IWriteStatistics statisticsWriter;
        static XElement statisticsPassedToWriter;
    }

By recording the XElement instance that is sent in the call to the writer I can assert against it in my specifications and I line them up with the xml file.
Here's the implementation:

    public class StatisticsManager : IManageStatistics
    {
        public static readonly string StatisticsNodeName = "statistics";
        public static readonly string ReachedTurn50NodeName = "reachedTurn50";
        public static readonly string StatisticsWrittenNodeName = "statisticsWritten";

        IWriteStatistics statisticsWriter;

        public StatisticsManager(IWriteStatistics statisticsWriter)
        {
            this.statisticsWriter = statisticsWriter;
        }

        public void EnsureWeStartWithCleanStatistics()
        {
            var statistics = new XElement(StatisticsNodeName);
            statistics.Add(new XElement(ReachedTurn50NodeName, "false"));
            statistics.Add(new XElement(StatisticsWrittenNodeName, GetCurrentDateTime()));

            statisticsWriter.WriteStatistics(statistics);
        }

        string GetCurrentDateTime()
        {
            return DateTime.Now.ToString("dd/MM/yyyy HH:mm");
        }
    }

I create a new XElement and fill it with the appropriate child elements and content.
I use readonly static members because I want to use these in my test assembly and I can ensure they don't get embedded into the call-site (if it were a constant).

The next step for statistics is to implement the statistics writer directly without specification:

    public class StatisticsWriter : IWriteStatistics
    {
        public static readonly string StatisticsFileLocation = 
            @"C:\dev\Projects\RoboCodeWars\TeamSlayer\Specifications\AcceptanceSpecs\
                                                battles\results\Statistics.xml";

        public void WriteStatistics(XElement statisticsElement)
        {
            statisticsElement.Save(StatisticsFileLocation);
        }
    }

I'm now ready to hook this into my robot. If you've followed previous posts you may remember I use a service locator to abstract autofac from my SlayerRobot in the adapter layer.
The robot call looked like this (where ServiceLocator is a property on the robot and Initialise() currently returns null and causes the exception my acceptance test is trying to prevent):

        public override void Run()
        {
            ImARobotEngine robotEngine = ServiceLocator.ProvideRobotEngine();            
            robotEngine.Initialise(this);
        }

So I need a specification for my non existent service locator

    public class when_told_to_provide_a_robot_engine
    {
        Establish context = () => serviceLocator = new ServiceLocator();

        Because of = () => robotEngine = serviceLocator.ProvideRobotEngine();

        It should_return_a_valid_robot_engine = () => robotEngine.ShouldNotBeNull();

        static ILocateServices serviceLocator;
        static ImARobotEngine robotEngine;
    }

And the implementation now hooks everything up:

    public class ServiceLocator : ILocateServices
    {
        IContainer _container;

        public ServiceLocator()
        {
            RegisterEverything();
        }

        void RegisterEverything()
        {
            var builder = new ContainerBuilder();

            builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                   .AsImplementedInterfaces();

            _container = builder.Build();
        }

        public ImARobotEngine ProvideRobotEngine()
        {
            return _container.Resolve<ImARobotEngine>();
        }
    }

When I run my acceptance test that runs a battle I now get a test failure where the value of reachedTurn50 is false - not because my robot threw an exception, but because I am explicitly writing clean statistics with the false value.

The next few posts will delve into writing the new statistics when the robot runs and reaches turn 50, hopefully then passing my acceptance test

Posted at at 7:55 AM on Thursday, August 12, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,

the first steps toward a working robot

A previous series of posts illustrated how I got to grips with acceptance testing for a robocode robot. I'm now ready to start  coding the robot itself so I want to refer back to the bottom of a previous post: starting the robocode robot with an anti-corruption layer :

"Note that the service locator purposefully returns null for the time being and causes a null reference exception when the Robot is run. This is so I can observe what happens when a robot does not function correctly and I'll be covering this in one of the next few posts."

By leaving my robot in an exception state, I observed that the robot is disabled when the exception is thrown:

disabledRobot

I therefore want to write an acceptance test that will always check that my robot doesn't throw an exception at the start of the battle. So here's how I want to express that in an acceptance test:

    public class in_a_one_round_battle_that_the_slayer_robot_takes_part : acceptance_test
    {
        Establish context = () => battleName = "in_a_one_round_battle";

        It should_not_disable_the_robot_at_the_start_of_battle = () =>
            robotStatistics.ReachedTurn50.ShouldBeTrue();
    }

I've introduced a new member that does not yet exist - the robotStatistics field and a property that ensures we have reached a reasonable number of turns within a battle.

Here's my idea: if I can write out an xml file during the battle, my acceptance tests can determine what occurred - so I create an xml file by hand and place it in my acceptance test battle results folder:

xmlStatistics
The robot will write out the information I need to establish it reached a certain number of turns and it also writes the date and time these statistics were written so I can establish in the acceptance test that it is a fresh file and I'm not asserting against a previous run.

So the first thing to do is add the reading of the statistics into my base acceptance test - the new lines are highlighted below:

    public class acceptance_test
    {
        Establish context = () => battleRunner = new BattleRunner(new ProcessRunner(), 
                  new BattleResultParser(new BattleResultsFileReader()));

        Because of = () =>
                         {
                             battleName.ShouldNotEqual(string.Empty);
                             battle = new Battle(battleName);
                             returnedResults = battleRunner.Run(battle);
                             robotStatistics = Statistics.RetrieveStatistics();   <---
                         };

        protected static string battleName = string.Empty;
        protected static IEnumerable<BattleResult> returnedResults;
        protected static RobotStatistics robotStatistics;                         <---
        static Battle battle;
        static BattleRunner battleRunner;   
    }

I also create a quick "Statistics" class solely for reading within the acceptance test:

    internal static class Statistics
    {
        public static RobotStatistics RetrieveStatistics()
        {
            var statistics = XElement.Load(@"C:\dev\Projects\RoboCodeWars\TeamSlayer\
                              Specifications\AcceptanceSpecs\battles\results\Statistics.xml");

            string reachedTurn50Value = statistics.Element("reachedTurn50").Value;

            var startDateAndTime = Convert.ToDateTime(
                               statistics.Element("statisticsWritten").Value);

            if (startDateAndTime < DateTime.Now.AddMinutes(-1))
                throw new Exception(string.Format("Statistics file looks old - start 
                                time in file was {0}", startDateAndTime));

            return new RobotStatistics {ReachedTurn50 = Convert.ToBoolean(reachedTurn50Value)};
        }
    }

    internal class RobotStatistics
    {
        public bool ReachedTurn50 { get; set; }
    }

I now re-save my xml file, run my acceptance test and see that it fails because the statistics say the robot did not reach turn 50:

failedToTeachTurn50

If I then run it a few minutes later, I get the exception stating that the file looks old so my acceptance test is up and running.
I'm now ready to start on my robot implementation to write these statistics out and I'll cover this on my next post.

Posted at at 7:49 AM on Tuesday, August 10, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,