From f3ff3d30239c8d2f28f1439688185237e161f877 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 19 Jul 2021 15:51:04 +0300 Subject: [PATCH] Updated resources unit tests --- data/conf/cgrates/cgrates.json | 76 ++++++++++++++++++++++++---------- engine/resources.go | 4 +- engine/z_resources_test.go | 35 ++++++++++------ 3 files changed, 78 insertions(+), 37 deletions(-) diff --git a/data/conf/cgrates/cgrates.json b/data/conf/cgrates/cgrates.json index f714d2952..c85f8c741 100755 --- a/data/conf/cgrates/cgrates.json +++ b/data/conf/cgrates/cgrates.json @@ -289,7 +289,7 @@ // "opts": { // // Partial // // "partialPath": "/", // the path were the partial events will be sent -// // "partialCacheAction": "*none", // the action that will be executed for the partial CSVs that are not matched<*none|*post_cdr|*dump_to_file> +// "partialCacheAction": "*none", // the action that will be executed for the partial CSVs that are not matched<*none|*post_cdr|*dump_to_file> // "partialOrderField": "~*req.AnswerTime", // the field after what the events are order when merged // // "partialcsvFieldSeparator": "," // separator used when dumping the fields @@ -354,6 +354,27 @@ // // "s3FolderPathProcessed": "", // only for S3 event posting // // "s3BucketIDProcessed": "cgrates_cdrs", // the bucket id for S3 readers were the events are sent after they are processed + +// // nats +// // "natsJetStream": false, // controls if the nats reader uses the JetStream +// // "natsConsumerName": "cgrates", // in case of JetStream the name of the consumer +// "natsSubject": "cgrates_cdrs", // the subject from were the events are read +// // "natsQueueID": "", // the queue id the consumer listen to +// // "natsJWTFile": "", // the path to the JWT file( can be the chained file or the user file) +// // "natsSeedFile": "", // the path to the seed files( if the JWT file is mention this is used as seedFile for the JWT user mentioned above) +// // "natsCertificateAuthority": "", // the path to a custom certificate authority file( used by tls) +// // "natsClientCertificate": "", // the path to a client certificate( used by tls) +// // "natsClientKey": "", // the path to a client key( used by tls) +// // "natsJetStreamMaxWait": "5s", // the maximum amount of time to wait for a response + +// // "natsJetStreamProcessed": false, // controls if the nats poster uses the JetStream +// // "natsSubjectProcessed": "cgrates_cdrs", // the subject were the events are posted +// // "natsJWTFileProcessed": "", // the path to the JWT file( can be the chained file or the user file) +// // "natsSeedFileProcessed": "", // the path to the seed files( if the JWT file is mention this is used as seedFile for the JWT user mentioned above) +// // "natsCertificateAuthorityProcessed": "", // the path to a custom certificate authority file( used by tls) +// // "natsClientCertificateProcessed": "", // the path to a client certificate( used by tls) +// // "natsClientKeyProcessed": "", // the path to a client key( used by tls) +// // "natsJetStreamMaxWaitProcessed": "5s ", // the maximum amount of time to wait for a response // }, // "tenant": "", // tenant used by import // "timezone": "", // timezone for timestamps where not specified <""|UTC|Local|$IANA_TZ_DB> @@ -444,6 +465,15 @@ // // "s3BucketID": "cgrates_cdrs", // the bucket id for S3 readers from where the events that are exported // // "s3FolderPath": "", // S3FolderPath +// // Nats +// // "natsJetStream": false, // controls if the nats poster uses the JetStream +// // "natsSubject": "cgrates_cdrs", // the subject were the events are exported +// // "natsJWTFile": "", // the path to the JWT file( can be the chained file or the user file) +// // "natsSeedFile": "", // the path to the seed files( if the JWT file is mention this is used as seedFile for the JWT user mentioned above) +// // "natsCertificateAuthority": "", // the path to a custom certificate authority file( used by tls) +// // "natsClientCertificate": "", // the path to a client certificate( used by tls) +// // "natsClientKey": "", // the path to a client key( used by tls) +// // "natsJetStreamMaxWait": "5s", // the maximum amount of time to wait for a response // }, // extra options for exporter // "timezone": "", // timezone for timestamps where not specified <""|UTC|Local|$IANA_TZ_DB> // "filters": [], // limit parsing based on the filters @@ -679,6 +709,17 @@ // "tp_out_dir": "/var/spool/cgrates/loader/out", // absolute path towards the directory where processed TPs will be moved // "data":[ // data profiles to load // { +// "type": "*filters", // data source type +// "file_name": "Filters.csv", // file name in the tp_in_dir +// "fields": [ +// {"tag": "Tenant", "path": "Tenant", "type": "*variable", "value": "~*req.0", "mandatory": true}, +// {"tag": "ID", "path": "ID", "type": "*variable", "value": "~*req.1", "mandatory": true}, +// {"tag": "Type", "path": "Type", "type": "*variable", "value": "~*req.2"}, +// {"tag": "Element", "path": "Element", "type": "*variable", "value": "~*req.3"}, +// {"tag": "Values", "path": "Values", "type": "*variable", "value": "~*req.4"}, +// ], +// }, +// { // "type": "*attributes", // data source type // "file_name": "Attributes.csv", // file name in the tp_in_dir // "fields": [ @@ -694,17 +735,6 @@ // ], // }, // { -// "type": "*filters", // data source type -// "file_name": "Filters.csv", // file name in the tp_in_dir -// "fields": [ -// {"tag": "Tenant", "path": "Tenant", "type": "*variable", "value": "~*req.0", "mandatory": true}, -// {"tag": "ID", "path": "ID", "type": "*variable", "value": "~*req.1", "mandatory": true}, -// {"tag": "Type", "path": "Type", "type": "*variable", "value": "~*req.2"}, -// {"tag": "Element", "path": "Element", "type": "*variable", "value": "~*req.3"}, -// {"tag": "Values", "path": "Values", "type": "*variable", "value": "~*req.4"}, -// ], -// }, -// { // "type": "*resources", // data source type // "file_name": "Resources.csv", // file name in the tp_in_dir // "fields": [ @@ -972,13 +1002,13 @@ // "rpc":{ // "enabled": false, // "registrars_conns": [], -// "hosts": [], +// "hosts": [], // "refresh_interval": "5m", // }, // "dispatchers":{ // "enabled": false, // "registrars_conns": [], -// "hosts": [], +// "hosts": [], // "refresh_interval": "5m", // }, // }, @@ -1173,15 +1203,15 @@ // "db_user": "", // username to use when connecting to data_db // "db_password": "", // password to use when connecting to data_db // "opts":{ -// "redis_sentinel": "", // the name of sentinel when used -// "redis_cluster": false, // if enabled the datadb will try to connect to the redis cluster -// "redis_cluster_sync": "5s", // the sync interval for the redis cluster -// "redis_cluster_ondown_delay": "0", // the delay before executing the commands if the redis cluster is in the CLUSTERDOWN state -// "query_timeout":"10s", -// "redis_tls": false, // if true it will use a tls connection and use the redis_client_certificate certificate, redis_client_key and redis_ca_certificate for tls connection -// "redis_client_certificate":"", // path to client certificate -// "redis_client_key":"", // path to client key -// "redis_ca_certificate":"", // path to CA certificate (populate for self-signed certificate otherwise let it empty) +// "redisSentinel": "", // the name of sentinel when used +// "redisCluster": false, // if enabled the datadb will try to connect to the redis cluster +// "redisClusterSync": "5s", // the sync interval for the redis cluster +// "redisClusterOndownDelay": "0", // the delay before executing the commands if the redis cluster is in the CLUSTERDOWN state +// "mongoQueryTimeout":"10s", // timeout for query when mongo is used +// "redisTLS": false, // if true it will use a tls connection and use the redisClientCertificate, redisClientKey and redisCACertificate for tls connection +// "redisClientCertificate":"", // path to client certificate +// "redisClientKey":"", // path to client key +// "redisCACertificate":"", // path to CA certificate (populate for self-signed certificate otherwise let it empty) // } // }, diff --git a/engine/resources.go b/engine/resources.go index fec9cf5af..da8ff618d 100644 --- a/engine/resources.go +++ b/engine/resources.go @@ -297,7 +297,7 @@ func (rs Resources) resIDsMp() (mp utils.StringSet) { return mp } -func (rs Resources) tenatIDs() []string { +func (rs Resources) tenantIDs() []string { ids := make([]string, len(rs)) for i, r := range rs { ids[i] = r.TenantID() @@ -453,6 +453,7 @@ func (rS *ResourceService) storeResources(ctx *context.Context) { rIf, ok := Cache.Get(utils.CacheResources, rID) if !ok || rIf == nil { utils.Logger.Warning(fmt.Sprintf("<%s> failed retrieving from cache resource with ID: %s", utils.ResourceS, rID)) + continue } r := rIf.(*Resource) r.lock(utils.EmptyString) @@ -562,7 +563,6 @@ func (rS *ResourceService) matchingResourcesForEvent(ctx *context.Context, tnt s err = errCh } } - return }() } else { // select the resourceIDs out of dataDB diff --git a/engine/z_resources_test.go b/engine/z_resources_test.go index 50d396eb6..f9aab48ef 100644 --- a/engine/z_resources_test.go +++ b/engine/z_resources_test.go @@ -137,7 +137,7 @@ func TestResourceTotalUsage1(t *testing.T) { }, }, } - result := testStruct.totalUsage() + result := testStruct.TotalUsage() if reflect.DeepEqual(3, result) { t.Errorf("\nExpecting <3>,\n Received <%+v>", result) } @@ -433,7 +433,7 @@ func TestResourceUsedUnits(t *testing.T) { ru1.ID: ru1, } r1.tUsage = nil - if usedUnits := r1.totalUsage(); usedUnits != 1 { + if usedUnits := r1.TotalUsage(); usedUnits != 1 { t.Errorf("Expecting: %+v, received: %+v", 1, usedUnits) } } @@ -603,7 +603,7 @@ func TestResourceClearUsage(t *testing.T) { if len(r1.Usages) != 0 { t.Errorf("Expecting: %+v, received: %+v", 0, len(r1.Usages)) } - if r1.totalUsage() != 0 { + if r1.TotalUsage() != 0 { t.Errorf("Expecting: %+v, received: %+v", 0, r1.tUsage) } if err := r2.clearUsage(ru2.ID); err != nil { @@ -1223,6 +1223,7 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { @@ -1236,6 +1237,7 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[1].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[1].ID, mres[0].ID) { @@ -1249,6 +1251,7 @@ func TestResourceMatchingResourcesForEvent(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[2].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[2].ID, mres[0].ID) { @@ -1442,6 +1445,7 @@ func TestResourceUsageTTLCase1(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { @@ -1635,6 +1639,7 @@ func TestResourceUsageTTLCase2(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { @@ -1828,6 +1833,7 @@ func TestResourceUsageTTLCase3(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { @@ -2022,6 +2028,7 @@ func TestResourceUsageTTLCase4(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { @@ -2410,6 +2417,7 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[0].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[0].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[0].ID, mres[0].ID) { @@ -2423,6 +2431,7 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[1].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[1].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[1].ID, mres[0].ID) { @@ -2436,6 +2445,7 @@ func TestResourceMatchWithIndexFalse(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resourceTest[2].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resourceTest[2].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resourceTest[2].ID, mres[0].ID) { @@ -2636,6 +2646,7 @@ func TestResourceCaching(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } + mres.unlock() if !reflect.DeepEqual(resources[0].Tenant, mres[0].Tenant) { t.Errorf("Expecting: %+v, received: %+v", resources[0].Tenant, mres[0].Tenant) } else if !reflect.DeepEqual(resources[0].ID, mres[0].ID) { @@ -3319,7 +3330,7 @@ func TestResourcesProcessThresholdsNoConns(t *testing.T) { } opts := map[string]interface{}{} - err := rS.processThresholds(context.TODO(), r, opts) + err := rS.processThresholds(context.TODO(), Resources{r}, opts) if err != nil { t.Errorf("\nexpected nil, received %+v", err) @@ -3380,7 +3391,7 @@ func TestResourcesProcessThresholdsOK(t *testing.T) { }, } - err := rS.processThresholds(context.TODO(), r, nil) + err := rS.processThresholds(context.TODO(), Resources{r}, nil) if err != nil { t.Errorf("\nexpected nil, received %+v", err) @@ -3454,8 +3465,8 @@ func TestResourcesProcessThresholdsCallErr(t *testing.T) { }, } - experr := utils.ErrExists - err := rS.processThresholds(context.TODO(), r, nil) + experr := utils.ErrPartiallyExecuted + err := rS.processThresholds(context.TODO(), Resources{r}, nil) if err == nil || err != experr { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) @@ -3481,7 +3492,7 @@ func TestResourcesProcessThresholdsThdConnMetaNone(t *testing.T) { } opts := map[string]interface{}{} - err := rS.processThresholds(context.TODO(), r, opts) + err := rS.processThresholds(context.TODO(), Resources{r}, opts) if err != nil { t.Errorf("\nexpected nil, received: %+v", err) @@ -5489,8 +5500,8 @@ func TestResourcesV1AllocateResourcesProcessThErr(t *testing.T) { var reply string if err := rS.V1AllocateResources(context.Background(), args, &reply); err == nil || - err != utils.ErrExists { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrExists, err) + err != utils.ErrPartiallyExecuted { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrPartiallyExecuted, err) } dm.DataDB().Flush(utils.EmptyString) } @@ -6016,8 +6027,8 @@ func TestResourcesV1ReleaseResourcesProcessThErr(t *testing.T) { } if err := rS.V1ReleaseResources(context.Background(), args, &reply); err == nil || - err != utils.ErrExists { - t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrExists, err) + err != utils.ErrPartiallyExecuted { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrPartiallyExecuted, err) } dm.DataDB().Flush(utils.EmptyString)