Skip to content

Commit 75f60fe

Browse files
authored
Refactoring Prometheus package (#218)
* Remove outdated instructions * Refactor NewServer functionality to include unit tests * Add unit tests for prometheus' getRouter function
1 parent 2cb6d9f commit 75f60fe

File tree

3 files changed

+92
-18
lines changed

3 files changed

+92
-18
lines changed

Diff for: docs/new-releases.md

+2-9
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,7 @@
1919
3. Publish new DVO release to Operator-Hub
2020

2121
- OperatorHub Repository for DVO - [DVO OLM](https://github.com/k8s-operatorhub/community-operators/tree/main/operators/deployment-validation-operator)
22-
- Edit deployment-validation-operator.package.yaml to reflect the new release
23-
24-
```yaml
25-
# RELEASE VERSION == 0.2.0, 0.2.1, etc.
26-
27-
* channels.currentCSV: deployment-validation-operator.v<RELEASE VERSION>
28-
```
29-
30-
- As a shortcut, you may choose to copy+paste the most recent already-existing DVO version directory (ex. 0.2.0, 0.2.1) and change the name of the directory to reflect the new release version
22+
- Copy and Paste the pre-existing DVO version directory (ex. 0.2.0, 0.2.1) and change the name of the directory to reflect the new release version
3123
- Modify the clusterserviceversion file's name within the directory to reflect the new release version
3224

3325
```yaml
@@ -39,6 +31,7 @@
3931
* spec.install.spec.deployments.spec.template.spec.containers.image: quay.io/deployment-validation-operator/dv-operator:<RELEASE VERSION>
4032
* spec.links.url: https://quay.io/deployment-validation-operator/dv-operator:<RELEASE VERSION>
4133
* spec.version: <RELEASE VERSION>
34+
* spec.skipRange: '>=0.0.10 <X.Y.Z' X.Y.Z being the new RELEASE VERSION
4235

4336
# Modify the following line to reflect the previous release version for upgrade purposes
4437
# (ex. If going from 0.2.1 -> 0.2.2, then the previous release was 0.2.1)

Diff for: pkg/prometheus/prometheus.go

+41-9
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,66 @@ type Registry interface {
1818
Gather() ([]*dto.MetricFamily, error)
1919
}
2020

21+
// registerCollectorError is returned by the NewServer method if the Registry
22+
// causes any error on registering a Collector
23+
type registerCollectorError struct {
24+
collector string
25+
trace error
26+
}
27+
28+
func (err registerCollectorError) Error() string {
29+
return fmt.Sprintf("registering %s collector: %s", err.collector, err.trace.Error())
30+
}
31+
32+
// NewServer returns a server configured to work on path and address given
33+
// It registers a collector which exports the current state of process metrics
34+
// and a collector that exports metrics about the current process
35+
// It may return registerCollectorError if the collectors are already registered
2136
func NewServer(registry Registry, path, addr string) (*Server, error) {
2237
if !strings.HasPrefix(path, "/") {
2338
path = "/" + path
2439
}
2540

41+
mux, err := getRouter(registry, path)
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
return &Server{
47+
s: &http.Server{
48+
Addr: addr,
49+
Handler: mux,
50+
ReadHeaderTimeout: 2 * time.Second,
51+
},
52+
}, nil
53+
}
54+
55+
// getRouter registers two collectors to deliver metrics on a given path
56+
// It may return registerCollectorError if the collectors are already registered
57+
func getRouter(registry Registry, path string) (*http.ServeMux, error) {
2658
var (
2759
processCollector = collectors.NewProcessCollector(collectors.ProcessCollectorOpts{})
2860
goCollector = collectors.NewGoCollector()
2961
)
3062

3163
if err := registry.Register(processCollector); err != nil {
32-
return nil, fmt.Errorf("registering process collector: %w", err)
64+
return nil, registerCollectorError{
65+
collector: "process",
66+
trace: err,
67+
}
3368
}
3469

3570
if err := registry.Register(goCollector); err != nil {
36-
return nil, fmt.Errorf("registering go collector: %w", err)
71+
return nil, registerCollectorError{
72+
collector: "go",
73+
trace: err,
74+
}
3775
}
3876

3977
mux := http.NewServeMux()
4078
mux.Handle(path, promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))
4179

42-
return &Server{
43-
s: &http.Server{
44-
Addr: addr,
45-
Handler: mux,
46-
ReadHeaderTimeout: 2 * time.Second,
47-
},
48-
}, nil
80+
return mux, nil
4981
}
5082

5183
type Server struct {

Diff for: pkg/prometheus/prometheus_test.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package prometheus
2+
3+
import (
4+
"net/http"
5+
"net/http/httptest"
6+
"testing"
7+
8+
"github.com/prometheus/client_golang/prometheus"
9+
"github.com/prometheus/client_golang/prometheus/collectors"
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
// TestOptionsStruct runs four tests on options struct methods:
14+
// -
15+
func TestGetRouter(t *testing.T) {
16+
17+
t.Run("router path is available", func(t *testing.T) {
18+
// Given
19+
recorder := httptest.NewRecorder()
20+
mockPath := "/test"
21+
mockReq, _ := http.NewRequest("GET", mockPath, nil)
22+
mockRegistry := prometheus.NewRegistry()
23+
24+
// When
25+
mux, err := getRouter(mockRegistry, mockPath)
26+
mux.ServeHTTP(recorder, mockReq)
27+
28+
// Assert
29+
assert.NoError(t, err)
30+
assert.Equal(t, http.StatusOK, recorder.Code)
31+
})
32+
33+
t.Run("handle error on collector registry", func(t *testing.T) {
34+
// Given
35+
mockRegistry := prometheus.NewRegistry()
36+
mockCollector := collectors.NewGoCollector()
37+
errMock := mockRegistry.Register(mockCollector)
38+
if errMock != nil {
39+
t.Errorf("Unexpected error at registering mock : %s", errMock.Error())
40+
}
41+
42+
// When
43+
_, err := getRouter(mockRegistry, "/test")
44+
45+
// Assert
46+
assert.Error(t, err)
47+
assert.IsType(t, registerCollectorError{}, err)
48+
})
49+
}

0 commit comments

Comments
 (0)