xunit icon indicating copy to clipboard operation
xunit copied to clipboard

XUnit and MSTest returnig different values. Why? Is this a bug?

Open alexmbra opened this issue 1 year ago • 6 comments

public static string DecryptString(string cipherText)
        {
            byte[] initVectorBytes = Encoding.UTF8.GetBytes(InitVector);
            byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
            PasswordDeriveBytes password = new PasswordDeriveBytes(StrEncriptyPass, null);
            byte[] keyBytes = password.GetBytes(Keysize / 8);
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
            memoryStream.Close();
            cryptoStream.Close();

            string result = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);

            return result;
        }

Using MSTest it works fine and the decryptedActual variable gets this value: "Testando encriptação".

[TestMethod()]
        public void DecryptStringTest_DecryptString_ReturnsEqual()
        {
            var decryptedActual = DecryptString("r2AegGm+zAYmaRL4i+62O2IJrhcHyPsWxHoDZ7bMimI=");
            var esperado = "Testando encriptação";

            Assert.AreEqual(decryptedActual, esperado);
        }

But if I use XUnit, it does not retun the same result. The decryptedActual variable gets this value: "Testando encript". It is missing "ação" from the decripted string.

[Fact]
        public void DecryptStringTest_DecryptString_ReturnsEqual()
        {
            var decryptedActual = DecryptString("r2AegGm+zAYmaRL4i+62O2IJrhcHyPsWxHoDZ7bMimI=");
            var esperado = "Testando encriptação";

            Assert.Equal(decryptedActual, esperado);
        }

While debbuging I found that this line of code...

byte[] plainTextBytes = new byte[cipherTextBytes.Length];

is the one returning different values with XUnit, but why? cipherTextBytes.Length returns 32, but plainTextBytes gets filled only until index 15 with XUnit and until 21 with STest, as we can see on the images: XUnit MSTest Somehow XUnit is affecting the way that function is working.

alexmbra avatar Aug 27 '22 13:08 alexmbra

Could you please provide a full example, since your code misses: InitVector, StrEncriptyPass and Keysize

trivalik avatar Sep 05 '22 06:09 trivalik

Xunit does not instrument your code in any way (neither does MSTest).

The issue is likely environmental in nature - either you have code that's sensitive to locale settings, or platform (x84/x86, dotnet version and/or bittedness).

There's also a small possibility of some encoding issues if these are in different files (but the texts cipherText does look identical above)

I'd suggest logging a full repro in Stackoverflow as the quickest way to get this resolved - there's not much point in logging blocks of code that don't reproduce the issue in here until you're at the point where you've proven that the problem is down

bartelink avatar Sep 05 '22 14:09 bartelink

The issue is likely environmental in nature

How would that be possible? I created a test with MSTest, run it and it worked fine. Right after I installed xunit, changed the test to Xunit instead of MStest, and got different results. Nothing was changed between changing MSTest to Xunit.

There's also a small possibility of some encoding issues if these are in different files.

The files are the same.

I'd suggest logging a full repro in Stackoverflow as the quickest way to get this resolved.

Thanks but I cannot do that.

alexmbra avatar Sep 12 '22 00:09 alexmbra

Could you please provide a full example, since your code misses: InitVector, StrEncriptyPass and Keysize

Keysize= 256. InitVector is a 16 character string and as StrEncriptyPass it can be text with that size.

alexmbra avatar Sep 12 '22 00:09 alexmbra

Thanks but I cannot do that.

It does not mean that you should make public all source code just the unit tests related. Means create a new git repository with just required.

trivalik avatar Sep 12 '22 05:09 trivalik

How would that be possible?

either you have code that's sensitive to locale settings, or platform (x84/x86, dotnet version and/or bittedness).

The bottom line is that xUnit is called by the test runner, and then it calls your code. It does not modify the IL or do any other tricks.

... and it's extremely unlikely that this is an xUnit issue

It's also extremely unlikely that the number of readers of this issue will get out of double figures here, especially when there is no repro, so doing a minimal test repo and/or narrowing the problem down is the way to go

bartelink avatar Sep 12 '22 07:09 bartelink

Without a repro it's hard to know exactly what's going on here, but if you're using .NET Framework (as opposed to .NET Core/.NET 5+), then my suspicion is that it has to do with the fact that the two tests are being run via different back-compat flags that cause .NET Framework itself to behave differently. One thing to check would be to make sure both are being compiled against the same target framework (for example, ensure both are net48).

bradwilson avatar Oct 16 '22 19:10 bradwilson

Please re-open with a repro project. Thanks!

bradwilson avatar Jan 22 '23 23:01 bradwilson