February 2008 Blog Posts

Note to Conference Organizers: No More Box Lunches

OK, conference organizers, listen up:

You never get the box lunch right. Ever. Even when I was in grade school and you were the field trip organizer, you still never got it right.

Not everyone wants a pre-made meat sandwich, and not everyone who doesn't want meat is a vegetarian. Giving me the choice between soggy ham, limp turkey, or sprouts-on-rye isn't a choice. I might consider the ham, but you made it six hours ago, threw a really moist tomato on there, and wrapped it tight as you could in plastic, thereby ensuring the tomato juice permeates the bread and makes it entirely inedible.

Normally I wouldn't even complain, except you make the assumption everyone's going to eat the box lunch so you don't give me enough time to go somewhere and get something else - I eat your lunch, or I don't eat at all.

I am tired of eating a lunch that consists of an undersized apple, a small bag of greasy chips, and a cookie. I'm tired of having people with lower food standards look at me with that pathetic gaze and offer me another bag of greasy chips.

There are ways you can fix this and still keep your precious box lunch. Seriously.

  • Stop pre-making the sandwiches. Put the individually packaged ingredients for each sandwich in the box instead so I can assemble it myself, ensuring the bread isn't soggy and that I can entirely ignore that overripe tomato slice.
  • Offer the peanut butter and jelly option. Yeah, I know there are nut allergy people. I think they can figure out not to eat the PB&J.
  • Actually ask me what I want during conference registration. Not just a checkbox for the "vegetarian option," but actually a menu of four or five different things you could package up that maybe aren't sandwiches. Or let me select which ingredients go on my sandwich from the menu. It can't be that hard.
  • Buffet.  I get a plate, I walk down the line of available items, I pick up what I want. Wow.
  • Give me the money you'd have spent on the box lunch and enough time to hit the Burger King down the street. I'll come back happier and probably have change left over.

Conference organizers everywhere, heed my call! No more box lunches!

Template for Quick TypeMock Testing

I use Snippet Compiler quite a bit for quick one-off testing to see if something will work. Something I've been doing a lot lately is doing little quick checks to see how you'd do certain things with TypeMock Isolator. Snippet Compiler basically starts you out with a very thin framework for a console application and when you hit the "Start" button, it builds and runs the app. (You could do the same thing in Visual Studio, but Snippet Compiler is very lightweight and is totally built for this sort of experimentation.)

To make my TypeMock experimentation easier, I created a template for a basic console app that will launch a separate process with TypeMock enabled and run the NUnit console test runner. The template starts you out with an empty class and an empty test fixture, ready to populate with tests. When you run the app, the NUnit console runner will execute any test fixtures you put in the current assembly.

Snippet Compiler showing the TypeMock template.

Instructions on how to set up Snippet Compiler with this template are included. Basically, drop the template into your Snippet Compiler templates folder and add references to NUnit and TypeMock.

[Download TypeMockSnippetTemplate.zip]

It's Not OK To Skip The Standup

I participate in agile projects where we have a daily standup meeting to discuss high-level task status and roadblocks. I've noticed that many times I find there is a general feel that if the manager is out sick or can't otherwise make the daily standup that the team feels the standup is inherently canceled. When you run past their desks to find out where the missing members are to round them up, they're astonished: "What? We're still having a standup?"

Even if the manager is sick, even if one of the team members is out, yes, we are still having the standup. Why am I being so jerky about it? It's just a standup, right?

Jason Yip wrote about patterns of daily standup meetings to address the more holistic concerns about what should and shouldn't happen at a standup, so I won't re-hash that. Go read that article - I'll wait.

Good. Now let me tell you what the standup means to me and why I believe you shouldn't skip the standup.

  1. The standup is for the team, not the manager. It's great when the manager is there. And, yes, I know that in some projects you may not have a manager - it may be a peer scrummaster or some other leader. Regardless, the meeting isn't for that leader - it's for the team. You're not reporting your status to the manager, you're reporting to the team.
  2. The standup is a vestigial sign of discipline. In any team, it's important to know that your peers can meet commitments and that you can trust them to have your back. If you can't trust your team to make a simple standup, how can you trust that they're on top of any of the other tasks they're working on?

Now, it may be that the standup is at a bad time of day or that maybe it should be an every-other-day standup because there's not enough developing to warrant daily updates. It may be that there are too many people (or too many uninvolved people). There are a lot of potential problems with a standup's format, but those can be addressed - so address them. Again, the Yip article talks about some of these problems and potential solutions.

Regardless, it is not OK to skip the standup.

Xbox Content Successfully Re-licensed

This weekend [finally] brought an end to my latest struggles with Xbox Live digital rights management. I didn't get a call from Xbox Support, which I was told I would get, but I did notice that several folks on the Xbox Live forums, also in my situation, suddenly had their issues resolved without any notification, so I figured I'd give it a shot, too.

When Xbox Support has fixed you up, you'll be able to go into the Xbox Marketplace section of the dashboard, go to "Account Management," view your Download History, and select "Download Again" for each of the items you purchased. Doing that will automatically re-license the downloadable content to the console so the other gamers in your household can play it without you having to be logged in and you should be able to play it without having to sign into Xbox Live. You don't need to delete the content first - just select "Download Again" and the license for the content will transfer.

Took about 15 minutes to go through my history and download everything a second time, but after that, I was totally in business again. And, hey, it only took, what - four months?

What To Do If "Copy Local" Works In VS But Not MSBuild

I'm in the process of updating a bunch of old Visual Studio 2003 projects and solutions to, well, something a little newer. I found this odd behavior issue where there were some references that were marked to as "Copy Local" and that would work fine in a Visual Studio build, but when run from MSBuild, the references weren't getting copied correctly, which would cause unit tests to fail and such because things weren't where they should be.

A little Googling led me to this forum post which basically boils down to:

Go through your projects in a text editor and look for references with <Private> tags in them. Like <Private>True</Private> or <Private>False</Private>. "Private" is a synonym for "Copy Local." Somewhere in the actions MSBuild is taking to locate dependencies, it's finding your dependency somewhere else and deciding not to copy it.

What I ended up donig is going through each converted .csproj file and removing the <Private> tags manually. Rebuild, and everything works in both Visual Studio and MSBuild. Once you've got that working, you can go back in and update things to where you think they need to be, and when things start failing, you'll know exactly where the problem is.

Resolve Multiple Dependency Versions in Sandcastle Help File Builder

Anymore, if you want to generate documentation, you're using Sandcastle along with, most likely, some community-generated wrapper for it so you're not manually executing the bajillion steps Sandcastle requires to get things done. (Wow, that didn't sound bitter at all.) I use Sandcastle Help File Builder for several projects and like it a lot.

When Sandcastle generates its reflection information (so it can properly resolve links in your docs), you need to tell it where it can find third-party dependencies so it can generate the information it needs. All of this has to happen on the command line (no, there's not currently a config file option for this), which means when your project gets to be of a significant enough size, you start running into command line length limitations. Sandcastle Help File Builder addresses this by copying all of your dependencies locally into a temporary folder and passing a single dependency location (that folder) to Sandcastle.

That works great... until you run into an issue where you inadvertently rely on multiple versions of a single dependency.

For example - say you have a custom NAnt task project with a compile-time dependency on log4net 1.2.1.40796 and NAnt 0.85.2344.0. NAnt 0.85.2344.0 has a reference to log4net 1.2.9.0. What that means is, unfortunately, that Sandcastle needs access to both versions of the log4net.dll. What it further means is that when Sandcastle Help File Builder tries to copy both versions locally to help you with the dependency thing, there can be only one and Sandcastle dies a miserable death telling you that it can't find the reference.

How do you resolve that?

Luckily, Sandcastle Help File Builder has a plugin model that allows you to swap in your own behavior for various stages of execution, and that's what I've done.

Since Sandcastle needs the assembly metadata and it doesn't matter what the physical filename is, I've replaced the existing dependency copy routine so that it still copies all of your specified dependencies but it copies them with GUID filenames - so you can have more than one version of a dependency without having a filename clash. Sandcastle resolves the dependencies correctly (it literally just iterates through all of the copied dependencies and caches the metadata) and docs get generated. Peace on Earth is restored.

The plugin copies your dependencies with GUID filenames.

To use it, just drop it in the PlugIns folder in your Sandcastle Help File Builder installation location. More on using plugins with Sandcastle Help File Builder is included in the SHFB documentation. (Basically, put it in the folder and SHFB will pick it up automatically.)

Grab the compiled version, the source (with unit tests), or both. Free, as usual.

[Download Paraesthesia.SandcastleHelpFileBuilder.Plugin 1.0.0.0 Compiled]
[Download Paraesthesia.SandcastleHelpFileBuilder.Plugin 1.0.0.0 Source]

Version History:
1.0.0.0: First release.

Searching for Floats in Lincoln City

Sunday Jenn, I, and our friends Angela and Keaka gathered up in the Wagon Queen Family Truckster and headed down to Lincoln City, OR. Every year they place a bunch of glass floats up and down the beach, and Angela's totally into floats, so we went to help her find one.

After a couple of hours walking around on the beach, searching with the other treasure hunters, we came up empty-handed. I was tempted to run to a local shop and just buy a float and then hide it in the sand somewhere to "find," but I couldn't sneak away. Somehow I think Angela would have known anyway and probably given me a stern talking-to.

Next time I think I want to blow my own glass float, though it costs like $65 to do it. I think it'd be a pretty neat experience and you'd get to take something cool home. I've never blown glass before. I did get myself some Mo's clam chowder, which is always worth the trip. And now, back to work!

Laser Hair Removal: Treatment 7

Saturday was my seventh in a series of laser hair removal treatments for my face. I had some excellent results from last time and my facial hair is getting pretty noticeably patchy. Especially at the end of the day, I get sort of "five o'clock dirty-face" now since it's less "shadow" and more sparse. (I went to the dermatologist the other day and forgot to mention I was getting the treatments. He was all, "I don't remember you mentioning you had really bad acne when you were younger..." It's pretty patchy.)

The area around my mouth is being a little stubborn, but my chin is the thickest/coarsest hair on my face, so that's to be expected, and we hadn't done the MedioStar laser around my lips because that's apparently the most painful area. To remedy some of that, this time we did MedioStar around the lips (not actually any more or less painful than anywhere else) and went over my chin twice. We also did full face with the DermoFlash IPL. We should be getting some great results this time, though my face burned for a day like a bad sunburn and it hurts to shave because it's very tender. My patchiness is also far more visible this morning because I have a small amount of bruising, which is not uncommon and generally goes away in four or five days.

Treatment is getting noticeably less painful every time. I'm pretty sure that doing the DermoFlash for a few treatments was the right way to go (for me) because it thinned things out enough that the MedioStar became bearable. They also fairly recently got this cold air machine that blows supercooled air and freezes you right up, making things, again, more bearable. It beats the crap out of putting ice on your face, which doesn't work.

Running with Fios

The Verizon Fios installers just left, and I've got my 15mbps up/2mpbs down running in full form. Got everything transferred over to use the Verizon router and Xbox Live, my primary network problem child, seems to be working swimmingly.

15494kbps download/1847kbps upload

Of course, it didn't come off without a hitch - the person taking our order mistyped the phone number, so the installers couldn't really transfer our phone number from Comcast to Verizon because the paperwork didn't match. So now we have Verizon video and data, and we have both Verizon and Comcast phone. How does that work? Verizon is actually hooked up and running but with the wrong phone number. We've had to temporarily keep the Comcast voice service, even if no Comcast junk is hooked up, so we don't lose our number. It will take a week of futzing around through annoying phone trees and fighting with service people who can't get off the standard script in order for us to get the number switched. A week to do a two minute job.

Oh, Verizon. I knew you had horrible customer service, and so far, well, I wasn't wrong.

I like the menus and the TV features a lot better than the Comcast stuff. The UI is far slicker and has a lot of little helpful things in it than the Comcast one did. The net connection seems pretty nice, too, but I can't really speak to it much since I've only written this blog entry and gotten things basically connected. We'll see how she goes soon.

Oh, and it's like $50/month cheaper, which doesn't hurt.

TypeMock, NUnit and NCover Together in MSBuild

Getting TypeMock, NUnit, and NCover to work together in your build script can sometimes be a tricky thing. Getting any one of those things to work individually is easy enough, getting two going is a little tougher, but getting all three together requires a bit of finesse. Add to that the fact that you may run different versions of different products (different NUnit versions, for example) for different source code bases and it gets downright complicated.

The way my product code works, when I check out the codeline I want to work on it comes with all of the dependencies - every third party assembly, every build tool. That includes TypeMock, NUnit, and NCover. That way the build server doesn't have to have anything installed when it runs a build - it can auto-deploy TypeMock, register NCover, do its thing, and undo all of that when it's done. (Yes, there are some drawbacks to that - parallel builds are limited when registered versions of profilers change, for example - but we've dealt with that sort of thing in other ways.)

On developer workstations, we have TypeMock installed so we can make use of the tracer and other helpful utilities, but on the build server, we auto-deploy TypeMock.

Since TypeMock is a profiler, if you use it in your unit tests, you can't just run NUnit in the build and have it work - you have to start TypeMock, then run NUnit, then shut TypeMock back down. If you're using NCover, you have to make sure NCover is registered and linked with TypeMock.

TypeMock comes with some custom build tasks to help you get this working. You will also want to get NCoverExplorer and NCoverExplorer.Extras to get this working well. NCoverExplorer will aggregate coverage logs for you and NCoverExplorer.Extras comes with NCover and NCoverExplorer MSBuild tasks.

The general flow of what needs to happen is this:

  1. Register TypeMock with the system (if it's not a developer workstation - our devs have it installed).
  2. Register NCover with the system.
  3. Start TypeMock and link it with NCover.
  4. Run NCover and pass it the command line parameters to run your NUnit tests. Tell it which assemblies to profile.
  5. Stop TypeMock.
  6. Unregister NCover with the system.
  7. Use NCoverExplorer to aggregate the coverage reports into a single report.
  8. On error, stop TypeMock and unregister NCover.

Here's the example:

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Register the tasks necessary for running tests and coverage. -->
  <Import Project="Relative\Path\To\TypeMock.NET\TypeMock.MSBuild.Tasks"/>
  <UsingTask
    TaskName="NCover"
    AssemblyFile="Relative\Path\To\NCoverExplorer.Extras\NCoverExplorer.MSBuildTasks.dll"/>
  <UsingTask
    TaskName="NCoverExplorer"
    AssemblyFile="Relative\Path\To\NCoverExplorer.Extras\NCoverExplorer.MSBuildTasks.dll"/>

  <PropertyGroup>
    <!-- Property indicating we're building on a dev machine - build server will set this to false. -->
    <DeveloperBuild>true</DeveloperBuild>
    <!-- Property indicating where build logs will go. -->
    <BuildLogDirectory>Relative\Path\To\Logs</BuildLogDirectory>
  </PropertyGroup>

  <Target Name="test">
    <!-- Register TypeMock only if it's the build server - it'll already be on a developer box. -->
    <TypeMockRegister
      Company="YOUR COMPANY"
      License="YOUR LICENSE"
      AutoDeploy="true"
      Condition="'$(DeveloperBuild)'!='true'"/>

    <!-- Register NCover so it's available for TypeMock. -->
    <Exec Command="regsvr32 /s &quot;Relative\Path\To\NCover\CoverLib.dll&quot;"/>

    <!-- Start TypeMock and link it with NCover. -->
    <TypeMockStart Link="NCover"/>

    <!-- Enumerate the test assemblies you'll be executing with NUnit. -->
    <CreateItem Include="Your\Build\Ouptut\*.Test.dll">
      <Output TaskParameter="Include" ItemName="UnitTestAssemblies"/>
    </CreateItem>

    <!-- Create the folder where unit test and coverage logs will go. -->
    <MakeDir Directories="$(BuildLogDirectory)"/>

    <!-- Run NUnit through NCover so profiling happens. -->
    <!-- Note the use of "batching" so this is equivalent to a "foreach" loop in MSBuild. -->
    <NCover
      ToolPath="Relative\Path\To\NCover\"
      CommandLineExe="Relative\Path\To\NUnit\nunit-console.exe"
      CommandLineArgs="&quot;%(UnitTestAssemblies.FullPath)&quot; /xml=&quot;$(BuildLogDirectory)\%(UnitTestAssemblies.Filename)-results.xml&quot;"
      AssemblyList="MyAssembliesToProfile"
      LogFile="$(BuildLogDirectory)\%(UnitTestAssemblies.Filename)-ncover.log"
      RegisterProfiler="false"
      CoverageFile="$(BuildLogDirectory)\%(UnitTestAssemblies.Filename)-coverage.xml"/>

    <!-- Stop TypeMock and unregister NCover. -->
    <CallTarget Targets="test-finally"/>

    <!-- Get all of the coverage logs and aggregate them with NCoverExplorer. -->
    <CreateItem Include="$(BuildLogDirectory)\*-coverage.xml">
      <Output TaskParameter="Include" ItemName="CoverageReports"/>
    </CreateItem>
    <NCoverExplorer
      ToolPath="Relative\Path\To\NCoverExplorer\"
      ProjectName="YourProjectNameHere"
      ReportType="4"
      Sort="CoveragePercentageAscending"
      Filter="None"
      OutputDir="$(BuildLogDirectory)"
      XmlReportName="CoverageReport.xml"
      HtmlReportName="CoverageReport.html"
      ShowExcluded="True"
      SatisfactoryCoverage="75"
      FailMinimum="True"
      CoverageFiles="@(CoverageReports)"/>

    <!-- In case one of the tests fails, make sure to stop TypeMock and unregister NCover. -->
    <OnError ExecuteTargets="test-finally"/>
  </Target>

  <!-- Stopping TypeMock and unregistering NCover is a separate target because it has to happen -->
  <!-- regardless of success or failure of the unit tests. Like the "finally" in a "try/finally" block. -->
  <Target Name="test-finally">
    <TypeMockStop/>
    <Exec Command="regsvr32 /u /s &quot;Relative\Path\To\NCover\CoverLib.dll&quot;" ContinueOnError="true"/>
  </Target>
</Project>

In the example, notice how the steps for stopping TypeMock and unregistering NCover have been placed in a separate target called "test-finally" since it's used a lot like a try/finally block. That's the sort of thing we're trying to emulate. You'll also notice that we're using MSBuild "batching" to run each test assembly through NCover and generate an individual coverage log.

Additional notes:

  • Obviously you're going to need to change the paths and other placeholder parameters to fit your build.
  • If you've got TypeMock installed on dev machines and on the build box, you can skip the TypeMockRegister task and just start/stop TypeMock.
  • If you've got NCover installed on dev machines and on the build box, you don't need to execute "regsvr32" to register/unregister NCover. As long as NCover is registered before you start TypeMock, you're OK.

TypeMock Isolator - Now With Debugging Goodness

I'm playing with the latest release of TypeMock (now "TypeMock Isolator," as it sounds like they have a suite of products planned beyond their mocking product) and I think my favorite feature is the better debugging support. Sure, you can mock fields now (admittedly, a little scary sounding, but with legitimate applications nonetheless) and they've cranked up the performance on it, but how many times have you fired up TestDriven.NET and started your test in the debugger only to get odd behavior because you tried to step into a mocked method?

Now, when you try that, you actually see the method outlined in the debugger so you get a visual cue about what you're doing:

TypeMock outlines mocked methods in the debugger.

Oh, and you know how you ran into trouble popping open the watch window, or QuickWatch, and evaluating a mocked call multiple times, causing mock verification problems? No more! The debugger works without hitches. Love it, love it, love it.

This is all in the new TypeMock Isolator 4.2.1 beta. If you get a chance, check it out. Good stuff coming from those TypeMock folks.

Coding Horror Finds 360 DRM Joy

Looks like Atwood is seeing the ugly Xbox 360 DRM beast for the first time. This is something I've been painfully aware of for far longer, as have many other people. Sorry you're having trouble, Jeff. Maybe you'll have better luck getting a DRM fix out of Microsoft than the rest of us poor saps.

Cloverfield

Went to see Cloverfield this weekend.

What I expected: A cool, maybe kinda scary, fun roller-coaster-ride monster movie.

What I got: A headache from too much shaky-cam following stupid people through New York.

Before I get a bunch of people telling me I missed the point, let me stem the tide: I got it. I mean, I get the whole "point of view" thing and how the interesting bit was that rather than tell the monster movie story from an omniscient perspective they drilled down and got it from a 'new and different" perspective - that of victims. I get it.

That doesn't make it good.

Really, I think the shaky-cam thing got old. Let's ignore the "but that's the point" argument. I've never seen home movies as ridiculously shaky as what they showed. Even the stuff at the beginning, when they weren't being chased by the monster, was shakier than any home movie I've ever seen. By the end of the movie, Jenn couldn't even watch it - she had to close her eyes and just listen because it was far, far more jarring than even Blair Witch (which also sucked).

Oh, and if you're being chased by a giant monster and buildings are falling all around you and you happen to drop the camera, are you going to go back and pick it up? Further, are you going to run around with it at eye level the whole time? Hell, no. You're going to throw the camera at the monster chasing you and you're going to high-tail it out of there.

Did I mention the thing pretty much just ended, without any resolution to what happened to the monster? Did it die? Did it live? We don't know.

There were really only three parts I dug about it (and, technically, these are spoilers, but you're going to be smart and save your money, right?):

  1. The part where the stealth bombers show up to lay waste on the monster.
  2. The part where the girl explodes after getting bitten.
  3. The fact that little mini-creatures get dropped off the one big creature. That shit creeped me out.

Other than that, lame, lame, lame. I wanted less of the morons running around the city and more of the military getting medieval on the monster. I wanted less shaky cam and more ability to actually see what was going on.

Save your money. Or, better, go see Juno. That movie was great.