Unit Test parallel execution of static classes or ServiceLocator

Please note that I am NOT promoting an anti-pattern or code smell here. I know using the service locator or static classes that hold the state or cause the side-effect are not in everyone’s favor but let’s face it. Life is not perfect. What if you happen to be in a decade old legacy project that heavily depends on static classes or service locator pattern? But it shouldn’t stop you from adding the unit tests if you want.

Source Code for Test Project: https://github.com/michaelsync/Michael-Sync-s-blog-sample/tree/master/XunitTestsParallel

Mocking Static Classes

The problem with the static class is that you can’t mock them unless your mocking library supports it. Here is the list of mock libraries (both free and commercial) that supports the static class mocking in .NET world.

Let’s say we are using Microsoft Fakes. You can mock the DateTime.Now as below.

// Shims can be used only in a ShimsContext:
            using (ShimsContext.Create())
            {
              // Arrange:
                // Shim DateTime.Now to return a fixed date:
                System.Fakes.ShimDateTime.NowGet = 
                () =>
                { return new DateTime(fixedYear, 1, 1); };

                // Instantiate the component under test:
                var componentUnderTest = new MyComponent();

              // Act:
                int year = componentUnderTest.GetTheCurrentYear();

              // Assert: 
                // This will always be true if the component is working:
                Assert.AreEqual(fixedYear, year);
            }

It’s pretty easy, huh? What about the service locator?

Mocking Service Locator

Mocking the service locator is very easy as well since it allows us to set the mock locator using

ServiceLocator.SetLocatorProvider()

method.

The example below shows how to mock the service locator using Moq in xunit test.


public class TestClass1 {

        public TestClass1() {
            var mock = new Mock<IDataStore>();
            mock.Setup(m => m.GetData())
                .Returns(1); /* Returns 1 from TestClass1 */

            var mockServiceLocator = new Mock<IServiceLocator>();
            mockServiceLocator.Setup(ms => ms.GetInstance<IDataStore>())
                .Returns(mock.Object);

            ServiceLocator.SetLocatorProvider(() => mockServiceLocator.Object);
        }

        [Fact]
        private void TestClass1TestMethod1() {
            var data = ServiceLocator.Current.GetInstance<IDataStore>().GetData();
            Assert.Equal<int>(1, data);
        }

        [Fact]
        private void TestClass1TestMethod2() {
            var data = ServiceLocator.Current.GetInstance<IDataStore>().GetData();
            Assert.Equal<int>(1, data);
        }
}

So far so good. What is the problem?

Test Parallelization

Some test frameworks let you run the tests in parallel. For example, xunit 2.0 which is released early this year (March 16, 2015) has a new feature that let the tests from different classes run in parallel by default. (You can read about it in “Parallelism” in the release note or here “Running Tests in Parallel” ). xUnit 2.0 uses the concepts called “Test Collection” to decide which tests can run against each other in parallel. Each test class is a unique test collection and

ParallelizeTestCollections

property is set to true by default.

So, the tests that has the dependency on server locator or static class will be failed randomly with test parallelization but the test will work fine when you run it individually. Because what you setup in one test will be overridden the setup from different test class so the assertion will be failed when the overrides happens.

I have TestClass1 in my previous example above. I will add another class called TestClass2 to show you te random test failture.

 
public class TestClass2 {
        public TestClass2() {
            var mock = new Mock<IDataStore>();
            mock.Setup(m => m.GetData())
                .Returns(2); /* Returns 2 here */

            var mockServiceLocator = new Mock<IServiceLocator>();
            mockServiceLocator.Setup(ms => ms.GetInstance<IDataStore>())
                .Returns(mock.Object);

            ServiceLocator.SetLocatorProvider(() => mockServiceLocator.Object);
        }

        [Fact]
        private void TestClass2TestMethod1() {
            var data = ServiceLocator.Current.GetInstance<IDataStore>().GetData();
            Assert.Equal<int>(2, data);
        }

        [Fact]
        private void TestClass2TestMethod2() {
            var data = ServiceLocator.Current.GetInstance<IDataStore>().GetData();
            Assert.Equal<int>(2, data);
        }
}

Try running all tests a few times after adding the TestClass2. You will see that at least one test out of four tests will be failed randomly. It is because the locator is a static class and what we setup (let’s say we return 1.) in TestClass1 will be overridden by the setup from TestClass2 so the assertion will be failed.

Random Test Failed

How do we fix that?

Initially, I looked at Microsoft Fakes which is shipped with Visual Studio and is also the next generation of Moles. According to the concurrency section of this document, it doesn’t have thread affinity so no go for me.

Shim types apply to all threads in the AppDomain and don’t have thread affinity. This is an important fact if you plan to use a test runner that support concurrency: tests involving shim types cannot run concurrently. This property is not enfored by the Fakes runtime.

Then, I look at Telerik’s JuckMock. The paid version of JuckMock supports what they called “elevated-mocking” that allows you to mock the static class. (Note: The free version “JuckMock Lite” doesn’t support the elevated-mocking. )

So, I refactored my test code as below.


public class TestClass1 {
    private readonly Mock<IServiceLocator> mockServiceLocator;

    public TestClass1() {
        var mock = new Mock<IDataStore>();
        mock.Setup(m => m.GetData())
            .Returns(1);

        mockServiceLocator = new Mock<IServiceLocator>();
        mockServiceLocator.Setup(ms => ms.GetInstance<IDataStore>())
            .Returns(mock.Object);
    }


    [Fact]
    private void TestClass1TestMethod1() {
        Telerik.JustMock.Mock.Arrange<IServiceLocator>(() => ServiceLocator.Current)
            .Returns(mockServiceLocator.Object);

        var data = ServiceLocator.Current.GetInstance<IDataStore>().GetData();
        Assert.Equal<int>(1, data);
    }

    [Fact]
    private void TestClass1TestMethod2() {
        Telerik.JustMock.Mock.Arrange<IServiceLocator>(() => ServiceLocator.Current)
                        .Returns(mockServiceLocator.Object);

        var data = ServiceLocator.Current.GetInstance<IDataStore>().GetData();
        Assert.Equal<int>(1, data);
    }
}

public class TestClass2 {
    private readonly Mock<IServiceLocator> mockServiceLocator;

    public TestClass2() {
        var mock = new Mock<IDataStore>();
        mock.Setup(m => m.GetData())
            .Returns(2);

        mockServiceLocator = new Mock<IServiceLocator>();
        mockServiceLocator.Setup(ms => ms.GetInstance<IDataStore>())
            .Returns(mock.Object);
    }

    [Fact]
    private void TestClass2TestMethod1() {
        Telerik.JustMock.Mock.Arrange<IServiceLocator>(() => ServiceLocator.Current)
            .Returns(mockServiceLocator.Object);

        var data = ServiceLocator.Current.GetInstance<IDataStore>().GetData();
        Assert.Equal<int>(2, data);
    }

    [Fact]
    private void TestClass2TestMethod2() {
        Telerik.JustMock.Mock.Arrange<IServiceLocator>(() => ServiceLocator.Current)
            .Returns(mockServiceLocator.Object);

        var data = ServiceLocator.Current.GetInstance<IDataStore>().GetData();
        Assert.Equal<int>(2, data);
    }
}

Edited: I can’t move Mock.Arrange() to the constructor because I think JustMock has a thread affinity and xunit might use the different thread to call the constructor and test method. That’s why I repeat the code in every test method. End Edited.

Before you run the test, there is a little small thing that you need to do. You need to enable the profiler in Telerik menu.

Enable Profiler

The reason is that JustMock is using the profiling API to enable the elevated mocking. I heard that TypeMock is using the same thing as well. Please read this post if you want to know more about it.

Now, you can run all tests without any failure.

All Tests passed

You can download the sample test project here “https://github.com/michaelsync/Michael-Sync-s-blog-sample/tree/master/XunitTestsParallel“.

That is. Yes. I am not encouraging you to use this feature. If you have the capacity to remove the service locator or static classes from your project then you should probably do that. Otherwise, using the elevated mocking is one way of solving problem.

Tips on compiling NuGetGallery source code and hosting it on IIS

Last week, I tried compiling the source code of NuGetGallery and hosting it on IIS but found some issues. Here is the list of issues/solutions that I found. I am sharing it here. Hope it will save some of your times if you are facing the same issues.

Note that I was using the master branch and the date that I downloaded the source from that branch was 22/09/2015.

Azure SDK

The first error that I got was the compile error. It was because I don’t have an Azure SDK on my VM. Well, I know installing the Azure SDK is one of the prerequisites but I am not going to host it on Azure so I decided to change the path of two assemblies below in NuGetGallery.csproj.

  • Microsoft.WindowsAzure.Diagnostics.dll
  • Microsoft.WindowsAzure.ServiceRuntime.dll

NuGet Gallery team shipped those assemblies under lib/AzureSDK so it’s quite easy to change it.

Wrong Path of Azure DLL

Entity Framework 5 + VS2013 Update 5 issue

I got this error when I tried to update the database.

22-09-2015 1-02-14 PM

It looks like a known issue with EF5+VS2013Update but I found the workaround Update-Database throwing “Could not load file or assembly EntityFramework .. or one of its dependencies” error.

The steps below is the workaround to fix this issue.

  • Start VS Command Prompt as Administrator
  • Go to your packages directory and find the EntityFramework package directory.
  • Go to lib\net45
  • Type: gacutil /i EntityFramework.dll
  • Restart Visual Studio

I managed to update the database after I did those steps but I got the runtime error below when I launch the NuGetGallery project.

Failed to set Database.DefaultConnectionFactory to an instance of the ‘System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework’ type as specified in the application configuration. See inner exception for details.

{“Could not load file or assembly ‘EntityFramework’ or one of its dependencies. The system cannot find the file specified.”:”EntityFramework”}

so I would suggest that you should uninstall EntityFramework.dll from GAC later.

gacutil /u EntityFramework

RequireSsl

It’s up to you whether you want to have SSL enabled or not. For me, I don’t need it so remove [RequireSsl] attribute from NuGetGallery/Controllers/AuthenticationController.cs.

Remove ReWrite

I don’t want to enable http-rewrite module and when I look at the config, it looks like they are just using it for nuget.org only so I removed the whole re-write session from config.

Remove rewrite

Enable-LocalTestMe

If you are running it from VS, you will have to enable the local test me by running .\Enable-LocalTestMe.ps1 script unless you want to change the configuration manually. but your goal is just to host it on IIS then you don’t have to do it.

Enable_localTestMeinIISExpress

NuGet Push “Method Not Allowed” error

After I manage to run NuGetGallery project, I got another small issue with nuget push.

[16:35:45][push] Failed to process request. ‘Method Not Allowed’.
[16:35:45][push] The remote server returned an error: (405) Method Not Allowed..
[16:35:45][push] Process exited with code 1
[16:35:45][Step 6/6] Step Push To NuGet (NuGet Publish) failed

I removed “WebDEV” from http-handler and module. After that, it works.

 

 

WebDev

I will probably upload the publish file and database schedule later this week or next week.

Where is the EndPoint setting for VM in new Azure portal?

The endpoint settings in VM allows us to configure the incoming traffic such as remote desktop, custom http ports (Teamcity, OctpusDeploy and etc.) to VM. It was pretty easy to find that setting on old HTML5 azure portal https://manage.windowsazure.com.

VM EndPoint Setting in old Azure portal

But you can’t use the new type of VM with a resource manager on old portal so you have no choice but to use the new Azure portal https://portal.azure.com. The problem (at least for me) came when I wanted to open some ports (endpoints) on new VM via new portal. It took me a while to search for it so I thought I will share it here for those who might have same issue.

Let’s see what you will get when you create a new VM with a resource manager.

Microsoft Azure Resource Group

By default, you will get the following things when you create a VM but of course, you have an option to choose what to create or what to re-use during the setup.

  • Virtual machine
  • Network Interface
  • Network Security Group
  • Public IP Address
  • Virtual network
  • Storage Account

Choose “Network Security Group” then you will see the setting page that looks similar to Windows Advanced Firewall interface on windows server or desktop.

 

 

Azure Network Security Group

Click on “Inbound security rules”. This is where you can enable the endpoint of your new VM. Of course, you forget to open the same port in your server OS as well.

Azure VM Firewall

Azure Website: ERROR_PROXY_GATEWAY in deploying an Azure website using MSDeploy from TeamCity

Error Message

[14:33:45][VSMSDeploy] C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.targets(4270, 5): error ERROR_PROXY_GATEWAY: Web deployment task failed. (Could not connect to the remote computer (“[yoursite].azurewebsites.net”) using the specified process (“Web Management Service”). This can happen if a proxy server is interrupting communication with the destination server. Disable the proxy server and try again. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_PROXY_GATEWAY.)

Solution

There is an official page that contains the list of error codes and possible resolution from IIS. What was suggested for ERROR_PROXY_GATEWAY is as below.

Diagnosis – A proxy gateway is preventing Web Deploy from communicating with the remote Web Deploy endpoint.Resolution – Web Deploy does not read system proxy settings. As a workaround, try disabling the system proxy:

  • Start Internet Explorer
  • Click Tools > Options
  • Click Connection
  • Click LAN Settings
  • Disable all checkboxes

It didn’t really help me directly because my build server is on Azure data center in same region where I host my test site and it used to work all the time since long time back. But when I tried to rdp the server then I found that there is a alert for the server restart. So, it seems to me that when the server needed to be restarted then it might limit the connection or something. I was still able to connect the team city website but it was just that msdeploy didn’t work so I did the restart and everything’s back to normal again.

So, if you are getting the same error all of a sudden, try to rdp to your server and see whether there is a restart alert or not. 

Azure WebJob Issue after package update – Host is not running

It took me a while to get the solution for this problem and Google gave me nothing when I search the error (warning) message so I thought its worth to share it here with you all.

Problem

Error Message: Host is not running; requests will be queued but not execute until the host is started

Screenshot

Web Job Issue

Solution

It happened because of the breaking changes in Beta 0.5 version. Azure used to have the problem with same name in different region due to their caching. I beleive that some parts of Azure tools like ‘Visual Studio’s publish dialog to azure’ and ‘SCM’ were not built to support the “same name/multiple regions” or multiple subscriptions in mind. I reported about “Problem: Issue with multiple Azure subscriptions with same name” before.

The solution for this issue is to make the class and method public. It’s an unusual practice for console programs but it’s how it is and it works.


public class Program {

private static Logger _logger = LogManager.GetCurrentClassLogger();

public static void Main(string[] args) {
_logger.Info(&quot;Test Main Started&quot;);
var host = new JobHost();
host.RunAndBlock();
_logger.Info(&quot;Test Main Ended&quot;);
}

public static async Task TestAsync([QueueTrigger(&quot;testqueue&quot;)] string _) {
_logger.Info(&quot;TestAsync Started&quot;);
await Task.Delay(30);
_logger.Info(&quot;TestAsync Ended&quot;);
}
}

And if you toggle the output of your webjob in SCM, you will see this log below. Then you will know that you need to make the class and methods public.

[INFO] No functions found. Try making job classes public and methods public static.

So, That’s it. Hope it helps saving some of your time.

 

Gmail password leaks download? For real? Tvskit – btcsec

A lot of people are changing their Gmail passwords since the news on 5 million Gmail passwords leaked widely spread all over the internet today. According to the new, the user “Tvskit” posted the zip file with the following screenshots in Russion Bitcoin forum.

Tvskit - Gmail Password Leak

Some sources said that the passwords in that file are 60% accurate but old passwords. I followed a few links to get the zip files from different source (including the original btcsec website) and extracted them on a VM. Here is the list of links that I downloaded the files. (Note: I intentionally didn’t link them from my blog. ) Gmail Password Downloads

Here is the size of those Gmail passwords files that I downloaded. Gmail Password Download Sizes

If you are planning to download those files from those websites that I posted in screenshot and the size are the same, don’t bother downloading it. Because those files don’t contain any password and it’s just the list of user names. (4929083 accounts in totals)

Gmail password leaks but no password

A user “cDull” from reddits also shared what they think about what happened as below in this post “5 Millions of “Gmail” passwords leaked [RUS], most likely it’s a compilation of passwords from other sites

That is pretty smart of you, and there are many others that had same idea. Just do a grep for ‘+’ in the gmail account dump and you see a lot of eharmony, filedrop, friendster, bravenet, bioware, savage, xtube, and others if you do the command below. There might be more than 20 different website references in there. This is definitely a compilation and a bunch of bullshit FUD.


grep '+' google_5000000.txt | cut -d+ -f2 | cut -d@ -f1 | sort | uniq -c | sort -h | tail -n 21
18 bravenet
18 filesavr
19 policeauctions
25 4
27 eh
28 3
32 freebiejeebies
40 hon
51 bryce
52 savage2
54 bioware
57 spam
60 2
62 savage
63 friendster
64 eharmony
66 daz3d
88 filedropper
125 1
132 daz
176 xtube

If you managed to get the file then don’t forget to use a VM before extracting the file. Of course, you have the file with passwords then let me know..