public void ConnectSharedResources_GivenTheSameSharedResourceTwice_DoesNothing() { // Arrange var resource = new SharedResource(); var resourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(resource); // Act resourceGroup.ConnectSharedResources(resource, resource); }
public void ConnectSharedResources_GivenTheSharedResourceGroupHasFreedItsSharedResources_ThrowsAnInvalidOperationException() { // Arrange var resource = new SharedResource(); var resourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(resource); resourceGroup.FreeSharedResources(); // Act resourceGroup.ConnectSharedResources(resource, resource); }
public void ConnectSharedResources_WhenGivenASharedResourceNotInTheSharedResourceGroup_ThrowsAnArgumentException() { // Arrange var resourceGroup = SharedResourceGroup.CreateWithNoAcquiredSharedResources(); var resource1 = new SharedResource(); var resource2 = new SharedResource(); // Act resourceGroup.ConnectSharedResources(resource1, resource2); }
public void AssociatedObject_RemembersTheObjectAssociatedToThisResource() { // Arrange var sharedResource = new SharedResource(); const int associatedObject = 3; // Act sharedResource.AssociatedObject = associatedObject; // Assert sharedResource.AssociatedObject.Should().Be(associatedObject); }
public void ConnectedSharedResources_IncludesTheResourceItself() { // Arrange var sharedResource = new SharedResource(); // Act var directlyConnectedSharedResources = sharedResource.ConnectedSharedResources; // Assert directlyConnectedSharedResources.Should().HaveCount(1); directlyConnectedSharedResources.Should().Contain(sharedResource); }
public void ConnectedSharedResources_GivenTheSharedResourcesAreConnectedInACycle_ResolvesTheCycleCorrectly() { // Arrange var sharedResource1 = new SharedResource(); var sharedResource2 = new SharedResource(); var sharedResource3 = new SharedResource(); var sharedResource4 = new SharedResource(); sharedResource1.DirectlyConnect(sharedResource2); sharedResource2.DirectlyConnect(sharedResource3); sharedResource3.DirectlyConnect(sharedResource4); // Act sharedResource3.DirectlyConnect(sharedResource1); // Assert sharedResource1.ConnectedSharedResources.Should().Contain(new[] { sharedResource1, sharedResource2, sharedResource3, sharedResource4 }); sharedResource2.ConnectedSharedResources.Should().Contain(new[] { sharedResource1, sharedResource2, sharedResource3, sharedResource4 }); sharedResource3.ConnectedSharedResources.Should().Contain(new[] { sharedResource1, sharedResource2, sharedResource3, sharedResource4 }); sharedResource4.ConnectedSharedResources.Should().Contain(new[] { sharedResource1, sharedResource2, sharedResource3, sharedResource4 }); }
public void ConnectSharedResources(SharedResource resource1, SharedResource resource2) { CheckSharedResourcesAcquired(); CheckSharedResourcesAreInGroup(resource1, resource2); if (resource1.Equals(resource2) || resource1.DirectlyConnectedSharedResources.Contains(resource2)) return; resource1.DirectlyConnect(resource2); var resource1Identifier = resource1.GetCurrentRootSharedResourceIdentifier(); var resource2Identifier = resource2.GetCurrentRootSharedResourceIdentifier(); if (resource1Identifier.Equals(resource2Identifier)) return; var parentResourceIdentifier = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(resource1Identifier, resource2Identifier); parentResourceIdentifier.Acquire(this); resource1Identifier.SetParentSharedResourceIdentifier(parentResourceIdentifier); resource2Identifier.SetParentSharedResourceIdentifier(parentResourceIdentifier); // We must free these SharedResource identifiers to ensure that we do not hold onto them after the group is freed. resource1Identifier.Free(this); resource2Identifier.Free(this); }
public void CreateAcquiringSharedResources_GivenMultipleSharedResourcesWithNoCompetition_AcquiresThemAll() { // Arrange var resource1 = new SharedResource(); var resource2 = new SharedResource(); // Act var resourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(resource1, resource2); // Assert resource1.GetCurrentRootSharedResourceIdentifier().IsAcquiredBy(resourceGroup).Should().BeTrue(); resource2.GetCurrentRootSharedResourceIdentifier().IsAcquiredBy(resourceGroup).Should().BeTrue(); }
public IReadOnlyCollection<SharedResource> GetSharedResourcesDirectlyConnectedTo(SharedResource resource) { return resource.DirectlyConnectedSharedResources; }
private bool TryAcquireSharedResource(SharedResource sharedResource) { var resourceIdentifier = sharedResource.GetCurrentRootSharedResourceIdentifier(); resourceIdentifier.Acquire(this); var acquiredRootResourceIdentifier = resourceIdentifier.Equals(sharedResource.GetCurrentRootSharedResourceIdentifier()); if (!acquiredRootResourceIdentifier) resourceIdentifier.Free(this); return acquiredRootResourceIdentifier; }
public SharedResource CreateAndAcquireSharedResource() { CheckSharedResourcesAcquired(); var resource = new SharedResource(); resource.GetCurrentRootSharedResourceIdentifier().Acquire(this); sharedResources.Add(resource); return resource; }
public void DisconnectSharedResources(SharedResource resource1, SharedResource resource2) { CheckSharedResourcesAcquired(); CheckSharedResourcesAreInGroup(resource1, resource2); if (resource1 == resource2) throw new ArgumentException("You cannot disconnect a shared resource form itself"); if (!resource1.DirectlyConnectedSharedResources.Contains(resource2)) return; resource1.RemoveDirectConnectionTo(resource2); if (resource1.ConnectedSharedResources.Contains(resource2)) return; // All resources connected to resource 1 or 2 should have been acquired and have the same root shared resource identifier var originalResourceIdentifier = resource1.GetCurrentRootSharedResourceIdentifier(); var newResourceIdentifierForResource1 = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(originalResourceIdentifier); newResourceIdentifierForResource1.Acquire(this); foreach (var resource in resource1.ConnectedSharedResources) { resource.ResetRootSharedResourceIdentifier(newResourceIdentifierForResource1); } var newResourceIdentifierForResource2 = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(newResourceIdentifierForResource1); newResourceIdentifierForResource2.Acquire(this); foreach (var resource in resource2.ConnectedSharedResources) { resource.ResetRootSharedResourceIdentifier(newResourceIdentifierForResource2); } originalResourceIdentifier.Free(this); }
public void DirectlyConnect_WhenAppliedToResourcesInAChain_ConnectsThemAllTogether() { // Arrange var sharedResource1 = new SharedResource(); var sharedResource2 = new SharedResource(); var sharedResource3 = new SharedResource(); var sharedResource4 = new SharedResource(); // Act sharedResource1.DirectlyConnect(sharedResource2); sharedResource2.DirectlyConnect(sharedResource3); sharedResource2.DirectlyConnect(sharedResource4); // Assert sharedResource1.DirectlyConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource1, sharedResource2 }.Contains(r)); sharedResource2.DirectlyConnectedSharedResources.Should().Contain(new [] { sharedResource1, sharedResource2, sharedResource3, sharedResource4 }); sharedResource3.DirectlyConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource3, sharedResource2 }.Contains(r)); sharedResource4.DirectlyConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource4, sharedResource2 }.Contains(r)); sharedResource2.ConnectedSharedResources.ShouldAllBeEquivalentTo(sharedResource1.ConnectedSharedResources); sharedResource3.ConnectedSharedResources.ShouldAllBeEquivalentTo(sharedResource1.ConnectedSharedResources); sharedResource4.ConnectedSharedResources.ShouldAllBeEquivalentTo(sharedResource1.ConnectedSharedResources); sharedResource1.ConnectedSharedResources.ShouldAllBeEquivalentTo(new[] { sharedResource1, sharedResource2, sharedResource3, sharedResource4 }); }
public void RemoveDirectConnectionTo_GivenAResourceThisIsNotConnectedTo_DoesNothing() { // Arrange var sharedResource1 = new SharedResource(); var sharedResource2 = new SharedResource(); // Act sharedResource1.RemoveDirectConnectionTo(sharedResource2); // Assert sharedResource1.ConnectedSharedResources.Should().HaveCount(1); sharedResource1.ConnectedSharedResources.Should().Contain(sharedResource1); sharedResource2.ConnectedSharedResources.Should().HaveCount(1); sharedResource2.ConnectedSharedResources.Should().Contain(sharedResource2); sharedResource1.DirectlyConnectedSharedResources.Should().HaveCount(1); sharedResource1.DirectlyConnectedSharedResources.Should().Contain(sharedResource1); sharedResource2.DirectlyConnectedSharedResources.Should().HaveCount(1); sharedResource2.DirectlyConnectedSharedResources.Should().Contain(sharedResource2); }
public void GetCurrentRootResourceIdentifier_GivenItsInitialResourceIdentifierHasAParent_ReturnsThatParent() { // Arrange var resource = new SharedResource(); var child = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(resource.GetCurrentRootSharedResourceIdentifier()); var parent = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(child); resource.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(child); child.SetParentSharedResourceIdentifier(parent); // Act var root = resource.GetCurrentRootSharedResourceIdentifier(); // Assert root.Should().Be(parent); }
public void GetCurrentRootResourceIdentifier_GivenAResourceJustInitialisedWithAResourceIdentifier_ReturnsThatResourceIdentifier() { // Arrange var resource = new SharedResource(); var resourceIdentifier = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(resource.GetCurrentRootSharedResourceIdentifier()); resource.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(resourceIdentifier); // Act var root = resource.GetCurrentRootSharedResourceIdentifier(); // Assert root.Should().Be(resourceIdentifier); }
public void ResetRootSharedResourceIdentifier_GivenASharedResourceIdentifier_SetsTheRootToBeThatSharedResourceIdentifier() { // Arrange var sharedResource1 = new SharedResource(); var sharedResource2 = new SharedResource(); var sharedRoot = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(sharedResource1.GetCurrentRootSharedResourceIdentifier(), sharedResource2.GetCurrentRootSharedResourceIdentifier()); sharedResource1.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(sharedRoot); sharedResource2.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(sharedRoot); var newRootForSharedResource1 = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(sharedRoot); var newRootForSharedResource2 = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(sharedRoot); // Act sharedResource1.ResetRootSharedResourceIdentifier(newRootForSharedResource1); sharedResource2.ResetRootSharedResourceIdentifier(newRootForSharedResource2); // Assert sharedResource1.GetCurrentRootSharedResourceIdentifier().Should().Be(newRootForSharedResource1); sharedResource2.GetCurrentRootSharedResourceIdentifier().Should().Be(newRootForSharedResource2); sharedResource1.GetCurrentRootSharedResourceIdentifier().Should().NotBeSameAs(sharedResource2.GetCurrentRootSharedResourceIdentifier()); }
public void RemoveDirectConnectionTo_WhenDisconnectingAChainOfSharedResources_BreaksThatChain() { // Arrange var sharedResource1 = new SharedResource(); var sharedResource2 = new SharedResource(); var sharedResource3 = new SharedResource(); var sharedResource4 = new SharedResource(); sharedResource1.DirectlyConnect(sharedResource2); sharedResource2.DirectlyConnect(sharedResource3); sharedResource3.DirectlyConnect(sharedResource4); // Act sharedResource2.RemoveDirectConnectionTo(sharedResource3); // Assert sharedResource2.DirectlyConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource1, sharedResource2 }.Contains(r)); sharedResource3.DirectlyConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource3, sharedResource4 }.Contains(r)); sharedResource1.ConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource1, sharedResource2 }.Contains(r)); sharedResource2.ConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource1, sharedResource2 }.Contains(r)); sharedResource3.ConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource3, sharedResource4 }.Contains(r)); sharedResource4.ConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource3, sharedResource4 }.Contains(r)); }
public void RemoveDirectConnectionTo_GivenTheResourceItself_ThrowsAnArgumentException() { // Arrange var sharedResource = new SharedResource(); // Act sharedResource.RemoveDirectConnectionTo(sharedResource); }
public void CreateAcquiringSharedResources_GivenMultipleSharedResourcesWithTheSameSharedResourceIdentifier_CanAcquireThemAll() { // Arrange var resource1 = new SharedResource(); var resource2 = new SharedResource(); var resourceIdentifier = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(resource1.GetCurrentRootSharedResourceIdentifier(), resource2.GetCurrentRootSharedResourceIdentifier()); resource1.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(resourceIdentifier); resource2.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(resourceIdentifier); // Act var resourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(resource1, resource2); // Assert resource1.GetCurrentRootSharedResourceIdentifier().IsAcquiredBy(resourceGroup).Should().BeTrue(); resource2.GetCurrentRootSharedResourceIdentifier().IsAcquiredBy(resourceGroup).Should().BeTrue(); }
public void DirectlyConnect_GivenASharedResource_ConnectsTheCurrentSharedResourceToThatSharedResource() { // Arrange var sharedResource1 = new SharedResource(); var sharedResource2 = new SharedResource(); // Act sharedResource1.DirectlyConnect(sharedResource2); // Assert sharedResource1.DirectlyConnectedSharedResources.Should().Contain(sharedResource2); sharedResource1.ConnectedSharedResources.Should().Contain(sharedResource2); sharedResource2.DirectlyConnectedSharedResources.Should().Contain(sharedResource1); sharedResource2.ConnectedSharedResources.Should().Contain(sharedResource1); }
public void CreateAcquiringSharedResources_GivenMultipleSharedResources_AcquiresTheSharedResourcesInOrderOfSharedResourceIdentifierAscending() { // Arrange var childResource = new SharedResource(); var parentResource = new SharedResource(); var child = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(childResource.GetCurrentRootSharedResourceIdentifier(), parentResource.GetCurrentRootSharedResourceIdentifier()); var parent = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(child); childResource.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(child); parentResource.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(parent); var competingResourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(childResource, parentResource); // Act SharedResourceGroup resourceGroup = null; var thread = new Thread(() => resourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(childResource, parentResource)); thread.Start(); Thread.Sleep(500); // Assert child.IsAcquiredBy(competingResourceGroup).Should().BeTrue(); parent.IsAcquiredBy(competingResourceGroup).Should().BeTrue(); // Act parent.Free(competingResourceGroup); Thread.Sleep(500); // Assert child.IsAcquiredBy(competingResourceGroup).Should().BeTrue(); parent.IsAcquired().Should().BeFalse(); // Act parent.Acquire(competingResourceGroup); child.Free(competingResourceGroup); Thread.Sleep(500); // Assert child.IsAcquired().Should().BeTrue(); child.IsAcquiredBy(competingResourceGroup).Should().BeFalse(); parent.IsAcquiredBy(competingResourceGroup).Should().BeTrue(); // Act parent.Free(competingResourceGroup); Thread.Sleep(500); // Assert resourceGroup.Should().NotBeNull(); child.IsAcquiredBy(resourceGroup).Should().BeTrue(); parent.IsAcquiredBy(resourceGroup).Should().BeTrue(); }
public void RemoveDirectConnectionTo_GivenAPairOfConnectedSharedResources_DisconnectsThemBoth() { // Arrange var sharedResource1 = new SharedResource(); var sharedResource2 = new SharedResource(); sharedResource1.DirectlyConnect(sharedResource2); // Act sharedResource2.RemoveDirectConnectionTo(sharedResource1); // Assert sharedResource1.DirectlyConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource1 }.Contains(r)); sharedResource1.ConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource1 }.Contains(r)); sharedResource2.DirectlyConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource2 }.Contains(r)); sharedResource2.ConnectedSharedResources.Should().OnlyContain(r => new[] { sharedResource2 }.Contains(r)); }
public void CreateAcquiringSharedResources_GivenTheSharedResourceIdentifierChangesAndThatChangesTheOrderInWhichToAcquireSharedResources_CanStillAcquireSharedResourcesEventually() { // Arrange var childResource = new SharedResource(); var parentResource = new SharedResource(); var child = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(childResource.GetCurrentRootSharedResourceIdentifier(), parentResource.GetCurrentRootSharedResourceIdentifier()); var parent = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(child); var grandParent = SharedResourceIdentifier.CreateSharedResourceIdentifierBiggerThan(parent); childResource.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(child); parentResource.GetCurrentRootSharedResourceIdentifier().SetParentSharedResourceIdentifier(parent); var competingResourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(childResource, parentResource); // Act SharedResourceGroup resourceGroup = null; var thread = new Thread(() => resourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(childResource, parentResource)); thread.Start(); Thread.Sleep(500); // Assert child.IsAcquiredBy(competingResourceGroup).Should().BeTrue(); parent.IsAcquiredBy(competingResourceGroup).Should().BeTrue(); // Act child.SetParentSharedResourceIdentifier(grandParent); child.Free(competingResourceGroup); Thread.Sleep(500); // Assert child.IsAcquired().Should().BeFalse(); parent.IsAcquiredBy(competingResourceGroup).Should().BeTrue(); grandParent.IsAcquired().Should().BeFalse(); // Act grandParent.Acquire(competingResourceGroup); parent.Free(competingResourceGroup); Thread.Sleep(500); // Assert grandParent.IsAcquiredBy(competingResourceGroup).Should().BeTrue(); parent.IsAcquired().Should().BeTrue(); // Act grandParent.Free(competingResourceGroup); Thread.Sleep(500); // Assert resourceGroup.Should().NotBeNull(); child.IsAcquired().Should().BeFalse(); parent.IsAcquiredBy(resourceGroup).Should().BeTrue(); grandParent.IsAcquiredBy(resourceGroup).Should().BeTrue(); }
internal void DirectlyConnect(SharedResource sharedResource) { if (!directlyConnectedSharedSharedResources.Contains(sharedResource)) { directlyConnectedSharedSharedResources.Add(sharedResource); mustRecalculateConnectedSharedResources = sharedResource.mustRecalculateConnectedSharedResources = true; } if (!sharedResource.directlyConnectedSharedSharedResources.Contains(this)) { sharedResource.directlyConnectedSharedSharedResources.Add(this); mustRecalculateConnectedSharedResources = sharedResource.mustRecalculateConnectedSharedResources = true; } }
public void FreeSharedResources_GivenTheSharedResourceGroupHasSharedResourcesThatHaveBeenConnected_FreesThemAll() { // Arrange var resource1 = new SharedResource(); var resource2 = new SharedResource(); var resourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(resource1, resource2); resourceGroup.ConnectSharedResources(resource1, resource2); // Act resourceGroup.FreeSharedResources(); // Assert resource1.GetCurrentRootSharedResourceIdentifier().IsAcquired().Should().BeFalse(); resource2.GetCurrentRootSharedResourceIdentifier().IsAcquired().Should().BeFalse(); }
internal void RemoveDirectConnectionTo(SharedResource sharedResource) { if (sharedResource == this) throw new ArgumentException("You cannot disconnect a resource from itself.", "sharedResource"); if (directlyConnectedSharedSharedResources.Contains(sharedResource)) { directlyConnectedSharedSharedResources.Remove(sharedResource); mustRecalculateConnectedSharedResources = sharedResource.mustRecalculateConnectedSharedResources = true; } if (sharedResource.directlyConnectedSharedSharedResources.Contains(this)) { sharedResource.directlyConnectedSharedSharedResources.Remove(this); mustRecalculateConnectedSharedResources = sharedResource.mustRecalculateConnectedSharedResources = true; } }
public void CreateAcquiringSharedResources_GivenASingleSharedResource_AcquiresThatSharedResource() { // Arrange var resource = new SharedResource(); // Act var resourceGroup = SharedResourceGroup.CreateAcquiringSharedResources(resource); // Assert resource.GetCurrentRootSharedResourceIdentifier().IsAcquiredBy(resourceGroup).Should().BeTrue(); }
public void DirectlyConnect_CalledTwiceForTheSameResource_OnlyConnectsThatResourceOnce() { // Arrange var sharedResource1 = new SharedResource(); var sharedResource2 = new SharedResource(); // Act sharedResource1.DirectlyConnect(sharedResource2); sharedResource1.DirectlyConnect(sharedResource2); // Assert sharedResource1.ConnectedSharedResources.Should().HaveCount(2); sharedResource2.ConnectedSharedResources.Should().HaveCount(2); sharedResource2.ConnectedSharedResources.ShouldAllBeEquivalentTo(sharedResource1.ConnectedSharedResources); sharedResource1.ConnectedSharedResources.Should().Contain(new[] { sharedResource1, sharedResource2 }); sharedResource1.DirectlyConnectedSharedResources.Should().HaveCount(2); sharedResource2.DirectlyConnectedSharedResources.Should().HaveCount(2); sharedResource2.DirectlyConnectedSharedResources.ShouldAllBeEquivalentTo(sharedResource1.ConnectedSharedResources); sharedResource1.DirectlyConnectedSharedResources.Should().Contain(new[] { sharedResource1, sharedResource2 }); }