Skip to content
Draft
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#### For the official .NET Release Notes please refer to https://docs.snowflake.com/en/release-notes/clients-drivers/dotnet

# Changelog
- v5.1.1
- v5.2.0
- Added multi-targeting support. The appropriate build is selected by NuGet based on target framework and OS.
- Fixed CRL validation to reject newly downloaded CRLs if their NextUpdate has already expired.
- Users can now specify non-string values in Toml. For example, `port` can be specified as an integer in the Toml.
- v5.1.0
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ The Snowflake .NET connector supports the following .NET framework and libraries

Disclaimer: While the connector targets netstandard2.0 and may work with versions in its [support matrix](https://learn.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-2-0#select-net-standard-version), only the versions listed above are supported and tested by the connector

## Target Frameworks and Platform-Specific Builds

Starting from version **5.2.0**, the Snowflake .NET connector uses multi-targeting to provide optimized builds for different platforms:

| Target Framework | Platform | Description |
|------------------|----------|-------------------------------------------------------------|
| `net481` | Windows (.NET Framework 4.8.1) | Optimized build for Windows .NET Framework without Mono.Unix |
| `net8.0-windows` | Windows (.NET 8+) | Optimized build for Windows .NET 8+ without Mono.Unix |
| `net8.0` | Linux, macOS (.NET 8+) | Full Unix file system support with Mono.Unix |
| `netstandard2.0` | All platforms | Backward compatibility for older .NET versions |

**What this means for you:**

- **Windows users** on .NET Framework 4.8.1 will receive the `net481` build without the `Mono.Unix` dependency.
- **Windows users** on .NET 8 or higher will receive the `net8.0-windows` build without the `Mono.Unix` dependency.
- **Linux and macOS users** on .NET 8 or higher will receive the `net8.0`.
- **Older .NET versions** (including older .NET Framework and .NET versions) will use the `netstandard2.0` build for backward compatibility.

The appropriate build is automatically selected by NuGet based on your application's target framework and operating system.

Please refer to the [Notice](#notice) section below for information about safe usage of the .NET Driver

# Coding conventions for the project
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using Mono.Unix;
using Mono.Unix.Native;
using NUnit.Framework;
Expand All @@ -9,7 +10,8 @@
namespace Snowflake.Data.Tests.UnitTests.Tools
{
[TestFixture, NonParallelizable]
public class DirectoryOperationsTest
[Platform(Exclude = "Win")]
public class DirectoryOperationsUnixTest
{
private static DirectoryOperations s_directoryOperations;
private static readonly string s_relativeWorkingDirectory = $"directory_operations_test_{Path.GetRandomFileName()}";
Expand All @@ -20,6 +22,11 @@ public class DirectoryOperationsTest
[SetUp]
public static void Before()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Ignore("Unix-specific tests are not run on Windows");
}

if (!Directory.Exists(s_workingDirectory))
{
Directory.CreateDirectory(s_workingDirectory);
Expand All @@ -31,23 +38,15 @@ public static void Before()
[TearDown]
public static void After()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return;
}

Directory.Delete(s_workingDirectory, true);
}

[Test]
[Platform("Win")]
public void TestDirectoryIsSafeOnWindows()
{
// arrange
var absoluteFilePath = Path.Combine(s_workingDirectory, s_dirName);
Directory.CreateDirectory(absoluteFilePath);

// act and assert
Assert.IsTrue(s_directoryOperations.IsDirectorySafe(absoluteFilePath));
}

[Test]
[Platform(Exclude = "Win")]
public void TestDirectoryIsNotSafeOnNotWindowsWhenPermissionsAreTooBroad(
[ValueSource(nameof(InsecurePermissions))]
FileAccessPermissions permissions)
Expand All @@ -60,18 +59,6 @@ public void TestDirectoryIsNotSafeOnNotWindowsWhenPermissionsAreTooBroad(
}

[Test]
public void TestShouldCreateDirectoryWithSafePermissions()
{
// act
s_directoryOperations.CreateDirectory(s_dirAbsolutePath);

// assert
Assert.IsTrue(Directory.Exists(s_dirAbsolutePath));
Assert.IsTrue(s_directoryOperations.IsDirectorySafe(s_dirAbsolutePath));
}

[Test]
[Platform(Exclude = "Win")]
public void TestOwnerIsCurrentUser()
{
// arrange
Expand All @@ -83,7 +70,6 @@ public void TestOwnerIsCurrentUser()
}

[Test]
[Platform(Exclude = "Win")]
public void TestOwnerIsNotCurrentUser()
{
// arrange
Expand All @@ -95,7 +81,6 @@ public void TestOwnerIsNotCurrentUser()
}

[Test]
[Platform(Exclude = "Win")]
public void TestDirectoryIsNotSecureWhenNotOwnedByCurrentUser()
{
// arrange
Expand All @@ -121,3 +106,4 @@ public static IEnumerable<FileAccessPermissions> InsecurePermissions()
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.IO;
using NUnit.Framework;
using Snowflake.Data.Core.Tools;

namespace Snowflake.Data.Tests.UnitTests.Tools
{
[TestFixture, NonParallelizable]
[Platform("Win")]
public class DirectoryOperationsWindowsTest
{
private static DirectoryOperations s_directoryOperations;
private static readonly string s_relativeWorkingDirectory = $"directory_operations_test_{Path.GetRandomFileName()}";
private static readonly string s_workingDirectory = Path.Combine(TempUtil.GetTempPath(), s_relativeWorkingDirectory);
private static readonly string s_dirName = "testdir";

[SetUp]
public static void Before()
{
if (!Directory.Exists(s_workingDirectory))
{
Directory.CreateDirectory(s_workingDirectory);
}

s_directoryOperations = new DirectoryOperations();
}

[TearDown]
public static void After()
{
Directory.Delete(s_workingDirectory, true);
}

[Test]
public void TestDirectoryIsSafeOnWindows()
{
// arrange
var absoluteFilePath = Path.Combine(s_workingDirectory, s_dirName);
Directory.CreateDirectory(absoluteFilePath);

// act and assert
Assert.IsTrue(s_directoryOperations.IsDirectorySafe(absoluteFilePath));
}

[Test]
public void TestShouldCreateDirectoryWithSafePermissions()
{
// arrange
var dirAbsolutePath = Path.Combine(s_workingDirectory, s_dirName);

// act
s_directoryOperations.CreateDirectory(dirAbsolutePath);

// assert
Assert.IsTrue(Directory.Exists(dirAbsolutePath));
Assert.IsTrue(s_directoryOperations.IsDirectorySafe(dirAbsolutePath));
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace Snowflake.Data.Tests.UnitTests.Tools
{
[TestFixture]
[Platform(Exclude = "Win")]
public class DirectoryUnixInformationTest
{
private const long UserId = 5;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using Mono.Unix;
using Mono.Unix.Native;
Expand All @@ -12,7 +13,8 @@
namespace Snowflake.Data.Tests.UnitTests.Tools
{
[TestFixture, NonParallelizable]
public class FileOperationsTest
[Platform(Exclude = "Win")]
public class FileOperationsUnixTest
{
private static FileOperations s_fileOperations;
private static readonly string s_relativeWorkingDirectory = $"file_operations_test_{Path.GetRandomFileName()}";
Expand All @@ -23,6 +25,11 @@ public class FileOperationsTest
[SetUp]
public static void Before()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Ignore("Unix-specific tests are not run on Windows");
}

if (!Directory.Exists(s_workingDirectory))
{
Directory.CreateDirectory(s_workingDirectory);
Expand All @@ -34,24 +41,15 @@ public static void Before()
[TearDown]
public static void After()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return;
}

Directory.Delete(s_workingDirectory, true);
}

[Test]
[Platform("Win")]
public void TestReadAllTextOnWindows()
{
var filePath = CreateConfigTempFile(s_workingDirectory, s_content);

// act
var result = s_fileOperations.ReadAllText(filePath, TomlConnectionBuilder.ValidateFilePermissions);

// assert
Assert.AreEqual(s_content, result);
}

[Test]
[Platform(Exclude = "Win")]
public void TestReadAllTextCheckingPermissionsUsingTomlConfigurationFileValidations(
[ValueSource(nameof(UserAllowedFilePermissions))]
FileAccessPermissions userAllowedFilePermissions)
Expand All @@ -69,7 +67,6 @@ public void TestReadAllTextCheckingPermissionsUsingTomlConfigurationFileValidati
}

[Test]
[Platform(Exclude = "Win")]
public void TestShouldThrowExceptionIfOtherPermissionsIsSetWhenReadConfigurationFile(
[ValueSource(nameof(UserAllowedFilePermissions))]
FileAccessPermissions userAllowedFilePermissions)
Expand All @@ -86,7 +83,6 @@ public void TestShouldThrowExceptionIfOtherPermissionsIsSetWhenReadConfiguration


[Test]
[Platform(Exclude = "Win")]
public void TestFileIsSafeOnNotWindows()
{
// arrange
Expand All @@ -98,7 +94,6 @@ public void TestFileIsSafeOnNotWindows()
}

[Test]
[Platform(Exclude = "Win")]
public void TestFileIsNotSafeOnNotWindowsWhenTooBroadPermissionsAreUsed(
[ValueSource(nameof(InsecurePermissions))]
FileAccessPermissions permissions)
Expand All @@ -112,19 +107,6 @@ public void TestFileIsNotSafeOnNotWindowsWhenTooBroadPermissionsAreUsed(
}

[Test]
[Platform("Win")]
public void TestFileIsSafeOnWindows()
{
// arrange
var absoluteFilePath = Path.Combine(s_workingDirectory, s_fileName);
File.Create(absoluteFilePath).Close();

// act and assert
Assert.IsTrue(s_fileOperations.IsFileSafe(absoluteFilePath));
}

[Test]
[Platform(Exclude = "Win")]
public void TestOwnerIsCurrentUser()
{
// arrange
Expand All @@ -137,7 +119,6 @@ public void TestOwnerIsCurrentUser()
}

[Test]
[Platform(Exclude = "Win")]
public void TestOwnerIsNotCurrentUser()
{
// arrange
Expand All @@ -150,7 +131,6 @@ public void TestOwnerIsNotCurrentUser()
}

[Test]
[Platform(Exclude = "Win")]
public void TestFileIsNotSecureWhenNotOwnedByCurrentUser()
{
// arrange
Expand All @@ -171,7 +151,6 @@ public void TestFileIsNotSecureWhenNotOwnedByCurrentUser()
}

[Test]
[Platform(Exclude = "Win")]
public void TestFileCopyUsesProperPermissions()
{
// arrange
Expand All @@ -193,7 +172,6 @@ public void TestFileCopyUsesProperPermissions()
}

[Test]
[Platform(Exclude = "Win")]
public void TestFileCopyShouldThrowExecptionIfTooBroadPermissionsAreUsed()
{
// arrange
Expand Down Expand Up @@ -232,3 +210,4 @@ public static IEnumerable<FileAccessPermissions> InsecurePermissions()
}
}
}

Loading
Loading