-
-
Notifications
You must be signed in to change notification settings - Fork 211
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
feat: Enumerate all .NET Framework installations #572
feat: Enumerate all .NET Framework installations #572
Conversation
Codecov Report
@@ Coverage Diff @@
## main #572 +/- ##
==========================================
+ Coverage 62.88% 63.04% +0.15%
==========================================
Files 176 179 +3
Lines 4985 5019 +34
Branches 854 861 +7
==========================================
+ Hits 3135 3164 +29
- Misses 1624 1627 +3
- Partials 226 228 +2
Continue to review full report at Codecov.
|
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.
Looking nice! Got a screenshot of what it looks like in Sentry?
internal static readonly string NetFxInstallationsKey = ".NET Framework"; | ||
|
||
private readonly Lazy<IEnumerable<FrameworkInstallation>> _netFxInstallations = | ||
new Lazy<IEnumerable<FrameworkInstallation>>(() => FrameworkInfo.GetInstallations()); |
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.
You need to consider multiple threads will capture events concurrently.
Use ExecutionAndPublication here.
Another point is error handling. You need to make sure an exception thrown in Lazy
ctor doesn't crash the whole process (or in this case since we'd handle it in the SDK, drop the whole event).
As stated earlier, a Lazy<T> object always returns the same object or value that it was initialized with, and therefore the Value property is read-only. If you enable exception caching, this immutability also extends to exception behavior. If a lazy-initialized object has exception caching enabled and throws an exception from its initialization method when the Value property is first accessed, that same exception is thrown on every subsequent attempt to access the Value property
We need to enable such caching, and when trying to access Value
do that under a try catch.
If an exception is thrown, log that with options.DiagnosticLogger?.LogError
and flip a flag in the object (a field) so that you don't try to access Value
again. From that point a LogDebug
is enough just to note that we skipped the integration.
} | ||
|
||
[Fact] | ||
public void Process_NetFxInstallationsKeyExist_UnchangedSentryEvent() |
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 a test that verifies we can actually add something to the context. Maybe call FrameworkInfo.GetInstallations()
and assert the items are there.
Ideally another that we can serialize the contexts
once you add the items to that list.
Also check if it returns anything because this code will run on Mono on Linux for example and there's no .NET Framework there |
|
Yeah, the test is failing because of that :c |
src/Sentry/PlatformAbstractions/FrameworkInstallationExtensions.cs
Outdated
Show resolved
Hide resolved
src/Sentry/PlatformAbstractions/NetFxInstallationsEventProcessor.cs
Outdated
Show resolved
Hide resolved
src/Sentry/PlatformAbstractions/NetFxInstallationsEventProcessor.cs
Outdated
Show resolved
Hide resolved
{ | ||
var versionsDictionary = new Dictionary<string, string>(); | ||
var installations = FrameworkInfo.GetInstallations(); | ||
foreach (var profile in installations.Select(p => p.Profile).Distinct()) |
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.
Why Distinct
here? Isn't this going to work on the object references?
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 goal of distinct is to avoid repeating keys to be inserted into the Dictionary and the foreach loop will then group the releases by profiles.
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.
But you're doing Distinct
on a reference type so unless GetHashCode
and Equals
was overriden, it will dedupe on the reference.
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.
Confirmed offline that it fails with dupe key in Map otherwise
src/Sentry/PlatformAbstractions/NetFxInstallationsEventProcessor.cs
Outdated
Show resolved
Hide resolved
test/Sentry.Tests/PlatformAbstractions/FrameworkInstallationExtensionsTests.cs
Outdated
Show resolved
Hide resolved
test/Sentry.Tests/PlatformAbstractions/FrameworkInstallationExtensionsTests.cs
Outdated
Show resolved
Hide 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.
LGTM. Just clarifying if that Distinct
does something or not
src/Sentry/PlatformAbstractions/FrameworkInstallationExtensions.cs
Outdated
Show resolved
Hide resolved
{ | ||
var versionsDictionary = new Dictionary<string, string>(); | ||
var installations = FrameworkInfo.GetInstallations(); | ||
foreach (var profile in installations.Select(p => p.Profile).Distinct()) |
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.
But you're doing Distinct
on a reference type so unless GetHashCode
and Equals
was overriden, it will dedupe on the reference.
@@ -103,7 +103,7 @@ public static IEnumerable<FrameworkInstallation> GetInstallations() | |||
if (version != null && versionKey.GetInt("Install") == 1) | |||
{ | |||
// 1.0 to 3.5 | |||
Version.TryParse(version, out var parsed); | |||
_ = Version.TryParse(version, out var parsed); |
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.
Is this some sort of analyzer we have that warns about this? I don't see it on my end and I'd say adding those _
makes things more noisy.
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.
I get the warnings too. Visual Studio
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.
Closes #531
When running a .NET Application, Sentry will add a list of installed .NET Frameworks with the events.
The operation can be opted-out.