Skip to content

Commit 9fa79a3

Browse files
authored
Merge branch 'develop' into control-station/migrate-to-zustand
2 parents 54736ab + c284f1a commit 9fa79a3

43 files changed

Lines changed: 1978 additions & 240 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
package blcu_test
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"github.com/HyperloopUPV-H8/h9-backend/pkg/abstraction"
7+
"github.com/HyperloopUPV-H8/h9-backend/pkg/broker"
8+
"github.com/HyperloopUPV-H8/h9-backend/pkg/broker/topics/blcu"
9+
"github.com/HyperloopUPV-H8/h9-backend/pkg/websocket"
10+
ws "github.com/gorilla/websocket"
11+
"github.com/rs/zerolog"
12+
"log"
13+
"net/http"
14+
"net/url"
15+
"os"
16+
"testing"
17+
"time"
18+
)
19+
20+
var errorFlag bool
21+
22+
type OutputNotMatchingError struct{}
23+
24+
func (e *OutputNotMatchingError) Error() string {
25+
return "Output does not match"
26+
}
27+
28+
type MockAPI struct{}
29+
30+
func (api MockAPI) UserPush(push abstraction.BrokerPush) error {
31+
switch push.(type) {
32+
case blcu.DownloadRequest:
33+
if push.(blcu.DownloadRequest).Board != "test" {
34+
errorFlag = true
35+
return &OutputNotMatchingError{}
36+
}
37+
errorFlag = false
38+
log.Printf("Output matches")
39+
return nil
40+
case blcu.UploadRequest:
41+
if push.(blcu.UploadRequest).Board != "test" || string(push.(blcu.UploadRequest).Data) != "test" {
42+
errorFlag = true
43+
fmt.Printf("Expected board 'test' and data 'test', got board '%s' and data '%s'\n", push.(blcu.UploadRequest).Board, string(push.(blcu.UploadRequest).Data))
44+
return &OutputNotMatchingError{}
45+
}
46+
errorFlag = false
47+
log.Printf("Output matches")
48+
return nil
49+
}
50+
return nil
51+
}
52+
53+
func (api MockAPI) UserPull(request abstraction.BrokerRequest) (abstraction.BrokerResponse, error) {
54+
return nil, nil
55+
}
56+
57+
func TestBLCUTopic_Download_Push(t *testing.T) {
58+
logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
59+
u := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/download"}
60+
clientChan := make(chan *websocket.Client)
61+
62+
// Start HTTP server with WebSocket upgrade and echo back
63+
http.HandleFunc("/download", func(writer http.ResponseWriter, request *http.Request) {
64+
upgrader := ws.Upgrader{
65+
CheckOrigin: func(r *http.Request) bool { return true },
66+
}
67+
conn, upgradeErr := upgrader.Upgrade(writer, request, nil)
68+
if upgradeErr != nil {
69+
logger.Error().Err(upgradeErr).Msg("Failed to upgrade")
70+
return
71+
}
72+
defer conn.Close()
73+
defer logger.Info().Str("id", "server").Msg("Connection closed")
74+
75+
// Handle and echo messages continuously
76+
go func() {
77+
for {
78+
_, msg, readMsgRead := conn.ReadMessage()
79+
if readMsgRead != nil {
80+
logger.Error().Err(readMsgRead).Msg("Read error")
81+
return
82+
}
83+
writeMsgErr := conn.WriteMessage(ws.TextMessage, msg)
84+
if writeMsgErr != nil {
85+
logger.Error().Err(writeMsgErr).Msg("Write error")
86+
return
87+
}
88+
}
89+
}()
90+
})
91+
92+
go http.ListenAndServe(":8080", nil)
93+
94+
// Mock first client as it always fails
95+
c, _, err := ws.DefaultDialer.Dial(u.String(), nil)
96+
if err != nil {
97+
log.Printf("Expected dial error")
98+
}
99+
c.Close()
100+
101+
// Set up the client
102+
c, _, err = ws.DefaultDialer.Dial(u.String(), nil)
103+
if err != nil {
104+
logger.Fatal().Err(err).Msg("Error dialing")
105+
}
106+
defer c.Close()
107+
defer logger.Info().Str("id", "client").Msg("Client connection closed")
108+
109+
api := broker.New(logger)
110+
pool := websocket.NewPool(clientChan, logger)
111+
client := websocket.NewClient(c)
112+
clientChan <- client
113+
114+
download := blcu.Download{}
115+
download.SetAPI(api)
116+
download.SetPool(pool)
117+
118+
// Simulate sending a download request
119+
request := blcu.DownloadRequest{Board: "test"}
120+
err = download.Push(request)
121+
if err != nil {
122+
t.Fatal("Error pushing download request:", err)
123+
}
124+
125+
// Use a timeout for client read
126+
done := make(chan struct{})
127+
go func() {
128+
output, readErr := client.Read()
129+
if readErr != nil {
130+
logger.Error().Err(readErr).Msg("Client read failed")
131+
done <- struct{}{}
132+
return
133+
}
134+
if output.Topic != blcu.DownloadName {
135+
t.Errorf("Expected topic %s, got %s", blcu.DownloadName, output.Topic)
136+
}
137+
if string(output.Payload) != "test" {
138+
t.Error("Expected payload 'test', got", string(output.Payload))
139+
}
140+
done <- struct{}{}
141+
}()
142+
143+
select {
144+
case <-done:
145+
logger.Info().Msg("Test completed successfully")
146+
case <-time.After(3 * time.Second):
147+
t.Error("Test timed out")
148+
}
149+
}
150+
151+
func TestBLCUTopic_Download_ClientMessage(t *testing.T) {
152+
download := blcu.Download{}
153+
download.SetAPI(&MockAPI{})
154+
155+
download.ClientMessage(websocket.ClientId{0}, &websocket.Message{
156+
Topic: blcu.DownloadName,
157+
Payload: []byte(`{"board":"test"}`),
158+
})
159+
160+
if errorFlag {
161+
t.Fatal("Output does not match")
162+
}
163+
}
164+
165+
func TestBLCUTopic_Upload_Push(t *testing.T) {
166+
logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
167+
u := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/upload"}
168+
clientChan := make(chan *websocket.Client)
169+
170+
// Start HTTP server with WebSocket upgrade and echo back
171+
http.HandleFunc("/upload", func(writer http.ResponseWriter, request *http.Request) {
172+
upgrader := ws.Upgrader{
173+
CheckOrigin: func(r *http.Request) bool { return true },
174+
}
175+
conn, err := upgrader.Upgrade(writer, request, nil)
176+
if err != nil {
177+
logger.Error().Err(err).Msg("Failed to upgrade")
178+
return
179+
}
180+
defer conn.Close()
181+
defer logger.Info().Str("id", "server").Msg("Connection closed")
182+
183+
// Handle and echo messages continuously
184+
go func() {
185+
for {
186+
_, msg, err := conn.ReadMessage()
187+
if err != nil {
188+
logger.Error().Err(err).Msg("Read error")
189+
return
190+
}
191+
err = conn.WriteMessage(ws.TextMessage, msg)
192+
if err != nil {
193+
logger.Error().Err(err).Msg("Write error")
194+
return
195+
}
196+
}
197+
}()
198+
})
199+
200+
go http.ListenAndServe(":8080", nil)
201+
202+
// Set up the client
203+
c, _, err := ws.DefaultDialer.Dial(u.String(), nil)
204+
if err != nil {
205+
logger.Fatal().Err(err).Msg("Error dialing")
206+
}
207+
defer c.Close()
208+
defer logger.Info().Str("id", "client").Msg("Client connection closed")
209+
210+
api := broker.New(logger)
211+
pool := websocket.NewPool(clientChan, logger)
212+
client := websocket.NewClient(c)
213+
clientChan <- client
214+
215+
upload := blcu.Upload{}
216+
upload.SetAPI(api)
217+
upload.SetPool(pool)
218+
219+
// Simulate sending a download request
220+
request := blcu.UploadRequest{Board: "test", Data: []byte("test")}
221+
err = upload.Push(request)
222+
if err != nil {
223+
t.Fatal("Error pushing upload request:", err)
224+
}
225+
226+
// Use a timeout for client read
227+
done := make(chan struct{})
228+
go func() {
229+
output, err := client.Read()
230+
if err != nil {
231+
logger.Error().Err(err).Msg("Client read failed")
232+
done <- struct{}{}
233+
return
234+
}
235+
if output.Topic != blcu.UploadName {
236+
t.Errorf("Expected topic %s, got %s", blcu.UploadName, output.Topic)
237+
}
238+
if string(output.Payload) != "test" {
239+
t.Error("Expected payload 'test', got", string(output.Payload))
240+
}
241+
done <- struct{}{}
242+
}()
243+
244+
select {
245+
case <-done:
246+
logger.Info().Msg("Test completed successfully")
247+
case <-time.After(3 * time.Second):
248+
t.Error("Test timed out")
249+
}
250+
}
251+
252+
func TestBLCUTopic_Upload_ClientMessage(t *testing.T) {
253+
upload := blcu.Upload{}
254+
upload.SetAPI(&MockAPI{})
255+
256+
payload := blcu.UploadRequest{Board: "test", Data: []byte("test")}
257+
payloadBytes, _ := json.Marshal(payload)
258+
259+
upload.ClientMessage(websocket.ClientId{0}, &websocket.Message{
260+
Topic: blcu.UploadName,
261+
Payload: payloadBytes,
262+
})
263+
264+
if errorFlag {
265+
t.Fatal("Output does not match")
266+
}
267+
}

0 commit comments

Comments
 (0)