Skip to content

Commit

Permalink
Adding AsyncCollection<T> for Storage enumeration (#6767)
Browse files Browse the repository at this point in the history
  • Loading branch information
tg-msft authored Jul 3, 2019
1 parent 5d309b0 commit c235cc3
Show file tree
Hide file tree
Showing 57 changed files with 3,142 additions and 1,678 deletions.
59 changes: 41 additions & 18 deletions sdk/core/Azure.Core/tests/TestFramework/RecordMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public RecordMatcher(RecordedTestSanitizer sanitizer)
"User-Agent"
};

public virtual int FindMatch(Request request, IList<RecordEntry> entries)
public virtual int FindMatch(Request request, IList<RecordEntry> entries, out string failureMessage)
{
SortedDictionary<string, string[]> headers = new SortedDictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);

Expand All @@ -40,42 +40,65 @@ public virtual int FindMatch(Request request, IList<RecordEntry> entries)

string uri = _sanitizer.SanitizeUri(request.UriBuilder.ToString());

int bestScore = int.MaxValue;
var messagePrefix = failureMessage = $"Unable to find recorded request for {request.Method} {request.UriBuilder.ToString()}";

for (int i = 0; i < entries.Count; i++)
{
RecordEntry entry = entries[i];

if (entry.RequestUri == uri &&
entry.RequestMethod == request.Method &&
CompareHeaderDictionaries(headers, entry.RequestHeaders))
if (entry.RequestUri == uri && entry.RequestMethod == request.Method)
{
return i;
int score = CompareHeaderDictionaries(headers, entry.RequestHeaders, out var diff);
if (score == 0)
{
failureMessage = null;
return i;
}
else if (score < bestScore)
{
bestScore = score;
failureMessage = $"{messagePrefix} (Best match: {diff})";
}
}
}

if (bestScore == int.MaxValue && entries.Count == 1)
{
failureMessage = $"{messagePrefix} (Best match: {entries[0].RequestMethod} {entries[0].RequestUri})";
}

return -1;
}

private bool CompareHeaderDictionaries(SortedDictionary<string, string[]> headers, SortedDictionary<string, string[]> entryHeaders)
private int CompareHeaderDictionaries(SortedDictionary<string, string[]> headers, SortedDictionary<string, string[]> entryHeaders, out string diff)
{
if (headers.Count != entryHeaders.Count)
{
return false;
}

List<string> deltas = new List<string>();
var remaining = new SortedDictionary<string, string[]>(entryHeaders, entryHeaders.Comparer);
foreach (KeyValuePair<string, string[]> header in headers)
{
if (ExcludeHeaders.Contains(header.Key))
if (remaining.TryGetValue(header.Key, out string[] values))
{
continue;
remaining.Remove(header.Key);
if (!ExcludeHeaders.Contains(header.Key) &&
!values.SequenceEqual(header.Value))
{
var expected = string.Join(",", header.Value);
var actual = string.Join(",", values);
deltas.Add($"{header.Key} expects <{expected}> not <{actual}>");
}
}
if (!entryHeaders.TryGetValue(header.Key, out string[] values) ||
!values.SequenceEqual(header.Value))
else
{
return false;
deltas.Add($"Missing {header.Key}");
}
}

return true;
foreach (KeyValuePair<string, string[]> header in remaining)
{
deltas.Add($"Extra {header.Key}");
}
diff = string.Join("; ", deltas);
return deltas.Count;
}
}
}
4 changes: 2 additions & 2 deletions sdk/core/Azure.Core/tests/TestFramework/RecordSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ public RecordEntry Lookup(Request request, RecordMatcher matcher)
{
lock (Entries)
{
var index = matcher.FindMatch(request, Entries);
var index = matcher.FindMatch(request, Entries, out var failureMessage);
if (index == -1)
{
throw new InvalidOperationException($"Unable to find recorded request with method {request.Method} and uri {request.UriBuilder.ToString()}");
throw new InvalidOperationException(failureMessage);
}

var entry = Entries[index];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,23 @@ public void Intercept(IInvocation invocation)
{
object result = methodInfo.Invoke(invocation.InvocationTarget, invocation.Arguments);


// Map IEnumerable to IAsyncEnumerable
if (returnsIEnumerable)
{
invocation.ReturnValue = Activator.CreateInstance(
typeof(AsyncEnumerableWrapper<>).MakeGenericType(returnType.GenericTypeArguments), new[] { result });
if (invocation.Method.ReturnType.IsGenericType &&
invocation.Method.ReturnType.GetGenericTypeDefinition().Name == "AsyncCollection`1")
{
// AsyncCollection can be used as either a sync or async
// collection so there's no need to wrap it in an
// IAsyncEnumerable
invocation.ReturnValue = result;
}
else
{
invocation.ReturnValue = Activator.CreateInstance(
typeof(AsyncEnumerableWrapper<>).MakeGenericType(returnType.GenericTypeArguments),
new[] { result });
}
}
else
{
Expand Down
1 change: 1 addition & 0 deletions sdk/storage/Azure.Storage.Blobs/src/BlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace Azure.Storage.Blobs
/// </summary>
public class BlobClient : BlobBaseClient
{
#pragma warning disable IDE0032 // Use auto property
/// <summary>
/// Initializes a new instance of the <see cref="BlobClient"/>
/// class for mocking.
Expand Down
Loading

0 comments on commit c235cc3

Please sign in to comment.