I have code that calculates the SHA256 integrity hash of a file from the web. For example, the integrity hash of jquery-3.7.1.min.js is /JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo= (source). I have some units tests to test the code, and that always worked fine. Now, I thinks since .NET 9, the tests fail on my Windows machine. In Github actions (Linux) these test still work fine. This is a simplified version of the code:
[Fact]
public void Test()
{
// Arrange
const string Expected = "/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=";
var fileContents = TestResources.GetFileContents("MyTests.Resources.jquery-3.7.1.min.js"); // read from embedded resource
var sha256Hasher = SHA256.Create();
// Act
var byteResult = sha256Hasher.ComputeHash(Encoding.UTF8.GetBytes(fileContents));
// Assert
var result = Convert.ToBase64String(byteResult);
result.Should().Be(Expected);
/*
Expected result to be the same string, but they differ at index 0:
↓ (actual)
"eqaw4I9IoPldjffqieTL…"
"/JqT3SQfawRcv/BIHPTh…"
↑ (expected).
*/
}
public static string GetFileContents(string filename)
{
var assembly = typeof(TestResources).GetTypeInfo().Assembly;
using var resource = assembly.GetManifestResourceStream(filename);
using var reader = new StreamReader(resource!);
var result = reader.ReadToEnd();
return result;
}
When I rewrite the test to fetch the actual CDN url, it works fine:
[Fact]
public async Task TestWithStream()
{
// Arrange
const string Expected = "/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=";
var httpClient = new HttpClient();
using var stream = await httpClient.GetStreamAsync(new Uri("https://code.jquery.com/jquery-3.7.1.min.js"));
var sha256Hasher = SHA256.Create();
// Act
var byteResult = sha256Hasher.ComputeHash(stream);
// Assert
var result = Convert.ToBase64String(byteResult);
result.Should().Be(Expected); // test passed!
}
This is not the situation I want in a unit test because it now depends on an external resource and internet access. So I think it might has something to do with encoding, how the resource is stored on disk, etc. But everything I try doesn't give the right result. Any ideas?
The issue here is with the line endings. I ran the same code but when I used CRLF line endings, I got the Hash eqaw4I9IoPldjffqieTL/h7z0ejA9zc/fyXt+05KMl4=.
As Jon Skeet mentioned, this is likely because you have autocrlf=true on your Git Repo.
You can either disable this (you may need to re-commit a new version of the jQuery.-3.7.1.min.js file, I am not too sure).
An alternate solution is to force fileContents to use LF line endings. The below code will achieve that :
var fileContents = TestResources.GetFileContents("MyTests.Resources.jquery-3.7.1.min.js").Replace("\r\n", "\n").Replace("\r", "\n");
This will ensure that fileContents is normalized to use LF Line endings.
I hope this helps, I am new to posting on StackOverflow so just trying to get the hang of it at the moment!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With