Archive for October, 2008

Loading PowerShell Profiles from Other Script Files

PowerShell profiles are used for loading common scripts, add-in’s, functions, etc into the PowerShell session at startup. There are four different locations where profiles are loaded from:

powershell

You can have four different profiles in Windows PowerShell. The profiles are listed in load order. The most specific profiles have precedence over less specific profiles where they apply.

    • %windir%\system32\WindowsPowerShell\v1.0\profile.ps1

      This profile applies to all users and all shells.

    • %windir%\system32\WindowsPowerShell\v1.0\ Microsoft.PowerShell_profile.ps1

      This profile applies to all users, but only to the Microsoft.PowerShell shell.

    • %UserProfile%\My Documents\WindowsPowerShell\profile.ps1

      This profile applies only to the current user, but affects all shells.

    The Problem

    This works out just fine if you want to write your own profile.ps1 file and load it from one of those areas. For example, you could perform a Set-Alias for MSBuild if you wanted to have “msbuild” run the msbuild file of your choice (2.0, 3.5, etc). But what happens when you want to load an external function that is located in another script?  For example, lets say I have a script called “Convert-Xml.ps1″ on my disk – as shown below (script source):

    function Convert-WithXslt($originalXmlFilePath, $xslFilePath, $outputFilePath)
    {
       ## Simplistic error handling
       $xslFilePath = resolve-path $xslFilePath
       if( -not (test-path $xslFilePath) ) { throw “Can’t find the XSL file” }
       $originalXmlFilePath = resolve-path $originalXmlFilePath
       if( -not (test-path $originalXmlFilePath) ) { throw “Can’t find the XML file” }
       $outputFilePath = resolve-path $outputFilePath
       if( -not (test-path (split-path $originalXmlFilePath)) ) { throw “Can’t find the output folder” }

       ## Get an XSL Transform object (try for the new .Net 3.5 version first)
       $EAP = $ErrorActionPreference
       $ErrorActionPreference = “SilentlyContinue”
       $script:xslt = new-object system.xml.xsl.xslcompiledtransfrm
       trap [System.Management.Automation.PSArgumentException]
       {  # no 3.5, use the slower 2.0 one
          $ErrorActionPreference = $EAP
          $script:xslt = new-object system.xml.xsl.xsltransform
       }
       $ErrorActionPreference = $EAP
       ## load xslt file
       $xslt.load( $xslFilePath )
       ## transform
       $xslt.Transform( $originalXmlFilePath, $outputFilePath )
    }

    The end result is that when I start PowerShell I want to load this function inside of my profile when PowerShell starts up. If that happened I would be able to start PowerShell and type Convert-WithXslt and get the function to work no problem. How do we load an external script into the current session via the profile.ps1 script? Hmm… not so simple at first.

     

    How To Load an External Script Into Your Profile 

    In your profile.ps1 file, you can script it like this (assuming that your profile.ps1 is in one of the locations above):

    # Loads the script into the profile.

    $fileContents = [string]::join([environment]::newline, (get-content -path C:\PowerShellScripts\Convert-Xml.ps1))
    invoke-expression $fileContents

    This will load the script (C:\PowerShellScripts\Convert-Xml.ps1) contents into your profile. Now the function Convert-WithXslt will be available from the shell.

     

    Script Explained

    1. (get-content -path C:\PowerShellScripts\Convert-Xml.ps1) – This opens the script, reads the contents and then returns the entire file. The ( ) are necessary because get-content returns an array of lines of text. ( ) force full evaluation  of the expression. Therefore the full array is returned. Each item in the array is a line of text.
    2. [string]::join([environment]::newline, (get-content -path C:\PowerShellScripts\Convert-Xml.ps1)) – In this script we take the array as shown above, and join it on the new line character. Therefore we have a full string of the file contents.
    3. $fileContents =  … – Now we just set it to a local variable.
    4. invoke-expression $fileContents – This runs the Invoke-expression cmdlet. In a nutshell this command takes the value of whats in $fileContents and runs it in the local session. Therefore, if we have a function declaration inside of that variable, we can then invoke the shell to evaluate that function declaration which in turn will then add that function to the shell’s session. Now your profile can execute whatever is in this script. Functions, aliases, etc.

     

    Taking it a Step Further

    What if you want to have a common set of scripts that everyone on your team should be using? You wont want to have those scattered over 25 PCs. What if you have to update one of them? You’ll have to update 25 machines. No good.

    So here’s a simple script that will go out to a network share, load all the files it finds in the share, and load them into the PowerShell session. Therefore we have now out-sourced our profile declaration to a centralized location. I’m sure there are 10 other ways to do this, but this is the way I stumbled upon it.

    I would put this file in the “%windir%\system32\WindowsPowerShell\v1.0\profile.ps1″ location so that each person who logs onto the machine now has access to the profile.

    # Loads the profile for all users.
    $locationOfScriptsToLoad = “\\YourCorporateShare\PowerShell\”

    $files = (ls -path $locationOfScriptsToLoad -recurse | where { $_.attributes -ne “directory” })

    foreach($file in $files)

        # Load the contents of the file into the profile
        $fileContents = [string]::join([environment]::newline, (get-content -path $file.fullname))
        invoke-expression $fileContents
    }

    Basically, this script will go up to \\YourCorporateShare\PowerShell\  and find all files inside of it – excluding directories (as directories are objects in PowerShell too, I want to exclude them and this is done with the { $_.attributes -ne “directory }. Once we have the file we will loop through each file and load it into the current PowerShell session. This allows you to store all of your shared PowerShell profile needs in one location. As long as this profile.ps1 script is loaded, the person executing PowerShell will have access to all the profile info.

    I hope this helps anyone who is using PowerShell and wants shared profiles.

     

    Downloads

    profile.ps1

    TFS Dependency Replicator Gotcha

    Recently I was working with Dependency Replicator and I ran into an issue.  

     

    Background

    The file that is the “dependency” does not exist in the destination yet. Therefore the replicator fails. If it does not find the destination file in the dependent project location it will fail. In English: In $/TeamProject/Main/SharedBinaries/ there was no “utility.dll”. However, this is EXACTLY where I wanted replicator to PUT the file. Since the file did not exist at the destination, I would receive this error in the event log:

    ———————————–
    Error in Event Viewer:

    Dependency Repliccator error:
    Event Type: Error
    Event Source: DependencyReplicator
    Event Category: None
    Event ID: 0
    Date:  10/23/2008
    Time:  11:24:30 AM
    User:  N/A
    Computer: TFSSERVER
    Description:
    An error occured processing the dependency ‘$/TeamProject/Path/To/Dependency/dependency.dll’ from build ‘TeamProject_CI_20081023.5′ in project ‘TeamProject’. Processing subsequent rules will continue:
    System.IO.DirectoryNotFoundException: Could not find a part of the path ‘C:\DependencyReplicator\TeamProject\Path\To\Dependency\Dependency.dll’.
       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
       at DependencyReplicator.BuildStoreWatcher.ExecuteDependencyReplicationRule(Rule rule, Workspace workspace)
    For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

    ———————

     

    Steps to recreate:

    1. Create two team projects
      1.   -  One being the one which will propogate the dependency (ex: shared utility dll or something). This would output a file called “utility.dll” which would then
          be propogated to other locations.
      2. Other being the project which utilizes the dependency “MytestProject”. DO NOT put the dependency (utility.dll) in this team project anywhere.
    2. Set Depdenency Replicator xml to have the utility.dll file placed somewhere in “MyTestProject”.
    3. Kick off a build for the utililty project. This should kick off the dependency repliccator.
    4. Error (above) occurs.

     

    Work Around

    Place a copy of the “utility.dll” into the destination where the dependency should be. From that point forward you will not have a problem.

     

    The Real Fix

    The real fix is to fix the source code. Since I’m not a developer on the project I whipped up this code (which please note is only POC at this time).

     

    string fullyQualifiedSource = Path.Combine(rule.Event.Data.DropLocation, rule.Source);
    string fullyQualifiedDestination = workspace.GetLocalItemForServerItem(rule.Destination);
    if(status.NumOperations != 0)
    {
    workspace.PendEdit(rule.Destination);
    File.Copy(fullyQualifiedSource, fullyQualifiedDestination, true);
    }
    else
    {
    File.Copy(fullyQualifiedSource, fullyQualifiedDestination, true);
    workspace.PendAdd(rule.Destination);
    }
    

    I’m going to build this hopefully later this week and submit it to the project. :)

    How Did C# Get Its Name?

    It’s an interesting name to say the least. Why the “sharp” symbol? Sometimes newcomers get it incorrect at first (usually people BRAND NEW to programming) and call it “C POUND”. It Almost sounds like a hip-hop thing as the “pound” word has different context in that arena.

    The knocking of fists as a form of greeting, departure or respect. – Urban Dictionary

    But, alas, this is NOT what it means in terms of programming.

     

    Here’s Where The Name Came From

    In the October 3rd 2008 edition of the CIO article “The A-Z of Programming Languages: C#” Naomi Hamilton interviewed the men of men, the one and only, Anders Hejlsberg (lead architect of C# – and other languages Pre c#). In this article he described where the name came from. The C# language was originally called “Cool” but it was changed. Here’s the scoop:

    [CIO] Why was the language originally named Cool, and what promoted the change to C#?

    [AH] The code name was Cool, which stood for ‘C like Object Oriented Language’. We kind of liked that name: all of our files were called .cool and that was kind of cool! We looked seriously at keeping the name for the final product but it was just not feasible from a trademark perspective, as there were way too many cool things out there.

    So the naming committee had to get to work and we sort of liked the notion of having an inherent reference to C in there, and a little word play on C++, as you can sort of view the sharp sign as four pluses, so it’s C++++. And the musical aspect was interesting too. So C# it was, and I’ve actually been really happy with that name. It’s served us well.

     

    Make sense?

    csharpOrigins

    Integration Testing

    Integration Testing

    gear-bevel Purpose: Testing how the layers/tiers/objects integrate with each other.

    When we’re unit testing, we’re testing a single unit of code. We’re testing to see if an addition operation results in what we expect it to.  Does five plus five equal ten? Does this complex calculation f(x) result in y when x = 5? These are the things we’re after with unit testing.

    With integration testing our goal is to test whether or not our components integrate together. Do they speak (interact) as we would expect?

    Example 1: If the “CustomerFacade” (Facade Layer) class interacts with the “CustomerService” (basically, a rules Layer) when we perform the action “CreateNewCustomer”, does it work the way we expect it to?

    Example 2: If the “CustomerService” (A Service Layer Implementation) must access a remote web service, what is the result? What is the result if the network is down? What is the result if the service is up but is throwing exceptions for every call (perhaps the interface changed). These are integration tests.

    A More Refined Definition: At a very basic level integration testing is the combining of two units that have already been tested into a component where the interface between them is tested. In this sense a component is an aggregate of more than one unit. Think of this as two pieces of the application. Perhaps the Customer Facade and the Customer Service. Both handle completely different things (Facade handling the orchestration of the commands, Service handling the execution of a particular command and the order of operations). Each can be tested individually but what happens when we test them together as they are actually going to work within a given system? We now have Integration Testing.

     

    Lets look at a quick example with some diagrams to help solidify this concept.

    Diagram of System:

     

    What We Want to Test: 

    image

     

    The End Goal of Integration Testing: To identify performance, functional and reliability of the given integration.

     

    What we can identify with Integration Tests:

    • Performance/Reliability: If we run 1000 iterations of the same test, does performance degrade? What about 10,000 iterations? What about 100,000? 1M?
    • Incompatibility: The interface between these components may be incorrect. This will usually occur very early in development of the code or in test development.
    • Pattern/Principle Usage: Testing components together can help identify areas in which may need to be refined more. If you realized you’re object is doing a price calculation, a customer age verification and a shopping cart total, you may be doing too many things. Look at the Single Responsibility Principle and the Law of Demeter.
    • Component Functional Testing: Are the objects functioning as we have designed them?

     

    Example of what we want to test:

    In this legacy example we want to test the actual interaction between Legacy and Customer Service. I want to make sure that these two classes work with each other as expected. Our legacy code would look like this:

        public class CustomerFacade
        {
            public void UpdateCustomer(Customer customer)
            {
                CustomerService service = new CustomerService();
                service.SaveCustomer(customer);
    
                // Do some other work ... 
    
            }
        }
    

    We need to re-factor this as we have done in our Unit Testing example. Doing so will turn this class into something  like this:

     

    public class CustomerFacade : ICustomerFacade
    {
        private ICustomerService customerService;
    
        public CustomerFacade(ICustomerService customerService)
        {
            this.customerService = customerService;
        }
    
        public void SaveCustomer(ICustomer customer)
        {
            customerService.SaveCustomer(customer);
            // Do some other work ...
        }
    }
    

    We also need to re-factor the CustomerService class as well…

     

    public class CustomerService : ICustomerService
    {
        private ICustomerRepository customerRepository;
    
        public CustomerService(ICustomerRepository customerRepository)
        {
            this.customerRepository = customerRepository;
        }
    
        public void SaveCustomer(ICustomer customer)
        {
            customer.EditDate = DateTime.Now;
            customerRepository.Update(customer);
        }
    }
    

     

    The reason we re-factored this is because the CustomerService object had a dependency on the CustomerRepository. Using the Extract Interface pattern we are able to eliminate the concrete dependency with an interface. We will be able to mock the repository with a mocking framework like Rhino Mocks or TypeMock Isolator.

    This is very important: The reason we are going to mock the repository is because we are trying to perform an integration test on the Facade and Service layer. I DO NOT want to test the repository integration. That is ANOHTER INTEGRATION TEST.

    Examples of Testing:

    In this test we are going to ensure that the CustomerFacade calls the CustomerService which in turn calls the CustomerRepository. If the CustomerRepository does not get called this means that there is something wrong with our integration because CustomerService calls into CustomerRepository. This is what our “integration expectation” is.

     

    [Test]
    public void Customer_Facade_Should_Not_Throw_With_A_Valid_Customer()
    {
    	MockRepository mockery = new MockRepository();
    	ICustomer customer = mockery.Stub<ICustomer>();
    	ICustomerRepository repositoryMock = mockery.DynamicMock<ICustomerRepository>(); 
    
    	// Lets make sure that the Repository got called.
    	// Review the Fluent Syntax here: http://ayende.com/Wiki/Comparison+of+different+Rhino+Mocks+syntaxes.ashx
    	With.Mocks(mockery)
    	.Expecting(() =>
    	{
    		// Lets make sure that repository gets called.
    		// If this DOES get called, the test will succeed. If it does not
    		// the test will fail, indicating that our integration test is not working.
    		// Which means we have a problem in how our objects are working together.
    		Expect.Call(delegate{repositoryMock.Update(customer);});
    	})
    	.Verify(() =>
    	{
    		ICustomerService service = new CustomerService(repositoryMock);
    		ICustomerFacade facade = new CustomerFacade(service);
    		facade.SaveCustomer(customer);
    	});
    }
    

     

    Now lets update the CustomerService class to throw if the customer age is under 18. Now this isn’t the best architecture for domain logic, but this is for a simple example. If I were to go down a full Domain design example the details of the test would get lost in the details of the classes.

    Here’s the new Customer Service:

     

    public class CustomerService : ICustomerService
    {
        private ICustomerRepository customerRepository;
    
        public CustomerService(ICustomerRepository customerRepository)
        {
            this.customerRepository = customerRepository;
        }   
    
        public void SaveCustomer(ICustomer customer)
        {
            if(customer.Age < 18)
            {
                throw new ApplicationException("Only customers over the age of 18 can purchase. Sorry!");
            }
            customer.EditDate = DateTime.Now;
            customerRepository.Update(customer);
        }
    }
    

     

    Now lets write our test …  This test should thrown an Application Exception if the customers age is under 18.

     

    [Test]
    public void Customer_Facade_Should_Throw_With_An_InValid_Customer()
    {
    	MockRepository mockery = new MockRepository();
    	ICustomer customer = mockery.Stub<ICustomer>();
    	customer.Age = 13;
    	ICustomerRepository repositoryMock = mockery.DynamicMock<ICustomerRepository>();
    
    	// Lets make sure that the Repository got called.
    	// Review the Fluent Syntax here: http://ayende.com/Wiki/Comparison+of+different+Rhino+Mocks+syntaxes.ashx
    	With.Mocks(mockery)
    	.Expecting(() =>
    	{
    		// Lets make sure that repository DOES NOT get called.
    		// If this DOES get called, the test will fail.
    		// This should never get called because the test should throw before
    		// we get to this point. However, if it does not throw, this will make the test
    		// fail.
    		Expect.Call(delegate { repositoryMock.Update(customer); }).Repeat.Never();
    	})
    	.Verify(() =>
    	{
    		ICustomerService service = new CustomerService(repositoryMock);
    		ICustomerFacade facade = new CustomerFacade(service);
    		facade.SaveCustomer(customer);
    	});
    }
    

    If we get our expected result, we should see an exception thrown. This is what the exception should look like (click for larger):

    image

    If for some reason the logic in the CustomerService is bypassed, our Expect.Call on the repository should catch the test and fail the test. Here’s what happens when this occurs. (Click for larger image)

    image

    Now that we have our expected integration results – an exception we need to make the test pass. Any time we throw an exception in a class and its expected, we need to add the “ExpectedException” for NUnit. Now our test looks like this:

     

    	[ExpectedException(typeof(ApplicationException))]
            public void Customer_Facade_Should_Throw_With_An_InValid_Customer()
            {
                // ... Test stuff (removed for brevity). Its the same as above.
            }
    

     

    Notice the ExpectedException Attribute on top of the method. This informs the unit test framework that we are expecting an exception to be thrown. This is “expected behaviour”.

     

    Conclusion

    We’ve covered the key differences between Unit Tests and Integration Tests.

    Unit Tests - To test an individual unit of code to ensure it is working properly.

    Integration Tests - Testing how layers/tier/objects integrate with one another.

    Regardless if your doing unit testing or integration testing, its a positive step towards cleaner, more maintainable code. Knowing the difference can help you identify what types of test you have written and types of test you may need to write. Just because you’ve tested all of your classes at the unit level does not mean that all of them are going to integrate properly. writing integration tests help do this.

    Follow the motto: Fail Early. Fail fast.

    Unit and Integration tests help do this, very quickly.

    Visual Studio Project MSBuild Import Error Fix

    If you get this error:

    Unable to read the project File <path.to.project>.csproj.

    C:\<path>\<to>\<projecct>\Project.csproj 77, 11): The imported project “C:\Microsoft.CSharp.targets’ was not Found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

    As shown in this screen shot …

    image

     

    Take a look at your project file. Open it in a text editor (such as NotePad++) and look for the import statement.

    Mine looked like this:

    clip_image001

     

    How to fix

    Change the MSBuild Property $(MSBuildToolsPath) to $(MSBuildBinPath) and the project should load.

    Like so:

    clip_image001[7]