Skip to content

Commit

Permalink
C#: Make the path tests independent.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelnebel committed Dec 10, 2024
1 parent 5624a77 commit 4275813
Showing 1 changed file with 115 additions and 81 deletions.
196 changes: 115 additions & 81 deletions csharp/extractor/Semmle.Util.Tests/LongPaths.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Xunit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Semmle.Util;
Expand All @@ -10,39 +11,51 @@ namespace SemmleTests.Semmle.Util
/// Ensure that the Extractor works with long paths.
/// These should be handled by .NET Core.
/// </summary>
public sealed class LongPaths : IDisposable
public sealed class LongPaths
{
private static readonly string tmpDir = Environment.GetEnvironmentVariable("TEST_TMPDIR") ?? Path.GetTempPath();
private static readonly string shortPath = Path.Combine(tmpDir, "test.txt");
private static readonly string longPath = Path.Combine(tmpDir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
private static readonly string longPathDir = Path.Combine(tmpDir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"ccccccccccccccccccccccccccccccc", "ddddddddddddddddddddddddddddddddddddd", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "fffffffffffffffffffffffffffffffff",
"ggggggggggggggggggggggggggggggggggg", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "iiiiiiiiiiiiiiii.txt");
"ggggggggggggggggggggggggggggggggggg", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");

public LongPaths()
private static string MakeLongPath()
{
CleanUp();
var uniquePostfix = Guid.NewGuid().ToString("N");
return Path.Combine(longPathDir, $"iiiiiiiiiiiiiiii{uniquePostfix}.txt");
}

public void Dispose()
private static string MakeShortPath()
{
CleanUp();
var uniquePostfix = Guid.NewGuid().ToString("N");
return Path.Combine(tmpDir, $"test{uniquePostfix}.txt");
}

private static void CleanUp()
public LongPaths()
{
try
{
File.Delete(shortPath);
}
catch (DirectoryNotFoundException)
// Create directory to avoid directory not found exceptions when deleting files
Directory.CreateDirectory(longPathDir);
}

private static void Cleanup(params IEnumerable<string> paths)
{
foreach (var path in paths)
{
File.Delete(path);
}
}

private static void WithSetUpAndTearDown(Action<string, string> test)
{
var longPath = MakeLongPath();
var shortPath = MakeShortPath();
Cleanup(longPath, shortPath);
try
{
File.Delete(longPath);
test(longPath, shortPath);
}
catch (DirectoryNotFoundException)
finally
{
Cleanup(longPath, shortPath);
}
}

Expand All @@ -63,122 +76,143 @@ public void ParentDirectory()
[Fact]
public void Delete()
{
// OK Do not exist.
File.Delete(shortPath);
File.Delete(longPath);
WithSetUpAndTearDown((longPath, shortPath) =>
{
// OK Do not exist.
File.Delete(shortPath);
File.Delete(longPath);
});
}

[Fact]
public void Move()
{
File.WriteAllText(shortPath, "abc");
Directory.CreateDirectory(Path.GetDirectoryName(longPath)!);
File.Delete(longPath);
File.Move(shortPath, longPath);
File.Move(longPath, shortPath);
Assert.Equal("abc", File.ReadAllText(shortPath));
WithSetUpAndTearDown((longPath, shortPath) =>
{
File.WriteAllText(shortPath, "abc");
File.Delete(longPath);
File.Move(shortPath, longPath);
File.Move(longPath, shortPath);
Assert.Equal("abc", File.ReadAllText(shortPath));
});
}

[Fact]
public void Replace()
{
File.WriteAllText(shortPath, "abc");
File.Delete(longPath);
Directory.CreateDirectory(Path.GetDirectoryName(longPath)!);
File.Move(shortPath, longPath);
File.WriteAllText(shortPath, "def");
FileUtils.MoveOrReplace(shortPath, longPath);
File.WriteAllText(shortPath, "abc");
FileUtils.MoveOrReplace(longPath, shortPath);
Assert.Equal("def", File.ReadAllText(shortPath));
WithSetUpAndTearDown((longPath, shortPath) =>
{
File.WriteAllText(shortPath, "abc");
File.Move(shortPath, longPath);
File.WriteAllText(shortPath, "def");
FileUtils.MoveOrReplace(shortPath, longPath);
File.WriteAllText(shortPath, "abc");
FileUtils.MoveOrReplace(longPath, shortPath);
Assert.Equal("def", File.ReadAllText(shortPath));
});
}

private readonly byte[] buffer1 = new byte[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
private readonly byte[] buffer1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

[Fact]
public void CreateShortStream()
{
var buffer2 = new byte[10];

using (var s1 = new FileStream(shortPath, FileMode.Create, FileAccess.Write, FileShare.None))
WithSetUpAndTearDown((_, shortPath) =>
{
s1.Write(buffer1, 0, 10);
}
var buffer2 = new byte[10];

using (var s2 = new FileStream(shortPath, FileMode.Open, FileAccess.Read, FileShare.None))
{
Assert.Equal(10, s2.Read(buffer2, 0, 10));
Assert.True(Enumerable.SequenceEqual(buffer1, buffer2));
}
using (var s1 = new FileStream(shortPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
s1.Write(buffer1, 0, 10);
}

using (var s2 = new FileStream(shortPath, FileMode.Open, FileAccess.Read, FileShare.None))
{
Assert.Equal(10, s2.Read(buffer2, 0, 10));
Assert.True(Enumerable.SequenceEqual(buffer1, buffer2));
}
});
}

[Fact]
public void CreateLongStream()
{
var buffer2 = new byte[10];
WithSetUpAndTearDown((longPath, _) =>
{
var buffer2 = new byte[10];

Directory.CreateDirectory(Path.GetDirectoryName(longPath)!);
Directory.CreateDirectory(Path.GetDirectoryName(longPath)!);

using (var s3 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
s3.Write(buffer1, 0, 10);
}
using (var s3 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
s3.Write(buffer1, 0, 10);
}

using (var s4 = new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None))
{
Assert.Equal(10, s4.Read(buffer2, 0, 10));
Assert.True(Enumerable.SequenceEqual(buffer1, buffer2));
}
using (var s4 = new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None))
{
Assert.Equal(10, s4.Read(buffer2, 0, 10));
Assert.True(Enumerable.SequenceEqual(buffer1, buffer2));
}
});
}

[Fact]
public void FileDoesNotExist()
{
// File does not exist
Assert.Throws<System.IO.FileNotFoundException>(() =>
WithSetUpAndTearDown((longPath, _) =>
{
using (new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None))
// File does not exist
Assert.Throws<System.IO.FileNotFoundException>(() =>
{
//
}
using (new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None))
{
//
}
});
});
}

[Fact]
public void OverwriteFile()
{
using (var s1 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None))
WithSetUpAndTearDown((longPath, _) =>
{
s1.Write(buffer1, 0, 10);
}
using (var s1 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
s1.Write(buffer1, 0, 10);
}

byte[] buffer2 = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
byte[] buffer2 = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };

using (var s2 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
s2.Write(buffer2, 0, 10);
}
using (var s2 = new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
s2.Write(buffer2, 0, 10);
}

byte[] buffer3 = new byte[10];
byte[] buffer3 = new byte[10];

using (var s3 = new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None))
{
Assert.Equal(10, s3.Read(buffer3, 0, 10));
}
using (var s3 = new FileStream(longPath, FileMode.Open, FileAccess.Read, FileShare.None))
{
Assert.Equal(10, s3.Read(buffer3, 0, 10));
}

Assert.True(Enumerable.SequenceEqual(buffer2, buffer3));
Assert.True(Enumerable.SequenceEqual(buffer2, buffer3));
});
}

[Fact]
public void LongFileExists()
{
Assert.False(File.Exists("no such file"));
Assert.False(File.Exists("\":"));
Assert.False(File.Exists(@"C:\")); // A directory
WithSetUpAndTearDown((longPath, _) =>
{
Assert.False(File.Exists("no such file"));
Assert.False(File.Exists("\":"));
Assert.False(File.Exists(@"C:\")); // A directory

Assert.False(File.Exists(longPath));
new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None).Close();
Assert.True(File.Exists(longPath));
Assert.False(File.Exists(longPath));
new FileStream(longPath, FileMode.Create, FileAccess.Write, FileShare.None).Close();
Assert.True(File.Exists(longPath));
});
}
}
}

0 comments on commit 4275813

Please sign in to comment.