diff --git a/backend/app.py b/backend/app.py index 2eb0b1c..7093f72 100644 --- a/backend/app.py +++ b/backend/app.py @@ -468,6 +468,7 @@ def get_schedule_week(start: str | None = None) -> dict[str, Any]: return { "start_date": week_start, "items": [_serialize_schedule_row(row) for row in rows], + "total_scheduled_tests": len(all_rows), "completion_date": completion_date, "windows": _build_schedule_windows(week_start_date, all_rows, holiday_dates), } diff --git a/backend/data/One_Week_Test_Plan.csv b/backend/data/One_Week_Test_Plan.csv new file mode 100644 index 0000000..11f53db --- /dev/null +++ b/backend/data/One_Week_Test_Plan.csv @@ -0,0 +1,206 @@ +Priority,Index,Interferer,COE Pair ,Rotation,TC ID,Victim Band,6GHz Power Mode,5G_Test Point,5G_Channel,5G_Bandwidth,5G_RSSI,5G_Direction,5G_STA,6G_Test Point,6G_Channel,6G_Bandwidth,6G_RSSI,6G_Direction,6G_STA,2G_Test Point,2G_Channel,2G_Bandwidth,2G_RSSI,2G_Direction,2G_STA,Remarks,,Execution day FOR CGW452,Execution day FOR CGW453 +P1,1,No,No,R3,P2PRXBE001,5G,LPI,T1F,36,80,-76,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,1,No,No,R3,P2PRXBE002,5G,LPI,T1B,36,80,-67,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,1,No,No,R3,P2PRXBE003,5G,LPI,T1C,36,80,-45,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,2,No,Yes,R3,P2PRXBE004,5G,LPI,T1F,100,80,-76,UL,STA63,,,,,,,,,,,,,85,COE Test Case,, +P1,2,No,No,R3,P2PRXBE005,5G,LPI,T1B,100,80,-67,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,2,No,No,R3,P2PRXBE006,5G,LPI,T1C,100,80,-45,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P2,3,Yes,Yes,R3,COERXBE001,5G,LPI,T1F,100,80,-76,UL,STA63,T2A,5,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P2,4,Yes,Yes,R3,COERXBE002,5G,LPI,T1F,100,80,-76,UL,STA63,T2A,133,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,5,No,Yes,R3,P2PRXBE007,5G,LPI,T1F,161,80,-76,UL,STA63,,,,,,,,,,,,,85,COE Test Case,, +P1,5,No,No,R3,P2PRXBE008,5G,LPI,T1B,161,80,-67,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,5,No,No,R3,P2PRXBE009,5G,LPI,T1C,161,80,-45,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P2,6,Yes,Yes,R3,COERXBE003,5G,LPI,T1F,161,80,-76,UL,STA63,T2A,5,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P2,7,Yes,Yes,R3,COERXBE004,5G,LPI,T1F,161,80,-76,UL,STA63,T2A,133,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,10,No,Yes,R3,P2PRXBE010,5G,LPI,T1F,100,160,-76,UL,STA63,,,,,,,,,,,,,85,COE Test Case,, +P1,10,No,No,R3,P2PRXBE011,5G,LPI,T1B,100,160,-67,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,10,No,No,R3,P2PRXBE012,5G,LPI,T1C,100,160,-45,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,13,No,Yes,R1,P2PRXBE013,6G,LPI,,,,,,,T2A,5,160,-79,UL,STA63,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,13,No,No,R1,P2PRXBE014,6G,LPI,,,,,,,T1B,5,160,-70,UL,STA63,,,,,,,85,P2P Only,Day 2,Day 2 +P1,13,No,No,R1,P2PRXBE015,6G,LPI,,,,,,,T1C,5,160,-45,UL,STA63,,,,,,,85,P2P Only,, +P2,14,Yes,Yes,R1,COERXBE009,6G,LPI,T1F,161,80,-76,DL,STA56,T2A,5,160,-79,UL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,15,No,Yes,R1,P2PRXBE016,6G,LPI,,,,,,,T2A,133,160,-79,UL,STA63,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,15,No,No,R1,P2PRXBE017,6G,LPI,,,,,,,T1B,133,160,-70,UL,STA63,,,,,,,85,P2P Only,Day 2,Day 2 +P1,15,No,No,R1,P2PRXBE018,6G,LPI,,,,,,,T1C,133,160,-45,UL,STA63,,,,,,,85,P2P Only,, +P2,16,Yes,Yes,R1,COERXBE010,6G,LPI,T1F,161,80,-76,DL,STA56,T2A,133,160,-79,UL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,17,No,Yes,R1,P2PRXBE019,6G,LPI,,,,,,,T2A,197,160,-79,UL,STA63,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,17,No,No,R1,P2PRXBE020,6G,LPI,,,,,,,T1B,197,160,-70,UL,STA63,,,,,,,85,P2P Only,Day 2,Day 2 +P1,17,No,No,R1,P2PRXBE021,6G,LPI,,,,,,,T1C,197,160,-45,UL,STA63,,,,,,,85,P2P Only,, +P2,18,Yes,Yes,R1,COERXBE011,6G,LPI,T1F,161,80,-76,DL,STA56,T2A,197,160,-79,UL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,23,No,Yes,R2,P2PRXBE028,2G,LPI,,,,,,,,,,,,,T3E,1,20,-70,UL,STA63,85,COE Test Case,, +P1,23,No,No,R2,P2PRXBE029,2G,LPI,,,,,,,,,,,,,T1D,1,20,-60,UL,STA63,85,P2P Only,, +P1,23,No,No,R2,P2PRXBE030,2G,LPI,,,,,,,,,,,,,T1C,1,20,-45,UL,STA63,85,P2P Only,, +P2,24,Yes,Yes,R2,COERXBE014,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,5,160,-79,DL,STA56,T3E,1,20,-70,UL,STA63,144,COE Test Case,COE test case. No plan to run, +P1,25,No,Yes,R2,P2PRXBE031,2G,LPI,,,,,,,,,,,,,T3E,6,20,-70,UL,STA63,85,COE Test Case,, +P1,25,No,No,R2,P2PRXBE032,2G,LPI,,,,,,,,,,,,,T1D,6,20,-60,UL,STA63,85,P2P Only,, +P1,25,No,No,R2,P2PRXBE033,2G,LPI,,,,,,,,,,,,,T1C,6,20,-45,UL,STA63,85,P2P Only,, +P2,26,Yes,Yes,R2,COERXBE015,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,133,160,-79,DL,STA56,T3E,6,20,-70,UL,STA63,144,COE Test Case,COE test case. No plan to run, +P1,27,No,Yes,R2,P2PRXBE034,2G,LPI,,,,,,,,,,,,,T3E,11,20,-70,UL,STA63,85,COE Test Case,, +P1,27,No,No,R2,P2PRXBE035,2G,LPI,,,,,,,,,,,,,T1D,11,20,-60,UL,STA63,85,P2P Only,, +P1,27,No,No,R2,P2PRXBE036,2G,LPI,,,,,,,,,,,,,T1C,11,20,-45,UL,STA63,85,P2P Only,, +P2,28,Yes,Yes,R2,COERXBE016,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,197,160,-79,DL,STA56,T3E,11,20,-70,UL,STA63,144,COE Test Case,COE test case. No plan to run, +P1,1,No,No,R3,P2PTXBE001,5G,LPI,T1F,36,80,-76,DL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,1,No,No,R3,P2PTXBE002,5G,LPI,T1B,36,80,-67,DL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,1,No,No,R3,P2PTXBE003,5G,LPI,T1C,36,80,-45,DL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,2,No,Yes,R3,P2PTXBE004,5G,LPI,T1F,100,80,-76,DL,STA63,,,,,,,,,,,,,85,COE Test Case,, +P1,2,No,No,R3,P2PTXBE005,5G,LPI,T1B,100,80,-67,DL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,2,No,No,R3,P2PTXBE006,5G,LPI,T1C,100,80,-45,DL,STA63,,,,,,,,,,,,,85,P2P Only,, +P2,3,Yes,Yes,R3,COETXBE001,5G,LPI,T1F,100,80,-76,DL,STA63,T2A,5,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P2,4,Yes,Yes,R3,COETXBE002,5G,LPI,T1F,100,80,-76,DL,STA63,T2A,133,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,5,No,Yes,R3,P2PTXBE007,5G,LPI,T1F,161,80,-76,DL,STA63,,,,,,,,,,,,,85,COE Test Case,, +P1,5,No,No,R3,P2PTXBE008,5G,LPI,T1B,161,80,-67,DL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,5,No,No,R3,P2PTXBE009,5G,LPI,T1C,161,80,-45,DL,STA63,,,,,,,,,,,,,85,P2P Only,, +P2,6,Yes,Yes,R3,COETXBE003,5G,LPI,T1F,161,80,-76,DL,STA63,T2A,5,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P2,7,Yes,Yes,R3,COETXBE004,5G,LPI,T1F,161,80,-76,DL,STA63,T2A,133,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,8,No,Yes,R3,P2PTXBE010,5G,LPI,T1F,100,160,-76,DL,STA63,,,,,,,,,,,,,85,COE Test Case,, +P1,8,No,No,R3,P2PTXBE011,5G,LPI,T1B,100,160,-67,DL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,8,No,No,R3,P2PTXBE012,5G,LPI,T1C,100,160,-45,DL,STA63,,,,,,,,,,,,,85,P2P Only,, +P1,11,No,Yes,R1,P2PTXBE013,6G,LPI,T2A,5,160,-79,DL,STA63,,,,,,,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,11,No,No,R1,P2PTXBE014,6G,LPI,T1B,5,160,-70,DL,STA63,,,,,,,,,,,,,85,P2P Only,Day 2,Day 2 +P1,11,No,No,R1,P2PTXBE015,6G,LPI,T1C,5,160,-45,DL,STA63,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P2,12,Yes,Yes,R1,COETXBE007,6G,LPI,T1F,161,80,-76,DL,STA56,T2A,5,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,13,No,Yes,R1,P2PTXBE016,6G,LPI,T2A,133,160,-79,DL,STA63,,,,,,,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,13,No,No,R1,P2PTXBE017,6G,LPI,T1B,133,160,-70,DL,STA63,,,,,,,,,,,,,85,P2P Only,Day 2,Day 2 +P1,13,No,No,R1,P2PTXBE018,6G,LPI,T1C,133,160,-45,DL,STA63,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P2,14,Yes,Yes,R1,COETXBE008,6G,LPI,T1F,161,80,-76,DL,STA56,T2A,133,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,15,No,Yes,R1,P2PTXBE019,6G,LPI,T2A,197,160,-79,DL,STA63,,,,,,,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,15,No,No,R1,P2PTXBE020,6G,LPI,T1B,197,160,-70,DL,STA63,,,,,,,,,,,,,85,P2P Only,Day 2,Day 2 +P1,15,No,No,R1,P2PTXBE021,6G,LPI,T1C,197,160,-45,DL,STA63,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P2,16,Yes,Yes,R1,COETXBE009,6G,LPI,T1F,161,80,-76,DL,STA56,T2A,197,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,21,No,Yes,R2,P2PTXBE028,2G,LPI,T3E,1,20,-70,UL,STA63,,,,,,,,,,,,,85,COE Test Case,, +P1,21,No,No,R2,P2PTXBE029,2G,LPI,T1D,1,20,-60,UL,STA63,,,,,,,,,,,,,85,P2P Only,Day 4,Day 4 +P1,21,No,No,R2,P2PTXBE030,2G,LPI,T1C,1,20,-45,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P2,22,Yes,Yes,R2,COETXBE012,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,5,160,-79,DL,STA56,T3E,1,20,-70,DL,STA63,144,COE Test Case,COE test case. No plan to run, +P1,23,No,Yes,R2,P2PTXBE031,2G,LPI,T3E,6,20,-70,UL,STA63,,,,,,,,,,,,,85,COE Test Case,, +P1,23,No,No,R2,P2PTXBE031,2G,LPI,T1D,6,20,-60,UL,STA63,,,,,,,,,,,,,85,P2P Only,Day 4,Day 4 +P1,23,No,No,R2,P2PTXBE033,2G,LPI,T1C,6,20,-45,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P2,24,Yes,Yes,R2,COETXBE013,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,133,160,-79,DL,STA56,T3E,6,20,-70,DL,STA63,144,COE Test Case,COE test case. No plan to run, +P1,25,No,Yes,R2,P2PTXBE034,2G,LPI,T3E,11,20,-70,UL,STA63,,,,,,,,,,,,,85,COE Test Case,, +P1,25,No,No,R2,P2PTXBE035,2G,LPI,T1D,11,20,-60,UL,STA63,,,,,,,,,,,,,85,P2P Only,Day 4,Day 4 +P1,25,No,No,R2,P2PTXBE036,2G,LPI,T1C,11,20,-45,UL,STA63,,,,,,,,,,,,,85,P2P Only,, +P2,26,Yes,Yes,R2,COETXBE014,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,197,160,-79,DL,STA56,T3E,11,20,-70,DL,STA63,144,COE Test Case,COE test case. No plan to run, +P1,1,No,No,R1,P2PRXAX001,5G,LPI,T1F,36,80,-76,UL,STA56,,,,,,,,,,,,,85,P2P Only,Day 4,Day 4 +P1,1,No,No,R1,P2PRXAX002,5G,LPI,T1B,36,80,-67,UL,STA56,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P1,1,No,No,R1,P2PRXAX003,5G,LPI,T1C,36,80,-45,UL,STA56,,,,,,,,,,,,,85,P2P Only,Day 2,Day 2 +P1,2,No,Yes,R1,P2PRXAX004,5G,LPI,T1F,100,80,-76,UL,STA56,,,,,,,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,2,No,No,R1,P2PRXAX005,5G,LPI,T1B,100,80,-67,UL,STA56,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P1,2,No,No,R1,P2PRXAX006,5G,LPI,T1C,100,80,-45,UL,STA56,,,,,,,,,,,,,85,P2P Only,Day 2,Day 2 +P2,3,Yes,Yes,R1,COERXAX001,5G,LPI,T1F,100,80,-76,UL,STA56,T2A,5,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P2,4,Yes,Yes,R1,COERXAX002,5G,LPI,T1F,100,80,-76,UL,STA56,T2A,133,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,5,No,Yes,R1,P2PRXAX007,5G,LPI,T1F,161,80,-76,UL,STA56,,,,,,,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,5,No,No,R1,P2PRXAX008,5G,LPI,T1B,161,80,-67,UL,STA56,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P1,5,No,No,R1,P2PRXAX009,5G,LPI,T1C,161,80,-45,UL,STA56,,,,,,,,,,,,,85,P2P Only,Day 2,Day 2 +P2,6,Yes,Yes,R1,COERXAX003,5G,LPI,T1F,161,80,-76,UL,STA56,T2A,5,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P2,7,Yes,Yes,R1,COERXAX004,5G,LPI,T1F,161,80,-76,UL,STA56,T2A,133,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,10,No,Yes,R1,P2PRXAX010,5G,LPI,T1F,100,160,-76,UL,STA56,,,,,,,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,10,No,No,R1,P2PRXAX011,5G,LPI,T1B,100,160,-67,UL,STA56,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P1,10,No,No,R1,P2PRXAX012,5G,LPI,T1C,100,160,-45,UL,STA56,,,,,,,,,,,,,85,P2P Only,Day 2,Day 2 +P1,13,No,Yes,R2,P2PRXAX013,6G,LPI,,,,,,,T2A,5,160,-79,UL,STA56,,,,,,,85,COE Test Case,, +P1,13,No,No,R2,P2PRXAX014,6G,LPI,,,,,,,T1B,5,160,-70,UL,STA56,,,,,,,85,P2P Only,, +P1,13,No,No,R2,P2PRXAX015,6G,LPI,,,,,,,T1C,5,160,-45,UL,STA56,,,,,,,85,P2P Only,, +P2,14,Yes,Yes,R2,COERXAX009,6G,LPI,T1F,161,80,-76,DL,STA63,T2A,5,160,-79,UL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,15,No,Yes,R2,P2PRXAX016,6G,LPI,,,,,,,T2A,133,160,-79,UL,STA56,,,,,,,85,COE Test Case,, +P1,15,No,No,R2,P2PRXAX017,6G,LPI,,,,,,,T1B,133,160,-70,UL,STA56,,,,,,,85,P2P Only,, +P1,15,No,No,R2,P2PRXAX018,6G,LPI,,,,,,,T1C,133,160,-45,UL,STA56,,,,,,,85,P2P Only,, +P2,16,Yes,Yes,R2,COERXAX010,6G,LPI,T1F,161,80,-76,DL,STA63,T2A,133,160,-79,UL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,17,No,Yes,R2,P2PRXAX019,6G,LPI,,,,,,,T2A,197,160,-79,UL,STA56,,,,,,,85,COE Test Case,, +P1,17,No,No,R2,P2PRXAX020,6G,LPI,,,,,,,T1B,197,160,-70,UL,STA56,,,,,,,85,P2P Only,, +P1,17,No,No,R2,P2PRXAX021,6G,LPI,,,,,,,T1C,197,160,-45,UL,STA56,,,,,,,85,P2P Only,, +P2,18,Yes,Yes,R2,COERXAX011,6G,LPI,T1F,161,80,-76,DL,STA63,T2A,197,160,-79,UL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,23,No,Yes,R3,P2PRXAX028,2G,LPI,,,,,,,,,,,,,T3E,1,20,-70,UL,STA56,85,COE Test Case,, +P1,23,No,No,R3,P2PRXAX029,2G,LPI,,,,,,,,,,,,,T1D,1,20,-60,UL,STA56,85,P2P Only,, +P1,23,No,No,R3,P2PRXAX030,2G,LPI,,,,,,,,,,,,,T1C,1,20,-45,UL,STA56,85,P2P Only,, +P2,24,Yes,Yes,R3,COERXAX014,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,5,160,-79,DL,STA63,T3E,1,20,-70,UL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,25,No,Yes,R3,P2PRXAX031,2G,LPI,,,,,,,,,,,,,T3E,6,20,-70,UL,STA56,85,COE Test Case,, +P1,25,No,No,R3,P2PRXAX032,2G,LPI,,,,,,,,,,,,,T1D,6,20,-60,UL,STA56,85,P2P Only,, +P1,25,No,No,R3,P2PRXAX033,2G,LPI,,,,,,,,,,,,,T1C,6,20,-45,UL,STA56,85,P2P Only,, +P2,26,Yes,Yes,R3,COERXAX015,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,133,160,-79,DL,STA63,T3E,6,20,-70,UL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,27,No,Yes,R3,P2PRXAX034,2G,LPI,,,,,,,,,,,,,T3E,11,20,-70,UL,STA56,85,COE Test Case,, +P1,27,No,No,R3,P2PRXAX035,2G,LPI,,,,,,,,,,,,,T1D,11,20,-60,UL,STA56,85,P2P Only,, +P1,27,No,No,R3,P2PRXAX036,2G,LPI,,,,,,,,,,,,,T1C,11,20,-45,UL,STA56,85,P2P Only,, +P2,28,Yes,Yes,R3,COERXAX016,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,197,160,-79,DL,STA63,T3E,11,20,-70,UL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,1,No,No,R1,P2PTXAX001,5G,LPI,T1F,36,80,-76,DL,STA56,,,,,,,,,,,,,85,P2P Only,Day 4,Day 4 +P1,1,No,No,R1,P2PTXAX002,5G,LPI,T1B,36,80,-67,DL,STA56,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P1,1,No,No,R1,P2PTXAX003,5G,LPI,T1C,36,80,-45,DL,STA56,,,,,,,,,,,,,85,P2P Only,Day 3,Day 3 +P1,2,No,Yes,R1,P2PTXAX004,5G,LPI,T1F,100,80,-76,DL,STA56,,,,,,,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,2,No,No,R1,P2PTXAX005,5G,LPI,T1B,100,80,-67,DL,STA56,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P1,2,No,No,R1,P2PTXAX006,5G,LPI,T1C,100,80,-45,DL,STA56,,,,,,,,,,,,,85,P2P Only,Day 3,Day 3 +P2,3,Yes,Yes,R1,COETXAX001,5G,LPI,T1F,100,80,-76,DL,STA56,T2A,5,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P2,4,Yes,Yes,R1,COETXAX002,5G,LPI,T1F,100,80,-76,DL,STA56,T2A,133,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,5,No,Yes,R1,P2PTXAX007,5G,LPI,T1F,161,80,-76,DL,STA56,,,,,,,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,5,No,No,R1,P2PTXAX008,5G,LPI,T1B,161,80,-67,DL,STA56,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P1,5,No,No,R1,P2PTXAX009,5G,LPI,T1C,161,80,-45,DL,STA56,,,,,,,,,,,,,85,P2P Only,Day 3,Day 3 +P2,6,Yes,Yes,R1,COETXAX003,5G,LPI,T1F,161,80,-76,DL,STA56,T2A,5,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P2,7,Yes,Yes,R1,COETXAX004,5G,LPI,T1F,161,80,-76,DL,STA56,T2A,133,160,-79,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,8,No,Yes,R1,P2PTXAX010,5G,LPI,T1F,100,160,-76,DL,STA56,,,,,,,,,,,,,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,8,No,No,R1,P2PTXAX011,5G,LPI,T1B,100,160,-67,DL,STA56,,,,,,,,,,,,,85,P2P Only,Day 1,Day 1 +P1,8,No,No,R1,P2PTXAX012,5G,LPI,T1C,100,160,-45,DL,STA56,,,,,,,,,,,,,85,P2P Only,Day 3,Day 3 +P1,11,No,Yes,R2,P2PTXAX013,6G,LPI,,,,,,,T2A,5,160,-79,DL,STA56,,,,,,,85,COE Test Case,, +P1,11,No,No,R2,P2PTXAX014,6G,LPI,,,,,,,T1B,5,160,-70,DL,STA56,,,,,,,85,P2P Only,, +P1,11,No,No,R2,P2PTXAX015,6G,LPI,,,,,,,T1C,5,160,-45,DL,STA56,,,,,,,85,P2P Only,, +P2,12,Yes,Yes,R2,COETXAX007,6G,LPI,T1F,161,80,-76,DL,STA63,T2A,5,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,13,No,Yes,R2,P2PTXAX016,6G,LPI,,,,,,,T2A,133,160,-79,DL,STA56,,,,,,,85,COE Test Case,, +P1,13,No,No,R2,P2PTXAX017,6G,LPI,,,,,,,T1B,133,160,-70,DL,STA56,,,,,,,85,P2P Only,, +P1,13,No,No,R2,P2PTXAX018,6G,LPI,,,,,,,T1C,133,160,-45,DL,STA56,,,,,,,85,P2P Only,, +P2,14,Yes,Yes,R2,COETXAX008,6G,LPI,T1F,161,80,-76,DL,STA63,T2A,133,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,15,No,Yes,R2,P2PTXAX019,6G,LPI,,,,,,,T2A,197,160,-79,DL,STA56,,,,,,,85,COE Test Case,, +P1,15,No,No,R2,P2PTXAX020,6G,LPI,,,,,,,T1B,197,160,-70,DL,STA56,,,,,,,85,P2P Only,, +P1,15,No,No,R2,P2PTXAX021,6G,LPI,,,,,,,T1C,197,160,-45,DL,STA56,,,,,,,85,P2P Only,, +P2,16,Yes,Yes,R2,COETXAX009,6G,LPI,T1F,161,80,-76,DL,STA63,T2A,197,160,-79,DL,STA56,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,21,No,Yes,R3,P2PTXAX028,2G,LPI,,,,,,,,,,,,,T3E,1,20,-70,UL,STA56,85,COE Test Case,, +P1,21,No,No,R3,P2PTXAX029,2G,LPI,,,,,,,,,,,,,T1D,1,20,-60,UL,STA56,85,P2P Only,, +P1,21,No,No,R3,P2PTXAX030,2G,LPI,,,,,,,,,,,,,T1C,1,20,-45,UL,STA56,85,P2P Only,, +P2,22,Yes,Yes,R3,COETXAX012,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,5,160,-79,DL,STA63,T3E,1,20,-70,DL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,23,No,Yes,R3,P2PTXAX031,2G,LPI,,,,,,,,,,,,,T3E,6,20,-70,UL,STA56,85,COE Test Case,, +P1,23,No,No,R3,P2PTXAX032,2G,LPI,,,,,,,,,,,,,T1D,6,20,-60,UL,STA56,85,P2P Only,, +P1,23,No,No,R3,P2PTXAX033,2G,LPI,,,,,,,,,,,,,T1C,6,20,-45,UL,STA56,85,P2P Only,, +P2,24,Yes,Yes,R3,COETXAX013,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,133,160,-79,DL,STA63,T3E,6,20,-70,DL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,25,No,Yes,R3,P2PTXAX034,2G,LPI,,,,,,,,,,,,,T3E,11,20,-70,UL,STA56,85,COE Test Case,, +P1,25,No,No,R3,P2PTXAX035,2G,LPI,,,,,,,,,,,,,T1D,11,20,-60,UL,STA56,85,P2P Only,, +P1,25,No,No,R3,P2PTXAX036,2G,LPI,,,,,,,,,,,,,T1C,11,20,-45,UL,STA56,85,P2P Only,, +P2,26,Yes,Yes,R3,COETXAX014,2G,LPI,T1F,36,80,-76,DL,STA4,T2A,197,160,-79,DL,STA63,T3E,11,20,-70,DL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,1,No,No,R2,P2PRXAC001,5G,LPI,T1F,36,80,-76,UL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,1,No,No,R2,P2PRXAC002,5G,LPI,T1B,36,80,-67,UL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,1,No,No,R2,P2PRXAC003,5G,LPI,T1C,36,80,-45,UL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,2,No,Yes,R2,P2PRXAC004,5G,LPI,T1F,100,80,-76,UL,STA4,,,,,,,,,,,,,85,COE Test Case,, +P1,2,No,No,R2,P2PRXAC005,5G,LPI,T1B,100,80,-67,UL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,2,No,No,R2,P2PRXAC006,5G,LPI,T1C,100,80,-45,UL,STA4,,,,,,,,,,,,,85,P2P Only,, +P2,3,Yes,Yes,R2,COERXAC001,5G,LPI,T1F,100,80,-76,UL,STA4,T2A,5,160,OFF,DL,STA63,T3E,6,20,-70,DL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,5,No,Yes,R2,P2PRXAC007,5G,LPI,T1F,161,80,-76,UL,STA4,,,,,,,,,,,,,85,COE Test Case,, +P1,5,No,No,R2,P2PRXAC008,5G,LPI,T1B,161,80,-67,UL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,5,No,No,R2,P2PRXAC009,5G,LPI,T1C,161,80,-45,UL,STA4,,,,,,,,,,,,,85,P2P Only,, +P2,6,Yes,Yes,R2,COERXAC002,5G,LPI,T1F,161,80,-76,UL,STA4,T2A,133,160,OFF,DL,STA63,T3E,6,20,-70,DL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,14,No,Yes,R1,P2PRXAC010,2G,LPI,,,,,,,,,,,,,T3E,1,20,-70,UL,STA4,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,14,No,No,R1,P2PRXAC011,2G,LPI,,,,,,,,,,,,,T1D,1,20,-60,UL,STA4,85,P2P Only,Day 3,Day 3 +P1,14,No,No,R1,P2PRXAC012,2G,LPI,,,,,,,,,,,,,T1C,1,20,-45,UL,STA4,85,P2P Only,Day 4,Day 4 +P2,15,Yes,Yes,R1,COERXAC003,2G,LPI,T1F,36,80,-76,DL,STA56,T2A,5,160,OFF,DL,STA63,T3E,1,20,-70,UL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,16,No,Yes,R1,P2PRXAC013,2G,LPI,,,,,,,,,,,,,T3E,6,20,-70,UL,STA4,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,16,No,No,R1,P2PRXAC014,2G,LPI,,,,,,,,,,,,,T1D,6,20,-60,UL,STA4,85,P2P Only,Day 3,Day 3 +P1,16,No,No,R1,P2PRXAC015,2G,LPI,,,,,,,,,,,,,T1C,6,20,-45,UL,STA4,85,P2P Only,Day 4,Day 4 +P2,17,Yes,Yes,R1,COERXAC004,2G,LPI,T1F,36,80,-76,DL,STA56,T2A,133,160,OFF,DL,STA63,T3E,6,20,-70,UL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,18,No,Yes,R1,P2PRXAC016,2G,LPI,,,,,,,,,,,,,T3E,11,20,-70,UL,STA4,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,18,No,No,R1,P2PRXAC017,2G,LPI,,,,,,,,,,,,,T1D,11,20,-60,UL,STA4,85,P2P Only,Day 3,Day 3 +P1,18,No,No,R1,P2PRXAC018,2G,LPI,,,,,,,,,,,,,T1C,11,20,-45,UL,STA4,85,P2P Only,Day 4,Day 4 +P2,19,Yes,Yes,R1,COERXAC005,2G,LPI,T1F,36,80,-76,DL,STA56,T2A,197,160,OFF,DL,STA63,T3E,11,20,-70,UL,STA4,144,COE Test Case,COE test case. No plan to run,Weekend evening CGW453 +P1,1,No,No,R2,P2PTXAC001,5G,LPI,T1F,36,80,-76,DL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,1,No,No,R2,P2PTXAC002,5G,LPI,T1B,36,80,-67,DL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,1,No,No,R2,P2PTXAC003,5G,LPI,T1C,36,80,-45,DL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,2,No,Yes,R2,P2PTXAC004,5G,LPI,T1F,100,80,-76,DL,STA4,,,,,,,,,,,,,85,COE Test Case,, +P1,2,No,No,R2,P2PTXAC005,5G,LPI,T1B,100,80,-67,DL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,2,No,No,R2,P2PTXAC006,5G,LPI,T1C,100,80,-45,DL,STA4,,,,,,,,,,,,,85,P2P Only,, +P2,3,Yes,Yes,R2,COETXAC001,5G,LPI,T1F,100,80,-76,DL,STA4,T2A,5,160,OFF,DL,STA63,T3E,6,20,-70,DL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,5,No,Yes,R2,P2PTXAC007,5G,LPI,T1F,161,80,-76,DL,STA4,,,,,,,,,,,,,85,COE Test Case,, +P1,5,No,No,R2,P2PTXAC008,5G,LPI,T1B,161,80,-67,DL,STA4,,,,,,,,,,,,,85,P2P Only,, +P1,5,No,No,R2,P2PTXAC009,5G,LPI,T1C,161,80,-45,DL,STA4,,,,,,,,,,,,,85,P2P Only,, +P2,6,Yes,Yes,R2,COETXAC002,5G,LPI,T1F,161,80,-76,DL,STA4,T2A,133,160,OFF,DL,STA63,T3E,6,20,-70,DL,STA56,144,COE Test Case,COE test case. No plan to run, +P1,14,No,Yes,R1,P2PTXAC010,2G,LPI,,,,,,,,,,,,,T3E,1,20,-70,DL,STA4,85,COE Test Case,Weekend evening CGW452,Weekend evening CGW453 +P1,14,No,No,R1,P2PTXAC011,2G,LPI,,,,,,,,,,,,,T1D,1,20,-60,DL,STA4,85,P2P Only,Day 3,Day 3 +P1,14,No,No,R1,P2PTXAC012,2G,LPI,,,,,,,,,,,,,T1C,1,20,-45,DL,STA4,85,P2P Only,Day 4,Day 4 +P2,15,Yes,Yes,R1,COETXAC003,2G,LPI,T1F,36,80,-76,DL,STA56,T2A,5,160,OFF,DL,STA63,T3E,1,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,16,No,Yes,R1,P2PTXAC013,2G,LPI,,,,,,,,,,,,,T3E,6,20,-70,DL,STA4,85,COE Test Case,Weekend evening CGW452, +P1,16,No,No,R1,P2PTXAC014,2G,LPI,,,,,,,,,,,,,T1D,6,20,-60,DL,STA4,85,P2P Only,Day 3,Day 3 +P1,16,No,No,R1,P2PTXAC015,2G,LPI,,,,,,,,,,,,,T1C,6,20,-45,DL,STA4,85,P2P Only,Day 4,Day 4 +P2,17,Yes,Yes,R1,COETXAC004,2G,LPI,T1F,36,80,-76,DL,STA56,T2A,133,160,OFF,DL,STA63,T3E,6,20,-70,DL,STA4,144,COE Test Case,COE test case. No plan to run, +P1,18,No,Yes,R1,P2PTXAC016,2G,LPI,,,,,,,,,,,,,T3E,11,20,-70,DL,STA4,85,COE Test Case,Weekend evening CGW452, +P1,18,No,No,R1,P2PTXAC017,2G,LPI,,,,,,,,,,,,,T1D,11,20,-60,DL,STA4,85,P2P Only,Day 3,Day 3 +P1,18,No,No,R1,P2PTXAC018,2G,LPI,,,,,,,,,,,,,T1C,11,20,-45,DL,STA4,85,P2P Only,Day 4,Day 4 diff --git a/backend/data/One_Week_Test_Plan_P3P.csv b/backend/data/One_Week_Test_Plan_P3P.csv new file mode 100644 index 0000000..f624c81 --- /dev/null +++ b/backend/data/One_Week_Test_Plan_P3P.csv @@ -0,0 +1 @@ +Priority,Index,Throttled,Rotation,TC ID,Band,6GHz Power Mode,STATION 1_Test Point,STATION 1_Channel,STATION 1_Bandwidth,STATION 1_RSSI,STATION 1_Direction,STATION 1_Rate,STATION 1_STA,STATION 2_Test Point,STATION 2_Channel,STATION 2_Bandwidth,STATION 2_RSSI,STATION 2_Direction,STATION 2_Rate,STATION 2_STA,STATION 3_Test Point,STATION 3_Channel,STATION 3_Bandwidth,STATION 3_RSSI,STATION 3_Direction,STATION 3_Rate,STATION 3_STA diff --git a/backend/parser.py b/backend/parser.py index 0c3475b..adf0153 100644 --- a/backend/parser.py +++ b/backend/parser.py @@ -212,7 +212,7 @@ def _columns_missing(normalized_fieldnames: set[str], required_columns: list[str return [ column for column in required_columns - if column.strip().upper() not in normalized_fieldnames + if _normalize_column_name(column) not in normalized_fieldnames ] @@ -348,7 +348,7 @@ def _parse_single_csv( if not reader.fieldnames: raise CsvValidationError("CSV is missing a header row.") - normalized_fieldnames = {name.strip().upper() for name in reader.fieldnames if name} + normalized_fieldnames = {_normalize_column_name(name) for name in reader.fieldnames if name} csv_format = _detect_csv_format(normalized_fieldnames) tests: list[TestRecord] = [] @@ -539,6 +539,13 @@ def _normalize_value(value: str | None) -> str: return " ".join(value.strip().upper().split()) +def _normalize_column_name(value: str | None) -> str: + if value is None: + return "" + # Accept common header variants, for example: "TC ID", "TC_ID", or "TC\u00A0ID". + return re.sub(r"[^A-Z0-9]+", "", value.upper()) + + def _normalize_yes_no(value: str | None) -> bool: return _normalize_value(value) == "YES" @@ -615,15 +622,15 @@ def _row_get(row: dict[str, str], key: str) -> str | None: if key in row: return row.get(key) - normalized_key = key.strip().upper() + normalized_key = _normalize_column_name(key) for existing_key, value in row.items(): - if existing_key and existing_key.strip().upper() == normalized_key: + if existing_key and _normalize_column_name(existing_key) == normalized_key: return value - if normalized_key == "COE PAIR": + if normalized_key == _normalize_column_name("COE PAIR"): for alias in ("COE PAIRING", "COE_PAIRING"): for existing_key, value in row.items(): - if existing_key and existing_key.strip().upper() == alias: + if existing_key and _normalize_column_name(existing_key) == _normalize_column_name(alias): return value return None diff --git a/backend/scanner.py b/backend/scanner.py index 329b339..f12d39b 100644 --- a/backend/scanner.py +++ b/backend/scanner.py @@ -172,13 +172,26 @@ def _normalize_input_path(path_value): path = resolve_runtime_path(path_value) path = str(path).strip() + # Normalize forward slashes to backslashes first + path = path.replace("/", "\\") + + # Accept \\server\share style UNC paths and ensure proper escaping + if path.startswith("\\\\"): + # Clean up any doubled backslashes from replacement + while "\\\\\\" in path: + path = path.replace("\\\\\\", "\\\\") + return path + # Accept //server/share style and normalize to UNC for smbclient. if path.startswith("//"): - return "\\\\" + path.lstrip("/").replace("/", "\\") + path = path.lstrip("/").replace("/", "\\") + return "\\\\" + path # Accept ///... and normalize to UNC for Linux-hosted inputs. - if re.match(r"^/\d{1,3}(?:\.\d{1,3}){3}/[^/]+", path): - return "\\\\" + path.lstrip("/").replace("/", "\\") + if re.match(r"^\\?\d{1,3}(?:\\\.\d{1,3}){3}\\[^\\]+", path): + if path.startswith("\\"): + path = path.lstrip("\\") + return "\\\\" + path return path @@ -225,6 +238,27 @@ def _iter_dir_entries(path, smb_credentials=None): return list(os.scandir(path)) +def path_exists_with_smb(path, smb_credentials=None): + """Check if a path exists, with SMB authentication for UNC paths.""" + if not path: + return False + + path = _normalize_input_path(path) + + # For UNC paths, use SMB to check + if _is_unc_path(path): + try: + _register_smb_session_if_needed(path, smb_credentials=smb_credentials) + # Try to list entries; if successful, path exists + _iter_dir_entries(path, smb_credentials=smb_credentials) + return True + except Exception: + return False + + # For local paths, use standard os.path.exists + return os.path.exists(path) + + def scan_results(results_dir_dut, results_dir_ref, smb_credentials=None): results_dir_dut = _normalize_input_path(results_dir_dut) results_dir_ref = _normalize_input_path(results_dir_ref) diff --git a/backend/watcher.py b/backend/watcher.py index a3ab930..e7a3c2c 100644 --- a/backend/watcher.py +++ b/backend/watcher.py @@ -10,7 +10,7 @@ from typing import Any from watchdog.events import FileSystemEvent, FileSystemEventHandler, FileSystemMovedEvent from watchdog.observers.polling import PollingObserver -from scanner import resolve_runtime_path, scan_results +from scanner import resolve_runtime_path, scan_results, path_exists_with_smb LOGGER = logging.getLogger("scheduler.watcher") @@ -76,9 +76,15 @@ class ResultDirectoryWatcher: handler = _ResultDirEventHandler(self._on_new_directory) observer = PollingObserver(timeout=self._poll_interval_seconds) + smb_creds = { + "username": new_config.smb_username, + "password": new_config.smb_password, + "domain": new_config.smb_domain, + } + scheduled_count = 0 for result_dir, label in ((dut_dir, "DUT"), (ref_dir, "REF")): - if not os.path.isdir(result_dir): + if not path_exists_with_smb(result_dir, smb_credentials=smb_creds): LOGGER.warning("%s result directory does not exist yet, skipping watch: %s", label, result_dir) continue observer.schedule(handler, result_dir, recursive=False) @@ -159,3 +165,5 @@ def _normalize_watch_path(path_value: Any) -> str: if not cleaned: return "" return str(resolve_runtime_path(cleaned)).strip() + +