mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
270 lines
8.9 KiB
Go
270 lines
8.9 KiB
Go
//go:build benchmark
|
|
|
|
/*
|
|
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 Affero 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 Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
*/
|
|
|
|
package engine
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cgrates/cgrates/config"
|
|
"github.com/cgrates/cgrates/utils"
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
)
|
|
|
|
// TestMsgPackBackwardsCompatibility verifies whether the msgpack library update is backwards-incompatible
|
|
// even with the TimeNotBuiltin legacy option set to true (see https://github.com/ugorji/go/issues/269).
|
|
// To use:
|
|
// - switch to a previous commit, that's using the original library
|
|
// - checkout this file
|
|
// - execute the test with the action variable set to 'SET'
|
|
// - return on the master branch and execute the test with action == 'GET'.
|
|
//
|
|
// If the 'GET' test passes, we can assume it's backwards-compatible.
|
|
//
|
|
// List of types that could be affected by the library update:
|
|
//
|
|
// - RatingProfile
|
|
// - Action
|
|
// - Account
|
|
// - utils.LoadInstance
|
|
// - ActionTrigger
|
|
// - ActionPlan
|
|
// - ResourceProfile
|
|
// - Resource
|
|
// - StatQueueProfile
|
|
// - StatQueue
|
|
// - ThresholdProfile
|
|
// - Threshold
|
|
// - Filter
|
|
// - RouteProfile
|
|
// - AttributeProfile
|
|
// - ChargerProfile
|
|
// - DispatcherProfile
|
|
func TestMsgPackBackwardsCompatibility(t *testing.T) {
|
|
t.SkipNow()
|
|
// Define reference dates.
|
|
currentDate := time.Now()
|
|
refTime := time.Date(currentDate.Year(), currentDate.Month(), 16, 14, 20, 33, 123456789, time.UTC)
|
|
refTimeNextYear := refTime.AddDate(1, 0, 0)
|
|
|
|
// Create the profiles. Use them to set on 'SET' action or to validate what
|
|
// we receive on 'GET' action.
|
|
ratingPrf := RatingProfile{
|
|
Id: "ratingPrf1",
|
|
RatingPlanActivations: RatingPlanActivations{
|
|
{
|
|
ActivationTime: refTime,
|
|
RatingPlanId: "ratingPlan1",
|
|
},
|
|
},
|
|
}
|
|
actionsKey := "Actions1"
|
|
actions := Actions{
|
|
{
|
|
Id: "action1",
|
|
ActionType: "*log",
|
|
ExtraParameters: "{\"Field\":\"Value\"}",
|
|
Filters: []string{"FLTR_1", "FLTR_2"},
|
|
ExpirationString: "1month",
|
|
Weight: 10,
|
|
Balance: &BalanceFilter{
|
|
ID: utils.StringPointer("balance_1"),
|
|
Type: utils.StringPointer("*monetary"),
|
|
Value: &utils.ValueFormula{
|
|
Static: 15,
|
|
},
|
|
ExpirationDate: &refTimeNextYear,
|
|
},
|
|
},
|
|
}
|
|
account := Account{
|
|
ID: "1001",
|
|
BalanceMap: map[string]Balances{
|
|
"*monetary": {
|
|
{
|
|
ID: "balance_1",
|
|
Value: 15,
|
|
ExpirationDate: refTimeNextYear,
|
|
},
|
|
},
|
|
},
|
|
|
|
// Might want to ignore this field as it's possible
|
|
// to get updated on its own.
|
|
UpdateTime: refTime,
|
|
}
|
|
fltr := Filter{
|
|
Tenant: "cgrates.org",
|
|
ID: "FLTR_1",
|
|
Rules: []*FilterRule{
|
|
{
|
|
Type: utils.MetaString,
|
|
Element: "~*req.Account",
|
|
Values: []string{"1001"},
|
|
},
|
|
},
|
|
ActivationInterval: &utils.ActivationInterval{
|
|
ActivationTime: refTime,
|
|
ExpiryTime: refTimeNextYear,
|
|
},
|
|
}
|
|
|
|
cfg := config.NewDefaultCGRConfig() // datadb opts has redis defaults
|
|
db, err := NewDataDBConn(cfg.DataDbCfg().Type,
|
|
cfg.DataDbCfg().Host, cfg.DataDbCfg().Port,
|
|
cfg.DataDbCfg().Name, cfg.DataDbCfg().User,
|
|
cfg.DataDbCfg().Password, cfg.GeneralCfg().DBDataEncoding,
|
|
cfg.DataDbCfg().Opts, cfg.DataDbCfg().Items)
|
|
if err != nil {
|
|
t.Fatalf("failed to establish connection to redis: %v", err)
|
|
}
|
|
|
|
// Decide whether to set or get the profiles by manually
|
|
// changing the following variable (SET|GET).
|
|
action := "GET"
|
|
|
|
switch action {
|
|
case "SET":
|
|
err = db.SetRatingProfileDrv(&ratingPrf)
|
|
if err != nil {
|
|
t.Errorf("SetRatingProfileDrv(%v) failed unexpectedly: %v", ratingPrf, err)
|
|
}
|
|
err = db.SetActionsDrv(actionsKey, actions)
|
|
if err != nil {
|
|
t.Errorf("SetActionsDrv(%q,%v) failed unexpectedly: %v", actionsKey, actions, err)
|
|
}
|
|
err = db.SetAccountDrv(&account)
|
|
if err != nil {
|
|
t.Errorf("SetAccountDrv(%v) failed unexpectedly: %v", account, err)
|
|
}
|
|
err = db.SetFilterDrv(&fltr)
|
|
if err != nil {
|
|
t.Errorf("SetFilterDrv(%v) failed unexpectedly: %v", fltr, err)
|
|
}
|
|
case "GET":
|
|
if got, err := db.GetRatingProfileDrv(ratingPrf.Id); err != nil {
|
|
t.Errorf("GetRatingProfileDrv(%q) failed unexpectedly: %v", ratingPrf.Id, err)
|
|
} else if diff := cmp.Diff(&ratingPrf, got); diff != "" {
|
|
t.Errorf("GetRatingProfileDrv(%q) returned unexpected profile (-want +got): \n%s", ratingPrf.Id, diff)
|
|
}
|
|
|
|
if got, err := db.GetActionsDrv(actionsKey); err != nil {
|
|
t.Errorf("GetActionsDrv(%q) failed unexpectedly: %v", actionsKey, err)
|
|
} else if diff := cmp.Diff(actions, got, cmpopts.IgnoreUnexported(Action{})); diff != "" {
|
|
t.Errorf("GetActionsDrv(%q) returned unexpected profile (-want +got): \n%s", ratingPrf.Id, diff)
|
|
}
|
|
|
|
if got, err := db.GetAccountDrv(account.ID); err != nil {
|
|
t.Errorf("GetAccountDrv(%q) failed unexpectedly: %v", account.ID, err)
|
|
} else if diff := cmp.Diff(&account, got, cmpopts.IgnoreUnexported(Account{})); diff != "" {
|
|
t.Errorf("GetAccountDrv(%q) returned unexpected profile (-want +got): \n%s", ratingPrf.Id, diff)
|
|
}
|
|
|
|
if got, err := db.GetFilterDrv(fltr.Tenant, fltr.ID); err != nil {
|
|
t.Errorf("GetFilterDrv(%q,%q) failed unexpectedly: %v", fltr.Tenant, fltr.ID, err)
|
|
} else if diff := cmp.Diff(&fltr, got, cmpopts.IgnoreUnexported(FilterRule{})); diff != "" {
|
|
t.Errorf("GetFilterDrv(%q) returned unexpected profile (-want +got): \n%s", ratingPrf.Id, diff)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkMsgpackTime(b *testing.B) {
|
|
type NestedStructWithTime struct {
|
|
ID string
|
|
TimeField time.Time
|
|
TimePointerField *time.Time
|
|
}
|
|
type StructWithTime struct {
|
|
ID string
|
|
TimeField time.Time
|
|
StructField NestedStructWithTime
|
|
}
|
|
refTime := time.Now()
|
|
obj := StructWithTime{
|
|
ID: "structWithTime",
|
|
TimeField: time.Now(),
|
|
StructField: NestedStructWithTime{
|
|
ID: "nestedStructWithTime",
|
|
TimeField: time.Now(),
|
|
TimePointerField: &refTime,
|
|
},
|
|
}
|
|
ms, err := NewMarshaler(utils.MsgPack)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
byt, err := ms.Marshal(obj)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
var s StructWithTime
|
|
if err := ms.Unmarshal(byt, &s); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
old version (github.com/cgrates/ugocodec):
|
|
|
|
go test -tags=benchmark -bench=BenchmarkMsgpack -run=^$ -benchtime=1s -count=5 -benchmem
|
|
goos: linux
|
|
goarch: amd64
|
|
pkg: github.com/cgrates/cgrates/general_tests
|
|
cpu: 12th Gen Intel(R) Core(TM) i7-1265U
|
|
BenchmarkMsgpack-3 652118 1976 ns/op 2952 B/op 18 allocs/op
|
|
BenchmarkMsgpack-3 565254 1890 ns/op 2952 B/op 18 allocs/op
|
|
BenchmarkMsgpack-3 640384 1841 ns/op 2952 B/op 18 allocs/op
|
|
BenchmarkMsgpack-3 663924 1855 ns/op 2952 B/op 18 allocs/op
|
|
BenchmarkMsgpack-3 641320 1834 ns/op 2952 B/op 18 allocs/op
|
|
|
|
|
|
new version with legacy option TimeNotBuiltin set to true (current implementation):
|
|
|
|
go test -tags=benchmark -bench=BenchmarkMsgpack -run=^$ -benchtime=1s -count=5 -benchmem
|
|
goos: linux
|
|
goarch: amd64
|
|
pkg: github.com/cgrates/cgrates/general_tests
|
|
cpu: 12th Gen Intel(R) Core(TM) i7-1265U
|
|
BenchmarkMsgpack-3 914578 1356 ns/op 2120 B/op 12 allocs/op
|
|
BenchmarkMsgpack-3 901622 1340 ns/op 2120 B/op 12 allocs/op
|
|
BenchmarkMsgpack-3 899760 1339 ns/op 2120 B/op 12 allocs/op
|
|
BenchmarkMsgpack-3 899694 1335 ns/op 2120 B/op 12 allocs/op
|
|
BenchmarkMsgpack-3 891693 1344 ns/op 2120 B/op 12 allocs/op
|
|
|
|
new version default:
|
|
|
|
go test -tags=benchmark -bench=BenchmarkMsgpack -run=^$ -benchtime=1s -count=5 -benchmem
|
|
goos: linux
|
|
goarch: amd64
|
|
pkg: github.com/cgrates/cgrates/general_tests
|
|
cpu: 12th Gen Intel(R) Core(TM) i7-1265U
|
|
BenchmarkMsgpack-3 980895 1180 ns/op 2072 B/op 9 allocs/op
|
|
BenchmarkMsgpack-3 978346 1181 ns/op 2072 B/op 9 allocs/op
|
|
BenchmarkMsgpack-3 1008806 1209 ns/op 2072 B/op 9 allocs/op
|
|
BenchmarkMsgpack-3 1013218 1192 ns/op 2072 B/op 9 allocs/op
|
|
BenchmarkMsgpack-3 995960 1282 ns/op 2072 B/op 9 allocs/op
|
|
|
|
*/
|