From 2c786ece1d310d3100ddc9d7de16bd410fc5ae6d Mon Sep 17 00:00:00 2001 From: Alvaro Cabanas Date: Thu, 18 Aug 2022 15:50:48 +0200 Subject: [PATCH] Add GetValueAsFloat to force returned value to be casted to float (#132) * Add GetValueAsFloat to force returned value to be casted to float * Remove unused NanOrNinf --- gojmx/types.go | 29 +++++++++++++++++- gojmx/types_test.go | 75 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/gojmx/types.go b/gojmx/types.go index 9fb5c66..e97fec2 100644 --- a/gojmx/types.go +++ b/gojmx/types.go @@ -7,9 +7,11 @@ package gojmx import ( "fmt" - "github.com/newrelic/nrjmx/gojmx/internal/nrprotocol" + "strconv" "strings" "unsafe" + + "github.com/newrelic/nrjmx/gojmx/internal/nrprotocol" ) /* @@ -56,6 +58,31 @@ func (j *AttributeResponse) GetValue() interface{} { } } +// GetValueAsFloat casts the value from AttributeResponse to float based on type. +func (j *AttributeResponse) GetValueAsFloat() (float64, error) { + switch (*j).ResponseType { + case ResponseTypeBool: + if j.BoolValue { + return 1, nil + } + return 0, nil + case ResponseTypeString: + parsedValue, err := strconv.ParseFloat(fmt.Sprintf("%v", j.StringValue), 64) + if err != nil { + return 0, err + } + return parsedValue, nil + case ResponseTypeDouble: + return j.DoubleValue, nil + case ResponseTypeInt: + return float64(j.IntValue), nil + case ResponseTypeErr: + return 0, nil + default: + panic(fmt.Sprintf("unkown value type: %v", j.ResponseType)) + } +} + // JMXError is reported when a JMX query fails. type JMXError nrprotocol.JMXError diff --git a/gojmx/types_test.go b/gojmx/types_test.go index fa59eea..6a8b059 100644 --- a/gojmx/types_test.go +++ b/gojmx/types_test.go @@ -70,3 +70,78 @@ func Test_JMXAttribute_GetValue(t *testing.T) { }) } } + +func Test_JMXAttribute_GetValueAsFloat(t *testing.T) { + testCases := []struct { + name string + jmxAttr *AttributeResponse + errorExpected bool + expected float64 + }{ + { + name: "Incorrect String Value", + jmxAttr: &AttributeResponse{ + Name: "test:type=Cat,name=tomas,attr=Name", + ResponseType: nrprotocol.ResponseType_STRING, + StringValue: "aaa", + }, + errorExpected: true, + expected: 0, + }, + { + name: "Double Value", + jmxAttr: &AttributeResponse{ + Name: "test:type=Cat,name=tomas,attr=FloatValue", + ResponseType: nrprotocol.ResponseType_DOUBLE, + DoubleValue: 2.222222, + }, + expected: 2.222222, + }, + { + name: "Number Value", + jmxAttr: &AttributeResponse{ + Name: "test:type=Cat,name=tomas,attr=NumberValue", + ResponseType: nrprotocol.ResponseType_INT, + IntValue: 3, + }, + expected: float64(3), + }, + { + name: "Bool Value", + jmxAttr: &AttributeResponse{ + Name: "test:type=Cat,name=tomas,attr=BoolValue", + ResponseType: nrprotocol.ResponseType_BOOL, + BoolValue: true, + }, + expected: 1, + }, + { + name: "Double Value", + jmxAttr: &AttributeResponse{ + Name: "test:type=Cat,name=tomas,attr=DoubleValue", + ResponseType: nrprotocol.ResponseType_DOUBLE, + DoubleValue: 1.2, + }, + expected: 1.2, + }, + { + name: "String Value", + jmxAttr: &AttributeResponse{ + Name: "test:type=Cat,name=tomas,attr=Name", + ResponseType: nrprotocol.ResponseType_STRING, + StringValue: "1.2", + }, + expected: 1.2, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + floatVal, err := testCase.jmxAttr.GetValueAsFloat() + if testCase.errorExpected { + assert.Error(t, err) + } + assert.Equal(t, testCase.expected, floatVal) + }) + } +}