From 8484f92633fc153669e0861370d347ed2454a2f0 Mon Sep 17 00:00:00 2001 From: TeoV Date: Wed, 6 Dec 2017 16:30:13 +0200 Subject: [PATCH] Add test for apier/v1/aliasprofile.go(alias_it_test.go) --- apier/v1/alias_it_test.go | 203 ++++++++++++++++++++++++++++++++++++++ apier/v1/aliasprofile.go | 41 ++------ engine/alias.go | 51 +++++++++- 3 files changed, 259 insertions(+), 36 deletions(-) create mode 100644 apier/v1/alias_it_test.go diff --git a/apier/v1/alias_it_test.go b/apier/v1/alias_it_test.go new file mode 100644 index 000000000..c6c9fcc58 --- /dev/null +++ b/apier/v1/alias_it_test.go @@ -0,0 +1,203 @@ +// +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 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 v1 + +import ( + "net/rpc" + "net/rpc/jsonrpc" + "path" + "reflect" + "testing" + "time" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +var ( + alsPrfCfgPath string + alsPrfCfg *config.CGRConfig + alsPrfRPC *rpc.Client + alsPrfDataDir = "/usr/share/cgrates" + alsPrf *engine.ExternalAliasProfile + alsPrfDelay int + alsPrfConfigDIR string //run tests for specific configuration +) + +var sTestsAlsPrf = []func(t *testing.T){ + testAlsPrfInitCfg, + testAlsPrfInitDataDb, + testAlsPrfResetStorDb, + testAlsPrfStartEngine, + testAlsPrfRPCConn, + testAlsPrfGetAlsPrfBeforeSet, + testAlsPrfSetAlsPrf, + testAlsPrfUpdateAlsPrf, + testAlsPrfRemAlsPrf, + testAlsPrfKillEngine, +} + +//Test start here +func TestAlsPrfITMySql(t *testing.T) { + alsPrfConfigDIR = "tutmysql" + for _, stest := range sTestsAlsPrf { + t.Run(alsPrfConfigDIR, stest) + } +} + +func TestAlsPrfITMongo(t *testing.T) { + alsPrfConfigDIR = "tutmongo" + for _, stest := range sTestsAlsPrf { + t.Run(alsPrfConfigDIR, stest) + } +} + +func testAlsPrfInitCfg(t *testing.T) { + var err error + alsPrfCfgPath = path.Join(alsPrfDataDir, "conf", "samples", alsPrfConfigDIR) + alsPrfCfg, err = config.NewCGRConfigFromFolder(alsPrfCfgPath) + if err != nil { + t.Error(err) + } + alsPrfCfg.DataFolderPath = alsPrfDataDir // Share DataFolderPath through config towards StoreDb for Flush() + config.SetCgrConfig(alsPrfCfg) + switch alsPrfConfigDIR { + case "tutmongo": // Mongo needs more time to reset db, need to investigate + alsPrfDelay = 2000 + default: + alsPrfDelay = 1000 + } +} + +func testAlsPrfInitDataDb(t *testing.T) { + if err := engine.InitDataDb(alsPrfCfg); err != nil { + t.Fatal(err) + } +} + +// Wipe out the cdr database +func testAlsPrfResetStorDb(t *testing.T) { + if err := engine.InitStorDb(alsPrfCfg); err != nil { + t.Fatal(err) + } +} + +// Start CGR Engine +func testAlsPrfStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(alsPrfCfgPath, alsPrfDelay); err != nil { + t.Fatal(err) + } +} + +// Connect rpc client to rater +func testAlsPrfRPCConn(t *testing.T) { + var err error + alsPrfRPC, err = jsonrpc.Dial("tcp", alsPrfCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} + +func testAlsPrfGetAlsPrfBeforeSet(t *testing.T) { + var reply *engine.ExternalAliasProfile + if err := alsPrfRPC.Call("ApierV1.GetAliasProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "ALS1"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +} + +func testAlsPrfSetAlsPrf(t *testing.T) { + alsPrf = &engine.ExternalAliasProfile{ + Tenant: "cgrates.org", + ID: "ALS1", + FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC).Local(), + ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC).Local(), + }, + Aliases: []*engine.AliasEntry{ + &engine.AliasEntry{ + FieldName: "FL1", + Initial: "In1", + Alias: "Al1", + }, + }, + Weight: 20, + } + var result string + if err := alsPrfRPC.Call("ApierV1.SetAliasProfile", alsPrf, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + var reply *engine.ExternalAliasProfile + if err := alsPrfRPC.Call("ApierV1.GetAliasProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "ALS1"}, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(alsPrf, reply) { + t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(alsPrf), utils.ToJSON(reply)) + } +} + +func testAlsPrfUpdateAlsPrf(t *testing.T) { + alsPrf.Aliases = []*engine.AliasEntry{ + &engine.AliasEntry{ + FieldName: "FL1", + Initial: "In1", + Alias: "Al1", + }, + &engine.AliasEntry{ + FieldName: "FL2", + Initial: "In2", + Alias: "Al2", + }, + } + var result string + if err := alsPrfRPC.Call("ApierV1.SetAliasProfile", alsPrf, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + var reply *engine.ExternalAliasProfile + if err := alsPrfRPC.Call("ApierV1.GetAliasProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "ALS1"}, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(alsPrf, reply) { + t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(alsPrf), utils.ToJSON(reply)) + } +} + +func testAlsPrfRemAlsPrf(t *testing.T) { + var resp string + if err := alsPrfRPC.Call("ApierV1.RemAliasProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "ALS1"}, &resp); err != nil { + t.Error(err) + } else if resp != utils.OK { + t.Error("Unexpected reply returned", resp) + } + var reply *engine.ExternalAliasProfile + if err := alsPrfRPC.Call("ApierV1.GetAliasProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "ALS1"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Error(err) + } +} + +func testAlsPrfKillEngine(t *testing.T) { + if err := engine.KillEngine(alsPrfDelay); err != nil { + t.Error(err) + } +} diff --git a/apier/v1/aliasprofile.go b/apier/v1/aliasprofile.go index 96d48e06d..d750ebd0d 100644 --- a/apier/v1/aliasprofile.go +++ b/apier/v1/aliasprofile.go @@ -23,56 +23,29 @@ import ( "github.com/cgrates/cgrates/utils" ) -type ExternalAliasProfile struct { - Tenant string - ID string - FilterIDs []string - ActivationInterval *utils.ActivationInterval // Activation interval - Aliases []*ExternalAliasEntry - Weight float64 -} - -type ExternalAliasEntry struct { - FieldName string - Initial string - Alias string -} - // GetAliasProfile returns an Alias Profile -func (apierV1 *ApierV1) GetAliasProfile(arg utils.TenantID, reply *engine.AliasProfile) error { +func (apierV1 *ApierV1) GetAliasProfile(arg utils.TenantID, reply *engine.ExternalAliasProfile) error { if missing := utils.MissingStructFields(&arg, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing return utils.NewErrMandatoryIeMissing(missing...) } - if alsPrf, err := apierV1.DataManager.GetAliasProfile(arg.Tenant, arg.ID, false, utils.NonTransactional); err != nil { + if alsPrf, err := apierV1.DataManager.GetAliasProfile(arg.Tenant, arg.ID, true, utils.NonTransactional); err != nil { if err.Error() != utils.ErrNotFound.Error() { err = utils.NewErrServerError(err) } return err } else { - *reply = *alsPrf + *reply = *engine.NewExternalAliasProfileFromAliasProfile(alsPrf) } return nil } //SetAliasProfile add a new Alias Profile -func (apierV1 *ApierV1) SetAliasProfile(alsPrf *ExternalAliasProfile, reply *string) error { - if missing := utils.MissingStructFields(alsPrf, []string{"Tenant", "ID"}); len(missing) != 0 { +func (apierV1 *ApierV1) SetAliasProfile(extAls *engine.ExternalAliasProfile, reply *string) error { + if missing := utils.MissingStructFields(extAls, []string{"Tenant", "ID"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } - alsPrfEngine := &engine.AliasProfile{ - Tenant: alsPrf.Tenant, - ID: alsPrf.ID, - Weight: alsPrf.Weight, - FilterIDs: alsPrf.FilterIDs, - ActivationInterval: alsPrf.ActivationInterval, - } - alsMap := make(map[string]map[string]string) - for _, als := range alsPrf.Aliases { - alsMap[als.FieldName] = make(map[string]string) - alsMap[als.FieldName][als.Initial] = als.Alias - } - alsPrfEngine.Aliases = alsMap - if err := apierV1.DataManager.SetAliasProfile(alsPrfEngine); err != nil { + alsPrf := extAls.AsAliasProfile() + if err := apierV1.DataManager.SetAliasProfile(alsPrf); err != nil { return utils.APIErrorHandler(err) } *reply = utils.OK diff --git a/engine/alias.go b/engine/alias.go index f4a79da44..e01871bae 100644 --- a/engine/alias.go +++ b/engine/alias.go @@ -39,8 +39,8 @@ type AliasProfile struct { Weight float64 } -func (tp *AliasProfile) TenantID() string { - return utils.ConcatenatedKey(tp.Tenant, tp.ID) +func (als *AliasProfile) TenantID() string { + return utils.ConcatenatedKey(als.Tenant, als.ID) } func NewAliasService(dm *DataManager, filterS *FilterS, indexedFields []string) (*AliasService, error) { @@ -67,3 +67,50 @@ func (alS *AliasService) Shutdown() (err error) { utils.Logger.Info(fmt.Sprintf("<%s> service shutdown complete", utils.AliasS)) return } + +type ExternalAliasProfile struct { + Tenant string + ID string + FilterIDs []string + ActivationInterval *utils.ActivationInterval // Activation interval + Aliases []*AliasEntry + Weight float64 +} + +func (eap *ExternalAliasProfile) AsAliasProfile() *AliasProfile { + alsPrf := &AliasProfile{ + Tenant: eap.Tenant, + ID: eap.ID, + Weight: eap.Weight, + FilterIDs: eap.FilterIDs, + ActivationInterval: eap.ActivationInterval, + } + alsMap := make(map[string]map[string]string) + for _, als := range eap.Aliases { + alsMap[als.FieldName] = make(map[string]string) + alsMap[als.FieldName][als.Initial] = als.Alias + } + alsPrf.Aliases = alsMap + return alsPrf +} + +func NewExternalAliasProfileFromAliasProfile(alsPrf *AliasProfile) *ExternalAliasProfile { + extals := &ExternalAliasProfile{ + Tenant: alsPrf.Tenant, + ID: alsPrf.ID, + Weight: alsPrf.Weight, + ActivationInterval: alsPrf.ActivationInterval, + FilterIDs: alsPrf.FilterIDs, + } + for key, val := range alsPrf.Aliases { + for key2, val2 := range val { + extals.Aliases = append(extals.Aliases, &AliasEntry{ + FieldName: key, + Initial: key2, + Alias: val2, + }) + } + } + return extals + +}