Skip to content

Commit

Permalink
SNOW-990111: Remove umask test and create dotnet subfolder with Mono.…
Browse files Browse the repository at this point in the history
…Unix
  • Loading branch information
sfc-gh-ext-simba-lf committed Jan 25, 2024
1 parent ea8d52e commit 3fabd05
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class EasyLoggingConfigFinderTest
private static Mock<FileOperations> t_fileOperations;

[ThreadStatic]
private static Mock<UnixFileOperations> t_unixFileOperations;
private static Mock<UnixOperations> t_unixOperations;

[ThreadStatic]
private static Mock<DirectoryOperations> t_directoryOperations;
Expand All @@ -42,10 +42,10 @@ public class EasyLoggingConfigFinderTest
public void Setup()
{
t_fileOperations = new Mock<FileOperations>();
t_unixFileOperations = new Mock<UnixFileOperations>();
t_unixOperations = new Mock<UnixOperations>();
t_directoryOperations = new Mock<DirectoryOperations>();
t_environmentOperations = new Mock<EnvironmentOperations>();
t_finder = new EasyLoggingConfigFinder(t_fileOperations.Object, t_unixFileOperations.Object, t_directoryOperations.Object, t_environmentOperations.Object);
t_finder = new EasyLoggingConfigFinder(t_fileOperations.Object, t_unixOperations.Object, t_directoryOperations.Object, t_environmentOperations.Object);
MockDirectoriesExist();
MockHomeDirectory();
}
Expand Down Expand Up @@ -207,8 +207,8 @@ private static void MockDirectoriesExist()

private static void MockHasFlagReturnsTrue()
{
t_unixFileOperations
.Setup(f => f.HasFlag(
t_unixOperations
.Setup(f => f.CheckFileHasPermissions(
It.Is<FileAccessPermissions>(p => p.Equals(FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite))))
.Returns(true);
}
Expand Down
89 changes: 39 additions & 50 deletions Snowflake.Data.Tests/UnitTests/Session/EasyLoggingStarterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
*/

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Mono.Unix;
using Mono.Unix.Native;
using Moq;
using NUnit.Framework;
using Snowflake.Data.Configuration;
Expand All @@ -19,7 +19,6 @@ namespace Snowflake.Data.Tests.UnitTests.Session
[TestFixture]
public class EasyLoggingStarterTest
{
private static readonly int AllPermissions = 777;
private static readonly string HomeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
private static readonly string LogPath = Path.Combine(HomeDirectory, "some-logs-path/some-folder");
private const string ConfigPath = "/some-path/config.json";
Expand Down Expand Up @@ -58,6 +57,9 @@ public class EasyLoggingStarterTest
[ThreadStatic]
private static Mock<EasyLoggerManager> t_easyLoggerManager;

[ThreadStatic]
private static Mock<UnixOperations> t_unixOperations;

[ThreadStatic]
private static Mock<DirectoryOperations> t_directoryOperations;

Expand All @@ -72,43 +74,15 @@ public void BeforeEach()
{
t_easyLoggingProvider = new Mock<EasyLoggingConfigProvider>();
t_easyLoggerManager = new Mock<EasyLoggerManager>();
t_unixOperations = new Mock<UnixOperations>();
t_directoryOperations = new Mock<DirectoryOperations>();
t_environmentOperations = new Mock<EnvironmentOperations>();
t_easyLoggerStarter = new EasyLoggingStarter(t_easyLoggingProvider.Object, t_easyLoggerManager.Object, t_directoryOperations.Object, t_environmentOperations.Object);
}

[Test]
public void TestThatCreatedDirectoryPermissionsFollowUmask()
{
// Note: To test with a different value than the default umask, it will have to be set before running this test
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Ignore("skip test on Windows");
}

// arrange
t_easyLoggingProvider
.Setup(provider => provider.ProvideConfig(ConfigPath))
.Returns(s_configWithInfoLevel);
t_directoryOperations
.Setup(provider => provider.Exists(ConfigPath))
.Returns(Directory.Exists(ConfigPath));
t_directoryOperations
.Setup(provider => provider.CreateDirectory(s_expectedLogPath))
.Returns(Directory.CreateDirectory(s_expectedLogPath));

var expectedDirPermissions = AllPermissions - int.Parse(CallBash("umask"));

// act
t_easyLoggerStarter.Init(ConfigPath);
var dirInfo = new UnixDirectoryInfo(s_expectedLogPath);
var dirPermissions = EasyLoggerUtil.ConvertFileAccessPermissionsToInt(dirInfo.FileAccessPermissions);

// assert
Assert.AreEqual(expectedDirPermissions, dirPermissions);

// cleanup
Directory.Delete(s_expectedLogPath);
t_easyLoggerStarter = new EasyLoggingStarter(
t_easyLoggingProvider.Object,
t_easyLoggerManager.Object,
t_unixOperations.Object,
t_directoryOperations.Object,
t_environmentOperations.Object);
}

[Test]
Expand Down Expand Up @@ -150,6 +124,34 @@ public void TestThatThrowsErrorWhenLogPathIsNotSetAndHomeDirectoryThrowsAnExcept
Assert.AreEqual(thrown.Message, $"Error while trying to retrieve the home directory: {ex}");
}

[Test]
public void TestThatDoesNotFailWhenDirectoryPermissionIsNot700()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Ignore("skip test on Windows");
}

// arrange
t_easyLoggingProvider
.Setup(provider => provider.ProvideConfig(ConfigPath))
.Returns(s_configWithInfoLevel);
t_directoryOperations
.Setup(provider => provider.Exists(ConfigPath))
.Returns(false);
t_unixOperations
.Setup(provider => provider.GetDirPermissions())
.Returns(FileAccessPermissions.AllPermissions);

// act
t_easyLoggerStarter.Init(ConfigPath);

// assert
t_unixOperations.Verify(u => u.CreateDirectoryWithPermissions(s_expectedLogPath,
FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Once);
t_unixOperations.Verify(u => u.SetDirInfo(s_expectedLogPath), Times.Once);
}

[Test]
public void TestThatConfiguresEasyLoggingOnlyOnceWhenInitializedWithConfigPath()
{
Expand Down Expand Up @@ -222,18 +224,5 @@ public void TestThatReconfiguresEasyLoggingWithConfigPathIfNotGivenForTheFirstTi
t_easyLoggerManager.Verify(manager => manager.ReconfigureEasyLogging(EasyLoggingLogLevel.Info, s_expectedLogPath), Times.Once);
t_easyLoggerManager.VerifyNoOtherCalls();
}

private static string CallBash(string command)
{
using (Process process = new Process())
{
process.StartInfo.FileName = "/bin/bash";
process.StartInfo.Arguments = $"-c \"{command}\"";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
return process.StandardOutput.ReadToEnd().Replace("\n", string.Empty);
}
}
}
}
12 changes: 6 additions & 6 deletions Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ internal class EasyLoggingConfigFinder
internal const string ClientConfigEnvironmentName = "SF_CLIENT_CONFIG_FILE";

private readonly FileOperations _fileOperations;
private readonly UnixFileOperations _unixFileOperations;
private readonly UnixOperations _unixOperations;
private readonly DirectoryOperations _directoryOperations;
private readonly EnvironmentOperations _environmentOperations;

public static readonly EasyLoggingConfigFinder Instance = new EasyLoggingConfigFinder(FileOperations.Instance, UnixFileOperations.Instance, DirectoryOperations.Instance, EnvironmentOperations.Instance);
public static readonly EasyLoggingConfigFinder Instance = new EasyLoggingConfigFinder(FileOperations.Instance, UnixOperations.Instance, DirectoryOperations.Instance, EnvironmentOperations.Instance);

internal EasyLoggingConfigFinder(FileOperations fileOperations, UnixFileOperations unixFileOperations, DirectoryOperations directoryOperations, EnvironmentOperations environmentOperations)
internal EasyLoggingConfigFinder(FileOperations fileOperations, UnixOperations unixFileOperations, DirectoryOperations directoryOperations, EnvironmentOperations environmentOperations)
{
_fileOperations = fileOperations;
_unixFileOperations = unixFileOperations;
_unixOperations = unixFileOperations;
_directoryOperations = directoryOperations;
_environmentOperations = environmentOperations;
}
Expand Down Expand Up @@ -112,8 +112,8 @@ private void CheckIfValidPermissions(string filePath)
return;

// Check if others have permissions to modify the file and fail if so
_unixFileOperations.SetUnixFileInfo(filePath);
if (_unixFileOperations.HasFlag(FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite))
_unixOperations.SetFileInfo(filePath);

Check warning on line 115 in Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs#L115

Added line #L115 was not covered by tests
if (_unixOperations.CheckFileHasPermissions(FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite))
{
var errorMessage = $"Error due to other users having permission to modify the config file: {filePath}";
s_logger.Error(errorMessage);
Expand Down
29 changes: 21 additions & 8 deletions Snowflake.Data/Core/Session/EasyLoggingStarter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.IO;
using System.Runtime.InteropServices;
using Mono.Unix;
using Mono.Unix.Native;
using Snowflake.Data.Configuration;
using Snowflake.Data.Core.Tools;
using Snowflake.Data.Log;
Expand All @@ -20,6 +21,8 @@ internal class EasyLoggingStarter

private readonly EasyLoggerManager _easyLoggerManager;

private readonly UnixOperations _unixOperations;

private readonly DirectoryOperations _directoryOperations;

private readonly EnvironmentOperations _environmentOperations;
Expand All @@ -29,16 +32,18 @@ internal class EasyLoggingStarter
private EasyLoggingInitTrialParameters _initTrialParameters = null;

public static readonly EasyLoggingStarter Instance = new EasyLoggingStarter(EasyLoggingConfigProvider.Instance,
EasyLoggerManager.Instance, DirectoryOperations.Instance, EnvironmentOperations.Instance);
EasyLoggerManager.Instance, UnixOperations.Instance, DirectoryOperations.Instance, EnvironmentOperations.Instance);

internal EasyLoggingStarter(
EasyLoggingConfigProvider easyLoggingConfigProvider,
EasyLoggerManager easyLoggerManager,
UnixOperations unixOperations,
DirectoryOperations directoryOperations,
EnvironmentOperations environmentOperations)
{
_easyLoggingConfigProvider = easyLoggingConfigProvider;
_easyLoggerManager = easyLoggerManager;
_unixOperations = unixOperations;
_directoryOperations = directoryOperations;
_environmentOperations = environmentOperations;
}
Expand Down Expand Up @@ -127,9 +132,16 @@ private string GetLogPath(string logPath)
var pathWithDotnetSubdirectory = Path.Combine(logPathOrDefault, "dotnet");
if (!_directoryOperations.Exists(pathWithDotnetSubdirectory))
{
_directoryOperations.CreateDirectory(pathWithDotnetSubdirectory);

CheckDirPermissionsOnlyAllowUser(pathWithDotnetSubdirectory);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
_directoryOperations.CreateDirectory(pathWithDotnetSubdirectory);
}
else
{
_unixOperations.CreateDirectoryWithPermissions(pathWithDotnetSubdirectory,
FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR);
CheckDirPermissionsOnlyAllowUser(pathWithDotnetSubdirectory);
}

Check warning on line 144 in Snowflake.Data/Core/Session/EasyLoggingStarter.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/EasyLoggingStarter.cs#L140-L144

Added lines #L140 - L144 were not covered by tests
}

return pathWithDotnetSubdirectory;
Expand All @@ -140,11 +152,12 @@ private void CheckDirPermissionsOnlyAllowUser(string dirPath)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return;

Check warning on line 153 in Snowflake.Data/Core/Session/EasyLoggingStarter.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/EasyLoggingStarter.cs#L153

Added line #L153 was not covered by tests

var dirInfo = new UnixDirectoryInfo(dirPath);
if (dirInfo.Exists && dirInfo.FileAccessPermissions != FileAccessPermissions.UserReadWriteExecute)
_unixOperations.SetDirInfo(dirPath);
var dirPermissions = _unixOperations.GetDirPermissions();

Check warning on line 156 in Snowflake.Data/Core/Session/EasyLoggingStarter.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/EasyLoggingStarter.cs#L155-L156

Added lines #L155 - L156 were not covered by tests
if (dirPermissions != FileAccessPermissions.UserReadWriteExecute)
{
var dirPermissions = EasyLoggerUtil.ConvertFileAccessPermissionsToInt(dirInfo.FileAccessPermissions);
s_logger.Warn($"Access permission for the logs directory is currently {dirPermissions}");
s_logger.Warn($"Access permission for the logs directory is currently " +
$"{EasyLoggerUtil.ConvertFileAccessPermissionsToInt(dirPermissions)}");
}
}

Check warning on line 162 in Snowflake.Data/Core/Session/EasyLoggingStarter.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/EasyLoggingStarter.cs#L158-L162

Added lines #L158 - L162 were not covered by tests
}
Expand Down
25 changes: 0 additions & 25 deletions Snowflake.Data/Core/Tools/UnixFileOperations.cs

This file was deleted.

48 changes: 48 additions & 0 deletions Snowflake.Data/Core/Tools/UnixOperations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2024 Snowflake Computing Inc. All rights reserved.
*/

using Mono.Unix;
using Mono.Unix.Native;
using System.IO;

namespace Snowflake.Data.Core.Tools
{
internal class UnixOperations
{
public static readonly UnixOperations Instance = new UnixOperations();

private UnixFileInfo _unixFileInfo;
private UnixDirectoryInfo _unixDirInfo;

public virtual void SetDirInfo(string path)
{
_unixDirInfo = new UnixDirectoryInfo(path);
}

Check warning on line 21 in Snowflake.Data/Core/Tools/UnixOperations.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Tools/UnixOperations.cs#L19-L21

Added lines #L19 - L21 were not covered by tests

public virtual void CreateDirectoryWithPermissions(string path, FilePermissions permissions)
{
string subPath = Path.GetDirectoryName(path);

Check warning on line 25 in Snowflake.Data/Core/Tools/UnixOperations.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Tools/UnixOperations.cs#L24-L25

Added lines #L24 - L25 were not covered by tests
if (!Directory.Exists(subPath))
{
Directory.CreateDirectory(subPath);
}
Syscall.mkdir(path, permissions);
}

Check warning on line 31 in Snowflake.Data/Core/Tools/UnixOperations.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Tools/UnixOperations.cs#L27-L31

Added lines #L27 - L31 were not covered by tests

public virtual FileAccessPermissions GetDirPermissions()
{
return _unixDirInfo.FileAccessPermissions;
}

Check warning on line 36 in Snowflake.Data/Core/Tools/UnixOperations.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Tools/UnixOperations.cs#L34-L36

Added lines #L34 - L36 were not covered by tests

public virtual void SetFileInfo(string path)
{
_unixFileInfo = new UnixFileInfo(path);
}

Check warning on line 41 in Snowflake.Data/Core/Tools/UnixOperations.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Tools/UnixOperations.cs#L39-L41

Added lines #L39 - L41 were not covered by tests

public virtual bool CheckFileHasPermissions(FileAccessPermissions permissions)
{
return _unixFileInfo.FileAccessPermissions.HasFlag(permissions);
}

Check warning on line 46 in Snowflake.Data/Core/Tools/UnixOperations.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Tools/UnixOperations.cs#L44-L46

Added lines #L44 - L46 were not covered by tests
}
}

0 comments on commit 3fabd05

Please sign in to comment.