From d4833c4cac935258b7ac1369e4c47c9b84c683dd Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Tue, 24 Dec 2019 16:55:51 +0000 Subject: [PATCH] Docker upgraded --- .../Common/DockerHelper.cs | 270 +++++++----------- .../Common/GenericSteps.cs | 40 +-- .../Common/Setup.cs | 86 +----- ...ansactionProcessor.IntegrationTests.csproj | 5 +- 4 files changed, 132 insertions(+), 269 deletions(-) diff --git a/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs b/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs index b037b0b2..af1c6ee3 100644 --- a/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs +++ b/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs @@ -2,11 +2,13 @@ { using System; using System.Collections.Generic; + using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Client; using Ductus.FluentDocker.Builders; + using Ductus.FluentDocker.Common; using Ductus.FluentDocker.Executors; using Ductus.FluentDocker.Extensions; using Ductus.FluentDocker.Model.Builders; @@ -16,209 +18,139 @@ using global::Shared.Logger; using SecurityService.Client; - public class DockerHelper + public class DockerHelper : global::Shared.IntegrationTesting.DockerHelper { private readonly NlogLogger Logger; - protected INetworkService TestNetwork; - - public Int32 SecurityServicePort; - protected Int32 EstateManagementPort; - protected Int32 TransactionProcessorPort; - protected Int32 EventStorePort; - - public IContainerService SecurityServiceContainer; - public IContainerService EstateManagementContainer; - public IContainerService TransactionProcessorContainer; - protected IContainerService EventStoreContainer; - - public IEstateClient EstateClient; - public ITransactionProcessorClient TransactionProcessorClient; - public ISecurityServiceClient SecurityServiceClient; - - protected String EventStoreConnectionString; - - public String SecurityServiceContainerName; - protected String EstateManagementContainerName; - protected String TransactionProcessorContainerName; - protected String EventStoreContainerName; - public DockerHelper(NlogLogger logger) { this.Logger = logger; + this.Containers = new List(); + this.TestNetworks = new List(); } - private void SetupTestNetwork() - { - // Build a network - this.TestNetwork = new Ductus.FluentDocker.Builders.Builder().UseNetwork($"testnetwork{Guid.NewGuid()}").Build(); - } public Guid TestId; - private void SetupEventStoreContainer(String traceFolder) - { - // Event Store Container - this.EventStoreContainer = new Ductus.FluentDocker.Builders.Builder() - .UseContainer() - .UseImage("eventstore/eventstore:release-5.0.2") - .ExposePort(2113) - .ExposePort(1113) - .WithName(this.EventStoreContainerName) - .WithEnvironment("EVENTSTORE_RUN_PROJECTIONS=all", "EVENTSTORE_START_STANDARD_PROJECTIONS=true") - .UseNetwork(this.TestNetwork) - .Mount(traceFolder, "/var/log/eventstore", MountType.ReadWrite) - .Build() - .Start().WaitForPort("2113/tcp", 30000); - } - public async Task StartContainersForScenarioRun(String scenarioName) + protected List Containers; + + protected List TestNetworks; + + public override async Task StartContainersForScenarioRun(String scenarioName) { - String traceFolder = $"/home/ubuntu/estatemanagement/trace/{scenarioName}/"; + String traceFolder = FdOs.IsWindows() ? $"D:\\home\\txnproc\\trace\\{scenarioName}" : $"//home//txnproc//trace//{scenarioName}"; Logging.Enabled(); Guid testGuid = Guid.NewGuid(); this.TestId = testGuid; + this.Logger.LogInformation($"Test Id is {testGuid}"); + // Setup the container names - this.SecurityServiceContainerName = $"securityservice{testGuid:N}"; - this.EstateManagementContainerName = $"estate{testGuid:N}"; - this.TransactionProcessorContainerName = $"txnprocessor{testGuid:N}"; - this.EventStoreContainerName = $"eventstore{testGuid:N}"; - - this.EventStoreConnectionString = - $"EventStoreSettings:ConnectionString=ConnectTo=tcp://admin:changeit@{this.EventStoreContainerName}:1113;VerboseLogging=true;"; - - this.SetupTestNetwork(); - this.SetupSecurityServiceContainer(traceFolder); - this.SetupEventStoreContainer(traceFolder); - this.SetupEstateManagementContainer(traceFolder); - this.SetupTransactionProcessorContainer(traceFolder); + String securityServiceContainerName = $"securityservice{testGuid:N}"; + String estateManagementApiContainerName = $"estate{testGuid:N}"; + String transactionProcessorContainerName = $"txnprocessor{testGuid:N}"; + String eventStoreContainerName = $"eventstore{testGuid:N}"; + + (String, String, String) dockerCredentials = ("https://www.docker.com", "stuartferguson", "Sc0tland"); + + INetworkService testNetwork = DockerHelper.SetupTestNetwork(); + this.TestNetworks.Add(testNetwork); + IContainerService eventStoreContainer = + DockerHelper.SetupEventStoreContainer(eventStoreContainerName, this.Logger, "eventstore/eventstore:release-5.0.2", testNetwork, traceFolder); + + + IContainerService estateManagementContainer = DockerHelper.SetupEstateManagementContainer(estateManagementApiContainerName, + this.Logger, + "stuartferguson/estatemanagement", + new List + { + testNetwork + }, + traceFolder, + dockerCredentials, + securityServiceContainerName, + eventStoreContainerName); + + IContainerService securityServiceContainer = DockerHelper.SetupSecurityServiceContainer(securityServiceContainerName, + this.Logger, + "stuartferguson/securityservice", + testNetwork, + traceFolder, + dockerCredentials); + + IContainerService transactionProcessorContainer = DockerHelper.SetupTransactionProcessorContainer(transactionProcessorContainerName, + this.Logger, + "transactionprocessor", + new List + { + testNetwork + }, + traceFolder, + dockerCredentials, + securityServiceContainerName, + eventStoreContainerName); + + + this.Containers.AddRange(new List + { + eventStoreContainer, + estateManagementContainer, + securityServiceContainer, + transactionProcessorContainer + }); // Cache the ports - this.EstateManagementPort = this.EstateManagementContainer.ToHostExposedEndpoint("5000/tcp").Port; - this.TransactionProcessorPort = this.TransactionProcessorContainer.ToHostExposedEndpoint("5002/tcp").Port; - this.EventStorePort = this.EventStoreContainer.ToHostExposedEndpoint("2113/tcp").Port; - this.SecurityServicePort = this.SecurityServiceContainer.ToHostExposedEndpoint("5001/tcp").Port; + this.EstateManagementApiPort = estateManagementContainer.ToHostExposedEndpoint("5000/tcp").Port; + this.SecurityServicePort = securityServiceContainer.ToHostExposedEndpoint("5001/tcp").Port; + this.EventStoreHttpPort = eventStoreContainer.ToHostExposedEndpoint("2113/tcp").Port; + this.TransactionProcessorPort = transactionProcessorContainer.ToHostExposedEndpoint("5002/tcp").Port; - // Setup the base address resolver - Func estateManagementBaseAddressResolver = api => $"http://127.0.0.1:{this.EstateManagementPort}"; - Func transactionProcessorBaseAddressResolver = api => $"http://127.0.0.1:{this.TransactionProcessorPort}"; - Func securityServiceBaseAddressResolver = api => $"http://127.0.0.1:{this.SecurityServicePort}"; + // Setup the base address resolvers + String EstateManagementBaseAddressResolver(String api) => $"http://127.0.0.1:{this.EstateManagementApiPort}"; + String SecurityServiceBaseAddressResolver(String api) => $"http://127.0.0.1:{this.SecurityServicePort}"; + String TransactionProcessorBaseAddressResolver(String api) => $"http://127.0.0.1:{this.TransactionProcessorPort}"; HttpClient httpClient = new HttpClient(); - this.EstateClient = new EstateClient(estateManagementBaseAddressResolver, httpClient); - this.TransactionProcessorClient = new TransactionProcessorClient(transactionProcessorBaseAddressResolver, httpClient); - this.SecurityServiceClient = new SecurityServiceClient(securityServiceBaseAddressResolver, httpClient); - // TODO: Use this to talk to txn processor until we have a client - //this.HttpClient = new HttpClient(); - //this.HttpClient.BaseAddress = new Uri(transactionProcessorBaseAddressResolver(String.Empty)); + this.EstateClient = new EstateClient(EstateManagementBaseAddressResolver, httpClient); + this.SecurityServiceClient = new SecurityServiceClient(SecurityServiceBaseAddressResolver, httpClient); + this.TransactionProcessorClient = new TransactionProcessorClient(TransactionProcessorBaseAddressResolver, httpClient); } - public async Task StopContainersForScenarioRun() - { - try - { - if (this.SecurityServiceContainer != null) - { - this.SecurityServiceContainer.StopOnDispose = true; - this.SecurityServiceContainer.RemoveOnDispose = true; - this.SecurityServiceContainer.Dispose(); - } + public IEstateClient EstateClient; - if (this.TransactionProcessorContainer != null) - { - this.TransactionProcessorContainer.StopOnDispose = true; - this.TransactionProcessorContainer.RemoveOnDispose = true; - this.TransactionProcessorContainer.Dispose(); - } + public ITransactionProcessorClient TransactionProcessorClient; - if (this.EstateManagementContainer != null) - { - this.EstateManagementContainer.StopOnDispose = true; - this.EstateManagementContainer.RemoveOnDispose = true; - this.EstateManagementContainer.Dispose(); - } + public ISecurityServiceClient SecurityServiceClient; - if (this.EventStoreContainer != null) - { - this.EventStoreContainer.StopOnDispose = true; - this.EventStoreContainer.RemoveOnDispose = true; - this.EventStoreContainer.Dispose(); - } + protected Int32 EstateManagementApiPort; - if (this.TestNetwork != null) - { - this.TestNetwork.Stop(); - this.TestNetwork.Remove(true); - } - } - catch (Exception e) - { - Console.WriteLine(e); - } - } + protected Int32 SecurityServicePort; - private void SetupSecurityServiceContainer(String traceFolder) - { - this.Logger.LogInformation("About to Start Security Container"); - - this.SecurityServiceContainer = new Builder().UseContainer().WithName(this.SecurityServiceContainerName) - .WithEnvironment($"ServiceOptions:PublicOrigin=http://{this.SecurityServiceContainerName}:5001", - $"ServiceOptions:IssuerUrl=http://{this.SecurityServiceContainerName}:5001", - "ASPNETCORE_ENVIRONMENT=IntegrationTest", - "urls=http://*:5001") - .WithCredential("https://www.docker.com", "stuartferguson", "Sc0tland") - .UseImage("stuartferguson/securityservice").ExposePort(5001).UseNetwork(new List - { - this.TestNetwork - }.ToArray()) - .Mount(traceFolder, "/home/txnproc/trace", MountType.ReadWrite).Build().Start().WaitForPort("5001/tcp", 30000); - Thread.Sleep(20000); - - this.Logger.LogInformation("Security Service Container Started"); + protected Int32 EventStoreHttpPort; - } + protected Int32 TransactionProcessorPort; - private void SetupEstateManagementContainer(String traceFolder) + public override async Task StopContainersForScenarioRun() { - // Management API Container - this.EstateManagementContainer = new Builder() - .UseContainer() - .WithName(this.EstateManagementContainerName) - .WithEnvironment(this.EventStoreConnectionString, - $"AppSettings:SecurityService=http://{this.SecurityServiceContainerName}:5001", - $"SecurityConfiguration:Authority=http://{this.SecurityServiceContainerName}:5001", - "urls=http://*:5000") //, - //"AppSettings:MigrateDatabase=true", - //"EventStoreSettings:START_PROJECTIONS=true", - //"EventStoreSettings:ContinuousProjectionsFolder=/app/projections/continuous") - .WithCredential("https://www.docker.com", "stuartferguson", "Sc0tland") - .UseImage("stuartferguson/estatemanagement") - .ExposePort(5000) - .UseNetwork(new List { this.TestNetwork, Setup.DatabaseServerNetwork }.ToArray()) - .Mount(traceFolder, "/home", MountType.ReadWrite) - .Build() - .Start().WaitForPort("5000/tcp", 30000); - } + if (this.Containers.Any()) + { + foreach (IContainerService containerService in this.Containers) + { + containerService.StopOnDispose = true; + containerService.RemoveOnDispose = true; + containerService.Dispose(); + } + } - private void SetupTransactionProcessorContainer(String traceFolder) - { - // Management API Container - this.TransactionProcessorContainer = new Builder() - .UseContainer() - .WithName(this.TransactionProcessorContainerName) - .WithEnvironment(this.EventStoreConnectionString, - $"AppSettings:SecurityService=http://{this.SecurityServiceContainerName}:5001", - $"SecurityConfiguration:Authority=http://{this.SecurityServiceContainerName}:5001") //, - //"AppSettings:MigrateDatabase=true", - //"EventStoreSettings:START_PROJECTIONS=true", - //"EventStoreSettings:ContinuousProjectionsFolder=/app/projections/continuous") - .UseImage("transactionprocessor") - .ExposePort(5002) - .UseNetwork(new List { this.TestNetwork, Setup.DatabaseServerNetwork }.ToArray()) - .Mount(traceFolder, "/home", MountType.ReadWrite) - .Build() - .Start().WaitForPort("5002/tcp", 30000); + if (this.TestNetworks.Any()) + { + foreach (INetworkService networkService in this.TestNetworks) + { + networkService.Stop(); + networkService.Remove(true); + } + } } } } diff --git a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs index af7fc5de..35c6f4e8 100644 --- a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs +++ b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs @@ -53,29 +53,29 @@ public async Task StopSystem() { if (this.ScenarioContext.TestError != null) { - Exception currentEx = this.ScenarioContext.TestError; - Console.Out.WriteLine(currentEx.Message); - while (currentEx.InnerException != null) - { - currentEx = currentEx.InnerException; - Console.Out.WriteLine(currentEx.Message); - } + //Exception currentEx = this.ScenarioContext.TestError; + //Console.Out.WriteLine(currentEx.Message); + //while (currentEx.InnerException != null) + //{ + // currentEx = currentEx.InnerException; + // Console.Out.WriteLine(currentEx.Message); + //} - // The test has failed, grab the logs from all the containers - List containers = new List(); - containers.Add(this.TestingContext.DockerHelper.EstateManagementContainer); - containers.Add(this.TestingContext.DockerHelper.TransactionProcessorContainer); + //// The test has failed, grab the logs from all the containers + //List containers = new List(); + //containers.Add(this.TestingContext.DockerHelper.EstateManagementContainer); + //containers.Add(this.TestingContext.DockerHelper.TransactionProcessorContainer); - foreach (IContainerService containerService in containers) - { - ConsoleStream logStream = containerService.Logs(); - IList logData = logStream.ReadToEnd(); + //foreach (IContainerService containerService in containers) + //{ + // ConsoleStream logStream = containerService.Logs(); + // IList logData = logStream.ReadToEnd(); - foreach (String s in logData) - { - Console.Out.WriteLine(s); - } - } + // foreach (String s in logData) + // { + // Console.Out.WriteLine(s); + // } + //} } await this.TestingContext.DockerHelper.StopContainersForScenarioRun().ConfigureAwait(false); diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index fa311e6b..18299510 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -26,93 +26,23 @@ public class Setup [BeforeTestRun] protected static void GlobalSetup() { - ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(1); + (String, String, String) dockerCredentials = ("https://www.docker.com", "stuartferguson", "Sc0tland"); // Setup a network for the DB Server - DatabaseServerNetwork = new Builder().UseNetwork($"sharednetwork").ReuseIfExist().Build(); + DatabaseServerNetwork = global::Shared.IntegrationTesting.DockerHelper.SetupTestNetwork("sharednetwork", true); // Start the Database Server here - DbConnectionStringWithNoDatabase = StartMySqlContainerWithOpenConnection(); + DbConnectionStringWithNoDatabase = global::Shared.IntegrationTesting.DockerHelper.StartSqlContainerWithOpenConnection("shareddatabasesqlserver", + null, + "stuartferguson/subscriptionservicedatabasesqlserver", + Setup.DatabaseServerNetwork, + "", + dockerCredentials); } public static String GetConnectionString(String databaseName) { return $"{DbConnectionStringWithNoDatabase} database={databaseName};"; } - - private static String StartMySqlContainerWithOpenConnection() - { - String containerName = $"shareddatabasesqlserver"; - DatabaseServerContainer = new Ductus.FluentDocker.Builders.Builder() - .UseContainer() - .WithName(containerName) - .WithCredential("https://docker.io", "stuartferguson", "Sc0tland") - .UseImage("stuartferguson/subscriptionservicedatabasesqlserver") - .WithEnvironment("ACCEPT_EULA=Y", $"SA_PASSWORD=thisisalongpassword123!") - .ExposePort(1433) - .UseNetwork(DatabaseServerNetwork) - .KeepContainer() - .KeepRunning() - .ReuseIfExists() - .Build() - .Start() - .WaitForPort("1433/tcp", 30000); - - IPEndPoint sqlServerEndpoint = DatabaseServerContainer.ToHostExposedEndpoint("1433/tcp"); - - // Try opening a connection - Int32 maxRetries = 10; - Int32 counter = 1; - - String server = "127.0.0.1"; - String database = "SubscriptionServiceConfiguration"; - String user = "sa"; - String password = "thisisalongpassword123!"; - String port = sqlServerEndpoint.Port.ToString(); - - String connectionString = $"server={server},{port};user id={user}; password={password}; database={database};"; - - SqlConnection connection = new SqlConnection(connectionString); - - using (StreamWriter sw = new StreamWriter("C:\\Temp\\testlog.log", true)) - { - while (counter <= maxRetries) - { - try - { - sw.WriteLine($"Attempt {counter}"); - sw.WriteLine(DateTime.Now); - - connection.Open(); - - SqlCommand command = connection.CreateCommand(); - command.CommandText = "SELECT * FROM EventStoreServers"; - command.ExecuteNonQuery(); - - sw.WriteLine("Connection Opened"); - - connection.Close(); - - break; - } - catch (SqlException ex) - { - if (connection.State == ConnectionState.Open) - { - connection.Close(); - } - - sw.WriteLine(ex); - Thread.Sleep(20000); - } - finally - { - counter++; - } - } - } - - return $"server={containerName};user id={user}; password={password};"; - } } } diff --git a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj index b9f26ce0..25084415 100644 --- a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj +++ b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj @@ -7,13 +7,14 @@ - + - + +