Files
signoz/pkg/modules/thirdpartyapi/translator_test.go
Nikhil Soni 1a5d37b25a fix: add missing filtering for ip address for scalar data (#10264)
* fix: add missing filtering for ip address for scalar data

In domain listing api for external api monitoring,
we have option to filter out the IP address but
it only handles timeseries and raw type data while
domain list handler returns scalar data.

* fix: switch to new derived attributes for ip filtering

---------

Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>
2026-02-24 10:26:10 +00:00

288 lines
6.6 KiB
Go

package thirdpartyapi
import (
"testing"
"github.com/SigNoz/signoz/pkg/types/thirdpartyapitypes"
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
"github.com/stretchr/testify/assert"
)
func TestFilterResponse(t *testing.T) {
tests := []struct {
name string
input []*qbtypes.QueryRangeResponse
expected []*qbtypes.QueryRangeResponse
}{
{
name: "should filter out IP addresses from series labels",
input: []*qbtypes.QueryRangeResponse{
{
Data: qbtypes.QueryData{
Results: []any{
&qbtypes.TimeSeriesData{
Aggregations: []*qbtypes.AggregationBucket{
{
Series: []*qbtypes.TimeSeries{
{
Labels: []*qbtypes.Label{
{
Key: telemetrytypes.TelemetryFieldKey{Name: derivedKeyHTTPHost},
Value: "192.168.1.1",
},
},
},
{
Labels: []*qbtypes.Label{
{
Key: telemetrytypes.TelemetryFieldKey{Name: derivedKeyHTTPHost},
Value: "example.com",
},
},
},
},
},
},
},
},
},
},
},
expected: []*qbtypes.QueryRangeResponse{
{
Data: qbtypes.QueryData{
Results: []any{
&qbtypes.TimeSeriesData{
Aggregations: []*qbtypes.AggregationBucket{
{
Series: []*qbtypes.TimeSeries{
{
Labels: []*qbtypes.Label{
{
Key: telemetrytypes.TelemetryFieldKey{Name: derivedKeyHTTPHost},
Value: "example.com",
},
},
},
},
},
},
},
},
},
},
},
},
{
name: "should filter out IP addresses from raw data",
input: []*qbtypes.QueryRangeResponse{
{
Data: qbtypes.QueryData{
Results: []any{
&qbtypes.RawData{
Rows: []*qbtypes.RawRow{
{
Data: map[string]any{
derivedKeyHTTPHost: "192.168.1.1",
},
},
{
Data: map[string]any{
derivedKeyHTTPHost: "example.com",
},
},
},
},
},
},
},
},
expected: []*qbtypes.QueryRangeResponse{
{
Data: qbtypes.QueryData{
Results: []any{
&qbtypes.RawData{
Rows: []*qbtypes.RawRow{
{
Data: map[string]any{
derivedKeyHTTPHost: "example.com",
},
},
},
},
},
},
},
},
},
{
name: "should filter out IP addresses from scalar data",
input: []*qbtypes.QueryRangeResponse{
{
Data: qbtypes.QueryData{
Results: []any{
&qbtypes.ScalarData{
QueryName: "endpoints",
Columns: []*qbtypes.ColumnDescriptor{
{
TelemetryFieldKey: telemetrytypes.TelemetryFieldKey{Name: derivedKeyHTTPHost},
Type: qbtypes.ColumnTypeGroup,
},
{
TelemetryFieldKey: telemetrytypes.TelemetryFieldKey{Name: "endpoints"},
Type: qbtypes.ColumnTypeAggregation,
},
},
Data: [][]any{
{"192.168.1.1", 10},
{"example.com", 20},
{"10.0.0.1", 5},
},
},
},
},
},
},
expected: []*qbtypes.QueryRangeResponse{
{
Data: qbtypes.QueryData{
Results: []any{
&qbtypes.ScalarData{
QueryName: "endpoints",
Columns: []*qbtypes.ColumnDescriptor{
{
TelemetryFieldKey: telemetrytypes.TelemetryFieldKey{Name: derivedKeyHTTPHost},
Type: qbtypes.ColumnTypeGroup,
},
{
TelemetryFieldKey: telemetrytypes.TelemetryFieldKey{Name: "endpoints"},
Type: qbtypes.ColumnTypeAggregation,
},
},
Data: [][]any{
{"example.com", 20},
},
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := FilterResponse(tt.input)
assert.Equal(t, tt.expected, result)
})
}
}
func TestList(t *testing.T) {
tests := []struct {
name string
input *thirdpartyapitypes.ThirdPartyApiRequest
wantErr bool
}{
{
name: "basic domain list query",
input: &thirdpartyapitypes.ThirdPartyApiRequest{
Start: 1000,
End: 2000,
},
wantErr: false,
},
{
name: "with filters and group by",
input: &thirdpartyapitypes.ThirdPartyApiRequest{
Start: 1000,
End: 2000,
Filter: &qbtypes.Filter{
Expression: "test = 'value'",
},
GroupBy: []qbtypes.GroupByKey{
{
TelemetryFieldKey: telemetrytypes.TelemetryFieldKey{
Name: "test",
},
},
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := BuildDomainList(tt.input)
if tt.wantErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, tt.input.Start, result.Start)
assert.Equal(t, tt.input.End, result.End)
assert.NotNil(t, result.CompositeQuery)
assert.Len(t, result.CompositeQuery.Queries, 7) // endpoints, lastseen, rps, error, total_span, p99, error_rate
assert.Equal(t, "v5", result.SchemaVersion)
assert.Equal(t, qbtypes.RequestTypeScalar, result.RequestType)
})
}
}
func TestBuildDomainInfo(t *testing.T) {
tests := []struct {
name string
input *thirdpartyapitypes.ThirdPartyApiRequest
wantErr bool
}{
{
name: "basic domain info query",
input: &thirdpartyapitypes.ThirdPartyApiRequest{
Start: 1000,
End: 2000,
},
wantErr: false,
},
{
name: "with filters and group by",
input: &thirdpartyapitypes.ThirdPartyApiRequest{
Start: 1000,
End: 2000,
Filter: &qbtypes.Filter{
Expression: "test = 'value'",
},
GroupBy: []qbtypes.GroupByKey{
{
TelemetryFieldKey: telemetrytypes.TelemetryFieldKey{
Name: "test",
},
},
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := BuildDomainInfo(tt.input)
if tt.wantErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, tt.input.Start, result.Start)
assert.Equal(t, tt.input.End, result.End)
assert.NotNil(t, result.CompositeQuery)
assert.Len(t, result.CompositeQuery.Queries, 4) // endpoints, p99, error_rate, lastseen
assert.Equal(t, "v5", result.SchemaVersion)
assert.Equal(t, qbtypes.RequestTypeScalar, result.RequestType)
})
}
}