1+ package boards_test
2+
3+ import (
4+ "encoding/json"
5+ "testing"
6+ "time"
7+
8+ "github.com/HyperloopUPV-H8/h9-backend/pkg/abstraction"
9+ "github.com/HyperloopUPV-H8/h9-backend/pkg/boards"
10+ "github.com/HyperloopUPV-H8/h9-backend/pkg/broker"
11+ blcu_topic "github.com/HyperloopUPV-H8/h9-backend/pkg/broker/topics/blcu"
12+ "github.com/HyperloopUPV-H8/h9-backend/pkg/vehicle"
13+ "github.com/HyperloopUPV-H8/h9-backend/pkg/websocket"
14+ "github.com/rs/zerolog"
15+ )
16+
17+ // MockTransport implements abstraction.Transport for testing
18+ type MockTransport struct {
19+ sentMessages []abstraction.TransportMessage
20+ }
21+
22+ func (m * MockTransport ) SendMessage (msg abstraction.TransportMessage ) error {
23+ m .sentMessages = append (m .sentMessages , msg )
24+ return nil
25+ }
26+
27+ func (m * MockTransport ) HandleClient (config interface {}, target string ) error {
28+ return nil
29+ }
30+
31+ func (m * MockTransport ) HandleServer (config interface {}, addr string ) error {
32+ return nil
33+ }
34+
35+ func (m * MockTransport ) HandleSniffer (sniffer interface {}) error {
36+ return nil
37+ }
38+
39+ func (m * MockTransport ) SetAPI (api abstraction.TransportAPI ) {}
40+
41+ func (m * MockTransport ) SetIdTarget (id abstraction.PacketId , target abstraction.TransportTarget ) {}
42+
43+ func (m * MockTransport ) SetTargetIp (ip string , target abstraction.TransportTarget ) {}
44+
45+ func (m * MockTransport ) SetpropagateFault (propagate bool ) {}
46+
47+ func (m * MockTransport ) WithDecoder (decoder interface {}) abstraction.Transport {
48+ return m
49+ }
50+
51+ func (m * MockTransport ) WithEncoder (encoder interface {}) abstraction.Transport {
52+ return m
53+ }
54+
55+ // MockLogger implements abstraction.Logger for testing
56+ type MockLogger struct {}
57+
58+ func (m * MockLogger ) Start () error {
59+ return nil
60+ }
61+
62+ func (m * MockLogger ) Stop () error {
63+ return nil
64+ }
65+
66+ func (m * MockLogger ) PushRecord (record abstraction.LoggerRecord ) error {
67+ return nil
68+ }
69+
70+ func (m * MockLogger ) PullRecord (request abstraction.LoggerRequest ) (abstraction.LoggerRecord , error ) {
71+ return nil , nil
72+ }
73+
74+ // TestBLCUDownloadOrder tests the BLCU download order flow
75+ func TestBLCUDownloadOrder (t * testing.T ) {
76+ // Setup
77+ logger := zerolog .New (nil ).Level (zerolog .Disabled )
78+
79+ // Create vehicle
80+ v := vehicle .New (logger )
81+
82+ // Create and setup broker
83+ b := broker .New (logger )
84+ connections := make (chan * websocket.Client )
85+ pool := websocket .NewPool (connections , logger )
86+ b .SetPool (pool )
87+
88+ // Register BLCU topics
89+ blcu_topic .RegisterTopics (b , pool )
90+
91+ // Set broker and transport
92+ v .SetBroker (b )
93+ mockTransport := & MockTransport {}
94+ v .SetTransport (mockTransport )
95+ mockLogger := & MockLogger {}
96+ v .SetLogger (mockLogger )
97+
98+ // Create BLCU board
99+ blcuBoard := boards .New ("192.168.0.10" ) // Example IP
100+
101+ // This is the missing step - register the BLCU board with the vehicle
102+ v .AddBoard (blcuBoard )
103+
104+ // Note: In a real scenario, we would capture responses through the broker
105+
106+ // Test download request
107+ t .Run ("Download Request" , func (t * testing.T ) {
108+ downloadRequest := & blcu_topic.DownloadRequest {
109+ Board : "VCU" ,
110+ }
111+
112+ // Send download request through UserPush
113+ err := v .UserPush (downloadRequest )
114+ if err != nil {
115+ t .Fatalf ("UserPush failed: %v" , err )
116+ }
117+
118+ // Simulate ACK from board
119+ blcuBoard .Notify (boards.AckNotification {
120+ ID : boards .AckId ,
121+ })
122+
123+ // Check if the download order was sent to the board
124+ if len (mockTransport .sentMessages ) == 0 {
125+ t .Fatal ("No message sent to transport" )
126+ }
127+
128+ // Verify the packet sent contains the correct order ID
129+ // In a real test, we would decode the packet and verify its contents
130+ })
131+ }
132+
133+ // TestBLCUUploadOrder tests the BLCU upload order flow
134+ func TestBLCUUploadOrder (t * testing.T ) {
135+ // Setup
136+ logger := zerolog .New (nil ).Level (zerolog .Disabled )
137+
138+ // Create vehicle
139+ v := vehicle .New (logger )
140+
141+ // Create and setup broker
142+ b := broker .New (logger )
143+ connections := make (chan * websocket.Client )
144+ pool := websocket .NewPool (connections , logger )
145+ b .SetPool (pool )
146+
147+ // Register BLCU topics
148+ blcu_topic .RegisterTopics (b , pool )
149+
150+ // Set broker and transport
151+ v .SetBroker (b )
152+ mockTransport := & MockTransport {}
153+ v .SetTransport (mockTransport )
154+ mockLogger := & MockLogger {}
155+ v .SetLogger (mockLogger )
156+
157+ // Create BLCU board
158+ blcuBoard := boards .New ("192.168.0.10" ) // Example IP
159+
160+ // Register the BLCU board with the vehicle
161+ v .AddBoard (blcuBoard )
162+
163+ // Test upload request
164+ t .Run ("Upload Request" , func (t * testing.T ) {
165+ // Using the internal request type that has Data field
166+ uploadRequest := & blcu_topic.UploadRequestInternal {
167+ Board : "VCU" ,
168+ Data : []byte ("test firmware data" ),
169+ }
170+
171+ // Send upload request through UserPush
172+ err := v .UserPush (uploadRequest )
173+ if err != nil {
174+ t .Fatalf ("UserPush failed: %v" , err )
175+ }
176+
177+ // Simulate ACK from board
178+ blcuBoard .Notify (boards.AckNotification {
179+ ID : boards .AckId ,
180+ })
181+
182+ // Check if the upload order was sent to the board
183+ if len (mockTransport .sentMessages ) == 0 {
184+ t .Fatal ("No message sent to transport" )
185+ }
186+ })
187+ }
188+
189+ // TestBLCUWebSocketFlow tests the complete WebSocket flow for BLCU orders
190+ func TestBLCUWebSocketFlow (t * testing.T ) {
191+ // Setup
192+ logger := zerolog .New (nil ).Level (zerolog .Disabled )
193+
194+ // Create vehicle
195+ v := vehicle .New (logger )
196+
197+ // Create and setup broker
198+ b := broker .New (logger )
199+ connections := make (chan * websocket.Client )
200+ pool := websocket .NewPool (connections , logger )
201+ b .SetPool (pool )
202+
203+ // Register BLCU topics
204+ blcu_topic .RegisterTopics (b , pool )
205+
206+ // Set broker
207+ v .SetBroker (b )
208+ mockTransport := & MockTransport {}
209+ v .SetTransport (mockTransport )
210+ mockLogger := & MockLogger {}
211+ v .SetLogger (mockLogger )
212+
213+ // Create BLCU board
214+ blcuBoard := boards .New ("192.168.0.10" )
215+ v .AddBoard (blcuBoard )
216+
217+ // Simulate WebSocket client message
218+ t .Run ("WebSocket Download Message" , func (t * testing.T ) {
219+ // Get download topic handler from registered topics
220+ downloadHandler := & blcu_topic.Download {}
221+ downloadHandler .SetAPI (b )
222+ downloadHandler .SetPool (pool )
223+
224+ // Create WebSocket message
225+ downloadReq := blcu_topic.DownloadRequest {
226+ Board : "VCU" ,
227+ }
228+ payload , _ := json .Marshal (downloadReq )
229+
230+ wsMessage := & websocket.Message {
231+ Topic : blcu_topic .DownloadName ,
232+ Payload : payload ,
233+ }
234+
235+ // Simulate client message
236+ // Create a valid UUID for ClientId
237+ clientUUID := [16 ]byte {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 }
238+ clientId := websocket .ClientId (clientUUID )
239+ downloadHandler .ClientMessage (clientId , wsMessage )
240+
241+ // Give some time for async operations
242+ time .Sleep (100 * time .Millisecond )
243+
244+ // Verify order was sent
245+ if len (mockTransport .sentMessages ) == 0 {
246+ t .Error ("No message sent to transport after WebSocket message" )
247+ }
248+ })
249+ }
250+
251+ // TestBLCURegistrationIssue demonstrates the issue when BLCU is not registered
252+ func TestBLCURegistrationIssue (t * testing.T ) {
253+ // Setup WITHOUT registering BLCU board
254+ logger := zerolog .New (nil ).Level (zerolog .Disabled )
255+
256+ v := vehicle .New (logger )
257+ b := broker .New (logger )
258+ connections := make (chan * websocket.Client )
259+ pool := websocket .NewPool (connections , logger )
260+ b .SetPool (pool )
261+ blcu_topic .RegisterTopics (b , pool )
262+ v .SetBroker (b )
263+
264+ // Try to send download request without BLCU board registered
265+ t .Run ("Download Without Registration" , func (t * testing.T ) {
266+ defer func () {
267+ if r := recover (); r == nil {
268+ // If no panic, check if the request was handled
269+ // In the current implementation, this will fail silently
270+ t .Log ("Request handled without BLCU registration - this is the bug!" )
271+ }
272+ }()
273+
274+ downloadRequest := & blcu_topic.DownloadRequest {
275+ Board : "VCU" ,
276+ }
277+
278+ // This will fail because boards[boards.BlcuId] is nil
279+ err := v .UserPush (downloadRequest )
280+ if err == nil {
281+ t .Log ("UserPush succeeded but BLCU board notification will fail" )
282+ }
283+ })
284+ }
0 commit comments