You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
haoliang-net/tests/CncCollector.Tests/CollectorApiServerTests.cs

180 lines
7.0 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Xunit;
using CncCollector.Core;
using CncCollector.Api;
using CncCollector.Config;
namespace CncCollector.Tests
{
/// <summary>
/// CollectorApiServer 单元测试。
/// 使用无效DB配置创建引擎和API服务器通过HTTP客户端验证认证和路由行为。
/// </summary>
public class CollectorApiServerTests : IDisposable
{
private readonly CollectorEngine _engine;
private readonly CollectorApiServer _server;
private readonly HttpClient _client;
private readonly int _port;
private readonly string _apiKey = "test_api_key_123";
public CollectorApiServerTests()
{
// 使用随机端口避免冲突
_port = 15800 + new Random().Next(0, 1000);
var config = new CollectorConfig
{
BusinessConnection = "Server=invalid;Database=invalid;User Id=invalid;Password=invalid;",
LogConnection = "Server=invalid;Database=invalid;User Id=invalid;Password=invalid;",
ApiPort = _port
};
_engine = new CollectorEngine(config);
_server = new CollectorApiServer(_engine, _apiKey, _port);
_server.Start();
_client = new HttpClient { Timeout = TimeSpan.FromSeconds(5) };
}
public void Dispose()
{
_server?.Stop();
_client?.Dispose();
}
// ===== 认证测试 =====
[Fact]
public async Task Status_APIKey_401()
{
var resp = await _client.GetAsync($"http://localhost:{_port}/api/collector/status");
Assert.Equal(HttpStatusCode.Unauthorized, resp.StatusCode);
}
[Fact]
public async Task Status_APIKey_401()
{
var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
request.Headers.Add("X-Api-Key", "wrong_key");
var resp = await _client.SendAsync(request);
Assert.Equal(HttpStatusCode.Unauthorized, resp.StatusCode);
}
[Fact]
public async Task Status_APIKey_200()
{
var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
request.Headers.Add("X-Api-Key", _apiKey);
var resp = await _client.SendAsync(request);
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
}
// ===== 响应格式测试 =====
[Fact]
public async Task Status_JSON()
{
var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
request.Headers.Add("X-Api-Key", _apiKey);
var resp = await _client.SendAsync(request);
var body = await resp.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<Dictionary<string, object>>(body);
Assert.NotNull(json);
Assert.True(json.ContainsKey("code"));
Assert.True(json.ContainsKey("message"));
Assert.True(json.ContainsKey("data"));
}
[Fact]
public async Task Status_data()
{
var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
request.Headers.Add("X-Api-Key", _apiKey);
var resp = await _client.SendAsync(request);
var body = await resp.Content.ReadAsStringAsync();
dynamic json = JsonConvert.DeserializeObject(body);
Assert.Equal(0, (int)json.code);
Assert.NotNull(json.data);
Assert.NotNull(json.data.isRunning);
Assert.NotNull(json.data.workerCount);
Assert.NotNull(json.data.workers);
}
// ===== 路由测试 =====
[Fact]
public async Task UnknownEndpoint_404()
{
var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/nonexistent");
request.Headers.Add("X-Api-Key", _apiKey);
var resp = await _client.SendAsync(request);
Assert.Equal(HttpStatusCode.NotFound, resp.StatusCode);
}
[Fact]
public async Task Refresh_APIKey_200()
{
var request = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/refresh");
request.Headers.Add("X-Api-Key", _apiKey);
var resp = await _client.SendAsync(request);
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
}
[Fact]
public async Task Stop_APIKey_200()
{
var request = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/stop");
request.Headers.Add("X-Api-Key", _apiKey);
var resp = await _client.SendAsync(request);
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
}
[Fact]
public async Task Start_APIKey_200()
{
var request = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/start");
request.Headers.Add("X-Api-Key", _apiKey);
var resp = await _client.SendAsync(request);
Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
}
// ===== 启停控制测试 =====
[Fact]
public async Task _()
{
// 停止
var stopReq = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/stop");
stopReq.Headers.Add("X-Api-Key", _apiKey);
await _client.SendAsync(stopReq);
// 检查状态为停止
var statusReq = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
statusReq.Headers.Add("X-Api-Key", _apiKey);
var statusResp = await _client.SendAsync(statusReq);
var body = await statusResp.Content.ReadAsStringAsync();
dynamic json = JsonConvert.DeserializeObject(body);
Assert.False((bool)json.data.isRunning);
// 启动
var startReq = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/start");
startReq.Headers.Add("X-Api-Key", _apiKey);
await _client.SendAsync(startReq);
// 检查状态为运行
statusReq = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
statusReq.Headers.Add("X-Api-Key", _apiKey);
statusResp = await _client.SendAsync(statusReq);
body = await statusResp.Content.ReadAsStringAsync();
json = JsonConvert.DeserializeObject(body);
Assert.True((bool)json.data.isRunning);
}
}
}