From ce59bc6597bd8330a93f68a692865af55801bdbe Mon Sep 17 00:00:00 2001 From: yutopp Date: Thu, 27 Jul 2023 01:01:15 +0900 Subject: [PATCH] Add tests. Reduce panics --- message/body_encoder_test.go | 144 +++++++++++++++++++++++++++++++++++ message/net_connection.go | 33 ++++++-- message/net_stream.go | 3 + 3 files changed, 173 insertions(+), 7 deletions(-) create mode 100644 message/body_encoder_test.go diff --git a/message/body_encoder_test.go b/message/body_encoder_test.go new file mode 100644 index 0000000..474d0de --- /dev/null +++ b/message/body_encoder_test.go @@ -0,0 +1,144 @@ +// +// Copyright (c) 2023- yutopp (yutopp@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) +// + +package message + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEncodeCmdMessageOnStatus(t *testing.T) { + tests := []struct { + name string + decoder BodyDecoderFunc + body AMFConvertible + }{ + { + name: "NetConnectionConnect", + decoder: DecodeBodyConnect, + body: &NetConnectionConnect{ + Command: NetConnectionConnectCommand{ + App: "app", + Type: "type", + FlashVer: "flashVer", + TCURL: "tcUrl", + Fpad: true, + Capabilities: 1, + AudioCodecs: 2, + VideoCodecs: 3, + VideoFunction: 4, + ObjectEncoding: EncodingTypeAMF3, + }, + }, + }, + { + name: "NetConnectionConnectResult", + decoder: DecodeBodyConnectResult, + body: &NetConnectionConnectResult{ + Properties: NetConnectionConnectResultProperties{ + FMSVer: "FMS/3,0,1,123", + Capabilities: 31, + Mode: 1, + }, + Information: NetConnectionConnectResultInformation{ + Level: "status", + Code: NetConnectionConnectCodeSuccess, + Description: "Connection succeeded", + }, + }, + }, + { + name: "NetConnectionConnectResult with data", + decoder: DecodeBodyConnectResult, + body: &NetConnectionConnectResult{ + Properties: NetConnectionConnectResultProperties{ + FMSVer: "FMS/3,0,1,123", + Capabilities: 31, + Mode: 1, + }, + Information: NetConnectionConnectResultInformation{ + Level: "status", + Code: NetConnectionConnectCodeSuccess, + Description: "Connection succeeded", + Data: map[string]interface{}{ + "test": "test", + }, + }, + }, + }, + { + name: "NetConnectionCreateStream", + decoder: DecodeBodyCreateStream, + body: &NetConnectionCreateStream{}, + }, + { + name: "NetConnectionCreateStreamResult", + decoder: DecodeBodyCreateStreamResult, + body: &NetConnectionCreateStreamResult{ + StreamID: 1, + }, + }, + { + name: "NetConnectionReleaseStream", + decoder: DecodeBodyReleaseStream, + body: &NetConnectionReleaseStream{ + StreamName: "stream", + }, + }, + { + name: "NetStreamOnStatus", + decoder: DecodeBodyOnStatus, + body: &NetStreamOnStatus{ + InfoObject: NetStreamOnStatusInfoObject{ + Level: NetStreamOnStatusLevelStatus, + Code: NetStreamOnStatusCodePlayStart, + Description: "abc", + ExtraProperties: map[string]interface{}{}, + }, + }, + }, + { + name: "NetStreamOnStatus with extra properties", + decoder: DecodeBodyOnStatus, + body: &NetStreamOnStatus{ + InfoObject: NetStreamOnStatusInfoObject{ + Level: NetStreamOnStatusLevelStatus, + Code: NetStreamOnStatusCodePlayStart, + Description: "abc", + ExtraProperties: map[string]interface{}{"foo": "bar"}, + }, + }, + }, + } + + for _, test := range tests { + test := test // capture + + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + amfTy := EncodingTypeAMF0 + buf := new(bytes.Buffer) + + // object to bytes(AMF0) + amfEnc := NewAMFEncoder(buf, amfTy) + err := EncodeBodyAnyValues(amfEnc, test.body) + require.Nil(t, err) + + // bytes(AMF0) to object + amfDec := NewAMFDecoder(buf, amfTy) + var v AMFConvertible + err = test.decoder(buf, amfDec, &v) + require.Nil(t, err) + + require.Equal(t, test.body, v) + }) + } +} diff --git a/message/net_connection.go b/message/net_connection.go index 4b5ff99..4c1cc0b 100644 --- a/message/net_connection.go +++ b/message/net_connection.go @@ -39,9 +39,12 @@ type NetConnectionConnectCommand struct { } func (t *NetConnectionConnect) FromArgs(args ...interface{}) error { - command := args[0].(map[string]interface{}) + command, ok := args[0].(map[string]interface{}) + if !ok { + return errors.Errorf("expect map[string]interface{} at arg[0], but got %T", args[0]) + } if err := mapstructure.Decode(command, &t.Command); err != nil { - return errors.Wrapf(err, "Failed to mapping NetConnectionConnect") + return errors.Wrapf(err, "failed to mapping arg[0] to NetConnectionConnectCommand") } return nil @@ -72,14 +75,20 @@ type NetConnectionConnectResultInformation struct { } func (t *NetConnectionConnectResult) FromArgs(args ...interface{}) error { - properties := args[0].(map[string]interface{}) + properties, ok := args[0].(map[string]interface{}) + if !ok { + return errors.Errorf("expect map[string]interface{} at arg[0], but got %T", args[0]) + } if err := mapstructure.Decode(properties, &t.Properties); err != nil { - return errors.Wrapf(err, "Failed to mapping NetConnectionConnectResultProperties") + return errors.Wrapf(err, "failed to mapping arg[0] to NetConnectionConnectResultProperties") } information := args[1].(map[string]interface{}) + if !ok { + return errors.Errorf("expect map[string]interface{} at arg[1], but got %T", args[1]) + } if err := mapstructure.Decode(information, &t.Information); err != nil { - return errors.Wrapf(err, "Failed to mapping NetConnectionConnectResultInformation") + return errors.Wrapf(err, "failed to mapping arg[1] to NetConnectionConnectResultInformation") } return nil @@ -113,7 +122,12 @@ type NetConnectionCreateStreamResult struct { func (t *NetConnectionCreateStreamResult) FromArgs(args ...interface{}) error { // args[0] is unknown, ignore - t.StreamID = args[1].(uint32) + + streamID, ok := args[1].(uint32) + if !ok { + return errors.Errorf("expect uint32 at arg[1], but got %T", args[1]) + } + t.StreamID = streamID return nil } @@ -131,7 +145,12 @@ type NetConnectionReleaseStream struct { func (t *NetConnectionReleaseStream) FromArgs(args ...interface{}) error { // args[0] is unknown, ignore - t.StreamName = args[1].(string) + + streamName, ok := args[1].(string) + if !ok { + return errors.Errorf("expect string at arg[1], but got %T", args[1]) + } + t.StreamName = streamName return nil } diff --git a/message/net_stream.go b/message/net_stream.go index 617dd86..e0d381a 100644 --- a/message/net_stream.go +++ b/message/net_stream.go @@ -144,6 +144,9 @@ func (t *NetStreamOnStatus) FromArgs(args ...interface{}) error { func (t *NetStreamOnStatus) ToArgs(ty EncodingType) ([]interface{}, error) { info := make(map[string]interface{}) + for k, v := range t.InfoObject.ExtraProperties { + info[k] = v + } info["level"] = t.InfoObject.Level info["code"] = t.InfoObject.Code info["description"] = t.InfoObject.Description