Pages

Friday, September 9, 2016

Disable Windows 10 Photo Automatic Albums

image

It’s dumb that:

  1. Windows 10’s default photo viewing app automatically creates albums for you.
    image
  2. You can’t disable that feature.
  3. Instead, you have to remove the application using PowerShell.
  4. Which means your default photo viewing app becomes something dumb like Paint.

image

http://answers.microsoft.com/en-us/windows/forum/apps_windows_10-photos/is-there-any-way-to-disable-the-windows-10-photo/ce616a54-7ce0-44e3-8d47-d56589fc3743?page=1

PowerShell command to remove Photos:

Get-AppxPackage *photo* | Remove-AppxPackage

Note: According to some, setting another program (like Paint) as your default photo viewer might disable automatic album generation without removing the app. I didn’t test it, because the only thing I’d use the app for is as a viewer. Not an editor. Just an on-the-fly viewer.

------------ EDIT 1 -------------

It’s possible to restore using the Windows 7 Windows Photo Viewer as the default. The program is still installed in Windows 10, it just doesn’t have its file associations enabled by default. Follow these instructions:

http://www.tenforums.com/tutorials/14312-windows-photo-viewer-restore-windows-10-a.html

Note: I haven’t tried the above, but TenForums (and its sister, SevenForums) is reputable.

------------ EDIT 2 -------------

I’ve installed the free (for home use) FastStone Image Viewer, set it as as my default photo viewer, and changed one setting. I’m now happy. I can already see this app will make me more productive, and I’ll likely be donating money to it.

Setting I Changed

The default behavior of FastStone is to open a double-clicked image file in full screen mode. I prefer opening in a window because I often need to view the photos while doing something else.

  1. Open FastStone
  2. Settings (F12) > Viewer
  3. Associated image launches in: Windowed View
    image

Features

In full screen mode, moving the mouse to the top, bottom, right or left of the screen reveals a specific menu. For instance, at the top is thumbnails and some command buttons.

FastStone has a lot of features, but here are my needs and how FastStone met them.

Double-click an image and view in window.

  1. Search > Default Programs
  2. For Photo viewer, choose FastStone.

image

Easily move to next/previous image.

    • In any view, use the arrows to navigate.
    • In windowed view, there are buttons in the tool bar.
    • In any view, bring the mouse toward the screen bottom and arrows will appear/

image

Quickly get some image properties.

    • In any view, press “I”.
      image
    • In full screen view, move cursor to right side.

View as a slide show.

    • In windowed view, click the Slide Show button image
    • In full screen, move mouse to top, bottom or left and find the Slide Show option in the menu.

image

References

Here are 4 Best Image Viewers for Windows 10

Monday, September 5, 2016

A Layman’s Explanation of Mocking and Dependency Injection

A Sad Tale of Woe Again

image

So your husband or wife is a software engineer, and you’re not. You like the idea of software, you even use software, but you are as interested in what goes into creating software as you are in soap manufacturing. He (or she, but programming is still a stupidly male-dominated field, so we’ll stick with the percentages) comes home, blathering on about his day. The conversation goes something like this:

Him: “They handed me a legacy codebase today. It’s ancient .Net 2 stuff. I’m supposed to refactor the existing code and, in parallel, rewrite it to .Net 4.5.”

You: (silent, but thinking, “I wonder if crocodiles attack alligators. Or can they mate with them? You only hear about crocodiles or alligators, not crocodiles and alligators. Is a ‘crocogator’ a thing?”)

Him: “I spent about five hours just looking at the stack. What a mess! I mean, it’s not bad, really, but before I make any changes I need a way to unit test, and it’s not architected for that. I don’t want to go down the rabbit hole since I’m rewriting the whole thing using SOLID DDD principles, but I’ve got to get some DI going, and I’m going to have to figure out how to mock some of the internals.”

You: (nodding, and thinking, “If I pull weeds today, then I can mow tomorrow and feel virtuous two days in a row, and treat myself to wine at lunch on Saturday.”)

Him: “Can I brainstorm the unit testing with you? Just, you know, talk it out? That would really help.”

You: (nodding slowly, thinking, “O! M! G! Just cut off my head and pour cabbage into it! Still, he’s a good man. All I have to do is listen.”

Him: “Stop me any time if I can explain how something works.”

You: “OK, honey.” (but thinking, “The weeds. I was going to pull the weeds.”)

Unbaffling Language to the Rescue!

The only thing worse than listening to a software developer talk about code is asking a sailor about an upcoming voyage. Here are some actual nautical terms and phrases: cumshaw, geedunk, abeam, baggywrinkle, beat to quarters, by and large, coxswain. The definition of “death roll”?:  “In a keel boat, a death roll is the act of broaching to windward, putting the spinnaker pole into the water and causing a crash-gybe of the boom and mainsail, which sweep across the deck and plunge down into the water.” [Wikipedia]

Water. I drink water. I understand water.

Programmers don’t need to live lives of unending, habitual obfuscation. We can explain, if we but remember the lessons of literature.

The Totally Contrived, Ridiculous Metaphor

Imagine you’re a high school teacher. Now, imagine that you have a four-inch wood splinter going through your left eyelid. Which is easier on your mental state? If you say “splinter,” you must be a teacher.

Now, imagine a magical school where you don’t have to grade your own papers. You finish your eight-hour work day, go home, take an hour planning the next day’s lessons, have dinner, and study an hour or two for your required continuing education course, but you don’t have to grade at least twenty-five of the 120 five-page essays from mid-term exams.

Instead, you get to hand the exams to your Grading And Reports Department. It works like this:

  1. Give Mr Michael Murphy your stack of 120 essays.
  2. A few days later, pick up the graded essays and a formatted report of the students’ grades, broken down by class period, by student, and summarized with comparative aggregates. It’s a great report.

Recently, you were tasked with testing the GARD system. You’re a great choice, because you helped create the department. Here’s what you know:

  1. Mr Murphy takes the papers and gives them to Dr Marcia Malone. Dr Malone grades every paper. She gives the results back to Mr Murphy.
  2. Mr Murphy aggregates the grades and creates the formatted report.
  3. You helped train Dr Malone, who is brilliant. She can grade anything. But teachers have no control over how she grades.
  4. The grading scale Dr Malone uses could change at any time. Today, 90-100% could be an “A.” Tomorrow, 93-100% could be an “A.” (Remember, this is a contrived example.)

Here’s a lousy illustration.

You give the papers to Mr Murphy

image

Mr Murphy gives the papers to Dr Malone, who does mysterious, magical mischief.

image

Mr Murphy gives you back the papers.

image

You have only been asked to test the report formatting. This is critical! You are not verifying the grades are correct. You only care about the report. You devise this test

Given a stack of 120 papers, if the grades are abc, then report should look like xyz.

So here’s your challenge. You are going to give Mr Murphy 120 papers. He’s going to create the report. You’re going to compare what he gives you with how you know the report should look, right down to the numbers and letter grades on it. If they match, the test passes. If not, the test fails.

“Crap!” you think, “I can’t depend on Dr Malone to always give Mr Murphy the same grades! Besides, it takes her three days on average to grade that many papers, and I want my tests to be done in a day. It only takes Mr Murphy a few hours to prepare a report.”

You develop a plan. You are a genius.

  1. You build an automaton that looks like Dr Malone. But, it doesn’t actually grade anything. It just gives back a consistent set of scores that you tell it.
  2. When you give Mr Murphy the papers, you’ll also give him the automaton.
  3. Instead of Mr Murphy handing the papers to Dr Malone, he’ll hand them to the automaton and immediately get back your scores from it.
  4. Mr Murphy formats the report and gives it to you.

More laughable illustrations, but let’s include the programming terms.

We have a dependency on our grader, Dr Malone. We’ll change the GARD room so that we can give it a real or fake grader. This is called Dependency Injection.

image

Mr Murphy doesn’t care which grader he gets answers from. For our test, he uses the fake one. That is, he uses a Mock (also called a fake, or stub, or substitute).

image

We get back the report made from data we injected. We just want to compare the reports, the work Mr Murphy does.

image

If they match, the test passes. If not, fail!

image

How a programmer sees this

A programmer sees it the same way. Except it’s all words that look like English, but are alien-ese.

The Interface

image

The Production Code

image

Using the Production Code

image

The Test Code

image

Wrap Up

Dependency Injection and Mocking solve two problems that affect how well software can be tested.

  1. Dependency Injection lets us control what external dependencies, like a grading engine, a method uses. If we couldn’t do this, we’d have to always use production data, when that’s not what we’re always testing.
  2. Once we can inject a dependency, we can Mock its behavior. That is, we can make it do whatever we want, giving the method under test consistent results. Again, we’re not testing the dependent service. We’re testing the method that is using it.

It takes some work, but once you get your head wrapped around these concepts and their implementation, their importance becomes clear.

Wednesday, August 31, 2016

Catching Up on Coding - TDD Part 3

I’ve been a software developer for twenty years, but am behind in some skills. This series chronicles my self-improvement.

It turns out that unit testing exercises a lot of coding methods for more maintainable code. Some methods involve deception, so who better to inspire us than our “Butch Cassidy/Sundance Kid” knockoffs from 70s show Alias Smith and Jones? The difference is, I’m not trying to “get out of this business.”

Previously on CUOC: TDD Part 2
Next Episode: SOLID Matters

 

 

Teaser

Unit testing benefits from mocking and Inversion of Control. I’d argue that it’s hard to effectively unit test without these techniques. Parts one and two of this TDD series used hand-crafted mocking and IoC. Today, we’ll redo some tests using 3rd party tools/frameworks.

Act 1 – Choosing the Tools

I researched what developers are recommending for mocking and IoC. Of course, opinions abound, but in the end I came to a few conclusions.

Mocking

  • No one recommends Rhino Mocks anymore. It appears to be a mostly dead project.
  • Moq is still used, but is falling out of favor.
  • Developers like NSubstitute and FakeItEasy.
  • NSubstitute has a more concise API. FakeItEasy is more natural language and less ambiguous.
  • My reaction to seeing them side-by-side is that I like FIE’s syntax more. I like tests that are immediately easy to understand.
  • But I’m a little put off by the verbosity, so I’ll try NSubstitute first.

References

C# Test Mocking Frameworks

NSubstitute: A Refreshingly Simple Mocking Framework for Unit Tests

Mocking: why we picked NSubstitute

Easy Mocking with FakeItEasy

IoC

  • Ninject is the most popular, and has the worst performance (though some developers argue that IoC container performance doesn’t matter).
  • Unity is supported (for now) by Microsoft, but people have complained about some limitations.
  • StructureMap, Autofac, and Simple Injector remain as the choices. Based on a few reviews—but mostly gut instinct—I’m going to use Simple Injector. (Autofac would be my second choice.)

References

IoC Container Benchmark – Performance comparison

Inversion of Control Containers Basic Comparison

IoC Battle in 2015 results: Using Ninject – think again!

Generic variance in DI containers

Simple Injector Migration Guide <-I love that they include how to migrate away from their product. Also serves as a coding comparison.

Act 2 – Making a Mockery of Testing

Install NSubstitute

  1. Install the package into the unit test project using NuGet.
  2. After installation, a nice readme.txt file opens. Read it.

Replace a Previous Test

In my previous tests, I created my own mock Registry wrappers from IRegistryWrapper and IRegistryMockWrapper. These are interfaces I created to allow Inversion of Control of the Registry. IRegistryWrapper looks like this

    public interface IRegistryWrapper
    {
        object GetValue(string keyName, string valueName, object defaultValue);
        void SetValue(string keyName, string valueName, object value, RegistryValueKind valueKind);
    }

the hand-crafted mock looks like this

    class RegistryMock : IRegistryWrapper
    {
        public object GetValue(string keyName, string valueName, object defaultValue)
        {
            //this may become cumbersome, but for now specify some return values
            switch (keyName)
            {
                case @"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgent":
                    if (valueName == "Version") return defaultValue;
                    break;
            }
            throw new Exception("Invalid keyName");
        }

        public void SetValue(string keyName, string valueName, object value, RegistryValueKind valueKind)
        {
            throw new NotImplementedException();
        }
    }

here’s the unit test

    public class RegistryService_GetRegistryKeyValue_Should
    {
        IRegistryWrapper _registry = new RegistryMock();
        IRegistryKeyWrapper _registryKey = new RegistryKeyMock();

        [Fact]
        public void ReturnNullConstantTextIfValueIsMissing()
        {
            var service = new RegistryService(_registry, _registryKey);
            var result = service.GetRegistryKeyValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgent", "Version");
            Assert.Equal(result, service.NoValue);
        }
    }

and finally, here's the RegistryService method that passes the test

        public string GetRegistryKeyValue(string keyName, string valueName)
        {
            try
            {
                //value will be null if no value found, and the default value if the key is missing. But we only care that there's no value.
                //Null can't be returned to the client. Don't return empty, since that's ambigious (did the key exist?).
                //Return a magic string.
                object value = _registry.GetValue(keyName, valueName, null); //guarantees null if no value or missing key.
                return value != null ? value.ToString() : NoValue;

            }
            catch (Exception ex)
            {
                return "Error attempting keyName '" + keyName + "' and valueName '" + valueName + "'\r\n" + ex.GetBaseException().Message;
            }
        }

All I’m going to do is refactor the test so that I use NSubstitute instead of my own mocks. I’ll need a mock for IRegistryKeyWrapper because the class expects it, but I won’t set any behavior on it.

Note: remember to add “using NSubstitute;”

In my hand-crafted mock, I specified return values based on the arguments to GetValue, and otherwise threw an exception. For my unit test, I need to do something similar. Here’s my first attempt, and it does indeed pass.

            
            var registry = Substitute.For<IRegistryWrapper>();
            var registryKey = Substitute.For<IRegistryKeyWrapper>();
            //Registry.GetValue will return null if the valueName doesn't exist.
            registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgent", "Version", null).Returns(null);
            var service = new RegistryService(registry, registryKey);
            var result = service.GetRegistryKeyValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgent", "Version");
            Assert.Equal(result, service.NoValue);

The problem is (or seems to be), if I change the substitute's argument "Version" to "Blamo", the test still passes. This is happening because given an unknown argument the method will still return null. I need to tell the substitute that it should only return null if it gets the right arguments.

Or do I?

No, I don’t. I’m attempting to give my mock too much behavior. I only want the mocked Registry to pretend that the value was missing and return null. Elsewhere I’ll test the behavior if the value exists. My hand-crafted mock was eventually going to give me trouble because it was doing too much and it wasn’t really behaving like the Registry class.

The Heart of Mocking

The method I’m testing happens to be  a good one for getting at the essence of mocking. RegistryService.GetValue is almost a pass-through to Registry.GetValue. But, it has its own behavior and is supposed to call Registry.GetValue.

As the developer and tester, I know three things:

  1. How external dependencies behave (Microsoft.Win32.Registry).
  2. How my test behaves.
  3. What’s in my method.

That last one is the problem. I know my method calls Registry.GetValue(), because I wrote it. But that’s a serious mental mistake when it comes to the test. I need to write my tests, whether before or after, as if I knew nothing about the method’s code. I should pretend the only things I know about the method are:

  1. The parameters it’s called with.
  2. The dependencies it has.
  3. The result when it’s called with particular values.

In short, my method is a black box. It could be empty, for all I know. That’s why TDD starts with an empty method, so that it fails first. If it succeeds when empty, that’s a problem. When my method has a dependency, I need to only mock up what that dependency will do if it’s called with the expected value.

But, I mustn’t assume the mocked dependency has been called at all.

So, here’s how my test should look.

            //Arrange
            var registry = Substitute.For<IRegistryWrapper>();
            var registryKey = Substitute.For<IRegistryKeyWrapper>();
            //Registry.GetValue will return null if the valueName doesn't exist.
            registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgent", "Version", null).Returns(null);
            var service = new RegistryService(registry, registryKey);
            //Act
            var result = service.GetRegistryKeyValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgent", "Version");
            //Assert
            //First, make sure the mocked Registry was called at least once. Otherwise, we might have a false positive.
            registry.Received().GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgent", "Version", null);
            //Now make sure we got back the expected value from our method.
            Assert.Equal(result, service.NoValue);

To sum up, some key lessons of unit testing are:

  1. Treat the method under test as a black box.
  2. Test behaviors of the method, not its dependencies.
  3. Verify mocked dependencies are called.

A mocking framework gives more value than just controlling return values. It lets you know that your dependencies are being used the way you expect.

Act 3 – Ouch! Injecting Dependencies

  1. Interfaces are used in production code to make it easier to inject dependencies.
  2. Mocking frameworks are used in unit testing code to control injected dependencies.
  3. IoC containers are used in production code to manage injected dependencies.

For the first two, see Act 2, above.

I don’t have  to use an IoC container. I can write code like this:

//pass the live registry wrappers
RegistryService service = new RegistryService(new RegistryWrapper(), new RegistryKeyWrapper());

I could also let my class have default dependencies. This might be OK, as long as the caller knows what to expect. It would be considered "convention over configuration."

    public class RegistryService
    {
        private IRegistryWrapper _registry;
        private IRegistryKeyWrapper _registryKey;

        public RegistryService()
        {
            _registry = new RegistryWrapper();
            _registryKey = new RegistryKeyWrapper();
        }
        public RegistryService(IRegistryWrapper registry, IRegistryKeyWrapper key)
        {
            _registry = registry;
            _registryKey = key;
        }
        ...
    }

    //usage, by default uses the Windows Registry.
    var service = new RegistryService();

For simple cases, using an IoC is overkill. In fact, I would say:

Don’t use an IoC container unless you have to.

When do you “have to”?

  • Where there are lots of dependencies.
  • When you have lots of nested dependencies.
  • When you want your dependency initialization to be in one place.

There are probably other reasons, but those will do for now.

Install Simple Injector

  1. Get it from NuGet, install to the project that’s injecting the dependencies.

Injection!

First, I prepare my RegistryService class for dependency injection.

    public class RegistryService
    {
        private IRegistryWrapper _registry;
        private IRegistryKeyWrapper _registryKey;

        public RegistryService(IRegistryWrapper registry, IRegistryKeyWrapper key)
        {
            _registry = registry;
            _registryKey = key;
        }

My Windows service, EduAgent, is calling the RegistryService, which is in a separate DLL. I want all my dependencies initialized once, in one place. The service’s Main method is the starting point. But, you know what, to make it easier for another developer, I’ll create a class called DependencyInjection, which we’ll call from Main. That makes it pretty clear where the dependencies are maintained, and how.

All we’re doing here is saying “if I request from ‘container’ a type of IRegistryWrapper, give me an instance of the class RegistryWrapper.”

    public static class DependencyInjection
    {
        public static Container container;
        public static void InitializeDependencies()
        {
            //create container
            container = new Container();
            //register interfaces
            container.Register<IRegistryWrapper, RegistryWrapper>();
            container.Register<IRegistryKeyWrapper, RegistryKeyWrapper>();
            //register concrete types
            container.Register<RegistryService>();
            //optionally verify
            container.Verify();
        }
    }

I initialize the dependencies.

    static class Program
    {
        /// 
        /// The main entry point for the application.
        /// 
        static void Main()
        {
            DependencyInjection.InitializeDependencies();
            ServiceBase[] ServicesToRun;
            ...

Notice that during initialization, I’m also registering the concrete type RegistryService. I’m doing this so that I can request an instance of RegistryService without passing any constructor arguments. The container knows what to pass in on my behalf.

   //pass the live registry wrappers, which are auto-wired by Simple Injector
   RegistryService service = DependencyInjection.container.GetInstance<RegistryService>();

This is the same as if I had done this:

   RegistryService service = new RegistryService(new RegistryWrapper(), new RegistryKeyWrapper());

But by using an IoC container, if I use a different (again, fictitious) registry provider, I only need to set it in one place: InitializeDependencies.

Tag

There’s a lot more to mocking and dependency injection than the above samples show. I ran into a pretty significant problem because my original IRegistryKeyWrapper included IDisposable, which plays hell with dependency injection.

Lesson: Sometimes these tools add complications. But other times, they reveal problems in your code.

On the subject of complications, one of the stars of Alias Smith and Jones killed himself during the first season. He suffered from depression and alcoholism. To this day, that makes me sad. Pete Duel, I miss what you could have done.

image

Wednesday, August 24, 2016

Catching Up on Coding - TDD Part 2

I’ve been a software developer for twenty years, but am behind in some skills. This series chronicles my self-improvement.

Taking a cue from the 70s and its badass fonts, my Fantastic Journey is traveling from skill to skill, trying to escape every software engineer’s Bermuda Triangle: obsolescence. I don’t have Jared Martin’s Sonic Energizer to focus my thoughts and manipulate matter. All I can do is listen to the groovy theme music.

Previously on CUOC: TDD Part 1
Next Episode: TDD Part 3

 

 

Teaser

It’s one thing to practice TDD from the start. It’s another to take legacy code that you wrote and create unit tests for it. My EduAgent project includes a client service that processes requests to update the registry.

Looking at my code, I right away see my first stumbling block: the purpose of the code is changing the registry. For testing, this means:

  • Affecting the registry of whatever computer the tests run on.
  • Guaranteeing each test starts with a clean environment. What does this mean for parallel testing?
  • Guaranteeing the registry returns to its original state, regardless of test results.
  • Not breaking the computer.

These are characteristics of integration/functional tests, not unit tests. Should I mock the registry classes to deal with this code?

object value = Registry.GetValue(keyName, valueName, null);

If I do—if I can—am I really testing anything? Or am I creating fake conditions that assure the test will pass? There’s a danger, in unit testing, of creating tests that don’t actually test the method: they “test” a mock that will always return the expected value.

Act 1 – What I Can Test, What I Should

The purpose of mocks is to allow the unit test to focus on what it can test, and ignore what can corrupt the test—assuming what can corrupts the test isn’t exactly what should be tested!

A classic, challenging example is methods that access a database. I don’t want to test if I can access the database. I want to test what I’m doing with the data. For example, consider this class method.

public class EmployeeInfoService
{
	IEmployeeDbContext _db;
	public EmployeeInfoService(IEmployeeDbContext db) { _db = db; }
	public List GetAverageHourlyPay(int[] employeeIds)
	{
		return from stats in _db.PayStubs
		//...a bunch of code that gets data and calculates the hourly pay by doing this:
                // stats.Hours / stats.Amount
		;
	}
}

I don’t care, in the test I’m about to write, if I can access the database, or if the database is returning the right data, or breaks when I hand it a list of EmployeeIds. All I care about is whether the method properly does the math given specific numbers. So, I’d mock the EmployeeDbContext and fabricate the numbers.

	[Fact]
	public void EmployeeInfoService_GetAverageHourlyPay_Should_Correctly_Calculate()
	{
		var db = new MockEmployeeDbContext();
		//...add a bunch of test data to the mock, then pass it to service
		var service = new EmployeeInfoService(db);
		var list = service.GetAverageHourlyPay(new int[] { 1, 2, 3 });
		Assert.Equals(23.34, list[0].AverageHourlyPay);
		Assert.Equals(17.98, list[1].AverageHourlyPay);
	}

Contrast that to this method.

	public string[] GetEmployeeNames()
	{      return _db.Employees.Select(a => a.Name).ToArray();
	}

Is there any reason to create a unit test for this method? I don’t think so. The test would look something like this.

	[Fact]
	public void EmployeeInfoService_GetEmployeeNames_Should_Return_A_List_Of_Names()
	{
		var db = new MockEmployeeDbContext();
		//...add a bunch of mock Employees with names, then pass to service
		var service = new EmployeeInfoService(db);
		var list = service.GetEmployeeNames();
		Assert.True(list.Contains("Varian"));
	}

This gets us nothing. All we did was test that our mocking framework works. So…

Lesson 1: Be sure you’re testing something that can fail.

Act 2 – The Simple Test

For my RegistryService class, I have a different problem as stated above. Can I even mock the .Net Registry class? We’ll look at that shortly. For right now, I’ll evaluate all the methods and see which ones I can test without mocking. Here’s the complete list:

  • ProcessRequest
  • GetRegistryKeyValue
  • GetRegistryValueKind
  • SetRegistryKeyValue
  • DeleteRegistryKey
  • DeleteRegistryValue
  • OpenSubKey64
  • ParseRegistryHive
  • NotifyAppsOfRegistryChange

Of all these, just one doesn’t require using registry data: ParseRegistryHive. The method’s purpose is to return the hive enum given a string.

        public static RegistryHive ParseRegistryHive(string hiveName)
        {
            if (hiveName.ToUpper() == "HKEY_CLASSES_ROOT") { return RegistryHive.ClassesRoot; }
            else if (hiveName.ToUpper() == "HKEY_CURRENT_USER") { return RegistryHive.CurrentUser; }
            else if (hiveName.ToUpper() == "HKEY_LOCAL_MACHINE") { return RegistryHive.LocalMachine; }
            else if (hiveName.ToUpper() == "HKEY_USERS") { return RegistryHive.Users; }
            else if (hiveName.ToUpper() == "HKEY_CURRENT_CONFIG") { return RegistryHive.CurrentConfig; }
            //last chance, will throw error if invalid
            else return (RegistryHive)Enum.Parse(typeof(RegistryHive), hiveName);
        }

I’m using xUnit.net for my unit testing. xUnit’s Theories are pretty nice, allowing testing sets of data. My tests verify that the method throws errors—or doesn’t—appropriately, and also that it returns the correct hive. I wrote a note to myself about that last one, summed up as:

Lesson 2: Don’t copy/paste any code from your test into the method you’re testing. What if your test has a bug?

    public class RegistryService_ParseRegistryHive_Should
    {
        [Theory]
        [InlineData("HKEY_CLASSES_ROOT")]
        [InlineData("HKEY_CURRENT_USER")]
        [InlineData("HKEY_LOCAL_MACHINE")]
        [InlineData("HKEY_USERS")]
        [InlineData("HKEY_CURRENT_CONFIG")]
        [InlineData("hkey_current_config")]
        public void NotThrowErrorWithValidHive(string name)
        {
            var hive = RegistryService.ParseRegistryHive(name);
        }

        [Theory]
        [InlineData("HKEY_CLASSES_ROOT")]
        [InlineData("HKEY_CURRENT_USER")]
        [InlineData("HKEY_LOCAL_MACHINE")]
        [InlineData("HKEY_USERS")]
        [InlineData("HKEY_CURRENT_CONFIG")]
        public void ReturnCorrectEnumWithValidHive(string name)
        {
            //This basically reproduces the method code. Need to NOT copy/paste from method, but
            //instead rewrite. In TDD, would NOT copy/paste from the test, otherwise there's a danger
            //the test duplicates a wrong condition.
            var hive = RegistryService.ParseRegistryHive(name);
            switch (name)
            {
                case "HKEY_CLASSES_ROOT":
                    Assert.True(hive == Microsoft.Win32.RegistryHive.ClassesRoot);
                    break;
                case "HKEY_CURRENT_USER":
                    Assert.True(hive == Microsoft.Win32.RegistryHive.CurrentUser);
                    break;
                case "HKEY_LOCAL_MACHINE":
                    Assert.True(hive == Microsoft.Win32.RegistryHive.LocalMachine);
                    break;
                case "HKEY_USERS":
                    Assert.True(hive == Microsoft.Win32.RegistryHive.Users);
                    break;
                case "HKEY_CURRENT_CONFIG":
                    Assert.True(hive == Microsoft.Win32.RegistryHive.CurrentConfig);
                    break;
                default:
                    Assert.True(false,name + " didn't return a valid hive. Hive enum returned was " + hive);
                    break;
            }
        }

        [Theory]
        [InlineData("fail")]
        [InlineData("")]
        public void ThrowErrorWithInvalidHive(string name)
        {
            Assert.Throws(() =>  RegistryService.ParseRegistryHive(name));
        }
    }

Act 3 – Testing the Difficult: Mock it, or . . .

I’ve been putting it off long enough. What about the rest of the methods? You know, the ones that could completely screw up my registry?

First, which methods do testable work? Some of them are just wrappers so that I can get back a better error message, for example:

        public static void SetRegistryKeyValue(string keyName, string valueName, string value, RegistryValueKind dataType = RegistryValueKind.String)
        {
            try
            {
                Registry.SetValue(keyName, valueName, value, dataType);
            }
            catch (Exception ex)
            {
                throw new Exception("Error setting registry value keyName '" + keyName + "', valueName '" + valueName + ", value '" + value + "'\r\n" + ex.GetBaseException().Message);
            }
        }

Do I need to test this? Well, I’d like to test that I get back the right exception, so…hmm. OK, let’s see if anyone has mocked the registry.

In the last bullet, I quote from an excellent Stack Overflow response on the subject. In fact, here are two comments.

The research tells me I have two choices:

  1. Mock the concrete Registry class
  2. Use a wrapper around the Registry class

I looked at the Prig example. Whew! That’s a lot of setup! And I’m not prepared to pay for TypeMock or JustMock, though I expect they’re excellent.

This means wrapping the Registry class. Before I try out SystemWrapper, I’m going to create my own wrapper. I want to understand what’s involved. (This is self-education, after all!) The methods I’m using are:

Registry.GetValue
Registry.SetValue
RegistryKey.GetValueKind
RegistryKey.DeleteSubKey
RegistryKey.DeleteValue
RegistryKey.OpenBaseKey
RegistryKey.OpenBaseKey.OpenSubKey

All right, boys! Wrap…That…Code!!!

I had to rethink my whole approach to my RegistryService class, which consumes the Microsoft.Win32.Registry. Originally I wrote it as a static class, since it didn’t need to be instantiated. But this class now could depend on different “registry providers.” I want to protect the class from being misused. A static SetRegistryProvider method won’t work, because of the danger that in production one caller sets it one way and another sets it differently. It’s the same as if a class could use more than one database back end; you wouldn’t make it static. The solution was to remove static, and make the class entirely instance-able.

Moving on, the Registry wrapper is pretty straight forward. The oddity is that I’m wrapping a static class in an instance.

    public interface IRegistryWrapper
    {
        object GetValue(string keyName, string valueName, object defaultValue);
        void SetValue(string keyName, string valueName, object value, RegistryValueKind valueKind);
    }

    public class RegistryWrapper : IRegistryWrapper
    {
        public object GetValue(string keyName, string valueName, object defaultValue)
        {
            return Registry.GetValue(keyName, valueName, defaultValue);
        }

        public void SetValue(string keyName, string valueName, object value, RegistryValueKind valueKind)
        {
            Registry.SetValue(keyName, valueName, value, valueKind);
        }
    }

The RegistryKey wrapper presented a challenge. The constructor for RegistryKey is private. You cannot create an instance of RegistryKey this way:

RegistryKey key = new RegistryKey(); //this won't compile

Instead, instances are created using the static method OpenBaseKey().

RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);

My abstraction needs to be clear, I want to create an interface, but interfaces can’t have static members.

A base key is required for RegistryKey to function, therefore it’s required for my wrapper to function. But the RegistryService class, which uses RegistryKey, encapsulates which base key will be used; each method could instantiate its own RegistryKey with different base keys. For example:

public void DeletePluginVersionValue(string id)
{
    //_registryKey was injected via the constructor
    RegistryKey basekey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
    using (RegistryKey key = basekey.OpenSubKey(@"SOFTWARE\EduAgent\RegistryPlugin", false))
    {
        key.DeleteValue("Value");
        key.Close();
    }
}

My abstracted class is going to work similarly.

public void DeletePluginVersionValue(string id)
{
    //_registryKey was injected via the constructor
    IRegistryKeyWrapper basekey = _registryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
    using (IRegistryKeyWrapper key = basekey.OpenSubKey(@"SOFTWARE\EduAgent\RegistryPlugin",false))
    {
        key.DeleteValue("Value");
        key.Close();
    }
}

But for testing, I need to pass in a non-null class instance that implements an interface, but does not have a base class yet. I can’t do this:

    public interface IRegistryKeyWrapper: IDisposable
    {
        IRegistryKeyWrapper OpenSubKey(string name, bool writable);
        //originally static
        IRegistryKeyWrapper OpenBaseKey(RegistryHive hKey, RegistryView view);
    }

    public class RegistryKeyWrapper : IRegistryKeyWrapper
    {
        private RegistryKey _baseKey;
        private RegistryKeyWrapper(RegistryKey key)
        {
            _baseKey = key;
        }
        //etc.

Why not? Follow along.

The RegistryService constructor:

    public class RegistryService
    {
        private IRegistryWrapper _registry;
        private IRegistryKeyWrapper _registryKey;

        public RegistryService(IRegistryWrapper registry, IRegistryKeyWrapper key)
        {
            _registry = registry;
            _registryKey = key;
        }

Using the RegistryService:

//this won't compile; RegistryKeyWrapper requires base key!
RegistryService service = new RegistryService(new RegistryWrapper(), new RegistryKeyWrapper());

I need to be able to create a new RegistryKeyWrapper(), but my live registry wrapper right now requires an actual registry base key. The (unfortunate) solution is to allow the user to create an instance of the class that can’t work.

    public class RegistryKeyWrapper : IRegistryKeyWrapper
    {
        private RegistryKey _baseKey;

        /// 
        /// Note the class can't be used until instantiated using OpenBaseKey or setting to another RegistryKeyWrapper.
        /// This constructor is here to allow an instance to be passed via dependency injection.
        /// 
        public RegistryKeyWrapper() { }

        private RegistryKeyWrapper(RegistryKey key)
        {
            _baseKey = key;
        }

In the RegistryService example, above, if the user were to use _registryKey immediately, without setting it using OpeBaseKey, it would fail because the private variable _baseKey has not been set.

I wouldn’t call this ideal, but it does allow us to test the class.

EDIT 8/31/16
-------------------------------------------------------------

Not only is it not ideal, but it’s not even good. What I’m trying to do is wrap RegistryKey in a pass-through manner. But that’s a mistake, because it implements IDisposable and in my wrapper I should not implement IDisposable.

In a later post, I’ll explain how I rewrote my RegistryKey wrapper in a better way. It doesn’t affect the validity of the info in this post.

-------------------------------------------------------------

First, I’ll fix up my previous tests for ParseRegistryHive that relied on Registry. In my unit test project I create the mock classes. At this point, I don’t even make the classes work, since ParseRegistryHive doesn’t depend on any methods.

    class RegistryMock : IRegistryWrapper
    {
        public object GetValue(string keyName, string valueName, object defaultValue)
        {
            throw new NotImplementedException();
        }

        public void SetValue(string keyName, string valueName, object value, RegistryValueKind valueKind)
        {
            throw new NotImplementedException();
        }
    }

And update a test to use the new service, passing in the mocks.

        IRegistryWrapper _registry = new RegistryMock();
        IRegistryKeyWrapper _registryKey = new RegistryKeyMock();
                
        [Theory]
        [InlineData("HKEY_CLASSES_ROOT")]
        [InlineData("HKEY_CURRENT_USER")]
        [InlineData("HKEY_LOCAL_MACHINE")]
        [InlineData("HKEY_USERS")]
        [InlineData("HKEY_CURRENT_CONFIG")]
        [InlineData("hkey_current_config")]
        public void NotThrowErrorWithValidHive(string name)
        {
            var service = new RegistryService(_registry, _registryKey);
            var hive = service.ParseRegistryHive(name);
        }

Now, create a test for the RegistryMock.

    public class RegistryService_GetRegistryKeyValue_Should
    {
        IRegistryWrapper _registry = new RegistryMock();
        IRegistryKeyWrapper _registryKey = new RegistryKeyMock();

        [Fact]
        public void ReturnNullConstantTextIfValueIsMissing()
        {
            var service = new RegistryService(_registry, _registryKey);
            var result = service.GetRegistryKeyValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgent", "Version");
            Assert.Equal(result, service.NoValue);
        }
    }

Which requires RegistryMock.GetValue to be implemented:

    class RegistryMock : IRegistryWrapper
    {
        public object GetValue(string keyName, string valueName, object defaultValue)
        {
            //this may become cumbersome, but for now specify some return values
            switch (keyName)
            {
                case @"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgent":
                    if (valueName == "Version") return defaultValue;
                    break;
            }
            throw new Exception("Invalid keyName");
        }

Running the test, it passes.

Next up, using the RegistryKeyMock. Here’s the test:

    public class RegistryService_OpenSubKey64_Should
    {
        IRegistryWrapper _registry = new RegistryMock();
        IRegistryKeyWrapper _registryKey = new RegistryKeyMock();

        [Fact]
        public void ThrowExceptionWhenUsingInvalidKey()
        {
            var service = new RegistryService(_registry, _registryKey);
            var ex = Assert.Throws(() => service.OpenSubKey64(@"HKEY_LOCAL_MACHINE\SOFTWARE\EduAgentMissing"));
            Assert.Equal("Error opening subkey 'HKEY_LOCAL_MACHINE\\SOFTWARE\\EduAgentMissing'. Operation returned null.", ex.Message);
        }
    }

Here are the relevant methods I had to implement. This one was kind of tricky because I have to set properties that are read only. I’m making use of the latest C# language features to set the value of read only properties in the constructor. I also needed a helper method to return the string representation of a hive name.

    public class RegistryKeyMock : IRegistryKeyWrapper
    {
        public RegistryKeyMock() { }
        public RegistryKeyMock(string name, int subKeyCount, int valueCount, RegistryView view)
        {
            Name = name;
            SubKeyCount = subKeyCount;
            ValueCount = valueCount;
            View = view;
        }

        public string Name { get; }
        public int SubKeyCount { get; }
        public int ValueCount { get; }
        public RegistryView View { get; }

        public IRegistryKeyWrapper OpenBaseKey(RegistryHive hKey, RegistryView view)
        {
            return new RegistryKeyMock(HiveToString(hKey), 10, 10, view);
        }

        public IRegistryKeyWrapper OpenSubKey(string name, bool writable)
        {
            if (name == @"SOFTWARE\EduAgentMissing")
                return null;
            return new RegistryKeyMock(Name + "\\" + name, SubKeyCount, ValueCount, View);
        }

        private string HiveToString(RegistryHive hive)
        {
            string key = "HKEY_";
            if (hive == RegistryHive.ClassesRoot) return key + "CLASSES_ROOT";
            if (hive == RegistryHive.CurrentConfig) return key + "CURRENT_CONFIG";
            if (hive == RegistryHive.CurrentUser) return key + "CURRENT_USER";
            if (hive == RegistryHive.LocalMachine) return key + "LOCAL_MACHINE";
            if (hive == RegistryHive.Users) return key + "USERS";
            return "";
        }
    }

Test it, it passes, love those green lights!

Tag

This was like a special made-for-TV movie of Fantastic Journey. With all the stuff I’ve done, what haven’t I? Well, there are two big ones:

But I’m leaving those for a future post. Otherwise, like our intrepid explorers, I’ll be canceled and never get back to my own time and place.

Thursday, August 18, 2016

Catching Up on Coding - TDD Part 1

I’ve been a software developer for twenty years, but am behind in some skills. This series chronicles my self-improvement.

There are some pretty high-tech tools out there, but nothing that matches the inspiration provided in the 70s TV show “Search” (originally “Probe”). I don’t have Burgess Meredith, a Probe Scanner or a catchy theme song to help me out, so, like Hugh O’Brian, I’ll have to rely on my wits and Test Driven Development (TDD).

Previously, on CUOC: The Syllabus.
Next Episode: TDD Part 2

 

Teaser

I’m not truly new to TDD. I wrote a (not very good) unit testing framework for Visual Basic 6 back in 2000. I’ve used TDD in professional projects. But now it’s time to make it a habit. To do that, I need a crash coarse, then retrofit my EduAgent code (applying “Test Eventually Development”) before writing new code.

Act 1 – The Elemental Education

Let’s give primary credit where it’s due. I read James Bender’s blog 30 Days of TDD. Bender’s series is very good overall. He does—frustratingly--have sloppy grammar and punctuation errors in every post. But his information is otherwise clear and solid. In fact, his description of SOLID is one of the best I’ve read. Thanks, James!

But first things first: what problem was TDD trying to solve?

Programmers, being human, don’t like to test our work. Most of us find it as hard as writers self-editing or composers checking for wrong notes. We like QA departments because they find our (careless) mistakes for us. We pretend to hate QA, because we pretend we’re egotistical Greek gods incapable of flaw.

Unit testing frameworks allowed testing the public interface of our classes. But that wasn’t enough. Kent Beck encouraged an upside-down approach to writing code, where we write a failing test first, then make it pass. This naturally builds up a library of tests that can be run quickly, reducing the chance of new features breaking the application, and building developer confidence. It also turned out that creating easily testable methods led to generally more maintainable code. Thus, some people revised TDD to mean test-driven design.

What are the elements of TDD? What’s needed to build testable code?

Elements

  • Test framework such as NUnit and xUnit.net
  • Test runner, for executing tests and viewing results.
  • Dependency Inversion (depend on abstractions) and Dependency Injection (decouple dependencies). Both are covered pretty well in this article.
  • Mocking (control results from external resources, such as databases)
  • Refactoring (improving code maintainability without changing the public interface)

Act 2 – Some Code, a Test

Here’s a simple example of TDD, creating code that needs to be tested, and problems with it. I’m using xUnit.Net because I’ve always liked it. I won’t go into how to set up your environment; you can learn that at Getting Started with xUnit.net. However, I do have three tips for using the VS Test Runner (which you open via Test > Windows > Test Explorer).

  • Tear off the Test Explorer into its own window, so that you can easily resize and see all the tests.
    image
  • Group the test results by class
    image
  • In your unit test project, add an app.config file with the following setting. This causes the result to display only the method name instead of the fully qualified name.
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <add key="xunit.methodDisplay" value="method"/>
      </appSettings>
    </configuration>
    

Our contrived application helps teachers grade coursework. We’re writing a class dealing with the coursework, and we’re consuming a third-party service—GradeMark—that returns a grade. One challenge, however, is we don’t control the grade that GradeMark returns given a set of scores. It depends on however the school has configured it. So, today 90% or higher could be an “A,” but tomorrow 93% or higher could be an “A.”

Our CourseWork class will have two methods. One that returns a percentage, and the other that returns a grade message. The grade in the message will come from the GradeMark “service,” and we’ll eventually have to mock that service.

First, in CourseWork, create a GetPercent function that doesn’t work. We want a failing test.

    public class CourseWork
    {
        public decimal GetPercent(decimal actual, decimal maximum)
        {
            throw new NotImplementedException();
        }
    }

In the unit tests project, create the test. Notice the naming convention I’m using along with nested classes; this will help make the test results readable. There are lots of naming conventions out there. Consistency and clarity are the big deals.

Our first test checks that we get back a percent in a particular format. We want “a hundred percent” to return as 100.00.

    public class BasicTdd
    {
        public class CourseWork_GetPercent_Should
        {
            [Fact]
            public void Return100PercentAs100PointZero()
            {
                var cw = new CourseWork();
                decimal percent = cw.GetPercent(100, 100);
                Assert.Equal(100m, percent);
            }
        }
    }

Run it and it fails.

image

Write enough code for the test to pass.

        public decimal GetPercent(decimal actual, decimal maximum)
        {
            decimal result = (actual / maximum) * 100m;
            return result;
        }

Run the test and it passes.

image

Our next test will check if the result is rounded. This does not depend on the first test; they could be run in reverse order.

    public class BasicTdd
    {
        public class CourseWork_GetPercent_Should
        {
            [Fact]
            public void RoundPercentToTwoDecimalPlaces()
            {
                var cw = new CourseWork();
                var percent = cw.GetPercent(1, 7);
                var roundedPercent = Math.Round(percent, 2);
                Assert.Equal(roundedPercent, percent);
            }
        }
    }

Run it, and it fails.

image

Update the code to make it pass.

        public decimal GetPercent(decimal actual, decimal maximum)
        {
            decimal result = Math.Round((actual / maximum) * 100m,2);
            return result;
        }

image

That’s enough to demonstrate a basic test. Now, on to something that will require mocking.

Act 3 – Mocu-mental Grades

Let’s create a class that represents our fictional third-party service, GradeMark. Remember, it returns a grade when supplied a percent, but we can’t depend on what that grade will be. For our dummy service, we won’t even use the percent parameter.

    public class GradeMarkService
    {
        public string GetGrade(decimal percent)
        {
            var rnd = new Random();
            int code = rnd.Next(65, 70);
            return ((char)code).ToString();
        }
    }

We’re just returning a random letter A-D (no failures in our courses!). Back in our CourseWork class, we’ll start a function that returns a grade, and write a test for it that will fail. Here’s the test.

        public class CourseWork_GetGradeMessage_Should
        {
            [Fact]
            public void ReturnTheCorrectlyFormattedMessage()
            {
                var cw = new CourseWork();
                string msg = cw.GetGradeMessage(4, 15); //these values don't matter
                string expected = "The grade is B";
                Assert.Equal(expected, msg);
            }
        }

What we’re testing is getting the expected message text. We’re not testing if GetPercent works, and we’re not testing if the GradeMark service works. When we run the test, it fails, so we write this code to try to make it pass. Some people would say that we shouldn’t bother with the GradeMark service yet, but let’s assume we’re at that point.

        public string GetGradeMessage(decimal actual, decimal maximum)
        {
            var service = new GradeMarkService();
            return "The grade is " + service.GetGrade(GetPercent(actual, maximum));
        }

We got lucky; it failed. But, remember, we can’t guarantee what letter grade will be returned. It could have passed. Run the tests enough times and it will pass.

image

Our GetGradeMessage function has a dependency on the GradeMark service, and is tightly coupled to it. We need to loosely couple that dependency by injecting it. We could do that at the method level, like this:

        public string GetGradeMessage(decimal actual, decimal maximum, GradeMarkService gradeService)
        {
            return "The grade is " + gradeService.GetGrade(GetPercent(actual, maximum));
        }

But, typically, a service like this is consumed by the class. So, we’ll inject it in the class’s constructor.

    public class CourseWork
    {
        GradeMarkService _gradeService;

        public CourseWork(GradeMarkService gradeService)
        {
            _gradeService = gradeService;
        }

        public string GetGradeMessage(decimal actual, decimal maximum)
        {
            return "The grade is " + _gradeService.GetGrade(GetPercent(actual, maximum));
        }

Great, but that doesn’t really help us, does it? We still need a GradeMarkService to pass in during our test, and control the letter grade it returns. Using some mocking frameworks, it’s possible to mock a legacy object. But in this case, we’re hoping for one of two things from our vendor to make our lives easier.

An Interface

Ideally, our vendor has programmed to an interface, using the Dependency Inversion Principle. We’ll simulate that in our fictional service class.

    public interface IGrader
    {
        string GetGrade(decimal percent);
    }

    public class GradeMarkService: IGrader
    {
        public string GetGrade(decimal percent)
        {
            var rnd = new Random();
            int code = rnd.Next(65, 70);
            return ((char)code).ToString();
        }
    }

Next, we update our class to inject the interface we’re testing, instead of the concrete instance.

public class CourseWork
{ IGrader _gradeService; public CourseWork(IGrader gradeService) { _gradeService = gradeService; }

Our class is now ready for testing. We don’t need the GradeMarkService. We just need our own mock class implementing the required interface. Back in our test project, we’ll create that.

    public class GradeMarkServiceMock: IGrader
    {
        public string GetGrade(decimal percent)
        {
            return "B";
        }
    }

And, update our tests to accept the mock object.

            [Fact]
            public void Return100PercentAs100PointZero()
            {
                var cw = new CourseWork(new GradeMarkServiceMock());
                decimal percent = cw.GetPercent(1, 1);
                Assert.Equal(100m, percent);
            }
            [Fact]
            public void RoundPercentToTwoDecimalPlaces()
            {
                var cw = new CourseWork(new GradeMarkServiceMock());
                var percent = cw.GetPercent(1, 7);
                var roundedPercent = Math.Round(percent, 2);
                Assert.Equal(roundedPercent, percent);
            }
        }

        public class CourseWork_GetGradeMessage_Should
        {
            [Fact]
            public void ReturnTheCorrectlyFormattedMessage()
            {
                var cw = new CourseWork(new GradeMarkServiceMock());
                string msg = cw.GetGradeMessage(4, 15); //these values don't matter
                string expected = "The grade is B";
                Assert.Equal(expected, msg);
            }
        }

When we run our tests a few times, the GetGradeMessage test passes consistently.

An overridable class

Our vendor could also have made the GetGrade method overridable. In that case, we’d create a mock object, override GetGrade, and always return “B”. But with a significant object, there could be many problems doing that. It’s best if we can program against interfaces, because that way  we don’t have to use the original classes at all.

What’s a real-world example? What about a shipping service that our application uses to calculate shipping rates? Several problems could exist in consuming that service instead of mocking it:

  • It could be very slow to use that service in our tests.
  • It could return inconsistent results that affect our tests.
  • We might get charged every time we use the service.

Databases are another example. Testing against a database is difficult because you want the data to always start in a consistent state. Database tests are slow. They are better left for integration tests.

Refactoring

The last step in TDD is making the code better, and also making the tests better. For example, we get an instance of the CourseWork class repeatedly. We can declare that as a class field. xUnit creates a new instance of the class for each test, so it will will always be a new instance of CourseWork.

    public class BasicTdd
    {
        public class CourseWork_GetPercent_Should
        {
            public CourseWork _cw = new CourseWork(new GradeMarkServiceMock());

            [Fact]
            public void Return100PercentAs100PointZero()
            {
                decimal percent = _cw.GetPercent(1, 1);
                Assert.Equal(100m, percent);
            }
            [Fact]
            public void RoundPercentToTwoDecimalPlaces()
            {
                var percent = _cw.GetPercent(1, 7);
                var roundedPercent = Math.Round(percent, 2);
                Assert.Equal(roundedPercent, percent);
            }
        }

        public class CourseWork_GetGradeMessage_Should
        {
            public CourseWork _cw = new CourseWork(new GradeMarkServiceMock());

            [Fact]
            public void ReturnTheCorrectlyFormattedMessage()
            {
                string msg = _cw.GetGradeMessage(4, 15); //these values don't matter
                string expected = "The grade is B";
                Assert.Equal(expected, msg);
            }
        }
    }

Of course, rerun the tests and make sure they pass!

Tag

Test-driven development isn’t natural at first. But it’s got a rat-hits-food-lever pleasure I can’t deny. Kind of like having Probe Control’s Angel Tompkins whispering in my ear.

References

30 Days of TDD

Getting Started with xUnit.net

xUnit: display only method name

xUnit: Shared Context Between Tests

7 Popular Unit Test Naming Conventions

Naming standards for unit tests

An Absolute Beginner's Tutorial on Dependency Inversion Principle

Thursday, July 28, 2016

Writing to the Current User(s) Registry When Running as System

In a project I’m working on, I need to change the Group Policy Object (GPO) registry settings, both for the computer and for the logged in user. Both of these present problems. This article addresses the logged in user scenario.

The actual application is a Windows service running on the client that accepts requests from a remote machine. The complication is that the service will need to run as System so that it can write to any part of the registry.

Below is prototyping and troubleshooting using a Console application.

Goal

Run a Console application as the System user and write to the GPO that restricts running applications. Here’s the GPO if you want to look it up in Group Policy Editor (gpedit.msc).

User Configuration\Administrative Templates\System\Don't run specified Windows applications.

Challenges/Issues

64-bit Windows has both logical and physical registry entries. This is a problem when updating keys that are used by other programs (in this case, Windows itself). You have to be sure you’re updating the right key. The problem really presents itself when writing to the LOCAL_MACHINE hive. The physical location—such as the Wow6432Node key—depends on whether the application is 64 or 32 bits.

The CURRENT_USER hive doesn’t care about 64/32 bits. But remember that a computer can have multiple users logged on. Also, where does the System user’s settings go? Finally, how will we find out who is logged in? What a mess!

Tools and Environment

I’m running Visual Studio 2015 Community on 64-bit Windows 10.

This is the registry key/value we’ll be creating throughout, setting its value to 1.

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\DisallowRun

Test Writing to the Registry

We first need to write to the registry and see the results. Create a Console Application with the following code.

using System;
using Microsoft.Win32;

namespace RegistryPrototyping
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                WriteRegistry();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.GetBaseException().Message);
            }
            Console.WriteLine("Finished. Press any key to close.");
            Console.ReadLine();
        }

        static void WriteRegistry()
        {
            string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";
            string valueName = "DisallowRun";
            string value = "1";
            RegistryValueKind dataType = RegistryValueKind.DWord;
            Registry.SetValue(keyName, valueName, value, dataType);
        }
    }
}

Run the application. You should get an error

Access to the registry key 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer' is denied.

This is our first problem. Our code needs permissions to write to the registry.

For some developers, this problem will be hidden because they turn off UAC or always run Visual Studio as administrator. I don’t do either of these exactly because I’ll catch some permissions issue early.

The obvious next step is to close our app, open Visual Studio using Run as Administrator, then reopen/run the app.

image

No error, and the key is written to the expected registry key (i.e. the currently logged in user).

image

Great! Next task, testing as Local System.

But first, delete the DisallowRun key!

Testing as Local System

We need to run our app—either the .exe or Visual Studio—as Local System. I didn’t find a built-in Windows way to do this. The recommended method is to use Sysinternals’ psexec utility, which is normally used to execute commands on remote domain machines.

  1. Download psexec.
  2. Open a command prompt As Administrator (you must do this), and navigate to the folder where you extracted psexec.exe.
  3. Launch the desired application with the –i and –s switches. These run the application locally in interactive mode under the System account.

I right-clicked on my Visual Studio icon > Properties to get the path, and ended up with this command.

psexec –i –s “C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe"

When you launch this way, you’re running as if logged in under a different profile, so VS will go through its initial startup prompts.

  1. Open your Console solution; you’ll need to navigate to its location via C:\Users\[username].
  2. Run it. Check your registry key. Where the heck is the new value? Because we’re running as System, the registry value will be written to the .Default user key.

image

Well, heck! This obviously isn’t what we want. We need to write to the currently logged on user’s profile. But this result gives us a clue how we’ll solve our problem later.

Impersonation – False Start

At first, impersonation seems like the way to go. If I can just find out who’s currently logged on and working, I should be able to impersonate that user and write to the registry on that user’s behalf.

There are two problems with this.

  1. What if there are multiple users logged on? How do I find out which user is actively working?
  2. Will I need to run with elevated privileges? (hint: yes, of course)

If there are multiple users logged in, I didn’t find a way to determine who is actively using the computer. That seems like a poor requirement anyway. Don’t I care if, for instance, a scheduled task starts running as the logged in (but not active) user? Yes, because I might want my agent to prohibit it. What if it’s a headless system that’s always logged on? Worse, what if I want to run the client on a Windows server (which allows multiple simultaneous users via RDP)?

But maybe someone more clever than me wants to figure this out. There might be a way by looking at the active desktop(s).

The second problem is, for us, the impractical barrier to overcome. Writing to the registry requires elevation. The way we’d be impersonating the user would be to get a handle to a running process, then impersonating via that handle. But the user will not be running a known-elevated process. So, we’d be stuck. As soon as we tried to write to the registry, it would fail. And if we try to elevate the process (if we even could do that), the user would get prompted, defeating the goal of the program.

But we can still do what we want. After all, as System we can write to most parts of the physical registry.

Writing to the User’s Key

When we wrote to the System user’s logical hive CURRENT_USER, we ended up in the physical hive USERS. That’s where all the user registry settings are. CURRENT_USER is a symbolic link, a redirection for the active user. Here’s my computer’s USERS hive:

image

Those long SIDs are the users. If I can get those, I can write to the user’s Group Policy setting.

Step one, revise the WriteRegistry method.

static void WriteRegistry(string sid)
    {
        string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";
        string valueName = "DisallowRun";
        string value = "1";
        keyName = keyName.Replace("HKEY_CURRENT_USER", @"HKEY_USERS\" + sid);
        RegistryValueKind dataType = RegistryValueKind.DWord;
        Registry.SetValue(keyName, valueName, value, dataType);
    }

Step two, crazy lots of code!

You’ll need these addtional references.

using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Diagnostics;
using System.Collections.Generic;

Use a Win32 API function to get the logged on users. This is some deeper stuff, and I didn’t write it. The most I did was put it in a class and make the function return all the users.

The meat of this—the cool part—is using Process.GetProcessesByName with an argument of “explorer”. This will return anyone logged on, because explorer is (typically) always running.

class WindowsIdentityHelper
{

    [DllImport("advapi32", SetLastError = true),
    SuppressUnmanagedCodeSecurityAttribute]
    static extern int OpenProcessToken(
    System.IntPtr ProcessHandle, // handle to process
    int DesiredAccess, // desired access to process
    ref IntPtr TokenHandle // handle to open access token
    );

    [DllImport("kernel32", SetLastError = true),
    SuppressUnmanagedCodeSecurityAttribute]
    static extern bool CloseHandle(IntPtr handle);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
    int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

    public const int TOKEN_ASSIGN_PRIMARY = 0x0001;
    public const int TOKEN_DUPLICATE = 0x0002;
    public const int TOKEN_IMPERSONATE = 0x0004;
    public const int TOKEN_QUERY = 0x0008;
    public const int TOKEN_QUERY_SOURCE = 0x0010;
    public const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
    public const int TOKEN_ADJUST_GROUPS = 0x0040;
    public const int TOKEN_ADJUST_DEFAULT = 0x0080;
    public const int TOKEN_ADJUST_SESSIONID = 0x0100;
    public const int TOKEN_READ = 0x00020000 | TOKEN_QUERY;
    public const int TOKEN_WRITE = 0x00020000 | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT;
    public const int TOKEN_EXECUTE = 0x00020000;

    public static List GetLoggedOnUsers()
    {
        List users = new List();
        string errs = "";
        IntPtr hToken = IntPtr.Zero;
        //Get a process that will always be available.
        foreach (Process proc in Process.GetProcessesByName("explorer"))
        {
            try
            {
                if (OpenProcessToken(proc.Handle,
                TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
                ref hToken) != 0)
                {
                    WindowsIdentity newId = new WindowsIdentity(hToken);
                    CloseHandle(hToken);
                    users.Add(newId);
                }
                else
                {
                    errs += String.Format("OpenProcess Failed {0}, privilege not held\r\n", Marshal.GetLastWin32Error());
                }

            }
            catch (Exception ex)
            {
                errs += String.Format("OpenProcess Failed {0}\r\n", ex.Message);
            }
        }
        if (errs.Length > 0) { throw new Exception(errs); }
        return users;
    }

And a method to write to the users’ registries.

static void WriteToLoggedOnUsers()
{
    foreach (var user in WindowsIdentityHelper.GetLoggedOnUsers())
    {
        try
        {
            WriteRegistry(user.Owner.Value);
            Console.WriteLine("Updated user " + user.Name + "  SID " + user.Owner.Value);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetBaseException().Message);
        }
    }
}

 

Notice we’re using WindowsIdentity.Owner.Value to return the SID. The property .Owner.AccountDomainSid doesn’t return the full, correct SID.

Finally, change the Main method.

static void Main(string[] args)
{
    try
    {
        WriteToLoggedOnUsers();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.GetBaseException().Message);
    }
    Console.WriteLine("Finished. Press any key to close.");
    Console.ReadLine();
}

One last thing before running the app. If you really want to test it, create a local user (named Test would be good), log that user on, leave it running and switch back to your regular user.

Now, run the application.

image

Check those User SIDs!

image

image

And finally, to prove the redirection, we’ll look at our CURRENT_USER hive.

image

(Remember, now, to delete those keys. You might also log off and delete the test user.)

Wrap Up

Our goal was to write to the logged on users’ Group Policy keys, with the future intention of preventing them from running certain applications. We need to do this running as System, and found that impersonation wouldn’t work because we had use an elevated process. Instead, we wrote to the running users’ physical registry keys.

One interesting aspect of this session is that there’s not a certain automated way to test for correctness. If I wrote a test that looked at a logical key (like CURRENT_USERS\…), and then checked if the value existed, I wouldn’t know if the correct physical key was updated. This may be a time when a human needs to test. (Maybe there’s a clever way around this, though.)

Full source code can be found after the References.

References

Registry Redirector

Registry Keys Affected by WOW64

Group Policy Object – Disallow Run

WindowsIdentity.Impersonate

Using OpenProcessToken  <=this is where the Win32 code came from. Very useful.

OpenProcessToken function

OpenProcessToken Access Rights

Constants for Token Access Rights

Process.GetProcessesByName

My machine’s named Nesbit, after the great children’s fantasy author.

Full Source

using System;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Diagnostics;
using System.Collections.Generic;

namespace RegistryPrototyping
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                WriteToLoggedOnUsers();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.GetBaseException().Message);
            }
            Console.WriteLine("Finished. Press any key to close.");
            Console.ReadLine();
        }

        static void WriteRegistry(string sid)
        {
            string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";
            string valueName = "DisallowRun";
            string value = "1";
            keyName = keyName.Replace("HKEY_CURRENT_USER", @"HKEY_USERS\" + sid);
            RegistryValueKind dataType = RegistryValueKind.DWord;
            Registry.SetValue(keyName, valueName, value, dataType);
        }

        static void WriteRegistry()
        {
            string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";
            string valueName = "DisallowRun";
            string value = "1";
            RegistryValueKind dataType = RegistryValueKind.DWord;
            Registry.SetValue(keyName, valueName, value, dataType);
        }

        static void WriteToLoggedOnUsers()
        {
            foreach (var user in WindowsIdentityHelper.GetLoggedOnUsers())
            {
                try
                {
                    WriteRegistry(user.Owner.Value);
                    Console.WriteLine("Updated user " + user.Name + "  SID " + user.Owner.Value);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.GetBaseException().Message);
                }
            }
        }
    }
}


class WindowsIdentityHelper
{

    [DllImport("advapi32", SetLastError = true),
    SuppressUnmanagedCodeSecurityAttribute]
    static extern int OpenProcessToken(
    System.IntPtr ProcessHandle, // handle to process
    int DesiredAccess, // desired access to process
    ref IntPtr TokenHandle // handle to open access token
    );

    [DllImport("kernel32", SetLastError = true),
    SuppressUnmanagedCodeSecurityAttribute]
    static extern bool CloseHandle(IntPtr handle);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
    int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

    public const int TOKEN_ASSIGN_PRIMARY = 0x0001;
    public const int TOKEN_DUPLICATE = 0x0002;
    public const int TOKEN_IMPERSONATE = 0x0004;
    public const int TOKEN_QUERY = 0x0008;
    public const int TOKEN_QUERY_SOURCE = 0x0010;
    public const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
    public const int TOKEN_ADJUST_GROUPS = 0x0040;
    public const int TOKEN_ADJUST_DEFAULT = 0x0080;
    public const int TOKEN_ADJUST_SESSIONID = 0x0100;
    public const int TOKEN_READ = 0x00020000 | TOKEN_QUERY;
    public const int TOKEN_WRITE = 0x00020000 | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT;
    public const int TOKEN_EXECUTE = 0x00020000;

    public static List GetLoggedOnUsers()
    {
        List users = new List();
        string errs = "";
        IntPtr hToken = IntPtr.Zero;
        //Get a process that will always be available.
        foreach (Process proc in Process.GetProcessesByName("explorer"))
        {
            try
            {
                if (OpenProcessToken(proc.Handle,
                TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
                ref hToken) != 0)
                {
                    WindowsIdentity newId = new WindowsIdentity(hToken); 
                    CloseHandle(hToken);
                    users.Add(newId);
                }
                else
                {
                    errs += String.Format("OpenProcess Failed {0}, privilege not held\r\n", Marshal.GetLastWin32Error());
                }

            }
            catch (Exception ex)
            {
                errs += String.Format("OpenProcess Failed {0}\r\n", ex.Message);
            }
        }
        if (errs.Length > 0) { throw new Exception(errs); }
        return users;
    }

}