Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Linux unit tests #87

Merged
merged 5 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
xoofx marked this conversation as resolved.
Show resolved Hide resolved
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);
xoofx marked this conversation as resolved.
Show resolved Hide resolved
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
Loading