mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-13 19:56:38 +05:00
Improve test setup helpers
- added hook support (executed after parsing config but before starting engine) - made db resets configurable - merged config parsing helper with the main Setup function - removed engineDelay parameter - replaced t.Log with t.Error for engine process kill error - improved option comments
This commit is contained in:
committed by
Dan Christian Bogos
parent
9236c8a1e7
commit
e228dda013
@@ -2258,7 +2258,7 @@ cgrates.org,ATTR_ARITH,,,,,,*req.MultiplyBetweenVariables,*multiply,~*req.Elem1;
|
||||
TpFiles: tpFiles,
|
||||
Encoding: *utils.Encoding,
|
||||
}
|
||||
client, _ := testEnv.Setup(t, context.Background(), 0)
|
||||
client, _ := testEnv.Setup(t, context.Background())
|
||||
|
||||
t.Run("SetAttributesThroughAPI", func(t *testing.T) {
|
||||
var reply string
|
||||
|
||||
@@ -317,6 +317,7 @@ func GetDefaultEmptyCacheStats() map[string]*ltcache.CacheStats {
|
||||
}
|
||||
}
|
||||
|
||||
// NewRPCClient establishes a connection to cgr-engine and returns the client.
|
||||
func NewRPCClient(cfg *config.ListenCfg, encoding string) (*birpc.Client, error) {
|
||||
switch encoding {
|
||||
case utils.MetaJSON:
|
||||
@@ -331,36 +332,52 @@ func NewRPCClient(cfg *config.ListenCfg, encoding string) (*birpc.Client, error)
|
||||
// TestEnvironment holds the setup parameters and configurations
|
||||
// required for running integration tests.
|
||||
type TestEnvironment struct {
|
||||
Name string // usually the name of the test
|
||||
ConfigPath string // file path to the main configuration file
|
||||
ConfigJSON string // contains the configuration JSON content if ConfigPath is missing
|
||||
TpPath string // specifies the path to the tariff plans
|
||||
TpFiles map[string]string // maps CSV filenames to their content for tariff plan loading
|
||||
LogBuffer io.Writer // captures the log output of the test environment
|
||||
Encoding string // specifies the data encoding type (e.g., JSON, GOB)
|
||||
ConfigPath string // path to the main configuration file
|
||||
ConfigJSON string // configuration JSON content (used if ConfigPath is empty)
|
||||
Encoding string // data encoding type (e.g., JSON, GOB)
|
||||
LogBuffer io.Writer // captures log output of the test environment
|
||||
PreserveDataDB bool // prevents automatic data_db flush when set
|
||||
PreserveStorDB bool // prevents automatic stor_db flush when set
|
||||
TpPath string // path to the tariff plans
|
||||
TpFiles map[string]string // CSV data for tariff plans: filename -> content
|
||||
|
||||
// PreStartHook executes custom logic relying on CGRConfig
|
||||
// before starting cgr-engine.
|
||||
PreStartHook func(*testing.T, *config.CGRConfig)
|
||||
}
|
||||
|
||||
// Setup initializes the testing environment using the provided configuration. It loads the configuration
|
||||
// from a specified path or creates a new one if the path is not provided. The method starts the engine,
|
||||
// establishes an RPC client connection, and loads CSV data if provided. It returns an RPC client and the
|
||||
// configuration.
|
||||
func (env TestEnvironment) Setup(t *testing.T, ctx *context.Context, engineDelay int) (*birpc.Client, *config.CGRConfig) {
|
||||
func (env TestEnvironment) Setup(t *testing.T, ctx *context.Context) (*birpc.Client, *config.CGRConfig) {
|
||||
t.Helper()
|
||||
|
||||
var cfg *config.CGRConfig
|
||||
// Parse config files.
|
||||
var cfgPath string
|
||||
switch {
|
||||
case env.ConfigPath != "":
|
||||
var err error
|
||||
cfg, err = config.NewCGRConfigFromPath(ctx, env.ConfigPath)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to init config from path %s: %v", env.ConfigPath, err)
|
||||
case env.ConfigJSON != "":
|
||||
cfgPath = t.TempDir()
|
||||
filePath := filepath.Join(cfgPath, "cgrates.json")
|
||||
if err := os.WriteFile(filePath, []byte(env.ConfigJSON), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
case env.ConfigPath != "":
|
||||
cfgPath = env.ConfigPath
|
||||
default:
|
||||
cfg, env.ConfigPath = initCfg(t, ctx, env.ConfigJSON)
|
||||
t.Fatal("missing config source")
|
||||
}
|
||||
cfg, err := config.NewCGRConfigFromPath(ctx, cfgPath)
|
||||
if err != nil {
|
||||
t.Fatalf("could not init config from path %s: %v", cfgPath, err)
|
||||
}
|
||||
|
||||
flushDBs(t, cfg, true, true)
|
||||
startEngine(t, ctx, cfg, env.ConfigPath, engineDelay, env.LogBuffer)
|
||||
flushDBs(t, cfg, !env.PreserveDataDB, !env.PreserveStorDB)
|
||||
|
||||
if env.PreStartHook != nil {
|
||||
env.PreStartHook(t, cfg)
|
||||
}
|
||||
startEngine(t, ctx, cfg, env.LogBuffer)
|
||||
|
||||
client, err := NewRPCClient(cfg.ListenCfg(), env.Encoding)
|
||||
if err != nil {
|
||||
@@ -372,31 +389,10 @@ func (env TestEnvironment) Setup(t *testing.T, ctx *context.Context, engineDelay
|
||||
return client, cfg
|
||||
}
|
||||
|
||||
// initCfg creates a new CGRConfig from the provided configuration content string.
|
||||
// It generates a temporary directory and file path, writes the content to the configuration
|
||||
// file, and returns the created CGRConfig and the configuration directory path.
|
||||
func initCfg(t *testing.T, ctx *context.Context, cfgContent string) (cfg *config.CGRConfig, cfgPath string) {
|
||||
t.Helper()
|
||||
if cfgContent == utils.EmptyString {
|
||||
t.Fatal("ConfigJSON is required but empty")
|
||||
}
|
||||
cfgPath = t.TempDir()
|
||||
filePath := filepath.Join(cfgPath, "cgrates.json")
|
||||
if err := os.WriteFile(filePath, []byte(cfgContent), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg, err := config.NewCGRConfigFromPath(ctx, cfgPath)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to init config from path %s: %v", cfgPath, err)
|
||||
}
|
||||
return cfg, cfgPath
|
||||
}
|
||||
|
||||
// loadCSVs loads tariff plan data from CSV files. The CSV files are created based on the csvFiles map, where
|
||||
// the key represents the file name and the value the contains its contents. Assumes the data is loaded
|
||||
// automatically (RunDelay != 0)
|
||||
func loadCSVs(t *testing.T, tpPath string, csvFiles map[string]string) {
|
||||
|
||||
t.Helper()
|
||||
if tpPath != "" {
|
||||
for fileName, content := range csvFiles {
|
||||
@@ -426,17 +422,16 @@ func flushDBs(t *testing.T, cfg *config.CGRConfig, flushDataDB, flushStorDB bool
|
||||
// startEngine starts the CGR engine process with the provided configuration. It writes engine logs to the provided
|
||||
// logBuffer (if any) and waits for the engine to be ready. If the passed context were to be cancelled, the engine
|
||||
// would also shut down.
|
||||
func startEngine(t *testing.T, ctx *context.Context, cfg *config.CGRConfig, cfgPath string, waitEngine int,
|
||||
logBuffer io.Writer) {
|
||||
func startEngine(t *testing.T, ctx *context.Context, cfg *config.CGRConfig, logBuffer io.Writer) {
|
||||
t.Helper()
|
||||
binPath, err := exec.LookPath("cgr-engine")
|
||||
if err != nil {
|
||||
t.Fatal("could not find cgr-engine executable")
|
||||
t.Fatal(err)
|
||||
}
|
||||
engine := exec.CommandContext(
|
||||
ctx,
|
||||
binPath,
|
||||
"-config_path", cfgPath,
|
||||
"-config_path", cfg.ConfigPath,
|
||||
"-logger", utils.MetaStdLog,
|
||||
)
|
||||
if logBuffer != nil {
|
||||
@@ -448,7 +443,7 @@ func startEngine(t *testing.T, ctx *context.Context, cfg *config.CGRConfig, cfgP
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if err := engine.Process.Kill(); err != nil {
|
||||
t.Logf("failed to kill cgr-engine process (%d): %v", engine.Process.Pid, err)
|
||||
t.Errorf("failed to kill cgr-engine process (%d): %v", engine.Process.Pid, err)
|
||||
}
|
||||
})
|
||||
fib := utils.FibDuration(time.Millisecond, 0)
|
||||
@@ -461,5 +456,4 @@ func startEngine(t *testing.T, ctx *context.Context, cfg *config.CGRConfig, cfgP
|
||||
if err != nil {
|
||||
t.Fatalf("starting cgr-engine on port %s failed: %v", cfg.ListenCfg().RPCJSONListen, err)
|
||||
}
|
||||
time.Sleep(time.Duration(waitEngine) * time.Millisecond)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user