-
Notifications
You must be signed in to change notification settings - Fork 324
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
Aborting test run when source and target frameworks/architectures are incompatible #1789
Aborting test run when source and target frameworks/architectures are incompatible #1789
Conversation
@dotnet-bot Test this again. |
fe61db5
to
0a8e968
Compare
@dotnet-bot test this please |
@@ -718,4 +718,7 @@ | |||
<data name="InvalidLoggerArgument" xml:space="preserve"> | |||
<value>Logger argument '{0}' is not valid.</value> | |||
</data> | |||
<data name="ConflictInFrameworkPlatform" xml:space="preserve"> | |||
<value>Conflicts in framework/platform identifier of provided sources.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change this to a more actionable message.
Suggestion:
"The given test sources target multiple frameworks/platforms that are incompatible. Please make sure the sources target the same framework and platform"
@PBoraMSFT @pvlakshm Can you please approve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PBoraMSFT @pvlakshm Is this message "The given test sources target multiple frameworks/platforms that are incompatible. Please make sure the sources target the same framework and platform" okay?
…getingDifferentFrameworks
Test run was aborted as the specified framework / platform {fx-value/plat-value} is incompatible with the target framework / platform of the test assemblies {fx-value/plat-value}. Ensure that the target framework and platform of the test assemblies match the specified value. |
// Update frmaework and platform if required. For commandline scenario update happens in ArgumentProcessor. | ||
if (isFrameworkIncompatible || isPlatformIncompatible) | ||
{ | ||
throw new TestPlatformException(Resources.ConflictInFrameworkPlatform); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have separate messages? It just makes it clear which exactly caused the failure #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the message in the description #Resolved
@@ -612,18 +612,21 @@ public static bool TryGetFrameworkXml(XPathNavigator runSettingsNavigator, out s | |||
/// Returns the sources matching the specified platform and framework settings. | |||
/// For incompatible sources, warning is added to incompatibleSettingWarning. | |||
/// </summary> | |||
public static IEnumerable<String> FilterCompatibleSources(Architecture chosenPlatform, Framework chosenFramework, IDictionary<String, Architecture> sourcePlatforms, IDictionary<String, Framework> sourceFrameworks, out String incompatibleSettingWarning) | |||
public static IEnumerable<String> FilterCompatibleSources(Architecture chosenPlatform, Framework chosenFramework, IDictionary<String, Architecture> sourcePlatforms, IDictionary<String, Framework> sourceFrameworks, out String incompatibleSettingWarning, out bool incompatibilityErrorFound) | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid multiple outs ?
It just makes it unreadable and confusing.
Ideally, we should change this method to TryFilterCompatibleSources or Throw an exception and catch it in the caller. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One way is to leave this method as it is and using public static bool TryGetSettingIncompatibility(Architecture chosenPlatform, Framework chosenFramework, IDictionary<String, Architecture> sourcePlatforms, IDictionary<String, Framework> sourceFrameworks)
to return if there is any incompatility found. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Split it into two functions as suggested TryGetSettingIncompatibility(Architecture chosenPlatform, Framework chosenFramework, IDictionary<String, Architecture> sourcePlatforms, IDictionary<String, Framework> sourceFrameworks)
#Resolved
/// </summary> | ||
private static bool IsPlatformArchitectureIncompatible(Architecture sourcePlatform, Architecture targetPlatform) | ||
{ | ||
if (sourcePlatform == Architecture.X86 && targetPlatform == Architecture.X64 || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we check not equals for source and target platform? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are different platforms(X86, X64, ARM, AnyCPU)
If we simply check for not equals, any of the incompatibility will be marked as true.
This might cause unnecessary incompatibility. For example source = Architecture.X64
is okay to run with target = Architecture.AnyCPU
.
Do we want to change that behavior? #Resolved
string sourceFrameworkName = sourceFramework.Name.Split(',')[0]; | ||
string targetFrameworkName = targetFramework.Name.Split(',')[0]; | ||
|
||
if(sourceFrameworkName.Equals(".NETFramework",StringComparison.OrdinalIgnoreCase) && targetFrameworkName.Equals(".NETCoreApp", StringComparison.OrdinalIgnoreCase) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when we have NetStandard ? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NetStandard will have no incompatibility with any of the other frameworks(NETFrameworks and NETCore).
Should it fail with NETStandard as well? #Resolved
@@ -363,12 +363,17 @@ private bool UpdateRunSettingsIfRequired(string runsettingsXml, List<string> sou | |||
|
|||
var navigator = document.CreateNavigator(); | |||
|
|||
var inferedFramework = inferHelper.AutoDetectFramework(sources, sourceFrameworks); | |||
var inferedFramework = inferHelper.AutoDetectFramework(sources, sourceFrameworks, out var isFrameworkIncompatible); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TryGetCompatibleFramework, and return true/false based on the detection #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Inferred #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How should be the method signature?
Current : public Framework AutoDetectFramework(List<string> sources, IDictionary<string, Framework> sourceFrameworkVersions, out bool isFrameworkIncompatible)
Possible public bool TryGetCompatibleFramework(List<string> sources, IDictionary<string, Framework> sourceFrameworkVersions, out Framework inferredFramework)
Shall I make this change? This was done to use the previous method signature as it is. #Resolved
@@ -767,10 +768,82 @@ public void DiscoverTestsShouldNotUpdateFrameworkAndPlatformInCommandLineScenari | |||
this.mockAssemblyMetadataProvider.Verify(a => a.GetArchitecture(It.IsAny<string>()), Times.Once); | |||
this.mockAssemblyMetadataProvider.Verify(a => a.GetFrameWork(It.IsAny<string>()), Times.Once); | |||
|
|||
Assert.IsFalse(actualDiscoveryCriteria.RunSettings.Contains(Constants.DotNetFramework46)); | |||
Assert.IsFalse(actualDiscoveryCriteria.RunSettings.Contains("Framework")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make this check more strong ?
…getingDifferentFrameworks
9bf652d
to
92fe52c
Compare
@@ -649,9 +649,25 @@ public static IEnumerable<String> FilterCompatibleSources(Architecture chosenPla | |||
} | |||
|
|||
/// <summary> | |||
/// Returns true if source settings are incomaptible with target settings. | |||
/// Returns true if framework runtime of target framework is incompatible with any source framework |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "framework runtime of target framework" imply ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The term runtime is removed. Basically wanted to distinguish if tw frameworks are different in terms that one is framework and the other is core (version not making any difference)
/// </summary> | ||
private static bool IsSettingIncompatible(Architecture sourcePlatform, | ||
public static bool TryGetSettingIncompatibility(Architecture chosenPlatform, Framework chosenFramework, IDictionary<String, Architecture> sourcePlatforms, IDictionary<String, Framework> sourceFrameworks) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method signature, TryGet* implies it has an out, out of the Incompatibility.
If we are simply returning the bool, why not IsSettingIncompatible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done #Resolved
@@ -685,5 +701,21 @@ private static bool IsFrameworkIncompatible(Framework sourceFramework, Framework | |||
} | |||
return !sourceFramework.Name.Equals(targetFramework.Name, StringComparison.OrdinalIgnoreCase); | |||
} | |||
|
|||
/// <summary> | |||
/// Returns true if source Framework Runtime is incompatible with target Framework. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Framework and runtime are two different concepts.
Let's just call it Framework.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed
@@ -121,7 +121,7 @@ | |||
<value>The parameter cannot be null or empty.</value> | |||
</data> | |||
<data name="DisplayChosenSettings" xml:space="preserve"> | |||
<value>Test run will use DLL(s) built for framework {0} and platform {1}. Following DLL(s) do not match framework/platform settings.{2}Go to {3} for more details on managing these settings. | |||
<value>The specified framework {0} and platform {1} is incompatible with the target framework/platform of test assemblies. Following DLL(s) do not match framework/platform settings.{2}Ensure that the target framework and platform of the test assemblies match the specified value. Go to {3} for more details on managing these settings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some redundancies and message looks very big.
How about. "The following DLL(s) do not match the specified framework {0} and platform {1} settings.{2}Ensure sure the test assemblies target the specified framework/platform settings. Go to {3} for more details on managing these settings."
/cc: @PBoraMSFT #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Message updated #Resolved
…getingDifferentFrameworks
b52f4b3
to
d7057e2
Compare
@mayankbansal018 Can you please review? |
string sourceFrameworkName = actualFramework.Name.Split(',')[0]; | ||
string targetFrameworkName = chosenFramework.Name.Split(',')[0]; | ||
|
||
if (sourceFrameworkName.Equals(".NETFramework", StringComparison.OrdinalIgnoreCase) && targetFrameworkName.Equals(".NETCoreApp", StringComparison.OrdinalIgnoreCase) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NETFramework [](start = 49, length = 12)
Make these strings as constants
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
{ | ||
return IsPlatformIncompatible(sourcePlatform, targetPlatform) || IsFrameworkIncompatible(sourceFramework, targetFramework); | ||
var res = IsPlatformIncompatible(sourcePlatform, targetPlatform) || IsFrameworkIncompatible(sourceFramework, targetFramework); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: no change needed #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restructured this code. IsSettingIncompatible
is directly inferring platform/frameworks incompatibility without calling anything else #Resolved
/// Returns true if source settings are incomaptible with target settings. | ||
/// Returns true if target framework is incompatible with any source framework, that is run needs to be aborted | ||
/// </summary> | ||
public static bool IsFrameworkIncompatible(Framework chosenFramework, IDictionary<String, Framework> sourceFrameworks) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public static bool IsFrameworkInc [](start = 8, length = 33)
nit: please move above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
/// Returns true if source settings are incomaptible with target settings. | ||
/// Returns true if target framework is incompatible with any source framework, that is run needs to be aborted | ||
/// </summary> | ||
public static bool IsFrameworkIncompatible(Framework chosenFramework, IDictionary<String, Framework> sourceFrameworks) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public static bool IsFrameworkIncompatibl [](start = 8, length = 41)
do we actually need this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need this to determine if the frameworks(full vs core scenario is happening), hence needing to be aborted. Restructured the other IsFrameworkIncompatible
/// </summary> | ||
public Architecture AutoDetectArchitecture(List<string> sources, IDictionary<string, Architecture> sourcePlatforms) | ||
public bool TryGetCompatibleArchitecture(List<string> sources, IDictionary<string, Architecture> sourcePlatforms, out Architecture inferredArchitecture) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This functions is still auto detecting Fx, please rename it accordingly. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to TryGetAutoDetectCompatibleArcitecture
and TryGetAutoDetectCompatibleFramework
#Resolved
@dotnet-bot test TestPlatform.PR please |
@dotnet-bot Test this please |
…isha-nidhi/vstest into TargetingDifferentFrameworks
…isha-nidhi/vstest into TargetingDifferentFrameworks
isFrameworkInCompatible = isFrameworkInCompatible || !actualFramework.Name.Equals(targetFramework.Name, StringComparison.OrdinalIgnoreCase); | ||
} | ||
|
||
string sourceFrameworkName = actualFramework.Name.Split(',')[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are checking with version, then we don't need to follow up on w/o version comparison
string sourceFrameworkName = actualFramework.Name.Split(',')[0]; | ||
string targetFrameworkName = targetFramework.Name.Split(',')[0]; | ||
|
||
if (sourceFrameworkName.Equals(DotNetFrameworkString, StringComparison.OrdinalIgnoreCase) && targetFrameworkName.Equals(DotNetCoreString, StringComparison.OrdinalIgnoreCase) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DotNetFrameworkString [](start = 47, length = 21)
Lets keep the framework comparison logic same as above, we shouldn't have to compare them with Const strings, & mark them as incompatible.
…getingDifferentFrameworks
…isha-nidhi/vstest into TargetingDifferentFrameworks
This error ("The given test sources target multiple frameworks/platforms that are incompatible. Please make sure the sources target the same framework and platform.") now throws when running tests where the the tested method is in a .NET Framework project which references a .NET Standard project (not the other way around). This occurs in on Azure DevOps, with latest version (=16.0.0) of "Visual Studio Test Platform Installer" |
…ures are incompatible (microsoft#1789)" This reverts commit 37678c4.
Description
Discrepancy in test state with actual/target framework/platform settings
Current Scenario :
Dll given : NETFramework 4.5
Target framework specified by the user : NetCoreApp
The vstest fails with unactionable message on what went wrong :
After change :
If two dlls of different frameworks/architectures are provided
Example : NetCoreApp 2.0 and NetFramework 4.6.1, the error message before change was
In case of platform, when both x64 & x86 DLL is passed x64 dll is ignored, therefore we are throwing exception in this case as well.
After change :
Same messages are displayed with architecture incompatibility.
Related issue
#1729