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

namespace ServerTest.Controllers;

/// <summary>压缩埋点上报测试。覆盖 Trace/ReportRaw 的 JSON 与 GZip 两条读体路径,以及鉴权要求</summary>
[Collection(StarTestServerCollection.Name)]
public class TraceReportRawTests : StarTestBase
{
    public TraceReportRawTests(StarTestServer fixture) : base(fixture) { }

    private async Task<String> AppLoginTokenAsync(String appId, String secret)
    {
        var client = _server.CreateClient();
        var rs = await client.PostAsync<LoginResponse>("app/login", new { AppId = appId, Secret = secret });
        Assert.NotNull(rs?.Token);
        return rs.Token;
    }

    private static App CreateApp(String name, String secret)
    {
        var app = new App { Name = name, Secret = secret, Enable = true };
        app.Insert();

        // 埋点上报需要已存在的 AppTracer
        new AppTracer { Name = name, AppId = app.Id, Enable = true }.Insert();

        return app;
    }

    private async Task<String> ReportRawAsync(String appId, String token, Boolean gzip)
    {
        var json = $@"{{""AppId"":""{appId}"",""ClientId"":""raw-client""}}";

        HttpContent content;
        if (gzip)
        {
            var ms = new MemoryStream();
            using (var gs = new GZipStream(ms, CompressionMode.Compress, true))
            {
                var buf = json.GetBytes();
                gs.Write(buf, 0, buf.Length);
            }
            content = new ByteArrayContent(ms.ToArray());
            content.Headers.ContentType = new("application/x-gzip");
        }
        else
        {
            content = new StringContent(json, Encoding.UTF8, "application/json");
        }

        var client = _server.CreateClient();
        if (!token.IsNullOrEmpty()) client.DefaultRequestHeaders.Add("X-Token", token);

        var response = await client.PostAsync("/Trace/ReportRaw", content);
        return await response.Content.ReadAsStringAsync();
    }

    [Fact(DisplayName = "ReportRaw 接收明文 JSON 并返回采样策略")]
    public async Task ReportRaw_JsonBody_ReturnsPeriod()
    {
        var app = CreateApp("trw_" + Rand.NextString(8), "trw-secret");
        try
        {
            var token = await AppLoginTokenAsync(app.Name, "trw-secret");

            var body = await ReportRawAsync(app.Name, token, false);

            Assert.Contains("period", body, StringComparison.OrdinalIgnoreCase);
            Assert.DoesNotContain("匿名", body);
        }
        finally
        {
            AppTracer.FindByName(app.Name)?.Delete();
            app.Delete();
        }
    }

    [Fact(DisplayName = "ReportRaw 接收 GZip 压缩体并解压处理")]
    public async Task ReportRaw_GzipBody_ReturnsPeriod()
    {
        var app = CreateApp("trg_" + Rand.NextString(8), "trg-secret");
        try
        {
            var token = await AppLoginTokenAsync(app.Name, "trg-secret");

            var body = await ReportRawAsync(app.Name, token, true);

            Assert.Contains("period", body, StringComparison.OrdinalIgnoreCase);
            Assert.DoesNotContain("匿名", body);
        }
        finally
        {
            AppTracer.FindByName(app.Name)?.Delete();
            app.Delete();
        }
    }

    [Fact(DisplayName = "ReportRaw 未携带令牌时被拒绝")]
    public async Task ReportRaw_WithoutToken_Rejected()
    {
        var app = CreateApp("trn_" + Rand.NextString(8), "trn-secret");
        try
        {
            var body = await ReportRawAsync(app.Name, "", false);

            Assert.Contains("匿名", body);
        }
        finally
        {
            AppTracer.FindByName(app.Name)?.Delete();
            app.Delete();
        }
    }
}