-
Notifications
You must be signed in to change notification settings - Fork 1
V9.0.0/housekeeping and cuemon aid #11
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
Changes from all commits
2d12919
44d88fb
0d4e3ce
8677dd6
c50d29b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| // This file is used by Code Analysis to maintain SuppressMessage | ||
| // attributes that are applied to this project. | ||
| // Project-level suppressions either have no target or are given | ||
| // a specific target and scoped to a namespace, type, member, etc. | ||
|
|
||
| using System.Diagnostics.CodeAnalysis; | ||
|
|
||
| [assembly: SuppressMessage("Major Code Smell", "S3881:\"IDisposable\" should be implemented correctly", Justification = "This is a base class implementation of the IDisposable interface tailored to avoid wrong implementations.", Scope = "type", Target = "~T:Codebelt.Extensions.Xunit.Test")] |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,9 +9,8 @@ namespace Codebelt.Extensions.Xunit | |||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||
| /// Represents the base class from which all implementations of unit testing should derive. | ||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||
| /// <seealso cref="Disposable"/> | ||||||||||||||||||||||||||||||||||||||
| /// <seealso cref="ITestOutputHelper"/> | ||||||||||||||||||||||||||||||||||||||
| public abstract class Test : Disposable, ITest | ||||||||||||||||||||||||||||||||||||||
| public abstract class Test : ITest | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Explicitly implement IDisposable interface The Apply this diff to update the class declaration: -public abstract class Test : ITest
+public abstract class Test : ITest, IDisposable📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||
| /// Provides a way, with wildcard support, to determine if <paramref name="actual" /> matches <paramref name="expected" />. | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -71,10 +70,47 @@ protected Test(ITestOutputHelper output = null, Type callerType = null) | |||||||||||||||||||||||||||||||||||||
| protected bool HasTestOutput => TestOutput != null; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||
| /// Called when this object is being disposed by either <see cref="M:Cuemon.Disposable.Dispose" /> or <see cref="M:Cuemon.Disposable.Dispose(System.Boolean)" /> having <c>disposing</c> set to <c>true</c> and <see cref="P:Cuemon.Disposable.Disposed" /> is <c>false</c>. | ||||||||||||||||||||||||||||||||||||||
| /// Gets a value indicating whether this <see cref="Test"/> object is disposed. | ||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||
| protected override void OnDisposeManagedResources() | ||||||||||||||||||||||||||||||||||||||
| /// <value><c>true</c> if this <see cref="Test"/> object is disposed; otherwise, <c>false</c>.</value> | ||||||||||||||||||||||||||||||||||||||
| public bool Disposed { get; private set; } | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+73
to
+76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Update XML documentation for Disposed property The XML documentation for the Apply this diff to correct the comments: -/// Gets a value indicating whether this <see cref="Test"/> object is disposed.
+/// Gets a value indicating whether this object is disposed.
-/// <value><c>true</c> if this <see cref="Test"/> object is disposed; otherwise, <c>false</c>.</value>
+/// <value><c>true</c> if this object is disposed; otherwise, <c>false</c>.</value>📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||
| /// Called when this object is being disposed by either <see cref="Dispose()" /> or <see cref="Dispose(bool)" /> having <c>disposing</c> set to <c>true</c> and <see cref="Disposed" /> is <c>false</c>. | ||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||
| protected virtual void OnDisposeManagedResources() | ||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||
| /// Called when this object is being disposed by either <see cref="Dispose()"/> or <see cref="Dispose(bool)"/> and <see cref="Disposed"/> is <c>false</c>. | ||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||
| protected virtual void OnDisposeUnmanagedResources() | ||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||
| /// Releases all resources used by the <see cref="Test"/> object. | ||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+93
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Update XML documentation for Dispose methods The XML documentation for both Apply these diffs to correct the comments: For -/// Releases all resources used by the <see cref="Test"/> object.
+/// Releases all resources used by the object.For -/// Releases the unmanaged resources used by the <see cref="Test"/> object and optionally releases the managed resources.
+/// Releases the unmanaged resources used by the object and optionally releases the managed resources.Also applies to: 102-104 |
||||||||||||||||||||||||||||||||||||||
| public void Dispose() | ||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||
| Dispose(true); | ||||||||||||||||||||||||||||||||||||||
| GC.SuppressFinalize(this); | ||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Evaluate the necessity of calling Since the Apply this diff: Dispose(true);
-GC.SuppressFinalize(this);📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+95
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Remove unnecessary GC.SuppressFinalize call Since the Apply this diff to remove the unnecessary call: public void Dispose()
{
Dispose(true);
- GC.SuppressFinalize(this);
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||
| /// Releases the unmanaged resources used by the <see cref="Test"/> object and optionally releases the managed resources. | ||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||
| /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> | ||||||||||||||||||||||||||||||||||||||
| protected void Dispose(bool disposing) | ||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||
| if (Disposed) { return; } | ||||||||||||||||||||||||||||||||||||||
| if (disposing) | ||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||
| OnDisposeManagedResources(); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| OnDisposeUnmanagedResources(); | ||||||||||||||||||||||||||||||||||||||
| Disposed = true; | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+105
to
+113
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider making To allow derived classes to override the disposal logic, the Apply this diff: -protected void Dispose(bool disposing)
+protected virtual void Dispose(bool disposing)📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| using System.IO; | ||
|
|
||
| namespace Codebelt.Extensions.Xunit.Assets | ||
| { | ||
| public class ManagedDisposable : Test | ||
| { | ||
| public ManagedDisposable() | ||
| { | ||
| Stream = new MemoryStream(); | ||
| } | ||
|
|
||
| public MemoryStream Stream { get; private set; } | ||
|
|
||
| protected override void OnDisposeManagedResources() | ||
| { | ||
| try | ||
| { | ||
| Stream?.Dispose(); | ||
| } | ||
| finally | ||
| { | ||
| Stream = null; | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| using System; | ||
| using System.Runtime.InteropServices; | ||
| #if NET48_OR_GREATER | ||
| using NativeLibraryLoader; | ||
| #endif | ||
|
Comment on lines
+3
to
+5
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct the conditional compilation symbols The symbol Update the conditional compilation directives to use the correct symbols: - #if NET48_OR_GREATER
+ #if NETFRAMEWORK
using NativeLibraryLoader;
#endifSimilarly, adjust other directives to match the appropriate target frameworks. Also applies to: 26-28 |
||
| namespace Codebelt.Extensions.Xunit.Assets | ||
| { | ||
| public class UnmanagedDisposable : Test | ||
| { | ||
| internal IntPtr _handle = IntPtr.Zero; | ||
| internal IntPtr _libHandle = IntPtr.Zero; | ||
|
|
||
| public delegate bool CloseHandle(IntPtr hObject); | ||
|
|
||
| public delegate IntPtr CreateFileDelegate(string lpFileName, | ||
| uint dwDesiredAccess, | ||
| uint dwShareMode, | ||
| IntPtr lpSecurityAttributes, | ||
| uint dwCreationDisposition, | ||
| uint dwFlagsAndAttributes, | ||
| IntPtr hTemplateFile); | ||
|
|
||
| public delegate IntPtr PtSname(int fd); | ||
|
|
||
| #if NET48_OR_GREATER | ||
| internal NativeLibrary _nativeLibrary; | ||
| #endif | ||
|
|
||
| public UnmanagedDisposable() | ||
| { | ||
| #if NET6_0_OR_GREATER | ||
| if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
| { | ||
| if (NativeLibrary.TryLoad("kernel32.dll", GetType().Assembly, DllImportSearchPath.System32, out _libHandle)) | ||
| { | ||
| if (NativeLibrary.TryGetExport(_libHandle, "CreateFileW", out var functionHandle)) | ||
| { | ||
| var createFileFunc = Marshal.GetDelegateForFunctionPointer<CreateFileDelegate>(functionHandle); | ||
| _handle = createFileFunc(@"C:\TestFile.txt", | ||
| 0x80000000, //access read-only | ||
| 1, //share-read | ||
| IntPtr.Zero, | ||
| 3, //open existing | ||
| 0, | ||
| IntPtr.Zero); | ||
| } | ||
| } | ||
| } | ||
| else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) | ||
| { | ||
| if (NativeLibrary.TryLoad("libc.so.6", GetType().Assembly, DllImportSearchPath.SafeDirectories, out _libHandle)) | ||
| { | ||
| _handle = _libHandle; // i don't know of any native methods on unix | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Review the assignment Assigning Consider removing this assignment or properly initializing Also applies to: 76-76 |
||
| } | ||
| } | ||
| #else | ||
| if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
| { | ||
| _nativeLibrary = new NativeLibrary("kernel32.dll"); | ||
| _libHandle = _nativeLibrary.Handle; | ||
| var functionHandle = _nativeLibrary.LoadFunction("CreateFileW"); | ||
| var createFileFunc = Marshal.GetDelegateForFunctionPointer<CreateFileDelegate>(functionHandle); | ||
| _handle = createFileFunc(@"C:\TestFile.txt", | ||
| 0x80000000, //access read-only | ||
| 1, //share-read | ||
| IntPtr.Zero, | ||
| 3, //open existing | ||
| 0, | ||
| IntPtr.Zero); | ||
| } | ||
| else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) | ||
| { | ||
| _nativeLibrary = new NativeLibrary("libc.so.6"); | ||
| _libHandle = _nativeLibrary.Handle; | ||
| _handle = _libHandle; // i don't know of any native methods on unix | ||
| } | ||
| #endif | ||
| } | ||
|
|
||
| ~UnmanagedDisposable() | ||
| { | ||
| Dispose(false); | ||
| } | ||
|
|
||
|
|
||
| protected override void OnDisposeManagedResources() | ||
| { | ||
|
|
||
| } | ||
|
|
||
| protected override void OnDisposeUnmanagedResources() | ||
| { | ||
| #if NET6_0_OR_GREATER | ||
| if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
| { | ||
| if (_handle != IntPtr.Zero) | ||
| { | ||
| if (NativeLibrary.TryGetExport(_libHandle, "CloseHandle", out var closeHandle)) | ||
| { | ||
| var closeHandleAction = Marshal.GetDelegateForFunctionPointer<CloseHandle>(closeHandle); | ||
| closeHandleAction(_handle); | ||
| } | ||
| } | ||
| NativeLibrary.Free(_libHandle); | ||
| } | ||
| else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) | ||
| { | ||
| NativeLibrary.Free(_libHandle); | ||
| } | ||
| #else | ||
| if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
| { | ||
| if (_handle != IntPtr.Zero) | ||
| { | ||
| var closeHandle = _nativeLibrary.LoadFunction("CloseHandle"); | ||
| var closeHandleAction = Marshal.GetDelegateForFunctionPointer<CloseHandle>(closeHandle); | ||
| closeHandleAction(_handle); | ||
| } | ||
| _nativeLibrary.Dispose(); | ||
| } | ||
| else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) | ||
| { | ||
| _nativeLibrary.Dispose(); | ||
| } | ||
| #endif | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| using System; | ||
| using Codebelt.Extensions.Xunit.Assets; | ||
| using Xunit; | ||
| using Xunit.Abstractions; | ||
|
|
||
| namespace Codebelt.Extensions.Xunit | ||
| { | ||
| public class DisposableTest : Test | ||
| { | ||
| public DisposableTest(ITestOutputHelper output) : base(output) | ||
| { | ||
| } | ||
|
|
||
|
|
||
|
|
||
| [Fact] | ||
| public void ManagedDisposable_VerifyThatAssetIsBeingDisposed() | ||
| { | ||
| ManagedDisposable mdRef = null; | ||
| using (var md = new ManagedDisposable()) | ||
| { | ||
| mdRef = md; | ||
| Assert.NotNull(md.Stream); | ||
| Assert.Equal(0, md.Stream.Length); | ||
| Assert.False(mdRef.Disposed); | ||
| } | ||
| Assert.NotNull(mdRef); | ||
| Assert.Null(mdRef.Stream); | ||
| Assert.True(mdRef.Disposed); | ||
| } | ||
|
|
||
| private WeakReference<UnmanagedDisposable> unmanaged = null; | ||
|
|
||
| [Fact] | ||
| public void UnmanagedDisposable_VerifyThatAssetIsBeingDisposedOnFinalize() | ||
| { | ||
| Action body = () => | ||
| { | ||
| var o = new UnmanagedDisposable(); | ||
| Assert.NotEqual(IntPtr.Zero, o._libHandle); | ||
| Assert.NotEqual(IntPtr.Zero, o._handle); | ||
| unmanaged = new WeakReference<UnmanagedDisposable>(o, true); | ||
| }; | ||
|
|
||
| try | ||
| { | ||
| body(); | ||
| } | ||
| finally | ||
| { | ||
| GC.Collect(0, GCCollectionMode.Forced); | ||
| GC.WaitForPendingFinalizers(); | ||
| } | ||
|
|
||
| if (unmanaged.TryGetTarget(out var ud2)) | ||
| { | ||
| Assert.True(ud2.Disposed); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+1
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider adding more test cases for comprehensive coverage. The
Here's an example of an additional test case for explicit disposal of [Fact]
public void UnmanagedDisposable_ExplicitDispose_VerifyResourcesAreReleased()
{
var ud = new UnmanagedDisposable();
Assert.NotEqual(IntPtr.Zero, ud._libHandle);
Assert.NotEqual(IntPtr.Zero, ud._handle);
ud.Dispose();
Assert.True(ud.Disposed);
Assert.Equal(IntPtr.Zero, ud._libHandle);
Assert.Equal(IntPtr.Zero, ud._handle);
}Adding these test cases will provide more comprehensive coverage and help ensure the robustness of your disposable implementations. |
||
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.
💡 Codebase verification
Found version discrepancies across Microsoft.Extensions packages.
Different target frameworks are using varying versions of Microsoft.Extensions packages:
9.0.0-rc.1.24431.78.0.0and8.0.12.1.1These inconsistencies may lead to compatibility and runtime issues. Please align the package versions across all target frameworks to ensure consistency and stability.
🔗 Analysis chain
Approve xunit.extensibility.core update with a compatibility check.
The update of xunit.extensibility.core from version 2.9.1 to 2.9.2 is a good practice to keep dependencies up-to-date. This minor version update likely includes bug fixes and small improvements.
To ensure compatibility, please verify that this update doesn't introduce any breaking changes by running the project's test suite. You can use the following command to check for any potential issues:
If any issues are found, please address them before merging this change.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 6640