github.com/netdata/go.d.plugin@v0.58.1/modules/ping/ping_test.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package ping
     4  
     5  import (
     6  	"errors"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/netdata/go.d.plugin/logger"
    11  
    12  	probing "github.com/prometheus-community/pro-bing"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestPing_Init(t *testing.T) {
    18  	tests := map[string]struct {
    19  		wantFail bool
    20  		config   Config
    21  	}{
    22  		"fail with default": {
    23  			wantFail: true,
    24  			config:   New().Config,
    25  		},
    26  		"success when 'hosts' set": {
    27  			wantFail: false,
    28  			config: Config{
    29  				SendPackets: 1,
    30  				Hosts:       []string{"192.0.2.0"},
    31  			},
    32  		},
    33  	}
    34  
    35  	for name, test := range tests {
    36  		t.Run(name, func(t *testing.T) {
    37  			ping := New()
    38  			ping.Config = test.config
    39  			ping.UpdateEvery = 1
    40  
    41  			if test.wantFail {
    42  				assert.False(t, ping.Init())
    43  			} else {
    44  				assert.True(t, ping.Init())
    45  			}
    46  		})
    47  	}
    48  }
    49  
    50  func TestPing_Charts(t *testing.T) {
    51  	assert.NotNil(t, New().Charts())
    52  }
    53  
    54  func TestPing_Cleanup(t *testing.T) {
    55  	assert.NotPanics(t, New().Cleanup)
    56  }
    57  
    58  func TestPing_Check(t *testing.T) {
    59  	tests := map[string]struct {
    60  		wantFail bool
    61  		prepare  func(t *testing.T) *Ping
    62  	}{
    63  		"success when ping does not return an error": {
    64  			wantFail: false,
    65  			prepare:  casePingSuccess,
    66  		},
    67  		"fail when ping returns an error": {
    68  			wantFail: true,
    69  			prepare:  casePingError,
    70  		},
    71  	}
    72  
    73  	for name, test := range tests {
    74  		t.Run(name, func(t *testing.T) {
    75  			ping := test.prepare(t)
    76  
    77  			if test.wantFail {
    78  				assert.False(t, ping.Check())
    79  			} else {
    80  				assert.True(t, ping.Check())
    81  			}
    82  		})
    83  	}
    84  }
    85  
    86  func TestPing_Collect(t *testing.T) {
    87  	tests := map[string]struct {
    88  		prepare       func(t *testing.T) *Ping
    89  		wantMetrics   map[string]int64
    90  		wantNumCharts int
    91  	}{
    92  		"success when ping does not return an error": {
    93  			prepare: casePingSuccess,
    94  			wantMetrics: map[string]int64{
    95  				"host_192.0.2.1_avg_rtt":        15000,
    96  				"host_192.0.2.1_max_rtt":        20000,
    97  				"host_192.0.2.1_min_rtt":        10000,
    98  				"host_192.0.2.1_packet_loss":    0,
    99  				"host_192.0.2.1_packets_recv":   5,
   100  				"host_192.0.2.1_packets_sent":   5,
   101  				"host_192.0.2.1_std_dev_rtt":    5000,
   102  				"host_192.0.2.2_avg_rtt":        15000,
   103  				"host_192.0.2.2_max_rtt":        20000,
   104  				"host_192.0.2.2_min_rtt":        10000,
   105  				"host_192.0.2.2_packet_loss":    0,
   106  				"host_192.0.2.2_packets_recv":   5,
   107  				"host_192.0.2.2_packets_sent":   5,
   108  				"host_192.0.2.2_std_dev_rtt":    5000,
   109  				"host_example.com_avg_rtt":      15000,
   110  				"host_example.com_max_rtt":      20000,
   111  				"host_example.com_min_rtt":      10000,
   112  				"host_example.com_packet_loss":  0,
   113  				"host_example.com_packets_recv": 5,
   114  				"host_example.com_packets_sent": 5,
   115  				"host_example.com_std_dev_rtt":  5000,
   116  			},
   117  			wantNumCharts: 3 * len(hostChartsTmpl),
   118  		},
   119  		"fail when ping returns an error": {
   120  			prepare:       casePingError,
   121  			wantMetrics:   nil,
   122  			wantNumCharts: 0,
   123  		},
   124  	}
   125  
   126  	for name, test := range tests {
   127  		t.Run(name, func(t *testing.T) {
   128  			ping := test.prepare(t)
   129  
   130  			mx := ping.Collect()
   131  
   132  			require.Equal(t, test.wantMetrics, mx)
   133  
   134  			if len(test.wantMetrics) > 0 {
   135  				assert.Len(t, *ping.Charts(), test.wantNumCharts)
   136  			}
   137  		})
   138  	}
   139  }
   140  
   141  func casePingSuccess(t *testing.T) *Ping {
   142  	ping := New()
   143  	ping.UpdateEvery = 1
   144  	ping.Hosts = []string{"192.0.2.1", "192.0.2.2", "example.com"}
   145  	ping.newProber = func(_ pingProberConfig, _ *logger.Logger) prober {
   146  		return &mockProber{}
   147  	}
   148  	require.True(t, ping.Init())
   149  	return ping
   150  }
   151  
   152  func casePingError(t *testing.T) *Ping {
   153  	ping := New()
   154  	ping.UpdateEvery = 1
   155  	ping.Hosts = []string{"192.0.2.1", "192.0.2.2", "example.com"}
   156  	ping.newProber = func(_ pingProberConfig, _ *logger.Logger) prober {
   157  		return &mockProber{errOnPing: true}
   158  	}
   159  	require.True(t, ping.Init())
   160  	return ping
   161  }
   162  
   163  type mockProber struct {
   164  	errOnPing bool
   165  }
   166  
   167  func (m *mockProber) ping(host string) (*probing.Statistics, error) {
   168  	if m.errOnPing {
   169  		return nil, errors.New("mock.ping() error")
   170  	}
   171  
   172  	stats := probing.Statistics{
   173  		PacketsRecv:           5,
   174  		PacketsSent:           5,
   175  		PacketsRecvDuplicates: 0,
   176  		PacketLoss:            0,
   177  		Addr:                  host,
   178  		Rtts:                  nil,
   179  		MinRtt:                time.Millisecond * 10,
   180  		MaxRtt:                time.Millisecond * 20,
   181  		AvgRtt:                time.Millisecond * 15,
   182  		StdDevRtt:             time.Millisecond * 5,
   183  	}
   184  
   185  	return &stats, nil
   186  }