forked from libgit2/libgit2sharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExpectedFetchState.cs
More file actions
183 lines (156 loc) · 7.63 KB
/
ExpectedFetchState.cs
File metadata and controls
183 lines (156 loc) · 7.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace LibGit2Sharp.Tests.TestHelpers
{
/// <summary>
/// Class to verify the expected state after fetching github.com/nulltoken/TestGitRepository into an empty repository.
/// Includes the expected reference callbacks and the expected branches / tags after fetch is completed.
/// </summary>
internal class ExpectedFetchState
{
/// <summary>
/// Name of the Remote being fetched from.
/// </summary>
internal string RemoteName { get; private set; }
/// <summary>
/// Expected branch tips after fetching into an empty repository.
/// </summary>
private Dictionary<string, ObjectId> ExpectedBranchTips = new Dictionary<string, ObjectId>();
/// <summary>
/// Expected tags after fetching into an empty repository
/// </summary>
private Dictionary<string, TestRemoteInfo.ExpectedTagInfo> ExpectedTags = new Dictionary<string, TestRemoteInfo.ExpectedTagInfo>();
/// <summary>
/// References that we expect to be updated in the UpdateReferenceTips callback.
/// </summary>
private Dictionary<string, ReferenceUpdate> ExpectedReferenceUpdates = new Dictionary<string, ReferenceUpdate>();
/// <summary>
/// References that were actually updated in the UpdateReferenceTips callback.
/// </summary>
private Dictionary<string, ReferenceUpdate> ObservedReferenceUpdates = new Dictionary<string, ReferenceUpdate>();
/// <summary>
/// Constructor.
/// </summary>
/// <param name="remoteName">Name of the remote being updated.</param>
public ExpectedFetchState(string remoteName)
{
RemoteName = remoteName;
}
/// <summary>
/// Add information on a branch that is expected to be updated during a fetch.
/// </summary>
/// <param name="branchName">Name of the branch.</param>
/// <param name="oldId">Old ID of the branch reference.</param>
/// <param name="newId">Expected updated ID of the branch reference.</param>
public void AddExpectedBranch(string branchName, ObjectId oldId, ObjectId newId)
{
string referenceUpdateBase = "refs/remotes/" + RemoteName + "/";
ExpectedBranchTips.Add(referenceUpdateBase + branchName, newId);
ExpectedReferenceUpdates.Add(referenceUpdateBase + branchName, new ReferenceUpdate(oldId, newId));
}
/// <summary>
/// Add information on a tag that is expected to be updated during a fetch.
/// </summary>
/// <param name="tagName">Name of the tag.</param>
/// <param name="oldId">Old ID of the tag.</param>
/// <param name="tag">Datastructure containing expected updated tag information.</param>
public void AddExpectedTag(string tagName, ObjectId oldId, TestRemoteInfo.ExpectedTagInfo tag)
{
string tagReferenceBase = "refs/tags/";
ExpectedTags.Add(tagReferenceBase + tagName, tag);
ObjectId referenceId = tag.IsAnnotated ? tag.AnnotationId : tag.TargetId;
ExpectedReferenceUpdates.Add(tagReferenceBase + tagName, new ReferenceUpdate(oldId, referenceId));
}
/// <summary>
/// Handler to hook up to UpdateTips callback.
/// </summary>
/// <param name="referenceName">Name of reference being updated.</param>
/// <param name="oldId">Old ID of reference.</param>
/// <param name="newId">New ID of reference.</param>
/// <returns>True to continue, false to cancel.</returns>
public bool RemoteUpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId)
{
// assert that we have not seen this reference before
Assert.DoesNotContain(referenceName, ObservedReferenceUpdates.Keys);
ObservedReferenceUpdates.Add(referenceName, new ReferenceUpdate(oldId, newId));
// verify that this reference is in the list of expected references
ReferenceUpdate referenceUpdate;
bool isReferenceFound = ExpectedReferenceUpdates.TryGetValue(referenceName, out referenceUpdate);
Assert.True(isReferenceFound, string.Format("Could not find the reference {0} in the list of expected reference updates.", referenceName));
// verify that the old / new Object IDs
if (isReferenceFound)
{
Assert.Equal(referenceUpdate.OldId, oldId);
Assert.Equal(referenceUpdate.NewId, newId);
}
return true;
}
/// <summary>
/// Check that all expected references have been updated.
/// </summary>
/// <param name="repo">Repository object whose state will be checked against expected state.</param>
public void CheckUpdatedReferences(IRepository repo)
{
// Verify the expected branches.
// First, verify the expected branches have been created and
List<string> sortedObservedBranches = repo.Branches.Select(branch => branch.CanonicalName).ToList();
sortedObservedBranches.Sort();
List<string> sortedExpectedBranches = ExpectedBranchTips.Keys.ToList();
sortedExpectedBranches.Sort();
Assert.Equal(sortedExpectedBranches, sortedObservedBranches);
// Verify branches reference expected commits.
foreach (KeyValuePair<string, ObjectId> kvp in ExpectedBranchTips)
{
Branch branch = repo.Branches[kvp.Key];
Assert.NotNull(branch);
Assert.Equal(kvp.Value, branch.Tip.Id);
}
// Verify the expected tags
// First, verify the expected tags have been created
List<string> sortedObservedTags = repo.Tags.Select(tag => tag.CanonicalName).ToList();
sortedObservedTags.Sort();
List<string> sortedExpectedTags = ExpectedTags.Keys.ToList();
sortedExpectedTags.Sort();
Assert.Equal(sortedExpectedTags, sortedObservedTags);
// Verify tags reference the expected IDs.
foreach (KeyValuePair<string, TestRemoteInfo.ExpectedTagInfo> kvp in ExpectedTags)
{
Tag tag = repo.Tags[kvp.Key];
TestRemoteInfo.ExpectedTagInfo expectedTagInfo = kvp.Value;
Assert.NotNull(tag);
Assert.NotNull(tag.Target);
Assert.Equal(expectedTagInfo.TargetId, tag.Target.Id);
if (expectedTagInfo.IsAnnotated)
{
Assert.NotNull(tag.Annotation);
Assert.Equal(expectedTagInfo.AnnotationId, tag.Annotation.Id);
}
}
// We have already verified that all observed reference updates are expected,
// verify that we have seen all expected reference updates.
Assert.Equal(ExpectedReferenceUpdates.Count, ObservedReferenceUpdates.Count);
}
#region ExpectedFetchState
/// <summary>
/// Structure to track a reference that has been updated.
/// </summary>
private struct ReferenceUpdate
{
/// <summary>
/// Old ID of the reference.
/// </summary>
public ObjectId OldId;
/// <summary>
/// New ID of the reference.
/// </summary>
public ObjectId NewId;
public ReferenceUpdate(ObjectId oldId, ObjectId newId)
{
OldId = oldId;
NewId = newId;
}
}
#endregion
}
}