节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
2.38 KiB
Stardust
using System;
using System.Collections.Concurrent;
using System.Reflection;
using System.Threading;
using NewLife;
using NewLife.Threading;
using Stardust.Data.Monitors;
using Stardust.Server.Services;
using Xunit;

namespace ServerTest.Services;

/// <summary>埋点项统计服务测试。覆盖入队去重、定时器开关与无数据时空跑(APM-5)</summary>
public class TraceItemStatServiceTests
{
    private static ConcurrentBag<Int32> GetBag(TraceItemStatService service)
    {
        var fi = typeof(TraceItemStatService).GetField("_bag", BindingFlags.NonPublic | BindingFlags.Instance);
        return (ConcurrentBag<Int32>)fi.GetValue(service);
    }

    private static TimerX GetTimer(TraceItemStatService service)
    {
        var fi = typeof(TraceItemStatService).GetField("_timer", BindingFlags.NonPublic | BindingFlags.Instance);
        return (TimerX)fi.GetValue(service);
    }

    [Fact(DisplayName = "同一应用重复入队只保留一条")]
    public void Add_Deduplicate()
    {
        var service = new TraceItemStatService(null) { BatchPeriod = 0 };
        try
        {
            service.Add(1001);
            service.Add(1001);
            service.Add(1002);

            var bag = GetBag(service);
            Assert.Equal(2, bag.Count);
            Assert.Contains(1001, bag);
            Assert.Contains(1002, bag);
        }
        finally
        {
            GetTimer(service)?.TryDispose();
        }
    }

    [Fact(DisplayName = "批计算周期为零时不启动定时器")]
    public void Add_NoTimer_WhenPeriodZero()
    {
        var service = new TraceItemStatService(null) { BatchPeriod = 0 };
        service.Add(2001);

        Assert.Null(GetTimer(service));
    }

    [Fact(DisplayName = "批计算周期为正时首次入队启动定时器")]
    public void Add_StartTimer_WhenPeriodPositive()
    {
        var service = new TraceItemStatService(null) { BatchPeriod = 3600 };
        try
        {
            service.Add(3001);

            Assert.NotNull(GetTimer(service));
        }
        finally
        {
            GetTimer(service)?.TryDispose();
        }
    }

    [Fact(DisplayName = "没有统计数据时处理空跑不抛异常")]
    public void Process_NoData_NoThrow()
    {
        var service = new TraceItemStatService(null);

        // 不存在应用编号,统计结果为空,不应抛异常
        service.Process(-99991, 1);
    }
}