Saturday, June 12, 2010

Silverlight Asynchronous Unit Test MVVM and RIA Services

Introduction

I am building up a Silverlight application and we needed to incorporate unit testing in our project. Specifically we needed to unit test our asynchronous RIA Services method calls. I needed to find some examples of this and did not find any really good clean examples. There is really nothing that just gives you a simple example of how to get started.

I was able to get things working and I decided to put together three very basic examples that will give you a place to start from. The first two just give you an understanding of how things work and the third will test a RIA method that resides in a ViewModel.

It is possible to call asynchronous RIA methods inside of a Silverlight unit test without doing what I am about to show you. However doing it this way you can:

  • Really quickly build up unit tests that use your ViewModels.
  • Allow you to capture the full duration of the unit.
  • Avoid issues with asserts failing in asynchronous callbacks which will result in all the unit tests stopping.

Setting Up Asynchronous Unit Test

The steps for setting up an asynchronous unit test are pretty simple:

  • Add a unit test to your Silverlight unit test project.
  • Modify the unit test to inherit from Microsoft.Silverlight.Testing.SilverlightTest.
  • Decorate your test method with Microsoft.Silverlight.Testing.Asynchronous.

Building Up Asynchronous Unit Test

When you inherit from SilverlightTest you will have access to some methods that will help you build up your asynchronous unit test.

  • EnqueueTestComplete() – This method should be used when the test is complete. You can place in your call backs and this will signify the test is over.
  • EnqueueCallback() – This method adds a Callback method into the test queue.
  • EnqueueConditional() – This basically tells the test queue to wait until the condition is true.
  • EnqueueDelay() – Add a delay before continuing to evaluate work items.
  • EnqueueWorkItem – This adds a task to the task queue.

Example 1 – Simple RIA Callback

Here is my first simple example. In this sample we will:

  • Log into Silverlight application.
  • Then call my RIA method to perform a search.
  • Then in the callback of the search, do a check to see if results were returned.
  • All I need to do is add EnqueueTestComplete() into my callback.
[TestClass]
public class Tests : SilverlightTest
{
MyBusinessContext context;

[Asynchronous]
[TestMethod]
public void TestMethod1()
{
LoginParameters userCreds = new LoginParameters("UserName", "Password");
WebContext.Current.Authentication.Login(userCreds, LoginOperation_Completed, null);
}

private void LoginOperation_Completed(LoginOperation loginOperation) {

context = new MyBusinessContext();

context.Load<SearchResult>(context.SearchQuery("foo", "bar", "blah"), SearchCompleted, null);
}

private void SearchCompleted(LoadOperation<SearchResult> loadOperation) {
if (loadOperation.HasError)
{
loadOperation.MarkErrorAsHandled();
Assert.Fail(loadOperation.Error.Message);
}
else {
Assert.IsTrue(context.SearchResults.Count > 0);
}

this.EnqueueTestComplete();
}

}

Example 2 – Multiple RIA Callbacks

Here on my second example, let’s add search two callbacks.

You will notice in this one I use EnqueueConditional() to evaluate that each search callback work item is completed. Then I call EnqueueComplete() after both of the EnqueueConditional() methods have been called.

[TestClass]
public class Tests : SilverlightTest
{
MyBusinessContext context;
bool blnSearch1Complete = false;
bool blnSearch2Complete = false;

[Asynchronous]
[TestMethod]
public void TestMethod1()
{
LoginParameters userCreds = new LoginParameters("UserName", "Password");
WebContext.Current.Authentication.Login(userCreds, LoginOperation_Completed, null);
}

private void LoginOperation_Completed(LoginOperation loginOperation) {

context = new MyBusinessContext();

context.Load<SearchResult>(context.SearchQuery("foo", "bar", "blah"), Search1Completed, null);
context.Load<SearchResult>(context.SearchQuery("blah", "yop", "flop"), Search2Completed, null);

this.EnqueueConditional(() => blnSearch1Complete);
this.EnqueueConditional(() => blnSearch2Complete);
this.EnqueueTestComplete();
}

private void Search1Completed(LoadOperation<SearchResult> loadOperation)
{
if (loadOperation.HasError)
{
loadOperation.MarkErrorAsHandled();
Assert.Fail(loadOperation.Error.Message);
}
else {
Assert.IsTrue(context.SearchResults.Count > 0);
}

blnSearch1Complete = true;
}

private void Search2Completed(LoadOperation<SearchResult> loadOperation)
{
if (loadOperation.HasError)
{
loadOperation.MarkErrorAsHandled();
Assert.Fail(loadOperation.Error.Message);
}
else
{
Assert.IsTrue(context.SearchResults.Count > 0);
}

blnSearch2Complete = true;
}

}

Example 3 – Testing ViewModel Asynchronous Methods

So now you may be wondering how to test ViewModels with your RIA method calls. Here is a simple ViewModel that performs a search which could be bound to a Silverlight control.

  • You see the search callback I part of the ViewModel.
  • There are IsSearching and IsSearchComplete properties that indicate the status of the search.
  • There is a property that returns a collection of search results.

public class MyViewModel
{
MyBusinessContext _context;
bool _IsSearchComplete = false;

public MyViewModel() {
_context = new MyBusinessContext();
}

public void Search(string Criteria1, string Criteria2, string Criteria3)
{
_IsSearchComplete = false;
_context.SearchResults.Clear();
_context.Load<SearchResult>(_context.SearchQuery(Criteria1, Criteria2, Criteria3), SearchCompleted, null);
}

private void SearchCompleted(LoadOperation<SearchResult> loadOperation)
{
if (loadOperation.HasError)
{
loadOperation.MarkErrorAsHandled();
}

_IsSearchComplete = true;
}

public EntitySet<SearchResult> GeSearchResults {
get {
return _context.SearchResults;
}
}

public bool IsSearching {
get {
return _context.IsLoading;
}
}

public bool IsSearchComplete {
get {
return _IsSearchComplete;
}
}
}


The following is a Silverlight Unit Test that will test this asynchronous method call:

  • First we create an instance of the ViewModel.
  • I then use the EnqueueCallback() method to call the Search method which has an asynchronous callback within the ViewModel. This basically puts the method onto the queue.
  • Then I call EnqueueConditional() where I set the ViewModel.IsSearchComplete to be evaluated to check to see of the asynchronous search operation has been completed. This basically blocks the queue from continuing until this is true.
  • Next I call EnqueueCallback() again and set an Assert to check to see if search results were returned. This assert will be evaluated after the EnqueueConditional() is complete.
  • Finally EnqueueTestComplete() is called to tell the queue that testing is over.

[TestClass]
public class Tests : SilverlightTest
{

[Asynchronous]
[TestMethod]
public void TestMethod1()
{
LoginParameters userCreds = new LoginParameters("UserName", "Password");
WebContext.Current.Authentication.Login(userCreds, LoginOperation_Completed, null);
}

private void LoginOperation_Completed(LoginOperation loginOperation) {

MyViewModel myViewModel = new MyViewModel();
EnqueueCallback(() => myViewModel.Search("foo", "bar", "blah"));
EnqueueConditional(() => myViewModel.IsSearchComplete);
EnqueueCallback(() => Assert.IsTrue(myViewModel.GeSearchResults.Count > 0));
EnqueueTestComplete();

}

}

Conclusions

Once I got the hang of this, I really saw how simple it is to put together good unit tests that exercise my Silverlight ViewModels and RIA Service calls.

References

Thursday, June 10, 2010

Silverlight Unit Test Project Templates Compile Error

Introduction

Silverlight Unit Test project templates work perfect fine Silverlight Application project templates for Silverlight 4 and Visual Studio 2010. They will compile right off the bat. However Silverlight Business Application project templates will not immediately compile with a Silverlight Unit Test project template.

If you were to:

  1. Create a Silverlight Business Application.
  2. Then add Silverlight Unit Test. Enable WCF RIA Services and select the Business Application project as the Host.
  3. Then compile without making any changes.

What will result is compile errors and you will get different compile errors based on using C# or VB.net

C# Template

The following are the errors you would see in C#. To resolve these errors all you need to do is add a reference to the Silverlight Business Application to the Silverlight Unit Test project.

The annoying thing about this bug is that when you add the Silverlight Unit Test project the expectation is that this reference would be created since you selected the Business Application as the hosting project. You do not have to do this with Silverlight Applications.

Error 1 The type or namespace name 'Resources' does not exist in the namespace 'BusinessApplication1.Web' (are you missing an assembly reference?) C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.cs 299 101 SilverlightTest1

Error 2 The type or namespace name 'Resources' does not exist in the namespace 'BusinessApplication1.Web' (are you missing an assembly reference?) C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.cs 334 92 SilverlightTest1

Error 3 The type or namespace name 'Resources' does not exist in the namespace 'BusinessApplication1.Web' (are you missing an assembly reference?) C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.cs 367 138 SilverlightTest1

Error 4 The type or namespace name 'Resources' does not exist in the namespace 'BusinessApplication1.Web' (are you missing an assembly reference?) C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.cs 398 103 SilverlightTest1

Error 5 The type or namespace name 'Resources' does not exist in the namespace 'BusinessApplication1.Web' (are you missing an assembly reference?) C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.cs 437 95 SilverlightTest1

VB.net Template

You will get a couple more errors when doing VB.net. To resolve first add a reference to the Business Application project as we did for the C# solution. That will resolve errors 6, 8, and 9 however 1 to 5 will still remain. This is pretty confusing because doing that resolved the same issues for VB.net.

Next you need to either the following:

  1. Go to the Silverlight Unit Test Project properties. Change the Root Namespace to BusinessApplication1 in this case.
  2. Or go the BusinessAppllication1.Web project (the RIA Services project), go to the Models folder, and modify RegistrationData.vb. You will need to remove all reference to RegistrationDataResources in that class. What is happening is the RegistrationDataResources.resx is not projecting to the Silverlight Unit Test project and subsequently creating reference errors.

Error 1 Type 'BusinessApplication1.RegistrationDataResources' is not defined. C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.vb 305 79 SilverlightTest1

Error 2 Type 'BusinessApplication1.RegistrationDataResources' is not defined. C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.vb 336 70 SilverlightTest1

Error 3 Type 'BusinessApplication1.RegistrationDataResources' is not defined. C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.vb 365 117 SilverlightTest1

Error 4 Type 'BusinessApplication1.RegistrationDataResources' is not defined. C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.vb 392 81 SilverlightTest1

Error 5 Type 'BusinessApplication1.RegistrationDataResources' is not defined. C:\BusinessApplication1\SilverlightTest1\Generated_Code\BusinessApplication1.Web.g.vb 427 73 SilverlightTest1

Error 6 'FriendlyName' is not a member of 'SilverlightTest1.Web.User'. C:\BusinessApplication1\SilverlightTest1\Generated_Code\Models\Shared\User.shared.vb 10 45 SilverlightTest1

Error 7 'FriendlyName' is not a member of 'SilverlightTest1.Web.User'. C:\BusinessApplication1\SilverlightTest1\Generated_Code\Models\Shared\User.shared.vb 11 28 SilverlightTest1

Error 8 'Name' is not a member of 'SilverlightTest1.Web.User'. C:\BusinessApplication1\SilverlightTest1\Generated_Code\Models\Shared\User.shared.vb 13 28 SilverlightTest1

Monday, June 7, 2010

Bind a Silverlight DataGrid Column to the User Control DataContext

Silverlight Data and Controls Series

Background

I recently had to come up with a solution for a problem that was bothering me for some time. The issue I was how to access the user control’s DataContext from a Silverlight column. I was able to find the exact solution I was looking for by using the code in Dan Wahlin’s genius blog posting (http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx).

The specific issue was I needed to enable and disable specific columns in a grid based on the form’s state; and not the state of object bound to the.

Take a look at the code exerts from a xaml control below:

  • You will see there is a DataGrid bound to a list of Employees that is on my ViewModel.
  • I then added autocomplete column to the grid. I bounded the Text property to the Employee’ s EmployeeCode property.
  • I then tried to bind to the ViewModel’s IsEmployeesIsEnabled property to the IsEnabled property of autocomplete column.

That solution will never work. You will never get a compile or runtime error however because EmployeesIsEnabled is not a property of the Employee object in the row, the binding will never work.

<!--User control-->
<UserControl x:Class="OCS.Controls.Canvass.DetailsInfo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:local="clr-namespace:OCS.Converters" xmlns:vm="clr-namespace:OCS.ViewModels" d:DesignHeight="450" d:DesignWidth="1024" x:Name="DetailsInfoControl">

<!--Data Grid-->
<sdk:DataGrid AutoGenerateColumns="False" Height="240" Name="dgDetailsEmployees" Width="Auto" BorderThickness="0"
ItemsSource="{Binding Employees}"
SelectedItem="{Binding SelectedEmployee, Mode=TwoWay}">

<!--Data Grid Column-->
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<sdk:AutoCompleteBox Name="acbEmployeeCode"
MinimumPrefixLength="0" MinimumPopulateDelay="0" IsTextCompletionEnabled="True" ItemsSource="{Binding EmployeeCodes, Source={StaticResource oLookups}}" ValueMemberBinding="{Binding Abbreviation}" Text="{Binding EmployeeCode, Mode=TwoWay, ValidatesOnDataErrors=True,NotifyOnValidationError=True}" IsEnabled="{Binding EmployeesIsEnabled}">

Solution

To solve this use the code in this blog (http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx). Here is the code so you do not have to go over there but thank you very much Nick!!!

using System.Windows.Controls;
using System.Windows.Data;

namespace JobPlan.Controls
{
public class DataContextProxy : FrameworkElement
{
public DataContextProxy()
{
this.Loaded += new RoutedEventHandler(DataContextProxy_Loaded);
}

void DataContextProxy_Loaded(object sender, RoutedEventArgs e)
{
Binding binding = new Binding();
if (!String.IsNullOrEmpty(BindingPropertyName))
{
binding.Path = new PropertyPath(BindingPropertyName);
}
binding.Source = this.DataContext;
binding.Mode = BindingMode;
this.SetBinding(DataContextProxy.DataSourceProperty, binding);
}

public Object DataSource
{
get { return (Object)GetValue(DataSourceProperty); }
set { SetValue(DataSourceProperty, value); }
}

public static readonly DependencyProperty DataSourceProperty =
DependencyProperty.Register("DataSource", typeof(Object), typeof(DataContextProxy), null);


public string BindingPropertyName { get; set; }

public BindingMode BindingMode { get; set; }

}
}

Solution

Then make the following modifications:

  • I added a new resource to the xaml that creates the DataContextProxy.
  • Then I modified the IsEnabled property of the autocomplete column to be bound to EmployeesIsEnabled property of the ViewModel set to the user control’s DataContext.

Voila – it works – the column will be enabled and disabled based on the form state and not the grid row.

<UserControl x:Class="OCS.Controls.Canvass.DetailsInfo" xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml xmlns:d=http://schemas.microsoft.com/expression/blend/2008 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" xmlns:sdk=http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk xmlns:local="clr-namespace:OCS.Converters" xmlns:vm="clr-namespace:OCS.ViewModels" d:DesignHeight="450" d:DesignWidth="1024">

<UserControl.Resources><vm:DataContextProxy x:Key="dataContextProxy" /></UserControl.Resources>

<!--Data Grid-->
<sdk:DataGrid AutoGenerateColumns="False" Height="240" Name="dgDetailsEmployees" Width="Auto" BorderThickness="0"
ItemsSource="{Binding Employees}"
SelectedItem="{Binding SelectedEmployee, Mode=TwoWay}">

<!--Data Grid Column-->
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<sdk:AutoCompleteBox Name="acbEmployeeCode"
MinimumPrefixLength="0" MinimumPopulateDelay="0" IsTextCompletionEnabled="True" ItemsSource="{Binding EmployeeCodes, Source={StaticResource oLookups}}" ValueMemberBinding="{Binding Abbreviation}" Text="{Binding EmployeeCode, Mode=TwoWay, ValidatesOnDataErrors=True,NotifyOnValidationError=True}" IsEnabled="{Binding Source={StaticResource dataContextProxy},Path=DataSource.EmployeesIsEnabled}">

Sunday, June 6, 2010

SharePoint 2010 Upgrade, Validation and References

Implementation and Validation Phases

This final phase is the actual upgrade of your SharePoint environment and validating that it was a success.

Communication Plan

A prerequisite of the upgrade is to make sure you have a rock solid communication plan for the business users and stakeholders. You need to:

  • Show them all of their functionality is being upgraded.
  • Explain to them your testing approach.
  • Ensure them that service level agreements will be maintained.
  • Describe to them how the upgrade process will work.
  • Explain to them where there will be changes.
  • Give the stakeholders confidence that you have accounted for everything.

I would not wait to start communications with stakeholders until this phase. I would actually start it very early in the upgrade project but there are things that will come out of testing that will affect your communication plan.

The Upgrade and Validation

The actual upgrade should be completed based on all the steps capture in your previous test runs. You should make sure you steps throughout your deployment plan that spell out who is doing what and when. You should also spell out specifically who needs to be on call during specific periods of during the deployment. A well prepared deployment plan will actually spell out to hour what tasks are being done by whom and what are the dependencies. The objective of any deployment (SharePoint or not) is to ensure that there is minimal downtime with little to no errors.

It is not possible for me to give you an actual plan for your SharePoint environment because every client has different dependencies. As well depending on the upgrade approach you chose the steps will be different. However the following need to be accounted for:

  • Hardware Configuration Steps
  • OS Configuration Steps
  • System Account Configuration Steps
  • SharePoint Installation Steps
  • SharePoint Configuration Steps
  • Upgrade Approach Steps
  • Customization Upgrade Steps
  • Data Recovery and Back-up Configuration steps
  • Validation Test

After the upgrade is complete, you need to make sure you validate things are working as expected. There are several things that you can do to ensure the upgrade went successfully (reference):

  • Review Logs – Review all of the logs. There are logs associated to the setup, the SharePoint Configuration wizard and the upgrade log that tell you if there were any errors.
  • Verify Version Numbers – Go into Central Admin and check the version number on the farm page.
  • Check Web Site Status Page – All sites can be checked in Central Admin to see if the site has been upgraded or is still in progress. This can also be checked via command line (localupgradestatus).
  • Walkthrough Service Configuration – Ensure services are configured as expected.
  • Search – Run a crawl and review the logs to see if there any errors.
  • Review Upgraded Sites – Very basic functionality, check placement of web parts and controls, review highly visible sites, check integration functionality, review large lists and ensure it works with the new SharePoint list throttling features, check branding and layouts, check user permissions to ensure they have access to what they used to, check customized (unghosted) pages, etc.

Conclusions

I hope by the end of this you have initial understanding of how to get started with your SharePoint Upgrade. It is complex process and there are tons of facets you need to think about. I believe success of a SharePoint migration is understanding the People, Process and Technology.

I also hope that during this upgrade process your organization begins to really focus on SharePoint Governance and create an official project to manage your SharePoint environments based on this experience.

References


SharePoint Migration Models

SharePoint 2010 Upgrade Testing

Test Phase

The next phase is to actually do a test run of the upgrade. We will need to build up test farms and upgrade real production data into these farms. We want to ensure that we know and understand all the steps needed to support the upgrade approach that was chosen and resolve as many issues as possible.

The Test Farm

First you will need to create a new test farm with a configuration as close as possible to the new production environment. It would best to copy the entire production content database(s) and ensure that you all of the services configured as close as you can to production. It will not be possible to have an identical configuration databases (because it is not very easy or really supported to copy configuration databases – yes I know you can) but having SharePoint central admin and services configured as close to production to possible is good enough.

It is also important to try to use similar hardware as possible for your test environment.

Test Run the Upgrade Approach and Documentation

Once you have a test environment as close to the production environment as possible you will need to go through the actual upgrade process. Earlier we discussed there is an In-Place, Database Attach and Hybrid approaches. You should test these approaches as if you were doing them in production. You should focus on catching/handling potential exceptions and minimizing downtime.

You should make sure that you have strong step-by-step documentation that captures all of the steps needed to support the upgrade. The documentation should capture:

  • Hardware configuration
  • OS configuration
  • System account configuration
  • SharePoint installation steps
  • SharePoint configuration steps
  • Upgrade approach steps
  • Data Recovery configuration steps
  • Tests that ensure upgrade was successful

I would recommend that once you have a successful run of it; make sure that you can do it again using all of the steps that you have documented.

The Actual Test

The actual testing of the new SharePoint environment must be comprehensive. It is not just as simple as running the upgrade and seeing of the homepage works. Here are some things you should be thinking about:

  • Have a test approach that will incorporate business users.
  • Have a test plan with actual test criteria that you can measure success by.
  • Create test plans will test all SharePoint services that you plan to utilize.
  • Have test plans that test the performance and utilization.
  • Have an approach for testing search and search crawl configuration.
  • Have test plans to test all customizations. Everything from branding to integration with external systems that feed or consume data from SharePoint.
  • Make sure your test plan really tests the boundaries of your SharePoint implementation.
  • Finally make sure you have a mitigation plan and approach on how to rollback an upgrade if there is a failure.

SharePoint 2010 Upgrade Preparation

Prepare Phase

The goal of this phase is to take the information that you learned in the previous phase and actually perform a detailed audit of the current SharePoint 2007 implementation. The focus will be to ensure you are ready to do the migration and have accounted for everything you need to. The focus should always be on risk mitigation. The challenge is with SharePoint is that it is commonplace that poor governance has not been put in place and this will lead to challenges with an upgrade.

Pre-Upgrade Checker

One thing you will need to do is run the Pre-Upgrade checker on the current SharePoint 2007 environment. This tool will check the status of your server environment and provide you a list of issues that need to be resolved before doing the upgrade. It will not resolve any issues for you. It will tell you:

  • The upgrade path for each server in the SharePoint 2007 and if it can be upgraded.
  • Will return a list of alternate access mapping settings.
  • Will return a list of all installed and customized elements on the SharePoint 2007 server. This list includes all site definitions, site templates, features and language packs. It will call out customizations to these elements as well. Knowing all these customizations and understanding their upgrade path is critical.
  • Unsupported customizations will also be listed.
  • Orphaned objects any databases will be listed. This would include list items, documents, web sites, and even site collections. These objects need to be resolved by running a tool prior to doing the upgrade otherwise they will not be recoverable after the upgrade.
  • Will report any missing or invalid configuration settings throughout the SharePoint farm. These again should be fixed before performing an upgrade (especially if you are doing an In-Place upgrade).
  • Will perform a check of the database and report if the current database meets the requirements for an upgrade.

The findings of running this tool will assist in making a decision of what upgrade approach you will take.

Technical Considerations

Some other things you will have to take into consideration as part of the upgrade are the following:

  • Upgrade Performance - Is proportional the amount of data to be upgraded. The number of site collections, web, lists, documents, document versions, document size, and basically the overall size of the content database. The more content, the longer it takes. As well, the database environment has a direct affect on the performance of the upgrade. You need to account for SQL Disk I/O, SQL disk layout, Temp DB optimizations, SQL CPU and Memory, Web Front End CPU and Memory. I wish I had great statistics to give you an idea of how long it actually takes.
  • Upgrade complexity - Is proportional to the amount of customizations made to SharePoint. This is rather broad and I have mentioned it before that customizations to SharePoint will make the upgrade process more difficult. Most customizations will be upgradable unless you were not following best practices. However you should pretty much review each every customization that has been made into SharePoint and understand its upgrade path. You also need to think about external application dependencies to SharePoint. If SharePoint is integrated with external applications, you need to consider how the upgrade will affect them. You also need to review all third party products that may have been installed into your SharePoint 2007 environment.
  • URL Changes – This is something you could easily forget about but could have majorly affect business users. You need to know how dependant they are to the current URLs. Even still, URL dependencies are not just user dependant, applications and custom solutions built for SharePoint use them to access content. An In-Place will require no URL changes. A Hybrid Approach where the content databases are attached into an In-Place upgrade will not require a URL change either.
  • Audit the Current Environment - I have mentioned earlier that you need to make sure that you audit your environment. You need to understand such things as how much data you have and what are the characteristics of that data. You need to know how many users you have and what do they do within SharePoint. You need to know how many SharePoint farms you have and what their migration path is. Another thing you need to understand is the topology of the each SharePoint farm and how you will migrate to the new SharePoint farm. Also you need to take into account what is the backup strategy and data recovery of SharePoint environment. The current hardware and network environment should be re-evaluated to ensure that it is still sufficient and if there are plans to move to new hardware, what is it?
  • Third Party Software - A special focus needs to be made on third party software that has been installed into SharePoint 2007. You specifically need to focus on any applications that may have modified the SharePoint DB Schema, configuration changes that will have to be migrated, check to see if you are at the proper path level, does it even support SharePoint 2010 and if it is even needed anymore with the new features of SharePoint 2010.
  • Evaluating Customizations to SharePoint 2007 – The most common customizations that you will need to check into are customizations to site templates, list template, custom css, master pages, SharePoint Designer Modifications, Features, custom web parts, event handlers, application pages and javascript. The most common way to understand what changes have been put into SharePoint it to check to see what solution packages may be deployed. However we have seen a lot of developers not follow best practices when deploying their SharePoint 2007 solutions so you may have to resort to more drastic approaches to find all customizations. One way is to do a complete diff on an out of the box SharePoint 12 hive and compare to a production 12 hive. Can also look at the web.config and look for SaveControls elements that have been added and look at the GAC or webs for custom DLLs.
  • Cleaning Up Environment Before Upgrade – Before doing the upgrade it would be recommended to clean up stuff that is no longer being used or does not need to be migrated. You can delete stale sites or webs, remove documents that are not being utilized anymore, and cleanup or back out of custom templates, features and web parts that are no longer needed.

Non Technical Considerations

I know I have mentioned this before but it is worth mentioning again that a successful SharePoint upgrade is not just driven by understanding the technology. You have to have a solid understanding of how users are using it today and ensure that they do not lose any functionality moving forward. Just because it is newer and better does not mean it is best for the business user. You need make sure you have strong communication plans and provide them a solid understanding of the new features of SharePoint 2010. Providing them early access to a SharePoint 2010 environment to test drive would be a great thing to do. You need to understand all the current use cases of how SharePoint 2007 is used and make sure that matches up with the upgrade approach you plan to use. You need to have an understanding of the functionality of SharePoint 2010 needs to be made available immediately and provide them with a vision of how SharePoint 2010 can better support their needs.

We all know have business owners and stakeholders on your side and allowing them to be part of the decision process is extremely important.

Preparing for the SharePoint Upgrade

To summarize, to prepare for your SharePoint 2010 upgrade you should:

  • Run the upgrade checker as we have discussed.
  • Complete a technical audit of the current SharePoint 2007 environment.
  • Complete functional audit of how SharePoint is used.
  • Create a new logical and physical architecture for SharePoint 2010 and understand how existing functionality will upgrade into.
  • Clean up your current SharePoint 2007 environment.
  • Finalize your upgrade approach based on all the information that has been captured.

SharePoint 2010 Upgrade Scenarios

Upgrade Scenarios

As part of your planning you planning you need to make a decision on the upgrade approach that is right for your organization and service level agreements you have with the business for solutions and applications hosted within SharePoint 2007. There will be no single upgrade approach that can be used for every organization.

  • Unsupported Upgrade Scenarios - There are several standard upgrade scenarios you can look into. There are few unsupported scenarios that you know immediately. First it is not possible to upgrade from any version of SharePoint earlier than WSS v3 or MOSS 2007 SP2. If you are not on those versions you first need to upgrade to that which will require you extra planning and validation to ensure those upgrades worked correctly. So if you are still on SharePoint 2003 you will need to upgrade to version 2007 first. Second, there is no side-by-side installation supported meaning you cannot run SharePoint 2010 and 2007 on the same machines. Third there is no more gradual upgrade supported anymore like there was with upgrading from SharePoint 2003 to 2007.
  • In Place Upgrade– First there is an In-Place upgrade which is to basically just go through the installation wizard. It is the most simple however all sites will be unavailable during the upgrade. Users can continue to use the same URLs after the upgrade is complete. You will be required to upgrade the machines SharePoint is running on from 32 to 64 bit and the previous version of SharePoint 2007 must be removed off the machine. You can be ensured that farm wide settings will be upgraded correctly and customizations to SharePoint 2007 will be brought forward if they are SharePoint 2010 compatible.
  • Database Attach Upgrade – Databases from SharePoint 2007 platform can be attached into SharePoint 2010. This would include content, profile service and project service databases. SharePoint 2007 configuration and search databases cannot be attached into SharePoint 2010. At a high level the process is as simple as backing up the databases, restoring on the SQL machine where SharePoint 2010 is pointing to and then run two PowerShell commands. Using this approach you can upgrade many content databases at a time and you have the ability to consolidate SharePoint farms into a single farm. However all farm settings and configurations will be lost using this approach and more importantly all customizations will have to be manually migrated. I personally do not that is such a bad thing because it will force you to do an audit of customizations in your SharePoint 2007 environments and provide you the opportunity to put in a new governance plan to control customizations from this point moving forward.
  • Hybrid Upgrade Approach 1 – Using the two approaches above there are some potential ways to minimize some of the cons. One approach is to create a brand new SharePoint 2010 farm and subsequently move over all customizations to that new farm. Once the customizations have been tested, make the SharePoint 2007 content databases read-only, perform a back up of the databases and restore them on the new 2010 farm. Once the new 2010 farm is tested, you can then take down the old servers and bring the new one online. The good thing about this process is that is minimizes downtime because read-only access is still available. It also provides you some time to test everything before opening it up for use. The downside is that more coordination is needed to do this, more hardware is required, and farm configurations from 2007 are not migrated.
  • Hybrid Upgrade Approach 2 – Another approach would to stop access your SharePoint farm and detach your content databases. Then perform an In-Place upgrade of just the service and configuration databases. Then once the In-Place upgrade is complete, then reattach your content databases into the upgrade server. The advantage of doing this is the In-Place upgrade process will perform quicker if it does not have to do the content databases at the same time. If you want to even speed it up more you could create a temporary SharePoint 2010 on the side for just upgrade content databases while the In-Place upgrade process is running on the main server. Using this approach you still have the flexibility of consolidating multiple content databases from other SharePoint 2007 farms. As well customizations do not have manually moved to a new SharePoint 2010 server. Still a down side of this is that the SharePoint farm will be down for a period of time.

I personally like Hybrid Upgrade Approach 1 because it allows for minimal downtime and you will have a new clean SharePoint 2010 farm to start from. I know will require extra re-configuration of the services and migration of customs. However there is no point bringing over a ton of stuff that may not need to be used anymore and it allows you to put in some new governance to get control of customizations that are put into SharePoint 2010 from this point on.

Minimizing Downtime

Microsoft has built several features in to the upgrade process to assist with keeping the size of your upgrades small.

  • Read-only Databases – Was introduced in SharePoint 2007 SP2 and during the upgrade process content databases will be marked as read-only. This will prevent any change to the content but still provide read-only access to SharePoint while the upgrade is going.
  • Attaching Content Databases in Parallel – The upgrade process allows you to attach multiple content databases at the same time. This can be done by using multiple Window PowerShell sessions. So you are not limited to attaching one content database at a time. Microsoft is aware that many of their customers have content databases that are very large. This is why it is important to have good SharePoint Governance plans in place to make sure you have site collections that do not get too large. SharePoint Content databases can be terabytes but when something gets that big it hard to back and restore; and in this case upgrade. If you have the ability to break apart your content databases before the upgrade, that could be a good thing to look into.
  • Alternate Access Mapping – There will be cases where the content databases are very large and it is not reasonable to do upgrade of the content database in a single shot. SharePoint 2010 upgrade process supports using alternate-access mapping redirections to direct traffic between the old and new SharePoint sites (reference).

Other Upgrade Considerations

Along the way there are lots of things that need to be thought about when doing a SharePoint upgrade. Here is a couple you should be thinking about right off the bat:

  • New Hardware Requirements - Understand the new hardware requirements need to support SharePoint 2010. For instance for production use you need to use 64-bit machines with a minimum of 8GB memory. You can use either SQL Server 2005 or 2008 but the OS must be Windows Server 2008. This could be news to your infrastructure team and need to get the new SharePoint 2010 requirements in front of them.
  • Install Prerequisites - There are a lot of pre-requisites that have to be installed on every machine that will be running SharePoint 2010; too many to list here. To assist with this, Microsoft has provided a Prerequisite Installer that can check each machine that SharePoint 2010 will be installed on to ensure that it is compliant.
  • Streamlined Installation - There are several installation wizards for SharePoint 2010 that will assist you with the installation. There is a SharePoint 2010 Preparation Tool (new) that will install all the prerequisites. Setup wizard to that installs the bits. Configuration wizard which installs configuration database, central admin and adds servers to the farm (nothing new there). Server Farm Configuration Wizard (new) which is used to configure the farm itself, site collections, service accounts, etc. You need to plan on how to use these wizards as part of your upgrade.
  • Client Requirements - Minimum client requirements are that Silverlight 3 be installed along with IE7, IE8 or Firefox 3.5. Safari 4.x a d Firefox 3.5 on OS X Snow Leopard. Firefox 3.5 on Unix/Linux 8.1.
  • Forms Based Authentication (FBA) – If you are using FBA authentication you will have to do some extra planning to move it forward. You will need to convert web applications to use the new claims-based authentication model of SharePoint 2010. You will need to make modifications to the web.config of those sites and you will need to use PowerShell to migrate users and permission forward.
  • Shared Service Providers (SSP) – If you did not know the concept of the SSP has been removed and there is a new service architecture has been introduced for SharePoint 2010 (read my blog here). You get an understanding of that an plan on how to move forward services that were being supported in SharePoint 2007 to 2010.
  • Understand the Logical Architecture for 2010 – As well the logical architecture for SharePoint 2010 has changed significantly and it more flexible than the previous version (read my blog here). You have so much more flexibility in the hosting and sharing of services and this should be accounted for when migrated SharePoint 2007 features to 2010.