15 changed files with 191 additions and 18 deletions
@ -0,0 +1,18 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<RootNamespace /> |
|||
<IsPackable>false</IsPackable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.IdGenerator\LINGYUN.Abp.IdGenerator.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,42 @@ |
|||
using LINGYUN.Abp.Tests; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IdGenerator; |
|||
|
|||
public class AbpIdGeneratorModuleTestBase : AbpTestsBase<AbpIdGeneratorModuleTestModule> |
|||
{ |
|||
protected IDistributedIdGenerator DistributedIdGenerator { get; set; } |
|||
|
|||
private void GenerateId(long[] idArray, int startIndex, int endIndex) |
|||
{ |
|||
for (int i = startIndex; i < endIndex; i++) |
|||
{ |
|||
idArray[i] = DistributedIdGenerator.Create(); |
|||
} |
|||
} |
|||
|
|||
protected long[] GenerateIdInSingleThread(int countIds) |
|||
{ |
|||
long[] ids = new long[countIds]; |
|||
|
|||
GenerateId(ids, 0, ids.Length); |
|||
|
|||
return ids; |
|||
} |
|||
|
|||
protected long[] GenerateIdInMutiThread(int countThreads, int countIdsPerThread) |
|||
{ |
|||
List<Task> tasks = new(); |
|||
long[] idArray = new long[countThreads * countIdsPerThread]; |
|||
|
|||
for (int i = 0; i < countThreads; i++) |
|||
{ |
|||
int threadId = i; |
|||
tasks.Add(Task.Run(() => GenerateId(idArray, threadId * countIdsPerThread, (threadId + 1) * countIdsPerThread))); |
|||
} |
|||
Task.WaitAll(tasks.ToArray()); |
|||
|
|||
return idArray; |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using LINGYUN.Abp.IdGenerator.Snowflake; |
|||
using LINGYUN.Abp.Tests; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.IdGenerator; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpIdGeneratorModule), |
|||
typeof(AbpTestsBaseModule))] |
|||
public class AbpIdGeneratorModuleTestModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<SnowflakeIdOptions>(options => |
|||
{ |
|||
options.WorkerId = 30010 - 30000; |
|||
options.WorkerIdBits = 5; |
|||
options.DatacenterId = 1; |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using Shouldly; |
|||
using System.Linq; |
|||
using Xunit; |
|||
|
|||
namespace LINGYUN.Abp.IdGenerator; |
|||
|
|||
public class IdGeneratorTests : AbpIdGeneratorModuleTestBase |
|||
{ |
|||
public IdGeneratorTests() |
|||
{ |
|||
DistributedIdGenerator = GetRequiredService<IDistributedIdGenerator>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void IdShouldBeUnique_SingleThread() |
|||
{ |
|||
const int countIds = 50000; |
|||
long[] ids = GenerateIdInSingleThread(countIds); |
|||
|
|||
var finalIds = ids.GroupBy(id => id).Select(d => d.Key).ToArray(); |
|||
finalIds.Length.ShouldBe(countIds); |
|||
} |
|||
|
|||
[Fact] |
|||
public void IdShouldBeUnique_MultiThread() |
|||
{ |
|||
const int countIdsPerThread = 50000; |
|||
const int countThreads = 8; |
|||
long[] ids = GenerateIdInMutiThread(countThreads, countIdsPerThread); |
|||
|
|||
var finalIds = ids.GroupBy(id => id).Select(d => d.Key).ToArray(); |
|||
finalIds.Length.ShouldBe(countThreads * countIdsPerThread); |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
using LINGYUN.Abp.IdGenerator.Snowflake; |
|||
using System; |
|||
using System.Linq; |
|||
using Shouldly; |
|||
using Xunit; |
|||
|
|||
namespace LINGYUN.Abp.IdGenerator; |
|||
|
|||
public class SnowflakeIdGeneratorTests : AbpIdGeneratorModuleTestBase |
|||
{ |
|||
public SnowflakeIdGeneratorTests() |
|||
{ |
|||
DistributedIdGenerator = null; |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(-1, 5)] |
|||
[InlineData(0, 5)] |
|||
[InlineData(10, 5)] |
|||
[InlineData(31, 5)] |
|||
[InlineData(32, 5)] |
|||
[InlineData(30010, 5)] |
|||
public void WorkerIdShouldInRange(int workerId, int workerIdBits) |
|||
{ |
|||
var snowflakeIdGenerator = SnowflakeIdGenerator.Create(new SnowflakeIdOptions |
|||
{ |
|||
WorkerId = workerId, |
|||
WorkerIdBits = workerIdBits |
|||
}); |
|||
|
|||
snowflakeIdGenerator.WorkerId.ShouldBeInRange(0, (long)Math.Pow(2, workerIdBits) - 1); |
|||
} |
|||
|
|||
[Fact] |
|||
public void BiggerWorkerIdMakeIdRepeated() |
|||
{ |
|||
var snowflakeIdGenerator = SnowflakeIdGenerator.Create(new SnowflakeIdOptions |
|||
{ |
|||
WorkerId = 30010, |
|||
WorkerIdBits = 5 |
|||
}); |
|||
snowflakeIdGenerator.GetType().GetProperty("WorkerId").SetValue(snowflakeIdGenerator, 30010); |
|||
DistributedIdGenerator = snowflakeIdGenerator; |
|||
|
|||
const int countIds = 50000; |
|||
long[] ids = GenerateIdInSingleThread(countIds); |
|||
|
|||
var finalIds = ids.GroupBy(id => id).Select(d => d.Key).ToArray(); |
|||
finalIds.Length.ShouldBeLessThan(countIds); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue