11/*
2- * Copyright (c) 2020, 2021 , Oracle and/or its affiliates.
2+ * Copyright (c) 2020, 2022 , Oracle and/or its affiliates.
33 * Licensed under the Universal Permissive License v 1.0 as shown at
44 * http://oss.oracle.com/licenses/upl.
55 */
@@ -9,10 +9,16 @@ package prometheus
99import (
1010 "encoding/json"
1111 "fmt"
12+ monitoring "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1"
13+ client "github.com/coreos/prometheus-operator/pkg/client/versioned/typed/monitoring/v1"
1214 . "github.com/onsi/gomega"
15+ coh "github.com/oracle/coherence-operator/api/v1"
1316 "github.com/oracle/coherence-operator/test/e2e/helper"
1417 "io/ioutil"
1518 corev1 "k8s.io/api/core/v1"
19+ apierrors "k8s.io/apimachinery/pkg/api/errors"
20+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+ "k8s.io/apimachinery/pkg/types"
1622 "k8s.io/apimachinery/pkg/util/wait"
1723 "net/http"
1824 "strings"
@@ -29,20 +35,32 @@ func TestPrometheus(t *testing.T) {
2935 g .Expect (err ).NotTo (HaveOccurred ())
3036 g .Expect (ok ).To (BeTrue (), "Cannot find any Prometheus Pods - this test requires Prometheus to have been installed" )
3137
32- AssertPrometheus (t , "prometheus-test.yaml" , promPod )
38+ promClient , err := client .NewForConfig (testContext .Config )
39+ g .Expect (err ).NotTo (HaveOccurred ())
40+
41+ AssertPrometheus (t , "prometheus-test.yaml" , promPod , promClient )
3342}
3443
35- func AssertPrometheus (t * testing.T , yamlFile string , promPod corev1.Pod ) {
44+ func AssertPrometheus (t * testing.T , yamlFile string , promPod corev1.Pod , promClient * client.MonitoringV1Client ) {
45+ g := NewGomegaWithT (t )
46+
3647 ShouldGetPrometheusConfig (t , promPod )
3748
3849 // Deploy the Coherence cluster
39- _ , cohPods := helper .AssertDeployments (testContext , t , yamlFile )
50+ deployments , cohPods := helper .AssertDeployments (testContext , t , yamlFile )
51+ deployment := deployments ["test" ]
52+
53+ err := ShouldEventuallyHaveServiceMonitor (t , deployment .Namespace , "test-metrics" , promClient , 10 * time .Second , 5 * time .Minute )
54+ g .Expect (err ).NotTo (HaveOccurred ())
4055
4156 // Wait for Coherence metrics to appear in Prometheus
4257 ShouldEventuallySeeClusterMetrics (t , promPod , cohPods )
4358
4459 // Ensure that we can see the deployments size metric
4560 ShouldGetClusterSizeMetric (t , promPod )
61+
62+ // Ensure we can update the Coherence deployment and cause the ServiceMonitor to be updated
63+ ShouldPatchServiceMonitor (t , deployment , promClient )
4664}
4765
4866func IsPrometheusInstalled () (bool , corev1.Pod , error ) {
@@ -107,6 +125,64 @@ func ShouldGetClusterSizeMetric(t *testing.T, pod corev1.Pod) {
107125 g .Expect (err ).NotTo (HaveOccurred ())
108126}
109127
128+ func ShouldPatchServiceMonitor (t * testing.T , deployment coh.Coherence , promClient * client.MonitoringV1Client ) {
129+ g := NewGomegaWithT (t )
130+
131+ current := & coh.Coherence {}
132+ err := testContext .Client .Get (testContext .Context , types.NamespacedName {Namespace : deployment .Namespace , Name : deployment .Name }, current )
133+ g .Expect (err ).NotTo (HaveOccurred ())
134+
135+ // update the ServiceMonitor interval to cause an update
136+ current .Spec .Ports [0 ].ServiceMonitor .Interval = "10s"
137+ err = testContext .Client .Update (testContext .Context , current )
138+ g .Expect (err ).NotTo (HaveOccurred ())
139+
140+ err = ShouldEventuallyHaveServiceMonitorWithState (t , deployment .Namespace , "test-metrics" , hasInterval , promClient , 10 * time .Second , 5 * time .Minute )
141+ g .Expect (err ).NotTo (HaveOccurred ())
142+
143+ }
144+
145+ func ShouldEventuallyHaveServiceMonitor (t * testing.T , namespace , name string , promClient * client.MonitoringV1Client , retryInterval , timeout time.Duration ) error {
146+ return ShouldEventuallyHaveServiceMonitorWithState (t , namespace , name , alwaysTrue , promClient , retryInterval , timeout )
147+ }
148+
149+ type ServiceMonitorPredicate func (* testing.T , * monitoring.ServiceMonitor ) bool
150+
151+ func alwaysTrue (* testing.T , * monitoring.ServiceMonitor ) bool {
152+ return true
153+ }
154+
155+ func hasInterval (t * testing.T , sm * monitoring.ServiceMonitor ) bool {
156+ if len (sm .Spec .Endpoints ) > 0 && sm .Spec .Endpoints [0 ].Interval == "10s" {
157+ return true
158+ }
159+ t .Logf ("Waiting for availability of ServiceMonitor resource %s - with endpoint interval of 10s" , sm .Name )
160+ return false
161+ }
162+
163+ func ShouldEventuallyHaveServiceMonitorWithState (t * testing.T , namespace , name string , predicate ServiceMonitorPredicate , promClient * client.MonitoringV1Client , retryInterval , timeout time.Duration ) error {
164+ var sm * monitoring.ServiceMonitor
165+
166+ err := wait .Poll (retryInterval , timeout , func () (done bool , err error ) {
167+ sm , err = promClient .ServiceMonitors (namespace ).Get (testContext .Context , name , v1.GetOptions {})
168+ if err != nil {
169+ if apierrors .IsNotFound (err ) {
170+ t .Logf ("Waiting for availability of ServiceMonitor resource %s - NotFound" , name )
171+ return false , nil
172+ }
173+ t .Logf ("Waiting for availability of ServiceMonitor resource %s - %s" , name , err .Error ())
174+ return false , nil
175+ }
176+ if predicate (t , sm ) {
177+ return true , nil
178+ }
179+ t .Logf ("Waiting for availability of ServiceMonitor resource %s - %s to match predicate" , name , err .Error ())
180+ return false , nil
181+ })
182+
183+ return err
184+ }
185+
110186func PrometheusQuery (t * testing.T , pod corev1.Pod , query string , result interface {}) error {
111187 r , err := PrometheusAPIRequest (pod , "/api/v1/query?query=" + query )
112188 if err != nil {
0 commit comments