Files
FlyShotHost/tests/Flyshot.Core.Tests/ControllerClientCompatConfigRootTests.cs
yunxiao.zhu a6579f1e5b feat(*): 添加 ConfigRoot 运行时配置目录隔离
* 新增 ControllerClientCompatOptions.ConfigRoot 及解析方法
* 兼容层默认从运行目录 Config 加载模型、轨迹和配置
* 移除隐式父工作区根目录推断,旧路径仅在显式配置时生效
* Host 项目编译时将 Config 目录复制到输出目录
* 请求响应日志中间件忽略 /api/status/snapshot 高频轮询
* 补充 ConfigRoot 和日志过滤相关单元测试
2026-04-29 18:27:03 +08:00

149 lines
5.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Flyshot.ControllerClientCompat;
using Flyshot.Core.Config;
namespace Flyshot.Core.Tests;
/// <summary>
/// 验证 ControllerClient 兼容层默认围绕运行目录 Config 读写配置和轨迹文件。
/// </summary>
public sealed class ControllerClientCompatConfigRootTests
{
/// <summary>
/// 验证路径兼容层优先命中运行目录 Config 下的 RobotConfig.json而不是旧仓库根目录候选。
/// </summary>
[Fact]
public void PathCompatibility_ResolvesRuntimeConfigBeforeLegacyCandidates()
{
var runtimeRoot = CreateTempDirectory();
try
{
var configPath = Path.Combine(runtimeRoot, "Config", "RobotConfig.json");
var legacyPath = Path.Combine(runtimeRoot, "RobotConfig.json");
Directory.CreateDirectory(Path.GetDirectoryName(configPath)!);
File.WriteAllText(configPath, "{}");
File.WriteAllText(legacyPath, "{}");
var resolved = PathCompatibility.ResolveConfigPath("RobotConfig.json", runtimeRoot);
Assert.Equal(configPath, resolved);
}
finally
{
Directory.Delete(runtimeRoot, recursive: true);
}
}
/// <summary>
/// 验证机器人目录优先从显式 ConfigRoot/Models 加载 .robot 文件。
/// </summary>
[Fact]
public void ControllerClientCompatRobotCatalog_LoadsModelFromConfigRootModels()
{
var configRoot = CreateTempConfigRoot();
try
{
CopySampleRobotModel(configRoot);
var options = new ControllerClientCompatOptions { ConfigRoot = configRoot };
var catalog = new ControllerClientCompatRobotCatalog(options, new RobotModelLoader());
var profile = catalog.LoadProfile("FANUC_LR_Mate_200iD");
Assert.Equal(Path.Combine(configRoot, "Models", "LR_Mate_200iD_7L.robot"), profile.ModelPath);
}
finally
{
Directory.Delete(configRoot, recursive: true);
}
}
/// <summary>
/// 验证 JSON 轨迹存储保存、加载和删除都落在 ConfigRoot/TrajectoryStore 目录。
/// </summary>
[Fact]
public void JsonFlyshotTrajectoryStore_PersistsTrajectoriesUnderConfigRootStore()
{
var configRoot = CreateTempConfigRoot();
try
{
var options = new ControllerClientCompatOptions { ConfigRoot = configRoot };
var store = new JsonFlyshotTrajectoryStore(options, new RobotConfigLoader());
var settings = new CompatibilityRobotSettings(
useDo: true,
ioAddresses: [7, 8],
ioKeepCycles: 2,
accLimitScale: 1.0,
jerkLimitScale: 1.0,
adaptIcspTryNum: 5);
var trajectory = TestRobotFactory.CreateUploadedTrajectoryWithSingleShot();
store.Save("FANUC_LR_Mate_200iD", settings, trajectory);
var expectedPath = Path.Combine(configRoot, "TrajectoryStore", "FANUC_LR_Mate_200iD_trajectories.json");
Assert.True(File.Exists(expectedPath), $"应在运行目录 Config 下创建轨迹文件: {expectedPath}");
var loaded = store.LoadAll("FANUC_LR_Mate_200iD", out var loadedSettings);
Assert.NotNull(loadedSettings);
Assert.Contains(trajectory.Name, loaded);
store.Delete("FANUC_LR_Mate_200iD", trajectory.Name);
var afterDelete = store.LoadAll("FANUC_LR_Mate_200iD", out _);
Assert.Empty(afterDelete);
}
finally
{
Directory.Delete(configRoot, recursive: true);
}
}
/// <summary>
/// 创建测试专用的运行目录 Config 根,避免污染真实输出目录。
/// </summary>
private static string CreateTempConfigRoot()
{
var root = Path.Combine(Path.GetTempPath(), "flyshot-config-root-tests", Guid.NewGuid().ToString("N"), "Config");
Directory.CreateDirectory(root);
return root;
}
/// <summary>
/// 创建测试专用的临时目录。
/// </summary>
private static string CreateTempDirectory()
{
var root = Path.Combine(Path.GetTempPath(), "flyshot-config-root-tests", Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(root);
return root;
}
/// <summary>
/// 复制仓库内已固化的现场机器人模型到临时 Config/Models 目录。
/// </summary>
private static void CopySampleRobotModel(string configRoot)
{
var modelDir = Path.Combine(configRoot, "Models");
Directory.CreateDirectory(modelDir);
File.Copy(
Path.Combine(GetReplacementRoot(), "Config", "Models", "LR_Mate_200iD_7L.robot"),
Path.Combine(modelDir, "LR_Mate_200iD_7L.robot"));
}
/// <summary>
/// 定位 replacement 仓库根目录,供测试读取仓库内固化样本。
/// </summary>
private static string GetReplacementRoot()
{
var current = new DirectoryInfo(AppContext.BaseDirectory);
while (current is not null)
{
if (File.Exists(Path.Combine(current.FullName, "FlyshotReplacement.sln")))
{
return current.FullName;
}
current = current.Parent;
}
throw new DirectoryNotFoundException("Unable to locate the flyshot replacement root.");
}
}