| | 1 | | // Copyright (c) Microsoft Corporation. All rights reserved. |
| | 2 | | // Licensed under the MIT License. |
| | 3 | |
|
| | 4 | | using System; |
| | 5 | | using System.Collections.Generic; |
| | 6 | | using System.Linq; |
| | 7 | | using System.Text.Json; |
| | 8 | |
|
| | 9 | | namespace Azure.Core.TestFramework |
| | 10 | | { |
| | 11 | | public class RecordSession |
| | 12 | | { |
| 1351688 | 13 | | public List<RecordEntry> Entries { get; } = new List<RecordEntry>(); |
| | 14 | |
|
| 55747 | 15 | | public SortedDictionary<string, string> Variables { get; } = new SortedDictionary<string, string>(StringComparer |
| | 16 | |
|
| | 17 | | //Used only for deserializing track 1 session record files |
| 0 | 18 | | public Dictionary<string, Queue<string>> Names { get; set; } = new Dictionary<string, Queue<string>>(); |
| | 19 | |
|
| | 20 | | public void Serialize(Utf8JsonWriter jsonWriter) |
| | 21 | | { |
| 30 | 22 | | jsonWriter.WriteStartObject(); |
| 30 | 23 | | jsonWriter.WriteStartArray(nameof(Entries)); |
| 116 | 24 | | foreach (RecordEntry record in Entries) |
| | 25 | | { |
| 28 | 26 | | record.Serialize(jsonWriter); |
| | 27 | | } |
| 30 | 28 | | jsonWriter.WriteEndArray(); |
| | 29 | |
|
| 30 | 30 | | jsonWriter.WriteStartObject(nameof(Variables)); |
| 172 | 31 | | foreach (KeyValuePair<string, string> variable in Variables) |
| | 32 | | { |
| 56 | 33 | | jsonWriter.WriteString(variable.Key, variable.Value); |
| | 34 | | } |
| 30 | 35 | | jsonWriter.WriteEndObject(); |
| | 36 | |
|
| 30 | 37 | | jsonWriter.WriteEndObject(); |
| 30 | 38 | | } |
| | 39 | |
|
| | 40 | | public static RecordSession Deserialize(JsonElement element) |
| | 41 | | { |
| 9135 | 42 | | var session = new RecordSession(); |
| 9135 | 43 | | if (element.TryGetProperty(nameof(Entries), out JsonElement property)) |
| | 44 | | { |
| 715654 | 45 | | foreach (JsonElement item in property.EnumerateArray()) |
| | 46 | | { |
| 348692 | 47 | | session.Entries.Add(RecordEntry.Deserialize(item)); |
| | 48 | | } |
| | 49 | | } |
| | 50 | |
|
| 9135 | 51 | | if (element.TryGetProperty(nameof(Variables), out property)) |
| | 52 | | { |
| 59542 | 53 | | foreach (JsonProperty item in property.EnumerateObject()) |
| | 54 | | { |
| 20636 | 55 | | session.Variables[item.Name] = item.Value.GetString(); |
| | 56 | | } |
| | 57 | | } |
| | 58 | |
|
| 9135 | 59 | | if (element.TryGetProperty(nameof(Names), out property)) |
| | 60 | | { |
| 0 | 61 | | foreach (JsonProperty item in property.EnumerateObject()) |
| | 62 | | { |
| 0 | 63 | | var queue = new Queue<string>(); |
| 0 | 64 | | foreach (JsonElement subItem in item.Value.EnumerateArray()) |
| | 65 | | { |
| 0 | 66 | | queue.Enqueue(subItem.GetString()); |
| | 67 | | } |
| 0 | 68 | | session.Names[item.Name] = queue; |
| | 69 | | } |
| | 70 | | } |
| 9135 | 71 | | return session; |
| | 72 | | } |
| | 73 | |
|
| | 74 | | public void Record(RecordEntry entry) |
| | 75 | | { |
| 4 | 76 | | lock (Entries) |
| | 77 | | { |
| 4 | 78 | | Entries.Add(entry); |
| 4 | 79 | | } |
| 4 | 80 | | } |
| | 81 | |
|
| | 82 | | public RecordEntry Lookup(RecordEntry requestEntry, RecordMatcher matcher, RecordedTestSanitizer sanitizer) |
| | 83 | | { |
| 326376 | 84 | | sanitizer.Sanitize(requestEntry); |
| | 85 | |
|
| 326376 | 86 | | lock (Entries) |
| | 87 | | { |
| 326376 | 88 | | RecordEntry entry = matcher.FindMatch(requestEntry, Entries); |
| 326326 | 89 | | Entries.Remove(entry); |
| 326326 | 90 | | return entry; |
| | 91 | | } |
| | 92 | |
|
| 326326 | 93 | | } |
| | 94 | |
|
| | 95 | | public void Sanitize(RecordedTestSanitizer sanitizer) |
| | 96 | | { |
| 6 | 97 | | lock (Entries) |
| | 98 | | { |
| 6 | 99 | | sanitizer.Sanitize(this); |
| 6 | 100 | | } |
| 6 | 101 | | } |
| | 102 | |
|
| | 103 | | public bool IsEquivalent(RecordSession session, RecordMatcher matcher) |
| | 104 | | { |
| 4 | 105 | | if (session == null) |
| | 106 | | { |
| 4 | 107 | | return false; |
| | 108 | | } |
| | 109 | |
|
| | 110 | | // The DateTimeOffsetNow variable is updated any time it's used so |
| | 111 | | // we only care that both sessions use it or both sessions don't. |
| 0 | 112 | | var now = TestRecording.DateTimeOffsetNowVariableKey; |
| 0 | 113 | | return session.Variables.TryGetValue(now, out string _) == Variables.TryGetValue(now, out string _) && |
| 0 | 114 | | session.Variables.Where(v => v.Key != now).SequenceEqual(Variables.Where(v => v.Key != now)) && |
| 0 | 115 | | session.Entries.SequenceEqual(Entries, new EntryEquivalentComparer(matcher)); |
| | 116 | | } |
| | 117 | |
|
| | 118 | | private class EntryEquivalentComparer : IEqualityComparer<RecordEntry> |
| | 119 | | { |
| | 120 | | private readonly RecordMatcher _matcher; |
| | 121 | |
|
| 0 | 122 | | public EntryEquivalentComparer(RecordMatcher matcher) |
| | 123 | | { |
| 0 | 124 | | _matcher = matcher; |
| 0 | 125 | | } |
| | 126 | |
|
| | 127 | | public bool Equals(RecordEntry x, RecordEntry y) |
| | 128 | | { |
| 0 | 129 | | return _matcher.IsEquivalentRecord(x, y); |
| | 130 | | } |
| | 131 | |
|
| | 132 | | public int GetHashCode(RecordEntry obj) |
| | 133 | | { |
| 0 | 134 | | return obj.GetHashCode(); |
| | 135 | | } |
| | 136 | | } |
| | 137 | | } |
| | 138 | | } |