From 8a83b3c8ca355aca64a1b664e86327e5ee58ce26 Mon Sep 17 00:00:00 2001 From: Joe Turki Date: Thu, 23 Jan 2025 19:53:04 -0600 Subject: [PATCH] Upgrade golangci-lint, more linters Introduces new linters, upgrade golangci-lint to version (v1.63.4) --- .golangci.yml | 47 +++++++++++++++++---------- datachannel.go | 71 +++++++++++++++++++++++------------------ datachannel_test.go | 19 +++++++---- errors.go | 16 ++++++---- message.go | 10 +++--- message_channel_ack.go | 6 ++-- message_channel_open.go | 22 ++++++++----- message_test.go | 13 +++++++- 8 files changed, 125 insertions(+), 79 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index a3235be..88cb4fb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -25,17 +25,32 @@ linters-settings: - ^os.Exit$ - ^panic$ - ^print(ln)?$ + varnamelen: + max-distance: 12 + min-name-length: 2 + ignore-type-assert-ok: true + ignore-map-index-ok: true + ignore-chan-recv-ok: true + ignore-decls: + - i int + - n int + - w io.Writer + - r io.Reader + - b []byte linters: enable: - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - bidichk # Checks for dangerous unicode character sequences - bodyclose # checks whether HTTP response body is closed successfully + - containedctx # containedctx is a linter that detects struct contained context.Context field - contextcheck # check the function whether use a non-inherited context + - cyclop # checks function and package cyclomatic complexity - decorder # check declaration order and count of types, constants, variables and functions - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - dupl # Tool for code clone detection - durationcheck # check for two durations multiplied together + - err113 # Golang linter to check the errors handling expressions - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. @@ -46,18 +61,17 @@ linters: - forcetypeassert # finds forced type assertions - gci # Gci control golang package import order and make it always deterministic. - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - gocognit # Computes and checks the cognitive complexity of functions - goconst # Finds repeated strings that could be replaced by a constant - gocritic # The most opinionated Go source code linter + - gocyclo # Computes and checks the cyclomatic complexity of functions + - godot # Check if comments end in a period - godox # Tool for detection of FIXME, TODO and other comment keywords - - err113 # Golang linter to check the errors handling expressions - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - gofumpt # Gofumpt checks whether code was gofumpt-ed. - goheader # Checks is file header matches to pattern - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - goprintffuncname # Checks that printf-like functions are named with `f` at the end - gosec # Inspects source code for security problems - gosimple # Linter for Go source code that specializes in simplifying a code @@ -65,9 +79,15 @@ linters: - grouper # An analyzer to analyze expression groups. - importas # Enforces consistent import aliases - ineffassign # Detects when assignments to existing variables are not used + - lll # Reports long lines + - maintidx # maintidx measures the maintainability index of each function. + - makezero # Finds slice declarations with non-zero initial length - misspell # Finds commonly misspelled English words in comments + - nakedret # Finds naked returns in functions greater than a specified function length + - nestif # Reports deeply nested if statements - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. + - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - noctx # noctx finds sending http request without context.Context - predeclared # find code that shadows one of Go's predeclared identifiers - revive # golint replacement, finds style mistakes @@ -75,28 +95,22 @@ linters: - stylecheck # Stylecheck is a replacement for golint - tagliatelle # Checks the struct tags. - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes + - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - unconvert # Remove unnecessary type conversions - unparam # Reports unused function parameters - unused # Checks Go code for unused constants, variables, functions and types + - varnamelen # checks that the length of a variable's name matches its scope - wastedassign # wastedassign finds wasted assignment statements - whitespace # Tool for detection of leading and trailing whitespace disable: - depguard # Go linter that checks if package imports are in a list of acceptable packages - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. + - gochecknoinits # Checks that no init functions are present in Go code + - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. + - interfacebloat # A linter that checks length of interface. - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - nakedret # Finds naked returns in functions greater than a specified function length - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity + - mnd # An analyzer to detect magic numbers - nolintlint # Reports ill-formed or insufficient nolint directives - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - prealloc # Finds slice declarations that could potentially be preallocated @@ -104,8 +118,7 @@ linters: - rowserrcheck # checks whether Err of rows is checked successfully - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope + - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - wrapcheck # Checks that errors returned from external packages are wrapped - wsl # Whitespace Linter - Forces you to use empty lines! diff --git a/datachannel.go b/datachannel.go index 8ece019..054704a 100644 --- a/datachannel.go +++ b/datachannel.go @@ -58,7 +58,7 @@ type ReadWriteCloserDeadliner interface { WriteDeadliner } -// DataChannel represents a data channel +// DataChannel represents a data channel. type DataChannel struct { Config @@ -95,7 +95,7 @@ func newDataChannel(stream *sctp.Stream, config *Config) *DataChannel { } } -// Dial opens a data channels over SCTP +// Dial opens a data channels over SCTP. func Dial(a *sctp.Association, id uint16, config *Config) (*DataChannel, error) { stream, err := a.OpenStream(id, sctp.PayloadTypeWebRTCBinary) if err != nil { @@ -110,7 +110,7 @@ func Dial(a *sctp.Association, id uint16, config *Config) (*DataChannel, error) return dc, nil } -// Client opens a data channel over an SCTP stream +// Client opens a data channel over an SCTP stream. func Client(stream *sctp.Stream, config *Config) (*DataChannel, error) { msg := &channelOpen{ ChannelType: config.ChannelType, @@ -131,10 +131,11 @@ func Client(stream *sctp.Stream, config *Config) (*DataChannel, error) { return nil, fmt.Errorf("failed to send ChannelOpen %w", err) } } + return newDataChannel(stream, config), nil } -// Accept is used to accept incoming data channels over SCTP +// Accept is used to accept incoming data channels over SCTP. func Accept(a *sctp.Association, config *Config, existingChannels ...*DataChannel) (*DataChannel, error) { stream, err := a.AcceptStream() if err != nil { @@ -143,6 +144,7 @@ func Accept(a *sctp.Association, config *Config, existingChannels ...*DataChanne for _, ch := range existingChannels { if ch.StreamIdentifier() == stream.StreamIdentifier() { ch.stream.SetDefaultPayloadType(sctp.PayloadTypeWebRTCBinary) + return ch, nil } } @@ -157,7 +159,7 @@ func Accept(a *sctp.Association, config *Config, existingChannels ...*DataChanne return dc, nil } -// Server accepts a data channel over an SCTP stream +// Server accepts a data channel over an SCTP stream. func Server(stream *sctp.Stream, config *Config) (*DataChannel, error) { buffer := make([]byte, receiveMTU) n, ppi, err := stream.ReadSCTP(buffer) @@ -191,19 +193,21 @@ func Server(stream *sctp.Stream, config *Config) (*DataChannel, error) { if err != nil { return nil, err } + return dataChannel, nil } -// Read reads a packet of len(p) bytes as binary data -func (c *DataChannel) Read(p []byte) (int, error) { - n, _, err := c.ReadDataChannel(p) +// Read reads a packet of len(pkt) bytes as binary data. +func (c *DataChannel) Read(pkt []byte) (int, error) { + n, _, err := c.ReadDataChannel(pkt) + return n, err } -// ReadDataChannel reads a packet of len(p) bytes -func (c *DataChannel) ReadDataChannel(p []byte) (int, bool, error) { +// ReadDataChannel reads a packet of len(pkt) bytes. +func (c *DataChannel) ReadDataChannel(pkt []byte) (int, bool, error) { for { - n, ppi, err := c.stream.ReadSCTP(p) + n, ppi, err := c.stream.ReadSCTP(pkt) if errors.Is(err, io.EOF) { // When the peer sees that an incoming stream was // reset, it also resets its corresponding outgoing stream. @@ -216,39 +220,41 @@ func (c *DataChannel) ReadDataChannel(p []byte) (int, bool, error) { } if ppi == sctp.PayloadTypeWebRTCDCEP { - if err = c.handleDCEP(p[:n]); err != nil { + if err = c.handleDCEP(pkt[:n]); err != nil { c.log.Errorf("Failed to handle DCEP: %s", err.Error()) } + continue } else if ppi == sctp.PayloadTypeWebRTCBinaryEmpty || ppi == sctp.PayloadTypeWebRTCStringEmpty { n = 0 } atomic.AddUint32(&c.messagesReceived, 1) - atomic.AddUint64(&c.bytesReceived, uint64(n)) + atomic.AddUint64(&c.bytesReceived, uint64(n)) //nolint:gosec //G115 isString := ppi == sctp.PayloadTypeWebRTCString || ppi == sctp.PayloadTypeWebRTCStringEmpty + return n, isString, err } } -// SetReadDeadline sets a deadline for reads to return +// SetReadDeadline sets a deadline for reads to return. func (c *DataChannel) SetReadDeadline(t time.Time) error { return c.stream.SetReadDeadline(t) } // SetWriteDeadline sets a deadline for writes to return, -// only available if the BlockWrite is enabled for sctp +// only available if the BlockWrite is enabled for sctp. func (c *DataChannel) SetWriteDeadline(t time.Time) error { return c.stream.SetWriteDeadline(t) } -// MessagesSent returns the number of messages sent +// MessagesSent returns the number of messages sent. func (c *DataChannel) MessagesSent() uint32 { return atomic.LoadUint32(&c.messagesSent) } -// MessagesReceived returns the number of messages received +// MessagesReceived returns the number of messages received. func (c *DataChannel) MessagesReceived() uint32 { return atomic.LoadUint32(&c.messagesReceived) } @@ -276,12 +282,12 @@ func (c *DataChannel) onOpenComplete() { } } -// BytesSent returns the number of bytes sent +// BytesSent returns the number of bytes sent. func (c *DataChannel) BytesSent() uint64 { return atomic.LoadUint64(&c.bytesSent) } -// BytesReceived returns the number of bytes received +// BytesReceived returns the number of bytes received. func (c *DataChannel) BytesReceived() uint64 { return atomic.LoadUint64(&c.bytesReceived) } @@ -310,13 +316,13 @@ func (c *DataChannel) handleDCEP(data []byte) error { return nil } -// Write writes len(p) bytes from p as binary data -func (c *DataChannel) Write(p []byte) (n int, err error) { - return c.WriteDataChannel(p, false) +// Write writes len(pkt) bytes from pkt as binary data. +func (c *DataChannel) Write(pkt []byte) (n int, err error) { + return c.WriteDataChannel(pkt, false) } -// WriteDataChannel writes len(p) bytes from p -func (c *DataChannel) WriteDataChannel(p []byte, isString bool) (n int, err error) { +// WriteDataChannel writes len(pkt) bytes from pkt. +func (c *DataChannel) WriteDataChannel(pkt []byte, isString bool) (n int, err error) { // https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-12#section-6.6 // SCTP does not support the sending of empty user messages. Therefore, // if an empty message has to be sent, the appropriate PPID (WebRTC @@ -326,24 +332,26 @@ func (c *DataChannel) WriteDataChannel(p []byte, isString bool) (n int, err erro // user message and process it as an empty message. var ppi sctp.PayloadProtocolIdentifier switch { - case !isString && len(p) > 0: + case !isString && len(pkt) > 0: ppi = sctp.PayloadTypeWebRTCBinary - case !isString && len(p) == 0: + case !isString && len(pkt) == 0: ppi = sctp.PayloadTypeWebRTCBinaryEmpty - case isString && len(p) > 0: + case isString && len(pkt) > 0: ppi = sctp.PayloadTypeWebRTCString - case isString && len(p) == 0: + case isString && len(pkt) == 0: ppi = sctp.PayloadTypeWebRTCStringEmpty } atomic.AddUint32(&c.messagesSent, 1) - atomic.AddUint64(&c.bytesSent, uint64(len(p))) + atomic.AddUint64(&c.bytesSent, uint64(len(pkt))) - if len(p) == 0 { + if len(pkt) == 0 { _, err := c.stream.WriteSCTP([]byte{0}, ppi) + return 0, err } - return c.stream.WriteSCTP(p, ppi) + + return c.stream.WriteSCTP(pkt, ppi) } func (c *DataChannel) writeDataChannelAck() error { @@ -417,5 +425,6 @@ func (c *DataChannel) commitReliabilityParams() error { default: return fmt.Errorf("%w %v", ErrInvalidChannelType, c.Config.ChannelType) } + return nil } diff --git a/datachannel_test.go b/datachannel_test.go index 0df30d6..2d0923d 100644 --- a/datachannel_test.go +++ b/datachannel_test.go @@ -17,7 +17,7 @@ import ( "github.com/stretchr/testify/assert" ) -// Check we implement our ReadWriteCloser +// Check we implement our ReadWriteCloser. var _ ReadWriteCloser = (*DataChannel)(nil) func bridgeProcessAtLeastOne(br *test.Bridge) { @@ -122,6 +122,8 @@ loop1: } func prOrderedTest(t *testing.T, channelType ChannelType) { + t.Helper() + // Limit runtime in case of deadlocks lim := test.TimeOut(time.Second * 10) defer lim.Stop() @@ -196,6 +198,8 @@ func prOrderedTest(t *testing.T, channelType ChannelType) { } func prUnorderedTest(t *testing.T, channelType ChannelType) { + t.Helper() + sbuf := make([]byte, 1000) rbuf := make([]byte, 2000) @@ -525,6 +529,7 @@ func TestDataChannelBufferedAmount(t *testing.T) { n, err = dc0.Write(sData) assert.Nil(t, err, "Write() should succeed") assert.Equal(t, len(sData), n, "data length should match") + //nolint:gosec //G115 assert.Equal(t, uint64(len(sData)*(i+1)+2), dc0.BufferedAmount(), "incorrect bufferedAmount") } @@ -595,7 +600,7 @@ func TestStats(t *testing.T) { n, err = dc0.Write(sbuf) assert.NoError(t, err, "Write() should succeed") assert.Equal(t, len(sbuf), n, "data length should match") - bytesSent += uint64(n) + bytesSent += uint64(n) //nolint:gosec //G115 assert.Equal(t, dc0.BytesSent(), bytesSent) assert.Equal(t, dc0.MessagesSent(), uint32(1)) @@ -603,7 +608,7 @@ func TestStats(t *testing.T) { n, err = dc0.Write(sbuf) assert.NoError(t, err, "Write() should succeed") assert.Equal(t, len(sbuf), n, "data length should match") - bytesSent += uint64(n) + bytesSent += uint64(n) //nolint:gosec //G115 assert.Equal(t, dc0.BytesSent(), bytesSent) assert.Equal(t, dc0.MessagesSent(), uint32(2)) @@ -611,7 +616,7 @@ func TestStats(t *testing.T) { n, err = dc0.Write([]byte{0}) assert.NoError(t, err, "Write() should succeed") assert.Equal(t, 1, n, "data length should match") - bytesSent += uint64(n) + bytesSent += uint64(n) //nolint:gosec //G115 assert.Equal(t, dc0.BytesSent(), bytesSent) assert.Equal(t, dc0.MessagesSent(), uint32(3)) @@ -629,21 +634,21 @@ func TestStats(t *testing.T) { n, err = dc1.Read(rbuf) assert.NoError(t, err, "Read() should succeed") - bytesRead += uint64(n) + bytesRead += uint64(n) //nolint:gosec //G115 assert.Equal(t, dc1.BytesReceived(), bytesRead) assert.Equal(t, dc1.MessagesReceived(), uint32(1)) n, err = dc1.Read(rbuf) assert.NoError(t, err, "Read() should succeed") - bytesRead += uint64(n) + bytesRead += uint64(n) //nolint:gosec //G115 assert.Equal(t, dc1.BytesReceived(), bytesRead) assert.Equal(t, dc1.MessagesReceived(), uint32(2)) n, err = dc1.Read(rbuf) assert.NoError(t, err, "Read() should succeed") - bytesRead += uint64(n) + bytesRead += uint64(n) //nolint:gosec //G115 assert.Equal(t, n, 1) assert.Equal(t, dc1.BytesReceived(), bytesRead) diff --git a/errors.go b/errors.go index 2f98bf8..a72d5bf 100644 --- a/errors.go +++ b/errors.go @@ -6,22 +6,24 @@ package datachannel import "errors" var ( - // ErrDataChannelMessageTooShort means that the data isn't long enough to be a valid DataChannel message + // ErrDataChannelMessageTooShort means that the data isn't long enough to be a valid DataChannel message. ErrDataChannelMessageTooShort = errors.New("DataChannel message is not long enough to determine type") // ErrInvalidPayloadProtocolIdentifier means that we got a DataChannel messages with a Payload Protocol Identifier - // we don't know how to handle - ErrInvalidPayloadProtocolIdentifier = errors.New("DataChannel message Payload Protocol Identifier is value we can't handle") + // we don't know how to handle. + ErrInvalidPayloadProtocolIdentifier = errors.New( + "DataChannel message Payload Protocol Identifier is value we can't handle", + ) - // ErrInvalidChannelType means that the remote requested a channel type that we don't support + // ErrInvalidChannelType means that the remote requested a channel type that we don't support. ErrInvalidChannelType = errors.New("invalid Channel Type") - // ErrInvalidMessageType is returned when a DataChannel Message has a type we don't support + // ErrInvalidMessageType is returned when a DataChannel Message has a type we don't support. ErrInvalidMessageType = errors.New("invalid Message Type") - // ErrExpectedAndActualLengthMismatch is when the declared length and actual length don't match + // ErrExpectedAndActualLengthMismatch is when the declared length and actual length don't match. ErrExpectedAndActualLengthMismatch = errors.New("expected and actual length do not match") - // ErrUnexpectedDataChannelType is when a message type does not match the expected type + // ErrUnexpectedDataChannelType is when a message type does not match the expected type. ErrUnexpectedDataChannelType = errors.New("expected and actual message type does not match") ) diff --git a/message.go b/message.go index f71ce7b..9568a7a 100644 --- a/message.go +++ b/message.go @@ -7,17 +7,17 @@ import ( "fmt" ) -// message is a parsed DataChannel message +// message is a parsed DataChannel message. type message interface { Marshal() ([]byte, error) Unmarshal([]byte) error String() string } -// messageType is the first byte in a DataChannel message that specifies type +// messageType is the first byte in a DataChannel message that specifies type. type messageType byte -// DataChannel Message Types +// DataChannel Message Types. const ( dataChannelAck messageType = 0x02 dataChannelOpen messageType = 0x03 @@ -34,7 +34,7 @@ func (t messageType) String() string { } } -// parse accepts raw input and returns a DataChannel message +// parse accepts raw input and returns a DataChannel message. func parse(raw []byte) (message, error) { if len(raw) == 0 { return nil, ErrDataChannelMessageTooShort @@ -58,7 +58,7 @@ func parse(raw []byte) (message, error) { } // parseExpectDataChannelOpen parses a DataChannelOpen message -// or throws an error +// or throws an error. func parseExpectDataChannelOpen(raw []byte) (*channelOpen, error) { if len(raw) == 0 { return nil, ErrDataChannelMessageTooShort diff --git a/message_channel_ack.go b/message_channel_ack.go index 8fe396f..f4ce81e 100644 --- a/message_channel_ack.go +++ b/message_channel_ack.go @@ -3,14 +3,14 @@ package datachannel -// channelAck is used to ACK a DataChannel open +// channelAck is used to ACK a DataChannel open. type channelAck struct{} const ( channelOpenAckLength = 4 ) -// Marshal returns raw bytes for the given message +// Marshal returns raw bytes for the given message. func (c *channelAck) Marshal() ([]byte, error) { raw := make([]byte, channelOpenAckLength) raw[0] = uint8(dataChannelAck) @@ -18,7 +18,7 @@ func (c *channelAck) Marshal() ([]byte, error) { return raw, nil } -// Unmarshal populates the struct with the given raw data +// Unmarshal populates the struct with the given raw data. func (c *channelAck) Unmarshal(_ []byte) error { // Message type already checked in Parse and there is no further data return nil diff --git a/message_channel_open.go b/message_channel_open.go index dac58ff..ca89beb 100644 --- a/message_channel_open.go +++ b/message_channel_open.go @@ -29,6 +29,7 @@ channelOpen represents a DATA_CHANNEL_OPEN Message | Protocol | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +. */ type channelOpen struct { ChannelType ChannelType @@ -43,10 +44,10 @@ const ( channelOpenHeaderLength = 12 ) -// ChannelType determines the reliability of the WebRTC DataChannel +// ChannelType determines the reliability of the WebRTC DataChannel. type ChannelType byte -// ChannelType enums +// ChannelType enums. const ( // ChannelTypeReliable determines the Data Channel provides a // reliable in-order bi-directional communication. @@ -89,10 +90,11 @@ func (c ChannelType) String() string { case ChannelTypePartialReliableTimedUnordered: return "PartialReliableTimedUnordered" } + return "Unknown" } -// ChannelPriority enums +// ChannelPriority enums. const ( ChannelPriorityBelowNormal uint16 = 128 ChannelPriorityNormal uint16 = 256 @@ -100,7 +102,7 @@ const ( ChannelPriorityExtraHigh uint16 = 1024 ) -// Marshal returns raw bytes for the given message +// Marshal returns raw bytes for the given message. func (c *channelOpen) Marshal() ([]byte, error) { labelLength := len(c.Label) protocolLength := len(c.Protocol) @@ -112,8 +114,8 @@ func (c *channelOpen) Marshal() ([]byte, error) { raw[1] = byte(c.ChannelType) binary.BigEndian.PutUint16(raw[2:], c.Priority) binary.BigEndian.PutUint32(raw[4:], c.ReliabilityParameter) - binary.BigEndian.PutUint16(raw[8:], uint16(labelLength)) - binary.BigEndian.PutUint16(raw[10:], uint16(protocolLength)) + binary.BigEndian.PutUint16(raw[8:], uint16(labelLength)) //nolint:gosec //G115 + binary.BigEndian.PutUint16(raw[10:], uint16(protocolLength)) //nolint:gosec //G115 endLabel := channelOpenHeaderLength + labelLength copy(raw[channelOpenHeaderLength:endLabel], c.Label) copy(raw[endLabel:endLabel+protocolLength], c.Protocol) @@ -121,7 +123,7 @@ func (c *channelOpen) Marshal() ([]byte, error) { return raw, nil } -// Unmarshal populates the struct with the given raw data +// Unmarshal populates the struct with the given raw data. func (c *channelOpen) Unmarshal(raw []byte) error { if len(raw) < channelOpenHeaderLength { return fmt.Errorf("%w expected(%d) actual(%d)", ErrExpectedAndActualLengthMismatch, channelOpenHeaderLength, len(raw)) @@ -139,9 +141,13 @@ func (c *channelOpen) Unmarshal(raw []byte) error { c.Label = raw[channelOpenHeaderLength : channelOpenHeaderLength+labelLength] c.Protocol = raw[channelOpenHeaderLength+labelLength : channelOpenHeaderLength+labelLength+protocolLength] + return nil } func (c channelOpen) String() string { - return fmt.Sprintf("Open ChannelType(%s) Priority(%v) ReliabilityParameter(%d) Label(%s) Protocol(%s)", c.ChannelType, c.Priority, c.ReliabilityParameter, string(c.Label), string(c.Protocol)) + return fmt.Sprintf( + "Open ChannelType(%s) Priority(%v) ReliabilityParameter(%d) Label(%s) Protocol(%s)", + c.ChannelType, c.Priority, c.ReliabilityParameter, string(c.Label), string(c.Protocol), + ) } diff --git a/message_test.go b/message_test.go index e32b95c..933c000 100644 --- a/message_test.go +++ b/message_test.go @@ -22,6 +22,7 @@ func TestChannelOpenMarshal(t *testing.T) { rawMsg, err := msg.Marshal() if err != nil { t.Errorf("Failed to marshal: %v", err) + return } @@ -32,12 +33,14 @@ func TestChannelOpenMarshal(t *testing.T) { if len(rawMsg) != len(result) { t.Errorf("%q != %q", rawMsg, result) + return } for i, v := range rawMsg { if v != result[i] { t.Errorf("%q != %q", rawMsg, result) + break } } @@ -48,18 +51,21 @@ func TestChannelAckMarshal(t *testing.T) { rawMsg, err := msg.Marshal() if err != nil { t.Errorf("Failed to marshal: %v", err) + return } result := []byte{0x02, 0x00, 0x00, 0x00} if len(rawMsg) != len(result) { t.Errorf("%q != %q", rawMsg, result) + return } for i, v := range rawMsg { if v != result[i] { t.Errorf("%q != %q", rawMsg, result) + break } } @@ -89,6 +95,7 @@ func TestChannelAckUnmarshal(t *testing.T) { msgUncast, err := parse(rawMsg) if err != nil { t.Errorf("Failed to parse: %v", err) + return } @@ -106,6 +113,10 @@ func TestChannelString(t *testing.T) { Protocol: []byte("bar"), }.String() - assert.Equal(t, channelString, "Open ChannelType(Unknown) Priority(0) ReliabilityParameter(0) Label(foo) Protocol(bar)") + assert.Equal( + t, + channelString, + "Open ChannelType(Unknown) Priority(0) ReliabilityParameter(0) Label(foo) Protocol(bar)", + ) assert.Equal(t, channelAck{}.String(), "ACK") }