diff --git a/internal/message/fixtures/TestDecode/test_notify_type.golden b/internal/message/fixtures/TestDecode/test_notify_type.golden deleted file mode 100644 index 5407bf3d..00000000 Binary files a/internal/message/fixtures/TestDecode/test_notify_type.golden and /dev/null differ diff --git a/internal/message/fixtures/TestDecode/test_push_type.golden b/internal/message/fixtures/TestDecode/test_push_type.golden deleted file mode 100644 index ac7ac5f0..00000000 Binary files a/internal/message/fixtures/TestDecode/test_push_type.golden and /dev/null differ diff --git a/internal/message/fixtures/TestDecode/test_push_type_compressed_code_2.golden b/internal/message/fixtures/TestDecode/test_push_type_compressed_code_2.golden deleted file mode 100644 index 7940198b..00000000 Binary files a/internal/message/fixtures/TestDecode/test_push_type_compressed_code_2.golden and /dev/null differ diff --git a/internal/message/fixtures/TestDecode/test_request_type.golden b/internal/message/fixtures/TestDecode/test_request_type.golden deleted file mode 100644 index 4227ca4e..00000000 Binary files a/internal/message/fixtures/TestDecode/test_request_type.golden and /dev/null differ diff --git a/internal/message/fixtures/TestEncode/test_notify_type_compressed.golden b/internal/message/fixtures/TestEncode/test_notify_type_compressed.golden deleted file mode 100644 index bdff0e1b..00000000 Binary files a/internal/message/fixtures/TestEncode/test_notify_type_compressed.golden and /dev/null differ diff --git a/internal/message/fixtures/TestEncode/test_push_type_compressed.golden b/internal/message/fixtures/TestEncode/test_push_type_compressed.golden deleted file mode 100644 index 7940198b..00000000 Binary files a/internal/message/fixtures/TestEncode/test_push_type_compressed.golden and /dev/null differ diff --git a/internal/message/fixtures/TestEncode/test_reponse_type.golden b/internal/message/fixtures/TestEncode/test_reponse_type.golden deleted file mode 100644 index d825e1ad..00000000 Binary files a/internal/message/fixtures/TestEncode/test_reponse_type.golden and /dev/null differ diff --git a/internal/message/fixtures/TestEncode/test_reponse_type_with_data.golden b/internal/message/fixtures/TestEncode/test_reponse_type_with_data.golden deleted file mode 100644 index a80aa55e..00000000 Binary files a/internal/message/fixtures/TestEncode/test_reponse_type_with_data.golden and /dev/null differ diff --git a/internal/message/fixtures/TestEncode/test_reponse_type_with_id.golden b/internal/message/fixtures/TestEncode/test_reponse_type_with_id.golden deleted file mode 100644 index 715792e0..00000000 --- a/internal/message/fixtures/TestEncode/test_reponse_type_with_id.golden +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/internal/message/fixtures/TestEncode/test_request_type_compressed.golden b/internal/message/fixtures/TestEncode/test_request_type_compressed.golden deleted file mode 100644 index 4b755560..00000000 Binary files a/internal/message/fixtures/TestEncode/test_request_type_compressed.golden and /dev/null differ diff --git a/internal/message/fixtures/TestEncode/test_wrong_type.golden b/internal/message/fixtures/test_invalid_message.golden similarity index 100% rename from internal/message/fixtures/TestEncode/test_wrong_type.golden rename to internal/message/fixtures/test_invalid_message.golden diff --git a/internal/message/fixtures/TestEncode/test_notify_type.golden b/internal/message/fixtures/test_notify_type.golden similarity index 100% rename from internal/message/fixtures/TestEncode/test_notify_type.golden rename to internal/message/fixtures/test_notify_type.golden diff --git a/internal/message/fixtures/TestDecode/test_notify_type_compressed.golden b/internal/message/fixtures/test_notify_type_compressed.golden similarity index 100% rename from internal/message/fixtures/TestDecode/test_notify_type_compressed.golden rename to internal/message/fixtures/test_notify_type_compressed.golden diff --git a/internal/message/fixtures/TestEncode/test_push_type.golden b/internal/message/fixtures/test_push_type.golden similarity index 100% rename from internal/message/fixtures/TestEncode/test_push_type.golden rename to internal/message/fixtures/test_push_type.golden diff --git a/internal/message/fixtures/TestDecode/test_push_type_compressed.golden b/internal/message/fixtures/test_push_type_compressed.golden similarity index 100% rename from internal/message/fixtures/TestDecode/test_push_type_compressed.golden rename to internal/message/fixtures/test_push_type_compressed.golden diff --git a/internal/message/fixtures/TestDecode/test_reponse_type.golden b/internal/message/fixtures/test_reponse_type.golden similarity index 100% rename from internal/message/fixtures/TestDecode/test_reponse_type.golden rename to internal/message/fixtures/test_reponse_type.golden diff --git a/internal/message/fixtures/TestDecode/test_reponse_type_with_data.golden b/internal/message/fixtures/test_reponse_type_with_data.golden similarity index 100% rename from internal/message/fixtures/TestDecode/test_reponse_type_with_data.golden rename to internal/message/fixtures/test_reponse_type_with_data.golden diff --git a/internal/message/fixtures/test_reponse_type_with_error.golden b/internal/message/fixtures/test_reponse_type_with_error.golden new file mode 100644 index 00000000..f534c2fe Binary files /dev/null and b/internal/message/fixtures/test_reponse_type_with_error.golden differ diff --git a/internal/message/fixtures/TestDecode/test_reponse_type_with_id.golden b/internal/message/fixtures/test_reponse_type_with_id.golden similarity index 100% rename from internal/message/fixtures/TestDecode/test_reponse_type_with_id.golden rename to internal/message/fixtures/test_reponse_type_with_id.golden diff --git a/internal/message/fixtures/TestEncode/test_request_type.golden b/internal/message/fixtures/test_request_type.golden similarity index 100% rename from internal/message/fixtures/TestEncode/test_request_type.golden rename to internal/message/fixtures/test_request_type.golden diff --git a/internal/message/fixtures/TestDecode/test_request_type_compressed.golden b/internal/message/fixtures/test_request_type_compressed.golden similarity index 100% rename from internal/message/fixtures/TestDecode/test_request_type_compressed.golden rename to internal/message/fixtures/test_request_type_compressed.golden diff --git a/internal/message/fixtures/test_wrong_type.golden b/internal/message/fixtures/test_wrong_type.golden new file mode 100644 index 00000000..e69de29b diff --git a/internal/message/message.go b/internal/message/message.go index b2f42de8..7d6ae05e 100644 --- a/internal/message/message.go +++ b/internal/message/message.go @@ -41,6 +41,7 @@ const ( ) const ( + errorMask = 0x10 msgRouteCompressMask = 0x01 msgTypeMask = 0x07 msgRouteLengthMask = 0xFF @@ -74,20 +75,26 @@ type Message struct { Route string // route for locating service Data []byte // payload compressed bool // is message compressed + err bool // is an error message } // New returns a new message instance -func New() *Message { - return &Message{} +func New(err ...bool) *Message { + m := &Message{} + if len(err) > 0 { + m.err = err[0] + } + return m } // String, implementation of fmt.Stringer interface func (m *Message) String() string { - return fmt.Sprintf("Type: %s, ID: %d, Route: %s, Compressed: %t, BodyLength: %d", + return fmt.Sprintf("Type: %s, ID: %d, Route: %s, Compressed: %t, Error: %t ,BodyLength: %d", types[m.Type], m.ID, m.Route, m.compressed, + m.err, len(m.Data)) } @@ -130,6 +137,11 @@ func Encode(m *Message) ([]byte, error) { if compressed { flag |= msgRouteCompressMask } + + if m.err { + flag |= errorMask + } + buf = append(buf, flag) if m.Type == Request || m.Type == Response { @@ -192,6 +204,8 @@ func Decode(data []byte) (*Message, error) { m.ID = id } + m.err = flag&errorMask == errorMask + if routable(m.Type) { if flag&msgRouteCompressMask == 1 { m.compressed = true diff --git a/internal/message/message_test.go b/internal/message/message_test.go index 20e1f042..44b1dc96 100644 --- a/internal/message/message_test.go +++ b/internal/message/message_test.go @@ -3,6 +3,7 @@ package message import ( "errors" "flag" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -28,25 +29,28 @@ func TestNew(t *testing.T) { var encodeTables = map[string]struct { message *Message routes map[string]uint16 + msgErr bool err error }{ - "test_wrong_type": {&Message{Type: 0xff}, nil, ErrWrongMessageType}, + "test_wrong_type": {&Message{Type: 0xff, Data: []byte{}}, nil, false, ErrWrongMessageType}, - "test_request_type": {&Message{Type: Request, Route: "a"}, nil, nil}, + "test_request_type": {&Message{Type: Request, Route: "a", Data: []uint8{}}, nil, false, nil}, "test_request_type_compressed": {&Message{Type: Request, Route: "a", Data: []byte{}, compressed: true}, - map[string]uint16{"a": 1}, nil}, + map[string]uint16{"a": 1}, false, nil}, - "test_notify_type": {&Message{Type: Notify, Route: "a", Data: []byte{}}, nil, nil}, + "test_notify_type": {&Message{Type: Notify, Route: "a", Data: []byte{}}, nil, false, nil}, "test_notify_type_compressed": {&Message{Type: Notify, Route: "a", Data: []byte{}, compressed: true}, - map[string]uint16{"a": 1}, nil}, + map[string]uint16{"a": 1}, false, nil}, - "test_push_type": {&Message{Type: Push, Route: "a", Data: []byte{}}, nil, nil}, + "test_push_type": {&Message{Type: Push, Route: "a", Data: []byte{}}, nil, false, nil}, "test_push_type_compressed": {&Message{Type: Push, Route: "a", Data: []byte{}, compressed: true}, - map[string]uint16{"a": 1}, nil}, + map[string]uint16{"a": 1}, false, nil}, - "test_reponse_type": {&Message{Type: Response, Data: []byte{}}, nil, nil}, - "test_reponse_type_with_data": {&Message{Type: Response, Data: []byte{0x01}}, nil, nil}, - "test_reponse_type_with_id": {&Message{Type: Response, ID: 129, Data: []byte{}}, nil, nil}, + "test_reponse_type": {&Message{Type: Response, Data: []byte{}}, nil, false, nil}, + "test_reponse_type_with_data": {&Message{Type: Response, Data: []byte{0x01}}, nil, false, nil}, + "test_reponse_type_with_id": {&Message{Type: Response, ID: 129, Data: []byte{}}, nil, false, nil}, + + "test_reponse_type_with_error": {&Message{Type: Response, Data: []byte{0x01}, err: true}, nil, true, nil}, } func TestEncode(t *testing.T) { @@ -56,7 +60,7 @@ func TestEncode(t *testing.T) { SetDictionary(table.routes) result, err := message.Encode() - gp := helpers.FixtureGoldenFileName(t, t.Name()) + gp := filepath.Join("fixtures", name+".golden") if *update { t.Log("updating golden file") @@ -78,6 +82,29 @@ func TestEncode(t *testing.T) { } } +func TestDecode(t *testing.T) { + for name, table := range encodeTables { + t.Run(name, func(t *testing.T) { + SetDictionary(table.routes) + + gp := filepath.Join("fixtures", name+".golden") + encoded := helpers.ReadFile(t, gp) + + message, err := Decode(encoded) + + if err == nil { + assert.Equal(t, table.message, message) + } + if name == "test_wrong_type" { + assert.EqualError(t, ErrInvalidMessage, err.Error()) + } else { + assert.Equal(t, table.err, err) + } + resetDicts(t) + }) + } +} + var dictTables = map[string]struct { dicts []map[string]uint16 routes map[string]uint16 @@ -108,66 +135,3 @@ func TestSetDictionaty(t *testing.T) { }) } } - -var decodeTables = map[string]struct { - encodedMessage *Message - decodedMessage *Message - routes map[string]uint16 - err error -}{ - "test_request_type": {&Message{Type: Request, Data: []byte{}}, - &Message{Type: Request, Data: []byte{}}, nil, nil}, - "test_request_type_compressed": {&Message{Type: Request, Route: "a", Data: []byte{}}, - &Message{Type: Request, Route: "a", Data: []byte{}, compressed: true}, map[string]uint16{"a": 1}, nil}, - - "test_notify_type": {&Message{Type: Notify, Data: []byte{}}, - &Message{Type: Notify, Data: []byte{}}, nil, nil}, - "test_notify_type_compressed": {&Message{Type: Notify, Route: "a", Data: []byte{}}, - &Message{Type: Notify, Route: "a", Data: []byte{}, compressed: true}, map[string]uint16{"a": 1}, nil}, - - "test_push_type": {&Message{Type: Push, Data: []byte{}}, - &Message{Type: Push, Data: []byte{}}, nil, nil}, - "test_push_type_compressed": {&Message{Type: Push, Route: "a", Data: []byte{}}, - &Message{Type: Push, Route: "a", Data: []byte{}, compressed: true}, map[string]uint16{"a": 1}, nil}, - "test_push_type_compressed_code_2": {&Message{Type: Push, Route: "a", Data: []byte{}}, - nil, map[string]uint16{"a": 2}, ErrRouteInfoNotFound}, - - "test_reponse_type": {&Message{Type: Response, Data: []byte{}}, - &Message{Type: Response, Data: []byte{}}, nil, nil}, - "test_reponse_type_with_data": {&Message{Type: Response, Data: []byte{0x01}}, - &Message{Type: Response, Data: []byte{0x01}}, nil, nil}, - "test_reponse_type_with_id": {&Message{Type: Response, ID: 129, Data: []byte{}}, - &Message{Type: Response, ID: 129, Data: []byte{}}, nil, nil}, -} - -func TestDecode(t *testing.T) { - for name, table := range decodeTables { - t.Run(name, func(t *testing.T) { - - if *update { - SetDictionary(map[string]uint16{"a": 1}) - - result, err := table.encodedMessage.Encode() - assert.NoError(t, err) - - gp := helpers.FixtureGoldenFileName(t, t.Name()) - - t.Log("updating golden file", gp) - helpers.WriteFile(t, gp, result) - resetDicts(t) - } - - SetDictionary(table.routes) - - gp := helpers.FixtureGoldenFileName(t, t.Name()) - encoded := helpers.ReadFile(t, gp) - - message, err := Decode(encoded) - - assert.Equal(t, table.decodedMessage, message) - assert.Equal(t, table.err, err) - - resetDicts(t) - }) - } -}