/// <summary> /// A very naive version of property-based testing API. /// </summary> /// <remarks> /// This implementation may be moved to a proper property-based testing framework like FsCheck. /// </remarks> private static void TestProperty(Func <MachineId[], MachineIdCollection, bool> propertyChecker, [CallerMemberName] string operation = null) { const ushort maxMachineId = 2048; const int count = 50; var random = new Random(); // Explicitly validating the property for empty collection and the collection with 1 element. validateProperty(0); validateProperty(1); for (int i = 0; i < count; i++) { var collectionLength = random.Next(count); validateProperty(collectionLength); } void validateProperty(int collectionLength) { var arrayOfMachineIds = Enumerable.Range(1, collectionLength).Select(_ => new MachineId(random.Next(maxMachineId))).ToArray(); var machineIdCollection = arrayOfMachineIds.Length == 1 ? MachineIdCollection.Create(arrayOfMachineIds[0]) : MachineIdCollection.Create(arrayOfMachineIds); Assert.True(propertyChecker(arrayOfMachineIds, machineIdCollection), $"The property '{operation}' is falsifiable."); } }
public void BinManagerExcludesMaster() { var amountMachines = 4; var machineMappings = Enumerable.Range(0, amountMachines).Select(i => new MachineMapping(new MachineLocation(i.ToString()), new MachineId(i))).ToArray(); var masterMapping = machineMappings[0]; var clusterState = new ClusterState(machineMappings[0].Id, machineMappings) { EnableBinManagerUpdates = true }; foreach (var mapping in machineMappings) { clusterState.AddMachine(mapping.Id, mapping.Location); } clusterState.SetMasterMachine(masterMapping.Location); clusterState.InitializeBinManagerIfNeeded(locationsPerBin: amountMachines, _clock, expiryTime: TimeSpan.Zero); var binMappings = clusterState.GetBinMappings().ThrowIfFailure(); foreach (var binMapping in binMappings) { // Master should not be there binMapping.Length.Should().Be(amountMachines - 1); binMapping.Should().NotContain(masterMapping.Id); } // Make sure this stays true after updates var inactiveMachines = new BitMachineIdSet(new byte[amountMachines], 0); inactiveMachines = inactiveMachines.SetExistenceBits(MachineIdCollection.Create(machineMappings[1].Id), true); clusterState.SetMachineStates(inactiveMachines).ShouldBeSuccess(); binMappings = clusterState.GetBinMappings().ThrowIfFailure(); foreach (var binMapping in binMappings) { // Master and inactive should not be there binMapping.Length.Should().Be(amountMachines - 2); binMapping.Should().NotContain(masterMapping.Id); } }