@@ -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
9981069func ErrorAs (err error , target interface {}) bool {
9991070 switch target := target .(type ) {
0 commit comments