Skip to content

Commit

Permalink
Merge pull request #87 from GerardSmit/fix/linux-unit-tests
Browse files Browse the repository at this point in the history
Fix Linux unit tests
  • Loading branch information
xoofx authored May 27, 2024
2 parents c23f0a0 + 7310200 commit 51cf2a1
Show file tree
Hide file tree
Showing 16 changed files with 187 additions and 86 deletions.
16 changes: 14 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ on:

jobs:
build:
runs-on: windows-latest
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest, windows-latest]

steps:
- name: Checkout
Expand All @@ -26,7 +30,15 @@ jobs:
dotnet-version: '8.0.x'

- name: Build, Test, Pack, Publish
if: matrix.os == 'windows-latest'
shell: bash
run: |
dotnet tool install -g dotnet-releaser --configfile .github/workflows/nuget_org_only.config
dotnet-releaser run --nuget-token "${{secrets.NUGET_TOKEN}}" --github-token "${{secrets.GITHUB_TOKEN}}" src/dotnet-releaser.toml
- name: Build, Test
if: matrix.os == 'ubuntu-latest'
shell: bash
run: |
dotnet tool install -g dotnet-releaser --configfile .github/workflows/nuget_org_only.config
dotnet-releaser run --nuget-token "${{secrets.NUGET_TOKEN}}" --github-token "${{secrets.GITHUB_TOKEN}}" src/dotnet-releaser.toml
dotnet-releaser build src/dotnet-releaser.toml
19 changes: 14 additions & 5 deletions src/Zio.Tests/FileSystems/TestFileSystemBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ protected void AssertCommonReadOnly(IFileSystem fs)
AssertCommonRead(fs, true);
}

protected void AssertCommonRead(IFileSystem fs, bool isReadOnly = false)
protected void AssertCommonRead(IFileSystem fs, bool isReadOnly = false, bool? isWindows = null)
{
{
var innerPath = fs.ConvertPathToInternal("/");
Expand Down Expand Up @@ -283,17 +283,26 @@ protected void AssertCommonRead(IFileSystem fs, bool isReadOnly = false)
Assert.StartsWith("content", fs.ReadAllText("/b.txt"));
Assert.StartsWith("content", fs.ReadAllText("/a/a/a1.txt"));

var fileFlag = (isWindows ?? IsWindows, isReadOnly) switch
{
// Windows
(true, true) => FileAttributes.ReadOnly | FileAttributes.Archive,
(true, false) => FileAttributes.Archive,

var readOnlyFlag = isReadOnly ? FileAttributes.ReadOnly : 0;
// Linux
(false, true) => FileAttributes.ReadOnly,
(false, false) => FileAttributes.Normal
};

Assert.Equal(readOnlyFlag | FileAttributes.Archive, fs.GetAttributes("/A.txt"));
Assert.Equal(readOnlyFlag | FileAttributes.Archive, fs.GetAttributes("/b.txt"));
Assert.Equal(readOnlyFlag | FileAttributes.Archive, fs.GetAttributes("/a/a/a1.txt"));
Assert.Equal(fileFlag, fs.GetAttributes("/A.txt"));
Assert.Equal(fileFlag, fs.GetAttributes("/b.txt"));
Assert.Equal(fileFlag, fs.GetAttributes("/a/a/a1.txt"));

Assert.True(fs.GetFileLength("/A.txt") > 0);
Assert.True(fs.GetFileLength("/b.txt") > 0);
Assert.True(fs.GetFileLength("/a/a/a1.txt") > 0);

var readOnlyFlag = isReadOnly ? FileAttributes.ReadOnly : 0;
Assert.Equal(readOnlyFlag | FileAttributes.Directory, fs.GetAttributes("/a"));
Assert.Equal(readOnlyFlag | FileAttributes.Directory, fs.GetAttributes("/a/a"));
Assert.Equal(readOnlyFlag | FileAttributes.Directory, fs.GetAttributes("/C"));
Expand Down
82 changes: 53 additions & 29 deletions src/Zio.Tests/FileSystems/TestFileSystemCompactBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,23 @@ public void TestDirectoryExceptions()

fs.WriteAllText("/toto.txt", "test");
Assert.Throws<IOException>(() => fs.CreateDirectory("/toto.txt"));
Assert.Throws<IOException>(() => fs.DeleteDirectory("/toto.txt", true));

if (IsWindows)
{
Assert.Throws<IOException>(() => fs.DeleteDirectory("/toto.txt", true));
}

Assert.Throws<IOException>(() => fs.MoveDirectory("/toto.txt", "/test"));

fs.CreateDirectory("/dir2");
Assert.Throws<IOException>(() => fs.MoveDirectory("/dir1", "/dir2"));

fs.SetAttributes("/dir1", FileAttributes.Directory | FileAttributes.ReadOnly);
Assert.Throws<IOException>(() => fs.DeleteDirectory("/dir1", true));
if (IsWindows)
{
// Linux allows modifications on directories while they are readonly.
fs.SetAttributes("/dir1", FileAttributes.Directory | FileAttributes.ReadOnly);
Assert.Throws<IOException>(() => fs.DeleteDirectory("/dir1", true));
}
}

[Fact]
Expand Down Expand Up @@ -122,25 +131,33 @@ public void TestFile()
Assert.True(fs.GetFileLength("/toto.txt") > 0);
Assert.Equal(fs.GetFileLength("/toto.txt"), fs.GetFileLength("/titi.txt"));
Assert.Equal(fs.GetAttributes("/toto.txt"), fs.GetAttributes("/titi.txt"));
Assert.NotEqual(fs.GetCreationTime("/toto.txt"), fs.GetCreationTime("/titi.txt"));
if (IsWindows) Assert.NotEqual(fs.GetCreationTime("/toto.txt"), fs.GetCreationTime("/titi.txt"));
// Because we read titi.txt just before, access time must be different
// Following test is disabled as it seems unstable with NTFS?
// Assert.NotEqual(fs.GetLastAccessTime("/toto.txt"), fs.GetLastAccessTime("/titi.txt"));
Assert.Equal(fs.GetLastWriteTime("/toto.txt"), fs.GetLastWriteTime("/titi.txt"));

var now = DateTime.Now + TimeSpan.FromSeconds(10);
var now1 = DateTime.Now + TimeSpan.FromSeconds(11);
var now2 = DateTime.Now + TimeSpan.FromSeconds(12);
fs.SetCreationTime("/toto.txt", now);
fs.SetLastAccessTime("/toto.txt", now1);
fs.SetLastWriteTime("/toto.txt", now2);
Assert.Equal(now, fs.GetCreationTime("/toto.txt"));
Assert.Equal(now1, fs.GetLastAccessTime("/toto.txt"));
Assert.Equal(now2, fs.GetLastWriteTime("/toto.txt"));
if (IsWindows)
{
var creationTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local);
fs.SetCreationTime("/toto.txt", creationTime);
Assert.Equal(creationTime, fs.GetCreationTime("/toto.txt"));
}

var lastWriteTime = new DateTime(2010, 1, 1, 0, 0, 0, DateTimeKind.Local);
fs.SetLastWriteTime("/toto.txt", lastWriteTime);
Assert.Equal(lastWriteTime, fs.GetLastWriteTime("/toto.txt"));

Assert.NotEqual(fs.GetCreationTime("/toto.txt"), fs.GetCreationTime("/titi.txt"));
Assert.NotEqual(fs.GetLastAccessTime("/toto.txt"), fs.GetLastAccessTime("/titi.txt"));
Assert.NotEqual(fs.GetLastWriteTime("/toto.txt"), fs.GetLastWriteTime("/titi.txt"));
var lastAccessTime = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Local);
fs.SetLastAccessTime("/toto.txt", lastAccessTime);
Assert.Equal(lastAccessTime, fs.GetLastAccessTime("/toto.txt"));

if (IsWindows)
{
Assert.NotEqual(fs.GetCreationTime("/toto.txt"), fs.GetCreationTime("/titi.txt"));
Assert.NotEqual(fs.GetLastAccessTime("/toto.txt"), fs.GetLastAccessTime("/titi.txt"));
Assert.NotEqual(fs.GetLastWriteTime("/toto.txt"), fs.GetLastWriteTime("/titi.txt"));
}

// Test MoveFile
fs.MoveFile("/toto.txt", "/tata.txt");
Expand Down Expand Up @@ -171,11 +188,15 @@ public void TestFile()
Assert.Equal(originalContent, content);

// Check File ReadOnly
fs.SetAttributes("/titi.txt", FileAttributes.ReadOnly);
Assert.Throws<UnauthorizedAccessException>(() => fs.DeleteFile("/titi.txt"));
Assert.Throws<UnauthorizedAccessException>(() => fs.CopyFile("/titi.bak.txt", "/titi.txt", true));
Assert.Throws<UnauthorizedAccessException>(() => fs.OpenFile("/titi.txt", FileMode.Open, FileAccess.ReadWrite));
fs.SetAttributes("/titi.txt", FileAttributes.Normal);
if (IsWindows)
{
// Linux allows modifications on files while they are readonly.
fs.SetAttributes("/titi.txt", FileAttributes.ReadOnly);
Assert.Throws<UnauthorizedAccessException>(() => fs.DeleteFile("/titi.txt"));
Assert.Throws<UnauthorizedAccessException>(() => fs.CopyFile("/titi.bak.txt", "/titi.txt", true));
Assert.Throws<UnauthorizedAccessException>(() => fs.OpenFile("/titi.txt", FileMode.Open, FileAccess.ReadWrite));
fs.SetAttributes("/titi.txt", FileAttributes.Normal);
}

// Delete File
fs.DeleteFile("/titi.txt");
Expand Down Expand Up @@ -279,21 +300,24 @@ public void TestFileExceptions()
Assert.Equal(defaultTime, fs.GetLastWriteTime("/dest"));
Assert.Equal(defaultTime, fs.GetLastAccessTime("/dest"));

using (var stream1 = fs.OpenFile("/toto.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
if (IsWindows)
{
Assert.Throws<IOException>(() =>
using (var stream1 = fs.OpenFile("/toto.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var stream2 = fs.OpenFile("/toto.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
Assert.Throws<IOException>(() =>
{
}
});
using (var stream2 = fs.OpenFile("/toto.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
}
});
}
}

Assert.Throws<UnauthorizedAccessException>(() => fs.OpenFile("/dir1", FileMode.Open, FileAccess.Read));
Assert.Throws<DirectoryNotFoundException>(() => fs.OpenFile("/dir/toto.txt", FileMode.Open, FileAccess.Read));
Assert.Throws<DirectoryNotFoundException>(() => fs.CopyFile("/toto.txt", "/dest/toto.txt", true));
Assert.Throws<IOException>(() => fs.CopyFile("/toto.txt", "/titi.txt", false));
Assert.Throws<IOException>(() => fs.CopyFile("/toto.txt", "/dir1", true));
if (IsWindows) Assert.Throws<IOException>(() => fs.CopyFile("/toto.txt", "/dir1", true));
Assert.Throws<DirectoryNotFoundException>(() => fs.MoveFile("/toto.txt", "/dest/toto.txt"));

fs.WriteAllText("/titi.txt", "yo2");
Expand All @@ -319,8 +343,8 @@ public void TestFileExceptions()
}
}

[Fact]
public void TestDirectoryDeleteAndOpenFile()
[SkippableFact]
public virtual void TestDirectoryDeleteAndOpenFileOnWindows()
{
fs.CreateDirectory("/dir");
fs.WriteAllText("/dir/toto.txt", "content");
Expand Down
103 changes: 65 additions & 38 deletions src/Zio.Tests/FileSystems/TestPhysicalFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ public void TestCommonRead()
AssertCommonRead(fs);
}

[Fact]
public void TestFileSystemInvalidDriveLetter()
[SkippableFact]
public void TestFileSystemInvalidDriveLetterOnWindows()
{
Skip.IfNot(IsWindows, "Exception is only thrown on Windows");

var driverLetter = SystemPath[0];
Assert.Throws<DirectoryNotFoundException>( () => new SubFileSystem(new PhysicalFileSystem(), $"/mnt/{driverLetter}"));
using (var fs = new SubFileSystem(new PhysicalFileSystem(), $"/mnt/{char.ToLowerInvariant(driverLetter)}"))
Expand Down Expand Up @@ -92,15 +94,20 @@ public void TestDirectory()
// LastAccessTime
// LastWriteTime
// CreationTime
var lastWriteTime = DateTime.Now + TimeSpan.FromSeconds(10);
var lastAccessTime = DateTime.Now + TimeSpan.FromSeconds(11);
var creationTime = DateTime.Now + TimeSpan.FromSeconds(12);
if (IsWindows)
{
var creationTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local);
fs.SetCreationTime(pathToCreate, creationTime);
Assert.Equal(creationTime, fs.GetCreationTime(pathToCreate));
}

var lastWriteTime = new DateTime(2010, 1, 1, 0, 0, 0, DateTimeKind.Local);
fs.SetLastWriteTime(pathToCreate, lastWriteTime);
fs.SetLastAccessTime(pathToCreate, lastAccessTime);
fs.SetCreationTime(pathToCreate, creationTime);
Assert.Equal(lastWriteTime, fs.GetLastWriteTime(pathToCreate));

var lastAccessTime = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Local);
fs.SetLastAccessTime(pathToCreate, lastAccessTime);
Assert.Equal(lastAccessTime, fs.GetLastAccessTime(pathToCreate));
Assert.Equal(creationTime, fs.GetCreationTime(pathToCreate));

// DirectoryExists
Assert.True(fs.DirectoryExists(pathToCreate));
Expand Down Expand Up @@ -155,9 +162,11 @@ public void TestDirectorySpecial()
}
}

[Fact]
public void TestDirectoryExceptions()
[SkippableFact]
public void TestDirectoryWindowsExceptions()
{
Skip.IfNot(IsWindows, "Exceptions are only thrown on Windows");

var fs = new PhysicalFileSystem();

// Test invalid characters in path
Expand Down Expand Up @@ -187,6 +196,18 @@ public void TestDirectoryExceptions()
Assert.Throws<DirectoryNotFoundException>(() => fs.DeleteDirectory("/mnt/yoyo", false));
}

[SkippableFact]
public void TestWindowsDirectoryAttributes()
{
Skip.IfNot(IsWindows, "Root attributes are only set on the Windows");

var fs = new PhysicalFileSystem();
var sysAttr = FileAttributes.Directory | FileAttributes.System | FileAttributes.ReadOnly;

Assert.True((fs.GetAttributes("/") & (sysAttr)) == sysAttr);
Assert.True((fs.GetAttributes("/mnt") & (sysAttr)) == sysAttr);
}

[Fact]
public void TestFile()
{
Expand Down Expand Up @@ -217,15 +238,20 @@ public void TestFile()
Assert.Equal(File.GetLastAccessTime(systemFilePath), fs.GetLastAccessTime(filePath));
Assert.Equal(File.GetCreationTime(systemFilePath), fs.GetCreationTime(filePath));

var lastWriteTime = DateTime.Now + TimeSpan.FromSeconds(10);
var lastAccessTime = DateTime.Now + TimeSpan.FromSeconds(11);
var creationTime = DateTime.Now + TimeSpan.FromSeconds(12);
if (IsWindows)
{
var creationTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local);
fs.SetCreationTime(filePath, creationTime);
Assert.Equal(creationTime, fs.GetCreationTime(filePath));
}

var lastWriteTime = new DateTime(2010, 1, 1, 0, 0, 0, DateTimeKind.Local);
fs.SetLastWriteTime(filePath, lastWriteTime);
fs.SetLastAccessTime(filePath, lastAccessTime);
fs.SetCreationTime(filePath, creationTime);
Assert.Equal(lastWriteTime, fs.GetLastWriteTime(filePath));

var lastAccessTime = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Local);
fs.SetLastAccessTime(filePath, lastAccessTime);
Assert.Equal(lastAccessTime, fs.GetLastAccessTime(filePath));
Assert.Equal(creationTime, fs.GetCreationTime(filePath));

// FileAttributes
Assert.Equal(File.GetAttributes(systemFilePath), fs.GetAttributes(filePath));
Expand Down Expand Up @@ -282,23 +308,22 @@ public void TestFile()
Assert.Equal(buffer2.Length, fs.GetFileLength(filePathDest));
Assert.Equal(buffer.Length, fs.GetFileLength(filePathBack));

// RootFileSystem
fs.GetLastWriteTime("/");
fs.GetLastAccessTime("/");
fs.GetCreationTime("/");

fs.GetLastWriteTime("/mnt");
fs.GetLastAccessTime("/mnt");
fs.GetCreationTime("/mnt");

fs.GetLastWriteTime("/mnt/c");
fs.GetLastAccessTime("/mnt/c");
fs.GetCreationTime("/mnt/c");
fs.GetAttributes("/mnt/c");

var sysAttr = FileAttributes.Directory | FileAttributes.System | FileAttributes.ReadOnly;
Assert.True((fs.GetAttributes("/") & (sysAttr)) == sysAttr);
Assert.True((fs.GetAttributes("/mnt") & (sysAttr)) == sysAttr);
if (IsWindows)
{
// RootFileSystem
fs.GetLastWriteTime("/");
fs.GetLastAccessTime("/");
fs.GetCreationTime("/");

fs.GetLastWriteTime("/mnt");
fs.GetLastAccessTime("/mnt");
fs.GetCreationTime("/mnt");

fs.GetLastWriteTime("/mnt/c");
fs.GetLastAccessTime("/mnt/c");
fs.GetCreationTime("/mnt/c");
fs.GetAttributes("/mnt/c");
}
}
finally
{
Expand All @@ -319,17 +344,19 @@ public void TestEnumerate()
Assert.Equal(expectedfiles, files);

var dirs = fs.EnumerateDirectories(path / "../../..").Select(p => fs.ConvertPathToInternal(p)).ToList();
var expecteddirs = Directory.EnumerateDirectories(Path.GetFullPath(Path.Combine(SystemPath, "..\\..\\.."))).ToList();
var expecteddirs = Directory.EnumerateDirectories(Path.GetFullPath(Path.Combine(SystemPath, "../../.."))).ToList();
Assert.Equal(expecteddirs, dirs);

var paths = fs.EnumeratePaths(path / "../..").Select(p => fs.ConvertPathToInternal(p)).ToList();
var expectedPaths = Directory.EnumerateFileSystemEntries(Path.GetFullPath(Path.Combine(SystemPath, "..\\.."))).ToList();
var expectedPaths = Directory.EnumerateFileSystemEntries(Path.GetFullPath(Path.Combine(SystemPath, "../.."))).ToList();
Assert.Equal(expectedPaths, paths);
}

[Fact]
public void TestFileExceptions()
[SkippableFact]
public void TestFileWindowsExceptions()
{
Skip.IfNot(IsWindows, "Exceptions are only thrown on Windows");

var fs = new PhysicalFileSystem();
var path = fs.ConvertPathFromInternal(SystemPath);
var fileName = $"toto-{Guid.NewGuid()}.txt";
Expand Down
7 changes: 7 additions & 0 deletions src/Zio.Tests/FileSystems/TestPhysicalFileSystemCompat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ public TestPhysicalFileSystemCompat()
fs = _fsHelper.PhysicalFileSystem;
}

public override void TestDirectoryDeleteAndOpenFileOnWindows()
{
Skip.IfNot(IsWindows, "Linux allows files to be deleted when they are open");

base.TestDirectoryDeleteAndOpenFileOnWindows();
}

public override void Dispose()
{
_fsHelper.Dispose();
Expand Down
Loading

0 comments on commit 51cf2a1

Please sign in to comment.