Exemple #1
0
 public LogServiceProvider(Application app) : base(app)
 {
     log = new InMemoryLog(
         maxRecordCount: 50,
         maxRecordSize: 5_000
         );
 }
Exemple #2
0
        public async Task Execute_MultipleWebAppSlotsWithTags_WebAppWithTags_CreatesCorrectTargets()
        {
            // Arrange
            var variables = new CalamariVariables();
            var context   = new RunningDeployment(variables);

            CreateVariables(context);
            var log = new InMemoryLog();
            var sut = new TargetDiscoveryBehaviour(log);

            // Set expected tags on each slot of the web app AND the web app itself
            var tags = new Dictionary <string, string>
            {
                { TargetTags.EnvironmentTagName, EnvironmentName },
                { TargetTags.RoleTagName, Role },
            };

            await CreateOrUpdateTestWebApp(tags);
            await CreateOrUpdateTestWebAppSlots(tags);

            // Act
            await sut.Execute(context);

            var serviceMessageToCreateWebAppTarget = TargetDiscoveryHelpers.CreateWebAppTargetCreationServiceMessage(resourceGroupName, appName, AccountId, Role, null);

            log.StandardOut.Should().Contain(serviceMessageToCreateWebAppTarget.ToString(), "A target should be created for the web app itself as well as for the slots");

            // Assert
            foreach (var slotName in slotNames)
            {
                var serviceMessageToCreateTargetForSlot = TargetDiscoveryHelpers.CreateWebAppDeploymentSlotTargetCreationServiceMessage(resourceGroupName, appName, slotName, AccountId, Role, null);
                log.StandardOut.Should().Contain(serviceMessageToCreateTargetForSlot.ToString());
            }
        }
        public void SetUp()
        {
            log = new InMemoryLog();
            var variables = new CalamariVariableDictionary();

            configurationTransformer = ConfigurationTransformer.FromVariables(variables, log);
        }
Exemple #4
0
        public void ShouldGetTermAtIndex()
        {
            var log = new InMemoryLog();

            log.Apply(new LogEntry(new FakeCommand("test"), typeof(string), 1));
            log.GetTermAtIndex(1).ShouldBe(1);
        }
Exemple #5
0
        public void ShouldSetLastLogTerm()
        {
            var log = new InMemoryLog();

            log.Apply(new LogEntry(new FakeCommand("test"), typeof(string), 1));
            log.LastLogTerm.ShouldBe(1);
        }
Exemple #6
0
        public async Task Execute_WebAppWithNonMatchingTags_CreatesNoTargets()
        {
            // Arrange
            var variables = new CalamariVariables();
            var context   = new RunningDeployment(variables);

            this.CreateVariables(context);
            var log = new InMemoryLog();
            var sut = new TargetDiscoveryBehaviour(log);

            // Set expected tags on our web app
            var tags = new Dictionary <string, string>
            {
                { TargetTags.EnvironmentTagName, EnvironmentName },
                { TargetTags.RoleTagName, "a-different-role" },
            };

            await CreateOrUpdateTestWebApp(tags);

            // Act
            await sut.Execute(context);

            // Assert
            var serviceMessageToCreateWebAppTarget = TargetDiscoveryHelpers.CreateWebAppTargetCreationServiceMessage(resourceGroupName, appName, AccountId, Role, null);

            log.StandardOut.Should().NotContain(serviceMessageToCreateWebAppTarget.ToString(), "The web app target should not be created as the role tag did not match");
        }
Exemple #7
0
        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 void DeleteStack(string stackName)
        {
            var variablesFile = Path.GetTempFileName();
            var variables     = new CalamariVariables();

            variables.Set("Octopus.Action.AwsAccount.Variable", "AWSAccount");
            variables.Set("AWSAccount.AccessKey", ExternalVariables.Get(ExternalVariable.AwsAcessKey));
            variables.Set("AWSAccount.SecretKey", ExternalVariables.Get(ExternalVariable.AwsSecretKey));
            variables.Set("Octopus.Action.Aws.Region", region);
            variables.Set(AwsSpecialVariables.CloudFormation.StackName, stackName);
            variables.Save(variablesFile);

            using (new TemporaryFile(variablesFile))
            {
                var log     = new InMemoryLog();
                var command = new DeleteCloudFormationCommand(
                    log,
                    variables
                    );
                var result = command.Execute(new[]
                {
                    "--variables", $"{variablesFile}",
                    "--waitForCompletion", "true"
                });

                result.Should().Be(0);
            }
        }
Exemple #9
0
        public async Task ShouldSetLastLogTerm()
        {
            var log = new InMemoryLog();
            await log.Apply(new LogEntry(new FakeCommand("test"), typeof(string), 1));

            log.LastLogTerm().Result.ShouldBe(1);
        }
Exemple #10
0
        public void GetLoanInfo_ValidInput_ShouldReturnCorrectInfo()
        {
            var log      = new InMemoryLog();
            var strategy = new CompoundInterestCalculationStrategy();
            var engine   = new LoanCalculationEngine(strategy, log);

            double amount      = 100000;
            double interest    = 5.5;
            double downpayment = 20000;
            int    term        = 30;


            var loanInfo = engine.GetLoanInfo(amount, downpayment, interest, term);

            Assert.IsNotNull(loanInfo);
            Assert.AreEqual(loanInfo.Amount, amount);
            Assert.AreEqual(loanInfo.AnnualInterestRate, interest);
            Assert.AreEqual(loanInfo.DownPayment, downpayment);
            Assert.AreEqual(loanInfo.Terms, term);

            Assert.AreEqual(loanInfo.MonthlyPayment, 454.23);
            Assert.AreEqual(loanInfo.Principle, 80000);
            Assert.AreEqual(loanInfo.TotalInterest, 83522.8);
            Assert.AreEqual(loanInfo.TotalPayment, 163522.8);
        }
        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>>();
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }


            var log      = new InMemoryLog();
            var fsm      = new InMemoryStateMachine();
            var settings = new InMemorySettings(1000, 3500, 50, 5000);

            var _peers = new List <IPeer>();
            var peer1  = new NodePeer();

            _peers.Add(new NodePeer()
            {
            });
            var peersProvider = new InMemoryPeersProvider(_peers);
            var node          = new Node(fsm, log, settings, peersProvider, loggerFactory);

            node.Start(new NodeId("gsw" + DateTime.Now.ToString("HHmmssfff")));

            app.UseMvc();
        }
Exemple #13
0
        public async Task ShouldGetTermAtIndex()
        {
            var log = new InMemoryLog();
            await log.Apply(new LogEntry(new FakeCommand("test"), typeof(string), 1));

            log.GetTermAtIndex(1).Result.ShouldBe(1);
        }
Exemple #14
0
        public async Task ShouldAppendCommandToLocalLog()
        {
            _peers = new List <IPeer>();
            for (var i = 0; i < 4; i++)
            {
                var peer = new RemoteControledPeer();
                peer.SetAppendEntriesResponse(new AppendEntriesResponse(1, true));
                _peers.Add(peer);
            }
            var log = new InMemoryLog();

            _currentState = new CurrentState(_id, 0, default(string), 0, 0, default(string));
            var leader = new Leader(_currentState, _fsm, (s) => _peers, log, _node, _settings, _rules, _loggerFactory.Object);
            await leader.Accept(new FakeCommand());

            log.ExposedForTesting.Count.ShouldBe(1);

            bool PeersReceiveCorrectAppendEntries(List <IPeer> peers)
            {
                var passed = 0;

                peers.ForEach(p =>
                {
                    var rc = (RemoteControledPeer)p;
                    if (rc.AppendEntriesResponsesWithLogEntries == 1)
                    {
                        passed++;
                    }
                });

                return(passed == peers.Count);
            }

            var result = WaitFor(1000).Until(() => PeersReceiveCorrectAppendEntries(_peers));

            result.ShouldBeTrue();

            bool FirstTest(List <PeerState> peerState)
            {
                var passed = 0;

                peerState.ForEach(pS =>
                {
                    if (pS.MatchIndex.IndexOfHighestKnownReplicatedLog == 1)
                    {
                        passed++;
                    }

                    if (pS.NextIndex.NextLogIndexToSendToPeer == 2)
                    {
                        passed++;
                    }
                });

                return(passed == peerState.Count * 2);
            }

            result = WaitFor(1000).Until(() => FirstTest(leader.PeerStates));
            result.ShouldBeTrue();
        }
Exemple #15
0
        public async Task ShouldApplyLog()
        {
            var log   = new InMemoryLog();
            var index = await log.Apply(new LogEntry(new FakeCommand("test"), typeof(string), 1));

            index.ShouldBe(1);
        }
Exemple #16
0
        public void ShouldInitialiseCorrectly()
        {
            var log = new InMemoryLog();

            log.LastLogIndex().Result.ShouldBe(1);
            log.LastLogTerm().Result.ShouldBe(0);
        }
Exemple #17
0
        protected string UploadEntireCompressedPackage(string packageFilePath, string packageId, string packageVersion, List <S3PackageOptions> propertiesList, VariableDictionary customVariables = null)
        {
            var bucketKeyPrefix = $"calamaritest/{Guid.NewGuid():N}/";
            var variables       = new CalamariVariables();

            propertiesList.ForEach(properties =>
            {
                properties.BucketKeyPrefix = bucketKeyPrefix;
                variables.Set(AwsSpecialVariables.S3.PackageOptions, JsonConvert.SerializeObject(properties, GetEnrichedSerializerSettings()));
                variables.Set(PackageVariables.PackageId, packageId);
                variables.Set(PackageVariables.PackageVersion, packageVersion);
            });

            var variablesFile = Path.GetTempFileName();

            variables.Set("Octopus.Action.AwsAccount.Variable", "AWSAccount");
            variables.Set("AWSAccount.AccessKey", ExternalVariables.Get(ExternalVariable.AwsAcessKey));
            variables.Set("AWSAccount.SecretKey", ExternalVariables.Get(ExternalVariable.AwsSecretKey));
            variables.Set("Octopus.Action.Aws.Region", region);

            if (customVariables != null)
            {
                variables.Merge(customVariables);
            }

            variables.Save(variablesFile);

            using (new TemporaryFile(variablesFile))
            {
                var log        = new InMemoryLog();
                var fileSystem = CalamariPhysicalFileSystem.GetPhysicalFileSystem();

                var command = new UploadAwsS3Command(
                    log,
                    variables,
                    fileSystem,
                    new SubstituteInFiles(log, fileSystem, new FileSubstituter(log, fileSystem), variables),
                    new ExtractPackage(new CombinedPackageExtractor(log, variables, new CommandLineRunner(log, variables)), fileSystem, variables, log),
                    new StructuredConfigVariablesService(new PrioritisedList <IFileFormatVariableReplacer>
                {
                    new JsonFormatVariableReplacer(fileSystem, log),
                    new XmlFormatVariableReplacer(fileSystem, log),
                    new YamlFormatVariableReplacer(fileSystem, log),
                    new PropertiesFormatVariableReplacer(fileSystem, log),
                }, variables, fileSystem, log)
                    );

                var result = command.Execute(new[] {
                    "--package", $"{packageFilePath}",
                    "--variables", $"{variablesFile}",
                    "--bucket", bucketName,
                    "--targetMode", S3TargetMode.EntirePackage.ToString()
                });

                result.Should().Be(0);
            }

            return(bucketKeyPrefix);
        }
Exemple #18
0
        public void ShouldRemoveFromLog()
        {
            var log   = new InMemoryLog();
            var index = log.Apply(new LogEntry(new FakeCommand("test"), typeof(string), 1));

            log.Remove(index);
            log.Count.ShouldBe(0);
        }
Exemple #19
0
        ICombinedPackageExtractor CreatePackageExtractor()
        {
            var log               = new InMemoryLog();
            var variables         = new CalamariVariables();
            var commandLineRunner = new TestCommandLineRunner(log, variables);

            return(new CombinedPackageExtractor(log, variables, commandLineRunner));
        }
        public void Setup()
        {
            variables = new CalamariVariables();
            log       = new DoNotDoubleLog();
            redactMap = new Dictionary <string, string>();

            SetTestClusterVariables();
        }
Exemple #21
0
        public void ShouldNotDeleteConflict()
        {
            var log = new InMemoryLog();

            log.Apply(new LogEntry(new FakeCommand("test"), typeof(string), 1));
            log.DeleteConflictsFromThisLog(1, new LogEntry(new FakeCommand("test"), typeof(string), 1));
            log.ExposedForTesting.Count.ShouldBe(1);
        }
        public void WhenThereIsEnoughFreeSpace_NothingIsRemoved()
        {
            var fileSystem = new FileSystemThatHasSpace(1000, 1000);
            var log        = new InMemoryLog();
            var subject    = new PercentFreeDiskSpacePackageCleaner(fileSystem, new FirstInFirstOutJournalEntrySort(), Substitute.For <IVariables>(), log);
            var result     = subject.GetPackagesToRemove(MakeSomeJournalEntries());

            result.Should().BeEmpty();
        }
Exemple #23
0
        public async Task ShouldRemoveFromLog()
        {
            var log   = new InMemoryLog();
            var index = await log.Apply(new LogEntry(new FakeCommand("test"), typeof(string), 1));

            await log.Remove(index);

            log.Count().Result.ShouldBe(0);
        }
        public void Add(DateTimeOffset logDate, IEnumerable <IDEEvent> logEntries)
        {
            var log = new InMemoryLog {
                Date = logDate
            };

            logEntries.ForEach(log.Append);
            _logs.Add(logDate, log);
        }
Exemple #25
0
        public async Task ShouldDeleteConflict()
        {
            var log = new InMemoryLog();
            await log.Apply(new LogEntry(new FakeCommand("test"), typeof(string), 1));

            await log.DeleteConflictsFromThisLog(1, new LogEntry(new FakeCommand("test"), typeof(string), 2));

            log.ExposedForTesting.Count.ShouldBe(0);
        }
        public void WhenFreeingUpTwoPackagesWorthOfSpace_TwoPackagesAreMarkedForRemoval()
        {
            var fileSystem = new FileSystemThatHasSpace(1000, 10000);
            var log        = new InMemoryLog();
            var subject    = new PercentFreeDiskSpacePackageCleaner(fileSystem, new FirstInFirstOutJournalEntrySort(), Substitute.For <IVariables>(), log);
            var result     = subject.GetPackagesToRemove(MakeSomeJournalEntries());

            result.Count().Should().Be(2);
        }
Exemple #27
0
        public async Task ShouldBeDuplicate()
        {
            var log   = new InMemoryLog();
            var entry = new LogEntry(new FakeCommand("test"), typeof(string), 1);
            var index = await log.Apply(entry);

            var result = await log.IsDuplicate(index, entry);

            result.ShouldBeTrue();
        }
Exemple #28
0
        string Upload(string packageName, List <S3FileSelectionProperties> fileSelections)
        {
            var bucketKeyPrefix = $"calamaritest/{Guid.NewGuid():N}/";

            fileSelections.ForEach(properties =>
            {
                if (properties is S3MultiFileSelectionProperties multiFileSelectionProperties)
                {
                    multiFileSelectionProperties.BucketKeyPrefix = bucketKeyPrefix;
                }

                if (properties is S3SingleFileSelectionProperties singleFileSelectionProperties)
                {
                    singleFileSelectionProperties.BucketKeyPrefix = bucketKeyPrefix;
                }
            });

            var variablesFile = Path.GetTempFileName();
            var variables     = new CalamariVariables();

            variables.Set("Octopus.Action.AwsAccount.Variable", "AWSAccount");
            variables.Set("AWSAccount.AccessKey", Environment.GetEnvironmentVariable("AWS_Calamari_Access"));
            variables.Set("AWSAccount.SecretKey", Environment.GetEnvironmentVariable("AWS_Calamari_Secret"));
            variables.Set("Octopus.Action.Aws.Region", RegionEndpoint.APSoutheast1.SystemName);
            variables.Set(AwsSpecialVariables.S3.FileSelections,
                          JsonConvert.SerializeObject(fileSelections, GetEnrichedSerializerSettings()));
            variables.Save(variablesFile);

            var packageDirectory = TestEnvironment.GetTestPath("AWS", "S3", packageName);

            using (var package =
                       new TemporaryFile(PackageBuilder.BuildSimpleZip(packageName, "1.0.0", packageDirectory)))
                using (new TemporaryFile(variablesFile))
                {
                    var log        = new InMemoryLog();
                    var fileSystem = CalamariPhysicalFileSystem.GetPhysicalFileSystem();
                    var command    = new UploadAwsS3Command(
                        log,
                        variables,
                        fileSystem,
                        new SubstituteInFiles(fileSystem, new FileSubstituter(log, fileSystem), variables),
                        new ExtractPackage(new CombinedPackageExtractor(log), fileSystem, variables, log)
                        );
                    var result = command.Execute(new[] {
                        "--package", $"{package.FilePath}",
                        "--variables", $"{variablesFile}",
                        "--bucket", BucketName,
                        "--targetMode", S3TargetMode.FileSelections.ToString()
                    });

                    result.Should().Be(0);
                }

            return(bucketKeyPrefix);
        }
Exemple #29
0
        public LeaderRoleTests(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);

            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 <LeaderRole <int> >();
        }
Exemple #30
0
        private void StartServer(int index)
        {
            var log           = new InMemoryLog();
            var fsm           = new InMemoryStateMachine();
            var settings      = new InMemorySettingsBuilder().WithMinTimeout(1000).WithMaxTimeout(3500).WithHeartbeatTimeout(50).Build();
            var peersProvider = new InMemoryPeersProvider(_peers);
            var node          = new Node(fsm, log, settings, peersProvider);
            var server        = new Server(log, fsm, node);

            _servers.TryAdd(index, server);
        }
Exemple #31
0
        static void Main(string[] args)
        {
            var log = new InMemoryLog();

            var fsm      = new InMemoryStateMachine();
            var settings = new InMemorySettings(1000, 3500, 50, 5000);

            var _peers        = new List <IPeer>();
            var peersProvider = new InMemoryPeersProvider(_peers);
            var node          = new Node(fsm, log, settings, peersProvider, null);

            node.Start(new NodeId("gsw"));
        }
        public LeaderRoleTests(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);
            
            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<LeaderRole<int>>();
        }
        public void SmtpConversationShouldBeLogged()
        {
            var inMemoryLog = new InMemoryLog();

            var commandHandlerMock = new Mock<ISmtpServerCommandHandler>();
            commandHandlerMock.Setup(f => f.HandleHelo("example.com")).Returns(SmtpCommandReply.CreateDefault250SuccessTask);
            commandHandlerMock.Setup(f => f.HandleMailFrom("*****@*****.**")).Returns(SmtpCommandReply.CreateDefault250SuccessTask);
            commandHandlerMock.Setup(f => f.HandleRcptTo("*****@*****.**")).Returns(SmtpCommandReply.CreateDefault250SuccessTask);
            commandHandlerMock.Setup(f => f.HandleData(It.IsAny<MemoryStreamWithFileBacking>())).Returns(SmtpCommandReply.CreateDefault250SuccessTask);

            var data = "Hello World\r\n.\r\n";
            var memory = new MemoryStream(Encoding.UTF8.GetBytes(data));

            var connectionMock = ConnectionMockFactory.Create(new string[]
                {
                    "HELO example.com",
                    "MAIL FROM: [email protected]",
                    "RCPT TO: [email protected]",
                    "DATA",
                    "QUIT"
                }, new[]
                {
                    memory
                });

            SmtpServerSession session = new SmtpServerSession(commandHandlerMock.Object, inMemoryLog, new SmtpServerSessionConfiguration());

            var task = session.HandleConnection(connectionMock);
            task.Wait();

            var expectedLogEntries = new List<string>()
                {
                    "HELO example.com",
                    "MAIL FROM: [email protected]",
                    "RCPT TO: [email protected]",
                    "DATA",
                    "QUIT",

                    "250 Ok"
                };


            foreach (var expectedLogEntry in expectedLogEntries)
                Assert.IsTrue(inMemoryLog.LogEntries.Any(logEntry => logEntry.Item1.Message.Contains(expectedLogEntry)), expectedLogEntry);


        }