Skip to content

CSHARP-4400: Upgrade xunit to 2.4.2 #935

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 12, 2022
Merged

Conversation

BorisDog
Copy link
Contributor

@BorisDog BorisDog commented Nov 7, 2022

SkippableTests removed

@BorisDog BorisDog requested a review from JamesKovacs November 7, 2022 15:37
CSharpDriver.sln Outdated
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30011.22
# Visual Studio Version 17
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good opportunity to update VS version as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CSharpDriver.sln Outdated
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongoDB.Driver.TestConsoleApplication", "tests\MongoDB.Driver.TestConsoleApplication\MongoDB.Driver.TestConsoleApplication.csproj", "{2E5780D2-29A5-483C-9CA2-844F45A66D0C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AstrolabeWorkloadExecutor", "tests\AstrolabeWorkloadExecutor\AstrolabeWorkloadExecutor.csproj", "{B90F025F-89D3-436A-AD78-6AA304A6E240}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoDB.Driver.SmokeTests.Sdk", "tests\SmokeTests\MongoDB.Driver.SmokeTests.Sdk\MongoDB.Driver.SmokeTests.Sdk.csproj", "{B711A69F-A337-452C-95E1-A6B15C727CBA}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongoDB.Driver.SmokeTests.Sdk", "tests\SmokeTests\MongoDB.Driver.SmokeTests.Sdk\MongoDB.Driver.SmokeTests.Sdk.csproj", "{B711A69F-A337-452C-95E1-A6B15C727CBA}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw this diff too, but didn't really understand why it exists and just ignored it

@JamesKovacs JamesKovacs requested review from DmitryLukyanov and removed request for JamesKovacs November 7, 2022 22:49
Copy link
Contributor

@DmitryLukyanov DmitryLukyanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question and then LGTM

@@ -26,7 +26,7 @@ namespace MongoDB.Driver.Core.TestHelpers.XunitExtensions.TimeoutEnforcing
[DebuggerStepThrough]
internal sealed class TimeoutEnforcingXunitTestMethodRunner : XunitTestMethodRunner
{
private static string[] __skippingExceptionNames = new string[] { typeof(SkipException).FullName };
private static string[] __skippingExceptionNames = new string[] { typeof(Xunit.SkipException).FullName };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To distinguish from Xunit.Sdk.SkipException that was introduced in 2.4.2. (we use Xunit.SkipException from Xunit.SkippableFact package).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If xUnit now has SkipException why do we still need the SkippableFact nuget package?

Copy link
Contributor Author

@BorisDog BorisDog Nov 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question.
That was my line of thought as well, and I even removed SkippableFact nuget package. Only to discover that raising Xunit.Sdk.SkipException marks test as failed and not skipped.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe xUnit now has a different way than [SkippableFact] to mark a test as skippable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not find any. The only way I found is to specify Skip reason in the Fact attribute.
Also SkipException is not referenced anywhere directly in xunit main repository (defined xunit/asserts), so looks like there is not special handling for it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I even can't create Sdk.SkipException (ie I don't see it from the code). Do you observe different behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, new Xunit.Sdk.SkipException(...) works.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I didn't see this class until I remove all bin/obj folders

@@ -47,6 +46,7 @@
using Xunit.Abstractions;
using Xunit.Sdk;
using Reflector = MongoDB.Bson.TestHelpers.Reflector;
using SkipException = Xunit.SkipException;
Copy link
Contributor

@DmitryLukyanov DmitryLukyanov Nov 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if SDK.SkipException is possible to create (see my another comment) and we support only the previous exception version, I would prefer to stick to the version where we don't have 2 different exceptions for the same goal. Ie we won't need to worry about such change each time when we want to throw SkipException. Can you remind me why we want this xunit upgrading?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We just need to Xunit.SkipException exception which is defined in Xunit.SkippableFact .
The goal is to better support generics, and looks like there are few bugs fixes in past two years.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think that the existence of TWO versions of SkipException is a problem. At the very least it's confusing. More likely it's a sign that there is duplicate functionality and we should be able to drop our dependency on the SkippableFact nuget package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, I've investigated the possibility for dropping SkippableFact package. I have not been able to find the matching functionality in any V2 version of xUnit. I'll happy to be mistaken here.
I don't think it's a real problem, as we very rarely use SkipException directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need to spend more time on this. I think it's clear that a new SkipException should be used somehow, it's definitely not added just to confuse people. Maybe it's something about this directive https://github.com/xunit/assert.xunit/blob/b78867e1aa4b2aa255b5dfc577f6014812445adb/Sdk/Exceptions/SkipException.cs#L10 that can be configured via csproj..

Copy link
Contributor

@DmitryLukyanov DmitryLukyanov Nov 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so it's not relevant for us.

you're right, we're working with complied binaries.

TimeoutEnforcingXunitTestMethodRunner. So that area will require some attention.

that was my main concern initially, so not sure how easy it will be

We can do this investigation in a follow up ticket.

How much urgent this change now? I would say not really and there is no rush with pushing these changes now. @rstam what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are two unrelated issues here:

  1. Enabling generics in tests with this PR
  2. Removing SkippableFact package (which from my research can't be done yet)

I think we can safely and easily achieve the original goal of this PR and deal with the second improvement when needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I see, Enabling generics in tests with this PR is not too urgent issue to introduce code weirdness. We can simply wait until we will figure out the right and not confusing way to do it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My estimation is that we will be able to remove the SkippableFact only when upgrading to v3 xUnit or other testing framework.
Having generics support now would be quite convenient, while code weirdness will be practically unnoticed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Xunit.Sdk.SkipException as skippable exception as well. Now either exception will skip the test.

Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While these changes make sense and clean up the project quite nicely, something isn't quite right. If you look at the patch build, all base statuses of Skip are now Failed. Something isn't working correctly on Evergreen even if it is working locally.

<PackageReference Include="JunitXml.TestLogger" Version="2.1.81" />
<PackageReference Include="Xunit.SkippableFact" Version="1.4.13">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this change to the package reference. What does PrivateAssets do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hides this reference from dependent projects.
For example: otherwise SkippableFact will be available in MongoDB.Driver.Tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok. That makes sense.

So the only remaining question is why all the skipped tests are failing on Evergreen.

@BorisDog BorisDog requested a review from JamesKovacs November 24, 2022 16:36
@@ -0,0 +1,9 @@
using System;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no copyright

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/// <inheritdoc />
public bool QueueMessage(IMessageSinkMessage message)
{
var failed = message as TestFailed;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it a copy of xunit logic? if no, what the point in this class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is functionality implemented in Xunit.SkippableFact (not xUnit)
It allows to skip the test when SkipException is raised.

{
[DebuggerStepThrough]
internal sealed class TimeoutEnforcingTestInvoker : XunitTestInvoker
{
private struct YieldNoContextAwaitable
Copy link
Contributor

@DmitryLukyanov DmitryLukyanov Nov 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a big fan of copying this class from the driver, but probably effective change here is placing this helper on some common level which only temporary is Bson level, so is it correct that this logic will be moved from here with some later refactoring?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes exactly, moving the TaskHelpers was comlicated. Do you think there should be a comment for that in the code?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, comment would be good

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

@@ -28,7 +29,7 @@
namespace MongoDB.Driver.Core.TestHelpers.Logging
{
[DebuggerStepThrough]
public abstract class LoggableTestClass : IDisposable, ILoggingService
public abstract class LoggableTestClass : IDisposable, ILoggingService, ITestExceptionHandler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this change

@@ -1,8 +0,0 @@
namespace MongoDB.Driver.Core.TestHelpers.XunitExtensions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copyright :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this file.

@@ -613,7 +614,7 @@ internal static class MongoClientSettingsReflection
{
#pragma warning disable CS0618 // Type or member is obsolete
public static void _connectionModeSwitch(this MongoClientSettings obj, ConnectionModeSwitch connectionModeSwitch)
=> Reflector.SetFieldValue(obj, nameof(_connectionModeSwitch), connectionModeSwitch);
=> Bson.TestHelpers.Reflector.SetFieldValue(obj, nameof(_connectionModeSwitch), connectionModeSwitch);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move prefix to using (same in other places if any)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It conflicts with Xunit.Sdk.Refelector

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, can we use xunit.sdk reflector instead of our implementation? Probably unrelated to current changes question :)

Copy link
Contributor Author

@BorisDog BorisDog Nov 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it is quite different. Also I would not recommend increasing our dependency in such areas on test framework.

@DmitryLukyanov DmitryLukyanov self-requested a review November 30, 2022 13:39
Copy link
Contributor

@DmitryLukyanov DmitryLukyanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Assuming the rest comments are resolved.

Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions / minor changes...

@@ -56,10 +84,10 @@ protected override async Task<decimal> InvokeTestMethodAsync(object testClassIns
var timeoutMS = xUnitTestCase?.Timeout ?? 0;
var timeout = Debugger.IsAttached
? Timeout.InfiniteTimeSpan // allow more flexible debugging expirience
: timeoutMS <= 0 ? CoreTestConfiguration.DefaultTestTimeout : TimeSpan.FromMilliseconds(timeoutMS);
: timeoutMS <= 0 ? XunitExtensionsConsts.DefaultTestTimeout : TimeSpan.FromMilliseconds(timeoutMS);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be named XunitExtensionsConstants.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


using System;

namespace MongoDB.Bson.TestHelpers.XunitExtensions.TimeoutEnforcing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not liking that these test helpers - which have nothing to do with BSON - are in the MongoDB.Bson namespace. I realize that BSON is the lowest common denominator, but I wonder if we should create a MongoDB.TestHelpers project to contain code such as this. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this idea!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


namespace MongoDB.Bson.TestHelpers.XunitExtensions
{
public static class XunitExtensionsConsts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XunitExtensionsConstants to follow our naming conventions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@rstam rstam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks great!

I have one small suggestion. See what you think. If you don't agree with it I'm happy to LGTM as is. Let me know and re-request my review.

public static IDiscriminatorConvention _discriminatorConvention(this ObjectSerializer obj) => (IDiscriminatorConvention)Reflector.GetFieldValue(obj, nameof(_discriminatorConvention));
public static GuidRepresentation _guidRepresentation(this ObjectSerializer obj) => (GuidRepresentation)Reflector.GetFieldValue(obj, nameof(_guidRepresentation));
public static IDiscriminatorConvention _discriminatorConvention(this ObjectSerializer obj) => (IDiscriminatorConvention)TestHelpers.Reflector.GetFieldValue(obj, nameof(_discriminatorConvention));
public static GuidRepresentation _guidRepresentation(this ObjectSerializer obj) => (GuidRepresentation)TestHelpers.Reflector.GetFieldValue(obj, nameof(_guidRepresentation));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn you Xunit.Sdk.Reflector... :(

Consider putting this at the top of the file to disambiguate once:

using Reflector = MongoDB.Bson.TestHelpers.Reflector;

and the same in all other files where this happens.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the only other file where this happens is MongoClientJsonDrivenTestRunnerBase.cs

Copy link
Contributor

@DmitryLukyanov DmitryLukyanov Dec 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since we already target c# 10, we can try setting global using: https://www.c-sharpcorner.com/article/global-using-directive-in-c-sharp-102/ (not sure whether it works in the way we need here though)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure whether global using applies to the using Name = FullTypeName format.

Also not sure in general that we actually want global usings... I'd be pretty cautious about forcing a using statement into every single file. It would have to be a pretty limited set I would think.

I don't think the number of using statements in each file is a problem. It's not like we type them manually, Visual Studio adds them for us automatically (via Ctrl-.).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion! Done.
I agree that making Reflector a global using is not a trivial decision.

Copy link
Contributor

@rstam rstam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM I think?

You squashed and rebased and force pushed and I can no longer tell what changed since I last reviewed...

@BorisDog
Copy link
Contributor Author

LGTM I think?

You squashed and rebased and force pushed and I can no longer tell what changed since I last reviewed...

Yes sorry, I spent some time on rebasing beforehand and it was just easier that way. The only new changes are namespaces resolutions with master and using Reflector = MongoDB.Bson.TestHelpers.Reflector;

@BorisDog BorisDog merged commit 2d60145 into mongodb:master Dec 12, 2022
BorisDog added a commit to BorisDog/mongo-csharp-driver that referenced this pull request Dec 22, 2022
BorisDog added a commit to BorisDog/mongo-csharp-driver that referenced this pull request Jan 30, 2023
dnickless pushed a commit to dnickless/mongo-csharp-driver that referenced this pull request Aug 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants