Skip to content

Commit f33bcc3

Browse files
committed
test(transport): add unit tests for TFTP read/write success and error
1 parent 206dc65 commit f33bcc3

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

backend/pkg/transport/transport_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/HyperloopUPV-H8/h9-backend/pkg/abstraction"
1616
"github.com/HyperloopUPV-H8/h9-backend/pkg/transport/network/tcp"
1717
"github.com/HyperloopUPV-H8/h9-backend/pkg/transport/network/tftp"
18+
tftpv3 "github.com/pin/tftp/v3"
1819
"github.com/HyperloopUPV-H8/h9-backend/pkg/transport/network/udp"
1920
"github.com/HyperloopUPV-H8/h9-backend/pkg/transport/packet/data"
2021
"github.com/HyperloopUPV-H8/h9-backend/pkg/transport/presentation"
@@ -994,6 +995,76 @@ func TestHandleUDPServer_Dispatches(t *testing.T) {
994995
}
995996
}
996997

998+
func TestHandleFileWriteRead_WithRealTFTP(t *testing.T) {
999+
readHandler := func(filename string, rf io.ReaderFrom) error {
1000+
_, err := rf.ReadFrom(bytes.NewBufferString("from-server"))
1001+
return err
1002+
}
1003+
writeBuf := &bytes.Buffer{}
1004+
writeHandler := func(filename string, wt io.WriterTo) error {
1005+
_, err := wt.WriteTo(writeBuf)
1006+
return err
1007+
}
1008+
server := tftpv3.NewServer(readHandler, writeHandler)
1009+
addr := fmt.Sprintf("127.0.0.1:%d", getAvailableUDPPort(t))
1010+
go func() {
1011+
_ = server.ListenAndServe(addr)
1012+
}()
1013+
defer server.Shutdown()
1014+
time.Sleep(20 * time.Millisecond)
1015+
1016+
client, err := tftp.NewClient(addr)
1017+
if err != nil {
1018+
t.Fatalf("failed to create tftp client: %v", err)
1019+
}
1020+
1021+
tr := NewTransport(defaultLogger()).WithTFTP(client)
1022+
tr.SetAPI(NewTestTransportAPI())
1023+
1024+
if err := tr.handleFileWrite(NewFileWriteMessage("file.bin", bytes.NewBufferString("hello"))); err != nil {
1025+
t.Fatalf("handleFileWrite error: %v", err)
1026+
}
1027+
if writeBuf.String() != "hello" {
1028+
t.Fatalf("expected written data 'hello', got %q", writeBuf.String())
1029+
}
1030+
1031+
out := &bytes.Buffer{}
1032+
if err := tr.handleFileRead(NewFileReadMessage("file.bin", out)); err != nil {
1033+
t.Fatalf("handleFileRead error: %v", err)
1034+
}
1035+
if out.String() != "from-server" {
1036+
t.Fatalf("expected read data 'from-server', got %q", out.String())
1037+
}
1038+
}
1039+
1040+
func TestHandleFileWriteRead_ErrorPath(t *testing.T) {
1041+
// Point to an unused UDP port to force WriteFile/ReadFile errors.
1042+
addr := fmt.Sprintf("127.0.0.1:%d", getAvailableUDPPort(t))
1043+
client, err := tftp.NewClient(addr, tftp.WithTimeout(50*time.Millisecond), tftp.WithRetries(1))
1044+
if err != nil {
1045+
t.Fatalf("failed to create tftp client: %v", err)
1046+
}
1047+
1048+
tr := NewTransport(defaultLogger()).WithTFTP(client)
1049+
api := NewTestTransportAPI()
1050+
tr.SetAPI(api)
1051+
1052+
if err := tr.handleFileWrite(NewFileWriteMessage("file.bin", bytes.NewBufferString("hello"))); err == nil {
1053+
t.Fatalf("expected error writing to unreachable TFTP server")
1054+
}
1055+
if err := waitForCondition(func() bool { return len(api.GetNotifications()) > 0 }, time.Second, "error notification"); err != nil {
1056+
t.Fatalf("expected error notification")
1057+
}
1058+
1059+
api.Reset()
1060+
if err := tr.handleFileRead(NewFileReadMessage("file.bin", &bytes.Buffer{})); err == nil {
1061+
t.Fatalf("expected error reading from unreachable TFTP server")
1062+
}
1063+
if err := waitForCondition(func() bool { return len(api.GetNotifications()) > 0 }, time.Second, "error notification"); err != nil {
1064+
t.Fatalf("expected error notification")
1065+
}
1066+
}
1067+
9971068
// Helper function to mimic errors.As behavior
9981069
func ErrorAs(err error, target interface{}) bool {
9991070
switch target := target.(type) {

0 commit comments

Comments
 (0)