/* Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments Copyright (C) ITsysCOM GmbH This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ package engine import ( "reflect" "testing" "time" "github.com/ericlagergren/decimal" "github.com/cgrates/cron" "github.com/cgrates/cgrates/utils" ) func TestRateProfileSort(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } secDecimal, err := utils.NewDecimalFromUsage("1s") if err != nil { t.Error(err) } rPrf := &RateProfile{ Tenant: "cgrates.org", ID: "RP1", Rates: map[string]*Rate{ "RT_WEEK": { ID: "RT_WEEK", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * 1-5", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, { IntervalStart: time.Minute, RecurrentFee: utils.NewDecimal(6, 2), Unit: minDecimal, Increment: secDecimal, }, }, }, "RT_Custom": { ID: "RT_Custom", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * 1-5", IntervalRates: []*IntervalRate{ { IntervalStart: time.Second, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, { IntervalStart: time.Second, RecurrentFee: utils.NewDecimal(19, 2), Unit: minDecimal, Increment: secDecimal, }, { IntervalStart: 15 * time.Second, RecurrentFee: utils.NewDecimal(4, 1), Unit: minDecimal, Increment: secDecimal, }, { IntervalStart: 10 * time.Second, RecurrentFee: utils.NewDecimal(27, 2), Unit: minDecimal, Increment: secDecimal, }, }, }, "RT_WEEKEND": { ID: "RT_WEEKEND", Weights: utils.DynamicWeights{ { Weight: 10, }, }, ActivationTimes: "* * * * 0,6", IntervalRates: []*IntervalRate{ { IntervalStart: 10 * time.Second, RecurrentFee: utils.NewDecimal(6, 2), Unit: minDecimal, Increment: secDecimal, }, { IntervalStart: time.Minute, RecurrentFee: utils.NewDecimal(18, 2), Unit: minDecimal, Increment: secDecimal, }, { IntervalStart: 18 * time.Second, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: secDecimal, }, }, }, "RT_CHRISTMAS": { ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: "* * 24 12 *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(6, 2), Unit: minDecimal, Increment: secDecimal, }, }, }, }, } exp := &RateProfile{ Tenant: "cgrates.org", ID: "RP1", Rates: map[string]*Rate{ "RT_WEEK": { ID: "RT_WEEK", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * 1-5", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, { IntervalStart: time.Minute, RecurrentFee: utils.NewDecimal(6, 2), Unit: minDecimal, Increment: secDecimal, }, }, }, "RT_WEEKEND": { ID: "RT_WEEKEND", Weights: utils.DynamicWeights{ { Weight: 10, }, }, ActivationTimes: "* * * * 0,6", IntervalRates: []*IntervalRate{ { IntervalStart: 10 * time.Second, RecurrentFee: utils.NewDecimal(6, 2), Unit: minDecimal, Increment: secDecimal, }, { IntervalStart: 18 * time.Second, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: secDecimal, }, { IntervalStart: time.Minute, RecurrentFee: utils.NewDecimal(18, 2), Unit: minDecimal, Increment: secDecimal, }, }, }, "RT_Custom": { ID: "RT_Custom", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * 1-5", IntervalRates: []*IntervalRate{ { IntervalStart: time.Second, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, { IntervalStart: time.Second, RecurrentFee: utils.NewDecimal(19, 2), Unit: minDecimal, Increment: secDecimal, }, { IntervalStart: 10 * time.Second, RecurrentFee: utils.NewDecimal(27, 2), Unit: minDecimal, Increment: secDecimal, }, { IntervalStart: 15 * time.Second, RecurrentFee: utils.NewDecimal(4, 1), Unit: minDecimal, Increment: secDecimal, }, }, }, "RT_CHRISTMAS": { ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: "* * 24 12 *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(6, 2), Unit: minDecimal, Increment: secDecimal, }, }, }, }, } rPrf.Sort() if !reflect.DeepEqual(rPrf, exp) { t.Errorf("Expected: %v,\n received: %v", utils.ToJSON(exp), utils.ToJSON(rPrf)) } } func TestRateProfileCompile(t *testing.T) { rt := &RateProfile{ Rates: map[string]*Rate{ "randomVal1": { ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: "* * 24 12 *", }, }, Tenant: "cgrates.org", ID: "RTP1", } expectedATime, err := cron.ParseStandard("* * 24 12 *") if err != nil { t.Fatal(err) } expRt := &RateProfile{ Rates: map[string]*Rate{ "randomVal1": { ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: "* * 24 12 *", sched: expectedATime, uID: utils.ConcatenatedKey(rt.Tenant, rt.ID, "RT_CHRISTMAS"), }, }, Tenant: "cgrates.org", ID: "RTP1", } if err := rt.Compile(); err != nil { t.Error(err) } else if !reflect.DeepEqual(rt, expRt) { t.Errorf("Expected %+v, received %+v", utils.ToJSON(expRt), utils.ToJSON(rt)) } } func TestRateUID(t *testing.T) { rt := &RateProfile{ Rates: map[string]*Rate{ "randomVal1": { ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: "* * 24 12 *", uID: "randomID", }, }, } expected := "randomID" if newID := rt.Rates["randomVal1"].UID(); !reflect.DeepEqual(newID, expected) { t.Errorf("Expected %+v, received %+v", expected, newID) } } func TestRateProfileCompileError(t *testing.T) { rt := &RateProfile{ Rates: map[string]*Rate{ "randomVal": { ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: "* * * *", }, }, } expectedErr := "expected exactly 5 fields, found 4: [* * * *]" if err := rt.Compile(); err == nil || err.Error() != expectedErr { t.Errorf("Expected %+v, received %+v ", expectedErr, err) } } func TestRateCompileChristmasTime(t *testing.T) { rt := &Rate{ ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: "* * 24 12 *", } expTime, err := cron.ParseStandard("* * 24 12 *") if err != nil { t.Error(err) } expectedRt := &Rate{ ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: "* * 24 12 *", sched: expTime, } if err := rt.Compile(); err != nil { t.Error(err) } else if !reflect.DeepEqual(expectedRt, rt) { t.Errorf("Expected %+v, received %+v", expectedRt, rt) } } func TestRateCompileEmptyActivationTime(t *testing.T) { rt := &Rate{ ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: utils.EmptyString, } expTime, err := cron.ParseStandard("* * * * *") if err != nil { t.Error(err) } expectedRt := &Rate{ ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: utils.EmptyString, sched: expTime, } if err := rt.Compile(); err != nil { t.Error(err) } else if !reflect.DeepEqual(rt, expectedRt) { t.Errorf("Expected %+v, received %+v", expectedRt, rt) } } func TestRateProfileRunTimes(t *testing.T) { rt := &Rate{ ID: "RATE0", IntervalRates: []*IntervalRate{ { IntervalStart: 0, }, }, } rt.Compile() sTime := time.Date(2020, time.June, 28, 18, 56, 05, 0, time.UTC) eTime := sTime.Add(2 * time.Minute) eRTimes := [][]time.Time{ {time.Date(2020, time.June, 28, 18, 56, 0, 0, time.UTC), time.Time{}}, } if rTimes, err := rt.RunTimes(sTime, eTime, 10); err != nil { t.Error(err) } else if !reflect.DeepEqual(eRTimes, rTimes) { t.Errorf("expecting: %+v, received: %+v", eRTimes, rTimes) } rt = &Rate{ ID: "RT_CHRISTMAS", Weights: utils.DynamicWeights{ { Weight: 30, }, }, ActivationTimes: "* * 24 12 *", } rt.Compile() // sTime and eTime inside the activation interval sTime = time.Date(2020, 12, 24, 12, 0, 0, 0, time.UTC) eTime = sTime.Add(time.Hour) eRTimes = [][]time.Time{ {time.Date(2020, 12, 24, 12, 0, 0, 0, time.UTC), time.Date(2020, 12, 25, 0, 0, 0, 0, time.UTC)}, } if rTimes, err := rt.RunTimes(sTime, eTime, 10); err != nil { t.Error(err) } else if !reflect.DeepEqual(eRTimes, rTimes) { t.Errorf("expecting: %+v, received: %+v", eRTimes, rTimes) } // sTime smaller than activation time, eTime equals aTime sTime = time.Date(2020, 12, 23, 23, 0, 0, 0, time.UTC) eTime = sTime.Add(time.Hour) eRTimes = nil // cannot cover full interval if rTimes, err := rt.RunTimes(sTime, eTime, 10); err != nil { t.Error(err) } else if !reflect.DeepEqual(eRTimes, rTimes) { t.Errorf("expecting: %+v, received: %+v", eRTimes, rTimes) } // sTime smaller than activation time but first aTime inside, eTime inside activation interval sTime = time.Date(2020, 12, 23, 23, 59, 59, 0, time.UTC) eTime = sTime.Add(time.Hour) eRTimes = [][]time.Time{ {time.Date(2020, 12, 24, 0, 0, 0, 0, time.UTC), time.Date(2020, 12, 25, 0, 0, 0, 0, time.UTC)}, } if rTimes, err := rt.RunTimes(sTime, eTime, 1000000); err != nil { t.Error(err) } else if !reflect.DeepEqual(eRTimes, rTimes) { t.Errorf("expecting: %+v, received: %+v", eRTimes, rTimes) } // sTime way before aTime, eTime inside aInterval sTime = time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC) eTime = time.Date(2021, 12, 24, 0, 1, 0, 0, time.UTC) eRTimes = [][]time.Time{ {time.Date(2021, 12, 24, 0, 0, 0, 0, time.UTC), time.Date(2021, 12, 25, 0, 0, 0, 0, time.UTC)}, } if rTimes, err := rt.RunTimes(sTime, eTime, 1000000); err != nil { t.Error(err) } else if !reflect.DeepEqual(eRTimes, rTimes) { t.Errorf("expecting: %+v, received: %+v", eRTimes, rTimes) } } func TestRateProfileRunTimesMaxIterations(t *testing.T) { rt := &Rate{ ID: "RATE0", IntervalRates: []*IntervalRate{ { IntervalStart: 0, }, }, ActivationTimes: "* * 24 12 *", } err := rt.Compile() if err != nil { t.Error(err) } sTime := time.Date(2020, 12, 24, 23, 30, 0, 0, time.UTC) eTime := time.Date(2021, 12, 25, 23, 30, 0, 0, time.UTC) expectedErr := "maximum iterations reached" if _, err := rt.RunTimes(sTime, eTime, 2); err == nil || err.Error() != expectedErr { t.Errorf("Expected %+v, received %+v", expectedErr, err) } } func TestRateProfileRunTimesPassingActivationTIme(t *testing.T) { rt := &Rate{ ID: "RATE0", IntervalRates: []*IntervalRate{ { IntervalStart: 0, }, }, ActivationTimes: "* * 24 * *", } err := rt.Compile() if err != nil { t.Error(err) } sTime := time.Date(2020, 12, 23, 0, 0, 0, 0, time.UTC) eTime := time.Date(2020, 12, 27, 0, 0, 0, 0, time.UTC) expectedTime := [][]time.Time{ {time.Date(2020, 12, 24, 0, 0, 0, 0, time.UTC), time.Date(2020, 12, 25, 0, 0, 0, 0, time.UTC)}, } if rTimes, err := rt.RunTimes(sTime, eTime, 2); err != nil { t.Error(err) } else if !reflect.DeepEqual(expectedTime, rTimes) { t.Errorf("Expected %+v, received %+v", expectedTime, rTimes) } } func TestCostForIntervals(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } secDecimal, err := utils.NewDecimalFromUsage("1s") if err != nil { t.Error(err) } rt0 := &Rate{ ID: "RATE0", IntervalRates: []*IntervalRate{ { IntervalStart: time.Duration(0), Unit: minDecimal, Increment: minDecimal, RecurrentFee: utils.NewDecimal(24, 1), }, { IntervalStart: time.Duration(60 * time.Second), Unit: minDecimal, Increment: secDecimal, RecurrentFee: utils.NewDecimal(24, 1), }, }, } rt0.Compile() rt1 := &Rate{ ID: "RATE1", IntervalRates: []*IntervalRate{ { IntervalStart: time.Duration(0), Unit: minDecimal, Increment: secDecimal, RecurrentFee: utils.NewDecimal(12, 1), }, { IntervalStart: time.Duration(2 * time.Minute), Unit: minDecimal, Increment: secDecimal, RecurrentFee: utils.NewDecimal(6, 1), }, }, } rt1.Compile() rtIvls := []*RateSInterval{ { UsageStart: time.Duration(0), Increments: []*RateSIncrement{ { UsageStart: time.Duration(0), Usage: time.Duration(time.Minute), Rate: rt0, IntervalRateIndex: 0, CompressFactor: 1, }, { UsageStart: time.Duration(time.Minute), Usage: time.Duration(30 * time.Second), Rate: rt0, IntervalRateIndex: 1, CompressFactor: 30, }, }, CompressFactor: 1, }, { UsageStart: time.Duration(90 * time.Second), Increments: []*RateSIncrement{ { UsageStart: time.Duration(90 * time.Second), Usage: time.Duration(30 * time.Second), Rate: rt1, IntervalRateIndex: 0, CompressFactor: 30, }, { UsageStart: time.Duration(2 * time.Minute), Usage: time.Duration(10 * time.Second), Rate: rt1, IntervalRateIndex: 1, CompressFactor: 10, }, }, CompressFactor: 1, }, } eDcml, _ := new(decimal.Big).SetFloat64(4.3).Float64() if cost, _ := CostForIntervals(rtIvls).Float64(); cost != eDcml { t.Errorf("eDcml: %f, received: %+v", eDcml, cost) } } func TestCostForIntervalsWIthFixedFee(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } secDecimal, err := utils.NewDecimalFromUsage("1s") if err != nil { t.Error(err) } rt0 := &Rate{ ID: "RATE0", IntervalRates: []*IntervalRate{ { IntervalStart: time.Duration(0), FixedFee: utils.NewDecimal(4, 1), RecurrentFee: utils.NewDecimal(24, 1), Unit: minDecimal, Increment: minDecimal, }, { IntervalStart: time.Duration(60 * time.Second), RecurrentFee: utils.NewDecimal(24, 1), Unit: minDecimal, Increment: secDecimal, }, }, } rt0.Compile() rt1 := &Rate{ ID: "RATE1", IntervalRates: []*IntervalRate{ { IntervalStart: time.Duration(0), FixedFee: utils.NewDecimal(2, 1), RecurrentFee: utils.NewDecimal(12, 1), Unit: minDecimal, Increment: secDecimal, }, { IntervalStart: time.Duration(2 * time.Minute), RecurrentFee: utils.NewDecimal(6, 1), Unit: minDecimal, Increment: secDecimal, }, }, } rt1.Compile() rtIvls := []*RateSInterval{ { UsageStart: time.Duration(0), Increments: []*RateSIncrement{ { // cost 0,4 UsageStart: time.Duration(0), Rate: rt0, IntervalRateIndex: 0, CompressFactor: 1, Usage: utils.InvalidDuration, }, { // cost 2,4 UsageStart: time.Duration(0), Rate: rt0, IntervalRateIndex: 0, CompressFactor: 1, Usage: time.Duration(time.Minute), }, { // cost 1,2 UsageStart: time.Duration(time.Minute), Rate: rt0, IntervalRateIndex: 1, CompressFactor: 30, Usage: time.Duration(30 * time.Second), }, }, CompressFactor: 1, }, { UsageStart: time.Duration(90 * time.Second), Increments: []*RateSIncrement{ { // cost 0,2 UsageStart: time.Duration(90 * time.Second), Rate: rt1, IntervalRateIndex: 0, CompressFactor: 1, Usage: utils.InvalidDuration, }, { // cost 0,6 UsageStart: time.Duration(90 * time.Second), Rate: rt1, IntervalRateIndex: 0, CompressFactor: 30, Usage: time.Duration(30 * time.Second), }, { // cost 0,1 UsageStart: time.Duration(2 * time.Minute), Rate: rt1, IntervalRateIndex: 1, CompressFactor: 10, Usage: time.Duration(10 * time.Second), }, }, CompressFactor: 1, }, } eDcml, _ := new(decimal.Big).SetFloat64(4.9).Float64() if cost, _ := CostForIntervals(rtIvls).Float64(); cost != eDcml { t.Errorf("eDcml: %f, received: %+v", eDcml, cost) } } func TestRateProfileCostCorrectCost(t *testing.T) { rPrfCost := &RateProfileCost{ ID: "Test1", Cost: 0.234, } rPrfCost.CorrectCost(utils.IntPointer(2), utils.MetaRoundingUp) if rPrfCost.Cost != 0.24 { t.Errorf("Expected: %+v, received: %+v", 0.24, rPrfCost.Cost) } if !reflect.DeepEqual(rPrfCost.Altered, []string{utils.RoundingDecimals}) { t.Errorf("Expected: %+v, received: %+v", []string{utils.RoundingDecimals}, rPrfCost.Altered) } } func TestRateProfileCostCorrectCostMinCost(t *testing.T) { testRPC := &RateProfileCost{ Cost: 0.5, MinCost: 1.5, } testRPC.CorrectCost(utils.IntPointer(2), "") if testRPC.Cost != 1.5 { t.Errorf("\nExpecting: <1.5>,\n Received: <%+v>", testRPC.Cost) } } func TestRateProfileCostCorrectCostMaxCost(t *testing.T) { testRPC := &RateProfileCost{ Cost: 2.5, MaxCost: 1.5, } testRPC.CorrectCost(utils.IntPointer(2), "") if testRPC.Cost != 1.5 { t.Errorf("\nExpecting: <1.5>,\n Received: <%+v>", testRPC.Cost) } } func TestRateSIncrementCompressEquals(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } secDecimal, err := utils.NewDecimalFromUsage("1s") if err != nil { t.Error(err) } rate1 := &Rate{ ID: "RATE1", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, { IntervalStart: time.Minute, RecurrentFee: utils.NewDecimal(6, 3), Unit: minDecimal, Increment: secDecimal, }, }, } inCr1 := &RateSIncrement{ UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, } inCr2 := &RateSIncrement{ UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, } result := inCr1.CompressEquals(inCr2) if result != true { t.Errorf("\nExpecting: ,\n Received: <%+v>", result) } } func TestRateSIncrementCompressEqualsCase1(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } rate1 := &Rate{ ID: "RATE1", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, }, uID: "ID", } rate2 := &Rate{ ID: "RATE1", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, }, uID: "ID2", } inCr1 := &RateSIncrement{ UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, } inCr2 := &RateSIncrement{ UsageStart: 0, Usage: time.Minute, Rate: rate2, IntervalRateIndex: 0, CompressFactor: 1, } result := inCr1.CompressEquals(inCr2) if result != false { t.Errorf("\nExpecting: ,\n Received: <%+v>", result) } } func TestRateSIncrementCompressEqualsCase2(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } rate1 := &Rate{ ID: "RATE1", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, }, } inCr1 := &RateSIncrement{ UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, } inCr2 := &RateSIncrement{ UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 1, CompressFactor: 1, } result := inCr1.CompressEquals(inCr2) if result != false { t.Errorf("\nExpecting: ,\n Received: <%+v>", result) } } func TestRateSIncrementCompressEqualsCase3(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } rate1 := &Rate{ ID: "RATE1", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, }, } inCr1 := &RateSIncrement{ UsageStart: 0, Usage: time.Second, Rate: rate1, IntervalRateIndex: 1, CompressFactor: 1, } inCr2 := &RateSIncrement{ UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 1, CompressFactor: 1, } result := inCr1.CompressEquals(inCr2) if result != false { t.Errorf("\nExpecting: ,\n Received: <%+v>", result) } } func TestRateSIntervalCompressEqualsCase1(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } secDecimal, err := utils.NewDecimalFromUsage("1s") if err != nil { t.Error(err) } rate1 := &Rate{ ID: "RATE1", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, { IntervalStart: time.Minute, RecurrentFee: utils.NewDecimal(6, 3), Unit: minDecimal, Increment: secDecimal, }, }, } rateSintrv1 := &RateSInterval{ UsageStart: 0, Increments: []*RateSIncrement{ { UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, }, { UsageStart: time.Minute, Usage: time.Minute + 10*time.Second, Rate: rate1, IntervalRateIndex: 1, CompressFactor: 70, }, }, CompressFactor: 1, } rateSintrv2 := &RateSInterval{ UsageStart: 0, Increments: []*RateSIncrement{ { UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, }, }, CompressFactor: 1, } result := rateSintrv1.CompressEquals(rateSintrv2) if result != false { t.Errorf("\nExpecting ,\nReceived <%+v>", result) } } func TestRateSIntervalCompressEqualsCase2(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } secDecimal, err := utils.NewDecimalFromUsage("1s") if err != nil { t.Error(err) } rate1 := &Rate{ ID: "RATE1", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, { IntervalStart: time.Minute, RecurrentFee: utils.NewDecimal(6, 3), Unit: minDecimal, Increment: secDecimal, }, }, } rate2 := &Rate{ ID: "RATE1", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, { IntervalStart: time.Minute, RecurrentFee: utils.NewDecimal(6, 3), Unit: minDecimal, Increment: secDecimal, }, }, } rateSintrv1 := &RateSInterval{ UsageStart: 0, Increments: []*RateSIncrement{ { UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, }, { UsageStart: 0, Usage: time.Second, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, }, }, CompressFactor: 1, } rateSintrv2 := &RateSInterval{ UsageStart: 1, Increments: []*RateSIncrement{ { UsageStart: 0, Usage: time.Minute, Rate: rate2, IntervalRateIndex: 0, CompressFactor: 1, }, { UsageStart: 0, Usage: time.Minute, Rate: rate2, IntervalRateIndex: 2, CompressFactor: 1, }, }, CompressFactor: 0, } result := rateSintrv1.CompressEquals(rateSintrv2) if result != false { t.Errorf("\nExpecting ,\nReceived <%+v>", result) } } func TestRateSIntervalCompressEqualsCase3(t *testing.T) { minDecimal, err := utils.NewDecimalFromUsage("1m") if err != nil { t.Error(err) } rate1 := &Rate{ ID: "RATE1", Weights: utils.DynamicWeights{ { Weight: 0, }, }, ActivationTimes: "* * * * *", IntervalRates: []*IntervalRate{ { IntervalStart: 0, RecurrentFee: utils.NewDecimal(12, 2), Unit: minDecimal, Increment: minDecimal, }, }, } rateSintrv1 := &RateSInterval{ UsageStart: 0, Increments: []*RateSIncrement{ { UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, }, }, CompressFactor: 1, } rateSintrv2 := &RateSInterval{ UsageStart: 0, Increments: []*RateSIncrement{ { UsageStart: 0, Usage: time.Minute, Rate: rate1, IntervalRateIndex: 0, CompressFactor: 1, }, }, CompressFactor: 1, } result := rateSintrv1.CompressEquals(rateSintrv2) if result != true { t.Errorf("\nExpecting ,\nReceived <%+v>", result) } }