// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package remoteinput import ( "encoding/binary" "errors" "testing" ) func TestHelperOperationCodec(t *testing.T) { for _, operation := range []Operation{ {Kind: Down, Epoch: 7, Sequence: 1, Name: "Control_R"}, {Kind: Up, Epoch: 7, Sequence: 2, Name: "KP_Enter"}, {Kind: Heartbeat, Epoch: 7, Sequence: ^uint64(0)}, {Kind: Close, Epoch: ^uint64(0), Sequence: 1}, } { frame, err := EncodeOperation(operation) if err != nil || len(frame) != OperationSize || frame[0] != 1 || frame[1] != operation.Kind || binary.BigEndian.Uint64(frame[4:12]) != operation.Epoch || binary.BigEndian.Uint64(frame[12:20]) != operation.Sequence { t.Fatal("wrong fixed operation representation", err) } if decoded, err := DecodeOperation(frame); err != nil || decoded != operation { t.Fatal("operation identity changed", err) } } for _, operation := range []Operation{ {Kind: 0, Epoch: 7, Sequence: 1}, {Kind: Heartbeat, Sequence: 1}, {Kind: Heartbeat, Epoch: 7}, {Kind: Down, Epoch: 7, Sequence: 1}, {Kind: Up, Epoch: 7, Sequence: 1, Name: "private unknown"}, {Kind: Down, Epoch: 7, Sequence: 1, Name: "a\x00"}, {Kind: Heartbeat, Epoch: 7, Sequence: 1, Name: "a"}, {Kind: Close, Epoch: 7, Sequence: 1, Name: "a"}, } { if _, err := EncodeOperation(operation); !errors.Is(err, ErrProtocol) { t.Fatal("invalid private operation was encoded") } } frame, _ := EncodeOperation(Operation{Kind: Down, Epoch: 7, Sequence: 1, Name: "a"}) for _, index := range []int{0, 1, 2, 3, 21, OperationSize - 1} { bad := append([]byte(nil), frame...) bad[index] = 255 if value, err := DecodeOperation(bad); !errors.Is(err, ErrProtocol) || value != (Operation{}) { t.Fatal("malformed version/kind/length/reserved/padding produced a partial operation") } } for _, bad := range [][]byte{nil, frame[:OperationSize-1], append(frame, 0)} { if _, err := DecodeOperation(bad); !errors.Is(err, ErrProtocol) { t.Fatal("nonfixed frame was accepted") } } } func TestHelperAckCodec(t *testing.T) { for _, ack := range []Ack{ {Kind: Ready, Epoch: 7}, {Kind: Accepted, Epoch: 7, Sequence: 1}, {Kind: Closed, Epoch: 7, Sequence: 2, Reason: ReasonClose}, {Kind: Closed, Epoch: 7, Sequence: ^uint64(0), Reason: ReasonEOF, CleanupFailed: true}, } { frame, err := EncodeAck(ack) if err != nil || len(frame) != AckSize { t.Fatal("acknowledgement was not fixed size", err) } if decoded, err := DecodeAck(frame); err != nil || decoded != ack { t.Fatal("acknowledgement lost cleanup/sequence identity", err) } } for _, ack := range []Ack{ {Kind: Ready}, {Kind: Ready, Epoch: 7, Sequence: 1}, {Kind: Ready, Epoch: 7, CleanupFailed: true}, {Kind: Accepted, Epoch: 7}, {Kind: Accepted, Epoch: 7, Sequence: 1, Reason: ReasonClose}, {Kind: Closed, Epoch: 7}, {Kind: Closed, Epoch: 7, Reason: 255}, {Kind: 255, Epoch: 7}, } { if _, err := EncodeAck(ack); !errors.Is(err, ErrProtocol) { t.Fatal("invalid acknowledgement was encoded") } } frame, _ := EncodeAck(Ack{Kind: Closed, Epoch: 7, Reason: ReasonEOF}) for _, index := range []int{0, 1, 2, 3} { bad := append([]byte(nil), frame...) bad[index] = 255 if value, err := DecodeAck(bad); !errors.Is(err, ErrProtocol) || value != (Ack{}) { t.Fatal("invalid acknowledgement flags or version were accepted") } } }