diff --git a/sessions/libsessions.go b/sessions/libsessions.go index 8b31082c2..cf4f27a63 100644 --- a/sessions/libsessions.go +++ b/sessions/libsessions.go @@ -280,22 +280,3 @@ func getDerivedEvents(events map[string]*utils.CGREvent, derivedReply bool) map[ utils.MetaRaw: events[utils.MetaRaw], } } - -// getDerivedMaxUsage returns only the *raw MaxUsage if derivedReply flag is not specified -func getDerivedMaxUsage(maxUsages map[string]time.Duration, derivedReply bool) (out map[string]time.Duration) { - if derivedReply { - out = maxUsages - } else { - out = make(map[string]time.Duration) - } - var maxUsage time.Duration - var maxUsageSet bool // so we know if we have set the 0 on purpose - for _, rplyMaxUsage := range maxUsages { - if !maxUsageSet || rplyMaxUsage < maxUsage { - maxUsage = rplyMaxUsage - maxUsageSet = true - } - } - out[utils.MetaRaw] = maxUsage - return -} diff --git a/sessions/libsessions_test.go b/sessions/libsessions_test.go index 6e3a817b7..df807493c 100644 --- a/sessions/libsessions_test.go +++ b/sessions/libsessions_test.go @@ -349,27 +349,3 @@ func TestGetDerivedEvents(t *testing.T) { t.Errorf("Expected %s received %s", utils.ToJSON(exp), utils.ToJSON(rply)) } } - -func TestGetDerivedMaxUsage(t *testing.T) { - max := map[string]time.Duration{ - utils.MetaDefault: time.Second, - "CustomRoute": time.Hour, - } - - exp := map[string]time.Duration{ - utils.MetaRaw: time.Second, - utils.MetaDefault: time.Second, - "CustomRoute": time.Hour, - } - - if rply := getDerivedMaxUsage(max, true); !reflect.DeepEqual(exp, rply) { - t.Errorf("Expected %s received %s", utils.ToJSON(exp), utils.ToJSON(rply)) - } - - exp = map[string]time.Duration{ - utils.MetaRaw: time.Second, - } - if rply := getDerivedMaxUsage(max, false); !reflect.DeepEqual(exp, rply) { - t.Errorf("Expected %s received %s", utils.ToJSON(exp), utils.ToJSON(rply)) - } -} diff --git a/sessions/session.go b/sessions/session.go index 37134d1bc..64ef46525 100644 --- a/sessions/session.go +++ b/sessions/session.go @@ -265,29 +265,6 @@ func (sr *SRun) Clone() (clsr *SRun) { return } -// debitReserve attempty to debit from ExtraDuration and returns remaining duration -// if lastUsage is not nil, the ExtraDuration is corrected -func (sr *SRun) debitReserve(dur time.Duration, lastUsage *time.Duration) (rDur time.Duration) { - if lastUsage != nil && - sr.LastUsage != *lastUsage { - diffUsage := sr.LastUsage - *lastUsage - sr.ExtraDuration += diffUsage - sr.TotalUsage -= sr.LastUsage - sr.TotalUsage += *lastUsage - sr.LastUsage = *lastUsage - } - // debit from reserved - if sr.ExtraDuration >= dur { - sr.ExtraDuration -= dur - sr.LastUsage = dur - sr.TotalUsage += dur - } else { - rDur = dur - sr.ExtraDuration - sr.ExtraDuration = 0 - } - return -} - // updateSRuns updates the SRuns event with the alterable fields (is not thread safe) func (s *Session) updateSRuns(updEv engine.MapEvent, alterableFields utils.StringSet) { if alterableFields.Size() == 0 { diff --git a/sessions/session_test.go b/sessions/session_test.go index 5c7c807d2..4084397e7 100644 --- a/sessions/session_test.go +++ b/sessions/session_test.go @@ -141,155 +141,6 @@ func TestSessionClone(t *testing.T) { } -//Test1 ExtraDuration 0 and LastUsage < initial - -//Test1 ExtraDuration 0 and LastUsage < initial -func TestSRunDebitReserve(t *testing.T) { - lastUsage := time.Minute + 30*time.Second - duration := 2 * time.Minute - sr := &SRun{ - ExtraDuration: 0, - LastUsage: duration, - TotalUsage: duration, - } - if rDur := sr.debitReserve(duration, &lastUsage); rDur != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, rDur) - } - //start with extraDuration 0 and the difference go in rDur - if sr.ExtraDuration != 0 { - t.Errorf("Expecting: %+v, received: %+v", 0, sr.ExtraDuration) - } - if sr.LastUsage != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, sr.LastUsage) - } - if sr.TotalUsage != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, sr.TotalUsage) - } -} - -//Test2 ExtraDuration 0 and LastUsage > initial -func TestSRunDebitReserve2(t *testing.T) { - lastUsage := 2*time.Minute + 30*time.Second - duration := 2 * time.Minute - sr := &SRun{ - ExtraDuration: 0, - LastUsage: duration, - TotalUsage: duration, - } - if rDur := sr.debitReserve(duration, &lastUsage); rDur != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, rDur) - } - if sr.ExtraDuration != 0 { - t.Errorf("Expecting: %+v, received: %+v", 0, sr.ExtraDuration) - } - if sr.LastUsage != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, sr.LastUsage) - } - if sr.TotalUsage != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, sr.TotalUsage) - } -} - -//Test3 ExtraDuration ( 1m < duration) and LastUsage < initial -func TestSRunDebitReserve3(t *testing.T) { - lastUsage := time.Minute + 30*time.Second - duration := 2 * time.Minute - sr := &SRun{ - ExtraDuration: time.Minute, - LastUsage: duration, - TotalUsage: duration, - } - if rDur := sr.debitReserve(duration, &lastUsage); rDur != (duration - lastUsage) { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, rDur) - } - if sr.ExtraDuration != 0 { - t.Errorf("Expecting: %+v, received: %+v", 0, sr.ExtraDuration) - } - if sr.LastUsage != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, sr.LastUsage) - } - if sr.TotalUsage != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, sr.TotalUsage) - } -} - -//Test4 ExtraDuration 1m and LastUsage > initial -func TestSRunDebitReserve4(t *testing.T) { - lastUsage := 2*time.Minute + 30*time.Second - duration := 2 * time.Minute - sr := &SRun{ - ExtraDuration: time.Minute, - LastUsage: duration, - TotalUsage: duration, - } - //We have extraDuration 1 minute and 30s different - if rDur := sr.debitReserve(duration, &lastUsage); rDur != time.Minute+30*time.Second { - t.Errorf("Expecting: %+v, received: %+v", time.Minute+30*time.Second, rDur) - } - if sr.ExtraDuration != 0 { - t.Errorf("Expecting: %+v, received: %+v", 0, sr.ExtraDuration) - } - if sr.LastUsage != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, sr.LastUsage) - } - if sr.TotalUsage != lastUsage { - t.Errorf("Expecting: %+v, received: %+v", lastUsage, sr.TotalUsage) - } -} - -//Test5 ExtraDuration 3m ( > initialDuration) and LastUsage < initial -func TestSRunDebitReserve5(t *testing.T) { - lastUsage := time.Minute + 30*time.Second - duration := 2 * time.Minute - sr := &SRun{ - ExtraDuration: 3 * time.Minute, - LastUsage: duration, - TotalUsage: duration, - } - //in debit reserve we start with an extraDuration 3m - //after we add the different dur-lastUsed (+30s) - if rDur := sr.debitReserve(duration, &lastUsage); rDur != 0 { - t.Errorf("Expecting: %+v, received: %+v", 0, rDur) - } - //ExtraDuration (3m30s - 2m) - if sr.ExtraDuration != time.Minute+30*time.Second { - t.Errorf("Expecting: %+v, received: %+v", time.Minute+30*time.Second, sr.ExtraDuration) - } - if sr.LastUsage != duration { - t.Errorf("Expecting: %+v, received: %+v", duration, sr.LastUsage) - } - if sr.TotalUsage != 3*time.Minute+30*time.Second { - t.Errorf("Expecting: %+v, received: %+v", 3*time.Minute+30*time.Second, sr.TotalUsage) - } -} - -//Test6 ExtraDuration 3m ( > initialDuration) and LastUsage > initial -func TestSRunDebitReserve6(t *testing.T) { - lastUsage := 2*time.Minute + 30*time.Second - duration := 2 * time.Minute - sr := &SRun{ - ExtraDuration: 3 * time.Minute, - LastUsage: duration, - TotalUsage: duration, - } - //in debit reserve we start with an extraDuration 3m - //after we add the different dur-lastUsed (-30s) - if rDur := sr.debitReserve(duration, &lastUsage); rDur != 0 { - t.Errorf("Expecting: %+v, received: %+v", 0, rDur) - } - //ExtraDuration (2m30s - 2m) - if sr.ExtraDuration != 30*time.Second { - t.Errorf("Expecting: %+v, received: %+v", 30*time.Second, sr.ExtraDuration) - } - if sr.LastUsage != duration { - t.Errorf("Expecting: %+v, received: %+v", duration, sr.LastUsage) - } - // 2m(initial Total) + 2m30s(correction) - if sr.TotalUsage != 4*time.Minute+30*time.Second { - t.Errorf("Expecting: %+v, received: %+v", 4*time.Minute+30*time.Second, sr.TotalUsage) - } -} - func TestSessionAsCGREventsRawEvent(t *testing.T) { ev := map[string]interface{}{ utils.EventName: "TEST_EVENT", diff --git a/sessions/sessions.go b/sessions/sessions.go index 77c50ed4b..72c31791a 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -430,9 +430,6 @@ func (sS *SessionS) debitSession(s *Session, sRunIdx int, dur time.Duration, return } -func (sS *SessionS) pause(sr *SRun, dur time.Duration) { -} - // debitLoopSession will periodically debit sessions, ie: automatic prepaid // threadSafe since it will run into it's own goroutine func (sS *SessionS) debitLoopSession(s *Session, sRunIdx int, @@ -519,20 +516,6 @@ func (sS *SessionS) debitLoopSession(s *Session, sRunIdx int, } } -// refundSession will refund the extra usage debitted by the end of session -// not thread-safe so the locks need to be done in a layer above -// rUsage represents the amount of usage to be refunded -func (sS *SessionS) refundSession(s *Session, sRunIdx int, rUsage time.Duration) (err error) { - return -} - -// storeSCost will post the session cost to CDRs -// not thread safe, need to be handled in a layer above -func (sS *SessionS) storeSCost(s *Session, sRunIdx int) (err error) { - - return -} - // disconnectSession will send disconnect from SessionS to clients // not thread safe, it considers that the session is already stopped by this time func (sS *SessionS) disconnectSession(s *Session, rsn string) (err error) { @@ -733,9 +716,6 @@ func (sS *SessionS) getIndexedFilters(tenant string, fltrs []string) ( f, err := sS.dm.GetFilter(tenant, fltrID, true, true, utils.NonTransactional) if err != nil { - if err == utils.ErrNotFound { - err = utils.ErrPrefixNotFound(fltrID) - } continue } if f.ActivationInterval != nil && @@ -964,26 +944,6 @@ func (sS *SessionS) newSession(cgrEv *utils.CGREvent, resID, clntConnID string, return } s.SRuns = make([]*SRun, len(chrgrs)) - for i, chrgr := range chrgrs { - me := engine.MapEvent(chrgr.CGREvent.Event) - startTime := me.GetTimeIgnoreErrors(utils.AnswerTime, - sS.cgrCfg.GeneralCfg().DefaultTimezone) - if startTime.IsZero() { // AnswerTime not parsable, try SetupTime - startTime = s.EventStart.GetTimeIgnoreErrors(utils.SetupTime, - sS.cgrCfg.GeneralCfg().DefaultTimezone) - } - category := me.GetStringIgnoreErrors(utils.Category) - if len(category) == 0 { - category = sS.cgrCfg.GeneralCfg().DefaultCategory - } - subject := me.GetStringIgnoreErrors(utils.Subject) - if len(subject) == 0 { - subject = me.GetStringIgnoreErrors(utils.AccountField) - } - s.SRuns[i] = &SRun{ - Event: me, - } - } return } @@ -1277,7 +1237,7 @@ func (sS *SessionS) updateSession(s *Session, updtEv, opts engine.MapEvent, isMs } var reqMaxUsage time.Duration - if reqMaxUsage, err = updtEv.GetDuration(utils.Usage); err != nil { + if _, err = updtEv.GetDuration(utils.Usage); err != nil { if err != utils.ErrNotFound { return } @@ -1629,7 +1589,6 @@ func (args *V1AuthorizeArgs) ParseFlags(flags, sep string) { } } args.Paginator, _ = utils.GetRoutePaginatorFromOpts(args.APIOpts) - return } // V1AuthorizeReply are options available in auth reply @@ -2598,7 +2557,6 @@ func (args *V1ProcessMessageArgs) ParseFlags(flags, sep string) { } } args.Paginator, _ = utils.GetRoutePaginatorFromOpts(args.APIOpts) - return } // V1ProcessMessageReply is the reply for the ProcessMessage API diff --git a/structmatcher/structmatcher.go b/structmatcher/structmatcher.go deleted file mode 100644 index 141943e96..000000000 --- a/structmatcher/structmatcher.go +++ /dev/null @@ -1,343 +0,0 @@ -/* -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 structmatcher - -/* -The condition syntax is a json encoded string similar to mongodb query language. - -Examples: -- {"Weight":{"*gt":50}} checks for a balance with weight greater than 50 -- {"*or":[{"Value":{"*eq":0}},{"Value":{"*gte":100}}] checks for a balance with value equal to 0 or equal or highr than 100 - -Available operators: -- *eq: equal -- *gt: greater than -- *gte: greater or equal than -- *lt: less then -- *lte: less or equal than -- *exp: expired -- *or: logical or -- *and: logical and -- *not: logical not -- *has: receives a list of elements and checks that the elements are present in the specified field (StringMap type) -- *rsr: will apply a rsr check to the field (see utils/rsrfield.go) - -Equal (*eq) and local and (*and) operators are implicit for shortcuts. In this way: - -{"*and":[{"Value":{"*eq":3}},{"Weight":{"*eq":10}}]} is equivalent to: {"Value":3, "Weight":10}. -*/ - -import ( - "encoding/json" - "errors" - "fmt" - "reflect" - "strings" - "time" - - "github.com/cgrates/cgrates/utils" -) - -const ( - CondOR = "*or" - CondAND = "*and" - CondHAS = "*has" -) - -func NewErrInvalidArgument(arg interface{}) error { - return fmt.Errorf("INVALID_ARGUMENT: %v", arg) -} - -type StringMap map[string]bool - -var ( - ErrParserError = errors.New("PARSER_ERROR") - - operatorMap = map[string]func(field, value interface{}) (bool, error){ - utils.MetaEqual: func(field, value interface{}) (bool, error) { - return value == field, nil - }, - utils.MetaGreaterThan: func(field, value interface{}) (bool, error) { - var of, vf float64 - var ok bool - if of, ok = field.(float64); !ok { - return false, NewErrInvalidArgument(field) - } - if vf, ok = value.(float64); !ok { - return false, NewErrInvalidArgument(value) - } - return of > vf, nil - }, - utils.MetaGreaterOrEqual: func(field, value interface{}) (bool, error) { - var of, vf float64 - var ok bool - if of, ok = field.(float64); !ok { - return false, NewErrInvalidArgument(field) - } - if vf, ok = value.(float64); !ok { - return false, NewErrInvalidArgument(value) - } - return of >= vf, nil - }, - utils.MetaLessThan: func(field, value interface{}) (bool, error) { - var of, vf float64 - var ok bool - if of, ok = field.(float64); !ok { - return false, NewErrInvalidArgument(field) - } - if vf, ok = value.(float64); !ok { - return false, NewErrInvalidArgument(value) - } - return of < vf, nil - }, - utils.MetaLessOrEqual: func(field, value interface{}) (bool, error) { - var of, vf float64 - var ok bool - if of, ok = field.(float64); !ok { - return false, NewErrInvalidArgument(field) - } - if vf, ok = value.(float64); !ok { - return false, NewErrInvalidArgument(value) - } - return of <= vf, nil - }, - utils.MetaExp: func(field, value interface{}) (bool, error) { - var expDate time.Time - var ok bool - if expDate, ok = field.(time.Time); !ok { - return false, NewErrInvalidArgument(field) - } - var expired bool - if expired, ok = value.(bool); !ok { - return false, NewErrInvalidArgument(value) - } - if expired { // check for expiration - return !expDate.IsZero() && expDate.Before(time.Now()), nil - } else { // check not expired - return expDate.IsZero() || expDate.After(time.Now()), nil - } - }, - CondHAS: func(field, value interface{}) (bool, error) { - var strMap StringMap - var ok bool - if strMap, ok = field.(StringMap); !ok { - return false, NewErrInvalidArgument(field) - } - var strSlice []interface{} - if strSlice, ok = value.([]interface{}); !ok { - return false, NewErrInvalidArgument(value) - } - for _, str := range strSlice { - if !strMap[str.(string)] { - return false, nil - } - } - return true, nil - }, - utils.MetaRSR: func(field, value interface{}) (bool, error) { - fltr, err := utils.NewRSRFilter(value.(string)) - if err != nil { - return false, err - } - return fltr.Pass(fmt.Sprintf("%v", field)), nil - }, - } -) - -type compositeElement interface { - element - addChild(element) error -} - -type element interface { - checkStruct(interface{}) (bool, error) -} - -type operatorSlice struct { - operator string - slice []element -} - -func (os *operatorSlice) addChild(ce element) error { - os.slice = append(os.slice, ce) - return nil -} -func (os *operatorSlice) checkStruct(o interface{}) (bool, error) { - switch os.operator { - case CondOR: - for _, cond := range os.slice { - check, err := cond.checkStruct(o) - if err != nil { - return false, err - } - if check { - return true, nil - } - } - case CondAND, utils.MetaNot: - accumulator := true - for _, cond := range os.slice { - check, err := cond.checkStruct(o) - if err != nil { - return false, err - } - accumulator = accumulator && check - } - if os.operator == CondAND { - return accumulator, nil - } else { - return !accumulator, nil - } - } - return false, nil -} - -type keyStruct struct { - key string - elem element -} - -func (ks *keyStruct) addChild(ce element) error { - ks.elem = ce - return nil -} -func (ks *keyStruct) checkStruct(o interface{}) (bool, error) { - obj := reflect.ValueOf(o) - if obj.Kind() == reflect.Ptr { - obj = obj.Elem() - } - value := obj.FieldByName(ks.key) - if !value.IsValid() { - return false, NewErrInvalidArgument(ks.key) - } - return ks.elem.checkStruct(value.Interface()) -} - -type operatorValue struct { - operator string - value interface{} -} - -func (ov *operatorValue) checkStruct(o interface{}) (bool, error) { - if f, ok := operatorMap[ov.operator]; ok { - return f(o, ov.value) - } - return false, nil -} - -type keyValue struct { - key string - value interface{} -} - -func (kv *keyValue) checkStruct(o interface{}) (bool, error) { - obj := reflect.ValueOf(o) - if obj.Kind() == reflect.Ptr { - obj = obj.Elem() - } - value := obj.FieldByName(kv.key) - if !value.IsValid() { - return false, NewErrInvalidArgument(kv.key) - } - return value.Interface() == kv.value, nil -} - -type trueElement struct{} - -func (te *trueElement) checkStruct(o interface{}) (bool, error) { - return true, nil -} - -func isOperator(s string) bool { - return strings.HasPrefix(s, "*") -} - -func notEmpty(x interface{}) bool { - return !reflect.DeepEqual(x, reflect.Zero(reflect.TypeOf(x)).Interface()) -} - -type StructMatcher struct { - rootElement element -} - -func NewStructMatcher(q string) (sm *StructMatcher, err error) { - sm = &StructMatcher{} - err = sm.Parse(q) - return -} - -func (sm *StructMatcher) load(a map[string]interface{}, parentElement compositeElement) (element, error) { - for key, value := range a { - var currentElement element - switch t := value.(type) { - case []interface{}: - if key == CondHAS { - currentElement = &operatorValue{operator: key, value: t} - } else { - currentElement = &operatorSlice{operator: key} - for _, e := range t { - sm.load(e.(map[string]interface{}), currentElement.(compositeElement)) - } - } - case map[string]interface{}: - currentElement = &keyStruct{key: key} - //log.Print("map: ", t) - sm.load(t, currentElement.(compositeElement)) - case interface{}: - if isOperator(key) { - currentElement = &operatorValue{operator: key, value: t} - } else { - currentElement = &keyValue{key: key, value: t} - } - //log.Print("generic interface: ", t) - default: - return nil, ErrParserError - } - if parentElement != nil { // normal recurrent action - parentElement.addChild(currentElement) - } else { - if len(a) > 1 { // we have more keys in the map - parentElement = &operatorSlice{operator: CondAND} - parentElement.addChild(currentElement) - } else { // it was only one key value - return currentElement, nil - } - } - } - return parentElement, nil -} - -func (sm *StructMatcher) Parse(s string) (err error) { - a := make(map[string]interface{}) - if len(s) != 0 { - if err := json.Unmarshal([]byte([]byte(s)), &a); err != nil { - return err - } - sm.rootElement, err = sm.load(a, nil) - } else { - sm.rootElement = &trueElement{} - } - return -} - -func (sm *StructMatcher) Match(o interface{}) (bool, error) { - if sm.rootElement == nil { - return false, ErrParserError - } - return sm.rootElement.checkStruct(o) -} diff --git a/structmatcher/structmatcher_test.go b/structmatcher/structmatcher_test.go deleted file mode 100644 index 27a8a509d..000000000 --- a/structmatcher/structmatcher_test.go +++ /dev/null @@ -1,483 +0,0 @@ -/* -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 structmatcher - -import ( - "encoding/json" - "strings" - "testing" - "time" - - "github.com/cgrates/cgrates/utils" -) - -func toJSON(v interface{}) string { - b, _ := json.MarshalIndent(v, "", " ") - return string(b) -} - -func TestStructMatcher(t *testing.T) { - cl := &StructMatcher{} - err := cl.Parse(`{"*or":[{"test":1},{"field":{"*gt":1}},{"best":"coco"}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - - err = cl.Parse(`{"*has":["NAT","RET","EUR"]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - err = cl.Parse(`{"Field":7, "Other":true}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - err = cl.Parse(``) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } -} - -func TestStructMatcherKeyValue(t *testing.T) { - o := struct { - Test string - Field float64 - Other bool - ExpDate time.Time - }{ - Test: "test", - Field: 6.0, - Other: true, - ExpDate: time.Date(2016, 1, 19, 20, 47, 0, 0, time.UTC), - } - cl := &StructMatcher{} - err := cl.Parse(`{"Test":"test"}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":6}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Other":true}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":6, "Other":true}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":7, "Other":true}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":6, "Other":false}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Other":true, "Field":{"*gt":5}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"*not":[{"Other":true, "Field":{"*gt":5}}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Other":true, "Field":{"*gt":7}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(``) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"ExpDate":{"*exp":true}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"ExpDate":{"*exp":false}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"*and":[{"Field":{"*gte":50}},{"Test":{"*eq":"test"}}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"WrongFieldName":{"*eq":1}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err == nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } -} - -func TestParseAndMatchError(t *testing.T) { - sMatch := &StructMatcher{} - expected := "invalid character 'C' looking for beginning of value" - err := sMatch.Parse("Can't unmarshal this") - if err == nil || err.Error() != expected { - t.Errorf("Expected %+v, received %+v", expected, err) - } - matchStr := &struct{}{} - _, err = sMatch.Match(matchStr) - if err == nil || err.Error() != ErrParserError.Error() { - t.Errorf("Expected %+v, received %+v", ErrParserError, err) - } -} - -func TestStructMatcherKeyValuePointer(t *testing.T) { - o := &struct { - Test string - Field float64 - Other bool - }{ - Test: "test", - Field: 6.0, - Other: true, - } - cl := &StructMatcher{} - err := cl.Parse(`{"Test":"test"}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":6}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Other":true}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } -} - -func TestStructMatcherOperatorValue(t *testing.T) { - root := &operatorValue{operator: utils.MetaGreaterThan, value: 3.4} - if check, err := root.checkStruct(3.5); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(root)) - } - root = &operatorValue{operator: utils.MetaEqual, value: 3.4} - if check, err := root.checkStruct(3.5); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(root)) - } - root = &operatorValue{operator: utils.MetaEqual, value: 3.4} - if check, err := root.checkStruct(3.4); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(root)) - } - root = &operatorValue{operator: utils.MetaEqual, value: "zinc"} - if check, err := root.checkStruct("zinc"); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(root)) - } - root = &operatorValue{operator: CondHAS, value: []interface{}{"NAT", "RET", "EUR"}} - if check, err := root.checkStruct(StringMap{"WOR": true, "EUR": true, "NAT": true, "RET": true, "ROM": true}); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", !check, err, toJSON(root)) - } -} - -func TestStructMatcherKeyStruct(t *testing.T) { - o := struct { - Test string - Field float64 - Other bool - }{ - Test: "test", - Field: 6.0, - Other: true, - } - cl := &StructMatcher{} - err := cl.Parse(`{"Field":{"*gt": 5}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Test":{"*gt": 5}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || !strings.HasPrefix(err.Error(), "INVALID_ARGUMENT") { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":{"*gte": 6}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":{"*lt": 7}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":{"*lte": 6}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":{"*eq": 6}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Test":{"*eq": "test"}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } -} - -func TestStructMatcherKeyStructPointer(t *testing.T) { - o := &struct { - Test string - Field float64 - Other bool - }{ - Test: "test", - Field: 6.0, - Other: true, - } - cl := &StructMatcher{} - err := cl.Parse(`{"Field":{"*gt": 5}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Test":{"*gt": 5}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || !strings.HasPrefix(err.Error(), "INVALID_ARGUMENT") { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":{"*gte": 6}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":{"*lt": 7}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":{"*lte": 6}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Field":{"*eq": 6}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"Test":{"*eq": "test"}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } -} - -func TestStructMatcherOperatorSlice(t *testing.T) { - o := &struct { - Test string - Field float64 - Other bool - }{ - Test: "test", - Field: 6.0, - Other: true, - } - cl := &StructMatcher{} - err := cl.Parse(`{"*or":[{"Test":"test"},{"Field":{"*gt":5}},{"Other":true}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"*or":[{"Test":"test"},{"Field":{"*gt":7}},{"Other":false}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"*not":[{"*or":[{"Test":"test"},{"Field":{"*gt":7}},{"Other":false}]}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"*and":[{"Test":"test"},{"Field":{"*gt":5}},{"Other":true}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"*not":[{"*and":[{"Test":"test"},{"Field":{"*gt":5}},{"Other":true}]}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"*and":[{"Test":"test"},{"Field":{"*gt":7}},{"Other":false}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } -} - -func TestStructMatcherMixed(t *testing.T) { - o := &struct { - Test string - Field float64 - Categories StringMap - Other bool - }{ - Test: "test", - Field: 6.0, - Categories: StringMap{"call": true, "data": true, "voice": true}, - Other: true, - } - cl := &StructMatcher{} - err := cl.Parse(`{"*and":[{"Test":"test"},{"Field":{"*gt":5}},{"Other":true},{"Categories":{"*has":["data", "call"]}}]}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", check, err, toJSON(cl.rootElement)) - } -} - -func TestStructMatcherBalanceType(t *testing.T) { - type Balance struct { - Value float64 - } - - o := &struct { - BalanceType string - Balance - }{ - BalanceType: "*monetary", - Balance: Balance{Value: 10}, - } - cl := &StructMatcher{} - err := cl.Parse(`{"BalanceType":"*monetary","Value":10}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", !check, err, toJSON(cl.rootElement)) - } -} - -func TestStructMatcherRSR(t *testing.T) { - o := &struct { - BalanceType string - }{ - BalanceType: "*monetary", - } - cl := &StructMatcher{} - err := cl.Parse(`{"BalanceType":{"*rsr":"^*mon"}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); !check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", !check, err, toJSON(cl.rootElement)) - } - err = cl.Parse(`{"BalanceType":{"*rsr":"^*min"}}`) - if err != nil { - t.Errorf("Error loading structure: %+v (%v)", toJSON(cl.rootElement), err) - } - if check, err := cl.Match(o); check || err != nil { - t.Errorf("Error checking struct: %v %v (%v)", !check, err, toJSON(cl.rootElement)) - } -} diff --git a/utils/accountcharges.go b/utils/accountcharges.go deleted file mode 100644 index be2b7f8c9..000000000 --- a/utils/accountcharges.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Real-time Online/Offline Charging System (OerS) 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 utils diff --git a/utils/datanode_test.go b/utils/datanode_test.go index e9c018b86..6abd55838 100644 --- a/utils/datanode_test.go +++ b/utils/datanode_test.go @@ -187,7 +187,7 @@ func TestFieldAsInterface(t *testing.T) { /// testPath = []string{"path"} dn.Map = map[string]*DataNode{ - "notPath": &DataNode{ + "notPath": { Type: 1, }, } @@ -235,7 +235,7 @@ func TestSet(t *testing.T) { dn := new(DataNode) testPath := make([]string, 0) val1 := map[string]*DataNode{ - "test": &DataNode{ + "test": { Type: 1, }, }