diff --git a/DotNetVault/Vaults/BasicMonitorVault.cs b/DotNetVault/Vaults/BasicMonitorVault.cs index 20d1721..9095a3e 100644 --- a/DotNetVault/Vaults/BasicMonitorVault.cs +++ b/DotNetVault/Vaults/BasicMonitorVault.cs @@ -30,25 +30,21 @@ public sealed class BasicMonitorVault<[VaultSafeTypeParam] T> : MonitorVault, #region CTORS /// public BasicMonitorVault(TimeSpan defaultTimeout) - : base(defaultTimeout) { } + : this(defaultTimeout, default) { } /// /// Creates a vault. The value of will be used as default timeout. /// /// initial value of protected resource - public BasicMonitorVault(T initialValue) : this(initialValue, FallbackTimeout) - { - - } + public BasicMonitorVault(T initialValue) + : this(initialValue, FallbackTimeout) {} /// /// Creates a vault using the default value of the protected resource and the value /// specified by as the default wait period. /// - public BasicMonitorVault() : this(default, FallbackTimeout) - { - - } + public BasicMonitorVault() + : this(default, FallbackTimeout) { } /// /// CTOR -- vault with specified value and timeout @@ -56,11 +52,15 @@ public BasicMonitorVault() : this(default, FallbackTimeout) /// initial value of protected resource /// default timeout period /// was null - public BasicMonitorVault(T initialValue, TimeSpan defaultTimeout) : base(defaultTimeout) + public BasicMonitorVault(T initialValue, TimeSpan defaultTimeout) + : this(defaultTimeout, initialValue) {} + + private BasicMonitorVault(TimeSpan defaultTimeout, T initialValue) + : base(defaultTimeout) { Init(initialValue); Debug.Assert(BoxPtr != null); - } + } #endregion #region Lock acquisition methods diff --git a/VaultUnitTests/BasicMonVAcqBehaviorTests.cs b/VaultUnitTests/BasicMonVAcqBehaviorTests.cs index d045b60..8ae4dae 100644 --- a/VaultUnitTests/BasicMonVAcqBehaviorTests.cs +++ b/VaultUnitTests/BasicMonVAcqBehaviorTests.cs @@ -6,10 +6,13 @@ using Xunit.Abstractions; using Xunit.Sdk; using ResourceType = System.String; - +using NullVtType = System.Nullable; +using VtType = System.UInt64; namespace VaultUnitTests { using VaultType = DotNetVault.Vaults.BasicMonitorVault; + using NullVtVault = DotNetVault.Vaults.BasicMonitorVault; + using VtVault = DotNetVault.Vaults.BasicMonitorVault; public delegate VaultType MonVaultCreationMethod(TimeSpan timeout, Func ctor = null); public sealed class BasicMonVaultAcqBehaviorTests : VaultAcqBehaviorTest @@ -20,7 +23,8 @@ public BasicMonVaultAcqBehaviorTests([NotNull] ITestOutputHelper helper, [NotNul _meth = (ts, ctor) => Fixture.CreateBasicMonitorVault(); } - + + [Fact] public void TestThrowsAlready() { @@ -229,7 +233,7 @@ static void DoThreadTwo(VaultType bv, StartToken tkn, ExceptionReceptor receptor public void TestSeqBlockAcqs() { string finalResult; - using (var vault = _meth(TimeSpan.FromMilliseconds(250))) + using (VaultType vault = _meth(TimeSpan.FromMilliseconds(250))) { vault.SetCurrentValue(TimeSpan.FromMilliseconds(10), string.Empty); @@ -254,8 +258,8 @@ public void TestSeqBlockAcqs() } Assert.True(finalResult == vault.CopyCurrentValue(TimeSpan.FromMilliseconds(10))); } - Helper.WriteLine(finalResult); - } + Helper.WriteLine(finalResult); + } [Fact] public void TestThrowsOperationCancelledWhenCancelBeforeTimeout() diff --git a/VaultUnitTests/Issue22Tests.cs b/VaultUnitTests/Issue22Tests.cs new file mode 100644 index 0000000..86a45d6 --- /dev/null +++ b/VaultUnitTests/Issue22Tests.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Xunit; +using Xunit.Abstractions; +using ResourceType = System.String; +using NullVtType = System.Nullable; +using VtType = System.UInt64; +namespace VaultUnitTests +{ + using VaultType = DotNetVault.Vaults.BasicMonitorVault; + using NullVtVault = DotNetVault.Vaults.BasicMonitorVault; + using VtVault = DotNetVault.Vaults.BasicMonitorVault; + public class Issue22Tests : NullableAcqTests + { + /// + public Issue22Tests([NotNull] ITestOutputHelper helper, + [NotNull] NullableVtVaultFactoryFixture fixture) : base(helper, fixture) {} + + [Fact] + public void TestGetLockUnsetNullableVt() + { + using (var vault = Fixture.CreateUnsetNullableVtVault()) + { + { + using var lck = vault.Lock(); + Helper.WriteLine($"Value now: {lck.Value?.ToString() ?? "NULL"}."); + } + } + } + + [Fact] + public void TestGetLockPresetNullableVt() + { + const ulong targetVal = 24; + using (var vault = Fixture.CreateUnsetNullableVtVault()) + { + vault.SetCurrentValue(TimeSpan.FromMilliseconds(250), targetVal); + { + using var lck = vault.Lock(); + Assert.True(lck.Value == targetVal); + } + } + } + + [Fact] + public void TestGetLockConstructedNullableVt() + { + const ulong targetVal = 66; + using (var vault = Fixture.CreateSetNullVtVault(targetVal)) + { + using var lck = vault.Lock(); + Assert.True(lck.Value == targetVal); + } + } + + [Fact] + public void TestGetLockUnsetVt() + { + using (var vault = Fixture.CreateUnsetVtVault()) + { + { + using var lck = vault.Lock(); + Helper.WriteLine($"Value now: {lck.Value.ToString()}."); + } + } + } + + [Fact] + public void TestGetLockPresetVt() + { + const ulong targetVal = 24; + using (var vault = Fixture.CreateUnsetVtVault()) + { + vault.SetCurrentValue(TimeSpan.FromMilliseconds(250), targetVal); + { + using var lck = vault.Lock(); + Assert.True(lck.Value == targetVal); + } + } + } + + [Fact] + public void TestGetLockConstructedVt() + { + const ulong targetVal = 66; + using (var vault = Fixture.CreateSetVtVault(targetVal)) + { + using var lck = vault.Lock(); + Assert.True(lck.Value == targetVal); + } + } + + [Fact] + public void TestGetLockUnsetRt() + { + using (var vault = Fixture.CreateUnsetVault()) + { + { + using var lck = vault.Lock(); + Helper.WriteLine($"Value now: {lck.Value ?? "NULL"}."); + } + } + } + + [Fact] + public void TestGetLockPreset() + { + const string targetVal = "FooBar"; + using (var vault = Fixture.CreateUnsetVault()) + { + vault.SetCurrentValue(TimeSpan.FromMilliseconds(250), targetVal); + { + using var lck = vault.Lock(); + Assert.True(lck.Value == targetVal); + } + } + } + + [Fact] + public void TestGetLockConstructedNullRt() + { + const string targetVal = null; + using (var vault = Fixture.CreateSetVault(targetVal)) + { + using var lck = vault.Lock(); + Assert.True(lck.Value == targetVal); + } + } + + [Fact] + public void TestGetLockConstructedNotNullRtVault() + { + const string targetVal = "frobnication"; + using (var vault = Fixture.CreateSetVault(targetVal)) + { + using var lck = vault.Lock(); + Assert.True(lck.Value == targetVal); + } + } + + } +} diff --git a/VaultUnitTests/VaultAcqBehaviorTest.cs b/VaultUnitTests/VaultAcqBehaviorTest.cs index f95caa1..40988c6 100644 --- a/VaultUnitTests/VaultAcqBehaviorTest.cs +++ b/VaultUnitTests/VaultAcqBehaviorTest.cs @@ -1,12 +1,21 @@ using System; +using DotNetVault.Exceptions; +using DotNetVault.Vaults; using JetBrains.Annotations; using Xunit; using Xunit.Abstractions; - +using ResourceType = System.String; +using NullVtType = System.Nullable; +using VtType = System.UInt64; namespace VaultUnitTests { + using VaultType = DotNetVault.Vaults.BasicMonitorVault; + using NullVtVault = DotNetVault.Vaults.BasicMonitorVault; + using VtVault = DotNetVault.Vaults.BasicMonitorVault; public abstract class VaultAcqBehaviorTest : TestBase { + + protected VaultAcqBehaviorTest([NotNull] ITestOutputHelper helper, [NotNull] VaultFactoryFixture fixture) : base(helper, fixture) { } @@ -23,4 +32,39 @@ protected TestBase([NotNull] ITestOutputHelper helper, [NotNull] TFixture fixtur Fixture = fixture ?? throw new ArgumentNullException(nameof(fixture)); } } + + public class NullableVtVaultFactoryFixture : VaultFactoryFixture + { + public TimeSpan VaultTimeout + { + get => _timeout; + init => _timeout = value > TimeSpan.Zero + ? value + : throw new ArgumentNotPositiveException(nameof(value), value); + } + + public NullVtVault CreateSetNullVtVault(NullVtType initial) => new(initial, _timeout); + + public NullVtVault CreateUnsetNullableVtVault() => new (_timeout); + + public VtVault CreateUnsetVtVault() => new(_timeout); + + public VtVault CreateSetVtVault(VtType value) => new(value, _timeout); + + public VaultType CreateUnsetVault() => new(_timeout); + + public VaultType CreateSetVault(ResourceType rt) => new(rt, _timeout); + + + private readonly TimeSpan _timeout = TimeSpan.FromMilliseconds(500); + } + + public abstract class NullableAcqTests : TestBase + { + /// + protected NullableAcqTests([NotNull] ITestOutputHelper helper, + [NotNull] NullableVtVaultFactoryFixture fixture) : base(helper, fixture) { } + } + + } diff --git a/VaultUnitTests/VaultUnitTests.csproj b/VaultUnitTests/VaultUnitTests.csproj index 8cef3bd..896011a 100644 --- a/VaultUnitTests/VaultUnitTests.csproj +++ b/VaultUnitTests/VaultUnitTests.csproj @@ -8,7 +8,7 @@ - netcoreapp3.1 + net6 @@ -26,10 +26,10 @@ - + - +