Updated migrator tests

This commit is contained in:
Tripon Alexandru-Ionut
2019-05-28 15:00:39 +03:00
committed by Dan Christian Bogos
parent 570db82c35
commit d1c7ca3369
27 changed files with 1490 additions and 33 deletions

View File

@@ -26,8 +26,22 @@ import (
)
func TestV1ActionPlanAsActionPlan(t *testing.T) {
v1ap := &v1ActionPlan{Id: "test", AccountIds: []string{"one"}, Timing: &engine.RateInterval{Timing: new(engine.RITiming)}}
ap := &engine.ActionPlan{Id: "test", AccountIDs: utils.StringMap{"one": true}, ActionTimings: []*engine.ActionTiming{&engine.ActionTiming{Timing: &engine.RateInterval{Timing: new(engine.RITiming)}}}}
v1ap := &v1ActionPlan{
Id: "test",
AccountIds: []string{"one"},
Timing: &engine.RateInterval{Timing: new(engine.RITiming)},
}
ap := &engine.ActionPlan{
Id: "test",
AccountIDs: utils.StringMap{"one": true},
ActionTimings: []*engine.ActionTiming{
&engine.ActionTiming{
Timing: &engine.RateInterval{
Timing: new(engine.RITiming),
},
},
},
}
newap := v1ap.AsActionPlan()
if ap.Id != newap.Id || !reflect.DeepEqual(ap.AccountIDs, newap.AccountIDs) {
t.Errorf("Expecting: %+v, received: %+v", *ap, newap)

View File

@@ -21,12 +21,66 @@ import (
"reflect"
"testing"
"github.com/cgrates/cgrates/utils"
"github.com/cgrates/cgrates/engine"
)
func TestV1ActionsAsActions(t *testing.T) {
v1act := &v1Action{Id: "", ActionType: "", BalanceType: "", Direction: "INBOUND", ExtraParameters: "", ExpirationString: "", Balance: &v1Balance{}}
act := &engine.Action{Id: "", ActionType: "", ExtraParameters: "", ExpirationString: "", Weight: 0.00, Balance: &engine.BalanceFilter{}}
v1act := &v1Action{
Id: "",
ActionType: "",
BalanceType: "",
Direction: "INBOUND",
ExtraParameters: "",
ExpirationString: "",
Balance: &v1Balance{},
}
act := &engine.Action{
Id: "",
ActionType: "",
ExtraParameters: "",
ExpirationString: "",
Weight: 0.00,
Balance: &engine.BalanceFilter{},
}
newact := v1act.AsAction()
if !reflect.DeepEqual(act, newact) {
t.Errorf("Expecting: %+v, received: %+v", act, newact)
}
}
func TestV1ActionsAsActions2(t *testing.T) {
v1act := &v1Action{
Id: "ID",
ActionType: "*log",
BalanceType: utils.MONETARY,
ExtraParameters: "",
ExpirationString: "",
Balance: &v1Balance{
Uuid: "UUID1",
Id: utils.MetaDefault,
Value: 10,
Weight: 30,
Category: utils.CALL,
},
}
act := &engine.Action{
Id: "ID",
ActionType: "*log",
ExtraParameters: "",
ExpirationString: "",
Weight: 0.00,
Balance: &engine.BalanceFilter{
Uuid: utils.StringPointer("UUID1"),
ID: utils.StringPointer(utils.MetaDefault),
Type: utils.StringPointer(utils.MONETARY),
Value: &utils.ValueFormula{Static: 10},
Weight: utils.Float64Pointer(30),
Categories: utils.StringMapPointer(utils.ParseStringMap(utils.CALL)),
},
}
newact := v1act.AsAction()
if !reflect.DeepEqual(act, newact) {
t.Errorf("Expecting: %+v, received: %+v", act, newact)

View File

@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package migrator
/*
import (
//"flag"
"log"
@@ -138,23 +137,25 @@ func TestActionTriggerITMoveEncoding2(t *testing.T) {
}
func testActTrgITConnect(t *testing.T) {
dataDBIn, err := NewMigratorDataDB(actTrgCfgIn.DataDbType,
actTrgCfgIn.DataDbHost, actTrgCfgIn.DataDbPort, actTrgCfgIn.DataDbName,
actTrgCfgIn.DataDbUser, actTrgCfgIn.DataDbPass, actTrgCfgIn.DBDataEncoding,
config.CgrConfig().CacheCfg(), *loadHistorySize)
dataDBIn, err := NewMigratorDataDB(actTrgCfgIn.DataDbCfg().DataDbType,
actTrgCfgIn.DataDbCfg().DataDbHost, actTrgCfgIn.DataDbCfg().DataDbPort,
actTrgCfgIn.DataDbCfg().DataDbName, actTrgCfgIn.DataDbCfg().DataDbUser,
actTrgCfgIn.DataDbCfg().DataDbPass, actTrgCfgIn.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
dataDBOut, err := NewMigratorDataDB(actTrgCfgOut.DataDbType,
actTrgCfgOut.DataDbHost, actTrgCfgOut.DataDbPort, actTrgCfgOut.DataDbName,
actTrgCfgOut.DataDbUser, actTrgCfgOut.DataDbPass, actTrgCfgOut.DBDataEncoding,
config.CgrConfig().CacheCfg(), *loadHistorySize)
dataDBOut, err := NewMigratorDataDB(actTrgCfgOut.DataDbCfg().DataDbType,
actTrgCfgOut.DataDbCfg().DataDbHost, actTrgCfgOut.DataDbCfg().DataDbPort,
actTrgCfgOut.DataDbCfg().DataDbName, actTrgCfgOut.DataDbCfg().DataDbUser,
actTrgCfgOut.DataDbCfg().DataDbPass, actTrgCfgOut.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
actTrgMigrator, err = NewMigrator(dataDBIn, dataDBOut,
nil, nil,
false, false, false)
false, false, false, false)
if err != nil {
log.Fatal(err)
}
@@ -162,6 +163,7 @@ func testActTrgITConnect(t *testing.T) {
func testActTrgITFlush(t *testing.T) {
actTrgMigrator.dmOut.DataManager().DataDB().Flush("")
actTrgMigrator.dmIN.DataManager().DataDB().Flush("")
if err := engine.SetDBVersions(actTrgMigrator.dmOut.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
@@ -185,10 +187,8 @@ func testActTrgITMigrateAndMove(t *testing.T) {
&engine.ActionTrigger{
ID: "Test",
Balance: &engine.BalanceFilter{
Timings: []*engine.RITiming{},
ExpirationDate: utils.TimePointer(tim),
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ExpirationDate: tim,
LastExecutionTime: tim,
@@ -202,7 +202,7 @@ func testActTrgITMigrateAndMove(t *testing.T) {
switch actActionTrigger {
case utils.Migrate:
err := actTrgMigrator.dmIN.setV2ActionTrigger(v1actTrg)
err := actTrgMigrator.dmIN.setV1ActionTriggers(v1actTrg)
if err != nil {
t.Error("Error when setting v1 ActionTriggers ", err.Error())
}
@@ -220,7 +220,7 @@ func testActTrgITMigrateAndMove(t *testing.T) {
t.Error("Error when getting ActionTriggers ", err.Error())
}
if !reflect.DeepEqual(actTrg, result) {
t.Errorf("Expecting: %+v, received: %+v", actTrg, result)
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(actTrg), utils.ToJSON(result))
}
// utils.tojson si verificat
case utils.Move:
@@ -228,7 +228,7 @@ func testActTrgITMigrateAndMove(t *testing.T) {
t.Error("Error when setting ActionTriggers ", err.Error())
}
currentVersion := engine.CurrentDataDBVersions()
err := actTrgMigrator.dmOut.DataManager().DataDB().SetVersions(currentVersion, false)
err := actTrgMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false)
if err != nil {
t.Error("Error when setting version for ActionTriggers ", err.Error())
}
@@ -245,4 +245,3 @@ func testActTrgITMigrateAndMove(t *testing.T) {
}
}
}
*/

View File

@@ -27,7 +27,7 @@ import (
"github.com/cgrates/cgrates/utils"
)
func Testv1AttributeProfileAsAttributeProfile(t *testing.T) {
func TestV1AttributeProfileAsAttributeProfile(t *testing.T) {
var cloneExpTime time.Time
expTime := time.Now().Add(time.Duration(20 * time.Minute))
if err := utils.Clone(expTime, &cloneExpTime); err != nil {
@@ -66,6 +66,7 @@ func Testv1AttributeProfileAsAttributeProfile(t *testing.T) {
&engine.Attribute{
FilterIDs: []string{"*string:FL1:In1"},
FieldName: "FL1",
Type: utils.MetaVariable,
Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP),
},
},
@@ -77,3 +78,96 @@ func Testv1AttributeProfileAsAttributeProfile(t *testing.T) {
t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(attrPrf), utils.ToJSON(ap))
}
}
func TestV2AttributeProfileAsAttributeProfile(t *testing.T) {
cloneExpTime := time.Now().Add(time.Duration(20 * time.Minute))
v2Attribute := v2AttributeProfile{
Tenant: "cgrates.org",
ID: "attributeprofile1",
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"filter1"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
ExpiryTime: cloneExpTime,
},
Attributes: []*v2Attribute{
&v2Attribute{
FieldName: "FL1",
Initial: "In1",
Substitute: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP),
Append: true,
},
},
Weight: 20,
}
attrPrf := &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "attributeprofile1",
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"filter1"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
ExpiryTime: cloneExpTime,
},
Attributes: []*engine.Attribute{
&engine.Attribute{
FilterIDs: []string{"*string:FL1:In1"},
FieldName: "FL1",
Type: utils.MetaVariable,
Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP),
},
},
Weight: 20,
}
if ap, err := v2Attribute.AsAttributeProfile(); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(attrPrf, ap) {
t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(attrPrf), utils.ToJSON(ap))
}
}
func TestV3AttributeProfileAsAttributeProfile(t *testing.T) {
cloneExpTime := time.Now().Add(time.Duration(20 * time.Minute))
v3Attribute := v3AttributeProfile{
Tenant: "cgrates.org",
ID: "attributeprofile1",
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"filter1"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
ExpiryTime: cloneExpTime,
},
Attributes: []*v3Attribute{
&v3Attribute{
FilterIDs: []string{"*string:FL1:In1"},
FieldName: "FL1",
Substitute: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP),
},
},
Weight: 20,
}
attrPrf := &engine.AttributeProfile{
Tenant: "cgrates.org",
ID: "attributeprofile1",
Contexts: []string{utils.MetaSessionS},
FilterIDs: []string{"filter1"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
ExpiryTime: cloneExpTime,
},
Attributes: []*engine.Attribute{
&engine.Attribute{
FilterIDs: []string{"*string:FL1:In1"},
FieldName: "FL1",
Type: utils.MetaVariable,
Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP),
},
},
Weight: 20,
}
if ap, err := v3Attribute.AsAttributeProfile(); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(attrPrf, ap) {
t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(attrPrf), utils.ToJSON(ap))
}
}

View File

@@ -133,15 +133,25 @@ func testCdrITMigrateAndMove(t *testing.T) {
TOR: utils.VOICE,
}
v1Cdr := &v1Cdrs{
CGRID: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()),
OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf", OriginHost: "192.168.1.1",
Source: utils.UNIT_TEST, RequestType: utils.META_RATED, Tenant: "cgrates.org",
Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC),
AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
RunID: utils.DEFAULT_RUNID, Usage: time.Duration(10),
CGRID: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()),
OrderID: 123,
ToR: utils.VOICE,
OriginID: "dsafdsaf",
OriginHost: "192.168.1.1",
Source: utils.UNIT_TEST,
RequestType: utils.META_RATED,
Tenant: "cgrates.org",
Category: "call",
Account: "1001",
Subject: "1001",
Destination: "1002",
SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC),
AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
RunID: utils.DEFAULT_RUNID,
Usage: time.Duration(10),
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
Cost: 1.01, Rated: true,
Cost: 1.01,
Rated: true,
CostDetails: cc,
}
var err error

View File

@@ -46,6 +46,10 @@ func (m *Migrator) migrateCurrentCharger() (err error) {
if err := m.dmOut.DataManager().SetChargerProfile(cpp, true); err != nil {
return err
}
if err := m.dmIN.DataManager().RemoveChargerProfile(tenant,
idg, utils.NonTransactional, false); err != nil {
return err
}
m.stats[utils.Chargers] += 1
}
return

View File

@@ -19,3 +19,202 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package migrator
import (
"log"
"path"
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
var (
chrgPathIn string
chrgPathOut string
chrgCfgIn *config.CGRConfig
chrgCfgOut *config.CGRConfig
chrgMigrator *Migrator
chrgAction string
)
var sTestsChrgIT = []func(t *testing.T){
testChrgITConnect,
testChrgITFlush,
testChrgITMigrateAndMove,
}
func TestChargersITMove1(t *testing.T) {
var err error
chrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
chrgCfgIn, err = config.NewCGRConfigFromPath(chrgPathIn)
if err != nil {
t.Fatal(err)
}
chrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
chrgCfgOut, err = config.NewCGRConfigFromPath(chrgPathOut)
if err != nil {
t.Fatal(err)
}
chrgAction = utils.Move
for _, stest := range sTestsChrgIT {
t.Run("TestChargersITMove", stest)
}
}
func TestChargersITMove2(t *testing.T) {
var err error
chrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
chrgCfgIn, err = config.NewCGRConfigFromPath(chrgPathIn)
if err != nil {
t.Fatal(err)
}
chrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
chrgCfgOut, err = config.NewCGRConfigFromPath(chrgPathOut)
if err != nil {
t.Fatal(err)
}
chrgAction = utils.Move
for _, stest := range sTestsChrgIT {
t.Run("TestChargersITMove", stest)
}
}
func TestChargersITMoveEncoding(t *testing.T) {
var err error
chrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
chrgCfgIn, err = config.NewCGRConfigFromPath(chrgPathIn)
if err != nil {
t.Fatal(err)
}
chrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
chrgCfgOut, err = config.NewCGRConfigFromPath(chrgPathOut)
if err != nil {
t.Fatal(err)
}
chrgAction = utils.Move
for _, stest := range sTestsChrgIT {
t.Run("TestChargersITMoveEncoding", stest)
}
}
func TestChargersITMoveEncoding2(t *testing.T) {
var err error
chrgPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
chrgCfgIn, err = config.NewCGRConfigFromPath(chrgPathIn)
if err != nil {
t.Fatal(err)
}
chrgPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
chrgCfgOut, err = config.NewCGRConfigFromPath(chrgPathOut)
if err != nil {
t.Fatal(err)
}
chrgAction = utils.Move
for _, stest := range sTestsChrgIT {
t.Run("TestChargersITMoveEncoding2", stest)
}
}
func testChrgITConnect(t *testing.T) {
dataDBIn, err := NewMigratorDataDB(chrgCfgIn.DataDbCfg().DataDbType,
chrgCfgIn.DataDbCfg().DataDbHost, chrgCfgIn.DataDbCfg().DataDbPort,
chrgCfgIn.DataDbCfg().DataDbName, chrgCfgIn.DataDbCfg().DataDbUser,
chrgCfgIn.DataDbCfg().DataDbPass, chrgCfgIn.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
dataDBOut, err := NewMigratorDataDB(chrgCfgOut.DataDbCfg().DataDbType,
chrgCfgOut.DataDbCfg().DataDbHost, chrgCfgOut.DataDbCfg().DataDbPort,
chrgCfgOut.DataDbCfg().DataDbName, chrgCfgOut.DataDbCfg().DataDbUser,
chrgCfgOut.DataDbCfg().DataDbPass, chrgCfgOut.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
chrgMigrator, err = NewMigrator(dataDBIn, dataDBOut,
nil, nil,
false, false, false, false)
if err != nil {
log.Fatal(err)
}
}
func testChrgITFlush(t *testing.T) {
if err := chrgMigrator.dmOut.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := chrgMigrator.dmOut.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(chrgMigrator.dmOut.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
if err := chrgMigrator.dmIN.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := chrgMigrator.dmIN.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(chrgMigrator.dmIN.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
}
func testChrgITMigrateAndMove(t *testing.T) {
chrgPrf := &engine.ChargerProfile{
Tenant: "cgrates.org",
ID: "CHRG_1",
FilterIDs: []string{"*string:Accont:1001"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
},
AttributeIDs: []string{"ATTR_1"},
Weight: 20,
}
switch chrgAction {
case utils.Migrate: // for the momment only one version of chargers exists
case utils.Move:
if err := chrgMigrator.dmIN.DataManager().SetChargerProfile(chrgPrf, false); err != nil {
t.Error(err)
}
currentVersion := engine.CurrentDataDBVersions()
err := chrgMigrator.dmOut.DataManager().DataDB().SetVersions(currentVersion, false)
if err != nil {
t.Error("Error when setting version for Chargers ", err.Error())
}
_, err = chrgMigrator.dmOut.DataManager().GetChargerProfile("cgrates.org",
"CHRG_1", false, false, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
err, _ = chrgMigrator.Migrate([]string{utils.MetaChargers})
if err != nil {
t.Error("Error when migrating Chargers ", err.Error())
}
result, err := chrgMigrator.dmOut.DataManager().GetChargerProfile("cgrates.org",
"CHRG_1", false, false, utils.NonTransactional)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(result, chrgPrf) {
t.Errorf("Expecting: %+v, received: %+v", chrgPrf, result)
}
result, err = chrgMigrator.dmIN.DataManager().GetChargerProfile("cgrates.org",
"CHRG_1", false, false, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
}
}

View File

@@ -181,9 +181,22 @@ func testDspITMigrateAndMove(t *testing.T) {
Strategy: utils.MetaRandom,
Weight: 20,
}
dspHost := &engine.DispatcherHost{
Tenant: "cgrates.org",
ID: "ALL",
Conns: []*config.RemoteHost{
&config.RemoteHost{
Address: "127.0.0.1",
Transport: utils.MetaJSONrpc,
},
},
}
if err := dspMigrator.dmIN.DataManager().SetDispatcherProfile(dspPrf, false); err != nil {
t.Error(err)
}
if err := dspMigrator.dmIN.DataManager().SetDispatcherHost(dspHost); err != nil {
t.Error(err)
}
currentVersion := engine.CurrentDataDBVersions()
err := dspMigrator.dmOut.DataManager().DataDB().SetVersions(currentVersion, false)
if err != nil {
@@ -213,4 +226,18 @@ func testDspITMigrateAndMove(t *testing.T) {
if err != utils.ErrNotFound {
t.Error(err)
}
resultHost, err := dspMigrator.dmOut.DataManager().GetDispatcherHost("cgrates.org",
"ALL", false, false, utils.NonTransactional)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(resultHost, dspHost) {
t.Errorf("Expecting: %+v, received: %+v", dspHost, resultHost)
}
resultHost, err = dspMigrator.dmIN.DataManager().GetDispatcherHost("cgrates.org",
"ALL", false, false, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
}

View File

@@ -343,3 +343,19 @@ func (m *Migrator) ensureIndexesStorDB(cols ...string) error {
mgo := m.storDBOut.StorDB().(*engine.MongoStorage)
return mgo.EnsureIndexes(cols...)
}
// closes all opened DBs
func (m *Migrator) Close() {
if m.dmIN != nil {
m.dmIN.close()
}
if m.dmOut != nil {
m.dmOut.close()
}
if m.storDBIn != nil {
m.storDBIn.close()
}
if m.storDBOut != nil {
m.storDBOut.close()
}
}

View File

@@ -63,4 +63,5 @@ type MigratorDataDB interface {
remV3AttributeProfile(tenant, id string) (err error)
DataManager() *engine.DataManager
close()
}

View File

@@ -31,4 +31,5 @@ type MigratorStorDB interface {
setV2SMCost(v2Cost *v2SessionsCost) (err error)
remV2SMCost(v2Cost *v2SessionsCost) (err error)
StorDB() engine.StorDB
close()
}

View File

@@ -44,6 +44,9 @@ func (m *Migrator) migrateCurrentRatingPlans() (err error) {
if err := m.dmOut.DataManager().SetRatingPlan(rp, utils.NonTransactional); err != nil {
return err
}
if err := m.dmIN.DataManager().RemoveRatingPlan(idg, utils.NonTransactional); err != nil {
return err
}
m.stats[utils.RatingPlan] += 1
}
return

View File

@@ -0,0 +1,218 @@
// +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 <http://www.gnu.org/licenses/>
*/
package migrator
import (
"log"
"path"
"reflect"
"testing"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
var (
rtplPathIn string
rtplPathOut string
rtplCfgIn *config.CGRConfig
rtplCfgOut *config.CGRConfig
rtplMigrator *Migrator
rtplAction string
)
var sTestsRtPlIT = []func(t *testing.T){
testRtPlITConnect,
testRtPlITFlush,
testRtPlITMigrateAndMove,
}
func TestRatingPlanITMove1(t *testing.T) {
var err error
rtplPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
rtplCfgIn, err = config.NewCGRConfigFromPath(rtplPathIn)
if err != nil {
t.Fatal(err)
}
rtplPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
rtplCfgOut, err = config.NewCGRConfigFromPath(rtplPathOut)
if err != nil {
t.Fatal(err)
}
rtplAction = utils.Move
for _, stest := range sTestsRtPlIT {
t.Run("TestRatingPlanITMove", stest)
}
}
func TestRatingPlanITMove2(t *testing.T) {
var err error
rtplPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
rtplCfgIn, err = config.NewCGRConfigFromPath(rtplPathIn)
if err != nil {
t.Fatal(err)
}
rtplPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
rtplCfgOut, err = config.NewCGRConfigFromPath(rtplPathOut)
if err != nil {
t.Fatal(err)
}
rtplAction = utils.Move
for _, stest := range sTestsRtPlIT {
t.Run("TestRatingPlanITMove", stest)
}
}
func TestRatingPlanITMoveEncoding(t *testing.T) {
var err error
rtplPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
rtplCfgIn, err = config.NewCGRConfigFromPath(rtplPathIn)
if err != nil {
t.Fatal(err)
}
rtplPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
rtplCfgOut, err = config.NewCGRConfigFromPath(rtplPathOut)
if err != nil {
t.Fatal(err)
}
rtplAction = utils.Move
for _, stest := range sTestsRtPlIT {
t.Run("TestRatingPlanITMoveEncoding", stest)
}
}
func TestRatingPlanITMoveEncoding2(t *testing.T) {
var err error
rtplPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
rtplCfgIn, err = config.NewCGRConfigFromPath(rtplPathIn)
if err != nil {
t.Fatal(err)
}
rtplPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
rtplCfgOut, err = config.NewCGRConfigFromPath(rtplPathOut)
if err != nil {
t.Fatal(err)
}
rtplAction = utils.Move
for _, stest := range sTestsRtPlIT {
t.Run("TestRatingPlanITMoveEncoding2", stest)
}
}
func testRtPlITConnect(t *testing.T) {
dataDBIn, err := NewMigratorDataDB(rtplCfgIn.DataDbCfg().DataDbType,
rtplCfgIn.DataDbCfg().DataDbHost, rtplCfgIn.DataDbCfg().DataDbPort,
rtplCfgIn.DataDbCfg().DataDbName, rtplCfgIn.DataDbCfg().DataDbUser,
rtplCfgIn.DataDbCfg().DataDbPass, rtplCfgIn.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
dataDBOut, err := NewMigratorDataDB(rtplCfgOut.DataDbCfg().DataDbType,
rtplCfgOut.DataDbCfg().DataDbHost, rtplCfgOut.DataDbCfg().DataDbPort,
rtplCfgOut.DataDbCfg().DataDbName, rtplCfgOut.DataDbCfg().DataDbUser,
rtplCfgOut.DataDbCfg().DataDbPass, rtplCfgOut.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
rtplMigrator, err = NewMigrator(dataDBIn, dataDBOut,
nil, nil,
false, false, false, false)
if err != nil {
log.Fatal(err)
}
}
func testRtPlITFlush(t *testing.T) {
if err := rtplMigrator.dmOut.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := rtplMigrator.dmOut.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(rtplMigrator.dmOut.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
if err := rtplMigrator.dmIN.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := rtplMigrator.dmIN.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(rtplMigrator.dmIN.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
}
func testRtPlITMigrateAndMove(t *testing.T) {
rtplPlan := &engine.RatingPlan{
Id: "RT_PLAN1",
Timings: map[string]*engine.RITiming{},
Ratings: map[string]*engine.RIRate{
"asjkilj": &engine.RIRate{
ConnectFee: 10,
RoundingMethod: utils.ROUNDING_UP,
RoundingDecimals: 1,
MaxCost: 10,
},
},
DestinationRates: map[string]engine.RPRateList{},
}
switch rtplAction {
case utils.Migrate: // for the momment only one version of rating plans exists
case utils.Move:
if err := rtplMigrator.dmIN.DataManager().SetRatingPlan(rtplPlan, utils.NonTransactional); err != nil {
t.Error(err)
}
currentVersion := engine.CurrentDataDBVersions()
err := rtplMigrator.dmOut.DataManager().DataDB().SetVersions(currentVersion, false)
if err != nil {
t.Error("Error when setting version for RatingPlan ", err.Error())
}
_, err = rtplMigrator.dmOut.DataManager().GetRatingPlan("RT_PLAN1", true, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
err, _ = rtplMigrator.Migrate([]string{utils.MetaRatingPlans})
if err != nil {
t.Error("Error when migrating RatingPlan ", err.Error())
}
result, err := rtplMigrator.dmOut.DataManager().GetRatingPlan("RT_PLAN1", true, utils.NonTransactional)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(result, rtplPlan) {
t.Errorf("Expecting: %+v, received: %+v", rtplPlan, result)
}
result, err = rtplMigrator.dmIN.DataManager().GetRatingPlan("RT_PLAN1", true, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
}
}

View File

@@ -44,6 +44,9 @@ func (m *Migrator) migrateCurrentRatingProfiles() (err error) {
if err := m.dmOut.DataManager().SetRatingProfile(rp, utils.NonTransactional); err != nil {
return err
}
if err := m.dmIN.DataManager().RemoveRatingProfile(idg, utils.NonTransactional); err != nil {
return err
}
m.stats[utils.RatingProfile] += 1
}
return

View File

@@ -0,0 +1,220 @@
// +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 <http://www.gnu.org/licenses/>
*/
package migrator
import (
"log"
"path"
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
var (
rtprflPathIn string
rtprflPathOut string
rtprflCfgIn *config.CGRConfig
rtprflCfgOut *config.CGRConfig
rtprflMigrator *Migrator
rtprflAction string
)
var sTestsRtPrfIT = []func(t *testing.T){
testRtPrfITConnect,
testRtPrfITFlush,
testRtPrfITMigrateAndMove,
}
func TestRatingProfileITMove1(t *testing.T) {
var err error
rtprflPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
rtprflCfgIn, err = config.NewCGRConfigFromPath(rtprflPathIn)
if err != nil {
t.Fatal(err)
}
rtprflPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
rtprflCfgOut, err = config.NewCGRConfigFromPath(rtprflPathOut)
if err != nil {
t.Fatal(err)
}
rtprflAction = utils.Move
for _, stest := range sTestsRtPrfIT {
t.Run("TestRatingProfileITMove", stest)
}
rtprflMigrator.Close()
}
func TestRatingProfileITMove2(t *testing.T) {
var err error
rtprflPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
rtprflCfgIn, err = config.NewCGRConfigFromPath(rtprflPathIn)
if err != nil {
t.Fatal(err)
}
rtprflPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
rtprflCfgOut, err = config.NewCGRConfigFromPath(rtprflPathOut)
if err != nil {
t.Fatal(err)
}
rtprflAction = utils.Move
for _, stest := range sTestsRtPrfIT {
t.Run("TestRatingProfileITMove", stest)
}
rtprflMigrator.Close()
}
func TestRatingProfileITMoveEncoding(t *testing.T) {
var err error
rtprflPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
rtprflCfgIn, err = config.NewCGRConfigFromPath(rtprflPathIn)
if err != nil {
t.Fatal(err)
}
rtprflPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
rtprflCfgOut, err = config.NewCGRConfigFromPath(rtprflPathOut)
if err != nil {
t.Fatal(err)
}
rtprflAction = utils.Move
for _, stest := range sTestsRtPrfIT {
t.Run("TestRatingProfileITMoveEncoding", stest)
}
rtprflMigrator.Close()
}
func TestRatingProfileITMoveEncoding2(t *testing.T) {
var err error
rtprflPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
rtprflCfgIn, err = config.NewCGRConfigFromPath(rtprflPathIn)
if err != nil {
t.Fatal(err)
}
rtprflPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
rtprflCfgOut, err = config.NewCGRConfigFromPath(rtprflPathOut)
if err != nil {
t.Fatal(err)
}
rtprflAction = utils.Move
for _, stest := range sTestsRtPrfIT {
t.Run("TestRatingProfileITMoveEncoding2", stest)
}
rtprflMigrator.Close()
}
func testRtPrfITConnect(t *testing.T) {
dataDBIn, err := NewMigratorDataDB(rtprflCfgIn.DataDbCfg().DataDbType,
rtprflCfgIn.DataDbCfg().DataDbHost, rtprflCfgIn.DataDbCfg().DataDbPort,
rtprflCfgIn.DataDbCfg().DataDbName, rtprflCfgIn.DataDbCfg().DataDbUser,
rtprflCfgIn.DataDbCfg().DataDbPass, rtprflCfgIn.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
dataDBOut, err := NewMigratorDataDB(rtprflCfgOut.DataDbCfg().DataDbType,
rtprflCfgOut.DataDbCfg().DataDbHost, rtprflCfgOut.DataDbCfg().DataDbPort,
rtprflCfgOut.DataDbCfg().DataDbName, rtprflCfgOut.DataDbCfg().DataDbUser,
rtprflCfgOut.DataDbCfg().DataDbPass, rtprflCfgOut.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
rtprflMigrator, err = NewMigrator(dataDBIn, dataDBOut,
nil, nil,
false, false, false, false)
if err != nil {
log.Fatal(err)
}
}
func testRtPrfITFlush(t *testing.T) {
if err := rtprflMigrator.dmOut.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := rtprflMigrator.dmOut.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(rtprflMigrator.dmOut.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
if err := rtprflMigrator.dmIN.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := rtprflMigrator.dmIN.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(rtprflMigrator.dmIN.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
}
func testRtPrfITMigrateAndMove(t *testing.T) {
rtprfl := &engine.RatingProfile{
Id: "RT_Profile",
RatingPlanActivations: engine.RatingPlanActivations{
&engine.RatingPlanActivation{
ActivationTime: time.Now().Round(time.Second).UTC(),
RatingPlanId: "RP_PLAN1",
FallbackKeys: []string{"1001"},
},
},
}
switch rtprflAction {
case utils.Migrate: // for the momment only one version of rating plans exists
case utils.Move:
if err := rtprflMigrator.dmIN.DataManager().SetRatingProfile(rtprfl, utils.NonTransactional); err != nil {
t.Error(err)
}
currentVersion := engine.CurrentDataDBVersions()
err := rtprflMigrator.dmOut.DataManager().DataDB().SetVersions(currentVersion, false)
if err != nil {
t.Error("Error when setting version for RatingProfile ", err.Error())
}
_, err = rtprflMigrator.dmOut.DataManager().GetRatingProfile("RT_Profile", true, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
err, _ = rtprflMigrator.Migrate([]string{utils.MetaRatingProfiles})
if err != nil {
t.Error("Error when migrating RatingProfile ", err.Error())
}
result, err := rtprflMigrator.dmOut.DataManager().GetRatingProfile("RT_Profile", true, utils.NonTransactional)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(result, rtprfl) {
t.Errorf("Expecting: %+v, received: %+v", rtprfl, result)
}
result, err = rtprflMigrator.dmIN.DataManager().GetRatingProfile("RT_Profile", true, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
}
}

View File

@@ -46,6 +46,9 @@ func (m *Migrator) migrateCurrentResource() (err error) {
if err := m.dmOut.DataManager().SetResourceProfile(res, true); err != nil {
return err
}
if err := m.dmIN.DataManager().RemoveResourceProfile(tenant, idg, utils.NonTransactional, false); err != nil {
return err
}
m.stats[utils.Resource] += 1
}
return

View File

@@ -0,0 +1,219 @@
// +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 <http://www.gnu.org/licenses/>
*/
package migrator
import (
"log"
"path"
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
var (
resPathIn string
resPathOut string
resCfgIn *config.CGRConfig
resCfgOut *config.CGRConfig
resMigrator *Migrator
resAction string
)
var sTestsResIT = []func(t *testing.T){
testResITConnect,
testResITFlush,
testResITMigrateAndMove,
}
func TestResourceITMove1(t *testing.T) {
var err error
resPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
resCfgIn, err = config.NewCGRConfigFromPath(resPathIn)
if err != nil {
t.Fatal(err)
}
resPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
resCfgOut, err = config.NewCGRConfigFromPath(resPathOut)
if err != nil {
t.Fatal(err)
}
resAction = utils.Move
for _, stest := range sTestsResIT {
t.Run("TestResourceITMove", stest)
}
resMigrator.Close()
}
func TestResourceITMove2(t *testing.T) {
var err error
resPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
resCfgIn, err = config.NewCGRConfigFromPath(resPathIn)
if err != nil {
t.Fatal(err)
}
resPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
resCfgOut, err = config.NewCGRConfigFromPath(resPathOut)
if err != nil {
t.Fatal(err)
}
resAction = utils.Move
for _, stest := range sTestsResIT {
t.Run("TestResourceITMove", stest)
}
resMigrator.Close()
}
func TestResourceITMoveEncoding(t *testing.T) {
var err error
resPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
resCfgIn, err = config.NewCGRConfigFromPath(resPathIn)
if err != nil {
t.Fatal(err)
}
resPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
resCfgOut, err = config.NewCGRConfigFromPath(resPathOut)
if err != nil {
t.Fatal(err)
}
resAction = utils.Move
for _, stest := range sTestsResIT {
t.Run("TestResourceITMoveEncoding", stest)
}
resMigrator.Close()
}
func TestResourceITMoveEncoding2(t *testing.T) {
var err error
resPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
resCfgIn, err = config.NewCGRConfigFromPath(resPathIn)
if err != nil {
t.Fatal(err)
}
resPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
resCfgOut, err = config.NewCGRConfigFromPath(resPathOut)
if err != nil {
t.Fatal(err)
}
resAction = utils.Move
for _, stest := range sTestsResIT {
t.Run("TestResourceITMoveEncoding2", stest)
}
resMigrator.Close()
}
func testResITConnect(t *testing.T) {
dataDBIn, err := NewMigratorDataDB(resCfgIn.DataDbCfg().DataDbType,
resCfgIn.DataDbCfg().DataDbHost, resCfgIn.DataDbCfg().DataDbPort,
resCfgIn.DataDbCfg().DataDbName, resCfgIn.DataDbCfg().DataDbUser,
resCfgIn.DataDbCfg().DataDbPass, resCfgIn.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
dataDBOut, err := NewMigratorDataDB(resCfgOut.DataDbCfg().DataDbType,
resCfgOut.DataDbCfg().DataDbHost, resCfgOut.DataDbCfg().DataDbPort,
resCfgOut.DataDbCfg().DataDbName, resCfgOut.DataDbCfg().DataDbUser,
resCfgOut.DataDbCfg().DataDbPass, resCfgOut.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
resMigrator, err = NewMigrator(dataDBIn, dataDBOut,
nil, nil,
false, false, false, false)
if err != nil {
log.Fatal(err)
}
}
func testResITFlush(t *testing.T) {
if err := resMigrator.dmOut.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := resMigrator.dmOut.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(resMigrator.dmOut.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
if err := resMigrator.dmIN.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := resMigrator.dmIN.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(resMigrator.dmIN.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
}
func testResITMigrateAndMove(t *testing.T) {
resPrfl := &engine.ResourceProfile{
Tenant: "cgrates.org",
ID: "RES1",
FilterIDs: []string{"*string:~Account:1001"},
UsageTTL: time.Second,
Limit: 1,
Weight: 10,
ThresholdIDs: []string{"TH1"},
}
switch resAction {
case utils.Migrate: // for the momment only one version of rating plans exists
case utils.Move:
if err := resMigrator.dmIN.DataManager().SetResourceProfile(resPrfl, true); err != nil {
t.Error(err)
}
currentVersion := engine.CurrentDataDBVersions()
err := resMigrator.dmOut.DataManager().DataDB().SetVersions(currentVersion, false)
if err != nil {
t.Error("Error when setting version for Resource ", err.Error())
}
_, err = resMigrator.dmOut.DataManager().GetResourceProfile("cgrates.org", "RES1", false, false, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
err, _ = resMigrator.Migrate([]string{utils.MetaResources})
if err != nil {
t.Error("Error when migrating Resource ", err.Error())
}
result, err := resMigrator.dmOut.DataManager().GetResourceProfile("cgrates.org", "RES1", false, false, utils.NonTransactional)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(result, resPrfl) {
t.Errorf("Expecting: %+v, received: %+v", resPrfl, result)
}
result, err = resMigrator.dmIN.DataManager().GetResourceProfile("cgrates.org", "RES1", false, false, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
}
}

View File

@@ -0,0 +1,95 @@
/*
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 <http://www.gnu.org/licenses/>
*/
package migrator
import (
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
func TestV2toV3Cost(t *testing.T) {
cc := &engine.CallCost{
Category: utils.CALL,
Tenant: "cgrates.org",
Subject: "1001",
Account: "1001",
Destination: "1002",
TOR: "ToR",
Cost: 10,
Timespans: engine.TimeSpans{
&engine.TimeSpan{
TimeStart: time.Now(),
TimeEnd: time.Now().Add(time.Minute),
Cost: 10,
RateInterval: &engine.RateInterval{
Rating: &engine.RIRate{
Rates: engine.RateGroups{
&engine.Rate{
GroupIntervalStart: 0,
Value: 100,
RateIncrement: 10 * time.Second,
RateUnit: time.Second,
},
},
},
},
},
},
RatedUsage: 10,
AccountSummary: &engine.AccountSummary{
Tenant: "cgrates.org",
ID: "1001",
BalanceSummaries: []*engine.BalanceSummary{
&engine.BalanceSummary{
UUID: "UUID",
ID: "First",
Type: utils.MONETARY,
Value: 10,
},
},
},
}
sv2 := v2SessionsCost{
CGRID: "CGRID",
RunID: utils.MetaDefault,
OriginHost: utils.FreeSWITCHAgent,
OriginID: "Origin1",
CostSource: utils.MetaSessionS,
Usage: time.Second,
CostDetails: cc,
}
sv3 := &engine.SMCost{
CGRID: "CGRID",
RunID: utils.MetaDefault,
OriginHost: utils.FreeSWITCHAgent,
OriginID: "Origin1",
Usage: time.Second,
CostSource: utils.MetaSessionS,
CostDetails: engine.NewEventCostFromCallCost(cc, "CGRID", utils.MetaDefault),
}
rply := sv2.V2toV3Cost()
rply.CostDetails = sv3.CostDetails
if !reflect.DeepEqual(sv3, rply) {
t.Errorf("Expected: %s ,received: %s", utils.ToJSON(sv3), utils.ToJSON(rply))
}
}

View File

@@ -246,3 +246,5 @@ func (v1ms *mapMigrator) setV3AttributeProfile(x *v3AttributeProfile) (err error
func (v1ms *mapMigrator) remV3AttributeProfile(tenant, id string) (err error) {
return utils.ErrNotImplemented
}
func (v1ms *mapMigrator) close() {}

View File

@@ -37,6 +37,8 @@ type mapStorDBMigrator struct {
qryIdx *int
}
func (mpMig *mapStorDBMigrator) close() {}
func (mpMig *mapStorDBMigrator) StorDB() engine.StorDB {
return *mpMig.storDB
}

View File

@@ -59,6 +59,10 @@ func newMongoMigrator(dm *engine.DataManager) (mgoMig *mongoMigrator) {
}
}
func (mgoMig *mongoMigrator) close() {
mgoMig.mgoDB.Close()
}
func (mgoMig *mongoMigrator) DataManager() *engine.DataManager {
return mgoMig.dm
}
@@ -202,12 +206,35 @@ func (v1ms *mongoMigrator) setV1Actions(x *v1Actions) (err error) {
//ActionTriggers methods
//get
func (v1ms *mongoMigrator) getV1ActionTriggers() (v1acts *v1ActionTriggers, err error) {
return nil, utils.ErrNotImplemented
if v1ms.cursor == nil {
var cursor mongo.Cursor
cursor, err = v1ms.mgoDB.DB().Collection(v1ActionTriggersCol).Find(v1ms.mgoDB.GetContext(), bson.D{})
if err != nil {
return nil, err
}
v1ms.cursor = &cursor
}
if !(*v1ms.cursor).Next(v1ms.mgoDB.GetContext()) {
(*v1ms.cursor).Close(v1ms.mgoDB.GetContext())
v1ms.cursor = nil
return nil, utils.ErrNoMoreData
}
v1act := new(v1ActionTrigger)
if err := (*v1ms.cursor).Decode(v1act); err != nil {
return nil, err
}
return &v1ActionTriggers{v1act}, nil
}
//set
func (v1ms *mongoMigrator) setV1ActionTriggers(x *v1ActionTriggers) (err error) {
return utils.ErrNotImplemented
func (v1ms *mongoMigrator) setV1ActionTriggers(act *v1ActionTriggers) (err error) {
for _, x := range *act {
_, err = v1ms.mgoDB.DB().Collection(v1ActionTriggersCol).InsertOne(v1ms.mgoDB.GetContext(), *x)
if err != nil {
return err
}
}
return
}
//Actions methods

View File

@@ -39,6 +39,10 @@ type mongoStorDBMigrator struct {
cursor *mongo.Cursor
}
func (mgoMig *mongoStorDBMigrator) close() {
mgoMig.mgoDB.Close()
}
func (mgoMig *mongoStorDBMigrator) StorDB() engine.StorDB {
return *mgoMig.storDB
}

View File

@@ -44,6 +44,10 @@ func newRedisMigrator(dm *engine.DataManager) (rM *redisMigrator) {
}
}
func (rdsMig *redisMigrator) close() {
rdsMig.rds.Close()
}
func (rdsMig *redisMigrator) DataManager() *engine.DataManager {
return rdsMig.dm
}

View File

@@ -41,6 +41,10 @@ type migratorSQL struct {
rowIter *sql.Rows
}
func (sqlMig *migratorSQL) close() {
sqlMig.sqlStorage.Close()
}
func (sqlMig *migratorSQL) StorDB() engine.StorDB {
return *sqlMig.storDB
}

View File

@@ -35,7 +35,7 @@ func (m *Migrator) migrateCurrentSupplierProfile() (err error) {
return err
}
for _, id := range ids {
idg := strings.TrimPrefix(id, utils.SupplierProfilePrefix)
idg := strings.TrimPrefix(id, utils.SupplierProfilePrefix+tenant+":")
splp, err := m.dmIN.DataManager().GetSupplierProfile(tenant, idg, false, false, utils.NonTransactional)
if err != nil {
return err
@@ -46,6 +46,9 @@ func (m *Migrator) migrateCurrentSupplierProfile() (err error) {
if err := m.dmOut.DataManager().SetSupplierProfile(splp, true); err != nil {
return err
}
if err := m.dmIN.DataManager().RemoveSupplierProfile(tenant, idg, utils.NonTransactional, true); err != nil {
return err
}
m.stats[utils.Suppliers] += 1
}
return

View File

@@ -0,0 +1,230 @@
// +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 <http://www.gnu.org/licenses/>
*/
package migrator
import (
"log"
"path"
"reflect"
"testing"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
var (
supPathIn string
supPathOut string
supCfgIn *config.CGRConfig
supCfgOut *config.CGRConfig
supMigrator *Migrator
supAction string
)
var sTestsSupIT = []func(t *testing.T){
testSupITConnect,
testSupITFlush,
testSupITMigrateAndMove,
}
func TestSuppliersITMove1(t *testing.T) {
var err error
supPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
supCfgIn, err = config.NewCGRConfigFromPath(supPathIn)
if err != nil {
t.Fatal(err)
}
supPathOut = path.Join(*dataDir, "conf", "samples", "tutmysql")
supCfgOut, err = config.NewCGRConfigFromPath(supPathOut)
if err != nil {
t.Fatal(err)
}
supAction = utils.Move
for _, stest := range sTestsSupIT {
t.Run("TestSuppliersITMove", stest)
}
supMigrator.Close()
}
func TestSuppliersITMove2(t *testing.T) {
var err error
supPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
supCfgIn, err = config.NewCGRConfigFromPath(supPathIn)
if err != nil {
t.Fatal(err)
}
supPathOut = path.Join(*dataDir, "conf", "samples", "tutmongo")
supCfgOut, err = config.NewCGRConfigFromPath(supPathOut)
if err != nil {
t.Fatal(err)
}
supAction = utils.Move
for _, stest := range sTestsSupIT {
t.Run("TestSuppliersITMove", stest)
}
supMigrator.Close()
}
func TestSuppliersITMoveEncoding(t *testing.T) {
var err error
supPathIn = path.Join(*dataDir, "conf", "samples", "tutmongo")
supCfgIn, err = config.NewCGRConfigFromPath(supPathIn)
if err != nil {
t.Fatal(err)
}
supPathOut = path.Join(*dataDir, "conf", "samples", "tutmongojson")
supCfgOut, err = config.NewCGRConfigFromPath(supPathOut)
if err != nil {
t.Fatal(err)
}
supAction = utils.Move
for _, stest := range sTestsSupIT {
t.Run("TestSuppliersITMoveEncoding", stest)
}
supMigrator.Close()
}
func TestSuppliersITMoveEncoding2(t *testing.T) {
var err error
supPathIn = path.Join(*dataDir, "conf", "samples", "tutmysql")
supCfgIn, err = config.NewCGRConfigFromPath(supPathIn)
if err != nil {
t.Fatal(err)
}
supPathOut = path.Join(*dataDir, "conf", "samples", "tutmysqljson")
supCfgOut, err = config.NewCGRConfigFromPath(supPathOut)
if err != nil {
t.Fatal(err)
}
supAction = utils.Move
for _, stest := range sTestsSupIT {
t.Run("TestSuppliersITMoveEncoding2", stest)
}
supMigrator.Close()
}
func testSupITConnect(t *testing.T) {
dataDBIn, err := NewMigratorDataDB(supCfgIn.DataDbCfg().DataDbType,
supCfgIn.DataDbCfg().DataDbHost, supCfgIn.DataDbCfg().DataDbPort,
supCfgIn.DataDbCfg().DataDbName, supCfgIn.DataDbCfg().DataDbUser,
supCfgIn.DataDbCfg().DataDbPass, supCfgIn.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
dataDBOut, err := NewMigratorDataDB(supCfgOut.DataDbCfg().DataDbType,
supCfgOut.DataDbCfg().DataDbHost, supCfgOut.DataDbCfg().DataDbPort,
supCfgOut.DataDbCfg().DataDbName, supCfgOut.DataDbCfg().DataDbUser,
supCfgOut.DataDbCfg().DataDbPass, supCfgOut.GeneralCfg().DBDataEncoding,
config.CgrConfig().CacheCfg(), "")
if err != nil {
log.Fatal(err)
}
supMigrator, err = NewMigrator(dataDBIn, dataDBOut,
nil, nil,
false, false, false, false)
if err != nil {
log.Fatal(err)
}
}
func testSupITFlush(t *testing.T) {
if err := supMigrator.dmOut.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := supMigrator.dmOut.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(supMigrator.dmOut.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
if err := supMigrator.dmIN.DataManager().DataDB().Flush(""); err != nil {
t.Error(err)
}
if isEmpty, err := supMigrator.dmIN.DataManager().DataDB().IsDBEmpty(); err != nil {
t.Error(err)
} else if isEmpty != true {
t.Errorf("\nExpecting: true got :%+v", isEmpty)
}
if err := engine.SetDBVersions(supMigrator.dmIN.DataManager().DataDB()); err != nil {
t.Error("Error ", err.Error())
}
}
func testSupITMigrateAndMove(t *testing.T) {
supPrfl := &engine.SupplierProfile{
Tenant: "cgrates.org",
ID: "SUP1",
FilterIDs: []string{"*string:~Account:1001"},
Weight: 10,
Sorting: utils.MetaQOS,
SortingParameters: []string{},
Suppliers: []*engine.Supplier{
&engine.Supplier{
ID: "Sup",
FilterIDs: []string{},
AccountIDs: []string{"1001"},
RatingPlanIDs: []string{"RT_PLAN1"},
ResourceIDs: []string{"RES1"},
Weight: 10,
},
},
}
switch supAction {
case utils.Migrate: // for the momment only one version of rating plans exists
case utils.Move:
if err := supMigrator.dmIN.DataManager().SetSupplierProfile(supPrfl, true); err != nil {
t.Error(err)
}
if _, err := supMigrator.dmIN.DataManager().GetSupplierProfile("cgrates.org", "SUP1", false, false, utils.NonTransactional); err != nil {
t.Error(err)
}
currentVersion := engine.CurrentDataDBVersions()
err := supMigrator.dmOut.DataManager().DataDB().SetVersions(currentVersion, false)
if err != nil {
t.Error("Error when setting version for Suppliers ", err.Error())
}
_, err = supMigrator.dmOut.DataManager().GetSupplierProfile("cgrates.org", "SUP1", false, false, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
err, _ = supMigrator.Migrate([]string{utils.MetaSuppliers})
if err != nil {
t.Error("Error when migrating Suppliers ", err.Error())
}
result, err := supMigrator.dmOut.DataManager().GetSupplierProfile("cgrates.org", "SUP1", false, false, utils.NonTransactional)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(result, supPrfl) {
t.Errorf("Expecting: %+v, received: %+v", supPrfl, result)
}
result, err = supMigrator.dmIN.DataManager().GetSupplierProfile("cgrates.org", "SUP1", false, false, utils.NonTransactional)
if err != utils.ErrNotFound {
t.Error(err)
}
}
}