节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
3.57 KiB
Stardust
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using NewLife.Data;
using NewLife.Security;
using Stardust.Data;
using Stardust.Server;
using Xunit;

namespace ServerTest.Controllers;

/// <summary>应用日志接收测试。覆盖 Log/Post 的日志行解析落库与未启用应用拒收</summary>
[Collection(StarTestServerCollection.Name)]
public class LogPostTests : StarTestBase
{
    public LogPostTests(StarTestServer fixture) : base(fixture) { }

    /// <summary>按应用查询当日日志。AppClientLog 按编号时间分表,需走分表感知查询</summary>
    private static IList<AppClientLog> SearchToday(Int32 appId)
        => AppClientLog.Search(appId, null, 0, DateTime.Today, DateTime.Today.AddDays(1), null, new PageParameter { PageSize = 100 });

    private async Task<String> PostAsync(String appName, String content)
    {
        var client = _server.CreateClient();
        client.DefaultRequestHeaders.Add("X-AppId", appName);
        client.DefaultRequestHeaders.Add("X-ClientId", "log-client@1");

        var resp = await client.PostAsync("/Log", new StringContent(content, Encoding.UTF8, "text/plain"));

        return $"{(Int32)resp.StatusCode}:{await resp.Content.ReadAsStringAsync()}";
    }

    /// <summary>等待日志异步落库</summary>
    private static IList<AppClientLog> WaitLogs(Int32 appId)
    {
        for (var i = 0; i < 25; i++)
        {
            var list = SearchToday(appId);
            if (list.Count > 0) return list;

            Thread.Sleep(200);
        }

        return SearchToday(appId);
    }

    [Fact(DisplayName = "上报日志行被解析并写入应用客户端日志")]
    public async Task Post_LogLines_ParsedAndSaved()
    {
        var name = "lpa_" + Rand.NextString(8);
        var app = new App { Name = name, Secret = "log-secret", Enable = true };
        app.Insert();

        try
        {
            // 格式:时间(12字符) 线程 类型 名称 消息,后续非日志行并入上一条消息
            var content = "00:00:04.205  7 Y NewLife.Core Hello Stardust\r\nsecond line of message\r\n";
            var status = await PostAsync(name, content);

            var list = WaitLogs(app.Id);
            Assert.True(list.Count > 0, "应写入应用客户端日志,POST 响应:" + status);

            var log = list[0];
            Assert.Equal(app.Id, log.AppId);
            Assert.Equal("00:00:04.205", log.Time);
            Assert.Equal("7", log.ThreadId);
            Assert.Equal("Y", log.Kind);
            Assert.Equal("NewLife.Core", log.Name);
            Assert.Contains("Hello Stardust", log.Message);
            Assert.Contains("second line of message", log.Message);
            Assert.Equal("log-client@1", log.ClientId);
        }
        finally
        {
            foreach (var item in SearchToday(app.Id))
            {
                item.Delete();
            }
            app.Delete();
        }
    }

    [Fact(DisplayName = "未启用应用上报日志被忽略")]
    public async Task Post_DisabledApp_Ignored()
    {
        var name = "lpd_" + Rand.NextString(8);
        var app = new App { Name = name, Secret = "log-secret", Enable = false };
        app.Insert();

        try
        {
            await PostAsync(name, "00:00:04.205  7 Y NewLife.Core should be ignored\r\n");

            Assert.Empty(SearchToday(app.Id));
        }
        finally
        {
            app.Delete();
        }
    }
}