Improve Sum method from utils/reflect.go

This commit is contained in:
TeoV
2019-04-14 11:40:22 +03:00
committed by Dan Christian Bogos
parent a484fc9388
commit 7a971cbb2e
5 changed files with 124 additions and 148 deletions

View File

@@ -128,8 +128,6 @@ func (ar *AgentRequest) AsNavigableMap(tplFlds []*config.FCTemplate) (
} else if !pass {
continue
}
fmt.Println("==============================================")
fmt.Println(utils.ToJSON(tplFld))
out, err := ar.ParseField(tplFld)
if err != nil {
if err == utils.ErrNotFound {
@@ -167,8 +165,6 @@ func (ar *AgentRequest) AsNavigableMap(tplFlds []*config.FCTemplate) (
}
valSet = append(valSet, nMItm)
ar.CGRAReq.Set(fldPath, valSet, false, true)
fmt.Println("Set the value in nM")
fmt.Println(ar.CGRAReq.String())
if tplFld.Blocker { // useful in case of processing errors first
break
}

View File

@@ -51,15 +51,15 @@ var sTestsDiam = []func(t *testing.T){
testDiamItInitCfg,
testDiamItResetDataDb,
testDiamItResetStorDb,
// testDiamItStartEngine,
testDiamItStartEngine,
testDiamItConnectDiameterClient,
testDiamItApierRpcConn,
testDiamItTPFromFolder,
//testDiamItDryRun,
testDiamItDryRun,
testDiamItCCRInit,
// testDiamItCCRUpdate,
// testDiamItCCRTerminate,
//testDiamItCCRSMS,
testDiamItCCRUpdate,
testDiamItCCRTerminate,
testDiamItCCRSMS,
testDiamItKillEngine,
}

View File

@@ -19,19 +19,10 @@
{"tag": "Account", "field_id": "Account", "type": "*constant", "value": "*attributes"},
{"tag": "Destination", "field_id": "Destination", "type": "*composed",
"value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true},
{"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed",
"value": "~*req.Event-Timestamp", "mandatory": true},
{"tag": "Usage", "field_id": "Usage", "type": "*composed",
"value": "~*req.Requested-Service-Unit.CC-Time:s/(.*)/${1}s/", "mandatory": true},
{"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*difference",
"value": "~*req.Event-Timestamp;~*cgrareq.Usage", "mandatory": true},
// {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed",
// "value": "~*req.Event-Timestamp", "mandatory": true},
// {"tag": "Usage", "field_id": "Usage", "type": "*composed",
// "value": "~*req.Requested-Service-Unit.CC-Time:s/(.*)/${1}s/", "mandatory": true},
{"tag": "SubscriberID", "field_id": "SubscriberId", "type": "*composed",
"value": "~*req.Subscription-Id.Subscription-Id-Data", "mandatory": true},
],
@@ -59,18 +50,10 @@
{"tag": "Account", "field_id": "Account", "type": "*constant", "value": "*attributes"},
{"tag": "Destination", "field_id": "Destination", "type": "*composed",
"value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true},
// {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed",
// "value": "~*req.Event-Timestamp", "mandatory": true},
// {"tag": "Usage", "field_id": "Usage", "type": "*composed",
// "value": "~*req.Requested-Service-Unit.CC-Time:s/(.*)/${1}s/", "mandatory": true},
{"tag": "Usage", "field_id": "Usage", "type": "*cc_usage", "mandatory": true,
"value": "~*req.CC-Request-Number;~*req.Used-Service-Unit.CC-Time:s/(.*)/${1}s/;30s"},
{"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*difference",
"value": "~*req.Event-Timestamp;~*cgreq.Usage", "mandatory": true},
{"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed",
"value": "~*req.Event-Timestamp", "mandatory": true},
{"tag": "Usage", "field_id": "Usage", "type": "*composed",
"value": "~*req.Requested-Service-Unit.CC-Time:s/(.*)/${1}s/", "mandatory": true},
{"tag": "LastUsed", "field_id": "LastUsed", "type": "*composed",
"value": "~*req.Used-Service-Unit.CC-Time:s/(.*)/${1}s/", "mandatory": true},
{"tag": "SubscriberID", "field_id": "SubscriberId", "type": "*composed",
@@ -99,19 +82,10 @@
{"tag": "Account", "field_id": "Account", "type": "*constant", "value": "*attributes"},
{"tag": "Destination", "field_id": "Destination", "type": "*composed",
"value": "~*req.Service-Information.IN-Information.Real-Called-Number", "mandatory": true},
// {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed",
// "value": "~*req.Event-Timestamp", "mandatory": true},
// {"tag": "Usage", "field_id": "Usage", "type": "*cc_usage", "mandatory": true,
// "value": "~*req.CC-Request-Number;~*req.Used-Service-Unit.CC-Time:s/(.*)/${1}s/;5m"},
{"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed",
"value": "~*req.Event-Timestamp", "mandatory": true},
{"tag": "Usage", "field_id": "Usage", "type": "*cc_usage", "mandatory": true,
"value": "~*req.CC-Request-Number;~*req.Used-Service-Unit.CC-Time:s/(.*)/${1}s/;30s"},
{"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*difference",
"value": "~*req.Event-Timestamp;~*cgreq.Usage", "mandatory": true},
"value": "~*req.CC-Request-Number;~*req.Used-Service-Unit.CC-Time:s/(.*)/${1}s/;5m"},
{"tag": "LastUsed", "field_id": "LastUsed", "type": "*composed",
"value": "~*req.Used-Service-Unit.CC-Time:s/(.*)/${1}s/", "mandatory": true},
{"tag": "SubscriberID", "field_id": "SubscriberId", "type": "*composed",

View File

@@ -129,36 +129,35 @@ func IfaceAsTime(itm interface{}, timezone string) (t time.Time, err error) {
}
func IfaceAsDuration(itm interface{}) (d time.Duration, err error) {
switch itm.(type) {
switch it := itm.(type) {
case time.Duration:
return itm.(time.Duration), nil
return it, nil
case float64: // automatically hitting here also ints
return time.Duration(int64(itm.(float64))), nil
return time.Duration(int64(it)), nil
case int64:
return time.Duration(itm.(int64)), nil
return time.Duration(it), nil
case int:
return time.Duration(itm.(int)), nil
return time.Duration(it), nil
case string:
return ParseDurationWithNanosecs(itm.(string))
default:
err = fmt.Errorf("cannot convert field: %+v to time.Duration", itm)
err = fmt.Errorf("cannot convert field: %+v to time.Duration", it)
}
return
}
func IfaceAsInt64(itm interface{}) (i int64, err error) {
switch itm.(type) {
switch it := itm.(type) {
case int:
return int64(itm.(int)), nil
return int64(it), nil
case time.Duration:
return itm.(time.Duration).Nanoseconds(), nil
return it.Nanoseconds(), nil
case int64:
return itm.(int64), nil
return it, nil
case string:
return strconv.ParseInt(itm.(string), 10, 64)
return strconv.ParseInt(it, 10, 64)
default:
err = fmt.Errorf("cannot convert field: %+v to int", itm)
err = fmt.Errorf("cannot convert field: %+v to int", it)
}
return
}
@@ -352,59 +351,56 @@ func Sum(items ...interface{}) (sum interface{}, err error) {
return nil, ErrNotEnoughParameters
}
// convert the type for first item
valItm := reflect.ValueOf(items[0])
switch valItm.Kind() {
case reflect.Float32:
items[0] = valItm.Float()
valItm = reflect.ValueOf(items[0])
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
items[0] = valItm.Int()
valItm = reflect.ValueOf(items[0])
}
typItem := reflect.TypeOf(items[0])
//populate sum with first item so we can add after
switch items[0].(type) {
case float64:
sum = valItm.Float()
case int64:
sum = valItm.Int()
switch dt := items[0].(type) {
case time.Duration:
tVal := items[0].(time.Duration)
sum = tVal
}
for _, item := range items[1:] {
valOtItm := reflect.ValueOf(item)
// convert to wider type so we can be compatible with StringToInterface function
switch valOtItm.Kind() {
case reflect.Float32:
item = valOtItm.Float()
valOtItm = reflect.ValueOf(item)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
item = valOtItm.Int()
valOtItm = reflect.ValueOf(item)
sum = dt
for _, item := range items[1:] {
if itmVal, err := IfaceAsDuration(item); err != nil {
return nil, err
} else {
sum = sum.(time.Duration) + itmVal
}
}
typOItem := reflect.TypeOf(item)
// check if the type for rest items is the same as first
if !typItem.Comparable() ||
!typOItem.Comparable() ||
typItem != typOItem {
return false, errors.New("incomparable")
case time.Time:
sum = dt
for _, item := range items[1:] {
if itmVal, err := IfaceAsDuration(item); err != nil {
return nil, err
} else {
sum = sum.(time.Time).Add(itmVal)
}
}
switch items[0].(type) {
case float64:
sum = reflect.ValueOf(sum).Float() + valOtItm.Float()
case int64:
sum = reflect.ValueOf(sum).Int() + valOtItm.Int()
case time.Duration:
tOVal := item.(time.Duration)
sum = sum.(time.Duration) + tOVal
default: // unsupported comparison
err = fmt.Errorf("unsupported comparison type: %v, kind: %v", typItem, typItem.Kind())
break
case float64:
sum = dt
for _, item := range items[1:] {
if itmVal, err := IfaceAsFloat64(item); err != nil {
return nil, err
} else {
sum = sum.(float64) + itmVal
}
}
case int64:
sum = dt
for _, item := range items[1:] {
if itmVal, err := IfaceAsInt64(item); err != nil {
return nil, err
} else {
sum = sum.(int64) + itmVal
}
}
case int:
// need explicit conversion for int
if firstItmVal, err := IfaceAsInt64(dt); err != nil {
return nil, err
} else {
sum = firstItmVal
}
for _, item := range items[1:] {
if itmVal, err := IfaceAsInt64(item); err != nil {
return nil, err
} else {
sum = sum.(int64) + itmVal
}
}
}
return
@@ -417,18 +413,16 @@ func Difference(items ...interface{}) (diff interface{}, err error) {
if len(items) < 2 {
return nil, ErrNotEnoughParameters
}
switch dt := items[0].(type) {
// case time.Duration:
// diff = dt
// for _, item := range items[1:] {
// if itmVal, err := IfaceAsDuration(item); err != nil {
// return nil, err
// } else {
// diff = diff.(time.Duration) - itmVal
// }
// }
case time.Duration:
diff = dt
for _, item := range items[1:] {
if itmVal, err := IfaceAsDuration(item); err != nil {
return nil, err
} else {
diff = diff.(time.Duration) - itmVal
}
}
case time.Time:
diff = dt
for _, item := range items[1:] {
@@ -438,7 +432,6 @@ func Difference(items ...interface{}) (diff interface{}, err error) {
diff = diff.(time.Time).Add(-itmVal)
}
}
case float64:
diff = dt
for _, item := range items[1:] {
@@ -448,18 +441,31 @@ func Difference(items ...interface{}) (diff interface{}, err error) {
diff = diff.(float64) - itmVal
}
}
// case int64:
// for _, item := range items[1:] {
// if itmVal, err := IfaceAsInt64(item); err != nil {
// return nil, err
// } else {
// diff = diff.(int64) - itmVal
// }
// }
case int64:
diff = dt
for _, item := range items[1:] {
if itmVal, err := IfaceAsInt64(item); err != nil {
return nil, err
} else {
diff = diff.(int64) - itmVal
}
}
case int:
// need explicit conversion for int
if firstItmVal, err := IfaceAsInt64(dt); err != nil {
return nil, err
} else {
diff = firstItmVal
}
for _, item := range items[1:] {
if itmVal, err := IfaceAsInt64(item); err != nil {
return nil, err
} else {
diff = diff.(int64) - itmVal
}
}
default: // unsupported comparison
return nil, fmt.Errorf("unsupported type")
}
return
}

View File

@@ -466,7 +466,7 @@ func TestSum(t *testing.T) {
if _, err := Sum(1); err == nil || err != ErrNotEnoughParameters {
t.Error(err)
}
if _, err := Sum(1, 1.2, false); err == nil || err.Error() != "incomparable" {
if _, err := Sum(1, 1.2, false); err == nil || err.Error() != "cannot convert field: 1.2 to int" {
t.Error(err)
}
if sum, err := Sum(1.2, 1.2, 1.2, 1.2); err != nil {
@@ -558,14 +558,14 @@ func TestDifference(t *testing.T) {
if _, err := Difference(10); err == nil || err != ErrNotEnoughParameters {
t.Error(err)
}
if _, err := Difference(10, 1.2, false); err == nil || err.Error() != "unsupported type" {
if _, err := Difference(10, 1.2, false); err == nil || err.Error() != "cannot convert field: 1.2 to int" {
t.Error(err)
}
// if diff, err := Difference(12, 1, 2, 3); err != nil {
// t.Error(err)
// } else if diff != int64(6) {
// t.Errorf("Expecting: 6, received: %+v", diff)
// }
if diff, err := Difference(12, 1, 2, 3); err != nil {
t.Error(err)
} else if diff != int64(6) {
t.Errorf("Expecting: 6, received: %+v", diff)
}
if diff, err := Difference(8.0, 4.0, 2.0, -1.0); err != nil {
t.Error(err)
} else if diff != 3.0 {
@@ -577,18 +577,18 @@ func TestDifference(t *testing.T) {
} else if diff != 3.0 {
t.Errorf("Expecting: 3.0, received: %+v", diff)
}
// if diff, err := Difference(10*time.Second, 1*time.Second, 2*time.Second,
// 4*time.Millisecond); err != nil {
// t.Error(err)
// } else if diff != int64(6996000000) {
// t.Errorf("Expecting: 6.996ms, received: %+v", diff)
// }
// if diff, err := Difference(time.Duration(2*time.Second),
// time.Duration(10*time.Millisecond)); err != nil {
// t.Error(err)
// } else if diff != int64(1990000000) {
// t.Errorf("Expecting: 1.99s, received: %+v", diff)
// }
if diff, err := Difference(10*time.Second, 1*time.Second, 2*time.Second,
4*time.Millisecond); err != nil {
t.Error(err)
} else if diff != time.Duration(6*time.Second+996*time.Millisecond) {
t.Errorf("Expecting: 6.996ms, received: %+v", diff)
}
if diff, err := Difference(time.Duration(2*time.Second),
time.Duration(10*time.Millisecond)); err != nil {
t.Error(err)
} else if diff != time.Duration(1*time.Second+990*time.Millisecond) {
t.Errorf("Expecting: 1.99s, received: %+v", diff)
}
if diff, err := Difference(time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC),
time.Duration(10*time.Second)); err != nil {