Monday, December 5, 2011

PowerShell 3.0 Job Scheduling

One of the brand new features introduced in PowerShell 3.0 is the ability to schedule jobs for execution at a later time. PowerShell doesn't host and run them actually by itself. Windows Task Manager is used to schedule and start jobs. It means when you put down something like this:

$trigger = New-JobTrigger -Daily -At 4am

Register-ScheduledJob -Name MyScheduledJob -ScriptBlock { Write-Host 'abc' } -Trigger $trigger

Get-ScheduledJob

the result would look like the following:

PowerShell just manages Windows Task Manager to do all that stuff. All jobs are created under Microsoft\Windows\PowerShell\ScheduledJobs category. So you still can use MMC console to manage all jobs including PowerShell scheduled jobs from the single UI.

Links:
Windows Management Framework 3.0 CTP2 (PowerShell and WinRM)
Windows PowerShell ISE Add-On Tools

Wednesday, July 6, 2011

The project has not been built - Resharper error when run unit tests

If you use Reshaper's Unit Test Explorer to run unit tests sooner or later you may run into an error dialog which says "The project X.X has not been built".


The reason of that is simple enough - just verify in Visual Studio Configuration Manager that your test projects are marked to be build.


Each time you run tests in Unit Test Explorer it re-builds the test project. So if it's excluded from the build process in Configuration Manager it won't build and Resharper cannot find the library.

Friday, July 1, 2011

LinkedIn runs on Apache Tomcat

Sometimes it is easy to figure out what server software a website runs. Accidentally it turned out
LinkedIn runs Apache Tomcat 6.

Sunday, June 19, 2011

Apple iMessage brings to mobile the Google Wave expirience

June 6-11 on WWDC 2011 (Worldwide Developer Conference) Apple representatives presented the brand new features of upcoming iOS 5 and MacOS X Lion. The new iOS version will upgrade iPhone 3gs/4, iPod Touch 3rd/4rd generations and iPad 1/2 devices. This major release bring to the scene a new embedded application - iMessage - new messaging service between all iOS devices. It has been already on iPhone for a while and now spread to all devices.




When chatting to the friends you can send the following:
  • text
  • photos
  • video
  • contacts
  • group messages

The iMessage has the following key features:
  • delivery receipts
  • read receipts
  • typing indication
  • messages pushed to all your devices
  • 3G + WiFi
  • secure encryption


Does the user experience of iMessage remind you of something you have seen not so long ago?


In my mind this is the same thing Google Wave does, but all over the mobile devices. Google didn't find the right use of their service and admitted its failure officially. They promised Wave's return in another form. But probably Apple did what Google did not - implemented on the existed mobile devices, solving the real problem, in the right place and right time.

Thumbs up to Apple! Great work!

Thursday, June 16, 2011

How Asserts change the execution flow of unit test

When you write unit tests you need yo check the expected result with the real one at the end. This is exactly what you write the tests for. But keep in mind that it doesn't mean you have to do asserts at the end only. The single test can cover many cases and you can put as many intermediate asserts as you want. As well if-statements may be replaced to asserts when you verify on null.

Let's have a look at the following sample where we verify that tag2 tag has a value in XmlDocument. The original execution flow could look like this:
XmlNode testNode = xmlDocument.DocumentElement.SelectSingleNode( @"/root/tag1/tag2" );
if( testNode != null )
{
    string realValue = testNode.InnerText;
    Assert.AreEqual( expectedValue, realValue, "Wrong tag2 value" );
}
else
{
    Assert.Fail( "tag2 tag is absent in XML" );
}
If statement comes from how the usual checks are done. But we can simplify that snippets in unit test replacing If to Assert.IsNotNull.
Assert.IsNotNull( xmlDocument.DocumentElement, "Wrong XML: the root element is absent." );

XmlNode testNode = xmlDocument.DocumentElement.SelectSingleNode( @"/root/tag1/tag2" );
Assert.IsNotNull( testNode, "tag2 tag is absent in XML." );

string realValue = testNode.InnerText;
Assert.AreEqual( expectedValue, realValue, "Wrong tag2 value" );
Here we used Assert.IsNotNull, but exactly the same way the other methods may be used to replace If-statements. Remember that you can place as meany Asserts as you want and it would not make your tests complex. It would rather simplify them.

Tuesday, June 14, 2011

Comparing two byte arrays in .NET

Doing unit testing we very often need to compare arrays, especially byte arrays dealing with streams. There are many way you can handle the actual comparison, including your own manual compare function, PInvoke int memcmp(byte[] b1, byte[] b2, long count) or something else. If you work with .NET 3.5 or greater, or Silverlight there is a LINQ extension method which does it for you - Enumerable.SequenceEqual. Let's look at how it works and test whether or not its results fit to us.
[TestMethod]
public void SequenceEqual_True_OnTheSame_ByteArrays()
{
    string content = @"hello world";
    string expectedContext = @"hello world";

    ASCIIEncoding encoding = new ASCIIEncoding();

    byte[] contextBytes = encoding.GetBytes( content );
    byte[] expectedContextBytes = encoding.GetBytes( expectedContext );

    bool isEqual = contextBytes.SequenceEqual( expectedContextBytes ); 
            
    Assert.IsTrue( isEqual );
}

[TestMethod]
public void SequenceEqual_IsCaseSensitive()
{
    string content = @"Hello world";
    string expectedContext = @"hello world";

    ASCIIEncoding encoding = new ASCIIEncoding();

    byte[] contextBytes = encoding.GetBytes( content );
    byte[] expectedContextBytes = encoding.GetBytes( expectedContext );

    bool isEqual = contextBytes.SequenceEqual( expectedContextBytes );

    Assert.IsFalse( isEqual );
}
Those tests are all green. So Enumerable.SequenceEqual is most likely fits the needs of comparing arrays.

Monday, June 13, 2011

MSTest ExpectedException and Code Coverage

Recently I've blogged about writing unit tests covering expected exceptions and how to do that using MSTest framework embedded to Visual Studio. The post was about ExpectedException attribute. Today I want to show the disadvantage of ExpectedException usage so you are not surprised.

Let's run the code coverage of the following test where we expect ArgumentNullException raised.
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void Test1()
{
    BlueHornetHttpWebRequest request = new BlueHornetHttpWebRequest();

    try
    {
        HttpWebResponse response = request.GetHttpWebResponse( null );
    }
    catch( ArgumentNullException ex )
    {
        Assert.AreEqual( @"request", ex.ParamName );
        throw;
    }
}
The picture will look like this.

Just because the exception is occurred and re-trowed at the end we cannot reach the 100% coverage, two rows are left uncovered at least.


In comparison the traditional test flow without ExpectedException attribute shows the better result. The only uncovered row is Assert.Fail so you are able to manage it.
[TestMethod]
public void Test1()
{
    BlueHornetHttpWebRequest request = new BlueHornetHttpWebRequest();

    try
    {
        HttpWebResponse response = request.GetHttpWebResponse( null );
        Assert.Fail( "Exception didn't occur as expected" );
    }
    catch( ArgumentNullException ex )
    {
        Assert.AreEqual( @"request", ex.ParamName );
    }
}

So please pay attention to the reasons why unit tests themselves might be not fully covered while they cover the target code well.

Saturday, June 11, 2011

MSTest ExpectedException and How to test Exceptions

Usually programming code has lots of pre-conditions and post-conditions to validate input parameters and a returning result. Those conditions throw exceptions. The exceptions might handle some logic in code as well. This is a good practice in my opinion. We really need to verify all this checks and exceptions somehow. Unit tests come to rescue but how simple and clear the writing such tests could be using MSTest framework.

The first try writing a unit test could look like this. We wrap the the required method call to try-catch block and wait a specific exception to occur - ArgumentNullException in our case. Also we check the parameter name which initiated this exception. Please note that Assert.Fail is required to fail the test execution if an exception doesn't occur when expected.
[TestMethod]
public void Test1()
{
    WebRequestWrapper wrapper = new WebRequestWrapper();

    try
    {
        // the test code goes here
        Stream requestStream = wrapper.GetRequestStream( null );

        Assert.Fail( "Exception didn't occur as expected" );
    }
    catch( ArgumentNullException ex )
    {
        Assert.AreEqual( "request", ex.ParamName );
    }
}
It's quite simple but MSTest gives us the declarative way to wait for exceptions - ExpectedException attribute. Let's look at whether or not it simplifies our code. We add ExpectedException attribute to the test method and pass in the type of expected exception. The test logic should differ then. We don't need Assert.Fail anymore. But instead we should re-throw an exception at the end.
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void Test1()
{
    WebRequestWrapper wrapper = new WebRequestWrapper();

    try
    {
        // the test code goes here
        Stream requestStream = wrapper.GetRequestStream( null );

        // Assert.Fail is gone
    }
    catch( ArgumentNullException ex )
    {
        Assert.AreEqual( "request", ex.ParamName );
        throw;  // but we have to re-throw an exception at the end of test
    }
}
Looks good but until you decide testing few methods in a single test. It means you cannot re-throw at a first fail because the next calls are not executed then. The solution might be collecting occurred exceptions, verifying the count and throwing a single exception at the end.
[TestMethod]
[ExpectedException( typeof( ArgumentNullException ) )]
public void Test1()
{
    List<ArgumentNullException> exceptions = new List<ArgumentNullException>();

    WebRequestWrapper wrapper = new WebRequestWrapper();

    try
    {
        Stream requestStream = wrapper.GetRequestStream( null );
    }
    catch( ArgumentNullException ex )
    {
        Assert.AreEqual( "request", ex.ParamName );
        exceptions.Add( ex );
    }

    try
    {
        Stream responseStream = wrapper.GetResponseStream( null );
    }
    catch( ArgumentNullException ex )
    {
        Assert.AreEqual( "request", ex.ParamName );
        exceptions.Add( ex );
    }

    if( exceptions.Count == 2 )
    {
        throw new ArgumentNullException();
    }
}
We expect two exceptions totally here so we verify that exactly two occurred. This approach is simple but does not handle resolving which exact method failed. Going further let's try to handle two types of exceptions... and we fail. We cannot declare more then one ExpectedException attribute to a single method.

Wednesday, June 8, 2011

Google +1 Buttons Embedding Code


Google just came up with the "share"-alike button similar to Facebook, Twitter and the others have. They called it +1 button. There are 4 different sizes of the button. To get the embedding code you can visit the Web masters site - http://www.google.com/webmasters/+1/button/ and it will look like this:
<!-- Place this tag in your head or just before your close body tag -->
<script type="text/javascript" src="http://apis.google.com/js/plusone.js"></script>

<!-- Place this tag where you want the +1 button to render -->
<g:plusone></g:plusone>
There is a better way to embed +1 button the similar to how Google embeds the Google Analytics counters.
<!-- Place this tag just before your close body tag -->
<script>
(function(d, t) {
    var g = d.createElement(t),
        s = d.getElementsByTagName(t)[0];
    g.async = true;
    g.src = 'https://apis.google.com/js/plusone.js';
    s.parentNode.insertBefore(g, s);
})(document, 'script');
</script>

<!-- Place this tag where you want the +1 button to render -->
<g:plusone></g:plusone>
That way would work much better. Please pay attention that the +1 button doesn't work in Blogger by default but the workaround already exists.


As of today I don't see the need to embed +1 button to blogger manually, Google already did this by themselves.

Tuesday, May 24, 2011

C# Compiler Command Line Options - csc.rsp file

Have you ever looked to csc.exe C# Compiler supporting files? The .NET 4.0 version compiler is located in C:\Windows\Microsoft.NET\Framework\v4.0.30319 folder and has app.config and csc.rsp file. The interesting point here is the purpose of that csc.rsp file. This text file contains command line options that the C# command line compiler (csc.exe) will process as part of every compilation unless the "/noconfig" option is specified in a command line.


By default it references the common .NET Framework libraries such as

/r:Accessibility.dll
/r:Microsoft.CSharp.dll
/r:System.Configuration.dll
/r:System.Configuration.Install.dll
/r:System.Core.dll
/r:System.Data.dll
/r:System.Data.DataSetExtensions.dll
/r:System.Data.Linq.dll
/r:System.Data.OracleClient.dll
/r:System.Deployment.dll
/r:System.Design.dll
/r:System.DirectoryServices.dll
/r:System.dll
/r:System.Drawing.Design.dll
/r:System.Drawing.dll
/r:System.EnterpriseServices.dll
/r:System.Management.dll
/r:System.Messaging.dll
/r:System.Runtime.Remoting.dll
/r:System.Runtime.Serialization.dll
/r:System.Runtime.Serialization.Formatters.Soap.dll
/r:System.Security.dll
/r:System.ServiceModel.dll
/r:System.ServiceModel.Web.dll
/r:System.ServiceProcess.dll
/r:System.Transactions.dll
/r:System.Web.dll
/r:System.Web.Extensions.Design.dll
/r:System.Web.Extensions.dll
/r:System.Web.Mobile.dll
/r:System.Web.RegularExpressions.dll
/r:System.Web.Services.dll
/r:System.Windows.Forms.Dll
/r:System.Workflow.Activities.dll
/r:System.Workflow.ComponentModel.dll
/r:System.Workflow.Runtime.dll
/r:System.Xml.dll
/r:System.Xml.Linq.dll

You can add your own to this file and forget to reference them on builds.