|
|
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);
|
|
|
}
|
|
|
}
|
|
|
}
|