Наследование: IRaftVolatileState
        public FollowerRoleTests(ITestOutputHelper output)
        {
            var builder = new AutoSubstitute();
            builder.Provide<ILogger>(new TestLogger(output));

            this.volatileState = new VolatileState();
            builder.Provide<IRaftVolatileState>(this.volatileState);

            // Configure settings
            this.settings = builder.Resolve<ISettings>();
            this.settings.ApplyEntriesOnFollowers.Returns(true);
            this.settings.MinElectionTimeoutMilliseconds.Returns(MinElectionTime);
            this.settings.MaxElectionTimeoutMilliseconds.Returns(MaxElectionTime);

            // Rig random number generator to always return the same value.
            this.random = builder.Resolve<IRandom>();
            this.random.Next(Arg.Any<int>(), Arg.Any<int>()).Returns(RiggedRandomResult);

            this.coordinator = builder.Resolve<IRoleCoordinator<int>>();
            this.stateMachine = builder.Resolve<IStateMachine<int>>();

            this.timers = new MockTimers();
            builder.Provide<RegisterTimerDelegate>(this.timers.RegisterTimer);

            this.persistentState = Substitute.ForPartsOf<InMemoryPersistentState>();
            builder.Provide<IRaftPersistentState>(this.persistentState);

            this.journal = Substitute.ForPartsOf<InMemoryLog<int>>();
            builder.Provide<IPersistentLog<int>>(this.journal);

            // After the container is configured, resolve required services.
            this.role = builder.Resolve<FollowerRole<int>>();
        }
        public CandidateRoleTests(ITestOutputHelper output)
        {
            var builder =
                new AutoSubstitute(cb => cb.Register(_ => Substitute.For<IRaftGrain<int>>()).InstancePerDependency());
            builder.Provide<ILogger>(new TestLogger(output));

            this.volatileState = new VolatileState();
            builder.Provide<IRaftVolatileState>(this.volatileState);

            // Configure settings
            this.settings = builder.Resolve<ISettings>();
            this.settings.MinElectionTimeoutMilliseconds.Returns(MinElectionTime);
            this.settings.MaxElectionTimeoutMilliseconds.Returns(MaxElectionTime);

            // Rig random number generator to always return the same value.
            this.random = builder.Resolve<IRandom>();
            this.random.Next(Arg.Any<int>(), Arg.Any<int>()).Returns(RiggedRandomResult);

            this.coordinator = builder.Resolve<IRoleCoordinator<int>>();
            this.coordinator.StepDownIfGreaterTerm(Arg.Any<IMessage>())
                .Returns(
                    info => Task.FromResult(((IMessage)info[0]).Term > this.persistentState.CurrentTerm));
            var currentRole = builder.Resolve<IRaftRole<int>>();
            currentRole.RequestVote(Arg.Any<RequestVoteRequest>())
                .Returns(Task.FromResult(new RequestVoteResponse { Term = 1, VoteGranted = true }));
            currentRole.Append(Arg.Any<AppendRequest<int>>())
                .Returns(Task.FromResult(new AppendResponse { Term = 1, Success = true }));
            this.coordinator.Role.Returns(currentRole);

            this.timers = new MockTimers();
            builder.Provide<RegisterTimerDelegate>(this.timers.RegisterTimer);

            this.persistentState = Substitute.ForPartsOf<InMemoryPersistentState>();
            builder.Provide<IRaftPersistentState>(this.persistentState);

            this.journal = Substitute.ForPartsOf<InMemoryLog<int>>();
            builder.Provide<IPersistentLog<int>>(this.journal);

            this.identity = Substitute.For<IServerIdentity>();
            this.identity.Id.Returns(Guid.NewGuid().ToString());
            builder.Provide(this.identity);

            this.members = builder.Resolve<StaticMembershipProvider>();
            this.members.SetServers(new[] { this.identity.Id, "other1", "other2", "other3", "other4" });
            builder.Provide<IMembershipProvider>(this.members);

            this.grainFactory = new FakeGrainFactory(builder.Container);
            builder.Provide<IGrainFactory>(this.grainFactory);
            this.OnRaftGrainCreated =
                (id, grain) =>
                grain.RequestVote(Arg.Any<RequestVoteRequest>())
                    .Returns(Task.FromResult(new RequestVoteResponse { VoteGranted = true }));

            // After the container is configured, resolve required services.
            this.role = builder.Resolve<CandidateRole<int>>();
            this.container = builder;
        }