kenegozi.com

<form id='kenegozi' action='post'></form>

   
2010 Jan 27

Can you spot the bug?

tagged as: tools | Testing

Can you spot what will cause the following NUnit test not to run on TeamCity 4.5?

[TestFixture("Testing some cool things")]
public class CoolThingsFixture
{
	[Test]
	public void When_Do_Expect()
	{
		Assert.That(2, Is.EqualTo(1+1));
	}
}

 

hint: TeamCity list it with the ignored tests, yelling “No suitable constructor was found”

2010 Jan 20

What’s new in Monorail 2.0

During the long, long time it took to get from 1.0RC3 to 2.0, many things have changed, and many things were added. I probably won’t cover it all in this post, and I’ll probably forget a few things that I got so accustomed to use (I have always used trunk versions, even way before I became a committer).

 

 

Programmatic config

If (like me) you do not like putting stuff in config files that the operations team do not care about, you can now run a Monorail application without the Monorail section in the web.config file.

How?  you’d need your Global class to implement IMonoRailConfigurationEvents.

e.g. from many of my websites: (I’m configuring AspView as view-engine)

public void Configure(IMonoRailConfiguration configuration)
{
	configuration.ControllersConfig.AddAssembly(Assembly.GetExecutingAssembly());
	configuration.ViewEngineConfig.ViewPathRoot = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views");
	configuration.ViewEngineConfig.ViewEngines.Add(new ViewEngineInfo(typeof(AspViewEngine), false));
}

you can setup many optional things that way. e.g.:

// configue jquery as the validation engine
configuration.JSGeneratorConfiguration.AddLibrary("jquery-1.2.1", typeof (JQueryGenerator))
	.AddExtension(typeof (CommonJSExtension))
	.ElementGenerator
	.AddExtension(typeof (JQueryElementGenerator))
	.Done
	.BrowserValidatorIs(typeof (JQueryValidator))
	.SetAsDefault();
// configure url extensions
configuration.UrlConfig.UseExtensions = false;

delve into the intellisense on the IMonoRailConfiguration interface to find more

 

Return binders

The example speaks for itself:

public class State
{
    public string Code { get; set; }
}

[return: JSONReturnBinder]
public State[] GetStates()
{
    // fake code for the sake of the demonstration
    return new[] { new State { Code=“CA” }, new State { Code=“WA” } };
}

will render the JSON representation of the given State array

 

New routing engine

see http://www.castleproject.org/monorail/documentation/trunk/advanced/routing.html

and http://www.kenegozi.com/blog/2009/02/10/monorail-routing-and-the-homepage-routing-rule.aspx for setting a homepage route

 

RescueController

A rescue controller will take care of exceptions that have happened during an Action.

You’d create your rescue controller, implement IRescueController, inherit from SmartDispatcherController, and setup the rescue controller in the RescueAttribute on the regular controller.

see more here: http://www.castleproject.org/monorail/documentation/trunk/usersguide/rescues.html

 

AspView

The C# based view engine became a first class citizen in Monorail. There has been many improvements there during the time, which deserve a separate post perhaps. meanwhile you can look at the aspview tag on this blog: http://www.kenegozi.com/blog/Tag/aspview.aspx

 

I can’t think of more stuff right now, so ping me if I forgot anything.

2010 Jan 19

Monorail 2.0 – why the hell did it take so long

Being an Open Source project, with very good test coverage and a very active development, most users that actually run Castle bits in production were running off of trunk anyway.

 

The trunk is very stable, and the act of “release” should have simply been tagging any single commit to trunk as the 2.0 RTM.

 

However, we felt that we wanted some more stuff to justify a release – like updating the documentation, re-doing samples and Visual Studio integration packages, etc.

That lead us to a halt, as active committers did not use neither integrations nor samples, and same for the documentation. My personal stand was (and still is) that if someone wanted an official release so badly, then that one should contribute toward this, either with time and work, or with sponsorship money to buy this time and work.

 

No one did.

 

A few attempts at these parts was taken, but none concluded.

 

Meanwhile the project grew more and more, and parts of it became mandatory dependencies to various mainstream projects (such as NHibernate), while Windsor became more and more adopted as an IoC container of choice for many people.

Getting to a single point of approval across the board for the whole castle stack, without breaking third-party projects that depends on parts of Castle, became very difficult.

 

Breaking apart

In order to allow a manageable release process, the project was broken down to its parts. Now we have the four main projects, released on their on, with depending projects using compiled releases of the others.

The main projects are:

  • Core (de-facto including Dynamic Proxy) which is used on many other OSS projects
  • ActiveRecord
  • IoC stack (MicroKernel + Windsor)
  • Monorail

More details can be found on the projects page of castle’s website

 

An all-trunk builds can be retrieved with the aid of the horn-get project.

 

So why is Monorail last?

The reason is rather simple. Monorail depends on almost any other part of the stack. It even has subprojects such as ActiveRecord’s DataBinder (ARDataBind) which depends on ActiveRecord, and a WindsorIntegration project which depends on the IoC stack.

As a result we had to wait to get releases for all other projects.

 

What’s next?

I still have no idea. There are a few discussions going on about that (such as this one on the new roadmap), and you are all welcome to join the debates.

2010 Jan 17

AutoStubber to ease stub based unit tests

tagged as: c# | tools | Testing

Tired of setting up stubs for your class under test?

Tired of compile errors when you add one more dependency to a class?

The AutoStubber to the rescue.

Given

interface IServiceA
{
	string GetThis(long param);
}
interface IServiceB
{
	Do DoThat(string s);
}

class MyService
{
	public MyService(IServiceA a, IServiceB b) { ... }
	...
}

...

you can write;

var service = new AutoStubber.Create();
// Arrange
var theString = "whatever";
service.Stubs().Get.Stub(x=>x.GetThis(0).IgnoreArguments().Return(theString);

// Act
service.Execute();

// Assert
service.Stubs().Get.AssertWasCalled(x=>x.DoThat(theString);

 

The code for AutoStubber:

* Mind you – it’s not the prettiest, but it gets the job done

public class AutoStubber<T> where T : class
{
	static readonly Type TypeofT;
	static readonly ConstructorInfo Constructor;
	static readonly Type[] ParameterTypes;
	static readonly Dictionary<object, AutoStubber<T>> Instances = new Dictionary<object, AutoStubber<T>>();
	static AutoStubber()
	{
		TypeofT = typeof(T);
		Constructor = TypeofT.GetConstructors().OrderByDescending(ci => ci.GetParameters().Length).First();
		ParameterTypes = Constructor.GetParameters().Select(pi => pi.ParameterType).ToArray();
	}

	public static AutoStubber<T> GetStubberFor(T obj)
	{
		return Instances[obj];
	}

	bool _created;
	public T Create()
	{
		if (_created)
			throw new InvalidOperationException("Create can only be called once per AutoStubber");
		_created = true;
		return Instance;
	}

	readonly Dictionary<Type, object> _dependencies = new Dictionary<Type, object>();
	private T Instance { get; set; }
	public AutoStubber()
	{
		var parameters = new List<object>(ParameterTypes.Length);
		foreach (var parameterType in ParameterTypes)
		{
			var parameter = MockRepository.GenerateStub(parameterType);
			parameters.Add(parameter);
			_dependencies[parameterType] = parameter;
		}
		Instance = (T)Constructor.Invoke(parameters.ToArray());
		Instances[Instance] = this;
	}
	public TDependency Get<TDependency>()
	{
		return (TDependency)_dependencies[typeof(TDependency)];
	}
}
public static class AutoStubberExtensions
{
	public static AutoStubber<T> Stubs<T>(this T obj)
		where T : class
	{
		return AutoStubber<T>.GetStubberFor(obj);
	}
}

 

I know there is the AutoMockingContainer, and various other stuff out there, but this thing just was very natural to me, it uses a very simple API (do not need to keep reference to the Container), and took me less than an hour to knock off.

An enhancement I consider would be to allow setting pre-created values to some of the parameters. But meanwhile I did not happen to need it.

2010 Jan 17

Monorail 2.0 is out

After a long huge wait, finally Monorail 2.0 is out, get yours from  https://sourceforge.net/projects/castleproject/files/

 

HUGE thanks to John Simons and the rest of the Castle project committers, plus the rest of the good people that have supplied us with patches, bug fixes, and whatnot.

 

This move somewhat concludes the move from the old 1.0RC3 release from 2007, to the new releases of the Castle stack about two years afterwards.

 

I’m going to follow up with a couple of “what’s new”, “how-to upgrade” and “why the hell did it take so long” posts soon, so keep watching.

2010 Jan 5

NHibernate (and ActiveRecord’s) show_sql in web application

Looking into

When using an OR/M of any kind, it is quite worthwhile to be able to look at the SQL generated by the tool, for various reasons (such as tuning the DB, finding SELECT N+1 issues, and sheer curiosity).

 

Solution #1

One way of doing that is to start a profiler on the DB engine, but it has its downsides. For one, you would need a profiler tool, which is not always freely available. You might also not be able to access the DB engine with that kind of tool on various hosted environments.

 

In NHibernate’s configuration (and it is also exposed to Castle’s ActiveRecord users) you can set a property names “show_sql” to true. This will cause NHibernate to spit every SQL query, along with its parameters, onto the Console. Very useful when running Tests, but when running within a Web Application, you do not have access to the Console window, and can’t really see what is going on.

That also leads to another problem with using a profiler on the DB engine – you won’t be able to figure out which queries belong to which web request.

 

Solution #2

One comprehensive solution is to use the excellent tool from Oren Eini – NhProf. I will not cover this tool here; it does lots of great stuff, and can help your development cycle. However not everyone will be willing to pay the price for using it.

 

not to worry, I hereby offer you two more options, which gives you less options, but are good enough for the problem at hand, and are free.

 

Free solution #1

NHibernate is using log4net. it stores a *lot* of what it’s doing there. So, one can always setup a logger named “NHibernate.SQL” and get a hold of the queries. I do not cover log4net usage here. Google it up, and then set up the NHibernate.SQL logger.

You’d also want to setup a log4net variable for you to group the queries it gets by the web-request that needed them. You can do so by setting a property on log4net’s GlobalContext. e.g., in Application_BeginRequest:

log4net.GlobalContext.Properties["page_url"] = Context.Request.RawUrl + "|" + Guid.NewGuid();

then you’d set the log appender to write the page_url value, and you’ll be able to Group By it.

 

 

But this suck. You need to depend on log4net even if you do not want to, and setup that hack-ish global property, then read it from the log4net storage, and lots of complexities. wouldn’t it be great if you could simply got a hold of the Console’s output (or at least the NH parts of it?)

 

Free solution #2 – even simpler

The Console object allow you to set a custom Writer to its Out stream. Meaning, you can grab the Console’s output into an in memory string during a request, and then at the end of the request, grab all lines that starts with “NHibernate:” and you’re done:

 

on Application_BeginRequest:

var writer = new StringWriter();
Console.SetOut(writer);
Context.Items[SqlLogFilter.SQL_LOG_WRITER_KEY] = writer;

on Application_EndRequest:

var writer = HttpContext.Current.Items[SQL_LOG_WRITER_KEY] as StringWriter;
if (writer != null)
{
	var lines = writer.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
	var relevantLines =
		lines.Where(l => l.StartsWith("NHibernate") || l.Length > 0 && char.IsWhiteSpace(l[0])).ToArray()
		;
	var queries = string.Join(Environment.NewLine, relevantLines)
		.Split(new[] {"NHibernate:"}, StringSplitOptions.RemoveEmptyEntries)
		.Select(q => q.Trim());
	DoSomethingWith(queries);
}

 

within DoSomethingWith you can do whatever you like with the queries string collection

 

The more complete solution that I use, is taking advantage of a feature in Monorail’s AspView called ViewFilter (you can do this with ASP.NET’s output filter; look up HttpFilter. it’s not as clean, but workable). I create a filter that wrap the stuff that’s on the Application_EndRequest, turn the queries collection into a bunch of <pre> elements, and stick it within the view-engine’s output by simple string.Replace call, injecting these <pre> elements into a marker location in the markup.

I’d then use jQuery to make these <pre> elements visible when clicking somewhere secret on the screen.

 

The ViewFilter’s code (for reference):

public class SqlLogFilter : IViewFilter
{
	public static readonly string SQL_LOG_PLACEHOLDER = "SQL_LOG_PLACEHOLDER";
	public static readonly string SQL_LOG_WRITER_KEY = "SQL_LOG_WRITER_KEY";
	public string ApplyOn(string input)
	{
		var log = "";
		var writer = HttpContext.Current.Items[SQL_LOG_WRITER_KEY] as StringWriter;
		if (writer != null)
		{
			var lines = writer.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
			var relevantLines =
				lines.Where(l => l.StartsWith("NHibernate") || l.Length > 0 && char.IsWhiteSpace(l[0])).ToArray()
				;
			var queries = string.Join(Environment.NewLine, relevantLines)
				.Split(new[] {"NHibernate:"}, StringSplitOptions.RemoveEmptyEntries)
				.Select(q => q.Trim());
			log = queries
				.Select(q => "<pre>" + q + "</pre>")
				.Aggregate("", (q1, q2) => q1 + q2);
			var count = queries.Count();
			log = "<p>Queries: " + count + "</p>" + log;
		}
		return input.Replace(SQL_LOG_PLACEHOLDER, log);
	}
}
2010 Jan 1

Interlocked.Increment vs. lock – surprise surprise !

tagged as: c#

 

Problem at hand: an ID generator.

 

Like many other things, developers can be categorized into three types : *

  1. Does not know anything about concurrency issues. Might try to put lock(this) on a couple of code blocks, and hope it will help.
  2. Will throw lock(locker) statements where ever needed. Probably even use a ReaderWriteLock, or the Slim-er brother of his
  3. Will use lock-free constructs.

Now I am definitely not a concurrency guru like my teammates, however when I looked at a code for an ID generator that had

public int GetNextId() {
	lock(locker)
		return nextId++;
}

I immediately ran a git-checkout, changed that offending piece of code to

public int GetNextId() {
	return Interlocked.Increment(ref nextId) – 1;
}

And created a patch to send to the innocent owner of the code.

 

Smart heh? **

 

Then I thought that it won’t hurt to throw in a little proof for this amazing improvement.

Running 1000 calls to a GetNextId that was using a lock, took longer than calling the method using Interlocked !  Ah Ha – who’s the man?

 

Then I realised that a better test will be to run these 100 calls in parallel. That is after all the whole idea of a shared generator. Many threads might need to call it on the same time !

 

To my surprise, when asking for IDs in parallel, the interlocked construct was almost always slower, taking about 150% of the time the lock construct took on most runs (I tried this again and again, every time averaging 100 repeats).

 

Here’s a screenshot of the test run

interlocked vs lock

 

Code is here: https://gist.github.com/24b9012a49392c4e458b

 

After thinking about this a little, I think that I have an idea why this is happening, assuming my SpawnAndWait call is not entirely stupid (is it?)

 

So I call you my dear readers (most of which are way smarter than I am): what is your take on that? why did that happen? and would you have chosen lock or interlocked for an ID generator?

 

 

* apparently there’s at least one more type – smartass, and I’m there

** probably not

Subscribe

Statistics

399
861

The Lounge

Related Jobs

Related Books

search page | Blog's home | About me