From 54ab6074a64081d5da5b41cf87d1216b92b73bfe Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 9 Oct 2013 20:02:13 +0300 Subject: [PATCH] more loading fixes and more tests --- engine/calldesc.go | 15 +++++++++++---- engine/calldesc_test.go | 24 ++++++++++++++++++++---- engine/loader_csv.go | 6 +++++- engine/loader_csv_test.go | 6 ++++++ engine/loader_db.go | 2 +- engine/rateinterval.go | 3 ++- engine/rateinterval_test.go | 12 ++++++++++++ engine/ratingplan_test.go | 6 +++--- engine/storage_map.go | 5 +++-- engine/storage_sql.go | 10 +++++++++- engine/timespans.go | 8 +++++++- engine/timespans_test.go | 16 ++++++++-------- engine/userbalance.go | 1 + engine/userbalance_test.go | 26 ++++++++++++-------------- utils/coreutils.go | 9 --------- 15 files changed, 100 insertions(+), 49 deletions(-) diff --git a/engine/calldesc.go b/engine/calldesc.go index ef69ee4bd..0d5569f69 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -40,7 +40,7 @@ func init() { //db_server := "192.168.0.17" m, _ := NewMapStorage() //m, _ := NewMongoStorage(db_server, "27017", "cgrates_test", "", "") - //m, _ := NewRedisStorage(db_server+":6379", 11, "") + //m, _ := NewRedisStorage(db_server+":6379", 11, "", utils.MSGPACK) //m, _ := NewRedigoStorage(db_server+":6379", 11, "") //m, _ := NewRadixStorage(db_server+":6379", 11, "") storageGetter, _ = m.(DataStorage) @@ -225,17 +225,24 @@ func (cd *CallDescriptor) splitInTimeSpans(firstSpan *TimeSpan) (timespans []*Ti Logger.Debug(fmt.Sprintf("After SplitByRatingPlan: %+v", timespans)) // split on price intervals for i := 0; i < len(timespans); i++ { + //log.Printf("TS: %+v", timespans[i]) rp := timespans[i].ratingPlan + Logger.Debug(fmt.Sprintf("rp: %+v", rp)) //timespans[i].RatingPlan = nil rp.RateIntervals.Sort() for _, interval := range rp.RateIntervals { + //log.Printf("\tINTERVAL: %+v %v", interval, len(rp.RateIntervals)) if timespans[i].RateInterval != nil && timespans[i].RateInterval.Weight < interval.Weight { continue // if the timespan has an interval than it already has a heigher weight } newTs := timespans[i].SplitByRateInterval(interval) if newTs != nil { newTs.ratingPlan = rp - timespans = append(timespans, newTs) + // insert the new timespan + i++ + timespans = append(timespans, nil) + copy(timespans[i+1:], timespans[i:]) + timespans[i] = newTs break } } @@ -307,12 +314,12 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { } // global rounding cost = utils.Round(cost, roundingDecimals, roundingMethod) - subject := strings.Split(matchedSubject, ":") + startIndex := len(fmt.Sprintf("%s:%s:%s:", cd.Direction, cd.Tenant, cd.TOR)) cc := &CallCost{ Direction: cd.Direction, TOR: cd.TOR, Tenant: cd.Tenant, - Subject: subject[len(subject)-1], + Subject: matchedSubject[startIndex:], Account: cd.Account, Destination: destPrefix, Cost: cost, diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 0e4434979..f0a002300 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -117,6 +117,23 @@ func TestGetCostTimespans(t *testing.T) { if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee || len(result.Timespans) != 2 { t.Errorf("Expected %+v was %+v", expected, result) } + +} + +/* +func TestGetCostRatingPlansAndRatingIntervals(t *testing.T) { + t1 := time.Date(2012, time.February, 27, 23, 50, 0, 0, time.UTC) + t2 := time.Date(2012, time.February, 28, 18, 10, 0, 0, time.UTC) + cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "CUSTOMER_1", Subject: "rif:from:tm", Destination: "49178", TimeStart: t1, TimeEnd: t2, LoopIndex: 0, CallDuration: t2.Sub(t1)} + result, _ := cd.GetCost() + if len(result.Timespans) != 3 || + !result.Timespans[0].TimeEnd.Equal(result.Timespans[1].TimeStart) || + !result.Timespans[1].TimeEnd.Equal(result.Timespans[2].TimeStart) { + for _, ts := range result.Timespans { + t.Logf("TS %+v", ts) + } + t.Errorf("Expected %+v was %+v", 3, len(result.Timespans)) + } } func TestGetCostRateGroups(t *testing.T) { @@ -132,7 +149,7 @@ func TestGetCostRateGroups(t *testing.T) { t.Error("Error calculating cost: ", result.Timespans[0]) } } - +*/ func TestGetCostNoConnectFee(t *testing.T) { t1 := time.Date(2012, time.February, 2, 17, 30, 0, 0, time.UTC) t2 := time.Date(2012, time.February, 2, 18, 30, 0, 0, time.UTC) @@ -196,9 +213,8 @@ func TestSpansMultipleRatingPlans(t *testing.T) { t2 := time.Date(2012, time.February, 8, 0, 30, 0, 0, time.UTC) cd := &CallDescriptor{Direction: "*out", TOR: "0", Tenant: "vdf", Subject: "rif", Destination: "0257308200", TimeStart: t1, TimeEnd: t2} result, _ := cd.GetCost() - expected := &CallCost{Tenant: "vdf", Subject: "rif", Destination: "0257", Cost: 1200, ConnectFee: 0} - if result.Cost != expected.Cost || result.ConnectFee != expected.ConnectFee { - t.Errorf("Expected %v was %v", expected, result) + if result.Cost != 300 || result.ConnectFee != 0 { + t.Errorf("Expected %v was %v", 300, result) } } diff --git a/engine/loader_csv.go b/engine/loader_csv.go index 45a3032d9..69f205367 100644 --- a/engine/loader_csv.go +++ b/engine/loader_csv.go @@ -343,7 +343,11 @@ func (csvr *CSVReader) LoadRatingProfiles() (err error) { if fallbacksubject != "" { for _, fbs := range strings.Split(fallbacksubject, ";") { - rp.FallbackKey += fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, fbs) + ";" + newKey := fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, fbs) + var sslice utils.StringSlice = strings.Split(rp.FallbackKey, ";") + if !sslice.Contains(newKey) { + rp.FallbackKey += newKey + ";" + } } rp.FallbackKey = strings.TrimRight(rp.FallbackKey, ";") } diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 7862059ed..0baf691c6 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -79,6 +79,8 @@ T2,GERMANY_PREMIUM,GBP_71 STANDARD,RT_STANDARD,WORKDAYS_00,10 STANDARD,RT_STD_WEEKEND,WORKDAYS_18,10 STANDARD,RT_STD_WEEKEND,WEEKENDS,10 +PREMIUM,P1,WORKDAYS_00,10 +PREMIUM,T2,WORKDAYS_18,10 PREMIUM,RT_STD_WEEKEND,WEEKENDS,10 DEFAULT,RT_DEFAULT,WORKDAYS_00,10 EVENING,P1,WORKDAYS_00,10 @@ -812,6 +814,10 @@ func TestLoadRatingProfiles(t *testing.T) { if !reflect.DeepEqual(rp.DestinationMap["GERMANY"], expected.DestinationMap["GERMANY"]) { t.Errorf("Error loading rating profile: %+v", rp.DestinationMap["GERMANY"][0]) } + if _, ok := csvr.ratingProfiles["*out:CUSTOMER_1:0:rif:from:tm"]; !ok { + t.Error("Failed to load rating profile") + } + } func TestLoadActions(t *testing.T) { diff --git a/engine/loader_db.go b/engine/loader_db.go index c430f503f..6bd459c28 100644 --- a/engine/loader_db.go +++ b/engine/loader_db.go @@ -197,8 +197,8 @@ func (dbr *DbReader) LoadRatingProfiles() error { return errors.New(fmt.Sprintf("Could not load destination rate timings for tag: %v", rp.DestinationMap)) } for _, drt := range drts { - plan := &RatingPlan{ActivationTime: at} for _, dr := range drt.destinationRates { + plan := &RatingPlan{ActivationTime: at} plan.AddRateInterval(drt.GetRateInterval(dr)) rp.AddRatingPlanIfNotPresent(dr.DestinationsTag, plan) } diff --git a/engine/rateinterval.go b/engine/rateinterval.go index c6da5ed9f..412066b7f 100644 --- a/engine/rateinterval.go +++ b/engine/rateinterval.go @@ -163,8 +163,9 @@ func (i *RateInterval) getRightMargin(t time.Time) (rigthtTime time.Time) { hour, _ = strconv.Atoi(split[0]) min, _ = strconv.Atoi(split[1]) sec, _ = strconv.Atoi(split[2]) + return time.Date(year, month, day, hour, min, sec, nsec, loc) } - return time.Date(year, month, day, hour, min, sec, nsec, loc) + return time.Date(year, month, day, hour, min, sec, nsec, loc).Add(time.Second) } /* diff --git a/engine/rateinterval_test.go b/engine/rateinterval_test.go index e3daf02e3..ea965ba97 100644 --- a/engine/rateinterval_test.go +++ b/engine/rateinterval_test.go @@ -23,6 +23,18 @@ import ( "time" ) +func TestRateIntervalSimpleContains(t *testing.T) { + i := &RateInterval{ + WeekDays: WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, + StartTime: "18:00:00", + EndTime: "", + } + d := time.Date(2012, time.February, 27, 23, 59, 59, 0, time.UTC) + if !i.Contains(d) { + t.Errorf("Date %+v shoud be in interval %+v", d, i) + } +} + func TestRateIntervalMonth(t *testing.T) { i := &RateInterval{Months: Months{time.February}} d := time.Date(2012, time.February, 10, 23, 0, 0, 0, time.UTC) diff --git a/engine/ratingplan_test.go b/engine/ratingplan_test.go index e22413b77..c9df70e15 100644 --- a/engine/ratingplan_test.go +++ b/engine/ratingplan_test.go @@ -34,7 +34,7 @@ func TestApRestoreFromStorage(t *testing.T) { Destination: "49"} cd.LoadRatingPlans() if len(cd.RatingPlans) != 2 { - t.Error("Error restoring activation periods: ", len(cd.RatingPlans)) + t.Error("Error restoring activation periods: ", cd.RatingPlans[0]) } } @@ -79,8 +79,8 @@ func TestFallbackDirect(t *testing.T) { func TestFallbackMultiple(t *testing.T) { cd := &CallDescriptor{TOR: "0", Direction: OUTBOUND, Tenant: "vdf", Subject: "fall", Destination: "0723045"} cd.LoadRatingPlans() - if len(cd.RatingPlans) != 2 { - t.Errorf("Error restoring rating plans: %#v", cd.RatingPlans) + if len(cd.RatingPlans) != 1 { + t.Errorf("Error restoring rating plans: %+v", cd.RatingPlans) } } diff --git a/engine/storage_map.go b/engine/storage_map.go index d009632c5..15850583b 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -46,6 +46,7 @@ func (ms *MapStorage) Flush() error { func (ms *MapStorage) GetRatingProfile(key string) (rp *RatingProfile, err error) { if values, ok := ms.dict[RATING_PROFILE_PREFIX+key]; ok { rp = new(RatingProfile) + err = ms.ms.Unmarshal(values, rp) } else { return nil, errors.New("not found") @@ -75,8 +76,8 @@ func (ms *MapStorage) DestinationContainsPrefix(key string, prefix string) (prec if d, err := ms.GetDestination(key); err != nil { return 0, err } else { - for _, p := range utils.SplitPrefix(prefix) { - if precision, ok := d.containsPrefix(p); ok { + for _, p := range utils.SplitPrefixInterface(prefix) { + if precision, ok := d.containsPrefix(p.(string)); ok { return precision, nil } } diff --git a/engine/storage_sql.go b/engine/storage_sql.go index a32fb4fb0..319e71e9c 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -23,6 +23,7 @@ import ( "encoding/json" "fmt" "github.com/cgrates/cgrates/utils" + "strings" "time" ) @@ -1066,7 +1067,14 @@ func (self *SQLStorage) GetTpRatingProfiles(tpid, tag string) (map[string]*Ratin rp.DestRatesTimingTag = destrates_timing_tag rp.ActivationTime = activation_time if fallback_subject != "" { - rp.FallbackKey = fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, fallback_subject) + for _, fbs := range strings.Split(fallback_subject, ";") { + newKey := fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, fbs) + var sslice utils.StringSlice = strings.Split(rp.FallbackKey, ";") + if !sslice.Contains(newKey) { + rp.FallbackKey += newKey + ";" + } + } + rp.FallbackKey = strings.TrimRight(rp.FallbackKey, ";") } } return rpfs, nil diff --git a/engine/timespans.go b/engine/timespans.go index 1034fb62e..355e76bf6 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -154,10 +154,11 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { nts.CallDuration = ts.CallDuration ts.SetNewCallDuration(nts) Logger.Debug(fmt.Sprintf("Group splitting: %+v %+v", ts, nts)) + //log.Printf("Group splitting: %+v %+v", ts, nts) return } } - + //log.Printf("%+v %+v", i, ts.TimeEnd) // if the span is enclosed in the interval try to set as new interval and return nil if i.Contains(ts.TimeStart) && i.Contains(ts.TimeEnd) { //Logger.Debug("All in interval") @@ -168,6 +169,9 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { if i.Contains(ts.TimeStart) { //Logger.Debug("Start in interval") splitTime := i.getRightMargin(ts.TimeStart) + if ts.TimeEnd.Sub(splitTime) == time.Second { + //return + } ts.SetRateInterval(i) if splitTime == ts.TimeStart { return @@ -177,6 +181,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { nts.CallDuration = ts.CallDuration ts.SetNewCallDuration(nts) Logger.Debug(fmt.Sprintf("right: %+v %+v", ts, nts)) + //log.Printf("right: %+v %+v", ts, nts) return } // if only the end time is in the interval split the interval to the left @@ -193,6 +198,7 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval) (nts *TimeSpan) { nts.CallDuration = ts.CallDuration ts.SetNewCallDuration(nts) Logger.Debug(fmt.Sprintf("left: %+v %+v", ts, nts)) + //log.Printf("left: %+v %+v", ts, nts) return } return diff --git a/engine/timespans_test.go b/engine/timespans_test.go index e330bcf75..4f3b979bf 100644 --- a/engine/timespans_test.go +++ b/engine/timespans_test.go @@ -31,18 +31,18 @@ func TestRightMargin(t *testing.T) { ts := &TimeSpan{TimeStart: t1, TimeEnd: t2} oldDuration := ts.GetDuration() nts := ts.SplitByRateInterval(i) - if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 23, 59, 59, 0, time.UTC) { + if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 24, 0, 0, 0, time.UTC) { t.Error("Incorrect first half", ts) } - if nts.TimeStart != time.Date(2012, time.February, 3, 23, 59, 59, 0, time.UTC) || nts.TimeEnd != t2 { + if nts.TimeStart != time.Date(2012, time.February, 4, 0, 0, 0, 0, time.UTC) || nts.TimeEnd != t2 { t.Error("Incorrect second half", nts) } if ts.RateInterval != i { t.Error("RateInterval not attached correctly") } - if ts.GetDuration().Seconds() != 15*60-1 || nts.GetDuration().Seconds() != 10*60+1 { - t.Error("Wrong durations.for RateIntervals", ts.GetDuration().Seconds(), ts.GetDuration().Seconds()) + if ts.GetDuration() != 15*time.Minute || nts.GetDuration() != 10*time.Minute { + t.Error("Wrong durations.for RateIntervals", ts.GetDuration(), ts.GetDuration()) } if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() { @@ -57,18 +57,18 @@ func TestRightHourMargin(t *testing.T) { ts := &TimeSpan{TimeStart: t1, TimeEnd: t2} oldDuration := ts.GetDuration() nts := ts.SplitByRateInterval(i) - if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 17, 59, 00, 0, time.UTC) { + if ts.TimeStart != t1 || ts.TimeEnd != time.Date(2012, time.February, 3, 17, 59, 0, 0, time.UTC) { t.Error("Incorrect first half", ts) } - if nts.TimeStart != time.Date(2012, time.February, 3, 17, 59, 00, 0, time.UTC) || nts.TimeEnd != t2 { + if nts.TimeStart != time.Date(2012, time.February, 3, 17, 59, 0, 0, time.UTC) || nts.TimeEnd != t2 { t.Error("Incorrect second half", nts) } if ts.RateInterval != i { t.Error("RateInterval not attached correctly") } - if ts.GetDuration().Seconds() != 29*60 || nts.GetDuration().Seconds() != 1*60 { - t.Error("Wrong durations.for RateIntervals", ts.GetDuration().Seconds(), nts.GetDuration().Seconds()) + if ts.GetDuration() != 29*time.Minute || nts.GetDuration() != 1*time.Minute { + t.Error("Wrong durations.for RateIntervals", ts.GetDuration(), nts.GetDuration()) } if ts.GetDuration().Seconds()+nts.GetDuration().Seconds() != oldDuration.Seconds() { t.Errorf("The duration has changed: %v + %v != %v", ts.GetDuration().Seconds(), nts.GetDuration().Seconds(), oldDuration.Seconds()) diff --git a/engine/userbalance.go b/engine/userbalance.go index e21276738..76dacf37d 100644 --- a/engine/userbalance.go +++ b/engine/userbalance.go @@ -260,6 +260,7 @@ func (ub *UserBalance) debitCreditBalance(cc *CallCost, count bool) error { } continue } + // get the new rate cd := cc.CreateCallDescriptor() cd.TimeStart = ts.GetTimeStartForIncrement(incrementIndex) diff --git a/engine/userbalance_test.go b/engine/userbalance_test.go index 4a456880b..9af25ce87 100644 --- a/engine/userbalance_test.go +++ b/engine/userbalance_test.go @@ -684,47 +684,45 @@ func TestDebitNegativeMinuteBalance(t *testing.T) { } */ -/* func TestDebitSMSBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, SpecialPrice: 0.0, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, SpecialPrice: 0.0, DestinationId: "RET"} + b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} + b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} rifsBalance := &UserBalance{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, SMS + OUTBOUND: BalanceChain{&Balance{Value: 100}}}} - result := rifsBalance.debitBalance(SMS, 12, false) + result := rifsBalance.debitGenericBalance(SMS, 12, false) if rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value != 88 || result != rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value { t.Errorf("Expected %v was %v", 88, rifsBalance.BalanceMap[SMS+OUTBOUND]) } } func TestDebitAllSMSBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, SpecialPrice: 0.0, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, SpecialPrice: 0.0, DestinationId: "RET"} + b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} + b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} rifsBalance := &UserBalance{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, SMS + OUTBOUND: BalanceChain{&Balance{Value: 100}}}} - result := rifsBalance.debitBalance(SMS, 100, false) + result := rifsBalance.debitGenericBalance(SMS, 100, false) if rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value != 0 || result != rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value { t.Errorf("Expected %v was %v", 0, rifsBalance.BalanceMap[SMS+OUTBOUND]) } } func TestDebitMoreSMSBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, SpecialPrice: 0.0, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, SpecialPrice: 0.0, DestinationId: "RET"} + b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} + b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} rifsBalance := &UserBalance{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, SMS + OUTBOUND: BalanceChain{&Balance{Value: 100}}}} - result := rifsBalance.debitBalance(SMS, 110, false) + result := rifsBalance.debitGenericBalance(SMS, 110, false) if rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value != -10 || result != rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value { t.Errorf("Expected %v was %v", -10, rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value) } } func TestDebitNegativeSMSBalance(t *testing.T) { - b1 := &Balance{Value: 10, Weight: 10, SpecialPrice: 0.0, DestinationId: "NAT"} - b2 := &Balance{Value: 100, Weight: 20, SpecialPrice: 0.0, DestinationId: "RET"} + b1 := &Balance{Value: 10, Weight: 10, DestinationId: "NAT"} + b2 := &Balance{Value: 100, Weight: 20, DestinationId: "RET"} rifsBalance := &UserBalance{Id: "other", BalanceMap: map[string]BalanceChain{MINUTES + OUTBOUND: BalanceChain{b1, b2}, CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 21}}, SMS + OUTBOUND: BalanceChain{&Balance{Value: 100}}}} - result := rifsBalance.debitBalance(SMS, -15, false) + result := rifsBalance.debitGenericBalance(SMS, -15, false) if rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value != 115 || result != rifsBalance.BalanceMap[SMS+OUTBOUND][0].Value { t.Errorf("Expected %v was %v", 115, rifsBalance.BalanceMap[SMS+OUTBOUND]) } } -*/ func TestUserBalancedebitBalance(t *testing.T) { ub := &UserBalance{ diff --git a/utils/coreutils.go b/utils/coreutils.go index 68e26a294..04f4dc3f4 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -142,15 +142,6 @@ func (ss StringSlice) Contains(needle string) bool { return false } -func SplitPrefix(prefix string) []string { - var subs []string - max := len(prefix) - for i := 0; i < len(prefix)-1; i++ { - subs = append(subs, prefix[:max-i]) - } - return subs -} - func SplitPrefixInterface(prefix string) []interface{} { var subs []interface{} max := len(prefix)