June 2010 Blog Posts

YouTube URL Hacks

I went looking for a list of YouTube URL hacks so I could send a link to a video and have it start at a particular time. I ended up coming across a couple of great posts that have some neat tricks.

My favorite two:

  • View high quality videos: Add "&fmt=18" for stereo 480 x 270 resolution or "&fmt=22" for stereo 1280x720 resolution.
  • Start at a specific time: Add "#t=XmYs" where X is the number of minutes and Y is the number of seconds, like "#t=5m16s" to start at 05:16. If you just want seconds (like to start at 0:14) you can just put the number, like "#t=14".

Check out the rest of the tips on the original sites - good stuff!

Unit Testing an ASP.NET VirtualPathProvider

The VirtualPathProvider class is (in my opinion) a fairly underused mechanism for extending where different files in your application come from. You can create providers that get files from zip archives, databases, or anywhere else you need.

The problem is, unit testing them is a nightmare. You either have to run the tests from inside a real web app or you have to set up so many mocks that your tests become fragile or unmanageable. Ugh.

Turns out there's a third option - create a special AppDomain that has just enough real setup to support working with the ASP.NET HostingEnvironment and VirtualPathProviders.

Here's a sample test fixture that does just that:

using System;
using System.IO;
using System.Reflection;
using System.Web.Hosting;
using NUnit.Framework;

namespace MyTests
{
  [TestFixture]
  public class MyTestFixture
  {
    // Instance property for the HostingEnvironment-enabled AppDomain.
    private AppDomain _hostingEnvironmentDomain = null;

    [TestFixtureSetUp]
    public void TestFixtureSetUp()
    {
      // Create the AppDomain that will support the VPP.
      this._hostingEnvironmentDomain =
        AppDomain.CreateDomain("HostingEnvironmentDomain",
        AppDomain.CurrentDomain.Evidence,
        AppDomain.CurrentDomain.SetupInformation,
        AppDomain.CurrentDomain.PermissionSet);

      // Set some required data that the runtime needs.
      this._hostingEnvironmentDomain.SetData(".appDomain", "HostingEnvironmentDomain");
      this._hostingEnvironmentDomain.SetData(".appId", "HostingEnvironmentTests");
      this._hostingEnvironmentDomain.SetData(".appPath", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
      this._hostingEnvironmentDomain.SetData(".appVPath", "/");
      this._hostingEnvironmentDomain.SetData(".domainId", "HostingEnvironmentTests");
      
      // Initialize the hosting environment.
      HostingEnvironment environment = this._hostingEnvironmentDomain.CreateInstanceAndUnwrap(typeof(HostingEnvironment).Assembly.FullName, typeof(HostingEnvironment).FullName) as HostingEnvironment;
      
      // Finally, register your VPP instance so you can test.
      this.Execute(() =>
        {
          HostingEnvironment.RegisterVirtualPathProvider(new TestVirtualPathProvider());
        });
    }

    [TestFixtureTearDown]
    public void TestFixtureTearDown()
    {
      // When the fixture is done, tear down the special AppDomain.
      AppDomain.Unload(this._hostingEnvironmentDomain);
    }

    [Test]
    public void FileExists()
    {
      // Use the special "Execute" method to run code
      // in the special AppDomain.
      this.Execute(() =>
        {
          Assert.IsTrue(HostingEnvironment.VirtualPathProvider.FileExists("~/Root/Folder1/Page1.aspx"));
        });
    }

    // This method allows you to execute code in the
    // special HostingEnvironment-enabled AppDomain.
    private void Execute(CrossAppDomainDelegate testMethod)
    {
      this._hostingEnvironmentDomain.DoCallBack(testMethod);
    }
  }
}

The difficult bit is setting up the special AppDomain, but once you do that and initialize the HostingEnvrionment, you can use the VirtualPathProvider just like you would in a real environment. The special AppDomain thinks the "root" of your application is in the same location as the executing unit test assembly, so there shouldn't be any issues with the runtime locating assemblies or anything.

Standard disclaimers apply: YMMV, I'm not responsible if it crashes your server, etc.

Works On My Machine!

Beware the WD Green Drives

That headline sounds a little foreboding, but this is important: If you are expanding your storage at home, be careful of choosing WD Green drives - only certain model numbers are good.

A while ago I upgraded my Windows Home Server storage with an eSATA port multiplier and some 1TB WD Green drives. A few months later I added more storage in the form of a 2TB WD Green drive.

During this time, I had installed PerfectDisk on the Windows Home Server and was using that to defrag my drives. When running it, I'd get all sorts of errors on random drives... but during regular day-to-day use, there were no problems. I was pretty well convinced this was a problem with PerfectDisk since that application was the only one causing issues. I couldn't have PerfectDisk enabled for more than a couple of days before the server would blue screen or hang and require a hard reboot.

After all of this trouble, I started losing faith in the reliability of the server and got a Synology DS1010+ to move my DVD images to - the primary bulk of my data. While researching compatible drives for the DS1010+, I found that there are actually specific notes on their compatibility list about certain model numbers of the WD Green drives testing well and most others causing problems. There are forum posts about this as well.

Per these sources, the only reliable WD Green model numbers are:

  • 2TB: WD20EADS-00R6B0
  • 1.5TB: WD15EADS-00R6B0
  • 1TB: WD10EADS-00L5B1

I looked at my drives in my Windows Home Server and, sure enough, about half of the drives were the "good" model numbers and half were "bad" models. As part of the move to the DS1010+, I reorganized the drives in my Windows Home Server so only the "good" model numbers remained in the system.

I've been running PerfectDisk on the Windows Home Server for a little over two weeks now with no issue.

There are a lot of factors in play here, to be sure.

  • I moved the drives in the WHS around so they're in different slots than they originally were. If there was some sort of problem with a drive being seated incorrectly or a particular slot disagreeing with a particular drive, that may no longer exist.
  • There are fewer drives in the eSATA port multiplier just because there are fewer drives in the system in general. If the port multiplier didn't like having so many drives in it, that issue may not be showing itself now.
  • I moved several terabytes of data off the home server so the majority of the space there is empty. If the problem was with PerfectDisk managing drives that have very little free space, that may not be displaying now.

Even given all of that, it's hard for me to deny that my experience with these drives is backed up by Synology testing and user experience, too. It's not just me. Moving these drives out of my system seems to have increased reliability quite a bit.

YMMV, but my recommendation: Beware the WD Green drives.

Developing as a Non-Admin: Testing WCF Services

If you're developing as a non-admin user and writing WCF services (or supporting entities like behaviors, etc.), you probably not only are unit testing the code but also want to write an integration test or two that actually fires up a real WCF service, makes a couple of requests, and validates the responses.

You may also have seen this exception:

System.ServiceModel.AddressAccessDeniedException : HTTP could not register URL http://+:1234/ServiceUnderTest/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details).

Following that link, you'll see that the reason you can't start your service listening to the port/URL you chose in your test fixture is that you're not running as admin. You also see some instructions telling you how to grant the user the rights to use that URL.

There's an easier way and it doesn't require permissions changes.

There is a special temporary URL base that anyone can use. Instead of starting up your service on an arbitrary port or URL like "http://localhost:1234/ServiceUnderTest" try putting the test service under "http://localhost:80/Temporary_Listen_Addresses/" like "http://localhost:80/Temporary_Listen_Addresses/ServiceUnderTest". You won't get prompted for credentials and things will run just fine on your local machine without having to grant your developer user any additional permissions.

This is one of those things that I figured out, forgot, figured out, and forgot again... and now I've figured it out one more time. This time I'm blogging it so I hopefully don't forget.

At Least Go Somewhere Close to the Speed Limit

It's been a while since my last traffic-related posting, mostly because my commute in recent years has been pretty short so I don't have those "Traffic Asshole of the Week" moments to post. Today, though, I found THIS guy:

20 in a 45? Sure! Why not? 

This giant GMC truck made my traffic day. If you, too, want to make my day in the same way, here's how:

  1. While I'm going a full 45mph, wait until I'm a little less than half a block away and then do a left-hand turn out of a side street and cut me off.
  2. Once you've cut me off, make sure and go somewhere around 20mph in a 45mph speed zone. Be sure this is in a no-passing area, too, so there's no way I can get around you.
  3. Do not put on your emergency flashers to indicate you're going slow on purpose. Make sure that, by all appearances, you're really just not paying any attention at all to the whole "driving experience."
  4. Stop for every green light. Seriously. Stop for anything that says "go."
  5. Every time I signal to change lanes, to get around you, go ahead and, without signaling, change lanes in front of me into the lane I was going for.

After I finally got around him (where there were finally two lanes), I looked in my rear view mirror and saw cars passing him in one lane like he was standing still... and somewhere over 10 or 15 cars piled up behind him, waiting for a chance to jam into the next lane and get around.

Dude, you are the single-handed reason for traffic. Pull over to the side of the road, take the keys out of the ignition, and throw them as hard as you can into the scrub. Walk home. You are fired as a driver.

posted @ Monday, June 07, 2010 7:56 AM | Feedback (1) | Filed Under [ Traffic ]

VerificationException During Coverage? Check Your Security Attributes

Ran into this yesterday and took a little bit to figure out:

I can run unit tests through NUnit or TestDriven.NET just fine... but if I run those same tests through NCover, I get a System.Security.VerificationException - "Operation could destabilize the runtime."

I searched around and found that the exception comes up basically when the JIT can't verify type safety of an assembly or when it tries to run something in medium trust that should be running in full trust. I also found another person who ran into something similar.

Turns out I had marked my assembly with AllowPartiallyTrustedCallersAttribute (for various reasons I won't get into) and that was causing problems when NCover tried to instrument it. Removing the attribute fixed the issue and I could get coverage running.

Long term that's probably not the best solution and I need to learn more about the new .NET 4 security model to figure out what really needs to happen, but if you're seeing a VerificationException when you run tests under coverage but you don't see that exception when you run without coverage... check your security attributes.

posted @ Friday, June 04, 2010 10:29 AM | Feedback (0) | Filed Under [ .NET ]

Looking at Moving to Android

Now that I've got my calendar/contact sync issues pretty much resolved, I'm starting to think about moving to an Android-based phone. You know, because I can't leave well enough alone.

Apparently Amazon has opened a new wireless store, which is interesting, and looks like, at the very least, a sort of vendor-neutral place you can see what's out there. My current leading choice, since I'm on Verizon now, is the HTC Droid Incredible. The speed and screen are appealing, and the camera is hands down better than my crappy Blackberry Curve camera (even if the Incredible gives things a slight blue tint).

Maybe in a couple of weeks or so, when I have a weekend free to head in and switch. I'll need the weekend to get myself all set up. :)