package mock import ( "testing" "time" ) func TestM1050Reply(t *testing.T) { m := NewMockPLC() // Step 1: PlaceWorkpieceToMachine (M1040 → M1049) m.Write("M1041", []byte{0, 7, 1, 0, 0, 0, 0, 0}) m.WriteByte("M1040", 1) // Wait for M1049 reply deadline := time.Now().Add(2 * time.Second) for time.Now().Before(deadline) { val, _ := m.ReadBool("M1049") if val { t.Log("M1049 reply received") break } time.Sleep(100 * time.Millisecond) } // Auto-clear like waitReply does m.Write("M1040", make([]byte, 9)) t.Log("Auto-cleared M1040") // Simulate MachineWait time.Sleep(1500 * time.Millisecond) // Step 2: FetchWorkpieceFromMachine (M1050 → M1059) m.Write("M1051", []byte{0, 7, 1, 0, 0, 0, 0, 0}) m.WriteByte("M1050", 1) t.Log("Signal M1050 written") // Wait for M1059 reply deadline = time.Now().Add(2 * time.Second) gotReply := false for time.Now().Before(deadline) { val, _ := m.ReadBool("M1059") if val { gotReply = true t.Log("M1059 reply received - SUCCESS") break } time.Sleep(100 * time.Millisecond) } if !gotReply { t.Fatal("M1059 reply never received - FAILED") } } // TestExchangePath 模拟换料路径:FetchWorkpieceFromTempStation(M1020) → ExchangeWorkpieceToMachine(M1060) → PlaceWorkpieceToTempStation(M1030) func TestExchangePath(t *testing.T) { m := NewMockPLC() // 1. FetchWorkpieceFromTempStation (M1020 → M1029) m.Write("M1021", []byte{1, 3, 0, 0, 0}) m.WriteByte("M1020", 1) t.Log("M1020 written, waiting for M1029") deadline := time.Now().Add(2 * time.Second) for time.Now().Before(deadline) { val, _ := m.ReadBool("M1029") if val { t.Log("M1029 reply received") break } time.Sleep(100 * time.Millisecond) } m.Write("M1020", make([]byte, 9)) // autoClear // 2. ExchangeWorkpieceToMachine (M1060 → M1069) m.Write("M1061", []byte{0, 7, 1, 0, 0, 0, 0, 0}) m.WriteByte("M1060", 1) t.Log("M1060 written, waiting for M1069") deadline = time.Now().Add(2 * time.Second) for time.Now().Before(deadline) { val, _ := m.ReadBool("M1069") if val { t.Log("M1069 reply received") break } time.Sleep(100 * time.Millisecond) } m.Write("M1060", make([]byte, 9)) // autoClear // 3. PlaceWorkpieceToTempStation (M1030 → M1039) m.Write("M1031", []byte{1, 3, 0, 0, 0}) m.WriteByte("M1030", 1) t.Log("M1030 written, waiting for M1039") deadline = time.Now().Add(2 * time.Second) gotReply := false for time.Now().Before(deadline) { val, _ := m.ReadBool("M1039") if val { gotReply = true t.Log("M1039 reply received - SUCCESS") break } time.Sleep(100 * time.Millisecond) } if !gotReply { t.Fatal("M1039 reply never received - FAILED") } } // TestConcurrentWriteByte 测试并发 WriteByte 是否会丢失 autoReply func TestConcurrentWriteByte(t *testing.T) { m := NewMockPLC() // 并发写入两个信号 go func() { m.Write("M1021", []byte{1, 3, 0, 0, 0}) m.WriteByte("M1020", 1) }() go func() { m.Write("M1031", []byte{1, 3, 0, 0, 0}) m.WriteByte("M1030", 1) }() // 等待两个回复 deadline := time.Now().Add(2 * time.Second) got1029 := false got1039 := false for time.Now().Before(deadline) { val1029, _ := m.ReadBool("M1029") val1039, _ := m.ReadBool("M1039") if val1029 { got1029 = true } if val1039 { got1039 = true } if got1029 && got1039 { t.Log("Both replies received - SUCCESS") return } time.Sleep(100 * time.Millisecond) } if !got1029 { t.Error("M1029 reply never received") } if !got1039 { t.Error("M1039 reply never received") } }