mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-13 02:56:24 +05:00
Merge pull request #756 from TeoV/master
Modify the struct of StatACD (Sum float64 -> Sum time.Duration) ; add StatTCD and test for it
This commit is contained in:
@@ -203,7 +203,7 @@ func testV1STSProcessEvent(t *testing.T) {
|
||||
}
|
||||
expectedMetrics := map[string]string{
|
||||
utils.MetaASR: "66.66667%",
|
||||
utils.MetaACD: "0",
|
||||
utils.MetaACD: "0s",
|
||||
}
|
||||
var metrics map[string]string
|
||||
if err := stsV1Rpc.Call("StatSV1.GetQueueStringMetrics", &utils.TenantID{"cgrates.org", "STATS_1"}, &metrics); err != nil {
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -119,6 +120,7 @@ func testTPImportTPFromFolderPath(t *testing.T) {
|
||||
} else if reply != utils.OK {
|
||||
t.Error("Calling ApierV1.ImportTarrifPlanFromFolder got reply: ", reply)
|
||||
}
|
||||
time.Sleep(time.Duration(2 * time.Second))
|
||||
}
|
||||
|
||||
func testTPExportTPToFolder(t *testing.T) {
|
||||
@@ -141,6 +143,7 @@ func testTPExportTPToFolder(t *testing.T) {
|
||||
} else if !reflect.DeepEqual(len(reply.ExportedFiles), len(expectedTPStas.ExportedFiles)) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", len(reply.ExportedFiles), len(expectedTPStas.ExportedFiles))
|
||||
}
|
||||
time.Sleep(time.Duration(2 * time.Second))
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ package engine
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// StatsConfig represents the configuration of a StatsInstance in StatS
|
||||
@@ -90,6 +90,22 @@ func (se StatEvent) Usage(timezone string) (at time.Duration, err error) {
|
||||
return utils.ParseDurationWithSecs(usStr)
|
||||
}
|
||||
|
||||
// Cost returns the Cost of StatEvent
|
||||
func (se StatEvent) Cost(timezone string) (cs float64, err error) {
|
||||
csIf, has := se.Fields[utils.COST]
|
||||
if !has {
|
||||
return cs, utils.ErrNotFound
|
||||
}
|
||||
if cs, canCast := csIf.(float64); canCast {
|
||||
return cs, nil
|
||||
}
|
||||
csStr, canCast := csIf.(string)
|
||||
if !canCast {
|
||||
return cs, errors.New("cannot cast to string")
|
||||
}
|
||||
return strconv.ParseFloat(csStr, 64)
|
||||
}
|
||||
|
||||
// NewStoredStatQueue initiates a StoredStatQueue out of StatQueue
|
||||
func NewStoredStatQueue(sq *StatQueue, ms Marshaler) (sSQ *StoredStatQueue, err error) {
|
||||
sSQ = &StoredStatQueue{
|
||||
|
||||
@@ -1959,7 +1959,7 @@ func testOnStorITCRUDStatQueueProfile(t *testing.T) {
|
||||
QueueLength: 2,
|
||||
TTL: timeTTL,
|
||||
Metrics: []string{},
|
||||
Store: true,
|
||||
Stored: true,
|
||||
Thresholds: []string{},
|
||||
}
|
||||
if _, rcvErr := onStor.GetStatQueueProfile(sq.Tenant, sq.ID, true, utils.NonTransactional); rcvErr != utils.ErrNotFound {
|
||||
|
||||
@@ -20,9 +20,10 @@ package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NewStatMetric instantiates the StatMetric
|
||||
@@ -31,6 +32,9 @@ func NewStatMetric(metricID string) (sm StatMetric, err error) {
|
||||
metrics := map[string]func() (StatMetric, error){
|
||||
utils.MetaASR: NewASR,
|
||||
utils.MetaACD: NewACD,
|
||||
utils.MetaTCD: NewTCD,
|
||||
utils.MetaACC: NewACC,
|
||||
utils.MetaTCC: NewTCC,
|
||||
}
|
||||
if _, has := metrics[metricID]; !has {
|
||||
return nil, fmt.Errorf("unsupported metric: %s", metricID)
|
||||
@@ -134,25 +138,24 @@ func (asr *StatASR) LoadMarshaled(ms Marshaler, marshaled []byte) (err error) {
|
||||
}
|
||||
|
||||
func NewACD() (StatMetric, error) {
|
||||
return &StatACD{Events: make(map[string]float64)}, nil
|
||||
return &StatACD{Events: make(map[string]time.Duration)}, nil
|
||||
}
|
||||
|
||||
// ACD implements AverageCallDuration metric
|
||||
type StatACD struct {
|
||||
Sum float64
|
||||
Count float64
|
||||
Events map[string]float64 // map[EventTenantID]Duration
|
||||
val *float64 // cached ACD value
|
||||
Sum time.Duration
|
||||
Count int64
|
||||
Events map[string]time.Duration // map[EventTenantID]Duration
|
||||
val *time.Duration // cached ACD value
|
||||
}
|
||||
|
||||
// getValue returns asr.val
|
||||
func (acd *StatACD) getValue() float64 {
|
||||
// getValue returns acr.val
|
||||
func (acd *StatACD) getValue() time.Duration {
|
||||
if acd.val == nil {
|
||||
if acd.Count == 0 {
|
||||
acd.val = utils.Float64Pointer(float64(STATS_NA))
|
||||
acd.val = utils.DurationPointer(time.Duration((-1) * time.Nanosecond))
|
||||
} else {
|
||||
acd.val = utils.Float64Pointer(utils.Round(acd.Sum/acd.Count,
|
||||
config.CgrConfig().RoundingDecimals, utils.ROUNDING_MIDDLE))
|
||||
acd.val = utils.DurationPointer(time.Duration(acd.Sum.Nanoseconds() / acd.Count))
|
||||
}
|
||||
}
|
||||
return *acd.val
|
||||
@@ -170,20 +173,27 @@ func (acd *StatACD) GetValue() (v interface{}) {
|
||||
}
|
||||
|
||||
func (acd *StatACD) GetFloat64Value() (v float64) {
|
||||
return acd.getValue()
|
||||
if acd.Count == 0 {
|
||||
return -1.0
|
||||
}
|
||||
return acd.getValue().Seconds()
|
||||
}
|
||||
|
||||
func (acd *StatACD) AddEvent(ev *StatEvent) (err error) {
|
||||
var answered float64
|
||||
var value time.Duration
|
||||
if at, err := ev.AnswerTime(config.CgrConfig().DefaultTimezone); err != nil &&
|
||||
err != utils.ErrNotFound {
|
||||
return err
|
||||
} else if !at.IsZero() {
|
||||
duration, _ := ev.Usage(config.CgrConfig().DefaultTimezone)
|
||||
answered = duration.Seconds()
|
||||
acd.Sum += duration.Seconds()
|
||||
if duration, err := ev.Usage(config.CgrConfig().DefaultTimezone); err != nil &&
|
||||
err != utils.ErrNotFound {
|
||||
return err
|
||||
} else {
|
||||
value = duration
|
||||
acd.Sum += duration
|
||||
}
|
||||
}
|
||||
acd.Events[ev.TenantID()] = answered
|
||||
acd.Events[ev.TenantID()] = value
|
||||
acd.Count += 1
|
||||
acd.val = nil
|
||||
return
|
||||
@@ -209,3 +219,252 @@ func (acd *StatACD) Marshal(ms Marshaler) (marshaled []byte, err error) {
|
||||
func (acd *StatACD) LoadMarshaled(ms Marshaler, marshaled []byte) (err error) {
|
||||
return ms.Unmarshal(marshaled, acd)
|
||||
}
|
||||
|
||||
func NewTCD() (StatMetric, error) {
|
||||
return &StatTCD{Events: make(map[string]time.Duration)}, nil
|
||||
}
|
||||
|
||||
// TCD implements TotalCallDuration metric
|
||||
type StatTCD struct {
|
||||
Sum time.Duration
|
||||
Count int64
|
||||
Events map[string]time.Duration // map[EventTenantID]Duration
|
||||
val *time.Duration // cached TCD value
|
||||
}
|
||||
|
||||
// getValue returns tcd.val
|
||||
func (tcd *StatTCD) getValue() time.Duration {
|
||||
if tcd.val == nil {
|
||||
if tcd.Count == 0 {
|
||||
tcd.val = utils.DurationPointer(time.Duration((-1) * time.Nanosecond))
|
||||
} else {
|
||||
tcd.val = utils.DurationPointer(time.Duration(tcd.Sum.Nanoseconds()))
|
||||
}
|
||||
}
|
||||
return *tcd.val
|
||||
}
|
||||
|
||||
func (tcd *StatTCD) GetStringValue(fmtOpts string) (val string) {
|
||||
if tcd.Count == 0 {
|
||||
return utils.NOT_AVAILABLE
|
||||
}
|
||||
return fmt.Sprintf("%+v", tcd.getValue())
|
||||
}
|
||||
|
||||
func (tcd *StatTCD) GetValue() (v interface{}) {
|
||||
return tcd.getValue()
|
||||
}
|
||||
|
||||
func (tcd *StatTCD) GetFloat64Value() (v float64) {
|
||||
if tcd.Count == 0 {
|
||||
return -1.0
|
||||
}
|
||||
return tcd.getValue().Seconds()
|
||||
}
|
||||
|
||||
func (tcd *StatTCD) AddEvent(ev *StatEvent) (err error) {
|
||||
var value time.Duration
|
||||
if at, err := ev.AnswerTime(config.CgrConfig().DefaultTimezone); err != nil &&
|
||||
err != utils.ErrNotFound {
|
||||
return err
|
||||
} else if !at.IsZero() {
|
||||
if duration, err := ev.Usage(config.CgrConfig().DefaultTimezone); err != nil &&
|
||||
err != utils.ErrNotFound {
|
||||
return err
|
||||
} else {
|
||||
value = duration
|
||||
tcd.Sum += duration
|
||||
}
|
||||
|
||||
}
|
||||
tcd.Events[ev.TenantID()] = value
|
||||
tcd.Count += 1
|
||||
tcd.val = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (tcd *StatTCD) RemEvent(evTenantID string) (err error) {
|
||||
duration, has := tcd.Events[evTenantID]
|
||||
if !has {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
if duration != 0 {
|
||||
tcd.Sum -= duration
|
||||
}
|
||||
tcd.Count -= 1
|
||||
delete(tcd.Events, evTenantID)
|
||||
tcd.val = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (tcd *StatTCD) Marshal(ms Marshaler) (marshaled []byte, err error) {
|
||||
return ms.Marshal(tcd)
|
||||
}
|
||||
|
||||
func (tcd *StatTCD) LoadMarshaled(ms Marshaler, marshaled []byte) (err error) {
|
||||
return ms.Unmarshal(marshaled, tcd)
|
||||
}
|
||||
|
||||
func NewACC() (StatMetric, error) {
|
||||
return &StatACC{Events: make(map[string]float64)}, nil
|
||||
}
|
||||
|
||||
// ACC implements AverageCallCost metric
|
||||
type StatACC struct {
|
||||
Sum float64
|
||||
Count float64
|
||||
Events map[string]float64 // map[EventTenantID]Cost
|
||||
val *float64 // cached ACC value
|
||||
}
|
||||
|
||||
// getValue returns tcd.val
|
||||
func (acc *StatACC) getValue() float64 {
|
||||
if acc.val == nil {
|
||||
if acc.Count == 0 {
|
||||
acc.val = utils.Float64Pointer(float64(STATS_NA))
|
||||
} else {
|
||||
acc.val = utils.Float64Pointer(utils.Round((acc.Sum / acc.Count * 100),
|
||||
config.CgrConfig().RoundingDecimals, utils.ROUNDING_MIDDLE))
|
||||
}
|
||||
}
|
||||
return *acc.val
|
||||
}
|
||||
|
||||
func (acc *StatACC) GetStringValue(fmtOpts string) (val string) {
|
||||
if acc.Count == 0 {
|
||||
return utils.NOT_AVAILABLE
|
||||
}
|
||||
return fmt.Sprintf("%s", strconv.FormatFloat(acc.getValue(), 'E', -1, 64))
|
||||
}
|
||||
|
||||
func (acc *StatACC) GetValue() (v interface{}) {
|
||||
return acc.getValue()
|
||||
}
|
||||
|
||||
func (acc *StatACC) GetFloat64Value() (v float64) {
|
||||
return acc.getValue()
|
||||
}
|
||||
|
||||
func (acc *StatACC) AddEvent(ev *StatEvent) (err error) {
|
||||
var value float64
|
||||
if at, err := ev.AnswerTime(config.CgrConfig().DefaultTimezone); err != nil &&
|
||||
err != utils.ErrNotFound {
|
||||
return err
|
||||
} else if !at.IsZero() {
|
||||
if cost, err := ev.Cost(config.CgrConfig().DefaultTimezone); err != nil &&
|
||||
err != utils.ErrNotFound {
|
||||
return err
|
||||
} else if cost >= 0 {
|
||||
value = cost
|
||||
acc.Sum += cost
|
||||
}
|
||||
}
|
||||
acc.Events[ev.TenantID()] = value
|
||||
acc.Count += 1
|
||||
acc.val = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (acc *StatACC) RemEvent(evTenantID string) (err error) {
|
||||
cost, has := acc.Events[evTenantID]
|
||||
if !has {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
if cost != 0 {
|
||||
acc.Sum -= cost
|
||||
}
|
||||
acc.Count -= 1
|
||||
delete(acc.Events, evTenantID)
|
||||
acc.val = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (acc *StatACC) Marshal(ms Marshaler) (marshaled []byte, err error) {
|
||||
return ms.Marshal(acc)
|
||||
}
|
||||
|
||||
func (acc *StatACC) LoadMarshaled(ms Marshaler, marshaled []byte) (err error) {
|
||||
return ms.Unmarshal(marshaled, acc)
|
||||
}
|
||||
|
||||
func NewTCC() (StatMetric, error) {
|
||||
return &StatTCC{Events: make(map[string]float64)}, nil
|
||||
}
|
||||
|
||||
// TCC implements TotalCallCost metric
|
||||
type StatTCC struct {
|
||||
Sum float64
|
||||
Count float64
|
||||
Events map[string]float64 // map[EventTenantID]Cost
|
||||
val *float64 // cached TCC value
|
||||
}
|
||||
|
||||
// getValue returns tcd.val
|
||||
func (tcc *StatTCC) getValue() float64 {
|
||||
if tcc.val == nil {
|
||||
if tcc.Count == 0 {
|
||||
tcc.val = utils.Float64Pointer(float64(STATS_NA))
|
||||
} else {
|
||||
tcc.val = utils.Float64Pointer(utils.Round(tcc.Sum,
|
||||
config.CgrConfig().RoundingDecimals, utils.ROUNDING_MIDDLE))
|
||||
}
|
||||
}
|
||||
return *tcc.val
|
||||
}
|
||||
|
||||
func (tcc *StatTCC) GetStringValue(fmtOpts string) (val string) {
|
||||
if tcc.Count == 0 {
|
||||
return utils.NOT_AVAILABLE
|
||||
}
|
||||
return fmt.Sprintf("%s", strconv.FormatFloat(tcc.getValue(), 'E', -1, 64))
|
||||
}
|
||||
|
||||
func (tcc *StatTCC) GetValue() (v interface{}) {
|
||||
return tcc.getValue()
|
||||
}
|
||||
|
||||
func (tcc *StatTCC) GetFloat64Value() (v float64) {
|
||||
return tcc.getValue()
|
||||
}
|
||||
|
||||
func (tcc *StatTCC) AddEvent(ev *StatEvent) (err error) {
|
||||
var value float64
|
||||
if at, err := ev.AnswerTime(config.CgrConfig().DefaultTimezone); err != nil &&
|
||||
err != utils.ErrNotFound {
|
||||
return err
|
||||
} else if !at.IsZero() {
|
||||
if cost, err := ev.Cost(config.CgrConfig().DefaultTimezone); err != nil &&
|
||||
err != utils.ErrNotFound {
|
||||
return err
|
||||
} else if cost >= 0 {
|
||||
value = cost
|
||||
tcc.Sum += cost
|
||||
}
|
||||
}
|
||||
tcc.Events[ev.TenantID()] = value
|
||||
tcc.Count += 1
|
||||
tcc.val = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (tcc *StatTCC) RemEvent(evTenantID string) (err error) {
|
||||
cost, has := tcc.Events[evTenantID]
|
||||
if !has {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
if cost != 0 {
|
||||
tcc.Sum -= cost
|
||||
}
|
||||
tcc.Count -= 1
|
||||
delete(tcc.Events, evTenantID)
|
||||
tcc.val = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (tcc *StatTCC) Marshal(ms Marshaler) (marshaled []byte, err error) {
|
||||
return ms.Marshal(tcc)
|
||||
}
|
||||
|
||||
func (tcc *StatTCC) LoadMarshaled(ms Marshaler, marshaled []byte) (err error) {
|
||||
return ms.Unmarshal(marshaled, tcc)
|
||||
}
|
||||
|
||||
@@ -46,15 +46,27 @@ func TestASRGetStringValue(t *testing.T) {
|
||||
if strVal := asr.GetStringValue(""); strVal != "50%" {
|
||||
t.Errorf("wrong asr value: %s", strVal)
|
||||
}
|
||||
ev4 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_4",
|
||||
Fields: map[string]interface{}{
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC)}}
|
||||
ev5 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_5",
|
||||
Fields: map[string]interface{}{
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC)}}
|
||||
asr.AddEvent(ev4)
|
||||
asr.AddEvent(ev5)
|
||||
asr.RemEvent(ev.TenantID())
|
||||
if strVal := asr.GetStringValue(""); strVal != "0%" {
|
||||
if strVal := asr.GetStringValue(""); strVal != "66.66667%" {
|
||||
t.Errorf("wrong asr value: %s", strVal)
|
||||
}
|
||||
asr.RemEvent(ev2.TenantID())
|
||||
if strVal := asr.GetStringValue(""); strVal != "100%" {
|
||||
t.Errorf("wrong asr value: %s", strVal)
|
||||
}
|
||||
asr.RemEvent(ev4.TenantID())
|
||||
asr.RemEvent(ev5.TenantID())
|
||||
if strVal := asr.GetStringValue(""); strVal != utils.NOT_AVAILABLE {
|
||||
t.Errorf("wrong asr value: %s", strVal)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestASRGetValue(t *testing.T) {
|
||||
@@ -77,11 +89,27 @@ func TestASRGetValue(t *testing.T) {
|
||||
if v := asr.GetValue(); v != 50.0 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
}
|
||||
ev4 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_4",
|
||||
Fields: map[string]interface{}{
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC)}}
|
||||
ev5 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_5",
|
||||
Fields: map[string]interface{}{
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC)}}
|
||||
asr.AddEvent(ev4)
|
||||
asr.AddEvent(ev5)
|
||||
asr.RemEvent(ev.TenantID())
|
||||
if v := asr.GetValue(); v != 0.0 {
|
||||
if v := asr.GetValue(); v != 66.666670 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
}
|
||||
asr.RemEvent(ev2.TenantID())
|
||||
if v := asr.GetValue(); v != 100.0 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
}
|
||||
asr.RemEvent(ev4.TenantID())
|
||||
if v := asr.GetValue(); v != 100.0 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
}
|
||||
asr.RemEvent(ev5.TenantID())
|
||||
if v := asr.GetValue(); v != -1.0 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
}
|
||||
@@ -98,29 +126,107 @@ func TestACDGetStringValue(t *testing.T) {
|
||||
t.Errorf("wrong acd value: %s", strVal)
|
||||
}
|
||||
acd.AddEvent(ev)
|
||||
if strVal := acd.GetStringValue(""); strVal != "10" {
|
||||
if strVal := acd.GetStringValue(""); strVal != "10s" {
|
||||
t.Errorf("wrong acd value: %s", strVal)
|
||||
}
|
||||
ev2 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_2"}
|
||||
ev3 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_3"}
|
||||
acd.AddEvent(ev2)
|
||||
acd.AddEvent(ev3)
|
||||
if strVal := acd.GetStringValue(""); strVal != "3.33333" {
|
||||
if strVal := acd.GetStringValue(""); strVal != "3.333333333s" {
|
||||
t.Errorf("wrong acd value: %s", strVal)
|
||||
}
|
||||
acd.RemEvent(ev3.TenantID())
|
||||
if strVal := acd.GetStringValue(""); strVal != "5" {
|
||||
if strVal := acd.GetStringValue(""); strVal != "5s" {
|
||||
t.Errorf("wrong acd value: %s", strVal)
|
||||
}
|
||||
acd.RemEvent(ev.TenantID())
|
||||
if strVal := acd.GetStringValue(""); strVal != "0" {
|
||||
if strVal := acd.GetStringValue(""); strVal != "0s" {
|
||||
t.Errorf("wrong acd value: %s", strVal)
|
||||
}
|
||||
ev4 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_4",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1 * time.Minute),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
ev5 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_5",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1*time.Minute + 30*time.Second),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
acd.AddEvent(ev4)
|
||||
if strVal := acd.GetStringValue(""); strVal != "30s" {
|
||||
t.Errorf("wrong acd value: %s", strVal)
|
||||
}
|
||||
acd.AddEvent(ev5)
|
||||
if strVal := acd.GetStringValue(""); strVal != "50s" {
|
||||
t.Errorf("wrong acd value: %s", strVal)
|
||||
}
|
||||
acd.RemEvent(ev2.TenantID())
|
||||
if strVal := acd.GetStringValue(""); strVal != "1m15s" {
|
||||
t.Errorf("wrong acd value: %s", strVal)
|
||||
}
|
||||
acd.RemEvent(ev5.TenantID())
|
||||
acd.RemEvent(ev4.TenantID())
|
||||
acd.RemEvent(ev5.TenantID())
|
||||
if strVal := acd.GetStringValue(""); strVal != utils.NOT_AVAILABLE {
|
||||
t.Errorf("wrong acd value: %s", strVal)
|
||||
}
|
||||
}
|
||||
|
||||
func TestACDGetFloat64Value(t *testing.T) {
|
||||
acd, _ := NewACD()
|
||||
ev := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_1",
|
||||
Fields: map[string]interface{}{
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
"Usage": time.Duration(10 * time.Second)}}
|
||||
acd.AddEvent(ev)
|
||||
if v := acd.GetFloat64Value(); v != 10.0 {
|
||||
t.Errorf("wrong acd value: %f", v)
|
||||
}
|
||||
ev2 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_2"}
|
||||
acd.AddEvent(ev2)
|
||||
if v := acd.GetFloat64Value(); v != 5.0 {
|
||||
t.Errorf("wrong acd value: %f", v)
|
||||
}
|
||||
ev4 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_4",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1 * time.Minute),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
ev5 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_5",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1*time.Minute + 30*time.Second),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
acd.AddEvent(ev4)
|
||||
if strVal := acd.GetFloat64Value(); strVal != 23.333333333 {
|
||||
t.Errorf("wrong acd value: %f", strVal)
|
||||
}
|
||||
acd.AddEvent(ev5)
|
||||
if strVal := acd.GetFloat64Value(); strVal != 40.0 {
|
||||
t.Errorf("wrong acd value: %f", strVal)
|
||||
}
|
||||
acd.RemEvent(ev2.TenantID())
|
||||
if strVal := acd.GetFloat64Value(); strVal != 53.333333333 {
|
||||
t.Errorf("wrong acd value: %f", strVal)
|
||||
}
|
||||
acd.RemEvent(ev4.TenantID())
|
||||
if strVal := acd.GetFloat64Value(); strVal != 50.0 {
|
||||
t.Errorf("wrong acd value: %f", strVal)
|
||||
}
|
||||
acd.RemEvent(ev.TenantID())
|
||||
if strVal := acd.GetFloat64Value(); strVal != 90.0 {
|
||||
t.Errorf("wrong acd value: %f", strVal)
|
||||
}
|
||||
acd.RemEvent(ev5.TenantID())
|
||||
if strVal := acd.GetFloat64Value(); strVal != -1.0 {
|
||||
t.Errorf("wrong acd value: %f", strVal)
|
||||
}
|
||||
}
|
||||
|
||||
func TestACDGetValue(t *testing.T) {
|
||||
@@ -130,27 +236,221 @@ func TestACDGetValue(t *testing.T) {
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
"Usage": time.Duration(10 * time.Second)}}
|
||||
acd.AddEvent(ev)
|
||||
if v := acd.GetValue(); v != 10.0 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
if v := acd.GetValue(); v != time.Duration(10*time.Second) {
|
||||
t.Errorf("wrong acd value: %+v", v)
|
||||
}
|
||||
ev2 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_2"}
|
||||
ev2 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_2",
|
||||
Fields: map[string]interface{}{
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
"Usage": time.Duration(8 * time.Second)}}
|
||||
ev3 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_3"}
|
||||
acd.AddEvent(ev2)
|
||||
acd.AddEvent(ev3)
|
||||
if v := acd.GetValue(); v != 3.33333 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
}
|
||||
acd.RemEvent(ev3.TenantID())
|
||||
if v := acd.GetValue(); v != 5.0 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
if v := acd.GetValue(); v != time.Duration(6*time.Second) {
|
||||
t.Errorf("wrong acd value: %+v", v)
|
||||
}
|
||||
acd.RemEvent(ev.TenantID())
|
||||
if v := acd.GetValue(); v != 0.0 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
if v := acd.GetValue(); v != time.Duration(4*time.Second) {
|
||||
t.Errorf("wrong acd value: %+v", v)
|
||||
}
|
||||
acd.RemEvent(ev2.TenantID())
|
||||
if v := acd.GetValue(); v != -1.0 {
|
||||
t.Errorf("wrong asr value: %f", v)
|
||||
if v := acd.GetValue(); v != time.Duration(0*time.Second) {
|
||||
t.Errorf("wrong acd value: %+v", v)
|
||||
}
|
||||
ev4 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_4",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1 * time.Minute),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
ev5 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_5",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(4*time.Minute + 30*time.Second),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
acd.AddEvent(ev4)
|
||||
acd.AddEvent(ev5)
|
||||
if v := acd.GetValue(); v != time.Duration(1*time.Minute+50*time.Second) {
|
||||
t.Errorf("wrong acd value: %+v", v)
|
||||
}
|
||||
acd.RemEvent(ev5.TenantID())
|
||||
acd.RemEvent(ev4.TenantID())
|
||||
if v := acd.GetValue(); v != time.Duration(0*time.Second) {
|
||||
t.Errorf("wrong acd value: %+v", v)
|
||||
}
|
||||
acd.RemEvent(ev3.TenantID())
|
||||
if v := acd.GetValue(); v != time.Duration((-1)*time.Nanosecond) {
|
||||
t.Errorf("wrong acd value: %+v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCDGetStringValue(t *testing.T) {
|
||||
tcd, _ := NewTCD()
|
||||
ev := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_1",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(10 * time.Second),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
}}
|
||||
if strVal := tcd.GetStringValue(""); strVal != utils.NOT_AVAILABLE {
|
||||
t.Errorf("wrong tcd value: %s", strVal)
|
||||
}
|
||||
tcd.AddEvent(ev)
|
||||
if strVal := tcd.GetStringValue(""); strVal != "10s" {
|
||||
t.Errorf("wrong tcd value: %s", strVal)
|
||||
}
|
||||
ev2 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_2",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(10 * time.Second),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
}}
|
||||
ev3 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_3"}
|
||||
tcd.AddEvent(ev2)
|
||||
tcd.AddEvent(ev3)
|
||||
if strVal := tcd.GetStringValue(""); strVal != "20s" {
|
||||
t.Errorf("wrong tcd value: %s", strVal)
|
||||
}
|
||||
tcd.RemEvent(ev2.TenantID())
|
||||
if strVal := tcd.GetStringValue(""); strVal != "10s" {
|
||||
t.Errorf("wrong tcd value: %s", strVal)
|
||||
}
|
||||
tcd.RemEvent(ev.TenantID())
|
||||
if strVal := tcd.GetStringValue(""); strVal != "0s" {
|
||||
t.Errorf("wrong tcd value: %s", strVal)
|
||||
}
|
||||
ev4 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_4",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1 * time.Minute),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
ev5 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_5",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1*time.Minute + 30*time.Second),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
tcd.AddEvent(ev4)
|
||||
tcd.AddEvent(ev5)
|
||||
if strVal := tcd.GetStringValue(""); strVal != "2m30s" {
|
||||
t.Errorf("wrong tcd value: %s", strVal)
|
||||
}
|
||||
tcd.RemEvent(ev4.TenantID())
|
||||
if strVal := tcd.GetStringValue(""); strVal != "1m30s" {
|
||||
t.Errorf("wrong tcd value: %s", strVal)
|
||||
}
|
||||
tcd.RemEvent(ev5.TenantID())
|
||||
tcd.RemEvent(ev3.TenantID())
|
||||
if strVal := tcd.GetStringValue(""); strVal != utils.NOT_AVAILABLE {
|
||||
t.Errorf("wrong tcd value: %s", strVal)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCDGetFloat64Value(t *testing.T) {
|
||||
tcd, _ := NewTCD()
|
||||
ev := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_1",
|
||||
Fields: map[string]interface{}{
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
"Usage": time.Duration(10 * time.Second)}}
|
||||
tcd.AddEvent(ev)
|
||||
if v := tcd.GetFloat64Value(); v != 10.0 {
|
||||
t.Errorf("wrong tcd value: %f", v)
|
||||
}
|
||||
ev2 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_2"}
|
||||
tcd.AddEvent(ev2)
|
||||
if v := tcd.GetFloat64Value(); v != 10.0 {
|
||||
t.Errorf("wrong tcd value: %f", v)
|
||||
}
|
||||
ev4 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_4",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1 * time.Minute),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
ev5 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_5",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1*time.Minute + 30*time.Second),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
tcd.AddEvent(ev4)
|
||||
if strVal := tcd.GetFloat64Value(); strVal != 70.0 {
|
||||
t.Errorf("wrong tcd value: %f", strVal)
|
||||
}
|
||||
tcd.AddEvent(ev5)
|
||||
if strVal := tcd.GetFloat64Value(); strVal != 160.0 {
|
||||
t.Errorf("wrong tcd value: %f", strVal)
|
||||
}
|
||||
tcd.RemEvent(ev2.TenantID())
|
||||
if strVal := tcd.GetFloat64Value(); strVal != 160.0 {
|
||||
t.Errorf("wrong tcd value: %f", strVal)
|
||||
}
|
||||
tcd.RemEvent(ev4.TenantID())
|
||||
if strVal := tcd.GetFloat64Value(); strVal != 100.0 {
|
||||
t.Errorf("wrong tcd value: %f", strVal)
|
||||
}
|
||||
tcd.RemEvent(ev.TenantID())
|
||||
if strVal := tcd.GetFloat64Value(); strVal != 90.0 {
|
||||
t.Errorf("wrong tcd value: %f", strVal)
|
||||
}
|
||||
tcd.RemEvent(ev5.TenantID())
|
||||
if strVal := tcd.GetFloat64Value(); strVal != -1.0 {
|
||||
t.Errorf("wrong tcd value: %f", strVal)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCDGetValue(t *testing.T) {
|
||||
tcd, _ := NewTCD()
|
||||
ev := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_1",
|
||||
Fields: map[string]interface{}{
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
"Usage": time.Duration(10 * time.Second)}}
|
||||
tcd.AddEvent(ev)
|
||||
if v := tcd.GetValue(); v != time.Duration(10*time.Second) {
|
||||
t.Errorf("wrong tcd value: %+v", v)
|
||||
}
|
||||
ev2 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_2",
|
||||
Fields: map[string]interface{}{
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
"Usage": time.Duration(5 * time.Second)}}
|
||||
ev3 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_3"}
|
||||
tcd.AddEvent(ev2)
|
||||
tcd.AddEvent(ev3)
|
||||
if v := tcd.GetValue(); v != time.Duration(15*time.Second) {
|
||||
t.Errorf("wrong tcd value: %+v", v)
|
||||
}
|
||||
tcd.RemEvent(ev.TenantID())
|
||||
if v := tcd.GetValue(); v != time.Duration(5*time.Second) {
|
||||
t.Errorf("wrong tcd value: %+v", v)
|
||||
}
|
||||
tcd.RemEvent(ev2.TenantID())
|
||||
if v := tcd.GetValue(); v != time.Duration(0*time.Second) {
|
||||
t.Errorf("wrong tcd value: %+v", v)
|
||||
}
|
||||
ev4 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_4",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1 * time.Minute),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
ev5 := &StatEvent{Tenant: "cgrates.org", ID: "EVENT_5",
|
||||
Fields: map[string]interface{}{
|
||||
"Usage": time.Duration(1*time.Minute + 30*time.Second),
|
||||
"AnswerTime": time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
},
|
||||
}
|
||||
tcd.AddEvent(ev4)
|
||||
tcd.AddEvent(ev5)
|
||||
if v := tcd.GetValue(); v != time.Duration(2*time.Minute+30*time.Second) {
|
||||
t.Errorf("wrong tcd value: %+v", v)
|
||||
}
|
||||
tcd.RemEvent(ev5.TenantID())
|
||||
tcd.RemEvent(ev4.TenantID())
|
||||
if v := tcd.GetValue(); v != time.Duration(0*time.Second) {
|
||||
t.Errorf("wrong tcd value: %+v", v)
|
||||
}
|
||||
tcd.RemEvent(ev3.TenantID())
|
||||
if v := tcd.GetValue(); v != time.Duration((-1)*time.Nanosecond) {
|
||||
t.Errorf("wrong tcd value: %+v", v)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -420,6 +420,11 @@ const (
|
||||
ID = "ID"
|
||||
MetaASR = "*asr"
|
||||
MetaACD = "*acd"
|
||||
MetaTCD = "*tcd"
|
||||
MetaACC = "*acc"
|
||||
MetaTCC = "*tcc"
|
||||
MetaPDD = "*pdd"
|
||||
MetaDDC = "*ddc"
|
||||
CacheDestinations = "destinations"
|
||||
CacheReverseDestinations = "reverse_destinations"
|
||||
CacheRatingPlans = "rating_plans"
|
||||
|
||||
Reference in New Issue
Block a user