Friday, January 14, 2011

Rhino ESB for Dummies

This will document my “dummy” experience. I’ve been using NServiceBus for a while, but the license model changed out from under us so we’ve been investigating alternatives. A fellow in the office pointed us to Rhino ESB (he had pointed us to NServiceBus earlier).

Immediate Impressions

C:\Source\external\rhino-esb>powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Source\external\rhino-esb> .\psake.ps1 .\default.ps1
So, that appears to be all there is to it.

Upsides/Downsides

  • We’ve been making extensive use of Autofac as our container and Rhino has a predisposition for Castle Windsor. We’ll just use Windsor in the handlers for now and leave other areas (i.e. ASP.NET MVC 2) to use Autofac. I’m told that a container agnostic version of Rhino ESB is in the works.
  • Testing with NServiceBus was pretty straightforward as it provided mocks of our handlers and also setup the expect portions. I’m told that with Rhino Mocks we don’t need to worry about that and we just test our handler’s independently from the ‘service bus’.
  • No more need to adorn our message classes with IMessage.
UPDATE

I had to enter Set-ExecutionPolicy Unrestricted to run the psake script.

Wednesday, January 5, 2011

Separating Integration Tests from Unit Tests with xUnit

How often do you find that you’ve written a very useful test that crosses a process boundary, or makes changes to another system (file system, database) which by definition of a Unit Test shouldn’t be tested as part of your code coverage, but its highly useful.

Here are some attributes that you can use to mark up your (these are inspired by several other posts out there on the internet).

public sealed class IntegrationFactAttribute : FactAttribute
{
protected override IEnumerable EnumerateTestCommands(IMethodInfo method)
{
var attrs = method.MethodInfo.GetCustomAttributes(typeof(IntegrationAttribute), true).Cast();

if (Skip == null && attrs.Any(x => x.ShouldRunTest))
{
return base.EnumerateTestCommands(method);
}

return new[] { new SkipCommand(method, method.Name, "Integration method skipped") };
}
}
The abstract class below defines a simple Boolean property in which we can define the circumstances under which we want to execute the method.
public abstract class IntegrationAttribute : Attribute
{
public abstract bool ShouldRunTest { get; }
}
Below is an example class that tests to see if there is a debugger attached, and if so, it returns true for the ‘ShouldRunTest’ property. When this is evaluated in the EnumerateTestCommands in the IntegrationFactAttribute it will run the marked test method.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class WhenInDebuggerAttribute : IntegrationAttribute
{
public override bool ShouldRunTest
{
get { return System.Diagnostics.Debugger.IsAttached; }
}
}
Example using both attributes. This test which tests through to the database will only be run if it was executing inside of the debugger. If you are using Resharper or TestDriven.NET then you can execute the test while debugging but no longer need to worry need to be concerned that your continuous build environment will be testing code depends on a shared resource.
[IntegrationFact, WhenInDebugger]
public void CheckLiveRepositoryOnClinicianByOrganizationID()
{
const int idToMatch = 1;

// Create LS2 Repository
var repository = CreateRepository();

// Use a Specification to retrieve results
var clinicians = repository.Find(ClinicianSpecs.ByOrganizationID(idToMatch)).ToList();

// Assert valid
clinicians.Should().Not.Be.Null();
}
Note that I’m using the Should Assertion Library instead of the Assert.NotNull(). If you’re interested in more behavior driven development then this library makes your assertions read well.

Sunday, July 18, 2010

CVS, CruiseControl.NET and mysterious errors

After many days of head scratching and trying to come up with the correct google phrase to find a solution to the infamous:
cvs checkout: move away xxx; it is in the way
I finally determined the cause and was then able to identify a post with a solution:

Switching CVS servers easily

It turns out that this error has two likely causes:

  • If you're on Windows then someone might have the same file named with different case. Our CVS server is hosted on a linux platform so that it is possible to store ThisFile.txt and THISFILE.TXT in the same directory. Upon cvs update, windows will try to overwrite the file and complain that the file is already there. This can be more evil if it was at the directory level!
  • The second cause, and the one that I wasn't aware of, is that the value contained in the hidden CVS\Root file must be the same as the CVSROOT value of your client (or environment variable if your client is aware of the %CVSROOT% variable.)


Our problem was that we routinely use multiple clients to access CVS (command line, TortoiseCVS, WinCVS and finally CC.NET as well). Whenever I saw this problem, I would usually log in to the build server and delete the offending directory. That usually works. However, since we had a different CVSROOT value specified in the TortoiseCVS than the one in the CC.NET configuration file, it was possible that the value stored in CVS\Root would be different.

The key is either to make sure that you're CVSROOT file is always the same one, or alternatively, if you suspect this is the issue, then check the CVS\Root file to make sure that it matches up to the one your client is using.

UPDATE

After several attempts I was able to identify yet another cause for the 'cvs checkout: move away xxx; it is in the way' message. Check to make sure that any 'Entries.log' files were removed by your build scripts. In our case we use NAnt and we had a clean target which removed all *.log files and in addition we had specifically ignored the default excludes. The default excludes has a pattern to exclude the hidden CVS directory and any contents of that directory.

So to sum it up, just keep in mind that the single 'cvs checkout: move away xxx; it is in the way' can occur for any of the following reasons:
  1. $CVSROOT (or %CVSROOT%) is different than the value found in the CVS/Root directory. This could also be an issue if you supply the -d {cvsroot} option to the cvs executable.
  2. If your CVS server is located on a case sensitive O/S (Linux for example) and your client is on a case insensitive O/S (Windows), then make sure some has not committed a similarly named directory or file.
  3. Check the Entries and Entries.log files in the hidden CVS directory to make sure that it matches what files are in the corresponding directory. If they don't then it's possible some other process has removed the Entries.log file!

Thursday, April 29, 2010

Netbook and Windows Anytime Upgrade

I mentioned in a previous post that I struggled with how to access my creative juices while on vacation while not toting around an extra ten pounds of gear. I settled on a HP Mini 210, it's a little underpowered, but it weighs in around 3 pounds which isn't too bad as extra weight. It has 1 GB memory (nothing like my Dell Quad Core with 8GB!) and it is limited in disk space. I left my 500GB hard drive at home as I didn't want to cart that around as well. I've got quite a bit of things on this laptop even so.

  • Visual Studio 2010
  • SQL Server 2008 Express
  • Mercurial plus all of the devs tools I could think of - WinMerge, e, nant... I did miss TestDriven.NET, so I'll have to figure how that works into writing code.

After rushing to install everything I thought I'd need I decided at 2.30 am (with a 4.45 wake up forthcoming!) to try an upgrade from Starter edition to Home Professional. Don't be fooled, it says that the upgrade will take 10 minutes or so, unless there are Windows Updates! Doh! I think I finished out with a workable system again more than an hour later! I recommend if you're going to do an Anytime Upgrade on your system to do it with time to spare. I was wondering if I had bricked my new system right before the trip! It all worked out and went smoothly, but not without some minutes of stress in the wee hours.

HG Walkabout

Just prior to taking a three week vacation to Europe I splurged and purchased a Netbook (HP Mini 210-1032CL). I don't recommend doing this at the very last minute, but sometimes...

I have a copy of O'Reilly's Mercurial book and I spent time looking around for a digital copy of the book. I didn't find it on the 'net. I finally located it while I was sitting at the gate in SFO in the TortoiseHG docs directory *sweet*!

I discovered that it was quite easy to use the great 'hg help' command. I found out that first I need to remove the chaff from CVS (CVS artifacts.) I also was scratching my head for a bit trying to figure out how to ignore files that I did not want added to the repository.

Directly from the hg help init:

hg init [-e CMD] [--remotecmd CMD] [DEST]

create a new repository in the given directory

    Initialize a new repository in the given directory. If the given directory
    does not exist, it will be created.

    If no directory is given, the current directory is used.

    It is possible to specify an "ssh://" URL as the destination. See 'hg help
    urls' for more information.

Now that I had a repository built I knew that I needed to tell Mercurial what files were in it. I forged ahead and did a 'hg add' only to discover that I'd inadvertently added all of the CVS directories as well as the files that typically end up in our .cvsignore files. So that lead me to discover both 'hg remove' and 'hg forget', all three commands are described below:

hg add [OPTION]... [FILE]...

add the specified files on the next commit

    Schedule files to be version controlled and added to the repository.

    The files will be added to the repository at the next commit. To undo an
    add before that, see hg forget.

    If no names are given, add all files to the repository.

hg remove [OPTION]... FILE...

aliases: rm

remove the specified files on the next commit

    Schedule the indicated files for removal from the repository.

    This only removes files from the current branch, not from the entire
    project history. -A/--after can be used to remove only files that have
    already been deleted, -f/--force can be used to force deletion, and -Af
    can be used to remove files from the next revision without deleting them
    from the working directory.

hg forget [OPTION]... FILE...

forget the specified files on the next commit

    Mark the specified files so they will no longer be tracked after the next
    commit.

    This only removes files from the current branch, not from the entire
    project history, and it does not delete them from the working directory.

To undo a forget before the next commit, see hg add.
I think I've figured out that there are multiple ways to save yourself with Mercurial. I thought I had to do a 'hg remove' and a 'hg forget', but I believe that could have been avoided by supplying an option to the remove command - 'hg remove --force' which says remove (and delete) file even if added or modified.

Sidebar: I'm flying at 573mph ground speed at 35000 feet somewhere over Lake Michigan right now. Yes I know in the first paragraph I said that I was sitting in the San Francisco airport at the gate, but I was interrupted when I had to get on the plane, a lunch/dinner and subsequent knap. My clock says its just after midnight in London, I'm not ready to give into the sleep and change time zones just yet :)

Using e-TextEditor now and you get the Mercurial icons in the Project viewer. Nice!

snap-20100429-0029

Friday, April 23, 2010

IIS7 CryptographicException - The system cannot find the file specified.

I found a strange error while getting my application to run on Server 2008 R2. Below is a description of a similar problem and the resolution. Its duplicated here in case the other blog disappears in the future.

From blog - MaeSitus-Sitecore

CryptographicException file not found in Sitecore
Today I came across issue with CryptographicException file not found in Sitecore. See below

Server Error in '/' Application.

THE SYSTEM CANNOT FIND THE FILE SPECIFIED.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Security.Cryptography.CryptographicException: The system cannot find the file specified.


Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.


Stack Trace:

[CryptographicException: The system cannot find the file specified. ] System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer) +7715070 System.Security.Cryptography.DSACryptoServiceProvider.ImportParameters(DSAParameters parameters) +258 System.Security.Cryptography.DSA.FromXmlString(String xmlString) +501 Sitecore.Nexus.Licensing.NexusLicenseApi. (String xml, Guid instance) +138 Sitecore.Nexus.Licensing.NexusLicenseApi.GetSnapShot(Guid instance) +764 Sitecore.SecurityModel.License.LicenseManager.GetSnapshotData(Guid instance) +59 Sitecore.SecurityModel.License.LicenseManager.UpdateSnapshot() +103 Sitecore.SecurityModel.License.LicenseManager.Initialize() +8 Sitecore.Nexus.Web.HttpModule.Application_Start() +76 Sitecore.Nexus.Web.HttpModule.Init(HttpApplication app) +435 System.Web.HttpApplication.InitModulesCommon() +65 System.Web.HttpApplication.InitModules() +43 System.Web.HttpApplication.InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) +729 System.Web.HttpApplicationFactory.GetNormalApplicationInstance(HttpContext context) +298 System.Web.HttpApplicationFactory.GetApplicationInstance(HttpContext context) +107 System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr) +289


Version Information: Microsoft .NET Framework Version:2.0.50727.4927; ASP.NET Version:2.0.50727.4927

After consulting with my colleague, the solution is to do with IIS settings.

To resolve this,

1. go to IIS Manager
2. go to the application pool instance
3. click advanced settings
4. Under Process model, set Load User Profile to true

Saturday, December 12, 2009

Getting Fluent NHibernate running under Windows 7

I just finished wiping my development box and going from Vista to Windows 7. Overall it wasn’t too bad. I did encounter two problems trying to get our unit tests (xUnit) running again.

The first problem was that I had copied the Source directory from my Vista install to the Windows 7 install. Almost everything was good until I run two tests that were getting a ReflectionTypeLoadException. That exception tells you to take a look at the LoaderExceptions property. When I did that I noticed that it was complaining about the fact that some of the DLLs that were being loaded (specifically FluentNHibernate.dll) was from a different machine. To fix this, I removed the copied Libraries folder and updated again from CVS. That problem then went away.

Friday, April 3, 2009

Enabling syntax highlighting in your Blogger Blog

This is a test of the SyntaxHighlighter code snippet formatter.

public void Foo(string bar, int baz)
{
if (YouSeeThis())
{
Console.WriteLine("It worked!");
}
}
For the above to work you need to have the following code:

<script src='http://[yourhostname]/scripts/shCore.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushGroovy.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushScala.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushVb.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushXml.js' type='text/javascript'/>
<link href='http://[yourhostname]/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://[yourhostname]/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script class='javascript'>
//<![CDATA[
function FindTagsByName(container, name, Tag){
var elements = document.getElementsByTagName(Tag);
for (var i = 0; i < elements.length; i++){
if (elements[i].getAttribute("name") == name){
container.push(elements[i]);
}
}
}
var elements = [];
FindTagsByName(elements, 'code', 'pre');
FindTagsByName(elements, 'code', 'textarea');

for(var i=0; i < elements.length; i++) {
if(elements[i].nodeName.toUpperCase() == 'TEXTAREA') {
var childNode = elements[i].childNodes[0];
var newNode = document.createTextNode(childNode.nodeValue
.replace(/<br\s*\/?>/gi,'\n'));
elements[i].replaceChild(newNode, childNode);
}
else if(elements[i].nodeName.toUpperCase() == 'PRE') {
brs = elements[i].getElementsByTagName('br');
for(var j = 0, brLength = brs.length; j < brLength; j++) {
var newNode = document.createTextNode("\n");
elements[i].replaceChild(newNode, brs[0]);
}
}
}
SyntaxHighlighter.all();
//]]>
</script>

Thanks go to the following for getting this working:

Tips for software engineer: Using SyntaxHighlighter on BLOGGER

Test of SyntaxHighlighter

This is a test of the SyntaxHighlighter code snippet formatter.

public void Foo(string bar, int baz)
{
if (YouSeeThis())
{
Console.WriteLine("It worked!");
}
}
For the above to work you need to have the following code:

<script src='http://[yourhostname]/scripts/shCore.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushGroovy.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushScala.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushVb.js' type='text/javascript'/>
<script src='http://[yourhostname]/scripts/shBrushXml.js' type='text/javascript'/>
<link href='http://[yourhostname]/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://[yourhostname]/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script class='javascript'>
//<![CDATA[
function FindTagsByName(container, name, Tag){
var elements = document.getElementsByTagName(Tag);
for (var i = 0; i < elements.length; i++){
if (elements[i].getAttribute("name") == name){
container.push(elements[i]);
}
}
}
var elements = [];
FindTagsByName(elements, 'code', 'pre');
FindTagsByName(elements, 'code', 'textarea');

for(var i=0; i < elements.length; i++) {
if(elements[i].nodeName.toUpperCase() == 'TEXTAREA') {
var childNode = elements[i].childNodes[0];
var newNode = document.createTextNode(childNode.nodeValue
.replace(/<br\s*\/?>/gi,'\n'));
elements[i].replaceChild(newNode, childNode);
}
else if(elements[i].nodeName.toUpperCase() == 'PRE') {
brs = elements[i].getElementsByTagName('br');
for(var j = 0, brLength = brs.length; j < brLength; j++) {
var newNode = document.createTextNode("\n");
elements[i].replaceChild(newNode, brs[0]);
}
}
}
SyntaxHighlighter.all();
//]]>
</script>


Thanks go to the following for getting this working:

http://developertips.blogspot.com/2007/08/syntaxhighlighter-on-blogger.html

Thursday, April 2, 2009

NAnt/MSBuild ClickOnce publishing ‘publish.htm’

The secret to this is specifying in the properties passed to MSBuild either directly or via NAnt. There are two specific properties you need to get the publish.htm published:

CreateWebPageOnPublish true
WebPage publish.htm

You can specify these as command line parameters as follows:

/property:CreateWebPageOnPublish=true

/property:WebPage=publish.htm

Once you are passing these parameters to MSBUILD it will move your publish.htm up to your publish location. Note, that there are many more properties that you can specify in the same way. Take a look inside of your .csproj file Property/PropertyGroup for a list of the values. You can experiment with the GUI inside of Visual Studio and then see how the values change so you can tweak your MSBuild/NAnt script accordingly.

UPDATE: It turns out I'm wrong on this. The above solution does not auto-generate a publish.htm. More to follow.


Technorati Tags: ,,

Adding your own Pre-requisite installer to a ClickOnce app

STEPS

  • Download and install the Bootstrap Manifest Generator
  • Start a New Project and choose Package Manifest
  • Give your project a name and code (these can be the same)
  • Click on Project/Add Install File and choose your installer
  • Give a Display Name in the Install File settings
  • Build your project with Project/Build
  • On Vista this will ignore any properties about where it creates the file. Look for it in \Users\{username}\Documents\{Project Name}
  • Copy this to your packages location. Usually here: C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\

You should now be able to choose this in your Project Properties\Publish\Prerequisites list.

LINKS

Bootstrap Manifest Generator

Customising your ClickOnce deployment

Technorati Tags: ,,

Monday, March 16, 2009

Is your application ready for deployment?

So, you’ve coded like a banshee for 7 weeks straight, listened to your manager badger you about “sprint” this, “agile” that, “can you tell me when its really going to be ready to install at the customer’s site?

Well, before you go there, you should run through a pre-deployment checklist. Here’s one that I’ve come up with after going through the motions on a number of occasions.

Build and CI

If you’re not using NAnt or MSBUILD scripts then start right now! The first thing you should do when you’re building out your new project source tree is to get it committed to your version control system and then make sure it will be built by your Continuous Integration server.

By integrating constantly you’ll know when the changes you are making are going to break what someone else is working on. I hear talking about changes they’ve held on to for weeks before attempting to commit them to version control out of fear of breaking the build. Face it, the days of Big Bang check-ins and waiting for the nightly build are light years behind us now.  To move fast, we have to identify the risks before it hits the deadline.

DO YOU KNOW YOUR INSTALLER?

How many times have you been burned by this:

Larry - You know, file fizzbin.dll is missing from the build.

Joe – Did you add it to the installer?

Larry – We have an installer?

Alright, I played that up a bit, but you catch my drift. Installers can be quite complicated beasties. In my team, I adopted a stripped down open source installer (Inno Setup). Sure, it doesn’t have all of the bells and whistles of some of the big name installers, but its damn simple. I combined that with something that we use every day (NAnt) and now we’ve got a half-way decent installer pattern.

If you write code, you should understand how your bits (DLLs, XML files, web files) get to where they need to go. Here are some things you should ask yourself about any file that needs to go into the installer:

  1. Is this a DLL? Is it already part of one of the projects whose output will be installed to the ‘bin’ directory, or is this something new?
  2. Is this a Configuration File? Should the values be preserved between installations/upgrades? How should I take care of values that are Added/Removed/Updated? Which services will access this file? Will the correct permissions be assigned to the file/directory? Does this file need to survive an uninstall?
  3. Is this a web virtual? Is there anything special that needs to be done to the virtual in the IIS Configuration? Does it need to be locked down?
  4. Is this a Windows Service? Have you followed the same naming conventions for the name, the .exe, the log file? The three of these should be similar in name so its easier for support to identify which service is associated with which executable and log file.
  5. Logging? Did you make sure that you are logging to the Log directory?
  6. Are there files that you no longer want to be included?

HARD CODED VALUES

OK, nobody does this anymore. We all have all the time we need to isolate the hard coded strings and have already moved them to configuration files or they reside inside of a resource file.

Now really, we all do this in our rush to quickly prototype the code we’ve got to get finished for the upcoming trade show or GA release of version 5.8. But really, you need to identify and move these values first to say a common access class and from there to a configuration file.

Check your configuration files

So all the code is done, you’ve made it through your xUnit tests and QA is saying that the risks are acceptable to deploy this app. And yet the application most likely has never been deployed to an environment similar to your (or your customer’s) production environment. So, now comes the hard part, we have to adjust all those configuration settings (URLs, passwords, connection strings, file paths, frequency values, etc). Sure that’s great. I know where all of those are. OK, but how many of those values are REPEATED in your configuration files? You know like, IP addresses to servers, account names, etc.

For those of us that enjoy using Resharper you become smoking ninja’s with your ability to keep your code DRY. But what about the ‘data’ in your configurations? How many connection strings do you reference? Do you have URL’s for services that contain the same server name over and over again?

If we apply the DRY principle to our configuration files as well as our code, then its far easier to create instructions on which values to change for production deployment, or better yet to automate or provide tools to safely adjust these values (and even better yet, make sure that the values that are in the configuration files will work when the service/application is running!)

Database connection string

Hey, you’ve tested this, you know it works. Works for me! Every time. Recently we had a “head scratching” moment with our newly arrived QA engineer. She’d built out a VM and installed our software on it to discover that one of our applications didn’t run at all after installation. My team looked at it and said, “Hmmm… that can’t be happening. It works everywhere else. Let’s rebuild your server and install again.” So, after rebuilding the server it worked fine and dandy.

Some weeks later, I stumbled upon a hard coded connection string in the previously mentioned application and had my “AH-HA” moment, “So this is why it failed!”. If you’ve been reading above then we should have reviewed this and identified that first, there was a hard coded string containing a connection string and second it was duplicated.

So, what’s the lesson here? Well, the deployment environment should be taken into account even when a developer is writing and testing his/her own code. In this particular case, we would have recognized that the connection string was pointed to localhost\sqlexpress and it needed to honor what has in our connections.config file.

mock me? NO MOCK YOU!

OK, funny! In today’s world we need to be able to provide “fake” interfaces or simulate external services. The only way to make sure that you’re really ready for the vagaries of what you’ll find out in the production wilderness is to mock the different services that you connect to. The benefits will allow you to have confidence that the application you’ve written will stand up when it encounters unexpected results.

This is really a follow on to TDD. Test driven development actually leads to building out mocked interfaces.

Naming Conventions

If you are writing an application for a company and there is more than one application you’ll want to follow similar patterns when naming and identifying your application. Things to keep in mind:

  • Keep track of the ports that you use if you use WCF services, proprietary listeners, etc. Support and the customer will want to know if your application needs to have inbound or outbound access on specific ports. Also, when it comes to TCP/IP ports, you really should check for a port range that is not used by other applications. Anymore, that is up in the 38,000+ range and anything below 10,000 should be reviewed carefully.
  • Name your virtuals so they are consistent, easy to type and make sense for their intended purpose.  Again you might have a common prefix for your application suite, or common suffixes for types of applications.
  • Windows services are a big pet peeve of mine. Make sure you’ve made sure that you have a consistent Service Name, Display Name and you’ve taken some time to write a decent 10-20 word description of what the service is.
  • Finally, make sure that your DLLs have the appropriate information in the ApplicationInfo files. The Company Name, Copyright, Product Name and version should all be there and be current. You can accomplish this by hand or by incorporating some steps into your build file.

Last Thoughts

This is entirely too long and I’ve most likely lost a lot of people by now. But the last step you should think through is about what you’ve done to your application during your own testing. Do you normally change values in the configuration files to debug settings? Have you deployed with the Log Level set to Debug? Have left the web.config with the debug turned on? Are you including your symbol files?

There’s a lot more of these types of questions that you should think about when you release your application into the wild. Some of this is about your ability to control your ADD (attention deficit disorder or bright shiny object chasing) and concentrate for an hour or two on the questions and topics I’ve brought up here.

Now Playing - Tom Scott - Reed My Lips - Saxappella

Thursday, March 12, 2009

xUnit tests and threads

OK, it goes against the idea of unit testing a little bit, but sometimes you can only get some code to fail by having another thread attempt to change a shared value. In my case, I hade a piece of code like this:

var thread = new Thread(() => Assert.NotNull(null));
thread.Start();
thread.Join();



This block of code starts a thread and checks that the value, null, is not null. The xUnit Assert will throw an exception once the thread is running. What happens to uncaught exceptions in threads? In the old 1.0 and 1.1 days the thread would terminate silently. It turns out that this is what this code will do if you attempt to run it in TestDriven.Net. In other words, the test will not fail!



To get this to work the Assert needs to be surrounded by a try/catch block.




var thread = new Thread(SafeAssertBlock);
thread.Start();
thread.Join();

...

public void SafeAssertBlock() {
try {
Assert.NotNull(null);
}
catch (Exception ex) {
// log the exception or pass it back to the owning thread...
}
}



What I eventually settled on was a form like this.




private Exception ThreadsException { get; set; }

...

ExceptionCatcher(() => Assert.Null(ContextScope<string>.GetInstance(ScopeKey)));

...

private void ExceptionCatcher(Action action)
{
try
{
ThreadsException = null;
action();
}
catch (Exception ex)
{
Logger.Error(ex.GetBaseException().Message);
ThreadsException = ex;
}
}



This passes the Assertion block into the ExceptionCatcher, which in turn sets a variable named ThreadsException back in the main thread. If ThreadsException is not null after we make the call then we can log that exception or re-throw it.



So, what happens to xUnit if you attempt to test code that throws an exception in a thread? It turns out that each test is run in its own AppDomain and when the exception is thrown there is an attempt to Serialize the exception. I'm not totally sure, but I believe that communication between AppDomains uses .NET Remoting. In any case, you get an ugly Marshalling exception down in the guts. This may have been helped if the xUnit guys had decided to have their Exception types be Serializable and have the appropriate serialization constructors. Perhaps in a later release?

Thread-specific data and the FreeNamedDataSlot function

First a bit of “context” setting before we proceed. If you’ve ever wanted to store data that is local to a single thread, you have three alternatives depending on your environment. If you’re only inside of a HTTP Web Request, you are in luck as you can set data into the HttpContext.Current.Items and its good for the duration of that web request.

If you happen to be writing any other type of application (Console, Windows Forms, Windows Service, etc…) then you have two alternatives. The easiest is to make a field with the ThreadStaticAttribute. You use this on a static field. With this attribute each thread has its own version of the field. That’s pretty easy!

If you want a little more control (or headaches) then you can use the Thread.GetNamedDataSlot and the Thread.GetData/Thread.SetData methods. What do all these do? Well, GetNamedDataSlot looks for a data slot on the current thread with the name that you pass to the method. If no slot is found it lazily instantiates one for you. The value returned is used as an argument to the GetData and the SetData methods, in other words your getter and setter for accessing thread local data.

BEWARE: There is another static method named FreeNamedDataSlot which you should use with extreme caution or not at all. This will free all of the data slots from each and every thread! The only time this makes sense to use is when you are absolutely sure that there are no threads running that are making use of the named slot you are about to free.

Technorati Tags: ,

Friday, March 6, 2009

Preview of Pioneer Connectivity Framework

Pioneer DebuggerThere have been rumors of what I was working on while in China. Since the first days of the Network I’ve imagined that we would have an agent that could be deployed to environments and be able to perform relatively simply operations.

The Pioneer Agent Connectivity Framework is the realization of this. To the right you see an example of the debugger running a script.

OK, but what is the Pioneer Connectivity Framework and what can we do with it? The Framework consists of the following components: a runtime with its own DSL (tokenizer, parser and interpreter that runs inside of the .NET 3.5), a Windows Service with installer to allow the runtime to be deployed on other computers, an interactive debugger to enable development, testing and diagnosing issues with the framework, connectivity to the CIQ Network, connectivity to any ADO.NET based database, a timer subsystem to allow for timed operations, and finally a file watching subsystem to watch folders for changed files. Phew! That was a mouthful.

OK, but why a new language on top of all the rest of this? Well, I’ve seen so many instances where we’ve deployed applications only to have to quickly act on an escalation to solve problems at customer sites. We’ve worked around a lot of deployment issues by isolating query files, but we’ve not extended this to the other aspects of our programming. With a small, light-weight language --  a domain specific language --  it will be possible to stitch together applications using a minimal amount of code.

Another possibility will be to deploy the agent without any of its application specific knowledge, this can be downloaded later by sending an event via the Network to obtain the latest code based on the environment and appropriate version.

Keywords

  • if, then, else – conditional statement
  • event – a way to access the event properties inside of a subscribe, timer and watch event definition. An example of this is event(‘FullPath’) in a watch definition will return the path to the file that was changed/deleted/created.
  • true/false – boolean constants
  • func – a function definition. There are no signatures to the functions similar to JavaScript. A function and a procedure are defined by whether they return a value.
  • include – inclusion of other pioneer script files
  • invoke – a way to call into the .NET BCL
  • namespace – able to mark function and variable definitions in different namespaces
  • null – the null constant
  • return – the ability to return from a function and/or return a value from a function.
  • start/stop – mechanism to start and stop previously defined timers
  • subscribe – define a subscription to a received network event/network document
  • timer – define a new timer that expires at a definite time, a relative time or is recurring
  • using – a way to define a namespace that should be searched when calling functions or referencing variables
  • watch – define a folder watcher
  • while, do, break – a looping statement
  • end – the end of a block (if, while, func and namespace)
  • var – the definition of a variable

The language is loosely typed similar to JavaScript. It is not an object language so it is not possible to create new types, however, it is possible to obtain references to .NET types and pass those to invoke() calls.

The implicit types are integers,  strings and lists.

Extensibility

Currently there are several ‘libraries’ that can be included. By creating an include file containing one or more invoke() statements and dropping a DLL into the Library folder, brand new functionality can be added without having to recompile and redistribute the framework.

What’s with the name?

I choose the name pioneer after the NASA Pioneer Program. The most famous of the spacecraft launched with this name were the Outer Solar System Missions, Pioneer 10 and 11, launched in March ‘72 and April ‘73 respectively. Pioneer 10 was the first probe to transit to Jupiter and its sister craft visited Jupiter and Saturn.

That’s great! But what does this name have to do with our work? The intent of the Connectivity Framework is to work out in “remote” regions away from the home planet and return data back to other services. The Pioneer program had launches that spanned over 20 years and the last successful telemetry with Pioneer 10 was April 2002, or 30 years after it was launched!

My hopes are that we’ll be able to apply the Pioneer Agent Framework to many of the fast moving connectivity projects that are the “bread and butter” of what we do here.

Last Words

All of this rides on top of the CIQ Network Foundation Libraries that provide ease of access to the Connect IQ Network as well as provide a stable platform for hosting Windows Services.

As more or less of a bonus, the editor/debugger recognizes the syntax and provides coloring.

 

Wednesday, February 25, 2009

IIS 7.0 and IHttpModules

When using IIS 7.0 an HttpModule needs to be configured in the

<system.webserver>
<modules>
<add type="HelloWorldModule" name="HelloWorldModule" />
</modules>
</system.webserver>



In addition to the section for IIS 6.0. This was troubling me for several days in China using Windows Vista until I checked the help file on IHttpModules!

Monday, September 8, 2008

ServiceController class, LINQ and Extension Methods

I ran across a nice article here on how to determine if a Windows Service is installed. I thought this would be better as an extension method. Previously, you would need to catch the InvalidOperationException and ignore it if you tried to use the ServiceController class to get information on a service that is not installed.

public static class ServiceControllerExtensions

{

    public static bool IsInstalled(this ServiceController controller, string serviceName)

    {

        return (from sc in ServiceController.GetServices()

                   where sc.ServiceName.EqualsIgnoreCase(serviceName)

                   select sc).Count() > 0;

    }

}

Sunday, September 7, 2008

Two birds with one stone (0xC0000005 failure for Google Chrome and SQLProfiler 2008)

In my previous blog entry on Google’s Chrome and Symantec’s EndPoint and provided a solution, which was to disable Chrome’s sandboxing. That’s really not a good idea. I noticed last week after installing SQL Server 2008 that it also was giving the same failure.

I went and re-googled for a solution and found a little further down in the article about using the —no-sandbox a link to Symantec’s site. You need to tweak a value in your Registry, reboot, and then both applications can run!

Here’s the link.

Thursday, September 4, 2008

Google's Chrome and Symantec's Endpoint Protection

I installed Google’s Chrome only to discover that our corporate anti-virus program was preventing its execution:

chrome-fail-a

And then you get the nice:

chrome-fail-b

Awww… reminds me of the old Sad Mac. I wonder if it plays the tones? Here’s a link to a temporary solution here.

chrome-fail-c


And now the love…

chrome-fail-d

Wednesday, September 3, 2008

Checking/Asserting for not null with a Generic Method

In my code I like to check parameters for entry conditions and assert where the parameters do not match with the contract for the method. I prefer to have a quick to type and one-line method to do so. My initial code to do this looked like the following:



public static void IsNotNull(object obj, string message)


{


    if (obj == null) throw new NullReferenceException(message);


}


That was great and it allowed me to check for null parameters inside of a method easily with some code that looks like this:



Assert.IsNotNull(account, "account was null");


Assert.IsNotNull(account != null, "account was null");


But notice that the signature of the method allows for the erroneous account != null to be used. To prevent this I changed the signature of method to:



public static void IsNotNull<T>(T obj, string message)


    where T : class


{


    if (obj == null) throw new NullReferenceException(message);


}


Now when you inadvertently put in a value type, it will correctly report this as an error. If you are new to Generics, then you might assume that you must identify the type. Either of the two usages below are equivalent thanks to the compiler inferring the type of the template ‘T’.


Assert.IsNotNull(account, "account was null");

Assert.IsNotNull<Account>(account, "account was null");


If you use Resharper, it will show you that you can safely remove the <Account> from the method call reporting that ‘Type argument specification is redundant.