depot/packages/networking/ipfs-cluster/monitor/metrics/checker_test.go

201 lines
4.1 KiB
Go
Raw Normal View History

2022-10-19 23:23:11 +03:00
package metrics
import (
"context"
"testing"
"time"
"github.com/ipfs-cluster/ipfs-cluster/api"
"github.com/ipfs-cluster/ipfs-cluster/test"
peer "github.com/libp2p/go-libp2p-core/peer"
)
func TestChecker_CheckPeers(t *testing.T) {
t.Run("check with single metric", func(t *testing.T) {
metrics := NewStore()
checker := NewChecker(context.Background(), metrics)
metr := api.Metric{
Name: "ping",
Peer: test.PeerID1,
Value: "1",
Valid: true,
}
metr.SetTTL(2 * time.Second)
metrics.Add(metr)
checker.CheckPeers([]peer.ID{test.PeerID1})
select {
case <-checker.Alerts():
t.Error("there should not be an alert yet")
default:
}
time.Sleep(3 * time.Second)
err := checker.CheckPeers([]peer.ID{test.PeerID1})
if err != nil {
t.Fatal(err)
}
select {
case <-checker.Alerts():
default:
t.Error("an alert should have been triggered")
}
checker.CheckPeers([]peer.ID{test.PeerID2})
select {
case <-checker.Alerts():
t.Error("there should not be alerts for different peer")
default:
}
})
}
func TestChecker_CheckAll(t *testing.T) {
t.Run("checkall with single metric", func(t *testing.T) {
metrics := NewStore()
checker := NewChecker(context.Background(), metrics)
metr := api.Metric{
Name: "ping",
Peer: test.PeerID1,
Value: "1",
Valid: true,
}
metr.SetTTL(2 * time.Second)
metrics.Add(metr)
checker.CheckAll()
select {
case <-checker.Alerts():
t.Error("there should not be an alert yet")
default:
}
time.Sleep(3 * time.Second)
err := checker.CheckAll()
if err != nil {
t.Fatal(err)
}
select {
case <-checker.Alerts():
default:
t.Error("an alert should have been triggered")
}
checker.CheckAll()
select {
case <-checker.Alerts():
t.Error("there should not be alerts for different peer")
default:
}
})
}
func TestChecker_Watch(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
metrics := NewStore()
checker := NewChecker(context.Background(), metrics)
metr := api.Metric{
Name: "ping",
Peer: test.PeerID1,
Value: "1",
Valid: true,
}
metr.SetTTL(100 * time.Millisecond)
metrics.Add(metr)
peersF := func(context.Context) ([]peer.ID, error) {
return []peer.ID{test.PeerID1}, nil
}
go checker.Watch(ctx, peersF, 200*time.Millisecond)
select {
case a := <-checker.Alerts():
t.Log("received alert:", a)
case <-ctx.Done():
t.Fatal("should have received an alert")
}
}
func TestChecker_Failed(t *testing.T) {
t.Run("standard failure check", func(t *testing.T) {
metrics := NewStore()
checker := NewChecker(context.Background(), metrics)
metrics.Add(makePeerMetric(test.PeerID1, "1", 100*time.Millisecond))
time.Sleep(50 * time.Millisecond)
got := checker.FailedMetric("ping", test.PeerID1)
if got {
t.Error("should not have failed so soon")
}
time.Sleep(100 * time.Millisecond)
got = checker.FailedMetric("ping", test.PeerID1)
if !got {
t.Error("should have failed")
}
})
}
func TestChecker_alert(t *testing.T) {
t.Run("remove peer from store after alert", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
metrics := NewStore()
checker := NewChecker(ctx, metrics)
metr := api.Metric{
Name: "ping",
Peer: test.PeerID1,
Value: "1",
Valid: true,
}
metr.SetTTL(100 * time.Millisecond)
metrics.Add(metr)
peersF := func(context.Context) ([]peer.ID, error) {
return []peer.ID{test.PeerID1}, nil
}
go checker.Watch(ctx, peersF, 200*time.Millisecond)
var alertCount int
for {
select {
case a := <-checker.Alerts():
t.Log("received alert:", a)
alertCount++
if alertCount > MaxAlertThreshold {
t.Fatalf("there should no more than %d alert", MaxAlertThreshold)
}
case <-ctx.Done():
if alertCount < 1 {
t.Fatal("should have received an alert")
}
return
}
}
})
}
func makePeerMetric(pid peer.ID, value string, ttl time.Duration) api.Metric {
metr := api.Metric{
Name: "ping",
Peer: pid,
Value: value,
Valid: true,
}
metr.SetTTL(ttl)
return metr
}