public async Task SaveAndHydrateRootScope_AddAndRemoveLeases() { Random random = new Random(); await ExecuteWithStreamErase(random, async (eventStore) => { Mock <IDHCPv6ServerPropertiesResolver> propertyResolverMock; DHCPv6StorageEngine engine; PrepareEngine(random, eventStore, out propertyResolverMock, out engine); DHCPv6RootScope initialRootScope = await engine.GetRootScope(); Guid rootScopeId = random.NextGuid(); initialRootScope.AddScope(new DHCPv6ScopeCreateInstruction { AddressProperties = new DHCPv6ScopeAddressProperties( IPv6Address.FromString("fe80::0"), IPv6Address.FromString("fe80::ff"), new List <IPv6Address> { IPv6Address.FromString("fe80::1") }, preferredLifeTime: TimeSpan.FromDays(0.5), validLifeTime: TimeSpan.FromDays(1), rapitCommitEnabled: true, informsAreAllowd: true, supportDirectUnicast: false, reuseAddressIfPossible: false, acceptDecline: true, t1: DHCPv6TimeScale.FromDouble(0.6), t2: DHCPv6TimeScale.FromDouble(0.8), addressAllocationStrategy: DHCPv6ScopeAddressProperties.AddressAllocationStrategies.Next), ScopeProperties = DHCPv6ScopeProperties.Empty, ResolverInformation = new CreateScopeResolverInformation { Typename = nameof(DHCPv6RemoteIdentifierEnterpriseNumberResolver), PropertiesAndValues = new Dictionary <String, String> { { nameof(DHCPv6RemoteIdentifierEnterpriseNumberResolver.EnterpriseNumber), random.NextUInt16().ToString() }, { nameof(DHCPv6RemoteIdentifierEnterpriseNumberResolver.RelayAgentIndex), 0.ToString() }, } }, Name = "Testscope", Id = rootScopeId, }); var clientDuid = new UUIDDUID(random.NextGuid()); DHCPv6Packet solicitPacket = DHCPv6Packet.AsInner(14, DHCPv6PacketTypes.Solicit, new List <DHCPv6PacketOption> { new DHCPv6PacketTrueOption(DHCPv6PacketOptionTypes.RapitCommit), new DHCPv6PacketIdentifierOption(DHCPv6PacketOptionTypes.ClientIdentifier, clientDuid), new DHCPv6PacketIdentityAssociationNonTemporaryAddressesOption(15, TimeSpan.Zero, TimeSpan.Zero, new List <DHCPv6PacketSuboption>()), }); DHCPv6RelayPacket outerSolicitPacket = DHCPv6RelayPacket.AsOuterRelay(new IPv6HeaderInformation(random.GetIPv6Address(), random.GetIPv6Address()), true, 0, IPv6Address.FromString("fe80::2"), IPv6Address.FromString("fe80::2"), new DHCPv6PacketOption[] { new DHCPv6PacketRemoteIdentifierOption(random.NextUInt16(), new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }), }, solicitPacket); initialRootScope.HandleSolicit(outerSolicitPacket, propertyResolverMock.Object); var firstLease = initialRootScope.GetRootScopes().First().Leases.GetAllLeases().First(); await engine.Save(initialRootScope); initialRootScope = await engine.GetRootScope(); DHCPv6Packet releasePacket = DHCPv6Packet.AsInner(14, DHCPv6PacketTypes.RELEASE, new List <DHCPv6PacketOption> { new DHCPv6PacketIdentifierOption(DHCPv6PacketOptionTypes.ClientIdentifier, clientDuid), new DHCPv6PacketIdentityAssociationNonTemporaryAddressesOption(15, TimeSpan.FromSeconds(random.Next()), TimeSpan.FromSeconds(random.Next()), new DHCPv6PacketSuboption[] { new DHCPv6PacketIdentityAssociationAddressSuboption(firstLease.Address, TimeSpan.FromSeconds(random.Next()), TimeSpan.FromSeconds(random.Next()), Array.Empty <DHCPv6PacketSuboption>()) }) }); DHCPv6RelayPacket outerreleasePacket = DHCPv6RelayPacket.AsOuterRelay(new IPv6HeaderInformation(random.GetIPv6Address(), random.GetIPv6Address()), true, 0, IPv6Address.FromString("fe80::2"), IPv6Address.FromString("fe80::2"), new DHCPv6PacketOption[] { new DHCPv6PacketRemoteIdentifierOption(random.NextUInt16(), new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }), }, releasePacket); firstLease = initialRootScope.GetRootScopes().First().Leases.GetAllLeases().First(); initialRootScope.HandleRelease(outerreleasePacket, propertyResolverMock.Object); Assert.Equal(LeaseStates.Released, firstLease.State); Assert.Empty(initialRootScope.GetRootScopes().First().Leases.GetAllLeases()); await engine.Save(initialRootScope); await Task.Delay(1000); initialRootScope.DropUnusedLeasesOlderThan(DateTime.Now); Assert.Empty(initialRootScope.GetRootScopes().First().Leases.GetAllLeases()); await engine.Save(initialRootScope); var rehydratedRootScope = await engine.GetRootScope(); Assert.Empty(rehydratedRootScope.GetRootScopes().First().Leases.GetAllLeases()); }); }