using System.Collections.Generic;
using AGVNavigationCore.Models;
namespace AGVPathTester
{
///
/// AGV 경로 탐색 테스트 케이스 정의
///
public static class TestCases
{
///
/// 기본 경로 탐색 테스트 케이스
///
public class BasicPathTestCase
{
public string StartNodeId { get; set; }
public string TargetNodeId { get; set; }
public AgvDirection CurrentDirection { get; set; }
public string Description { get; set; }
public bool ExpectedSuccess { get; set; }
public BasicPathTestCase(string startNodeId, string targetNodeId, AgvDirection currentDirection, string description, bool expectedSuccess = true)
{
StartNodeId = startNodeId;
TargetNodeId = targetNodeId;
CurrentDirection = currentDirection;
Description = description;
ExpectedSuccess = expectedSuccess;
}
}
///
/// 방향 전환 테스트 케이스
///
public class DirectionChangeTestCase
{
public string StartNodeId { get; set; }
public string TargetNodeId { get; set; }
public AgvDirection CurrentDirection { get; set; }
public AgvDirection RequiredDirection { get; set; }
public string Description { get; set; }
public bool ExpectedSuccess { get; set; }
public List ExpectedPath { get; set; }
public DirectionChangeTestCase(string startNodeId, string targetNodeId, AgvDirection currentDirection, AgvDirection requiredDirection, string description, bool expectedSuccess = true, List expectedPath = null)
{
StartNodeId = startNodeId;
TargetNodeId = targetNodeId;
CurrentDirection = currentDirection;
RequiredDirection = requiredDirection;
Description = description;
ExpectedSuccess = expectedSuccess;
ExpectedPath = expectedPath ?? new List();
}
}
///
/// 이동 기반 테스트 케이스 (이전 위치 → 현재 위치 → 목표 위치)
///
public class MovementBasedTestCase
{
public string PreviousRfid { get; set; }
public string CurrentRfid { get; set; }
public string TargetRfid { get; set; }
public AgvDirection ExpectedDirection { get; set; }
public string Description { get; set; }
public bool ExpectedSuccess { get; set; }
public List ExpectedRfidPath { get; set; }
public MovementBasedTestCase(string previousRfid, string currentRfid, string targetRfid, AgvDirection expectedDirection, string description, bool expectedSuccess = true, List expectedRfidPath = null)
{
PreviousRfid = previousRfid;
CurrentRfid = currentRfid;
TargetRfid = targetRfid;
ExpectedDirection = expectedDirection;
Description = description;
ExpectedSuccess = expectedSuccess;
ExpectedRfidPath = expectedRfidPath ?? new List();
}
}
///
/// 기본 경로 탐색 테스트 케이스 목록 (RFID 기반으로 수정)
/// RFID 매핑: 001→N001, 005→N011, 037→N015, 041→존재하지않음
///
public static List GetBasicPathTestCases()
{
return new List
{
// 단순 직선 경로
new BasicPathTestCase("N001", "N002", AgvDirection.Forward, "단순 인접 노드 이동"),
new BasicPathTestCase("N001", "N003", AgvDirection.Forward, "단거리 직선 경로"),
// 중거리 경로
new BasicPathTestCase("N001", "N010", AgvDirection.Forward, "중거리 경로 탐색"),
new BasicPathTestCase("N011", "N019", AgvDirection.Backward, "RFID 005→015: 후진 상태에서 중거리 이동"),
// 갈림길을 포함한 경로
new BasicPathTestCase("N001", "N020", AgvDirection.Forward, "갈림길 포함 경로"),
new BasicPathTestCase("N010", "N030", AgvDirection.Forward, "복잡한 갈림길 경로"),
// RFID 기반 실제 경로 (PATHSCENARIO.md 기반) - 올바른 NodeID 매핑 사용
new BasicPathTestCase("N013", "N019", AgvDirection.Forward, "RFID 007→015: 직진 경로"),
new BasicPathTestCase("N013", "N026", AgvDirection.Forward, "RFID 007→019: 충전기 경로"),
new BasicPathTestCase("N013", "N001", AgvDirection.Forward, "RFID 007→001: 장비 경로"),
// 갈림길 테스트 (RFID 005는 N011 갈림길)
new BasicPathTestCase("N004", "N019", AgvDirection.Forward, "RFID 004→015: N011 갈림길 통과"),
new BasicPathTestCase("N012", "N023", AgvDirection.Backward, "RFID 012→016: 갈림길 역방향"),
};
}
///
/// 방향 전환 테스트 케이스 목록 (PATHSCENARIO.md RFID 기반)
/// RFID → NodeID 매핑: 005→N011, 037→N028, 007→N013, 015→N019, 001→N001, 004→N004
///
public static List GetDirectionChangeTestCases()
{
return new List
{
// PATHSCENARIO.md Case 1: AGV가 전진방향으로 008→007 이동 후
// Q1: 007→015 (충전기, 전진 도킹) - 방향전환 불필요
new DirectionChangeTestCase("N013", "N019", AgvDirection.Forward, AgvDirection.Forward,
"Q1: RFID 007→015 (충전기, 전진 도킹) - 방향전환 불필요",
true, new List { "N013", "N012", "N011", "N004", "N022", "N023", "N024", "N019" }),
// Q2: 007→019 (충전기, 전진 도킹) - 방향전환 불필요
new DirectionChangeTestCase("N013", "N026", AgvDirection.Forward, AgvDirection.Forward,
"Q2: RFID 007→019 (충전기, 전진 도킹) - 방향전환 불필요",
true, new List { "N013", "N012", "N011", "N004", "N022", "N023", "N024", "N025", "N026" }),
// Q3: 007→001 (장비, 후진 도킹) - 005 갈림길에서 037 우회
new DirectionChangeTestCase("N013", "N001", AgvDirection.Forward, AgvDirection.Backward,
"Q3: RFID 007→001 (장비, 후진 도킹) - 005 갈림길에서 037 우회",
true, new List { "N013", "N012", "N011", "N028", "N011", "N004", "N003", "N002", "N001" }),
// Q4: 007→011 (장비, 후진 도킹) - 005 갈림길에서 037 우회
// RFID 011 → N010
new DirectionChangeTestCase("N013", "N010", AgvDirection.Forward, AgvDirection.Backward,
"Q4: RFID 007→011 (장비, 후진 도킹) - 005 갈림길에서 037 우회",
true, new List { "N013", "N012", "N011", "N028", "N011", "N004", "N031", "N008", "N009", "N010" }),
// Case 2: AGV가 후진방향으로 008→007 이동 후
// Q7: 007→015 (충전기, 전진 도킹) - 005에서 037 우회 후 전환
new DirectionChangeTestCase("N013", "N019", AgvDirection.Backward, AgvDirection.Forward,
"Q7: RFID 007→015 (충전기, 전진 도킹) - 005에서 037 우회 후 전환",
true, new List { "N013", "N012", "N011", "N028", "N011", "N004", "N022", "N023", "N024", "N019" }),
// 실제 맵 기반 간단한 테스트들
// N004 갈림길 활용 (N003, N022, N031 연결)
new DirectionChangeTestCase("N003", "N022", AgvDirection.Forward, AgvDirection.Backward,
"N004 갈림길: N003→N022 (전진→후진 전환)",
true, new List { "N003", "N004", "N022" }),
new DirectionChangeTestCase("N003", "N031", AgvDirection.Forward, AgvDirection.Backward,
"N004 갈림길: N003→N031 (전진→후진 전환)",
true, new List { "N003", "N004", "N031" }),
// N011 갈림길 활용 (N012, N004, N015 연결) - RFID 005는 N011
new DirectionChangeTestCase("N012", "N019", AgvDirection.Forward, AgvDirection.Backward,
"N011 갈림길 (RFID 005): N012→N019 (전진→후진 전환)",
true, new List { "N012", "N011", "N004", "N022", "N023", "N024", "N019" }),
// 방향 전환이 필요 없는 경우 (같은 방향)
new DirectionChangeTestCase("N013", "N019", AgvDirection.Forward, AgvDirection.Forward,
"방향 전환 불필요: RFID 007→015 (전진→전진)",
true, new List { "N013", "N012", "N011", "N004", "N022", "N023", "N024", "N019" }),
new DirectionChangeTestCase("N012", "N019", AgvDirection.Backward, AgvDirection.Backward,
"방향 전환 불필요: N012→N019 (후진→후진)",
true, new List { "N012", "N011", "N004", "N022", "N023", "N024", "N019" })
};
}
///
/// 특정 문제 시나리오 테스트 케이스 (디버깅용)
///
public static List GetProblematicTestCases()
{
return new List
{
// 사용자가 직접 보고한 문제들 (RFID 매핑 적용)
new DirectionChangeTestCase("N004", "N015", AgvDirection.Forward, AgvDirection.Backward,
"🚨 사용자 보고: RFID 004→037(N015) 되돌아가기 발생"),
new DirectionChangeTestCase("N012", "N015", AgvDirection.Backward, AgvDirection.Backward,
"🚨 사용자 보고: RFID 012→037(N015) 비효율적 경로"),
new DirectionChangeTestCase("N012", "N023", AgvDirection.Backward, AgvDirection.Forward,
"🚨 사용자 보고: RFID 012→016(N023) 되돌아가기 발생"),
};
}
///
/// 스트레스 테스트용 대량 케이스 생성
///
public static List GenerateStressTestCases(List allNodeIds, int count = 50)
{
var testCases = new List();
var random = new System.Random(42); // 고정 시드로 재현 가능한 테스트
for (int i = 0; i < count; i++)
{
var startNodeId = allNodeIds[random.Next(allNodeIds.Count)];
var targetNodeId = allNodeIds[random.Next(allNodeIds.Count)];
var direction = random.Next(2) == 0 ? AgvDirection.Forward : AgvDirection.Backward;
if (startNodeId != targetNodeId)
{
testCases.Add(new BasicPathTestCase(
startNodeId,
targetNodeId,
direction,
$"스트레스 테스트 #{i + 1}"
));
}
}
return testCases;
}
///
/// 이동 기반 테스트 케이스 목록 (실제 AGV 이동 시나리오)
///
public static List GetMovementBasedTestCases()
{
return new List
{
// 핵심 시나리오: 033→032 후진 이동 중인 AGV가 001로 가는 경우
new MovementBasedTestCase("033", "032", "001", AgvDirection.Backward,
"🎯 핵심 시나리오: RFID 033→032 후진 이동 AGV가 001(장비) 목적지",
true, new List { "032", "031", "030", "...", "001" }),
// 다양한 이동 패턴 테스트
new MovementBasedTestCase("001", "002", "015", AgvDirection.Forward,
"RFID 001→002 전진 이동 AGV가 015(충전기) 목적지",
true, new List { "002", "003", "004", "012", "013", "014", "015" }),
new MovementBasedTestCase("015", "014", "001", AgvDirection.Backward,
"RFID 015→014 후진 이동 AGV가 001(장비) 목적지",
true, new List { "014", "013", "012", "004", "003", "002", "001" }),
new MovementBasedTestCase("004", "005", "019", AgvDirection.Forward,
"RFID 004→005 전진 이동(갈림길 진입) AGV가 019(충전기) 목적지",
true, new List { "005", "037", "036", "035", "034", "018", "019" }),
new MovementBasedTestCase("005", "004", "037", AgvDirection.Backward,
"RFID 005→004 후진 이동(갈림길 이탈) AGV가 037 목적지",
true, new List { "004", "005", "037" }),
// 🚨 AGV 물리적 제약사항 테스트: 갈림길 즉시 방향전환 금지
new MovementBasedTestCase("018", "019", "015", AgvDirection.Forward,
"🚨 물리적 제약: RFID 018→019 전진 이동 AGV가 015(충전기) 목적지 - 012 갈림길 즉시 방향전환 금지",
true, new List { "019", "018", "017", "016", "012", "004", "012", "013", "014", "015" }),
new MovementBasedTestCase("016", "012", "013", AgvDirection.Backward,
"🚨 물리적 제약: RFID 016→012 후진 이동 AGV가 013 목적지 - 012에서 즉시 013 전진 금지",
true, new List { "012", "004", "012", "013" }),
// 🔥 핵심 시나리오: AGV 물리적 방향과 갈림길 방향전환
new MovementBasedTestCase("032", "031", "008", AgvDirection.Backward,
"🔥 핵심 시나리오: RFID 032→031 후진 이동 AGV가 008 목적지 - 031→005(전진)→004(좌회전)→008(후진)",
true, new List { "031", "032", "033", "034", "035", "036", "037", "005", "004", "012", "006", "007", "008" }),
// 방향 전환이 필요한 시나리오
new MovementBasedTestCase("032", "033", "001", AgvDirection.Forward,
"RFID 032→033 전진 이동 AGV가 001(후진 도킹) 목적지 - 방향 전환 필요",
true, new List { "033", "034", "018", "017", "016", "037", "005", "004", "003", "002", "001" }),
new MovementBasedTestCase("007", "006", "015", AgvDirection.Backward,
"RFID 007→006 후진 이동 AGV가 015(전진 도킹) 목적지 - 방향 전환 필요",
true, new List { "006", "005", "037", "005", "004", "012", "013", "014", "015" }),
};
}
}
}