mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-21 07:08:45 +05:00
Merge branch 'master' into hapool
This commit is contained in:
@@ -149,12 +149,15 @@ func (ub *Account) debitBalanceAction(a *Action, reset bool) error {
|
||||
// add shared group member
|
||||
sg, err := ratingStorage.GetSharedGroup(sgId, false)
|
||||
if err != nil || sg == nil {
|
||||
//than problem
|
||||
//than is problem
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId))
|
||||
} else {
|
||||
if !utils.IsSliceMember(sg.MemberIds, ub.Id) {
|
||||
if _, found := sg.MemberIds[ub.Id]; !found {
|
||||
// add member and save
|
||||
sg.MemberIds = append(sg.MemberIds, ub.Id)
|
||||
if sg.MemberIds == nil {
|
||||
sg.MemberIds = make(utils.StringMap)
|
||||
}
|
||||
sg.MemberIds[ub.Id] = true
|
||||
ratingStorage.SetSharedGroup(sg)
|
||||
}
|
||||
}
|
||||
@@ -610,7 +613,7 @@ func (acc *Account) GetSharedGroups() (groups []string) {
|
||||
return
|
||||
}
|
||||
|
||||
func (account *Account) GetUniqueSharedGroupMembers(cd *CallDescriptor) ([]string, error) {
|
||||
func (account *Account) GetUniqueSharedGroupMembers(cd *CallDescriptor) (utils.StringMap, error) {
|
||||
var balances []*Balance
|
||||
balances = append(balances, account.getBalancesForPrefix(cd.Destination, cd.Category, cd.Direction, utils.MONETARY, "")...)
|
||||
balances = append(balances, account.getBalancesForPrefix(cd.Destination, cd.Category, cd.Direction, cd.TOR, "")...)
|
||||
@@ -621,17 +624,15 @@ func (account *Account) GetUniqueSharedGroupMembers(cd *CallDescriptor) ([]strin
|
||||
sharedGroupIds = append(sharedGroupIds, sg)
|
||||
}
|
||||
}
|
||||
var memberIds []string
|
||||
memberIds := make(utils.StringMap)
|
||||
for _, sgID := range sharedGroupIds {
|
||||
sharedGroup, err := ratingStorage.GetSharedGroup(sgID, false)
|
||||
if err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgID))
|
||||
return nil, err
|
||||
}
|
||||
for _, memberId := range sharedGroup.MemberIds {
|
||||
if !utils.IsSliceMember(memberIds, memberId) {
|
||||
memberIds = append(memberIds, memberId)
|
||||
}
|
||||
for memberID := range sharedGroup.MemberIds {
|
||||
memberIds[memberID] = true
|
||||
}
|
||||
}
|
||||
return memberIds, nil
|
||||
|
||||
@@ -1111,7 +1111,7 @@ func TestDebitShared(t *testing.T) {
|
||||
utils.MONETARY: BalanceChain{&Balance{Uuid: "moneyc", Value: 130, SharedGroups: utils.NewStringMap("SG_TEST")}},
|
||||
}}
|
||||
|
||||
sg := &SharedGroup{Id: "SG_TEST", MemberIds: []string{rif.Id, groupie.Id}, AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}}
|
||||
sg := &SharedGroup{Id: "SG_TEST", MemberIds: utils.NewStringMap(rif.Id, groupie.Id), AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}}
|
||||
|
||||
accountingStorage.SetAccount(groupie)
|
||||
ratingStorage.SetSharedGroup(sg)
|
||||
@@ -1181,7 +1181,7 @@ func TestMaxDurationShared(t *testing.T) {
|
||||
utils.MONETARY: BalanceChain{&Balance{Uuid: "moneyc", Value: 130, SharedGroups: utils.NewStringMap("SG_TEST")}},
|
||||
}}
|
||||
|
||||
sg := &SharedGroup{Id: "SG_TEST", MemberIds: []string{rif.Id, groupie.Id}, AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}}
|
||||
sg := &SharedGroup{Id: "SG_TEST", MemberIds: utils.NewStringMap(rif.Id, groupie.Id), AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}}
|
||||
|
||||
accountingStorage.SetAccount(groupie)
|
||||
ratingStorage.SetSharedGroup(sg)
|
||||
|
||||
@@ -48,29 +48,30 @@ type Action struct {
|
||||
}
|
||||
|
||||
const (
|
||||
LOG = "*log"
|
||||
RESET_TRIGGERS = "*reset_triggers"
|
||||
SET_RECURRENT = "*set_recurrent"
|
||||
UNSET_RECURRENT = "*unset_recurrent"
|
||||
ALLOW_NEGATIVE = "*allow_negative"
|
||||
DENY_NEGATIVE = "*deny_negative"
|
||||
RESET_ACCOUNT = "*reset_account"
|
||||
REMOVE_ACCOUNT = "*remove_account"
|
||||
REMOVE_BALANCE = "*remove_balance"
|
||||
TOPUP_RESET = "*topup_reset"
|
||||
TOPUP = "*topup"
|
||||
DEBIT_RESET = "*debit_reset"
|
||||
DEBIT = "*debit"
|
||||
RESET_COUNTERS = "*reset_counters"
|
||||
ENABLE_ACCOUNT = "*enable_account"
|
||||
DISABLE_ACCOUNT = "*disable_account"
|
||||
ENABLE_DISABLE_BALANCE = "*enable_disable_balance"
|
||||
CALL_URL = "*call_url"
|
||||
CALL_URL_ASYNC = "*call_url_async"
|
||||
MAIL_ASYNC = "*mail_async"
|
||||
UNLIMITED = "*unlimited"
|
||||
CDRLOG = "*cdrlog"
|
||||
SET_DDESTINATIONS = "*set_ddestinations"
|
||||
LOG = "*log"
|
||||
RESET_TRIGGERS = "*reset_triggers"
|
||||
SET_RECURRENT = "*set_recurrent"
|
||||
UNSET_RECURRENT = "*unset_recurrent"
|
||||
ALLOW_NEGATIVE = "*allow_negative"
|
||||
DENY_NEGATIVE = "*deny_negative"
|
||||
RESET_ACCOUNT = "*reset_account"
|
||||
REMOVE_ACCOUNT = "*remove_account"
|
||||
REMOVE_BALANCE = "*remove_balance"
|
||||
TOPUP_RESET = "*topup_reset"
|
||||
TOPUP = "*topup"
|
||||
DEBIT_RESET = "*debit_reset"
|
||||
DEBIT = "*debit"
|
||||
RESET_COUNTERS = "*reset_counters"
|
||||
ENABLE_ACCOUNT = "*enable_account"
|
||||
DISABLE_ACCOUNT = "*disable_account"
|
||||
ENABLE_DISABLE_BALANCE = "*enable_disable_balance"
|
||||
CALL_URL = "*call_url"
|
||||
CALL_URL_ASYNC = "*call_url_async"
|
||||
MAIL_ASYNC = "*mail_async"
|
||||
UNLIMITED = "*unlimited"
|
||||
CDRLOG = "*cdrlog"
|
||||
SET_DDESTINATIONS = "*set_ddestinations"
|
||||
TRANSFER_MONETARY_DEFAULT = "*transfer_monetary_default"
|
||||
)
|
||||
|
||||
func (a *Action) Clone() *Action {
|
||||
@@ -133,6 +134,8 @@ func getActionFunc(typ string) (actionTypeFunc, bool) {
|
||||
return removeAccount, true
|
||||
case REMOVE_BALANCE:
|
||||
return removeBalance, true
|
||||
case TRANSFER_MONETARY_DEFAULT:
|
||||
return transferMonetaryDefault, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
@@ -588,6 +591,25 @@ func removeBalance(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions)
|
||||
return accountingStorage.SetAccount(ub)
|
||||
}
|
||||
|
||||
func transferMonetaryDefault(acc *Account, sq *StatsQueueTriggered, a *Action, acs Actions) error {
|
||||
if _, exists := acc.BalanceMap[utils.MONETARY]; !exists {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
defaultBalance := acc.GetDefaultMoneyBalance()
|
||||
bChain := acc.BalanceMap[utils.MONETARY]
|
||||
for _, balance := range bChain {
|
||||
if balance.Uuid != defaultBalance.Uuid &&
|
||||
balance.Id != defaultBalance.Id { // extra caution
|
||||
if balance.Value > 0 {
|
||||
defaultBalance.Value += balance.Value
|
||||
balance.Value = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
// update account in storage
|
||||
return accountingStorage.SetAccount(acc)
|
||||
}
|
||||
|
||||
// Structure to store actions according to weight
|
||||
type Actions []*Action
|
||||
|
||||
|
||||
@@ -1451,6 +1451,62 @@ func TestActionRemoveBalance(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionTransferMonetaryDefault(t *testing.T) {
|
||||
err := accountingStorage.SetAccount(
|
||||
&Account{
|
||||
Id: "cgrates.org:trans",
|
||||
BalanceMap: map[string]BalanceChain{
|
||||
utils.MONETARY: BalanceChain{
|
||||
&Balance{
|
||||
Uuid: utils.GenUUID(),
|
||||
Id: utils.META_DEFAULT,
|
||||
Value: 10,
|
||||
},
|
||||
&Balance{
|
||||
Uuid: utils.GenUUID(),
|
||||
Value: 3,
|
||||
},
|
||||
&Balance{
|
||||
Uuid: utils.GenUUID(),
|
||||
Value: 6,
|
||||
},
|
||||
&Balance{
|
||||
Uuid: utils.GenUUID(),
|
||||
Value: -2,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("error setting account: %v", err)
|
||||
}
|
||||
|
||||
a := &Action{
|
||||
ActionType: TRANSFER_MONETARY_DEFAULT,
|
||||
}
|
||||
|
||||
at := &ActionTiming{
|
||||
accountIDs: map[string]struct{}{"cgrates.org:trans": struct{}{}},
|
||||
actions: Actions{a},
|
||||
}
|
||||
at.Execute()
|
||||
|
||||
afterUb, err := accountingStorage.GetAccount("cgrates.org:trans")
|
||||
if err != nil {
|
||||
t.Error("account not found: ", err, afterUb)
|
||||
}
|
||||
if afterUb.BalanceMap[utils.MONETARY].GetTotalValue() != 17 ||
|
||||
afterUb.BalanceMap[utils.MONETARY][0].Value != 19 ||
|
||||
afterUb.BalanceMap[utils.MONETARY][1].Value != 0 ||
|
||||
afterUb.BalanceMap[utils.MONETARY][2].Value != 0 ||
|
||||
afterUb.BalanceMap[utils.MONETARY][3].Value != -2 {
|
||||
for _, b := range afterUb.BalanceMap[utils.MONETARY] {
|
||||
t.Logf("B: %+v", b)
|
||||
}
|
||||
t.Error("ransfer balance value: ", afterUb.BalanceMap[utils.MONETARY].GetTotalValue())
|
||||
}
|
||||
}
|
||||
|
||||
/**************** Benchmarks ********************************/
|
||||
|
||||
func BenchmarkUUID(b *testing.B) {
|
||||
|
||||
@@ -624,7 +624,7 @@ func (cd *CallDescriptor) GetMaxSessionDuration() (duration time.Duration, err e
|
||||
if _, err := Guardian.Guard(func() (interface{}, error) {
|
||||
duration, err = cd.getMaxSessionDuration(account)
|
||||
return 0, err
|
||||
}, 0, memberIds...); err != nil {
|
||||
}, 0, memberIds.Slice()...); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
@@ -681,7 +681,7 @@ func (cd *CallDescriptor) Debit() (cc *CallCost, err error) {
|
||||
_, err = Guardian.Guard(func() (interface{}, error) {
|
||||
cc, err = cd.debit(account, false, true)
|
||||
return 0, err
|
||||
}, 0, memberIds...)
|
||||
}, 0, memberIds.Slice()...)
|
||||
} else {
|
||||
return nil, sgerr
|
||||
}
|
||||
@@ -700,7 +700,7 @@ func (cd *CallDescriptor) FakeDebit() (cc *CallCost, err error) {
|
||||
_, err = Guardian.Guard(func() (interface{}, error) {
|
||||
cc, err = cd.debit(account, true, true)
|
||||
return 0, err
|
||||
}, 0, memberIds...)
|
||||
}, 0, memberIds.Slice()...)
|
||||
} else {
|
||||
return nil, sgerr
|
||||
}
|
||||
@@ -749,7 +749,7 @@ func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) {
|
||||
cc, err = cd.debit(account, false, true)
|
||||
//log.Print(balanceMap[0].Value, balanceMap[1].Value)
|
||||
return 0, err
|
||||
}, 0, memberIds...)
|
||||
}, 0, memberIds.Slice()...)
|
||||
if err != nil {
|
||||
return cc, err
|
||||
}
|
||||
@@ -766,6 +766,7 @@ func (cd *CallDescriptor) RefundIncrements() (left float64, err error) {
|
||||
// all must be locked in order to use cache
|
||||
accMap := make(map[string]struct{})
|
||||
var accountIDs []string
|
||||
cd.Increments.Decompress()
|
||||
for _, increment := range cd.Increments {
|
||||
accMap[increment.BalanceInfo.AccountId] = struct{}{}
|
||||
}
|
||||
|
||||
@@ -301,6 +301,12 @@ func (i *RateInterval) String_DISABLED() string {
|
||||
}
|
||||
|
||||
func (i *RateInterval) Equal(o *RateInterval) bool {
|
||||
if i == nil && o == nil {
|
||||
return true
|
||||
}
|
||||
if i.Weight != o.Weight {
|
||||
return false
|
||||
}
|
||||
if i.Timing == nil && o.Timing == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -191,6 +191,14 @@ func TestRateIntervalEqual(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateIntervalEqualWeight(t *testing.T) {
|
||||
i1 := &RateInterval{Weight: 1}
|
||||
i2 := &RateInterval{Weight: 2}
|
||||
if i1.Equal(i2) {
|
||||
t.Errorf("%v and %v should not be equal", i1, i2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateIntervalNotEqual(t *testing.T) {
|
||||
i1 := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
|
||||
@@ -450,6 +450,7 @@ func (rs *Responder) GetSessionRuns(ev *CDR, sRuns *[]*SessionRun) error {
|
||||
}
|
||||
cd := &CallDescriptor{
|
||||
CgrId: ev.GetCgrId(rs.Timezone),
|
||||
TOR: ev.ToR,
|
||||
Direction: ev.GetDirection(dc.DirectionField),
|
||||
Tenant: ev.GetTenant(dc.TenantField),
|
||||
Category: ev.GetCategory(dc.CategoryField),
|
||||
|
||||
@@ -153,15 +153,15 @@ func TestResponderGetSessionRuns(t *testing.T) {
|
||||
&SessionRun{DerivedCharger: extra1DC,
|
||||
CallDescriptor: &CallDescriptor{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Direction: "*out", Category: "0",
|
||||
Tenant: "vdf", Subject: "rif", Account: "minitsboy", Destination: "0256", TimeStart: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}},
|
||||
TOR: utils.VOICE, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}},
|
||||
&SessionRun{DerivedCharger: extra2DC,
|
||||
CallDescriptor: &CallDescriptor{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Direction: "*out", Category: "call",
|
||||
Tenant: "vdf", Subject: "ivo", Account: "ivo", Destination: "1002", TimeStart: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}},
|
||||
TOR: utils.VOICE, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}},
|
||||
&SessionRun{DerivedCharger: dfDC,
|
||||
CallDescriptor: &CallDescriptor{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), Direction: "*out", Category: "call",
|
||||
Tenant: "vdf", Subject: "dan2", Account: "dan2", Destination: "1002", TimeStart: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}}}
|
||||
TOR: utils.VOICE, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}}}}
|
||||
if err := rsponder.GetSessionRuns(cdr, &sesRuns); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eSRuns, sesRuns) {
|
||||
|
||||
@@ -40,7 +40,7 @@ const (
|
||||
type SharedGroup struct {
|
||||
Id string
|
||||
AccountParameters map[string]*SharingParameters
|
||||
MemberIds []string
|
||||
MemberIds utils.StringMap
|
||||
//members []*Account // accounts caching
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ func (sg *SharedGroup) SortBalancesByStrategy(myBalance *Balance, bc BalanceChai
|
||||
// Returns all shared group's balances collected from user accounts'
|
||||
func (sg *SharedGroup) GetBalances(destination, category, direction, balanceType string, ub *Account) (bc BalanceChain) {
|
||||
// if len(sg.members) == 0 {
|
||||
for _, ubId := range sg.MemberIds {
|
||||
for ubId := range sg.MemberIds {
|
||||
var nUb *Account
|
||||
if ubId == ub.Id { // skip the initiating user
|
||||
nUb = ub
|
||||
|
||||
@@ -21,6 +21,8 @@ package engine
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func TestSharedSetGet(t *testing.T) {
|
||||
@@ -30,7 +32,7 @@ func TestSharedSetGet(t *testing.T) {
|
||||
AccountParameters: map[string]*SharingParameters{
|
||||
"test": &SharingParameters{Strategy: STRATEGY_HIGHEST},
|
||||
},
|
||||
MemberIds: []string{"1", "2", "3"},
|
||||
MemberIds: utils.NewStringMap("1", "2", "3"),
|
||||
}
|
||||
err := ratingStorage.SetSharedGroup(sg)
|
||||
if err != nil {
|
||||
|
||||
@@ -38,6 +38,7 @@ type TimeSpan struct {
|
||||
DurationIndex time.Duration // the call duration so far till TimeEnd
|
||||
Increments Increments
|
||||
MatchedSubject, MatchedPrefix, MatchedDestId, RatingPlanId string
|
||||
CompressFactor int
|
||||
}
|
||||
|
||||
type Increment struct {
|
||||
@@ -60,7 +61,8 @@ type UnitInfo struct {
|
||||
|
||||
func (mi *UnitInfo) Equal(other *UnitInfo) bool {
|
||||
return mi.DestinationId == other.DestinationId &&
|
||||
mi.Quantity == other.Quantity
|
||||
mi.Quantity == other.Quantity &&
|
||||
mi.TOR == other.TOR
|
||||
}
|
||||
|
||||
// Holds information about the balance that made a specific payment
|
||||
@@ -162,31 +164,51 @@ func (timespans *TimeSpans) OverlapWithTimeSpans(paidTs TimeSpans, newTs *TimeSp
|
||||
return false
|
||||
}
|
||||
|
||||
func (tss TimeSpans) Compress() {
|
||||
for _, ts := range tss {
|
||||
var cIncrs Increments
|
||||
for _, incr := range ts.Increments {
|
||||
if len(cIncrs) == 0 || !cIncrs[len(cIncrs)-1].Equal(incr) {
|
||||
incr.GetCompressFactor() // sideefect
|
||||
cIncrs = append(cIncrs, incr)
|
||||
} else {
|
||||
cIncrs[len(cIncrs)-1].CompressFactor++
|
||||
}
|
||||
}
|
||||
ts.Increments = cIncrs
|
||||
func (tss *TimeSpans) Compress() { // must be pointer receiver
|
||||
for _, ts := range *tss {
|
||||
ts.Increments.Compress()
|
||||
}
|
||||
var cTss TimeSpans
|
||||
for _, ts := range *tss {
|
||||
if len(cTss) == 0 || !cTss[len(cTss)-1].Equal(ts) {
|
||||
ts.GetCompressFactor() // sideefect
|
||||
cTss = append(cTss, ts)
|
||||
} else {
|
||||
cTs := cTss[len(cTss)-1]
|
||||
cTs.CompressFactor++
|
||||
cTs.Cost += ts.Cost
|
||||
cTs.TimeEnd = ts.TimeEnd
|
||||
cTs.DurationIndex = ts.DurationIndex
|
||||
}
|
||||
}
|
||||
*tss = cTss
|
||||
}
|
||||
|
||||
func (tss TimeSpans) Decompress() {
|
||||
for _, ts := range tss {
|
||||
var incrs Increments
|
||||
for _, cIncr := range ts.Increments {
|
||||
for i := 0; i < cIncr.GetCompressFactor(); i++ {
|
||||
incrs = append(incrs, cIncr.Clone())
|
||||
}
|
||||
}
|
||||
ts.Increments = incrs
|
||||
func (tss *TimeSpans) Decompress() { // must be pointer receiver
|
||||
for _, ts := range *tss {
|
||||
ts.Increments.Decompress()
|
||||
}
|
||||
var cTss TimeSpans
|
||||
for _, cTs := range *tss {
|
||||
var duration time.Duration
|
||||
if cTs.GetCompressFactor() > 1 {
|
||||
duration = cTs.GetUnitDuration()
|
||||
}
|
||||
for i := cTs.GetCompressFactor(); i > 1; i-- {
|
||||
uTs := &TimeSpan{}
|
||||
*uTs = *cTs // cloned by copy
|
||||
uTs.TimeEnd = cTs.TimeStart.Add(duration)
|
||||
uTs.DurationIndex = cTs.DurationIndex - time.Duration((i-1)*int(duration))
|
||||
uTs.CompressFactor = 1
|
||||
uTs.Cost = cTs.Cost / float64(cTs.GetCompressFactor())
|
||||
cTs.TimeStart = uTs.TimeEnd
|
||||
cTss = append(cTss, uTs)
|
||||
}
|
||||
cTs.Cost = cTs.GetUnitCost()
|
||||
cTs.CompressFactor = 1
|
||||
cTss = append(cTss, cTs)
|
||||
}
|
||||
*tss = cTss
|
||||
}
|
||||
|
||||
func (incr *Increment) Clone() *Increment {
|
||||
@@ -215,12 +237,48 @@ func (incr *Increment) GetCompressFactor() int {
|
||||
return incr.CompressFactor
|
||||
}
|
||||
|
||||
func (incr *Increment) GetCost() float64 {
|
||||
return float64(incr.GetCompressFactor()) * incr.Cost
|
||||
}
|
||||
|
||||
type Increments []*Increment
|
||||
|
||||
func (incs Increments) Equal(other Increments) bool {
|
||||
for index, i := range incs {
|
||||
if !i.Equal(other[index]) || i.GetCompressFactor() != other[index].GetCompressFactor() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (incs *Increments) Compress() { // must be pointer receiver
|
||||
var cIncrs Increments
|
||||
for _, incr := range *incs {
|
||||
if len(cIncrs) == 0 || !cIncrs[len(cIncrs)-1].Equal(incr) {
|
||||
incr.GetCompressFactor() // sideefect
|
||||
cIncrs = append(cIncrs, incr)
|
||||
} else {
|
||||
cIncrs[len(cIncrs)-1].CompressFactor++
|
||||
}
|
||||
}
|
||||
*incs = cIncrs
|
||||
}
|
||||
|
||||
func (incs *Increments) Decompress() { // must be pointer receiver
|
||||
var cIncrs Increments
|
||||
for _, cIncr := range *incs {
|
||||
for i := 0; i < cIncr.GetCompressFactor(); i++ {
|
||||
cIncrs = append(cIncrs, cIncr.Clone())
|
||||
}
|
||||
}
|
||||
*incs = cIncrs
|
||||
}
|
||||
|
||||
func (incs Increments) GetTotalCost() float64 {
|
||||
cost := 0.0
|
||||
for _, increment := range incs {
|
||||
cost += (float64(increment.GetCompressFactor()) * increment.Cost)
|
||||
cost += increment.GetCost()
|
||||
}
|
||||
return cost
|
||||
}
|
||||
@@ -237,6 +295,15 @@ func (ts *TimeSpan) GetDuration() time.Duration {
|
||||
return ts.TimeEnd.Sub(ts.TimeStart)
|
||||
}
|
||||
|
||||
//Returns the duration of a unitary timespan in a compressed set
|
||||
func (ts *TimeSpan) GetUnitDuration() time.Duration {
|
||||
return time.Duration(int(ts.TimeEnd.Sub(ts.TimeStart)) / ts.GetCompressFactor())
|
||||
}
|
||||
|
||||
func (ts *TimeSpan) GetUnitCost() float64 {
|
||||
return ts.Cost / float64(ts.GetCompressFactor())
|
||||
}
|
||||
|
||||
// Returns true if the given time is inside timespan range.
|
||||
func (ts *TimeSpan) Contains(t time.Time) bool {
|
||||
return t.After(ts.TimeStart) && t.Before(ts.TimeEnd)
|
||||
@@ -573,3 +640,21 @@ func (ts *TimeSpan) hasBetterRateIntervalThan(interval *RateInterval) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (ts *TimeSpan) Equal(other *TimeSpan) bool {
|
||||
return ts.Increments.Equal(other.Increments) &&
|
||||
ts.RateInterval.Equal(other.RateInterval) &&
|
||||
ts.GetUnitCost() == other.GetUnitCost() &&
|
||||
ts.GetUnitDuration() == other.GetUnitDuration() &&
|
||||
ts.MatchedSubject == other.MatchedSubject &&
|
||||
ts.MatchedPrefix == other.MatchedPrefix &&
|
||||
ts.MatchedDestId == other.MatchedDestId &&
|
||||
ts.RatingPlanId == other.RatingPlanId
|
||||
}
|
||||
|
||||
func (ts *TimeSpan) GetCompressFactor() int {
|
||||
if ts.CompressFactor == 0 {
|
||||
ts.CompressFactor = 1
|
||||
}
|
||||
return ts.CompressFactor
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func TestRightMargin(t *testing.T) {
|
||||
func TestTSRightMargin(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}}}
|
||||
t1 := time.Date(2012, time.February, 3, 23, 45, 0, 0, time.UTC)
|
||||
@@ -52,7 +52,7 @@ func TestRightMargin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitMiddle(t *testing.T) {
|
||||
func TestTSSplitMiddle(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
WeekDays: utils.WeekDays{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
|
||||
@@ -75,7 +75,7 @@ func TestSplitMiddle(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRightHourMargin(t *testing.T) {
|
||||
func TestTSRightHourMargin(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}, EndTime: "17:59:00"}}
|
||||
t1 := time.Date(2012, time.February, 3, 17, 30, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 3, 18, 00, 0, 0, time.UTC)
|
||||
@@ -100,7 +100,7 @@ func TestRightHourMargin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLeftMargin(t *testing.T) {
|
||||
func TestTSLeftMargin(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday}}}
|
||||
t1 := time.Date(2012, time.February, 5, 23, 45, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 6, 0, 10, 0, 0, time.UTC)
|
||||
@@ -124,7 +124,7 @@ func TestLeftMargin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLeftHourMargin(t *testing.T) {
|
||||
func TestTSLeftHourMargin(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{Months: utils.Months{time.December}, MonthDays: utils.MonthDays{1}, StartTime: "09:00:00"}}
|
||||
t1 := time.Date(2012, time.December, 1, 8, 45, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.December, 1, 9, 20, 0, 0, time.UTC)
|
||||
@@ -148,7 +148,7 @@ func TestLeftHourMargin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnclosingMargin(t *testing.T) {
|
||||
func TestTSEnclosingMargin(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Sunday}}}
|
||||
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 5, 18, 10, 0, 0, time.UTC)
|
||||
@@ -162,7 +162,7 @@ func TestEnclosingMargin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOutsideMargin(t *testing.T) {
|
||||
func TestTSOutsideMargin(t *testing.T) {
|
||||
i := &RateInterval{Timing: &RITiming{WeekDays: []time.Weekday{time.Monday}}}
|
||||
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 5, 18, 10, 0, 0, time.UTC)
|
||||
@@ -173,7 +173,7 @@ func TestOutsideMargin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestContains(t *testing.T) {
|
||||
func TestTSContains(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
|
||||
t3 := time.Date(2012, time.February, 5, 17, 50, 0, 0, time.UTC)
|
||||
@@ -189,7 +189,7 @@ func TestContains(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitByRatingPlan(t *testing.T) {
|
||||
func TestTSSplitByRatingPlan(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
|
||||
t3 := time.Date(2012, time.February, 5, 17, 50, 0, 0, time.UTC)
|
||||
@@ -210,7 +210,7 @@ func TestSplitByRatingPlan(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanGetCost(t *testing.T) {
|
||||
func TestTSTimespanGetCost(t *testing.T) {
|
||||
t1 := time.Date(2012, time.February, 5, 17, 45, 0, 0, time.UTC)
|
||||
t2 := time.Date(2012, time.February, 5, 17, 55, 0, 0, time.UTC)
|
||||
ts1 := TimeSpan{TimeStart: t1, TimeEnd: t2}
|
||||
@@ -233,7 +233,7 @@ func TestTimespanGetCost(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanGetCostIntervals(t *testing.T) {
|
||||
func TestTSTimespanGetCostIntervals(t *testing.T) {
|
||||
ts := &TimeSpan{}
|
||||
ts.Increments = make(Increments, 11)
|
||||
for i := 0; i < 11; i++ {
|
||||
@@ -244,7 +244,7 @@ func TestTimespanGetCostIntervals(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetRateInterval(t *testing.T) {
|
||||
func TestTSSetRateInterval(t *testing.T) {
|
||||
i1 := &RateInterval{
|
||||
Timing: &RITiming{},
|
||||
Rating: &RIRate{Rates: RateGroups{&Rate{0, 1.0, 1 * time.Second, 1 * time.Second}}},
|
||||
@@ -267,7 +267,7 @@ func TestSetRateInterval(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitGroupedRates(t *testing.T) {
|
||||
func TestTSTimespanSplitGroupedRates(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
EndTime: "17:59:00",
|
||||
@@ -305,7 +305,7 @@ func TestTimespanSplitGroupedRates(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitGroupedRatesIncrements(t *testing.T) {
|
||||
func TestTSTimespanSplitGroupedRatesIncrements(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
EndTime: "17:59:00",
|
||||
@@ -361,7 +361,7 @@ func TestTimespanSplitGroupedRatesIncrements(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitRightHourMarginBeforeGroup(t *testing.T) {
|
||||
func TestTSTimespanSplitRightHourMarginBeforeGroup(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
EndTime: "17:00:30",
|
||||
@@ -398,7 +398,7 @@ func TestTimespanSplitRightHourMarginBeforeGroup(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitGroupSecondSplit(t *testing.T) {
|
||||
func TestTSTimespanSplitGroupSecondSplit(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
EndTime: "17:03:30",
|
||||
@@ -445,7 +445,7 @@ func TestTimespanSplitGroupSecondSplit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitLong(t *testing.T) {
|
||||
func TestTSTimespanSplitLong(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
StartTime: "18:00:00",
|
||||
@@ -475,7 +475,7 @@ func TestTimespanSplitLong(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitMultipleGroup(t *testing.T) {
|
||||
func TestTSTimespanSplitMultipleGroup(t *testing.T) {
|
||||
i := &RateInterval{
|
||||
Timing: &RITiming{
|
||||
EndTime: "17:05:00",
|
||||
@@ -522,7 +522,7 @@ func TestTimespanSplitMultipleGroup(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanExpandingPastEnd(t *testing.T) {
|
||||
func TestTSTimespanExpandingPastEnd(t *testing.T) {
|
||||
timespans := []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
|
||||
@@ -546,7 +546,7 @@ func TestTimespanExpandingPastEnd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanExpandingDurationIndex(t *testing.T) {
|
||||
func TestTSTimespanExpandingDurationIndex(t *testing.T) {
|
||||
timespans := []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
|
||||
@@ -568,7 +568,7 @@ func TestTimespanExpandingDurationIndex(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanExpandingRoundingPastEnd(t *testing.T) {
|
||||
func TestTSTimespanExpandingRoundingPastEnd(t *testing.T) {
|
||||
timespans := []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
|
||||
@@ -592,7 +592,7 @@ func TestTimespanExpandingRoundingPastEnd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanExpandingPastEndMultiple(t *testing.T) {
|
||||
func TestTSTimespanExpandingPastEndMultiple(t *testing.T) {
|
||||
timespans := []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
|
||||
@@ -620,7 +620,7 @@ func TestTimespanExpandingPastEndMultiple(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanExpandingPastEndMultipleEqual(t *testing.T) {
|
||||
func TestTSTimespanExpandingPastEndMultipleEqual(t *testing.T) {
|
||||
timespans := []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
|
||||
@@ -648,7 +648,7 @@ func TestTimespanExpandingPastEndMultipleEqual(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanExpandingBeforeEnd(t *testing.T) {
|
||||
func TestTSTimespanExpandingBeforeEnd(t *testing.T) {
|
||||
timespans := []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
|
||||
@@ -674,7 +674,7 @@ func TestTimespanExpandingBeforeEnd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanExpandingBeforeEndMultiple(t *testing.T) {
|
||||
func TestTSTimespanExpandingBeforeEndMultiple(t *testing.T) {
|
||||
timespans := []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
|
||||
@@ -704,7 +704,7 @@ func TestTimespanExpandingBeforeEndMultiple(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanCreateSecondsSlice(t *testing.T) {
|
||||
func TestTSTimespanCreateSecondsSlice(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 0, time.UTC),
|
||||
@@ -721,7 +721,7 @@ func TestTimespanCreateSecondsSlice(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanCreateIncrements(t *testing.T) {
|
||||
func TestTSTimespanCreateIncrements(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 14, 30, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 10, 14, 30, 30, 100000000, time.UTC),
|
||||
@@ -747,7 +747,7 @@ func TestTimespanCreateIncrements(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitByIncrement(t *testing.T) {
|
||||
func TestTSTimespanSplitByIncrement(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
|
||||
@@ -782,7 +782,7 @@ func TestTimespanSplitByIncrement(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitByIncrementStart(t *testing.T) {
|
||||
func TestTSTimespanSplitByIncrementStart(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
|
||||
@@ -816,7 +816,7 @@ func TestTimespanSplitByIncrementStart(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitByIncrementEnd(t *testing.T) {
|
||||
func TestTSTimespanSplitByIncrementEnd(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
|
||||
@@ -850,7 +850,7 @@ func TestTimespanSplitByIncrementEnd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimespanSplitByDuration(t *testing.T) {
|
||||
func TestTSTimespanSplitByDuration(t *testing.T) {
|
||||
ts := &TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 19, 18, 30, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 19, 18, 31, 00, 0, time.UTC),
|
||||
@@ -888,7 +888,7 @@ func TestTimespanSplitByDuration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOverlapedFromIndexMiddle(t *testing.T) {
|
||||
func TestTSRemoveOverlapedFromIndexMiddle(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -919,7 +919,7 @@ func TestRemoveOverlapedFromIndexMiddle(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOverlapedFromIndexMiddleNonBounds(t *testing.T) {
|
||||
func TestTSRemoveOverlapedFromIndexMiddleNonBounds(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -952,7 +952,7 @@ func TestRemoveOverlapedFromIndexMiddleNonBounds(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOverlapedFromIndexMiddleNonBoundsOver(t *testing.T) {
|
||||
func TestTSRemoveOverlapedFromIndexMiddleNonBoundsOver(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -984,7 +984,7 @@ func TestRemoveOverlapedFromIndexMiddleNonBoundsOver(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOverlapedFromIndexEnd(t *testing.T) {
|
||||
func TestTSRemoveOverlapedFromIndexEnd(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1014,7 +1014,7 @@ func TestRemoveOverlapedFromIndexEnd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOverlapedFromIndexEndPast(t *testing.T) {
|
||||
func TestTSRemoveOverlapedFromIndexEndPast(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1044,7 +1044,7 @@ func TestRemoveOverlapedFromIndexEndPast(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOverlapedFromIndexAll(t *testing.T) {
|
||||
func TestTSRemoveOverlapedFromIndexAll(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1073,7 +1073,7 @@ func TestRemoveOverlapedFromIndexAll(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOverlapedFromIndexNone(t *testing.T) {
|
||||
func TestTSRemoveOverlapedFromIndexNone(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1105,7 +1105,7 @@ func TestRemoveOverlapedFromIndexNone(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOverlapedFromIndexOne(t *testing.T) {
|
||||
func TestTSRemoveOverlapedFromIndexOne(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1122,7 +1122,7 @@ func TestRemoveOverlapedFromIndexOne(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveOverlapedFromIndexTwo(t *testing.T) {
|
||||
func TestTSRemoveOverlapedFromIndexTwo(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1143,7 +1143,7 @@ func TestRemoveOverlapedFromIndexTwo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansMiddleLong(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansMiddleLong(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1180,7 +1180,7 @@ func TestOverlapWithTimeSpansMiddleLong(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansMiddleMedium(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansMiddleMedium(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1218,7 +1218,7 @@ func TestOverlapWithTimeSpansMiddleMedium(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansMiddleShort(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansMiddleShort(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1257,7 +1257,7 @@ func TestOverlapWithTimeSpansMiddleShort(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansStart(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansStart(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1294,7 +1294,7 @@ func TestOverlapWithTimeSpansStart(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansAlmostEnd(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansAlmostEnd(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1333,7 +1333,7 @@ func TestOverlapWithTimeSpansAlmostEnd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansEnd(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansEnd(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1371,7 +1371,7 @@ func TestOverlapWithTimeSpansEnd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansPastEnd(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansPastEnd(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1409,7 +1409,7 @@ func TestOverlapWithTimeSpansPastEnd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansAll(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansAll(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1445,7 +1445,7 @@ func TestOverlapWithTimeSpansAll(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansAllPast(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansAllPast(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1481,7 +1481,7 @@ func TestOverlapWithTimeSpansAllPast(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlapWithTimeSpansOne(t *testing.T) {
|
||||
func TestTSOverlapWithTimeSpansOne(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 12, 5, 15, 45, 0, 0, time.UTC),
|
||||
@@ -1505,7 +1505,7 @@ func TestOverlapWithTimeSpansOne(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSCompressDecompress(t *testing.T) {
|
||||
func TestTSIncrementsCompressDecompress(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
Increments: Increments{
|
||||
@@ -1557,7 +1557,7 @@ func TestTSCompressDecompress(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSMultipleCompressDecompress(t *testing.T) {
|
||||
func TestTSMultipleIncrementsCompressDecompress(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
Increments: Increments{
|
||||
@@ -1694,3 +1694,150 @@ func TestTSBetterIntervalAgainAfter(t *testing.T) {
|
||||
t.Error("Wrong better rate interval!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSCompressDecompress(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
|
||||
Cost: 1.2,
|
||||
DurationIndex: 1 * time.Minute,
|
||||
},
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
|
||||
Cost: 1.2,
|
||||
DurationIndex: 2 * time.Minute,
|
||||
},
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
|
||||
Cost: 1.2,
|
||||
DurationIndex: 3 * time.Minute,
|
||||
},
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC),
|
||||
Cost: 1.2,
|
||||
DurationIndex: 4 * time.Minute,
|
||||
},
|
||||
}
|
||||
tss.Compress()
|
||||
if len(tss) != 1 ||
|
||||
!tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
|
||||
!tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
|
||||
tss[0].DurationIndex != 4*time.Minute ||
|
||||
tss[0].Cost != 4.8 ||
|
||||
tss[0].CompressFactor != 4 {
|
||||
for _, ts := range tss {
|
||||
t.Logf("TS: %+v", ts)
|
||||
}
|
||||
t.Error("Error compressing timespans: ", tss)
|
||||
}
|
||||
tss.Decompress()
|
||||
if len(tss) != 4 ||
|
||||
!tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
|
||||
!tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
|
||||
tss[0].DurationIndex != 1*time.Minute ||
|
||||
tss[0].CompressFactor != 1 ||
|
||||
tss[0].Cost != 1.2 ||
|
||||
!tss[1].TimeStart.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
|
||||
!tss[1].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
|
||||
tss[1].DurationIndex != 2*time.Minute ||
|
||||
tss[1].CompressFactor != 1 ||
|
||||
tss[1].Cost != 1.2 ||
|
||||
!tss[2].TimeStart.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
|
||||
!tss[2].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
|
||||
tss[2].DurationIndex != 3*time.Minute ||
|
||||
tss[2].CompressFactor != 1 ||
|
||||
tss[2].Cost != 1.2 ||
|
||||
!tss[3].TimeStart.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
|
||||
!tss[3].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
|
||||
tss[3].DurationIndex != 4*time.Minute ||
|
||||
tss[3].CompressFactor != 1 ||
|
||||
tss[3].Cost != 1.2 {
|
||||
for i, ts := range tss {
|
||||
t.Logf("TS(%d): %+v", i, ts)
|
||||
}
|
||||
t.Error("Error decompressing timespans: ", tss)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTSDifferentCompressDecompress(t *testing.T) {
|
||||
tss := TimeSpans{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Weight: 1},
|
||||
Cost: 1.2,
|
||||
DurationIndex: 1 * time.Minute,
|
||||
},
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Weight: 2},
|
||||
Cost: 1.2,
|
||||
DurationIndex: 2 * time.Minute,
|
||||
},
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Weight: 1},
|
||||
Cost: 1.2,
|
||||
DurationIndex: 3 * time.Minute,
|
||||
},
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC),
|
||||
RateInterval: &RateInterval{Weight: 1},
|
||||
Cost: 1.2,
|
||||
DurationIndex: 4 * time.Minute,
|
||||
},
|
||||
}
|
||||
tss.Compress()
|
||||
if len(tss) != 3 ||
|
||||
!tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
|
||||
!tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
|
||||
tss[0].DurationIndex != 1*time.Minute ||
|
||||
tss[0].Cost != 1.2 ||
|
||||
!tss[1].TimeStart.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
|
||||
!tss[1].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
|
||||
tss[1].DurationIndex != 2*time.Minute ||
|
||||
tss[1].Cost != 1.2 ||
|
||||
!tss[2].TimeStart.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
|
||||
!tss[2].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
|
||||
tss[2].DurationIndex != 4*time.Minute ||
|
||||
tss[2].Cost != 2.4 {
|
||||
for _, ts := range tss {
|
||||
t.Logf("TS: %+v", ts)
|
||||
}
|
||||
t.Error("Error compressing timespans: ", tss)
|
||||
}
|
||||
tss.Decompress()
|
||||
if len(tss) != 4 ||
|
||||
!tss[0].TimeStart.Equal(time.Date(2015, 1, 9, 16, 18, 0, 0, time.UTC)) ||
|
||||
!tss[0].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
|
||||
tss[0].DurationIndex != 1*time.Minute ||
|
||||
tss[0].CompressFactor != 1 ||
|
||||
tss[0].Cost != 1.2 ||
|
||||
!tss[1].TimeStart.Equal(time.Date(2015, 1, 9, 16, 19, 0, 0, time.UTC)) ||
|
||||
!tss[1].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
|
||||
tss[1].DurationIndex != 2*time.Minute ||
|
||||
tss[1].CompressFactor != 1 ||
|
||||
tss[1].Cost != 1.2 ||
|
||||
!tss[2].TimeStart.Equal(time.Date(2015, 1, 9, 16, 20, 0, 0, time.UTC)) ||
|
||||
!tss[2].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
|
||||
tss[2].DurationIndex != 3*time.Minute ||
|
||||
tss[2].CompressFactor != 1 ||
|
||||
tss[2].Cost != 1.2 ||
|
||||
!tss[3].TimeStart.Equal(time.Date(2015, 1, 9, 16, 21, 0, 0, time.UTC)) ||
|
||||
!tss[3].TimeEnd.Equal(time.Date(2015, 1, 9, 16, 22, 0, 0, time.UTC)) ||
|
||||
tss[3].DurationIndex != 4*time.Minute ||
|
||||
tss[3].CompressFactor != 1 ||
|
||||
tss[3].Cost != 1.2 {
|
||||
for i, ts := range tss {
|
||||
t.Logf("TS(%d): %+v", i, ts)
|
||||
}
|
||||
t.Error("Error decompressing timespans: ", tss)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user