diff options
Diffstat (limited to 'internal/encoding/ssh/filexfer/response_packets_test.go')
-rw-r--r-- | internal/encoding/ssh/filexfer/response_packets_test.go | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/internal/encoding/ssh/filexfer/response_packets_test.go b/internal/encoding/ssh/filexfer/response_packets_test.go new file mode 100644 index 0000000..9468665 --- /dev/null +++ b/internal/encoding/ssh/filexfer/response_packets_test.go @@ -0,0 +1,296 @@ +package filexfer + +import ( + "bytes" + "errors" + "testing" +) + +func TestStatusPacketIs(t *testing.T) { + status := &StatusPacket{ + StatusCode: StatusFailure, + ErrorMessage: "error message", + LanguageTag: "language tag", + } + + if !errors.Is(status, StatusFailure) { + t.Error("errors.Is(StatusFailure, StatusFailure) != true") + } + if !errors.Is(status, &StatusPacket{StatusCode: StatusFailure}) { + t.Error("errors.Is(StatusFailure, StatusPacket{StatusFailure}) != true") + } + if errors.Is(status, StatusOK) { + t.Error("errors.Is(StatusFailure, StatusFailure) == true") + } + if errors.Is(status, &StatusPacket{StatusCode: StatusOK}) { + t.Error("errors.Is(StatusFailure, StatusPacket{StatusFailure}) == true") + } +} + +var _ Packet = &StatusPacket{} + +func TestStatusPacket(t *testing.T) { + const ( + id = 42 + statusCode = StatusBadMessage + errorMessage = "foo" + languageTag = "x-example" + ) + + p := &StatusPacket{ + StatusCode: statusCode, + ErrorMessage: errorMessage, + LanguageTag: languageTag, + } + + buf, err := ComposePacket(p.MarshalPacket(id, nil)) + if err != nil { + t.Fatal("unexpected error:", err) + } + + want := []byte{ + 0x00, 0x00, 0x00, 29, + 101, + 0x00, 0x00, 0x00, 42, + 0x00, 0x00, 0x00, 5, + 0x00, 0x00, 0x00, 3, 'f', 'o', 'o', + 0x00, 0x00, 0x00, 9, 'x', '-', 'e', 'x', 'a', 'm', 'p', 'l', 'e', + } + + if !bytes.Equal(buf, want) { + t.Fatalf("MarshalPacket() = %X, but wanted %X", buf, want) + } + + *p = StatusPacket{} + + // UnmarshalBinary assumes the uint32(length) + uint8(type) have already been consumed. + if err := p.UnmarshalPacketBody(NewBuffer(buf[9:])); err != nil { + t.Fatal("unexpected error:", err) + } + + if p.StatusCode != statusCode { + t.Errorf("UnmarshalBinary(): StatusCode was %v, but expected %v", p.StatusCode, statusCode) + } + + if p.ErrorMessage != errorMessage { + t.Errorf("UnmarshalBinary(): ErrorMessage was %q, but expected %q", p.ErrorMessage, errorMessage) + } + + if p.LanguageTag != languageTag { + t.Errorf("UnmarshalBinary(): LanguageTag was %q, but expected %q", p.LanguageTag, languageTag) + } +} + +var _ Packet = &HandlePacket{} + +func TestHandlePacket(t *testing.T) { + const ( + id = 42 + handle = "somehandle" + ) + + p := &HandlePacket{ + Handle: "somehandle", + } + + buf, err := ComposePacket(p.MarshalPacket(id, nil)) + if err != nil { + t.Fatal("unexpected error:", err) + } + + want := []byte{ + 0x00, 0x00, 0x00, 19, + 102, + 0x00, 0x00, 0x00, 42, + 0x00, 0x00, 0x00, 10, 's', 'o', 'm', 'e', 'h', 'a', 'n', 'd', 'l', 'e', + } + + if !bytes.Equal(buf, want) { + t.Fatalf("MarshalPacket() = %X, but wanted %X", buf, want) + } + + *p = HandlePacket{} + + // UnmarshalBinary assumes the uint32(length) + uint8(type) have already been consumed. + if err := p.UnmarshalPacketBody(NewBuffer(buf[9:])); err != nil { + t.Fatal("unexpected error:", err) + } + + if p.Handle != handle { + t.Errorf("UnmarshalBinary(): Handle was %q, but expected %q", p.Handle, handle) + } +} + +var _ Packet = &DataPacket{} + +func TestDataPacket(t *testing.T) { + const ( + id = 42 + ) + + var payload = []byte(`foobar`) + + p := &DataPacket{ + Data: payload, + } + + buf, err := ComposePacket(p.MarshalPacket(id, nil)) + if err != nil { + t.Fatal("unexpected error:", err) + } + + want := []byte{ + 0x00, 0x00, 0x00, 15, + 103, + 0x00, 0x00, 0x00, 42, + 0x00, 0x00, 0x00, 6, 'f', 'o', 'o', 'b', 'a', 'r', + } + + if !bytes.Equal(buf, want) { + t.Fatalf("MarshalPacket() = %X, but wanted %X", buf, want) + } + + *p = DataPacket{} + + // UnmarshalBinary assumes the uint32(length) + uint8(type) have already been consumed. + if err := p.UnmarshalPacketBody(NewBuffer(buf[9:])); err != nil { + t.Fatal("unexpected error:", err) + } + + if !bytes.Equal(p.Data, payload) { + t.Errorf("UnmarshalBinary(): Data was %X, but expected %X", p.Data, payload) + } +} + +var _ Packet = &NamePacket{} + +func TestNamePacket(t *testing.T) { + const ( + id = 42 + filename = "foo" + longname = "bar" + perms = 0x87654300 + ) + + p := &NamePacket{ + Entries: []*NameEntry{ + &NameEntry{ + Filename: filename + "1", + Longname: longname + "1", + Attrs: Attributes{ + Flags: AttrPermissions | (1 << 8), + Permissions: perms | 1, + }, + }, + &NameEntry{ + Filename: filename + "2", + Longname: longname + "2", + Attrs: Attributes{ + Flags: AttrPermissions | (2 << 8), + Permissions: perms | 2, + }, + }, + }, + } + + buf, err := ComposePacket(p.MarshalPacket(id, nil)) + if err != nil { + t.Fatal("unexpected error:", err) + } + + want := []byte{ + 0x00, 0x00, 0x00, 57, + 104, + 0x00, 0x00, 0x00, 42, + 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 4, 'f', 'o', 'o', '1', + 0x00, 0x00, 0x00, 4, 'b', 'a', 'r', '1', + 0x00, 0x00, 0x01, 0x04, + 0x87, 0x65, 0x43, 0x01, + 0x00, 0x00, 0x00, 4, 'f', 'o', 'o', '2', + 0x00, 0x00, 0x00, 4, 'b', 'a', 'r', '2', + 0x00, 0x00, 0x02, 0x04, + 0x87, 0x65, 0x43, 0x02, + } + + if !bytes.Equal(buf, want) { + t.Fatalf("MarshalPacket() = %X, but wanted %X", buf, want) + } + + *p = NamePacket{} + + // UnmarshalBinary assumes the uint32(length) + uint8(type) have already been consumed. + if err := p.UnmarshalPacketBody(NewBuffer(buf[9:])); err != nil { + t.Fatal("unexpected error:", err) + } + + if count := len(p.Entries); count != 2 { + t.Fatalf("UnmarshalBinary(): len(NameEntries) was %d, but expected %d", count, 2) + } + + for i, e := range p.Entries { + if got, want := e.Filename, filename+string('1'+rune(i)); got != want { + t.Errorf("UnmarshalBinary(): Entries[%d].Filename was %q, but expected %q", i, got, want) + } + + if got, want := e.Longname, longname+string('1'+rune(i)); got != want { + t.Errorf("UnmarshalBinary(): Entries[%d].Longname was %q, but expected %q", i, got, want) + } + + if got, want := e.Attrs.Flags, AttrPermissions|((i+1)<<8); got != uint32(want) { + t.Errorf("UnmarshalBinary(): Entries[%d].Attrs.Flags was %#x, but expected %#x", i, got, want) + } + + if got, want := e.Attrs.Permissions, FileMode(perms|(i+1)); got != want { + t.Errorf("UnmarshalBinary(): Entries[%d].Attrs.Permissions was %#v, but expected %#v", i, got, want) + } + } +} + +var _ Packet = &AttrsPacket{} + +func TestAttrsPacket(t *testing.T) { + const ( + id = 42 + perms = 0x87654321 + ) + + p := &AttrsPacket{ + Attrs: Attributes{ + Flags: AttrPermissions, + Permissions: perms, + }, + } + + buf, err := ComposePacket(p.MarshalPacket(id, nil)) + if err != nil { + t.Fatal("unexpected error:", err) + } + + want := []byte{ + 0x00, 0x00, 0x00, 13, + 105, + 0x00, 0x00, 0x00, 42, + 0x00, 0x00, 0x00, 0x04, + 0x87, 0x65, 0x43, 0x21, + } + + if !bytes.Equal(buf, want) { + t.Fatalf("MarshalPacket() = %X, but wanted %X", buf, want) + } + + *p = AttrsPacket{} + + // UnmarshalBinary assumes the uint32(length) + uint8(type) have already been consumed. + if err := p.UnmarshalPacketBody(NewBuffer(buf[9:])); err != nil { + t.Fatal("unexpected error:", err) + } + + if p.Attrs.Flags != AttrPermissions { + t.Errorf("UnmarshalBinary(): Attrs.Flags was %#x, but expected %#x", p.Attrs.Flags, AttrPermissions) + } + + if p.Attrs.Permissions != perms { + t.Errorf("UnmarshalBinary(): Attrs.Permissions was %#v, but expected %#v", p.Attrs.Permissions, perms) + } +} |