Raw File
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package ipsec

import (
	"fmt"
	"strings"

	. "github.com/cilium/checkmate"
	"github.com/prometheus/client_golang/prometheus/testutil"
	"github.com/prometheus/procfs"
)

type XFRMCollectorTest struct{}

var _ = Suite(&XFRMCollectorTest{})

var sampleStats = procfs.XfrmStat{
	XfrmInError:             1,
	XfrmInBufferError:       2,
	XfrmInHdrError:          3,
	XfrmInNoStates:          4,
	XfrmInStateProtoError:   5,
	XfrmInStateModeError:    6,
	XfrmInStateSeqError:     7,
	XfrmInStateExpired:      8,
	XfrmInStateMismatch:     9,
	XfrmInStateInvalid:      10,
	XfrmInTmplMismatch:      11,
	XfrmInNoPols:            12,
	XfrmInPolBlock:          13,
	XfrmInPolError:          14,
	XfrmOutError:            15,
	XfrmOutBundleGenError:   16,
	XfrmOutBundleCheckError: 17,
	XfrmOutNoStates:         18,
	XfrmOutStateProtoError:  19,
	XfrmOutStateModeError:   20,
	XfrmOutStateSeqError:    21,
	XfrmOutStateExpired:     22,
	XfrmOutPolBlock:         23,
	XfrmOutPolDead:          24,
	XfrmOutPolError:         25,
	XfrmFwdHdrError:         26,
	XfrmOutStateInvalid:     27,
	XfrmAcquireError:        28,
}

const (
	noErrorMetric = `
# HELP cilium_ipsec_xfrm_error Total number of xfrm errors
# TYPE cilium_ipsec_xfrm_error gauge
cilium_ipsec_xfrm_error{error="acquire",type="inbound"} 0
cilium_ipsec_xfrm_error{error="bundle_check",type="outbound"} 0
cilium_ipsec_xfrm_error{error="bundle_generation",type="outbound"} 0
cilium_ipsec_xfrm_error{error="forward_header",type="inbound"} 0
cilium_ipsec_xfrm_error{error="header",type="inbound"} 0
cilium_ipsec_xfrm_error{error="no_buffer",type="inbound"} 0
cilium_ipsec_xfrm_error{error="no_policy",type="inbound"} 0
cilium_ipsec_xfrm_error{error="no_state",type="inbound"} 0
cilium_ipsec_xfrm_error{error="no_state",type="outbound"} 0
cilium_ipsec_xfrm_error{error="other",type="inbound"} 0
cilium_ipsec_xfrm_error{error="other",type="outbound"} 0
cilium_ipsec_xfrm_error{error="policy",type="inbound"} 0
cilium_ipsec_xfrm_error{error="policy",type="outbound"} 0
cilium_ipsec_xfrm_error{error="policy_blocked",type="inbound"} 0
cilium_ipsec_xfrm_error{error="policy_blocked",type="outbound"} 0
cilium_ipsec_xfrm_error{error="policy_dead",type="outbound"} 0
cilium_ipsec_xfrm_error{error="state_expired",type="inbound"} 0
cilium_ipsec_xfrm_error{error="state_expired",type="outbound"} 0
cilium_ipsec_xfrm_error{error="state_invalid",type="inbound"} 0
cilium_ipsec_xfrm_error{error="state_invalid",type="outbound"} 0
cilium_ipsec_xfrm_error{error="state_mismatched",type="inbound"} 0
cilium_ipsec_xfrm_error{error="state_mode",type="inbound"} 0
cilium_ipsec_xfrm_error{error="state_mode",type="outbound"} 0
cilium_ipsec_xfrm_error{error="state_protocol",type="inbound"} 0
cilium_ipsec_xfrm_error{error="state_protocol",type="outbound"} 0
cilium_ipsec_xfrm_error{error="state_sequence",type="inbound"} 0
cilium_ipsec_xfrm_error{error="state_sequence",type="outbound"} 0
cilium_ipsec_xfrm_error{error="template_mismatched",type="inbound"} 0
`
	someErrorMetric = `
# HELP cilium_ipsec_xfrm_error Total number of xfrm errors
# TYPE cilium_ipsec_xfrm_error gauge
cilium_ipsec_xfrm_error{error="acquire",type="inbound"} 28
cilium_ipsec_xfrm_error{error="bundle_check",type="outbound"} 17
cilium_ipsec_xfrm_error{error="bundle_generation",type="outbound"} 16
cilium_ipsec_xfrm_error{error="forward_header",type="inbound"} 26
cilium_ipsec_xfrm_error{error="header",type="inbound"} 3
cilium_ipsec_xfrm_error{error="no_buffer",type="inbound"} 2
cilium_ipsec_xfrm_error{error="no_policy",type="inbound"} 12
cilium_ipsec_xfrm_error{error="no_state",type="inbound"} 4
cilium_ipsec_xfrm_error{error="no_state",type="outbound"} 18
cilium_ipsec_xfrm_error{error="other",type="inbound"} 1
cilium_ipsec_xfrm_error{error="other",type="outbound"} 15
cilium_ipsec_xfrm_error{error="policy",type="inbound"} 14
cilium_ipsec_xfrm_error{error="policy",type="outbound"} 25
cilium_ipsec_xfrm_error{error="policy_blocked",type="inbound"} 13
cilium_ipsec_xfrm_error{error="policy_blocked",type="outbound"} 23
cilium_ipsec_xfrm_error{error="policy_dead",type="outbound"} 24
cilium_ipsec_xfrm_error{error="state_expired",type="inbound"} 8
cilium_ipsec_xfrm_error{error="state_expired",type="outbound"} 22
cilium_ipsec_xfrm_error{error="state_invalid",type="inbound"} 10
cilium_ipsec_xfrm_error{error="state_invalid",type="outbound"} 27
cilium_ipsec_xfrm_error{error="state_mismatched",type="inbound"} 9
cilium_ipsec_xfrm_error{error="state_mode",type="inbound"} 6
cilium_ipsec_xfrm_error{error="state_mode",type="outbound"} 20
cilium_ipsec_xfrm_error{error="state_protocol",type="inbound"} 5
cilium_ipsec_xfrm_error{error="state_protocol",type="outbound"} 19
cilium_ipsec_xfrm_error{error="state_sequence",type="inbound"} 7
cilium_ipsec_xfrm_error{error="state_sequence",type="outbound"} 21
cilium_ipsec_xfrm_error{error="template_mismatched",type="inbound"} 11
`
)

func (x *XFRMCollectorTest) Test_xfrmCollector_Collect(c *C) {
	tests := []struct {
		name           string
		statsFn        func() (procfs.XfrmStat, error)
		expectedMetric string
		expectedCount  int
	}{
		{
			name: "error while getting stats",
			statsFn: func() (procfs.XfrmStat, error) {
				return procfs.XfrmStat{}, fmt.Errorf("error due to some reason")
			},
			expectedCount:  0,
			expectedMetric: "",
		},
		{
			name: "no data at all",
			statsFn: func() (procfs.XfrmStat, error) {
				return procfs.XfrmStat{}, nil
			},
			expectedCount:  28,
			expectedMetric: noErrorMetric,
		},
		{
			name: "some data",
			statsFn: func() (procfs.XfrmStat, error) {
				return sampleStats, nil
			},
			expectedCount:  28,
			expectedMetric: someErrorMetric,
		},
	}

	for _, tt := range tests {
		c.Log("Test : ", tt.name)
		collector := newXFRMCollector(tt.statsFn)

		// perform static checks such as prometheus naming convention, number of labels matching, etc
		lintProblems, err := testutil.CollectAndLint(collector)
		c.Assert(err, IsNil)
		c.Assert(lintProblems, HasLen, 0)

		// check the number of metrics
		count := testutil.CollectAndCount(collector)
		c.Assert(count, Equals, tt.expectedCount)

		// compare the metric output
		err = testutil.CollectAndCompare(collector, strings.NewReader(tt.expectedMetric))
		c.Assert(err, IsNil)
	}
}
back to top