diff --git a/pkg/monitoring/prometheus.go b/pkg/monitoring/prometheus.go index eb31a35..34ceb8f 100644 --- a/pkg/monitoring/prometheus.go +++ b/pkg/monitoring/prometheus.go @@ -13,7 +13,7 @@ import ( type PrometheusReporter struct { countersVec map[string]*prometheus.CounterVec counters map[string]prometheus.Counter - gaugesVec map[string]prometheus.GaugeVec + gaugesVec map[string]*prometheus.GaugeVec gauges map[string]prometheus.Gauge histograms map[string]prometheus.Histogram histogramsVec map[string]*prometheus.HistogramVec @@ -24,7 +24,7 @@ func NewPrometheusReporter() *PrometheusReporter { p := PrometheusReporter{} p.countersVec = make(map[string]*prometheus.CounterVec) p.counters = make(map[string]prometheus.Counter) - p.gaugesVec = make(map[string]prometheus.GaugeVec) + p.gaugesVec = make(map[string]*prometheus.GaugeVec) p.gauges = make(map[string]prometheus.Gauge) p.histograms = make(map[string]prometheus.Histogram) p.histogramsVec = make(map[string]*prometheus.HistogramVec) @@ -128,7 +128,7 @@ func (p *PrometheusReporter) RegisterGauge(name string, c prometheus.Gauge) { // RegisterGaugeVec register gaugeVec in prometheus default registry // and add to map counter -func (p *PrometheusReporter) RegisterGaugeVec(name string, c prometheus.GaugeVec) { +func (p *PrometheusReporter) RegisterGaugeVec(name string, c *prometheus.GaugeVec) { prometheus.MustRegister(c) p.gaugesVec[name] = c } diff --git a/pkg/monitoring/prometheus_test.go b/pkg/monitoring/prometheus_test.go new file mode 100644 index 0000000..fe01a73 --- /dev/null +++ b/pkg/monitoring/prometheus_test.go @@ -0,0 +1,128 @@ +package monitoring + +import ( + "testing" + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" + + "github.com/stretchr/testify/assert" + "time" +) + +func TestPrometheusReporter_Counter(t *testing.T) { + p := NewPrometheusReporter() + + p.RegisterCounter("test", prometheus.NewCounter(prometheus.CounterOpts{ + Name: "mort_cache_ratio", + Help: "mort cache ratio", + })) + + p.Counter("test", 2) + + result := dto.Metric{} + p.counters["test"].Write(&result) + + assert.Equal(t, *result.Counter.Value, 2.) +} + +func TestPrometheusReporter_Gauge(t *testing.T) { + p := NewPrometheusReporter() + + p.RegisterGauge("test1", prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "mort_cache_ratio1", + Help: "mort cache ratio", + })) + + p.Gauge("test1", 5) + + result := dto.Metric{} + p.gauges["test1"].Write(&result) + + assert.Equal(t, *result.Gauge.Value, 5.) +} + +func TestPrometheusReporter_Histogram(t *testing.T) { + p := NewPrometheusReporter() + + p.RegisterHistogram("test2", prometheus.NewHistogram(prometheus.HistogramOpts{ + Name: "mort_cache_ratio2", + Help: "mort cache ratio", + })) + + p.Histogram("test2", 55) + + result := dto.Metric{} + p.histograms["test2"].Write(&result) + + assert.Equal(t, *result.Histogram.SampleSum, 55.) +} + +func TestPrometheusReporter_Inc(t *testing.T) { + p := NewPrometheusReporter() + + p.RegisterCounter("test3", prometheus.NewCounter(prometheus.CounterOpts{ + Name: "mort_cache_ratio3", + Help: "mort cache ratio", + })) + + p.Inc("test3", ) + + result := dto.Metric{} + p.counters["test3"].Write(&result) + + assert.Equal(t, *result.Counter.Value, 1.) +} + +func TestPrometheusReporter_Timer(t *testing.T) { + p := NewPrometheusReporter() + + p.RegisterHistogram("test-2", prometheus.NewHistogram(prometheus.HistogramOpts{ + Name: "mort_cache_ratio_2", + Help: "mort cache ratio", + })) + + tr := p.Timer("test-2") + time.Sleep(time.Millisecond * 100) + tr.Done() + + result := dto.Metric{} + p.histograms["test-2"].Write(&result) + + assert.InEpsilon(t, *result.Histogram.SampleSum, 100, 5) +} + +func TestPrometheusReporter_CounterVec(t *testing.T) { + p := NewPrometheusReporter() + + p.RegisterCounterVec("testvec", prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "mort_cache_ratio_vec", + Help: "mort cache ratio", + }, + []string{"label"}, + )) + + p.Counter("testvec;label:elo", 2) + + result := dto.Metric{} + p.countersVec["testvec"].With(prometheus.Labels{"label":"elo"}).Write(&result) + + assert.Equal(t, *result.Counter.Value, 2.) +} + +func TestPrometheusReporter_GaugeVec(t *testing.T) { + p := NewPrometheusReporter() + + p.RegisterGaugeVec("test1vec", prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "mort_cache_ratio1_vec", + Help: "mort cache ratio", + }, + []string{"label"}, + )) + + p.Gauge("test1vec;label:hej", 5) + + result := dto.Metric{} + p.gaugesVec["test1vec"].With(prometheus.Labels{"label":"hej"}).Write(&result) + + assert.Equal(t, *result.Gauge.Value, 5.) +} diff --git a/pkg/processor/benchmark/small.yml b/pkg/processor/benchmark/small.yml index 38f9e50..d5b727b 100644 --- a/pkg/processor/benchmark/small.yml +++ b/pkg/processor/benchmark/small.yml @@ -5,7 +5,7 @@ buckets: local: transform: path: "\\/(?P[a-zA-Z0-9\\.\\/]+)\\-(?P[a-z]+)" - kind: "presets" + kind: "presets-query" parentBucket: "local" presets: small: diff --git a/pkg/processor/processor_test.go b/pkg/processor/processor_test.go index 058f996..2248a86 100644 --- a/pkg/processor/processor_test.go +++ b/pkg/processor/processor_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "net/http" "testing" + "context" ) func TestNewRequestProcessor(t *testing.T) { @@ -30,6 +31,57 @@ func TestNewRequestProcessor(t *testing.T) { assert.Equal(t, res.Headers.Get("ETag"), "W/\"7eaa484e8c841e7e\"") } +func TestReturn404WhenParentNotFound(t *testing.T) { + req, _ := http.NewRequest("GET", "http://mort/local/small.not-m", nil) + + mortConfig := config.Config{} + err := mortConfig.Load("./benchmark/small.yml") + assert.Nil(t, err) + + obj, err := object.NewFileObject(req.URL, &mortConfig) + assert.Nil(t, err) + + rp := NewRequestProcessor(mortConfig.Server, lock.NewMemoryLock(), throttler.NewBucketThrottler(10)) + res := rp.Process(req, obj) + + assert.Equal(t, res.StatusCode, 404) +} + +func TestReturn503WhenThrottled(t *testing.T) { + req, _ := http.NewRequest("GET", "http://mort/local/small.jpg?width=5", nil) + + mortConfig := config.Config{} + err := mortConfig.Load("./benchmark/small.yml") + assert.Nil(t, err) + + obj, err := object.NewFileObject(req.URL, &mortConfig) + assert.Nil(t, err) + + rp := NewRequestProcessor(mortConfig.Server, lock.NewMemoryLock(), throttler.NewBucketThrottler(0)) + res := rp.Process(req, obj) + + assert.Equal(t, res.StatusCode, 503) +} + +func TestContextTimeout(t *testing.T) { + req, _ := http.NewRequest("GET", "http://mort/local/small.jpg?width=5", nil) + ctx, cancel := context.WithCancel(context.Background()) + req = req.WithContext(ctx) + cancel() + + mortConfig := config.Config{} + err := mortConfig.Load("./benchmark/small.yml") + assert.Nil(t, err) + + obj, err := object.NewFileObject(req.URL, &mortConfig) + assert.Nil(t, err) + + rp := NewRequestProcessor(mortConfig.Server, lock.NewMemoryLock(), throttler.NewBucketThrottler(0)) + res := rp.Process(req, obj) + + assert.Equal(t, res.StatusCode, 499) +} + func BenchmarkNewRequestProcessorMemoryLock(b *testing.B) { benchmarks := []struct { name string