@@ -1,7 +0,0 @@ | |||
namespace DotNetCore.CAP.MongoDB.Test | |||
{ | |||
public class ConnectionUtil | |||
{ | |||
public static string ConnectionString = "mongodb://localhost:27017"; | |||
} | |||
} |
@@ -1,56 +0,0 @@ | |||
using System; | |||
using System.Threading; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Options; | |||
using MongoDB.Driver; | |||
namespace DotNetCore.CAP.MongoDB.Test | |||
{ | |||
public abstract class DatabaseTestHost : IDisposable | |||
{ | |||
private string _connectionString; | |||
protected IServiceProvider Provider { get; private set; } | |||
protected IMongoClient MongoClient => Provider.GetService<IMongoClient>(); | |||
protected IMongoDatabase Database => MongoClient.GetDatabase(MongoDBOptions.Value.DatabaseName); | |||
protected CapOptions CapOptions => Provider.GetService<IOptions<CapOptions>>().Value; | |||
protected IOptions<MongoDBOptions> MongoDBOptions => Provider.GetService<IOptions<MongoDBOptions>>(); | |||
protected DatabaseTestHost() | |||
{ | |||
CreateServiceCollection(); | |||
CreateDatabase(); | |||
} | |||
private void CreateDatabase() | |||
{ | |||
Provider.GetService<MongoDBStorage>().InitializeAsync(CancellationToken.None).GetAwaiter().GetResult(); | |||
} | |||
protected virtual void AddService(ServiceCollection serviceCollection) | |||
{ | |||
} | |||
private void CreateServiceCollection() | |||
{ | |||
var services = new ServiceCollection(); | |||
services.AddOptions(); | |||
services.AddLogging(); | |||
_connectionString = ConnectionUtil.ConnectionString; | |||
services.AddOptions<CapOptions>(); | |||
services.Configure<MongoDBOptions>(x => x.DatabaseConnection = _connectionString); | |||
services.AddSingleton<IMongoClient>(x => new MongoClient(_connectionString)); | |||
services.AddSingleton<MongoDBStorage>(); | |||
AddService(services); | |||
Provider = services.BuildServiceProvider(); | |||
} | |||
public void Dispose() | |||
{ | |||
MongoClient.DropDatabase(MongoDBOptions.Value.DatabaseName); | |||
} | |||
} | |||
} |
@@ -1,25 +0,0 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" /> | |||
<PackageReference Include="FluentAssertions" Version="5.5.3" /> | |||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> | |||
<PackageReference Include="xunit" Version="2.4.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | |||
<PrivateAssets>all</PrivateAssets> | |||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> | |||
</PackageReference> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\DotNetCore.CAP.MongoDB\DotNetCore.CAP.MongoDB.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -1,73 +0,0 @@ | |||
using System; | |||
using System.Linq; | |||
using DotNetCore.CAP.Dashboard.Monitoring; | |||
using DotNetCore.CAP.Infrastructure; | |||
using DotNetCore.CAP.Messages; | |||
using FluentAssertions; | |||
using Xunit; | |||
namespace DotNetCore.CAP.MongoDB.Test | |||
{ | |||
[Collection("MongoDB")] | |||
public class MongoDBMonitoringApiTest : DatabaseTestHost | |||
{ | |||
private readonly MongoDBMonitoringApi _api; | |||
public MongoDBMonitoringApiTest() | |||
{ | |||
_api = new MongoDBMonitoringApi(MongoClient, MongoDBOptions); | |||
var collection = Database.GetCollection<PublishedMessage>(MongoDBOptions.Value.PublishedCollection); | |||
collection.InsertMany(new[] | |||
{ | |||
new PublishedMessage | |||
{ | |||
Id = SnowflakeId.Default().NextId(), | |||
Added = DateTime.Now.AddHours(-1), | |||
StatusName = "Failed", | |||
Version = "v1", | |||
Content = "abc" | |||
}, | |||
new PublishedMessage | |||
{ | |||
Id = SnowflakeId.Default().NextId(), | |||
Added = DateTime.Now, | |||
StatusName = "Failed", | |||
Version = "v1", | |||
Content = "bbc" | |||
} | |||
}); | |||
} | |||
[Fact] | |||
public void HourlyFailedJobs_Test() | |||
{ | |||
var result = _api.HourlyFailedJobs(MessageType.Publish); | |||
result.Should().HaveCount(24); | |||
} | |||
[Fact] | |||
public void Messages_Test() | |||
{ | |||
var messages = | |||
_api.Messages(new MessageQueryDto | |||
{ | |||
MessageType = MessageType.Publish, | |||
StatusName = StatusName.Failed, | |||
Content = "b", | |||
CurrentPage = 1, | |||
PageSize = 1 | |||
}); | |||
messages.Should().HaveCount(1); | |||
messages.First().Content.Should().Contain("b"); | |||
} | |||
[Fact] | |||
public void PublishedFailedCount_Test() | |||
{ | |||
var count = _api.PublishedFailedCount(); | |||
count.Should().BeGreaterThan(1); | |||
} | |||
} | |||
} |
@@ -1,85 +0,0 @@ | |||
using System; | |||
using DotNetCore.CAP.Infrastructure; | |||
using DotNetCore.CAP.Messages; | |||
using FluentAssertions; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using MongoDB.Driver; | |||
using Xunit; | |||
namespace DotNetCore.CAP.MongoDB.Test | |||
{ | |||
[Collection("MongoDB")] | |||
public class MongoDBStorageConnectionTest : DatabaseTestHost | |||
{ | |||
private IStorageConnection _connection => | |||
Provider.GetService<MongoDBStorage>().GetConnection(); | |||
[Fact] | |||
public void StoreReceivedMessageAsync_TestAsync() | |||
{ | |||
var messageContext = new MessageContext | |||
{ | |||
Group = "test", | |||
Name = "test", | |||
Content = "test-content" | |||
}; | |||
_connection.StoreReceivedMessage(new ReceivedMessage() | |||
{ | |||
Id = SnowflakeId.Default().NextId(), | |||
Group=messageContext.Group, | |||
Content=messageContext.Content, | |||
Name=messageContext.Name, | |||
Version="v1" | |||
}); | |||
} | |||
[Fact] | |||
public void ChangeReceivedState_Test() | |||
{ | |||
StoreReceivedMessageAsync_TestAsync(); | |||
var collection = Database.GetCollection<ReceivedMessage>(MongoDBOptions.Value.ReceivedCollection); | |||
var msg = collection.Find(x => true).FirstOrDefault(); | |||
_connection.ChangeReceivedState(msg.Id, StatusName.Scheduled).Should().BeTrue(); | |||
collection.Find(x => x.Id == msg.Id).FirstOrDefault()?.StatusName.Should().Be(StatusName.Scheduled); | |||
} | |||
[Fact] | |||
public async void GetReceivedMessagesOfNeedRetry_TestAsync() | |||
{ | |||
var msgs = await _connection.GetReceivedMessagesOfNeedRetry(); | |||
msgs.Should().BeEmpty(); | |||
var id = SnowflakeId.Default().NextId(); | |||
var msg = new CapReceivedMessage | |||
{ | |||
Id = id, | |||
Group = "test", | |||
Name = "test", | |||
Content = "test-content", | |||
StatusName = StatusName.Failed | |||
}; | |||
_connection.StoreReceivedMessage(msg); | |||
var collection = Database.GetCollection<ReceivedMessage>(MongoDBOptions.Value.ReceivedCollection); | |||
var updateDef = Builders<ReceivedMessage> | |||
.Update.Set(x => x.Added, DateTime.Now.AddMinutes(-5)); | |||
await collection.UpdateOneAsync(x => x.Id == id, updateDef); | |||
msgs = await _connection.GetReceivedMessagesOfNeedRetry(); | |||
msgs.Should().HaveCountGreaterThan(0); | |||
} | |||
[Fact] | |||
public void GetReceivedMessageAsync_Test() | |||
{ | |||
var msg = _connection.GetReceivedMessageAsync(1); | |||
msg.Should().NotBeNull(); | |||
} | |||
} | |||
} |
@@ -1,21 +0,0 @@ | |||
using FluentAssertions; | |||
using MongoDB.Driver; | |||
using Xunit; | |||
namespace DotNetCore.CAP.MongoDB.Test | |||
{ | |||
[Collection("MongoDB")] | |||
public class MongoDBStorageTest : DatabaseTestHost | |||
{ | |||
[Fact] | |||
public void InitializeAsync_Test() | |||
{ | |||
var names = MongoClient.ListDatabaseNames()?.ToList(); | |||
names.Should().Contain(MongoDBOptions.Value.DatabaseName); | |||
var collections = Database.ListCollectionNames()?.ToList(); | |||
collections.Should().Contain(MongoDBOptions.Value.PublishedCollection); | |||
collections.Should().Contain(MongoDBOptions.Value.ReceivedCollection); | |||
} | |||
} | |||
} |
@@ -1,76 +0,0 @@ | |||
using System; | |||
using FluentAssertions; | |||
using MongoDB.Bson; | |||
using MongoDB.Driver; | |||
using Xunit; | |||
namespace DotNetCore.CAP.MongoDB.Test | |||
{ | |||
[Collection("MongoDB")] | |||
public class MongoDBTransactionTest : DatabaseTestHost | |||
{ | |||
[Fact] | |||
public void MongoDB_Connection_Test() | |||
{ | |||
var names = MongoClient.ListDatabaseNames(); | |||
names.ToList().Should().NotBeNullOrEmpty(); | |||
} | |||
[Fact(Skip = "Because of Appveyor dose not support MongoDB 4.0, so we skip this test for now.")] | |||
public void Transaction_Test() | |||
{ | |||
var document = new BsonDocument | |||
{ | |||
{ "name", "MongoDB" }, | |||
{ "type", "Database" }, | |||
{ "count", 1 }, | |||
{ "info", new BsonDocument | |||
{ | |||
{ "x", 203 }, | |||
{ "y", 102 } | |||
}} | |||
}; | |||
var db = MongoClient.GetDatabase("test"); | |||
var collection1 = db.GetCollection<BsonDocument>("test1"); | |||
var collection2 = db.GetCollection<BsonDocument>("test2"); | |||
using (var sesstion = MongoClient.StartSession()) | |||
{ | |||
sesstion.StartTransaction(); | |||
collection1.InsertOne(document); | |||
collection2.InsertOne(document); | |||
sesstion.CommitTransaction(); | |||
} | |||
var filter = new BsonDocument("name", "MongoDB"); | |||
collection1.CountDocuments(filter).Should().BeGreaterThan(0); | |||
collection2.CountDocuments(filter).Should().BeGreaterThan(0); | |||
} | |||
[Fact(Skip = "Because of Appveyor dose not support MongoDB 4.0, so we skip this test for now.")] | |||
public void Transaction_Rollback_Test() | |||
{ | |||
var document = new BsonDocument | |||
{ | |||
{"name", "MongoDB"}, | |||
{"date", DateTimeOffset.Now.ToString()} | |||
}; | |||
var db = MongoClient.GetDatabase("test"); | |||
var collection = db.GetCollection<BsonDocument>("test3"); | |||
var collection4 = db.GetCollection<BsonDocument>("test4"); | |||
using (var session = MongoClient.StartSession()) | |||
{ | |||
session.IsInTransaction.Should().BeFalse(); | |||
session.StartTransaction(); | |||
session.IsInTransaction.Should().BeTrue(); | |||
collection.InsertOne(session, document); | |||
collection4.InsertOne(session, new BsonDocument { { "name", "MongoDB" } }); | |||
session.AbortTransaction(); | |||
} | |||
var filter = new BsonDocument("name", "MongoDB"); | |||
collection.CountDocuments(filter).Should().Be(0); | |||
collection4.CountDocuments(filter).Should().Be(0); | |||
} | |||
} | |||
} |
@@ -1,47 +0,0 @@ | |||
using System; | |||
using Npgsql; | |||
namespace DotNetCore.CAP.PostgreSql.Test | |||
{ | |||
public static class ConnectionUtil | |||
{ | |||
private const string DatabaseVariable = "Cap_PostgreSql_DatabaseName"; | |||
private const string ConnectionStringTemplateVariable = "Cap_PostgreSql_ConnectionStringTemplate"; | |||
private const string MasterDatabaseName = "postgres"; | |||
private const string DefaultDatabaseName = @"DotNetCore.CAP.PostgreSql.Test"; | |||
private const string DefaultConnectionStringTemplate = | |||
@"Server=localhost;Database={0};UserId=postgres;Password=123123;"; | |||
public static string GetDatabaseName() | |||
{ | |||
return Environment.GetEnvironmentVariable(DatabaseVariable) ?? DefaultDatabaseName; | |||
} | |||
public static string GetMasterConnectionString() | |||
{ | |||
return string.Format(GetConnectionStringTemplate(), MasterDatabaseName); | |||
} | |||
public static string GetConnectionString() | |||
{ | |||
return string.Format(GetConnectionStringTemplate(), GetDatabaseName()); | |||
} | |||
private static string GetConnectionStringTemplate() | |||
{ | |||
return | |||
Environment.GetEnvironmentVariable(ConnectionStringTemplateVariable) ?? | |||
DefaultConnectionStringTemplate; | |||
} | |||
public static NpgsqlConnection CreateConnection(string connectionString = null) | |||
{ | |||
connectionString = connectionString ?? GetConnectionString(); | |||
var connection = new NpgsqlConnection(connectionString); | |||
connection.Open(); | |||
return connection; | |||
} | |||
} | |||
} |
@@ -1,66 +0,0 @@ | |||
using System.Threading; | |||
using Dapper; | |||
using Microsoft.EntityFrameworkCore; | |||
namespace DotNetCore.CAP.PostgreSql.Test | |||
{ | |||
public abstract class DatabaseTestHost : TestHost | |||
{ | |||
private static bool _sqlObjectInstalled; | |||
public static object _lock = new object(); | |||
protected override void PostBuildServices() | |||
{ | |||
base.PostBuildServices(); | |||
lock (_lock) | |||
{ | |||
if (!_sqlObjectInstalled) | |||
{ | |||
InitializeDatabase(); | |||
} | |||
} | |||
} | |||
public override void Dispose() | |||
{ | |||
DeleteAllData(); | |||
base.Dispose(); | |||
} | |||
private void InitializeDatabase() | |||
{ | |||
using (CreateScope()) | |||
{ | |||
var storage = GetService<PostgreSqlStorage>(); | |||
var token = new CancellationTokenSource().Token; | |||
CreateDatabase(); | |||
storage.InitializeAsync(token).GetAwaiter().GetResult(); | |||
_sqlObjectInstalled = true; | |||
} | |||
} | |||
private void CreateDatabase() | |||
{ | |||
var masterConn = ConnectionUtil.GetMasterConnectionString(); | |||
var databaseName = ConnectionUtil.GetDatabaseName(); | |||
using (var connection = ConnectionUtil.CreateConnection(masterConn)) | |||
{ | |||
connection.Execute($@" | |||
DROP DATABASE IF EXISTS ""{databaseName}""; | |||
CREATE DATABASE ""{databaseName}"";"); | |||
} | |||
} | |||
private void DeleteAllData() | |||
{ | |||
var conn = ConnectionUtil.GetConnectionString(); | |||
using (var connection = ConnectionUtil.CreateConnection(conn)) | |||
{ | |||
connection.Execute($@" | |||
TRUNCATE TABLE ""cap"".""published""; | |||
TRUNCATE TABLE ""cap"".""received"";"); | |||
} | |||
} | |||
} | |||
} |
@@ -1,24 +0,0 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Dapper" Version="1.60.6" /> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" /> | |||
<PackageReference Include="Npgsql" Version="4.0.6" /> | |||
<PackageReference Include="xunit" Version="2.4.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | |||
<PrivateAssets>all</PrivateAssets> | |||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> | |||
</PackageReference> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\DotNetCore.CAP.PostgreSql\DotNetCore.CAP.PostgreSql.csproj" /> | |||
<ProjectReference Include="..\..\src\DotNetCore.CAP\DotNetCore.CAP.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -1,98 +0,0 @@ | |||
using System; | |||
using System.Threading.Tasks; | |||
using Dapper; | |||
using DotNetCore.CAP.Infrastructure; | |||
using DotNetCore.CAP.Messages; | |||
using Microsoft.Extensions.Options; | |||
using Xunit; | |||
namespace DotNetCore.CAP.PostgreSql.Test | |||
{ | |||
[Collection("postgresql")] | |||
public class PostgreSqlStorageConnectionTest : DatabaseTestHost | |||
{ | |||
private PostgreSqlStorageConnection _storage; | |||
public PostgreSqlStorageConnectionTest() | |||
{ | |||
var options = GetService<IOptions<PostgreSqlOptions>>(); | |||
var capOptions = GetService<IOptions<CapOptions>>(); | |||
_storage = new PostgreSqlStorageConnection(options, capOptions); | |||
} | |||
[Fact] | |||
public async Task GetPublishedMessageAsync_Test() | |||
{ | |||
var sql = @"INSERT INTO ""cap"".""published""(""Id"",""Version"",""Name"",""Content"",""Retries"",""Added"",""ExpiresAt"",""StatusName"") VALUES(@Id,'v1',@Name,@Content,@Retries,@Added,@ExpiresAt,@StatusName);"; | |||
var insertedId = SnowflakeId.Default().NextId(); | |||
var publishMessage = new CapPublishedMessage | |||
{ | |||
Id = insertedId, | |||
Name = "PostgreSqlStorageConnectionTest", | |||
Content = "", | |||
StatusName = StatusName.Scheduled | |||
}; | |||
using (var connection = ConnectionUtil.CreateConnection()) | |||
{ | |||
await connection.ExecuteAsync(sql, publishMessage); | |||
} | |||
var message = await _storage.GetPublishedMessageAsync(insertedId); | |||
Assert.NotNull(message); | |||
Assert.Equal("PostgreSqlStorageConnectionTest", message.Name); | |||
Assert.Equal(StatusName.Scheduled, message.StatusName); | |||
} | |||
[Fact] | |||
public void StoreReceivedMessageAsync_Test() | |||
{ | |||
var receivedMessage = new CapReceivedMessage | |||
{ | |||
Id = SnowflakeId.Default().NextId(), | |||
Name = "PostgreSqlStorageConnectionTest", | |||
Content = "", | |||
Group = "mygroup", | |||
StatusName = StatusName.Scheduled | |||
}; | |||
Exception exception = null; | |||
try | |||
{ | |||
_storage.StoreReceivedMessage(receivedMessage); | |||
} | |||
catch (Exception ex) | |||
{ | |||
exception = ex; | |||
} | |||
Assert.Null(exception); | |||
} | |||
[Fact] | |||
public async Task GetReceivedMessageAsync_Test() | |||
{ | |||
var sql = $@" | |||
INSERT INTO ""cap"".""received""(""Id"",""Version"",""Name"",""Group"",""Content"",""Retries"",""Added"",""ExpiresAt"",""StatusName"") | |||
VALUES(@Id,'v1',@Name,@Group,@Content,@Retries,@Added,@ExpiresAt,@StatusName);"; | |||
var insertedId = SnowflakeId.Default().NextId(); | |||
var receivedMessage = new CapReceivedMessage | |||
{ | |||
Id = insertedId, | |||
Name = "PostgreSqlStorageConnectionTest", | |||
Content = "", | |||
Group = "mygroup", | |||
StatusName = StatusName.Scheduled | |||
}; | |||
using (var connection = ConnectionUtil.CreateConnection()) | |||
{ | |||
await connection.ExecuteAsync(sql, receivedMessage); | |||
} | |||
var message = await _storage.GetReceivedMessageAsync(insertedId); | |||
Assert.NotNull(message); | |||
Assert.Equal(StatusName.Scheduled, message.StatusName); | |||
Assert.Equal("PostgreSqlStorageConnectionTest", message.Name); | |||
Assert.Equal("mygroup", message.Group); | |||
} | |||
} | |||
} |
@@ -1,44 +0,0 @@ | |||
using Dapper; | |||
using Xunit; | |||
namespace DotNetCore.CAP.PostgreSql.Test | |||
{ | |||
[Collection("postgresql")] | |||
public class SqlServerStorageTest : DatabaseTestHost | |||
{ | |||
private readonly string _masterDbConnectionString; | |||
private readonly string _dbConnectionString; | |||
public SqlServerStorageTest() | |||
{ | |||
_masterDbConnectionString = ConnectionUtil.GetMasterConnectionString(); | |||
_dbConnectionString = ConnectionUtil.GetConnectionString(); | |||
} | |||
[Fact] | |||
public void Database_IsExists() | |||
{ | |||
using (var connection = ConnectionUtil.CreateConnection(_masterDbConnectionString)) | |||
{ | |||
var databaseName = ConnectionUtil.GetDatabaseName(); | |||
var sql = $@"select * from pg_database where datname = '{databaseName}'"; | |||
var result = connection.QueryFirstOrDefault<string>(sql); | |||
Assert.NotNull(result); | |||
Assert.True(databaseName.Equals(result, System.StringComparison.CurrentCultureIgnoreCase)); | |||
} | |||
} | |||
[Theory] | |||
[InlineData("cap.published")] | |||
[InlineData("cap.received")] | |||
public void DatabaseTable_IsExists(string tableName) | |||
{ | |||
using (var connection = ConnectionUtil.CreateConnection(_dbConnectionString)) | |||
{ | |||
var sql = $"SELECT to_regclass('{tableName}') is not null;"; | |||
var result = connection.QueryFirstOrDefault<bool>(sql); | |||
Assert.True(result); | |||
} | |||
} | |||
} | |||
} |
@@ -1,99 +0,0 @@ | |||
using System; | |||
using Microsoft.Extensions.DependencyInjection; | |||
namespace DotNetCore.CAP.PostgreSql.Test | |||
{ | |||
public abstract class TestHost : IDisposable | |||
{ | |||
protected IServiceCollection _services; | |||
protected string _connectionString; | |||
private IServiceProvider _provider; | |||
private IServiceProvider _scopedProvider; | |||
public TestHost() | |||
{ | |||
CreateServiceCollection(); | |||
PreBuildServices(); | |||
BuildServices(); | |||
PostBuildServices(); | |||
} | |||
protected IServiceProvider Provider => _scopedProvider ?? _provider; | |||
private void CreateServiceCollection() | |||
{ | |||
var services = new ServiceCollection(); | |||
services.AddOptions(); | |||
services.AddLogging(); | |||
_connectionString = ConnectionUtil.GetConnectionString(); | |||
services.AddOptions<CapOptions>(); | |||
services.Configure<PostgreSqlOptions>(x => x.ConnectionString = _connectionString); | |||
services.AddSingleton<PostgreSqlStorage>(); | |||
_services = services; | |||
} | |||
protected virtual void PreBuildServices() | |||
{ | |||
} | |||
private void BuildServices() | |||
{ | |||
_provider = _services.BuildServiceProvider(); | |||
} | |||
protected virtual void PostBuildServices() | |||
{ | |||
} | |||
public IDisposable CreateScope() | |||
{ | |||
var scope = CreateScope(_provider); | |||
var loc = scope.ServiceProvider; | |||
_scopedProvider = loc; | |||
return new DelegateDisposable(() => | |||
{ | |||
if (_scopedProvider == loc) | |||
{ | |||
_scopedProvider = null; | |||
} | |||
scope.Dispose(); | |||
}); | |||
} | |||
public IServiceScope CreateScope(IServiceProvider provider) | |||
{ | |||
var scope = provider.GetService<IServiceScopeFactory>().CreateScope(); | |||
return scope; | |||
} | |||
public T GetService<T>() => Provider.GetService<T>(); | |||
public T Ensure<T>(ref T service) | |||
where T : class | |||
=> service ?? (service = GetService<T>()); | |||
public virtual void Dispose() | |||
{ | |||
(_provider as IDisposable)?.Dispose(); | |||
} | |||
private class DelegateDisposable : IDisposable | |||
{ | |||
private Action _dispose; | |||
public DelegateDisposable(Action dispose) | |||
{ | |||
_dispose = dispose; | |||
} | |||
public void Dispose() | |||
{ | |||
_dispose(); | |||
} | |||
} | |||
} | |||
} |
@@ -1,47 +0,0 @@ | |||
using System; | |||
using System.Data.SqlClient; | |||
namespace DotNetCore.CAP.SqlServer.Test | |||
{ | |||
public static class ConnectionUtil | |||
{ | |||
private const string DatabaseVariable = "Cap_SqlServer_DatabaseName"; | |||
private const string ConnectionStringTemplateVariable = "Cap_SqlServer_ConnectionStringTemplate"; | |||
private const string MasterDatabaseName = "master"; | |||
private const string DefaultDatabaseName = @"DotNetCore.CAP.SqlServer.Test"; | |||
private const string DefaultConnectionStringTemplate = | |||
@"Server=192.168.2.206;Initial Catalog={0};User Id=sa;Password=123123;MultipleActiveResultSets=True"; | |||
public static string GetDatabaseName() | |||
{ | |||
return Environment.GetEnvironmentVariable(DatabaseVariable) ?? DefaultDatabaseName; | |||
} | |||
public static string GetMasterConnectionString() | |||
{ | |||
return string.Format(GetConnectionStringTemplate(), MasterDatabaseName); | |||
} | |||
public static string GetConnectionString() | |||
{ | |||
return string.Format(GetConnectionStringTemplate(), GetDatabaseName()); | |||
} | |||
private static string GetConnectionStringTemplate() | |||
{ | |||
return | |||
Environment.GetEnvironmentVariable(ConnectionStringTemplateVariable) ?? | |||
DefaultConnectionStringTemplate; | |||
} | |||
public static SqlConnection CreateConnection(string connectionString = null) | |||
{ | |||
connectionString = connectionString ?? GetConnectionString(); | |||
var connection = new SqlConnection(connectionString); | |||
connection.Open(); | |||
return connection; | |||
} | |||
} | |||
} |
@@ -1,82 +0,0 @@ | |||
using System; | |||
using System.Data; | |||
using System.Data.SqlClient; | |||
using Dapper; | |||
using DotNetCore.CAP.SqlServer.Diagnostics; | |||
using Microsoft.Extensions.Logging; | |||
using Microsoft.Extensions.Options; | |||
using Moq; | |||
namespace DotNetCore.CAP.SqlServer.Test | |||
{ | |||
public abstract class DatabaseTestHost : IDisposable | |||
{ | |||
protected ILogger<SqlServerStorage> Logger; | |||
protected IOptions<CapOptions> CapOptions; | |||
protected IOptions<SqlServerOptions> SqlSeverOptions; | |||
protected DiagnosticProcessorObserver DiagnosticProcessorObserver; | |||
public bool SqlObjectInstalled; | |||
protected DatabaseTestHost() | |||
{ | |||
Logger = new Mock<ILogger<SqlServerStorage>>().Object; | |||
var capOptions = new Mock<IOptions<CapOptions>>(); | |||
capOptions.Setup(x => x.Value).Returns(new CapOptions()); | |||
CapOptions = capOptions.Object; | |||
var options = new Mock<IOptions<SqlServerOptions>>(); | |||
options.Setup(x => x.Value).Returns(new SqlServerOptions { ConnectionString = ConnectionUtil.GetConnectionString() }); | |||
SqlSeverOptions = options.Object; | |||
DiagnosticProcessorObserver = new DiagnosticProcessorObserver(new Mock<IDispatcher>().Object); | |||
InitializeDatabase(); | |||
} | |||
public void Dispose() | |||
{ | |||
DeleteAllData(); | |||
} | |||
private void InitializeDatabase() | |||
{ | |||
var masterConn = ConnectionUtil.GetMasterConnectionString(); | |||
var databaseName = ConnectionUtil.GetDatabaseName(); | |||
using (var connection = ConnectionUtil.CreateConnection(masterConn)) | |||
{ | |||
connection.Execute($@" | |||
IF NOT EXISTS (SELECT * FROM sysdatabases WHERE name = N'{databaseName}') | |||
CREATE DATABASE [{databaseName}];"); | |||
} | |||
new SqlServerStorage(Logger, CapOptions, SqlSeverOptions, DiagnosticProcessorObserver).InitializeAsync().GetAwaiter().GetResult(); | |||
SqlObjectInstalled = true; | |||
} | |||
private void DeleteAllData() | |||
{ | |||
var conn = ConnectionUtil.GetConnectionString(); | |||
using (var connection = new SqlConnection(conn)) | |||
{ | |||
var commands = new[] { | |||
"DISABLE TRIGGER ALL ON ?", | |||
"ALTER TABLE ? NOCHECK CONSTRAINT ALL", | |||
"DELETE FROM ?", | |||
"ALTER TABLE ? CHECK CONSTRAINT ALL", | |||
"ENABLE TRIGGER ALL ON ?" | |||
}; | |||
foreach (var command in commands) | |||
{ | |||
connection.Execute( | |||
"sp_MSforeachtable", | |||
new { command1 = command }, | |||
commandType: CommandType.StoredProcedure); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -1,33 +0,0 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\DotNetCore.CAP.SqlServer\DotNetCore.CAP.SqlServer.csproj" /> | |||
<ProjectReference Include="..\..\src\DotNetCore.CAP\DotNetCore.CAP.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Dapper" Version="1.60.6" /> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" /> | |||
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> | |||
<PrivateAssets>all</PrivateAssets> | |||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> | |||
</PackageReference> | |||
<PackageReference Include="xunit" Version="2.4.1" /> | |||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /> | |||
<PackageReference Include="Moq" Version="4.10.1" /> | |||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.0" /> | |||
</ItemGroup> | |||
</Project> |
@@ -1,94 +0,0 @@ | |||
using System; | |||
using System.Threading.Tasks; | |||
using Dapper; | |||
using DotNetCore.CAP.Infrastructure; | |||
using DotNetCore.CAP.Messages; | |||
using Xunit; | |||
namespace DotNetCore.CAP.SqlServer.Test | |||
{ | |||
[Collection("sqlserver")] | |||
public class SqlServerStorageConnectionTest : DatabaseTestHost | |||
{ | |||
private readonly SqlServerStorageConnection _storage; | |||
public SqlServerStorageConnectionTest() | |||
{ | |||
_storage = new SqlServerStorageConnection(SqlSeverOptions, CapOptions); | |||
} | |||
[Fact] | |||
public async Task GetPublishedMessageAsync_Test() | |||
{ | |||
var sql = "INSERT INTO [Cap].[Published]([Id],[Version],[Name],[Content],[Retries],[Added],[ExpiresAt],[StatusName]) VALUES(@Id,'v1',@Name,@Content,@Retries,@Added,@ExpiresAt,@StatusName);"; | |||
var insertedId = SnowflakeId.Default().NextId(); | |||
var publishMessage = new CapPublishedMessage | |||
{ | |||
Id= insertedId, | |||
Name = "SqlServerStorageConnectionTest", | |||
Content = "", | |||
StatusName = StatusName.Scheduled | |||
}; | |||
using (var connection = ConnectionUtil.CreateConnection()) | |||
{ | |||
await connection.ExecuteAsync(sql, publishMessage); | |||
} | |||
var message = await _storage.GetPublishedMessageAsync(insertedId); | |||
Assert.NotNull(message); | |||
Assert.Equal("SqlServerStorageConnectionTest", message.Name); | |||
Assert.Equal(StatusName.Scheduled, message.StatusName); | |||
} | |||
[Fact] | |||
public void StoreReceivedMessageAsync_Test() | |||
{ | |||
var receivedMessage = new CapReceivedMessage | |||
{ | |||
Name = "SqlServerStorageConnectionTest", | |||
Content = "", | |||
Group = "mygroup", | |||
StatusName = StatusName.Scheduled | |||
}; | |||
Exception exception = null; | |||
try | |||
{ | |||
_storage.StoreReceivedMessage(receivedMessage); | |||
} | |||
catch (Exception ex) | |||
{ | |||
exception = ex; | |||
} | |||
Assert.Null(exception); | |||
} | |||
[Fact] | |||
public async Task GetReceivedMessageAsync_Test() | |||
{ | |||
var sql = @"INSERT INTO [Cap].[Received]([Id],[Version],[Name],[Group],[Content],[Retries],[Added],[ExpiresAt],[StatusName]) VALUES(@Id,'v1',@Name,@Group,@Content,@Retries,@Added,@ExpiresAt,@StatusName);"; | |||
var insertedId = SnowflakeId.Default().NextId(); | |||
var receivedMessage = new CapReceivedMessage | |||
{ | |||
Id= insertedId, | |||
Name = "SqlServerStorageConnectionTest", | |||
Content = "", | |||
Group = "mygroup", | |||
StatusName = StatusName.Scheduled | |||
}; | |||
using (var connection = ConnectionUtil.CreateConnection()) | |||
{ | |||
await connection.ExecuteAsync(sql, receivedMessage); | |||
} | |||
var message = await _storage.GetReceivedMessageAsync(insertedId); | |||
Assert.NotNull(message); | |||
Assert.Equal(StatusName.Scheduled, message.StatusName); | |||
Assert.Equal("SqlServerStorageConnectionTest", message.Name); | |||
Assert.Equal("mygroup", message.Group); | |||
} | |||
} | |||
} |
@@ -1,43 +0,0 @@ | |||
using Dapper; | |||
using Xunit; | |||
namespace DotNetCore.CAP.SqlServer.Test | |||
{ | |||
[Collection("sqlserver")] | |||
public class SqlServerStorageTest : DatabaseTestHost | |||
{ | |||
[Fact] | |||
public void Database_IsExists() | |||
{ | |||
var master = ConnectionUtil.GetMasterConnectionString(); | |||
using (var connection = ConnectionUtil.CreateConnection(master)) | |||
{ | |||
var databaseName = ConnectionUtil.GetDatabaseName(); | |||
var sql = $@" | |||
IF EXISTS (SELECT * FROM sysdatabases WHERE name = N'{databaseName}') | |||
SELECT 'True' | |||
ELSE | |||
SELECT 'False'"; | |||
var result = connection.QueryFirst<bool>(sql); | |||
Assert.True(result); | |||
} | |||
} | |||
[Theory] | |||
[InlineData("[Cap].[Published]")] | |||
[InlineData("[Cap].[Received]")] | |||
public void DatabaseTable_IsExists(string tableName) | |||
{ | |||
using (var connection = ConnectionUtil.CreateConnection()) | |||
{ | |||
var sql = $@" | |||
IF OBJECT_ID(N'{tableName}',N'U') IS NOT NULL | |||
SELECT 'True' | |||
ELSE | |||
SELECT 'False'"; | |||
var result = connection.QueryFirst<bool>(sql); | |||
Assert.True(result); | |||
} | |||
} | |||
} | |||
} |