mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-26 19:31:48 +01:00
Add support for Faults (#360)
* FaultType - wip * . * copy fault * tests * code-factor * more tests * fix tests * fixed * remove RANDOM_DATA_THEN_CLOSE
This commit is contained in:
18
src/WireMock.Net/Admin/Mappings/FaultModel.cs
Normal file
18
src/WireMock.Net/Admin/Mappings/FaultModel.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
namespace WireMock.Admin.Mappings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Fault Model
|
||||||
|
/// </summary>
|
||||||
|
public class FaultModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the fault. Can be null, "", NONE, EMPTY_RESPONSE, MALFORMED_RESPONSE_CHUNK or RANDOM_DATA_THEN_CLOSE.
|
||||||
|
/// </summary>
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the fault percentage.
|
||||||
|
/// </summary>
|
||||||
|
public double? Percentage { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -86,5 +86,10 @@ namespace WireMock.Admin.Mappings
|
|||||||
/// The client X509Certificate2 Thumbprint or SubjectName to use.
|
/// The client X509Certificate2 Thumbprint or SubjectName to use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string X509Certificate2ThumbprintOrSubjectName { get; set; }
|
public string X509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the fault.
|
||||||
|
/// </summary>
|
||||||
|
public FaultModel Fault { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
|
using WireMock.ResponseBuilders;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.Admin.Requests
|
namespace WireMock.Admin.Requests
|
||||||
@@ -68,5 +69,15 @@ namespace WireMock.Admin.Requests
|
|||||||
/// The detected body type (detection based on Content-Type).
|
/// The detected body type (detection based on Content-Type).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BodyType DetectedBodyTypeFromContentType { get; set; }
|
public BodyType DetectedBodyTypeFromContentType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The FaultType.
|
||||||
|
/// </summary>
|
||||||
|
public string FaultType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Fault percentage.
|
||||||
|
/// </summary>
|
||||||
|
public double? FaultPercentage { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,8 +4,11 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using RandomDataGenerator.FieldOptions;
|
||||||
|
using RandomDataGenerator.Randomizers;
|
||||||
using WireMock.Handlers;
|
using WireMock.Handlers;
|
||||||
using WireMock.Http;
|
using WireMock.Http;
|
||||||
|
using WireMock.ResponseBuilders;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
#if !USE_ASPNETCORE
|
#if !USE_ASPNETCORE
|
||||||
@@ -22,6 +25,8 @@ namespace WireMock.Owin.Mappers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class OwinResponseMapper : IOwinResponseMapper
|
public class OwinResponseMapper : IOwinResponseMapper
|
||||||
{
|
{
|
||||||
|
private readonly IRandomizerNumber<double> _randomizerDouble = RandomizerFactory.GetRandomizer(new FieldOptionsDouble { Min = 0, Max = 1 });
|
||||||
|
private readonly IRandomizerBytes _randomizerBytes = RandomizerFactory.GetRandomizer(new FieldOptionsBytes { Min = 100, Max = 200 });
|
||||||
private readonly IFileSystemHandler _fileSystemHandler;
|
private readonly IFileSystemHandler _fileSystemHandler;
|
||||||
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
|
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
|
||||||
|
|
||||||
@@ -53,8 +58,43 @@ namespace WireMock.Owin.Mappers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.StatusCode = responseMessage.StatusCode;
|
byte[] bytes;
|
||||||
|
switch (responseMessage.FaultType)
|
||||||
|
{
|
||||||
|
case FaultType.EMPTY_RESPONSE:
|
||||||
|
bytes = IsFault(responseMessage) ? new byte[0] : GetNormalBody(responseMessage);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FaultType.MALFORMED_RESPONSE_CHUNK:
|
||||||
|
bytes = GetNormalBody(responseMessage) ?? new byte[0];
|
||||||
|
if (IsFault(responseMessage))
|
||||||
|
{
|
||||||
|
bytes = bytes.Take(bytes.Length / 2).Union(_randomizerBytes.Generate()).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
bytes = GetNormalBody(responseMessage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.StatusCode = responseMessage.StatusCode;
|
||||||
|
SetResponseHeaders(responseMessage, response);
|
||||||
|
|
||||||
|
if (bytes != null)
|
||||||
|
{
|
||||||
|
await response.Body.WriteAsync(bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsFault(ResponseMessage responseMessage)
|
||||||
|
{
|
||||||
|
return responseMessage.FaultPercentage == null || _randomizerDouble.Generate() <= responseMessage.FaultPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] GetNormalBody(ResponseMessage responseMessage)
|
||||||
|
{
|
||||||
byte[] bytes = null;
|
byte[] bytes = null;
|
||||||
switch (responseMessage.BodyData?.DetectedBodyType)
|
switch (responseMessage.BodyData?.DetectedBodyType)
|
||||||
{
|
{
|
||||||
@@ -63,7 +103,9 @@ namespace WireMock.Owin.Mappers
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BodyType.Json:
|
case BodyType.Json:
|
||||||
Formatting formatting = responseMessage.BodyData.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
|
Formatting formatting = responseMessage.BodyData.BodyAsJsonIndented == true
|
||||||
|
? Formatting.Indented
|
||||||
|
: Formatting.None;
|
||||||
string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
|
string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
|
||||||
bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
|
bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
|
||||||
break;
|
break;
|
||||||
@@ -77,12 +119,7 @@ namespace WireMock.Owin.Mappers
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetResponseHeaders(responseMessage, response);
|
return bytes;
|
||||||
|
|
||||||
if (bytes != null)
|
|
||||||
{
|
|
||||||
await response.Body.WriteAsync(bytes, 0, bytes.Length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetResponseHeaders(ResponseMessage responseMessage, IResponse response)
|
private void SetResponseHeaders(ResponseMessage responseMessage, IResponse response)
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using System;
|
using System;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
|
using WireMock.Matchers.Request;
|
||||||
|
|
||||||
namespace WireMock.RequestBuilders
|
namespace WireMock.RequestBuilders
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The BodyRequestBuilder interface.
|
/// The BodyRequestBuilder interface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBodyRequestBuilder
|
public interface IBodyRequestBuilder : IRequestMatcher
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithBody: IMatcher
|
/// WithBody: IMatcher
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
using System;
|
using JetBrains.Annotations;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
using WireMock.Matchers.Request;
|
|
||||||
|
|
||||||
namespace WireMock.RequestBuilders
|
namespace WireMock.RequestBuilders
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The HeadersAndCookieRequestBuilder interface.
|
/// The HeadersAndCookieRequestBuilder interface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHeadersAndCookiesRequestBuilder : IBodyRequestBuilder, IRequestMatcher, IParamsRequestBuilder
|
public interface IHeadersAndCookiesRequestBuilder : IParamsRequestBuilder
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithHeader: matching based on name, pattern and matchBehaviour.
|
/// WithHeader: matching based on name, pattern and matchBehaviour.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ParamsRequestBuilder interface.
|
/// The ParamsRequestBuilder interface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IParamsRequestBuilder
|
public interface IParamsRequestBuilder : IBodyRequestBuilder
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithParam: matching on key only.
|
/// WithParam: matching on key only.
|
||||||
|
|||||||
23
src/WireMock.Net/ResponseBuilders/FaultType.cs
Normal file
23
src/WireMock.Net/ResponseBuilders/FaultType.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
namespace WireMock.ResponseBuilders
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The FaultType enumeration
|
||||||
|
/// </summary>
|
||||||
|
public enum FaultType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No Fault
|
||||||
|
/// </summary>
|
||||||
|
NONE,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return a completely empty response.
|
||||||
|
/// </summary>
|
||||||
|
EMPTY_RESPONSE,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send a defined status header, then garbage, then close the connection.
|
||||||
|
/// </summary>
|
||||||
|
MALFORMED_RESPONSE_CHUNK
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ namespace WireMock.ResponseBuilders
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The BodyResponseBuilder interface.
|
/// The BodyResponseBuilder interface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBodyResponseBuilder : ITransformResponseBuilder
|
public interface IBodyResponseBuilder : IFaultResponseBuilder
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithBody : Create a ... response based on a string.
|
/// WithBody : Create a ... response based on a string.
|
||||||
|
|||||||
18
src/WireMock.Net/ResponseBuilders/IFaultRequestBuilder.cs
Normal file
18
src/WireMock.Net/ResponseBuilders/IFaultRequestBuilder.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace WireMock.ResponseBuilders
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The FaultRequestBuilder interface.
|
||||||
|
/// </summary>
|
||||||
|
public interface IFaultResponseBuilder : ITransformResponseBuilder
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// WithBody : Create a fault response.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="faultType">The FaultType.</param>
|
||||||
|
/// <param name="percentage">The percentage when this fault should occur. When null, it's always.</param>
|
||||||
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
|
IResponseBuilder WithFault(FaultType faultType, [CanBeNull] double? percentage = null);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/WireMock.Net/ResponseBuilders/Response.WithFault.cs
Normal file
14
src/WireMock.Net/ResponseBuilders/Response.WithFault.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
namespace WireMock.ResponseBuilders
|
||||||
|
{
|
||||||
|
public partial class Response
|
||||||
|
{
|
||||||
|
/// <inheritdoc cref="IFaultResponseBuilder.WithFault(FaultType, double?)"/>
|
||||||
|
public IResponseBuilder WithFault(FaultType faultType, double? percentage = null)
|
||||||
|
{
|
||||||
|
ResponseMessage.FaultType = faultType;
|
||||||
|
ResponseMessage.FaultPercentage = percentage;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ namespace WireMock.ResponseBuilders
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Response.
|
/// The Response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Response : IResponseBuilder
|
public partial class Response : IResponseBuilder
|
||||||
{
|
{
|
||||||
private HttpClient _httpClientForProxy;
|
private HttpClient _httpClientForProxy;
|
||||||
|
|
||||||
@@ -375,6 +375,7 @@ namespace WireMock.ResponseBuilders
|
|||||||
public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IFluentMockServerSettings settings)
|
public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IFluentMockServerSettings settings)
|
||||||
{
|
{
|
||||||
Check.NotNull(requestMessage, nameof(requestMessage));
|
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||||
|
Check.NotNull(settings, nameof(settings));
|
||||||
|
|
||||||
if (Delay != null)
|
if (Delay != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using WireMock.ResponseBuilders;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
|
|
||||||
@@ -35,6 +36,16 @@ namespace WireMock
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public BodyData BodyData { get; set; }
|
public BodyData BodyData { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The FaultType.
|
||||||
|
/// </summary>
|
||||||
|
public FaultType FaultType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Fault percentage.
|
||||||
|
/// </summary>
|
||||||
|
public double? FaultPercentage { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the header.
|
/// Adds the header.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
using WireMock.Admin.Requests;
|
using WireMock.Admin.Requests;
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
|
using WireMock.ResponseBuilders;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.Serialization
|
namespace WireMock.Serialization
|
||||||
@@ -61,6 +62,12 @@ namespace WireMock.Serialization
|
|||||||
Headers = logEntry.ResponseMessage.Headers
|
Headers = logEntry.ResponseMessage.Headers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (logEntry.ResponseMessage.FaultType != FaultType.NONE)
|
||||||
|
{
|
||||||
|
logResponseModel.FaultType = logEntry.ResponseMessage.FaultType.ToString();
|
||||||
|
logResponseModel.FaultPercentage = logEntry.ResponseMessage.FaultPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
if (logEntry.ResponseMessage.BodyData != null)
|
if (logEntry.ResponseMessage.BodyData != null)
|
||||||
{
|
{
|
||||||
logResponseModel.BodyOriginal = logEntry.ResponseMessage.BodyOriginal;
|
logResponseModel.BodyOriginal = logEntry.ResponseMessage.BodyOriginal;
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ namespace WireMock.Serialization
|
|||||||
mappingModel.Response.UseTransformer = null;
|
mappingModel.Response.UseTransformer = null;
|
||||||
mappingModel.Response.BodyEncoding = null;
|
mappingModel.Response.BodyEncoding = null;
|
||||||
mappingModel.Response.ProxyUrl = response.ProxyUrl;
|
mappingModel.Response.ProxyUrl = response.ProxyUrl;
|
||||||
|
mappingModel.Response.Fault = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -161,6 +162,15 @@ namespace WireMock.Serialization
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.ResponseMessage.FaultType != FaultType.NONE)
|
||||||
|
{
|
||||||
|
mappingModel.Response.Fault = new FaultModel
|
||||||
|
{
|
||||||
|
Type = response.ResponseMessage.FaultType.ToString(),
|
||||||
|
Percentage = response.ResponseMessage.FaultPercentage
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mappingModel;
|
return mappingModel;
|
||||||
|
|||||||
@@ -820,6 +820,11 @@ namespace WireMock.Server
|
|||||||
responseBuilder = responseBuilder.WithBodyFromFile(responseModel.BodyAsFile);
|
responseBuilder = responseBuilder.WithBodyFromFile(responseModel.BodyAsFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (responseModel.Fault != null && Enum.TryParse(responseModel.Fault.Type, out FaultType faultType))
|
||||||
|
{
|
||||||
|
responseBuilder.WithFault(faultType, responseModel.Fault.Percentage);
|
||||||
|
}
|
||||||
|
|
||||||
return responseBuilder;
|
return responseBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ namespace WireMock.Transformers
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
responseMessage.FaultType = original.FaultType;
|
||||||
|
responseMessage.FaultPercentage = original.FaultPercentage;
|
||||||
|
|
||||||
// Headers
|
// Headers
|
||||||
var newHeaders = new Dictionary<string, WireMockList<string>>();
|
var newHeaders = new Dictionary<string, WireMockList<string>>();
|
||||||
foreach (var header in original.Headers)
|
foreach (var header in original.Headers)
|
||||||
|
|||||||
@@ -57,11 +57,16 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Remove="RequestBuilders\Request.WithFault.cs" />
|
||||||
<Compile Remove="Util\CloneUtils.cs" />
|
<Compile Remove="Util\CloneUtils.cs" />
|
||||||
<Compile Remove="Util\IndexableDictionary.cs" />
|
<Compile Remove="Util\IndexableDictionary.cs" />
|
||||||
<Compile Remove="Util\NamedReaderWriterLocker.cs" />
|
<Compile Remove="Util\NamedReaderWriterLocker.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="ResponseBuilders\Response.WithFault.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2018.2.1">
|
<PackageReference Include="JetBrains.Annotations" Version="2018.2.1">
|
||||||
<PrivateAssets>All</PrivateAssets>
|
<PrivateAssets>All</PrivateAssets>
|
||||||
@@ -75,7 +80,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
|
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
|
||||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.8" />
|
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.10" />
|
||||||
<PackageReference Include="JmesPath.Net" Version="1.0.125" />
|
<PackageReference Include="JmesPath.Net" Version="1.0.125" />
|
||||||
<!--<PackageReference Include="CloneExtensionsEx" Version="1.0.2" />-->
|
<!--<PackageReference Include="CloneExtensionsEx" Version="1.0.2" />-->
|
||||||
<!--<PackageReference Include="FastDeepCloner" Version="1.2.5" />-->
|
<!--<PackageReference Include="FastDeepCloner" Version="1.2.5" />-->
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using WireMock.Handlers;
|
using WireMock.Handlers;
|
||||||
using WireMock.Owin.Mappers;
|
using WireMock.Owin.Mappers;
|
||||||
|
using WireMock.ResponseBuilders;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
#if NET452
|
#if NET452
|
||||||
using Microsoft.Owin;
|
using Microsoft.Owin;
|
||||||
@@ -97,7 +98,7 @@ namespace WireMock.Net.Tests.Owin.Mappers
|
|||||||
public async Task OwinResponseMapper_MapAsync_Body()
|
public async Task OwinResponseMapper_MapAsync_Body()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
string body = "abc";
|
string body = "abcd";
|
||||||
var responseMessage = new ResponseMessage
|
var responseMessage = new ResponseMessage
|
||||||
{
|
{
|
||||||
Headers = new Dictionary<string, WireMockList<string>>(),
|
Headers = new Dictionary<string, WireMockList<string>>(),
|
||||||
@@ -108,7 +109,7 @@ namespace WireMock.Net.Tests.Owin.Mappers
|
|||||||
await _sut.MapAsync(responseMessage, _responseMock.Object);
|
await _sut.MapAsync(responseMessage, _responseMock.Object);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
_stream.Verify(s => s.WriteAsync(new byte[] { 97, 98, 99 }, 0, 3, It.IsAny<CancellationToken>()), Times.Once);
|
_stream.Verify(s => s.WriteAsync(new byte[] { 97, 98, 99, 100 }, 0, 4, It.IsAny<CancellationToken>()), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -167,5 +168,47 @@ namespace WireMock.Net.Tests.Owin.Mappers
|
|||||||
_headers.Verify(h => h.TryGetValue("h", out v), Times.Once);
|
_headers.Verify(h => h.TryGetValue("h", out v), Times.Once);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task OwinResponseMapper_MapAsync_WithFault_EMPTY_RESPONSE()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
string body = "abc";
|
||||||
|
var responseMessage = new ResponseMessage
|
||||||
|
{
|
||||||
|
Headers = new Dictionary<string, WireMockList<string>>(),
|
||||||
|
BodyData = new BodyData { DetectedBodyType = BodyType.String, BodyAsString = body },
|
||||||
|
FaultType = FaultType.EMPTY_RESPONSE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await _sut.MapAsync(responseMessage, _responseMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_stream.Verify(s => s.WriteAsync(new byte[0], 0, 0, It.IsAny<CancellationToken>()), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("abcd", BodyType.String)]
|
||||||
|
[InlineData("", BodyType.String)]
|
||||||
|
[InlineData(null, BodyType.None)]
|
||||||
|
public async Task OwinResponseMapper_MapAsync_WithFault_MALFORMED_RESPONSE_CHUNK(string body, BodyType detected)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var responseMessage = new ResponseMessage
|
||||||
|
{
|
||||||
|
Headers = new Dictionary<string, WireMockList<string>>(),
|
||||||
|
BodyData = new BodyData { DetectedBodyType = detected, BodyAsString = body },
|
||||||
|
StatusCode = 100,
|
||||||
|
FaultType = FaultType.MALFORMED_RESPONSE_CHUNK
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await _sut.MapAsync(responseMessage, _responseMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_responseMock.VerifySet(r => r.StatusCode = 100, Times.Once);
|
||||||
|
_stream.Verify(s => s.WriteAsync(It.IsAny<byte[]>(), 0, It.Is<int>(count => count >= 0), It.IsAny<CancellationToken>()), Times.Once);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using WireMock.Models;
|
||||||
|
using WireMock.ResponseBuilders;
|
||||||
|
using WireMock.Settings;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Tests.ResponseBuilders
|
||||||
|
{
|
||||||
|
public class ResponseWithWithFaultTests
|
||||||
|
{
|
||||||
|
private readonly Mock<IFluentMockServerSettings> _settingsMock = new Mock<IFluentMockServerSettings>();
|
||||||
|
private const string ClientIp = "::1";
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(FaultType.EMPTY_RESPONSE)]
|
||||||
|
[InlineData(FaultType.MALFORMED_RESPONSE_CHUNK)]
|
||||||
|
public async Task Response_ProvideResponse_WithFault(FaultType faultType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var request = new RequestMessage(new UrlDetails("http://localhost/fault"), "GET", ClientIp);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = Response.Create().WithFault(faultType);
|
||||||
|
var responseMessage = await response.ProvideResponseAsync(request, _settingsMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
responseMessage.FaultType.Should().Be(faultType);
|
||||||
|
responseMessage.FaultPercentage.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(FaultType.EMPTY_RESPONSE, 0.5)]
|
||||||
|
public async Task Response_ProvideResponse_WithFault_IncludingPercentage(FaultType faultType, double percentage)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var request = new RequestMessage(new UrlDetails("http://localhost/fault"), "GET", ClientIp);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = Response.Create().WithFault(faultType, percentage);
|
||||||
|
var responseMessage = await response.ProvideResponseAsync(request, _settingsMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
responseMessage.FaultType.Should().Be(faultType);
|
||||||
|
responseMessage.FaultPercentage.Should().Be(percentage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using NFluent;
|
using FluentAssertions;
|
||||||
|
using NFluent;
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
using WireMock.Models;
|
using WireMock.Models;
|
||||||
|
using WireMock.ResponseBuilders;
|
||||||
using WireMock.Serialization;
|
using WireMock.Serialization;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@@ -59,8 +61,7 @@ namespace WireMock.Net.Tests.Serialization
|
|||||||
// Assign
|
// Assign
|
||||||
var logEntry = new LogEntry
|
var logEntry = new LogEntry
|
||||||
{
|
{
|
||||||
RequestMessage = new RequestMessage(new UrlDetails("http://localhost"), "get", "::1"
|
RequestMessage = new RequestMessage(new UrlDetails("http://localhost"), "get", "::1"),
|
||||||
),
|
|
||||||
ResponseMessage = new ResponseMessage
|
ResponseMessage = new ResponseMessage
|
||||||
{
|
{
|
||||||
BodyData = new BodyData
|
BodyData = new BodyData
|
||||||
@@ -88,5 +89,32 @@ namespace WireMock.Net.Tests.Serialization
|
|||||||
Check.That(result.Response.BodyAsJson).IsNull();
|
Check.That(result.Response.BodyAsJson).IsNull();
|
||||||
Check.That(result.Response.BodyAsFile).IsEqualTo("test");
|
Check.That(result.Response.BodyAsFile).IsEqualTo("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LogEntryMapper_Map_LogEntry_WithFault()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
var logEntry = new LogEntry
|
||||||
|
{
|
||||||
|
RequestMessage = new RequestMessage(new UrlDetails("http://localhost"), "get", "::1"),
|
||||||
|
ResponseMessage = new ResponseMessage
|
||||||
|
{
|
||||||
|
BodyData = new BodyData
|
||||||
|
{
|
||||||
|
DetectedBodyType = BodyType.File,
|
||||||
|
BodyAsFile = "test"
|
||||||
|
},
|
||||||
|
FaultType = FaultType.EMPTY_RESPONSE,
|
||||||
|
FaultPercentage = 0.5
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = LogEntryMapper.Map(logEntry);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Response.FaultType.Should().Be("EMPTY_RESPONSE");
|
||||||
|
result.Response.FaultPercentage.Should().Be(0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<PackageReference Include="FluentAssertions" Version="5.7.0" />
|
<PackageReference Include="FluentAssertions" Version="5.7.0" />
|
||||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||||
<PackageReference Include="RestEase" Version="1.4.7" />
|
<PackageReference Include="RestEase" Version="1.4.7" />
|
||||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.8" />
|
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.10" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||||
<PackageReference Include="Moq" Version="4.10.1" />
|
<PackageReference Include="Moq" Version="4.10.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
|
|||||||
Reference in New Issue
Block a user