Added DryRun option for ReloadConfig

This commit is contained in:
Trial97
2020-11-25 13:59:17 +02:00
committed by Dan Christian Bogos
parent f158b191f3
commit 0b50c4763a
4 changed files with 162 additions and 22 deletions

View File

@@ -48,9 +48,12 @@ var (
testConfigSStartEngine,
testConfigSRPCConn,
testConfigSSetConfigSessionS,
testConfigSSetConfigEEsDryRun,
testConfigSSetConfigEEs,
testConfigSv1GetJSONSectionWithoutTenant,
testConfigSSetConfigFromJSONCoreSDryRun,
testConfigSSetConfigFromJSONCoreS,
testConfigSReloadConfigCoreSDryRun,
testConfigSReloadConfigCoreS,
testConfigSKillEngine,
testConfigStartEngineWithConfigs,
@@ -231,6 +234,34 @@ func testConfigSv1GetJSONSectionWithoutTenant(t *testing.T) {
}
}
func testConfigSSetConfigEEsDryRun(t *testing.T) {
if *encoding == utils.MetaGOB {
t.SkipNow()
}
var reply string
if err := configRPC.Call(utils.ConfigSv1SetConfig, &config.SetConfigArgs{
Config: map[string]interface{}{
"ees": map[string]interface{}{
"enabled": true,
},
},
DryRun: true,
}, &reply); err != nil {
t.Error(err)
} else if reply != utils.OK {
t.Errorf("Expected OK received: %s", reply)
}
var rpl map[string]interface{}
if err := configRPC.Call(utils.ConfigSv1GetConfig, &config.SectionWithOpts{
Section: config.EEsJson,
}, &rpl); err != nil {
t.Error(err)
} else if rpl[config.EEsJson].(map[string]interface{})["enabled"] != false {
t.Errorf("Expected EEs to not change , received: %+v ", utils.ToJSON(rpl))
}
}
func testConfigSSetConfigEEs(t *testing.T) {
if *encoding == utils.MetaGOB {
t.SkipNow()
@@ -348,6 +379,31 @@ func testConfigStartEngineFromHTTP(t *testing.T) {
}
}
func testConfigSSetConfigFromJSONCoreSDryRun(t *testing.T) {
cfgStr := `{"cores":{"caps":0,"caps_stats_interval":"0","caps_strategy":"*queue","shutdown_timeout":"1s"}}`
var reply string
if err := configRPC.Call(utils.ConfigSv1SetConfigFromJSON, &config.SetConfigFromJSONArgs{
Tenant: "cgrates.org",
Config: cfgStr,
DryRun: true,
}, &reply); err != nil {
t.Error(err)
} else if reply != utils.OK {
t.Errorf("Expected OK received: %s", reply)
}
expCfg := "{\"cores\":{\"caps\":0,\"caps_stats_interval\":\"0\",\"caps_strategy\":\"*busy\",\"shutdown_timeout\":\"1s\"}}"
var rpl string
if err := configRPC.Call(utils.ConfigSv1GetConfigAsJSON, &config.SectionWithOpts{
Tenant: "cgrates.org",
Section: config.CoreSCfgJson,
}, &rpl); err != nil {
t.Error(err)
} else if expCfg != rpl {
t.Errorf("Expected %q , received: %q", expCfg, rpl)
}
}
func testConfigSSetConfigFromJSONCoreS(t *testing.T) {
cfgStr := `{"cores":{"caps":0,"caps_stats_interval":"0","caps_strategy":"*queue","shutdown_timeout":"1s"}}`
var reply string
@@ -371,6 +427,31 @@ func testConfigSSetConfigFromJSONCoreS(t *testing.T) {
}
}
func testConfigSReloadConfigCoreSDryRun(t *testing.T) {
cfgStr := `{"cores":{"caps":0,"caps_stats_interval":"0","caps_strategy":"*queue","shutdown_timeout":"1s"}}`
var reply string
if err := configRPC.Call(utils.ConfigSv1ReloadConfig, &config.ReloadArgs{
Tenant: "cgrates.org",
Path: path.Join(*dataDir, "conf", "samples", "caps_busy"),
Section: config.CoreSCfgJson,
DryRun: true,
}, &reply); err != nil {
t.Error(err)
} else if reply != utils.OK {
t.Errorf("Expected OK received: %s", reply)
}
var rpl string
if err := configRPC.Call(utils.ConfigSv1GetConfigAsJSON, &config.SectionWithOpts{
Tenant: "cgrates.org",
Section: config.CoreSCfgJson,
}, &rpl); err != nil {
t.Error(err)
} else if cfgStr != rpl {
t.Errorf("Expected %q , received: %q", cfgStr, rpl)
}
}
func testConfigSReloadConfigCoreS(t *testing.T) {
cfgStr := `{"cores":{"caps":2,"caps_stats_interval":"0","caps_strategy":"*busy","shutdown_timeout":"1s"}}`
var reply string

View File

@@ -1541,6 +1541,7 @@ type ReloadArgs struct {
Tenant string
Path string
Section string
DryRun bool
}
// V1ReloadConfig reloads the configuration
@@ -1548,24 +1549,29 @@ func (cfg *CGRConfig) V1ReloadConfig(args *ReloadArgs, reply *string) (err error
if missing := utils.MissingStructFields(args, []string{"Path"}); len(missing) != 0 {
return utils.NewErrMandatoryIeMissing(missing...)
}
if err = cfg.loadCfgWithLocks(args.Path, args.Section); err != nil {
cfgV := cfg
if args.DryRun {
cfgV = cfg.Clone()
}
if err = cfgV.loadCfgWithLocks(args.Path, args.Section); err != nil {
return
}
// lock all sections
cfg.rLockSections()
cfgV.rLockSections()
err = cfg.checkConfigSanity()
err = cfgV.checkConfigSanity()
cfg.rUnlockSections() // unlock before checking the error
cfgV.rUnlockSections() // unlock before checking the error
if err != nil {
return
}
if args.Section == utils.EmptyString || args.Section == utils.MetaAll {
cfg.reloadSections(sortedCfgSections...)
} else {
cfg.reloadSections(args.Section)
if !args.DryRun {
if args.Section == utils.EmptyString || args.Section == utils.MetaAll {
cfgV.reloadSections(sortedCfgSections...)
} else {
cfgV.reloadSections(args.Section)
}
}
*reply = utils.OK
return
@@ -1687,6 +1693,7 @@ type SetConfigArgs struct {
Opts map[string]interface{}
Tenant string
Config map[string]interface{}
DryRun bool
}
// V1SetConfig reloads the sections of config
@@ -1703,20 +1710,25 @@ func (cfg *CGRConfig) V1SetConfig(args *SetConfigArgs, reply *string) (err error
if b, err = json.Marshal(args.Config); err != nil {
return
}
if err = cfg.loadCfgFromJSONWithLocks(bytes.NewBuffer(b), sections); err != nil {
cfgV := cfg
if args.DryRun {
cfgV = cfg.Clone()
}
if err = cfgV.loadCfgFromJSONWithLocks(bytes.NewBuffer(b), sections); err != nil {
return
}
// lock all sections
cfg.rLockSections()
cfgV.rLockSections()
err = cfg.checkConfigSanity()
err = cfgV.checkConfigSanity()
cfg.rUnlockSections() // unlock before checking the error
cfgV.rUnlockSections() // unlock before checking the error
if err != nil {
return
}
cfg.reloadSections(sections...)
if !args.DryRun {
cfgV.reloadSections(sections...)
}
*reply = utils.OK
return
}
@@ -1831,6 +1843,7 @@ type SetConfigFromJSONArgs struct {
Opts map[string]interface{}
Tenant string
Config string
DryRun bool
}
// V1SetConfigFromJSON reloads the sections of config
@@ -1839,20 +1852,24 @@ func (cfg *CGRConfig) V1SetConfigFromJSON(args *SetConfigFromJSONArgs, reply *st
*reply = utils.OK
return
}
if err = cfg.loadCfgFromJSONWithLocks(bytes.NewBufferString(args.Config), sortedCfgSections); err != nil {
cfgV := cfg
if args.DryRun {
cfgV = cfg.Clone()
}
if err = cfgV.loadCfgFromJSONWithLocks(bytes.NewBufferString(args.Config), sortedCfgSections); err != nil {
return
}
// lock all sections
cfg.rLockSections()
err = cfg.checkConfigSanity()
cfg.rUnlockSections() // unlock before checking the error
cfgV.rLockSections()
err = cfgV.checkConfigSanity()
cfgV.rUnlockSections() // unlock before checking the error
if err != nil {
return
}
cfg.reloadSections(sortedCfgSections...)
if !args.DryRun {
cfgV.reloadSections(sortedCfgSections...)
}
*reply = utils.OK
return
}

View File

@@ -40,6 +40,7 @@ var (
testNewCgrJsonCfgFromHttp,
testNewCGRConfigFromPath,
testCGRConfigReloadAttributeS,
testCGRConfigReloadChargerSDryRun,
testCGRConfigReloadChargerS,
testCGRConfigReloadThresholdS,
testCGRConfigReloadStatS,
@@ -161,6 +162,28 @@ func testCGRConfigReloadAttributeS(t *testing.T) {
}
}
func testCGRConfigReloadChargerSDryRun(t *testing.T) {
cfg, err := NewDefaultCGRConfig()
if err != nil {
t.Fatal(err)
}
var reply string
if err = cfg.V1ReloadConfig(&ReloadArgs{
Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"),
Section: ChargerSCfgJson,
DryRun: true,
}, &reply); err != nil {
t.Error(err)
} else if reply != utils.OK {
t.Errorf("Expected OK received: %s", reply)
}
ecfg, _ := NewDefaultCGRConfig()
if !reflect.DeepEqual(ecfg.ChargerSCfg(), cfg.ChargerSCfg()) {
t.Errorf("Expected %s , received: %s ", utils.ToJSON(ecfg.ChargerSCfg()), utils.ToJSON(cfg.ChargerSCfg()))
}
}
func testCGRConfigReloadChargerS(t *testing.T) {
cfg, err := NewDefaultCGRConfig()
if err != nil {

View File

@@ -4699,6 +4699,16 @@ func TestV1GetConfigSectionConfigs(t *testing.T) {
}
var result string
if cfgCgr2, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
} else if err = cfgCgr2.V1SetConfig(&SetConfigArgs{Config: reply, DryRun: true}, &result); err != nil {
t.Error(err)
} else if result != utils.OK {
t.Errorf("Unexpected result")
} else if cfgCgr, _ := NewDefaultCGRConfig(); !reflect.DeepEqual(cfgCgr.ConfigSCfg(), cfgCgr2.ConfigSCfg()) {
t.Errorf("Expected %+v, received %+v", utils.ToJSON(cfgCgr.ConfigSCfg()), utils.ToJSON(cfgCgr2.ConfigSCfg()))
}
if cfgCgr2, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
} else if err = cfgCgr2.V1SetConfig(&SetConfigArgs{Config: reply}, &result); err != nil {
@@ -5401,6 +5411,15 @@ func TestV1GetConfigAsJSONCoreS(t *testing.T) {
}
var result string
if cfgCgr2, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
} else if err = cfgCgr2.V1SetConfigFromJSON(&SetConfigFromJSONArgs{Config: reply, DryRun: true}, &result); err != nil {
t.Error(err)
} else if result != utils.OK {
t.Errorf("Unexpected result")
} else if cgrCfg, _ := NewDefaultCGRConfig(); !reflect.DeepEqual(cgrCfg.CoreSCfg(), cfgCgr2.CoreSCfg()) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(cgrCfg.CoreSCfg()), utils.ToJSON(cfgCgr2.CoreSCfg()))
}
if cfgCgr2, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
} else if err = cfgCgr2.V1SetConfigFromJSON(&SetConfigFromJSONArgs{Config: reply}, &result); err != nil {