2018-08-05 09:03:18 +00:00
// Copyright 2018 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 main
import (
"fmt"
"net/http"
"net/http/httptest"
2020-12-23 18:52:04 +00:00
"net/url"
2018-08-05 09:03:18 +00:00
"testing"
"time"
2020-08-25 10:32:25 +00:00
2021-08-22 16:03:42 +00:00
"github.com/prometheus/prometheus/pkg/labels"
2021-08-27 05:44:46 +00:00
"github.com/prometheus/prometheus/pkg/rulefmt"
2020-10-29 09:43:23 +00:00
"github.com/stretchr/testify/require"
2018-08-05 09:03:18 +00:00
)
func TestQueryRange ( t * testing . T ) {
2019-05-17 16:09:47 +00:00
s , getRequest := mockServer ( 200 , ` { "status": "success", "data": { "resultType": "matrix", "result": []}} ` )
2018-08-05 09:03:18 +00:00
defer s . Close ( )
2020-12-23 18:52:04 +00:00
urlObject , err := url . Parse ( s . URL )
require . Equal ( t , nil , err )
2018-11-14 17:40:07 +00:00
p := & promqlPrinter { }
2020-12-23 18:52:04 +00:00
exitCode := QueryRange ( urlObject , map [ string ] string { } , "up" , "0" , "300" , 0 , p )
2020-10-29 09:43:23 +00:00
require . Equal ( t , "/api/v1/query_range" , getRequest ( ) . URL . Path )
2019-05-17 16:09:47 +00:00
form := getRequest ( ) . Form
2020-10-29 09:43:23 +00:00
require . Equal ( t , "up" , form . Get ( "query" ) )
require . Equal ( t , "1" , form . Get ( "step" ) )
require . Equal ( t , 0 , exitCode )
2018-08-05 09:03:18 +00:00
2020-12-23 18:52:04 +00:00
exitCode = QueryRange ( urlObject , map [ string ] string { } , "up" , "0" , "300" , 10 * time . Millisecond , p )
2020-10-29 09:43:23 +00:00
require . Equal ( t , "/api/v1/query_range" , getRequest ( ) . URL . Path )
2019-05-17 16:09:47 +00:00
form = getRequest ( ) . Form
2020-10-29 09:43:23 +00:00
require . Equal ( t , "up" , form . Get ( "query" ) )
require . Equal ( t , "0.01" , form . Get ( "step" ) )
require . Equal ( t , 0 , exitCode )
2020-08-25 10:32:25 +00:00
}
func TestQueryInstant ( t * testing . T ) {
s , getRequest := mockServer ( 200 , ` { "status": "success", "data": { "resultType": "vector", "result": []}} ` )
defer s . Close ( )
2020-12-23 18:52:04 +00:00
urlObject , err := url . Parse ( s . URL )
require . Equal ( t , nil , err )
2020-08-25 10:32:25 +00:00
p := & promqlPrinter { }
2020-12-23 18:52:04 +00:00
exitCode := QueryInstant ( urlObject , "up" , "300" , p )
2020-10-29 09:43:23 +00:00
require . Equal ( t , "/api/v1/query" , getRequest ( ) . URL . Path )
2020-08-25 10:32:25 +00:00
form := getRequest ( ) . Form
2020-10-29 09:43:23 +00:00
require . Equal ( t , "up" , form . Get ( "query" ) )
require . Equal ( t , "300" , form . Get ( "time" ) )
require . Equal ( t , 0 , exitCode )
2018-08-05 09:03:18 +00:00
}
2019-05-17 16:09:47 +00:00
func mockServer ( code int , body string ) ( * httptest . Server , func ( ) * http . Request ) {
var req * http . Request
2018-08-05 09:03:18 +00:00
server := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
2019-05-17 16:09:47 +00:00
r . ParseForm ( )
req = r
2018-08-05 09:03:18 +00:00
w . WriteHeader ( code )
fmt . Fprintln ( w , body )
} ) )
2019-05-17 16:09:47 +00:00
f := func ( ) * http . Request {
return req
2018-08-05 09:03:18 +00:00
}
return server , f
}
2021-06-29 15:32:59 +00:00
func TestCheckSDFile ( t * testing . T ) {
cases := [ ] struct {
name string
file string
err string
} {
{
name : "good .yml" ,
file : "./testdata/good-sd-file.yml" ,
} ,
{
name : "good .yaml" ,
file : "./testdata/good-sd-file.yaml" ,
} ,
{
name : "good .json" ,
file : "./testdata/good-sd-file.json" ,
} ,
{
name : "bad file extension" ,
file : "./testdata/bad-sd-file-extension.nonexistant" ,
err : "invalid file extension: \".nonexistant\"" ,
} ,
{
name : "bad format" ,
file : "./testdata/bad-sd-file-format.yml" ,
err : "yaml: unmarshal errors:\n line 1: field targats not found in type struct { Targets []string \"yaml:\\\"targets\\\"\"; Labels model.LabelSet \"yaml:\\\"labels\\\"\" }" ,
} ,
}
for _ , test := range cases {
t . Run ( test . name , func ( t * testing . T ) {
err := checkSDFile ( test . file )
if test . err != "" {
require . Equalf ( t , test . err , err . Error ( ) , "Expected error %q, got %q" , test . err , err . Error ( ) )
return
}
require . NoError ( t , err )
} )
}
}
2021-08-27 05:44:46 +00:00
func TestCheckDuplicates ( t * testing . T ) {
cases := [ ] struct {
name string
ruleFile string
expectedDups [ ] compareRuleType
} {
{
name : "no duplicates" ,
ruleFile : "./testdata/rules.yml" ,
} ,
{
name : "duplicate in other group" ,
ruleFile : "./testdata/rules_duplicates.yml" ,
expectedDups : [ ] compareRuleType {
{
metric : "job:test:count_over_time1m" ,
2021-08-22 16:03:42 +00:00
label : labels . New ( ) ,
2021-08-27 05:44:46 +00:00
} ,
} ,
} ,
}
for _ , test := range cases {
c := test
t . Run ( c . name , func ( t * testing . T ) {
rgs , err := rulefmt . ParseFile ( c . ruleFile )
require . Empty ( t , err )
dups := checkDuplicates ( rgs . Groups )
require . Equal ( t , c . expectedDups , dups )
} )
}
}
2021-08-27 06:22:34 +00:00
func BenchmarkCheckDuplicates ( b * testing . B ) {
rgs , err := rulefmt . ParseFile ( "./testdata/rules_large.yml" )
require . Empty ( b , err )
b . ResetTimer ( )
for i := 0 ; i < b . N ; i ++ {
checkDuplicates ( rgs . Groups )
}
}