diff --git a/ees/filecsv_test.go b/ees/filecsv_test.go index a31c78b07..1aa06a45e 100644 --- a/ees/filecsv_test.go +++ b/ees/filecsv_test.go @@ -61,6 +61,7 @@ type nopCloser struct { } func (nopCloser) Close() error { return nil } + func TestFileCsvComposeHeader(t *testing.T) { cgrCfg := config.NewDefaultCGRConfig() newIDb := engine.NewInternalDB(nil, nil, true) @@ -269,5 +270,72 @@ func TestFileCsvExportEvent(t *testing.T) { if err := fCsv.ExportEvent(cgrEv); err == nil || err.Error() != errExpect { t.Errorf("Expected %q but received %q", errExpect, err) } +} + +func TestFileCsvOnEvictedTrailer(t *testing.T) { + cgrCfg := config.NewDefaultCGRConfig() + newIDb := engine.NewInternalDB(nil, nil, true) + newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) + filterS := engine.NewFilterS(cgrCfg, nil, newDM) + byteBuff := new(bytes.Buffer) + csvNW := csv.NewWriter(byteBuff) + fCsv := &FileCSVee{ + id: "string", + cgrCfg: cgrCfg, + cfgIdx: 0, + filterS: filterS, + file: nopCloserWrite{byteBuff}, + csvWriter: csvNW, + dc: utils.MapStorage{}, + } + cgrCfg.EEsCfg().Exporters[fCsv.cfgIdx].Fields = []*config.FCTemplate{ + { + Path: "*trl.1", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field1", utils.InfieldSep), + Filters: []string{"*wrong-type"}, + }, + { + Path: "*trl.2", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field2", utils.InfieldSep), + Filters: []string{"*wrong-type"}, + }, + } + for _, field := range cgrCfg.EEsCfg().Exporters[fCsv.cfgIdx].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[fCsv.cfgIdx].ComputeFields() + fCsv.OnEvicted("test", "test") +} + +func TestFileCsvOnEvictedClose(t *testing.T) { + cgrCfg := config.NewDefaultCGRConfig() + newIDb := engine.NewInternalDB(nil, nil, true) + newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) + filterS := engine.NewFilterS(cgrCfg, nil, newDM) + byteBuff := new(bytes.Buffer) + csvNW := csv.NewWriter(byteBuff) + fCsv := &FileCSVee{ + id: "string", + cgrCfg: cgrCfg, + cfgIdx: 0, + filterS: filterS, + file: nopCloserError{byteBuff}, + csvWriter: csvNW, + dc: utils.MapStorage{}, + } + cgrCfg.EEsCfg().Exporters[fCsv.cfgIdx].Fields = []*config.FCTemplate{ + { + Path: "*trl.1", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field1", utils.InfieldSep), + }, + { + Path: "*trl.2", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field2", utils.InfieldSep), + }, + } + for _, field := range cgrCfg.EEsCfg().Exporters[fCsv.cfgIdx].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[fCsv.cfgIdx].ComputeFields() fCsv.OnEvicted("test", "test") } diff --git a/ees/filefwv_test.go b/ees/filefwv_test.go index eb7020e38..343d8a510 100644 --- a/ees/filefwv_test.go +++ b/ees/filefwv_test.go @@ -21,6 +21,7 @@ package ees import ( "bytes" "encoding/csv" + "io" "reflect" "testing" @@ -125,7 +126,6 @@ func TestFileFwvComposeHeader(t *testing.T) { if err := fFwv.composeHeader(); err == nil || err.Error() != errExpect { t.Errorf("Expected %q but received %q", errExpect, err) } - } func TestFileFwvComposeTrailer(t *testing.T) { @@ -270,3 +270,182 @@ func TestFileFwvExportEvent(t *testing.T) { t.Errorf("Expected %q but received %q", errExpect, err) } } + +type nopCloserWrite struct { + io.Writer +} + +func (nopCloserWrite) Close() error { return nil } +func (nopCloserWrite) Write(s []byte) (n int, err error) { + return 0, utils.ErrNotImplemented +} + +func TestFileFwvExportEventWriteError(t *testing.T) { + cgrCfg := config.NewDefaultCGRConfig() + cgrEv := new(utils.CGREvent) + newIDb := engine.NewInternalDB(nil, nil, true) + newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) + filterS := engine.NewFilterS(cgrCfg, nil, newDM) + byteBuff := new(bytes.Buffer) + dc, err := newEEMetrics(utils.FirstNonEmpty( + "Local", + utils.EmptyString, + )) + if err != nil { + t.Error(err) + } + fFwv := &FileFWVee{ + id: "string", + cgrCfg: cgrCfg, + cfgIdx: 0, + filterS: filterS, + file: nopCloserWrite{byteBuff}, + dc: dc, + } + cgrEv.Event = map[string]interface{}{ + "test1": "value", + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields = []*config.FCTemplate{{}} + for _, field := range cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].ComputeFields() + if err := fFwv.ExportEvent(cgrEv); err == nil || err != utils.ErrNotImplemented { + t.Errorf("Expected %q but received %q", utils.ErrNotImplemented, err) + } +} + +func TestFileFwvComposeHeaderWriteError(t *testing.T) { + cgrCfg := config.NewDefaultCGRConfig() + newIDb := engine.NewInternalDB(nil, nil, true) + newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) + filterS := engine.NewFilterS(cgrCfg, nil, newDM) + byteBuff := new(bytes.Buffer) + fFwv := &FileFWVee{ + id: "string", + cgrCfg: cgrCfg, + cfgIdx: 0, + filterS: filterS, + file: nopCloserWrite{byteBuff}, + dc: utils.MapStorage{}, + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields = []*config.FCTemplate{ + { + Path: "*hdr.1", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field1", utils.InfieldSep), + }, + { + Path: "*hdr.2", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field2", utils.InfieldSep), + }, + } + for _, field := range cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].ComputeFields() + if err := fFwv.composeHeader(); err == nil || err != utils.ErrNotImplemented { + t.Errorf("Expected %q but received %q", utils.ErrNotImplemented, err) + } +} + +func TestFileFwvComposeTrailerWriteError(t *testing.T) { + cgrCfg := config.NewDefaultCGRConfig() + newIDb := engine.NewInternalDB(nil, nil, true) + newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) + filterS := engine.NewFilterS(cgrCfg, nil, newDM) + byteBuff := new(bytes.Buffer) + fFwv := &FileFWVee{ + id: "string", + cgrCfg: cgrCfg, + cfgIdx: 0, + filterS: filterS, + file: nopCloserWrite{byteBuff}, + dc: utils.MapStorage{}, + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields = []*config.FCTemplate{ + { + Path: "*trl.1", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field1", utils.InfieldSep), + }, + { + Path: "*trl.2", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field2", utils.InfieldSep), + }, + } + for _, field := range cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].ComputeFields() + if err := fFwv.composeTrailer(); err == nil || err != utils.ErrNotImplemented { + t.Errorf("Expected %q but received %q", utils.ErrNotImplemented, err) + } +} +func TestFileFwvOnEvictedTrailer(t *testing.T) { + cgrCfg := config.NewDefaultCGRConfig() + newIDb := engine.NewInternalDB(nil, nil, true) + newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) + filterS := engine.NewFilterS(cgrCfg, nil, newDM) + byteBuff := new(bytes.Buffer) + fFwv := &FileFWVee{ + id: "string", + cgrCfg: cgrCfg, + cfgIdx: 0, + filterS: filterS, + file: nopCloserWrite{byteBuff}, + dc: utils.MapStorage{}, + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields = []*config.FCTemplate{ + { + Path: "*trl.1", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field1", utils.InfieldSep), + }, + { + Path: "*trl.2", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field2", utils.InfieldSep), + }, + } + for _, field := range cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].ComputeFields() + fFwv.OnEvicted("test", "test") +} + +type nopCloserError struct { + io.Writer +} + +func (nopCloserError) Close() error { return utils.ErrNotImplemented } +func (nopCloserError) Write(s []byte) (n int, err error) { + return 0, utils.ErrNotImplemented +} +func TestFileFwvOnEvictedClose(t *testing.T) { + cgrCfg := config.NewDefaultCGRConfig() + newIDb := engine.NewInternalDB(nil, nil, true) + newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) + filterS := engine.NewFilterS(cgrCfg, nil, newDM) + byteBuff := new(bytes.Buffer) + fFwv := &FileFWVee{ + id: "string", + cgrCfg: cgrCfg, + cfgIdx: 0, + filterS: filterS, + file: nopCloserError{byteBuff}, + dc: utils.MapStorage{}, + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields = []*config.FCTemplate{ + { + Path: "*trl.1", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field1", utils.InfieldSep), + }, + { + Path: "*trl.2", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("field2", utils.InfieldSep), + }, + } + for _, field := range cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[fFwv.cfgIdx].ComputeFields() + fFwv.OnEvicted("test", "test") +} diff --git a/ees/httpjsonmap_test.go b/ees/httpjsonmap_test.go index 25f8e87a9..5a42e1139 100644 --- a/ees/httpjsonmap_test.go +++ b/ees/httpjsonmap_test.go @@ -19,6 +19,9 @@ along with this program. If not, see package ees import ( + "encoding/json" + "net/http" + "net/http/httptest" "reflect" "testing" @@ -53,7 +56,7 @@ func TestHttpJsonMapGetMetrics(t *testing.T) { } } -func TestHttpJsonMapExportEvent(t *testing.T) { +func TestHttpJsonMapExportEvent1(t *testing.T) { cgrCfg := config.NewDefaultCGRConfig() cgrCfg.EEsCfg().Exporters[0].Type = utils.MetaSQSjsonMap cgrEv := new(utils.CGREvent) @@ -139,9 +142,78 @@ func TestHttpJsonMapExportEvent(t *testing.T) { if err := httpEE.ExportEvent(cgrEv); err == nil || err.Error() != errExpect { t.Errorf("Expected %q but received %q", errExpect, err) } + //test marshal invalid input + cgrEv.Event = map[string]interface{}{ + "test": make(chan int), + } + cgrCfg.EEsCfg().Exporters[0].Fields = []*config.FCTemplate{{}} + for _, field := range cgrCfg.EEsCfg().Exporters[0].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[0].ComputeFields() + errExpect = "json: unsupported type: chan int" + if err := httpEE.ExportEvent(cgrEv); err == nil || err.Error() != errExpect { + t.Errorf("Expected %q but received %q", errExpect, err) + } httpEE.OnEvicted("test", "test") } +func TestHttpJsonMapExportEvent2(t *testing.T) { + cgrCfg := config.NewDefaultCGRConfig() + cgrCfg.EEsCfg().Exporters[0].Type = utils.MetaSQSjsonMap + cgrEv := new(utils.CGREvent) + newIDb := engine.NewInternalDB(nil, nil, true) + newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) + filterS := engine.NewFilterS(cgrCfg, nil, newDM) + dc, err := newEEMetrics(utils.FirstNonEmpty( + "Local", + utils.EmptyString, + )) + if err != nil { + t.Error(err) + } + bodyExpect := map[string]interface{}{ + "2": "*req.field2", + } + srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + defer r.Body.Close() + var body map[string]interface{} + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(body, bodyExpect) { + t.Errorf("Expected %q but received %q", bodyExpect, body) + } + rw.WriteHeader(http.StatusOK) + })) + defer srv.Close() + cgrCfg.EEsCfg().Exporters[0].ExportPath = srv.URL + "/" + httpEE, err := NewHTTPjsonMapEE(cgrCfg, 0, filterS, dc) + if err != nil { + t.Error(err) + } + cgrEv.Event = map[string]interface{}{ + "test": "string", + } + cgrCfg.EEsCfg().Exporters[0].Fields = []*config.FCTemplate{ + { + Path: "*exp.1", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("~*req.field1", utils.InfieldSep), + }, + { + Path: "*exp.2", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("*req.field2", utils.InfieldSep), + }, + } + for _, field := range cgrCfg.EEsCfg().Exporters[0].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[0].ComputeFields() + if err := httpEE.ExportEvent(cgrEv); err != nil { + t.Error(err) + } +} + func TestHttpJsonMapComposeHeader(t *testing.T) { cgrCfg := config.NewDefaultCGRConfig() cgrCfg.EEsCfg().Exporters[0].Type = utils.MetaHTTPjson diff --git a/ees/httppost_test.go b/ees/httppost_test.go index da64b71e7..f4d78d186 100644 --- a/ees/httppost_test.go +++ b/ees/httppost_test.go @@ -19,6 +19,9 @@ along with this program. If not, see package ees import ( + "io" + "net/http" + "net/http/httptest" "reflect" "testing" @@ -141,6 +144,65 @@ func TestHttpPostExportEvent(t *testing.T) { httpPost.OnEvicted("test", "test") } +func TestHttpPostExportEvent2(t *testing.T) { + cgrCfg := config.NewDefaultCGRConfig() + cgrCfg.EEsCfg().Exporters[0].Type = utils.MetaHTTPPost + cgrEv := new(utils.CGREvent) + newIDb := engine.NewInternalDB(nil, nil, true) + newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) + filterS := engine.NewFilterS(cgrCfg, nil, newDM) + dc, err := newEEMetrics(utils.FirstNonEmpty( + "Local", + utils.EmptyString, + )) + if err != nil { + t.Error(err) + } + // hdrExpect := map[string][]string { + // "Accept-Encoding": []string{"gzip"}, + // "Content-Type": []string{"application/x-www-form-urlencoded"}, + + // } + bodyExpect := "2=%2Areq.field2" + srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + defer r.Body.Close() + body, err := io.ReadAll(r.Body) + if err != nil { + t.Error(err) + } + if strBody := string(body); strBody != bodyExpect { + t.Errorf("Expected %q but received %q", bodyExpect, strBody) + } + rw.WriteHeader(http.StatusOK) + })) + defer srv.Close() + cgrCfg.EEsCfg().Exporters[0].ExportPath = srv.URL + "/" + httpPost, err := NewHTTPPostEe(cgrCfg, 0, filterS, dc) + if err != nil { + t.Error(err) + } + cgrEv.Event = map[string]interface{}{ + "test": "string", + } + cgrCfg.EEsCfg().Exporters[0].Fields = []*config.FCTemplate{ + { + Path: "*exp.1", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("~*req.field1", utils.InfieldSep), + }, + { + Path: "*exp.2", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("*req.field2", utils.InfieldSep), + }, + } + for _, field := range cgrCfg.EEsCfg().Exporters[0].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[0].ComputeFields() + if err := httpPost.ExportEvent(cgrEv); err != nil { + t.Error(err) + } +} + func TestHttpPostComposeHeader(t *testing.T) { cgrCfg := config.NewDefaultCGRConfig() cgrCfg.EEsCfg().Exporters[0].Type = utils.MetaHTTPPost diff --git a/ees/posterjsonmap_test.go b/ees/posterjsonmap_test.go index 02921cbeb..6f6b290c2 100644 --- a/ees/posterjsonmap_test.go +++ b/ees/posterjsonmap_test.go @@ -205,5 +205,71 @@ func TestPosterJsonMapExportEvent(t *testing.T) { if err := pstrEE.ExportEvent(cgrEv); err == nil || err.Error() != errExpect { t.Errorf("Expected %q but received %q", errExpect, err) } + //test marshal invalid input + cgrEv.Event = map[string]interface{}{ + "test": make(chan int), + } + cgrCfg.EEsCfg().Exporters[0].Fields = []*config.FCTemplate{{}} + for _, field := range cgrCfg.EEsCfg().Exporters[0].Fields { + field.ComputePath() + } + cgrCfg.EEsCfg().Exporters[0].ComputeFields() + errExpect = "json: unsupported type: chan int" + if err := pstrEE.ExportEvent(cgrEv); err == nil || err.Error() != errExpect { + t.Errorf("Expected %q but received %q", errExpect, err) + } pstrEE.OnEvicted("test", "test") } + +// func TestPosterJsonMapExportEvent2(t *testing.T) { +// cgrCfg := config.NewDefaultCGRConfig() +// cgrCfg.EEsCfg().Exporters[0].Type = utils.MetaSQSjsonMap +// cgrEv := new(utils.CGREvent) +// newIDb := engine.NewInternalDB(nil, nil, true) +// newDM := engine.NewDataManager(newIDb, cgrCfg.CacheCfg(), nil) +// filterS := engine.NewFilterS(cgrCfg, nil, newDM) +// dc, err := newEEMetrics(utils.FirstNonEmpty( +// "Local", +// utils.EmptyString, +// )) +// if err != nil { +// t.Error(err) +// } +// srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { +// defer r.Body.Close() +// // body, err := io.ReadAll(r.Body) +// // if err != nil { +// // t.Error(err) +// // } +// // if strBody := string(body); strBody != bodyExpect { +// // t.Errorf("Expected %q but received %q", bodyExpect, strBody) +// // } +// rw.WriteHeader(http.StatusOK) +// })) +// defer srv.Close() +// cgrCfg.EEsCfg().Exporters[0].ExportPath = srv.URL + "/" +// pstrEE, err := NewPosterJSONMapEE(cgrCfg, 0, filterS, dc) +// if err != nil { +// t.Error(err) +// } +// cgrEv.Event = map[string]interface{}{ +// "test": "string", +// } +// cgrCfg.EEsCfg().Exporters[pstrEE.cfgIdx].Fields = []*config.FCTemplate{ +// { +// Path: "*exp.1", Type: utils.MetaVariable, +// Value: config.NewRSRParsersMustCompile("~*req.field1", utils.InfieldSep), +// }, +// { +// Path: "*exp.2", Type: utils.MetaVariable, +// Value: config.NewRSRParsersMustCompile("*req.field2", utils.InfieldSep), +// }, +// } +// for _, field := range cgrCfg.EEsCfg().Exporters[pstrEE.cfgIdx].Fields { +// field.ComputePath() +// } +// cgrCfg.EEsCfg().Exporters[pstrEE.cfgIdx].ComputeFields() +// if err := pstrEE.ExportEvent(cgrEv); err != nil { +// t.Error(err) +// } +// } diff --git a/ees/sql_test.go b/ees/sql_test.go index 8f7a1d5c0..e9092732b 100644 --- a/ees/sql_test.go +++ b/ees/sql_test.go @@ -1,5 +1,3 @@ -// +build integration - /* Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments Copyright (C) ITsysCOM GmbH @@ -48,7 +46,7 @@ func TestSqlGetMetrics(t *testing.T) { dc: dc, } - if rcv := sqlEe.ID(); !reflect.DeepEqual(rcv, "3") { - t.Errorf("Expected %+v but got %+v", "3", rcv) + if rcv := sqlEe.GetMetrics(); !reflect.DeepEqual(rcv, sqlEe.dc) { + t.Errorf("Expected %+v but got %+v", utils.ToJSON(rcv), utils.ToJSON(sqlEe.dc)) } }