using System; using System.Data.Common; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Hosting.Internal; using Microsoft.Extensions.Logging; using Microsoft.Extensions.OptionsModel; using Yavsc.Lib; using Yavsc.Services; using Yavsc; using Yavsc.Models; using Xunit; using Npgsql; using Microsoft.Data.Entity; using Microsoft.Data.Entity.Metadata.Conventions; using yavscTests.Settings; using System.Threading.Tasks; using System.IO; namespace yavscTests { [Trait("regression", "II")] public class ServerSideFixture : IDisposable { SiteSettings _siteSetup; ILogger _logger; IApplication _app; readonly EMailer _mailer; readonly ILoggerFactory _loggerFactory; IEmailSender _mailSender; public string ApiKey { get; private set; } public ApplicationDbContext DbContext { get; private set; } public SiteSettings SiteSetup { get { return _siteSetup; } set { _siteSetup = value; } } /// /// initialized by Init /// /// public TestingSetup TestingSetup { get; private set; } public IEmailSender MailSender { get { return _mailSender; } set { _mailSender = value; } } public IApplication App { get { return _app; } set { _app = value; } } internal int UpgradeDb() { return Microsoft.Data.Entity.Commands.Program.Main( new string[] { "database", "update" }); } public ILogger Logger { get { return _logger; } set { _logger = value; } } bool dbCreated; public WebHostBuilder Host { get; private set; } private readonly IHostingEngine hostengnine; void AssertNotNull(object obj, string msg) { if (obj == null) throw new Exception(msg); } // public ServerSideFixture() { Host = new WebHostBuilder(); AssertNotNull(Host, nameof(Host)); hostengnine = Host .UseEnvironment("Testing") .UseServer("yavscTests") .UseStartup() .Build(); AssertNotNull(hostengnine, nameof(hostengnine)); App = hostengnine.Start(); AssertNotNull(App, nameof(App)); // hostengnine.ApplicationServices _mailer = App.Services.GetService(typeof(EMailer)) as EMailer; AssertNotNull(_mailer, nameof(_mailer)); MailSender = App.Services.GetService(typeof(IEmailSender)) as IEmailSender; AssertNotNull(MailSender, nameof(MailSender)); _loggerFactory = App.Services.GetService(typeof(ILoggerFactory)) as ILoggerFactory; AssertNotNull(_loggerFactory, nameof(_loggerFactory)); var siteSetup = App.Services.GetService(typeof(IOptions)) as IOptions; AssertNotNull(siteSetup, nameof(siteSetup)); var testingSetup = App.Services.GetService(typeof(IOptions)) as IOptions; AssertNotNull(testingSetup, nameof(testingSetup)); DbContext = App.Services.GetService(typeof(ApplicationDbContext)) as ApplicationDbContext; SiteSetup = siteSetup.Value; AssertNotNull(SiteSetup, nameof(SiteSetup)); TestingSetup = testingSetup.Value; AssertNotNull(TestingSetup, nameof(TestingSetup)); Logger = _loggerFactory.CreateLogger(); AssertNotNull(Logger, nameof(Logger)); var builder = new DbConnectionStringBuilder { ConnectionString = Startup.TestingSetup.ConnectionStrings.Default }; ConventionSet conventions = new ConventionSet(); modelBuilder = new ModelBuilder(conventions); ApplicationDbContext context = new ApplicationDbContext(); TestingDatabase = (string)builder["Database"]; AssertNotNull(TestingDatabase, nameof(TestingDatabase)); Logger.LogInformation("ServerSideFixture created."); } private readonly ModelBuilder modelBuilder; public string TestingDatabase { get; private set; } public void CheckDbExistence() { using ( NpgsqlConnection cx = new NpgsqlConnection(Startup.TestingSetup.ConnectionStrings.Default)) { cx.Open(); _logger.LogInformation($"check db for TestingDatabase:{TestingDatabase}"); var command = cx.CreateCommand(); command.CommandText = $"SELECT 1 FROM pg_database WHERE datname='{TestingDatabase}';"; dbCreated = (command.ExecuteScalar()!=null); _logger.LogInformation($"DbCreated:{dbCreated}"); cx.Close(); } } public bool EnsureTestDb() { if (!DbCreated) { using (NpgsqlConnection cx = new NpgsqlConnection(Startup.TestingSetup.ConnectionStrings.DatabaseCtor)) { _logger.LogInformation($"create database for TestingDatabase : {TestingDatabase}"); cx.Open(); var command = cx.CreateCommand(); using (NpgsqlConnection ownercx = new NpgsqlConnection(Startup.TestingSetup.ConnectionStrings.Default)) command.CommandText = $"create database \"{TestingDatabase}\" OWNER \"{ownercx.UserName}\";"; _logger.LogInformation(command.CommandText); command.ExecuteNonQuery(); cx.Close(); } dbCreated = true; } return dbCreated; } public void DropTestDb() { if (dbCreated) DbContext.Database.EnsureDeleted(); dbCreated = false; } public bool EnsureWeb() { if (WebApp!=null) return true; Task.Run(() => { var di = new DirectoryInfo(Startup.TestingSetup.YavscWebPath); Assert.True(di.Exists); Environment.CurrentDirectory = di.FullName; WebHostBuilder = new WebHostBuilder(); webhostengnine = WebHostBuilder .UseEnvironment("Development") .UseServer("yavscTests") .UseStartup() .Build(); WebApp = webhostengnine.Start(); }).Wait(); return true; } public void Dispose() { if (DbCreated) DropTestDb(); if (WebApp!=null) WebApp.Dispose(); if (Logger!=null) Logger.LogInformation("Disposing"); } public bool DbCreated { get { try { CheckDbExistence(); } catch (Exception ex) { _logger.LogError(ex.Message); _logger.LogError(ex.StackTrace); } return dbCreated; } } public WebHostBuilder WebHostBuilder { get; private set; } private IHostingEngine webhostengnine; public IApplication WebApp { get; private set; } } }