mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-19 11:06:37 +01:00
169 lines
4.6 KiB
C#
169 lines
4.6 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.IO.Abstractions;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Principal;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
|
|
namespace Tgstation.Server.Host.IO.Tests
|
|
{
|
|
[TestClass]
|
|
public sealed class TestFilesystemLinkFactory
|
|
{
|
|
static IFilesystemLinkFactory linkFactory;
|
|
|
|
[ClassInitialize]
|
|
public static void SelectFactory(TestContext _)
|
|
{
|
|
var fileSystem = new FileSystem();
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
linkFactory = new WindowsFilesystemLinkFactory(fileSystem);
|
|
else
|
|
linkFactory = new PosixFilesystemLinkFactory(fileSystem);
|
|
}
|
|
|
|
public static bool HasPermissionToMakeSymlinks()
|
|
{
|
|
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
return true;
|
|
var identity = WindowsIdentity.GetCurrent();
|
|
var principal = new WindowsPrincipal(identity);
|
|
return principal.IsInRole(WindowsBuiltInRole.Administrator);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestHardLinkWorks()
|
|
{
|
|
string f2 = null;
|
|
var f1 = Path.GetTempFileName();
|
|
try
|
|
{
|
|
f2 = f1 + ".linked";
|
|
const string Text = "Hello world";
|
|
File.WriteAllText(f1, Text);
|
|
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
{
|
|
await Assert.ThrowsExactlyAsync<NotSupportedException>(() => linkFactory.CreateHardLink(f1, f2, CancellationToken.None));
|
|
Assert.Inconclusive("Windows does not support hardlinks");
|
|
}
|
|
|
|
await Assert.ThrowsExactlyAsync<ArgumentNullException>(() => linkFactory.CreateHardLink(null, null, CancellationToken.None));
|
|
await Assert.ThrowsExactlyAsync<ArgumentNullException>(() => linkFactory.CreateHardLink(f1, null, CancellationToken.None));
|
|
|
|
await linkFactory.CreateHardLink(f1, f2, default);
|
|
Assert.IsTrue(File.Exists(f2));
|
|
|
|
var f2Contents = File.ReadAllText(f2);
|
|
Assert.AreEqual(Text, f2Contents);
|
|
|
|
const string NewText = "asdf";
|
|
File.WriteAllText(f1, NewText);
|
|
|
|
f2Contents = File.ReadAllText(f2);
|
|
Assert.AreEqual(NewText, f2Contents);
|
|
|
|
const string NewText2 = "fdsa";
|
|
File.WriteAllText(f2, NewText2);
|
|
|
|
var f1Contents = File.ReadAllText(f1);
|
|
Assert.AreEqual(NewText2, f1Contents);
|
|
|
|
File.Delete(f1);
|
|
Assert.IsFalse(File.Exists(f1));
|
|
Assert.IsTrue(File.Exists(f2));
|
|
f2Contents = File.ReadAllText(f2);
|
|
Assert.AreEqual(NewText2, f2Contents);
|
|
}
|
|
finally
|
|
{
|
|
File.Delete(f2);
|
|
File.Delete(f1);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestFileWorks()
|
|
{
|
|
if (!HasPermissionToMakeSymlinks())
|
|
Assert.Inconclusive("Current user does not have permission to create symlinks!");
|
|
const string Text = "Hello world";
|
|
string f2 = null;
|
|
var f1 = Path.GetTempFileName();
|
|
try
|
|
{
|
|
f2 = f1 + ".linked";
|
|
File.WriteAllText(f1, Text);
|
|
|
|
await Assert.ThrowsExactlyAsync<ArgumentNullException>(() => linkFactory.CreateSymbolicLink(null, null, default));
|
|
await Assert.ThrowsExactlyAsync<ArgumentNullException>(() => linkFactory.CreateSymbolicLink(f1, null, default));
|
|
|
|
await linkFactory.CreateSymbolicLink(f1, f2, default);
|
|
Assert.IsTrue(File.Exists(f2));
|
|
|
|
var f2Contents = File.ReadAllText(f2);
|
|
Assert.AreEqual(Text, f2Contents);
|
|
}
|
|
finally
|
|
{
|
|
File.Delete(f2);
|
|
File.Delete(f1);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestDirectoryWorks()
|
|
{
|
|
if (!HasPermissionToMakeSymlinks())
|
|
Assert.Inconclusive("Current user does not have permission to create symlinks!");
|
|
const string FileName = "TestFile.txt";
|
|
const string Text = "Hello world";
|
|
string f2 = null;
|
|
var f1 = Path.GetTempFileName();
|
|
File.Delete(f1);
|
|
Directory.CreateDirectory(f1);
|
|
try
|
|
{
|
|
f2 = f1 + ".linked";
|
|
var p1 = Path.Combine(f1, FileName);
|
|
File.WriteAllText(p1, Text);
|
|
|
|
await Assert.ThrowsExactlyAsync<ArgumentNullException>(() => linkFactory.CreateSymbolicLink(null, null, default));
|
|
await Assert.ThrowsExactlyAsync<ArgumentNullException>(() => linkFactory.CreateSymbolicLink(f1, null, default));
|
|
|
|
await linkFactory.CreateSymbolicLink(f1, f2, default);
|
|
|
|
var p2 = Path.Combine(f2, FileName);
|
|
Assert.IsTrue(File.Exists(p2));
|
|
|
|
var f2Contents = File.ReadAllText(p2);
|
|
Assert.AreEqual(Text, f2Contents);
|
|
|
|
File.Delete(p2);
|
|
Assert.IsFalse(File.Exists(p1));
|
|
}
|
|
finally
|
|
{
|
|
Directory.Delete(f2, true);
|
|
Directory.Delete(f1, true);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestFailsProperly()
|
|
{
|
|
const string BadPath = "/../../?>!@#$%^&*()O(UF+}P{{??>/////";
|
|
|
|
try
|
|
{
|
|
await linkFactory.CreateSymbolicLink(BadPath, BadPath, default);
|
|
Assert.Fail("No exception thrown!");
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
}
|