Skip to content

Commit

Permalink
Merge pull request #3310 from yeya24/e2e-probe
Browse files Browse the repository at this point in the history
Add E2E test for probe static targets
  • Loading branch information
brancz authored Jul 3, 2020
2 parents 8b4c670 + e0c6836 commit 65055ad
Show file tree
Hide file tree
Showing 3 changed files with 272 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/e2e/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func testAllNSPrometheus(t *testing.T) {
"PromArbitraryFSAcc": testPromArbitraryFSAcc,
"PromTLSConfigViaSecret": testPromTLSConfigViaSecret,
"Thanos": testThanos,
"PromStaticProbe": testPromStaticProbe,
}

for name, f := range testFuncs {
Expand Down
81 changes: 81 additions & 0 deletions test/e2e/prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"io/ioutil"
"log"
"net/url"
"reflect"
"sort"
"strconv"
Expand Down Expand Up @@ -2284,6 +2285,86 @@ func testPromTLSConfigViaSecret(t *testing.T) {
}
}

func testPromStaticProbe(t *testing.T) {
t.Parallel()

ctx := framework.NewTestCtx(t)
defer ctx.Cleanup(t)
ns := ctx.CreateNamespace(t, framework.KubeClient)
ctx.SetupPrometheusRBAC(t, ns, framework.KubeClient)

blackboxExporterName := "blackbox-exporter"
if err := framework.CreateBlackBoxExporterAndWaitUntilReady(ns, blackboxExporterName); err != nil {
t.Fatal("Creating blackbox exporter failed: ", err)
}

blackboxSvc := framework.MakeBlackBoxExporterService(ns, blackboxExporterName)
if finalizerFn, err := testFramework.CreateServiceAndWaitUntilReady(framework.KubeClient, ns, blackboxSvc); err != nil {
t.Fatal("creating blackbox exporter service failed ", err)
} else {
ctx.AddFinalizerFn(finalizerFn)
}

prometheusName := "test"
group := "probe-test"
svc := framework.MakePrometheusService(prometheusName, group, v1.ServiceTypeClusterIP)

proberUrl := blackboxExporterName + ":9115"
targets := []string{svc.Name + ":9090"}

probe := framework.MakeBasicStaticProbe(group, proberUrl, targets)
if _, err := framework.MonClientV1.Probes(ns).Create(context.TODO(), probe, metav1.CreateOptions{}); err != nil {
t.Fatal("Creating Probe failed: ", err)
}

p := framework.MakeBasicPrometheus(ns, prometheusName, group, 1)
p.Spec.ProbeSelector = &metav1.LabelSelector{
MatchLabels: map[string]string{
"group": group,
},
}
if _, err := framework.CreatePrometheusAndWaitUntilReady(ns, p); err != nil {
t.Fatal(err)
}

if finalizerFn, err := testFramework.CreateServiceAndWaitUntilReady(framework.KubeClient, ns, svc); err != nil {
t.Fatal(errors.Wrap(err, "creating prometheus service failed"))
} else {
ctx.AddFinalizerFn(finalizerFn)
}

expectedURL := url.URL{Host: proberUrl, Scheme: "http", Path: "/probe"}
q := expectedURL.Query()
q.Set("module", "http_2xx")
q.Set("target", targets[0])
expectedURL.RawQuery = q.Encode()

if err := wait.Poll(time.Second, time.Minute*5, func() (bool, error) {
activeTargets, err := framework.GetActiveTargets(ns, svc.Name)
if err != nil {
return false, err
}

if len(activeTargets) != 1 {
return false, nil
}

exp := expectedURL.String()
if activeTargets[0].ScrapeURL != exp {
return false, nil
}

if value, ok := activeTargets[0].Labels["instance"]; !ok || value != targets[0] {
return false, nil
}

return true, nil
}); err != nil {
t.Fatal("waiting for static probe targets timed out.")
}

}

func isAlertmanagerDiscoveryWorking(ns, promSVCName, alertmanagerName string) func() (bool, error) {
return func() (bool, error) {
pods, err := framework.KubeClient.CoreV1().Pods(ns).List(context.TODO(), alertmanager.ListOptions(alertmanagerName))
Expand Down
190 changes: 190 additions & 0 deletions test/framework/probe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
// Copyright 2020 The prometheus-operator 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 framework

import (
"context"
"time"

monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/wait"
)

func (f *Framework) MakeBlackBoxExporterService(ns, name string) *v1.Service {
return &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: ns,
},
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
Selector: map[string]string{
"app": "blackbox-exporter",
},
Ports: []v1.ServicePort{
{
Port: 9115,
TargetPort: intstr.FromInt(9115),
},
},
},
}
}

func (f *Framework) createBlackBoxExporterConfigMapAndWaitExists(ns, name string) error {
cm := &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: ns,
},
Data: map[string]string{
"blackbox.yml": `modules:
http_2xx:
http:
no_follow_redirects: false
preferred_ip_protocol: ip4
valid_http_versions:
- HTTP/1.1
- HTTP/2
prober: http
`,
},
}
ctx := context.TODO()
if _, err := f.KubeClient.CoreV1().ConfigMaps(ns).Create(ctx, cm, metav1.CreateOptions{}); err != nil {
return err
}

if _, err := f.WaitForConfigMapExist(ns, name); err != nil {
return err
}
return nil
}

func (f *Framework) createBlackBoxExporterDeploymentAndWaitReady(ns, name string, replicas int32) error {
deploy := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: ns,
},
Spec: appsv1.DeploymentSpec{
Replicas: &replicas,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "blackbox-exporter",
},
},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": "blackbox-exporter",
},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: "blackbox-exporter",
Image: "prom/blackbox-exporter:v0.17.0",
Args: []string{
"--config.file=/config/blackbox.yml",
},
Ports: []v1.ContainerPort{
{
ContainerPort: 9115,
Protocol: v1.ProtocolTCP,
},
},
VolumeMounts: []v1.VolumeMount{
{
Name: "config",
MountPath: "/config",
},
},
},
},
Volumes: []v1.Volume{
{
Name: "config",
VolumeSource: v1.VolumeSource{
ConfigMap: &v1.ConfigMapVolumeSource{
LocalObjectReference: v1.LocalObjectReference{
Name: name,
},
},
},
},
},
},
},
},
}
ctx := context.TODO()
deploymentInterface := f.KubeClient.AppsV1().Deployments(ns)
if _, err := deploymentInterface.Create(ctx, deploy, metav1.CreateOptions{}); err != nil {
return err
}

return wait.Poll(2*time.Second, f.DefaultTimeout, func() (bool, error) {
blackbox, err := deploymentInterface.Get(ctx, name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
return false, nil
}
if err != nil {
return false, err
}

if blackbox.Status.ReadyReplicas != *blackbox.Spec.Replicas {
return false, nil
}

return true, nil
})
}

func (f *Framework) CreateBlackBoxExporterAndWaitUntilReady(ns, name string) error {
if err := f.createBlackBoxExporterConfigMapAndWaitExists(ns, name); err != nil {
return err
}

return f.createBlackBoxExporterDeploymentAndWaitReady(ns, name, 1)
}

func (f *Framework) MakeBasicStaticProbe(name, url string, targets []string) *monitoringv1.Probe {
return &monitoringv1.Probe{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: map[string]string{
"group": name,
},
},
Spec: monitoringv1.ProbeSpec{
Interval: "15s",
Module: "http_2xx",
ProberSpec: monitoringv1.ProberSpec{
URL: url,
},
Targets: monitoringv1.ProbeTargets{
StaticConfig: &monitoringv1.ProbeTargetStaticConfig{
Targets: targets,
},
},
},
}
}

0 comments on commit 65055ad

Please sign in to comment.