节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
4.72 KiB
Stardust
using Stardust.Data.Platform;
using Xunit;

namespace ServerTest.Mcp;

/// <summary>MCP审计日志单元测试。覆盖审计实体CRUD、必填字段校验、搜索过滤</summary>
public class McpAuditTests
{
    [Fact(DisplayName = "审计日志-插入并查询")]
    public void InsertAndSearch()
    {
        var entity = new McpAudit
        {
            TokenId = 1,
            ToolName = "test_tool",
            ActionName = "test_action",
            Success = true,
            Duration = 100,
            CallerIp = "127.0.0.1",
        };

        try
        {
            var count = entity.Insert();
            Assert.True(count > 0);
            Assert.True(entity.Id > 0);

            var found = McpAudit.FindById(entity.Id);
            Assert.NotNull(found);
            Assert.Equal("test_tool", found.ToolName);
            Assert.Equal("test_action", found.ActionName);
            Assert.True(found.Success);
            Assert.Equal(100, found.Duration);
        }
        finally
        {
            entity.Delete();
        }
    }

    [Fact(DisplayName = "边界-失败调用审计")]
    public void FailedCall_AuditRecord()
    {
        var entity = new McpAudit
        {
            TokenId = 2,
            ToolName = "invoke_action",
            ActionName = "node_upgrade",
            Success = false,
            Duration = 5000,
            ErrorMessage = "Node not found",
            CallerIp = "10.0.0.1",
        };

        try
        {
            var count = entity.Insert();
            Assert.True(count > 0);

            var found = McpAudit.FindById(entity.Id);
            Assert.NotNull(found);
            Assert.False(found.Success);
            Assert.Equal("Node not found", found.ErrorMessage);
        }
        finally
        {
            entity.Delete();
        }
    }

    [Fact(DisplayName = "边界-零耗时审计")]
    public void ZeroDuration_AuditRecord()
    {
        var entity = new McpAudit
        {
            TokenId = 1,
            ToolName = "list_actions",
            Success = true,
            Duration = 0,
            CallerIp = "::1",
        };

        try
        {
            var count = entity.Insert();
            Assert.True(count > 0);

            var found = McpAudit.FindById(entity.Id);
            Assert.NotNull(found);
            Assert.Equal(0, found.Duration);
        }
        finally
        {
            entity.Delete();
        }
    }

    [Fact(DisplayName = "搜索-按TokenId过滤")]
    public void Search_ByTokenId()
    {
        var entity = new McpAudit
        {
            TokenId = 999,
            ToolName = "test_search",
            ActionName = "test_action",
            Success = true,
            Duration = 50,
            CallerIp = "127.0.0.1",
        };

        try
        {
            entity.Insert();

            var list = McpAudit.Search(999, null, DateTime.MinValue, DateTime.MinValue, null, null);
            Assert.NotEmpty(list);
            Assert.Contains(list, e => e.TokenId == 999);
        }
        finally
        {
            entity.Delete();
        }
    }

    [Fact(DisplayName = "边界-无匹配搜索返回空")]
    public void Search_NoMatch_ReturnsEmpty()
    {
        // 用专属 tokenId 验证 Search 的 tokenId 过滤语义,避免依赖全局空表。
        // 根因:集成测试用 Task.Run 异步写审计且未在测试库清理,共享 SQLite 库(Bin/*.db)长期累积残余行;
        // 原测试用 tokenId=-1(因 -1>0 为假不施加过滤)+ Between(MinValue,MinValue) 空操作,导致返回全部残余行。
        const Int32 sentinel = 91234567;
        var start = DateTime.Now.AddYears(-10);
        var end = DateTime.Now.AddYears(10);

        // 清理可能残留的同号行,保证断言只针对“过滤语义”而非全局空表
        foreach (var e in McpAudit.FindAll(McpAudit._.TokenId == sentinel)) e.Delete();

        var entity = new McpAudit
        {
            TokenId = sentinel,
            ToolName = "no_match_test",
            ActionName = "no_match_action",
            Success = true,
            Duration = 10,
            CallerIp = "127.0.0.1",
            CreateTime = DateTime.Now,
        };

        try
        {
            entity.Insert();

            // 不存在的 tokenId 查询 → 必须为空
            var results = McpAudit.Search(sentinel + 1, null, start, end, null, null);
            Assert.Empty(results);

            // 反向验证:存在的 tokenId 能精确命中(证明过滤生效,非空是数据污染而非逻辑错误)
            var matched = McpAudit.Search(sentinel, null, start, end, null, null);
            Assert.Single(matched);
        }
        finally
        {
            entity.Delete();
        }
    }
}