Browse Source

cache update plus tests

Former-commit-id: 7f43a044f5c68a232e20b65d4d40e21f62c0a0cc
af/merge-core
JimBobSquarePants 13 years ago
parent
commit
8956b2d063
  1. 12
      src/ImageProcessor.Web/Caching/CachedImage.cs
  2. 104
      src/ImageProcessor.Web/Caching/DiskCache.cs
  3. 2
      src/ImageProcessor.Web/Caching/LockedDictionary.cs
  4. 3
      src/ImageProcessor.Web/Caching/SQLContext.cs
  5. 59
      src/ImageProcessor.Web/Helpers/FileCompareLastwritetime.cs
  6. 4
      src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs
  7. 31
      src/ImageProcessor.Web/ImageFactoryExtensions.cs
  8. 1
      src/ImageProcessor.Web/ImageProcessor.Web.csproj
  9. 49
      src/ImageProcessor.sln
  10. 10
      src/Local.testsettings
  11. 2
      src/Test/Test/Web.config
  12. 435
      src/Web.Test/LoadTest1.loadtest
  13. 35
      src/Web.Test/Properties/AssemblyInfo.cs
  14. 89
      src/Web.Test/Web.Tests.csproj
  15. 1
      src/Web.Test/WebTest1.497d23f8-ba06-4350-9f93-8ba9772d5650.rec.webtestresult.REMOVED.git-id
  16. 14
      src/Web.Test/WebTest1.webtest
  17. 28
      src/Web.Test/WebTest1Coded.cs

12
src/ImageProcessor.Web/Caching/CachedImage.cs

@ -14,7 +14,7 @@ namespace ImageProcessor.Web.Caching
/// <summary>
/// Describes a cached image
/// </summary>
internal sealed class CachedImage : IComparable<CachedImage>
internal sealed class CachedImage
{
/// <summary>
/// Initializes a new instance of the <see cref="CachedImage"/> class.
@ -49,15 +49,5 @@ namespace ImageProcessor.Web.Caching
/// Gets or sets when the cached image should expire from the cache.
/// </summary>
public DateTime ExpiresUtc { get; set; }
/// <summary>
///
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
public int CompareTo(CachedImage other)
{
return this.ExpiresUtc.CompareTo(other.ExpiresUtc);
}
}
}

104
src/ImageProcessor.Web/Caching/DiskCache.cs

@ -13,8 +13,6 @@ namespace ImageProcessor.Web.Caching
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Hosting;
using ImageProcessor.Helpers.Extensions;
@ -44,7 +42,7 @@ namespace ImageProcessor.Web.Caching
/// <summary>
/// The regular expression to search strings for extension changes.
/// </summary>
private static readonly Regex FormatRegex = new Regex(@"format=(jpeg|png|bmp|gif)", RegexOptions.Compiled);
private static readonly Regex FormatRegex = new Regex(@"(jpeg|png|bmp|gif)", RegexOptions.RightToLeft | RegexOptions.Compiled);
/// <summary>
/// The default paths for Cached folders on the server.
@ -130,21 +128,6 @@ namespace ImageProcessor.Web.Caching
throw new InvalidOperationException("We can only map an absolute back to a relative path if the application path is available.");
}
/// <summary>
/// Purges any files from the file-system cache in a background thread.
/// </summary>
internal static void PurgeCachedFolders()
{
ThreadStart threadStart = PurgeFolders;
Thread thread = new Thread(threadStart)
{
IsBackground = true
};
thread.Start();
}
/// <summary>
/// Returns a value indicating whether the original file has been updated.
/// </summary>
@ -156,16 +139,18 @@ namespace ImageProcessor.Web.Caching
internal static bool IsUpdatedFile(string imagePath, string cachedImagePath)
{
string key = Path.GetFileNameWithoutExtension(cachedImagePath);
CachedImage cachedImage;
bool isUpdated = false;
if (File.Exists(imagePath))
{
FileInfo imageFileInfo = new FileInfo(imagePath);
CachedImage cachedImage;
if (PersistantDictionary.Instance.TryGetValue(key, out cachedImage))
{
if (!imageFileInfo.LastWriteTimeUtc.Equals(cachedImage.LastWriteTimeUtc))
// Check to see if the last write time is different of whether the
// chached image is set to expire.
if (imageFileInfo.LastWriteTimeUtc != cachedImage.LastWriteTimeUtc || cachedImage.ExpiresUtc < DateTime.UtcNow.AddDays(-MaxFileCachedDuration))
{
if (PersistantDictionary.Instance.TryRemove(key, out cachedImage))
{
@ -205,16 +190,13 @@ namespace ImageProcessor.Web.Caching
/// <summary>
/// Purges any files from the file-system cache in the given folders.
/// </summary>
internal static void PurgeFolders()
internal static void TrimCachedFolders()
{
// Group each cache folder and clear any expired items or any that exeed
// the maximum allowable count.
Regex searchTerm = new Regex(@"(jpeg|png|bmp|gif)");
var groups = PersistantDictionary.Instance.ToList()
.GroupBy(x => searchTerm.Match(x.Value.Path).Value)
.GroupBy(x => FormatRegex.Match(x.Value.Path).Value)
.Where(g => g.Count() > MaxFilesCount);
//.Where(g => g.Count() > MaxFilesCount
// || g.Select(a => a.Value.ExpiresUtc < DateTime.UtcNow.AddDays(-MaxFileCachedDuration)).Count() > 0);
foreach (var group in groups)
{
@ -230,11 +212,10 @@ namespace ImageProcessor.Web.Caching
break;
}
// Delete each CachedImage.
try
{
// Remove from the cache and delete each CachedImage.
FileInfo fileInfo = new FileInfo(pair.Value.Path);
// Remove from the cache.
string key = Path.GetFileNameWithoutExtension(fileInfo.Name);
CachedImage cachedImage;
@ -252,64 +233,6 @@ namespace ImageProcessor.Web.Caching
}
}
}
//string folder = HostingEnvironment.MapPath(CachePath);
//if (folder != null)
//{
// DirectoryInfo directoryInfo = new DirectoryInfo(folder);
// if (directoryInfo.Exists)
// {
// List<DirectoryInfo> directoryInfos = directoryInfo
// .EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
// .ToList();
// Parallel.ForEach(
// directoryInfos,
// subDirectoryInfo =>
// {
// // Get all the files in the cache ordered by LastAccessTime - oldest first.
// List<FileInfo> fileInfos = subDirectoryInfo.EnumerateFiles("*", SearchOption.TopDirectoryOnly)
// .OrderBy(x => x.LastAccessTimeUtc).ToList();
// int counter = fileInfos.Count;
// Parallel.ForEach(
// fileInfos,
// fileInfo =>
// {
// // Delete the file if we are nearing our limit buffer.
// if (counter >= MaxFilesCount || fileInfo.LastAccessTimeUtc < DateTime.UtcNow.AddDays(-MaxFileCachedDuration))
// {
// lock (SyncRoot)
// {
// try
// {
// // Remove from the cache.
// string key = Path.GetFileNameWithoutExtension(fileInfo.Name);
// CachedImage cachedImage;
// if (PersistantDictionary.Instance.TryGetValue(key, out cachedImage))
// {
// if (PersistantDictionary.Instance.TryRemove(key, out cachedImage))
// {
// fileInfo.Delete();
// counter -= 1;
// }
// }
// }
// catch (IOException)
// {
// // Do Nothing, skip to the next.
// // TODO: Should we handle this?
// }
// }
// }
// });
// });
// }
//}
}
/// <summary>
@ -323,16 +246,11 @@ namespace ImageProcessor.Web.Caching
/// </returns>
private static string ParseExtension(string input)
{
foreach (Match match in FormatRegex.Matches(input))
{
if (match.Success)
{
return match.Value.Split('=')[1];
}
}
Match match = FormatRegex.Match(input);
return string.Empty;
return match.Success ? match.Value : string.Empty;
}
#endregion
}
}

2
src/ImageProcessor.Web/Caching/LockedDictionary.cs

@ -35,7 +35,7 @@ namespace ImageProcessor.Web.Caching
/// <param name="val">
/// The value to initialize the LockedDictionary with.
/// </param>
public LockedDictionary(IDictionary<TKey, TVal> val = null)
public LockedDictionary(IEnumerable<KeyValuePair<TKey, TVal>> val = null)
{
if (val != null)
{

3
src/ImageProcessor.Web/Caching/SQLContext.cs

@ -154,7 +154,8 @@ namespace ImageProcessor.Web.Caching
{
using (SQLiteCommand command = new SQLiteCommand(connection))
{
command.CommandText = string.Format("DELETE FROM names WHERE key = '{0}';", key);
command.CommandText = "DELETE FROM names WHERE key = @searchParam;";
command.Parameters.Add(new SQLiteParameter("searchParam", key));
command.ExecuteNonQuery();
}

59
src/ImageProcessor.Web/Helpers/FileCompareLastwritetime.cs

@ -1,59 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="FileCompareLastwritetime.cs" company="James South">
// Copyright (c) James South.
// Dual licensed under the MIT or GPL Version 2 licenses.
// </copyright>
// -----------------------------------------------------------------------
namespace ImageProcessor.Web.Helpers
{
#region Using
using System;
using System.Collections.Generic;
#endregion
/// <summary>
/// Encapsulates methods to support the comparison of <see cref="T:System.IO.FileInfo"/> objects for equality.
/// </summary>
public class FileCompareLastwritetime : IEqualityComparer<System.IO.FileInfo>
{
/// <summary>
/// Converts the value of the current <see cref="T:System.DateTime"/> object to its equivalent
/// nearest minute representation.
/// </summary>
/// <param name="value">An instance of <see cref="T:System.DateTime"/>.</param>
/// <returns>
/// A value of the current <see cref="T:System.DateTime"/> object to its equivalent
/// nearest minute representation.
/// </returns>
public static DateTime ToMinute(DateTime value)
{
return new DateTime(value.Year, value.Month, value.Day, value.Hour, value.Minute, 0, value.Kind).ToUniversalTime();
}
/// <summary>
/// Determines whether the specified instances of <see cref="T:System.IO.FileInfo"/> object are equal.
/// </summary>
/// <param name="f1">
/// The first <see cref="T:System.IO.FileInfo"/> object to compare.
/// </param>
/// <param name="f2">
/// The second <see cref="T:System.IO.FileInfo"/> object to compare.
/// </param>
/// <returns>true if the specified objects are equal; otherwise, false.</returns>
public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
{
return ToMinute(f1.LastWriteTimeUtc) == ToMinute(f2.LastWriteTimeUtc);
}
/// <summary>
/// Returns a hash code for the specified <see cref="T:System.IO.FileInfo"/>.
/// </summary>
/// <param name="fi">The FileInfo to return the hash code for.</param>
/// <returns>A hash code for the specified <see cref="T:System.IO.FileInfo"/>.</returns>
public int GetHashCode(System.IO.FileInfo fi)
{
return ToMinute(fi.LastWriteTimeUtc).GetHashCode();
}
}
}

4
src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs

@ -129,7 +129,7 @@ namespace ImageProcessor.Web.HttpModules
lock (SyncRoot)
{
// Trim the cache.
DiskCache.PurgeFolders();
DiskCache.TrimCachedFolders();
responseStream.CopyTo(memoryStream);
@ -153,7 +153,7 @@ namespace ImageProcessor.Web.HttpModules
lock (SyncRoot)
{
// Trim the cache.
DiskCache.PurgeFolders();
DiskCache.TrimCachedFolders();
imageFactory.Load(fullPath).AutoProcess().Save(cachedPath);

31
src/ImageProcessor.Web/ImageFactoryExtensions.cs

@ -19,11 +19,6 @@ namespace ImageProcessor.Web
/// </summary>
public static class ImageFactoryExtensions
{
/// <summary>
/// The object to lock against.
/// </summary>
private static readonly object SyncRoot = new object();
/// <summary>
/// Auto processes image files based on any query string parameters added to the image path.
/// </summary>
@ -38,22 +33,18 @@ namespace ImageProcessor.Web
{
if (factory.ShouldProcess)
{
// TODO: This is going to be a bottleneck for speed. Find a faster way.
//lock (SyncRoot)
//{
// Get a list of all graphics processors that have parsed and matched the querystring.
List<IGraphicsProcessor> list =
ImageProcessorConfig.Instance.GraphicsProcessors
.Where(x => x.MatchRegexIndex(factory.QueryString) != int.MaxValue)
.OrderBy(y => y.SortOrder)
.ToList();
// Get a list of all graphics processors that have parsed and matched the querystring.
List<IGraphicsProcessor> list =
ImageProcessorConfig.Instance.GraphicsProcessors
.Where(x => x.MatchRegexIndex(factory.QueryString) != int.MaxValue)
.OrderBy(y => y.SortOrder)
.ToList();
// Loop through and process the image.
foreach (IGraphicsProcessor graphicsProcessor in list)
{
factory.Image = graphicsProcessor.ProcessImage(factory);
}
//}
// Loop through and process the image.
foreach (IGraphicsProcessor graphicsProcessor in list)
{
factory.Image = graphicsProcessor.ProcessImage(factory);
}
}
return factory;

1
src/ImageProcessor.Web/ImageProcessor.Web.csproj

@ -95,7 +95,6 @@
<Compile Include="Config\ImageProcessingSection.cs" />
<Compile Include="Config\ImageProcessorConfig.cs" />
<Compile Include="Config\ImageSecuritySection.cs" />
<Compile Include="Helpers\FileCompareLastwritetime.cs" />
<Compile Include="Helpers\RemoteFile.cs" />
<Compile Include="HttpModules\ImageProcessingModule.cs" />
<Compile Include="ImageFactoryExtensions.cs" />

49
src/ImageProcessor.sln

@ -9,64 +9,113 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web", "Image
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Tests", "ImageProcessor.Tests\ImageProcessor.Tests.csproj", "{39911A38-CA06-413C-80AA-39EF60CE984F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web.Tests", "Web.Test\Web.Tests.csproj", "{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C427A497-74DC-49B1-8420-D6E68354F29B}"
ProjectSection(SolutionItems) = preProject
Local.testsettings = Local.testsettings
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Any CPU = All|Any CPU
All|Mixed Platforms = All|Mixed Platforms
All|x86 = All|x86
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.All|Any CPU.ActiveCfg = All|Any CPU
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.All|Any CPU.Build.0 = All|Any CPU
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.All|Mixed Platforms.ActiveCfg = All|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.All|Mixed Platforms.Build.0 = All|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.All|x86.ActiveCfg = All|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.All|x86.Build.0 = All|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Debug|Any CPU.Build.0 = Release|Any CPU
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Debug|Mixed Platforms.Build.0 = Debug|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Debug|x86.ActiveCfg = Debug|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Debug|x86.Build.0 = Debug|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Release|Any CPU.Build.0 = Release|Any CPU
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Release|Mixed Platforms.ActiveCfg = Release|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Release|Mixed Platforms.Build.0 = Release|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Release|x86.ActiveCfg = Release|x86
{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}.Release|x86.Build.0 = Release|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.All|Any CPU.ActiveCfg = All|Any CPU
{30327C08-7574-4D7E-AC95-6A58753C6855}.All|Any CPU.Build.0 = All|Any CPU
{30327C08-7574-4D7E-AC95-6A58753C6855}.All|Mixed Platforms.ActiveCfg = All|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.All|Mixed Platforms.Build.0 = All|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.All|x86.ActiveCfg = All|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.All|x86.Build.0 = All|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30327C08-7574-4D7E-AC95-6A58753C6855}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30327C08-7574-4D7E-AC95-6A58753C6855}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.Debug|Mixed Platforms.Build.0 = Debug|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.Debug|x86.ActiveCfg = Debug|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.Debug|x86.Build.0 = Debug|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30327C08-7574-4D7E-AC95-6A58753C6855}.Release|Any CPU.Build.0 = Release|Any CPU
{30327C08-7574-4D7E-AC95-6A58753C6855}.Release|Mixed Platforms.ActiveCfg = Release|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.Release|Mixed Platforms.Build.0 = Release|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.Release|x86.ActiveCfg = Release|x86
{30327C08-7574-4D7E-AC95-6A58753C6855}.Release|x86.Build.0 = Release|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.All|Any CPU.ActiveCfg = All|Any CPU
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.All|Any CPU.Build.0 = All|Any CPU
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.All|Mixed Platforms.ActiveCfg = All|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.All|Mixed Platforms.Build.0 = All|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.All|x86.ActiveCfg = All|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.All|x86.Build.0 = All|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Debug|Any CPU.Build.0 = Release|Any CPU
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Debug|Mixed Platforms.Build.0 = Debug|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Debug|x86.ActiveCfg = Debug|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Debug|x86.Build.0 = Debug|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Release|Any CPU.Build.0 = Release|Any CPU
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Release|Mixed Platforms.ActiveCfg = Release|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Release|Mixed Platforms.Build.0 = Release|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Release|x86.ActiveCfg = Release|x86
{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}.Release|x86.Build.0 = Release|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.All|Any CPU.ActiveCfg = Release|Any CPU
{39911A38-CA06-413C-80AA-39EF60CE984F}.All|Any CPU.Build.0 = Release|Any CPU
{39911A38-CA06-413C-80AA-39EF60CE984F}.All|Mixed Platforms.ActiveCfg = Release|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.All|Mixed Platforms.Build.0 = Release|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.All|x86.ActiveCfg = Release|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.All|x86.Build.0 = Release|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39911A38-CA06-413C-80AA-39EF60CE984F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39911A38-CA06-413C-80AA-39EF60CE984F}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.Debug|Mixed Platforms.Build.0 = Debug|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.Debug|x86.ActiveCfg = Debug|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.Debug|x86.Build.0 = Debug|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39911A38-CA06-413C-80AA-39EF60CE984F}.Release|Any CPU.Build.0 = Release|Any CPU
{39911A38-CA06-413C-80AA-39EF60CE984F}.Release|Mixed Platforms.ActiveCfg = Release|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.Release|Mixed Platforms.Build.0 = Release|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.Release|x86.ActiveCfg = Release|x86
{39911A38-CA06-413C-80AA-39EF60CE984F}.Release|x86.Build.0 = Release|x86
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.All|Any CPU.ActiveCfg = Release|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.All|Any CPU.Build.0 = Release|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.All|Mixed Platforms.ActiveCfg = Release|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.All|Mixed Platforms.Build.0 = Release|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.All|x86.ActiveCfg = Release|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Debug|x86.ActiveCfg = Debug|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Release|Any CPU.Build.0 = Release|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

10
src/Local.testsettings

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestSettings name="Local" id="7707ff8b-37f7-4192-88cc-339cb7fc8874" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Description>These are default test settings for a local test run.</Description>
<Deployment enabled="false" />
<Execution>
<TestTypeSpecific />
<AgentRule name="Execution Agents">
</AgentRule>
</Execution>
</TestSettings>

2
src/Test/Test/Web.config

@ -64,7 +64,7 @@
<add url="http://images.mymovies.net"/>
</whiteList>
</security>
<cache virtualPath="~/cache" maxDays="28"/>
<cache virtualPath="~/cache" maxDays="10"/>
<processing>
<plugins>
<plugin name="Resize">

435
src/Web.Test/LoadTest1.loadtest

@ -0,0 +1,435 @@
<?xml version="1.0" encoding="utf-8"?>
<LoadTest Name="LoadTest1" Description="" Owner="" storage="c:\users\james south\documents\github\imageprocessor\src\web.test\loadtest1.loadtest" Priority="2147483647" Enabled="true" CssProjectStructure="" CssIteration="" DeploymentItemsEditable="" WorkItemIds="" TraceLevel="None" CurrentRunConfig="Run Settings1" Id="bd358b6a-19c7-4fa0-ad90-9664f5b85e79" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Scenarios>
<Scenario Name="Scenario basic stress" DelayBetweenIterations="0" PercentNewUsers="0" IPSwitching="true" TestMixType="PercentageOfTestsStarted" ApplyDistributionToPacingDelay="true" MaxTestIterations="0" DisableDuringWarmup="false" DelayStartTime="0" AllowedAgents="">
<ThinkProfile Value="0.2" Pattern="NormalDistribution" />
<LoadProfile Pattern="Constant" InitialUsers="100" />
<TestMix>
<TestProfile Name="WebTest1" Path="webtest1.webtest" Id="2573f2eb-56b5-4552-8818-12748986ff45" Percentage="100" Type="Microsoft.VisualStudio.TestTools.WebStress.DeclarativeWebTestElement, Microsoft.VisualStudio.QualityTools.LoadTest, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</TestMix>
<BrowserMix>
<BrowserProfile Percentage="100">
<Browser Name="Internet Explorer 9.0" MaxConnections="6">
<Headers>
<Header Name="User-Agent" Value="Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)" />
<Header Name="Accept" Value="*/*" />
<Header Name="Accept-Language" Value="{{$IEAcceptLanguage}}" />
<Header Name="Accept-Encoding" Value="GZIP" />
</Headers>
</Browser>
</BrowserProfile>
</BrowserMix>
<NetworkMix>
<NetworkProfile Percentage="100">
<Network Name="LAN" BandwidthInKbps="1000000" NetworkProfileConfigurationXml="&lt;Emulation&gt;&lt;VirtualChannel name=&quot;defaultChannel&quot;&gt;&lt;FilterList/&gt;&lt;VirtualLink instances=&quot;1&quot; name=&quot;defaultLink&quot;&gt;&lt;LinkRule dir=&quot;upstream&quot;&gt;&lt;Bandwidth&gt;&lt;Speed unit=&quot;kbps&quot;&gt;1000000&lt;/Speed&gt;&lt;/Bandwidth&gt;&lt;/LinkRule&gt;&lt;LinkRule dir=&quot;downstream&quot;&gt;&lt;Bandwidth&gt;&lt;Speed unit=&quot;kbps&quot;&gt;1000000&lt;/Speed&gt;&lt;/Bandwidth&gt;&lt;/LinkRule&gt;&lt;/VirtualLink&gt;&lt;/VirtualChannel&gt;&lt;/Emulation&gt;" />
</NetworkProfile>
</NetworkMix>
</Scenario>
</Scenarios>
<CounterSets>
<CounterSet Name="LoadTest" CounterSetType="LoadTest" LocId="">
<CounterCategories>
<CounterCategory Name="LoadTest:Scenario">
<Counters>
<Counter Name="User Load" HigherIsBetter="true" />
<Counter Name="Tests Running" HigherIsBetter="true" />
</Counters>
</CounterCategory>
<CounterCategory Name="LoadTest:Test">
<Counters>
<Counter Name="Total Tests" HigherIsBetter="true" />
<Counter Name="Passed Tests" HigherIsBetter="true" />
<Counter Name="Failed Tests" />
<Counter Name="Tests/Sec" HigherIsBetter="true" />
<Counter Name="Passed Tests/Sec" HigherIsBetter="true" />
<Counter Name="Failed Tests/Sec" />
<Counter Name="Avg. Requests/Test" HigherIsBetter="true" />
<Counter Name="Avg. Test Time" />
<Counter Name="% Time in LoadTestPlugin" />
<Counter Name="% Time in WebTest code" />
<Counter Name="% Time in Rules" />
</Counters>
</CounterCategory>
<CounterCategory Name="LoadTest:Transaction">
<Counters>
<Counter Name="Total Transactions" HigherIsBetter="true" />
<Counter Name="Avg. Transaction Time" />
<Counter Name="Avg. Response Time" />
<Counter Name="Transactions/Sec" HigherIsBetter="true" />
</Counters>
</CounterCategory>
<CounterCategory Name="LoadTest:Errors">
<Counters>
<Counter Name="Http Errors" />
<Counter Name="Validation Rule Errors" />
<Counter Name="Extraction Rule Errors" />
<Counter Name="Requests Timed Out" />
<Counter Name="Exceptions" />
<Counter Name="Total Errors" />
<Counter Name="Errors/Sec" />
<Counter Name="Threshold Violations/Sec" />
</Counters>
</CounterCategory>
<CounterCategory Name="LoadTest:Page">
<Counters>
<Counter Name="Total Pages" HigherIsBetter="true" />
<Counter Name="Avg. Page Time" />
<Counter Name="Page Response Time Goal" HigherIsBetter="true" />
<Counter Name="% Pages Meeting Goal" HigherIsBetter="true" />
<Counter Name="Pages/Sec" HigherIsBetter="true" />
</Counters>
</CounterCategory>
<CounterCategory Name="LoadTest:Request">
<Counters>
<Counter Name="Total Requests" HigherIsBetter="true" />
<Counter Name="Passed Requests" HigherIsBetter="true" />
<Counter Name="Failed Requests" />
<Counter Name="Cached Requests" HigherIsBetter="true" />
<Counter Name="Requests/Sec" HigherIsBetter="true" />
<Counter Name="Passed Requests/Sec" HigherIsBetter="true" />
<Counter Name="Failed Requests/Sec" />
<Counter Name="Avg. First Byte Time" />
<Counter Name="Avg. Response Time" />
<Counter Name="Avg. Connection Wait Time">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareCounters, Microsoft.VisualStudio.QualityTools.LoadTest, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<RuleParameters>
<RuleParameter Name="DependentCategory" Value="LoadTest:Page" />
<RuleParameter Name="DependentCounter" Value="Avg. Page Time" />
<RuleParameter Name="DependentInstance" Value="_Total" />
<RuleParameter Name="AlertIfOver" Value="True" />
<RuleParameter Name="WarningThreshold" Value="0.25" />
<RuleParameter Name="CriticalThreshold" Value="0.5" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
<Counter Name="Avg. Content Length" />
</Counters>
</CounterCategory>
<CounterCategory Name="LoadTest:LogEntries">
<Counters>
<Counter Name="Total Log Entries" />
<Counter Name="Log Entries/Sec" />
</Counters>
</CounterCategory>
</CounterCategories>
</CounterSet>
<CounterSet Name="Controller" CounterSetType="Controller" LocId="CounterSet_Controller">
<CounterCategories>
<CounterCategory Name="Memory">
<Counters>
<Counter Name="% Committed Bytes In Use" Range="100" />
<Counter Name="Available MBytes" RangeGroup="Memory Bytes" HigherIsBetter="true">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareConstant, Microsoft.VisualStudio.QualityTools.LoadTest">
<RuleParameters>
<RuleParameter Name="AlertIfOver" Value="False" />
<RuleParameter Name="WarningThreshold" Value="100" />
<RuleParameter Name="CriticalThreshold" Value="50" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
<Counter Name="Page Faults/sec" />
<Counter Name="Pages/sec" />
<Counter Name="Pool Paged Bytes" RangeGroup="Memory Bytes" />
<Counter Name="Pool Nonpaged bytes" RangeGroup="Memory Bytes" />
</Counters>
</CounterCategory>
<CounterCategory Name="Network Interface">
<Counters>
<Counter Name="Bytes Received/sec" RangeGroup="Network Bytes" />
<Counter Name="Bytes Sent/sec" RangeGroup="Network Bytes" />
<Counter Name="Output Queue Length">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareConstant, Microsoft.VisualStudio.QualityTools.LoadTest">
<RuleParameters>
<RuleParameter Name="AlertIfOver" Value="True" />
<RuleParameter Name="WarningThreshold" Value="1.5" />
<RuleParameter Name="CriticalThreshold" Value="2" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
<Counter Name="Packets Received/sec" RangeGroup="Network Packets" />
<Counter Name="Packets Sent/sec" RangeGroup="Network Packets" />
<Counter Name="Current Bandwidth" RangeGroup="Network Bytes" />
<Counter Name="Bytes Total/sec" RangeGroup="Network Bytes">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareCounters, Microsoft.VisualStudio.QualityTools.LoadTest, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<RuleParameters>
<RuleParameter Name="DependentCategory" Value="Network Interface" />
<RuleParameter Name="DependentCounter" Value="Current Bandwidth" />
<RuleParameter Name="DependentInstance" Value="" />
<RuleParameter Name="AlertIfOver" Value="True" />
<RuleParameter Name="WarningThreshold" Value="0.6" />
<RuleParameter Name="CriticalThreshold" Value="0.7" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
</Counters>
<Instances>
<Instance Name="*" />
</Instances>
</CounterCategory>
<CounterCategory Name="PhysicalDisk">
<Counters>
<Counter Name="% Disk Read Time" Range="100" />
<Counter Name="% Disk Time" Range="100" />
<Counter Name="% Disk Write Time" Range="100" />
<Counter Name="% Idle Time" Range="100" HigherIsBetter="true">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareConstant, Microsoft.VisualStudio.QualityTools.LoadTest">
<RuleParameters>
<RuleParameter Name="AlertIfOver" Value="False" />
<RuleParameter Name="WarningThreshold" Value="40" />
<RuleParameter Name="CriticalThreshold" Value="20" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
<Counter Name="Avg. Disk Bytes/Read" RangeGroup="DiskBytesRate" />
<Counter Name="Avg. Disk Bytes/Transfer" RangeGroup="DiskBytesRate" />
<Counter Name="Avg. Disk Bytes/Write" RangeGroup="DiskBytesRate" />
<Counter Name="Avg. Disk Queue Length" RangeGroup="Disk Queue Length" />
<Counter Name="Avg. Disk Read Queue Length" RangeGroup="Disk Queue Length" />
<Counter Name="Avg. Disk Write Queue Length" RangeGroup="Disk Queue Length" />
<Counter Name="Current Disk Queue Length" RangeGroup="Disk Queue Length" />
<Counter Name="Avg. Disk sec/Read" RangeGroup="Disk sec" />
<Counter Name="Avg. Disk sec/Transfer" RangeGroup="Disk sec" />
<Counter Name="Avg. Disk sec/Write" RangeGroup="Disk sec" />
<Counter Name="Disk Bytes/sec" RangeGroup="Disk Bytes sec" />
<Counter Name="Disk Read Bytes/sec" RangeGroup="Disk Bytes sec" />
<Counter Name="Disk Reads/sec" RangeGroup="Disk Transfers sec" />
<Counter Name="Disk Transfers/sec" RangeGroup="Disk Transfers sec" />
<Counter Name="Disk Write Bytes/sec" RangeGroup="Disk Bytes sec" />
<Counter Name="Disk Writes/sec" RangeGroup="Disk Transfers sec" />
<Counter Name="Split IO/Sec" RangeGroup="Disk Transfers sec" />
</Counters>
<Instances>
<Instance Name="*" />
</Instances>
</CounterCategory>
<CounterCategory Name="Processor">
<Counters>
<Counter Name="% Processor Time" Range="100">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareConstant, Microsoft.VisualStudio.QualityTools.LoadTest">
<RuleParameters>
<RuleParameter Name="AlertIfOver" Value="True" />
<RuleParameter Name="WarningThreshold" Value="75" />
<RuleParameter Name="CriticalThreshold" Value="90" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
<Counter Name="% Privileged Time" Range="100" />
<Counter Name="% User Time" Range="100" />
</Counters>
<Instances>
<Instance Name="_Total" />
</Instances>
</CounterCategory>
<CounterCategory Name="System">
<Counters>
<Counter Name="Context Switches/sec" />
<Counter Name="Processes" />
<Counter Name="Processor Queue Length" />
<Counter Name="Threads" />
</Counters>
</CounterCategory>
<CounterCategory Name="Process">
<Counters>
<Counter Name="% Processor Time" RangeGroup="Processor Time" />
<Counter Name="% Privileged Time" RangeGroup="Processor Time" />
<Counter Name="% User Time" RangeGroup="Processor Time" />
<Counter Name="Handle Count" />
<Counter Name="Thread Count" />
<Counter Name="Private Bytes" RangeGroup="Memory Bytes" />
<Counter Name="Virtual Bytes" RangeGroup="Memory Bytes" />
<Counter Name="Working Set" RangeGroup="Memory Bytes" />
</Counters>
<Instances>
<Instance Name="QTController" />
</Instances>
</CounterCategory>
</CounterCategories>
<DefaultCountersForAutomaticGraphs>
<DefaultCounter CategoryName="Processor" CounterName="% Processor Time" InstanceName="_Total" GraphName="" />
<DefaultCounter CategoryName="Memory" CounterName="Available MBytes" InstanceName="" GraphName="" />
</DefaultCountersForAutomaticGraphs>
</CounterSet>
<CounterSet Name="Agent" CounterSetType="Agent" LocId="CounterSet_Agent">
<CounterCategories>
<CounterCategory Name="Memory">
<Counters>
<Counter Name="% Committed Bytes In Use" Range="100" />
<Counter Name="Available MBytes" RangeGroup="Memory Bytes" HigherIsBetter="true">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareConstant, Microsoft.VisualStudio.QualityTools.LoadTest">
<RuleParameters>
<RuleParameter Name="AlertIfOver" Value="False" />
<RuleParameter Name="WarningThreshold" Value="100" />
<RuleParameter Name="CriticalThreshold" Value="50" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
<Counter Name="Page Faults/sec" />
<Counter Name="Pages/sec" />
<Counter Name="Pool Paged Bytes" RangeGroup="Memory Bytes" />
<Counter Name="Pool Nonpaged bytes" RangeGroup="Memory Bytes" />
</Counters>
</CounterCategory>
<CounterCategory Name="Network Interface">
<Counters>
<Counter Name="Bytes Received/sec" RangeGroup="Network Bytes" />
<Counter Name="Bytes Sent/sec" RangeGroup="Network Bytes" />
<Counter Name="Output Queue Length">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareConstant, Microsoft.VisualStudio.QualityTools.LoadTest">
<RuleParameters>
<RuleParameter Name="AlertIfOver" Value="True" />
<RuleParameter Name="WarningThreshold" Value="1.5" />
<RuleParameter Name="CriticalThreshold" Value="2" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
<Counter Name="Packets Received/sec" RangeGroup="Network Packets" />
<Counter Name="Packets Sent/sec" RangeGroup="Network Packets" />
<Counter Name="Current Bandwidth" RangeGroup="Network Bytes" />
<Counter Name="Bytes Total/sec" RangeGroup="Network Bytes">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareCounters, Microsoft.VisualStudio.QualityTools.LoadTest, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<RuleParameters>
<RuleParameter Name="DependentCategory" Value="Network Interface" />
<RuleParameter Name="DependentCounter" Value="Current Bandwidth" />
<RuleParameter Name="DependentInstance" Value="" />
<RuleParameter Name="AlertIfOver" Value="True" />
<RuleParameter Name="WarningThreshold" Value="0.6" />
<RuleParameter Name="CriticalThreshold" Value="0.7" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
</Counters>
<Instances>
<Instance Name="*" />
</Instances>
</CounterCategory>
<CounterCategory Name="PhysicalDisk">
<Counters>
<Counter Name="% Disk Read Time" Range="100" />
<Counter Name="% Disk Time" Range="100" />
<Counter Name="% Disk Write Time" Range="100" />
<Counter Name="% Idle Time" Range="100" HigherIsBetter="true">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareConstant, Microsoft.VisualStudio.QualityTools.LoadTest">
<RuleParameters>
<RuleParameter Name="AlertIfOver" Value="False" />
<RuleParameter Name="WarningThreshold" Value="40" />
<RuleParameter Name="CriticalThreshold" Value="20" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
<Counter Name="Avg. Disk Bytes/Read" RangeGroup="DiskBytesRate" />
<Counter Name="Avg. Disk Bytes/Transfer" RangeGroup="DiskBytesRate" />
<Counter Name="Avg. Disk Bytes/Write" RangeGroup="DiskBytesRate" />
<Counter Name="Avg. Disk Queue Length" RangeGroup="Disk Queue Length" />
<Counter Name="Avg. Disk Read Queue Length" RangeGroup="Disk Queue Length" />
<Counter Name="Avg. Disk Write Queue Length" RangeGroup="Disk Queue Length" />
<Counter Name="Current Disk Queue Length" RangeGroup="Disk Queue Length" />
<Counter Name="Avg. Disk sec/Read" RangeGroup="Disk sec" />
<Counter Name="Avg. Disk sec/Transfer" RangeGroup="Disk sec" />
<Counter Name="Avg. Disk sec/Write" RangeGroup="Disk sec" />
<Counter Name="Disk Bytes/sec" RangeGroup="Disk Bytes sec" />
<Counter Name="Disk Read Bytes/sec" RangeGroup="Disk Bytes sec" />
<Counter Name="Disk Reads/sec" RangeGroup="Disk Transfers sec" />
<Counter Name="Disk Transfers/sec" RangeGroup="Disk Transfers sec" />
<Counter Name="Disk Write Bytes/sec" RangeGroup="Disk Bytes sec" />
<Counter Name="Disk Writes/sec" RangeGroup="Disk Transfers sec" />
<Counter Name="Split IO/Sec" RangeGroup="Disk Transfers sec" />
</Counters>
<Instances>
<Instance Name="*" />
</Instances>
</CounterCategory>
<CounterCategory Name="Processor">
<Counters>
<Counter Name="% Processor Time" Range="100">
<ThresholdRules>
<ThresholdRule Classname="Microsoft.VisualStudio.TestTools.WebStress.Rules.ThresholdRuleCompareConstant, Microsoft.VisualStudio.QualityTools.LoadTest">
<RuleParameters>
<RuleParameter Name="AlertIfOver" Value="True" />
<RuleParameter Name="WarningThreshold" Value="75" />
<RuleParameter Name="CriticalThreshold" Value="90" />
</RuleParameters>
</ThresholdRule>
</ThresholdRules>
</Counter>
<Counter Name="% Privileged Time" Range="100" />
<Counter Name="% User Time" Range="100" />
</Counters>
<Instances>
<Instance Name="0" />
<Instance Name="_Total" />
</Instances>
</CounterCategory>
<CounterCategory Name="System">
<Counters>
<Counter Name="Context Switches/sec" />
<Counter Name="Processes" />
<Counter Name="Processor Queue Length" />
<Counter Name="Threads" />
</Counters>
</CounterCategory>
<CounterCategory Name="Process">
<Counters>
<Counter Name="% Processor Time" RangeGroup="Processor Time" />
<Counter Name="% Privileged Time" RangeGroup="Processor Time" />
<Counter Name="% User Time" RangeGroup="Processor Time" />
<Counter Name="Handle Count" />
<Counter Name="Thread Count" />
<Counter Name="Private Bytes" RangeGroup="Memory Bytes" />
<Counter Name="Virtual Bytes" RangeGroup="Memory Bytes" />
<Counter Name="Working Set" RangeGroup="Memory Bytes" />
</Counters>
<Instances>
<Instance Name="devenv" />
<Instance Name="QTAgentService" />
<Instance Name="QTAgent" />
<Instance Name="QTAgent32" />
<Instance Name="QTDCAgent" />
<Instance Name="QTDCAgent32" />
</Instances>
</CounterCategory>
</CounterCategories>
<DefaultCountersForAutomaticGraphs>
<DefaultCounter CategoryName="Processor" CounterName="% Processor Time" InstanceName="0" GraphName="" RunType="Local" />
<DefaultCounter CategoryName="Processor" CounterName="% Processor Time" InstanceName="_Total" GraphName="" RunType="Remote" />
<DefaultCounter CategoryName="Memory" CounterName="Available MBytes" InstanceName="" GraphName="" />
</DefaultCountersForAutomaticGraphs>
</CounterSet>
</CounterSets>
<RunConfigurations>
<RunConfiguration Name="Run Settings1" Description="" ResultsStoreType="Database" TimingDetailsStorage="AllIndividualDetails" SaveTestLogsOnError="true" SaveTestLogsFrequency="0" MaxErrorDetails="200" MaxErrorsPerType="1000" MaxThresholdViolations="1000" MaxRequestUrlsReported="1000" UseTestIterations="false" RunDuration="600" WarmupTime="0" CoolDownTime="0" TestIterations="100" WebTestConnectionModel="ConnectionPerUser" WebTestConnectionPoolSize="50" SampleRate="5" ValidationLevel="High" SqlTracingConnectString="" SqlTracingConnectStringDisplayValue="" SqlTracingDirectory="" SqlTracingEnabled="false" SqlTracingFileCount="2" SqlTracingRolloverEnabled="true" SqlTracingMinimumDuration="500" RunUnitTestsInAppDomain="true" RigType="Small">
<CounterSetMappings>
<CounterSetMapping ComputerName="[CONTROLLER MACHINE]">
<CounterSetReferences>
<CounterSetReference CounterSetName="LoadTest" />
<CounterSetReference CounterSetName="Controller" />
</CounterSetReferences>
</CounterSetMapping>
<CounterSetMapping ComputerName="[AGENT MACHINES]">
<CounterSetReferences>
<CounterSetReference CounterSetName="Agent" />
</CounterSetReferences>
</CounterSetMapping>
</CounterSetMappings>
</RunConfiguration>
</RunConfigurations>
</LoadTest>

35
src/Web.Test/Properties/AssemblyInfo.cs

@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Web.Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Web.Test")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("fca3a159-343c-449c-a4a7-eb111948088a")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

89
src/Web.Test/Web.Tests.csproj

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Web.Test</RootNamespace>
<AssemblyName>Web.Test</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TestProjectType>WebTest</TestProjectType>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.LoadTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="Microsoft.VisualStudio.QualityTools.WebTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
<Visible>False</Visible>
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WebTest1Coded.cs" />
</ItemGroup>
<ItemGroup>
<None Include="LoadTest1.loadtest">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="WebTest1.webtest">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

1
src/Web.Test/WebTest1.497d23f8-ba06-4350-9f93-8ba9772d5650.rec.webtestresult.REMOVED.git-id

@ -0,0 +1 @@
0ef62688bafd770fda6994538f8e83a1f632d6c4

14
src/Web.Test/WebTest1.webtest

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<WebTest Name="WebTest1" Id="2573f2eb-56b5-4552-8818-12748986ff45" Owner="" Priority="2147483647" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="0" WorkItemIds="" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="" StopOnError="False" RecordedResultFile="WebTest1.497d23f8-ba06-4350-9f93-8ba9772d5650.rec.webtestresult">
<Items>
<Request Method="GET" Guid="d0032065-a7ca-4340-9fbf-ac511d60471a" Version="1.1" Url="http://localhost:6261/" ThinkTime="6" Timeout="300" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8" ExpectedHttpStatusCode="0" ExpectedResponseUrl="" ReportingName="" IgnoreHttpStatusCode="False" />
</Items>
<ValidationRules>
<ValidationRule Classname="Microsoft.VisualStudio.TestTools.WebTesting.Rules.ValidateResponseUrl, Microsoft.VisualStudio.QualityTools.WebTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" DisplayName="Response URL" Description="Validates that the response URL after redirects are followed is the same as the recorded response URL. QueryString parameters are ignored." Level="Low" ExectuionOrder="BeforeDependents" />
<ValidationRule Classname="Microsoft.VisualStudio.TestTools.WebTesting.Rules.ValidationRuleResponseTimeGoal, Microsoft.VisualStudio.QualityTools.WebTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" DisplayName="Response Time Goal" Description="Validates that the response time for the request is less than or equal to the response time goal as specified on the request. Response time goals of zero will be ignored." Level="Low" ExectuionOrder="AfterDependents">
<RuleParameters>
<RuleParameter Name="Tolerance" Value="0" />
</RuleParameters>
</ValidationRule>
</ValidationRules>
</WebTest>

28
src/Web.Test/WebTest1Coded.cs

@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18033
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Web.Test {
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.TestTools.WebTesting;
public class WebTest1Coded : WebTest {
public WebTest1Coded() {
this.PreAuthenticate = true;
}
public override IEnumerator<WebTestRequest> GetRequestEnumerator() {
yield break;
}
}
}
Loading…
Cancel
Save