Skip to content

Commit 71dc2c1

Browse files
author
J Wyman
committed
Added LFS like test to FilterFixture
1 parent def0c7b commit 71dc2c1

File tree

3 files changed

+193
-0
lines changed

3 files changed

+193
-0
lines changed

LibGit2Sharp.Tests/FilterFixture.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,113 @@ public void WhenCheckingOutAFileFileSmudgeWritesCorrectFileToWorkingDirectory()
176176
GlobalSettings.DeregisterFilter(filterRegistration);
177177
}
178178

179+
[Fact]
180+
public void CanFilterLargeFiles()
181+
{
182+
const int ContentLength = 128 * 1024 * 1024;
183+
const char ContentValue = 'x';
184+
185+
char[] content = (new string(ContentValue, 1024)).ToCharArray();
186+
187+
string repoPath = InitNewRepository();
188+
189+
var filter = new FileExportFilter("exportFilter", attributes);
190+
var filterRegistration = GlobalSettings.RegisterFilter(filter);
191+
192+
string filePath = Path.Combine(Directory.GetParent(repoPath).Parent.FullName, Guid.NewGuid().ToString() + ".blob");
193+
FileInfo contentFile = new FileInfo(filePath);
194+
using (var writer = new StreamWriter(contentFile.OpenWrite()) { AutoFlush = true })
195+
{
196+
for (int i = 0; i < ContentLength / content.Length; i++)
197+
{
198+
writer.Write(content);
199+
}
200+
}
201+
202+
string attributesPath = Path.Combine(Directory.GetParent(repoPath).Parent.FullName, ".gitattributes");
203+
FileInfo attributesFile = new FileInfo(attributesPath);
204+
205+
string configPath = CreateConfigurationWithDummyUser(Constants.Signature);
206+
var repositoryOptions = new RepositoryOptions { GlobalConfigurationLocation = configPath };
207+
208+
using (Repository repo = new Repository(repoPath, repositoryOptions))
209+
{
210+
File.WriteAllText(attributesPath, "*.blob filter=test");
211+
repo.Stage(attributesFile.Name);
212+
repo.Stage(contentFile.Name);
213+
repo.Commit("test");
214+
contentFile.Delete();
215+
repo.Checkout("HEAD", new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force });
216+
}
217+
218+
contentFile = new FileInfo(filePath);
219+
Assert.True(contentFile.Exists, "Contents not restored correctly by forced checkout.");
220+
using (StreamReader reader = contentFile.OpenText())
221+
{
222+
int totalRead = 0;
223+
char[] block = new char[1024];
224+
int read;
225+
while ((read = reader.Read(block, 0, block.Length)) > 0)
226+
{
227+
Assert.True(CharArrayAreEqual(block, content, read));
228+
totalRead += read;
229+
}
230+
231+
Assert.Equal(ContentLength, totalRead);
232+
}
233+
234+
contentFile.Delete();
235+
236+
GlobalSettings.DeregisterFilter(filterRegistration);
237+
}
238+
239+
private unsafe bool CharArrayAreEqual(char[] array1, char[] array2, int count)
240+
{
241+
if (Object.ReferenceEquals(array1, array2))
242+
{
243+
return true;
244+
}
245+
if (Object.ReferenceEquals(array1, null) || Object.ReferenceEquals(null, array2))
246+
{
247+
return false;
248+
}
249+
if (array1.Length < count || array2.Length < count)
250+
{
251+
return false;
252+
}
253+
254+
int len = count * sizeof(char);
255+
int cnt = len / sizeof(long);
256+
257+
fixed (char* c1 = array1, c2 = array2)
258+
{
259+
long* p1 = (long*)c1,
260+
p2 = (long*)c2;
261+
262+
for (int i = 0; i < cnt; i++)
263+
{
264+
if (p1[i] != p2[i])
265+
{
266+
return false;
267+
}
268+
}
269+
270+
byte* b1 = (byte*)c1,
271+
b2 = (byte*)c2;
272+
273+
for (int i = len * sizeof(long); i < len; i++)
274+
{
275+
if (b1[i] != b2[i])
276+
{
277+
return false;
278+
}
279+
}
280+
}
281+
282+
return true;
283+
}
284+
285+
179286
private FileInfo CheckoutFileForSmudge(string repoPath, string branchName, string content)
180287
{
181288
FileInfo expectedPath;

LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<DefineConstants>TRACE;DEBUG;NET40</DefineConstants>
2424
<ErrorReport>prompt</ErrorReport>
2525
<WarningLevel>4</WarningLevel>
26+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
2627
</PropertyGroup>
2728
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
2829
<DebugType>pdbonly</DebugType>
@@ -31,6 +32,7 @@
3132
<DefineConstants>TRACE</DefineConstants>
3233
<ErrorReport>prompt</ErrorReport>
3334
<WarningLevel>4</WarningLevel>
35+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
3436
</PropertyGroup>
3537
<ItemGroup>
3638
<Reference Include="Moq, Version=4.2.1409.1722, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
@@ -118,6 +120,7 @@
118120
<Compile Include="RepositoryFixture.cs" />
119121
<Compile Include="TagFixture.cs" />
120122
<Compile Include="TestHelpers\DateTimeOffsetExtensions.cs" />
123+
<Compile Include="TestHelpers\FileExportFilter.cs" />
121124
<Compile Include="TestHelpers\OdbHelper.cs" />
122125
<Compile Include="TestHelpers\DirectoryHelper.cs" />
123126
<Compile Include="TestHelpers\ExpectedFetchState.cs" />
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System.Collections.Generic;
2+
using System.IO;
3+
using System.Text;
4+
5+
namespace LibGit2Sharp.Tests.TestHelpers
6+
{
7+
class FileExportFilter : Filter
8+
{
9+
public int CleanCalledCount = 0;
10+
public int CompleteCalledCount = 0;
11+
public int SmudgeCalledCount = 0;
12+
public readonly HashSet<string> FilesFiltered;
13+
14+
private bool clean;
15+
16+
public FileExportFilter(string name, IEnumerable<FilterAttributeEntry> attributes)
17+
: base(name, attributes)
18+
{
19+
FilesFiltered = new HashSet<string>();
20+
}
21+
22+
protected override void Clean(string path, string root, Stream input, Stream output)
23+
{
24+
CleanCalledCount++;
25+
26+
string filename = Path.GetFileName(path);
27+
string cachePath = Path.Combine(root, ".git", filename);
28+
29+
using (var file = File.Exists(cachePath) ? File.Open(cachePath, FileMode.Append, FileAccess.Write, FileShare.None) : File.Create(cachePath))
30+
{
31+
input.CopyTo(file);
32+
}
33+
34+
clean = true;
35+
}
36+
37+
protected override void Complete(string path, string root, Stream output)
38+
{
39+
CompleteCalledCount++;
40+
41+
string filename = Path.GetFileName(path);
42+
string cachePath = Path.Combine(root, ".git", filename);
43+
44+
if (clean)
45+
{
46+
byte[] bytes = Encoding.UTF8.GetBytes(path);
47+
output.Write(bytes, 0, bytes.Length);
48+
FilesFiltered.Add(path);
49+
}
50+
else
51+
{
52+
if (File.Exists(cachePath))
53+
{
54+
using (var file = File.Open(cachePath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None))
55+
{
56+
file.CopyTo(output);
57+
}
58+
}
59+
}
60+
}
61+
62+
protected override void Smudge(string path, string root, Stream input, Stream output)
63+
{
64+
SmudgeCalledCount++;
65+
66+
string filename = Path.GetFileName(path);
67+
StringBuilder text = new StringBuilder();
68+
69+
byte[] buffer = new byte[64 * 1024];
70+
int read;
71+
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
72+
{
73+
string decoded = Encoding.UTF8.GetString(buffer, 0, read);
74+
text.Append(decoded);
75+
}
76+
77+
if (!FilesFiltered.Contains(text.ToString()))
78+
throw new FileNotFoundException();
79+
80+
clean = false;
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)