From d506fa690b56ffaf11e6fb89ae213f2f300fd34c Mon Sep 17 00:00:00 2001 From: Krzysztof Nozderko Date: Tue, 20 Feb 2024 15:10:04 +0100 Subject: [PATCH] handle case when directory creation fails --- .../IntegrationTests/EasyLoggingIT.cs | 25 +++++++++++++++++++ .../Session/EasyLoggingStarterTest.cs | 23 +++++++++++++++++ .../Core/Session/EasyLoggingStarter.cs | 7 +++++- Snowflake.Data/Core/Tools/UnixOperations.cs | 4 +-- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs b/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs index d120abcfd..595fbb65d 100644 --- a/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/EasyLoggingIT.cs @@ -95,5 +95,30 @@ public void TestFailToEnableEasyLoggingWhenConfigHasWrongPermissions() Assert.IsFalse(EasyLoggerManager.HasEasyLoggingAppender()); } } + + [Test] + public void TestFailToEnableEasyLoggingWhenLogDirectoryNotAccessible() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Assert.Ignore("skip test on Windows"); + } + + // arrange + var configFilePath = CreateConfigTempFile(s_workingDirectory, Config("WARN", "/")); + using (IDbConnection conn = new SnowflakeDbConnection()) + { + conn.ConnectionString = ConnectionString + $"CLIENT_CONFIG_FILE={configFilePath}"; + + // act + var thrown = Assert.Throws(() => conn.Open()); + + // assert + Assert.That(thrown.Message, Does.Contain("Connection string is invalid: Unable to connect")); + Assert.That(thrown.InnerException.Message, Does.Contain("Failed to create logs directory")); + Assert.IsFalse(EasyLoggerManager.HasEasyLoggingAppender()); + } + + } } } \ No newline at end of file diff --git a/Snowflake.Data.Tests/UnitTests/Session/EasyLoggingStarterTest.cs b/Snowflake.Data.Tests/UnitTests/Session/EasyLoggingStarterTest.cs index 3b96339a0..8b1c6ebfe 100644 --- a/Snowflake.Data.Tests/UnitTests/Session/EasyLoggingStarterTest.cs +++ b/Snowflake.Data.Tests/UnitTests/Session/EasyLoggingStarterTest.cs @@ -151,6 +151,29 @@ public void TestThatDoesNotFailWhenLogDirectoryPermissionIsNot700() FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR), Times.Never); } + [Test] + public void TestFailIfDirectoryCreationFails() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Assert.Ignore("skip test on Windows"); + } + + // arrange + t_easyLoggingProvider + .Setup(provider => provider.ProvideConfig(ConfigPath)) + .Returns(s_configWithErrorLevel); + t_unixOperations + .Setup(u => u.CreateDirectoryWithPermissions(s_expectedLogPath, FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR)) + .Returns((int)Errno.EPERM); + + // act + var thrown = Assert.Throws(() => t_easyLoggerStarter.Init(ConfigPath)); + + // assert + Assert.That(thrown.Message, Does.Contain("Failed to create logs directory")); + } + [Test] public void TestThatConfiguresEasyLoggingOnlyOnceWhenInitializedWithConfigPath() { diff --git a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs index 894e9308a..51a402bf1 100644 --- a/Snowflake.Data/Core/Session/EasyLoggingStarter.cs +++ b/Snowflake.Data/Core/Session/EasyLoggingStarter.cs @@ -141,8 +141,13 @@ private string GetLogPath(string logPath) { Directory.CreateDirectory(logPathOrDefault); } - _unixOperations.CreateDirectoryWithPermissions(pathWithDotnetSubdirectory, + var createDirResult = _unixOperations.CreateDirectoryWithPermissions(pathWithDotnetSubdirectory, FilePermissions.S_IRUSR | FilePermissions.S_IWUSR | FilePermissions.S_IXUSR); + if (createDirResult != 0) + { + s_logger.Error($"Failed to create logs directory: {pathWithDotnetSubdirectory}"); + throw new Exception("Failed to create logs directory"); + } } } CheckDirPermissionsOnlyAllowUser(pathWithDotnetSubdirectory); diff --git a/Snowflake.Data/Core/Tools/UnixOperations.cs b/Snowflake.Data/Core/Tools/UnixOperations.cs index 2437e7b74..cb44099b7 100644 --- a/Snowflake.Data/Core/Tools/UnixOperations.cs +++ b/Snowflake.Data/Core/Tools/UnixOperations.cs @@ -11,9 +11,9 @@ internal class UnixOperations { public static readonly UnixOperations Instance = new UnixOperations(); - public virtual void CreateDirectoryWithPermissions(string path, FilePermissions permissions) + public virtual int CreateDirectoryWithPermissions(string path, FilePermissions permissions) { - Syscall.mkdir(path, permissions); + return Syscall.mkdir(path, permissions); } public virtual FileAccessPermissions GetDirPermissions(string path)