mirror of
https://github.com/hanzoai/otel-collector.git
synced 2026-11-03 02:20:04 +00:00
697 lines
18 KiB
Go
697 lines
18 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package clickhousemetricsexporter
|
|
|
|
import (
|
|
"context"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/gogo/protobuf/proto"
|
|
"github.com/golang/snappy"
|
|
"github.com/prometheus/prometheus/model/value"
|
|
"github.com/prometheus/prometheus/prompb"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.opentelemetry.io/collector/component"
|
|
"go.opentelemetry.io/collector/component/componenttest"
|
|
"go.opentelemetry.io/collector/config/confighttp"
|
|
"go.opentelemetry.io/collector/config/configtls"
|
|
"go.opentelemetry.io/collector/exporter"
|
|
"go.opentelemetry.io/collector/exporter/exporterhelper"
|
|
"go.opentelemetry.io/collector/exporter/exportertest"
|
|
"go.opentelemetry.io/collector/pdata/pmetric"
|
|
|
|
"github.com/SigNoz/signoz-otel-collector/exporter/clickhousemetricsexporter/testdata"
|
|
)
|
|
|
|
// Test_NewPRWExporter checks that a new exporter instance with non-nil fields is initialized
|
|
// FIXME(srikanthccv): Enable the tests once this issue is fixed: https://github.com/SigNoz/signoz-otel-collector/issues/65
|
|
func skip_Test_NewPRWExporter(t *testing.T) {
|
|
cfg := &Config{
|
|
TimeoutSettings: exporterhelper.TimeoutSettings{},
|
|
RetrySettings: exporterhelper.RetrySettings{},
|
|
Namespace: "",
|
|
ExternalLabels: map[string]string{},
|
|
HTTPClientSettings: confighttp.HTTPClientSettings{Endpoint: ""},
|
|
}
|
|
buildInfo := component.BuildInfo{
|
|
Description: "OpenTelemetry Collector",
|
|
Version: "1.0",
|
|
}
|
|
set := exportertest.NewNopCreateSettings()
|
|
set.BuildInfo = buildInfo
|
|
|
|
tests := []struct {
|
|
name string
|
|
config *Config
|
|
namespace string
|
|
endpoint string
|
|
concurrency int
|
|
externalLabels map[string]string
|
|
returnErrorOnCreate bool
|
|
set exporter.CreateSettings
|
|
}{
|
|
{
|
|
name: "invalid_URL",
|
|
config: cfg,
|
|
namespace: "test",
|
|
endpoint: "invalid URL",
|
|
concurrency: 5,
|
|
externalLabels: map[string]string{"Key1": "Val1"},
|
|
returnErrorOnCreate: true,
|
|
set: set,
|
|
},
|
|
{
|
|
name: "invalid_labels_case",
|
|
config: cfg,
|
|
namespace: "test",
|
|
endpoint: "http://some.url:9411/api/prom/push",
|
|
concurrency: 5,
|
|
externalLabels: map[string]string{"Key1": ""},
|
|
returnErrorOnCreate: true,
|
|
set: set,
|
|
},
|
|
{
|
|
name: "success_case",
|
|
config: cfg,
|
|
namespace: "test",
|
|
endpoint: "http://some.url:9411/api/prom/push",
|
|
concurrency: 5,
|
|
externalLabels: map[string]string{"Key1": "Val1"},
|
|
set: set,
|
|
},
|
|
{
|
|
name: "success_case_no_labels",
|
|
config: cfg,
|
|
namespace: "test",
|
|
endpoint: "http://some.url:9411/api/prom/push",
|
|
concurrency: 5,
|
|
externalLabels: map[string]string{},
|
|
set: set,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cfg.HTTPClientSettings.Endpoint = tt.endpoint
|
|
cfg.ExternalLabels = tt.externalLabels
|
|
cfg.Namespace = tt.namespace
|
|
cfg.RemoteWriteQueue.NumConsumers = 1
|
|
prwe, err := NewPrwExporter(cfg, tt.set)
|
|
|
|
if tt.returnErrorOnCreate {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, prwe)
|
|
assert.NotNil(t, prwe.namespace)
|
|
assert.NotNil(t, prwe.endpointURL)
|
|
assert.NotNil(t, prwe.externalLabels)
|
|
assert.NotNil(t, prwe.closeChan)
|
|
assert.NotNil(t, prwe.wg)
|
|
assert.NotNil(t, prwe.userAgentHeader)
|
|
assert.NotNil(t, prwe.clientSettings)
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test_Start checks if the client is properly created as expected.
|
|
// FIXME(srikanthccv): Enable the tests once this issue is fixed: https://github.com/SigNoz/signoz-otel-collector/issues/65
|
|
func skip_Test_Start(t *testing.T) {
|
|
cfg := &Config{
|
|
TimeoutSettings: exporterhelper.TimeoutSettings{},
|
|
RetrySettings: exporterhelper.RetrySettings{},
|
|
Namespace: "",
|
|
ExternalLabels: map[string]string{},
|
|
}
|
|
buildInfo := component.BuildInfo{
|
|
Description: "OpenTelemetry Collector",
|
|
Version: "1.0",
|
|
}
|
|
set := exportertest.NewNopCreateSettings()
|
|
set.BuildInfo = buildInfo
|
|
tests := []struct {
|
|
name string
|
|
config *Config
|
|
namespace string
|
|
concurrency int
|
|
externalLabels map[string]string
|
|
returnErrorOnStartUp bool
|
|
set exporter.CreateSettings
|
|
endpoint string
|
|
clientSettings confighttp.HTTPClientSettings
|
|
}{
|
|
{
|
|
name: "success_case",
|
|
config: cfg,
|
|
namespace: "test",
|
|
concurrency: 5,
|
|
externalLabels: map[string]string{"Key1": "Val1"},
|
|
set: set,
|
|
clientSettings: confighttp.HTTPClientSettings{Endpoint: "https://some.url:9411/api/prom/push"},
|
|
},
|
|
{
|
|
name: "invalid_tls",
|
|
config: cfg,
|
|
namespace: "test",
|
|
concurrency: 5,
|
|
externalLabels: map[string]string{"Key1": "Val1"},
|
|
set: set,
|
|
returnErrorOnStartUp: true,
|
|
clientSettings: confighttp.HTTPClientSettings{
|
|
Endpoint: "https://some.url:9411/api/prom/push",
|
|
TLSSetting: configtls.TLSClientSetting{
|
|
TLSSetting: configtls.TLSSetting{
|
|
CAFile: "non-existent file",
|
|
CertFile: "",
|
|
KeyFile: "",
|
|
},
|
|
Insecure: false,
|
|
ServerName: "",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cfg.ExternalLabels = tt.externalLabels
|
|
cfg.Namespace = tt.namespace
|
|
cfg.RemoteWriteQueue.NumConsumers = 1
|
|
cfg.HTTPClientSettings = tt.clientSettings
|
|
|
|
prwe, err := NewPrwExporter(cfg, tt.set)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, prwe)
|
|
|
|
err = prwe.Start(context.Background(), componenttest.NewNopHost())
|
|
if tt.returnErrorOnStartUp {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
assert.NotNil(t, prwe.client)
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test_Shutdown checks after Shutdown is called, incoming calls to PushMetrics return error.
|
|
func Test_Shutdown(t *testing.T) {
|
|
prwe := &PrwExporter{
|
|
wg: new(sync.WaitGroup),
|
|
closeChan: make(chan struct{}),
|
|
}
|
|
wg := new(sync.WaitGroup)
|
|
err := prwe.Shutdown(context.Background())
|
|
require.NoError(t, err)
|
|
errChan := make(chan error, 5)
|
|
for i := 0; i < 5; i++ {
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
errChan <- prwe.PushMetrics(context.Background(), pmetric.NewMetrics())
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
close(errChan)
|
|
for ok := range errChan {
|
|
assert.Error(t, ok)
|
|
}
|
|
}
|
|
|
|
// Test whether or not the Server receives the correct TimeSeries.
|
|
// Currently considering making this test an iterative for loop of multiple TimeSeries much akin to Test_PushMetrics
|
|
func temp_disable_Test_export(t *testing.T) {
|
|
// First we will instantiate a dummy TimeSeries instance to pass into both the export call and compare the http request
|
|
labels := getPromLabels(label11, value11, label12, value12, label21, value21, label22, value22)
|
|
sample1 := getSample(floatVal1, msTime1)
|
|
sample2 := getSample(floatVal2, msTime2)
|
|
ts1 := getTimeSeries(labels, sample1, sample2)
|
|
handleFunc := func(w http.ResponseWriter, r *http.Request, code int) {
|
|
// The following is a handler function that reads the sent httpRequest, unmarshal, and checks if the WriteRequest
|
|
// preserves the TimeSeries data correctly
|
|
body, err := ioutil.ReadAll(r.Body)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
require.NotNil(t, body)
|
|
// Receives the http requests and unzip, unmarshalls, and extracts TimeSeries
|
|
assert.Equal(t, "0.1.0", r.Header.Get("X-Prometheus-Remote-Write-Version"))
|
|
assert.Equal(t, "snappy", r.Header.Get("Content-Encoding"))
|
|
assert.Equal(t, "opentelemetry-collector/1.0", r.Header.Get("User-Agent"))
|
|
writeReq := &prompb.WriteRequest{}
|
|
unzipped := []byte{}
|
|
|
|
dest, err := snappy.Decode(unzipped, body)
|
|
require.NoError(t, err)
|
|
|
|
ok := proto.Unmarshal(dest, writeReq)
|
|
require.NoError(t, ok)
|
|
|
|
assert.EqualValues(t, 1, len(writeReq.Timeseries))
|
|
require.NotNil(t, writeReq.GetTimeseries())
|
|
assert.Equal(t, *ts1, writeReq.GetTimeseries()[0])
|
|
w.WriteHeader(code)
|
|
}
|
|
|
|
// Create in test table format to check if different HTTP response codes or server errors
|
|
// are properly identified
|
|
tests := []struct {
|
|
name string
|
|
ts prompb.TimeSeries
|
|
serverUp bool
|
|
httpResponseCode int
|
|
returnErrorOnCreate bool
|
|
}{
|
|
{"success_case",
|
|
*ts1,
|
|
true,
|
|
http.StatusAccepted,
|
|
false,
|
|
},
|
|
{
|
|
"server_no_response_case",
|
|
*ts1,
|
|
false,
|
|
http.StatusAccepted,
|
|
true,
|
|
}, {
|
|
"error_status_code_case",
|
|
*ts1,
|
|
true,
|
|
http.StatusForbidden,
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if handleFunc != nil {
|
|
handleFunc(w, r, tt.httpResponseCode)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
serverURL, uErr := url.Parse(server.URL)
|
|
assert.NoError(t, uErr)
|
|
if !tt.serverUp {
|
|
server.Close()
|
|
}
|
|
errs := runExportPipeline(ts1, serverURL)
|
|
if tt.returnErrorOnCreate {
|
|
assert.Error(t, errs[0])
|
|
return
|
|
}
|
|
assert.Len(t, errs, 0)
|
|
})
|
|
}
|
|
}
|
|
|
|
func runExportPipeline(ts *prompb.TimeSeries, endpoint *url.URL) []error {
|
|
var errs []error
|
|
|
|
// First we will construct a TimeSeries array from the testutils package
|
|
testmap := make(map[string]*prompb.TimeSeries)
|
|
testmap["test"] = ts
|
|
|
|
cfg := createDefaultConfig().(*Config)
|
|
cfg.HTTPClientSettings.Endpoint = endpoint.String()
|
|
cfg.RemoteWriteQueue.NumConsumers = 1
|
|
|
|
buildInfo := component.BuildInfo{
|
|
Description: "OpenTelemetry Collector",
|
|
Version: "1.0",
|
|
}
|
|
set := exportertest.NewNopCreateSettings()
|
|
set.BuildInfo = buildInfo
|
|
// after this, instantiate a CortexExporter with the current HTTP client and endpoint set to passed in endpoint
|
|
prwe, err := NewPrwExporter(cfg, set)
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
return errs
|
|
}
|
|
|
|
if err = prwe.Start(context.Background(), componenttest.NewNopHost()); err != nil {
|
|
errs = append(errs, err)
|
|
return errs
|
|
}
|
|
|
|
errs = append(errs, prwe.export(context.Background(), testmap)...)
|
|
return errs
|
|
}
|
|
|
|
// Test_PushMetrics checks the number of TimeSeries received by server and the number of metrics dropped is the same as
|
|
// expected
|
|
func temp_dis_Test_PushMetrics(t *testing.T) {
|
|
|
|
invalidTypeBatch := testdata.GenerateMetricsMetricTypeInvalid()
|
|
|
|
// success cases
|
|
intSumBatch := testdata.GenerateMetricsManyMetricsSameResource(10)
|
|
|
|
sumBatch := getMetricsFromMetricList(validMetrics1[validSum], validMetrics2[validSum])
|
|
|
|
intGaugeBatch := getMetricsFromMetricList(validMetrics1[validIntGauge], validMetrics2[validIntGauge])
|
|
|
|
doubleGaugeBatch := getMetricsFromMetricList(validMetrics1[validDoubleGauge], validMetrics2[validDoubleGauge])
|
|
|
|
histogramBatch := getMetricsFromMetricList(validMetrics1[validHistogram], validMetrics2[validHistogram])
|
|
|
|
summaryBatch := getMetricsFromMetricList(validMetrics1[validSummary], validMetrics2[validSummary])
|
|
|
|
// len(BucketCount) > len(ExplicitBounds)
|
|
unmatchedBoundBucketHistBatch := getMetricsFromMetricList(validMetrics2[unmatchedBoundBucketHist])
|
|
|
|
// fail cases
|
|
emptyDoubleGaugeBatch := getMetricsFromMetricList(invalidMetrics[emptyGauge])
|
|
|
|
emptyCumulativeSumBatch := getMetricsFromMetricList(invalidMetrics[emptyCumulativeSum])
|
|
|
|
emptyCumulativeHistogramBatch := getMetricsFromMetricList(invalidMetrics[emptyCumulativeHistogram])
|
|
|
|
emptySummaryBatch := getMetricsFromMetricList(invalidMetrics[emptySummary])
|
|
|
|
// staleNaN cases
|
|
staleNaNHistogramBatch := getMetricsFromMetricList(staleNaNMetrics[staleNaNHistogram])
|
|
|
|
staleNaNSummaryBatch := getMetricsFromMetricList(staleNaNMetrics[staleNaNSummary])
|
|
|
|
staleNaNIntGaugeBatch := getMetricsFromMetricList(staleNaNMetrics[staleNaNIntGauge])
|
|
|
|
staleNaNDoubleGaugeBatch := getMetricsFromMetricList(staleNaNMetrics[staleNaNDoubleGauge])
|
|
|
|
staleNaNIntSumBatch := getMetricsFromMetricList(staleNaNMetrics[staleNaNIntSum])
|
|
|
|
staleNaNSumBatch := getMetricsFromMetricList(staleNaNMetrics[staleNaNSum])
|
|
|
|
checkFunc := func(t *testing.T, r *http.Request, expected int, isStaleMarker bool) {
|
|
body, err := ioutil.ReadAll(r.Body)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
buf := make([]byte, len(body))
|
|
dest, err := snappy.Decode(buf, body)
|
|
assert.Equal(t, "0.1.0", r.Header.Get("x-prometheus-remote-write-version"))
|
|
assert.Equal(t, "snappy", r.Header.Get("content-encoding"))
|
|
assert.Equal(t, "opentelemetry-collector/1.0", r.Header.Get("User-Agent"))
|
|
assert.NotNil(t, r.Header.Get("tenant-id"))
|
|
require.NoError(t, err)
|
|
wr := &prompb.WriteRequest{}
|
|
ok := proto.Unmarshal(dest, wr)
|
|
require.Nil(t, ok)
|
|
assert.EqualValues(t, expected, len(wr.Timeseries))
|
|
if isStaleMarker {
|
|
assert.True(t, value.IsStaleNaN(wr.Timeseries[0].Samples[0].Value))
|
|
}
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
md *pmetric.Metrics
|
|
reqTestFunc func(t *testing.T, r *http.Request, expected int, isStaleMarker bool)
|
|
expectedTimeSeries int
|
|
httpResponseCode int
|
|
returnErr bool
|
|
isStaleMarker bool
|
|
}{
|
|
{
|
|
"invalid_type_case",
|
|
&invalidTypeBatch,
|
|
nil,
|
|
0,
|
|
http.StatusAccepted,
|
|
true,
|
|
false,
|
|
},
|
|
{
|
|
"intSum_case",
|
|
&intSumBatch,
|
|
checkFunc,
|
|
2,
|
|
http.StatusAccepted,
|
|
false,
|
|
false,
|
|
},
|
|
{
|
|
"doubleSum_case",
|
|
&sumBatch,
|
|
checkFunc,
|
|
2,
|
|
http.StatusAccepted,
|
|
false,
|
|
false,
|
|
},
|
|
{
|
|
"doubleGauge_case",
|
|
&doubleGaugeBatch,
|
|
checkFunc,
|
|
2,
|
|
http.StatusAccepted,
|
|
false,
|
|
false,
|
|
},
|
|
{
|
|
"intGauge_case",
|
|
&intGaugeBatch,
|
|
checkFunc,
|
|
2,
|
|
http.StatusAccepted,
|
|
false,
|
|
false,
|
|
},
|
|
{
|
|
"histogram_case",
|
|
&histogramBatch,
|
|
checkFunc,
|
|
12,
|
|
http.StatusAccepted,
|
|
false,
|
|
false,
|
|
},
|
|
{
|
|
"summary_case",
|
|
&summaryBatch,
|
|
checkFunc,
|
|
10,
|
|
http.StatusAccepted,
|
|
false,
|
|
false,
|
|
},
|
|
{
|
|
"unmatchedBoundBucketHist_case",
|
|
&unmatchedBoundBucketHistBatch,
|
|
checkFunc,
|
|
5,
|
|
http.StatusAccepted,
|
|
false,
|
|
false,
|
|
},
|
|
{
|
|
"5xx_case",
|
|
&unmatchedBoundBucketHistBatch,
|
|
checkFunc,
|
|
5,
|
|
http.StatusServiceUnavailable,
|
|
true,
|
|
false,
|
|
},
|
|
{
|
|
"emptyGauge_case",
|
|
&emptyDoubleGaugeBatch,
|
|
checkFunc,
|
|
0,
|
|
http.StatusAccepted,
|
|
true,
|
|
false,
|
|
},
|
|
{
|
|
"emptyCumulativeSum_case",
|
|
&emptyCumulativeSumBatch,
|
|
checkFunc,
|
|
0,
|
|
http.StatusAccepted,
|
|
true,
|
|
false,
|
|
},
|
|
{
|
|
"emptyCumulativeHistogram_case",
|
|
&emptyCumulativeHistogramBatch,
|
|
checkFunc,
|
|
0,
|
|
http.StatusAccepted,
|
|
true,
|
|
false,
|
|
},
|
|
{
|
|
"emptySummary_case",
|
|
&emptySummaryBatch,
|
|
checkFunc,
|
|
0,
|
|
http.StatusAccepted,
|
|
true,
|
|
false,
|
|
},
|
|
{
|
|
"staleNaNIntGauge_case",
|
|
&staleNaNIntGaugeBatch,
|
|
checkFunc,
|
|
1,
|
|
http.StatusAccepted,
|
|
false,
|
|
true,
|
|
},
|
|
{
|
|
"staleNaNDoubleGauge_case",
|
|
&staleNaNDoubleGaugeBatch,
|
|
checkFunc,
|
|
1,
|
|
http.StatusAccepted,
|
|
false,
|
|
true,
|
|
},
|
|
{
|
|
"staleNaNIntSum_case",
|
|
&staleNaNIntSumBatch,
|
|
checkFunc,
|
|
1,
|
|
http.StatusAccepted,
|
|
false,
|
|
true,
|
|
},
|
|
{
|
|
"staleNaNSum_case",
|
|
&staleNaNSumBatch,
|
|
checkFunc,
|
|
1,
|
|
http.StatusAccepted,
|
|
false,
|
|
true,
|
|
},
|
|
{
|
|
"staleNaNHistogram_case",
|
|
&staleNaNHistogramBatch,
|
|
checkFunc,
|
|
6,
|
|
http.StatusAccepted,
|
|
false,
|
|
true,
|
|
},
|
|
{
|
|
"staleNaNSummary_case",
|
|
&staleNaNSummaryBatch,
|
|
checkFunc,
|
|
5,
|
|
http.StatusAccepted,
|
|
false,
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if tt.reqTestFunc != nil {
|
|
tt.reqTestFunc(t, r, tt.expectedTimeSeries, tt.isStaleMarker)
|
|
}
|
|
w.WriteHeader(tt.httpResponseCode)
|
|
}))
|
|
|
|
defer server.Close()
|
|
|
|
cfg := &Config{
|
|
Namespace: "",
|
|
HTTPClientSettings: confighttp.HTTPClientSettings{
|
|
Endpoint: server.URL,
|
|
// We almost read 0 bytes, so no need to tune ReadBufferSize.
|
|
ReadBufferSize: 0,
|
|
WriteBufferSize: 512 * 1024,
|
|
},
|
|
RemoteWriteQueue: RemoteWriteQueue{NumConsumers: 5},
|
|
}
|
|
assert.NotNil(t, cfg)
|
|
// c, err := config.HTTPClientSettings.ToClient()
|
|
// assert.Nil(t, err)
|
|
buildInfo := component.BuildInfo{
|
|
Description: "OpenTelemetry Collector",
|
|
Version: "1.0",
|
|
}
|
|
set := exportertest.NewNopCreateSettings()
|
|
set.BuildInfo = buildInfo
|
|
prwe, nErr := NewPrwExporter(cfg, set)
|
|
require.NoError(t, nErr)
|
|
require.NoError(t, prwe.Start(context.Background(), componenttest.NewNopHost()))
|
|
err := prwe.PushMetrics(context.Background(), *tt.md)
|
|
if tt.returnErr {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
assert.NoError(t, err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_validateAndSanitizeExternalLabels(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
inputLabels map[string]string
|
|
expectedLabels map[string]string
|
|
returnErrorOnCreate bool
|
|
}{
|
|
{"success_case_no_labels",
|
|
map[string]string{},
|
|
map[string]string{},
|
|
false,
|
|
},
|
|
{"success_case_with_labels",
|
|
map[string]string{"key1": "val1"},
|
|
map[string]string{"key1": "val1"},
|
|
false,
|
|
},
|
|
{"success_case_2_with_labels",
|
|
map[string]string{"__key1__": "val1"},
|
|
map[string]string{"__key1__": "val1"},
|
|
false,
|
|
},
|
|
{"success_case_with_sanitized_labels",
|
|
map[string]string{"__key1.key__": "val1"},
|
|
map[string]string{"__key1_key__": "val1"},
|
|
false,
|
|
},
|
|
{"fail_case_empty_label",
|
|
map[string]string{"": "val1"},
|
|
map[string]string{},
|
|
true,
|
|
},
|
|
}
|
|
// run tests
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
newLabels, err := validateAndSanitizeExternalLabels(tt.inputLabels)
|
|
if tt.returnErrorOnCreate {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
assert.EqualValues(t, tt.expectedLabels, newLabels)
|
|
assert.NoError(t, err)
|
|
})
|
|
}
|
|
}
|