Skip to content

Commit

Permalink
Merge branch 'main' into fix-vlad-update
Browse files Browse the repository at this point in the history
  • Loading branch information
mohnjiles authored Jul 5, 2023
2 parents ebece70 + 539cd81 commit eb9d4bb
Show file tree
Hide file tree
Showing 15 changed files with 817 additions and 38 deletions.
86 changes: 86 additions & 0 deletions StabilityMatrix.Tests/Models/SharedFoldersTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using StabilityMatrix.Extensions;
using StabilityMatrix.Models;

namespace StabilityMatrix.Tests.Models;

[TestClass]
public class SharedFoldersTests
{
private string tempFolder = string.Empty;
private string TempModelsFolder => Path.Combine(tempFolder, "models");
private string TempPackageFolder => Path.Combine(tempFolder, "package");

private readonly Dictionary<SharedFolderType, string> sampleDefinitions = new()
{
[SharedFolderType.StableDiffusion] = "models/Stable-diffusion",
[SharedFolderType.ESRGAN] = "models/ESRGAN",
[SharedFolderType.TextualInversion] = "embeddings",
};

[TestInitialize]
public void Initialize()
{
tempFolder = Path.GetTempFileName();
File.Delete(tempFolder);
Directory.CreateDirectory(tempFolder);
}

[TestCleanup]
public void Cleanup()
{
if (string.IsNullOrEmpty(tempFolder)) return;
TempFiles.DeleteDirectory(tempFolder);
}

private void CreateSampleJunctions()
{
var definitions = new Dictionary<SharedFolderType, string>
{
[SharedFolderType.StableDiffusion] = "models/Stable-diffusion",
[SharedFolderType.ESRGAN] = "models/ESRGAN",
[SharedFolderType.TextualInversion] = "embeddings",
};
SharedFolders.SetupLinks(definitions, TempModelsFolder, TempPackageFolder);
}

[TestMethod]
public void SetupLinks_CreatesJunctions()
{
CreateSampleJunctions();

// Check model folders
foreach (var (folderType, relativePath) in sampleDefinitions)
{
var packagePath = Path.Combine(TempPackageFolder, relativePath);
var modelFolder = Path.Combine(TempModelsFolder, folderType.GetStringValue());
// Should exist and be a junction
Assert.IsTrue(Directory.Exists(packagePath), $"Package folder {packagePath} does not exist.");
var info = new DirectoryInfo(packagePath);
Assert.IsTrue(info.Attributes.HasFlag(FileAttributes.ReparsePoint), $"Package folder {packagePath} is not a junction.");
// Check junction target should be in models folder
Assert.AreEqual(modelFolder, info.LinkTarget, $"Package folder {packagePath} does not point to {modelFolder}.");
}
}

[TestMethod]
public void SetupLinks_CanDeleteJunctions()
{
CreateSampleJunctions();

var modelFolder = Path.Combine(tempFolder, "models", SharedFolderType.StableDiffusion.GetStringValue());
var packagePath = Path.Combine(tempFolder, "package", sampleDefinitions[SharedFolderType.StableDiffusion]);

// Write a file to a model folder
File.Create(Path.Combine(modelFolder, "AFile")).Close();
Assert.IsTrue(File.Exists(Path.Combine(modelFolder, "AFile")), $"File should exist in {modelFolder}.");
// Should exist in the package folder
Assert.IsTrue(File.Exists(Path.Combine(packagePath, "AFile")), $"File should exist in {packagePath}.");

// Now delete the junction
Directory.Delete(packagePath, false);
Assert.IsFalse(Directory.Exists(packagePath), $"Package folder {packagePath} should not exist.");

// The file should still exist in the model folder
Assert.IsTrue(File.Exists(Path.Combine(modelFolder, "AFile")), $"File should exist in {modelFolder}.");
}
}
163 changes: 163 additions & 0 deletions StabilityMatrix.Tests/ReparsePoints/JunctionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
using Microsoft.VisualBasic;
using StabilityMatrix.ReparsePoints;

namespace StabilityMatrix.Tests.ReparsePoints;

using System.IO;


[TestClass]
public class JunctionTest
{
private string tempFolder = string.Empty;

[TestInitialize]
public void Initialize()
{
tempFolder = Path.GetTempFileName();
File.Delete(tempFolder);
Directory.CreateDirectory(tempFolder);
}

[TestCleanup]
public void Cleanup()
{
if (string.IsNullOrEmpty(tempFolder)) return;
TempFiles.DeleteDirectory(tempFolder);
}

[TestMethod]
public void Exists_NoSuchFile()
{
Assert.IsFalse(Junction.Exists(Path.Combine(tempFolder, "$$$NoSuchFolder$$$")));
}

[TestMethod]
public void Exists_IsADirectory()
{
File.Create(Path.Combine(tempFolder, "AFile")).Close();

Assert.IsFalse(Junction.Exists(Path.Combine(tempFolder, "AFile")));
}

[TestMethod]
public void Create_VerifyExists_GetTarget_Delete()
{
var targetFolder = Path.Combine(tempFolder, "ADirectory");
var junctionPoint = Path.Combine(tempFolder, "SymLink");

Directory.CreateDirectory(targetFolder);
File.Create(Path.Combine(targetFolder, "AFile")).Close();

// Verify behavior before junction point created.
Assert.IsFalse(File.Exists(Path.Combine(junctionPoint, "AFile")),
"File should not be located until junction point created.");

Assert.IsFalse(Junction.Exists(junctionPoint), "Junction point not created yet.");

// Create junction point and confirm its properties.
Junction.Create(junctionPoint, targetFolder, false /*don't overwrite*/);

Assert.IsTrue(Junction.Exists(junctionPoint), "Junction point exists now.");

Assert.AreEqual(targetFolder, Junction.GetTarget(junctionPoint));

Assert.IsTrue(File.Exists(Path.Combine(junctionPoint, "AFile")),
"File should be accessible via the junction point.");

// Delete junction point.
Junction.Delete(junctionPoint);

Assert.IsFalse(Junction.Exists(junctionPoint), "Junction point should not exist now.");

Assert.IsFalse(File.Exists(Path.Combine(junctionPoint, "AFile")),
"File should not be located after junction point deleted.");

Assert.IsFalse(Directory.Exists(junctionPoint), "Ensure directory was deleted too.");

// Cleanup
File.Delete(Path.Combine(targetFolder, "AFile"));
}

[TestMethod]
[ExpectedException(typeof(IOException), "Directory already exists and overwrite parameter is false.")]
public void Create_ThrowsIfOverwriteNotSpecifiedAndDirectoryExists()
{
var targetFolder = Path.Combine(tempFolder, "ADirectory");
var junctionPoint = Path.Combine(tempFolder, "SymLink");

Directory.CreateDirectory(junctionPoint);

Junction.Create(junctionPoint, targetFolder, false);
}

[TestMethod]
public void Create_OverwritesIfSpecifiedAndDirectoryExists()
{
var targetFolder = Path.Combine(tempFolder, "ADirectory");
var junctionPoint = Path.Combine(tempFolder, "SymLink");

Directory.CreateDirectory(junctionPoint);
Directory.CreateDirectory(targetFolder);

Junction.Create(junctionPoint, targetFolder, true);

Assert.AreEqual(targetFolder, Junction.GetTarget(junctionPoint));
}

[TestMethod]
[ExpectedException(typeof(IOException), "Target path does not exist or is not a directory.")]
public void Create_ThrowsIfTargetDirectoryDoesNotExist()
{
var targetFolder = Path.Combine(tempFolder, "ADirectory");
var junctionPoint = Path.Combine(tempFolder, "SymLink");

Junction.Create(junctionPoint, targetFolder, false);
}

[TestMethod]
[ExpectedException(typeof(IOException), "Unable to open reparse point.")]
public void GetTarget_NonExistentJunctionPoint()
{
Junction.GetTarget(Path.Combine(tempFolder, "SymLink"));
}

[TestMethod]
[ExpectedException(typeof(IOException), "Path is not a junction point.")]
public void GetTarget_CalledOnADirectoryThatIsNotAJunctionPoint()
{
Junction.GetTarget(tempFolder);
}

[TestMethod]
[ExpectedException(typeof(IOException), "Path is not a junction point.")]
public void GetTarget_CalledOnAFile()
{
File.Create(Path.Combine(tempFolder, "AFile")).Close();

Junction.GetTarget(Path.Combine(tempFolder, "AFile"));
}

[TestMethod]
public void Delete_NonExistentJunctionPoint()
{
// Should do nothing.
Junction.Delete(Path.Combine(tempFolder, "SymLink"));
}

[TestMethod]
[ExpectedException(typeof(IOException), "Unable to delete junction point.")]
public void Delete_CalledOnADirectoryThatIsNotAJunctionPoint()
{
Junction.Delete(tempFolder);
}

[TestMethod]
[ExpectedException(typeof(IOException), "Path is not a junction point.")]
public void Delete_CalledOnAFile()
{
File.Create(Path.Combine(tempFolder, "AFile")).Close();

Junction.Delete(Path.Combine(tempFolder, "AFile"));
}
}
22 changes: 22 additions & 0 deletions StabilityMatrix.Tests/TempFiles.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace StabilityMatrix.Tests;

public static class TempFiles
{
// Deletes directory while handling junction folders
public static void DeleteDirectory(string directory)
{
// Enumerate to delete any directory links
foreach (var item in Directory.EnumerateDirectories(directory))
{
var info = new DirectoryInfo(item);
if (info.Exists && info.Attributes.HasFlag(FileAttributes.ReparsePoint))
{
info.Delete();
}
else
{
DeleteDirectory(item);
}
}
}
}
3 changes: 3 additions & 0 deletions StabilityMatrix/Models/FileInterfaces/DirectoryPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public Task<long> GetSizeAsync(bool includeSymbolicLinks)
// DirectoryPath + FilePath = FilePath
public static FilePath operator +(DirectoryPath path, FilePath other) => new(Path.Combine(path, other.FullPath));

// DirectoryPath + FileInfo = FilePath
public static FilePath operator +(DirectoryPath path, FileInfo other) => new(Path.Combine(path, other.FullName));

// DirectoryPath + string = string
public static string operator +(DirectoryPath path, string other) => Path.Combine(path, other);

Expand Down
7 changes: 4 additions & 3 deletions StabilityMatrix/Models/ISharedFolders.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using StabilityMatrix.Models.Packages;
using StabilityMatrix.Models.FileInterfaces;
using StabilityMatrix.Models.Packages;

namespace StabilityMatrix.Models;

public interface ISharedFolders
{
void SetupLinksForPackage(BasePackage basePackage, string installPath);
void UpdateLinksForPackage(BasePackage basePackage, string installPath);
void SetupLinksForPackage(BasePackage basePackage, DirectoryPath installDirectory);
void UpdateLinksForPackage(BasePackage basePackage, DirectoryPath installDirectory);
void RemoveLinksForAllPackages();
}
Loading

0 comments on commit eb9d4bb

Please sign in to comment.