From 4d166074759f9b69d65d150e493511431ae517f8 Mon Sep 17 00:00:00 2001 From: Ying WANG Date: Tue, 15 Apr 2025 23:22:30 +0200 Subject: [PATCH 1/3] implement fake for prometheus API Signed-off-by: Ying WANG --- api/prometheus/v1/api_fake.go | 161 +++++++++++++++++++++++++++++ api/prometheus/v1/api_fake_test.go | 102 ++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 api/prometheus/v1/api_fake.go create mode 100644 api/prometheus/v1/api_fake_test.go diff --git a/api/prometheus/v1/api_fake.go b/api/prometheus/v1/api_fake.go new file mode 100644 index 000000000..7cad35179 --- /dev/null +++ b/api/prometheus/v1/api_fake.go @@ -0,0 +1,161 @@ +package v1 + +import ( + "context" + "time" + + "github.com/prometheus/common/model" +) + +type FakeAPI struct { + // FakeAPI is a mock API for testing purposes. + // It implements the API interface and provides fake data for testing. + ExpectedAlertsResult []*Alert + ExpectedAlertsError error + + ExpectedAlertManagersResult AlertManagersResult + ExpectedAlertManagersError error + + ExpectedCleanTombstonesError error + + ExpectedConfigResult ConfigResult + ExpectedConfigError error + + ExpectedDeleteSeriesError error + + ExpectedFlagsResult FlagsResult + ExpectedFlagsError error + + ExpectedLabelNamesResult []string + ExpectedLabelNamesWarnings Warnings + ExpectedLabelNamesError error + + ExpectedLabelValuesResult model.LabelValues + ExpectedLabelValuesWarnings Warnings + ExpectedLabelValuesError error + + ExpectedQueryResult model.Value + ExpectedQueryWarnings Warnings + ExpectedQueryError error + + ExpectedQueryRangeResult model.Value + ExpectedQueryRangeWarnings Warnings + ExpectedQueryRangeError error + + ExpectedQueryExemplarsResult []ExemplarQueryResult + ExpectedQueryExemplarsError error + + ExpectedBuildinfoResult BuildinfoResult + ExpectedBuildinfoError error + + ExpectedRuntimeinfoResult RuntimeinfoResult + ExpectedRuntimeinfoError error + + ExpectedSeriesResult []model.LabelSet + ExpectedSeriesWarnings Warnings + ExpectedSeriesError error + + ExpectedSnapshotResult SnapshotResult + ExpectedSnapshotError error + + ExpectedRulesResult RulesResult + ExpectedRulesError error + + ExpectedTargetsResult TargetsResult + ExpectedTargetsError error + + ExpectedTargetsMetadataResult []MetricMetadata + ExpectedTargetsMetadataError error + + ExpectedMetadataResult map[string][]Metadata + ExpectedMetadataError error + + ExpectedTSDBResult TSDBResult + ExpectedTSDBError error + + ExpectedWalReplayResult WalReplayStatus + ExpectedWalReplayError error +} + +func (f *FakeAPI) Alerts(ctx context.Context) ([]*Alert, error) { + return f.ExpectedAlertsResult, f.ExpectedAlertsError +} + +func (f *FakeAPI) AlertManagers(ctx context.Context) (AlertManagersResult, error) { + return f.ExpectedAlertManagersResult, f.ExpectedAlertManagersError +} + +func (f *FakeAPI) CleanTombstones(ctx context.Context) error { + return f.ExpectedCleanTombstonesError +} + +func (f *FakeAPI) Config(ctx context.Context) (ConfigResult, error) { + return f.ExpectedConfigResult, f.ExpectedConfigError +} + +func (f *FakeAPI) DeleteSeries(ctx context.Context, matches []string, startTime, endTime time.Time) error { + return f.ExpectedDeleteSeriesError +} +func (f *FakeAPI) Flags(ctx context.Context) (FlagsResult, error) { + return f.ExpectedFlagsResult, f.ExpectedFlagsError +} + +func (f *FakeAPI) LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]string, Warnings, error) { + return f.ExpectedLabelNamesResult, f.ExpectedLabelNamesWarnings, f.ExpectedLabelNamesError +} + +func (f *FakeAPI) LabelValues(ctx context.Context, label string, matches []string, startTime, endTime time.Time, opts ...Option) (model.LabelValues, Warnings, error) { + return f.ExpectedLabelValuesResult, f.ExpectedLabelValuesWarnings, f.ExpectedLabelValuesError +} + +func (f *FakeAPI) Query(ctx context.Context, query string, ts time.Time, opts ...Option) (model.Value, Warnings, error) { + return f.ExpectedQueryResult, f.ExpectedQueryWarnings, f.ExpectedQueryError +} + +func (f *FakeAPI) QueryRange(ctx context.Context, query string, r Range, opts ...Option) (model.Value, Warnings, error) { + return f.ExpectedQueryRangeResult, f.ExpectedQueryRangeWarnings, f.ExpectedQueryRangeError +} + +func (f *FakeAPI) QueryExemplars(ctx context.Context, query string, startTime, endTime time.Time) ([]ExemplarQueryResult, error) { + return f.ExpectedQueryExemplarsResult, f.ExpectedQueryExemplarsError +} + +func (f *FakeAPI) Buildinfo(ctx context.Context) (BuildinfoResult, error) { + return f.ExpectedBuildinfoResult, f.ExpectedBuildinfoError +} + +func (f *FakeAPI) Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) { + return f.ExpectedRuntimeinfoResult, f.ExpectedRuntimeinfoError +} + +func (f *FakeAPI) Series(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]model.LabelSet, Warnings, error) { + return f.ExpectedSeriesResult, f.ExpectedSeriesWarnings, f.ExpectedSeriesError +} + +func (f *FakeAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) { + return f.ExpectedSnapshotResult, f.ExpectedSnapshotError +} + +func (f *FakeAPI) Rules(ctx context.Context) (RulesResult, error) { + return f.ExpectedRulesResult, f.ExpectedRulesError +} + +func (f *FakeAPI) Targets(ctx context.Context) (TargetsResult, error) { + return f.ExpectedTargetsResult, f.ExpectedTargetsError +} + +func (f *FakeAPI) TargetsMetadata(ctx context.Context, matchTarget, metric, limit string) ([]MetricMetadata, error) { + return f.ExpectedTargetsMetadataResult, f.ExpectedTargetsMetadataError +} + +func (f *FakeAPI) Metadata(ctx context.Context, metric, limit string) (map[string][]Metadata, error) { + return f.ExpectedMetadataResult, f.ExpectedMetadataError +} + +func (f *FakeAPI) TSDB(ctx context.Context, opts ...Option) (TSDBResult, error) { + return f.ExpectedTSDBResult, f.ExpectedTSDBError +} + +func (f *FakeAPI) WalReplay(ctx context.Context) (WalReplayStatus, error) { + return f.ExpectedWalReplayResult, f.ExpectedWalReplayError +} diff --git a/api/prometheus/v1/api_fake_test.go b/api/prometheus/v1/api_fake_test.go new file mode 100644 index 000000000..694899baa --- /dev/null +++ b/api/prometheus/v1/api_fake_test.go @@ -0,0 +1,102 @@ +package v1 + +import ( + "context" + "fmt" + "reflect" + "testing" + "time" + + "github.com/prometheus/common/model" +) + +func assertEqual(t *testing.T, a, b interface{}) { + if !reflect.DeepEqual(a, b) { + t.Errorf("%v != %v", a, b) + } +} + +func TestFakeAPI_Query(t *testing.T) { + tests := []struct { + name string + query string + expectedResult model.Value + expectedWarnings Warnings + expectedError error + }{ + { + name: "Valid query", + query: "up == 1", + expectedResult: &model.String{Value: "1"}, + }, + { + name: "Query with no results, warning present", + query: "up == 0", + expectedResult: nil, + expectedWarnings: Warnings{"Warning: No data found for query, check if the time range is correct"}, + expectedError: nil, + }, + { + name: "Error query", + query: "invalid_query", + expectedError: fmt.Errorf("mock error"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Setup FakeAPI + fakeAPI := &FakeAPI{ + ExpectedQueryResult: tt.expectedResult, + ExpectedQueryWarnings: tt.expectedWarnings, + ExpectedQueryError: tt.expectedError, + } + + result, warnings, err := fakeAPI.Query(context.Background(), tt.query, time.Now()) + assertEqual(t, tt.expectedResult, result) + assertEqual(t, tt.expectedWarnings, warnings) + assertEqual(t, tt.expectedError, err) + }) + } +} + +func TestFakeAPI_LabelNames(t *testing.T) { + tests := []struct { + name string + matches []string + expectedLabels []string + expectedWarnings Warnings + expectedError error + }{ + { + name: "Valid label names", + matches: []string{"up"}, + expectedLabels: []string{"label1", "label2"}, + expectedWarnings: nil, + expectedError: nil, + }, + { + name: "Error in label names", + matches: []string{"error"}, + expectedLabels: nil, + expectedWarnings: nil, + expectedError: fmt.Errorf("mock label error"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Setup FakeAPI + fakeAPI := &FakeAPI{ + ExpectedLabelNamesResult: tt.expectedLabels, + ExpectedLabelNamesWarnings: tt.expectedWarnings, + ExpectedLabelNamesError: tt.expectedError, + } + + result, warnings, err := fakeAPI.LabelNames(context.Background(), tt.matches, time.Now(), time.Now()) + assertEqual(t, tt.expectedLabels, result) + assertEqual(t, tt.expectedWarnings, warnings) + assertEqual(t, tt.expectedError, err) + }) + } +} From cbd79f1627e8433e6ccc4479ed6c8894199005b4 Mon Sep 17 00:00:00 2001 From: Ying WANG Date: Tue, 15 Apr 2025 23:24:45 +0200 Subject: [PATCH 2/3] fix header Signed-off-by: Ying WANG --- api/prometheus/v1/api_fake.go | 12 ++++++++++++ api/prometheus/v1/api_fake_test.go | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/api/prometheus/v1/api_fake.go b/api/prometheus/v1/api_fake.go index 7cad35179..2229b304e 100644 --- a/api/prometheus/v1/api_fake.go +++ b/api/prometheus/v1/api_fake.go @@ -1,3 +1,15 @@ +// Copyright 2019 The Prometheus 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 v1 import ( diff --git a/api/prometheus/v1/api_fake_test.go b/api/prometheus/v1/api_fake_test.go index 694899baa..78fb67cc6 100644 --- a/api/prometheus/v1/api_fake_test.go +++ b/api/prometheus/v1/api_fake_test.go @@ -1,3 +1,15 @@ +// Copyright 2019 The Prometheus 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 v1 import ( From db3274666622a0871d23e1f3a5f45bd4460d52a4 Mon Sep 17 00:00:00 2001 From: Ying WANG Date: Tue, 15 Apr 2025 23:33:19 +0200 Subject: [PATCH 3/3] formatting Signed-off-by: Ying WANG --- api/prometheus/v1/api_fake.go | 1 + api/prometheus/v1/api_fake_test.go | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/api/prometheus/v1/api_fake.go b/api/prometheus/v1/api_fake.go index 2229b304e..dc16023b7 100644 --- a/api/prometheus/v1/api_fake.go +++ b/api/prometheus/v1/api_fake.go @@ -108,6 +108,7 @@ func (f *FakeAPI) Config(ctx context.Context) (ConfigResult, error) { func (f *FakeAPI) DeleteSeries(ctx context.Context, matches []string, startTime, endTime time.Time) error { return f.ExpectedDeleteSeriesError } + func (f *FakeAPI) Flags(ctx context.Context) (FlagsResult, error) { return f.ExpectedFlagsResult, f.ExpectedFlagsError } diff --git a/api/prometheus/v1/api_fake_test.go b/api/prometheus/v1/api_fake_test.go index 78fb67cc6..e64bbbcc9 100644 --- a/api/prometheus/v1/api_fake_test.go +++ b/api/prometheus/v1/api_fake_test.go @@ -14,7 +14,7 @@ package v1 import ( "context" - "fmt" + "errors" "reflect" "testing" "time" @@ -51,7 +51,7 @@ func TestFakeAPI_Query(t *testing.T) { { name: "Error query", query: "invalid_query", - expectedError: fmt.Errorf("mock error"), + expectedError: errors.New("mock error"), }, } @@ -92,7 +92,7 @@ func TestFakeAPI_LabelNames(t *testing.T) { matches: []string{"error"}, expectedLabels: nil, expectedWarnings: nil, - expectedError: fmt.Errorf("mock label error"), + expectedError: errors.New("mock label error"), }, }