Search And Destroy

Look out honey, ’cause I’m using technology!

Why Didn’t They Ask Evans?

Posted by kilfour on February 4, 2010

I haven’t been blogging a lot lately, and have not mentioned QuickNet recently.
Work has continued though. But as it’s still all quite experimental I’m reluctant to share it with the world.

Some QuickPreviews :
Me like this :

[Using(typeof(Login))]
[Using(typeof(Logout))]
public class NavigateSpecs : AcidTest<SecuredNavigatorState>
{
    public NavigateSpecs() : base(50, 10) { }

    [SpecFor(typeof(Navigate))]
    public Spec ThrowsSecurityExceptionIfUserIsNotLoggedOn(string input, IResource output)
    {
        return
            new Spec()
            .If(State.UserIsNotLoggedOn)
            .Throws<SecurityException>();
    }

    [SpecFor(typeof(Navigate))]
    public Spec ReturnsAResourceIfUserIsLoggedOn(string input, IResource output)
    {
        return
            new Spec(() => Ensure.NotNull(output))
            .If(State.UserIsLoggedOn);
    }
}

This is a rewrite of the example found on google code downloads. It defines specs on the navigate transition while still ‘using’ the login and logout transitions to get to certain states.

Also Agatha and QuickNet really play nice when it boils down to writing integration tests.
f.i. :
for the transition :

public class PrepareForGenerateOrderTransition : MetaTransition<PrepareForGenerateOrderRequest, PrepareForGenerateOrderResponse, State>
{
    public PrepareForGenerateOrderTransition(State state)
    {
        Precondition = () => state.Current == (state.Current & (States.Editing));
        GenerateInput = () => new PrepareForGenerateOrderRequest {Offer = state.OfferDto};
        Execute =
            i =>
            {
                var response = state.Dispatcher().Get<PrepareForGenerateOrderResponse>(i);
                state.Current = States.InGenerateOrder;
                state.OfferDto = response.Offer;
                return response;
            };
    }
}

And then the spec :

[SpecFor(typeof(PrepareForGenerateOrderTransition))]
public Spec PrepareForGenerateOrderNoException(PrepareForGenerateOrderRequest input, PrepareForGenerateOrderResponse output)
{
    return new Spec(() => Ensure.Null(output.Exception))
        .If(() => input.Offer.CurrentSalesRep2ID > 0);
}

This is the result :

TestCase 'PrepareForGenerateOrderTransition PrepareForGenerateOrderNoException'
failed: QuickNet.FalsifiableException :
Expected : null.
Actual : An ExceptionInfo whose value is:
Corelio.SalesTool.Common.BusinessException: Line #1 in the offer has no edition yet.
   at Corelio.SalesTool.Business.PriceCalculation.CalculatorValidator.CheckWheterEachOfferDetailHasAProduct(Offer offer) in D:\Corelio-MAMS\MAMS\SalesTool\Business\PriceCalculation\CalculatorValidator.cs:line 21
   at Corelio.SalesTool.Business.PriceCalculation.PriceCalculator.CalculatePrice(Offer offer) in D:\Corelio-MAMS\MAMS\SalesTool\Business\PriceCalculation\PriceCalculator.cs:line 62
   at Corelio.SalesTool.Service.Offers.PrepareForGenerateOrderHandler.ExecuteOfferOperation(Offer offer) in D:\Corelio-MAMS\MAMS\SalesTool\Service\Offers\PrepareForGenerateOrderHandler.cs:line 34
   at Corelio.SalesTool.Service.Offers.OfferHandler`2.Handle(TRequest request) in D:\Corelio-MAMS\MAMS\SalesTool\Service\Offers\OfferHandler.cs:line 26
   at Agatha.ServiceLayer.RequestHandler`2.Handle(Request request) in D:\DotNetDev\agatha-rrsl\Agatha.ServiceLayer\RequestHandler.cs:line 72
   at IRequestHandler`1Proxyc2453212705444138a4974dd6f97b51d.InvocationHandle_2.InvokeMethodOnTarget()
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Corelio.SalesTool.Business.Repo.WithUnitOfWork.Intercept(IInvocation invocation) in D:\Corelio-MAMS\MAMS\SalesTool\Business\Repo\WithUnitOfWork.cs:line 17
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Corelio.SalesTool.Business.Repo.WithAOUnitOfWork.Intercept(IInvocation invocation) in D:\Corelio-MAMS\MAMS\SalesTool\Business\Repo\WithAOUnitOfWork.cs:line 15
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at IRequestHandler`1Proxyc2453212705444138a4974dd6f97b51d.Handle(Request request)
   at Agatha.ServiceLayer.RequestProcessor.GetResponseFromHandler(Request request, IRequestHandler responseHandler) in D:\DotNetDev\agatha-rrsl\Agatha.ServiceLayer\RequestProcessor.cs:line 128.

	D:\DotNetDev\QuickSuite\QN\QuickNet\Ensure.cs(23,0): at QuickNet.Ensure.Null(Object value)
	D:\Corelio-MAMS\MAMS\SalesTool\QuickNetTests\Specs.cs(46,0): at QuickNetTests.Specs.<>c__DisplayClassc.<PrepareForGenerateOrderNoException>b__b()
	D:\DotNetDev\QuickSuite\QN\QuickNet\Spec.cs(103,0): at QuickNet.Spec.VerifyInvariant(ITestRunReport report)

Output from PrepareForGenerateOrderTransition PrepareForGenerateOrderNoException:
  no configuration section <common/logging> found - suppressing logging output
  ----------------------------------------------------------
  PrepareForGenerateOrderTransition PrepareForGenerateOrderNoException
  Falsifiable after 6 test(s), 3 Transition(s).
  --------------------Simplest Fail Case--------------------
  1 : Transition : NewOfferTransition, Output : Corelio.SalesTool.RequestsAndResponses.Offers.GetNewOfferResponse
  Corelio.SalesTool.RequestsAndResponses.Offers.GetNewOfferRequest
  2 : Transition : PrepareForGenerateOrderTransition, Output : Corelio.SalesTool.RequestsAndResponses.Offers.PrepareForGenerateOrderResponse
  Corelio.SalesTool.RequestsAndResponses.Offers.PrepareForGenerateOrderRequest
  ----------------------------------------------------------

0 passed, 1 failed, 0 skipped, took 17,03 seconds.

As I said experimental, the bit operations will be abstracted f.i.

Posted in Agatha, QuickNet | Leave a Comment »

My Favourite M.C. : We Pack and Deliver like U.P.S. Trucks.

Posted by kilfour on January 31, 2010

Allready gone to hell… just pumping that gas.
M.I.A.
M.I.A.

Not a big fan of hip-hop in general, they usually tend to talk about sex in a not very inventive way (do better than Penetration by the Stooges and we’ll talk again), but as always there are exceptions …

The current politics regarding Haiti, make some of her lyrics even more poignant. Third World Democracy… All I want to do … and a, and take your money …

Posted in Music, My Favourite | 1 Comment »

Conway’s Law

Posted by kilfour on January 28, 2010

…organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.

I’m a believer.

Posted in Rants | Leave a Comment »

From Rags Right Through to Stitches

Posted by kilfour on January 20, 2010

A brain frying SQL alias : ‘a’.

select …. from labeladordckl a left outer join editions e on a.edition = e.axedinr

I don’t like the habit a lot of sql statement spitters have to alias tables using a single letter but above statement really shocked me.
The fact that I found it in a view linking several tables, which is based on another view also linking to the same tables, which returns a dataset that the consuming application left outer joins … twice … didn’t make me any happier.

And in case you’re wondering about the strange table name, here are some others :
– RGHISKLT
– CDEP_CSIT
– KAHISXDT
– LABELADORD
– LABELADORDE
– LABELADORDW
– LABELADORDH
– …

I think i’ll go and have a beer now….

Posted in Rants | 1 Comment »

One, Two, Buckle My Shoe

Posted by kilfour on January 19, 2010

I’m currently on one of those projects that seem to have taken the coding guidelines from the paper I linked to in this post.

It started out as a web app, where most of the logic, including hard-baked sql statements was found in the aspx files. A rewrite was ordered by the customer. They also decide to go for a winforms application this time. Mainly for performance reasons, which I think are the wrong reasons, but…

So now we have a fat client. I did follow a lot of the well known patterns, including a service layer translating from business objects to dto’s and passing them on to the Gui, and back again. Every once in a while a reference to the business layer popped up in the frontend project though.

So a while ago when Agatha started supporting an In-Process service layer, I introduced requests, responses and handlers. These days almost all of the service layer is implemented using Agatha. With a funny side-effect : when things go smoothly the devs talk about their handlers and when things go wrong they talk about my dispatcher. Still trying to explain the concept of CollectiveCodeOwnership. ;-)

Now there was one thing which the web app handled far more easily than the win app : the uploading of files to a server. The webapp was deployed on the server where the files needed to be, so it could just drop the uploaded files in the destination folder. Doing this in the winapp we would have to resort to some kind of ftp stuff, which means setting up a site, managing users from different domains or impersonating, etc…

So I figured I’d try to write an Upload WCF Service. The idea is to seperate the service layer from the frontend at some point in the future, so this service would also serve as a spike to see if this migration could be done incrementally.

Writing the Agatha handler was pretty easy.
Setting up the service in IIS was a breeze.
Getting the client configured was a bit tricky as there’s no example on how to have two Dispatchers (one in-process and one using a proxy) in the Agatha project and up untill now I had only used out-of-the-box configuration features. But it did not take too long to figure it out.

I’m not entirely sure if this the preferred way of doing this, but this is how it currently works for me :

After doing the normal configuration in the client I added the following :

public interface IUploadServiceRequestProcessor : IAsyncRequestProcessor{}
public class UploadServiceRequestProcessor
	: AsyncRequestProcessorProxy, IUploadServiceRequestProcessor
{
}

public interface IUploadServiceRequestDispatcher : IAsyncRequestDispatcher{}
public class UploadServiceRequestDispatcher
	: AsyncRequestDispatcher, IUploadServiceRequestDispatcher
{
    public UploadServiceRequestDispatcher(IUploadServiceRequestProcessor requestProcessor)
    	: base(requestProcessor) { }
}

And then just added those to my container :

Common.IoC.Container.Register(
    Component.For<IUploadServiceRequestProcessor>()
        .ImplementedBy<UploadServiceRequestProcessor>()
        .LifeStyle.Transient);

Common.IoC.Container.Register(
    Component.For<IUploadServiceRequestDispatcher>()
        .ImplementedBy<UploadServiceRequestDispatcher>()
        .LifeStyle.Transient);

Now resolving IRequestDispatcher gets me the in process one, and resolving IUploadServiceRequestDispatcher gets me the WCF one.

And as an added bonus migrating one of the handlers from the one service layer to the other, means moving it from one project to another and changing the dispatcher in the client. Pretty easy, so it looks like we can do aforementioned migration incrementally :-) .

Posted in Agatha, C# Musings | 1 Comment »

My Favourite OS

Posted by kilfour on January 16, 2010

squeak
Squeak.

Posted in My Favourite | Leave a Comment »

Ere Thrice the Sun Done Salutation to the Dawn

Posted by kilfour on January 15, 2010

A while ago davy brion posted a nice base class for nhibernate crud tests, which i eagerly copy/pasted.

I used the QuickNet Generators to simplify things a little further.

Using this slightly modified version of davy’s class (there’s no IHaveAnId class in our codebase, things are slightly different there):

public abstract class CrudTest<TEntity, TId> : InMemoryDatabaseTest
{
    [Fact]
    public virtual void SelectQueryWorks()
    {
        NHibernateSession.CreateCriteria(typeof(TEntity)).SetMaxResults(5).List();
    }

    [Fact]
    public virtual void AddEntity_EntityWasAdded()
    {
        var entity = BuildEntity();

        InsertEntity(entity);

        NHibernateSession.Evict(entity);

        var reloadedEntity = NHibernateSession.Get<TEntity>(GetId(entity));

        Assert.NotNull(reloadedEntity);
        AssertAreEqual(entity, reloadedEntity);

        AssertValidId(reloadedEntity);
    }

    [Fact]
    public virtual void UpdateEntity_EntityWasUpdated()
    {
        var entity = BuildEntity();

        InsertEntity(entity);
        ModifyEntity(entity);
        UpdateEntity(entity);

        NHibernateSession.Evict(entity);

        var reloadedEntity = NHibernateSession.Get<TEntity>(GetId(entity));
        Assert.NotNull(reloadedEntity);
        AssertAreEqual(entity, reloadedEntity);
    }

    [Fact]
    public virtual void DeleteEntity_EntityWasDeleted()
    {
        var entity = BuildEntity();

        InsertEntity(entity);
        DeleteEntity(entity);

        Assert.Null(NHibernateSession.Get<TEntity>(GetId(entity)));
    }

    protected virtual void InsertEntity(TEntity entity)
    {
        NHibernateSession.Save(entity);
        NHibernateSession.Flush();
    }

    protected virtual void UpdateEntity(TEntity entity)
    {
        NHibernateSession.Update(entity);
        NHibernateSession.Flush();
    }

    protected virtual void DeleteEntity(TEntity entity)
    {
        NHibernateSession.Delete(entity);
        NHibernateSession.Flush();
    }

    protected abstract TEntity BuildEntity();

    protected abstract TEntity ModifyEntity(TEntity entity);

    protected abstract void AssertValidId(TEntity entity);

    protected abstract void AssertAreEqual(TEntity expectedEntity, TEntity actualEntity);

    protected abstract TId GetId(TEntity entity);
}

I then use the following base class for what we call a BaseIdEntity, there are one or two others.

public abstract class BaseIdEntityCrudTest<TEntity> : CrudTest<TEntity, long>
    where TEntity : BaseIdEntity
{
    public class EntityGenerator : GeneratorFor<TEntity>
    {
        public EntityGenerator()
        {
            IgnoreProperty(t => t.Id);
        }
    }

    public class UpdateEntityGenerator : EntityGenerator
    {
        private readonly TEntity entity;
        public UpdateEntityGenerator(TEntity entity)
        {
            this.entity = entity;
        }
        protected override TEntity GetDefaultInstance()
        {
            return entity;
        }
    }

    protected override long GetId(TEntity entity)
    {
        return entity.Id;
    }

    protected override TEntity BuildEntity()
    {
        return new EntityGenerator().GetRandomValue();
    }

    protected override TEntity ModifyEntity(TEntity entity)
    {
        return new UpdateEntityGenerator(entity).GetRandomValue();
    }

    protected override void AssertValidId(TEntity entity)
    {
        Assert.True(entity.Id > 0);
    }
}

This uses the quicknet generators to build/modify the entities, reducing a concrete crud test to :

public class SomeEntityMappingTest : BaseIdEntityCrudTest<SomeEntity>
{
    protected override void AssertAreEqual(SomeEntity expectedEntity, SomeEntity actualEntity)
    {
        Assert.Equal(expectedEntity.Name, actualEntity.Name);
        Assert.Equal(expectedEntity.Description, actualEntity.Description);
        Assert.Equal(expectedEntity.Label, actualEntity.Label);
        Assert.Equal(expectedEntity.IsActive, actualEntity.IsActive);
    }
}

Posted in QuickNet | 1 Comment »

When Routine Bites Hard

Posted by kilfour on January 14, 2010

Just another example of how to use the GeneratorMap.

From Agatha.Tests :

GeneratorMap.SetGenerator<string>(new StringGenerator(1, 1));

GeneratorMap.SetGenerator<int>(new IntGenerator(0, 5));

GeneratorMap.SetGenerator<Request>(
    new BaseClassGenerator<Request>()
        .AddGenerator(new GeneratorFor<Request, FirstRequest>())
        .AddGenerator(new GeneratorFor<Request, SecondRequest>())
        .AddGenerator(new GeneratorFor<Request, ThirdRequest>())
        .AddGenerator(new GeneratorFor<Request, FourthRequest>())
        .AddGenerator(new GeneratorFor<Request, FifthRequest>())
        .AddGenerator(new GeneratorFor<Request, FirstCachedRequest>())
        .AddGenerator(new GeneratorFor<Request, SecondCachedRequest>()));

GeneratorMap.SetGenerator<DescribedAction>(
    new ChoiceGenerator<DescribedAction>(
        new[]
            {
                new DescribedAction { Exception = null, Description = "Does nothing" },
                new DescribedAction { Exception = new BusinessException(), Description = "Throws BusinessException" },
                new DescribedAction { Exception = new SecurityException(), Description = "Throws SecurityException" },
                new DescribedAction { Exception = new UnknownException(), Description = "Throws UnknownException" },
                new DescribedAction { Exception = new AnotherUnknownException(), Description = "Throws AnotherUnknownException" }
            }));

And then the transition’s Generator can be defined like so :

Generator = ListGenerator.For<Tuple<Request,DescribedAction>>(0, 10);

Posted in QuickNet | Leave a Comment »

You Were Just a Painted Face on a Trip Down to Suicide Road

Posted by kilfour on January 13, 2010

I just refactored the Agatha RequestProcessorTest.ExceptionHandling AcidTest to take advantage of the new QuickNet features and it is throwing a failure.

This might be a bug in QuickNet.
This might be an erroneous spec definition.
This might be a bug in Agatha.

I’m hoping for the latter ;-) .

I added the new features in order to deal with problems I face in a production environment.
Agatha, however, is a totally different thing. We’re testing a framework/lib, not an app.
Apart from the fact that definitely something is going wrong somewhere, this test clearly exposes some weaknesses of the newly implemented features.
F.i. :
– Shrinking does not seem to produce the minimal fail case.
– Reporting is too confusing.

I will have to fix this first in order to be able to determine whether the bug is in QuickNet, in Agatha, or in the spec definition.

And that, my friends, gets me all excited.

Posted in Agatha, Hey Man Now You're Really Living, QuickNet | Leave a Comment »

The Children Are Walking Back From the Beach

Posted by kilfour on January 11, 2010

The last in this series of posts that quickly touches on the new features in the upcoming release.

Better support for inheritence in generators
It is now possible to define an ‘Ubergenerator’ like so :

GeneratorFor<MyBaseClass, MyDerivedClass>

And then in a class that has some property of the type MyBaseClass this generator would supply the right value, and more importantly ‘Shrinking’ would still work. The MyBaseClass could be abstract or whatever.

Taking this idea a little further a new ‘Meta’-Generator was introduced : the BaseClassGenerator.
Example of usage :

public abstract class Base { }

public class DerivedWithInteger : Base
{
    public int Integer { get; set; }
}

public class DerivedWithString : Base
{
    public string String { get; set; }
}

public class Bugger
{
    private int count = 0;
    public void Run(Base input)
    {
        DerivedWithInteger derived = input as DerivedWithInteger;
        if (derived != null && derived.Integer == 6)
            if (++count == 2)
                throw new Exception();
    }
}

public class BetterBaseClassGenerator : BaseClassGenerator<Base>
{
    public BetterBaseClassGenerator()
    {
        AddGenerator(new GeneratorFor<Base, DerivedWithInteger>());
        AddGenerator(new GeneratorFor<Base, DerivedWithString>());
    }
}

public class TheFirstTest : AcidTest
{
    private static Bugger bugger;

    public TheFirstTest() : base(5,500) { }

    public override void Setup()
    {
        bugger = new Bugger();
    }

    class BuggerTransition : MetaTransition<Base, Null>
    {
        public BuggerTransition()
        {
            Generator = new BetterBaseClassGenerator();
            Execute =
                input =>
                    {
                        bugger.Run(input);
                        return null;
                    };
        }
    }

    [SpecFor(typeof (BuggerTransition))]
    public Spec Func(Base input, Null output)
    {
        return new Spec(() => { });
    }
}

And this toy example results in this output :

Output from BuggerTransition Func:
  ----------------------------------------------------------
  BuggerTransition Func
  Falsifiable after 2 test(s), 365 Transition(s).
  --------------------Simplest Fail Case--------------------
  1 : Transition : BuggerTransition, Output : null
  Base
  Integer : 6

  2 : Transition : BuggerTransition, Output : null
  Base
  Integer : 6

  ----------------------------------------------------------

A contrived example, I know, it’s the one I used as a spike to get it to work. QuickNet is turning into _that_ kind of code. I’m not proud of the implementation, but I am proud of how it can be used. The main problem in keeping the implementation clean is in how it is practically impossible to write tests for it. If the user of the framework doesn’t have to jump through too many hoops I’m happy with the result these days, although I know how painfull adding a feature to the lib can be. Getting it mature enough to test itself would be a dream.

I know I am being, and have been, very concise in my explanations of the new features, but I’m still verifying that everything behaves as desired. Once that’s done I’ll release QuickNet 0.6 and update the wiki on google code, explaining things more thouroughly.

For those of you that wish to contribute, there’s always Paris, … I mean the trunk, and the Google Group.

F.i. recently (see the Google Group Discussions) somebody, who had some experience with QuickCheck, Pex, … i.e. somebody with experience in property based testing, displayed an interest in QuickNet and decided to include an example into a presentation of his. I (pro-)actively went looking for the source code and made some suggestions on how to improve the QuickNet test. The assumptions he made about the framework and that I hadn’t thought of, forced me to add some extra checks, improving the user experience. Exactly the kind of stuff I need.

As I said before, I truly believe property based testing is a revolutionary idea (albeit not a very new one), and if QuickNet doesn’t deliver some other lib will. I use this thing in production and am very willing to accept any improvement that can be made.

The first time QuickNet pointed out a bug, my myriad of unit tests, covering the code in question, couldn’t detect, I was ecstatic. I had been coding on my free time for quite a number of hours and suddenly it turned out this effort paid off.
It really kind of blows your mind when a simple idea/pattern turns out to be more clever than you are.
I’m sure a lot of QuickCheck users out there know what I’m talking about.

Posted in QuickNet | Leave a Comment »