Added test project for selfhost and added test for HttpSelfHostConfiguration (fixed bugs that showed up as a result)

Added helpers for verifying properties of type int/long/bool/enum -- this compliments the one we have already for reference types.
This commit is contained in:
henrikn 2012-03-14 16:50:20 -07:00
Родитель cc10b42e05
Коммит 645d8c561a
11 изменённых файлов: 522 добавлений и 47 удалений

Просмотреть файл

@ -98,6 +98,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Web.WebPages.OAut
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Web.WebPages.OAuth.Test", "test\Microsoft.Web.WebPages.OAuth.Test\Microsoft.Web.WebPages.OAuth.Test.csproj", "{694C6EDF-EA52-438F-B745-82B025ECC0E7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Web.Http.SelfHost.Test", "test\System.Web.Http.SelfHost.Test\System.Web.Http.SelfHost.Test.csproj", "{7F29EE87-6A63-43C6-B7FF-74DD06815830}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
CodeCov|Any CPU = CodeCov|Any CPU
@ -1014,6 +1016,26 @@ Global
{694C6EDF-EA52-438F-B745-82B025ECC0E7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{694C6EDF-EA52-438F-B745-82B025ECC0E7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{694C6EDF-EA52-438F-B745-82B025ECC0E7}.Release|x86.ActiveCfg = Release|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|Any CPU.ActiveCfg = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|Any CPU.Build.0 = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|Mixed Platforms.ActiveCfg = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|Mixed Platforms.Build.0 = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCov|x86.ActiveCfg = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|Any CPU.ActiveCfg = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|Any CPU.Build.0 = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|Mixed Platforms.ActiveCfg = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|Mixed Platforms.Build.0 = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.CodeCoverage|x86.ActiveCfg = CodeCoverage|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Debug|x86.ActiveCfg = Debug|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|Any CPU.Build.0 = Release|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{7F29EE87-6A63-43C6-B7FF-74DD06815830}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1064,5 +1086,6 @@ Global
{EA62944F-BD25-4730-9405-9BE8FF5BEACD} = {C40883CD-366D-4534-8B58-3EA0D13136DF}
{7B8601F8-8D1F-4B9C-8C20-772B673A2FA6} = {C40883CD-366D-4534-8B58-3EA0D13136DF}
{694C6EDF-EA52-438F-B745-82B025ECC0E7} = {C40883CD-366D-4534-8B58-3EA0D13136DF}
{7F29EE87-6A63-43C6-B7FF-74DD06815830} = {C40883CD-366D-4534-8B58-3EA0D13136DF}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -25,7 +25,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with the provided properties and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentException"/> with the provided properties.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
@ -36,7 +36,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with the provided properties and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentException"/> with the provided properties.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
@ -48,7 +48,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with a message saying that the argument must be an "http" or "https" URI and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentException"/> with a message saying that the argument must be an "http" or "https" URI.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
@ -59,7 +59,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with a message saying that the argument must be an absolute URI and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentException"/> with a message saying that the argument must be an absolute URI.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
@ -82,7 +82,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentNullException"/> with the provided properties and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentNullException"/> with the provided properties.
/// </summary>
/// <returns>The logged <see cref="Exception"/>.</returns>
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "The purpose of this API is to return an error for properties")]
@ -92,7 +92,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentNullException"/> with the provided properties and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentNullException"/> with the provided properties.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
@ -102,7 +102,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentNullException"/> with the provided properties and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentNullException"/> with the provided properties.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
@ -114,7 +114,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with a default message and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentException"/> with a default message.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
@ -124,7 +124,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentOutOfRangeException"/> with the provided properties and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentOutOfRangeException"/> with the provided properties.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
@ -137,7 +137,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentOutOfRangeException"/> with a message saying that the argument must be greater than or equal to <paramref name="minValue"/> and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentOutOfRangeException"/> with a message saying that the argument must be greater than or equal to <paramref name="minValue"/>.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
@ -149,7 +149,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ArgumentOutOfRangeException"/> with a message saying that the argument must be less than or equal to <paramref name="maxValue"/> and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ArgumentOutOfRangeException"/> with a message saying that the argument must be less than or equal to <paramref name="maxValue"/>.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
@ -161,7 +161,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="KeyNotFoundException"/> with a message saying that the key was not found and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="KeyNotFoundException"/> with a message saying that the key was not found.
/// </summary>
/// <returns>The logged <see cref="Exception"/>.</returns>
public static KeyNotFoundException KeyNotFound()
@ -170,7 +170,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="KeyNotFoundException"/> with a message saying that the key was not found and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="KeyNotFoundException"/> with a message saying that the key was not found.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
@ -181,7 +181,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="ObjectDisposedException"/> initialized according to guidelines and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="ObjectDisposedException"/> initialized according to guidelines.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
@ -193,7 +193,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="OperationCanceledException"/> initialized with the provided parameters and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="OperationCanceledException"/> initialized with the provided parameters.
/// </summary>
/// <returns>The logged <see cref="Exception"/>.</returns>
public static OperationCanceledException OperationCanceled()
@ -202,7 +202,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="OperationCanceledException"/> initialized with the provided parameters and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="OperationCanceledException"/> initialized with the provided parameters.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
@ -213,7 +213,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="InvalidEnumArgumentException"/> and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="InvalidEnumArgumentException"/>.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="invalidValue">The value of the argument that failed.</param>
@ -225,7 +225,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="InvalidOperationException"/> and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="InvalidOperationException"/>.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
@ -236,7 +236,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="InvalidOperationException"/> and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="InvalidOperationException"/>.
/// </summary>
/// <param name="innerException">Inner exception</param>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
@ -248,7 +248,7 @@ namespace System.Web.Http.Common
}
/// <summary>
/// Creates an <see cref="NotSupportedException"/> and logs it with <see cref="F:TraceLevel.Error"/>.
/// Creates an <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>

Просмотреть файл

@ -79,7 +79,7 @@ namespace System.Web.Http.Common.Properties {
}
/// <summary>
/// Looks up a localized string similar to The argument &apos;{0}&apos; must be greater than or equal to {1}..
/// Looks up a localized string similar to Value must be greater than or equal to {1}..
/// </summary>
internal static string ArgumentMustBeGreaterThanOrEqualTo {
get {
@ -88,7 +88,7 @@ namespace System.Web.Http.Common.Properties {
}
/// <summary>
/// Looks up a localized string similar to The argument &apos;{0}&apos; must be less than or equal to {1}..
/// Looks up a localized string similar to Value must be less than or equal to {1}..
/// </summary>
internal static string ArgumentMustBeLessThanOrEqualTo {
get {

Просмотреть файл

@ -124,10 +124,10 @@
<value>Unsupported URI scheme: '{0}'. The URI scheme must be either '{1}' or '{2}'.</value>
</data>
<data name="ArgumentMustBeGreaterThanOrEqualTo" xml:space="preserve">
<value>The argument '{0}' must be greater than or equal to {1}.</value>
<value>Value must be greater than or equal to {1}.</value>
</data>
<data name="ArgumentMustBeLessThanOrEqualTo" xml:space="preserve">
<value>The argument '{0}' must be less than or equal to {1}.</value>
<value>Value must be less than or equal to {1}.</value>
</data>
<data name="ArgumentNullOrEmpty" xml:space="preserve">
<value>The argument '{0}' is null or empty.</value>

Просмотреть файл

@ -18,6 +18,9 @@ namespace System.Web.Http.SelfHost
public class HttpSelfHostConfiguration : HttpConfiguration
{
private const int DefaultMaxConcurrentRequests = 100;
private const int DefaultMaxBufferSize = 64 * 1024;
private const int DefaultReceivedMessageSize = 64 * 1024;
private const int PendingContextFactor = 100;
private const int MinConcurrentRequests = 1;
private const int MinBufferSize = 0;
@ -28,15 +31,16 @@ namespace System.Web.Http.SelfHost
private ServiceCredentials _credentials = new ServiceCredentials();
private bool _useWindowsAuth;
private TransferMode _transferMode;
private int _maxBufferSize;
private long _maxReceivedMessageSize;
private int _maxBufferSize = DefaultMaxBufferSize;
private long _maxReceivedMessageSize = DefaultReceivedMessageSize;
private HostNameComparisonMode _hostNameComparisonMode;
/// <summary>
/// Initializes a new instance of the <see cref="HttpSelfHostConfiguration"/> class.
/// </summary>
/// <param name="baseAddress">The base address.</param>
public HttpSelfHostConfiguration(string baseAddress)
: this(new Uri(baseAddress, UriKind.RelativeOrAbsolute))
: this(CreateBaseAddress(baseAddress))
{
}
@ -82,6 +86,7 @@ namespace System.Web.Http.SelfHost
{
throw Error.ArgumentTooSmall("value", value, MinConcurrentRequests);
}
_maxConcurrentRequests = value;
}
}
@ -102,6 +107,20 @@ namespace System.Web.Http.SelfHost
}
}
/// <summary>
/// Specifies how the host name should be used in URI comparisons when dispatching an incoming message.
/// </summary>
public HostNameComparisonMode HostNameComparisonMode
{
get { return _hostNameComparisonMode; }
set
{
HostNameComparisonModeHelper.Validate(value);
_hostNameComparisonMode = value;
}
}
/// <summary>
/// Gets or sets the size of the max buffer.
/// </summary>
@ -118,7 +137,6 @@ namespace System.Web.Http.SelfHost
{
throw Error.ArgumentTooSmall("value", value, MinBufferSize);
}
_maxBufferSize = value;
}
}
@ -139,7 +157,6 @@ namespace System.Web.Http.SelfHost
{
throw Error.ArgumentTooSmall("value", value, MinReceivedMessageSize);
}
_maxReceivedMessageSize = value;
}
}
@ -203,6 +220,8 @@ namespace System.Web.Http.SelfHost
httpBinding.MaxBufferSize = MaxBufferSize;
httpBinding.MaxReceivedMessageSize = MaxReceivedMessageSize;
httpBinding.TransferMode = TransferMode;
httpBinding.HostNameComparisonMode = HostNameComparisonMode;
if (_baseAddress.Scheme == Uri.UriSchemeHttps)
{
// we need to use SSL
@ -232,7 +251,7 @@ namespace System.Web.Http.SelfHost
}
else if (_useWindowsAuth)
{
if (httpBinding.Security == null)
if (httpBinding.Security == null || httpBinding.Security.Mode == HttpBindingSecurityMode.None)
{
// Basic over HTTP case, should we even allow this?
httpBinding.Security = new HttpBindingSecurity()
@ -257,6 +276,16 @@ namespace System.Web.Http.SelfHost
return bindingParameters;
}
private static Uri CreateBaseAddress(string baseAddress)
{
if (baseAddress == null)
{
throw Error.ArgumentNull("baseAddress");
}
return new Uri(baseAddress, UriKind.RelativeOrAbsolute);
}
private static Uri ValidateBaseAddress(Uri baseAddress)
{
if (baseAddress == null)

Просмотреть файл

@ -342,12 +342,14 @@ namespace Microsoft.TestCommon
/// <param name="paramName">The name of the parameter that should throw the exception</param>
/// <param name="exceptionMessage">The exception message to verify</param>
/// <param name="allowDerivedExceptions">Pass true to allow exceptions which derive from TException; pass false, otherwise</param>
/// <param name="actualValue">The actual value provided</param>
/// <returns>The exception that was thrown, when successful</returns>
/// <exception cref="ThrowsException">Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown</exception>
public static ArgumentOutOfRangeException ThrowsArgumentOutOfRange(Action testCode, string paramName, string exceptionMessage, bool allowDerivedExceptions = false)
public static ArgumentOutOfRangeException ThrowsArgumentOutOfRange(Action testCode, string paramName, string exceptionMessage, bool allowDerivedExceptions = false, object actualValue = null)
{
exceptionMessage = exceptionMessage != null
? exceptionMessage + "\r\nParameter name: " + paramName
? exceptionMessage + "\r\nParameter name: " + paramName +
(actualValue != null ? "\r\nActual value was " + actualValue.ToString() + "." : "")
: exceptionMessage;
var ex = Throws<ArgumentOutOfRangeException>(testCode, exceptionMessage, allowDerivedExceptions);
@ -361,16 +363,17 @@ namespace Microsoft.TestCommon
/// <summary>
/// Verifies that the code throws an <see cref="ArgumentOutOfRangeException"/> with the expected message that indicates that
/// the value must be greater than the given value.
/// the value must be greater than the given <paramref name="minValue"/>.
/// </summary>
/// <param name="testCode">A delegate to the code to be tested</param>
/// <param name="paramName">The name of the parameter that should throw the exception</param>
/// <param name="value">The expected limit value.</param>
/// <param name="actualValue">The actual value provided.</param>
/// <param name="minValue">The expected limit value.</param>
/// <returns>The exception that was thrown, when successful</returns>
/// <exception cref="ThrowsException">Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown</exception>
public static ArgumentOutOfRangeException ThrowsArgumentGreaterThan(Action testCode, string paramName, string value)
public static ArgumentOutOfRangeException ThrowsArgumentGreaterThan(Action testCode, string paramName, string minValue, object actualValue = null)
{
return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be greater than {0}.", value));
return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be greater than {0}.", minValue), false, actualValue);
}
/// <summary>
@ -379,40 +382,42 @@ namespace Microsoft.TestCommon
/// </summary>
/// <param name="testCode">A delegate to the code to be tested</param>
/// <param name="paramName">The name of the parameter that should throw the exception</param>
/// <param name="value">The expected limit value.</param>
/// <param name="minValue">The expected limit value.</param>
/// <returns>The exception that was thrown, when successful</returns>
/// <exception cref="ThrowsException">Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown</exception>
public static ArgumentOutOfRangeException ThrowsArgumentGreaterThanOrEqualTo(Action testCode, string paramName, string value)
public static ArgumentOutOfRangeException ThrowsArgumentGreaterThanOrEqualTo(Action testCode, string paramName, string minValue, object actualValue = null)
{
return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be greater than or equal to {0}.", value));
return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be greater than or equal to {0}.", minValue), false, actualValue);
}
/// <summary>
/// Verifies that the code throws an <see cref="ArgumentOutOfRangeException"/> with the expected message that indicates that
/// the value must be less than the given value.
/// the value must be less than the given <paramref name="maxValue"/>.
/// </summary>
/// <param name="testCode">A delegate to the code to be tested</param>
/// <param name="paramName">The name of the parameter that should throw the exception</param>
/// <param name="value">The expected limit value.</param>
/// <param name="actualValue">The actual value provided.</param>
/// <param name="maxValue">The expected limit value.</param>
/// <returns>The exception that was thrown, when successful</returns>
/// <exception cref="ThrowsException">Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown</exception>
public static ArgumentOutOfRangeException ThrowsArgumentLessThan(Action testCode, string paramName, string value)
public static ArgumentOutOfRangeException ThrowsArgumentLessThan(Action testCode, string paramName, string maxValue, object actualValue = null)
{
return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be less than {0}.", value));
return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be less than {0}.", maxValue), false, actualValue);
}
/// <summary>
/// Verifies that the code throws an <see cref="ArgumentOutOfRangeException"/> with the expected message that indicates that
/// the value must be less than or equal to the given value.
/// the value must be less than or equal to the given <paramref name="maxValue"/>.
/// </summary>
/// <param name="testCode">A delegate to the code to be tested</param>
/// <param name="paramName">The name of the parameter that should throw the exception</param>
/// <param name="value">The expected limit value.</param>
/// <param name="actualValue">The actual value provided.</param>
/// <param name="maxValue">The expected limit value.</param>
/// <returns>The exception that was thrown, when successful</returns>
/// <exception cref="ThrowsException">Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown</exception>
public static ArgumentOutOfRangeException ThrowsArgumentLessThanOrEqualTo(Action testCode, string paramName, string value)
public static ArgumentOutOfRangeException ThrowsArgumentLessThanOrEqualTo(Action testCode, string paramName, string maxValue, object actualValue = null)
{
return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be less than or equal to {0}.", value));
return ThrowsArgumentOutOfRange(testCode, paramName, String.Format("Value must be less than or equal to {0}.", maxValue), false, actualValue);
}
/// <summary>

Просмотреть файл

@ -61,6 +61,64 @@ namespace Microsoft.TestCommon
}
}
public void IntegerProperty<T, TResult>(T instance, Expression<Func<T, TResult>> propertyGetter, TResult expectedDefaultValue,
TResult? minLegalValue, TResult? illegalLowerValue,
TResult? maxLegalValue, TResult? illegalUpperValue,
TResult roundTripTestValue) where TResult : struct
{
PropertyInfo property = GetPropertyInfo(propertyGetter);
Func<T, TResult> getFunc = (obj) => (TResult)property.GetValue(obj, index: null);
Action<T, TResult> setFunc = (obj, value) => property.SetValue(obj, value, index: null);
Assert.Equal(expectedDefaultValue, getFunc(instance));
if (minLegalValue.HasValue)
{
TestPropertyValue(instance, getFunc, setFunc, minLegalValue.Value);
}
if (maxLegalValue.HasValue)
{
TestPropertyValue(instance, getFunc, setFunc, maxLegalValue.Value);
}
if (illegalLowerValue.HasValue)
{
Assert.ThrowsArgumentGreaterThanOrEqualTo(() => { setFunc(instance, illegalLowerValue.Value); }, "value", minLegalValue.Value.ToString(), illegalLowerValue.Value);
}
if (illegalUpperValue.HasValue)
{
Assert.ThrowsArgumentLessThanOrEqualTo(() => { setFunc(instance, illegalLowerValue.Value); }, "value", maxLegalValue.Value.ToString(), illegalUpperValue.Value);
}
TestPropertyValue(instance, getFunc, setFunc, roundTripTestValue);
}
public void BooleanProperty<T>(T instance, Expression<Func<T, bool>> propertyGetter, bool expectedDefaultValue)
{
PropertyInfo property = GetPropertyInfo(propertyGetter);
Func<T, bool> getFunc = (obj) => (bool)property.GetValue(obj, index: null);
Action<T, bool> setFunc = (obj, value) => property.SetValue(obj, value, index: null);
Assert.Equal(expectedDefaultValue, getFunc(instance));
TestPropertyValue(instance, getFunc, setFunc, !expectedDefaultValue);
}
public void EnumProperty<T, TResult>(T instance, Expression<Func<T, TResult>> propertyGetter, TResult expectedDefaultValue, TResult illegalValue, TResult roundTripTestValue) where TResult : struct
{
PropertyInfo property = GetPropertyInfo(propertyGetter);
Func<T, TResult> getFunc = (obj) => (TResult)property.GetValue(obj, index: null);
Action<T, TResult> setFunc = (obj, value) => property.SetValue(obj, value, index: null);
Assert.Equal(expectedDefaultValue, getFunc(instance));
Assert.ThrowsInvalidEnumArgument(() => { setFunc(instance, illegalValue); }, "value", Convert.ToInt32(illegalValue), typeof(TResult));
TestPropertyValue(instance, getFunc, setFunc, roundTripTestValue);
}
public void StringProperty<T>(T instance, Expression<Func<T, string>> propertyGetter, string expectedDefaultValue,
bool allowNullAndEmpty = true, string nullAndEmptyReturnValue = "")
{

Просмотреть файл

@ -0,0 +1,258 @@
using System.IdentityModel.Selectors;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Web.Http.SelfHost;
using System.Web.Http.SelfHost.Channels;
using Moq;
using Xunit;
using Xunit.Extensions;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Http.WebHost
{
public class HttpSelfHostConfigurationTest
{
[Fact]
public void HttpSelfHostConfiguration_NullBaseAddressString_Throws()
{
Assert.ThrowsArgumentNull(() => new HttpSelfHostConfiguration((string)null), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_RelativeBaseAddressString_Throws()
{
Assert.ThrowsArgument(() => new HttpSelfHostConfiguration("relative"), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_QueryBaseAddressString_Throws()
{
Assert.ThrowsArgument(() => new HttpSelfHostConfiguration("http://localhost?somequery"), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_FragmentBaseAddressString_Throws()
{
Assert.ThrowsArgument(() => new HttpSelfHostConfiguration("http://localhost#somefragment"), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_InvalidSchemeBaseAddressString_Throws()
{
Assert.ThrowsArgument(() => new HttpSelfHostConfiguration("ftp://localhost"), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_NullBaseAddress_Throws()
{
Assert.ThrowsArgumentNull(() => new HttpSelfHostConfiguration((Uri)null), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_RelativeBaseAddress_Throws()
{
Assert.ThrowsArgument(() => new HttpSelfHostConfiguration(new Uri("relative", UriKind.Relative)), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_QueryBaseAddress_Throws()
{
Assert.ThrowsArgument(() => new HttpSelfHostConfiguration(new Uri("http://localhost?somequery")), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_FragmentBaseAddress_Throws()
{
Assert.ThrowsArgument(() => new HttpSelfHostConfiguration(new Uri("http://localhost#somefragment")), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_InvalidSchemeBaseAddress_Throws()
{
Assert.ThrowsArgument(() => new HttpSelfHostConfiguration(new Uri("ftp://localhost")), "baseAddress");
}
[Fact]
public void HttpSelfHostConfiguration_BaseAddress_IsSet()
{
// Arrange
Uri baseAddress = new Uri("http://localhost");
// Act
HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(baseAddress);
// Assert
Assert.Same(baseAddress, config.BaseAddress);
}
[Fact]
public void HttpSelfHostConfiguration_MaxConcurrentRequests_RoundTrips()
{
Assert.Reflection.IntegerProperty(
new HttpSelfHostConfiguration("http://localhost"),
c => c.MaxConcurrentRequests,
expectedDefaultValue: GetDefaultMaxConcurrentRequests(),
minLegalValue: 1,
illegalLowerValue: 0,
maxLegalValue: null,
illegalUpperValue: null,
roundTripTestValue: 10);
}
[Fact]
public void HttpSelfHostConfiguration_MaxBufferSize_RoundTrips()
{
Assert.Reflection.IntegerProperty(
new HttpSelfHostConfiguration("http://localhost"),
c => c.MaxBufferSize,
expectedDefaultValue: 64 * 1024,
minLegalValue: 0,
illegalLowerValue: -1,
maxLegalValue: null,
illegalUpperValue: null,
roundTripTestValue: 10);
}
[Fact]
public void HttpSelfHostConfiguration_MaxReceivedMessageSize_RoundTrips()
{
Assert.Reflection.IntegerProperty(
new HttpSelfHostConfiguration("http://localhost"),
c => c.MaxReceivedMessageSize,
expectedDefaultValue: 64 * 1024,
minLegalValue: 0,
illegalLowerValue: -1,
maxLegalValue: null,
illegalUpperValue: null,
roundTripTestValue: 10);
}
[Fact]
public void HttpSelfHostConfiguration_UseWindowsAuthentication_RoundTrips()
{
Assert.Reflection.BooleanProperty(
new HttpSelfHostConfiguration("http://localhost"),
c => c.UseWindowsAuthentication,
expectedDefaultValue: false);
}
[Fact]
public void HttpSelfHostConfiguration_UserNamePasswordValidator_RoundTrips()
{
// Arrange
UserNamePasswordValidator userNamePasswordValidator = new Mock<UserNamePasswordValidator>().Object;
Assert.Reflection.Property(
new HttpSelfHostConfiguration("http://localhost"),
c => c.UserNamePasswordValidator,
expectedDefaultValue: null,
allowNull: true,
roundTripTestValue: userNamePasswordValidator);
}
[Fact]
public void HttpSelfHostConfiguration_TransferMode_RoundTrips()
{
Assert.Reflection.EnumProperty(
new HttpSelfHostConfiguration("http://localhost"),
c => c.TransferMode,
expectedDefaultValue: TransferMode.Buffered,
illegalValue: (TransferMode)999,
roundTripTestValue: TransferMode.Streamed);
}
[Fact]
public void HttpSelfHostConfiguration_HostNameComparisonMode_RoundTrips()
{
Assert.Reflection.EnumProperty(
new HttpSelfHostConfiguration("http://localhost"),
c => c.HostNameComparisonMode,
expectedDefaultValue: HostNameComparisonMode.StrongWildcard,
illegalValue: (HostNameComparisonMode)999,
roundTripTestValue: HostNameComparisonMode.Exact);
}
[Fact]
public void HttpSelfHostConfiguration_Settings_PropagateToBinding()
{
// Arrange
HttpBinding binding = new HttpBinding();
HttpSelfHostConfiguration config = new HttpSelfHostConfiguration("http://localhost")
{
MaxBufferSize = 10,
MaxReceivedMessageSize = 11,
TransferMode = TransferMode.StreamedResponse,
HostNameComparisonMode = HostNameComparisonMode.WeakWildcard
};
// Act
config.ConfigureBinding(binding);
// Assert
Assert.Equal(10, binding.MaxBufferSize);
Assert.Equal(11, binding.MaxReceivedMessageSize);
Assert.Equal(TransferMode.StreamedResponse, binding.TransferMode);
Assert.Equal(HostNameComparisonMode.WeakWildcard, binding.HostNameComparisonMode);
}
[Theory]
[InlineData("http://localhost", HttpBindingSecurityMode.TransportCredentialOnly)]
[InlineData("https://localhost", HttpBindingSecurityMode.Transport)]
public void HttpSelfHostConfiguration_UseWindowsAuth_PropagatesToHttpBinding(string address, HttpBindingSecurityMode mode)
{
// Arrange
HttpBinding binding = new HttpBinding();
HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(address)
{
UseWindowsAuthentication = true
};
// Act
BindingParameterCollection parameters = config.ConfigureBinding(binding);
// Assert
Assert.NotNull(parameters);
ServiceCredentials serviceCredentials = parameters.Find<ServiceCredentials>();
Assert.NotNull(serviceCredentials);
Assert.Equal(HttpClientCredentialType.Windows, binding.Security.Transport.ClientCredentialType);
Assert.Equal(mode, binding.Security.Mode);
}
[Theory]
[InlineData("http://localhost", HttpBindingSecurityMode.TransportCredentialOnly)]
[InlineData("https://localhost", HttpBindingSecurityMode.Transport)]
public void HttpSelfHostConfiguration_UserNamePasswordValidator_PropagatesToBinding(string address, HttpBindingSecurityMode mode)
{
// Arrange
HttpBinding binding = new HttpBinding();
UserNamePasswordValidator validator = new Mock<UserNamePasswordValidator>().Object;
HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(address)
{
UserNamePasswordValidator = validator
};
// Act
BindingParameterCollection parameters = config.ConfigureBinding(binding);
// Assert
Assert.NotNull(parameters);
ServiceCredentials serviceCredentials = parameters.Find<ServiceCredentials>();
Assert.NotNull(serviceCredentials);
Assert.Equal(HttpClientCredentialType.Basic, binding.Security.Transport.ClientCredentialType);
Assert.Equal(mode, binding.Security.Mode);
}
private static int GetDefaultMaxConcurrentRequests()
{
try
{
return Math.Max(Environment.ProcessorCount * 100, 100);
}
catch
{
return 100;
}
}
}
}

Просмотреть файл

@ -0,0 +1,3 @@
using System;
[assembly: CLSCompliant(false)]

Просмотреть файл

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),Runtime.sln))\tools\WebStack.settings.targets" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{7F29EE87-6A63-43C6-B7FF-74DD06815830}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>System.Web.Http.SelfHost</RootNamespace>
<AssemblyName>System.Web.Http.SelfHost.Test</AssemblyName>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>$(WebStackRootPath)\bin\Debug\Test\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>$(WebStackRootPath)\bin\Release\Test\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'CodeCoverage' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>$(WebStackRootPath)\bin\CodeCoverage\Test\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Moq, Version=4.0.10827.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.IdentityModel" />
<Reference Include="System.Net.Http">
<HintPath>..\..\packages\Microsoft.Net.Http.2.0.20302.1\lib\net40\System.Net.Http.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest">
<HintPath>..\..\packages\Microsoft.Net.Http.2.0.20302.1\lib\net40\System.Net.Http.WebRequest.dll</HintPath>
</Reference>
<Reference Include="System.ServiceModel" />
<Reference Include="System.Web" />
<Reference Include="xunit">
<HintPath>..\..\packages\xunit.1.9.0.1566\lib\xunit.dll</HintPath>
</Reference>
<Reference Include="xunit.extensions">
<HintPath>..\..\packages\xunit.extensions.1.9.0.1566\lib\xunit.extensions.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="HttpSelfHostConfigurationTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\System.Web.Http.SelfHost\System.Web.Http.SelfHost.csproj">
<Project>{66492E69-CE4C-4FB1-9B1F-88DEE09D06F1}</Project>
<Name>System.Web.Http.SelfHost</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\System.Web.Http\System.Web.Http.csproj">
<Project>{DDC1CE0C-486E-4E35-BB3B-EAB61F8F9440}</Project>
<Name>System.Web.Http</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\System.Web.Mvc\System.Web.Mvc.csproj">
<Project>{3D3FFD8A-624D-4E9B-954B-E1C105507975}</Project>
<Name>System.Web.Mvc</Name>
</ProjectReference>
<ProjectReference Include="..\Microsoft.TestCommon\Microsoft.TestCommon.csproj">
<Project>{FCCC4CB7-BAF7-4A57-9F89-E5766FE536C0}</Project>
<Name>Microsoft.TestCommon</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Net.Http" version="2.0.20302.1" />
<package id="Moq" version="4.0.10827" />
<package id="xunit" version="1.9.0.1566" />
<package id="xunit.extensions" version="1.9.0.1566" />
</packages>