test diameter-stats-prometheus integration

This commit is contained in:
ionutboangiu
2025-06-04 19:57:53 +03:00
committed by Dan Christian Bogos
parent 671c7474b8
commit f300ecea7e

296
agents/diam_prom_it_test.go Normal file
View File

@@ -0,0 +1,296 @@
//go: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 agents
import (
"bytes"
"fmt"
"io"
"net/http"
"testing"
"time"
"github.com/cgrates/birpc/context"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
func TestDiamPrometheus(t *testing.T) {
t.Skip("test by looking at the log output")
switch *utils.DBType {
case utils.MetaInternal:
case utils.MetaMySQL, utils.MetaMongo, utils.MetaPostgres:
t.SkipNow()
default:
t.Fatal("unsupported dbtype value")
}
ng := engine.TestEngine{
ConfigJSON: `{
"apiers": {
"enabled": true
},
"sessions": {
"enabled": true,
"chargers_conns": ["*internal"],
"rals_conns": ["*internal"],
"cdrs_conns": ["*internal"]
},
"chargers": {
"enabled": true,
"string_indexed_fields": ["*req.Account"]
},
"cdrs": {
"enabled": true,
"rals_conns": ["*internal"],
"store_cdrs": false
},
"rals": {
"enabled": true
},
"prometheus_agent": {
"enabled": true,
"stats_conns": ["*localhost"],
"stat_queue_ids": ["SQ_1"]
},
"stats": {
"enabled": true,
"store_interval": "-1"
},
"thresholds": {
"enabled": true,
"store_interval": "-1"
},
"rpc_conns": {
"async": {
"strategy": "*async",
"conns": [
{
"address": "*internal"
}
]
}
},
"diameter_agent": {
"enabled": true,
"sessions_conns": ["*birpc_internal"],
"stats_conns": ["async"],
"thresholds_conns": ["async"],
"request_processors": [{
"id": "message",
"filters": [
"*string:~*vars.*cmd:CCR",
"*prefix:~*req.Service-Context-Id:message",
"*string:~*req.CC-Request-Type:4"
],
"flags": [
"*message",
"*accounts",
"*cdrs",
"*daStats:*ids:SQ_1",
"*daThresholds:*ids:TH_1",
],
"request_fields": [{
"tag": "ToR",
"path": "*cgreq.ToR",
"type": "*constant",
"value": "*sms"
},
{
"tag": "OriginID",
"path": "*cgreq.OriginID",
"type": "*variable",
"value": "~*req.Session-Id",
"mandatory": true
},
{
"tag": "Category",
"path": "*cgreq.Category",
"type": "*constant",
"value": "sms"
},
{
"tag": "RequestType",
"path": "*cgreq.RequestType",
"type": "*constant",
"value": "*prepaid"
},
{
"tag": "Account",
"path": "*cgreq.Account",
"type": "*variable",
"mandatory": true,
"value": "~*req.Subscription-Id.Subscription-Id-Data[~Subscription-Id-Type(0)]"
},
{
"tag": "Destination",
"path": "*cgreq.Destination",
"type": "*variable",
"mandatory": true,
"value": "~*req.Service-Information.SMS-Information.Recipient-Address.Address-Data"
},
{
"tag": "SetupTime",
"path": "*cgreq.SetupTime",
"type": "*variable",
"value": "~*req.Event-Timestamp",
"mandatory": true
},
{
"tag": "AnswerTime",
"path": "*cgreq.AnswerTime",
"type": "*variable",
"value": "~*req.Event-Timestamp",
"mandatory": true
},
{
"tag": "Usage",
"path": "*cgreq.Usage",
"type": "*variable",
"value": "~*req.Requested-Service-Unit.CC-Time",
"mandatory": true
}
],
"reply_fields": [{
"tag": "CCATemplate",
"type": "*template",
"value": "*cca"
},
{
"tag": "ResultCode",
"path": "*rep.Result-Code",
"filters": ["*notempty:~*cgrep.Error:"],
"type": "*constant",
"value": "5030",
"blocker": true
}
]
}]
}
}`,
TpFiles: map[string]string{
// import Chargers via CSV to avoid cyclic imports (agents->v1->agents)
utils.ChargersCsv: `
#Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight
cgrates.org,DEFAULT,*string:~*req.Account:1001,,*default,*none,10`,
},
DBCfg: engine.InternalDBCfg,
LogBuffer: &bytes.Buffer{},
GracefulShutdown: true,
}
t.Cleanup(func() { fmt.Println(ng.LogBuffer) })
client, cfg := ng.Run(t)
var reply string
if err := client.Call(context.Background(), utils.APIerSv2SetBalance,
utils.AttrSetBalance{
Tenant: "cgrates.org",
Account: "1001",
Value: 100,
BalanceType: utils.MetaSMS,
Balance: map[string]any{
utils.ID: "balance_sms",
},
}, &reply); err != nil {
t.Fatal(err)
}
if err := client.Call(context.Background(), utils.APIerSv2SetActions,
utils.AttrSetActions{
ActionsId: "ACT_LOG_WARNING",
Actions: []*utils.TPAction{
{
Identifier: utils.MetaLog,
},
},
}, &reply); err != nil {
t.Fatal(err)
}
if err := client.Call(context.Background(), utils.APIerSv1SetStatQueueProfile,
engine.StatQueueProfileWithAPIOpts{
StatQueueProfile: &engine.StatQueueProfile{
Tenant: "cgrates.org",
ID: "SQ_1",
FilterIDs: []string{"*string:~*req.Category:sms"},
QueueLength: -1,
TTL: 5 * time.Second,
Metrics: []*engine.MetricWithFilters{
{
MetricID: "*average#~*req.ProcessingTime",
},
{
MetricID: "*sum#~*req.ProcessingTime",
},
},
Stored: true,
MinItems: 1,
},
}, &reply); err != nil {
t.Fatal(err)
}
if err := client.Call(context.Background(), utils.APIerSv1SetThresholdProfile,
engine.ThresholdProfileWithAPIOpts{
ThresholdProfile: &engine.ThresholdProfile{
Tenant: "cgrates.org",
ID: "TH_1",
FilterIDs: []string{"*string:~*req.Category:sms"},
MaxHits: -1,
MinHits: 8,
MinSleep: time.Second,
ActionIDs: []string{"ACT_LOG_WARNING"},
},
}, &reply); err != nil {
t.Fatal(err)
}
time.Sleep(500 * time.Millisecond)
diamClient, err := NewDiameterClient(cfg.DiameterAgentCfg().Listen, "localhost",
cfg.DiameterAgentCfg().OriginRealm, cfg.DiameterAgentCfg().VendorID,
cfg.DiameterAgentCfg().ProductName, utils.DiameterFirmwareRevision,
cfg.DiameterAgentCfg().DictionariesPath, cfg.DiameterAgentCfg().ListenNet)
if err != nil {
t.Fatal(err)
}
for range 10 {
time.Sleep(time.Second)
sendDiamCCR(t, diamClient, 5*time.Second, "2001")
scrapePromURL(t)
}
}
func scrapePromURL(t *testing.T) {
t.Helper()
url := "http://localhost:2080/prometheus"
resp, err := http.Get(url)
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
bodyString := string(body)
fmt.Println(bodyString)
}