2019-06-05 05:39:46 +08:00
package cisco_telemetry_mdt
import (
"context"
"encoding/binary"
"errors"
2021-04-23 05:08:03 +08:00
"io"
2019-06-05 05:39:46 +08:00
"net"
"testing"
dialout "github.com/cisco-ie/nx-telemetry-proto/mdt_dialout"
2021-04-28 09:41:52 +08:00
telemetryBis "github.com/cisco-ie/nx-telemetry-proto/telemetry_bis"
"github.com/golang/protobuf/proto" //nolint:staticcheck // Cannot switch to "google.golang.org/protobuf/proto", "github.com/golang/protobuf/proto" is used by "github.com/cisco-ie/nx-telemetry-proto/telemetry_bis"
2020-02-07 06:18:42 +08:00
"github.com/stretchr/testify/require"
2019-06-05 05:39:46 +08:00
"google.golang.org/grpc"
2021-04-28 09:41:52 +08:00
"github.com/influxdata/telegraf/testutil"
2019-06-05 05:39:46 +08:00
)
func TestHandleTelemetryTwoSimple ( t * testing . T ) {
2019-09-24 06:39:50 +08:00
c := & CiscoTelemetryMDT { Log : testutil . Logger { } , Transport : "dummy" , Aliases : map [ string ] string { "alias" : "type:model/some/path" } }
2019-06-05 05:39:46 +08:00
acc := & testutil . Accumulator { }
2020-02-07 06:18:42 +08:00
err := c . Start ( acc )
// error is expected since we are passing in dummy transport
require . Error ( t , err )
2019-06-05 05:39:46 +08:00
2021-04-28 09:41:52 +08:00
telemetry := & telemetryBis . Telemetry {
2019-06-05 05:39:46 +08:00
MsgTimestamp : 1543236572000 ,
EncodingPath : "type:model/some/path" ,
2021-04-28 09:41:52 +08:00
NodeId : & telemetryBis . Telemetry_NodeIdStr { NodeIdStr : "hostname" } ,
Subscription : & telemetryBis . Telemetry_SubscriptionIdStr { SubscriptionIdStr : "subscription" } ,
DataGpbkv : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "keys" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "name" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "str" } ,
2019-06-05 05:39:46 +08:00
} ,
{
Name : "uint64" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_Uint64Value { Uint64Value : 1234 } ,
2019-06-05 05:39:46 +08:00
} ,
} ,
} ,
{
Name : "content" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "bool" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_BoolValue { BoolValue : true } ,
2019-06-05 05:39:46 +08:00
} ,
} ,
} ,
} ,
} ,
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "keys" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "name" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "str2" } ,
2019-06-05 05:39:46 +08:00
} ,
} ,
} ,
{
Name : "content" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "bool" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_BoolValue { BoolValue : false } ,
2019-06-05 05:39:46 +08:00
} ,
} ,
} ,
} ,
} ,
} ,
}
2021-04-23 05:08:03 +08:00
data , err := proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
c . handleTelemetry ( data )
2020-02-07 06:18:42 +08:00
require . Empty ( t , acc . Errors )
2019-06-05 05:39:46 +08:00
tags := map [ string ] string { "path" : "type:model/some/path" , "name" : "str" , "uint64" : "1234" , "source" : "hostname" , "subscription" : "subscription" }
fields := map [ string ] interface { } { "bool" : true }
acc . AssertContainsTaggedFields ( t , "alias" , fields , tags )
tags = map [ string ] string { "path" : "type:model/some/path" , "name" : "str2" , "source" : "hostname" , "subscription" : "subscription" }
fields = map [ string ] interface { } { "bool" : false }
acc . AssertContainsTaggedFields ( t , "alias" , fields , tags )
}
func TestHandleTelemetrySingleNested ( t * testing . T ) {
2019-09-24 06:39:50 +08:00
c := & CiscoTelemetryMDT { Log : testutil . Logger { } , Transport : "dummy" , Aliases : map [ string ] string { "nested" : "type:model/nested/path" } }
2019-06-05 05:39:46 +08:00
acc := & testutil . Accumulator { }
2020-02-07 06:18:42 +08:00
err := c . Start ( acc )
// error is expected since we are passing in dummy transport
require . Error ( t , err )
2019-06-05 05:39:46 +08:00
2021-04-28 09:41:52 +08:00
telemetry := & telemetryBis . Telemetry {
2019-06-05 05:39:46 +08:00
MsgTimestamp : 1543236572000 ,
EncodingPath : "type:model/nested/path" ,
2021-04-28 09:41:52 +08:00
NodeId : & telemetryBis . Telemetry_NodeIdStr { NodeIdStr : "hostname" } ,
Subscription : & telemetryBis . Telemetry_SubscriptionIdStr { SubscriptionIdStr : "subscription" } ,
DataGpbkv : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "keys" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "nested" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "key" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "level" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_DoubleValue { DoubleValue : 3 } ,
2019-06-05 05:39:46 +08:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
{
Name : "content" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "nested" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "value" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "foo" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "bar" } ,
2019-06-05 05:39:46 +08:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
2021-04-23 05:08:03 +08:00
data , err := proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
c . handleTelemetry ( data )
2020-02-07 06:18:42 +08:00
require . Empty ( t , acc . Errors )
2019-06-05 05:39:46 +08:00
tags := map [ string ] string { "path" : "type:model/nested/path" , "level" : "3" , "source" : "hostname" , "subscription" : "subscription" }
fields := map [ string ] interface { } { "nested/value/foo" : "bar" }
acc . AssertContainsTaggedFields ( t , "nested" , fields , tags )
}
2019-09-17 07:57:25 +08:00
func TestHandleEmbeddedTags ( t * testing . T ) {
c := & CiscoTelemetryMDT { Transport : "dummy" , Aliases : map [ string ] string { "extra" : "type:model/extra" } , EmbeddedTags : [ ] string { "type:model/extra/list/name" } }
acc := & testutil . Accumulator { }
2020-02-07 06:18:42 +08:00
err := c . Start ( acc )
// error is expected since we are passing in dummy transport
require . Error ( t , err )
2019-09-17 07:57:25 +08:00
2021-04-28 09:41:52 +08:00
telemetry := & telemetryBis . Telemetry {
2019-09-17 07:57:25 +08:00
MsgTimestamp : 1543236572000 ,
EncodingPath : "type:model/extra" ,
2021-04-28 09:41:52 +08:00
NodeId : & telemetryBis . Telemetry_NodeIdStr { NodeIdStr : "hostname" } ,
Subscription : & telemetryBis . Telemetry_SubscriptionIdStr { SubscriptionIdStr : "subscription" } ,
DataGpbkv : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "keys" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "foo" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "bar" } ,
2019-09-17 07:57:25 +08:00
} ,
} ,
} ,
{
Name : "content" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "list" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "name" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "entry1" } ,
2019-09-17 07:57:25 +08:00
} ,
{
Name : "test" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "foo" } ,
2019-09-17 07:57:25 +08:00
} ,
} ,
} ,
{
Name : "list" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "name" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "entry2" } ,
2019-09-17 07:57:25 +08:00
} ,
{
Name : "test" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "bar" } ,
2019-09-17 07:57:25 +08:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
2021-04-23 05:08:03 +08:00
data , err := proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-09-17 07:57:25 +08:00
c . handleTelemetry ( data )
2020-02-07 06:18:42 +08:00
require . Empty ( t , acc . Errors )
2019-09-17 07:57:25 +08:00
tags1 := map [ string ] string { "path" : "type:model/extra" , "foo" : "bar" , "source" : "hostname" , "subscription" : "subscription" , "list/name" : "entry1" }
fields1 := map [ string ] interface { } { "list/test" : "foo" }
tags2 := map [ string ] string { "path" : "type:model/extra" , "foo" : "bar" , "source" : "hostname" , "subscription" : "subscription" , "list/name" : "entry2" }
fields2 := map [ string ] interface { } { "list/test" : "bar" }
acc . AssertContainsTaggedFields ( t , "extra" , fields1 , tags1 )
acc . AssertContainsTaggedFields ( t , "extra" , fields2 , tags2 )
}
func TestHandleNXAPI ( t * testing . T ) {
c := & CiscoTelemetryMDT { Transport : "dummy" , Aliases : map [ string ] string { "nxapi" : "show nxapi" } }
acc := & testutil . Accumulator { }
2020-02-07 06:18:42 +08:00
err := c . Start ( acc )
// error is expected since we are passing in dummy transport
require . Error ( t , err )
2019-09-17 07:57:25 +08:00
2021-04-28 09:41:52 +08:00
telemetry := & telemetryBis . Telemetry {
2019-09-17 07:57:25 +08:00
MsgTimestamp : 1543236572000 ,
EncodingPath : "show nxapi" ,
2021-04-28 09:41:52 +08:00
NodeId : & telemetryBis . Telemetry_NodeIdStr { NodeIdStr : "hostname" } ,
Subscription : & telemetryBis . Telemetry_SubscriptionIdStr { SubscriptionIdStr : "subscription" } ,
DataGpbkv : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "keys" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "foo" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "bar" } ,
2019-09-17 07:57:25 +08:00
} ,
} ,
} ,
{
Name : "content" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "TABLE_nxapi" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "ROW_nxapi" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "index" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "i1" } ,
2019-09-17 07:57:25 +08:00
} ,
{
Name : "value" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "foo" } ,
2019-09-17 07:57:25 +08:00
} ,
} ,
} ,
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "index" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "i2" } ,
2019-09-17 07:57:25 +08:00
} ,
{
Name : "value" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "bar" } ,
2019-09-17 07:57:25 +08:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
2021-04-23 05:08:03 +08:00
data , err := proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-09-17 07:57:25 +08:00
c . handleTelemetry ( data )
2020-02-07 06:18:42 +08:00
require . Empty ( t , acc . Errors )
2019-09-17 07:57:25 +08:00
2021-03-17 05:49:07 +08:00
tags1 := map [ string ] string { "path" : "show nxapi" , "foo" : "bar" , "TABLE_nxapi" : "i1" , "row_number" : "0" , "source" : "hostname" , "subscription" : "subscription" }
2019-09-17 07:57:25 +08:00
fields1 := map [ string ] interface { } { "value" : "foo" }
2021-03-17 05:49:07 +08:00
tags2 := map [ string ] string { "path" : "show nxapi" , "foo" : "bar" , "TABLE_nxapi" : "i2" , "row_number" : "0" , "source" : "hostname" , "subscription" : "subscription" }
2019-09-17 07:57:25 +08:00
fields2 := map [ string ] interface { } { "value" : "bar" }
acc . AssertContainsTaggedFields ( t , "nxapi" , fields1 , tags1 )
acc . AssertContainsTaggedFields ( t , "nxapi" , fields2 , tags2 )
}
2021-03-17 05:49:07 +08:00
func TestHandleNXAPIXformNXAPI ( t * testing . T ) {
c := & CiscoTelemetryMDT { Log : testutil . Logger { } , Transport : "dummy" , Aliases : map [ string ] string { "nxapi" : "show nxapi" } }
acc := & testutil . Accumulator { }
err := c . Start ( acc )
// error is expected since we are passing in dummy transport
require . Error ( t , err )
2021-04-28 09:41:52 +08:00
telemetry := & telemetryBis . Telemetry {
2021-03-17 05:49:07 +08:00
MsgTimestamp : 1543236572000 ,
EncodingPath : "show processes cpu" ,
2021-04-28 09:41:52 +08:00
NodeId : & telemetryBis . Telemetry_NodeIdStr { NodeIdStr : "hostname" } ,
Subscription : & telemetryBis . Telemetry_SubscriptionIdStr { SubscriptionIdStr : "subscription" } ,
DataGpbkv : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "keys" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "foo" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "bar" } ,
2021-03-17 05:49:07 +08:00
} ,
} ,
} ,
{
Name : "content" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "TABLE_process_cpu" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "ROW_process_cpu" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "index" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "i1" } ,
2021-03-17 05:49:07 +08:00
} ,
{
Name : "value" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "foo" } ,
2021-03-17 05:49:07 +08:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
2021-04-23 05:08:03 +08:00
data , err := proto . Marshal ( telemetry )
require . NoError ( t , err )
2021-03-17 05:49:07 +08:00
c . handleTelemetry ( data )
require . Empty ( t , acc . Errors )
tags1 := map [ string ] string { "path" : "show processes cpu" , "foo" : "bar" , "TABLE_process_cpu" : "i1" , "row_number" : "0" , "source" : "hostname" , "subscription" : "subscription" }
fields1 := map [ string ] interface { } { "value" : "foo" }
acc . AssertContainsTaggedFields ( t , "show processes cpu" , fields1 , tags1 )
}
func TestHandleNXXformMulti ( t * testing . T ) {
c := & CiscoTelemetryMDT { Transport : "dummy" , Aliases : map [ string ] string { "dme" : "sys/lldp" } }
acc := & testutil . Accumulator { }
err := c . Start ( acc )
// error is expected since we are passing in dummy transport
require . Error ( t , err )
2021-04-28 09:41:52 +08:00
telemetry := & telemetryBis . Telemetry {
2021-03-17 05:49:07 +08:00
MsgTimestamp : 1543236572000 ,
EncodingPath : "sys/lldp" ,
2021-04-28 09:41:52 +08:00
NodeId : & telemetryBis . Telemetry_NodeIdStr { NodeIdStr : "hostname" } ,
Subscription : & telemetryBis . Telemetry_SubscriptionIdStr { SubscriptionIdStr : "subscription" } ,
DataGpbkv : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "keys" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "foo" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "bar" } ,
2021-03-17 05:49:07 +08:00
} ,
} ,
} ,
{
Name : "content" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "fooEntity" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "attributes" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2021-03-17 05:49:07 +08:00
{
Name : "rn" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "some-rn" } ,
2021-03-17 05:49:07 +08:00
} ,
{
Name : "portIdV" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_Uint32Value { Uint32Value : 12 } ,
2021-03-17 05:49:07 +08:00
} ,
{
Name : "portDesc" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_Uint64Value { Uint64Value : 100 } ,
2021-03-17 05:49:07 +08:00
} ,
{
Name : "test" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_Uint64Value { Uint64Value : 281474976710655 } ,
2021-03-17 05:49:07 +08:00
} ,
{
Name : "subscriptionId" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_Uint64Value { Uint64Value : 2814749767106551 } ,
2021-03-17 05:49:07 +08:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
2021-04-23 05:08:03 +08:00
data , err := proto . Marshal ( telemetry )
require . NoError ( t , err )
2021-03-17 05:49:07 +08:00
c . handleTelemetry ( data )
require . Empty ( t , acc . Errors )
//validate various transformation scenaarios newly added in the code.
fields := map [ string ] interface { } { "portIdV" : "12" , "portDesc" : "100" , "test" : int64 ( 281474976710655 ) , "subscriptionId" : "2814749767106551" }
acc . AssertContainsFields ( t , "dme" , fields )
}
2019-09-17 07:57:25 +08:00
func TestHandleNXDME ( t * testing . T ) {
c := & CiscoTelemetryMDT { Transport : "dummy" , Aliases : map [ string ] string { "dme" : "sys/dme" } }
acc := & testutil . Accumulator { }
2020-02-07 06:18:42 +08:00
err := c . Start ( acc )
// error is expected since we are passing in dummy transport
require . Error ( t , err )
2019-09-17 07:57:25 +08:00
2021-04-28 09:41:52 +08:00
telemetry := & telemetryBis . Telemetry {
2019-09-17 07:57:25 +08:00
MsgTimestamp : 1543236572000 ,
EncodingPath : "sys/dme" ,
2021-04-28 09:41:52 +08:00
NodeId : & telemetryBis . Telemetry_NodeIdStr { NodeIdStr : "hostname" } ,
Subscription : & telemetryBis . Telemetry_SubscriptionIdStr { SubscriptionIdStr : "subscription" } ,
DataGpbkv : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "keys" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "foo" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "bar" } ,
2019-09-17 07:57:25 +08:00
} ,
} ,
} ,
{
Name : "content" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "fooEntity" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "attributes" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-09-17 07:57:25 +08:00
{
Name : "rn" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "some-rn" } ,
2019-09-17 07:57:25 +08:00
} ,
{
Name : "value" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "foo" } ,
2019-09-17 07:57:25 +08:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
2021-04-23 05:08:03 +08:00
data , err := proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-09-17 07:57:25 +08:00
c . handleTelemetry ( data )
2020-02-07 06:18:42 +08:00
require . Empty ( t , acc . Errors )
2019-09-17 07:57:25 +08:00
tags1 := map [ string ] string { "path" : "sys/dme" , "foo" : "bar" , "fooEntity" : "some-rn" , "source" : "hostname" , "subscription" : "subscription" }
fields1 := map [ string ] interface { } { "value" : "foo" }
acc . AssertContainsTaggedFields ( t , "dme" , fields1 , tags1 )
}
2019-06-05 05:39:46 +08:00
func TestTCPDialoutOverflow ( t * testing . T ) {
2020-02-07 06:18:42 +08:00
c := & CiscoTelemetryMDT { Log : testutil . Logger { } , Transport : "tcp" , ServiceAddress : "127.0.0.1:0" }
2019-06-05 05:39:46 +08:00
acc := & testutil . Accumulator { }
2020-02-07 06:18:42 +08:00
err := c . Start ( acc )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
hdr := struct {
MsgType uint16
MsgEncap uint16
MsgHdrVersion uint16
MsgFlags uint16
MsgLen uint32
} { MsgLen : uint32 ( 1000000000 ) }
2020-02-07 06:18:42 +08:00
addr := c . Address ( )
conn , err := net . Dial ( addr . Network ( ) , addr . String ( ) )
require . NoError ( t , err )
2021-04-23 05:08:03 +08:00
require . NoError ( t , binary . Write ( conn , binary . BigEndian , hdr ) )
_ , err = conn . Read ( [ ] byte { 0 } )
require . True ( t , err == nil || err == io . EOF )
require . NoError ( t , conn . Close ( ) )
2019-06-05 05:39:46 +08:00
c . Stop ( )
2020-02-07 06:18:42 +08:00
require . Contains ( t , acc . Errors , errors . New ( "dialout packet too long: 1000000000" ) )
2019-06-05 05:39:46 +08:00
}
2021-04-28 09:41:52 +08:00
func mockTelemetryMessage ( ) * telemetryBis . Telemetry {
return & telemetryBis . Telemetry {
2019-06-05 05:39:46 +08:00
MsgTimestamp : 1543236572000 ,
EncodingPath : "type:model/some/path" ,
2021-04-28 09:41:52 +08:00
NodeId : & telemetryBis . Telemetry_NodeIdStr { NodeIdStr : "hostname" } ,
Subscription : & telemetryBis . Telemetry_SubscriptionIdStr { SubscriptionIdStr : "subscription" } ,
DataGpbkv : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "keys" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "name" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_StringValue { StringValue : "str" } ,
2019-06-05 05:39:46 +08:00
} ,
} ,
} ,
{
Name : "content" ,
2021-04-28 09:41:52 +08:00
Fields : [ ] * telemetryBis . TelemetryField {
2019-06-05 05:39:46 +08:00
{
Name : "value" ,
2021-04-28 09:41:52 +08:00
ValueByType : & telemetryBis . TelemetryField_Sint64Value { Sint64Value : - 1 } ,
2019-06-05 05:39:46 +08:00
} ,
} ,
} ,
} ,
} ,
} ,
}
}
func TestTCPDialoutMultiple ( t * testing . T ) {
2020-02-07 06:18:42 +08:00
c := & CiscoTelemetryMDT { Log : testutil . Logger { } , Transport : "tcp" , ServiceAddress : "127.0.0.1:0" , Aliases : map [ string ] string {
2019-06-05 05:39:46 +08:00
"some" : "type:model/some/path" , "parallel" : "type:model/parallel/path" , "other" : "type:model/other/path" } }
acc := & testutil . Accumulator { }
2020-02-07 06:18:42 +08:00
err := c . Start ( acc )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
telemetry := mockTelemetryMessage ( )
hdr := struct {
MsgType uint16
MsgEncap uint16
MsgHdrVersion uint16
MsgFlags uint16
MsgLen uint32
} { }
2020-02-07 06:18:42 +08:00
addr := c . Address ( )
conn , err := net . Dial ( addr . Network ( ) , addr . String ( ) )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
2021-04-23 05:08:03 +08:00
data , err := proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
hdr . MsgLen = uint32 ( len ( data ) )
2021-04-23 05:08:03 +08:00
require . NoError ( t , binary . Write ( conn , binary . BigEndian , hdr ) )
_ , err = conn . Write ( data )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
2020-02-07 06:18:42 +08:00
conn2 , err := net . Dial ( addr . Network ( ) , addr . String ( ) )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
telemetry . EncodingPath = "type:model/parallel/path"
2021-04-23 05:08:03 +08:00
data , err = proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
hdr . MsgLen = uint32 ( len ( data ) )
2021-04-23 05:08:03 +08:00
require . NoError ( t , binary . Write ( conn2 , binary . BigEndian , hdr ) )
_ , err = conn2 . Write ( data )
require . NoError ( t , err )
_ , err = conn2 . Write ( [ ] byte { 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 } )
require . NoError ( t , err )
_ , err = conn2 . Read ( [ ] byte { 0 } )
require . True ( t , err == nil || err == io . EOF )
require . NoError ( t , conn2 . Close ( ) )
2019-06-05 05:39:46 +08:00
telemetry . EncodingPath = "type:model/other/path"
2021-04-23 05:08:03 +08:00
data , err = proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
hdr . MsgLen = uint32 ( len ( data ) )
2021-04-23 05:08:03 +08:00
require . NoError ( t , binary . Write ( conn , binary . BigEndian , hdr ) )
_ , err = conn . Write ( data )
require . NoError ( t , err )
_ , err = conn . Write ( [ ] byte { 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 } )
require . NoError ( t , err )
_ , err = conn . Read ( [ ] byte { 0 } )
require . True ( t , err == nil || err == io . EOF )
2019-06-05 05:39:46 +08:00
c . Stop ( )
2021-04-23 05:08:03 +08:00
require . NoError ( t , conn . Close ( ) )
2019-06-05 05:39:46 +08:00
// We use the invalid dialout flags to let the server close the connection
2020-02-07 06:18:42 +08:00
require . Equal ( t , acc . Errors , [ ] error { errors . New ( "invalid dialout flags: 257" ) , errors . New ( "invalid dialout flags: 257" ) } )
2019-06-05 05:39:46 +08:00
tags := map [ string ] string { "path" : "type:model/some/path" , "name" : "str" , "source" : "hostname" , "subscription" : "subscription" }
fields := map [ string ] interface { } { "value" : int64 ( - 1 ) }
acc . AssertContainsTaggedFields ( t , "some" , fields , tags )
tags = map [ string ] string { "path" : "type:model/parallel/path" , "name" : "str" , "source" : "hostname" , "subscription" : "subscription" }
fields = map [ string ] interface { } { "value" : int64 ( - 1 ) }
acc . AssertContainsTaggedFields ( t , "parallel" , fields , tags )
tags = map [ string ] string { "path" : "type:model/other/path" , "name" : "str" , "source" : "hostname" , "subscription" : "subscription" }
fields = map [ string ] interface { } { "value" : int64 ( - 1 ) }
acc . AssertContainsTaggedFields ( t , "other" , fields , tags )
}
func TestGRPCDialoutError ( t * testing . T ) {
2020-02-07 06:18:42 +08:00
c := & CiscoTelemetryMDT { Log : testutil . Logger { } , Transport : "grpc" , ServiceAddress : "127.0.0.1:0" }
2019-06-05 05:39:46 +08:00
acc := & testutil . Accumulator { }
2020-02-07 06:18:42 +08:00
err := c . Start ( acc )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
2020-02-07 06:18:42 +08:00
addr := c . Address ( )
2021-04-23 05:08:03 +08:00
conn , err := grpc . Dial ( addr . String ( ) , grpc . WithInsecure ( ) )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
client := dialout . NewGRPCMdtDialoutClient ( conn )
2021-04-23 05:08:03 +08:00
stream , err := client . MdtDialout ( context . Background ( ) )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
args := & dialout . MdtDialoutArgs { Errors : "foobar" }
2021-04-23 05:08:03 +08:00
require . NoError ( t , stream . Send ( args ) )
2019-06-05 05:39:46 +08:00
// Wait for the server to close
2021-04-23 05:08:03 +08:00
_ , err = stream . Recv ( )
require . True ( t , err == nil || err == io . EOF )
2019-06-05 05:39:46 +08:00
c . Stop ( )
2020-02-07 06:18:42 +08:00
require . Equal ( t , acc . Errors , [ ] error { errors . New ( "GRPC dialout error: foobar" ) } )
2019-06-05 05:39:46 +08:00
}
func TestGRPCDialoutMultiple ( t * testing . T ) {
2020-02-07 06:18:42 +08:00
c := & CiscoTelemetryMDT { Log : testutil . Logger { } , Transport : "grpc" , ServiceAddress : "127.0.0.1:0" , Aliases : map [ string ] string {
2019-06-05 05:39:46 +08:00
"some" : "type:model/some/path" , "parallel" : "type:model/parallel/path" , "other" : "type:model/other/path" } }
acc := & testutil . Accumulator { }
2020-02-07 06:18:42 +08:00
err := c . Start ( acc )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
telemetry := mockTelemetryMessage ( )
2020-02-07 06:18:42 +08:00
addr := c . Address ( )
2021-04-23 05:08:03 +08:00
conn , err := grpc . Dial ( addr . String ( ) , grpc . WithInsecure ( ) , grpc . WithBlock ( ) )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
client := dialout . NewGRPCMdtDialoutClient ( conn )
2021-04-23 05:08:03 +08:00
stream , err := client . MdtDialout ( context . TODO ( ) )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
2021-04-23 05:08:03 +08:00
data , err := proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
args := & dialout . MdtDialoutArgs { Data : data , ReqId : 456 }
2021-04-23 05:08:03 +08:00
require . NoError ( t , stream . Send ( args ) )
2019-06-05 05:39:46 +08:00
2021-04-23 05:08:03 +08:00
conn2 , err := grpc . Dial ( addr . String ( ) , grpc . WithInsecure ( ) , grpc . WithBlock ( ) )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
client2 := dialout . NewGRPCMdtDialoutClient ( conn2 )
2021-04-23 05:08:03 +08:00
stream2 , err := client2 . MdtDialout ( context . TODO ( ) )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
telemetry . EncodingPath = "type:model/parallel/path"
2021-04-23 05:08:03 +08:00
data , err = proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
args = & dialout . MdtDialoutArgs { Data : data }
2021-04-23 05:08:03 +08:00
require . NoError ( t , stream2 . Send ( args ) )
require . NoError ( t , stream2 . Send ( & dialout . MdtDialoutArgs { Errors : "testclose" } ) )
_ , err = stream2 . Recv ( )
require . True ( t , err == nil || err == io . EOF )
require . NoError ( t , conn2 . Close ( ) )
2019-06-05 05:39:46 +08:00
telemetry . EncodingPath = "type:model/other/path"
2021-04-23 05:08:03 +08:00
data , err = proto . Marshal ( telemetry )
require . NoError ( t , err )
2019-06-05 05:39:46 +08:00
args = & dialout . MdtDialoutArgs { Data : data }
2021-04-23 05:08:03 +08:00
require . NoError ( t , stream . Send ( args ) )
require . NoError ( t , stream . Send ( & dialout . MdtDialoutArgs { Errors : "testclose" } ) )
_ , err = stream . Recv ( )
require . True ( t , err == nil || err == io . EOF )
2019-06-05 05:39:46 +08:00
c . Stop ( )
2021-04-23 05:08:03 +08:00
require . NoError ( t , conn . Close ( ) )
2019-06-05 05:39:46 +08:00
2020-02-07 06:18:42 +08:00
require . Equal ( t , acc . Errors , [ ] error { errors . New ( "GRPC dialout error: testclose" ) , errors . New ( "GRPC dialout error: testclose" ) } )
2019-06-05 05:39:46 +08:00
tags := map [ string ] string { "path" : "type:model/some/path" , "name" : "str" , "source" : "hostname" , "subscription" : "subscription" }
fields := map [ string ] interface { } { "value" : int64 ( - 1 ) }
acc . AssertContainsTaggedFields ( t , "some" , fields , tags )
tags = map [ string ] string { "path" : "type:model/parallel/path" , "name" : "str" , "source" : "hostname" , "subscription" : "subscription" }
fields = map [ string ] interface { } { "value" : int64 ( - 1 ) }
acc . AssertContainsTaggedFields ( t , "parallel" , fields , tags )
tags = map [ string ] string { "path" : "type:model/other/path" , "name" : "str" , "source" : "hostname" , "subscription" : "subscription" }
fields = map [ string ] interface { } { "value" : int64 ( - 1 ) }
acc . AssertContainsTaggedFields ( t , "other" , fields , tags )
}