Files
gotenberg/pkg/modules/prometheus/prometheus_test.go
2023-11-19 14:43:19 +01:00

361 lines
7.7 KiB
Go

package prometheus
import (
"errors"
"reflect"
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/gotenberg/gotenberg/v7/pkg/gotenberg"
)
func TestPrometheus_Descriptor(t *testing.T) {
descriptor := new(Prometheus).Descriptor()
actual := reflect.TypeOf(descriptor.New())
expect := reflect.TypeOf(new(Prometheus))
if actual != expect {
t.Errorf("expected '%s' but got '%s'", expect, actual)
}
}
func TestPrometheus_Provision(t *testing.T) {
for _, tc := range []struct {
scenario string
ctx *gotenberg.Context
expectMetrics []gotenberg.Metric
expectError bool
}{
{
scenario: "disable collect",
ctx: func() *gotenberg.Context {
fs := new(Prometheus).Descriptor().FlagSet
err := fs.Parse([]string{"--prometheus-disable-collect=true"})
if err != nil {
t.Fatalf("expected no error but got: %v", err)
}
return gotenberg.NewContext(
gotenberg.ParsedFlags{
FlagSet: fs,
},
nil,
)
}(),
expectError: false,
},
{
scenario: "invalid metrics provider",
ctx: func() *gotenberg.Context {
mod := &struct {
gotenberg.ModuleMock
gotenberg.ValidatorMock
gotenberg.MetricsProviderMock
}{}
mod.DescriptorMock = func() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }}
}
mod.ValidateMock = func() error {
return errors.New("foo")
}
mod.MetricsMock = func() ([]gotenberg.Metric, error) {
return nil, nil
}
return gotenberg.NewContext(
gotenberg.ParsedFlags{
FlagSet: new(Prometheus).Descriptor().FlagSet,
},
[]gotenberg.ModuleDescriptor{
mod.Descriptor(),
},
)
}(),
expectError: true,
},
{
scenario: "invalid metrics from metrics provider",
ctx: func() *gotenberg.Context {
mod := &struct {
gotenberg.ModuleMock
gotenberg.ValidatorMock
gotenberg.MetricsProviderMock
}{}
mod.DescriptorMock = func() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }}
}
mod.ValidateMock = func() error {
return nil
}
mod.MetricsMock = func() ([]gotenberg.Metric, error) {
return nil, errors.New("foo")
}
return gotenberg.NewContext(
gotenberg.ParsedFlags{
FlagSet: new(Prometheus).Descriptor().FlagSet,
},
[]gotenberg.ModuleDescriptor{
mod.Descriptor(),
},
)
}(),
expectError: true,
},
{
scenario: "provision success",
ctx: func() *gotenberg.Context {
mod := &struct {
gotenberg.ModuleMock
gotenberg.ValidatorMock
gotenberg.MetricsProviderMock
}{}
mod.DescriptorMock = func() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }}
}
mod.ValidateMock = func() error {
return nil
}
mod.MetricsMock = func() ([]gotenberg.Metric, error) {
return []gotenberg.Metric{
{
Name: "foo",
Description: "Bar.",
},
}, nil
}
return gotenberg.NewContext(
gotenberg.ParsedFlags{
FlagSet: new(Prometheus).Descriptor().FlagSet,
},
[]gotenberg.ModuleDescriptor{
mod.Descriptor(),
},
)
}(),
expectMetrics: []gotenberg.Metric{
{
Name: "foo",
Description: "Bar.",
},
},
expectError: false,
},
} {
t.Run(tc.scenario, func(t *testing.T) {
mod := new(Prometheus)
err := mod.Provision(tc.ctx)
if !reflect.DeepEqual(mod.metrics, tc.expectMetrics) {
t.Fatalf("expected metrics %+v, but got: %+v", tc.expectMetrics, mod.metrics)
}
if !tc.expectError && err != nil {
t.Fatalf("expected no error but got: %v", err)
}
if tc.expectError && err == nil {
t.Fatal("expected error but got none")
}
})
}
}
func TestPrometheus_Validate(t *testing.T) {
for _, tc := range []struct {
scenario string
namespace string
metrics []gotenberg.Metric
disableCollect bool
expectError bool
}{
{
scenario: "collect disabled",
namespace: "foo",
disableCollect: true,
expectError: false,
},
{
scenario: "empty namespace",
namespace: "",
disableCollect: false,
expectError: true,
},
{
scenario: "empty metric name",
namespace: "foo",
metrics: []gotenberg.Metric{
{
Name: "",
},
},
disableCollect: false,
expectError: true,
},
{
scenario: "nil read metric method",
namespace: "foo",
metrics: []gotenberg.Metric{
{
Name: "foo",
Read: nil,
},
},
disableCollect: false,
expectError: true,
},
{
scenario: "already registered metric",
namespace: "foo",
metrics: []gotenberg.Metric{
{
Name: "foo",
Read: func() float64 {
return 0
},
},
{
Name: "foo",
Read: func() float64 {
return 0
},
},
},
disableCollect: false,
expectError: true,
},
{
scenario: "validate success",
namespace: "foo",
metrics: []gotenberg.Metric{
{
Name: "foo",
Read: func() float64 {
return 0
},
},
{
Name: "bar",
Read: func() float64 {
return 0
},
},
},
disableCollect: false,
expectError: false,
},
} {
t.Run(tc.scenario, func(t *testing.T) {
mod := &Prometheus{
namespace: tc.namespace,
metrics: tc.metrics,
disableCollect: tc.disableCollect,
}
err := mod.Validate()
if !tc.expectError && err != nil {
t.Fatalf("expected no error but got: %v", err)
}
if tc.expectError && err == nil {
t.Fatal("expected error but got none")
}
})
}
}
func TestPrometheus_Start(t *testing.T) {
for _, tc := range []struct {
scenario string
metrics []gotenberg.Metric
disableCollect bool
}{
{
scenario: "collect disabled",
disableCollect: true,
},
{
scenario: "start success",
metrics: []gotenberg.Metric{
{
Name: "foo",
Read: func() float64 {
return 0
},
},
},
},
} {
t.Run(tc.scenario, func(t *testing.T) {
mod := &Prometheus{
namespace: "foo",
interval: time.Duration(1) * time.Second,
metrics: tc.metrics,
disableCollect: tc.disableCollect,
registry: prometheus.NewRegistry(),
}
err := mod.Start()
if err != nil {
t.Errorf("expected no error but got: %v", err)
}
})
}
}
func TestPrometheus_StartupMessage(t *testing.T) {
mod := new(Prometheus)
mod.disableCollect = true
disableCollectMsg := mod.StartupMessage()
mod.disableCollect = false
noDisableCollectMsg := mod.StartupMessage()
if disableCollectMsg == noDisableCollectMsg {
t.Errorf("expected differrent startup messages if collect is disabled or not, but got '%s'", disableCollectMsg)
}
}
func TestPrometheus_Stop(t *testing.T) {
err := new(Prometheus).Stop(nil)
if err != nil {
t.Errorf("expected no error but got: %v", err)
}
}
func TestPrometheus_Routes(t *testing.T) {
for _, tc := range []struct {
scenario string
disableCollect bool
expectRoutes int
}{
{
scenario: "collect disabled",
disableCollect: true,
expectRoutes: 0,
},
{
scenario: "routes not disabled",
disableCollect: false,
expectRoutes: 1,
},
} {
t.Run(tc.scenario, func(t *testing.T) {
mod := &Prometheus{
disableCollect: tc.disableCollect,
registry: prometheus.NewRegistry(),
}
routes, err := mod.Routes()
if err != nil {
t.Fatalf("expected no error but got: %v", err)
}
if tc.expectRoutes != len(routes) {
t.Errorf("expected %d routes but got %d", tc.expectRoutes, len(routes))
}
})
}
}