//go:build integration // +build integration /* 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 */ package engine import ( "reflect" "testing" "time" "github.com/cgrates/birpc/context" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" ) func TestSetGetRemoveConfigSectionsDrvRedis(t *testing.T) { cfg := config.NewDefaultCGRConfig() db, err := NewRedisStorage("127.0.0.1:6379", 10, utils.CGRateSLwr, cfg.DbCfg().DBConns[utils.MetaDefault].Password, cfg.GeneralCfg().DBDataEncoding, cfg.DbCfg().DBConns[utils.MetaDefault].Opts.RedisMaxConns, cfg.DbCfg().DBConns[utils.MetaDefault].Opts.RedisConnectAttempts, utils.EmptyString, false, 0, 0, 0, 0, 0, 150*time.Microsecond, 0, false, utils.EmptyString, utils.EmptyString, utils.EmptyString, nil, nil) if err != nil { t.Error(err) } defer db.Close() sectionIDs := []string{"thresholds", "resources"} expected := make(map[string][]byte) // Try to retrieve the values before setting them (should receive an empty map) if rcv, err := db.GetConfigSectionsDrv(context.Background(), "1234", sectionIDs); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if !reflect.DeepEqual(rcv, expected) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(expected), utils.ToJSON(rcv)) } ms, err := utils.NewMarshaler(utils.JSON) if err != nil { t.Error(err) } thCfg := &config.ThresholdSJsonCfg{ Enabled: utils.BoolPointer(true), Indexed_selects: utils.BoolPointer(true), Store_interval: utils.StringPointer("2s"), String_indexed_fields: &[]string{"req.index11"}, Prefix_indexed_fields: &[]string{"req.index22"}, Suffix_indexed_fields: &[]string{"req.index33"}, Actions_conns: &[]string{"*internal"}, Nested_fields: utils.BoolPointer(true), Opts: &config.ThresholdsOptsJson{ ProfileIDs: []*config.DynamicStringSliceOpt{ { Tenant: "cgrates.org", Values: []string{"value1"}, }, }, ProfileIgnoreFilters: []*config.DynamicInterfaceOpt{ { Tenant: "cgrates.org", Value: "true", }, }, }, } thJsnCfg, err := ms.Marshal(thCfg) if err != nil { t.Error(err) } rsCfg := &config.ResourceSJsonCfg{ Enabled: utils.BoolPointer(true), Indexed_selects: utils.BoolPointer(true), Thresholds_conns: &[]string{"*birpc"}, Store_interval: utils.StringPointer("2s"), String_indexed_fields: &[]string{"*req.index11"}, Prefix_indexed_fields: &[]string{"*req.index22"}, Suffix_indexed_fields: &[]string{"*req.index33"}, Nested_fields: utils.BoolPointer(true), Opts: &config.ResourcesOptsJson{ UsageID: []*config.DynamicInterfaceOpt{ { Value: "usg2", }, }, UsageTTL: []*config.DynamicInterfaceOpt{ { Value: "1m0s", }, }, Units: []*config.DynamicInterfaceOpt{ { Value: "2", }, }, }, } rsJsnCfg, err := ms.Marshal(rsCfg) if err != nil { t.Error(err) } sectData := map[string][]byte{ "thresholds": thJsnCfg, "resources": rsJsnCfg, } if err := db.SetConfigSectionsDrv(context.Background(), "1234", sectData); err != nil { t.Error(err) } if rcv, err := db.GetConfigSectionsDrv(context.Background(), "1234", sectionIDs); err != nil { t.Error(err) } else if !reflect.DeepEqual(rcv, sectData) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(sectData), utils.ToJSON(rcv)) } else { rcvThCfg := &config.ThresholdSJsonCfg{} ms.Unmarshal(rcv["thresholds"], &rcvThCfg) if !reflect.DeepEqual(rcvThCfg, thCfg) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(thCfg), utils.ToJSON(rcvThCfg)) } rcvRsCfg := &config.ResourceSJsonCfg{} ms.Unmarshal(rcv["resources"], &rcvRsCfg) if !reflect.DeepEqual(rcvRsCfg, rsCfg) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(rsCfg), utils.ToJSON(rcvRsCfg)) } } if err := db.RemoveConfigSectionsDrv(context.Background(), "1234", sectionIDs); err != nil { t.Error(err) } if rcv, err := db.GetConfigSectionsDrv(context.Background(), "1234", sectionIDs); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if !reflect.DeepEqual(rcv, expected) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(expected), utils.ToJSON(rcv)) } } func TestSetGetRemoveConfigSectionsDrvMongo(t *testing.T) { cfg := config.NewDefaultCGRConfig() db, err := NewMongoStorage(cfg.DbCfg().DBConns[utils.MetaDefault].Opts.MongoConnScheme, cfg.DbCfg().DBConns[utils.MetaDefault].Host, "27017", "10", cfg.DbCfg().DBConns[utils.MetaDefault].User, cfg.DbCfg().DBConns[utils.MetaDefault].Password, cfg.GeneralCfg().DBDataEncoding, nil, 10*time.Second) if err != nil { t.Error(err) } defer db.Close() sectionIDs := []string{"thresholds", "resources"} // Try to retrieve the values before setting them (should receive an empty map) if rcv, err := db.GetConfigSectionsDrv(context.Background(), "1234", sectionIDs); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if rcv != nil { t.Errorf("expected: <%+v>, \nreceived: <%+v>", nil, utils.ToJSON(rcv)) } ms, err := utils.NewMarshaler(utils.JSON) if err != nil { t.Error(err) } thCfg := &config.ThresholdSJsonCfg{ Enabled: utils.BoolPointer(true), Indexed_selects: utils.BoolPointer(true), Store_interval: utils.StringPointer("2s"), String_indexed_fields: &[]string{"req.index11"}, Prefix_indexed_fields: &[]string{"req.index22"}, Suffix_indexed_fields: &[]string{"req.index33"}, Actions_conns: &[]string{"*internal"}, Nested_fields: utils.BoolPointer(true), Opts: &config.ThresholdsOptsJson{ ProfileIDs: []*config.DynamicStringSliceOpt{ { Tenant: "cgrates.org", Values: []string{"value1"}, }, }, ProfileIgnoreFilters: []*config.DynamicInterfaceOpt{ { Tenant: "cgrates.org", Value: "true", }, }, }, } thJsnCfg, err := ms.Marshal(thCfg) if err != nil { t.Error(err) } rsCfg := &config.ResourceSJsonCfg{ Enabled: utils.BoolPointer(true), Indexed_selects: utils.BoolPointer(true), Thresholds_conns: &[]string{"*birpc"}, Store_interval: utils.StringPointer("2s"), String_indexed_fields: &[]string{"*req.index11"}, Prefix_indexed_fields: &[]string{"*req.index22"}, Suffix_indexed_fields: &[]string{"*req.index33"}, Nested_fields: utils.BoolPointer(true), Opts: &config.ResourcesOptsJson{ UsageID: []*config.DynamicInterfaceOpt{ { Value: "usg2", }, }, UsageTTL: []*config.DynamicInterfaceOpt{ { Value: "1m0s", }, }, Units: []*config.DynamicInterfaceOpt{ { Value: "2", }, }, }, } rsJsnCfg, err := ms.Marshal(rsCfg) if err != nil { t.Error(err) } sectData := map[string][]byte{ "thresholds": thJsnCfg, "resources": rsJsnCfg, } if err := db.SetConfigSectionsDrv(context.Background(), "1234", sectData); err != nil { t.Error(err) } if rcv, err := db.GetConfigSectionsDrv(context.Background(), "1234", sectionIDs); err != nil { t.Error(err) } else if !reflect.DeepEqual(rcv, sectData) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(sectData), utils.ToJSON(rcv)) } else { rcvThCfg := &config.ThresholdSJsonCfg{} ms.Unmarshal(rcv["thresholds"], &rcvThCfg) if !reflect.DeepEqual(rcvThCfg, thCfg) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(thCfg), utils.ToJSON(rcvThCfg)) } rcvRsCfg := &config.ResourceSJsonCfg{} ms.Unmarshal(rcv["resources"], &rcvRsCfg) if !reflect.DeepEqual(rcvRsCfg, rsCfg) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(rsCfg), utils.ToJSON(rcvRsCfg)) } } if err := db.RemoveConfigSectionsDrv(context.Background(), "1234", sectionIDs); err != nil { t.Error(err) } if rcv, err := db.GetConfigSectionsDrv(context.Background(), "1234", sectionIDs); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if rcv != nil { t.Errorf("expected: <%+v>, \nreceived: <%+v>", nil, utils.ToJSON(rcv)) } } func TestSetGetRemoveConfigSectionsDrvInternal(t *testing.T) { db, _ := NewInternalDB(nil, nil, nil, nil) defer db.Close() sectionIDs := []string{"thresholds", "resources"} expected := make(map[string][]byte) // Try to retrieve the values before setting them (should receive an empty map) if rcv, err := db.GetConfigSectionsDrv(context.Background(), "1234", sectionIDs); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if !reflect.DeepEqual(rcv, expected) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(expected), utils.ToJSON(rcv)) } ms, err := utils.NewMarshaler(utils.JSON) if err != nil { t.Error(err) } thCfg := &config.ThresholdSJsonCfg{ Enabled: utils.BoolPointer(true), Indexed_selects: utils.BoolPointer(true), Store_interval: utils.StringPointer("2s"), String_indexed_fields: &[]string{"req.index11"}, Prefix_indexed_fields: &[]string{"req.index22"}, Suffix_indexed_fields: &[]string{"req.index33"}, Actions_conns: &[]string{"*internal"}, Nested_fields: utils.BoolPointer(true), Opts: &config.ThresholdsOptsJson{ ProfileIDs: []*config.DynamicStringSliceOpt{ { Tenant: "cgrates.org", Values: []string{"value1"}, }, }, ProfileIgnoreFilters: []*config.DynamicInterfaceOpt{ { Tenant: "cgrates.org", Value: "true", }, }, }, } thJsnCfg, err := ms.Marshal(thCfg) if err != nil { t.Error(err) } rsCfg := &config.ResourceSJsonCfg{ Enabled: utils.BoolPointer(true), Indexed_selects: utils.BoolPointer(true), Thresholds_conns: &[]string{"*birpc"}, Store_interval: utils.StringPointer("2s"), String_indexed_fields: &[]string{"*req.index11"}, Prefix_indexed_fields: &[]string{"*req.index22"}, Suffix_indexed_fields: &[]string{"*req.index33"}, Nested_fields: utils.BoolPointer(true), Opts: &config.ResourcesOptsJson{ UsageID: []*config.DynamicInterfaceOpt{ { Value: "usg2", }, }, UsageTTL: []*config.DynamicInterfaceOpt{ { Value: "1m0s", }, }, Units: []*config.DynamicInterfaceOpt{ { Value: "2", }, }, }, } rsJsnCfg, err := ms.Marshal(rsCfg) if err != nil { t.Error(err) } sectData := map[string][]byte{ "thresholds": thJsnCfg, "resources": rsJsnCfg, } if err := db.SetConfigSectionsDrv(context.Background(), "1234", sectData); err != nil { t.Error(err) } if rcv, err := db.GetConfigSectionsDrv(context.Background(), "1234", sectionIDs); err != nil { t.Error(err) } else if !reflect.DeepEqual(rcv, sectData) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(sectData), utils.ToJSON(rcv)) } else { rcvThCfg := &config.ThresholdSJsonCfg{} ms.Unmarshal(rcv["thresholds"], &rcvThCfg) if !reflect.DeepEqual(rcvThCfg, thCfg) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(thCfg), utils.ToJSON(rcvThCfg)) } rcvRsCfg := &config.ResourceSJsonCfg{} ms.Unmarshal(rcv["resources"], &rcvRsCfg) if !reflect.DeepEqual(rcvRsCfg, rsCfg) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(rsCfg), utils.ToJSON(rcvRsCfg)) } } if err := db.RemoveConfigSectionsDrv(context.Background(), "1234", sectionIDs); err != nil { t.Error(err) } if rcv, err := db.GetConfigSectionsDrv(context.Background(), "1234", sectionIDs); err == nil || err.Error() != utils.ErrNotFound.Error() { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if !reflect.DeepEqual(rcv, expected) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(expected), utils.ToJSON(rcv)) } }