Load Testing SharePoint 2013–Part 1

Welcome everyone. I’m Brian Jordan and I am the Developer Technology Specialist covering US Public Sector Federal. Over time, I’ll be covering a number of announcements and technical topics across our development platform.

To get started, I wanted to share the some information I provided one of my clients that wanted to understand how to use the capabilities inside of Visual Studio 2013 Ultimate for load testing SharePoint 2013 sites. The current MSDN documentation on the subject is located at Web performance and load testing SharePoint 2010 and 2013 applications (https://msdn.microsoft.com/en-us/library/jj710162.aspx).  However, the examples are all in terms of testing SharePoint 2010 sites.  I developed the demonstrations for them and discovered some differences that you need to be aware of when testing SharePoint 2013 sites.  So today, I want to start on a series of posts that cover how to use Visual Studio 2013 Ultimate to do performance and load testing against SharePoint 2013 and discuss some of the differences. Specifically, I will walk you through a series of standard use cases in SharePoint (upload files, download files, etc.) and show how you:

  1. Record the web performance tests
  2. Make the web performance test ready for playback
    • Extraction and validation rules
    • Data source for data driving test
  3. Author a load test using the web performance test

The first scenario that we are going to cover is how to create a web performance test for uploading a file to one or more SharePoint Site Collections with one or more Document Libraries. To make it easy for you to follow along, I’ve created a PowerShell script that will create a base set of Site Collections and Document Libraries (see at end of post).  Below is an image of the LTDEmo1 site collection that I created with the standard Shared Documents library (Documents) and an additional five document libraries named DocLib1 - DocLib5.  There is a second LTDemo2 collection with the same set of document libraries that will be used for making sure that the web performance test covers multiple sites and multiple document libraries.

1. Load Test site

You first start out by selecting a web and performance load test project in Visual studio 2013 Ultimate by File->New Project and selecting the Test node under your language of choice (Visual C# or Visual Basic).  The language choice is really only important if you decide to generated code from your recorded tests.  For all the normal types of operations, Visual Studio provides you with a declarative approach to building out the test, 

6. New WebPerformance and Load Test Project 2

You give the project a name such as SPWebAndLoadTestProject, browse to a location to store the project on disk (optional), and then click the OK button.  After a brief interval, you will be presented with a project with a default test named WebTest1.webtest.

7. Project Loaded

At this point, you click on the red record button as shown below

8. Start Add Recording 1   

and this will bring up Internet Explorer with the Web Test Recorder visible.

      8. Start Add Recording A

Then walk through the following steps to record a file upload in the DocLib1 document library.

  1. Enter the address of your site collection into the browser address bar.  This was https://demo1/sites/LTDemo1 for the test case I created here.
  2. Select the link for the DocLib1 document library.  This will bring up the AllItems.aspx page.
  3. On the AllItems page, click the new document link to bring up a a web dialog to select a file to upload.
  4. Browse to the file you want to upload and save it.  When the file is uploaded, your browser will look similar to below.

9. Record Upload Test

Click the Stop button in the Web Test Recorder to complete the test and have Visual Studio start automatically removing noise requests and searching for dynamic parameters that need to be accounted for with extraction rules.

10. Detecting Paramerts

Accept the Dynamic Parameters listed in the Promote Dynamic Parameters to Web Test Parameters dialog – _REQUESTDIGEST, _VIEWSTATE, _EVENTVALIDATION.  You will then have an initial Web Performance test with the HTTP requests that mirrored your user interaction with the browser to upload the file to the DocLib1 document library. See the image below where  I have also renamed the test to Upload to better distinguish it.

12. Initial Project after Renaming

The first thing you want to deal with is the SiteName1 and SiteName2 context parameters.  The test has them as the extracted values of the site collection and document library used in recording the test.  The webtest will substitute these values where these context parameters appear in the HTTP request.  For example, https://demo1/sites/{{SiteName1}}/{{SiteName2}}/Home.aspx becomes https://demo1/sites/LTDemo1/DocLib1/Home.aspx.  Fixing this requires that we add a data source to the test.  This is easily done in the test window by selecting the database symbol with a plus on it or right-clicking on the test name an selecting Add Data Source.  When you do so, the New Test Data Source Wizard dialog displays giving you the opportunity toe name the data source and to select from three different data source types – Database, CSV File and XML File.  See Add a data source to a web performance test for more information.

13. Add Data Source

I used a CSV file that contained the following information based on my earlier experiments.  You notice that I have an additional column beyond the two expected sets of values for site and list name  that I will discuss later.  I’ve also encoded the “space” using “%20” in the Shared Documents list name so that I remove any potential issues.

14. Viewing Datasource

Using this data source, I will have 12 different combinations of site collection and document library (2 site collections x 6 document libraries).  If I want to test that all of my data source combinations work correctly before load testing, I am going to add a loop counter to the web test so that I can verify all of the combinations are exercised and determine if there will be any issues in running the tests.  To add a loop, you simply right-click on the top-level web test node and select Add Loop … which will bring up a list of loop types.  I want to run through 12 data values so I select a Counting Loop.

15. Adding Counting Loop

In the Counting Loop, I configure the Advance Data Cursor to true.  If I did not do so, I would take the first data value from the data source for each iteration of the loop.  I will show you an example of what is looks like when you don’t set the cursor update to true a bit below.  Next, I set the Number of Iterations to 12 for the 12 data values in the data source.  Then I finish be choosing the first and last item corresponding to my requests that will represent the requests to be looped through.  When I click the OK button, I have the loop added t the web test as shown below.

16. Completed Loop

The last step is to now to substitute the values in the data source for the correct parameters in the web test.  Again, we make this pretty simple by right-clicking on the web test and selecting the Find and Replace in Request menu item.This will bring up a dialog box for you to specify what to find and what to replace it with.

20. Find and Replace in Request

Here we are first going to replace the SiteName1 parameter.  In the web requests you will notice that it is enclosed in double curly braces -- {{ }}.   All substitutable parameters in a web test are enclosed in double curly braces.  What we want to do is replace this value with the corresponding value in our data source.  We use dot notation to get to the correct value in the data source file – <Data Source Name>.<Data Source File Name>.<Data Source Field Name>.  We use the SiteName filed in the SiteAndListNames  csv file associated with the SitesAndListNames data source for the values we want to substitute for the SiteName1 parameter.

21. Replacing SiteName1

In a similar manner, we use the ListName field in the data source to substitute for the SiteName2 parameter that corresponds to the document library.

22. Replacing ListName1

At this point, I can run the test and observer the responses for each of the requests. Here I notice that everything passes but upon closer inspection, I find that I was uploading the same file (SharePoint Load Test Demo.docx) to the same site and document library.  I had forgotten to advance the data cursor when I first ran this.

17. Ran Test 12 Times

However, no errors occurred due to prompting for uploading an already existing file.  As I look at the actual documents in the document library, I see that each has a different file name that is a GUID prefix to the original document name.  That explains why there were not errors, but how did that happen?

18. DocLib1 with 13 copies

To understand what happened, we need to examine the web test Form Post parameter for the UploadEx.aspx page where the actual file upload operation takes place.  If we scroll down and look at the properties of the File Upload Parameter, we see that the Unique Name  property has been automagically set for us so that unique names will be generated and they will be prefixed by GUIDs (the other option that cab be chose is large random integer values).

19. Use Guids

So, correcting my data cursor to advance and rerunning the test again, we get the following results.  There are failures in 10 of the 12 iterations.

23. Upload Something went wrong

As I start troubleshooting the test, I look at the Details tab of the AllItems.aspx page request and observe that the Extraction rule was looking for the DocLib1 string in the ctx.ListTitle context parameter.  Well that only happens twice in the data source which explains why only two of the iterations passed.

24. Doclib1 List not found

What I need to do to fix the issue is to go into the properties of the SharePoint – Extract WebParts ListView Values rule of the AllItems.aspx page request and

25. Extract ListId does not have parameterized List Title

change the List Title value to that third column value in the data source – ListTitle.  Remember, I mentioned we would need this later?

26. Parameterize List Title

Now, when I rerun the test, the extraction rule finds the correct List Title and puts in the correct context parameter value. 

27. Everything Passes for Upload

All 12 loop iterations pass and documents with GUID prefixed file names have been uploaded to Shared Documents and DocLib1..5 document libraries.  Below is a view of the two different site collections populated for two document libraries with the DocLib2 name.

28. Populated Sites and Libraries

Now that I know that my data source values will be iterated through correctly, I can remove the loop so that I have my first baseline file upload web test for use when I construct my load test. 

That concludes this post.  The next post in the series will walk through recording and debugging a web test that uploads a file to a SharePoint 2013 document library.  Let me know if you have any questions…

Sample Files - SPWebAndLoadTestProject.zip

Comments

  • Anonymous
    June 17, 2014
    Thank you for the article. Do you have more articles planned for govdev types? Specifically, SharePoint development in disconnected environments.

  • Anonymous
    June 17, 2014
    @RJ  Absolutely.  If you provide a bit more context around your ask on "SharePoint development in disconnected environments", I can add it to the my list of topics.

  • Anonymous
    June 24, 2014
    Very nice post Brian! I'm just wondring if you would be able to simulate creating additional site collections in a farm and see the impact on this?

  • Anonymous
    August 14, 2014
    @Wim Hill.  You certainly can as these actions are all accessible via the SharePoint web based administration interface.  You would definitely need to parameterize the site Collection name, etc.  Creating site collections does have an impact on a number resources but you generally don't create lots of Site Collections without some specific thought behind it.  I can think of some scenarios where you might want to do this but I would need to understand your use case better to comment on it.

  • Anonymous
    October 17, 2014
    The comment has been removed