Category: Umbraco

Second wind

Tweet

CodeGarden 2012 is just around the corner. I’m really excited about all the progression that the Umbraco project has made in the lead-up to this annual conference, and even more so by the prospects for the future with such a fantastic community pouring more and more time into helping it grow and develop.

Sadly though, for the first time in a few years, I won’t be there this year to take part first-hand, as it’s time to pass on the baton; I’m leaving the Umbraco HQ and taking another role.

Copyright ©2011 Doug Robar / Percipient Studios Great guys

The v5 project has been a fun, rewarding and challenging whirlwind over 2 years, and I’ve had the opportunity to meet incredibly clever people, make some great friends and even better memories of all the lively discussions we had.

During this time the Umbraco project itself has added a lot of great facets to its virtual character – for example the community site Our Umbraco relaunched with its public package repository at about the same time we began sketching out v5 itself. Although looking back it can often seem like one of the biggest strings to Umbraco’s bow has always been there, at the time we could have only hoped for a fraction of the upsurge in community-developed packages and the overwhelmingly helpful response of the community on its forums earning Karma for each helpful answer. The Karminator himself was so prevalent with packages and forum posts, he even ended up joining the company!

The v4 core too evolved quickly as a result of brilliant input from volunteers the world over – Razor support & its DynamicNode query style launched 6 months before the 5.0 CTP at CodeGarden 11, and got even better a few months later in 4.7 with the addition of many helper methods and improvements.

v5 has had some great input from volunteers too, and for that we remain incredibly grateful and wanted to do what we could to enable people to do more – adding tools such as the Progress page, with its data based on the YouTrack system we introduced as part of the v5 project.

When we presented v5 at various meetups, we mentioned we’d release 5.0 with a limited featureset and iterate over the following months on performance and features to get it supporting both small and large sites alike. The pace with which people wanted to push it further and faster than we could ship it was a testament to how vibrant the Umbraco ecosystem is. 5.2 Beta is now out in the hands of the many generous beta testers out there since we put it live on CodePlex last week, and is a big step forward with performance improvements, the beginnings of those all-important packaging tools by the stellar Matt Brailsford and Morten Christensen, and a really nice NodeSelector by Shannon Deminick, to help people build upon it. There’s also Contour 2, uCommerce 3 Beta, CMSImport.. tonnes of exciting stuff.

There’s a very interesting road ahead with great features of both v4 and v5 that I’m sure people will want combining, and it’s a fair bet all kinds of exciting prospects for the future are going to emerge. I know the community and core team will have a great time this summer and beyond, helping Umbraco realise its continually improving potential, and there are some really interesting sessions lined up for CG12.

Umbraco has been in my blood for years, since I was at Condé Nast and chose 4.0 to relaunch Wired. I subsequently was honoured to become a core contributor and discovered the many generous, fun and friendly people in its community. Although it’s time for me to move on during the daylight hours, I’ll be keeping up to date with Umbraco and hope to keep in touch with its many talented, friendly people and help out where I can for a long while yet.

Tweet

< Part One: Medium Trust primer

< Part Two: Devising a solution

Welcome to part three! We’re going to get some work done on unit testing in Medium Trust. If you want a primer, check out the previous posts. If you came here from there, well hello there recursive sentence!

First things first: the code for the below is all in MIT-licensed Umbraco 5! As you may / may not know, Umbraco 5 will be shipping both a set of Framework assemblies in addition to the core CMS when we release later this year. You can use it all for free, isn’t that grand?

For today, here’s a big unmissable link to download a preview zip of Umbraco.Framework.Testing. It’s MIT licensed and you can use this in your tests real easy. I’ve put it on my DropBox for now – I want to get this post out quick and go to the pub! into your hands! In an upcoming release we’ll make Framework & CMS downloads available as individual zips on CodePlex.

A quick note: I only came up with this last week, so (ironically) Umbraco 5 does not yet support Medium Trust as of today’s Alpha 3 – but the point is, we’ll now be able to use this technique to test our code in partial trust and make it happen reliably, and soon.

If you’d like to download all of the Umbraco codebase and see what other goodies are in our Framework and CMS, visit the repository at http://umbraco.codeplex.com/SourceControl/list/changesets.

To use this in your NUnit tests

I’ll walk through the code in another post, but if you want to jump straight into using this, download the zip, add a reference to Umbraco.Framework and Umbraco.Framework.Testing and you’re set.

Note: Because your tests will call NUnit’s Assert methods, NUnit itself needs to be able to run in partial trust. The zip contains a rebuild of NUnit.Framework.dll – the only change from 2.5.10.11092 is adding the AllowPartiallTrustedCallersAttribute to their assembly. Don’t believe me? Check out my fork at https://bitbucket.org/boxbinary/nunit-2.5x

Your test runner does not need to be rebuilt, so this is still compatible with NUnit’s runner, ReSharper’s runner, TeamCity etc.; only your own code referencing the NUnit Framework needs to reference the assembly.

Once you’ve added the references, let’s make a new fixture called MyCoolFixture. Set the fixture so it inherits from AbstractPartialTrustFixture, like so:

  1. using NUnit.Framework;
  2. using Umbraco.Framework.Testing.PartialTrust;
  3. namespace PartialTrustTest
  4. {
  5. [TestFixture]
  6. public class MyCoolFixture : AbstractPartialTrustFixture<MyCoolFixture>
  7. {
  8. public override void TestSetup()
  9. {
  10. return;
  11. }
  12. public override void TestTearDown()
  13. {
  14. return;
  15. }
  16. }
  17. }



Those TestSetup / TestTearDowns are there for you to put relevant code or just return if nothing’s needed.

Next let’s add a test or two:

  1. using System;
  2. using System.IO;
  3. using System.Runtime.Serialization.Formatters.Binary;
  4. using NUnit.Framework;
  5. using Umbraco.Framework.Testing.PartialTrust;
  6. namespace PartialTrustTest
  7. {
  8. [TestFixture]
  9. public class MyCoolFixture : AbstractPartialTrustFixture<MyCoolFixture>
  10. {
  11. [Test]
  12. public void ThisShouldWork()
  13. {
  14. // Arrange, Act
  15. Console.WriteLine(“Hiyaaa”);
  16. // Assert
  17. Assert.Pass(“Yeah this is a bit pedantic”);
  18. }
  19. [Test]
  20. public void ThisShouldNotWork()
  21. {
  22. // Arrange
  23. var myObject = DateTimeOffset.Now;
  24. // Act
  25. var myClone = Clone(myObject);
  26. // Assert
  27. Assert.Fail(“Wait, why did we get here?”);
  28. }
  29. ///
  30. /// Makes a copy from the object.
  31. /// Doesn’t copy the reference memory, only data.
  32. ///
  33. /// Type of the return object.
  34. /// Object to be copied.
  35. /// Returns the copied object.
  36. public static T Clone(T item)
  37. {
  38. if (item != null)
  39. {
  40. var formatter = new BinaryFormatter();
  41. var stream = new MemoryStream();
  42. formatter.Serialize(stream, item);
  43. stream.Seek(0, SeekOrigin.Begin);
  44. T result = (T)formatter.Deserialize(stream);
  45. stream.Close();
  46. return result;
  47. }
  48. else
  49. return default(T);
  50. }
  51. public override void TestSetup()
  52. {
  53. return;
  54. }
  55. public override void TestTearDown()
  56. {
  57. return;
  58. }
  59. }
  60. }



Nothing crazy, just a simple thing which should work and a simple thing which should not.

What, pray tell, should not? Well, that there Clone method is a really handy, and extremely common extension method that uses binary serialization to give you an exact copy of an object. FluentNHibernate uses it, in fact. But BinaryFormatter tries to set private members, and as we now know you can’t do that in Medium Trust!

So in theory that second test should fail. Let’s run that to see if all my promises are true:

image

Check .. that .. OUT!

SetUp : Umbraco.Framework.Testing.PartialTrust.PartialTrustTestException : Test ThisShouldNotWork fails in a partial trust environment, due to: Request for the permission of type ‘System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ failed.
—-> System.Security.SecurityException : Request for the permission of type ‘System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ failed.

So let’s fix the test so TestShouldFail() appropriately asserts that … it should fail:

  1. using System;
  2. using System.IO;
  3. using System.Runtime.Serialization.Formatters.Binary;
  4. using System.Security;
  5. using NUnit.Framework;
  6. using Umbraco.Framework.Testing.PartialTrust;
  7. namespace PartialTrustTest
  8. {
  9. [TestFixture]
  10. public class MyCoolFixture : AbstractPartialTrustFixture<MyCoolFixture>
  11. {
  12. [Test]
  13. public void ThisShouldWork()
  14. {
  15. // Arrange, Act
  16. Console.WriteLine(“Hiyaaa”);
  17. // Assert
  18. Assert.Pass(“Yeah this is a bit pedantic”);
  19. }
  20. [Test]
  21. public void ThisShouldNotWork()
  22. {
  23. // Arrange
  24. var myObject = DateTimeOffset.Now;
  25. // Act & Assert
  26. Assert.Throws<SecurityException>(() => Clone(myObject));
  27. }
  28. ///
  29. /// Makes a copy from the object.
  30. /// Doesn’t copy the reference memory, only data.
  31. ///
  32. /// Type of the return object.
  33. /// Object to be copied.
  34. /// Returns the copied object.
  35. public static T Clone(T item)
  36. {
  37. if (item != null)
  38. {
  39. var formatter = new BinaryFormatter();
  40. var stream = new MemoryStream();
  41. formatter.Serialize(stream, item);
  42. stream.Seek(0, SeekOrigin.Begin);
  43. T result = (T)formatter.Deserialize(stream);
  44. stream.Close();
  45. return result;
  46. }
  47. else
  48. return default(T);
  49. }
  50. public override void TestSetup()
  51. {
  52. return;
  53. }
  54. public override void TestTearDown()
  55. {
  56. return;
  57. }
  58. }
  59. }



And run it:

image

Woo!

But what if I want some tests to literally only test something in full-trust?

Well, you can of course have full-trust tests in a separate fixture. OR, you could decorate the test with the [TestOnlyInFullTrust] attribute I’ve added to our library. I’ll change the test again to demonstrate:

  1. [Test]
  2. public void ThisShouldNotWorkInFullTrust()
  3. {
  4. // Arrange
  5. var myObject = DateTimeOffset.Now;
  6. // Act & Assert
  7. Assert.Throws<SecurityException>(() => Clone(myObject));
  8. }
  9. [Test]
  10. [TestOnlyInFullTrust]
  11. public void ThisShouldWorkOnlyInFullTrust()
  12. {
  13. // Arrange
  14. var myObject = DateTimeOffset.Now;
  15. // Act & impicitly Assert
  16. Clone(myObject);
  17. }



And run:

image

Sweet!

So, there you have it. Easy partial-trust testing by inheriting from one base class.

In the next post – which may be next week, at this rate – I’ll walk through the code and explain how it works, for example if you’d like not to inherit from another class and just want to spin up an individual test yourself in a partial trust context individually.

We can also look into making this work with other testing frameworks, if you’re really nice.

Hope this helps you; let me know if so!